/**
 * 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:indexed_db' show indexed_dbBlinkFunctionMap;
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_gl' show web_glBlinkFunctionMap;
import 'dart:web_sql';
import 'dart:svg' as svg;
import 'dart:svg' show svgBlinkMap;
import 'dart:svg' show svgBlinkFunctionMap;
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:web_audio' show web_audioBlinkFunctionMap;
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 = wrap_jso(js.JsNative.getProperty(js.context, 'window'));
  return _window;
}

HtmlDocument _document;

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

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

};

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

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

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

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

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

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

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

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

  return null;
}

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

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

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

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

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

Type _getSvgType(String key) {
  if (svgBlinkMap.containsKey(key)) {
    return svgBlinkMap[key]();
  }
  return null;
}

// FIXME: Can we make this private?
@Deprecated("Internal Use Only")
final htmlBlinkFunctionMap = {
  'Animation': () => Animation.internalCreateAnimation,
  'AnimationEffectReadOnly': () => AnimationEffectReadOnly.internalCreateAnimationEffectReadOnly,
  'AnimationEffectTiming': () => AnimationEffectTiming.internalCreateAnimationEffectTiming,
  'AnimationEvent': () => AnimationEvent.internalCreateAnimationEvent,
  'AnimationPlayerEvent': () => AnimationPlayerEvent.internalCreateAnimationPlayerEvent,
  'AnimationTimeline': () => AnimationTimeline.internalCreateAnimationTimeline,
  'AppBannerPromptResult': () => AppBannerPromptResult.internalCreateAppBannerPromptResult,
  'ApplicationCache': () => ApplicationCache.internalCreateApplicationCache,
  'ApplicationCacheErrorEvent': () => ApplicationCacheErrorEvent.internalCreateApplicationCacheErrorEvent,
  'Attr': () => _Attr.internalCreate_Attr,
  'AudioTrack': () => AudioTrack.internalCreateAudioTrack,
  'AudioTrackList': () => AudioTrackList.internalCreateAudioTrackList,
  'AutocompleteErrorEvent': () => AutocompleteErrorEvent.internalCreateAutocompleteErrorEvent,
  'BarProp': () => BarProp.internalCreateBarProp,
  'BatteryManager': () => BatteryManager.internalCreateBatteryManager,
  'BeforeInstallPromptEvent': () => BeforeInstallPromptEvent.internalCreateBeforeInstallPromptEvent,
  'BeforeUnloadEvent': () => BeforeUnloadEvent.internalCreateBeforeUnloadEvent,
  'Blob': () => Blob.internalCreateBlob,
  'Bluetooth': () => Bluetooth.internalCreateBluetooth,
  'BluetoothDevice': () => BluetoothDevice.internalCreateBluetoothDevice,
  'BluetoothGATTCharacteristic': () => BluetoothGattCharacteristic.internalCreateBluetoothGattCharacteristic,
  'BluetoothGATTRemoteServer': () => BluetoothGattRemoteServer.internalCreateBluetoothGattRemoteServer,
  'BluetoothGATTService': () => BluetoothGattService.internalCreateBluetoothGattService,
  'BluetoothUUID': () => BluetoothUuid.internalCreateBluetoothUuid,
  'Body': () => Body.internalCreateBody,
  'CDATASection': () => CDataSection.internalCreateCDataSection,
  'CHROMIUMValuebuffer': () => ChromiumValuebuffer.internalCreateChromiumValuebuffer,
  'CSS': () => Css.internalCreateCss,
  'CSSCharsetRule': () => CssCharsetRule.internalCreateCssCharsetRule,
  'CSSFontFaceRule': () => CssFontFaceRule.internalCreateCssFontFaceRule,
  'CSSGroupingRule': () => CssGroupingRule.internalCreateCssGroupingRule,
  'CSSImportRule': () => CssImportRule.internalCreateCssImportRule,
  'CSSKeyframeRule': () => CssKeyframeRule.internalCreateCssKeyframeRule,
  'CSSKeyframesRule': () => CssKeyframesRule.internalCreateCssKeyframesRule,
  'CSSMediaRule': () => CssMediaRule.internalCreateCssMediaRule,
  'CSSPageRule': () => CssPageRule.internalCreateCssPageRule,
  'CSSRule': () => CssRule.internalCreateCssRule,
  'CSSRuleList': () => _CssRuleList.internalCreate_CssRuleList,
  'CSSStyleDeclaration': () => CssStyleDeclaration.internalCreateCssStyleDeclaration,
  'CSSStyleRule': () => CssStyleRule.internalCreateCssStyleRule,
  'CSSStyleSheet': () => CssStyleSheet.internalCreateCssStyleSheet,
  'CSSSupportsRule': () => CssSupportsRule.internalCreateCssSupportsRule,
  'CSSViewportRule': () => CssViewportRule.internalCreateCssViewportRule,
  'Cache': () => _Cache.internalCreate_Cache,
  'CacheStorage': () => CacheStorage.internalCreateCacheStorage,
  'CanvasGradient': () => CanvasGradient.internalCreateCanvasGradient,
  'CanvasPattern': () => CanvasPattern.internalCreateCanvasPattern,
  'CanvasRenderingContext2D': () => CanvasRenderingContext2D.internalCreateCanvasRenderingContext2D,
  'CharacterData': () => CharacterData.internalCreateCharacterData,
  'CircularGeofencingRegion': () => CircularGeofencingRegion.internalCreateCircularGeofencingRegion,
  'Client': () => Client.internalCreateClient,
  'ClientRect': () => _ClientRect.internalCreate_ClientRect,
  'ClientRectList': () => _ClientRectList.internalCreate_ClientRectList,
  'Clients': () => Clients.internalCreateClients,
  'ClipboardEvent': () => ClipboardEvent.internalCreateClipboardEvent,
  'CloseEvent': () => CloseEvent.internalCreateCloseEvent,
  'Comment': () => Comment.internalCreateComment,
  'CompositionEvent': () => CompositionEvent.internalCreateCompositionEvent,
  'CompositorProxy': () => CompositorProxy.internalCreateCompositorProxy,
  'CompositorWorker': () => CompositorWorker.internalCreateCompositorWorker,
  'CompositorWorkerGlobalScope': () => CompositorWorkerGlobalScope.internalCreateCompositorWorkerGlobalScope,
  'Console': () => Console.internalCreateConsole,
  'ConsoleBase': () => ConsoleBase.internalCreateConsoleBase,
  'Coordinates': () => Coordinates.internalCreateCoordinates,
  'Credential': () => Credential.internalCreateCredential,
  'CredentialsContainer': () => CredentialsContainer.internalCreateCredentialsContainer,
  'CrossOriginConnectEvent': () => CrossOriginConnectEvent.internalCreateCrossOriginConnectEvent,
  'CrossOriginServiceWorkerClient': () => CrossOriginServiceWorkerClient.internalCreateCrossOriginServiceWorkerClient,
  'Crypto': () => Crypto.internalCreateCrypto,
  'CryptoKey': () => CryptoKey.internalCreateCryptoKey,
  'CustomEvent': () => CustomEvent.internalCreateCustomEvent,
  'DOMError': () => DomError.internalCreateDomError,
  'DOMException': () => DomException.internalCreateDomException,
  'DOMFileSystem': () => FileSystem.internalCreateFileSystem,
  'DOMFileSystemSync': () => _DOMFileSystemSync.internalCreate_DOMFileSystemSync,
  'DOMImplementation': () => DomImplementation.internalCreateDomImplementation,
  'DOMMatrix': () => DomMatrix.internalCreateDomMatrix,
  'DOMMatrixReadOnly': () => DomMatrixReadOnly.internalCreateDomMatrixReadOnly,
  'DOMParser': () => DomParser.internalCreateDomParser,
  'DOMPoint': () => DomPoint.internalCreateDomPoint,
  'DOMPointReadOnly': () => DomPointReadOnly.internalCreateDomPointReadOnly,
  'DOMRect': () => _DomRect.internalCreate_DomRect,
  'DOMRectReadOnly': () => DomRectReadOnly.internalCreateDomRectReadOnly,
  'DOMSettableTokenList': () => DomSettableTokenList.internalCreateDomSettableTokenList,
  'DOMStringList': () => DomStringList.internalCreateDomStringList,
  'DOMTokenList': () => DomTokenList.internalCreateDomTokenList,
  'DataTransfer': () => DataTransfer.internalCreateDataTransfer,
  'DataTransferItem': () => DataTransferItem.internalCreateDataTransferItem,
  'DataTransferItemList': () => DataTransferItemList.internalCreateDataTransferItemList,
  'DedicatedWorkerGlobalScope': () => DedicatedWorkerGlobalScope.internalCreateDedicatedWorkerGlobalScope,
  'DefaultSessionStartEvent': () => DefaultSessionStartEvent.internalCreateDefaultSessionStartEvent,
  'DeprecatedStorageInfo': () => DeprecatedStorageInfo.internalCreateDeprecatedStorageInfo,
  'DeprecatedStorageQuota': () => DeprecatedStorageQuota.internalCreateDeprecatedStorageQuota,
  'DeviceAcceleration': () => DeviceAcceleration.internalCreateDeviceAcceleration,
  'DeviceLightEvent': () => DeviceLightEvent.internalCreateDeviceLightEvent,
  'DeviceMotionEvent': () => DeviceMotionEvent.internalCreateDeviceMotionEvent,
  'DeviceOrientationEvent': () => DeviceOrientationEvent.internalCreateDeviceOrientationEvent,
  'DeviceRotationRate': () => DeviceRotationRate.internalCreateDeviceRotationRate,
  'DirectoryEntry': () => DirectoryEntry.internalCreateDirectoryEntry,
  'DirectoryEntrySync': () => _DirectoryEntrySync.internalCreate_DirectoryEntrySync,
  'DirectoryReader': () => DirectoryReader.internalCreateDirectoryReader,
  'DirectoryReaderSync': () => _DirectoryReaderSync.internalCreate_DirectoryReaderSync,
  'Document': () => Document.internalCreateDocument,
  'DocumentFragment': () => DocumentFragment.internalCreateDocumentFragment,
  'DocumentType': () => _DocumentType.internalCreate_DocumentType,
  'EffectModel': () => EffectModel.internalCreateEffectModel,
  'Element': () => Element.internalCreateElement,
  'Entry': () => Entry.internalCreateEntry,
  'EntrySync': () => _EntrySync.internalCreate_EntrySync,
  'ErrorEvent': () => ErrorEvent.internalCreateErrorEvent,
  'Event': () => Event.internalCreateEvent,
  'EventSource': () => EventSource.internalCreateEventSource,
  'EventTarget': () => EventTarget.internalCreateEventTarget,
  'ExtendableEvent': () => ExtendableEvent.internalCreateExtendableEvent,
  'FederatedCredential': () => FederatedCredential.internalCreateFederatedCredential,
  'FetchEvent': () => FetchEvent.internalCreateFetchEvent,
  'File': () => File.internalCreateFile,
  'FileEntry': () => FileEntry.internalCreateFileEntry,
  'FileEntrySync': () => _FileEntrySync.internalCreate_FileEntrySync,
  'FileError': () => FileError.internalCreateFileError,
  'FileList': () => FileList.internalCreateFileList,
  'FileReader': () => FileReader.internalCreateFileReader,
  'FileReaderSync': () => _FileReaderSync.internalCreate_FileReaderSync,
  'FileWriter': () => FileWriter.internalCreateFileWriter,
  'FileWriterSync': () => _FileWriterSync.internalCreate_FileWriterSync,
  'FocusEvent': () => FocusEvent.internalCreateFocusEvent,
  'FontFace': () => FontFace.internalCreateFontFace,
  'FontFaceSet': () => FontFaceSet.internalCreateFontFaceSet,
  'FontFaceSetLoadEvent': () => FontFaceSetLoadEvent.internalCreateFontFaceSetLoadEvent,
  'FormData': () => FormData.internalCreateFormData,
  'Gamepad': () => Gamepad.internalCreateGamepad,
  'GamepadButton': () => GamepadButton.internalCreateGamepadButton,
  'GamepadEvent': () => GamepadEvent.internalCreateGamepadEvent,
  'GamepadList': () => _GamepadList.internalCreate_GamepadList,
  'Geofencing': () => Geofencing.internalCreateGeofencing,
  'GeofencingEvent': () => GeofencingEvent.internalCreateGeofencingEvent,
  'GeofencingRegion': () => GeofencingRegion.internalCreateGeofencingRegion,
  'Geolocation': () => Geolocation.internalCreateGeolocation,
  'Geoposition': () => Geoposition.internalCreateGeoposition,
  'HMDVRDevice': () => HmdvrDevice.internalCreateHmdvrDevice,
  'HTMLAllCollection': () => _HTMLAllCollection.internalCreate_HTMLAllCollection,
  'HTMLAnchorElement': () => AnchorElement.internalCreateAnchorElement,
  'HTMLAppletElement': () => _HTMLAppletElement.internalCreate_HTMLAppletElement,
  'HTMLAreaElement': () => AreaElement.internalCreateAreaElement,
  'HTMLAudioElement': () => AudioElement.internalCreateAudioElement,
  'HTMLBRElement': () => BRElement.internalCreateBRElement,
  'HTMLBaseElement': () => BaseElement.internalCreateBaseElement,
  'HTMLBodyElement': () => BodyElement.internalCreateBodyElement,
  'HTMLButtonElement': () => ButtonElement.internalCreateButtonElement,
  'HTMLCanvasElement': () => CanvasElement.internalCreateCanvasElement,
  'HTMLCollection': () => HtmlCollection.internalCreateHtmlCollection,
  'HTMLContentElement': () => ContentElement.internalCreateContentElement,
  'HTMLDListElement': () => DListElement.internalCreateDListElement,
  'HTMLDataListElement': () => DataListElement.internalCreateDataListElement,
  'HTMLDetailsElement': () => DetailsElement.internalCreateDetailsElement,
  'HTMLDialogElement': () => DialogElement.internalCreateDialogElement,
  'HTMLDirectoryElement': () => _HTMLDirectoryElement.internalCreate_HTMLDirectoryElement,
  'HTMLDivElement': () => DivElement.internalCreateDivElement,
  'HTMLDocument': () => HtmlDocument.internalCreateHtmlDocument,
  'HTMLElement': () => HtmlElement.internalCreateHtmlElement,
  'HTMLEmbedElement': () => EmbedElement.internalCreateEmbedElement,
  'HTMLFieldSetElement': () => FieldSetElement.internalCreateFieldSetElement,
  'HTMLFontElement': () => _HTMLFontElement.internalCreate_HTMLFontElement,
  'HTMLFormControlsCollection': () => HtmlFormControlsCollection.internalCreateHtmlFormControlsCollection,
  'HTMLFormElement': () => FormElement.internalCreateFormElement,
  'HTMLFrameElement': () => _HTMLFrameElement.internalCreate_HTMLFrameElement,
  'HTMLFrameSetElement': () => _HTMLFrameSetElement.internalCreate_HTMLFrameSetElement,
  'HTMLHRElement': () => HRElement.internalCreateHRElement,
  'HTMLHeadElement': () => HeadElement.internalCreateHeadElement,
  'HTMLHeadingElement': () => HeadingElement.internalCreateHeadingElement,
  'HTMLHtmlElement': () => HtmlHtmlElement.internalCreateHtmlHtmlElement,
  'HTMLIFrameElement': () => IFrameElement.internalCreateIFrameElement,
  'HTMLImageElement': () => ImageElement.internalCreateImageElement,
  'HTMLInputElement': () => InputElement.internalCreateInputElement,
  'HTMLKeygenElement': () => KeygenElement.internalCreateKeygenElement,
  'HTMLLIElement': () => LIElement.internalCreateLIElement,
  'HTMLLabelElement': () => LabelElement.internalCreateLabelElement,
  'HTMLLegendElement': () => LegendElement.internalCreateLegendElement,
  'HTMLLinkElement': () => LinkElement.internalCreateLinkElement,
  'HTMLMapElement': () => MapElement.internalCreateMapElement,
  'HTMLMarqueeElement': () => _HTMLMarqueeElement.internalCreate_HTMLMarqueeElement,
  'HTMLMediaElement': () => MediaElement.internalCreateMediaElement,
  'HTMLMenuElement': () => MenuElement.internalCreateMenuElement,
  'HTMLMenuItemElement': () => MenuItemElement.internalCreateMenuItemElement,
  'HTMLMetaElement': () => MetaElement.internalCreateMetaElement,
  'HTMLMeterElement': () => MeterElement.internalCreateMeterElement,
  'HTMLModElement': () => ModElement.internalCreateModElement,
  'HTMLOListElement': () => OListElement.internalCreateOListElement,
  'HTMLObjectElement': () => ObjectElement.internalCreateObjectElement,
  'HTMLOptGroupElement': () => OptGroupElement.internalCreateOptGroupElement,
  'HTMLOptionElement': () => OptionElement.internalCreateOptionElement,
  'HTMLOptionsCollection': () => HtmlOptionsCollection.internalCreateHtmlOptionsCollection,
  'HTMLOutputElement': () => OutputElement.internalCreateOutputElement,
  'HTMLParagraphElement': () => ParagraphElement.internalCreateParagraphElement,
  'HTMLParamElement': () => ParamElement.internalCreateParamElement,
  'HTMLPictureElement': () => PictureElement.internalCreatePictureElement,
  'HTMLPreElement': () => PreElement.internalCreatePreElement,
  'HTMLProgressElement': () => ProgressElement.internalCreateProgressElement,
  'HTMLQuoteElement': () => QuoteElement.internalCreateQuoteElement,
  'HTMLScriptElement': () => ScriptElement.internalCreateScriptElement,
  'HTMLSelectElement': () => SelectElement.internalCreateSelectElement,
  'HTMLShadowElement': () => ShadowElement.internalCreateShadowElement,
  'HTMLSourceElement': () => SourceElement.internalCreateSourceElement,
  'HTMLSpanElement': () => SpanElement.internalCreateSpanElement,
  'HTMLStyleElement': () => StyleElement.internalCreateStyleElement,
  'HTMLTableCaptionElement': () => TableCaptionElement.internalCreateTableCaptionElement,
  'HTMLTableCellElement': () => TableCellElement.internalCreateTableCellElement,
  'HTMLTableColElement': () => TableColElement.internalCreateTableColElement,
  'HTMLTableElement': () => TableElement.internalCreateTableElement,
  'HTMLTableRowElement': () => TableRowElement.internalCreateTableRowElement,
  'HTMLTableSectionElement': () => TableSectionElement.internalCreateTableSectionElement,
  'HTMLTemplateElement': () => TemplateElement.internalCreateTemplateElement,
  'HTMLTextAreaElement': () => TextAreaElement.internalCreateTextAreaElement,
  'HTMLTitleElement': () => TitleElement.internalCreateTitleElement,
  'HTMLTrackElement': () => TrackElement.internalCreateTrackElement,
  'HTMLUListElement': () => UListElement.internalCreateUListElement,
  'HTMLUnknownElement': () => UnknownElement.internalCreateUnknownElement,
  'HTMLVideoElement': () => VideoElement.internalCreateVideoElement,
  'HashChangeEvent': () => HashChangeEvent.internalCreateHashChangeEvent,
  'Headers': () => Headers.internalCreateHeaders,
  'History': () => History.internalCreateHistory,
  'ImageBitmap': () => ImageBitmap.internalCreateImageBitmap,
  'ImageData': () => ImageData.internalCreateImageData,
  'InjectedScriptHost': () => InjectedScriptHost.internalCreateInjectedScriptHost,
  'InputDevice': () => InputDevice.internalCreateInputDevice,
  'Iterator': () => DomIterator.internalCreateDomIterator,
  'KeyboardEvent': () => KeyboardEvent.internalCreateKeyboardEvent,
  'KeyframeEffect': () => KeyframeEffect.internalCreateKeyframeEffect,
  'Location': () => Location.internalCreateLocation,
  'MIDIAccess': () => MidiAccess.internalCreateMidiAccess,
  'MIDIConnectionEvent': () => MidiConnectionEvent.internalCreateMidiConnectionEvent,
  'MIDIInput': () => MidiInput.internalCreateMidiInput,
  'MIDIInputMap': () => MidiInputMap.internalCreateMidiInputMap,
  'MIDIMessageEvent': () => MidiMessageEvent.internalCreateMidiMessageEvent,
  'MIDIOutput': () => MidiOutput.internalCreateMidiOutput,
  'MIDIOutputMap': () => MidiOutputMap.internalCreateMidiOutputMap,
  'MIDIPort': () => MidiPort.internalCreateMidiPort,
  'MediaController': () => MediaController.internalCreateMediaController,
  'MediaDeviceInfo': () => MediaDeviceInfo.internalCreateMediaDeviceInfo,
  'MediaDevices': () => MediaDevices.internalCreateMediaDevices,
  'MediaEncryptedEvent': () => MediaEncryptedEvent.internalCreateMediaEncryptedEvent,
  'MediaError': () => MediaError.internalCreateMediaError,
  'MediaKeyError': () => MediaKeyError.internalCreateMediaKeyError,
  'MediaKeyEvent': () => MediaKeyEvent.internalCreateMediaKeyEvent,
  'MediaKeyMessageEvent': () => MediaKeyMessageEvent.internalCreateMediaKeyMessageEvent,
  'MediaKeySession': () => MediaKeySession.internalCreateMediaKeySession,
  'MediaKeyStatusMap': () => MediaKeyStatusMap.internalCreateMediaKeyStatusMap,
  'MediaKeySystemAccess': () => MediaKeySystemAccess.internalCreateMediaKeySystemAccess,
  'MediaKeys': () => MediaKeys.internalCreateMediaKeys,
  'MediaList': () => MediaList.internalCreateMediaList,
  'MediaQueryList': () => MediaQueryList.internalCreateMediaQueryList,
  'MediaQueryListEvent': () => MediaQueryListEvent.internalCreateMediaQueryListEvent,
  'MediaSession': () => MediaSession.internalCreateMediaSession,
  'MediaSource': () => MediaSource.internalCreateMediaSource,
  'MediaStream': () => MediaStream.internalCreateMediaStream,
  'MediaStreamEvent': () => MediaStreamEvent.internalCreateMediaStreamEvent,
  'MediaStreamTrack': () => MediaStreamTrack.internalCreateMediaStreamTrack,
  'MediaStreamTrackEvent': () => MediaStreamTrackEvent.internalCreateMediaStreamTrackEvent,
  'MemoryInfo': () => MemoryInfo.internalCreateMemoryInfo,
  'MessageChannel': () => MessageChannel.internalCreateMessageChannel,
  'MessageEvent': () => MessageEvent.internalCreateMessageEvent,
  'MessagePort': () => MessagePort.internalCreateMessagePort,
  'Metadata': () => Metadata.internalCreateMetadata,
  'MimeType': () => MimeType.internalCreateMimeType,
  'MimeTypeArray': () => MimeTypeArray.internalCreateMimeTypeArray,
  'MouseEvent': () => MouseEvent.internalCreateMouseEvent,
  'MutationEvent': () => _MutationEvent.internalCreate_MutationEvent,
  'MutationObserver': () => MutationObserver.internalCreateMutationObserver,
  'MutationRecord': () => MutationRecord.internalCreateMutationRecord,
  'NamedNodeMap': () => _NamedNodeMap.internalCreate_NamedNodeMap,
  'Navigator': () => Navigator.internalCreateNavigator,
  'NavigatorStorageUtils': () => NavigatorStorageUtils.internalCreateNavigatorStorageUtils,
  'NavigatorUserMediaError': () => NavigatorUserMediaError.internalCreateNavigatorUserMediaError,
  'NetworkInformation': () => NetworkInformation.internalCreateNetworkInformation,
  'Node': () => Node.internalCreateNode,
  'NodeFilter': () => NodeFilter.internalCreateNodeFilter,
  'NodeIterator': () => NodeIterator.internalCreateNodeIterator,
  'NodeList': () => NodeList.internalCreateNodeList,
  'NonDocumentTypeChildNode': () => NonDocumentTypeChildNode.internalCreateNonDocumentTypeChildNode,
  'NonElementParentNode': () => NonElementParentNode.internalCreateNonElementParentNode,
  'Notification': () => Notification.internalCreateNotification,
  'NotificationEvent': () => NotificationEvent.internalCreateNotificationEvent,
  'PagePopupController': () => _PagePopupController.internalCreate_PagePopupController,
  'PageTransitionEvent': () => PageTransitionEvent.internalCreatePageTransitionEvent,
  'PasswordCredential': () => PasswordCredential.internalCreatePasswordCredential,
  'Path2D': () => Path2D.internalCreatePath2D,
  'Performance': () => Performance.internalCreatePerformance,
  'PerformanceCompositeTiming': () => PerformanceCompositeTiming.internalCreatePerformanceCompositeTiming,
  'PerformanceEntry': () => PerformanceEntry.internalCreatePerformanceEntry,
  'PerformanceMark': () => PerformanceMark.internalCreatePerformanceMark,
  'PerformanceMeasure': () => PerformanceMeasure.internalCreatePerformanceMeasure,
  'PerformanceNavigation': () => PerformanceNavigation.internalCreatePerformanceNavigation,
  'PerformanceRenderTiming': () => PerformanceRenderTiming.internalCreatePerformanceRenderTiming,
  'PerformanceResourceTiming': () => PerformanceResourceTiming.internalCreatePerformanceResourceTiming,
  'PerformanceTiming': () => PerformanceTiming.internalCreatePerformanceTiming,
  'PeriodicSyncEvent': () => PeriodicSyncEvent.internalCreatePeriodicSyncEvent,
  'PeriodicSyncManager': () => PeriodicSyncManager.internalCreatePeriodicSyncManager,
  'PeriodicSyncRegistration': () => PeriodicSyncRegistration.internalCreatePeriodicSyncRegistration,
  'PermissionStatus': () => PermissionStatus.internalCreatePermissionStatus,
  'Permissions': () => Permissions.internalCreatePermissions,
  'Plugin': () => Plugin.internalCreatePlugin,
  'PluginArray': () => PluginArray.internalCreatePluginArray,
  'PluginPlaceholderElement': () => PluginPlaceholderElement.internalCreatePluginPlaceholderElement,
  'PointerEvent': () => PointerEvent.internalCreatePointerEvent,
  'PopStateEvent': () => PopStateEvent.internalCreatePopStateEvent,
  'PositionError': () => PositionError.internalCreatePositionError,
  'PositionSensorVRDevice': () => PositionSensorVRDevice.internalCreatePositionSensorVRDevice,
  'Presentation': () => Presentation.internalCreatePresentation,
  'PresentationAvailability': () => PresentationAvailability.internalCreatePresentationAvailability,
  'PresentationSession': () => PresentationSession.internalCreatePresentationSession,
  'ProcessingInstruction': () => ProcessingInstruction.internalCreateProcessingInstruction,
  'ProgressEvent': () => ProgressEvent.internalCreateProgressEvent,
  'PromiseRejectionEvent': () => PromiseRejectionEvent.internalCreatePromiseRejectionEvent,
  'PushEvent': () => PushEvent.internalCreatePushEvent,
  'PushManager': () => PushManager.internalCreatePushManager,
  'PushMessageData': () => PushMessageData.internalCreatePushMessageData,
  'PushSubscription': () => PushSubscription.internalCreatePushSubscription,
  'RTCDTMFSender': () => RtcDtmfSender.internalCreateRtcDtmfSender,
  'RTCDTMFToneChangeEvent': () => RtcDtmfToneChangeEvent.internalCreateRtcDtmfToneChangeEvent,
  'RTCDataChannel': () => RtcDataChannel.internalCreateRtcDataChannel,
  'RTCDataChannelEvent': () => RtcDataChannelEvent.internalCreateRtcDataChannelEvent,
  'RTCIceCandidate': () => RtcIceCandidate.internalCreateRtcIceCandidate,
  'RTCIceCandidateEvent': () => RtcIceCandidateEvent.internalCreateRtcIceCandidateEvent,
  'RTCPeerConnection': () => RtcPeerConnection.internalCreateRtcPeerConnection,
  'RTCSessionDescription': () => RtcSessionDescription.internalCreateRtcSessionDescription,
  'RTCStatsReport': () => RtcStatsReport.internalCreateRtcStatsReport,
  'RTCStatsResponse': () => RtcStatsResponse.internalCreateRtcStatsResponse,
  'RadioNodeList': () => _RadioNodeList.internalCreate_RadioNodeList,
  'Range': () => Range.internalCreateRange,
  'ReadableByteStream': () => ReadableByteStream.internalCreateReadableByteStream,
  'ReadableByteStreamReader': () => ReadableByteStreamReader.internalCreateReadableByteStreamReader,
  'ReadableStream': () => ReadableStream.internalCreateReadableStream,
  'ReadableStreamReader': () => ReadableStreamReader.internalCreateReadableStreamReader,
  'RelatedEvent': () => RelatedEvent.internalCreateRelatedEvent,
  'Request': () => _Request.internalCreate_Request,
  'ResourceProgressEvent': () => ResourceProgressEvent.internalCreateResourceProgressEvent,
  'Response': () => _Response.internalCreate_Response,
  'Screen': () => Screen.internalCreateScreen,
  'ScreenOrientation': () => ScreenOrientation.internalCreateScreenOrientation,
  'ScrollState': () => ScrollState.internalCreateScrollState,
  'SecurityPolicyViolationEvent': () => SecurityPolicyViolationEvent.internalCreateSecurityPolicyViolationEvent,
  'Selection': () => Selection.internalCreateSelection,
  'ServicePort': () => ServicePort.internalCreateServicePort,
  'ServicePortCollection': () => ServicePortCollection.internalCreateServicePortCollection,
  'ServicePortConnectEvent': () => ServicePortConnectEvent.internalCreateServicePortConnectEvent,
  'ServiceWorker': () => _ServiceWorker.internalCreate_ServiceWorker,
  'ServiceWorkerContainer': () => ServiceWorkerContainer.internalCreateServiceWorkerContainer,
  'ServiceWorkerGlobalScope': () => ServiceWorkerGlobalScope.internalCreateServiceWorkerGlobalScope,
  'ServiceWorkerMessageEvent': () => ServiceWorkerMessageEvent.internalCreateServiceWorkerMessageEvent,
  'ServiceWorkerRegistration': () => ServiceWorkerRegistration.internalCreateServiceWorkerRegistration,
  'ShadowRoot': () => ShadowRoot.internalCreateShadowRoot,
  'SharedArrayBuffer': () => SharedArrayBuffer.internalCreateSharedArrayBuffer,
  'SharedWorker': () => SharedWorker.internalCreateSharedWorker,
  'SharedWorkerGlobalScope': () => SharedWorkerGlobalScope.internalCreateSharedWorkerGlobalScope,
  'SourceBuffer': () => SourceBuffer.internalCreateSourceBuffer,
  'SourceBufferList': () => SourceBufferList.internalCreateSourceBufferList,
  'SourceInfo': () => SourceInfo.internalCreateSourceInfo,
  'SpeechGrammar': () => SpeechGrammar.internalCreateSpeechGrammar,
  'SpeechGrammarList': () => SpeechGrammarList.internalCreateSpeechGrammarList,
  'SpeechRecognition': () => SpeechRecognition.internalCreateSpeechRecognition,
  'SpeechRecognitionAlternative': () => SpeechRecognitionAlternative.internalCreateSpeechRecognitionAlternative,
  'SpeechRecognitionError': () => SpeechRecognitionError.internalCreateSpeechRecognitionError,
  'SpeechRecognitionEvent': () => SpeechRecognitionEvent.internalCreateSpeechRecognitionEvent,
  'SpeechRecognitionResult': () => SpeechRecognitionResult.internalCreateSpeechRecognitionResult,
  'SpeechRecognitionResultList': () => _SpeechRecognitionResultList.internalCreate_SpeechRecognitionResultList,
  'SpeechSynthesis': () => SpeechSynthesis.internalCreateSpeechSynthesis,
  'SpeechSynthesisEvent': () => SpeechSynthesisEvent.internalCreateSpeechSynthesisEvent,
  'SpeechSynthesisUtterance': () => SpeechSynthesisUtterance.internalCreateSpeechSynthesisUtterance,
  'SpeechSynthesisVoice': () => SpeechSynthesisVoice.internalCreateSpeechSynthesisVoice,
  'StashedMessagePort': () => StashedMessagePort.internalCreateStashedMessagePort,
  'StashedPortCollection': () => StashedPortCollection.internalCreateStashedPortCollection,
  'Storage': () => Storage.internalCreateStorage,
  'StorageEvent': () => StorageEvent.internalCreateStorageEvent,
  'StorageInfo': () => StorageInfo.internalCreateStorageInfo,
  'StorageQuota': () => StorageQuota.internalCreateStorageQuota,
  'Stream': () => FileStream.internalCreateFileStream,
  'StyleMedia': () => StyleMedia.internalCreateStyleMedia,
  'StyleSheet': () => StyleSheet.internalCreateStyleSheet,
  'StyleSheetList': () => _StyleSheetList.internalCreate_StyleSheetList,
  'SubtleCrypto': () => _SubtleCrypto.internalCreate_SubtleCrypto,
  'SyncEvent': () => SyncEvent.internalCreateSyncEvent,
  'SyncManager': () => SyncManager.internalCreateSyncManager,
  'SyncRegistration': () => SyncRegistration.internalCreateSyncRegistration,
  'Text': () => Text.internalCreateText,
  'TextEvent': () => TextEvent.internalCreateTextEvent,
  'TextMetrics': () => TextMetrics.internalCreateTextMetrics,
  'TextTrack': () => TextTrack.internalCreateTextTrack,
  'TextTrackCue': () => TextTrackCue.internalCreateTextTrackCue,
  'TextTrackCueList': () => TextTrackCueList.internalCreateTextTrackCueList,
  'TextTrackList': () => TextTrackList.internalCreateTextTrackList,
  'TimeRanges': () => TimeRanges.internalCreateTimeRanges,
  'Touch': () => Touch.internalCreateTouch,
  'TouchEvent': () => TouchEvent.internalCreateTouchEvent,
  'TouchList': () => TouchList.internalCreateTouchList,
  'TrackDefault': () => TrackDefault.internalCreateTrackDefault,
  'TrackDefaultList': () => TrackDefaultList.internalCreateTrackDefaultList,
  'TrackEvent': () => TrackEvent.internalCreateTrackEvent,
  'TransitionEvent': () => TransitionEvent.internalCreateTransitionEvent,
  'TreeWalker': () => TreeWalker.internalCreateTreeWalker,
  'UIEvent': () => UIEvent.internalCreateUIEvent,
  'URL': () => Url.internalCreateUrl,
  'VRDevice': () => VRDevice.internalCreateVRDevice,
  'VREyeParameters': () => VREyeParameters.internalCreateVREyeParameters,
  'VRFieldOfView': () => VRFieldOfView.internalCreateVRFieldOfView,
  'VRPositionState': () => VRPositionState.internalCreateVRPositionState,
  'VTTCue': () => VttCue.internalCreateVttCue,
  'VTTRegion': () => VttRegion.internalCreateVttRegion,
  'VTTRegionList': () => VttRegionList.internalCreateVttRegionList,
  'ValidityState': () => ValidityState.internalCreateValidityState,
  'VideoPlaybackQuality': () => VideoPlaybackQuality.internalCreateVideoPlaybackQuality,
  'VideoTrack': () => VideoTrack.internalCreateVideoTrack,
  'VideoTrackList': () => VideoTrackList.internalCreateVideoTrackList,
  'WebKitCSSMatrix': () => _WebKitCSSMatrix.internalCreate_WebKitCSSMatrix,
  'WebSocket': () => WebSocket.internalCreateWebSocket,
  'WheelEvent': () => WheelEvent.internalCreateWheelEvent,
  'Window': () => Window.internalCreateWindow,
  'WindowClient': () => WindowClient.internalCreateWindowClient,
  'Worker': () => Worker.internalCreateWorker,
  'WorkerConsole': () => WorkerConsole.internalCreateWorkerConsole,
  'WorkerGlobalScope': () => WorkerGlobalScope.internalCreateWorkerGlobalScope,
  'WorkerLocation': () => _WorkerLocation.internalCreate_WorkerLocation,
  'WorkerNavigator': () => _WorkerNavigator.internalCreate_WorkerNavigator,
  'WorkerPerformance': () => WorkerPerformance.internalCreateWorkerPerformance,
  'XMLDocument': () => XmlDocument.internalCreateXmlDocument,
  'XMLHttpRequest': () => HttpRequest.internalCreateHttpRequest,
  'XMLHttpRequestEventTarget': () => HttpRequestEventTarget.internalCreateHttpRequestEventTarget,
  'XMLHttpRequestProgressEvent': () => _XMLHttpRequestProgressEvent.internalCreate_XMLHttpRequestProgressEvent,
  'XMLHttpRequestUpload': () => HttpRequestUpload.internalCreateHttpRequestUpload,
  'XMLSerializer': () => XmlSerializer.internalCreateXmlSerializer,
  'XPathEvaluator': () => XPathEvaluator.internalCreateXPathEvaluator,
  'XPathExpression': () => XPathExpression.internalCreateXPathExpression,
  'XPathNSResolver': () => XPathNSResolver.internalCreateXPathNSResolver,
  'XPathResult': () => XPathResult.internalCreateXPathResult,
  'XSLTProcessor': () => XsltProcessor.internalCreateXsltProcessor,
  'polymer-element': () => HtmlElement.internalCreateHtmlElement,

};

// TODO(terry): We may want to move this elsewhere if html becomes
// a package to avoid dartium depending on pkg:html.
@Deprecated("Internal Use Only")
getHtmlCreateFunction(String key) {
  var result;

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

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

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

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

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

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

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

  return null;
}

Function _getHtmlFunction(String key) {
  if (htmlBlinkFunctionMap.containsKey(key)) {
    return htmlBlinkFunctionMap[key]();
  }
  return null;
}

Function _getWebGlFunction(String key) {
  if (web_glBlinkFunctionMap.containsKey(key)) {
    return web_glBlinkFunctionMap[key]();
  }
  return null;
}

Function _getIndexDbFunction(String key) {
  if (indexed_dbBlinkFunctionMap.containsKey(key)) {
    return indexed_dbBlinkFunctionMap[key]();
  }
  return null;
}

Function _getWebAudioFunction(String key) {
  if (web_audioBlinkFunctionMap.containsKey(key)) {
    return web_audioBlinkFunctionMap[key]();
  }
  return null;
}

Function _getWebSqlFunction(String key) {
  if (web_sqlBlinkFunctionMap.containsKey(key)) {
    return web_sqlBlinkFunctionMap[key]();
  }
  return null;
}

Function _getSvgFunction(String key) {
  if (svgBlinkFunctionMap.containsKey(key)) {
    return svgBlinkFunctionMap[key]();
  }
  return null;
}


/******************************************************************************
 **********                                                          **********
 **********                    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 == HtmlElement) {
    tag = element.localName;
  } else if (runtimeType == TemplateElement) {
    // Data binding with a Dart class.
    tag = element.attributes['is'];
  } else if (runtimeType == js.JsObject) {
    // It's a Polymer core element (written in JS).
    // Make sure it's an element anything else we can ignore.
    if (element.hasProperty('nodeType') && element['nodeType'] == 1) {
      if (js.JsNative.callMethod(element, 'hasAttribute', ['is'])) {
        // It's data binding use the is attribute.
        tag = js.JsNative.callMethod(element, 'getAttribute', ['is']);
      } else {
        // 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] = wrap_jso(js.JsNative.getProperty(jsObject, key));
  }
  return result;
}

/**
 * Upgrade the JS HTMLElement to the Dart class.  Used by Dart's Polymer.
 */
_createCustomUpgrader(Type customElementClass, $this) {
  var dartClass;
  try {
    dartClass = _blink.Blink_Utils.constructElement(customElementClass, $this);
  } catch (e) {
    // Did the dartClass get allocated but the created failed?  Otherwise, other
    // components inside of this failed somewhere (could be JS custom element).
    if (dartClass != null) {
      // Yes, mark as didn't upgrade.
      dartClass._badUpgrade();
    }
    throw e;
  } finally {
    // Need to remember the Dart class that was created for this custom so
    // return it and setup the blink_jsObject to the $this that we'll be working
    // with as we talk to blink.
    js.setDartHtmlWrapperFor($this, dartClass);
  }

  return dartClass;
}

// 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<ErrorEvent> errorEvent = const EventStreamProvider<ErrorEvent>('error');

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

// WARNING: Do not edit - generated code.


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

  @DomName('HTMLAnchorElement.HTMLAnchorElement')
  @DocsEditable()
  factory AnchorElement({String href}) {
    var e = document.createElement("a");
    if (href != null) e.href = href;
    return e;
  }


  @Deprecated("Internal Use Only")
  static AnchorElement internalCreateAnchorElement() {
    return new AnchorElement._internalWrap();
  }

  external factory AnchorElement._internalWrap();

  @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_(unwrap_jso(this));
  
  @DomName('HTMLAnchorElement.download')
  @DocsEditable()
  set download(String value) => _blink.BlinkHTMLAnchorElement.instance.download_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLAnchorElement.hreflang')
  @DocsEditable()
  String get hreflang => _blink.BlinkHTMLAnchorElement.instance.hreflang_Getter_(unwrap_jso(this));
  
  @DomName('HTMLAnchorElement.hreflang')
  @DocsEditable()
  set hreflang(String value) => _blink.BlinkHTMLAnchorElement.instance.hreflang_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLAnchorElement.rel')
  @DocsEditable()
  String get rel => _blink.BlinkHTMLAnchorElement.instance.rel_Getter_(unwrap_jso(this));
  
  @DomName('HTMLAnchorElement.rel')
  @DocsEditable()
  set rel(String value) => _blink.BlinkHTMLAnchorElement.instance.rel_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLAnchorElement.target')
  @DocsEditable()
  String get target => _blink.BlinkHTMLAnchorElement.instance.target_Getter_(unwrap_jso(this));
  
  @DomName('HTMLAnchorElement.target')
  @DocsEditable()
  set target(String value) => _blink.BlinkHTMLAnchorElement.instance.target_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLAnchorElement.type')
  @DocsEditable()
  String get type => _blink.BlinkHTMLAnchorElement.instance.type_Getter_(unwrap_jso(this));
  
  @DomName('HTMLAnchorElement.type')
  @DocsEditable()
  set type(String value) => _blink.BlinkHTMLAnchorElement.instance.type_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLAnchorElement.hash')
  @DocsEditable()
  String get hash => _blink.BlinkHTMLAnchorElement.instance.hash_Getter_(unwrap_jso(this));
  
  @DomName('HTMLAnchorElement.hash')
  @DocsEditable()
  set hash(String value) => _blink.BlinkHTMLAnchorElement.instance.hash_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLAnchorElement.host')
  @DocsEditable()
  String get host => _blink.BlinkHTMLAnchorElement.instance.host_Getter_(unwrap_jso(this));
  
  @DomName('HTMLAnchorElement.host')
  @DocsEditable()
  set host(String value) => _blink.BlinkHTMLAnchorElement.instance.host_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLAnchorElement.hostname')
  @DocsEditable()
  String get hostname => _blink.BlinkHTMLAnchorElement.instance.hostname_Getter_(unwrap_jso(this));
  
  @DomName('HTMLAnchorElement.hostname')
  @DocsEditable()
  set hostname(String value) => _blink.BlinkHTMLAnchorElement.instance.hostname_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLAnchorElement.href')
  @DocsEditable()
  String get href => _blink.BlinkHTMLAnchorElement.instance.href_Getter_(unwrap_jso(this));
  
  @DomName('HTMLAnchorElement.href')
  @DocsEditable()
  set href(String value) => _blink.BlinkHTMLAnchorElement.instance.href_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLAnchorElement.origin')
  @DocsEditable()
  // WebKit only
  @Experimental() // non-standard
  String get origin => _blink.BlinkHTMLAnchorElement.instance.origin_Getter_(unwrap_jso(this));
  
  @DomName('HTMLAnchorElement.password')
  @DocsEditable()
  @Experimental() // untriaged
  String get password => _blink.BlinkHTMLAnchorElement.instance.password_Getter_(unwrap_jso(this));
  
  @DomName('HTMLAnchorElement.password')
  @DocsEditable()
  @Experimental() // untriaged
  set password(String value) => _blink.BlinkHTMLAnchorElement.instance.password_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLAnchorElement.pathname')
  @DocsEditable()
  String get pathname => _blink.BlinkHTMLAnchorElement.instance.pathname_Getter_(unwrap_jso(this));
  
  @DomName('HTMLAnchorElement.pathname')
  @DocsEditable()
  set pathname(String value) => _blink.BlinkHTMLAnchorElement.instance.pathname_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLAnchorElement.port')
  @DocsEditable()
  String get port => _blink.BlinkHTMLAnchorElement.instance.port_Getter_(unwrap_jso(this));
  
  @DomName('HTMLAnchorElement.port')
  @DocsEditable()
  set port(String value) => _blink.BlinkHTMLAnchorElement.instance.port_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLAnchorElement.protocol')
  @DocsEditable()
  String get protocol => _blink.BlinkHTMLAnchorElement.instance.protocol_Getter_(unwrap_jso(this));
  
  @DomName('HTMLAnchorElement.protocol')
  @DocsEditable()
  set protocol(String value) => _blink.BlinkHTMLAnchorElement.instance.protocol_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLAnchorElement.search')
  @DocsEditable()
  String get search => _blink.BlinkHTMLAnchorElement.instance.search_Getter_(unwrap_jso(this));
  
  @DomName('HTMLAnchorElement.search')
  @DocsEditable()
  set search(String value) => _blink.BlinkHTMLAnchorElement.instance.search_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLAnchorElement.username')
  @DocsEditable()
  @Experimental() // untriaged
  String get username => _blink.BlinkHTMLAnchorElement.instance.username_Getter_(unwrap_jso(this));
  
  @DomName('HTMLAnchorElement.username')
  @DocsEditable()
  @Experimental() // untriaged
  set username(String value) => _blink.BlinkHTMLAnchorElement.instance.username_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLAnchorElement.toString')
  @DocsEditable()
  String toString() => _blink.BlinkHTMLAnchorElement.instance.toString_Callback_0_(unwrap_jso(this));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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")
  static Animation internalCreateAnimation() {
    return new Animation._internalWrap();
  }

  external factory Animation._internalWrap();

  @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_(unwrap_jso(this));
  
  @DomName('Animation.currentTime')
  @DocsEditable()
  @Experimental() // untriaged
  set currentTime(num value) => _blink.BlinkAnimation.instance.currentTime_Setter_(unwrap_jso(this), value);
  
  @DomName('Animation.effect')
  @DocsEditable()
  @Experimental() // untriaged
  AnimationEffectReadOnly get effect => wrap_jso(_blink.BlinkAnimation.instance.effect_Getter_(unwrap_jso(this)));
  
  @DomName('Animation.effect')
  @DocsEditable()
  @Experimental() // untriaged
  set effect(AnimationEffectReadOnly value) => _blink.BlinkAnimation.instance.effect_Setter_(unwrap_jso(this), unwrap_jso(value));
  
  @DomName('Animation.endClip')
  @DocsEditable()
  @Experimental() // untriaged
  num get endClip => _blink.BlinkAnimation.instance.endClip_Getter_(unwrap_jso(this));
  
  @DomName('Animation.endClip')
  @DocsEditable()
  @Experimental() // untriaged
  set endClip(num value) => _blink.BlinkAnimation.instance.endClip_Setter_(unwrap_jso(this), value);
  
  @DomName('Animation.finished')
  @DocsEditable()
  @Experimental() // untriaged
  Future get finished => wrap_jso(_blink.BlinkAnimation.instance.finished_Getter_(unwrap_jso(this)));
  
  @DomName('Animation.playState')
  @DocsEditable()
  @Experimental() // untriaged
  String get playState => _blink.BlinkAnimation.instance.playState_Getter_(unwrap_jso(this));
  
  @DomName('Animation.playbackRate')
  @DocsEditable()
  @Experimental() // untriaged
  num get playbackRate => _blink.BlinkAnimation.instance.playbackRate_Getter_(unwrap_jso(this));
  
  @DomName('Animation.playbackRate')
  @DocsEditable()
  @Experimental() // untriaged
  set playbackRate(num value) => _blink.BlinkAnimation.instance.playbackRate_Setter_(unwrap_jso(this), value);
  
  @DomName('Animation.ready')
  @DocsEditable()
  @Experimental() // untriaged
  Future get ready => wrap_jso(_blink.BlinkAnimation.instance.ready_Getter_(unwrap_jso(this)));
  
  @DomName('Animation.startClip')
  @DocsEditable()
  @Experimental() // untriaged
  num get startClip => _blink.BlinkAnimation.instance.startClip_Getter_(unwrap_jso(this));
  
  @DomName('Animation.startClip')
  @DocsEditable()
  @Experimental() // untriaged
  set startClip(num value) => _blink.BlinkAnimation.instance.startClip_Setter_(unwrap_jso(this), value);
  
  @DomName('Animation.startTime')
  @DocsEditable()
  @Experimental() // untriaged
  num get startTime => _blink.BlinkAnimation.instance.startTime_Getter_(unwrap_jso(this));
  
  @DomName('Animation.startTime')
  @DocsEditable()
  @Experimental() // untriaged
  set startTime(num value) => _blink.BlinkAnimation.instance.startTime_Setter_(unwrap_jso(this), value);
  
  @DomName('Animation.cancel')
  @DocsEditable()
  @Experimental() // untriaged
  void cancel() => _blink.BlinkAnimation.instance.cancel_Callback_0_(unwrap_jso(this));
  
  @DomName('Animation.finish')
  @DocsEditable()
  @Experimental() // untriaged
  void finish() => _blink.BlinkAnimation.instance.finish_Callback_0_(unwrap_jso(this));
  
  @DomName('Animation.pause')
  @DocsEditable()
  @Experimental() // untriaged
  void pause() => _blink.BlinkAnimation.instance.pause_Callback_0_(unwrap_jso(this));
  
  @DomName('Animation.play')
  @DocsEditable()
  @Experimental() // untriaged
  void play() => _blink.BlinkAnimation.instance.play_Callback_0_(unwrap_jso(this));
  
  @DomName('Animation.reverse')
  @DocsEditable()
  @Experimental() // untriaged
  void reverse() => _blink.BlinkAnimation.instance.reverse_Callback_0_(unwrap_jso(this));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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")
  static AnimationEffectReadOnly internalCreateAnimationEffectReadOnly() {
    return new AnimationEffectReadOnly._internalWrap();
  }

  factory AnimationEffectReadOnly._internalWrap() {
    return new AnimationEffectReadOnly.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  @DomName('AnimationEffectReadOnly.computedTiming')
  @DocsEditable()
  @Experimental() // untriaged
   get computedTiming => convertNativeDictionaryToDartDictionary(wrap_jso(_blink.BlinkAnimationEffectReadOnly.instance.computedTiming_Getter_(unwrap_jso(this))));
  
  @DomName('AnimationEffectReadOnly.timing')
  @DocsEditable()
  @Experimental() // untriaged
  AnimationEffectTiming get timing => wrap_jso(_blink.BlinkAnimationEffectReadOnly.instance.timing_Getter_(unwrap_jso(this)));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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")
  static AnimationEffectTiming internalCreateAnimationEffectTiming() {
    return new AnimationEffectTiming._internalWrap();
  }

  factory AnimationEffectTiming._internalWrap() {
    return new AnimationEffectTiming.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  @DomName('AnimationEffectTiming.delay')
  @DocsEditable()
  @Experimental() // untriaged
  num get delay => _blink.BlinkAnimationEffectTiming.instance.delay_Getter_(unwrap_jso(this));
  
  @DomName('AnimationEffectTiming.delay')
  @DocsEditable()
  @Experimental() // untriaged
  set delay(num value) => _blink.BlinkAnimationEffectTiming.instance.delay_Setter_(unwrap_jso(this), value);
  
  @DomName('AnimationEffectTiming.direction')
  @DocsEditable()
  @Experimental() // untriaged
  String get direction => _blink.BlinkAnimationEffectTiming.instance.direction_Getter_(unwrap_jso(this));
  
  @DomName('AnimationEffectTiming.direction')
  @DocsEditable()
  @Experimental() // untriaged
  set direction(String value) => _blink.BlinkAnimationEffectTiming.instance.direction_Setter_(unwrap_jso(this), value);
  
  @DomName('AnimationEffectTiming.duration')
  @DocsEditable()
  @Experimental() // untriaged
  Object get duration => wrap_jso(_blink.BlinkAnimationEffectTiming.instance.duration_Getter_(unwrap_jso(this)));
  
  @DomName('AnimationEffectTiming.duration')
  @DocsEditable()
  @Experimental() // untriaged
  set duration(Object value) => _blink.BlinkAnimationEffectTiming.instance.duration_Setter_(unwrap_jso(this), unwrap_jso(value));
  
  @DomName('AnimationEffectTiming.easing')
  @DocsEditable()
  @Experimental() // untriaged
  String get easing => _blink.BlinkAnimationEffectTiming.instance.easing_Getter_(unwrap_jso(this));
  
  @DomName('AnimationEffectTiming.easing')
  @DocsEditable()
  @Experimental() // untriaged
  set easing(String value) => _blink.BlinkAnimationEffectTiming.instance.easing_Setter_(unwrap_jso(this), value);
  
  @DomName('AnimationEffectTiming.endDelay')
  @DocsEditable()
  @Experimental() // untriaged
  num get endDelay => _blink.BlinkAnimationEffectTiming.instance.endDelay_Getter_(unwrap_jso(this));
  
  @DomName('AnimationEffectTiming.endDelay')
  @DocsEditable()
  @Experimental() // untriaged
  set endDelay(num value) => _blink.BlinkAnimationEffectTiming.instance.endDelay_Setter_(unwrap_jso(this), value);
  
  @DomName('AnimationEffectTiming.fill')
  @DocsEditable()
  @Experimental() // untriaged
  String get fill => _blink.BlinkAnimationEffectTiming.instance.fill_Getter_(unwrap_jso(this));
  
  @DomName('AnimationEffectTiming.fill')
  @DocsEditable()
  @Experimental() // untriaged
  set fill(String value) => _blink.BlinkAnimationEffectTiming.instance.fill_Setter_(unwrap_jso(this), value);
  
  @DomName('AnimationEffectTiming.iterationStart')
  @DocsEditable()
  @Experimental() // untriaged
  num get iterationStart => _blink.BlinkAnimationEffectTiming.instance.iterationStart_Getter_(unwrap_jso(this));
  
  @DomName('AnimationEffectTiming.iterationStart')
  @DocsEditable()
  @Experimental() // untriaged
  set iterationStart(num value) => _blink.BlinkAnimationEffectTiming.instance.iterationStart_Setter_(unwrap_jso(this), value);
  
  @DomName('AnimationEffectTiming.iterations')
  @DocsEditable()
  @Experimental() // untriaged
  num get iterations => _blink.BlinkAnimationEffectTiming.instance.iterations_Getter_(unwrap_jso(this));
  
  @DomName('AnimationEffectTiming.iterations')
  @DocsEditable()
  @Experimental() // untriaged
  set iterations(num value) => _blink.BlinkAnimationEffectTiming.instance.iterations_Setter_(unwrap_jso(this), value);
  
  @DomName('AnimationEffectTiming.playbackRate')
  @DocsEditable()
  @Experimental() // untriaged
  num get playbackRate => _blink.BlinkAnimationEffectTiming.instance.playbackRate_Getter_(unwrap_jso(this));
  
  @DomName('AnimationEffectTiming.playbackRate')
  @DocsEditable()
  @Experimental() // untriaged
  set playbackRate(num value) => _blink.BlinkAnimationEffectTiming.instance.playbackRate_Setter_(unwrap_jso(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 wrap_jso(_blink.BlinkAnimationEvent.instance.constructorCallback_2_(type, eventInitDict_1));
    }
    return wrap_jso(_blink.BlinkAnimationEvent.instance.constructorCallback_1_(type));
  }


  @Deprecated("Internal Use Only")
  static AnimationEvent internalCreateAnimationEvent() {
    return new AnimationEvent._internalWrap();
  }

  external factory AnimationEvent._internalWrap();

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


  @DomName('AnimationEvent.animationName')
  @DocsEditable()
  @Experimental() // untriaged
  String get animationName => _blink.BlinkAnimationEvent.instance.animationName_Getter_(unwrap_jso(this));
  
  @DomName('AnimationEvent.elapsedTime')
  @DocsEditable()
  @Experimental() // untriaged
  num get elapsedTime => _blink.BlinkAnimationEvent.instance.elapsedTime_Getter_(unwrap_jso(this));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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 wrap_jso(_blink.BlinkAnimationPlayerEvent.instance.constructorCallback_2_(type, eventInitDict_1));
    }
    return wrap_jso(_blink.BlinkAnimationPlayerEvent.instance.constructorCallback_1_(type));
  }


  @Deprecated("Internal Use Only")
  static AnimationPlayerEvent internalCreateAnimationPlayerEvent() {
    return new AnimationPlayerEvent._internalWrap();
  }

  external factory AnimationPlayerEvent._internalWrap();

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


  @DomName('AnimationPlayerEvent.currentTime')
  @DocsEditable()
  @Experimental() // untriaged
  num get currentTime => _blink.BlinkAnimationPlayerEvent.instance.currentTime_Getter_(unwrap_jso(this));
  
  @DomName('AnimationPlayerEvent.timelineTime')
  @DocsEditable()
  @Experimental() // untriaged
  num get timelineTime => _blink.BlinkAnimationPlayerEvent.instance.timelineTime_Getter_(unwrap_jso(this));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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")
  static AnimationTimeline internalCreateAnimationTimeline() {
    return new AnimationTimeline._internalWrap();
  }

  factory AnimationTimeline._internalWrap() {
    return new AnimationTimeline.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  @DomName('AnimationTimeline.currentTime')
  @DocsEditable()
  @Experimental() // untriaged
  num get currentTime => _blink.BlinkAnimationTimeline.instance.currentTime_Getter_(unwrap_jso(this));
  
  @DomName('AnimationTimeline.currentTime')
  @DocsEditable()
  @Experimental() // untriaged
  set currentTime(num value) => _blink.BlinkAnimationTimeline.instance.currentTime_Setter_(unwrap_jso(this), value);
  
  @DomName('AnimationTimeline.playbackRate')
  @DocsEditable()
  @Experimental() // untriaged
  num get playbackRate => _blink.BlinkAnimationTimeline.instance.playbackRate_Getter_(unwrap_jso(this));
  
  @DomName('AnimationTimeline.playbackRate')
  @DocsEditable()
  @Experimental() // untriaged
  set playbackRate(num value) => _blink.BlinkAnimationTimeline.instance.playbackRate_Setter_(unwrap_jso(this), value);
  
  @DomName('AnimationTimeline.getAnimations')
  @DocsEditable()
  @Experimental() // untriaged
  List<Animation> getAnimations() => wrap_jso(_blink.BlinkAnimationTimeline.instance.getAnimations_Callback_0_(unwrap_jso(this)));
  
  @DomName('AnimationTimeline.play')
  @DocsEditable()
  @Experimental() // untriaged
  Animation play(AnimationEffectReadOnly source) => wrap_jso(_blink.BlinkAnimationTimeline.instance.play_Callback_1_(unwrap_jso(this), unwrap_jso(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")
  static AppBannerPromptResult internalCreateAppBannerPromptResult() {
    return new AppBannerPromptResult._internalWrap();
  }

  factory AppBannerPromptResult._internalWrap() {
    return new AppBannerPromptResult.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  @DomName('AppBannerPromptResult.outcome')
  @DocsEditable()
  @Experimental() // untriaged
  String get outcome => _blink.BlinkAppBannerPromptResult.instance.outcome_Getter_(unwrap_jso(this));
  
  @DomName('AppBannerPromptResult.platform')
  @DocsEditable()
  @Experimental() // untriaged
  String get platform => _blink.BlinkAppBannerPromptResult.instance.platform_Getter_(unwrap_jso(this));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this 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")
  static ApplicationCache internalCreateApplicationCache() {
    return new ApplicationCache._internalWrap();
  }

  external factory ApplicationCache._internalWrap();

  @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_(unwrap_jso(this));
  
  @DomName('ApplicationCache.abort')
  @DocsEditable()
  void abort() => _blink.BlinkApplicationCache.instance.abort_Callback_0_(unwrap_jso(this));
  
  @DomName('ApplicationCache.swapCache')
  @DocsEditable()
  void swapCache() => _blink.BlinkApplicationCache.instance.swapCache_Callback_0_(unwrap_jso(this));
  
  @DomName('ApplicationCache.update')
  @DocsEditable()
  void update() => _blink.BlinkApplicationCache.instance.update_Callback_0_(unwrap_jso(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 wrap_jso(_blink.BlinkApplicationCacheErrorEvent.instance.constructorCallback_2_(type, eventInitDict_1));
    }
    return wrap_jso(_blink.BlinkApplicationCacheErrorEvent.instance.constructorCallback_1_(type));
  }


  @Deprecated("Internal Use Only")
  static ApplicationCacheErrorEvent internalCreateApplicationCacheErrorEvent() {
    return new ApplicationCacheErrorEvent._internalWrap();
  }

  external factory ApplicationCacheErrorEvent._internalWrap();

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


  @DomName('ApplicationCacheErrorEvent.message')
  @DocsEditable()
  @Experimental() // untriaged
  String get message => _blink.BlinkApplicationCacheErrorEvent.instance.message_Getter_(unwrap_jso(this));
  
  @DomName('ApplicationCacheErrorEvent.reason')
  @DocsEditable()
  @Experimental() // untriaged
  String get reason => _blink.BlinkApplicationCacheErrorEvent.instance.reason_Getter_(unwrap_jso(this));
  
  @DomName('ApplicationCacheErrorEvent.status')
  @DocsEditable()
  @Experimental() // untriaged
  int get status => _blink.BlinkApplicationCacheErrorEvent.instance.status_Getter_(unwrap_jso(this));
  
  @DomName('ApplicationCacheErrorEvent.url')
  @DocsEditable()
  @Experimental() // untriaged
  String get url => _blink.BlinkApplicationCacheErrorEvent.instance.url_Getter_(unwrap_jso(this));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this 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")
  static AreaElement internalCreateAreaElement() {
    return new AreaElement._internalWrap();
  }

  external factory AreaElement._internalWrap();

  @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_(unwrap_jso(this));
  
  @DomName('HTMLAreaElement.alt')
  @DocsEditable()
  set alt(String value) => _blink.BlinkHTMLAreaElement.instance.alt_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLAreaElement.coords')
  @DocsEditable()
  String get coords => _blink.BlinkHTMLAreaElement.instance.coords_Getter_(unwrap_jso(this));
  
  @DomName('HTMLAreaElement.coords')
  @DocsEditable()
  set coords(String value) => _blink.BlinkHTMLAreaElement.instance.coords_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLAreaElement.shape')
  @DocsEditable()
  String get shape => _blink.BlinkHTMLAreaElement.instance.shape_Getter_(unwrap_jso(this));
  
  @DomName('HTMLAreaElement.shape')
  @DocsEditable()
  set shape(String value) => _blink.BlinkHTMLAreaElement.instance.shape_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLAreaElement.target')
  @DocsEditable()
  String get target => _blink.BlinkHTMLAreaElement.instance.target_Getter_(unwrap_jso(this));
  
  @DomName('HTMLAreaElement.target')
  @DocsEditable()
  set target(String value) => _blink.BlinkHTMLAreaElement.instance.target_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLAreaElement.hash')
  @DocsEditable()
  String get hash => _blink.BlinkHTMLAreaElement.instance.hash_Getter_(unwrap_jso(this));
  
  @DomName('HTMLAreaElement.hash')
  @DocsEditable()
  set hash(String value) => _blink.BlinkHTMLAreaElement.instance.hash_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLAreaElement.host')
  @DocsEditable()
  String get host => _blink.BlinkHTMLAreaElement.instance.host_Getter_(unwrap_jso(this));
  
  @DomName('HTMLAreaElement.host')
  @DocsEditable()
  set host(String value) => _blink.BlinkHTMLAreaElement.instance.host_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLAreaElement.hostname')
  @DocsEditable()
  String get hostname => _blink.BlinkHTMLAreaElement.instance.hostname_Getter_(unwrap_jso(this));
  
  @DomName('HTMLAreaElement.hostname')
  @DocsEditable()
  set hostname(String value) => _blink.BlinkHTMLAreaElement.instance.hostname_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLAreaElement.href')
  @DocsEditable()
  String get href => _blink.BlinkHTMLAreaElement.instance.href_Getter_(unwrap_jso(this));
  
  @DomName('HTMLAreaElement.href')
  @DocsEditable()
  set href(String value) => _blink.BlinkHTMLAreaElement.instance.href_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLAreaElement.origin')
  @DocsEditable()
  @Experimental() // untriaged
  String get origin => _blink.BlinkHTMLAreaElement.instance.origin_Getter_(unwrap_jso(this));
  
  @DomName('HTMLAreaElement.password')
  @DocsEditable()
  @Experimental() // untriaged
  String get password => _blink.BlinkHTMLAreaElement.instance.password_Getter_(unwrap_jso(this));
  
  @DomName('HTMLAreaElement.password')
  @DocsEditable()
  @Experimental() // untriaged
  set password(String value) => _blink.BlinkHTMLAreaElement.instance.password_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLAreaElement.pathname')
  @DocsEditable()
  String get pathname => _blink.BlinkHTMLAreaElement.instance.pathname_Getter_(unwrap_jso(this));
  
  @DomName('HTMLAreaElement.pathname')
  @DocsEditable()
  set pathname(String value) => _blink.BlinkHTMLAreaElement.instance.pathname_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLAreaElement.port')
  @DocsEditable()
  String get port => _blink.BlinkHTMLAreaElement.instance.port_Getter_(unwrap_jso(this));
  
  @DomName('HTMLAreaElement.port')
  @DocsEditable()
  set port(String value) => _blink.BlinkHTMLAreaElement.instance.port_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLAreaElement.protocol')
  @DocsEditable()
  String get protocol => _blink.BlinkHTMLAreaElement.instance.protocol_Getter_(unwrap_jso(this));
  
  @DomName('HTMLAreaElement.protocol')
  @DocsEditable()
  set protocol(String value) => _blink.BlinkHTMLAreaElement.instance.protocol_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLAreaElement.search')
  @DocsEditable()
  String get search => _blink.BlinkHTMLAreaElement.instance.search_Getter_(unwrap_jso(this));
  
  @DomName('HTMLAreaElement.search')
  @DocsEditable()
  set search(String value) => _blink.BlinkHTMLAreaElement.instance.search_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLAreaElement.username')
  @DocsEditable()
  @Experimental() // untriaged
  String get username => _blink.BlinkHTMLAreaElement.instance.username_Getter_(unwrap_jso(this));
  
  @DomName('HTMLAreaElement.username')
  @DocsEditable()
  @Experimental() // untriaged
  set username(String value) => _blink.BlinkHTMLAreaElement.instance.username_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLAreaElement.toString')
  @DocsEditable()
  @Experimental() // untriaged
  String toString() => _blink.BlinkHTMLAreaElement.instance.toString_Callback_0_(unwrap_jso(this));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All 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 wrap_jso(_blink.BlinkHTMLAudioElement.instance.constructorCallback_1_(src));
  }


  @Deprecated("Internal Use Only")
  static AudioElement internalCreateAudioElement() {
    return new AudioElement._internalWrap();
  }

  external factory AudioElement._internalWrap();

  @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 wrap_jso(_blink.BlinkHTMLAudioElement.instance.constructorCallback_0_());
    else
      return wrap_jso(_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")
  static AudioTrack internalCreateAudioTrack() {
    return new AudioTrack._internalWrap();
  }

  factory AudioTrack._internalWrap() {
    return new AudioTrack.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  @DomName('AudioTrack.enabled')
  @DocsEditable()
  @Experimental() // untriaged
  bool get enabled => _blink.BlinkAudioTrack.instance.enabled_Getter_(unwrap_jso(this));
  
  @DomName('AudioTrack.enabled')
  @DocsEditable()
  @Experimental() // untriaged
  set enabled(bool value) => _blink.BlinkAudioTrack.instance.enabled_Setter_(unwrap_jso(this), value);
  
  @DomName('AudioTrack.id')
  @DocsEditable()
  @Experimental() // untriaged
  String get id => _blink.BlinkAudioTrack.instance.id_Getter_(unwrap_jso(this));
  
  @DomName('AudioTrack.kind')
  @DocsEditable()
  @Experimental() // untriaged
  String get kind => _blink.BlinkAudioTrack.instance.kind_Getter_(unwrap_jso(this));
  
  @DomName('AudioTrack.label')
  @DocsEditable()
  @Experimental() // untriaged
  String get label => _blink.BlinkAudioTrack.instance.label_Getter_(unwrap_jso(this));
  
  @DomName('AudioTrack.language')
  @DocsEditable()
  @Experimental() // untriaged
  String get language => _blink.BlinkAudioTrack.instance.language_Getter_(unwrap_jso(this));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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")
  static AudioTrackList internalCreateAudioTrackList() {
    return new AudioTrackList._internalWrap();
  }

  external factory AudioTrackList._internalWrap();

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


  @DomName('AudioTrackList.length')
  @DocsEditable()
  @Experimental() // untriaged
  int get length => _blink.BlinkAudioTrackList.instance.length_Getter_(unwrap_jso(this));
  
  @DomName('AudioTrackList.__getter__')
  @DocsEditable()
  @Experimental() // untriaged
  AudioTrack __getter__(int index) => wrap_jso(_blink.BlinkAudioTrackList.instance.$__getter___Callback_1_(unwrap_jso(this), index));
  
  @DomName('AudioTrackList.getTrackById')
  @DocsEditable()
  @Experimental() // untriaged
  AudioTrack getTrackById(String id) => wrap_jso(_blink.BlinkAudioTrackList.instance.getTrackById_Callback_1_(unwrap_jso(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 wrap_jso(_blink.BlinkAutocompleteErrorEvent.instance.constructorCallback_2_(type, eventInitDict_1));
    }
    return wrap_jso(_blink.BlinkAutocompleteErrorEvent.instance.constructorCallback_1_(type));
  }


  @Deprecated("Internal Use Only")
  static AutocompleteErrorEvent internalCreateAutocompleteErrorEvent() {
    return new AutocompleteErrorEvent._internalWrap();
  }

  external factory AutocompleteErrorEvent._internalWrap();

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


  @DomName('AutocompleteErrorEvent.reason')
  @DocsEditable()
  String get reason => _blink.BlinkAutocompleteErrorEvent.instance.reason_Getter_(unwrap_jso(this));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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")
  static BRElement internalCreateBRElement() {
    return new BRElement._internalWrap();
  }

  external factory BRElement._internalWrap();

  @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")
  static BarProp internalCreateBarProp() {
    return new BarProp._internalWrap();
  }

  factory BarProp._internalWrap() {
    return new BarProp.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  @DomName('BarProp.visible')
  @DocsEditable()
  bool get visible => _blink.BlinkBarProp.instance.visible_Getter_(unwrap_jso(this));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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")
  static BaseElement internalCreateBaseElement() {
    return new BaseElement._internalWrap();
  }

  external factory BaseElement._internalWrap();

  @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_(unwrap_jso(this));
  
  @DomName('HTMLBaseElement.href')
  @DocsEditable()
  set href(String value) => _blink.BlinkHTMLBaseElement.instance.href_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLBaseElement.target')
  @DocsEditable()
  String get target => _blink.BlinkHTMLBaseElement.instance.target_Getter_(unwrap_jso(this));
  
  @DomName('HTMLBaseElement.target')
  @DocsEditable()
  set target(String value) => _blink.BlinkHTMLBaseElement.instance.target_Setter_(unwrap_jso(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")
  static BatteryManager internalCreateBatteryManager() {
    return new BatteryManager._internalWrap();
  }

  external factory BatteryManager._internalWrap();

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


  @DomName('BatteryManager.charging')
  @DocsEditable()
  bool get charging => _blink.BlinkBatteryManager.instance.charging_Getter_(unwrap_jso(this));
  
  @DomName('BatteryManager.chargingTime')
  @DocsEditable()
  num get chargingTime => _blink.BlinkBatteryManager.instance.chargingTime_Getter_(unwrap_jso(this));
  
  @DomName('BatteryManager.dischargingTime')
  @DocsEditable()
  num get dischargingTime => _blink.BlinkBatteryManager.instance.dischargingTime_Getter_(unwrap_jso(this));
  
  @DomName('BatteryManager.level')
  @DocsEditable()
  num get level => _blink.BlinkBatteryManager.instance.level_Getter_(unwrap_jso(this));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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 wrap_jso(_blink.BlinkBeforeInstallPromptEvent.instance.constructorCallback_2_(type, eventInitDict_1));
    }
    return wrap_jso(_blink.BlinkBeforeInstallPromptEvent.instance.constructorCallback_1_(type));
  }


  @Deprecated("Internal Use Only")
  static BeforeInstallPromptEvent internalCreateBeforeInstallPromptEvent() {
    return new BeforeInstallPromptEvent._internalWrap();
  }

  external factory BeforeInstallPromptEvent._internalWrap();

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


  @DomName('BeforeInstallPromptEvent.platforms')
  @DocsEditable()
  @Experimental() // untriaged
  List<String> get platforms => _blink.BlinkBeforeInstallPromptEvent.instance.platforms_Getter_(unwrap_jso(this));
  
  @DomName('BeforeInstallPromptEvent.userChoice')
  @DocsEditable()
  @Experimental() // untriaged
  Future get userChoice => wrap_jso(_blink.BlinkBeforeInstallPromptEvent.instance.userChoice_Getter_(unwrap_jso(this)));
  
  @DomName('BeforeInstallPromptEvent.prompt')
  @DocsEditable()
  @Experimental() // untriaged
  Future prompt() => wrap_jso(_blink.BlinkBeforeInstallPromptEvent.instance.prompt_Callback_0_(unwrap_jso(this)));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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")
  static BeforeUnloadEvent internalCreateBeforeUnloadEvent() {
    return new BeforeUnloadEvent._internalWrap();
  }

  external factory BeforeUnloadEvent._internalWrap();

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


  @DomName('BeforeUnloadEvent.returnValue')
  @DocsEditable()
  String get returnValue => _blink.BlinkBeforeUnloadEvent.instance.returnValue_Getter_(unwrap_jso(this));
  
  @DomName('BeforeUnloadEvent.returnValue')
  @DocsEditable()
  set returnValue(String value) => _blink.BlinkBeforeUnloadEvent.instance.returnValue_Setter_(unwrap_jso(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")
  static Blob internalCreateBlob() {
    return new Blob._internalWrap();
  }

  factory Blob._internalWrap() {
    return new Blob.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  @DomName('Blob.size')
  @DocsEditable()
  int get size => _blink.BlinkBlob.instance.size_Getter_(unwrap_jso(this));
  
  @DomName('Blob.type')
  @DocsEditable()
  String get type => _blink.BlinkBlob.instance.type_Getter_(unwrap_jso(this));
  
  @DomName('Blob.close')
  @DocsEditable()
  @Experimental() // untriaged
  void close() => _blink.BlinkBlob.instance.close_Callback_0_(unwrap_jso(this));
  
  Blob slice([int start, int end, String contentType]) {
    if (contentType != null) {
      return wrap_jso(_blink.BlinkBlob.instance.slice_Callback_3_(unwrap_jso(this), start, end, contentType));
    }
    if (end != null) {
      return wrap_jso(_blink.BlinkBlob.instance.slice_Callback_2_(unwrap_jso(this), start, end));
    }
    if (start != null) {
      return wrap_jso(_blink.BlinkBlob.instance.slice_Callback_1_(unwrap_jso(this), start));
    }
    return wrap_jso(_blink.BlinkBlob.instance.slice_Callback_0_(unwrap_jso(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.map(unwrap_jso).toList());
    if (type == null && endings == null) {
      return wrap_jso(_blink.BlinkBlob.instance.constructorCallback_1_(parts));
    }
    var bag = {};
    if (type != null) bag['type'] = type;
    if (endings != null) bag['endings'] = endings;
    return wrap_jso(_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")
  static Bluetooth internalCreateBluetooth() {
    return new Bluetooth._internalWrap();
  }

  factory Bluetooth._internalWrap() {
    return new Bluetooth.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  @DomName('Bluetooth.requestDevice')
  @DocsEditable()
  @Experimental() // untriaged
  Future requestDevice(Map options) => wrap_jso(_blink.BlinkBluetooth.instance.requestDevice_Callback_1_(unwrap_jso(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")
  static BluetoothDevice internalCreateBluetoothDevice() {
    return new BluetoothDevice._internalWrap();
  }

  factory BluetoothDevice._internalWrap() {
    return new BluetoothDevice.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  @DomName('BluetoothDevice.deviceClass')
  @DocsEditable()
  @Experimental() // untriaged
  int get deviceClass => _blink.BlinkBluetoothDevice.instance.deviceClass_Getter_(unwrap_jso(this));
  
  @DomName('BluetoothDevice.instanceID')
  @DocsEditable()
  @Experimental() // untriaged
  String get instanceID => _blink.BlinkBluetoothDevice.instance.instanceID_Getter_(unwrap_jso(this));
  
  @DomName('BluetoothDevice.name')
  @DocsEditable()
  @Experimental() // untriaged
  String get name => _blink.BlinkBluetoothDevice.instance.name_Getter_(unwrap_jso(this));
  
  @DomName('BluetoothDevice.paired')
  @DocsEditable()
  @Experimental() // untriaged
  bool get paired => _blink.BlinkBluetoothDevice.instance.paired_Getter_(unwrap_jso(this));
  
  @DomName('BluetoothDevice.productID')
  @DocsEditable()
  @Experimental() // untriaged
  int get productID => _blink.BlinkBluetoothDevice.instance.productID_Getter_(unwrap_jso(this));
  
  @DomName('BluetoothDevice.productVersion')
  @DocsEditable()
  @Experimental() // untriaged
  int get productVersion => _blink.BlinkBluetoothDevice.instance.productVersion_Getter_(unwrap_jso(this));
  
  @DomName('BluetoothDevice.vendorID')
  @DocsEditable()
  @Experimental() // untriaged
  int get vendorID => _blink.BlinkBluetoothDevice.instance.vendorID_Getter_(unwrap_jso(this));
  
  @DomName('BluetoothDevice.vendorIDSource')
  @DocsEditable()
  @Experimental() // untriaged
  String get vendorIDSource => _blink.BlinkBluetoothDevice.instance.vendorIDSource_Getter_(unwrap_jso(this));
  
  @DomName('BluetoothDevice.connectGATT')
  @DocsEditable()
  @Experimental() // untriaged
  Future connectGatt() => wrap_jso(_blink.BlinkBluetoothDevice.instance.connectGATT_Callback_0_(unwrap_jso(this)));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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")
  static BluetoothGattCharacteristic internalCreateBluetoothGattCharacteristic() {
    return new BluetoothGattCharacteristic._internalWrap();
  }

  factory BluetoothGattCharacteristic._internalWrap() {
    return new BluetoothGattCharacteristic.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  @DomName('BluetoothGATTCharacteristic.uuid')
  @DocsEditable()
  @Experimental() // untriaged
  String get uuid => _blink.BlinkBluetoothGATTCharacteristic.instance.uuid_Getter_(unwrap_jso(this));
  
  @DomName('BluetoothGATTCharacteristic.readValue')
  @DocsEditable()
  @Experimental() // untriaged
  Future readValue() => wrap_jso(_blink.BlinkBluetoothGATTCharacteristic.instance.readValue_Callback_0_(unwrap_jso(this)));
  
  @DomName('BluetoothGATTCharacteristic.writeValue')
  @DocsEditable()
  @Experimental() // untriaged
  Future writeValue(/*BufferSource*/ value) => wrap_jso(_blink.BlinkBluetoothGATTCharacteristic.instance.writeValue_Callback_1_(unwrap_jso(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")
  static BluetoothGattRemoteServer internalCreateBluetoothGattRemoteServer() {
    return new BluetoothGattRemoteServer._internalWrap();
  }

  factory BluetoothGattRemoteServer._internalWrap() {
    return new BluetoothGattRemoteServer.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  @DomName('BluetoothGATTRemoteServer.connected')
  @DocsEditable()
  @Experimental() // untriaged
  bool get connected => _blink.BlinkBluetoothGATTRemoteServer.instance.connected_Getter_(unwrap_jso(this));
  
  @DomName('BluetoothGATTRemoteServer.getPrimaryService')
  @DocsEditable()
  @Experimental() // untriaged
  Future getPrimaryService(/*BluetoothServiceUUID*/ service) => wrap_jso(_blink.BlinkBluetoothGATTRemoteServer.instance.getPrimaryService_Callback_1_(unwrap_jso(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")
  static BluetoothGattService internalCreateBluetoothGattService() {
    return new BluetoothGattService._internalWrap();
  }

  factory BluetoothGattService._internalWrap() {
    return new BluetoothGattService.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  @DomName('BluetoothGATTService.isPrimary')
  @DocsEditable()
  @Experimental() // untriaged
  bool get isPrimary => _blink.BlinkBluetoothGATTService.instance.isPrimary_Getter_(unwrap_jso(this));
  
  @DomName('BluetoothGATTService.uuid')
  @DocsEditable()
  @Experimental() // untriaged
  String get uuid => _blink.BlinkBluetoothGATTService.instance.uuid_Getter_(unwrap_jso(this));
  
  @DomName('BluetoothGATTService.getCharacteristic')
  @DocsEditable()
  @Experimental() // untriaged
  Future getCharacteristic(/*BluetoothCharacteristicUUID*/ characteristic) => wrap_jso(_blink.BlinkBluetoothGATTService.instance.getCharacteristic_Callback_1_(unwrap_jso(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")
  static BluetoothUuid internalCreateBluetoothUuid() {
    return new BluetoothUuid._internalWrap();
  }

  factory BluetoothUuid._internalWrap() {
    return new BluetoothUuid.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  @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")
  static Body internalCreateBody() {
    return new Body._internalWrap();
  }

  factory Body._internalWrap() {
    return new Body.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  @DomName('Body.bodyUsed')
  @DocsEditable()
  @Experimental() // untriaged
  bool get bodyUsed => _blink.BlinkBody.instance.bodyUsed_Getter_(unwrap_jso(this));
  
  @DomName('Body.arrayBuffer')
  @DocsEditable()
  @Experimental() // untriaged
  Future arrayBuffer() => wrap_jso(_blink.BlinkBody.instance.arrayBuffer_Callback_0_(unwrap_jso(this)));
  
  @DomName('Body.blob')
  @DocsEditable()
  @Experimental() // untriaged
  Future blob() => wrap_jso(_blink.BlinkBody.instance.blob_Callback_0_(unwrap_jso(this)));
  
  @DomName('Body.json')
  @DocsEditable()
  @Experimental() // untriaged
  Future json() => wrap_jso(_blink.BlinkBody.instance.json_Callback_0_(unwrap_jso(this)));
  
  @DomName('Body.text')
  @DocsEditable()
  @Experimental() // untriaged
  Future text() => wrap_jso(_blink.BlinkBody.instance.text_Callback_0_(unwrap_jso(this)));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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")
  static BodyElement internalCreateBodyElement() {
    return new BodyElement._internalWrap();
  }

  external factory BodyElement._internalWrap();

  @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")
  static ButtonElement internalCreateButtonElement() {
    return new ButtonElement._internalWrap();
  }

  external factory ButtonElement._internalWrap();

  @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_(unwrap_jso(this));
  
  @DomName('HTMLButtonElement.autofocus')
  @DocsEditable()
  set autofocus(bool value) => _blink.BlinkHTMLButtonElement.instance.autofocus_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLButtonElement.disabled')
  @DocsEditable()
  bool get disabled => _blink.BlinkHTMLButtonElement.instance.disabled_Getter_(unwrap_jso(this));
  
  @DomName('HTMLButtonElement.disabled')
  @DocsEditable()
  set disabled(bool value) => _blink.BlinkHTMLButtonElement.instance.disabled_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLButtonElement.form')
  @DocsEditable()
  FormElement get form => wrap_jso(_blink.BlinkHTMLButtonElement.instance.form_Getter_(unwrap_jso(this)));
  
  @DomName('HTMLButtonElement.formAction')
  @DocsEditable()
  String get formAction => _blink.BlinkHTMLButtonElement.instance.formAction_Getter_(unwrap_jso(this));
  
  @DomName('HTMLButtonElement.formAction')
  @DocsEditable()
  set formAction(String value) => _blink.BlinkHTMLButtonElement.instance.formAction_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLButtonElement.formEnctype')
  @DocsEditable()
  String get formEnctype => _blink.BlinkHTMLButtonElement.instance.formEnctype_Getter_(unwrap_jso(this));
  
  @DomName('HTMLButtonElement.formEnctype')
  @DocsEditable()
  set formEnctype(String value) => _blink.BlinkHTMLButtonElement.instance.formEnctype_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLButtonElement.formMethod')
  @DocsEditable()
  String get formMethod => _blink.BlinkHTMLButtonElement.instance.formMethod_Getter_(unwrap_jso(this));
  
  @DomName('HTMLButtonElement.formMethod')
  @DocsEditable()
  set formMethod(String value) => _blink.BlinkHTMLButtonElement.instance.formMethod_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLButtonElement.formNoValidate')
  @DocsEditable()
  bool get formNoValidate => _blink.BlinkHTMLButtonElement.instance.formNoValidate_Getter_(unwrap_jso(this));
  
  @DomName('HTMLButtonElement.formNoValidate')
  @DocsEditable()
  set formNoValidate(bool value) => _blink.BlinkHTMLButtonElement.instance.formNoValidate_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLButtonElement.formTarget')
  @DocsEditable()
  String get formTarget => _blink.BlinkHTMLButtonElement.instance.formTarget_Getter_(unwrap_jso(this));
  
  @DomName('HTMLButtonElement.formTarget')
  @DocsEditable()
  set formTarget(String value) => _blink.BlinkHTMLButtonElement.instance.formTarget_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLButtonElement.labels')
  @DocsEditable()
  @Unstable()
  List<Node> get labels => wrap_jso(_blink.BlinkHTMLButtonElement.instance.labels_Getter_(unwrap_jso(this)));
  
  @DomName('HTMLButtonElement.name')
  @DocsEditable()
  String get name => _blink.BlinkHTMLButtonElement.instance.name_Getter_(unwrap_jso(this));
  
  @DomName('HTMLButtonElement.name')
  @DocsEditable()
  set name(String value) => _blink.BlinkHTMLButtonElement.instance.name_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLButtonElement.type')
  @DocsEditable()
  String get type => _blink.BlinkHTMLButtonElement.instance.type_Getter_(unwrap_jso(this));
  
  @DomName('HTMLButtonElement.type')
  @DocsEditable()
  set type(String value) => _blink.BlinkHTMLButtonElement.instance.type_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLButtonElement.validationMessage')
  @DocsEditable()
  String get validationMessage => _blink.BlinkHTMLButtonElement.instance.validationMessage_Getter_(unwrap_jso(this));
  
  @DomName('HTMLButtonElement.validity')
  @DocsEditable()
  ValidityState get validity => wrap_jso(_blink.BlinkHTMLButtonElement.instance.validity_Getter_(unwrap_jso(this)));
  
  @DomName('HTMLButtonElement.value')
  @DocsEditable()
  String get value => _blink.BlinkHTMLButtonElement.instance.value_Getter_(unwrap_jso(this));
  
  @DomName('HTMLButtonElement.value')
  @DocsEditable()
  set value(String value) => _blink.BlinkHTMLButtonElement.instance.value_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLButtonElement.willValidate')
  @DocsEditable()
  bool get willValidate => _blink.BlinkHTMLButtonElement.instance.willValidate_Getter_(unwrap_jso(this));
  
  @DomName('HTMLButtonElement.checkValidity')
  @DocsEditable()
  bool checkValidity() => _blink.BlinkHTMLButtonElement.instance.checkValidity_Callback_0_(unwrap_jso(this));
  
  @DomName('HTMLButtonElement.reportValidity')
  @DocsEditable()
  @Experimental() // untriaged
  bool reportValidity() => _blink.BlinkHTMLButtonElement.instance.reportValidity_Callback_0_(unwrap_jso(this));
  
  @DomName('HTMLButtonElement.setCustomValidity')
  @DocsEditable()
  void setCustomValidity(String error) => _blink.BlinkHTMLButtonElement.instance.setCustomValidity_Callback_1_(unwrap_jso(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")
  static CDataSection internalCreateCDataSection() {
    return new CDataSection._internalWrap();
  }

  external factory CDataSection._internalWrap();

  @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")
  static CacheStorage internalCreateCacheStorage() {
    return new CacheStorage._internalWrap();
  }

  factory CacheStorage._internalWrap() {
    return new CacheStorage.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

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

  @DomName('CacheStorage.open')
  @DocsEditable()
  @Experimental() // untriaged
  Future open(String cacheName) => wrap_jso(_blink.BlinkCacheStorage.instance.open_Callback_1_(unwrap_jso(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}) {
    var e = document.createElement("canvas");
    if (width != null) e.width = width;
    if (height != null) e.height = height;
    return e;
  }


  @Deprecated("Internal Use Only")
  static CanvasElement internalCreateCanvasElement() {
    return new CanvasElement._internalWrap();
  }

  external factory CanvasElement._internalWrap();

  @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_(unwrap_jso(this));
  
  /// The height of this canvas element in CSS pixels.
  @DomName('HTMLCanvasElement.height')
  @DocsEditable()
  set height(int value) => _blink.BlinkHTMLCanvasElement.instance.height_Setter_(unwrap_jso(this), value);
  
  /// The width of this canvas element in CSS pixels.
  @DomName('HTMLCanvasElement.width')
  @DocsEditable()
  int get width => _blink.BlinkHTMLCanvasElement.instance.width_Getter_(unwrap_jso(this));
  
  /// The width of this canvas element in CSS pixels.
  @DomName('HTMLCanvasElement.width')
  @DocsEditable()
  set width(int value) => _blink.BlinkHTMLCanvasElement.instance.width_Setter_(unwrap_jso(this), value);
  
  Object getContext(String contextId, [Map attributes]) {
    if (attributes != null) {
      return wrap_jso(_blink.BlinkHTMLCanvasElement.instance.getContext_Callback_2_(unwrap_jso(this), contextId, convertDartToNative_Dictionary(attributes)));
    }
    return wrap_jso(_blink.BlinkHTMLCanvasElement.instance.getContext_Callback_1_(unwrap_jso(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_(unwrap_jso(this), type);
    }
    if (arguments_OR_quality != null && (type is String || type == null)) {
      return _blink.BlinkHTMLCanvasElement.instance.toDataURL_Callback_2_(unwrap_jso(this), type, unwrap_jso(arguments_OR_quality));
    }
    if ((type is String || type == null) && arguments_OR_quality == null) {
      return _blink.BlinkHTMLCanvasElement.instance.toDataURL_Callback_1_(unwrap_jso(this), type);
    }
    if ((arguments_OR_quality is num || arguments_OR_quality == null) && (type is String || type == null)) {
      return _blink.BlinkHTMLCanvasElement.instance.toDataURL_Callback_2_(unwrap_jso(this), type, unwrap_jso(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")
  static CanvasGradient internalCreateCanvasGradient() {
    return new CanvasGradient._internalWrap();
  }

  factory CanvasGradient._internalWrap() {
    return new CanvasGradient.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  /**
   * 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_(unwrap_jso(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")
  static CanvasPattern internalCreateCanvasPattern() {
    return new CanvasPattern._internalWrap();
  }

  factory CanvasPattern._internalWrap() {
    return new CanvasPattern.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  @DomName('CanvasPattern.setTransform')
  @DocsEditable()
  @Experimental() // untriaged
  void setTransform(Matrix transform) => _blink.BlinkCanvasPattern.instance.setTransform_Callback_1_(unwrap_jso(this), unwrap_jso(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")
  static CanvasRenderingContext2D internalCreateCanvasRenderingContext2D() {
    return new CanvasRenderingContext2D._internalWrap();
  }

  factory CanvasRenderingContext2D._internalWrap() {
    return new CanvasRenderingContext2D.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  @DomName('CanvasRenderingContext2D.canvas')
  @DocsEditable()
  @Experimental() // untriaged
  CanvasElement get canvas => wrap_jso(_blink.BlinkCanvasRenderingContext2D.instance.canvas_Getter_(unwrap_jso(this)));
  
  @DomName('CanvasRenderingContext2D.currentTransform')
  @DocsEditable()
  @Experimental() // untriaged
  Matrix get currentTransform => wrap_jso(_blink.BlinkCanvasRenderingContext2D.instance.currentTransform_Getter_(unwrap_jso(this)));
  
  @DomName('CanvasRenderingContext2D.currentTransform')
  @DocsEditable()
  @Experimental() // untriaged
  set currentTransform(Matrix value) => _blink.BlinkCanvasRenderingContext2D.instance.currentTransform_Setter_(unwrap_jso(this), unwrap_jso(value));
  
  @DomName('CanvasRenderingContext2D.direction')
  @DocsEditable()
  @Experimental() // untriaged
  String get direction => _blink.BlinkCanvasRenderingContext2D.instance.direction_Getter_(unwrap_jso(this));
  
  @DomName('CanvasRenderingContext2D.direction')
  @DocsEditable()
  @Experimental() // untriaged
  set direction(String value) => _blink.BlinkCanvasRenderingContext2D.instance.direction_Setter_(unwrap_jso(this), value);
  
  @DomName('CanvasRenderingContext2D.fillStyle')
  @DocsEditable()
  Object get fillStyle => wrap_jso(_blink.BlinkCanvasRenderingContext2D.instance.fillStyle_Getter_(unwrap_jso(this)));
  
  @DomName('CanvasRenderingContext2D.fillStyle')
  @DocsEditable()
  set fillStyle(Object value) => _blink.BlinkCanvasRenderingContext2D.instance.fillStyle_Setter_(unwrap_jso(this), unwrap_jso(value));
  
  @DomName('CanvasRenderingContext2D.filter')
  @DocsEditable()
  @Experimental() // untriaged
  String get filter => _blink.BlinkCanvasRenderingContext2D.instance.filter_Getter_(unwrap_jso(this));
  
  @DomName('CanvasRenderingContext2D.filter')
  @DocsEditable()
  @Experimental() // untriaged
  set filter(String value) => _blink.BlinkCanvasRenderingContext2D.instance.filter_Setter_(unwrap_jso(this), value);
  
  @DomName('CanvasRenderingContext2D.font')
  @DocsEditable()
  String get font => _blink.BlinkCanvasRenderingContext2D.instance.font_Getter_(unwrap_jso(this));
  
  @DomName('CanvasRenderingContext2D.font')
  @DocsEditable()
  set font(String value) => _blink.BlinkCanvasRenderingContext2D.instance.font_Setter_(unwrap_jso(this), value);
  
  @DomName('CanvasRenderingContext2D.globalAlpha')
  @DocsEditable()
  num get globalAlpha => _blink.BlinkCanvasRenderingContext2D.instance.globalAlpha_Getter_(unwrap_jso(this));
  
  @DomName('CanvasRenderingContext2D.globalAlpha')
  @DocsEditable()
  set globalAlpha(num value) => _blink.BlinkCanvasRenderingContext2D.instance.globalAlpha_Setter_(unwrap_jso(this), value);
  
  @DomName('CanvasRenderingContext2D.globalCompositeOperation')
  @DocsEditable()
  String get globalCompositeOperation => _blink.BlinkCanvasRenderingContext2D.instance.globalCompositeOperation_Getter_(unwrap_jso(this));
  
  @DomName('CanvasRenderingContext2D.globalCompositeOperation')
  @DocsEditable()
  set globalCompositeOperation(String value) => _blink.BlinkCanvasRenderingContext2D.instance.globalCompositeOperation_Setter_(unwrap_jso(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_(unwrap_jso(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_(unwrap_jso(this), value);
  
  @DomName('CanvasRenderingContext2D.lineCap')
  @DocsEditable()
  String get lineCap => _blink.BlinkCanvasRenderingContext2D.instance.lineCap_Getter_(unwrap_jso(this));
  
  @DomName('CanvasRenderingContext2D.lineCap')
  @DocsEditable()
  set lineCap(String value) => _blink.BlinkCanvasRenderingContext2D.instance.lineCap_Setter_(unwrap_jso(this), value);
  
  @DomName('CanvasRenderingContext2D.lineDashOffset')
  @DocsEditable()
  num get lineDashOffset => _blink.BlinkCanvasRenderingContext2D.instance.lineDashOffset_Getter_(unwrap_jso(this));
  
  @DomName('CanvasRenderingContext2D.lineDashOffset')
  @DocsEditable()
  set lineDashOffset(num value) => _blink.BlinkCanvasRenderingContext2D.instance.lineDashOffset_Setter_(unwrap_jso(this), value);
  
  @DomName('CanvasRenderingContext2D.lineJoin')
  @DocsEditable()
  String get lineJoin => _blink.BlinkCanvasRenderingContext2D.instance.lineJoin_Getter_(unwrap_jso(this));
  
  @DomName('CanvasRenderingContext2D.lineJoin')
  @DocsEditable()
  set lineJoin(String value) => _blink.BlinkCanvasRenderingContext2D.instance.lineJoin_Setter_(unwrap_jso(this), value);
  
  @DomName('CanvasRenderingContext2D.lineWidth')
  @DocsEditable()
  num get lineWidth => _blink.BlinkCanvasRenderingContext2D.instance.lineWidth_Getter_(unwrap_jso(this));
  
  @DomName('CanvasRenderingContext2D.lineWidth')
  @DocsEditable()
  set lineWidth(num value) => _blink.BlinkCanvasRenderingContext2D.instance.lineWidth_Setter_(unwrap_jso(this), value);
  
  @DomName('CanvasRenderingContext2D.miterLimit')
  @DocsEditable()
  num get miterLimit => _blink.BlinkCanvasRenderingContext2D.instance.miterLimit_Getter_(unwrap_jso(this));
  
  @DomName('CanvasRenderingContext2D.miterLimit')
  @DocsEditable()
  set miterLimit(num value) => _blink.BlinkCanvasRenderingContext2D.instance.miterLimit_Setter_(unwrap_jso(this), value);
  
  @DomName('CanvasRenderingContext2D.shadowBlur')
  @DocsEditable()
  num get shadowBlur => _blink.BlinkCanvasRenderingContext2D.instance.shadowBlur_Getter_(unwrap_jso(this));
  
  @DomName('CanvasRenderingContext2D.shadowBlur')
  @DocsEditable()
  set shadowBlur(num value) => _blink.BlinkCanvasRenderingContext2D.instance.shadowBlur_Setter_(unwrap_jso(this), value);
  
  @DomName('CanvasRenderingContext2D.shadowColor')
  @DocsEditable()
  String get shadowColor => _blink.BlinkCanvasRenderingContext2D.instance.shadowColor_Getter_(unwrap_jso(this));
  
  @DomName('CanvasRenderingContext2D.shadowColor')
  @DocsEditable()
  set shadowColor(String value) => _blink.BlinkCanvasRenderingContext2D.instance.shadowColor_Setter_(unwrap_jso(this), value);
  
  @DomName('CanvasRenderingContext2D.shadowOffsetX')
  @DocsEditable()
  num get shadowOffsetX => _blink.BlinkCanvasRenderingContext2D.instance.shadowOffsetX_Getter_(unwrap_jso(this));
  
  @DomName('CanvasRenderingContext2D.shadowOffsetX')
  @DocsEditable()
  set shadowOffsetX(num value) => _blink.BlinkCanvasRenderingContext2D.instance.shadowOffsetX_Setter_(unwrap_jso(this), value);
  
  @DomName('CanvasRenderingContext2D.shadowOffsetY')
  @DocsEditable()
  num get shadowOffsetY => _blink.BlinkCanvasRenderingContext2D.instance.shadowOffsetY_Getter_(unwrap_jso(this));
  
  @DomName('CanvasRenderingContext2D.shadowOffsetY')
  @DocsEditable()
  set shadowOffsetY(num value) => _blink.BlinkCanvasRenderingContext2D.instance.shadowOffsetY_Setter_(unwrap_jso(this), value);
  
  @DomName('CanvasRenderingContext2D.strokeStyle')
  @DocsEditable()
  Object get strokeStyle => wrap_jso(_blink.BlinkCanvasRenderingContext2D.instance.strokeStyle_Getter_(unwrap_jso(this)));
  
  @DomName('CanvasRenderingContext2D.strokeStyle')
  @DocsEditable()
  set strokeStyle(Object value) => _blink.BlinkCanvasRenderingContext2D.instance.strokeStyle_Setter_(unwrap_jso(this), unwrap_jso(value));
  
  @DomName('CanvasRenderingContext2D.textAlign')
  @DocsEditable()
  String get textAlign => _blink.BlinkCanvasRenderingContext2D.instance.textAlign_Getter_(unwrap_jso(this));
  
  @DomName('CanvasRenderingContext2D.textAlign')
  @DocsEditable()
  set textAlign(String value) => _blink.BlinkCanvasRenderingContext2D.instance.textAlign_Setter_(unwrap_jso(this), value);
  
  @DomName('CanvasRenderingContext2D.textBaseline')
  @DocsEditable()
  String get textBaseline => _blink.BlinkCanvasRenderingContext2D.instance.textBaseline_Getter_(unwrap_jso(this));
  
  @DomName('CanvasRenderingContext2D.textBaseline')
  @DocsEditable()
  set textBaseline(String value) => _blink.BlinkCanvasRenderingContext2D.instance.textBaseline_Setter_(unwrap_jso(this), value);
  
  void addHitRegion([Map options]) {
    if (options != null) {
      _blink.BlinkCanvasRenderingContext2D.instance.addHitRegion_Callback_1_(unwrap_jso(this), convertDartToNative_Dictionary(options));
      return;
    }
    _blink.BlinkCanvasRenderingContext2D.instance.addHitRegion_Callback_0_(unwrap_jso(this));
    return;
  }

  @DomName('CanvasRenderingContext2D.beginPath')
  @DocsEditable()
  void beginPath() => _blink.BlinkCanvasRenderingContext2D.instance.beginPath_Callback_0_(unwrap_jso(this));
  
  @DomName('CanvasRenderingContext2D.clearHitRegions')
  @DocsEditable()
  @Experimental() // untriaged
  void clearHitRegions() => _blink.BlinkCanvasRenderingContext2D.instance.clearHitRegions_Callback_0_(unwrap_jso(this));
  
  @DomName('CanvasRenderingContext2D.clearRect')
  @DocsEditable()
  void clearRect(num x, num y, num width, num height) => _blink.BlinkCanvasRenderingContext2D.instance.clearRect_Callback_4_(unwrap_jso(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_(unwrap_jso(this));
      return;
    }
    if ((path_OR_winding is String) && winding == null) {
      _blink.BlinkCanvasRenderingContext2D.instance.clip_Callback_1_(unwrap_jso(this), unwrap_jso(path_OR_winding));
      return;
    }
    if ((path_OR_winding is Path2D) && winding == null) {
      _blink.BlinkCanvasRenderingContext2D.instance.clip_Callback_1_(unwrap_jso(this), unwrap_jso(path_OR_winding));
      return;
    }
    if ((winding is String) && (path_OR_winding is Path2D)) {
      _blink.BlinkCanvasRenderingContext2D.instance.clip_Callback_2_(unwrap_jso(this), unwrap_jso(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 wrap_jso(_blink.BlinkCanvasRenderingContext2D.instance.createImageData_Callback_1_(unwrap_jso(this), unwrap_jso(imagedata_OR_sw)));
    }
    if ((sh is num) && (imagedata_OR_sw is num)) {
      return wrap_jso(_blink.BlinkCanvasRenderingContext2D.instance.createImageData_Callback_2_(unwrap_jso(this), unwrap_jso(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) => wrap_jso(_blink.BlinkCanvasRenderingContext2D.instance.createLinearGradient_Callback_4_(unwrap_jso(this), x0, y0, x1, y1));
  
  @DomName('CanvasRenderingContext2D.createPattern')
  @DocsEditable()
  CanvasPattern createPattern(Object image, String repetitionType) => wrap_jso(_blink.BlinkCanvasRenderingContext2D.instance.createPattern_Callback_2_(unwrap_jso(this), image, repetitionType));
  
  @DomName('CanvasRenderingContext2D.createRadialGradient')
  @DocsEditable()
  CanvasGradient createRadialGradient(num x0, num y0, num r0, num x1, num y1, num r1) => wrap_jso(_blink.BlinkCanvasRenderingContext2D.instance.createRadialGradient_Callback_6_(unwrap_jso(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_(unwrap_jso(this), unwrap_jso(element_OR_path));
      return;
    }
    if ((element is Element) && (element_OR_path is Path2D)) {
      _blink.BlinkCanvasRenderingContext2D.instance.drawFocusIfNeeded_Callback_2_(unwrap_jso(this), unwrap_jso(element_OR_path), unwrap_jso(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_(unwrap_jso(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_(unwrap_jso(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_(unwrap_jso(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_(unwrap_jso(this));
      return;
    }
    if ((path_OR_winding is String) && winding == null) {
      _blink.BlinkCanvasRenderingContext2D.instance.fill_Callback_1_(unwrap_jso(this), unwrap_jso(path_OR_winding));
      return;
    }
    if ((path_OR_winding is Path2D) && winding == null) {
      _blink.BlinkCanvasRenderingContext2D.instance.fill_Callback_1_(unwrap_jso(this), unwrap_jso(path_OR_winding));
      return;
    }
    if ((winding is String) && (path_OR_winding is Path2D)) {
      _blink.BlinkCanvasRenderingContext2D.instance.fill_Callback_2_(unwrap_jso(this), unwrap_jso(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_(unwrap_jso(this), x, y, width, height);
  
  void fillText(String text, num x, num y, [num maxWidth]) {
    if (maxWidth != null) {
      _blink.BlinkCanvasRenderingContext2D.instance.fillText_Callback_4_(unwrap_jso(this), text, x, y, maxWidth);
      return;
    }
    _blink.BlinkCanvasRenderingContext2D.instance.fillText_Callback_3_(unwrap_jso(this), text, x, y);
    return;
  }

  @DomName('CanvasRenderingContext2D.getContextAttributes')
  @DocsEditable()
  // http://wiki.whatwg.org/wiki/CanvasOpaque#Suggested_IDL
  @Experimental()
   getContextAttributes() => convertNativeDictionaryToDartDictionary(wrap_jso(_blink.BlinkCanvasRenderingContext2D.instance.getContextAttributes_Callback_0_(unwrap_jso(this))));
  
  @DomName('CanvasRenderingContext2D.getImageData')
  @DocsEditable()
  ImageData getImageData(num sx, num sy, num sw, num sh) => wrap_jso(_blink.BlinkCanvasRenderingContext2D.instance.getImageData_Callback_4_(unwrap_jso(this), sx, sy, sw, sh));
  
  @DomName('CanvasRenderingContext2D.getLineDash')
  @DocsEditable()
  List<num> _getLineDash() => _blink.BlinkCanvasRenderingContext2D.instance.getLineDash_Callback_0_(unwrap_jso(this));
  
  @DomName('CanvasRenderingContext2D.isContextLost')
  @DocsEditable()
  @Experimental() // untriaged
  bool isContextLost() => _blink.BlinkCanvasRenderingContext2D.instance.isContextLost_Callback_0_(unwrap_jso(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_(unwrap_jso(this), unwrap_jso(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_(unwrap_jso(this), unwrap_jso(path_OR_x), x_OR_y, unwrap_jso(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_(unwrap_jso(this), unwrap_jso(path_OR_x), x_OR_y, unwrap_jso(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_(unwrap_jso(this), unwrap_jso(path_OR_x), x_OR_y, unwrap_jso(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_(unwrap_jso(this), unwrap_jso(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_(unwrap_jso(this), unwrap_jso(path_OR_x), x_OR_y, y);
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }

  @DomName('CanvasRenderingContext2D.measureText')
  @DocsEditable()
  TextMetrics measureText(String text) => wrap_jso(_blink.BlinkCanvasRenderingContext2D.instance.measureText_Callback_1_(unwrap_jso(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_(unwrap_jso(this), unwrap_jso(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_(unwrap_jso(this), unwrap_jso(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_(unwrap_jso(this), id);
  
  @DomName('CanvasRenderingContext2D.resetTransform')
  @DocsEditable()
  @Experimental() // untriaged
  void resetTransform() => _blink.BlinkCanvasRenderingContext2D.instance.resetTransform_Callback_0_(unwrap_jso(this));
  
  @DomName('CanvasRenderingContext2D.restore')
  @DocsEditable()
  void restore() => _blink.BlinkCanvasRenderingContext2D.instance.restore_Callback_0_(unwrap_jso(this));
  
  @DomName('CanvasRenderingContext2D.rotate')
  @DocsEditable()
  void rotate(num angle) => _blink.BlinkCanvasRenderingContext2D.instance.rotate_Callback_1_(unwrap_jso(this), angle);
  
  @DomName('CanvasRenderingContext2D.save')
  @DocsEditable()
  void save() => _blink.BlinkCanvasRenderingContext2D.instance.save_Callback_0_(unwrap_jso(this));
  
  @DomName('CanvasRenderingContext2D.scale')
  @DocsEditable()
  void scale(num x, num y) => _blink.BlinkCanvasRenderingContext2D.instance.scale_Callback_2_(unwrap_jso(this), x, y);
  
  void scrollPathIntoView([Path2D path]) {
    if (path != null) {
      _blink.BlinkCanvasRenderingContext2D.instance.scrollPathIntoView_Callback_1_(unwrap_jso(this), unwrap_jso(path));
      return;
    }
    _blink.BlinkCanvasRenderingContext2D.instance.scrollPathIntoView_Callback_0_(unwrap_jso(this));
    return;
  }

  @DomName('CanvasRenderingContext2D.setLineDash')
  @DocsEditable()
  void setLineDash(List<num> dash) => _blink.BlinkCanvasRenderingContext2D.instance.setLineDash_Callback_1_(unwrap_jso(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_(unwrap_jso(this), a, b, c, d, e, f);
  
  void stroke([Path2D path]) {
    if (path == null) {
      _blink.BlinkCanvasRenderingContext2D.instance.stroke_Callback_0_(unwrap_jso(this));
      return;
    }
    if ((path is Path2D)) {
      _blink.BlinkCanvasRenderingContext2D.instance.stroke_Callback_1_(unwrap_jso(this), unwrap_jso(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_(unwrap_jso(this), x, y, width, height);
  
  void strokeText(String text, num x, num y, [num maxWidth]) {
    if (maxWidth != null) {
      _blink.BlinkCanvasRenderingContext2D.instance.strokeText_Callback_4_(unwrap_jso(this), text, x, y, maxWidth);
      return;
    }
    _blink.BlinkCanvasRenderingContext2D.instance.strokeText_Callback_3_(unwrap_jso(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_(unwrap_jso(this), a, b, c, d, e, f);
  
  @DomName('CanvasRenderingContext2D.translate')
  @DocsEditable()
  void translate(num x, num y) => _blink.BlinkCanvasRenderingContext2D.instance.translate_Callback_2_(unwrap_jso(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_(unwrap_jso(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_(unwrap_jso(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_(unwrap_jso(this), cp1x, cp1y, cp2x, cp2y, x, y);
  
  @DomName('CanvasRenderingContext2D.closePath')
  @DocsEditable()
  void closePath() => _blink.BlinkCanvasRenderingContext2D.instance.closePath_Callback_0_(unwrap_jso(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_(unwrap_jso(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_(unwrap_jso(this), x, y);
  
  @DomName('CanvasRenderingContext2D.moveTo')
  @DocsEditable()
  void moveTo(num x, num y) => _blink.BlinkCanvasRenderingContext2D.instance.moveTo_Callback_2_(unwrap_jso(this), x, y);
  
  @DomName('CanvasRenderingContext2D.quadraticCurveTo')
  @DocsEditable()
  void quadraticCurveTo(num cpx, num cpy, num x, num y) => _blink.BlinkCanvasRenderingContext2D.instance.quadraticCurveTo_Callback_4_(unwrap_jso(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_(unwrap_jso(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")
  static CharacterData internalCreateCharacterData() {
    return new CharacterData._internalWrap();
  }

  external factory CharacterData._internalWrap();

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


  @DomName('CharacterData.data')
  @DocsEditable()
  String get data => _blink.BlinkCharacterData.instance.data_Getter_(unwrap_jso(this));
  
  @DomName('CharacterData.data')
  @DocsEditable()
  set data(String value) => _blink.BlinkCharacterData.instance.data_Setter_(unwrap_jso(this), value);
  
  @DomName('CharacterData.length')
  @DocsEditable()
  int get length => _blink.BlinkCharacterData.instance.length_Getter_(unwrap_jso(this));
  
  @DomName('CharacterData.appendData')
  @DocsEditable()
  void appendData(String data) => _blink.BlinkCharacterData.instance.appendData_Callback_1_(unwrap_jso(this), data);
  
  @DomName('CharacterData.deleteData')
  @DocsEditable()
  void deleteData(int offset, int count) => _blink.BlinkCharacterData.instance.deleteData_Callback_2_(unwrap_jso(this), offset, count);
  
  @DomName('CharacterData.insertData')
  @DocsEditable()
  void insertData(int offset, String data) => _blink.BlinkCharacterData.instance.insertData_Callback_2_(unwrap_jso(this), offset, data);
  
  @DomName('CharacterData.replaceData')
  @DocsEditable()
  void replaceData(int offset, int count, String data) => _blink.BlinkCharacterData.instance.replaceData_Callback_3_(unwrap_jso(this), offset, count, data);
  
  @DomName('CharacterData.substringData')
  @DocsEditable()
  String substringData(int offset, int count) => _blink.BlinkCharacterData.instance.substringData_Callback_2_(unwrap_jso(this), offset, count);
  
  @DomName('CharacterData.after')
  @DocsEditable()
  @Experimental() // untriaged
  void after(Object nodes) => _blink.BlinkCharacterData.instance.after_Callback_1_(unwrap_jso(this), nodes);
  
  @DomName('CharacterData.before')
  @DocsEditable()
  @Experimental() // untriaged
  void before(Object nodes) => _blink.BlinkCharacterData.instance.before_Callback_1_(unwrap_jso(this), nodes);
  
  @DomName('CharacterData.nextElementSibling')
  @DocsEditable()
  Element get nextElementSibling => wrap_jso(_blink.BlinkCharacterData.instance.nextElementSibling_Getter_(unwrap_jso(this)));
  
  @DomName('CharacterData.previousElementSibling')
  @DocsEditable()
  Element get previousElementSibling => wrap_jso(_blink.BlinkCharacterData.instance.previousElementSibling_Getter_(unwrap_jso(this)));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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")
  static ChromiumValuebuffer internalCreateChromiumValuebuffer() {
    return new ChromiumValuebuffer._internalWrap();
  }

  factory ChromiumValuebuffer._internalWrap() {
    return new ChromiumValuebuffer.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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 wrap_jso(_blink.BlinkCircularGeofencingRegion.instance.constructorCallback_1_(init_1));
  }


  @Deprecated("Internal Use Only")
  static CircularGeofencingRegion internalCreateCircularGeofencingRegion() {
    return new CircularGeofencingRegion._internalWrap();
  }

  external factory CircularGeofencingRegion._internalWrap();

  @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_(unwrap_jso(this));
  
  @DomName('CircularGeofencingRegion.longitude')
  @DocsEditable()
  @Experimental() // untriaged
  num get longitude => _blink.BlinkCircularGeofencingRegion.instance.longitude_Getter_(unwrap_jso(this));
  
  @DomName('CircularGeofencingRegion.radius')
  @DocsEditable()
  @Experimental() // untriaged
  num get radius => _blink.BlinkCircularGeofencingRegion.instance.radius_Getter_(unwrap_jso(this));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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")
  static Client internalCreateClient() {
    return new Client._internalWrap();
  }

  factory Client._internalWrap() {
    return new Client.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  @DomName('Client.frameType')
  @DocsEditable()
  @Experimental() // untriaged
  String get frameType => _blink.BlinkClient.instance.frameType_Getter_(unwrap_jso(this));
  
  @DomName('Client.id')
  @DocsEditable()
  @Experimental() // untriaged
  String get id => _blink.BlinkClient.instance.id_Getter_(unwrap_jso(this));
  
  @DomName('Client.url')
  @DocsEditable()
  @Experimental() // untriaged
  String get url => _blink.BlinkClient.instance.url_Getter_(unwrap_jso(this));
  
  void postMessage(/*SerializedScriptValue*/ message, [List<MessagePort> transfer]) {
    if (transfer != null) {
      _blink.BlinkClient.instance.postMessage_Callback_2_(unwrap_jso(this), convertDartToNative_SerializedScriptValue(message), transfer);
      return;
    }
    _blink.BlinkClient.instance.postMessage_Callback_1_(unwrap_jso(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")
  static Clients internalCreateClients() {
    return new Clients._internalWrap();
  }

  factory Clients._internalWrap() {
    return new Clients.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

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

  @DomName('Clients.openWindow')
  @DocsEditable()
  @Experimental() // untriaged
  Future openWindow(String url) => wrap_jso(_blink.BlinkClients.instance.openWindow_Callback_1_(unwrap_jso(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")
  static ClipboardEvent internalCreateClipboardEvent() {
    return new ClipboardEvent._internalWrap();
  }

  external factory ClipboardEvent._internalWrap();

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


  @DomName('ClipboardEvent.clipboardData')
  @DocsEditable()
  @Experimental() // untriaged
  DataTransfer get clipboardData => wrap_jso(_blink.BlinkClipboardEvent.instance.clipboardData_Getter_(unwrap_jso(this)));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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 wrap_jso(_blink.BlinkCloseEvent.instance.constructorCallback_2_(type, eventInitDict_1));
    }
    return wrap_jso(_blink.BlinkCloseEvent.instance.constructorCallback_1_(type));
  }


  @Deprecated("Internal Use Only")
  static CloseEvent internalCreateCloseEvent() {
    return new CloseEvent._internalWrap();
  }

  external factory CloseEvent._internalWrap();

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


  @DomName('CloseEvent.code')
  @DocsEditable()
  int get code => _blink.BlinkCloseEvent.instance.code_Getter_(unwrap_jso(this));
  
  @DomName('CloseEvent.reason')
  @DocsEditable()
  String get reason => _blink.BlinkCloseEvent.instance.reason_Getter_(unwrap_jso(this));
  
  @DomName('CloseEvent.wasClean')
  @DocsEditable()
  bool get wasClean => _blink.BlinkCloseEvent.instance.wasClean_Getter_(unwrap_jso(this));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All 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 wrap_jso(_blink.BlinkComment.instance.constructorCallback_1_(data));
    }
    return wrap_jso(_blink.BlinkComment.instance.constructorCallback_0_());
  }


  @Deprecated("Internal Use Only")
  static Comment internalCreateComment() {
    return new Comment._internalWrap();
  }

  external factory Comment._internalWrap();

  @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;
    }
    var 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 wrap_jso(_blink.BlinkCompositionEvent.instance.constructorCallback_2_(type, eventInitDict_1));
    }
    return wrap_jso(_blink.BlinkCompositionEvent.instance.constructorCallback_1_(type));
  }


  @Deprecated("Internal Use Only")
  static CompositionEvent internalCreateCompositionEvent() {
    return new CompositionEvent._internalWrap();
  }

  external factory CompositionEvent._internalWrap();

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


  @DomName('CompositionEvent.data')
  @DocsEditable()
  String get data => _blink.BlinkCompositionEvent.instance.data_Getter_(unwrap_jso(this));
  
  @DomName('CompositionEvent.initCompositionEvent')
  @DocsEditable()
  void _initCompositionEvent(String type, bool bubbles, bool cancelable, Window view, String data) => _blink.BlinkCompositionEvent.instance.initCompositionEvent_Callback_5_(unwrap_jso(this), type, bubbles, cancelable, unwrap_jso(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 wrap_jso(_blink.BlinkCompositorProxy.instance.constructorCallback_2_(element, attributeArray));
  }

  @Deprecated("Internal Use Only")
  static CompositorProxy internalCreateCompositorProxy() {
    return new CompositorProxy._internalWrap();
  }

  factory CompositorProxy._internalWrap() {
    return new CompositorProxy.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  @DomName('CompositorProxy.opacity')
  @DocsEditable()
  @Experimental() // untriaged
  num get opacity => _blink.BlinkCompositorProxy.instance.opacity_Getter_(unwrap_jso(this));
  
  @DomName('CompositorProxy.opacity')
  @DocsEditable()
  @Experimental() // untriaged
  set opacity(num value) => _blink.BlinkCompositorProxy.instance.opacity_Setter_(unwrap_jso(this), value);
  
  @DomName('CompositorProxy.scrollLeft')
  @DocsEditable()
  @Experimental() // untriaged
  num get scrollLeft => _blink.BlinkCompositorProxy.instance.scrollLeft_Getter_(unwrap_jso(this));
  
  @DomName('CompositorProxy.scrollLeft')
  @DocsEditable()
  @Experimental() // untriaged
  set scrollLeft(num value) => _blink.BlinkCompositorProxy.instance.scrollLeft_Setter_(unwrap_jso(this), value);
  
  @DomName('CompositorProxy.scrollTop')
  @DocsEditable()
  @Experimental() // untriaged
  num get scrollTop => _blink.BlinkCompositorProxy.instance.scrollTop_Getter_(unwrap_jso(this));
  
  @DomName('CompositorProxy.scrollTop')
  @DocsEditable()
  @Experimental() // untriaged
  set scrollTop(num value) => _blink.BlinkCompositorProxy.instance.scrollTop_Setter_(unwrap_jso(this), value);
  
  @DomName('CompositorProxy.transform')
  @DocsEditable()
  @Experimental() // untriaged
  DomMatrix get transform => wrap_jso(_blink.BlinkCompositorProxy.instance.transform_Getter_(unwrap_jso(this)));
  
  @DomName('CompositorProxy.transform')
  @DocsEditable()
  @Experimental() // untriaged
  set transform(DomMatrix value) => _blink.BlinkCompositorProxy.instance.transform_Setter_(unwrap_jso(this), unwrap_jso(value));
  
  @DomName('CompositorProxy.disconnect')
  @DocsEditable()
  @Experimental() // untriaged
  void disconnect() => _blink.BlinkCompositorProxy.instance.disconnect_Callback_0_(unwrap_jso(this));
  
  @DomName('CompositorProxy.supports')
  @DocsEditable()
  @Experimental() // untriaged
  bool supports(String attribute) => _blink.BlinkCompositorProxy.instance.supports_Callback_1_(unwrap_jso(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 wrap_jso(_blink.BlinkCompositorWorker.instance.constructorCallback_1_(scriptUrl));
  }


  @Deprecated("Internal Use Only")
  static CompositorWorker internalCreateCompositorWorker() {
    return new CompositorWorker._internalWrap();
  }

  external factory CompositorWorker._internalWrap();

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


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

  @DomName('CompositorWorker.terminate')
  @DocsEditable()
  @Experimental() // untriaged
  void terminate() => _blink.BlinkCompositorWorker.instance.terminate_Callback_0_(unwrap_jso(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")
  static CompositorWorkerGlobalScope internalCreateCompositorWorkerGlobalScope() {
    return new CompositorWorkerGlobalScope._internalWrap();
  }

  external factory CompositorWorkerGlobalScope._internalWrap();

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


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

  @DomName('CompositorWorkerGlobalScope.requestAnimationFrame')
  @DocsEditable()
  @Experimental() // untriaged
  int requestAnimationFrame(FrameRequestCallback callback) => _blink.BlinkCompositorWorkerGlobalScope.instance.requestAnimationFrame_Callback_1_(unwrap_jso(this), unwrap_jso((highResTime) => callback(highResTime)));
  
  @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")
  static Console internalCreateConsole() {
    return new Console._internalWrap();
  }

  external factory Console._internalWrap();

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


  @DomName('Console.memory')
  @DocsEditable()
  @Experimental()
  MemoryInfo get memory => wrap_jso(_blink.BlinkConsole.instance.memory_Getter_(unwrap_jso(this)));
  
  @DomName('Console.memory')
  @DocsEditable()
  @Experimental()
  set memory(MemoryInfo value) => _blink.BlinkConsole.instance.memory_Setter_(unwrap_jso(this), unwrap_jso(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")
  static ConsoleBase internalCreateConsoleBase() {
    return new ConsoleBase._internalWrap();
  }

  factory ConsoleBase._internalWrap() {
    return new ConsoleBase.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  @DomName('ConsoleBase.assert')
  @DocsEditable()
  @Experimental() // untriaged
  void assertCondition(bool condition, Object arg) => _blink.BlinkConsoleBase.instance.assert_Callback_2_(unwrap_jso(this), condition, arg);
  
  @DomName('ConsoleBase.clear')
  @DocsEditable()
  @Experimental() // untriaged
  void clear(Object arg) => _blink.BlinkConsoleBase.instance.clear_Callback_1_(unwrap_jso(this), arg);
  
  @DomName('ConsoleBase.count')
  @DocsEditable()
  @Experimental() // untriaged
  void count(Object arg) => _blink.BlinkConsoleBase.instance.count_Callback_1_(unwrap_jso(this), arg);
  
  @DomName('ConsoleBase.debug')
  @DocsEditable()
  @Experimental() // untriaged
  void debug(Object arg) => _blink.BlinkConsoleBase.instance.debug_Callback_1_(unwrap_jso(this), arg);
  
  @DomName('ConsoleBase.dir')
  @DocsEditable()
  @Experimental() // untriaged
  void dir(Object arg) => _blink.BlinkConsoleBase.instance.dir_Callback_1_(unwrap_jso(this), arg);
  
  @DomName('ConsoleBase.dirxml')
  @DocsEditable()
  @Experimental() // untriaged
  void dirxml(Object arg) => _blink.BlinkConsoleBase.instance.dirxml_Callback_1_(unwrap_jso(this), arg);
  
  @DomName('ConsoleBase.error')
  @DocsEditable()
  @Experimental() // untriaged
  void error(Object arg) => _blink.BlinkConsoleBase.instance.error_Callback_1_(unwrap_jso(this), arg);
  
  @DomName('ConsoleBase.group')
  @DocsEditable()
  @Experimental() // untriaged
  void group(Object arg) => _blink.BlinkConsoleBase.instance.group_Callback_1_(unwrap_jso(this), arg);
  
  @DomName('ConsoleBase.groupCollapsed')
  @DocsEditable()
  @Experimental() // untriaged
  void groupCollapsed(Object arg) => _blink.BlinkConsoleBase.instance.groupCollapsed_Callback_1_(unwrap_jso(this), arg);
  
  @DomName('ConsoleBase.groupEnd')
  @DocsEditable()
  @Experimental() // untriaged
  void groupEnd() => _blink.BlinkConsoleBase.instance.groupEnd_Callback_0_(unwrap_jso(this));
  
  @DomName('ConsoleBase.info')
  @DocsEditable()
  @Experimental() // untriaged
  void info(Object arg) => _blink.BlinkConsoleBase.instance.info_Callback_1_(unwrap_jso(this), arg);
  
  @DomName('ConsoleBase.log')
  @DocsEditable()
  @Experimental() // untriaged
  void log(Object arg) => _blink.BlinkConsoleBase.instance.log_Callback_1_(unwrap_jso(this), arg);
  
  @DomName('ConsoleBase.markTimeline')
  @DocsEditable()
  @Experimental() // untriaged
  void markTimeline(String title) => _blink.BlinkConsoleBase.instance.markTimeline_Callback_1_(unwrap_jso(this), title);
  
  @DomName('ConsoleBase.profile')
  @DocsEditable()
  @Experimental() // untriaged
  void profile(String title) => _blink.BlinkConsoleBase.instance.profile_Callback_1_(unwrap_jso(this), title);
  
  @DomName('ConsoleBase.profileEnd')
  @DocsEditable()
  @Experimental() // untriaged
  void profileEnd(String title) => _blink.BlinkConsoleBase.instance.profileEnd_Callback_1_(unwrap_jso(this), title);
  
  @DomName('ConsoleBase.table')
  @DocsEditable()
  @Experimental() // untriaged
  void table(Object arg) => _blink.BlinkConsoleBase.instance.table_Callback_1_(unwrap_jso(this), arg);
  
  @DomName('ConsoleBase.time')
  @DocsEditable()
  @Experimental() // untriaged
  void time(String title) => _blink.BlinkConsoleBase.instance.time_Callback_1_(unwrap_jso(this), title);
  
  @DomName('ConsoleBase.timeEnd')
  @DocsEditable()
  @Experimental() // untriaged
  void timeEnd(String title) => _blink.BlinkConsoleBase.instance.timeEnd_Callback_1_(unwrap_jso(this), title);
  
  @DomName('ConsoleBase.timeStamp')
  @DocsEditable()
  @Experimental() // untriaged
  void timeStamp(String title) => _blink.BlinkConsoleBase.instance.timeStamp_Callback_1_(unwrap_jso(this), title);
  
  @DomName('ConsoleBase.timeline')
  @DocsEditable()
  @Experimental() // untriaged
  void timeline(String title) => _blink.BlinkConsoleBase.instance.timeline_Callback_1_(unwrap_jso(this), title);
  
  @DomName('ConsoleBase.timelineEnd')
  @DocsEditable()
  @Experimental() // untriaged
  void timelineEnd(String title) => _blink.BlinkConsoleBase.instance.timelineEnd_Callback_1_(unwrap_jso(this), title);
  
  @DomName('ConsoleBase.trace')
  @DocsEditable()
  @Experimental() // untriaged
  void trace(Object arg) => _blink.BlinkConsoleBase.instance.trace_Callback_1_(unwrap_jso(this), arg);
  
  @DomName('ConsoleBase.warn')
  @DocsEditable()
  @Experimental() // untriaged
  void warn(Object arg) => _blink.BlinkConsoleBase.instance.warn_Callback_1_(unwrap_jso(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")
  static ContentElement internalCreateContentElement() {
    return new ContentElement._internalWrap();
  }

  external factory ContentElement._internalWrap();

  @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_(unwrap_jso(this));
  
  @DomName('HTMLContentElement.select')
  @DocsEditable()
  set select(String value) => _blink.BlinkHTMLContentElement.instance.select_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLContentElement.getDistributedNodes')
  @DocsEditable()
  List<Node> getDistributedNodes() => wrap_jso(_blink.BlinkHTMLContentElement.instance.getDistributedNodes_Callback_0_(unwrap_jso(this)));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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")
  static Coordinates internalCreateCoordinates() {
    return new Coordinates._internalWrap();
  }

  factory Coordinates._internalWrap() {
    return new Coordinates.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  @DomName('Coordinates.accuracy')
  @DocsEditable()
  num get accuracy => _blink.BlinkCoordinates.instance.accuracy_Getter_(unwrap_jso(this));
  
  @DomName('Coordinates.altitude')
  @DocsEditable()
  num get altitude => _blink.BlinkCoordinates.instance.altitude_Getter_(unwrap_jso(this));
  
  @DomName('Coordinates.altitudeAccuracy')
  @DocsEditable()
  num get altitudeAccuracy => _blink.BlinkCoordinates.instance.altitudeAccuracy_Getter_(unwrap_jso(this));
  
  @DomName('Coordinates.heading')
  @DocsEditable()
  num get heading => _blink.BlinkCoordinates.instance.heading_Getter_(unwrap_jso(this));
  
  @DomName('Coordinates.latitude')
  @DocsEditable()
  num get latitude => _blink.BlinkCoordinates.instance.latitude_Getter_(unwrap_jso(this));
  
  @DomName('Coordinates.longitude')
  @DocsEditable()
  num get longitude => _blink.BlinkCoordinates.instance.longitude_Getter_(unwrap_jso(this));
  
  @DomName('Coordinates.speed')
  @DocsEditable()
  num get speed => _blink.BlinkCoordinates.instance.speed_Getter_(unwrap_jso(this));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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")
  static Credential internalCreateCredential() {
    return new Credential._internalWrap();
  }

  factory Credential._internalWrap() {
    return new Credential.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  @DomName('Credential.iconURL')
  @DocsEditable()
  @Experimental() // untriaged
  String get iconUrl => _blink.BlinkCredential.instance.iconURL_Getter_(unwrap_jso(this));
  
  @DomName('Credential.id')
  @DocsEditable()
  @Experimental() // untriaged
  String get id => _blink.BlinkCredential.instance.id_Getter_(unwrap_jso(this));
  
  @DomName('Credential.name')
  @DocsEditable()
  @Experimental() // untriaged
  String get name => _blink.BlinkCredential.instance.name_Getter_(unwrap_jso(this));
  
  @DomName('Credential.type')
  @DocsEditable()
  @Experimental() // untriaged
  String get type => _blink.BlinkCredential.instance.type_Getter_(unwrap_jso(this));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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")
  static CredentialsContainer internalCreateCredentialsContainer() {
    return new CredentialsContainer._internalWrap();
  }

  factory CredentialsContainer._internalWrap() {
    return new CredentialsContainer.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

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

  @DomName('CredentialsContainer.requireUserMediation')
  @DocsEditable()
  @Experimental() // untriaged
  Future requireUserMediation() => wrap_jso(_blink.BlinkCredentialsContainer.instance.requireUserMediation_Callback_0_(unwrap_jso(this)));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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")
  static CrossOriginConnectEvent internalCreateCrossOriginConnectEvent() {
    return new CrossOriginConnectEvent._internalWrap();
  }

  external factory CrossOriginConnectEvent._internalWrap();

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


  @DomName('CrossOriginConnectEvent.client')
  @DocsEditable()
  @Experimental() // untriaged
  CrossOriginServiceWorkerClient get client => wrap_jso(_blink.BlinkCrossOriginConnectEvent.instance.client_Getter_(unwrap_jso(this)));
  
  @DomName('CrossOriginConnectEvent.acceptConnection')
  @DocsEditable()
  @Experimental() // untriaged
  void acceptConnection(Future shouldAccept) => _blink.BlinkCrossOriginConnectEvent.instance.acceptConnection_Callback_1_(unwrap_jso(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")
  static CrossOriginServiceWorkerClient internalCreateCrossOriginServiceWorkerClient() {
    return new CrossOriginServiceWorkerClient._internalWrap();
  }

  external factory CrossOriginServiceWorkerClient._internalWrap();

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


  @DomName('CrossOriginServiceWorkerClient.origin')
  @DocsEditable()
  @Experimental() // untriaged
  String get origin => _blink.BlinkCrossOriginServiceWorkerClient.instance.origin_Getter_(unwrap_jso(this));
  
  @DomName('CrossOriginServiceWorkerClient.targetUrl')
  @DocsEditable()
  @Experimental() // untriaged
  String get targetUrl => _blink.BlinkCrossOriginServiceWorkerClient.instance.targetUrl_Getter_(unwrap_jso(this));
  
  void postMessage(/*SerializedScriptValue*/ message, [List<MessagePort> transfer]) {
    if (transfer != null) {
      _blink.BlinkCrossOriginServiceWorkerClient.instance.postMessage_Callback_2_(unwrap_jso(this), convertDartToNative_SerializedScriptValue(message), transfer);
      return;
    }
    _blink.BlinkCrossOriginServiceWorkerClient.instance.postMessage_Callback_1_(unwrap_jso(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")
  static Crypto internalCreateCrypto() {
    return new Crypto._internalWrap();
  }

  factory Crypto._internalWrap() {
    return new Crypto.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

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

  @DomName('Crypto.subtle')
  @DocsEditable()
  @Experimental() // untriaged
  _SubtleCrypto get subtle => wrap_jso(_blink.BlinkCrypto.instance.subtle_Getter_(unwrap_jso(this)));
  
  @DomName('Crypto.getRandomValues')
  @DocsEditable()
  TypedData _getRandomValues(TypedData array) => wrap_jso(_blink.BlinkCrypto.instance.getRandomValues_Callback_1_(unwrap_jso(this), unwrap_jso(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")
  static CryptoKey internalCreateCryptoKey() {
    return new CryptoKey._internalWrap();
  }

  factory CryptoKey._internalWrap() {
    return new CryptoKey.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  @DomName('CryptoKey.algorithm')
  @DocsEditable()
  @Experimental() // untriaged
  Object get algorithm => wrap_jso(_blink.BlinkCryptoKey.instance.algorithm_Getter_(unwrap_jso(this)));
  
  @DomName('CryptoKey.extractable')
  @DocsEditable()
  @Experimental() // untriaged
  bool get extractable => _blink.BlinkCryptoKey.instance.extractable_Getter_(unwrap_jso(this));
  
  @DomName('CryptoKey.type')
  @DocsEditable()
  @Experimental() // untriaged
  String get type => _blink.BlinkCryptoKey.instance.type_Getter_(unwrap_jso(this));
  
  @DomName('CryptoKey.usages')
  @DocsEditable()
  @Experimental() // untriaged
  List<String> get usages => _blink.BlinkCryptoKey.instance.usages_Getter_(unwrap_jso(this));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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")
  static Css internalCreateCss() {
    return new Css._internalWrap();
  }

  factory Css._internalWrap() {
    return new Css.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  @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")
  static CssCharsetRule internalCreateCssCharsetRule() {
    return new CssCharsetRule._internalWrap();
  }

  external factory CssCharsetRule._internalWrap();

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


  @DomName('CSSCharsetRule.encoding')
  @DocsEditable()
  String get encoding => _blink.BlinkCSSCharsetRule.instance.encoding_Getter_(unwrap_jso(this));
  
  @DomName('CSSCharsetRule.encoding')
  @DocsEditable()
  set encoding(String value) => _blink.BlinkCSSCharsetRule.instance.encoding_Setter_(unwrap_jso(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")
  static CssFontFaceRule internalCreateCssFontFaceRule() {
    return new CssFontFaceRule._internalWrap();
  }

  external factory CssFontFaceRule._internalWrap();

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


  @DomName('CSSFontFaceRule.style')
  @DocsEditable()
  CssStyleDeclaration get style => wrap_jso(_blink.BlinkCSSFontFaceRule.instance.style_Getter_(unwrap_jso(this)));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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")
  static CssGroupingRule internalCreateCssGroupingRule() {
    return new CssGroupingRule._internalWrap();
  }

  external factory CssGroupingRule._internalWrap();

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


  @DomName('CSSGroupingRule.cssRules')
  @DocsEditable()
  @Experimental() // untriaged
  List<CssRule> get cssRules => wrap_jso(_blink.BlinkCSSGroupingRule.instance.cssRules_Getter_(unwrap_jso(this)));
  
  @DomName('CSSGroupingRule.deleteRule')
  @DocsEditable()
  @Experimental() // untriaged
  void deleteRule(int index) => _blink.BlinkCSSGroupingRule.instance.deleteRule_Callback_1_(unwrap_jso(this), index);
  
  @DomName('CSSGroupingRule.insertRule')
  @DocsEditable()
  @Experimental() // untriaged
  int insertRule(String rule, int index) => _blink.BlinkCSSGroupingRule.instance.insertRule_Callback_2_(unwrap_jso(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")
  static CssImportRule internalCreateCssImportRule() {
    return new CssImportRule._internalWrap();
  }

  external factory CssImportRule._internalWrap();

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


  @DomName('CSSImportRule.href')
  @DocsEditable()
  String get href => _blink.BlinkCSSImportRule.instance.href_Getter_(unwrap_jso(this));
  
  @DomName('CSSImportRule.media')
  @DocsEditable()
  MediaList get media => wrap_jso(_blink.BlinkCSSImportRule.instance.media_Getter_(unwrap_jso(this)));
  
  @DomName('CSSImportRule.styleSheet')
  @DocsEditable()
  CssStyleSheet get styleSheet => wrap_jso(_blink.BlinkCSSImportRule.instance.styleSheet_Getter_(unwrap_jso(this)));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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")
  static CssKeyframeRule internalCreateCssKeyframeRule() {
    return new CssKeyframeRule._internalWrap();
  }

  external factory CssKeyframeRule._internalWrap();

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


  @DomName('CSSKeyframeRule.keyText')
  @DocsEditable()
  @Experimental() // untriaged
  String get keyText => _blink.BlinkCSSKeyframeRule.instance.keyText_Getter_(unwrap_jso(this));
  
  @DomName('CSSKeyframeRule.keyText')
  @DocsEditable()
  @Experimental() // untriaged
  set keyText(String value) => _blink.BlinkCSSKeyframeRule.instance.keyText_Setter_(unwrap_jso(this), value);
  
  @DomName('CSSKeyframeRule.style')
  @DocsEditable()
  @Experimental() // untriaged
  CssStyleDeclaration get style => wrap_jso(_blink.BlinkCSSKeyframeRule.instance.style_Getter_(unwrap_jso(this)));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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")
  static CssKeyframesRule internalCreateCssKeyframesRule() {
    return new CssKeyframesRule._internalWrap();
  }

  external factory CssKeyframesRule._internalWrap();

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


  @DomName('CSSKeyframesRule.cssRules')
  @DocsEditable()
  @Experimental() // untriaged
  List<CssRule> get cssRules => wrap_jso(_blink.BlinkCSSKeyframesRule.instance.cssRules_Getter_(unwrap_jso(this)));
  
  @DomName('CSSKeyframesRule.name')
  @DocsEditable()
  @Experimental() // untriaged
  String get name => _blink.BlinkCSSKeyframesRule.instance.name_Getter_(unwrap_jso(this));
  
  @DomName('CSSKeyframesRule.name')
  @DocsEditable()
  @Experimental() // untriaged
  set name(String value) => _blink.BlinkCSSKeyframesRule.instance.name_Setter_(unwrap_jso(this), value);
  
  @DomName('CSSKeyframesRule.__getter__')
  @DocsEditable()
  @Experimental() // untriaged
  CssKeyframeRule __getter__(int index) => wrap_jso(_blink.BlinkCSSKeyframesRule.instance.$__getter___Callback_1_(unwrap_jso(this), index));
  
  @DomName('CSSKeyframesRule.appendRule')
  @DocsEditable()
  @Experimental() // untriaged
  void appendRule(String rule) => _blink.BlinkCSSKeyframesRule.instance.appendRule_Callback_1_(unwrap_jso(this), rule);
  
  @DomName('CSSKeyframesRule.deleteRule')
  @DocsEditable()
  @Experimental() // untriaged
  void deleteRule(String select) => _blink.BlinkCSSKeyframesRule.instance.deleteRule_Callback_1_(unwrap_jso(this), select);
  
  @DomName('CSSKeyframesRule.findRule')
  @DocsEditable()
  @Experimental() // untriaged
  CssKeyframeRule findRule(String select) => wrap_jso(_blink.BlinkCSSKeyframesRule.instance.findRule_Callback_1_(unwrap_jso(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")
  static CssMediaRule internalCreateCssMediaRule() {
    return new CssMediaRule._internalWrap();
  }

  external factory CssMediaRule._internalWrap();

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


  @DomName('CSSMediaRule.media')
  @DocsEditable()
  MediaList get media => wrap_jso(_blink.BlinkCSSMediaRule.instance.media_Getter_(unwrap_jso(this)));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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")
  static CssPageRule internalCreateCssPageRule() {
    return new CssPageRule._internalWrap();
  }

  external factory CssPageRule._internalWrap();

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


  @DomName('CSSPageRule.selectorText')
  @DocsEditable()
  String get selectorText => _blink.BlinkCSSPageRule.instance.selectorText_Getter_(unwrap_jso(this));
  
  @DomName('CSSPageRule.selectorText')
  @DocsEditable()
  set selectorText(String value) => _blink.BlinkCSSPageRule.instance.selectorText_Setter_(unwrap_jso(this), value);
  
  @DomName('CSSPageRule.style')
  @DocsEditable()
  CssStyleDeclaration get style => wrap_jso(_blink.BlinkCSSPageRule.instance.style_Getter_(unwrap_jso(this)));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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")
  static CssRule internalCreateCssRule() {
    return new CssRule._internalWrap();
  }

  factory CssRule._internalWrap() {
    return new CssRule.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  @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_(unwrap_jso(this));
  
  @DomName('CSSRule.cssText')
  @DocsEditable()
  set cssText(String value) => _blink.BlinkCSSRule.instance.cssText_Setter_(unwrap_jso(this), value);
  
  @DomName('CSSRule.parentRule')
  @DocsEditable()
  CssRule get parentRule => wrap_jso(_blink.BlinkCSSRule.instance.parentRule_Getter_(unwrap_jso(this)));
  
  @DomName('CSSRule.parentStyleSheet')
  @DocsEditable()
  CssStyleSheet get parentStyleSheet => wrap_jso(_blink.BlinkCSSRule.instance.parentStyleSheet_Getter_(unwrap_jso(this)));
  
  @DomName('CSSRule.type')
  @DocsEditable()
  int get type => _blink.BlinkCSSRule.instance.type_Getter_(unwrap_jso(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_(unwrap_jso(this), propertyName) != null;

  @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")
  static CssStyleDeclaration internalCreateCssStyleDeclaration() {
    return new CssStyleDeclaration._internalWrap();
  }

  factory CssStyleDeclaration._internalWrap() {
    return new CssStyleDeclaration.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  @DomName('CSSStyleDeclaration.cssText')
  @DocsEditable()
  String get cssText => _blink.BlinkCSSStyleDeclaration.instance.cssText_Getter_(unwrap_jso(this));
  
  @DomName('CSSStyleDeclaration.cssText')
  @DocsEditable()
  set cssText(String value) => _blink.BlinkCSSStyleDeclaration.instance.cssText_Setter_(unwrap_jso(this), value);
  
  @DomName('CSSStyleDeclaration.length')
  @DocsEditable()
  int get length => _blink.BlinkCSSStyleDeclaration.instance.length_Getter_(unwrap_jso(this));
  
  @DomName('CSSStyleDeclaration.parentRule')
  @DocsEditable()
  CssRule get parentRule => wrap_jso(_blink.BlinkCSSStyleDeclaration.instance.parentRule_Getter_(unwrap_jso(this)));
  
  @DomName('CSSStyleDeclaration.__propertyQuery__')
  @DocsEditable()
  @Experimental() // untriaged
  bool __propertyQuery__(String name) => _blink.BlinkCSSStyleDeclaration.instance.$__propertyQuery___Callback_1_(unwrap_jso(this), name);
  
  @DomName('CSSStyleDeclaration.getPropertyPriority')
  @DocsEditable()
  String getPropertyPriority(String property) => _blink.BlinkCSSStyleDeclaration.instance.getPropertyPriority_Callback_1_(unwrap_jso(this), property);
  
  @DomName('CSSStyleDeclaration.getPropertyValue')
  @DocsEditable()
  String _getPropertyValue(String property) => _blink.BlinkCSSStyleDeclaration.instance.getPropertyValue_Callback_1_(unwrap_jso(this), property);
  
  @DomName('CSSStyleDeclaration.item')
  @DocsEditable()
  String item(int index) => _blink.BlinkCSSStyleDeclaration.instance.item_Callback_1_(unwrap_jso(this), index);
  
  @DomName('CSSStyleDeclaration.removeProperty')
  @DocsEditable()
  String removeProperty(String property) => _blink.BlinkCSSStyleDeclaration.instance.removeProperty_Callback_1_(unwrap_jso(this), property);
  
  @DomName('CSSStyleDeclaration.setProperty')
  @DocsEditable()
  void _setProperty(String property, String value, String priority) => _blink.BlinkCSSStyleDeclaration.instance.setProperty_Callback_3_(unwrap_jso(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")
  static CssStyleRule internalCreateCssStyleRule() {
    return new CssStyleRule._internalWrap();
  }

  external factory CssStyleRule._internalWrap();

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


  @DomName('CSSStyleRule.selectorText')
  @DocsEditable()
  String get selectorText => _blink.BlinkCSSStyleRule.instance.selectorText_Getter_(unwrap_jso(this));
  
  @DomName('CSSStyleRule.selectorText')
  @DocsEditable()
  set selectorText(String value) => _blink.BlinkCSSStyleRule.instance.selectorText_Setter_(unwrap_jso(this), value);
  
  @DomName('CSSStyleRule.style')
  @DocsEditable()
  CssStyleDeclaration get style => wrap_jso(_blink.BlinkCSSStyleRule.instance.style_Getter_(unwrap_jso(this)));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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")
  static CssStyleSheet internalCreateCssStyleSheet() {
    return new CssStyleSheet._internalWrap();
  }

  external factory CssStyleSheet._internalWrap();

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


  @DomName('CSSStyleSheet.cssRules')
  @DocsEditable()
  List<CssRule> get cssRules => wrap_jso(_blink.BlinkCSSStyleSheet.instance.cssRules_Getter_(unwrap_jso(this)));
  
  @DomName('CSSStyleSheet.ownerRule')
  @DocsEditable()
  CssRule get ownerRule => wrap_jso(_blink.BlinkCSSStyleSheet.instance.ownerRule_Getter_(unwrap_jso(this)));
  
  @DomName('CSSStyleSheet.rules')
  @DocsEditable()
  @Experimental() // non-standard
  List<CssRule> get rules => wrap_jso(_blink.BlinkCSSStyleSheet.instance.rules_Getter_(unwrap_jso(this)));
  
  int addRule(String selector, String style, [int index]) {
    if (index != null) {
      return _blink.BlinkCSSStyleSheet.instance.addRule_Callback_3_(unwrap_jso(this), selector, style, index);
    }
    return _blink.BlinkCSSStyleSheet.instance.addRule_Callback_2_(unwrap_jso(this), selector, style);
  }

  @DomName('CSSStyleSheet.deleteRule')
  @DocsEditable()
  void deleteRule(int index) => _blink.BlinkCSSStyleSheet.instance.deleteRule_Callback_1_(unwrap_jso(this), index);
  
  int insertRule(String rule, [int index]) {
    if (index != null) {
      return _blink.BlinkCSSStyleSheet.instance.insertRule_Callback_2_(unwrap_jso(this), rule, index);
    }
    return _blink.BlinkCSSStyleSheet.instance.insertRule_Callback_1_(unwrap_jso(this), rule);
  }

  @DomName('CSSStyleSheet.removeRule')
  @DocsEditable()
  @Experimental() // non-standard
  void removeRule(int index) => _blink.BlinkCSSStyleSheet.instance.removeRule_Callback_1_(unwrap_jso(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")
  static CssSupportsRule internalCreateCssSupportsRule() {
    return new CssSupportsRule._internalWrap();
  }

  external factory CssSupportsRule._internalWrap();

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


  @DomName('CSSSupportsRule.conditionText')
  @DocsEditable()
  String get conditionText => _blink.BlinkCSSSupportsRule.instance.conditionText_Getter_(unwrap_jso(this));
  
  @DomName('CSSSupportsRule.cssRules')
  @DocsEditable()
  List<CssRule> get cssRules => wrap_jso(_blink.BlinkCSSSupportsRule.instance.cssRules_Getter_(unwrap_jso(this)));
  
  @DomName('CSSSupportsRule.deleteRule')
  @DocsEditable()
  void deleteRule(int index) => _blink.BlinkCSSSupportsRule.instance.deleteRule_Callback_1_(unwrap_jso(this), index);
  
  @DomName('CSSSupportsRule.insertRule')
  @DocsEditable()
  int insertRule(String rule, int index) => _blink.BlinkCSSSupportsRule.instance.insertRule_Callback_2_(unwrap_jso(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")
  static CssViewportRule internalCreateCssViewportRule() {
    return new CssViewportRule._internalWrap();
  }

  external factory CssViewportRule._internalWrap();

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


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

// WARNING: Do not edit - generated code.


@DomName('CustomEvent')
class CustomEvent extends Event {
  var _dartDetail;

  factory CustomEvent(String type,
      {bool canBubble: true, bool cancelable: true, Object detail}) {

    final CustomEvent e = document._createEvent('CustomEvent');

    e._dartDetail = detail;

    // Only try setting the detail if it's one of these types to avoid
    // first-chance exceptions. Can expand this list in the future as needed.
    if (detail is List || detail is Map || detail is String || detail is num) {
      try {
        e._initCustomEvent(type, canBubble, cancelable, detail);
      } catch(_) {
        e._initCustomEvent(type, canBubble, cancelable, null);
      }
    } else {
      e._initCustomEvent(type, canBubble, cancelable, null);
    }

    // Need for identity.
    js.setDartHtmlWrapperFor(e.blink_jsObject, e);

    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 wrap_jso(_blink.BlinkCustomEvent.instance.constructorCallback_2_(type, eventInitDict_1));
    }
    return wrap_jso(_blink.BlinkCustomEvent.instance.constructorCallback_1_(type));
  }


  @Deprecated("Internal Use Only")
  static CustomEvent internalCreateCustomEvent() {
    return new CustomEvent._internalWrap();
  }

  external factory CustomEvent._internalWrap();

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


  @DomName('CustomEvent.detail')
  @DocsEditable()
  Object get _detail => wrap_jso(_blink.BlinkCustomEvent.instance.detail_Getter_(unwrap_jso(this)));
  
  @DomName('CustomEvent.initCustomEvent')
  @DocsEditable()
  void _initCustomEvent(String type, bool bubbles, bool cancelable, Object detail) => _blink.BlinkCustomEvent.instance.initCustomEvent_Callback_4_(unwrap_jso(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")
  static DListElement internalCreateDListElement() {
    return new DListElement._internalWrap();
  }

  external factory DListElement._internalWrap();

  @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")
  static DataListElement internalCreateDataListElement() {
    return new DataListElement._internalWrap();
  }

  external factory DataListElement._internalWrap();

  @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 => wrap_jso(_blink.BlinkHTMLDataListElement.instance.options_Getter_(unwrap_jso(this)));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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")
  static DataTransfer internalCreateDataTransfer() {
    return new DataTransfer._internalWrap();
  }

  factory DataTransfer._internalWrap() {
    return new DataTransfer.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  @DomName('DataTransfer.dropEffect')
  @DocsEditable()
  @Experimental() // untriaged
  String get dropEffect => _blink.BlinkDataTransfer.instance.dropEffect_Getter_(unwrap_jso(this));
  
  @DomName('DataTransfer.dropEffect')
  @DocsEditable()
  @Experimental() // untriaged
  set dropEffect(String value) => _blink.BlinkDataTransfer.instance.dropEffect_Setter_(unwrap_jso(this), value);
  
  @DomName('DataTransfer.effectAllowed')
  @DocsEditable()
  @Experimental() // untriaged
  String get effectAllowed => _blink.BlinkDataTransfer.instance.effectAllowed_Getter_(unwrap_jso(this));
  
  @DomName('DataTransfer.effectAllowed')
  @DocsEditable()
  @Experimental() // untriaged
  set effectAllowed(String value) => _blink.BlinkDataTransfer.instance.effectAllowed_Setter_(unwrap_jso(this), value);
  
  @DomName('DataTransfer.files')
  @DocsEditable()
  @Experimental() // untriaged
  List<File> get files => wrap_jso(_blink.BlinkDataTransfer.instance.files_Getter_(unwrap_jso(this)));
  
  @DomName('DataTransfer.items')
  @DocsEditable()
  @Experimental() // untriaged
  DataTransferItemList get items => wrap_jso(_blink.BlinkDataTransfer.instance.items_Getter_(unwrap_jso(this)));
  
  @DomName('DataTransfer.types')
  @DocsEditable()
  @Experimental() // untriaged
  List<String> get types => _blink.BlinkDataTransfer.instance.types_Getter_(unwrap_jso(this));
  
  void clearData([String format]) {
    if (format != null) {
      _blink.BlinkDataTransfer.instance.clearData_Callback_1_(unwrap_jso(this), format);
      return;
    }
    _blink.BlinkDataTransfer.instance.clearData_Callback_0_(unwrap_jso(this));
    return;
  }

  @DomName('DataTransfer.getData')
  @DocsEditable()
  @Experimental() // untriaged
  String getData(String format) => _blink.BlinkDataTransfer.instance.getData_Callback_1_(unwrap_jso(this), format);
  
  @DomName('DataTransfer.setData')
  @DocsEditable()
  @Experimental() // untriaged
  void setData(String format, String data) => _blink.BlinkDataTransfer.instance.setData_Callback_2_(unwrap_jso(this), format, data);
  
  @DomName('DataTransfer.setDragImage')
  @DocsEditable()
  @Experimental() // untriaged
  void setDragImage(Element image, int x, int y) => _blink.BlinkDataTransfer.instance.setDragImage_Callback_3_(unwrap_jso(this), unwrap_jso(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")
  static DataTransferItem internalCreateDataTransferItem() {
    return new DataTransferItem._internalWrap();
  }

  factory DataTransferItem._internalWrap() {
    return new DataTransferItem.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  @DomName('DataTransferItem.kind')
  @DocsEditable()
  String get kind => _blink.BlinkDataTransferItem.instance.kind_Getter_(unwrap_jso(this));
  
  @DomName('DataTransferItem.type')
  @DocsEditable()
  String get type => _blink.BlinkDataTransferItem.instance.type_Getter_(unwrap_jso(this));
  
  @DomName('DataTransferItem.getAsFile')
  @DocsEditable()
  Blob getAsFile() => wrap_jso(_blink.BlinkDataTransferItem.instance.getAsFile_Callback_0_(unwrap_jso(this)));
  
  @DomName('DataTransferItem.getAsString')
  @DocsEditable()
  void _getAsString(_StringCallback callback) => _blink.BlinkDataTransferItem.instance.getAsString_Callback_1_(unwrap_jso(this), unwrap_jso((data) => callback(data)));
  
  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() => wrap_jso(_blink.BlinkDataTransferItem.instance.webkitGetAsEntry_Callback_0_(unwrap_jso(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")
  static DataTransferItemList internalCreateDataTransferItemList() {
    return new DataTransferItemList._internalWrap();
  }

  factory DataTransferItemList._internalWrap() {
    return new DataTransferItemList.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  @DomName('DataTransferItemList.length')
  @DocsEditable()
  int get length => _blink.BlinkDataTransferItemList.instance.length_Getter_(unwrap_jso(this));
  
  DataTransferItem add(data_OR_file, [String type]) {
    if ((type is String) && (data_OR_file is String)) {
      return wrap_jso(_blink.BlinkDataTransferItemList.instance.add_Callback_2_(unwrap_jso(this), unwrap_jso(data_OR_file), type));
    }
    if ((data_OR_file is File || data_OR_file == null) && type == null) {
      return wrap_jso(_blink.BlinkDataTransferItemList.instance.add_Callback_1_(unwrap_jso(this), unwrap_jso(data_OR_file)));
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }

  @DomName('DataTransferItemList.addData')
  @DocsEditable()
  DataTransferItem addData(String data, String type) => wrap_jso(_blink.BlinkDataTransferItemList.instance.add_Callback_2_(unwrap_jso(this), data, type));
  
  @DomName('DataTransferItemList.addFile')
  @DocsEditable()
  DataTransferItem addFile(File file) => wrap_jso(_blink.BlinkDataTransferItemList.instance.add_Callback_1_(unwrap_jso(this), unwrap_jso(file)));
  
  @DomName('DataTransferItemList.clear')
  @DocsEditable()
  void clear() => _blink.BlinkDataTransferItemList.instance.clear_Callback_0_(unwrap_jso(this));
  
  @DomName('DataTransferItemList.item')
  @DocsEditable()
  DataTransferItem item(int index) => wrap_jso(_blink.BlinkDataTransferItemList.instance.item_Callback_1_(unwrap_jso(this), index));
  
  @DomName('DataTransferItemList.remove')
  @DocsEditable()
  @Experimental() // untriaged
  void remove(int index) => _blink.BlinkDataTransferItemList.instance.remove_Callback_1_(unwrap_jso(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(unwrap_jso(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")
  static DedicatedWorkerGlobalScope internalCreateDedicatedWorkerGlobalScope() {
    return new DedicatedWorkerGlobalScope._internalWrap();
  }

  external factory DedicatedWorkerGlobalScope._internalWrap();

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


  void postMessage(Object message, [List<MessagePort> transfer]) {
    if (transfer != null) {
      _blink.BlinkDedicatedWorkerGlobalScope.instance.postMessage_Callback_2_(unwrap_jso(this), convertDartToNative_SerializedScriptValue(message), transfer);
      return;
    }
    _blink.BlinkDedicatedWorkerGlobalScope.instance.postMessage_Callback_1_(unwrap_jso(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 wrap_jso(_blink.BlinkDefaultSessionStartEvent.instance.constructorCallback_2_(type, eventInitDict_1));
    }
    return wrap_jso(_blink.BlinkDefaultSessionStartEvent.instance.constructorCallback_1_(type));
  }


  @Deprecated("Internal Use Only")
  static DefaultSessionStartEvent internalCreateDefaultSessionStartEvent() {
    return new DefaultSessionStartEvent._internalWrap();
  }

  external factory DefaultSessionStartEvent._internalWrap();

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


  @DomName('DefaultSessionStartEvent.session')
  @DocsEditable()
  @Experimental() // untriaged
  PresentationSession get session => wrap_jso(_blink.BlinkDefaultSessionStartEvent.instance.session_Getter_(unwrap_jso(this)));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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")
  static DeprecatedStorageInfo internalCreateDeprecatedStorageInfo() {
    return new DeprecatedStorageInfo._internalWrap();
  }

  factory DeprecatedStorageInfo._internalWrap() {
    return new DeprecatedStorageInfo.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  @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_(unwrap_jso(this), storageType, unwrap_jso((currentUsageInBytes, currentQuotaInBytes) => usageCallback(currentUsageInBytes, currentQuotaInBytes)), unwrap_jso((error) => errorCallback(wrap_jso(error))));
      return;
    }
    if (usageCallback != null) {
      _blink.BlinkDeprecatedStorageInfo.instance.queryUsageAndQuota_Callback_2_(unwrap_jso(this), storageType, unwrap_jso((currentUsageInBytes, currentQuotaInBytes) => usageCallback(currentUsageInBytes, currentQuotaInBytes)));
      return;
    }
    _blink.BlinkDeprecatedStorageInfo.instance.queryUsageAndQuota_Callback_1_(unwrap_jso(this), storageType);
    return;
  }

  void requestQuota(int storageType, int newQuotaInBytes, [StorageQuotaCallback quotaCallback, StorageErrorCallback errorCallback]) {
    if (errorCallback != null) {
      _blink.BlinkDeprecatedStorageInfo.instance.requestQuota_Callback_4_(unwrap_jso(this), storageType, newQuotaInBytes, unwrap_jso((grantedQuotaInBytes) => quotaCallback(grantedQuotaInBytes)), unwrap_jso((error) => errorCallback(wrap_jso(error))));
      return;
    }
    if (quotaCallback != null) {
      _blink.BlinkDeprecatedStorageInfo.instance.requestQuota_Callback_3_(unwrap_jso(this), storageType, newQuotaInBytes, unwrap_jso((grantedQuotaInBytes) => quotaCallback(grantedQuotaInBytes)));
      return;
    }
    _blink.BlinkDeprecatedStorageInfo.instance.requestQuota_Callback_2_(unwrap_jso(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")
  static DeprecatedStorageQuota internalCreateDeprecatedStorageQuota() {
    return new DeprecatedStorageQuota._internalWrap();
  }

  factory DeprecatedStorageQuota._internalWrap() {
    return new DeprecatedStorageQuota.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  void queryUsageAndQuota(StorageUsageCallback usageCallback, [StorageErrorCallback errorCallback]) {
    if (errorCallback != null) {
      _blink.BlinkDeprecatedStorageQuota.instance.queryUsageAndQuota_Callback_2_(unwrap_jso(this), unwrap_jso((currentUsageInBytes, currentQuotaInBytes) => usageCallback(currentUsageInBytes, currentQuotaInBytes)), unwrap_jso((error) => errorCallback(wrap_jso(error))));
      return;
    }
    _blink.BlinkDeprecatedStorageQuota.instance.queryUsageAndQuota_Callback_1_(unwrap_jso(this), unwrap_jso((currentUsageInBytes, currentQuotaInBytes) => usageCallback(currentUsageInBytes, currentQuotaInBytes)));
    return;
  }

  void requestQuota(int newQuotaInBytes, [StorageQuotaCallback quotaCallback, StorageErrorCallback errorCallback]) {
    if (errorCallback != null) {
      _blink.BlinkDeprecatedStorageQuota.instance.requestQuota_Callback_3_(unwrap_jso(this), newQuotaInBytes, unwrap_jso((grantedQuotaInBytes) => quotaCallback(grantedQuotaInBytes)), unwrap_jso((error) => errorCallback(wrap_jso(error))));
      return;
    }
    if (quotaCallback != null) {
      _blink.BlinkDeprecatedStorageQuota.instance.requestQuota_Callback_2_(unwrap_jso(this), newQuotaInBytes, unwrap_jso((grantedQuotaInBytes) => quotaCallback(grantedQuotaInBytes)));
      return;
    }
    _blink.BlinkDeprecatedStorageQuota.instance.requestQuota_Callback_1_(unwrap_jso(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")
  static DetailsElement internalCreateDetailsElement() {
    return new DetailsElement._internalWrap();
  }

  external factory DetailsElement._internalWrap();

  @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_(unwrap_jso(this));
  
  @DomName('HTMLDetailsElement.open')
  @DocsEditable()
  set open(bool value) => _blink.BlinkHTMLDetailsElement.instance.open_Setter_(unwrap_jso(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")
  static DeviceAcceleration internalCreateDeviceAcceleration() {
    return new DeviceAcceleration._internalWrap();
  }

  factory DeviceAcceleration._internalWrap() {
    return new DeviceAcceleration.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  @DomName('DeviceAcceleration.x')
  @DocsEditable()
  num get x => _blink.BlinkDeviceAcceleration.instance.x_Getter_(unwrap_jso(this));
  
  @DomName('DeviceAcceleration.y')
  @DocsEditable()
  num get y => _blink.BlinkDeviceAcceleration.instance.y_Getter_(unwrap_jso(this));
  
  @DomName('DeviceAcceleration.z')
  @DocsEditable()
  num get z => _blink.BlinkDeviceAcceleration.instance.z_Getter_(unwrap_jso(this));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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 wrap_jso(_blink.BlinkDeviceLightEvent.instance.constructorCallback_2_(type, eventInitDict_1));
    }
    return wrap_jso(_blink.BlinkDeviceLightEvent.instance.constructorCallback_1_(type));
  }


  @Deprecated("Internal Use Only")
  static DeviceLightEvent internalCreateDeviceLightEvent() {
    return new DeviceLightEvent._internalWrap();
  }

  external factory DeviceLightEvent._internalWrap();

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


  @DomName('DeviceLightEvent.value')
  @DocsEditable()
  @Experimental() // untriaged
  num get value => _blink.BlinkDeviceLightEvent.instance.value_Getter_(unwrap_jso(this));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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")
  static DeviceMotionEvent internalCreateDeviceMotionEvent() {
    return new DeviceMotionEvent._internalWrap();
  }

  external factory DeviceMotionEvent._internalWrap();

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


  @DomName('DeviceMotionEvent.acceleration')
  @DocsEditable()
  DeviceAcceleration get acceleration => wrap_jso(_blink.BlinkDeviceMotionEvent.instance.acceleration_Getter_(unwrap_jso(this)));
  
  @DomName('DeviceMotionEvent.accelerationIncludingGravity')
  @DocsEditable()
  DeviceAcceleration get accelerationIncludingGravity => wrap_jso(_blink.BlinkDeviceMotionEvent.instance.accelerationIncludingGravity_Getter_(unwrap_jso(this)));
  
  @DomName('DeviceMotionEvent.interval')
  @DocsEditable()
  num get interval => _blink.BlinkDeviceMotionEvent.instance.interval_Getter_(unwrap_jso(this));
  
  @DomName('DeviceMotionEvent.rotationRate')
  @DocsEditable()
  DeviceRotationRate get rotationRate => wrap_jso(_blink.BlinkDeviceMotionEvent.instance.rotationRate_Getter_(unwrap_jso(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_(unwrap_jso(this), type, bubbles, cancelable, unwrap_jso(acceleration), unwrap_jso(accelerationIncludingGravity), unwrap_jso(rotationRate), interval);
  
}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.

@DomName('DeviceOrientationEvent')
// http://dev.w3.org/geo/api/spec-source-orientation.html#devicemotion
@Experimental()
class DeviceOrientationEvent extends Event {
  factory DeviceOrientationEvent(String type,
      {bool canBubble: true, bool cancelable: true, num alpha: 0, num beta: 0,
      num gamma: 0, bool absolute: false}) {
    var e = document._createEvent("DeviceOrientationEvent");
    e._initDeviceOrientationEvent(type, canBubble, cancelable, alpha, beta,
        gamma, absolute);
    return e;
  }
  // To suppress missing implicit constructor warnings.
  factory DeviceOrientationEvent._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  static DeviceOrientationEvent internalCreateDeviceOrientationEvent() {
    return new DeviceOrientationEvent._internalWrap();
  }

  external factory DeviceOrientationEvent._internalWrap();

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


  @DomName('DeviceOrientationEvent.absolute')
  @DocsEditable()
  bool get absolute => _blink.BlinkDeviceOrientationEvent.instance.absolute_Getter_(unwrap_jso(this));
  
  @DomName('DeviceOrientationEvent.alpha')
  @DocsEditable()
  num get alpha => _blink.BlinkDeviceOrientationEvent.instance.alpha_Getter_(unwrap_jso(this));
  
  @DomName('DeviceOrientationEvent.beta')
  @DocsEditable()
  num get beta => _blink.BlinkDeviceOrientationEvent.instance.beta_Getter_(unwrap_jso(this));
  
  @DomName('DeviceOrientationEvent.gamma')
  @DocsEditable()
  num get gamma => _blink.BlinkDeviceOrientationEvent.instance.gamma_Getter_(unwrap_jso(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_(unwrap_jso(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")
  static DeviceRotationRate internalCreateDeviceRotationRate() {
    return new DeviceRotationRate._internalWrap();
  }

  factory DeviceRotationRate._internalWrap() {
    return new DeviceRotationRate.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  @DomName('DeviceRotationRate.alpha')
  @DocsEditable()
  num get alpha => _blink.BlinkDeviceRotationRate.instance.alpha_Getter_(unwrap_jso(this));
  
  @DomName('DeviceRotationRate.beta')
  @DocsEditable()
  num get beta => _blink.BlinkDeviceRotationRate.instance.beta_Getter_(unwrap_jso(this));
  
  @DomName('DeviceRotationRate.gamma')
  @DocsEditable()
  num get gamma => _blink.BlinkDeviceRotationRate.instance.gamma_Getter_(unwrap_jso(this));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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")
  static DialogElement internalCreateDialogElement() {
    return new DialogElement._internalWrap();
  }

  external factory DialogElement._internalWrap();

  @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_(unwrap_jso(this));
  
  @DomName('HTMLDialogElement.open')
  @DocsEditable()
  set open(bool value) => _blink.BlinkHTMLDialogElement.instance.open_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLDialogElement.returnValue')
  @DocsEditable()
  @Experimental() // untriaged
  String get returnValue => _blink.BlinkHTMLDialogElement.instance.returnValue_Getter_(unwrap_jso(this));
  
  @DomName('HTMLDialogElement.returnValue')
  @DocsEditable()
  @Experimental() // untriaged
  set returnValue(String value) => _blink.BlinkHTMLDialogElement.instance.returnValue_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLDialogElement.close')
  @DocsEditable()
  void close(String returnValue) => _blink.BlinkHTMLDialogElement.instance.close_Callback_1_(unwrap_jso(this), returnValue);
  
  @DomName('HTMLDialogElement.show')
  @DocsEditable()
  void show() => _blink.BlinkHTMLDialogElement.instance.show_Callback_0_(unwrap_jso(this));
  
  @DomName('HTMLDialogElement.showModal')
  @DocsEditable()
  void showModal() => _blink.BlinkHTMLDialogElement.instance.showModal_Callback_0_(unwrap_jso(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")
  static DirectoryEntry internalCreateDirectoryEntry() {
    return new DirectoryEntry._internalWrap();
  }

  external factory DirectoryEntry._internalWrap();

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


  @DomName('DirectoryEntry.createReader')
  @DocsEditable()
  DirectoryReader createReader() => wrap_jso(_blink.BlinkDirectoryEntry.instance.createReader_Callback_0_(unwrap_jso(this)));
  
  void __getDirectory(String path, {Map options, _EntryCallback successCallback, _ErrorCallback errorCallback}) {
    if (errorCallback != null) {
      _blink.BlinkDirectoryEntry.instance.getDirectory_Callback_4_(unwrap_jso(this), path, convertDartToNative_Dictionary(options), unwrap_jso((entry) => successCallback(wrap_jso(entry))), unwrap_jso((error) => errorCallback(wrap_jso(error))));
      return;
    }
    if (successCallback != null) {
      _blink.BlinkDirectoryEntry.instance.getDirectory_Callback_3_(unwrap_jso(this), path, convertDartToNative_Dictionary(options), unwrap_jso((entry) => successCallback(wrap_jso(entry))));
      return;
    }
    if (options != null) {
      _blink.BlinkDirectoryEntry.instance.getDirectory_Callback_2_(unwrap_jso(this), path, convertDartToNative_Dictionary(options));
      return;
    }
    _blink.BlinkDirectoryEntry.instance.getDirectory_Callback_1_(unwrap_jso(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_(unwrap_jso(this), path, convertDartToNative_Dictionary(options), unwrap_jso((entry) => successCallback(wrap_jso(entry))), unwrap_jso((error) => errorCallback(wrap_jso(error))));
      return;
    }
    if (successCallback != null) {
      _blink.BlinkDirectoryEntry.instance.getFile_Callback_3_(unwrap_jso(this), path, convertDartToNative_Dictionary(options), unwrap_jso((entry) => successCallback(wrap_jso(entry))));
      return;
    }
    if (options != null) {
      _blink.BlinkDirectoryEntry.instance.getFile_Callback_2_(unwrap_jso(this), path, convertDartToNative_Dictionary(options));
      return;
    }
    _blink.BlinkDirectoryEntry.instance.getFile_Callback_1_(unwrap_jso(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_(unwrap_jso(this), unwrap_jso(() => successCallback()), unwrap_jso((error) => errorCallback(wrap_jso(error))));
      return;
    }
    _blink.BlinkDirectoryEntry.instance.removeRecursively_Callback_1_(unwrap_jso(this), unwrap_jso(() => 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")
  static DirectoryReader internalCreateDirectoryReader() {
    return new DirectoryReader._internalWrap();
  }

  factory DirectoryReader._internalWrap() {
    return new DirectoryReader.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  void _readEntries(_EntriesCallback successCallback, [_ErrorCallback errorCallback]) {
    if (errorCallback != null) {
      _blink.BlinkDirectoryReader.instance.readEntries_Callback_2_(unwrap_jso(this), unwrap_jso((entries) => successCallback(wrap_jso(entries))), unwrap_jso((error) => errorCallback(wrap_jso(error))));
      return;
    }
    _blink.BlinkDirectoryReader.instance.readEntries_Callback_1_(unwrap_jso(this), unwrap_jso((entries) => successCallback(wrap_jso(entries))));
    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")
  static DivElement internalCreateDivElement() {
    return new DivElement._internalWrap();
  }

  external factory DivElement._internalWrap();

  @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")
  static Document internalCreateDocument() {
    return new Document._internalWrap();
  }

  external factory Document._internalWrap();

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


  @DomName('Document.activeElement')
  @DocsEditable()
  @Experimental() // untriaged
  Element get activeElement => wrap_jso(_blink.BlinkDocument.instance.activeElement_Getter_(unwrap_jso(this)));
  
  @DomName('Document.body')
  @DocsEditable()
  HtmlElement get _body => wrap_jso(_blink.BlinkDocument.instance.body_Getter_(unwrap_jso(this)));
  
  @DomName('Document.body')
  @DocsEditable()
  set _body(HtmlElement value) => _blink.BlinkDocument.instance.body_Setter_(unwrap_jso(this), unwrap_jso(value));
  
  @DomName('Document.contentType')
  @DocsEditable()
  @Experimental() // untriaged
  String get contentType => _blink.BlinkDocument.instance.contentType_Getter_(unwrap_jso(this));
  
  @DomName('Document.cookie')
  @DocsEditable()
  String get cookie => _blink.BlinkDocument.instance.cookie_Getter_(unwrap_jso(this));
  
  @DomName('Document.cookie')
  @DocsEditable()
  set cookie(String value) => _blink.BlinkDocument.instance.cookie_Setter_(unwrap_jso(this), value);
  
  @DomName('Document.currentScript')
  @DocsEditable()
  @Experimental() // untriaged
  ScriptElement get currentScript => wrap_jso(_blink.BlinkDocument.instance.currentScript_Getter_(unwrap_jso(this)));
  
  @DomName('Document.defaultView')
  @DocsEditable()
  WindowBase get window => wrap_jso(_blink.BlinkDocument.instance.defaultView_Getter_(unwrap_jso(this)));
  
  @DomName('Document.documentElement')
  @DocsEditable()
  Element get documentElement => wrap_jso(_blink.BlinkDocument.instance.documentElement_Getter_(unwrap_jso(this)));
  
  @DomName('Document.domain')
  @DocsEditable()
  String get domain => _blink.BlinkDocument.instance.domain_Getter_(unwrap_jso(this));
  
  @DomName('Document.fonts')
  @DocsEditable()
  @Experimental() // untriaged
  FontFaceSet get fonts => wrap_jso(_blink.BlinkDocument.instance.fonts_Getter_(unwrap_jso(this)));
  
  @DomName('Document.fullscreenElement')
  @DocsEditable()
  @Experimental() // untriaged
  Element get fullscreenElement => wrap_jso(_blink.BlinkDocument.instance.fullscreenElement_Getter_(unwrap_jso(this)));
  
  @DomName('Document.fullscreenEnabled')
  @DocsEditable()
  @Experimental() // untriaged
  bool get fullscreenEnabled => _blink.BlinkDocument.instance.fullscreenEnabled_Getter_(unwrap_jso(this));
  
  @DomName('Document.head')
  @DocsEditable()
  HeadElement get _head => wrap_jso(_blink.BlinkDocument.instance.head_Getter_(unwrap_jso(this)));
  
  @DomName('Document.hidden')
  @DocsEditable()
  @Experimental() // untriaged
  bool get hidden => _blink.BlinkDocument.instance.hidden_Getter_(unwrap_jso(this));
  
  @DomName('Document.implementation')
  @DocsEditable()
  DomImplementation get implementation => wrap_jso(_blink.BlinkDocument.instance.implementation_Getter_(unwrap_jso(this)));
  
  @DomName('Document.lastModified')
  @DocsEditable()
  String get _lastModified => _blink.BlinkDocument.instance.lastModified_Getter_(unwrap_jso(this));
  
  @DomName('Document.origin')
  @DocsEditable()
  @Experimental() // untriaged
  String get origin => _blink.BlinkDocument.instance.origin_Getter_(unwrap_jso(this));
  
  @DomName('Document.pointerLockElement')
  @DocsEditable()
  @Experimental() // untriaged
  Element get pointerLockElement => wrap_jso(_blink.BlinkDocument.instance.pointerLockElement_Getter_(unwrap_jso(this)));
  
  @DomName('Document.preferredStylesheetSet')
  @DocsEditable()
  String get _preferredStylesheetSet => _blink.BlinkDocument.instance.preferredStylesheetSet_Getter_(unwrap_jso(this));
  
  @DomName('Document.readyState')
  @DocsEditable()
  String get readyState => _blink.BlinkDocument.instance.readyState_Getter_(unwrap_jso(this));
  
  @DomName('Document.referrer')
  @DocsEditable()
  String get _referrer => _blink.BlinkDocument.instance.referrer_Getter_(unwrap_jso(this));
  
  @DomName('Document.rootElement')
  @DocsEditable()
  @Experimental() // untriaged
  SvgSvgElement get rootElement => wrap_jso(_blink.BlinkDocument.instance.rootElement_Getter_(unwrap_jso(this)));
  
  @DomName('Document.scrollingElement')
  @DocsEditable()
  @Experimental() // untriaged
  Element get scrollingElement => wrap_jso(_blink.BlinkDocument.instance.scrollingElement_Getter_(unwrap_jso(this)));
  
  @DomName('Document.selectedStylesheetSet')
  @DocsEditable()
  String get _selectedStylesheetSet => _blink.BlinkDocument.instance.selectedStylesheetSet_Getter_(unwrap_jso(this));
  
  @DomName('Document.selectedStylesheetSet')
  @DocsEditable()
  set _selectedStylesheetSet(String value) => _blink.BlinkDocument.instance.selectedStylesheetSet_Setter_(unwrap_jso(this), value);
  
  @DomName('Document.styleSheets')
  @DocsEditable()
  List<StyleSheet> get _styleSheets => wrap_jso(_blink.BlinkDocument.instance.styleSheets_Getter_(unwrap_jso(this)));
  
  @DomName('Document.timeline')
  @DocsEditable()
  @Experimental() // untriaged
  AnimationTimeline get timeline => wrap_jso(_blink.BlinkDocument.instance.timeline_Getter_(unwrap_jso(this)));
  
  @DomName('Document.title')
  @DocsEditable()
  String get _title => _blink.BlinkDocument.instance.title_Getter_(unwrap_jso(this));
  
  @DomName('Document.title')
  @DocsEditable()
  set _title(String value) => _blink.BlinkDocument.instance.title_Setter_(unwrap_jso(this), value);
  
  @DomName('Document.visibilityState')
  @DocsEditable()
  @Experimental() // untriaged
  String get visibilityState => _blink.BlinkDocument.instance.visibilityState_Getter_(unwrap_jso(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 => wrap_jso(_blink.BlinkDocument.instance.webkitFullscreenElement_Getter_(unwrap_jso(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_(unwrap_jso(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_(unwrap_jso(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_(unwrap_jso(this));
  
  @DomName('Document.adoptNode')
  @DocsEditable()
  Node adoptNode(Node node) => wrap_jso(_blink.BlinkDocument.instance.adoptNode_Callback_1_(unwrap_jso(this), unwrap_jso(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) => wrap_jso(_blink.BlinkDocument.instance.caretRangeFromPoint_Callback_2_(unwrap_jso(this), x, y));
  
  @DomName('Document.createDocumentFragment')
  @DocsEditable()
  DocumentFragment createDocumentFragment() => wrap_jso(_blink.BlinkDocument.instance.createDocumentFragment_Callback_0_(unwrap_jso(this)));
  
  @DomName('Document.createElement')
  @DocsEditable()
  Element _createElement(String localName_OR_tagName, [String typeExtension]) => wrap_jso(_blink.BlinkDocument.instance.createElement_Callback_2_(unwrap_jso(this), localName_OR_tagName, typeExtension));
  
  @DomName('Document.createElementNS')
  @DocsEditable()
  Element _createElementNS(String namespaceURI, String qualifiedName, [String typeExtension]) => wrap_jso(_blink.BlinkDocument.instance.createElementNS_Callback_3_(unwrap_jso(this), namespaceURI, qualifiedName, typeExtension));
  
  @DomName('Document.createEvent')
  @DocsEditable()
  Event _createEvent(String eventType) => wrap_jso(_blink.BlinkDocument.instance.createEvent_Callback_1_(unwrap_jso(this), eventType));
  
  NodeIterator _createNodeIterator(Node root, [int whatToShow, NodeFilter filter]) {
    if (whatToShow != null) {
      return wrap_jso(_blink.BlinkDocument.instance.createNodeIterator_Callback_3_(unwrap_jso(this), unwrap_jso(root), whatToShow, unwrap_jso(filter)));
    }
    return wrap_jso(_blink.BlinkDocument.instance.createNodeIterator_Callback_1_(unwrap_jso(this), unwrap_jso(root)));
  }

  @DomName('Document.createRange')
  @DocsEditable()
  Range createRange() => wrap_jso(_blink.BlinkDocument.instance.createRange_Callback_0_(unwrap_jso(this)));
  
  @DomName('Document.createTextNode')
  @DocsEditable()
  Text _createTextNode(String data) => wrap_jso(_blink.BlinkDocument.instance.createTextNode_Callback_1_(unwrap_jso(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) => wrap_jso(_blink.BlinkDocument.instance.createTouch_Callback_11_(unwrap_jso(this), unwrap_jso(window), unwrap_jso(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) => wrap_jso(_blink.BlinkDocument.instance.createTouchList_Callback_1_(unwrap_jso(this), unwrap_jso(touches)));
  
  TreeWalker _createTreeWalker(Node root, [int whatToShow, NodeFilter filter]) {
    if (whatToShow != null) {
      return wrap_jso(_blink.BlinkDocument.instance.createTreeWalker_Callback_3_(unwrap_jso(this), unwrap_jso(root), whatToShow, unwrap_jso(filter)));
    }
    return wrap_jso(_blink.BlinkDocument.instance.createTreeWalker_Callback_1_(unwrap_jso(this), unwrap_jso(root)));
  }

  @DomName('Document.elementFromPoint')
  @DocsEditable()
  Element _elementFromPoint(int x, int y) => wrap_jso(_blink.BlinkDocument.instance.elementFromPoint_Callback_2_(unwrap_jso(this), x, y));
  
  @DomName('Document.elementsFromPoint')
  @DocsEditable()
  @Experimental() // untriaged
  List<Element> elementsFromPoint(int x, int y) => wrap_jso(_blink.BlinkDocument.instance.elementsFromPoint_Callback_2_(unwrap_jso(this), x, y));
  
  bool execCommand(String commandId, [bool showUI, String value]) {
    if (value != null) {
      return _blink.BlinkDocument.instance.execCommand_Callback_3_(unwrap_jso(this), commandId, showUI, value);
    }
    if (showUI != null) {
      return _blink.BlinkDocument.instance.execCommand_Callback_2_(unwrap_jso(this), commandId, showUI);
    }
    return _blink.BlinkDocument.instance.execCommand_Callback_1_(unwrap_jso(this), commandId);
  }

  @DomName('Document.exitFullscreen')
  @DocsEditable()
  @Experimental() // untriaged
  void exitFullscreen() => _blink.BlinkDocument.instance.exitFullscreen_Callback_0_(unwrap_jso(this));
  
  @DomName('Document.exitPointerLock')
  @DocsEditable()
  @Experimental() // untriaged
  void exitPointerLock() => _blink.BlinkDocument.instance.exitPointerLock_Callback_0_(unwrap_jso(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) => wrap_jso(_blink.BlinkDocument.instance.getCSSCanvasContext_Callback_4_(unwrap_jso(this), contextId, name, width, height));
  
  @DomName('Document.getElementsByClassName')
  @DocsEditable()
  List<Node> getElementsByClassName(String classNames) => wrap_jso(_blink.BlinkDocument.instance.getElementsByClassName_Callback_1_(unwrap_jso(this), classNames));
  
  @DomName('Document.getElementsByName')
  @DocsEditable()
  List<Node> getElementsByName(String elementName) => wrap_jso(_blink.BlinkDocument.instance.getElementsByName_Callback_1_(unwrap_jso(this), elementName));
  
  @DomName('Document.getElementsByTagName')
  @DocsEditable()
  List<Node> getElementsByTagName(String localName) => wrap_jso(_blink.BlinkDocument.instance.getElementsByTagName_Callback_1_(unwrap_jso(this), localName));
  
  Node importNode(Node node, [bool deep]) {
    if (deep != null) {
      return wrap_jso(_blink.BlinkDocument.instance.importNode_Callback_2_(unwrap_jso(this), unwrap_jso(node), deep));
    }
    return wrap_jso(_blink.BlinkDocument.instance.importNode_Callback_1_(unwrap_jso(this), unwrap_jso(node)));
  }

  @DomName('Document.queryCommandEnabled')
  @DocsEditable()
  bool queryCommandEnabled(String commandId) => _blink.BlinkDocument.instance.queryCommandEnabled_Callback_1_(unwrap_jso(this), commandId);
  
  @DomName('Document.queryCommandIndeterm')
  @DocsEditable()
  bool queryCommandIndeterm(String commandId) => _blink.BlinkDocument.instance.queryCommandIndeterm_Callback_1_(unwrap_jso(this), commandId);
  
  @DomName('Document.queryCommandState')
  @DocsEditable()
  bool queryCommandState(String commandId) => _blink.BlinkDocument.instance.queryCommandState_Callback_1_(unwrap_jso(this), commandId);
  
  @DomName('Document.queryCommandSupported')
  @DocsEditable()
  bool queryCommandSupported(String commandId) => _blink.BlinkDocument.instance.queryCommandSupported_Callback_1_(unwrap_jso(this), commandId);
  
  @DomName('Document.queryCommandValue')
  @DocsEditable()
  String queryCommandValue(String commandId) => _blink.BlinkDocument.instance.queryCommandValue_Callback_1_(unwrap_jso(this), commandId);
  
  @DomName('Document.transformDocumentToTreeView')
  @DocsEditable()
  @Experimental() // untriaged
  void transformDocumentToTreeView(String noStyleMessage) => _blink.BlinkDocument.instance.transformDocumentToTreeView_Callback_1_(unwrap_jso(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_(unwrap_jso(this));
  
  @DomName('Document.getElementById')
  @DocsEditable()
  Element getElementById(String elementId) => wrap_jso(_blink.BlinkDocument.instance.getElementById_Callback_1_(unwrap_jso(this), elementId));
  
  @DomName('Document.childElementCount')
  @DocsEditable()
  int get _childElementCount => _blink.BlinkDocument.instance.childElementCount_Getter_(unwrap_jso(this));
  
  @DomName('Document.children')
  @DocsEditable()
  List<Node> get _children => wrap_jso(_blink.BlinkDocument.instance.children_Getter_(unwrap_jso(this)));
  
  @DomName('Document.firstElementChild')
  @DocsEditable()
  Element get _firstElementChild => wrap_jso(_blink.BlinkDocument.instance.firstElementChild_Getter_(unwrap_jso(this)));
  
  @DomName('Document.lastElementChild')
  @DocsEditable()
  Element get _lastElementChild => wrap_jso(_blink.BlinkDocument.instance.lastElementChild_Getter_(unwrap_jso(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) => wrap_jso(_blink.BlinkDocument.instance.querySelector_Callback_1_(unwrap_jso(this), selectors));
  
  @DomName('Document.querySelectorAll')
  @DocsEditable()
  List<Node> _querySelectorAll(String selectors) => wrap_jso(_blink.BlinkDocument.instance.querySelectorAll_Callback_1_(unwrap_jso(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> querySelectorAll(String selectors) {
    return new _FrozenElementList._wrap(_querySelectorAll(selectors));
  }

  /**
   * Alias for [querySelector]. Note this function is deprecated because its
   * semantics will be changing in the future.
   */
  @deprecated
  @Experimental()
  @DomName('Document.querySelector')
  Element query(String relativeSelectors) => querySelector(relativeSelectors);

  /**
   * Alias for [querySelectorAll]. Note this function is deprecated because its
   * semantics will be changing in the future.
   */
  @deprecated
  @Experimental()
  @DomName('Document.querySelectorAll')
  ElementList<Element> queryAll(String relativeSelectors) =>
      querySelectorAll(relativeSelectors);

  /// Checks if [registerElement] is supported on the current platform.
  bool get supportsRegisterElement {
    return true;
  }

  /// *Deprecated*: use [supportsRegisterElement] instead.
  @deprecated
  bool get supportsRegister => supportsRegisterElement;

  @DomName('Document.createElement')
  Element createElement(String tagName, [String typeExtension]) {
    var newElement = (typeExtension == null) ?
      _blink.BlinkDocument.instance.createElement_Callback_1_(unwrap_jso(this), tagName) :
      _blink.BlinkDocument.instance.createElement_Callback_2_(unwrap_jso(this), tagName, typeExtension);

    var wrapped = js.getDartHtmlWrapperFor(newElement);  // Here's our Dart class.
    if (wrapped != null) {
      wrapped.blink_jsObject = newElement;
    } else {
      wrapped = wrap_jso(newElement);
      if (wrapped == null) {
        wrapped = wrap_jso_custom_element(newElement);
      } else {
        js.setDartHtmlWrapperFor(wrapped.blink_jsObject, wrapped);
      }
    }

    return wrapped;
  }

  @DomName('Document.createElementNS')
  @DocsEditable()
  Element createElementNS(String namespaceURI, String qualifiedName, [String typeExtension]) {
    var newElement = (typeExtension == null) ?
      _blink.BlinkDocument.instance.createElementNS_Callback_2_(unwrap_jso(this), namespaceURI, qualifiedName) :
      _blink.BlinkDocument.instance.createElementNS_Callback_3_(unwrap_jso(this), namespaceURI, qualifiedName, typeExtension);

    var wrapped;

    wrapped = js.getDartHtmlWrapperFor(newElement);  // Here's our Dart class.
    if (wrapped != null) {
      wrapped.blink_jsObject = newElement;
    } else {
      wrapped = wrap_jso(newElement);
      if (wrapped == null) {
        wrapped = wrap_jso_custom_element(newElement);
      } else {
        js.setDartHtmlWrapperFor(wrapped.blink_jsObject, wrapped);  // Here's our Dart class.
      }
    }

    return wrapped;
  }

}
// 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.
    List copy = new List.from(value);
    var children = this.children;
    children.clear();
    children.addAll(copy);
  }

  /**
   * Finds all descendant elements of this document fragment that match the
   * specified group of selectors.
   *
   * [selectors] should be a string using CSS selector syntax.
   *
   *     var items = document.querySelectorAll('.itemClassName');
   *
   * For details about CSS selector syntax, see the
   * [CSS selector specification](http://www.w3.org/TR/css3-selectors/).
   */
  ElementList<Element> querySelectorAll(String selectors) =>
    new _FrozenElementList._wrap(_querySelectorAll(selectors));

  String get innerHtml {
    final e = new Element.tag("div");
    e.append(this.clone(true));
    return e.innerHtml;
  }

  set innerHtml(String value) {
    this.setInnerHtml(value);
  }

  void setInnerHtml(String html,
    {NodeValidator validator, NodeTreeSanitizer treeSanitizer}) {

    this.nodes.clear();
    append(document.body.createFragment(
        html, validator: validator, treeSanitizer: treeSanitizer));
  }

  /**
   * Adds the specified text as a text node after the last child of this
   * document fragment.
   */
  void appendText(String text) {
    this.append(new Text(text));
  }


  /**
   * Parses the specified text as HTML and adds the resulting node after the
   * last child of this document fragment.
   */
  void appendHtml(String text, {NodeValidator validator,
      NodeTreeSanitizer, treeSanitizer}) {
    this.append(new DocumentFragment.html(text, validator: validator,
        treeSanitizer: treeSanitizer));
  }

  /** 
   * Alias for [querySelector]. Note this function is deprecated because its
   * semantics will be changing in the future.
   */
  @deprecated
  @Experimental()
  @DomName('DocumentFragment.querySelector')
  Element query(String relativeSelectors) {
    return querySelector(relativeSelectors);
  }

  /** 
   * Alias for [querySelectorAll]. Note this function is deprecated because its
   * semantics will be changing in the future.
   */
  @deprecated
  @Experimental()
  @DomName('DocumentFragment.querySelectorAll')
  ElementList<Element> queryAll(String relativeSelectors) {
    return querySelectorAll(relativeSelectors);
  }
  // To suppress missing implicit constructor warnings.
  factory DocumentFragment._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  static DocumentFragment internalCreateDocumentFragment() {
    return new DocumentFragment._internalWrap();
  }

  external factory DocumentFragment._internalWrap();

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


  @DomName('DocumentFragment.getElementById')
  @DocsEditable()
  @Experimental() // untriaged
  Element getElementById(String elementId) => wrap_jso(_blink.BlinkDocumentFragment.instance.getElementById_Callback_1_(unwrap_jso(this), elementId));
  
  @DomName('DocumentFragment.childElementCount')
  @DocsEditable()
  int get _childElementCount => _blink.BlinkDocumentFragment.instance.childElementCount_Getter_(unwrap_jso(this));
  
  @DomName('DocumentFragment.firstElementChild')
  @DocsEditable()
  Element get _firstElementChild => wrap_jso(_blink.BlinkDocumentFragment.instance.firstElementChild_Getter_(unwrap_jso(this)));
  
  @DomName('DocumentFragment.lastElementChild')
  @DocsEditable()
  Element get _lastElementChild => wrap_jso(_blink.BlinkDocumentFragment.instance.lastElementChild_Getter_(unwrap_jso(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) => wrap_jso(_blink.BlinkDocumentFragment.instance.querySelector_Callback_1_(unwrap_jso(this), selectors));
  
  @DomName('DocumentFragment.querySelectorAll')
  @DocsEditable()
  List<Node> _querySelectorAll(String selectors) => wrap_jso(_blink.BlinkDocumentFragment.instance.querySelectorAll_Callback_1_(unwrap_jso(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 wrap_jso(_blink.BlinkDOMError.instance.constructorCallback_2_(name, message));
  }

  @Deprecated("Internal Use Only")
  static DomError internalCreateDomError() {
    return new DomError._internalWrap();
  }

  factory DomError._internalWrap() {
    return new DomError.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  @DomName('DOMError.message')
  @DocsEditable()
  @Experimental() // untriaged
  String get message => _blink.BlinkDOMError.instance.message_Getter_(unwrap_jso(this));
  
  @DomName('DOMError.name')
  @DocsEditable()
  String get name => _blink.BlinkDOMError.instance.name_Getter_(unwrap_jso(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")
  static DomImplementation internalCreateDomImplementation() {
    return new DomImplementation._internalWrap();
  }

  factory DomImplementation._internalWrap() {
    return new DomImplementation.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  @DomName('DOMImplementation.createDocument')
  @DocsEditable()
  XmlDocument createDocument(String namespaceURI, String qualifiedName, _DocumentType doctype) => wrap_jso(_blink.BlinkDOMImplementation.instance.createDocument_Callback_3_(unwrap_jso(this), namespaceURI, qualifiedName, unwrap_jso(doctype)));
  
  @DomName('DOMImplementation.createDocumentType')
  @DocsEditable()
  _DocumentType createDocumentType(String qualifiedName, String publicId, String systemId) => wrap_jso(_blink.BlinkDOMImplementation.instance.createDocumentType_Callback_3_(unwrap_jso(this), qualifiedName, publicId, systemId));
  
  @DomName('DOMImplementation.createHTMLDocument')
  @DocsEditable()
  HtmlDocument createHtmlDocument(String title) => wrap_jso(_blink.BlinkDOMImplementation.instance.createHTMLDocument_Callback_1_(unwrap_jso(this), title));
  
  @DomName('DOMImplementation.hasFeature')
  @DocsEditable()
  bool hasFeature() => _blink.BlinkDOMImplementation.instance.hasFeature_Callback_0_(unwrap_jso(this));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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")
  static DomIterator internalCreateDomIterator() {
    return new DomIterator._internalWrap();
  }

  factory DomIterator._internalWrap() {
    return new DomIterator.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  Object next([Object value]) {
    if (value != null) {
      return wrap_jso(_blink.BlinkIterator.instance.next_Callback_1_(unwrap_jso(this), value));
    }
    return wrap_jso(_blink.BlinkIterator.instance.next_Callback_0_(unwrap_jso(this)));
  }

}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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 wrap_jso(_blink.BlinkDOMMatrix.instance.constructorCallback_0_());
    }
    if ((other is DomMatrixReadOnly || other == null)) {
      return wrap_jso(_blink.BlinkDOMMatrix.instance.constructorCallback_1_(other));
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }


  @Deprecated("Internal Use Only")
  static DomMatrix internalCreateDomMatrix() {
    return new DomMatrix._internalWrap();
  }

  external factory DomMatrix._internalWrap();

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


  @DomName('DOMMatrix.a')
  @DocsEditable()
  @Experimental() // untriaged
  num get a => _blink.BlinkDOMMatrix.instance.a_Getter_(unwrap_jso(this));
  
  @DomName('DOMMatrix.a')
  @DocsEditable()
  @Experimental() // untriaged
  set a(num value) => _blink.BlinkDOMMatrix.instance.a_Setter_(unwrap_jso(this), value);
  
  @DomName('DOMMatrix.b')
  @DocsEditable()
  @Experimental() // untriaged
  num get b => _blink.BlinkDOMMatrix.instance.b_Getter_(unwrap_jso(this));
  
  @DomName('DOMMatrix.b')
  @DocsEditable()
  @Experimental() // untriaged
  set b(num value) => _blink.BlinkDOMMatrix.instance.b_Setter_(unwrap_jso(this), value);
  
  @DomName('DOMMatrix.c')
  @DocsEditable()
  @Experimental() // untriaged
  num get c => _blink.BlinkDOMMatrix.instance.c_Getter_(unwrap_jso(this));
  
  @DomName('DOMMatrix.c')
  @DocsEditable()
  @Experimental() // untriaged
  set c(num value) => _blink.BlinkDOMMatrix.instance.c_Setter_(unwrap_jso(this), value);
  
  @DomName('DOMMatrix.d')
  @DocsEditable()
  @Experimental() // untriaged
  num get d => _blink.BlinkDOMMatrix.instance.d_Getter_(unwrap_jso(this));
  
  @DomName('DOMMatrix.d')
  @DocsEditable()
  @Experimental() // untriaged
  set d(num value) => _blink.BlinkDOMMatrix.instance.d_Setter_(unwrap_jso(this), value);
  
  @DomName('DOMMatrix.e')
  @DocsEditable()
  @Experimental() // untriaged
  num get e => _blink.BlinkDOMMatrix.instance.e_Getter_(unwrap_jso(this));
  
  @DomName('DOMMatrix.e')
  @DocsEditable()
  @Experimental() // untriaged
  set e(num value) => _blink.BlinkDOMMatrix.instance.e_Setter_(unwrap_jso(this), value);
  
  @DomName('DOMMatrix.f')
  @DocsEditable()
  @Experimental() // untriaged
  num get f => _blink.BlinkDOMMatrix.instance.f_Getter_(unwrap_jso(this));
  
  @DomName('DOMMatrix.f')
  @DocsEditable()
  @Experimental() // untriaged
  set f(num value) => _blink.BlinkDOMMatrix.instance.f_Setter_(unwrap_jso(this), value);
  
  @DomName('DOMMatrix.m11')
  @DocsEditable()
  @Experimental() // untriaged
  num get m11 => _blink.BlinkDOMMatrix.instance.m11_Getter_(unwrap_jso(this));
  
  @DomName('DOMMatrix.m11')
  @DocsEditable()
  @Experimental() // untriaged
  set m11(num value) => _blink.BlinkDOMMatrix.instance.m11_Setter_(unwrap_jso(this), value);
  
  @DomName('DOMMatrix.m12')
  @DocsEditable()
  @Experimental() // untriaged
  num get m12 => _blink.BlinkDOMMatrix.instance.m12_Getter_(unwrap_jso(this));
  
  @DomName('DOMMatrix.m12')
  @DocsEditable()
  @Experimental() // untriaged
  set m12(num value) => _blink.BlinkDOMMatrix.instance.m12_Setter_(unwrap_jso(this), value);
  
  @DomName('DOMMatrix.m13')
  @DocsEditable()
  @Experimental() // untriaged
  num get m13 => _blink.BlinkDOMMatrix.instance.m13_Getter_(unwrap_jso(this));
  
  @DomName('DOMMatrix.m13')
  @DocsEditable()
  @Experimental() // untriaged
  set m13(num value) => _blink.BlinkDOMMatrix.instance.m13_Setter_(unwrap_jso(this), value);
  
  @DomName('DOMMatrix.m14')
  @DocsEditable()
  @Experimental() // untriaged
  num get m14 => _blink.BlinkDOMMatrix.instance.m14_Getter_(unwrap_jso(this));
  
  @DomName('DOMMatrix.m14')
  @DocsEditable()
  @Experimental() // untriaged
  set m14(num value) => _blink.BlinkDOMMatrix.instance.m14_Setter_(unwrap_jso(this), value);
  
  @DomName('DOMMatrix.m21')
  @DocsEditable()
  @Experimental() // untriaged
  num get m21 => _blink.BlinkDOMMatrix.instance.m21_Getter_(unwrap_jso(this));
  
  @DomName('DOMMatrix.m21')
  @DocsEditable()
  @Experimental() // untriaged
  set m21(num value) => _blink.BlinkDOMMatrix.instance.m21_Setter_(unwrap_jso(this), value);
  
  @DomName('DOMMatrix.m22')
  @DocsEditable()
  @Experimental() // untriaged
  num get m22 => _blink.BlinkDOMMatrix.instance.m22_Getter_(unwrap_jso(this));
  
  @DomName('DOMMatrix.m22')
  @DocsEditable()
  @Experimental() // untriaged
  set m22(num value) => _blink.BlinkDOMMatrix.instance.m22_Setter_(unwrap_jso(this), value);
  
  @DomName('DOMMatrix.m23')
  @DocsEditable()
  @Experimental() // untriaged
  num get m23 => _blink.BlinkDOMMatrix.instance.m23_Getter_(unwrap_jso(this));
  
  @DomName('DOMMatrix.m23')
  @DocsEditable()
  @Experimental() // untriaged
  set m23(num value) => _blink.BlinkDOMMatrix.instance.m23_Setter_(unwrap_jso(this), value);
  
  @DomName('DOMMatrix.m24')
  @DocsEditable()
  @Experimental() // untriaged
  num get m24 => _blink.BlinkDOMMatrix.instance.m24_Getter_(unwrap_jso(this));
  
  @DomName('DOMMatrix.m24')
  @DocsEditable()
  @Experimental() // untriaged
  set m24(num value) => _blink.BlinkDOMMatrix.instance.m24_Setter_(unwrap_jso(this), value);
  
  @DomName('DOMMatrix.m31')
  @DocsEditable()
  @Experimental() // untriaged
  num get m31 => _blink.BlinkDOMMatrix.instance.m31_Getter_(unwrap_jso(this));
  
  @DomName('DOMMatrix.m31')
  @DocsEditable()
  @Experimental() // untriaged
  set m31(num value) => _blink.BlinkDOMMatrix.instance.m31_Setter_(unwrap_jso(this), value);
  
  @DomName('DOMMatrix.m32')
  @DocsEditable()
  @Experimental() // untriaged
  num get m32 => _blink.BlinkDOMMatrix.instance.m32_Getter_(unwrap_jso(this));
  
  @DomName('DOMMatrix.m32')
  @DocsEditable()
  @Experimental() // untriaged
  set m32(num value) => _blink.BlinkDOMMatrix.instance.m32_Setter_(unwrap_jso(this), value);
  
  @DomName('DOMMatrix.m33')
  @DocsEditable()
  @Experimental() // untriaged
  num get m33 => _blink.BlinkDOMMatrix.instance.m33_Getter_(unwrap_jso(this));
  
  @DomName('DOMMatrix.m33')
  @DocsEditable()
  @Experimental() // untriaged
  set m33(num value) => _blink.BlinkDOMMatrix.instance.m33_Setter_(unwrap_jso(this), value);
  
  @DomName('DOMMatrix.m34')
  @DocsEditable()
  @Experimental() // untriaged
  num get m34 => _blink.BlinkDOMMatrix.instance.m34_Getter_(unwrap_jso(this));
  
  @DomName('DOMMatrix.m34')
  @DocsEditable()
  @Experimental() // untriaged
  set m34(num value) => _blink.BlinkDOMMatrix.instance.m34_Setter_(unwrap_jso(this), value);
  
  @DomName('DOMMatrix.m41')
  @DocsEditable()
  @Experimental() // untriaged
  num get m41 => _blink.BlinkDOMMatrix.instance.m41_Getter_(unwrap_jso(this));
  
  @DomName('DOMMatrix.m41')
  @DocsEditable()
  @Experimental() // untriaged
  set m41(num value) => _blink.BlinkDOMMatrix.instance.m41_Setter_(unwrap_jso(this), value);
  
  @DomName('DOMMatrix.m42')
  @DocsEditable()
  @Experimental() // untriaged
  num get m42 => _blink.BlinkDOMMatrix.instance.m42_Getter_(unwrap_jso(this));
  
  @DomName('DOMMatrix.m42')
  @DocsEditable()
  @Experimental() // untriaged
  set m42(num value) => _blink.BlinkDOMMatrix.instance.m42_Setter_(unwrap_jso(this), value);
  
  @DomName('DOMMatrix.m43')
  @DocsEditable()
  @Experimental() // untriaged
  num get m43 => _blink.BlinkDOMMatrix.instance.m43_Getter_(unwrap_jso(this));
  
  @DomName('DOMMatrix.m43')
  @DocsEditable()
  @Experimental() // untriaged
  set m43(num value) => _blink.BlinkDOMMatrix.instance.m43_Setter_(unwrap_jso(this), value);
  
  @DomName('DOMMatrix.m44')
  @DocsEditable()
  @Experimental() // untriaged
  num get m44 => _blink.BlinkDOMMatrix.instance.m44_Getter_(unwrap_jso(this));
  
  @DomName('DOMMatrix.m44')
  @DocsEditable()
  @Experimental() // untriaged
  set m44(num value) => _blink.BlinkDOMMatrix.instance.m44_Setter_(unwrap_jso(this), value);
  
  @DomName('DOMMatrix.multiplySelf')
  @DocsEditable()
  @Experimental() // untriaged
  DomMatrix multiplySelf(DomMatrix other) => wrap_jso(_blink.BlinkDOMMatrix.instance.multiplySelf_Callback_1_(unwrap_jso(this), unwrap_jso(other)));
  
  @DomName('DOMMatrix.preMultiplySelf')
  @DocsEditable()
  @Experimental() // untriaged
  DomMatrix preMultiplySelf(DomMatrix other) => wrap_jso(_blink.BlinkDOMMatrix.instance.preMultiplySelf_Callback_1_(unwrap_jso(this), unwrap_jso(other)));
  
  DomMatrix scale3dSelf(num scale, [num originX, num originY, num originZ]) {
    if (originZ != null) {
      return wrap_jso(_blink.BlinkDOMMatrix.instance.scale3dSelf_Callback_4_(unwrap_jso(this), scale, originX, originY, originZ));
    }
    if (originY != null) {
      return wrap_jso(_blink.BlinkDOMMatrix.instance.scale3dSelf_Callback_3_(unwrap_jso(this), scale, originX, originY));
    }
    if (originX != null) {
      return wrap_jso(_blink.BlinkDOMMatrix.instance.scale3dSelf_Callback_2_(unwrap_jso(this), scale, originX));
    }
    return wrap_jso(_blink.BlinkDOMMatrix.instance.scale3dSelf_Callback_1_(unwrap_jso(this), scale));
  }

  DomMatrix scaleNonUniformSelf(num scaleX, [num scaleY, num scaleZ, num originX, num originY, num originZ]) {
    if (originZ != null) {
      return wrap_jso(_blink.BlinkDOMMatrix.instance.scaleNonUniformSelf_Callback_6_(unwrap_jso(this), scaleX, scaleY, scaleZ, originX, originY, originZ));
    }
    if (originY != null) {
      return wrap_jso(_blink.BlinkDOMMatrix.instance.scaleNonUniformSelf_Callback_5_(unwrap_jso(this), scaleX, scaleY, scaleZ, originX, originY));
    }
    if (originX != null) {
      return wrap_jso(_blink.BlinkDOMMatrix.instance.scaleNonUniformSelf_Callback_4_(unwrap_jso(this), scaleX, scaleY, scaleZ, originX));
    }
    if (scaleZ != null) {
      return wrap_jso(_blink.BlinkDOMMatrix.instance.scaleNonUniformSelf_Callback_3_(unwrap_jso(this), scaleX, scaleY, scaleZ));
    }
    if (scaleY != null) {
      return wrap_jso(_blink.BlinkDOMMatrix.instance.scaleNonUniformSelf_Callback_2_(unwrap_jso(this), scaleX, scaleY));
    }
    return wrap_jso(_blink.BlinkDOMMatrix.instance.scaleNonUniformSelf_Callback_1_(unwrap_jso(this), scaleX));
  }

  DomMatrix scaleSelf(num scale, [num originX, num originY]) {
    if (originY != null) {
      return wrap_jso(_blink.BlinkDOMMatrix.instance.scaleSelf_Callback_3_(unwrap_jso(this), scale, originX, originY));
    }
    if (originX != null) {
      return wrap_jso(_blink.BlinkDOMMatrix.instance.scaleSelf_Callback_2_(unwrap_jso(this), scale, originX));
    }
    return wrap_jso(_blink.BlinkDOMMatrix.instance.scaleSelf_Callback_1_(unwrap_jso(this), scale));
  }

  DomMatrix translateSelf(num tx, num ty, [num tz]) {
    if (tz != null) {
      return wrap_jso(_blink.BlinkDOMMatrix.instance.translateSelf_Callback_3_(unwrap_jso(this), tx, ty, tz));
    }
    return wrap_jso(_blink.BlinkDOMMatrix.instance.translateSelf_Callback_2_(unwrap_jso(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")
  static DomMatrixReadOnly internalCreateDomMatrixReadOnly() {
    return new DomMatrixReadOnly._internalWrap();
  }

  factory DomMatrixReadOnly._internalWrap() {
    return new DomMatrixReadOnly.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  @DomName('DOMMatrixReadOnly.a')
  @DocsEditable()
  @Experimental() // untriaged
  num get a => _blink.BlinkDOMMatrixReadOnly.instance.a_Getter_(unwrap_jso(this));
  
  @DomName('DOMMatrixReadOnly.b')
  @DocsEditable()
  @Experimental() // untriaged
  num get b => _blink.BlinkDOMMatrixReadOnly.instance.b_Getter_(unwrap_jso(this));
  
  @DomName('DOMMatrixReadOnly.c')
  @DocsEditable()
  @Experimental() // untriaged
  num get c => _blink.BlinkDOMMatrixReadOnly.instance.c_Getter_(unwrap_jso(this));
  
  @DomName('DOMMatrixReadOnly.d')
  @DocsEditable()
  @Experimental() // untriaged
  num get d => _blink.BlinkDOMMatrixReadOnly.instance.d_Getter_(unwrap_jso(this));
  
  @DomName('DOMMatrixReadOnly.e')
  @DocsEditable()
  @Experimental() // untriaged
  num get e => _blink.BlinkDOMMatrixReadOnly.instance.e_Getter_(unwrap_jso(this));
  
  @DomName('DOMMatrixReadOnly.f')
  @DocsEditable()
  @Experimental() // untriaged
  num get f => _blink.BlinkDOMMatrixReadOnly.instance.f_Getter_(unwrap_jso(this));
  
  @DomName('DOMMatrixReadOnly.is2D')
  @DocsEditable()
  @Experimental() // untriaged
  bool get is2D => _blink.BlinkDOMMatrixReadOnly.instance.is2D_Getter_(unwrap_jso(this));
  
  @DomName('DOMMatrixReadOnly.isIdentity')
  @DocsEditable()
  @Experimental() // untriaged
  bool get isIdentity => _blink.BlinkDOMMatrixReadOnly.instance.isIdentity_Getter_(unwrap_jso(this));
  
  @DomName('DOMMatrixReadOnly.m11')
  @DocsEditable()
  @Experimental() // untriaged
  num get m11 => _blink.BlinkDOMMatrixReadOnly.instance.m11_Getter_(unwrap_jso(this));
  
  @DomName('DOMMatrixReadOnly.m12')
  @DocsEditable()
  @Experimental() // untriaged
  num get m12 => _blink.BlinkDOMMatrixReadOnly.instance.m12_Getter_(unwrap_jso(this));
  
  @DomName('DOMMatrixReadOnly.m13')
  @DocsEditable()
  @Experimental() // untriaged
  num get m13 => _blink.BlinkDOMMatrixReadOnly.instance.m13_Getter_(unwrap_jso(this));
  
  @DomName('DOMMatrixReadOnly.m14')
  @DocsEditable()
  @Experimental() // untriaged
  num get m14 => _blink.BlinkDOMMatrixReadOnly.instance.m14_Getter_(unwrap_jso(this));
  
  @DomName('DOMMatrixReadOnly.m21')
  @DocsEditable()
  @Experimental() // untriaged
  num get m21 => _blink.BlinkDOMMatrixReadOnly.instance.m21_Getter_(unwrap_jso(this));
  
  @DomName('DOMMatrixReadOnly.m22')
  @DocsEditable()
  @Experimental() // untriaged
  num get m22 => _blink.BlinkDOMMatrixReadOnly.instance.m22_Getter_(unwrap_jso(this));
  
  @DomName('DOMMatrixReadOnly.m23')
  @DocsEditable()
  @Experimental() // untriaged
  num get m23 => _blink.BlinkDOMMatrixReadOnly.instance.m23_Getter_(unwrap_jso(this));
  
  @DomName('DOMMatrixReadOnly.m24')
  @DocsEditable()
  @Experimental() // untriaged
  num get m24 => _blink.BlinkDOMMatrixReadOnly.instance.m24_Getter_(unwrap_jso(this));
  
  @DomName('DOMMatrixReadOnly.m31')
  @DocsEditable()
  @Experimental() // untriaged
  num get m31 => _blink.BlinkDOMMatrixReadOnly.instance.m31_Getter_(unwrap_jso(this));
  
  @DomName('DOMMatrixReadOnly.m32')
  @DocsEditable()
  @Experimental() // untriaged
  num get m32 => _blink.BlinkDOMMatrixReadOnly.instance.m32_Getter_(unwrap_jso(this));
  
  @DomName('DOMMatrixReadOnly.m33')
  @DocsEditable()
  @Experimental() // untriaged
  num get m33 => _blink.BlinkDOMMatrixReadOnly.instance.m33_Getter_(unwrap_jso(this));
  
  @DomName('DOMMatrixReadOnly.m34')
  @DocsEditable()
  @Experimental() // untriaged
  num get m34 => _blink.BlinkDOMMatrixReadOnly.instance.m34_Getter_(unwrap_jso(this));
  
  @DomName('DOMMatrixReadOnly.m41')
  @DocsEditable()
  @Experimental() // untriaged
  num get m41 => _blink.BlinkDOMMatrixReadOnly.instance.m41_Getter_(unwrap_jso(this));
  
  @DomName('DOMMatrixReadOnly.m42')
  @DocsEditable()
  @Experimental() // untriaged
  num get m42 => _blink.BlinkDOMMatrixReadOnly.instance.m42_Getter_(unwrap_jso(this));
  
  @DomName('DOMMatrixReadOnly.m43')
  @DocsEditable()
  @Experimental() // untriaged
  num get m43 => _blink.BlinkDOMMatrixReadOnly.instance.m43_Getter_(unwrap_jso(this));
  
  @DomName('DOMMatrixReadOnly.m44')
  @DocsEditable()
  @Experimental() // untriaged
  num get m44 => _blink.BlinkDOMMatrixReadOnly.instance.m44_Getter_(unwrap_jso(this));
  
  @DomName('DOMMatrixReadOnly.multiply')
  @DocsEditable()
  @Experimental() // untriaged
  DomMatrix multiply(DomMatrix other) => wrap_jso(_blink.BlinkDOMMatrixReadOnly.instance.multiply_Callback_1_(unwrap_jso(this), unwrap_jso(other)));
  
  DomMatrix scale(num scale, [num originX, num originY]) {
    if (originY != null) {
      return wrap_jso(_blink.BlinkDOMMatrixReadOnly.instance.scale_Callback_3_(unwrap_jso(this), scale, originX, originY));
    }
    if (originX != null) {
      return wrap_jso(_blink.BlinkDOMMatrixReadOnly.instance.scale_Callback_2_(unwrap_jso(this), scale, originX));
    }
    return wrap_jso(_blink.BlinkDOMMatrixReadOnly.instance.scale_Callback_1_(unwrap_jso(this), scale));
  }

  DomMatrix scale3d(num scale, [num originX, num originY, num originZ]) {
    if (originZ != null) {
      return wrap_jso(_blink.BlinkDOMMatrixReadOnly.instance.scale3d_Callback_4_(unwrap_jso(this), scale, originX, originY, originZ));
    }
    if (originY != null) {
      return wrap_jso(_blink.BlinkDOMMatrixReadOnly.instance.scale3d_Callback_3_(unwrap_jso(this), scale, originX, originY));
    }
    if (originX != null) {
      return wrap_jso(_blink.BlinkDOMMatrixReadOnly.instance.scale3d_Callback_2_(unwrap_jso(this), scale, originX));
    }
    return wrap_jso(_blink.BlinkDOMMatrixReadOnly.instance.scale3d_Callback_1_(unwrap_jso(this), scale));
  }

  DomMatrix scaleNonUniform(num scaleX, [num scaleY, num scaleZn, num originX, num originY, num originZ]) {
    if (originZ != null) {
      return wrap_jso(_blink.BlinkDOMMatrixReadOnly.instance.scaleNonUniform_Callback_6_(unwrap_jso(this), scaleX, scaleY, scaleZn, originX, originY, originZ));
    }
    if (originY != null) {
      return wrap_jso(_blink.BlinkDOMMatrixReadOnly.instance.scaleNonUniform_Callback_5_(unwrap_jso(this), scaleX, scaleY, scaleZn, originX, originY));
    }
    if (originX != null) {
      return wrap_jso(_blink.BlinkDOMMatrixReadOnly.instance.scaleNonUniform_Callback_4_(unwrap_jso(this), scaleX, scaleY, scaleZn, originX));
    }
    if (scaleZn != null) {
      return wrap_jso(_blink.BlinkDOMMatrixReadOnly.instance.scaleNonUniform_Callback_3_(unwrap_jso(this), scaleX, scaleY, scaleZn));
    }
    if (scaleY != null) {
      return wrap_jso(_blink.BlinkDOMMatrixReadOnly.instance.scaleNonUniform_Callback_2_(unwrap_jso(this), scaleX, scaleY));
    }
    return wrap_jso(_blink.BlinkDOMMatrixReadOnly.instance.scaleNonUniform_Callback_1_(unwrap_jso(this), scaleX));
  }

  @DomName('DOMMatrixReadOnly.toFloat32Array')
  @DocsEditable()
  @Experimental() // untriaged
  Float32List toFloat32Array() => wrap_jso(_blink.BlinkDOMMatrixReadOnly.instance.toFloat32Array_Callback_0_(unwrap_jso(this)));
  
  @DomName('DOMMatrixReadOnly.toFloat64Array')
  @DocsEditable()
  @Experimental() // untriaged
  Float64List toFloat64Array() => wrap_jso(_blink.BlinkDOMMatrixReadOnly.instance.toFloat64Array_Callback_0_(unwrap_jso(this)));
  
  DomMatrix translate(num tx, num ty, [num tz]) {
    if (tz != null) {
      return wrap_jso(_blink.BlinkDOMMatrixReadOnly.instance.translate_Callback_3_(unwrap_jso(this), tx, ty, tz));
    }
    return wrap_jso(_blink.BlinkDOMMatrixReadOnly.instance.translate_Callback_2_(unwrap_jso(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 wrap_jso(_blink.BlinkDOMParser.instance.constructorCallback_0_());
  }

  @Deprecated("Internal Use Only")
  static DomParser internalCreateDomParser() {
    return new DomParser._internalWrap();
  }

  factory DomParser._internalWrap() {
    return new DomParser.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  @DomName('DOMParser.parseFromString')
  @DocsEditable()
  Document parseFromString(String str, String type) => wrap_jso(_blink.BlinkDOMParser.instance.parseFromString_Callback_2_(unwrap_jso(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 wrap_jso(_blink.BlinkDOMPoint.instance.constructorCallback_1_(point_1));
    }
    if (point_OR_x == null && y == null && z == null && w == null) {
      return wrap_jso(_blink.BlinkDOMPoint.instance.constructorCallback_0_());
    }
    if ((point_OR_x is num || point_OR_x == null) && y == null && z == null && w == null) {
      return wrap_jso(_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 wrap_jso(_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 wrap_jso(_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 wrap_jso(_blink.BlinkDOMPoint.instance.constructorCallback_4_(point_OR_x, y, z, w));
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }


  @Deprecated("Internal Use Only")
  static DomPoint internalCreateDomPoint() {
    return new DomPoint._internalWrap();
  }

  external factory DomPoint._internalWrap();

  @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_(unwrap_jso(this));
  
  @DomName('DOMPoint.w')
  @DocsEditable()
  @Experimental() // untriaged
  set w(num value) => _blink.BlinkDOMPoint.instance.w_Setter_(unwrap_jso(this), value);
  
  @DomName('DOMPoint.x')
  @DocsEditable()
  @Experimental() // untriaged
  num get x => _blink.BlinkDOMPoint.instance.x_Getter_(unwrap_jso(this));
  
  @DomName('DOMPoint.x')
  @DocsEditable()
  @Experimental() // untriaged
  set x(num value) => _blink.BlinkDOMPoint.instance.x_Setter_(unwrap_jso(this), value);
  
  @DomName('DOMPoint.y')
  @DocsEditable()
  @Experimental() // untriaged
  num get y => _blink.BlinkDOMPoint.instance.y_Getter_(unwrap_jso(this));
  
  @DomName('DOMPoint.y')
  @DocsEditable()
  @Experimental() // untriaged
  set y(num value) => _blink.BlinkDOMPoint.instance.y_Setter_(unwrap_jso(this), value);
  
  @DomName('DOMPoint.z')
  @DocsEditable()
  @Experimental() // untriaged
  num get z => _blink.BlinkDOMPoint.instance.z_Getter_(unwrap_jso(this));
  
  @DomName('DOMPoint.z')
  @DocsEditable()
  @Experimental() // untriaged
  set z(num value) => _blink.BlinkDOMPoint.instance.z_Setter_(unwrap_jso(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 wrap_jso(_blink.BlinkDOMPointReadOnly.instance.constructorCallback_4_(x, y, z, w));
  }

  @Deprecated("Internal Use Only")
  static DomPointReadOnly internalCreateDomPointReadOnly() {
    return new DomPointReadOnly._internalWrap();
  }

  factory DomPointReadOnly._internalWrap() {
    return new DomPointReadOnly.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  @DomName('DOMPointReadOnly.w')
  @DocsEditable()
  @Experimental() // untriaged
  num get w => _blink.BlinkDOMPointReadOnly.instance.w_Getter_(unwrap_jso(this));
  
  @DomName('DOMPointReadOnly.x')
  @DocsEditable()
  @Experimental() // untriaged
  num get x => _blink.BlinkDOMPointReadOnly.instance.x_Getter_(unwrap_jso(this));
  
  @DomName('DOMPointReadOnly.y')
  @DocsEditable()
  @Experimental() // untriaged
  num get y => _blink.BlinkDOMPointReadOnly.instance.y_Getter_(unwrap_jso(this));
  
  @DomName('DOMPointReadOnly.z')
  @DocsEditable()
  @Experimental() // untriaged
  num get z => _blink.BlinkDOMPointReadOnly.instance.z_Getter_(unwrap_jso(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 wrap_jso(_blink.BlinkDOMRectReadOnly.instance.constructorCallback_4_(x, y, width, height));
  }

  @Deprecated("Internal Use Only")
  static DomRectReadOnly internalCreateDomRectReadOnly() {
    return new DomRectReadOnly._internalWrap();
  }

  factory DomRectReadOnly._internalWrap() {
    return new DomRectReadOnly.internal_();
  }

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


  @DomName('DOMRectReadOnly.bottom')
  @DocsEditable()
  @Experimental() // untriaged
  num get bottom => _blink.BlinkDOMRectReadOnly.instance.bottom_Getter_(unwrap_jso(this));
  
  @DomName('DOMRectReadOnly.height')
  @DocsEditable()
  @Experimental() // untriaged
  num get height => _blink.BlinkDOMRectReadOnly.instance.height_Getter_(unwrap_jso(this));
  
  @DomName('DOMRectReadOnly.left')
  @DocsEditable()
  @Experimental() // untriaged
  num get left => _blink.BlinkDOMRectReadOnly.instance.left_Getter_(unwrap_jso(this));
  
  @DomName('DOMRectReadOnly.right')
  @DocsEditable()
  @Experimental() // untriaged
  num get right => _blink.BlinkDOMRectReadOnly.instance.right_Getter_(unwrap_jso(this));
  
  @DomName('DOMRectReadOnly.top')
  @DocsEditable()
  @Experimental() // untriaged
  num get top => _blink.BlinkDOMRectReadOnly.instance.top_Getter_(unwrap_jso(this));
  
  @DomName('DOMRectReadOnly.width')
  @DocsEditable()
  @Experimental() // untriaged
  num get width => _blink.BlinkDOMRectReadOnly.instance.width_Getter_(unwrap_jso(this));
  
  @DomName('DOMRectReadOnly.x')
  @DocsEditable()
  @Experimental() // untriaged
  num get x => _blink.BlinkDOMRectReadOnly.instance.x_Getter_(unwrap_jso(this));
  
  @DomName('DOMRectReadOnly.y')
  @DocsEditable()
  @Experimental() // untriaged
  num get y => _blink.BlinkDOMRectReadOnly.instance.y_Getter_(unwrap_jso(this));
  }

// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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")
  static DomSettableTokenList internalCreateDomSettableTokenList() {
    return new DomSettableTokenList._internalWrap();
  }

  external factory DomSettableTokenList._internalWrap();

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


  @DomName('DOMSettableTokenList.value')
  @DocsEditable()
  String get value => _blink.BlinkDOMSettableTokenList.instance.value_Getter_(unwrap_jso(this));
  
  @DomName('DOMSettableTokenList.value')
  @DocsEditable()
  set value(String value) => _blink.BlinkDOMSettableTokenList.instance.value_Setter_(unwrap_jso(this), value);
  
  @DomName('DOMSettableTokenList.item')
  @DocsEditable()
  @Experimental() // untriaged
  String item(int index) => _blink.BlinkDOMSettableTokenList.instance.item_Callback_1_(unwrap_jso(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")
  static DomStringList internalCreateDomStringList() {
    return new DomStringList._internalWrap();
  }

  factory DomStringList._internalWrap() {
    return new DomStringList.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  @DomName('DOMStringList.length')
  @DocsEditable()
  int get length => _blink.BlinkDOMStringList.instance.length_Getter_(unwrap_jso(this));
  
  String operator[](int index) {
    if (index < 0 || index >= length)
      throw new RangeError.index(index, this);
    return _blink.BlinkDOMStringList.instance.item_Callback_1_(unwrap_jso(this), index);
  }

  String _nativeIndexedGetter(int index) => _blink.BlinkDOMStringList.instance.item_Callback_1_(unwrap_jso(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_(unwrap_jso(this), index);
  
  @DomName('DOMStringList.contains')
  @DocsEditable()
  bool contains(String string) => _blink.BlinkDOMStringList.instance.contains_Callback_1_(unwrap_jso(this), string);
  
  @DomName('DOMStringList.item')
  @DocsEditable()
  String item(int index) => _blink.BlinkDOMStringList.instance.item_Callback_1_(unwrap_jso(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"); }

  void __delete__(index_OR_name) {
    if ((index_OR_name is String || index_OR_name == null)) {
      _blink.BlinkDOMStringMap.instance.$__delete___Callback_1_(unwrap_jso(this), unwrap_jso(index_OR_name));
      return;
    }
    if ((index_OR_name is int || index_OR_name == null)) {
      _blink.BlinkDOMStringMap.instance.$__delete___Callback_1_(unwrap_jso(this), unwrap_jso(index_OR_name));
      return;
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }

  @DomName('DOMStringMap.__getter__')
  @DocsEditable()
  String __getter__(int 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_(unwrap_jso(this), unwrap_jso(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_(unwrap_jso(this), unwrap_jso(index_OR_name), value);
      return;
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }

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

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

// WARNING: Do not edit - generated code.


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

  @Deprecated("Internal Use Only")
  static DomTokenList internalCreateDomTokenList() {
    return new DomTokenList._internalWrap();
  }

  factory DomTokenList._internalWrap() {
    return new DomTokenList.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  @DomName('DOMTokenList.length')
  @DocsEditable()
  int get length => _blink.BlinkDOMTokenList.instance.length_Getter_(unwrap_jso(this));
  
  @DomName('DOMTokenList.add')
  @DocsEditable()
  @Experimental() // untriaged
  void add(String tokens) => _blink.BlinkDOMTokenList.instance.add_Callback_1_(unwrap_jso(this), tokens);
  
  @DomName('DOMTokenList.contains')
  @DocsEditable()
  bool contains(String token) => _blink.BlinkDOMTokenList.instance.contains_Callback_1_(unwrap_jso(this), token);
  
  @DomName('DOMTokenList.item')
  @DocsEditable()
  String item(int index) => _blink.BlinkDOMTokenList.instance.item_Callback_1_(unwrap_jso(this), index);
  
  @DomName('DOMTokenList.remove')
  @DocsEditable()
  @Experimental() // untriaged
  void remove(String tokens) => _blink.BlinkDOMTokenList.instance.remove_Callback_1_(unwrap_jso(this), tokens);
  
  bool toggle(String token, [bool force]) {
    if (force != null) {
      return _blink.BlinkDOMTokenList.instance.toggle_Callback_2_(unwrap_jso(this), token, force);
    }
    return _blink.BlinkDOMTokenList.instance.toggle_Callback_1_(unwrap_jso(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")
  static EffectModel internalCreateEffectModel() {
    return new EffectModel._internalWrap();
  }

  factory EffectModel._internalWrap() {
    return new EffectModel.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

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


class _ChildrenElementList extends ListBase<Element>
    implements NodeListWrapper {
  // Raw Element.
  final Element _element;
  final HtmlCollection _childElements;

  _ChildrenElementList._wrap(Element element)
    : _childElements = element._children,
      _element = element;

  bool contains(Object element) => _childElements.contains(element);


  bool get isEmpty {
    return _element._firstElementChild == null;
  }

  int get length {
    return _childElements.length;
  }

  Element operator [](int index) {
    return _childElements[index];
  }

  void operator []=(int index, Element value) {
    _element._replaceChild(value, _childElements[index]);
  }

  set length(int newLength) {
    // TODO(jacobr): remove children when length is reduced.
    throw new UnsupportedError('Cannot resize element lists');
  }

  Element add(Element value) {
    _element.append(value);
    return value;
  }

  Iterator<Element> get iterator => toList().iterator;

  void addAll(Iterable<Element> iterable) {
    if (iterable is _ChildNodeListLazy) {
      iterable = new List.from(iterable);
    }

    for (Element element in iterable) {
      _element.append(element);
    }
  }

  void sort([int compare(Element a, Element b)]) {
    throw new UnsupportedError('Cannot sort element lists');
  }

  void shuffle([Random random]) {
    throw new UnsupportedError('Cannot shuffle element lists');
  }

  void removeWhere(bool test(Element element)) {
    _filter(test, false);
  }

  void retainWhere(bool test(Element element)) {
    _filter(test, true);
  }

  void _filter(bool test(var element), bool retainMatching) {
    var removed;
    if (retainMatching) {
      removed = _element.children.where((e) => !test(e));
    } else {
      removed = _element.children.where(test);
    }
    for (var e in removed) e.remove();
  }

  void setRange(int start, int end, Iterable<Element> iterable,
                [int skipCount = 0]) {
    throw new UnimplementedError();
  }

  void replaceRange(int start, int end, Iterable<Element> iterable) {
    throw new UnimplementedError();
  }

  void fillRange(int start, int end, [Element fillValue]) {
    throw new UnimplementedError();
  }

  bool remove(Object object) {
    if (object is Element) {
      Element element = object;
      // 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 extends ListBase
    implements ElementList, NodeListWrapper {
  final List<Node> _nodeList;

  var dartClass_instance;

  _FrozenElementList._wrap(this._nodeList) {
      this.dartClass_instance = this._nodeList;
  }

  int get length => _nodeList.length;

  Element operator [](int index) => _nodeList[index];

  void operator []=(int index, Element value) {
    throw new UnsupportedError('Cannot modify list');
  }

  set length(int newLength) {
    throw new UnsupportedError('Cannot modify list');
  }

  void sort([Comparator<Element> compare]) {
    throw new UnsupportedError('Cannot sort list');
  }

  void shuffle([Random random]) {
    throw new UnsupportedError('Cannot shuffle list');
  }

  Element get first => _nodeList.first;

  Element get last => _nodeList.last;

  Element get single => _nodeList.single;

  CssClassSet get classes => new _MultiElementCssClassSet(this);

  CssStyleDeclarationBase get style =>
      new _CssStyleDeclarationSet(this);

  set classes(Iterable<String> value) {
    // TODO(sra): This might be faster for Sets:
    //
    //     new _MultiElementCssClassSet(this).writeClasses(value)
    //
    // as the code below converts the Iterable[value] to a string multiple
    // times.  Maybe compute the string and set className here.
    _nodeList.forEach((e) => e.classes = value);
  }

  CssRect get contentEdge => new _ContentCssListRect(this);

  CssRect get paddingEdge => this.first.paddingEdge;

  CssRect get borderEdge => this.first.borderEdge;

  CssRect get marginEdge => this.first.marginEdge;

  List<Node> get rawList => _nodeList;


  /// Stream of `abort` events handled by this [Element].
  @DomName('Element.onabort')
  @DocsEditable()
  ElementStream<Event> get onAbort => Element.abortEvent._forElementList(this);

  /// Stream of `beforecopy` events handled by this [Element].
  @DomName('Element.onbeforecopy')
  @DocsEditable()
  ElementStream<Event> get onBeforeCopy => Element.beforeCopyEvent._forElementList(this);

  /// Stream of `beforecut` events handled by this [Element].
  @DomName('Element.onbeforecut')
  @DocsEditable()
  ElementStream<Event> get onBeforeCut => Element.beforeCutEvent._forElementList(this);

  /// Stream of `beforepaste` events handled by this [Element].
  @DomName('Element.onbeforepaste')
  @DocsEditable()
  ElementStream<Event> get onBeforePaste => Element.beforePasteEvent._forElementList(this);

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

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

  @DomName('Element.oncanplaythrough')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onCanPlayThrough => Element.canPlayThroughEvent._forElementList(this);

  /// Stream of `change` events handled by this [Element].
  @DomName('Element.onchange')
  @DocsEditable()
  ElementStream<Event> get onChange => Element.changeEvent._forElementList(this);

  /// Stream of `click` events handled by this [Element].
  @DomName('Element.onclick')
  @DocsEditable()
  ElementStream<MouseEvent> get onClick => Element.clickEvent._forElementList(this);

  /// Stream of `contextmenu` events handled by this [Element].
  @DomName('Element.oncontextmenu')
  @DocsEditable()
  ElementStream<MouseEvent> get onContextMenu => Element.contextMenuEvent._forElementList(this);

  /// Stream of `copy` events handled by this [Element].
  @DomName('Element.oncopy')
  @DocsEditable()
  ElementStream<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();

  /**
   * Creates the HTML element specified by the tag name.
   *
   * This is similar to [Document.createElement].
   * [tag] should be a valid HTML tag name. If [tag] is an unknown tag then
   * this will create an [UnknownElement].
   *
   *     var divElement = new Element.tag('div');
   *     print(divElement is DivElement); // 'true'
   *     var myElement = new Element.tag('unknownTag');
   *     print(myElement is UnknownElement); // 'true'
   *
   * For standard elements it is more preferable to use the type constructors:
   *     var element = new DivElement();
   *
   * See also:
   *
   * * [isTagSupported]
   */
  factory Element.tag(String tag, [String typeExtention]) =>
      _ElementFactoryProvider.createElement_tag(tag, typeExtention);

  /// Creates a new `<a>` element.
  ///
  /// This is identical to calling `new Element.tag('a')`.
  factory Element.a() => new Element.tag('a');

  /// Creates a new `<article>` element.
  ///
  /// This is identical to calling `new Element.tag('article')`.
  factory Element.article() => new Element.tag('article');

  /// Creates a new `<aside>` element.
  ///
  /// This is identical to calling `new Element.tag('aside')`.
  factory Element.aside() => new Element.tag('aside');

  /// Creates a new `<audio>` element.
  ///
  /// This is identical to calling `new Element.tag('audio')`.
  factory Element.audio() => new Element.tag('audio');

  /// Creates a new `<br>` element.
  ///
  /// This is identical to calling `new Element.tag('br')`.
  factory Element.br() => new Element.tag('br');

  /// Creates a new `<canvas>` element.
  ///
  /// This is identical to calling `new Element.tag('canvas')`.
  factory Element.canvas() => new Element.tag('canvas');

  /// Creates a new `<div>` element.
  ///
  /// This is identical to calling `new Element.tag('div')`.
  factory Element.div() => new Element.tag('div');

  /// Creates a new `<footer>` element.
  ///
  /// This is identical to calling `new Element.tag('footer')`.
  factory Element.footer() => new Element.tag('footer');

  /// Creates a new `<header>` element.
  ///
  /// This is identical to calling `new Element.tag('header')`.
  factory Element.header() => new Element.tag('header');

  /// Creates a new `<hr>` element.
  ///
  /// This is identical to calling `new Element.tag('hr')`.
  factory Element.hr() => new Element.tag('hr');

  /// Creates a new `<iframe>` element.
  ///
  /// This is identical to calling `new Element.tag('iframe')`.
  factory Element.iframe() => new Element.tag('iframe');

  /// Creates a new `<img>` element.
  ///
  /// This is identical to calling `new Element.tag('img')`.
  factory Element.img() => new Element.tag('img');

  /// Creates a new `<li>` element.
  ///
  /// This is identical to calling `new Element.tag('li')`.
  factory Element.li() => new Element.tag('li');

  /// Creates a new `<nav>` element.
  ///
  /// This is identical to calling `new Element.tag('nav')`.
  factory Element.nav() => new Element.tag('nav');

  /// Creates a new `<ol>` element.
  ///
  /// This is identical to calling `new Element.tag('ol')`.
  factory Element.ol() => new Element.tag('ol');

  /// Creates a new `<option>` element.
  ///
  /// This is identical to calling `new Element.tag('option')`.
  factory Element.option() => new Element.tag('option');

  /// Creates a new `<p>` element.
  ///
  /// This is identical to calling `new Element.tag('p')`.
  factory Element.p() => new Element.tag('p');

  /// Creates a new `<pre>` element.
  ///
  /// This is identical to calling `new Element.tag('pre')`.
  factory Element.pre() => new Element.tag('pre');

  /// Creates a new `<section>` element.
  ///
  /// This is identical to calling `new Element.tag('section')`.
  factory Element.section() => new Element.tag('section');

  /// Creates a new `<select>` element.
  ///
  /// This is identical to calling `new Element.tag('select')`.
  factory Element.select() => new Element.tag('select');

  /// Creates a new `<span>` element.
  ///
  /// This is identical to calling `new Element.tag('span')`.
  factory Element.span() => new Element.tag('span');

  /// Creates a new `<svg>` element.
  ///
  /// This is identical to calling `new Element.tag('svg')`.
  factory Element.svg() => new Element.tag('svg');

  /// Creates a new `<table>` element.
  ///
  /// This is identical to calling `new Element.tag('table')`.
  factory Element.table() => new Element.tag('table');

  /// Creates a new `<td>` element.
  ///
  /// This is identical to calling `new Element.tag('td')`.
  factory Element.td() => new Element.tag('td');

  /// Creates a new `<textarea>` element.
  ///
  /// This is identical to calling `new Element.tag('textarea')`.
  factory Element.textarea() => new Element.tag('textarea');

  /// Creates a new `<th>` element.
  ///
  /// This is identical to calling `new Element.tag('th')`.
  factory Element.th() => new Element.tag('th');

  /// Creates a new `<tr>` element.
  ///
  /// This is identical to calling `new Element.tag('tr')`.
  factory Element.tr() => new Element.tag('tr');

  /// Creates a new `<ul>` element.
  ///
  /// This is identical to calling `new Element.tag('ul')`.
  factory Element.ul() => new Element.tag('ul');

  /// Creates a new `<video>` element.
  ///
  /// This is identical to calling `new Element.tag('video')`.
  factory Element.video() => new Element.tag('video');

  /**
   * All attributes on this element.
   *
   * Any modifications to the attribute map will automatically be applied to
   * this element.
   *
   * This only includes attributes which are not in a namespace
   * (such as 'xlink:href'), additional attributes can be accessed via
   * [getNamespacedAttributes].
   */
  Map<String, String> get attributes => new _ElementAttributeMap(this);

  set attributes(Map<String, String> value) {
    Map<String, String> attributes = this.attributes;
    attributes.clear();
    for (String key in value.keys) {
      attributes[key] = value[key];
    }
  }

  /**
   * List of the direct children of this element.
   *
   * This collection can be used to add and remove elements from the document.
   *
   *     var item = new DivElement();
   *     item.text = 'Something';
   *     document.body.children.add(item) // Item is now displayed on the page.
   *     for (var element in document.body.children) {
   *       element.style.background = 'red'; // Turns every child of body red.
   *     }
   */
  List<Element> get children => new _ChildrenElementList._wrap(this);

  set children(List<Element> value) {
    // Copy list first since we don't want liveness during iteration.
    List copy = new List.from(value);
    var children = this.children;
    children.clear();
    children.addAll(copy);
  }

  /**
   * Finds all descendent elements of this element that match the specified
   * group of selectors.
   *
   * [selectors] should be a string using CSS selector syntax.
   *
   *     var items = element.querySelectorAll('.itemClassName');
   *
   * For details about CSS selector syntax, see the
   * [CSS selector specification](http://www.w3.org/TR/css3-selectors/).
   */
  @DomName('Element.querySelectorAll')
  ElementList<Element> querySelectorAll(String selectors) =>
    new _FrozenElementList._wrap(_querySelectorAll(selectors));

  /**
   * Alias for [querySelector]. Note this function is deprecated because its
   * semantics will be changing in the future.
   */
  @deprecated
  @DomName('Element.querySelector')
  @Experimental()
  Element query(String relativeSelectors) => querySelector(relativeSelectors);

  /**
   * Alias for [querySelectorAll]. Note this function is deprecated because its
   * semantics will be changing in the future.
   */
  @deprecated
  @DomName('Element.querySelectorAll')
  @Experimental()
  ElementList<Element> queryAll(String relativeSelectors) =>
      querySelectorAll(relativeSelectors);

  /**
   * The set of CSS classes applied to this element.
   *
   * This set makes it easy to add, remove or toggle the classes applied to
   * this element.
   *
   *     element.classes.add('selected');
   *     element.classes.toggle('isOnline');
   *     element.classes.remove('selected');
   */
  CssClassSet get classes => new _ElementCssClassSet(this);

  set classes(Iterable<String> value) {
    // TODO(sra): Do this without reading the classes in clear() and addAll(),
    // or writing the classes in clear().
    CssClassSet classSet = classes;
    classSet.clear();
    classSet.addAll(value);
  }

  /**
   * Allows access to all custom data attributes (data-*) set on this element.
   *
   * The keys for the map must follow these rules:
   *
   * * The name must not begin with 'xml'.
   * * The name cannot contain a semi-colon (';').
   * * The name cannot contain any capital letters.
   *
   * Any keys from markup will be converted to camel-cased keys in the map.
   *
   * For example, HTML specified as:
   *
   *     <div data-my-random-value='value'></div>
   *
   * Would be accessed in Dart as:
   *
   *     var value = element.dataset['myRandomValue'];
   *
   * See also:
   *
   * * [Custom data
   *   attributes](http://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 = frames;
    if (convertedFrames is Iterable) {
      convertedFrames = convertDartToNative_List(
          frames.map(convertDartToNative_Dictionary).toList());
    }
    var convertedTiming = timing;
    if (convertedTiming is Map) {
      convertedTiming = convertDartToNative_Dictionary(convertedTiming);
    }
    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.
      var base = _parseDocument.createElement('base');
      base.href = document.baseUri;
      _parseDocument.head.append(base);
    }
    var contextElement;
    if (this is BodyElement) {
      contextElement = _parseDocument.body;
    } else {
      contextElement = _parseDocument.createElement(tagName);
      _parseDocument.body.append(contextElement);
    }
    var fragment;
    if (Range.supportsCreateContextualFragment &&
        _canBeUsedToCreateContextualFragment) {
      _parseRange.selectNodeContents(contextElement);
      fragment = _parseRange.createContextualFragment(html);
    } else {
      contextElement._innerHtml = html;

      fragment = _parseDocument.createDocumentFragment();
      while (contextElement.firstChild != null) {
        fragment.append(contextElement.firstChild);
      }
    }
    if (contextElement != _parseDocument.body) {
      contextElement.remove();
    }

    treeSanitizer.sanitizeTree(fragment);
    // Copy the fragment over to the main document (fix for 14184)
    document.adoptNode(fragment);

    return fragment;
  }

  /** Test if createContextualFragment is supported for this element type */
  bool get _canBeUsedToCreateContextualFragment =>
      !_cannotBeUsedToCreateContextualFragment;

  /** Test if createContextualFragment is NOT supported for this element type */
  bool get _cannotBeUsedToCreateContextualFragment =>
      _tagsForWhichCreateContextualFragmentIsNotSupported.contains(tagName);

  /**
   * A hard-coded list of the tag names for which createContextualFragment
   * isn't supported.
   */
  static const _tagsForWhichCreateContextualFragmentIsNotSupported =
      const ['HEAD', 'AREA',
      'BASE', 'BASEFONT', 'BR', 'COL', 'COLGROUP', 'EMBED', 'FRAME', 'FRAMESET',
      'HR', 'IMAGE', 'IMG', 'INPUT', 'ISINDEX', 'LINK', 'META', 'PARAM',
      'SOURCE', 'STYLE', 'TITLE', 'WBR'];

  /**
   * Parses the HTML fragment and sets it as the contents of this element.
   *
   * This uses the default sanitization behavior to sanitize the HTML fragment,
   * use [setInnerHtml] to override the default behavior.
   */
  set innerHtml(String html) {
    this.setInnerHtml(html);
  }

  /**
   * Parses the HTML fragment and sets it as the contents of this element.
   * This ensures that the generated content follows the sanitization rules
   * specified by the validator or treeSanitizer.
   *
   * If the default validation behavior is too restrictive then a new
   * NodeValidator should be created, either extending or wrapping a default
   * validator and overriding the validation APIs.
   *
   * The treeSanitizer is used to walk the generated node tree and sanitize it.
   * A custom treeSanitizer can also be provided to perform special validation
   * rules but since the API is more complex to implement this is discouraged.
   *
   * The resulting tree is guaranteed to only contain nodes and attributes which
   * are allowed by the provided validator.
   *
   * See also:
   *
   * * [NodeValidator]
   * * [NodeTreeSanitizer]
   */
  void setInnerHtml(String html,
    {NodeValidator validator, NodeTreeSanitizer treeSanitizer}) {
    text = null;
    if (treeSanitizer is _TrustedHtmlTreeSanitizer) {
      _innerHtml = html;
    } else {
      append(createFragment(
          html, validator: validator, treeSanitizer: treeSanitizer));
    }
  }
  String get innerHtml => _innerHtml;

  /**
   * This is an ease-of-use accessor for event streams which should only be
   * used when an explicit accessor is not available.
   */
  ElementEvents get on => new ElementEvents(this);

  /**
   * Verify if any of the attributes that we use in the sanitizer look unexpected,
   * possibly indicating DOM clobbering attacks.
   *
   * Those attributes are: attributes, lastChild, children, previousNode and tagName.
   */

  static var _namedNodeMap = js.context["NamedNodeMap"];
  static var _htmlCollection = js.context["HTMLCollection"];
  static var _nodeList = js.context["NodeList"];

  static bool _hasCorruptedAttributes(Element element) {
    var attributes = unwrap_jso(element)["attributes"];
    if (!attributes.instanceof(_namedNodeMap)) {
      return true;
    }
    var childNodes = unwrap_jso(element.childNodes);
    var length = childNodes["length"];
    var lastChild = unwrap_jso(element.lastChild);
    if (null != lastChild &&
        lastChild != childNodes[length - 1]) {
      return true;
    }
    var children = unwrap_jso(element._children);
    if (null != children) { // On Safari, children can apparently be null.
      if (!children.instanceof(_htmlCollection) ||
          children.instanceof(_nodeList)) {
	return true;
      }
    }
    return false;
  }

  /// A secondary check for corruption, needed on IE
  static bool _hasCorruptedAttributesAdditionalCheck(Element element) => false;

  static String _safeTagName(element) {
    String result = 'element tag unavailable';
    try {
      if (element.tagName is String) {
        result = element.tagName;
      }
    } catch (e) {}
    return result;
  }

  // Need to explicitly delegate because Element is no longer abstract for Dartium.
  bool get isContentEditable => _blink.BlinkHTMLElement.instance.isContentEditable_Getter_(unwrap_jso(this));
  void click() => _blink.BlinkHTMLElement.instance.click_Callback_0_(unwrap_jso(this));

  @DomName('Element.offsetParent')
  @DocsEditable()
  Element get offsetParent => wrap_jso(_blink.BlinkElement.instance.offsetParent_Getter_(unwrap_jso(this)));

  @DomName('Element.offsetHeight')
  @DocsEditable()
  int get offsetHeight => _blink.BlinkElement.instance.offsetHeight_Getter_(unwrap_jso(this));

  @DomName('Element.offsetLeft')
  @DocsEditable()
  int get offsetLeft => _blink.BlinkElement.instance.offsetLeft_Getter_(unwrap_jso(this));

  @DomName('Element.offsetTop')
  @DocsEditable()
  int get offsetTop => _blink.BlinkElement.instance.offsetTop_Getter_(unwrap_jso(this));

  @DomName('Element.offsetWidth')
  @DocsEditable()
  int get offsetWidth => _blink.BlinkElement.instance.offsetWidth_Getter_(unwrap_jso(this));

  @DomName('Element.scrollHeight')
  @DocsEditable()
  int get scrollHeight => _blink.BlinkElement.instance.scrollHeight_Getter_(unwrap_jso(this)).round();

  @DomName('Element.scrollLeft')
  @DocsEditable()
  int get scrollLeft => _blink.BlinkElement.instance.scrollLeft_Getter_(unwrap_jso(this)).round();

  @DomName('Element.scrollLeft')
  @DocsEditable()
  set scrollLeft(int value) => _blink.BlinkElement.instance.scrollLeft_Setter_(unwrap_jso(this), value.round());

  @DomName('Element.scrollTop')
  @DocsEditable()
  int get scrollTop => _blink.BlinkElement.instance.scrollTop_Getter_(unwrap_jso(this)).round();

  @DomName('Element.scrollTop')
  @DocsEditable()
  set scrollTop(int value) => _blink.BlinkElement.instance.scrollTop_Setter_(unwrap_jso(this), value.round());

  @DomName('Element.scrollWidth')
  @DocsEditable()
  int get scrollWidth => _blink.BlinkElement.instance.scrollWidth_Getter_(unwrap_jso(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")
  static Element internalCreateElement() {
    return new Element._internalWrap();
  }

  external factory Element._internalWrap();

  @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 => wrap_jso(_blink.BlinkElement.instance.attributes_Getter_(unwrap_jso(this)));
  
  @DomName('Element.className')
  @DocsEditable()
  String get className => _blink.BlinkElement.instance.className_Getter_(unwrap_jso(this));
  
  @DomName('Element.className')
  @DocsEditable()
  set className(String value) => _blink.BlinkElement.instance.className_Setter_(unwrap_jso(this), value);
  
  @DomName('Element.clientHeight')
  @DocsEditable()
  int get clientHeight => _blink.BlinkElement.instance.clientHeight_Getter_(unwrap_jso(this));
  
  @DomName('Element.clientLeft')
  @DocsEditable()
  int get clientLeft => _blink.BlinkElement.instance.clientLeft_Getter_(unwrap_jso(this));
  
  @DomName('Element.clientTop')
  @DocsEditable()
  int get clientTop => _blink.BlinkElement.instance.clientTop_Getter_(unwrap_jso(this));
  
  @DomName('Element.clientWidth')
  @DocsEditable()
  int get clientWidth => _blink.BlinkElement.instance.clientWidth_Getter_(unwrap_jso(this));
  
  @DomName('Element.computedName')
  @DocsEditable()
  @Experimental() // untriaged
  String get computedName => _blink.BlinkElement.instance.computedName_Getter_(unwrap_jso(this));
  
  @DomName('Element.computedRole')
  @DocsEditable()
  @Experimental() // untriaged
  String get computedRole => _blink.BlinkElement.instance.computedRole_Getter_(unwrap_jso(this));
  
  @DomName('Element.id')
  @DocsEditable()
  String get id => _blink.BlinkElement.instance.id_Getter_(unwrap_jso(this));
  
  @DomName('Element.id')
  @DocsEditable()
  set id(String value) => _blink.BlinkElement.instance.id_Setter_(unwrap_jso(this), value);
  
  @DomName('Element.innerHTML')
  @DocsEditable()
  String get _innerHtml => _blink.BlinkElement.instance.innerHTML_Getter_(unwrap_jso(this));
  
  @DomName('Element.innerHTML')
  @DocsEditable()
  set _innerHtml(String value) => _blink.BlinkElement.instance.innerHTML_Setter_(unwrap_jso(this), value);
  
  @DomName('Element.localName')
  @DocsEditable()
  @Experimental() // untriaged
  String get _localName => _blink.BlinkElement.instance.localName_Getter_(unwrap_jso(this));
  
  @DomName('Element.namespaceURI')
  @DocsEditable()
  @Experimental() // untriaged
  String get _namespaceUri => _blink.BlinkElement.instance.namespaceURI_Getter_(unwrap_jso(this));
  
  @DomName('Element.outerHTML')
  @DocsEditable()
  String get outerHtml => _blink.BlinkElement.instance.outerHTML_Getter_(unwrap_jso(this));
  
  @DomName('Element.scrollHeight')
  @DocsEditable()
  int get _scrollHeight => _blink.BlinkElement.instance.scrollHeight_Getter_(unwrap_jso(this));
  
  @DomName('Element.scrollLeft')
  @DocsEditable()
  num get _scrollLeft => _blink.BlinkElement.instance.scrollLeft_Getter_(unwrap_jso(this));
  
  @DomName('Element.scrollLeft')
  @DocsEditable()
  set _scrollLeft(num value) => _blink.BlinkElement.instance.scrollLeft_Setter_(unwrap_jso(this), value);
  
  @DomName('Element.scrollTop')
  @DocsEditable()
  num get _scrollTop => _blink.BlinkElement.instance.scrollTop_Getter_(unwrap_jso(this));
  
  @DomName('Element.scrollTop')
  @DocsEditable()
  set _scrollTop(num value) => _blink.BlinkElement.instance.scrollTop_Setter_(unwrap_jso(this), value);
  
  @DomName('Element.scrollWidth')
  @DocsEditable()
  int get _scrollWidth => _blink.BlinkElement.instance.scrollWidth_Getter_(unwrap_jso(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 => wrap_jso(_blink.BlinkElement.instance.shadowRoot_Getter_(unwrap_jso(this)));
  
  @DomName('Element.tagName')
  @DocsEditable()
  String get tagName => _blink.BlinkElement.instance.tagName_Getter_(unwrap_jso(this));
  
  Animation _animate(Object effect, [timing]) {
    if (effect != null && timing == null) {
      return wrap_jso(_blink.BlinkElement.instance.animate_Callback_1_(unwrap_jso(this), effect));
    }
    if ((timing is num) && effect != null) {
      return wrap_jso(_blink.BlinkElement.instance.animate_Callback_2_(unwrap_jso(this), effect, unwrap_jso(timing)));
    }
    if (timing != null && effect != null) {
      return wrap_jso(_blink.BlinkElement.instance.animate_Callback_2_(unwrap_jso(this), effect, unwrap_jso(timing)));
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }

  @DomName('Element.closest')
  @DocsEditable()
  @Experimental() // untriaged
  Element closest(String selectors) => wrap_jso(_blink.BlinkElement.instance.closest_Callback_1_(unwrap_jso(this), selectors));
  
  ShadowRoot createShadowRoot([Map shadowRootInitDict]) {
    if (shadowRootInitDict == null) {
      return wrap_jso(_blink.BlinkElement.instance.createShadowRoot_Callback_0_(unwrap_jso(this)));
    }
    if ((shadowRootInitDict is Map)) {
      return wrap_jso(_blink.BlinkElement.instance.createShadowRoot_Callback_1_(unwrap_jso(this), convertDartToNative_Dictionary(shadowRootInitDict)));
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }

  @DomName('Element.getAnimations')
  @DocsEditable()
  @Experimental() // untriaged
  List<Animation> getAnimations() => wrap_jso(_blink.BlinkElement.instance.getAnimations_Callback_0_(unwrap_jso(this)));
  
  @DomName('Element.getAttribute')
  @DocsEditable()
  @Experimental() // untriaged
  String getAttribute(String name) => _blink.BlinkElement.instance.getAttribute_Callback_1_(unwrap_jso(this), name);
  
  @DomName('Element.getAttributeNS')
  @DocsEditable()
  @Experimental() // untriaged
  String getAttributeNS(String namespaceURI, String localName) => _blink.BlinkElement.instance.getAttributeNS_Callback_2_(unwrap_jso(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_(unwrap_jso(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() => wrap_jso(_blink.BlinkElement.instance.getClientRects_Callback_0_(unwrap_jso(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() => wrap_jso(_blink.BlinkElement.instance.getDestinationInsertionPoints_Callback_0_(unwrap_jso(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) => wrap_jso(_blink.BlinkElement.instance.getElementsByClassName_Callback_1_(unwrap_jso(this), classNames));
  
  @DomName('Element.getElementsByTagName')
  @DocsEditable()
  List<Node> _getElementsByTagName(String localName) => wrap_jso(_blink.BlinkElement.instance.getElementsByTagName_Callback_1_(unwrap_jso(this), localName));
  
  @DomName('Element.hasAttribute')
  @DocsEditable()
  bool _hasAttribute(String name) => _blink.BlinkElement.instance.hasAttribute_Callback_1_(unwrap_jso(this), name);
  
  @DomName('Element.hasAttributeNS')
  @DocsEditable()
  bool _hasAttributeNS(String namespaceURI, String localName) => _blink.BlinkElement.instance.hasAttributeNS_Callback_2_(unwrap_jso(this), namespaceURI, localName);
  
  @DomName('Element.insertAdjacentElement')
  @DocsEditable()
  @Experimental() // untriaged
  Element insertAdjacentElement(String where, Element element) => wrap_jso(_blink.BlinkElement.instance.insertAdjacentElement_Callback_2_(unwrap_jso(this), where, unwrap_jso(element)));
  
  @DomName('Element.insertAdjacentHTML')
  @DocsEditable()
  @Experimental() // untriaged
  void _insertAdjacentHtml(String position, String text) => _blink.BlinkElement.instance.insertAdjacentHTML_Callback_2_(unwrap_jso(this), position, text);
  
  @DomName('Element.insertAdjacentText')
  @DocsEditable()
  @Experimental() // untriaged
  void insertAdjacentText(String where, String text) => _blink.BlinkElement.instance.insertAdjacentText_Callback_2_(unwrap_jso(this), where, text);
  
  @DomName('Element.matches')
  @DocsEditable()
  @Experimental() // untriaged
  bool matches(String selectors) => _blink.BlinkElement.instance.matches_Callback_1_(unwrap_jso(this), selectors);
  
  @DomName('Element.removeAttribute')
  @DocsEditable()
  void _removeAttribute(String name) => _blink.BlinkElement.instance.removeAttribute_Callback_1_(unwrap_jso(this), name);
  
  @DomName('Element.removeAttributeNS')
  @DocsEditable()
  void _removeAttributeNS(String namespaceURI, String localName) => _blink.BlinkElement.instance.removeAttributeNS_Callback_2_(unwrap_jso(this), namespaceURI, localName);
  
  @DomName('Element.requestFullscreen')
  @DocsEditable()
  @Experimental() // untriaged
  void requestFullscreen() => _blink.BlinkElement.instance.requestFullscreen_Callback_0_(unwrap_jso(this));
  
  @DomName('Element.requestPointerLock')
  @DocsEditable()
  @Experimental() // untriaged
  void requestPointerLock() => _blink.BlinkElement.instance.requestPointerLock_Callback_0_(unwrap_jso(this));
  
  void scroll([options_OR_x, num y]) {
    if (options_OR_x == null && y == null) {
      _blink.BlinkElement.instance.scroll_Callback_0_(unwrap_jso(this));
      return;
    }
    if ((options_OR_x is Map) && y == null) {
      _blink.BlinkElement.instance.scroll_Callback_1_(unwrap_jso(this), unwrap_jso(options_OR_x));
      return;
    }
    if ((y is num) && (options_OR_x is num)) {
      _blink.BlinkElement.instance.scroll_Callback_2_(unwrap_jso(this), unwrap_jso(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_(unwrap_jso(this));
      return;
    }
    if ((options_OR_x is Map) && y == null) {
      _blink.BlinkElement.instance.scrollBy_Callback_1_(unwrap_jso(this), unwrap_jso(options_OR_x));
      return;
    }
    if ((y is num) && (options_OR_x is num)) {
      _blink.BlinkElement.instance.scrollBy_Callback_2_(unwrap_jso(this), unwrap_jso(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_(unwrap_jso(this), alignWithTop);
      return;
    }
    _blink.BlinkElement.instance.scrollIntoView_Callback_0_(unwrap_jso(this));
    return;
  }

  void _scrollIntoViewIfNeeded([bool centerIfNeeded]) {
    if (centerIfNeeded != null) {
      _blink.BlinkElement.instance.scrollIntoViewIfNeeded_Callback_1_(unwrap_jso(this), centerIfNeeded);
      return;
    }
    _blink.BlinkElement.instance.scrollIntoViewIfNeeded_Callback_0_(unwrap_jso(this));
    return;
  }

  void scrollTo([options_OR_x, num y]) {
    if (options_OR_x == null && y == null) {
      _blink.BlinkElement.instance.scrollTo_Callback_0_(unwrap_jso(this));
      return;
    }
    if ((options_OR_x is Map) && y == null) {
      _blink.BlinkElement.instance.scrollTo_Callback_1_(unwrap_jso(this), unwrap_jso(options_OR_x));
      return;
    }
    if ((y is num) && (options_OR_x is num)) {
      _blink.BlinkElement.instance.scrollTo_Callback_2_(unwrap_jso(this), unwrap_jso(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_(unwrap_jso(this), name, value);
  
  @DomName('Element.setAttributeNS')
  @DocsEditable()
  void setAttributeNS(String namespaceURI, String name, String value) => _blink.BlinkElement.instance.setAttributeNS_Callback_3_(unwrap_jso(this), namespaceURI, name, value);
  
  @DomName('Element.after')
  @DocsEditable()
  @Experimental() // untriaged
  void after(Object nodes) => _blink.BlinkElement.instance.after_Callback_1_(unwrap_jso(this), nodes);
  
  @DomName('Element.before')
  @DocsEditable()
  @Experimental() // untriaged
  void before(Object nodes) => _blink.BlinkElement.instance.before_Callback_1_(unwrap_jso(this), nodes);
  
  @DomName('Element.remove')
  @DocsEditable()
  void remove() => _blink.BlinkElement.instance.remove_Callback_0_(unwrap_jso(this));
  
  @DomName('Element.nextElementSibling')
  @DocsEditable()
  Element get nextElementSibling => wrap_jso(_blink.BlinkElement.instance.nextElementSibling_Getter_(unwrap_jso(this)));
  
  @DomName('Element.previousElementSibling')
  @DocsEditable()
  Element get previousElementSibling => wrap_jso(_blink.BlinkElement.instance.previousElementSibling_Getter_(unwrap_jso(this)));
  
  @DomName('Element.childElementCount')
  @DocsEditable()
  int get _childElementCount => _blink.BlinkElement.instance.childElementCount_Getter_(unwrap_jso(this));
  
  @DomName('Element.children')
  @DocsEditable()
  List<Node> get _children => wrap_jso(_blink.BlinkElement.instance.children_Getter_(unwrap_jso(this)));
  
  @DomName('Element.firstElementChild')
  @DocsEditable()
  Element get _firstElementChild => wrap_jso(_blink.BlinkElement.instance.firstElementChild_Getter_(unwrap_jso(this)));
  
  @DomName('Element.lastElementChild')
  @DocsEditable()
  Element get _lastElementChild => wrap_jso(_blink.BlinkElement.instance.lastElementChild_Getter_(unwrap_jso(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) => wrap_jso(_blink.BlinkElement.instance.querySelector_Callback_1_(unwrap_jso(this), selectors));
  
  @DomName('Element.querySelectorAll')
  @DocsEditable()
  List<Node> _querySelectorAll(String selectors) => wrap_jso(_blink.BlinkElement.instance.querySelectorAll_Callback_1_(unwrap_jso(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")
  static EmbedElement internalCreateEmbedElement() {
    return new EmbedElement._internalWrap();
  }

  external factory EmbedElement._internalWrap();

  @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_(unwrap_jso(this));
  
  @DomName('HTMLEmbedElement.height')
  @DocsEditable()
  set height(String value) => _blink.BlinkHTMLEmbedElement.instance.height_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLEmbedElement.name')
  @DocsEditable()
  String get name => _blink.BlinkHTMLEmbedElement.instance.name_Getter_(unwrap_jso(this));
  
  @DomName('HTMLEmbedElement.name')
  @DocsEditable()
  set name(String value) => _blink.BlinkHTMLEmbedElement.instance.name_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLEmbedElement.src')
  @DocsEditable()
  String get src => _blink.BlinkHTMLEmbedElement.instance.src_Getter_(unwrap_jso(this));
  
  @DomName('HTMLEmbedElement.src')
  @DocsEditable()
  set src(String value) => _blink.BlinkHTMLEmbedElement.instance.src_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLEmbedElement.type')
  @DocsEditable()
  String get type => _blink.BlinkHTMLEmbedElement.instance.type_Getter_(unwrap_jso(this));
  
  @DomName('HTMLEmbedElement.type')
  @DocsEditable()
  set type(String value) => _blink.BlinkHTMLEmbedElement.instance.type_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLEmbedElement.width')
  @DocsEditable()
  String get width => _blink.BlinkHTMLEmbedElement.instance.width_Getter_(unwrap_jso(this));
  
  @DomName('HTMLEmbedElement.width')
  @DocsEditable()
  set width(String value) => _blink.BlinkHTMLEmbedElement.instance.width_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLEmbedElement.__getter__')
  @DocsEditable()
  bool __getter__(index_OR_name) => _blink.BlinkHTMLEmbedElement.instance.$__getter___Callback_1_(unwrap_jso(this), unwrap_jso(index_OR_name));
  
  @DomName('HTMLEmbedElement.__setter__')
  @DocsEditable()
  void __setter__(index_OR_name, Node value) => _blink.BlinkHTMLEmbedElement.instance.$__setter___Callback_2_(unwrap_jso(this), unwrap_jso(index_OR_name), unwrap_jso(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")
  static Entry internalCreateEntry() {
    return new Entry._internalWrap();
  }

  factory Entry._internalWrap() {
    return new Entry.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  @DomName('Entry.filesystem')
  @DocsEditable()
  FileSystem get filesystem => wrap_jso(_blink.BlinkEntry.instance.filesystem_Getter_(unwrap_jso(this)));
  
  @DomName('Entry.fullPath')
  @DocsEditable()
  String get fullPath => _blink.BlinkEntry.instance.fullPath_Getter_(unwrap_jso(this));
  
  @DomName('Entry.isDirectory')
  @DocsEditable()
  bool get isDirectory => _blink.BlinkEntry.instance.isDirectory_Getter_(unwrap_jso(this));
  
  @DomName('Entry.isFile')
  @DocsEditable()
  bool get isFile => _blink.BlinkEntry.instance.isFile_Getter_(unwrap_jso(this));
  
  @DomName('Entry.name')
  @DocsEditable()
  String get name => _blink.BlinkEntry.instance.name_Getter_(unwrap_jso(this));
  
  void _copyTo(DirectoryEntry parent, {String name, _EntryCallback successCallback, _ErrorCallback errorCallback}) {
    if (errorCallback != null) {
      _blink.BlinkEntry.instance.copyTo_Callback_4_(unwrap_jso(this), unwrap_jso(parent), name, unwrap_jso((entry) => successCallback(wrap_jso(entry))), unwrap_jso((error) => errorCallback(wrap_jso(error))));
      return;
    }
    if (successCallback != null) {
      _blink.BlinkEntry.instance.copyTo_Callback_3_(unwrap_jso(this), unwrap_jso(parent), name, unwrap_jso((entry) => successCallback(wrap_jso(entry))));
      return;
    }
    if (name != null) {
      _blink.BlinkEntry.instance.copyTo_Callback_2_(unwrap_jso(this), unwrap_jso(parent), name);
      return;
    }
    _blink.BlinkEntry.instance.copyTo_Callback_1_(unwrap_jso(this), unwrap_jso(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_(unwrap_jso(this), unwrap_jso((metadata) => successCallback(wrap_jso(metadata))), unwrap_jso((error) => errorCallback(wrap_jso(error))));
      return;
    }
    _blink.BlinkEntry.instance.getMetadata_Callback_1_(unwrap_jso(this), unwrap_jso((metadata) => successCallback(wrap_jso(metadata))));
    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_(unwrap_jso(this), unwrap_jso((entry) => successCallback(wrap_jso(entry))), unwrap_jso((error) => errorCallback(wrap_jso(error))));
      return;
    }
    if (successCallback != null) {
      _blink.BlinkEntry.instance.getParent_Callback_1_(unwrap_jso(this), unwrap_jso((entry) => successCallback(wrap_jso(entry))));
      return;
    }
    _blink.BlinkEntry.instance.getParent_Callback_0_(unwrap_jso(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_(unwrap_jso(this), unwrap_jso(parent), name, unwrap_jso((entry) => successCallback(wrap_jso(entry))), unwrap_jso((error) => errorCallback(wrap_jso(error))));
      return;
    }
    if (successCallback != null) {
      _blink.BlinkEntry.instance.moveTo_Callback_3_(unwrap_jso(this), unwrap_jso(parent), name, unwrap_jso((entry) => successCallback(wrap_jso(entry))));
      return;
    }
    if (name != null) {
      _blink.BlinkEntry.instance.moveTo_Callback_2_(unwrap_jso(this), unwrap_jso(parent), name);
      return;
    }
    _blink.BlinkEntry.instance.moveTo_Callback_1_(unwrap_jso(this), unwrap_jso(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_(unwrap_jso(this), unwrap_jso(() => successCallback()), unwrap_jso((error) => errorCallback(wrap_jso(error))));
      return;
    }
    _blink.BlinkEntry.instance.remove_Callback_1_(unwrap_jso(this), unwrap_jso(() => 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_(unwrap_jso(this));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of 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 wrap_jso(_blink.BlinkErrorEvent.instance.constructorCallback_2_(type, eventInitDict_1));
    }
    return wrap_jso(_blink.BlinkErrorEvent.instance.constructorCallback_1_(type));
  }


  @Deprecated("Internal Use Only")
  static ErrorEvent internalCreateErrorEvent() {
    return new ErrorEvent._internalWrap();
  }

  external factory ErrorEvent._internalWrap();

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


  @DomName('ErrorEvent.colno')
  @DocsEditable()
  @Experimental() // untriaged
  int get colno => _blink.BlinkErrorEvent.instance.colno_Getter_(unwrap_jso(this));
  
  @DomName('ErrorEvent.error')
  @DocsEditable()
  @Experimental() // untriaged
  Object get error => wrap_jso(_blink.BlinkErrorEvent.instance.error_Getter_(unwrap_jso(this)));
  
  @DomName('ErrorEvent.filename')
  @DocsEditable()
  String get filename => _blink.BlinkErrorEvent.instance.filename_Getter_(unwrap_jso(this));
  
  @DomName('ErrorEvent.lineno')
  @DocsEditable()
  int get lineno => _blink.BlinkErrorEvent.instance.lineno_Getter_(unwrap_jso(this));
  
  @DomName('ErrorEvent.message')
  @DocsEditable()
  String get message => _blink.BlinkErrorEvent.instance.message_Getter_(unwrap_jso(this));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of 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.');
    }
    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.');
  }

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

  @Deprecated("Internal Use Only")
  static Event internalCreateEvent() {
    return new Event._internalWrap();
  }

  factory Event._internalWrap() {
    return new Event.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  /**
   * 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_(unwrap_jso(this));
  
  @DomName('Event.cancelable')
  @DocsEditable()
  bool get cancelable => _blink.BlinkEvent.instance.cancelable_Getter_(unwrap_jso(this));
  
  @DomName('Event.currentTarget')
  @DocsEditable()
  EventTarget get currentTarget => wrap_jso(_blink.BlinkEvent.instance.currentTarget_Getter_(unwrap_jso(this)));
  
  @DomName('Event.defaultPrevented')
  @DocsEditable()
  bool get defaultPrevented => _blink.BlinkEvent.instance.defaultPrevented_Getter_(unwrap_jso(this));
  
  @DomName('Event.eventPhase')
  @DocsEditable()
  int get eventPhase => _blink.BlinkEvent.instance.eventPhase_Getter_(unwrap_jso(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 => wrap_jso(_blink.BlinkEvent.instance.path_Getter_(unwrap_jso(this)));
  
  @DomName('Event.target')
  @DocsEditable()
  EventTarget get target => wrap_jso(_blink.BlinkEvent.instance.target_Getter_(unwrap_jso(this)));
  
  @DomName('Event.timeStamp')
  @DocsEditable()
  int get timeStamp => _blink.BlinkEvent.instance.timeStamp_Getter_(unwrap_jso(this));
  
  @DomName('Event.type')
  @DocsEditable()
  String get type => _blink.BlinkEvent.instance.type_Getter_(unwrap_jso(this));
  
  @DomName('Event.initEvent')
  @DocsEditable()
  void _initEvent(String type, bool bubbles, bool cancelable) => _blink.BlinkEvent.instance.initEvent_Callback_3_(unwrap_jso(this), type, bubbles, cancelable);
  
  @DomName('Event.preventDefault')
  @DocsEditable()
  void preventDefault() => _blink.BlinkEvent.instance.preventDefault_Callback_0_(unwrap_jso(this));
  
  @DomName('Event.stopImmediatePropagation')
  @DocsEditable()
  void stopImmediatePropagation() => _blink.BlinkEvent.instance.stopImmediatePropagation_Callback_0_(unwrap_jso(this));
  
  @DomName('Event.stopPropagation')
  @DocsEditable()
  void stopPropagation() => _blink.BlinkEvent.instance.stopPropagation_Callback_0_(unwrap_jso(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 wrap_jso(_blink.BlinkEventSource.instance.constructorCallback_2_(url, eventSourceInitDict_1));
    }
    return wrap_jso(_blink.BlinkEventSource.instance.constructorCallback_1_(url));
  }


  @Deprecated("Internal Use Only")
  static EventSource internalCreateEventSource() {
    return new EventSource._internalWrap();
  }

  external factory EventSource._internalWrap();

  @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_(unwrap_jso(this));
  
  @DomName('EventSource.url')
  @DocsEditable()
  String get url => _blink.BlinkEventSource.instance.url_Getter_(unwrap_jso(this));
  
  @DomName('EventSource.withCredentials')
  @DocsEditable()
  bool get withCredentials => _blink.BlinkEventSource.instance.withCredentials_Getter_(unwrap_jso(this));
  
  @DomName('EventSource.close')
  @DocsEditable()
  void close() => _blink.BlinkEventSource.instance.close_Callback_0_(unwrap_jso(this));
  
  /// Stream of `error` events handled by this [EventSource].
  @DomName('EventSource.onerror')
  @DocsEditable()
  Stream<Event> get onError => errorEvent.forTarget(this);

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

  /// Stream of `open` events handled by this [EventSource].
  @DomName('EventSource.onopen')
  @DocsEditable()
  Stream<Event> get onOpen => openEvent.forTarget(this);

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


/**
 * Base class that supports listening for and dispatching browser events.
 *
 * Normally events are accessed via the Stream getter:
 *
 *     element.onMouseOver.listen((e) => print('Mouse over!'));
 *
 * To access bubbling events which are declared on one element, but may bubble
 * up to another element type (common for MediaElement events):
 *
 *     MediaElement.pauseEvent.forTarget(document.body).listen(...);
 *
 * To useCapture on events:
 *
 *     Element.keyDownEvent.forTarget(element, useCapture: true).listen(...);
 *
 * Custom events can be declared as:
 *
 *     class DataGenerator {
 *       static EventStreamProvider<Event> dataEvent =
 *           new EventStreamProvider('data');
 *     }
 *
 * Then listeners should access the event with:
 *
 *     DataGenerator.dataEvent.forTarget(element).listen(...);
 *
 * Custom events can also be accessed as:
 *
 *     element.on['some_event'].listen(...);
 *
 * This approach is generally discouraged as it loses the event typing and
 * some DOM events may have multiple platform-dependent event names under the
 * covers. By using the standard Stream getters you will get the platform
 * specific event name automatically.
 */
class Events {
  /* Raw event target. */
  final EventTarget _ptr;

  Events(this._ptr);

  Stream operator [](String type) {
    return new _EventStream(_ptr, type, false);
  }
}

class ElementEvents extends Events {
  /* Raw event target. */
  final Element _ptr;
  static final webkitEvents = {
    'animationend' : 'webkitAnimationEnd', 
    'animationiteration' : 'webkitAnimationIteration', 
    'animationstart' : 'webkitAnimationStart', 
    'fullscreenchange' : 'webkitfullscreenchange', 
    'fullscreenerror' : 'webkitfullscreenerror',
    'keyadded' : 'webkitkeyadded', 
    'keyerror' : 'webkitkeyerror', 
    'keymessage' : 'webkitkeymessage', 
    'needkey' : 'webkitneedkey', 
    'pointerlockchange' : 'webkitpointerlockchange', 
    'pointerlockerror' : 'webkitpointerlockerror', 
    'resourcetimingbufferfull' : 'webkitresourcetimingbufferfull', 
    'transitionend': 'webkitTransitionEnd',
    'speechchange' : 'webkitSpeechChange'
  };

  ElementEvents(Element ptr) : this._ptr = ptr, super(ptr);

  Stream operator [](String type) {
    if (webkitEvents.keys.contains(type.toLowerCase())) {
      if (Device.isWebKit) {
        return new _ElementEventStreamImpl(
            _ptr, webkitEvents[type.toLowerCase()], false);
      }
    }
    return new _ElementEventStreamImpl(_ptr, type, false);
  }
}

/**
 * Base class for all browser objects that support events.
 *
 * Use the [on] property to add, and remove events
 * for compile-time type checks and a more concise API.
 */
@DomName('EventTarget')
class EventTarget extends 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")
  static EventTarget internalCreateEventTarget() {
    return new EventTarget._internalWrap();
  }

  factory EventTarget._internalWrap() {
    return new EventTarget.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  @DomName('EventTarget.addEventListener')
  @DocsEditable()
  void _addEventListener(String type, EventListener listener, [bool capture]) => _blink.BlinkEventTarget.instance.addEventListener_Callback_3_(unwrap_jso(this), type, unwrap_jso(js.allowInterop(listener)), capture);
  
  @DomName('EventTarget.dispatchEvent')
  @DocsEditable()
  bool dispatchEvent(Event event) => _blink.BlinkEventTarget.instance.dispatchEvent_Callback_1_(unwrap_jso(this), unwrap_jso(event));
  
  @DomName('EventTarget.removeEventListener')
  @DocsEditable()
  void _removeEventListener(String type, EventListener listener, [bool capture]) => _blink.BlinkEventTarget.instance.removeEventListener_Callback_3_(unwrap_jso(this), type, unwrap_jso(js.allowInterop(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 wrap_jso(_blink.BlinkExtendableEvent.instance.constructorCallback_2_(type, eventInitDict_1));
    }
    return wrap_jso(_blink.BlinkExtendableEvent.instance.constructorCallback_1_(type));
  }


  @Deprecated("Internal Use Only")
  static ExtendableEvent internalCreateExtendableEvent() {
    return new ExtendableEvent._internalWrap();
  }

  external factory ExtendableEvent._internalWrap();

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


  @DomName('ExtendableEvent.waitUntil')
  @DocsEditable()
  @Experimental() // untriaged
  void waitUntil(Object value) => _blink.BlinkExtendableEvent.instance.waitUntil_Callback_1_(unwrap_jso(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 wrap_jso(_blink.BlinkFederatedCredential.instance.constructorCallback_1_(data_1));
  }


  @Deprecated("Internal Use Only")
  static FederatedCredential internalCreateFederatedCredential() {
    return new FederatedCredential._internalWrap();
  }

  external factory FederatedCredential._internalWrap();

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


  @DomName('FederatedCredential.protocol')
  @DocsEditable()
  @Experimental() // untriaged
  String get protocol => _blink.BlinkFederatedCredential.instance.protocol_Getter_(unwrap_jso(this));
  
  @DomName('FederatedCredential.provider')
  @DocsEditable()
  @Experimental() // untriaged
  String get provider => _blink.BlinkFederatedCredential.instance.provider_Getter_(unwrap_jso(this));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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 wrap_jso(_blink.BlinkFetchEvent.instance.constructorCallback_2_(type, eventInitDict_1));
    }
    return wrap_jso(_blink.BlinkFetchEvent.instance.constructorCallback_1_(type));
  }


  @Deprecated("Internal Use Only")
  static FetchEvent internalCreateFetchEvent() {
    return new FetchEvent._internalWrap();
  }

  external factory FetchEvent._internalWrap();

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


  @DomName('FetchEvent.isReload')
  @DocsEditable()
  @Experimental() // untriaged
  bool get isReload => _blink.BlinkFetchEvent.instance.isReload_Getter_(unwrap_jso(this));
  
  @DomName('FetchEvent.request')
  @DocsEditable()
  @Experimental() // untriaged
  _Request get request => wrap_jso(_blink.BlinkFetchEvent.instance.request_Getter_(unwrap_jso(this)));
  
  @DomName('FetchEvent.respondWith')
  @DocsEditable()
  @Experimental() // untriaged
  void respondWith(Object value) => _blink.BlinkFetchEvent.instance.respondWith_Callback_1_(unwrap_jso(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")
  static FieldSetElement internalCreateFieldSetElement() {
    return new FieldSetElement._internalWrap();
  }

  external factory FieldSetElement._internalWrap();

  @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_(unwrap_jso(this));
  
  @DomName('HTMLFieldSetElement.disabled')
  @DocsEditable()
  set disabled(bool value) => _blink.BlinkHTMLFieldSetElement.instance.disabled_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLFieldSetElement.elements')
  @DocsEditable()
  HtmlFormControlsCollection get elements => wrap_jso(_blink.BlinkHTMLFieldSetElement.instance.elements_Getter_(unwrap_jso(this)));
  
  @DomName('HTMLFieldSetElement.form')
  @DocsEditable()
  FormElement get form => wrap_jso(_blink.BlinkHTMLFieldSetElement.instance.form_Getter_(unwrap_jso(this)));
  
  @DomName('HTMLFieldSetElement.name')
  @DocsEditable()
  String get name => _blink.BlinkHTMLFieldSetElement.instance.name_Getter_(unwrap_jso(this));
  
  @DomName('HTMLFieldSetElement.name')
  @DocsEditable()
  set name(String value) => _blink.BlinkHTMLFieldSetElement.instance.name_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLFieldSetElement.type')
  @DocsEditable()
  String get type => _blink.BlinkHTMLFieldSetElement.instance.type_Getter_(unwrap_jso(this));
  
  @DomName('HTMLFieldSetElement.validationMessage')
  @DocsEditable()
  String get validationMessage => _blink.BlinkHTMLFieldSetElement.instance.validationMessage_Getter_(unwrap_jso(this));
  
  @DomName('HTMLFieldSetElement.validity')
  @DocsEditable()
  ValidityState get validity => wrap_jso(_blink.BlinkHTMLFieldSetElement.instance.validity_Getter_(unwrap_jso(this)));
  
  @DomName('HTMLFieldSetElement.willValidate')
  @DocsEditable()
  bool get willValidate => _blink.BlinkHTMLFieldSetElement.instance.willValidate_Getter_(unwrap_jso(this));
  
  @DomName('HTMLFieldSetElement.checkValidity')
  @DocsEditable()
  bool checkValidity() => _blink.BlinkHTMLFieldSetElement.instance.checkValidity_Callback_0_(unwrap_jso(this));
  
  @DomName('HTMLFieldSetElement.reportValidity')
  @DocsEditable()
  @Experimental() // untriaged
  bool reportValidity() => _blink.BlinkHTMLFieldSetElement.instance.reportValidity_Callback_0_(unwrap_jso(this));
  
  @DomName('HTMLFieldSetElement.setCustomValidity')
  @DocsEditable()
  void setCustomValidity(String error) => _blink.BlinkHTMLFieldSetElement.instance.setCustomValidity_Callback_1_(unwrap_jso(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 wrap_jso(_blink.BlinkFile.instance.constructorCallback_3_(fileBits, fileName, options_1));
    }
    return wrap_jso(_blink.BlinkFile.instance.constructorCallback_2_(fileBits, fileName));
  }


  @Deprecated("Internal Use Only")
  static File internalCreateFile() {
    return new File._internalWrap();
  }

  external factory File._internalWrap();

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


  @DomName('File.lastModified')
  @DocsEditable()
  @Experimental() // untriaged
  int get lastModified => _blink.BlinkFile.instance.lastModified_Getter_(unwrap_jso(this));
  
  @DomName('File.lastModifiedDate')
  @DocsEditable()
  DateTime get lastModifiedDate => _blink.BlinkFile.instance.lastModifiedDate_Getter_(unwrap_jso(this));
  
  @DomName('File.name')
  @DocsEditable()
  String get name => _blink.BlinkFile.instance.name_Getter_(unwrap_jso(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_(unwrap_jso(this));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of 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")
  static FileEntry internalCreateFileEntry() {
    return new FileEntry._internalWrap();
  }

  external factory FileEntry._internalWrap();

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


  void _createWriter(_FileWriterCallback successCallback, [_ErrorCallback errorCallback]) {
    if (errorCallback != null) {
      _blink.BlinkFileEntry.instance.createWriter_Callback_2_(unwrap_jso(this), unwrap_jso((fileWriter) => successCallback(wrap_jso(fileWriter))), unwrap_jso((error) => errorCallback(wrap_jso(error))));
      return;
    }
    _blink.BlinkFileEntry.instance.createWriter_Callback_1_(unwrap_jso(this), unwrap_jso((fileWriter) => successCallback(wrap_jso(fileWriter))));
    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_(unwrap_jso(this), unwrap_jso((file) => successCallback(wrap_jso(file))), unwrap_jso((error) => errorCallback(wrap_jso(error))));
      return;
    }
    _blink.BlinkFileEntry.instance.file_Callback_1_(unwrap_jso(this), unwrap_jso((file) => successCallback(wrap_jso(file))));
    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")
  static FileError internalCreateFileError() {
    return new FileError._internalWrap();
  }

  external factory FileError._internalWrap();

  @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_(unwrap_jso(this));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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")
  static FileList internalCreateFileList() {
    return new FileList._internalWrap();
  }

  factory FileList._internalWrap() {
    return new FileList.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  @DomName('FileList.length')
  @DocsEditable()
  int get length => _blink.BlinkFileList.instance.length_Getter_(unwrap_jso(this));
  
  File operator[](int index) {
    if (index < 0 || index >= length)
      throw new RangeError.index(index, this);
    return wrap_jso(_blink.BlinkFileList.instance.item_Callback_1_(unwrap_jso(this), index));
  }

  File _nativeIndexedGetter(int index) => wrap_jso(_blink.BlinkFileList.instance.item_Callback_1_(unwrap_jso(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) => wrap_jso(_blink.BlinkFileList.instance.item_Callback_1_(unwrap_jso(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_(unwrap_jso(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 wrap_jso(_blink.BlinkFileReader.instance.constructorCallback_0_());
  }


  @Deprecated("Internal Use Only")
  static FileReader internalCreateFileReader() {
    return new FileReader._internalWrap();
  }

  external factory FileReader._internalWrap();

  @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 => wrap_jso(_blink.BlinkFileReader.instance.error_Getter_(unwrap_jso(this)));
  
  @DomName('FileReader.readyState')
  @DocsEditable()
  int get readyState => _blink.BlinkFileReader.instance.readyState_Getter_(unwrap_jso(this));
  
  @DomName('FileReader.result')
  @DocsEditable()
  Object get _result => wrap_jso(_blink.BlinkFileReader.instance.result_Getter_(unwrap_jso(this)));
  
  @DomName('FileReader.abort')
  @DocsEditable()
  void abort() => _blink.BlinkFileReader.instance.abort_Callback_0_(unwrap_jso(this));
  
  @DomName('FileReader.readAsArrayBuffer')
  @DocsEditable()
  void readAsArrayBuffer(Blob blob) => _blink.BlinkFileReader.instance.readAsArrayBuffer_Callback_1_(unwrap_jso(this), unwrap_jso(blob));
  
  @DomName('FileReader.readAsDataURL')
  @DocsEditable()
  void readAsDataUrl(Blob blob) => _blink.BlinkFileReader.instance.readAsDataURL_Callback_1_(unwrap_jso(this), unwrap_jso(blob));
  
  void readAsText(Blob blob, [String label]) {
    if (label != null) {
      _blink.BlinkFileReader.instance.readAsText_Callback_2_(unwrap_jso(this), unwrap_jso(blob), label);
      return;
    }
    _blink.BlinkFileReader.instance.readAsText_Callback_1_(unwrap_jso(this), unwrap_jso(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")
  static FileStream internalCreateFileStream() {
    return new FileStream._internalWrap();
  }

  factory FileStream._internalWrap() {
    return new FileStream.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  @DomName('Stream.type')
  @DocsEditable()
  @Experimental() // untriaged
  String get type => _blink.BlinkStream.instance.type_Getter_(unwrap_jso(this));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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")
  static FileSystem internalCreateFileSystem() {
    return new FileSystem._internalWrap();
  }

  factory FileSystem._internalWrap() {
    return new FileSystem.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  /// 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_(unwrap_jso(this));
  
  @DomName('DOMFileSystem.root')
  @DocsEditable()
  DirectoryEntry get root => wrap_jso(_blink.BlinkDOMFileSystem.instance.root_Getter_(unwrap_jso(this)));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of 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")
  static FileWriter internalCreateFileWriter() {
    return new FileWriter._internalWrap();
  }

  external factory FileWriter._internalWrap();

  @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 => wrap_jso(_blink.BlinkFileWriter.instance.error_Getter_(unwrap_jso(this)));
  
  @DomName('FileWriter.length')
  @DocsEditable()
  int get length => _blink.BlinkFileWriter.instance.length_Getter_(unwrap_jso(this));
  
  @DomName('FileWriter.position')
  @DocsEditable()
  int get position => _blink.BlinkFileWriter.instance.position_Getter_(unwrap_jso(this));
  
  @DomName('FileWriter.readyState')
  @DocsEditable()
  int get readyState => _blink.BlinkFileWriter.instance.readyState_Getter_(unwrap_jso(this));
  
  @DomName('FileWriter.abort')
  @DocsEditable()
  void abort() => _blink.BlinkFileWriter.instance.abort_Callback_0_(unwrap_jso(this));
  
  @DomName('FileWriter.seek')
  @DocsEditable()
  void seek(int position) => _blink.BlinkFileWriter.instance.seek_Callback_1_(unwrap_jso(this), position);
  
  @DomName('FileWriter.truncate')
  @DocsEditable()
  void truncate(int size) => _blink.BlinkFileWriter.instance.truncate_Callback_1_(unwrap_jso(this), size);
  
  @DomName('FileWriter.write')
  @DocsEditable()
  void write(Blob data) => _blink.BlinkFileWriter.instance.write_Callback_1_(unwrap_jso(this), unwrap_jso(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 wrap_jso(_blink.BlinkFocusEvent.instance.constructorCallback_2_(type, eventInitDict_1));
    }
    return wrap_jso(_blink.BlinkFocusEvent.instance.constructorCallback_1_(type));
  }


  @Deprecated("Internal Use Only")
  static FocusEvent internalCreateFocusEvent() {
    return new FocusEvent._internalWrap();
  }

  external factory FocusEvent._internalWrap();

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


  @DomName('FocusEvent.relatedTarget')
  @DocsEditable()
  EventTarget get relatedTarget => wrap_jso(_blink.BlinkFocusEvent.instance.relatedTarget_Getter_(unwrap_jso(this)));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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 wrap_jso(_blink.BlinkFontFace.instance.constructorCallback_3_(family, source, descriptors_1));
    }
    return wrap_jso(_blink.BlinkFontFace.instance.constructorCallback_2_(family, source));
  }

  @Deprecated("Internal Use Only")
  static FontFace internalCreateFontFace() {
    return new FontFace._internalWrap();
  }

  factory FontFace._internalWrap() {
    return new FontFace.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  @DomName('FontFace.family')
  @DocsEditable()
  @Experimental() // untriaged
  String get family => _blink.BlinkFontFace.instance.family_Getter_(unwrap_jso(this));
  
  @DomName('FontFace.family')
  @DocsEditable()
  @Experimental() // untriaged
  set family(String value) => _blink.BlinkFontFace.instance.family_Setter_(unwrap_jso(this), value);
  
  @DomName('FontFace.featureSettings')
  @DocsEditable()
  @Experimental() // untriaged
  String get featureSettings => _blink.BlinkFontFace.instance.featureSettings_Getter_(unwrap_jso(this));
  
  @DomName('FontFace.featureSettings')
  @DocsEditable()
  @Experimental() // untriaged
  set featureSettings(String value) => _blink.BlinkFontFace.instance.featureSettings_Setter_(unwrap_jso(this), value);
  
  @DomName('FontFace.loaded')
  @DocsEditable()
  @Experimental() // untriaged
  Future get loaded => wrap_jso(_blink.BlinkFontFace.instance.loaded_Getter_(unwrap_jso(this)));
  
  @DomName('FontFace.status')
  @DocsEditable()
  @Experimental() // untriaged
  String get status => _blink.BlinkFontFace.instance.status_Getter_(unwrap_jso(this));
  
  @DomName('FontFace.stretch')
  @DocsEditable()
  @Experimental() // untriaged
  String get stretch => _blink.BlinkFontFace.instance.stretch_Getter_(unwrap_jso(this));
  
  @DomName('FontFace.stretch')
  @DocsEditable()
  @Experimental() // untriaged
  set stretch(String value) => _blink.BlinkFontFace.instance.stretch_Setter_(unwrap_jso(this), value);
  
  @DomName('FontFace.style')
  @DocsEditable()
  @Experimental() // untriaged
  String get style => _blink.BlinkFontFace.instance.style_Getter_(unwrap_jso(this));
  
  @DomName('FontFace.style')
  @DocsEditable()
  @Experimental() // untriaged
  set style(String value) => _blink.BlinkFontFace.instance.style_Setter_(unwrap_jso(this), value);
  
  @DomName('FontFace.unicodeRange')
  @DocsEditable()
  @Experimental() // untriaged
  String get unicodeRange => _blink.BlinkFontFace.instance.unicodeRange_Getter_(unwrap_jso(this));
  
  @DomName('FontFace.unicodeRange')
  @DocsEditable()
  @Experimental() // untriaged
  set unicodeRange(String value) => _blink.BlinkFontFace.instance.unicodeRange_Setter_(unwrap_jso(this), value);
  
  @DomName('FontFace.variant')
  @DocsEditable()
  @Experimental() // untriaged
  String get variant => _blink.BlinkFontFace.instance.variant_Getter_(unwrap_jso(this));
  
  @DomName('FontFace.variant')
  @DocsEditable()
  @Experimental() // untriaged
  set variant(String value) => _blink.BlinkFontFace.instance.variant_Setter_(unwrap_jso(this), value);
  
  @DomName('FontFace.weight')
  @DocsEditable()
  @Experimental() // untriaged
  String get weight => _blink.BlinkFontFace.instance.weight_Getter_(unwrap_jso(this));
  
  @DomName('FontFace.weight')
  @DocsEditable()
  @Experimental() // untriaged
  set weight(String value) => _blink.BlinkFontFace.instance.weight_Setter_(unwrap_jso(this), value);
  
  @DomName('FontFace.load')
  @DocsEditable()
  @Experimental() // untriaged
  Future load() => wrap_jso(_blink.BlinkFontFace.instance.load_Callback_0_(unwrap_jso(this)));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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")
  static FontFaceSet internalCreateFontFaceSet() {
    return new FontFaceSet._internalWrap();
  }

  external factory FontFaceSet._internalWrap();

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


  @DomName('FontFaceSet.size')
  @DocsEditable()
  @Experimental() // untriaged
  int get size => _blink.BlinkFontFaceSet.instance.size_Getter_(unwrap_jso(this));
  
  @DomName('FontFaceSet.status')
  @DocsEditable()
  @Experimental() // untriaged
  String get status => _blink.BlinkFontFaceSet.instance.status_Getter_(unwrap_jso(this));
  
  @DomName('FontFaceSet.add')
  @DocsEditable()
  @Experimental() // untriaged
  void add(FontFace fontFace) => _blink.BlinkFontFaceSet.instance.add_Callback_1_(unwrap_jso(this), unwrap_jso(fontFace));
  
  bool check(String font, [String text]) {
    if (text != null) {
      return _blink.BlinkFontFaceSet.instance.check_Callback_2_(unwrap_jso(this), font, text);
    }
    return _blink.BlinkFontFaceSet.instance.check_Callback_1_(unwrap_jso(this), font);
  }

  @DomName('FontFaceSet.clear')
  @DocsEditable()
  @Experimental() // untriaged
  void clear() => _blink.BlinkFontFaceSet.instance.clear_Callback_0_(unwrap_jso(this));
  
  @DomName('FontFaceSet.delete')
  @DocsEditable()
  @Experimental() // untriaged
  bool delete(FontFace fontFace) => _blink.BlinkFontFaceSet.instance.delete_Callback_1_(unwrap_jso(this), unwrap_jso(fontFace));
  
  void forEach(FontFaceSetForEachCallback callback, [Object thisArg]) {
    if (thisArg != null) {
      _blink.BlinkFontFaceSet.instance.forEach_Callback_2_(unwrap_jso(this), unwrap_jso((fontFace, fontFaceAgain, set) => callback(wrap_jso(fontFace), wrap_jso(fontFaceAgain), wrap_jso(set))), thisArg);
      return;
    }
    _blink.BlinkFontFaceSet.instance.forEach_Callback_1_(unwrap_jso(this), unwrap_jso((fontFace, fontFaceAgain, set) => callback(wrap_jso(fontFace), wrap_jso(fontFaceAgain), wrap_jso(set))));
    return;
  }

  @DomName('FontFaceSet.has')
  @DocsEditable()
  @Experimental() // untriaged
  bool has(FontFace fontFace) => _blink.BlinkFontFaceSet.instance.has_Callback_1_(unwrap_jso(this), unwrap_jso(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")
  static FontFaceSetLoadEvent internalCreateFontFaceSetLoadEvent() {
    return new FontFaceSetLoadEvent._internalWrap();
  }

  external factory FontFaceSetLoadEvent._internalWrap();

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


  @DomName('FontFaceSetLoadEvent.fontfaces')
  @DocsEditable()
  @Experimental() // untriaged
  List<FontFace> get fontfaces => wrap_jso(_blink.BlinkFontFaceSetLoadEvent.instance.fontfaces_Getter_(unwrap_jso(this)));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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]) => wrap_jso(_create(form));

  @DocsEditable()
  static FormData _create(form) => wrap_jso(_blink.BlinkFormData.instance.constructorCallback_1_(form));

  @Deprecated("Internal Use Only")
  static FormData internalCreateFormData() {
    return new FormData._internalWrap();
  }

  factory FormData._internalWrap() {
    return new FormData.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  /// 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_(unwrap_jso(this), name, value);
  
  @DomName('FormData.appendBlob')
  @DocsEditable()
  void appendBlob(String name, Blob value, [String filename]) => _blink.BlinkFormData.instance.append_Callback_3_(unwrap_jso(this), name, unwrap_jso(value), filename);
  
  @DomName('FormData.delete')
  @DocsEditable()
  @Experimental() // untriaged
  void delete(String name) => _blink.BlinkFormData.instance.delete_Callback_1_(unwrap_jso(this), name);
  
  @DomName('FormData.get')
  @DocsEditable()
  @Experimental() // untriaged
  Object get(String name) => wrap_jso(_blink.BlinkFormData.instance.get_Callback_1_(unwrap_jso(this), name));
  
  @DomName('FormData.getAll')
  @DocsEditable()
  @Experimental() // untriaged
  List<Object> getAll(String name) => _blink.BlinkFormData.instance.getAll_Callback_1_(unwrap_jso(this), name);
  
  @DomName('FormData.has')
  @DocsEditable()
  @Experimental() // untriaged
  bool has(String name) => _blink.BlinkFormData.instance.has_Callback_1_(unwrap_jso(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_(unwrap_jso(this), name, unwrap_jso(value));
      return;
    }
    if ((filename is String || filename == null) && (value is Blob || value == null) && (name is String || name == null)) {
      _blink.BlinkFormData.instance.set_Callback_3_(unwrap_jso(this), name, unwrap_jso(value), filename);
      return;
    }
    if ((value is String || value == null) && (name is String || name == null) && filename == null) {
      _blink.BlinkFormData.instance.set_Callback_2_(unwrap_jso(this), name, unwrap_jso(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")
  static FormElement internalCreateFormElement() {
    return new FormElement._internalWrap();
  }

  external factory FormElement._internalWrap();

  @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_(unwrap_jso(this));
  
  @DomName('HTMLFormElement.acceptCharset')
  @DocsEditable()
  set acceptCharset(String value) => _blink.BlinkHTMLFormElement.instance.acceptCharset_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLFormElement.action')
  @DocsEditable()
  String get action => _blink.BlinkHTMLFormElement.instance.action_Getter_(unwrap_jso(this));
  
  @DomName('HTMLFormElement.action')
  @DocsEditable()
  set action(String value) => _blink.BlinkHTMLFormElement.instance.action_Setter_(unwrap_jso(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_(unwrap_jso(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_(unwrap_jso(this), value);
  
  @DomName('HTMLFormElement.encoding')
  @DocsEditable()
  String get encoding => _blink.BlinkHTMLFormElement.instance.encoding_Getter_(unwrap_jso(this));
  
  @DomName('HTMLFormElement.encoding')
  @DocsEditable()
  set encoding(String value) => _blink.BlinkHTMLFormElement.instance.encoding_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLFormElement.enctype')
  @DocsEditable()
  String get enctype => _blink.BlinkHTMLFormElement.instance.enctype_Getter_(unwrap_jso(this));
  
  @DomName('HTMLFormElement.enctype')
  @DocsEditable()
  set enctype(String value) => _blink.BlinkHTMLFormElement.instance.enctype_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLFormElement.length')
  @DocsEditable()
  int get length => _blink.BlinkHTMLFormElement.instance.length_Getter_(unwrap_jso(this));
  
  @DomName('HTMLFormElement.method')
  @DocsEditable()
  String get method => _blink.BlinkHTMLFormElement.instance.method_Getter_(unwrap_jso(this));
  
  @DomName('HTMLFormElement.method')
  @DocsEditable()
  set method(String value) => _blink.BlinkHTMLFormElement.instance.method_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLFormElement.name')
  @DocsEditable()
  String get name => _blink.BlinkHTMLFormElement.instance.name_Getter_(unwrap_jso(this));
  
  @DomName('HTMLFormElement.name')
  @DocsEditable()
  set name(String value) => _blink.BlinkHTMLFormElement.instance.name_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLFormElement.noValidate')
  @DocsEditable()
  bool get noValidate => _blink.BlinkHTMLFormElement.instance.noValidate_Getter_(unwrap_jso(this));
  
  @DomName('HTMLFormElement.noValidate')
  @DocsEditable()
  set noValidate(bool value) => _blink.BlinkHTMLFormElement.instance.noValidate_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLFormElement.target')
  @DocsEditable()
  String get target => _blink.BlinkHTMLFormElement.instance.target_Getter_(unwrap_jso(this));
  
  @DomName('HTMLFormElement.target')
  @DocsEditable()
  set target(String value) => _blink.BlinkHTMLFormElement.instance.target_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLFormElement.__getter__')
  @DocsEditable()
  Object __getter__(String name) => wrap_jso(_blink.BlinkHTMLFormElement.instance.$__getter___Callback_1_(unwrap_jso(this), name));
  
  @DomName('HTMLFormElement.checkValidity')
  @DocsEditable()
  bool checkValidity() => _blink.BlinkHTMLFormElement.instance.checkValidity_Callback_0_(unwrap_jso(this));
  
  @DomName('HTMLFormElement.item')
  @DocsEditable()
  @Experimental() // untriaged
  Element item(int index) => wrap_jso(_blink.BlinkHTMLFormElement.instance.item_Callback_1_(unwrap_jso(this), index));
  
  @DomName('HTMLFormElement.reportValidity')
  @DocsEditable()
  @Experimental() // untriaged
  bool reportValidity() => _blink.BlinkHTMLFormElement.instance.reportValidity_Callback_0_(unwrap_jso(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_(unwrap_jso(this), convertDartToNative_Dictionary(details));
  
  @DomName('HTMLFormElement.reset')
  @DocsEditable()
  void reset() => _blink.BlinkHTMLFormElement.instance.reset_Callback_0_(unwrap_jso(this));
  
  @DomName('HTMLFormElement.submit')
  @DocsEditable()
  void submit() => _blink.BlinkHTMLFormElement.instance.submit_Callback_0_(unwrap_jso(this));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of 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")
  static Gamepad internalCreateGamepad() {
    return new Gamepad._internalWrap();
  }

  factory Gamepad._internalWrap() {
    return new Gamepad.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  @DomName('Gamepad.axes')
  @DocsEditable()
  List<num> get axes => wrap_jso(_blink.BlinkGamepad.instance.axes_Getter_(unwrap_jso(this)));
  
  @DomName('Gamepad.buttons')
  @DocsEditable()
  List<GamepadButton> get buttons => wrap_jso(_blink.BlinkGamepad.instance.buttons_Getter_(unwrap_jso(this)));
  
  @DomName('Gamepad.connected')
  @DocsEditable()
  @Experimental() // untriaged
  bool get connected => _blink.BlinkGamepad.instance.connected_Getter_(unwrap_jso(this));
  
  @DomName('Gamepad.id')
  @DocsEditable()
  String get id => _blink.BlinkGamepad.instance.id_Getter_(unwrap_jso(this));
  
  @DomName('Gamepad.index')
  @DocsEditable()
  int get index => _blink.BlinkGamepad.instance.index_Getter_(unwrap_jso(this));
  
  @DomName('Gamepad.mapping')
  @DocsEditable()
  @Experimental() // untriaged
  String get mapping => _blink.BlinkGamepad.instance.mapping_Getter_(unwrap_jso(this));
  
  @DomName('Gamepad.timestamp')
  @DocsEditable()
  int get timestamp => _blink.BlinkGamepad.instance.timestamp_Getter_(unwrap_jso(this));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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")
  static GamepadButton internalCreateGamepadButton() {
    return new GamepadButton._internalWrap();
  }

  factory GamepadButton._internalWrap() {
    return new GamepadButton.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  @DomName('GamepadButton.pressed')
  @DocsEditable()
  @Experimental() // untriaged
  bool get pressed => _blink.BlinkGamepadButton.instance.pressed_Getter_(unwrap_jso(this));
  
  @DomName('GamepadButton.value')
  @DocsEditable()
  @Experimental() // untriaged
  num get value => _blink.BlinkGamepadButton.instance.value_Getter_(unwrap_jso(this));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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 wrap_jso(_blink.BlinkGamepadEvent.instance.constructorCallback_2_(type, eventInitDict_1));
    }
    return wrap_jso(_blink.BlinkGamepadEvent.instance.constructorCallback_1_(type));
  }


  @Deprecated("Internal Use Only")
  static GamepadEvent internalCreateGamepadEvent() {
    return new GamepadEvent._internalWrap();
  }

  external factory GamepadEvent._internalWrap();

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


  @DomName('GamepadEvent.gamepad')
  @DocsEditable()
  @Experimental() // untriaged
  Gamepad get gamepad => wrap_jso(_blink.BlinkGamepadEvent.instance.gamepad_Getter_(unwrap_jso(this)));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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")
  static Geofencing internalCreateGeofencing() {
    return new Geofencing._internalWrap();
  }

  factory Geofencing._internalWrap() {
    return new Geofencing.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  @DomName('Geofencing.getRegisteredRegions')
  @DocsEditable()
  @Experimental() // untriaged
  Future getRegisteredRegions() => wrap_jso(_blink.BlinkGeofencing.instance.getRegisteredRegions_Callback_0_(unwrap_jso(this)));
  
  @DomName('Geofencing.registerRegion')
  @DocsEditable()
  @Experimental() // untriaged
  Future registerRegion(GeofencingRegion region) => wrap_jso(_blink.BlinkGeofencing.instance.registerRegion_Callback_1_(unwrap_jso(this), unwrap_jso(region)));
  
  @DomName('Geofencing.unregisterRegion')
  @DocsEditable()
  @Experimental() // untriaged
  Future unregisterRegion(String regionId) => wrap_jso(_blink.BlinkGeofencing.instance.unregisterRegion_Callback_1_(unwrap_jso(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")
  static GeofencingEvent internalCreateGeofencingEvent() {
    return new GeofencingEvent._internalWrap();
  }

  external factory GeofencingEvent._internalWrap();

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


  @DomName('GeofencingEvent.id')
  @DocsEditable()
  @Experimental() // untriaged
  String get id => _blink.BlinkGeofencingEvent.instance.id_Getter_(unwrap_jso(this));
  
  @DomName('GeofencingEvent.region')
  @DocsEditable()
  @Experimental() // untriaged
  GeofencingRegion get region => wrap_jso(_blink.BlinkGeofencingEvent.instance.region_Getter_(unwrap_jso(this)));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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")
  static GeofencingRegion internalCreateGeofencingRegion() {
    return new GeofencingRegion._internalWrap();
  }

  factory GeofencingRegion._internalWrap() {
    return new GeofencingRegion.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  @DomName('GeofencingRegion.id')
  @DocsEditable()
  @Experimental() // untriaged
  String get id => _blink.BlinkGeofencingRegion.instance.id_Getter_(unwrap_jso(this));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All 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;
    var controller;
    controller = new StreamController<Geoposition>(sync: true,
      onListen: () {
        assert(watchId == null);
        watchId = _watchPosition(
            (position) {
              controller.add(_ensurePosition(position));
            },
            (error) {
              controller.addError(error);
            },
            options);
      },
      onCancel: () {
        assert(watchId != null);
        _clearWatch(watchId);
      });

    return controller.stream;
  }

  Geoposition _ensurePosition(domPosition) {
    return domPosition;
  }

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

  @Deprecated("Internal Use Only")
  static Geolocation internalCreateGeolocation() {
    return new Geolocation._internalWrap();
  }

  factory Geolocation._internalWrap() {
    return new Geolocation.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  @DomName('Geolocation.clearWatch')
  @DocsEditable()
  void _clearWatch(int watchID) => _blink.BlinkGeolocation.instance.clearWatch_Callback_1_(unwrap_jso(this), watchID);
  
  void _getCurrentPosition(_PositionCallback successCallback, [_PositionErrorCallback errorCallback, Map options]) {
    if (options != null) {
      _blink.BlinkGeolocation.instance.getCurrentPosition_Callback_3_(unwrap_jso(this), unwrap_jso((position) => successCallback(wrap_jso(position))), unwrap_jso((error) => errorCallback(wrap_jso(error))), convertDartToNative_Dictionary(options));
      return;
    }
    if (errorCallback != null) {
      _blink.BlinkGeolocation.instance.getCurrentPosition_Callback_2_(unwrap_jso(this), unwrap_jso((position) => successCallback(wrap_jso(position))), unwrap_jso((error) => errorCallback(wrap_jso(error))));
      return;
    }
    _blink.BlinkGeolocation.instance.getCurrentPosition_Callback_1_(unwrap_jso(this), unwrap_jso((position) => successCallback(wrap_jso(position))));
    return;
  }

  int _watchPosition(_PositionCallback successCallback, [_PositionErrorCallback errorCallback, Map options]) {
    if (options != null) {
      return _blink.BlinkGeolocation.instance.watchPosition_Callback_3_(unwrap_jso(this), unwrap_jso((position) => successCallback(wrap_jso(position))), unwrap_jso((error) => errorCallback(wrap_jso(error))), convertDartToNative_Dictionary(options));
    }
    if (errorCallback != null) {
      return _blink.BlinkGeolocation.instance.watchPosition_Callback_2_(unwrap_jso(this), unwrap_jso((position) => successCallback(wrap_jso(position))), unwrap_jso((error) => errorCallback(wrap_jso(error))));
    }
    return _blink.BlinkGeolocation.instance.watchPosition_Callback_1_(unwrap_jso(this), unwrap_jso((position) => successCallback(wrap_jso(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('Geoposition')
@Unstable()
class Geoposition extends DartHtmlDomObject {
  // To suppress missing implicit constructor warnings.
  factory Geoposition._() { throw new UnsupportedError("Not supported"); }

  @Deprecated("Internal Use Only")
  static Geoposition internalCreateGeoposition() {
    return new Geoposition._internalWrap();
  }

  factory Geoposition._internalWrap() {
    return new Geoposition.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  @DomName('Geoposition.coords')
  @DocsEditable()
  Coordinates get coords => wrap_jso(_blink.BlinkGeoposition.instance.coords_Getter_(unwrap_jso(this)));
  
  @DomName('Geoposition.timestamp')
  @DocsEditable()
  int get timestamp => _blink.BlinkGeoposition.instance.timestamp_Getter_(unwrap_jso(this));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for 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")
  static HRElement internalCreateHRElement() {
    return new HRElement._internalWrap();
  }

  external factory HRElement._internalWrap();

  @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_(unwrap_jso(this));
  
  @DomName('HTMLHRElement.color')
  @DocsEditable()
  @Experimental() // untriaged
  set color(String value) => _blink.BlinkHTMLHRElement.instance.color_Setter_(unwrap_jso(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 wrap_jso(_blink.BlinkHashChangeEvent.instance.constructorCallback_2_(type, eventInitDict_1));
    }
    return wrap_jso(_blink.BlinkHashChangeEvent.instance.constructorCallback_1_(type));
  }


  @Deprecated("Internal Use Only")
  static HashChangeEvent internalCreateHashChangeEvent() {
    return new HashChangeEvent._internalWrap();
  }

  external factory HashChangeEvent._internalWrap();

  @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_(unwrap_jso(this));
  
  @DomName('HashChangeEvent.oldURL')
  @DocsEditable()
  String get oldUrl => _blink.BlinkHashChangeEvent.instance.oldURL_Getter_(unwrap_jso(this));
  
  @DomName('HashChangeEvent.initHashChangeEvent')
  @DocsEditable()
  void _initHashChangeEvent(String type, bool canBubble, bool cancelable, String oldURL, String newURL) => _blink.BlinkHashChangeEvent.instance.initHashChangeEvent_Callback_5_(unwrap_jso(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")
  static HeadElement internalCreateHeadElement() {
    return new HeadElement._internalWrap();
  }

  external factory HeadElement._internalWrap();

  @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 wrap_jso(_blink.BlinkHeaders.instance.constructorCallback_0_());
    }
    if ((input is Headers)) {
      return wrap_jso(_blink.BlinkHeaders.instance.constructorCallback_1_(input));
    }
    if ((input is Map)) {
      var input_1 = convertDartToNative_Dictionary(input);
      return wrap_jso(_blink.BlinkHeaders.instance.constructorCallback_1_(input_1));
    }
    if ((input is List<Object>)) {
      return wrap_jso(_blink.BlinkHeaders.instance.constructorCallback_1_(input));
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }

  @Deprecated("Internal Use Only")
  static Headers internalCreateHeaders() {
    return new Headers._internalWrap();
  }

  factory Headers._internalWrap() {
    return new Headers.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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")
  static HeadingElement internalCreateHeadingElement() {
    return new HeadingElement._internalWrap();
  }

  external factory HeadingElement._internalWrap();

  @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")
  static History internalCreateHistory() {
    return new History._internalWrap();
  }

  factory History._internalWrap() {
    return new History.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  @DomName('History.length')
  @DocsEditable()
  int get length => _blink.BlinkHistory.instance.length_Getter_(unwrap_jso(this));
  
  @DomName('History.options')
  @DocsEditable()
  @Experimental() // untriaged
   get options => convertNativeDictionaryToDartDictionary(wrap_jso(_blink.BlinkHistory.instance.options_Getter_(unwrap_jso(this))));
  
  @DomName('History.state')
  @DocsEditable()
  dynamic get state => wrap_jso(_blink.BlinkHistory.instance.state_Getter_(unwrap_jso(this)));
  
  @DomName('History.back')
  @DocsEditable()
  void back() => _blink.BlinkHistory.instance.back_Callback_0_(unwrap_jso(this));
  
  @DomName('History.forward')
  @DocsEditable()
  void forward() => _blink.BlinkHistory.instance.forward_Callback_0_(unwrap_jso(this));
  
  void go([int delta]) {
    if (delta != null) {
      _blink.BlinkHistory.instance.go_Callback_1_(unwrap_jso(this), delta);
      return;
    }
    _blink.BlinkHistory.instance.go_Callback_0_(unwrap_jso(this));
    return;
  }

  void pushState(/*SerializedScriptValue*/ data, String title, String url, [Map options]) {
    if (options != null) {
      _blink.BlinkHistory.instance.pushState_Callback_4_(unwrap_jso(this), convertDartToNative_SerializedScriptValue(data), title, url, convertDartToNative_Dictionary(options));
      return;
    }
    _blink.BlinkHistory.instance.pushState_Callback_3_(unwrap_jso(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_(unwrap_jso(this), convertDartToNative_SerializedScriptValue(data), title, url, convertDartToNative_Dictionary(options));
      return;
    }
    _blink.BlinkHistory.instance.replaceState_Callback_3_(unwrap_jso(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")
  static HmdvrDevice internalCreateHmdvrDevice() {
    return new HmdvrDevice._internalWrap();
  }

  external factory HmdvrDevice._internalWrap();

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


  @DomName('HMDVRDevice.getEyeParameters')
  @DocsEditable()
  @Experimental() // untriaged
  VREyeParameters getEyeParameters(String whichEye) => wrap_jso(_blink.BlinkHMDVRDevice.instance.getEyeParameters_Callback_1_(unwrap_jso(this), whichEye));
  
  void setFieldOfView([VRFieldOfView leftFov, VRFieldOfView rightFov]) {
    if (rightFov != null) {
      _blink.BlinkHMDVRDevice.instance.setFieldOfView_Callback_2_(unwrap_jso(this), unwrap_jso(leftFov), unwrap_jso(rightFov));
      return;
    }
    if (leftFov != null) {
      _blink.BlinkHMDVRDevice.instance.setFieldOfView_Callback_1_(unwrap_jso(this), unwrap_jso(leftFov));
      return;
    }
    _blink.BlinkHMDVRDevice.instance.setFieldOfView_Callback_0_(unwrap_jso(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")
  static HtmlCollection internalCreateHtmlCollection() {
    return new HtmlCollection._internalWrap();
  }

  factory HtmlCollection._internalWrap() {
    return new HtmlCollection.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  @DomName('HTMLCollection.length')
  @DocsEditable()
  int get length => _blink.BlinkHTMLCollection.instance.length_Getter_(unwrap_jso(this));
  
  Node operator[](int index) {
    if (index < 0 || index >= length)
      throw new RangeError.index(index, this);
    return wrap_jso(_blink.BlinkHTMLCollection.instance.item_Callback_1_(unwrap_jso(this), index));
  }

  Node _nativeIndexedGetter(int index) => wrap_jso(_blink.BlinkHTMLCollection.instance.item_Callback_1_(unwrap_jso(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()
  Element item(int index) => wrap_jso(_blink.BlinkHTMLCollection.instance.item_Callback_1_(unwrap_jso(this), index));
  
  @DomName('HTMLCollection.namedItem')
  @DocsEditable()
  Element namedItem(String name) => wrap_jso(_blink.BlinkHTMLCollection.instance.namedItem_Callback_1_(unwrap_jso(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")
  static HtmlDocument internalCreateHtmlDocument() {
    return new HtmlDocument._internalWrap();
  }

  external factory HtmlDocument._internalWrap();

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

  /**
   * Returns the element, if any, that is currently displayed in fullscreen.
   *
   * Returns null if there is currently no fullscreen element. You can use
   * this to determine if the page is in fullscreen mode.
   *
   *     myVideo = new VideoElement();
   *     if (document.fullscreenElement == null) {
   *       myVideo.requestFullscreen();
   *       print(document.fullscreenElement == myVideo); // true
   *     }
   *
   * ## Other resources
   *
   * * [Using the fullscreen
   *   API](http://docs.webplatform.org/wiki/tutorials/using_the_full-screen_api)
   *   from WebPlatform.org.
   * * [Fullscreen specification](http://www.w3.org/TR/fullscreen/) from W3C.
   */
  @DomName('Document.webkitFullscreenElement')
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  Element get fullscreenElement => _webkitFullscreenElement;

  /**
   * Returns true if this document can display elements in fullscreen mode.
   *
   * ## Other resources
   *
   * * [Using the fullscreen
   *   API](http://docs.webplatform.org/wiki/tutorials/using_the_full-screen_api)
   *   from WebPlatform.org.
   * * [Fullscreen specification](http://www.w3.org/TR/fullscreen/) from W3C.
   */
  @DomName('Document.webkitFullscreenEnabled')
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  bool get fullscreenEnabled => _webkitFullscreenEnabled;

  @DomName('Document.webkitHidden')
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  bool get hidden => _webkitHidden;

  @DomName('Document.visibilityState')
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.FIREFOX)
  @SupportedBrowser(SupportedBrowser.IE, '10')
  @Experimental()
  String get visibilityState => _webkitVisibilityState;

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

      // Remember for any upgrading done in wrap_jso.
      addCustomElementType(tag, customElementClass, extendsTag);

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

      // If any JS code is hooked we want to call it too.
      var oldCreatedCallback = elemProto['createdCallback'];
      var oldAttributeChangedCallback = elemProto['attributeChangedCallback'];
      var oldAttachedCallback = elemProto['attachedCallback'];
      var oldDetachedCallback = elemProto['detachedCallback'];

      // TODO(jacobr): warning:
      elemProto['createdCallback'] = js.JsNative.withThis(($this) {
        if (_getJSClassName(reflectClass(customElementClass).superclass) != null && creating < 2) {
          creating++;

          var dartClass;
          try {
            if (extendsTag != null) {
              // If we're extending a native element then create that element.
              // Then upgrade that element to the customElementClass through
              // normal flow.
              dartClass = document.createElement(extendsTag);
              js.setDartHtmlWrapperFor($this, dartClass);
              dartClass.blink_jsObject = $this;
            }

            // Upgrade to the CustomElement Dart class.
            dartClass = _blink.Blink_Utils.constructElement(customElementClass, $this);
          } catch (e) {
            // Got a problem make it an HtmlElement and rethrow the error.
            dartClass = HtmlElement.internalCreateHtmlElement();
            // We need to remember the JS object (because constructElement failed
            // it normally sets up the blink_jsObject.
            dartClass.blink_jsObject = $this;

            // Mark to only try this once don't try upgrading from HtmlElement
            // to the user's Dart class - we had a problem.
            dartClass._badUpgrade();
            throw e;
          } finally {
            // Need to remember the Dart class that was created for this custom so
            // return it and setup the blink_jsObject to the $this that we'll be working
            // with as we talk to blink.
            js.setDartHtmlWrapperFor($this, dartClass);

            creating--;
          }
        }

        if (oldCreatedCallback != null)
          oldCreatedCallback.apply([], thisArg: unwrap_jso($this));
      });
      elemProto['attributeChangedCallback'] = new js.JsFunction.withThis(($this, attrName, oldVal, newVal) {
        $this.attributeChanged(attrName, oldVal, newVal);

        if (oldAttributeChangedCallback != null)
          oldAttributeChangedCallback.apply([], thisArg: unwrap_jso($this));
      });
      elemProto['attachedCallback'] = new js.JsFunction.withThis(($this) {
        $this.attached();

        if (oldAttachedCallback != null)
          oldAttachedCallback.apply([], thisArg: unwrap_jso($this));
      });
      elemProto['detachedCallback'] = new js.JsFunction.withThis(($this) {
        $this.detached();

        if (oldDetachedCallback != null)
          oldDetachedCallback.apply([], thisArg: unwrap_jso($this));
      });
      // document.registerElement('x-foo', {prototype: elemProto, extends: extendsTag});
      var jsMap = new js.JsObject.jsify({'prototype': elemProto, 'extends': extendsTag});
      js.JsNative.callMethod(js.JsNative.getProperty(js.context, '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")
  static HtmlElement internalCreateHtmlElement() {
    return new HtmlElement._internalWrap();
  }

  external factory HtmlElement._internalWrap();

  @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_(unwrap_jso(this));
  
  @DomName('HTMLElement.contentEditable')
  @DocsEditable()
  set contentEditable(String value) => _blink.BlinkHTMLElement.instance.contentEditable_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLElement.contextMenu')
  @DocsEditable()
  @Experimental() // untriaged
  MenuElement get contextMenu => wrap_jso(_blink.BlinkHTMLElement.instance.contextMenu_Getter_(unwrap_jso(this)));
  
  @DomName('HTMLElement.contextMenu')
  @DocsEditable()
  @Experimental() // untriaged
  set contextMenu(MenuElement value) => _blink.BlinkHTMLElement.instance.contextMenu_Setter_(unwrap_jso(this), unwrap_jso(value));
  
  @DomName('HTMLElement.dir')
  @DocsEditable()
  String get dir => _blink.BlinkHTMLElement.instance.dir_Getter_(unwrap_jso(this));
  
  @DomName('HTMLElement.dir')
  @DocsEditable()
  set dir(String value) => _blink.BlinkHTMLElement.instance.dir_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLElement.draggable')
  @DocsEditable()
  bool get draggable => _blink.BlinkHTMLElement.instance.draggable_Getter_(unwrap_jso(this));
  
  @DomName('HTMLElement.draggable')
  @DocsEditable()
  set draggable(bool value) => _blink.BlinkHTMLElement.instance.draggable_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLElement.hidden')
  @DocsEditable()
  bool get hidden => _blink.BlinkHTMLElement.instance.hidden_Getter_(unwrap_jso(this));
  
  @DomName('HTMLElement.hidden')
  @DocsEditable()
  set hidden(bool value) => _blink.BlinkHTMLElement.instance.hidden_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLElement.isContentEditable')
  @DocsEditable()
  bool get isContentEditable => _blink.BlinkHTMLElement.instance.isContentEditable_Getter_(unwrap_jso(this));
  
  @DomName('HTMLElement.lang')
  @DocsEditable()
  String get lang => _blink.BlinkHTMLElement.instance.lang_Getter_(unwrap_jso(this));
  
  @DomName('HTMLElement.lang')
  @DocsEditable()
  set lang(String value) => _blink.BlinkHTMLElement.instance.lang_Setter_(unwrap_jso(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_(unwrap_jso(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_(unwrap_jso(this), value);
  
  @DomName('HTMLElement.style')
  @DocsEditable()
  @Experimental() // untriaged
  CssStyleDeclaration get style => wrap_jso(_blink.BlinkHTMLElement.instance.style_Getter_(unwrap_jso(this)));
  
  @DomName('HTMLElement.tabIndex')
  @DocsEditable()
  int get tabIndex => _blink.BlinkHTMLElement.instance.tabIndex_Getter_(unwrap_jso(this));
  
  @DomName('HTMLElement.tabIndex')
  @DocsEditable()
  set tabIndex(int value) => _blink.BlinkHTMLElement.instance.tabIndex_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLElement.title')
  @DocsEditable()
  String get title => _blink.BlinkHTMLElement.instance.title_Getter_(unwrap_jso(this));
  
  @DomName('HTMLElement.title')
  @DocsEditable()
  set title(String value) => _blink.BlinkHTMLElement.instance.title_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLElement.translate')
  @DocsEditable()
  bool get translate => _blink.BlinkHTMLElement.instance.translate_Getter_(unwrap_jso(this));
  
  @DomName('HTMLElement.translate')
  @DocsEditable()
  set translate(bool value) => _blink.BlinkHTMLElement.instance.translate_Setter_(unwrap_jso(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_(unwrap_jso(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_(unwrap_jso(this), value);
  
  @DomName('HTMLElement.blur')
  @DocsEditable()
  @Experimental() // untriaged
  void blur() => _blink.BlinkHTMLElement.instance.blur_Callback_0_(unwrap_jso(this));
  
  @DomName('HTMLElement.click')
  @DocsEditable()
  void click() => _blink.BlinkHTMLElement.instance.click_Callback_0_(unwrap_jso(this));
  
  @DomName('HTMLElement.focus')
  @DocsEditable()
  @Experimental() // untriaged
  void focus() => _blink.BlinkHTMLElement.instance.focus_Callback_0_(unwrap_jso(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);

  // Flags to only try upgrading once. If there's a failure don't try upgrading
  // anymore.
  bool _badUpgradeOccurred = false;

  /// Required for SDK Infrastructure. Internal use only.
  ///
  /// Did this encounter a failure attempting to upgrade to
  /// a custom element.
  @Deprecated("Required for SDK Infrastructure. Internal use only.")
  bool get isBadUpgrade => _badUpgradeOccurred;

  void _badUpgrade() { _badUpgradeOccurred = 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('HTMLFormControlsCollection')
class HtmlFormControlsCollection extends HtmlCollection {
  // To suppress missing implicit constructor warnings.
  factory HtmlFormControlsCollection._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  static HtmlFormControlsCollection internalCreateHtmlFormControlsCollection() {
    return new HtmlFormControlsCollection._internalWrap();
  }

  external factory HtmlFormControlsCollection._internalWrap();

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


  @DomName('HTMLFormControlsCollection.item')
  @DocsEditable()
  @Experimental() // untriaged
  Node item(int index) => wrap_jso(_blink.BlinkHTMLFormControlsCollection.instance.item_Callback_1_(unwrap_jso(this), index));
  
  @DomName('HTMLFormControlsCollection.namedItem')
  @DocsEditable()
  Object namedItem(String name) => wrap_jso(_blink.BlinkHTMLFormControlsCollection.instance.namedItem_Callback_1_(unwrap_jso(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")
  static HtmlHtmlElement internalCreateHtmlHtmlElement() {
    return new HtmlHtmlElement._internalWrap();
  }

  external factory HtmlHtmlElement._internalWrap();

  @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")
  static HtmlOptionsCollection internalCreateHtmlOptionsCollection() {
    return new HtmlOptionsCollection._internalWrap();
  }

  external factory HtmlOptionsCollection._internalWrap();

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


  @DomName('HTMLOptionsCollection.item')
  @DocsEditable()
  @Experimental() // untriaged
  Node _item(int index) => wrap_jso(_blink.BlinkHTMLOptionsCollection.instance.item_Callback_1_(unwrap_jso(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_(unwrap_jso(this), method, url);
    } else {
      _blink.BlinkXMLHttpRequest.instance.open_Callback_5_(unwrap_jso(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 wrap_jso(_blink.BlinkXMLHttpRequest.instance.constructorCallback_0_());
  }


  @Deprecated("Internal Use Only")
  static HttpRequest internalCreateHttpRequest() {
    return new HttpRequest._internalWrap();
  }

  external factory HttpRequest._internalWrap();

  @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_(unwrap_jso(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 => wrap_jso(_blink.BlinkXMLHttpRequest.instance.response_Getter_(unwrap_jso(this)));
  
  /**
   * The response in String form or empty String on failure.
   */
  @DomName('XMLHttpRequest.responseText')
  @DocsEditable()
  String get responseText => _blink.BlinkXMLHttpRequest.instance.responseText_Getter_(unwrap_jso(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_(unwrap_jso(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_(unwrap_jso(this), value);
  
  @DomName('XMLHttpRequest.responseURL')
  @DocsEditable()
  @Experimental() // untriaged
  String get responseUrl => _blink.BlinkXMLHttpRequest.instance.responseURL_Getter_(unwrap_jso(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 => wrap_jso(_blink.BlinkXMLHttpRequest.instance.responseXML_Getter_(unwrap_jso(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_(unwrap_jso(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_(unwrap_jso(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_(unwrap_jso(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_(unwrap_jso(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 => wrap_jso(_blink.BlinkXMLHttpRequest.instance.upload_Getter_(unwrap_jso(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_(unwrap_jso(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_(unwrap_jso(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_(unwrap_jso(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_(unwrap_jso(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_(unwrap_jso(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_(unwrap_jso(this), mime);
  
  void send([body_OR_data]) {
    if (body_OR_data != null) {
      _blink.BlinkXMLHttpRequest.instance.send_Callback_1_(unwrap_jso(this), unwrap_jso(body_OR_data));
      return;
    }
    if ((body_OR_data is TypedData || body_OR_data == null)) {
      _blink.BlinkXMLHttpRequest.instance.send_Callback_1_(unwrap_jso(this), unwrap_jso(body_OR_data));
      return;
    }
    if ((body_OR_data is ByteBuffer || body_OR_data == null)) {
      _blink.BlinkXMLHttpRequest.instance.send_Callback_1_(unwrap_jso(this), unwrap_jso(body_OR_data));
      return;
    }
    if ((body_OR_data is Document || body_OR_data == null)) {
      _blink.BlinkXMLHttpRequest.instance.send_Callback_1_(unwrap_jso(this), unwrap_jso(body_OR_data));
      return;
    }
    if ((body_OR_data is String || body_OR_data == null)) {
      _blink.BlinkXMLHttpRequest.instance.send_Callback_1_(unwrap_jso(this), unwrap_jso(body_OR_data));
      return;
    }
    if ((body_OR_data is FormData || body_OR_data == null)) {
      _blink.BlinkXMLHttpRequest.instance.send_Callback_1_(unwrap_jso(this), unwrap_jso(body_OR_data));
      return;
    }
    if ((body_OR_data is Blob || body_OR_data == null)) {
      _blink.BlinkXMLHttpRequest.instance.send_Callback_1_(unwrap_jso(this), unwrap_jso(body_OR_data));
      return;
    }
    if (body_OR_data == null) {
      _blink.BlinkXMLHttpRequest.instance.send_Callback_0_(unwrap_jso(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_(unwrap_jso(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")
  static HttpRequestEventTarget internalCreateHttpRequestEventTarget() {
    return new HttpRequestEventTarget._internalWrap();
  }

  external factory HttpRequestEventTarget._internalWrap();

  @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")
  static HttpRequestUpload internalCreateHttpRequestUpload() {
    return new HttpRequestUpload._internalWrap();
  }

  external factory HttpRequestUpload._internalWrap();

  @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")
  static IFrameElement internalCreateIFrameElement() {
    return new IFrameElement._internalWrap();
  }

  external factory IFrameElement._internalWrap();

  @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_(unwrap_jso(this));
  
  @DomName('HTMLIFrameElement.allowFullscreen')
  @DocsEditable()
  @Experimental() // untriaged
  set allowFullscreen(bool value) => _blink.BlinkHTMLIFrameElement.instance.allowFullscreen_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLIFrameElement.contentWindow')
  @DocsEditable()
  WindowBase get contentWindow => wrap_jso(_blink.BlinkHTMLIFrameElement.instance.contentWindow_Getter_(unwrap_jso(this)));
  
  @DomName('HTMLIFrameElement.height')
  @DocsEditable()
  String get height => _blink.BlinkHTMLIFrameElement.instance.height_Getter_(unwrap_jso(this));
  
  @DomName('HTMLIFrameElement.height')
  @DocsEditable()
  set height(String value) => _blink.BlinkHTMLIFrameElement.instance.height_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLIFrameElement.name')
  @DocsEditable()
  String get name => _blink.BlinkHTMLIFrameElement.instance.name_Getter_(unwrap_jso(this));
  
  @DomName('HTMLIFrameElement.name')
  @DocsEditable()
  set name(String value) => _blink.BlinkHTMLIFrameElement.instance.name_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLIFrameElement.sandbox')
  @DocsEditable()
  DomSettableTokenList get sandbox => wrap_jso(_blink.BlinkHTMLIFrameElement.instance.sandbox_Getter_(unwrap_jso(this)));
  
  @DomName('HTMLIFrameElement.src')
  @DocsEditable()
  String get src => _blink.BlinkHTMLIFrameElement.instance.src_Getter_(unwrap_jso(this));
  
  @DomName('HTMLIFrameElement.src')
  @DocsEditable()
  set src(String value) => _blink.BlinkHTMLIFrameElement.instance.src_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLIFrameElement.srcdoc')
  @DocsEditable()
  String get srcdoc => _blink.BlinkHTMLIFrameElement.instance.srcdoc_Getter_(unwrap_jso(this));
  
  @DomName('HTMLIFrameElement.srcdoc')
  @DocsEditable()
  set srcdoc(String value) => _blink.BlinkHTMLIFrameElement.instance.srcdoc_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLIFrameElement.width')
  @DocsEditable()
  String get width => _blink.BlinkHTMLIFrameElement.instance.width_Getter_(unwrap_jso(this));
  
  @DomName('HTMLIFrameElement.width')
  @DocsEditable()
  set width(String value) => _blink.BlinkHTMLIFrameElement.instance.width_Setter_(unwrap_jso(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")
  static ImageBitmap internalCreateImageBitmap() {
    return new ImageBitmap._internalWrap();
  }

  factory ImageBitmap._internalWrap() {
    return new ImageBitmap.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  @DomName('ImageBitmap.height')
  @DocsEditable()
  @Experimental() // untriaged
  int get height => _blink.BlinkImageBitmap.instance.height_Getter_(unwrap_jso(this));
  
  @DomName('ImageBitmap.width')
  @DocsEditable()
  @Experimental() // untriaged
  int get width => _blink.BlinkImageBitmap.instance.width_Getter_(unwrap_jso(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 wrap_jso(_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 wrap_jso(_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 wrap_jso(_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")
  static ImageData internalCreateImageData() {
    return new ImageData._internalWrap();
  }

  factory ImageData._internalWrap() {
    return new ImageData.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  @DomName('ImageData.data')
  @DocsEditable()
  Uint8ClampedList get _data => wrap_jso(_blink.BlinkImageData.instance.data_Getter_(unwrap_jso(this)));
  
  @DomName('ImageData.height')
  @DocsEditable()
  int get height => _blink.BlinkImageData.instance.height_Getter_(unwrap_jso(this));
  
  @DomName('ImageData.width')
  @DocsEditable()
  int get width => _blink.BlinkImageData.instance.width_Getter_(unwrap_jso(this));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


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

  @DomName('HTMLImageElement.HTMLImageElement')
  @DocsEditable()
  factory ImageElement({String src, int width, int height}) {
    var e = document.createElement("img");
    if (src != null) e.src = src;
    if (width != null) e.width = width;
    if (height != null) e.height = height;
    return e;
  }


  @Deprecated("Internal Use Only")
  static ImageElement internalCreateImageElement() {
    return new ImageElement._internalWrap();
  }

  external factory ImageElement._internalWrap();

  @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_(unwrap_jso(this));
  
  @DomName('HTMLImageElement.alt')
  @DocsEditable()
  set alt(String value) => _blink.BlinkHTMLImageElement.instance.alt_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLImageElement.complete')
  @DocsEditable()
  bool get complete => _blink.BlinkHTMLImageElement.instance.complete_Getter_(unwrap_jso(this));
  
  @DomName('HTMLImageElement.crossOrigin')
  @DocsEditable()
  String get crossOrigin => _blink.BlinkHTMLImageElement.instance.crossOrigin_Getter_(unwrap_jso(this));
  
  @DomName('HTMLImageElement.crossOrigin')
  @DocsEditable()
  set crossOrigin(String value) => _blink.BlinkHTMLImageElement.instance.crossOrigin_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLImageElement.currentSrc')
  @DocsEditable()
  @Experimental() // untriaged
  String get currentSrc => _blink.BlinkHTMLImageElement.instance.currentSrc_Getter_(unwrap_jso(this));
  
  @DomName('HTMLImageElement.height')
  @DocsEditable()
  int get height => _blink.BlinkHTMLImageElement.instance.height_Getter_(unwrap_jso(this));
  
  @DomName('HTMLImageElement.height')
  @DocsEditable()
  set height(int value) => _blink.BlinkHTMLImageElement.instance.height_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLImageElement.isMap')
  @DocsEditable()
  bool get isMap => _blink.BlinkHTMLImageElement.instance.isMap_Getter_(unwrap_jso(this));
  
  @DomName('HTMLImageElement.isMap')
  @DocsEditable()
  set isMap(bool value) => _blink.BlinkHTMLImageElement.instance.isMap_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLImageElement.naturalHeight')
  @DocsEditable()
  int get naturalHeight => _blink.BlinkHTMLImageElement.instance.naturalHeight_Getter_(unwrap_jso(this));
  
  @DomName('HTMLImageElement.naturalWidth')
  @DocsEditable()
  int get naturalWidth => _blink.BlinkHTMLImageElement.instance.naturalWidth_Getter_(unwrap_jso(this));
  
  @DomName('HTMLImageElement.sizes')
  @DocsEditable()
  @Experimental() // untriaged
  String get sizes => _blink.BlinkHTMLImageElement.instance.sizes_Getter_(unwrap_jso(this));
  
  @DomName('HTMLImageElement.sizes')
  @DocsEditable()
  @Experimental() // untriaged
  set sizes(String value) => _blink.BlinkHTMLImageElement.instance.sizes_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLImageElement.src')
  @DocsEditable()
  String get src => _blink.BlinkHTMLImageElement.instance.src_Getter_(unwrap_jso(this));
  
  @DomName('HTMLImageElement.src')
  @DocsEditable()
  set src(String value) => _blink.BlinkHTMLImageElement.instance.src_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLImageElement.srcset')
  @DocsEditable()
  @Experimental() // untriaged
  String get srcset => _blink.BlinkHTMLImageElement.instance.srcset_Getter_(unwrap_jso(this));
  
  @DomName('HTMLImageElement.srcset')
  @DocsEditable()
  @Experimental() // untriaged
  set srcset(String value) => _blink.BlinkHTMLImageElement.instance.srcset_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLImageElement.useMap')
  @DocsEditable()
  String get useMap => _blink.BlinkHTMLImageElement.instance.useMap_Getter_(unwrap_jso(this));
  
  @DomName('HTMLImageElement.useMap')
  @DocsEditable()
  set useMap(String value) => _blink.BlinkHTMLImageElement.instance.useMap_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLImageElement.width')
  @DocsEditable()
  int get width => _blink.BlinkHTMLImageElement.instance.width_Getter_(unwrap_jso(this));
  
  @DomName('HTMLImageElement.width')
  @DocsEditable()
  set width(int value) => _blink.BlinkHTMLImageElement.instance.width_Setter_(unwrap_jso(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")
  static InjectedScriptHost internalCreateInjectedScriptHost() {
    return new InjectedScriptHost._internalWrap();
  }

  factory InjectedScriptHost._internalWrap() {
    return new InjectedScriptHost.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  @DomName('InjectedScriptHost.inspect')
  @DocsEditable()
  @Experimental() // untriaged
  void inspect(Object objectId, Object hints) => _blink.BlinkInjectedScriptHost.instance.inspect_Callback_2_(unwrap_jso(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 wrap_jso(_blink.BlinkInputDevice.instance.constructorCallback_1_(deviceInitDict_1));
    }
    return wrap_jso(_blink.BlinkInputDevice.instance.constructorCallback_0_());
  }

  @Deprecated("Internal Use Only")
  static InputDevice internalCreateInputDevice() {
    return new InputDevice._internalWrap();
  }

  factory InputDevice._internalWrap() {
    return new InputDevice.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  @DomName('InputDevice.firesTouchEvents')
  @DocsEditable()
  @Experimental() // untriaged
  bool get firesTouchEvents => _blink.BlinkInputDevice.instance.firesTouchEvents_Getter_(unwrap_jso(this));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


@DomName('HTMLInputElement')
class InputElement extends HtmlElement implements
    HiddenInputElement,
    SearchInputElement,
    TextInputElement,
    UrlInputElement,
    TelephoneInputElement,
    EmailInputElement,
    PasswordInputElement,
    DateInputElement,
    MonthInputElement,
    WeekInputElement,
    TimeInputElement,
    LocalDateTimeInputElement,
    NumberInputElement,
    RangeInputElement,
    CheckboxInputElement,
    RadioButtonInputElement,
    FileUploadInputElement,
    SubmitButtonInputElement,
    ImageButtonInputElement,
    ResetButtonInputElement,
    ButtonInputElement {

  factory InputElement({String type}) {
    var e = document.createElement("input");
    if (type != null) {
      try {
        // IE throws an exception for unknown types.
        e.type = type;
      } catch(_) {}
    }
    return e;
  }

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


  @Deprecated("Internal Use Only")
  static InputElement internalCreateInputElement() {
    return new InputElement._internalWrap();
  }

  external factory InputElement._internalWrap();

  @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_(unwrap_jso(this));
  
  @DomName('HTMLInputElement.accept')
  @DocsEditable()
  set accept(String value) => _blink.BlinkHTMLInputElement.instance.accept_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLInputElement.alt')
  @DocsEditable()
  String get alt => _blink.BlinkHTMLInputElement.instance.alt_Getter_(unwrap_jso(this));
  
  @DomName('HTMLInputElement.alt')
  @DocsEditable()
  set alt(String value) => _blink.BlinkHTMLInputElement.instance.alt_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLInputElement.autocapitalize')
  @DocsEditable()
  @Experimental() // untriaged
  String get autocapitalize => _blink.BlinkHTMLInputElement.instance.autocapitalize_Getter_(unwrap_jso(this));
  
  @DomName('HTMLInputElement.autocapitalize')
  @DocsEditable()
  @Experimental() // untriaged
  set autocapitalize(String value) => _blink.BlinkHTMLInputElement.instance.autocapitalize_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLInputElement.autocomplete')
  @DocsEditable()
  String get autocomplete => _blink.BlinkHTMLInputElement.instance.autocomplete_Getter_(unwrap_jso(this));
  
  @DomName('HTMLInputElement.autocomplete')
  @DocsEditable()
  set autocomplete(String value) => _blink.BlinkHTMLInputElement.instance.autocomplete_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLInputElement.autofocus')
  @DocsEditable()
  bool get autofocus => _blink.BlinkHTMLInputElement.instance.autofocus_Getter_(unwrap_jso(this));
  
  @DomName('HTMLInputElement.autofocus')
  @DocsEditable()
  set autofocus(bool value) => _blink.BlinkHTMLInputElement.instance.autofocus_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLInputElement.capture')
  @DocsEditable()
  @Experimental() // untriaged
  bool get capture => _blink.BlinkHTMLInputElement.instance.capture_Getter_(unwrap_jso(this));
  
  @DomName('HTMLInputElement.capture')
  @DocsEditable()
  @Experimental() // untriaged
  set capture(bool value) => _blink.BlinkHTMLInputElement.instance.capture_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLInputElement.checked')
  @DocsEditable()
  bool get checked => _blink.BlinkHTMLInputElement.instance.checked_Getter_(unwrap_jso(this));
  
  @DomName('HTMLInputElement.checked')
  @DocsEditable()
  set checked(bool value) => _blink.BlinkHTMLInputElement.instance.checked_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLInputElement.defaultChecked')
  @DocsEditable()
  bool get defaultChecked => _blink.BlinkHTMLInputElement.instance.defaultChecked_Getter_(unwrap_jso(this));
  
  @DomName('HTMLInputElement.defaultChecked')
  @DocsEditable()
  set defaultChecked(bool value) => _blink.BlinkHTMLInputElement.instance.defaultChecked_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLInputElement.defaultValue')
  @DocsEditable()
  String get defaultValue => _blink.BlinkHTMLInputElement.instance.defaultValue_Getter_(unwrap_jso(this));
  
  @DomName('HTMLInputElement.defaultValue')
  @DocsEditable()
  set defaultValue(String value) => _blink.BlinkHTMLInputElement.instance.defaultValue_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLInputElement.dirName')
  @DocsEditable()
  String get dirName => _blink.BlinkHTMLInputElement.instance.dirName_Getter_(unwrap_jso(this));
  
  @DomName('HTMLInputElement.dirName')
  @DocsEditable()
  set dirName(String value) => _blink.BlinkHTMLInputElement.instance.dirName_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLInputElement.disabled')
  @DocsEditable()
  bool get disabled => _blink.BlinkHTMLInputElement.instance.disabled_Getter_(unwrap_jso(this));
  
  @DomName('HTMLInputElement.disabled')
  @DocsEditable()
  set disabled(bool value) => _blink.BlinkHTMLInputElement.instance.disabled_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLInputElement.files')
  @DocsEditable()
  List<File> get files => wrap_jso(_blink.BlinkHTMLInputElement.instance.files_Getter_(unwrap_jso(this)));
  
  @DomName('HTMLInputElement.files')
  @DocsEditable()
  set files(List<File> value) => _blink.BlinkHTMLInputElement.instance.files_Setter_(unwrap_jso(this), unwrap_jso(value));
  
  @DomName('HTMLInputElement.form')
  @DocsEditable()
  FormElement get form => wrap_jso(_blink.BlinkHTMLInputElement.instance.form_Getter_(unwrap_jso(this)));
  
  @DomName('HTMLInputElement.formAction')
  @DocsEditable()
  String get formAction => _blink.BlinkHTMLInputElement.instance.formAction_Getter_(unwrap_jso(this));
  
  @DomName('HTMLInputElement.formAction')
  @DocsEditable()
  set formAction(String value) => _blink.BlinkHTMLInputElement.instance.formAction_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLInputElement.formEnctype')
  @DocsEditable()
  String get formEnctype => _blink.BlinkHTMLInputElement.instance.formEnctype_Getter_(unwrap_jso(this));
  
  @DomName('HTMLInputElement.formEnctype')
  @DocsEditable()
  set formEnctype(String value) => _blink.BlinkHTMLInputElement.instance.formEnctype_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLInputElement.formMethod')
  @DocsEditable()
  String get formMethod => _blink.BlinkHTMLInputElement.instance.formMethod_Getter_(unwrap_jso(this));
  
  @DomName('HTMLInputElement.formMethod')
  @DocsEditable()
  set formMethod(String value) => _blink.BlinkHTMLInputElement.instance.formMethod_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLInputElement.formNoValidate')
  @DocsEditable()
  bool get formNoValidate => _blink.BlinkHTMLInputElement.instance.formNoValidate_Getter_(unwrap_jso(this));
  
  @DomName('HTMLInputElement.formNoValidate')
  @DocsEditable()
  set formNoValidate(bool value) => _blink.BlinkHTMLInputElement.instance.formNoValidate_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLInputElement.formTarget')
  @DocsEditable()
  String get formTarget => _blink.BlinkHTMLInputElement.instance.formTarget_Getter_(unwrap_jso(this));
  
  @DomName('HTMLInputElement.formTarget')
  @DocsEditable()
  set formTarget(String value) => _blink.BlinkHTMLInputElement.instance.formTarget_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLInputElement.height')
  @DocsEditable()
  int get height => _blink.BlinkHTMLInputElement.instance.height_Getter_(unwrap_jso(this));
  
  @DomName('HTMLInputElement.height')
  @DocsEditable()
  set height(int value) => _blink.BlinkHTMLInputElement.instance.height_Setter_(unwrap_jso(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_(unwrap_jso(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_(unwrap_jso(this), value);
  
  @DomName('HTMLInputElement.indeterminate')
  @DocsEditable()
  bool get indeterminate => _blink.BlinkHTMLInputElement.instance.indeterminate_Getter_(unwrap_jso(this));
  
  @DomName('HTMLInputElement.indeterminate')
  @DocsEditable()
  set indeterminate(bool value) => _blink.BlinkHTMLInputElement.instance.indeterminate_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLInputElement.inputMode')
  @DocsEditable()
  @Experimental() // untriaged
  String get inputMode => _blink.BlinkHTMLInputElement.instance.inputMode_Getter_(unwrap_jso(this));
  
  @DomName('HTMLInputElement.inputMode')
  @DocsEditable()
  @Experimental() // untriaged
  set inputMode(String value) => _blink.BlinkHTMLInputElement.instance.inputMode_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLInputElement.labels')
  @DocsEditable()
  List<Node> get labels => wrap_jso(_blink.BlinkHTMLInputElement.instance.labels_Getter_(unwrap_jso(this)));
  
  @DomName('HTMLInputElement.list')
  @DocsEditable()
  HtmlElement get list => wrap_jso(_blink.BlinkHTMLInputElement.instance.list_Getter_(unwrap_jso(this)));
  
  @DomName('HTMLInputElement.max')
  @DocsEditable()
  String get max => _blink.BlinkHTMLInputElement.instance.max_Getter_(unwrap_jso(this));
  
  @DomName('HTMLInputElement.max')
  @DocsEditable()
  set max(String value) => _blink.BlinkHTMLInputElement.instance.max_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLInputElement.maxLength')
  @DocsEditable()
  int get maxLength => _blink.BlinkHTMLInputElement.instance.maxLength_Getter_(unwrap_jso(this));
  
  @DomName('HTMLInputElement.maxLength')
  @DocsEditable()
  set maxLength(int value) => _blink.BlinkHTMLInputElement.instance.maxLength_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLInputElement.min')
  @DocsEditable()
  String get min => _blink.BlinkHTMLInputElement.instance.min_Getter_(unwrap_jso(this));
  
  @DomName('HTMLInputElement.min')
  @DocsEditable()
  set min(String value) => _blink.BlinkHTMLInputElement.instance.min_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLInputElement.minLength')
  @DocsEditable()
  @Experimental() // untriaged
  int get minLength => _blink.BlinkHTMLInputElement.instance.minLength_Getter_(unwrap_jso(this));
  
  @DomName('HTMLInputElement.minLength')
  @DocsEditable()
  @Experimental() // untriaged
  set minLength(int value) => _blink.BlinkHTMLInputElement.instance.minLength_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLInputElement.multiple')
  @DocsEditable()
  bool get multiple => _blink.BlinkHTMLInputElement.instance.multiple_Getter_(unwrap_jso(this));
  
  @DomName('HTMLInputElement.multiple')
  @DocsEditable()
  set multiple(bool value) => _blink.BlinkHTMLInputElement.instance.multiple_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLInputElement.name')
  @DocsEditable()
  String get name => _blink.BlinkHTMLInputElement.instance.name_Getter_(unwrap_jso(this));
  
  @DomName('HTMLInputElement.name')
  @DocsEditable()
  set name(String value) => _blink.BlinkHTMLInputElement.instance.name_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLInputElement.pattern')
  @DocsEditable()
  String get pattern => _blink.BlinkHTMLInputElement.instance.pattern_Getter_(unwrap_jso(this));
  
  @DomName('HTMLInputElement.pattern')
  @DocsEditable()
  set pattern(String value) => _blink.BlinkHTMLInputElement.instance.pattern_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLInputElement.placeholder')
  @DocsEditable()
  String get placeholder => _blink.BlinkHTMLInputElement.instance.placeholder_Getter_(unwrap_jso(this));
  
  @DomName('HTMLInputElement.placeholder')
  @DocsEditable()
  set placeholder(String value) => _blink.BlinkHTMLInputElement.instance.placeholder_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLInputElement.readOnly')
  @DocsEditable()
  bool get readOnly => _blink.BlinkHTMLInputElement.instance.readOnly_Getter_(unwrap_jso(this));
  
  @DomName('HTMLInputElement.readOnly')
  @DocsEditable()
  set readOnly(bool value) => _blink.BlinkHTMLInputElement.instance.readOnly_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLInputElement.required')
  @DocsEditable()
  bool get required => _blink.BlinkHTMLInputElement.instance.required_Getter_(unwrap_jso(this));
  
  @DomName('HTMLInputElement.required')
  @DocsEditable()
  set required(bool value) => _blink.BlinkHTMLInputElement.instance.required_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLInputElement.selectionDirection')
  @DocsEditable()
  String get selectionDirection => _blink.BlinkHTMLInputElement.instance.selectionDirection_Getter_(unwrap_jso(this));
  
  @DomName('HTMLInputElement.selectionDirection')
  @DocsEditable()
  set selectionDirection(String value) => _blink.BlinkHTMLInputElement.instance.selectionDirection_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLInputElement.selectionEnd')
  @DocsEditable()
  int get selectionEnd => _blink.BlinkHTMLInputElement.instance.selectionEnd_Getter_(unwrap_jso(this));
  
  @DomName('HTMLInputElement.selectionEnd')
  @DocsEditable()
  set selectionEnd(int value) => _blink.BlinkHTMLInputElement.instance.selectionEnd_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLInputElement.selectionStart')
  @DocsEditable()
  int get selectionStart => _blink.BlinkHTMLInputElement.instance.selectionStart_Getter_(unwrap_jso(this));
  
  @DomName('HTMLInputElement.selectionStart')
  @DocsEditable()
  set selectionStart(int value) => _blink.BlinkHTMLInputElement.instance.selectionStart_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLInputElement.size')
  @DocsEditable()
  int get size => _blink.BlinkHTMLInputElement.instance.size_Getter_(unwrap_jso(this));
  
  @DomName('HTMLInputElement.size')
  @DocsEditable()
  set size(int value) => _blink.BlinkHTMLInputElement.instance.size_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLInputElement.src')
  @DocsEditable()
  String get src => _blink.BlinkHTMLInputElement.instance.src_Getter_(unwrap_jso(this));
  
  @DomName('HTMLInputElement.src')
  @DocsEditable()
  set src(String value) => _blink.BlinkHTMLInputElement.instance.src_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLInputElement.step')
  @DocsEditable()
  String get step => _blink.BlinkHTMLInputElement.instance.step_Getter_(unwrap_jso(this));
  
  @DomName('HTMLInputElement.step')
  @DocsEditable()
  set step(String value) => _blink.BlinkHTMLInputElement.instance.step_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLInputElement.type')
  @DocsEditable()
  String get type => _blink.BlinkHTMLInputElement.instance.type_Getter_(unwrap_jso(this));
  
  @DomName('HTMLInputElement.type')
  @DocsEditable()
  set type(String value) => _blink.BlinkHTMLInputElement.instance.type_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLInputElement.validationMessage')
  @DocsEditable()
  String get validationMessage => _blink.BlinkHTMLInputElement.instance.validationMessage_Getter_(unwrap_jso(this));
  
  @DomName('HTMLInputElement.validity')
  @DocsEditable()
  ValidityState get validity => wrap_jso(_blink.BlinkHTMLInputElement.instance.validity_Getter_(unwrap_jso(this)));
  
  @DomName('HTMLInputElement.value')
  @DocsEditable()
  String get value => _blink.BlinkHTMLInputElement.instance.value_Getter_(unwrap_jso(this));
  
  @DomName('HTMLInputElement.value')
  @DocsEditable()
  set value(String value) => _blink.BlinkHTMLInputElement.instance.value_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLInputElement.valueAsDate')
  @DocsEditable()
  DateTime get valueAsDate => _blink.BlinkHTMLInputElement.instance.valueAsDate_Getter_(unwrap_jso(this));
  
  @DomName('HTMLInputElement.valueAsDate')
  @DocsEditable()
  set valueAsDate(DateTime value) => _blink.BlinkHTMLInputElement.instance.valueAsDate_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLInputElement.valueAsNumber')
  @DocsEditable()
  num get valueAsNumber => _blink.BlinkHTMLInputElement.instance.valueAsNumber_Getter_(unwrap_jso(this));
  
  @DomName('HTMLInputElement.valueAsNumber')
  @DocsEditable()
  set valueAsNumber(num value) => _blink.BlinkHTMLInputElement.instance.valueAsNumber_Setter_(unwrap_jso(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 => wrap_jso(_blink.BlinkHTMLInputElement.instance.webkitEntries_Getter_(unwrap_jso(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_(unwrap_jso(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_(unwrap_jso(this), value);
  
  @DomName('HTMLInputElement.width')
  @DocsEditable()
  int get width => _blink.BlinkHTMLInputElement.instance.width_Getter_(unwrap_jso(this));
  
  @DomName('HTMLInputElement.width')
  @DocsEditable()
  set width(int value) => _blink.BlinkHTMLInputElement.instance.width_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLInputElement.willValidate')
  @DocsEditable()
  bool get willValidate => _blink.BlinkHTMLInputElement.instance.willValidate_Getter_(unwrap_jso(this));
  
  @DomName('HTMLInputElement.checkValidity')
  @DocsEditable()
  bool checkValidity() => _blink.BlinkHTMLInputElement.instance.checkValidity_Callback_0_(unwrap_jso(this));
  
  @DomName('HTMLInputElement.reportValidity')
  @DocsEditable()
  @Experimental() // untriaged
  bool reportValidity() => _blink.BlinkHTMLInputElement.instance.reportValidity_Callback_0_(unwrap_jso(this));
  
  @DomName('HTMLInputElement.select')
  @DocsEditable()
  void select() => _blink.BlinkHTMLInputElement.instance.select_Callback_0_(unwrap_jso(this));
  
  @DomName('HTMLInputElement.setCustomValidity')
  @DocsEditable()
  void setCustomValidity(String error) => _blink.BlinkHTMLInputElement.instance.setCustomValidity_Callback_1_(unwrap_jso(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_(unwrap_jso(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_(unwrap_jso(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_(unwrap_jso(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_(unwrap_jso(this), start, end, direction);
      return;
    }
    _blink.BlinkHTMLInputElement.instance.setSelectionRange_Callback_2_(unwrap_jso(this), start, end);
    return;
  }

  void stepDown([int n]) {
    if (n != null) {
      _blink.BlinkHTMLInputElement.instance.stepDown_Callback_1_(unwrap_jso(this), n);
      return;
    }
    _blink.BlinkHTMLInputElement.instance.stepDown_Callback_0_(unwrap_jso(this));
    return;
  }

  void stepUp([int n]) {
    if (n != null) {
      _blink.BlinkHTMLInputElement.instance.stepUp_Callback_1_(unwrap_jso(this), n);
      return;
    }
    _blink.BlinkHTMLInputElement.instance.stepUp_Callback_0_(unwrap_jso(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 wrap_jso(_blink.BlinkKeyboardEvent.instance.constructorCallback_2_(type, eventInitDict_1));
    }
    return wrap_jso(_blink.BlinkKeyboardEvent.instance.constructorCallback_1_(type));
  }


  @Deprecated("Internal Use Only")
  static KeyboardEvent internalCreateKeyboardEvent() {
    return new KeyboardEvent._internalWrap();
  }

  external factory KeyboardEvent._internalWrap();

  @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_(unwrap_jso(this));
  
  @DomName('KeyboardEvent.code')
  @DocsEditable()
  @Experimental() // untriaged
  String get code => _blink.BlinkKeyboardEvent.instance.code_Getter_(unwrap_jso(this));
  
  @DomName('KeyboardEvent.ctrlKey')
  @DocsEditable()
  bool get ctrlKey => _blink.BlinkKeyboardEvent.instance.ctrlKey_Getter_(unwrap_jso(this));
  
  @DomName('KeyboardEvent.key')
  @DocsEditable()
  @Experimental() // untriaged
  String get key => _blink.BlinkKeyboardEvent.instance.key_Getter_(unwrap_jso(this));
  
  @DomName('KeyboardEvent.keyIdentifier')
  @DocsEditable()
  @Experimental() // nonstandard
  String get _keyIdentifier => _blink.BlinkKeyboardEvent.instance.keyIdentifier_Getter_(unwrap_jso(this));
  
  @DomName('KeyboardEvent.keyLocation')
  @DocsEditable()
  @Experimental() // nonstandard
  int get keyLocation => _blink.BlinkKeyboardEvent.instance.keyLocation_Getter_(unwrap_jso(this));
  
  @DomName('KeyboardEvent.location')
  @DocsEditable()
  @Experimental() // untriaged
  int get location => _blink.BlinkKeyboardEvent.instance.location_Getter_(unwrap_jso(this));
  
  @DomName('KeyboardEvent.metaKey')
  @DocsEditable()
  bool get metaKey => _blink.BlinkKeyboardEvent.instance.metaKey_Getter_(unwrap_jso(this));
  
  @DomName('KeyboardEvent.repeat')
  @DocsEditable()
  @Experimental() // untriaged
  bool get repeat => _blink.BlinkKeyboardEvent.instance.repeat_Getter_(unwrap_jso(this));
  
  @DomName('KeyboardEvent.shiftKey')
  @DocsEditable()
  bool get shiftKey => _blink.BlinkKeyboardEvent.instance.shiftKey_Getter_(unwrap_jso(this));
  
  @DomName('KeyboardEvent.getModifierState')
  @DocsEditable()
  @Experimental() // untriaged
  bool getModifierState(String keyArg) => _blink.BlinkKeyboardEvent.instance.getModifierState_Callback_1_(unwrap_jso(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_(unwrap_jso(this), type, bubbles, cancelable, unwrap_jso(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 wrap_jso(_blink.BlinkKeyframeEffect.instance.constructorCallback_2_(target, keyframes));
    }
    if ((timing is num) && (keyframes is List<Map>) && (target is Element || target == null)) {
      return wrap_jso(_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 wrap_jso(_blink.BlinkKeyframeEffect.instance.constructorCallback_3_(target, keyframes, timing_1));
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }


  @Deprecated("Internal Use Only")
  static KeyframeEffect internalCreateKeyframeEffect() {
    return new KeyframeEffect._internalWrap();
  }

  external factory KeyframeEffect._internalWrap();

  @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")
  static KeygenElement internalCreateKeygenElement() {
    return new KeygenElement._internalWrap();
  }

  external factory KeygenElement._internalWrap();

  @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_(unwrap_jso(this));
  
  @DomName('HTMLKeygenElement.autofocus')
  @DocsEditable()
  set autofocus(bool value) => _blink.BlinkHTMLKeygenElement.instance.autofocus_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLKeygenElement.challenge')
  @DocsEditable()
  String get challenge => _blink.BlinkHTMLKeygenElement.instance.challenge_Getter_(unwrap_jso(this));
  
  @DomName('HTMLKeygenElement.challenge')
  @DocsEditable()
  set challenge(String value) => _blink.BlinkHTMLKeygenElement.instance.challenge_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLKeygenElement.disabled')
  @DocsEditable()
  bool get disabled => _blink.BlinkHTMLKeygenElement.instance.disabled_Getter_(unwrap_jso(this));
  
  @DomName('HTMLKeygenElement.disabled')
  @DocsEditable()
  set disabled(bool value) => _blink.BlinkHTMLKeygenElement.instance.disabled_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLKeygenElement.form')
  @DocsEditable()
  FormElement get form => wrap_jso(_blink.BlinkHTMLKeygenElement.instance.form_Getter_(unwrap_jso(this)));
  
  @DomName('HTMLKeygenElement.keytype')
  @DocsEditable()
  String get keytype => _blink.BlinkHTMLKeygenElement.instance.keytype_Getter_(unwrap_jso(this));
  
  @DomName('HTMLKeygenElement.keytype')
  @DocsEditable()
  set keytype(String value) => _blink.BlinkHTMLKeygenElement.instance.keytype_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLKeygenElement.labels')
  @DocsEditable()
  @Unstable()
  List<Node> get labels => wrap_jso(_blink.BlinkHTMLKeygenElement.instance.labels_Getter_(unwrap_jso(this)));
  
  @DomName('HTMLKeygenElement.name')
  @DocsEditable()
  String get name => _blink.BlinkHTMLKeygenElement.instance.name_Getter_(unwrap_jso(this));
  
  @DomName('HTMLKeygenElement.name')
  @DocsEditable()
  set name(String value) => _blink.BlinkHTMLKeygenElement.instance.name_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLKeygenElement.type')
  @DocsEditable()
  String get type => _blink.BlinkHTMLKeygenElement.instance.type_Getter_(unwrap_jso(this));
  
  @DomName('HTMLKeygenElement.validationMessage')
  @DocsEditable()
  String get validationMessage => _blink.BlinkHTMLKeygenElement.instance.validationMessage_Getter_(unwrap_jso(this));
  
  @DomName('HTMLKeygenElement.validity')
  @DocsEditable()
  ValidityState get validity => wrap_jso(_blink.BlinkHTMLKeygenElement.instance.validity_Getter_(unwrap_jso(this)));
  
  @DomName('HTMLKeygenElement.willValidate')
  @DocsEditable()
  bool get willValidate => _blink.BlinkHTMLKeygenElement.instance.willValidate_Getter_(unwrap_jso(this));
  
  @DomName('HTMLKeygenElement.checkValidity')
  @DocsEditable()
  bool checkValidity() => _blink.BlinkHTMLKeygenElement.instance.checkValidity_Callback_0_(unwrap_jso(this));
  
  @DomName('HTMLKeygenElement.reportValidity')
  @DocsEditable()
  @Experimental() // untriaged
  bool reportValidity() => _blink.BlinkHTMLKeygenElement.instance.reportValidity_Callback_0_(unwrap_jso(this));
  
  @DomName('HTMLKeygenElement.setCustomValidity')
  @DocsEditable()
  void setCustomValidity(String error) => _blink.BlinkHTMLKeygenElement.instance.setCustomValidity_Callback_1_(unwrap_jso(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")
  static LIElement internalCreateLIElement() {
    return new LIElement._internalWrap();
  }

  external factory LIElement._internalWrap();

  @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_(unwrap_jso(this));
  
  @DomName('HTMLLIElement.value')
  @DocsEditable()
  set value(int value) => _blink.BlinkHTMLLIElement.instance.value_Setter_(unwrap_jso(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")
  static LabelElement internalCreateLabelElement() {
    return new LabelElement._internalWrap();
  }

  external factory LabelElement._internalWrap();

  @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 => wrap_jso(_blink.BlinkHTMLLabelElement.instance.control_Getter_(unwrap_jso(this)));
  
  @DomName('HTMLLabelElement.form')
  @DocsEditable()
  FormElement get form => wrap_jso(_blink.BlinkHTMLLabelElement.instance.form_Getter_(unwrap_jso(this)));
  
  @DomName('HTMLLabelElement.htmlFor')
  @DocsEditable()
  String get htmlFor => _blink.BlinkHTMLLabelElement.instance.htmlFor_Getter_(unwrap_jso(this));
  
  @DomName('HTMLLabelElement.htmlFor')
  @DocsEditable()
  set htmlFor(String value) => _blink.BlinkHTMLLabelElement.instance.htmlFor_Setter_(unwrap_jso(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")
  static LegendElement internalCreateLegendElement() {
    return new LegendElement._internalWrap();
  }

  external factory LegendElement._internalWrap();

  @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 => wrap_jso(_blink.BlinkHTMLLegendElement.instance.form_Getter_(unwrap_jso(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")
  static LinkElement internalCreateLinkElement() {
    return new LinkElement._internalWrap();
  }

  external factory LinkElement._internalWrap();

  @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_(unwrap_jso(this));
  
  @DomName('HTMLLinkElement.crossOrigin')
  @DocsEditable()
  @Experimental() // untriaged
  set crossOrigin(String value) => _blink.BlinkHTMLLinkElement.instance.crossOrigin_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLLinkElement.disabled')
  @DocsEditable()
  bool get disabled => _blink.BlinkHTMLLinkElement.instance.disabled_Getter_(unwrap_jso(this));
  
  @DomName('HTMLLinkElement.disabled')
  @DocsEditable()
  set disabled(bool value) => _blink.BlinkHTMLLinkElement.instance.disabled_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLLinkElement.href')
  @DocsEditable()
  String get href => _blink.BlinkHTMLLinkElement.instance.href_Getter_(unwrap_jso(this));
  
  @DomName('HTMLLinkElement.href')
  @DocsEditable()
  set href(String value) => _blink.BlinkHTMLLinkElement.instance.href_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLLinkElement.hreflang')
  @DocsEditable()
  String get hreflang => _blink.BlinkHTMLLinkElement.instance.hreflang_Getter_(unwrap_jso(this));
  
  @DomName('HTMLLinkElement.hreflang')
  @DocsEditable()
  set hreflang(String value) => _blink.BlinkHTMLLinkElement.instance.hreflang_Setter_(unwrap_jso(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 => wrap_jso(_blink.BlinkHTMLLinkElement.instance.import_Getter_(unwrap_jso(this)));
  
  @DomName('HTMLLinkElement.integrity')
  @DocsEditable()
  @Experimental() // untriaged
  String get integrity => _blink.BlinkHTMLLinkElement.instance.integrity_Getter_(unwrap_jso(this));
  
  @DomName('HTMLLinkElement.integrity')
  @DocsEditable()
  @Experimental() // untriaged
  set integrity(String value) => _blink.BlinkHTMLLinkElement.instance.integrity_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLLinkElement.media')
  @DocsEditable()
  String get media => _blink.BlinkHTMLLinkElement.instance.media_Getter_(unwrap_jso(this));
  
  @DomName('HTMLLinkElement.media')
  @DocsEditable()
  set media(String value) => _blink.BlinkHTMLLinkElement.instance.media_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLLinkElement.rel')
  @DocsEditable()
  String get rel => _blink.BlinkHTMLLinkElement.instance.rel_Getter_(unwrap_jso(this));
  
  @DomName('HTMLLinkElement.rel')
  @DocsEditable()
  set rel(String value) => _blink.BlinkHTMLLinkElement.instance.rel_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLLinkElement.sheet')
  @DocsEditable()
  StyleSheet get sheet => wrap_jso(_blink.BlinkHTMLLinkElement.instance.sheet_Getter_(unwrap_jso(this)));
  
  @DomName('HTMLLinkElement.sizes')
  @DocsEditable()
  DomSettableTokenList get sizes => wrap_jso(_blink.BlinkHTMLLinkElement.instance.sizes_Getter_(unwrap_jso(this)));
  
  @DomName('HTMLLinkElement.type')
  @DocsEditable()
  String get type => _blink.BlinkHTMLLinkElement.instance.type_Getter_(unwrap_jso(this));
  
  @DomName('HTMLLinkElement.type')
  @DocsEditable()
  set type(String value) => _blink.BlinkHTMLLinkElement.instance.type_Setter_(unwrap_jso(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")
  static Location internalCreateLocation() {
    return new Location._internalWrap();
  }

  factory Location._internalWrap() {
    return new Location.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  @DomName('Location.ancestorOrigins')
  @DocsEditable()
  @Experimental() // nonstandard
  List<String> get ancestorOrigins => wrap_jso(_blink.BlinkLocation.instance.ancestorOrigins_Getter_(unwrap_jso(this)));
  
  @DomName('Location.hash')
  @DocsEditable()
  String get hash => _blink.BlinkLocation.instance.hash_Getter_(unwrap_jso(this));
  
  @DomName('Location.hash')
  @DocsEditable()
  set hash(String value) => _blink.BlinkLocation.instance.hash_Setter_(unwrap_jso(this), value);
  
  @DomName('Location.host')
  @DocsEditable()
  String get host => _blink.BlinkLocation.instance.host_Getter_(unwrap_jso(this));
  
  @DomName('Location.host')
  @DocsEditable()
  set host(String value) => _blink.BlinkLocation.instance.host_Setter_(unwrap_jso(this), value);
  
  @DomName('Location.hostname')
  @DocsEditable()
  String get hostname => _blink.BlinkLocation.instance.hostname_Getter_(unwrap_jso(this));
  
  @DomName('Location.hostname')
  @DocsEditable()
  set hostname(String value) => _blink.BlinkLocation.instance.hostname_Setter_(unwrap_jso(this), value);
  
  @DomName('Location.href')
  @DocsEditable()
  String get href => _blink.BlinkLocation.instance.href_Getter_(unwrap_jso(this));
  
  @DomName('Location.href')
  @DocsEditable()
  set href(String value) => _blink.BlinkLocation.instance.href_Setter_(unwrap_jso(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_(unwrap_jso(this));
  
  @DomName('Location.pathname')
  @DocsEditable()
  String get pathname => _blink.BlinkLocation.instance.pathname_Getter_(unwrap_jso(this));
  
  @DomName('Location.pathname')
  @DocsEditable()
  set pathname(String value) => _blink.BlinkLocation.instance.pathname_Setter_(unwrap_jso(this), value);
  
  @DomName('Location.port')
  @DocsEditable()
  String get port => _blink.BlinkLocation.instance.port_Getter_(unwrap_jso(this));
  
  @DomName('Location.port')
  @DocsEditable()
  set port(String value) => _blink.BlinkLocation.instance.port_Setter_(unwrap_jso(this), value);
  
  @DomName('Location.protocol')
  @DocsEditable()
  String get protocol => _blink.BlinkLocation.instance.protocol_Getter_(unwrap_jso(this));
  
  @DomName('Location.protocol')
  @DocsEditable()
  set protocol(String value) => _blink.BlinkLocation.instance.protocol_Setter_(unwrap_jso(this), value);
  
  @DomName('Location.search')
  @DocsEditable()
  String get search => _blink.BlinkLocation.instance.search_Getter_(unwrap_jso(this));
  
  @DomName('Location.search')
  @DocsEditable()
  set search(String value) => _blink.BlinkLocation.instance.search_Setter_(unwrap_jso(this), value);
  
  @DomName('Location.assign')
  @DocsEditable()
  void assign([String url]) => _blink.BlinkLocation.instance.assign_Callback_1_(unwrap_jso(this), url);
  
  @DomName('Location.reload')
  @DocsEditable()
  void reload() => _blink.BlinkLocation.instance.reload_Callback_0_(unwrap_jso(this));
  
  @DomName('Location.replace')
  @DocsEditable()
  void replace(String url) => _blink.BlinkLocation.instance.replace_Callback_1_(unwrap_jso(this), url);
  
  @DomName('Location.toString')
  @DocsEditable()
  String toString() => _blink.BlinkLocation.instance.toString_Callback_0_(unwrap_jso(this));
  


}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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")
  static MapElement internalCreateMapElement() {
    return new MapElement._internalWrap();
  }

  external factory MapElement._internalWrap();

  @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 => wrap_jso(_blink.BlinkHTMLMapElement.instance.areas_Getter_(unwrap_jso(this)));
  
  @DomName('HTMLMapElement.name')
  @DocsEditable()
  String get name => _blink.BlinkHTMLMapElement.instance.name_Getter_(unwrap_jso(this));
  
  @DomName('HTMLMapElement.name')
  @DocsEditable()
  set name(String value) => _blink.BlinkHTMLMapElement.instance.name_Setter_(unwrap_jso(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 wrap_jso(_blink.BlinkMediaController.instance.constructorCallback_0_());
  }


  @Deprecated("Internal Use Only")
  static MediaController internalCreateMediaController() {
    return new MediaController._internalWrap();
  }

  external factory MediaController._internalWrap();

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


  @DomName('MediaController.buffered')
  @DocsEditable()
  TimeRanges get buffered => wrap_jso(_blink.BlinkMediaController.instance.buffered_Getter_(unwrap_jso(this)));
  
  @DomName('MediaController.currentTime')
  @DocsEditable()
  num get currentTime => _blink.BlinkMediaController.instance.currentTime_Getter_(unwrap_jso(this));
  
  @DomName('MediaController.currentTime')
  @DocsEditable()
  set currentTime(num value) => _blink.BlinkMediaController.instance.currentTime_Setter_(unwrap_jso(this), value);
  
  @DomName('MediaController.defaultPlaybackRate')
  @DocsEditable()
  num get defaultPlaybackRate => _blink.BlinkMediaController.instance.defaultPlaybackRate_Getter_(unwrap_jso(this));
  
  @DomName('MediaController.defaultPlaybackRate')
  @DocsEditable()
  set defaultPlaybackRate(num value) => _blink.BlinkMediaController.instance.defaultPlaybackRate_Setter_(unwrap_jso(this), value);
  
  @DomName('MediaController.duration')
  @DocsEditable()
  num get duration => _blink.BlinkMediaController.instance.duration_Getter_(unwrap_jso(this));
  
  @DomName('MediaController.muted')
  @DocsEditable()
  bool get muted => _blink.BlinkMediaController.instance.muted_Getter_(unwrap_jso(this));
  
  @DomName('MediaController.muted')
  @DocsEditable()
  set muted(bool value) => _blink.BlinkMediaController.instance.muted_Setter_(unwrap_jso(this), value);
  
  @DomName('MediaController.paused')
  @DocsEditable()
  bool get paused => _blink.BlinkMediaController.instance.paused_Getter_(unwrap_jso(this));
  
  @DomName('MediaController.playbackRate')
  @DocsEditable()
  num get playbackRate => _blink.BlinkMediaController.instance.playbackRate_Getter_(unwrap_jso(this));
  
  @DomName('MediaController.playbackRate')
  @DocsEditable()
  set playbackRate(num value) => _blink.BlinkMediaController.instance.playbackRate_Setter_(unwrap_jso(this), value);
  
  @DomName('MediaController.playbackState')
  @DocsEditable()
  String get playbackState => _blink.BlinkMediaController.instance.playbackState_Getter_(unwrap_jso(this));
  
  @DomName('MediaController.played')
  @DocsEditable()
  TimeRanges get played => wrap_jso(_blink.BlinkMediaController.instance.played_Getter_(unwrap_jso(this)));
  
  @DomName('MediaController.seekable')
  @DocsEditable()
  TimeRanges get seekable => wrap_jso(_blink.BlinkMediaController.instance.seekable_Getter_(unwrap_jso(this)));
  
  @DomName('MediaController.volume')
  @DocsEditable()
  num get volume => _blink.BlinkMediaController.instance.volume_Getter_(unwrap_jso(this));
  
  @DomName('MediaController.volume')
  @DocsEditable()
  set volume(num value) => _blink.BlinkMediaController.instance.volume_Setter_(unwrap_jso(this), value);
  
  @DomName('MediaController.pause')
  @DocsEditable()
  void pause() => _blink.BlinkMediaController.instance.pause_Callback_0_(unwrap_jso(this));
  
  @DomName('MediaController.play')
  @DocsEditable()
  void play() => _blink.BlinkMediaController.instance.play_Callback_0_(unwrap_jso(this));
  
  @DomName('MediaController.unpause')
  @DocsEditable()
  void unpause() => _blink.BlinkMediaController.instance.unpause_Callback_0_(unwrap_jso(this));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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")
  static MediaDeviceInfo internalCreateMediaDeviceInfo() {
    return new MediaDeviceInfo._internalWrap();
  }

  factory MediaDeviceInfo._internalWrap() {
    return new MediaDeviceInfo.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  @DomName('MediaDeviceInfo.deviceId')
  @DocsEditable()
  @Experimental() // untriaged
  String get deviceId => _blink.BlinkMediaDeviceInfo.instance.deviceId_Getter_(unwrap_jso(this));
  
  @DomName('MediaDeviceInfo.groupId')
  @DocsEditable()
  @Experimental() // untriaged
  String get groupId => _blink.BlinkMediaDeviceInfo.instance.groupId_Getter_(unwrap_jso(this));
  
  @DomName('MediaDeviceInfo.kind')
  @DocsEditable()
  @Experimental() // untriaged
  String get kind => _blink.BlinkMediaDeviceInfo.instance.kind_Getter_(unwrap_jso(this));
  
  @DomName('MediaDeviceInfo.label')
  @DocsEditable()
  @Experimental() // untriaged
  String get label => _blink.BlinkMediaDeviceInfo.instance.label_Getter_(unwrap_jso(this));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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")
  static MediaDevices internalCreateMediaDevices() {
    return new MediaDevices._internalWrap();
  }

  factory MediaDevices._internalWrap() {
    return new MediaDevices.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  @DomName('MediaDevices.enumerateDevices')
  @DocsEditable()
  @Experimental() // untriaged
  Future enumerateDevices() => wrap_jso(_blink.BlinkMediaDevices.instance.enumerateDevices_Callback_0_(unwrap_jso(this)));
  
  @DomName('MediaDevices.getUserMedia')
  @DocsEditable()
  @Experimental() // untriaged
  Future getUserMedia(Map options) => wrap_jso(_blink.BlinkMediaDevices.instance.getUserMedia_Callback_1_(unwrap_jso(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")
  static MediaElement internalCreateMediaElement() {
    return new MediaElement._internalWrap();
  }

  external factory MediaElement._internalWrap();

  @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 => wrap_jso(_blink.BlinkHTMLMediaElement.instance.audioTracks_Getter_(unwrap_jso(this)));
  
  @DomName('HTMLMediaElement.autoplay')
  @DocsEditable()
  bool get autoplay => _blink.BlinkHTMLMediaElement.instance.autoplay_Getter_(unwrap_jso(this));
  
  @DomName('HTMLMediaElement.autoplay')
  @DocsEditable()
  set autoplay(bool value) => _blink.BlinkHTMLMediaElement.instance.autoplay_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLMediaElement.buffered')
  @DocsEditable()
  TimeRanges get buffered => wrap_jso(_blink.BlinkHTMLMediaElement.instance.buffered_Getter_(unwrap_jso(this)));
  
  @DomName('HTMLMediaElement.controller')
  @DocsEditable()
  MediaController get controller => wrap_jso(_blink.BlinkHTMLMediaElement.instance.controller_Getter_(unwrap_jso(this)));
  
  @DomName('HTMLMediaElement.controller')
  @DocsEditable()
  set controller(MediaController value) => _blink.BlinkHTMLMediaElement.instance.controller_Setter_(unwrap_jso(this), unwrap_jso(value));
  
  @DomName('HTMLMediaElement.controls')
  @DocsEditable()
  bool get controls => _blink.BlinkHTMLMediaElement.instance.controls_Getter_(unwrap_jso(this));
  
  @DomName('HTMLMediaElement.controls')
  @DocsEditable()
  set controls(bool value) => _blink.BlinkHTMLMediaElement.instance.controls_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLMediaElement.crossOrigin')
  @DocsEditable()
  @Experimental() // untriaged
  String get crossOrigin => _blink.BlinkHTMLMediaElement.instance.crossOrigin_Getter_(unwrap_jso(this));
  
  @DomName('HTMLMediaElement.crossOrigin')
  @DocsEditable()
  @Experimental() // untriaged
  set crossOrigin(String value) => _blink.BlinkHTMLMediaElement.instance.crossOrigin_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLMediaElement.currentSrc')
  @DocsEditable()
  String get currentSrc => _blink.BlinkHTMLMediaElement.instance.currentSrc_Getter_(unwrap_jso(this));
  
  @DomName('HTMLMediaElement.currentTime')
  @DocsEditable()
  num get currentTime => _blink.BlinkHTMLMediaElement.instance.currentTime_Getter_(unwrap_jso(this));
  
  @DomName('HTMLMediaElement.currentTime')
  @DocsEditable()
  set currentTime(num value) => _blink.BlinkHTMLMediaElement.instance.currentTime_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLMediaElement.defaultMuted')
  @DocsEditable()
  bool get defaultMuted => _blink.BlinkHTMLMediaElement.instance.defaultMuted_Getter_(unwrap_jso(this));
  
  @DomName('HTMLMediaElement.defaultMuted')
  @DocsEditable()
  set defaultMuted(bool value) => _blink.BlinkHTMLMediaElement.instance.defaultMuted_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLMediaElement.defaultPlaybackRate')
  @DocsEditable()
  num get defaultPlaybackRate => _blink.BlinkHTMLMediaElement.instance.defaultPlaybackRate_Getter_(unwrap_jso(this));
  
  @DomName('HTMLMediaElement.defaultPlaybackRate')
  @DocsEditable()
  set defaultPlaybackRate(num value) => _blink.BlinkHTMLMediaElement.instance.defaultPlaybackRate_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLMediaElement.duration')
  @DocsEditable()
  num get duration => _blink.BlinkHTMLMediaElement.instance.duration_Getter_(unwrap_jso(this));
  
  @DomName('HTMLMediaElement.ended')
  @DocsEditable()
  bool get ended => _blink.BlinkHTMLMediaElement.instance.ended_Getter_(unwrap_jso(this));
  
  @DomName('HTMLMediaElement.error')
  @DocsEditable()
  MediaError get error => wrap_jso(_blink.BlinkHTMLMediaElement.instance.error_Getter_(unwrap_jso(this)));
  
  @DomName('HTMLMediaElement.loop')
  @DocsEditable()
  bool get loop => _blink.BlinkHTMLMediaElement.instance.loop_Getter_(unwrap_jso(this));
  
  @DomName('HTMLMediaElement.loop')
  @DocsEditable()
  set loop(bool value) => _blink.BlinkHTMLMediaElement.instance.loop_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLMediaElement.mediaGroup')
  @DocsEditable()
  String get mediaGroup => _blink.BlinkHTMLMediaElement.instance.mediaGroup_Getter_(unwrap_jso(this));
  
  @DomName('HTMLMediaElement.mediaGroup')
  @DocsEditable()
  set mediaGroup(String value) => _blink.BlinkHTMLMediaElement.instance.mediaGroup_Setter_(unwrap_jso(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 => wrap_jso(_blink.BlinkHTMLMediaElement.instance.mediaKeys_Getter_(unwrap_jso(this)));
  
  @DomName('HTMLMediaElement.muted')
  @DocsEditable()
  bool get muted => _blink.BlinkHTMLMediaElement.instance.muted_Getter_(unwrap_jso(this));
  
  @DomName('HTMLMediaElement.muted')
  @DocsEditable()
  set muted(bool value) => _blink.BlinkHTMLMediaElement.instance.muted_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLMediaElement.networkState')
  @DocsEditable()
  int get networkState => _blink.BlinkHTMLMediaElement.instance.networkState_Getter_(unwrap_jso(this));
  
  @DomName('HTMLMediaElement.paused')
  @DocsEditable()
  bool get paused => _blink.BlinkHTMLMediaElement.instance.paused_Getter_(unwrap_jso(this));
  
  @DomName('HTMLMediaElement.playbackRate')
  @DocsEditable()
  num get playbackRate => _blink.BlinkHTMLMediaElement.instance.playbackRate_Getter_(unwrap_jso(this));
  
  @DomName('HTMLMediaElement.playbackRate')
  @DocsEditable()
  set playbackRate(num value) => _blink.BlinkHTMLMediaElement.instance.playbackRate_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLMediaElement.played')
  @DocsEditable()
  TimeRanges get played => wrap_jso(_blink.BlinkHTMLMediaElement.instance.played_Getter_(unwrap_jso(this)));
  
  @DomName('HTMLMediaElement.preload')
  @DocsEditable()
  String get preload => _blink.BlinkHTMLMediaElement.instance.preload_Getter_(unwrap_jso(this));
  
  @DomName('HTMLMediaElement.preload')
  @DocsEditable()
  set preload(String value) => _blink.BlinkHTMLMediaElement.instance.preload_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLMediaElement.readyState')
  @DocsEditable()
  int get readyState => _blink.BlinkHTMLMediaElement.instance.readyState_Getter_(unwrap_jso(this));
  
  @DomName('HTMLMediaElement.seekable')
  @DocsEditable()
  TimeRanges get seekable => wrap_jso(_blink.BlinkHTMLMediaElement.instance.seekable_Getter_(unwrap_jso(this)));
  
  @DomName('HTMLMediaElement.seeking')
  @DocsEditable()
  bool get seeking => _blink.BlinkHTMLMediaElement.instance.seeking_Getter_(unwrap_jso(this));
  
  @DomName('HTMLMediaElement.session')
  @DocsEditable()
  @Experimental() // untriaged
  MediaSession get session => wrap_jso(_blink.BlinkHTMLMediaElement.instance.session_Getter_(unwrap_jso(this)));
  
  @DomName('HTMLMediaElement.session')
  @DocsEditable()
  @Experimental() // untriaged
  set session(MediaSession value) => _blink.BlinkHTMLMediaElement.instance.session_Setter_(unwrap_jso(this), unwrap_jso(value));
  
  @DomName('HTMLMediaElement.sinkId')
  @DocsEditable()
  @Experimental() // untriaged
  String get sinkId => _blink.BlinkHTMLMediaElement.instance.sinkId_Getter_(unwrap_jso(this));
  
  @DomName('HTMLMediaElement.src')
  @DocsEditable()
  String get src => _blink.BlinkHTMLMediaElement.instance.src_Getter_(unwrap_jso(this));
  
  @DomName('HTMLMediaElement.src')
  @DocsEditable()
  set src(String value) => _blink.BlinkHTMLMediaElement.instance.src_Setter_(unwrap_jso(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 => wrap_jso(_blink.BlinkHTMLMediaElement.instance.textTracks_Getter_(unwrap_jso(this)));
  
  @DomName('HTMLMediaElement.videoTracks')
  @DocsEditable()
  @Experimental() // untriaged
  VideoTrackList get videoTracks => wrap_jso(_blink.BlinkHTMLMediaElement.instance.videoTracks_Getter_(unwrap_jso(this)));
  
  @DomName('HTMLMediaElement.volume')
  @DocsEditable()
  num get volume => _blink.BlinkHTMLMediaElement.instance.volume_Getter_(unwrap_jso(this));
  
  @DomName('HTMLMediaElement.volume')
  @DocsEditable()
  set volume(num value) => _blink.BlinkHTMLMediaElement.instance.volume_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLMediaElement.webkitAudioDecodedByteCount')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  @Experimental() // nonstandard
  int get audioDecodedByteCount => _blink.BlinkHTMLMediaElement.instance.webkitAudioDecodedByteCount_Getter_(unwrap_jso(this));
  
  @DomName('HTMLMediaElement.webkitVideoDecodedByteCount')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  @Experimental() // nonstandard
  int get videoDecodedByteCount => _blink.BlinkHTMLMediaElement.instance.webkitVideoDecodedByteCount_Getter_(unwrap_jso(this));
  
  TextTrack addTextTrack(String kind, [String label, String language]) {
    if (language != null) {
      return wrap_jso(_blink.BlinkHTMLMediaElement.instance.addTextTrack_Callback_3_(unwrap_jso(this), kind, label, language));
    }
    if (label != null) {
      return wrap_jso(_blink.BlinkHTMLMediaElement.instance.addTextTrack_Callback_2_(unwrap_jso(this), kind, label));
    }
    return wrap_jso(_blink.BlinkHTMLMediaElement.instance.addTextTrack_Callback_1_(unwrap_jso(this), kind));
  }

  String canPlayType(String type, [String keySystem]) {
    if ((type is String) && keySystem == null) {
      return _blink.BlinkHTMLMediaElement.instance.canPlayType_Callback_1_(unwrap_jso(this), type);
    }
    if ((type is String || type == null) && keySystem == null) {
      return _blink.BlinkHTMLMediaElement.instance.canPlayType_Callback_1_(unwrap_jso(this), type);
    }
    if ((keySystem is String || keySystem == null) && (type is String || type == null)) {
      return _blink.BlinkHTMLMediaElement.instance.canPlayType_Callback_2_(unwrap_jso(this), type, keySystem);
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }

  @DomName('HTMLMediaElement.load')
  @DocsEditable()
  void load() => _blink.BlinkHTMLMediaElement.instance.load_Callback_0_(unwrap_jso(this));
  
  @DomName('HTMLMediaElement.pause')
  @DocsEditable()
  void pause() => _blink.BlinkHTMLMediaElement.instance.pause_Callback_0_(unwrap_jso(this));
  
  @DomName('HTMLMediaElement.play')
  @DocsEditable()
  void play() => _blink.BlinkHTMLMediaElement.instance.play_Callback_0_(unwrap_jso(this));
  
  @DomName('HTMLMediaElement.setMediaKeys')
  @DocsEditable()
  @Experimental() // untriaged
  Future setMediaKeys(MediaKeys mediaKeys) => wrap_jso(_blink.BlinkHTMLMediaElement.instance.setMediaKeys_Callback_1_(unwrap_jso(this), unwrap_jso(mediaKeys)));
  
  @DomName('HTMLMediaElement.setSinkId')
  @DocsEditable()
  @Experimental() // untriaged
  Future setSinkId(String sinkId) => wrap_jso(_blink.BlinkHTMLMediaElement.instance.setSinkId_Callback_1_(unwrap_jso(this), sinkId));
  
  void addKey(String keySystem, Uint8List key, [Uint8List initData, String sessionId]) {
    if (initData != null) {
      _blink.BlinkHTMLMediaElement.instance.webkitAddKey_Callback_4_(unwrap_jso(this), keySystem, unwrap_jso(key), unwrap_jso(initData), sessionId);
      return;
    }
    _blink.BlinkHTMLMediaElement.instance.webkitAddKey_Callback_2_(unwrap_jso(this), keySystem, unwrap_jso(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_(unwrap_jso(this), keySystem, sessionId);
  
  void generateKeyRequest(String keySystem, [Uint8List initData]) {
    if (initData != null) {
      _blink.BlinkHTMLMediaElement.instance.webkitGenerateKeyRequest_Callback_2_(unwrap_jso(this), keySystem, unwrap_jso(initData));
      return;
    }
    _blink.BlinkHTMLMediaElement.instance.webkitGenerateKeyRequest_Callback_1_(unwrap_jso(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 wrap_jso(_blink.BlinkMediaEncryptedEvent.instance.constructorCallback_2_(type, eventInitDict_1));
    }
    return wrap_jso(_blink.BlinkMediaEncryptedEvent.instance.constructorCallback_1_(type));
  }


  @Deprecated("Internal Use Only")
  static MediaEncryptedEvent internalCreateMediaEncryptedEvent() {
    return new MediaEncryptedEvent._internalWrap();
  }

  external factory MediaEncryptedEvent._internalWrap();

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


  @DomName('MediaEncryptedEvent.initData')
  @DocsEditable()
  @Experimental() // untriaged
  ByteBuffer get initData => wrap_jso(_blink.BlinkMediaEncryptedEvent.instance.initData_Getter_(unwrap_jso(this)));
  
  @DomName('MediaEncryptedEvent.initDataType')
  @DocsEditable()
  @Experimental() // untriaged
  String get initDataType => _blink.BlinkMediaEncryptedEvent.instance.initDataType_Getter_(unwrap_jso(this));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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")
  static MediaError internalCreateMediaError() {
    return new MediaError._internalWrap();
  }

  factory MediaError._internalWrap() {
    return new MediaError.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  @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_(unwrap_jso(this));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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")
  static MediaKeyError internalCreateMediaKeyError() {
    return new MediaKeyError._internalWrap();
  }

  factory MediaKeyError._internalWrap() {
    return new MediaKeyError.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  @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_(unwrap_jso(this));
  
  @DomName('MediaKeyError.systemCode')
  @DocsEditable()
  @Experimental() // non-standard
  int get systemCode => _blink.BlinkMediaKeyError.instance.systemCode_Getter_(unwrap_jso(this));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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 wrap_jso(_blink.BlinkMediaKeyEvent.instance.constructorCallback_2_(type, eventInitDict_1));
    }
    return wrap_jso(_blink.BlinkMediaKeyEvent.instance.constructorCallback_1_(type));
  }


  @Deprecated("Internal Use Only")
  static MediaKeyEvent internalCreateMediaKeyEvent() {
    return new MediaKeyEvent._internalWrap();
  }

  external factory MediaKeyEvent._internalWrap();

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


  @DomName('MediaKeyEvent.defaultURL')
  @DocsEditable()
  String get defaultUrl => _blink.BlinkMediaKeyEvent.instance.defaultURL_Getter_(unwrap_jso(this));
  
  @DomName('MediaKeyEvent.errorCode')
  @DocsEditable()
  MediaKeyError get errorCode => wrap_jso(_blink.BlinkMediaKeyEvent.instance.errorCode_Getter_(unwrap_jso(this)));
  
  @DomName('MediaKeyEvent.initData')
  @DocsEditable()
  Uint8List get initData => wrap_jso(_blink.BlinkMediaKeyEvent.instance.initData_Getter_(unwrap_jso(this)));
  
  @DomName('MediaKeyEvent.keySystem')
  @DocsEditable()
  String get keySystem => _blink.BlinkMediaKeyEvent.instance.keySystem_Getter_(unwrap_jso(this));
  
  @DomName('MediaKeyEvent.message')
  @DocsEditable()
  Uint8List get message => wrap_jso(_blink.BlinkMediaKeyEvent.instance.message_Getter_(unwrap_jso(this)));
  
  @DomName('MediaKeyEvent.sessionId')
  @DocsEditable()
  String get sessionId => _blink.BlinkMediaKeyEvent.instance.sessionId_Getter_(unwrap_jso(this));
  
  @DomName('MediaKeyEvent.systemCode')
  @DocsEditable()
  int get systemCode => _blink.BlinkMediaKeyEvent.instance.systemCode_Getter_(unwrap_jso(this));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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 wrap_jso(_blink.BlinkMediaKeyMessageEvent.instance.constructorCallback_2_(type, eventInitDict_1));
    }
    return wrap_jso(_blink.BlinkMediaKeyMessageEvent.instance.constructorCallback_1_(type));
  }


  @Deprecated("Internal Use Only")
  static MediaKeyMessageEvent internalCreateMediaKeyMessageEvent() {
    return new MediaKeyMessageEvent._internalWrap();
  }

  external factory MediaKeyMessageEvent._internalWrap();

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


  @DomName('MediaKeyMessageEvent.message')
  @DocsEditable()
  ByteBuffer get message => wrap_jso(_blink.BlinkMediaKeyMessageEvent.instance.message_Getter_(unwrap_jso(this)));
  
  @DomName('MediaKeyMessageEvent.messageType')
  @DocsEditable()
  @Experimental() // untriaged
  String get messageType => _blink.BlinkMediaKeyMessageEvent.instance.messageType_Getter_(unwrap_jso(this));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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")
  static MediaKeySession internalCreateMediaKeySession() {
    return new MediaKeySession._internalWrap();
  }

  external factory MediaKeySession._internalWrap();

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


  @DomName('MediaKeySession.closed')
  @DocsEditable()
  @Experimental() // untriaged
  Future get closed => wrap_jso(_blink.BlinkMediaKeySession.instance.closed_Getter_(unwrap_jso(this)));
  
  @DomName('MediaKeySession.expiration')
  @DocsEditable()
  @Experimental() // untriaged
  num get expiration => _blink.BlinkMediaKeySession.instance.expiration_Getter_(unwrap_jso(this));
  
  @DomName('MediaKeySession.keyStatuses')
  @DocsEditable()
  @Experimental() // untriaged
  MediaKeyStatusMap get keyStatuses => wrap_jso(_blink.BlinkMediaKeySession.instance.keyStatuses_Getter_(unwrap_jso(this)));
  
  @DomName('MediaKeySession.sessionId')
  @DocsEditable()
  String get sessionId => _blink.BlinkMediaKeySession.instance.sessionId_Getter_(unwrap_jso(this));
  
  @DomName('MediaKeySession.close')
  @DocsEditable()
  Future close() => wrap_jso(_blink.BlinkMediaKeySession.instance.close_Callback_0_(unwrap_jso(this)));
  
  @DomName('MediaKeySession.generateRequest')
  @DocsEditable()
  @Experimental() // untriaged
  Future generateRequest(String initDataType, /*BufferSource*/ initData) => wrap_jso(_blink.BlinkMediaKeySession.instance.generateRequest_Callback_2_(unwrap_jso(this), initDataType, initData));
  
  @DomName('MediaKeySession.load')
  @DocsEditable()
  @Experimental() // untriaged
  Future load(String sessionId) => wrap_jso(_blink.BlinkMediaKeySession.instance.load_Callback_1_(unwrap_jso(this), sessionId));
  
  @DomName('MediaKeySession.remove')
  @DocsEditable()
  @Experimental() // untriaged
  Future remove() => wrap_jso(_blink.BlinkMediaKeySession.instance.remove_Callback_0_(unwrap_jso(this)));
  
  @DomName('MediaKeySession.update')
  @DocsEditable()
  Future _update(/*BufferSource*/ response) => wrap_jso(_blink.BlinkMediaKeySession.instance.update_Callback_1_(unwrap_jso(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")
  static MediaKeyStatusMap internalCreateMediaKeyStatusMap() {
    return new MediaKeyStatusMap._internalWrap();
  }

  factory MediaKeyStatusMap._internalWrap() {
    return new MediaKeyStatusMap.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  @DomName('MediaKeyStatusMap.size')
  @DocsEditable()
  @Experimental() // untriaged
  int get size => _blink.BlinkMediaKeyStatusMap.instance.size_Getter_(unwrap_jso(this));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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")
  static MediaKeySystemAccess internalCreateMediaKeySystemAccess() {
    return new MediaKeySystemAccess._internalWrap();
  }

  factory MediaKeySystemAccess._internalWrap() {
    return new MediaKeySystemAccess.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  @DomName('MediaKeySystemAccess.keySystem')
  @DocsEditable()
  @Experimental() // untriaged
  String get keySystem => _blink.BlinkMediaKeySystemAccess.instance.keySystem_Getter_(unwrap_jso(this));
  
  @DomName('MediaKeySystemAccess.createMediaKeys')
  @DocsEditable()
  @Experimental() // untriaged
  Future createMediaKeys() => wrap_jso(_blink.BlinkMediaKeySystemAccess.instance.createMediaKeys_Callback_0_(unwrap_jso(this)));
  
  @DomName('MediaKeySystemAccess.getConfiguration')
  @DocsEditable()
  @Experimental() // untriaged
   getConfiguration() => convertNativeDictionaryToDartDictionary(wrap_jso(_blink.BlinkMediaKeySystemAccess.instance.getConfiguration_Callback_0_(unwrap_jso(this))));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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")
  static MediaKeys internalCreateMediaKeys() {
    return new MediaKeys._internalWrap();
  }

  factory MediaKeys._internalWrap() {
    return new MediaKeys.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  MediaKeySession _createSession([String sessionType]) {
    if (sessionType != null) {
      return wrap_jso(_blink.BlinkMediaKeys.instance.createSession_Callback_1_(unwrap_jso(this), sessionType));
    }
    return wrap_jso(_blink.BlinkMediaKeys.instance.createSession_Callback_0_(unwrap_jso(this)));
  }

  @DomName('MediaKeys.setServerCertificate')
  @DocsEditable()
  @Experimental() // untriaged
  Future setServerCertificate(/*BufferSource*/ serverCertificate) => wrap_jso(_blink.BlinkMediaKeys.instance.setServerCertificate_Callback_1_(unwrap_jso(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")
  static MediaList internalCreateMediaList() {
    return new MediaList._internalWrap();
  }

  factory MediaList._internalWrap() {
    return new MediaList.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  @DomName('MediaList.length')
  @DocsEditable()
  int get length => _blink.BlinkMediaList.instance.length_Getter_(unwrap_jso(this));
  
  @DomName('MediaList.mediaText')
  @DocsEditable()
  String get mediaText => _blink.BlinkMediaList.instance.mediaText_Getter_(unwrap_jso(this));
  
  @DomName('MediaList.mediaText')
  @DocsEditable()
  set mediaText(String value) => _blink.BlinkMediaList.instance.mediaText_Setter_(unwrap_jso(this), value);
  
  @DomName('MediaList.appendMedium')
  @DocsEditable()
  void appendMedium(String medium) => _blink.BlinkMediaList.instance.appendMedium_Callback_1_(unwrap_jso(this), medium);
  
  @DomName('MediaList.deleteMedium')
  @DocsEditable()
  void deleteMedium(String medium) => _blink.BlinkMediaList.instance.deleteMedium_Callback_1_(unwrap_jso(this), medium);
  
  @DomName('MediaList.item')
  @DocsEditable()
  String item(int index) => _blink.BlinkMediaList.instance.item_Callback_1_(unwrap_jso(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")
  static MediaQueryList internalCreateMediaQueryList() {
    return new MediaQueryList._internalWrap();
  }

  external factory MediaQueryList._internalWrap();

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


  @DomName('MediaQueryList.matches')
  @DocsEditable()
  bool get matches => _blink.BlinkMediaQueryList.instance.matches_Getter_(unwrap_jso(this));
  
  @DomName('MediaQueryList.media')
  @DocsEditable()
  String get media => _blink.BlinkMediaQueryList.instance.media_Getter_(unwrap_jso(this));
  
  @DomName('MediaQueryList.addListener')
  @DocsEditable()
  void addListener(EventListener listener) => _blink.BlinkMediaQueryList.instance.addListener_Callback_1_(unwrap_jso(this), unwrap_jso((event) => listener(wrap_jso(event))));
  
  @DomName('MediaQueryList.removeListener')
  @DocsEditable()
  void removeListener(EventListener listener) => _blink.BlinkMediaQueryList.instance.removeListener_Callback_1_(unwrap_jso(this), unwrap_jso(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 wrap_jso(_blink.BlinkMediaQueryListEvent.instance.constructorCallback_2_(type, eventInitDict_1));
    }
    return wrap_jso(_blink.BlinkMediaQueryListEvent.instance.constructorCallback_1_(type));
  }


  @Deprecated("Internal Use Only")
  static MediaQueryListEvent internalCreateMediaQueryListEvent() {
    return new MediaQueryListEvent._internalWrap();
  }

  external factory MediaQueryListEvent._internalWrap();

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


  @DomName('MediaQueryListEvent.matches')
  @DocsEditable()
  @Experimental() // untriaged
  bool get matches => _blink.BlinkMediaQueryListEvent.instance.matches_Getter_(unwrap_jso(this));
  
  @DomName('MediaQueryListEvent.media')
  @DocsEditable()
  @Experimental() // untriaged
  String get media => _blink.BlinkMediaQueryListEvent.instance.media_Getter_(unwrap_jso(this));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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 wrap_jso(_blink.BlinkMediaSession.instance.constructorCallback_0_());
  }

  @Deprecated("Internal Use Only")
  static MediaSession internalCreateMediaSession() {
    return new MediaSession._internalWrap();
  }

  factory MediaSession._internalWrap() {
    return new MediaSession.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  @DomName('MediaSession.activate')
  @DocsEditable()
  @Experimental() // untriaged
  void activate() => _blink.BlinkMediaSession.instance.activate_Callback_0_(unwrap_jso(this));
  
  @DomName('MediaSession.deactivate')
  @DocsEditable()
  @Experimental() // untriaged
  void deactivate() => _blink.BlinkMediaSession.instance.deactivate_Callback_0_(unwrap_jso(this));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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 wrap_jso(_blink.BlinkMediaSource.instance.constructorCallback_0_());
  }


  @Deprecated("Internal Use Only")
  static MediaSource internalCreateMediaSource() {
    return new MediaSource._internalWrap();
  }

  external factory MediaSource._internalWrap();

  @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 => wrap_jso(_blink.BlinkMediaSource.instance.activeSourceBuffers_Getter_(unwrap_jso(this)));
  
  @DomName('MediaSource.duration')
  @DocsEditable()
  num get duration => _blink.BlinkMediaSource.instance.duration_Getter_(unwrap_jso(this));
  
  @DomName('MediaSource.duration')
  @DocsEditable()
  set duration(num value) => _blink.BlinkMediaSource.instance.duration_Setter_(unwrap_jso(this), value);
  
  @DomName('MediaSource.readyState')
  @DocsEditable()
  String get readyState => _blink.BlinkMediaSource.instance.readyState_Getter_(unwrap_jso(this));
  
  @DomName('MediaSource.sourceBuffers')
  @DocsEditable()
  SourceBufferList get sourceBuffers => wrap_jso(_blink.BlinkMediaSource.instance.sourceBuffers_Getter_(unwrap_jso(this)));
  
  @DomName('MediaSource.addSourceBuffer')
  @DocsEditable()
  SourceBuffer addSourceBuffer(String type) => wrap_jso(_blink.BlinkMediaSource.instance.addSourceBuffer_Callback_1_(unwrap_jso(this), type));
  
  void endOfStream([String error]) {
    if (error != null) {
      _blink.BlinkMediaSource.instance.endOfStream_Callback_1_(unwrap_jso(this), error);
      return;
    }
    _blink.BlinkMediaSource.instance.endOfStream_Callback_0_(unwrap_jso(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_(unwrap_jso(this), unwrap_jso(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 wrap_jso(_blink.BlinkMediaStream.instance.constructorCallback_0_());
    }
    if ((stream_OR_tracks is MediaStream || stream_OR_tracks == null)) {
      return wrap_jso(_blink.BlinkMediaStream.instance.constructorCallback_1_(stream_OR_tracks));
    }
    if ((stream_OR_tracks is List<MediaStreamTrack> || stream_OR_tracks == null)) {
      return wrap_jso(_blink.BlinkMediaStream.instance.constructorCallback_1_(stream_OR_tracks));
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }


  @Deprecated("Internal Use Only")
  static MediaStream internalCreateMediaStream() {
    return new MediaStream._internalWrap();
  }

  external factory MediaStream._internalWrap();

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


  @DomName('MediaStream.active')
  @DocsEditable()
  @Experimental() // untriaged
  bool get active => _blink.BlinkMediaStream.instance.active_Getter_(unwrap_jso(this));
  
  @DomName('MediaStream.ended')
  @DocsEditable()
  bool get ended => _blink.BlinkMediaStream.instance.ended_Getter_(unwrap_jso(this));
  
  @DomName('MediaStream.id')
  @DocsEditable()
  String get id => _blink.BlinkMediaStream.instance.id_Getter_(unwrap_jso(this));
  
  @DomName('MediaStream.label')
  @DocsEditable()
  @Experimental() // non-standard
  String get label => _blink.BlinkMediaStream.instance.label_Getter_(unwrap_jso(this));
  
  @DomName('MediaStream.addTrack')
  @DocsEditable()
  void addTrack(MediaStreamTrack track) => _blink.BlinkMediaStream.instance.addTrack_Callback_1_(unwrap_jso(this), unwrap_jso(track));
  
  @DomName('MediaStream.clone')
  @DocsEditable()
  @Experimental() // untriaged
  MediaStream clone() => wrap_jso(_blink.BlinkMediaStream.instance.clone_Callback_0_(unwrap_jso(this)));
  
  @DomName('MediaStream.getAudioTracks')
  @DocsEditable()
  List<MediaStreamTrack> getAudioTracks() => wrap_jso(_blink.BlinkMediaStream.instance.getAudioTracks_Callback_0_(unwrap_jso(this)));
  
  @DomName('MediaStream.getTrackById')
  @DocsEditable()
  MediaStreamTrack getTrackById(String trackId) => wrap_jso(_blink.BlinkMediaStream.instance.getTrackById_Callback_1_(unwrap_jso(this), trackId));
  
  @DomName('MediaStream.getTracks')
  @DocsEditable()
  @Experimental() // untriaged
  List<MediaStreamTrack> getTracks() => wrap_jso(_blink.BlinkMediaStream.instance.getTracks_Callback_0_(unwrap_jso(this)));
  
  @DomName('MediaStream.getVideoTracks')
  @DocsEditable()
  List<MediaStreamTrack> getVideoTracks() => wrap_jso(_blink.BlinkMediaStream.instance.getVideoTracks_Callback_0_(unwrap_jso(this)));
  
  @DomName('MediaStream.removeTrack')
  @DocsEditable()
  void removeTrack(MediaStreamTrack track) => _blink.BlinkMediaStream.instance.removeTrack_Callback_1_(unwrap_jso(this), unwrap_jso(track));
  
  @DomName('MediaStream.stop')
  @DocsEditable()
  void stop() => _blink.BlinkMediaStream.instance.stop_Callback_0_(unwrap_jso(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 wrap_jso(_blink.BlinkMediaStreamEvent.instance.constructorCallback_2_(type, eventInitDict_1));
    }
    return wrap_jso(_blink.BlinkMediaStreamEvent.instance.constructorCallback_1_(type));
  }


  @Deprecated("Internal Use Only")
  static MediaStreamEvent internalCreateMediaStreamEvent() {
    return new MediaStreamEvent._internalWrap();
  }

  external factory MediaStreamEvent._internalWrap();

  @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 => wrap_jso(_blink.BlinkMediaStreamEvent.instance.stream_Getter_(unwrap_jso(this)));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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")
  static MediaStreamTrack internalCreateMediaStreamTrack() {
    return new MediaStreamTrack._internalWrap();
  }

  external factory MediaStreamTrack._internalWrap();

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


  @DomName('MediaStreamTrack.enabled')
  @DocsEditable()
  bool get enabled => _blink.BlinkMediaStreamTrack.instance.enabled_Getter_(unwrap_jso(this));
  
  @DomName('MediaStreamTrack.enabled')
  @DocsEditable()
  set enabled(bool value) => _blink.BlinkMediaStreamTrack.instance.enabled_Setter_(unwrap_jso(this), value);
  
  @DomName('MediaStreamTrack.id')
  @DocsEditable()
  String get id => _blink.BlinkMediaStreamTrack.instance.id_Getter_(unwrap_jso(this));
  
  @DomName('MediaStreamTrack.kind')
  @DocsEditable()
  String get kind => _blink.BlinkMediaStreamTrack.instance.kind_Getter_(unwrap_jso(this));
  
  @DomName('MediaStreamTrack.label')
  @DocsEditable()
  String get label => _blink.BlinkMediaStreamTrack.instance.label_Getter_(unwrap_jso(this));
  
  @DomName('MediaStreamTrack.muted')
  @DocsEditable()
  @Experimental() // untriaged
  bool get muted => _blink.BlinkMediaStreamTrack.instance.muted_Getter_(unwrap_jso(this));
  
  @DomName('MediaStreamTrack.readyState')
  @DocsEditable()
  String get readyState => _blink.BlinkMediaStreamTrack.instance.readyState_Getter_(unwrap_jso(this));
  
  @DomName('MediaStreamTrack.clone')
  @DocsEditable()
  @Experimental() // untriaged
  MediaStreamTrack clone() => wrap_jso(_blink.BlinkMediaStreamTrack.instance.clone_Callback_0_(unwrap_jso(this)));
  
  @DomName('MediaStreamTrack.getSources')
  @DocsEditable()
  @Experimental() // untriaged
  static void _getSources(MediaStreamTrackSourcesCallback callback) => _blink.BlinkMediaStreamTrack.instance.getSources_Callback_1_(unwrap_jso((sources) => callback(sources)));
  
  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_(unwrap_jso(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")
  static MediaStreamTrackEvent internalCreateMediaStreamTrackEvent() {
    return new MediaStreamTrackEvent._internalWrap();
  }

  external factory MediaStreamTrackEvent._internalWrap();

  @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 => wrap_jso(_blink.BlinkMediaStreamTrackEvent.instance.track_Getter_(unwrap_jso(this)));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of 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")
  static MemoryInfo internalCreateMemoryInfo() {
    return new MemoryInfo._internalWrap();
  }

  factory MemoryInfo._internalWrap() {
    return new MemoryInfo.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  @DomName('MemoryInfo.jsHeapSizeLimit')
  @DocsEditable()
  int get jsHeapSizeLimit => _blink.BlinkMemoryInfo.instance.jsHeapSizeLimit_Getter_(unwrap_jso(this));
  
  @DomName('MemoryInfo.totalJSHeapSize')
  @DocsEditable()
  int get totalJSHeapSize => _blink.BlinkMemoryInfo.instance.totalJSHeapSize_Getter_(unwrap_jso(this));
  
  @DomName('MemoryInfo.usedJSHeapSize')
  @DocsEditable()
  int get usedJSHeapSize => _blink.BlinkMemoryInfo.instance.usedJSHeapSize_Getter_(unwrap_jso(this));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this 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")
  static MenuElement internalCreateMenuElement() {
    return new MenuElement._internalWrap();
  }

  external factory MenuElement._internalWrap();

  @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_(unwrap_jso(this));
  
  @DomName('HTMLMenuElement.label')
  @DocsEditable()
  @Experimental() // untriaged
  set label(String value) => _blink.BlinkHTMLMenuElement.instance.label_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLMenuElement.type')
  @DocsEditable()
  @Experimental() // untriaged
  String get type => _blink.BlinkHTMLMenuElement.instance.type_Getter_(unwrap_jso(this));
  
  @DomName('HTMLMenuElement.type')
  @DocsEditable()
  @Experimental() // untriaged
  set type(String value) => _blink.BlinkHTMLMenuElement.instance.type_Setter_(unwrap_jso(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")
  static MenuItemElement internalCreateMenuItemElement() {
    return new MenuItemElement._internalWrap();
  }

  external factory MenuItemElement._internalWrap();

  @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_(unwrap_jso(this));
  
  @DomName('HTMLMenuItemElement.checked')
  @DocsEditable()
  @Experimental() // untriaged
  set checked(bool value) => _blink.BlinkHTMLMenuItemElement.instance.checked_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLMenuItemElement.default')
  @DocsEditable()
  @Experimental() // untriaged
  bool get defaultValue => _blink.BlinkHTMLMenuItemElement.instance.default_Getter_(unwrap_jso(this));
  
  @DomName('HTMLMenuItemElement.default')
  @DocsEditable()
  @Experimental() // untriaged
  set defaultValue(bool value) => _blink.BlinkHTMLMenuItemElement.instance.default_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLMenuItemElement.disabled')
  @DocsEditable()
  @Experimental() // untriaged
  bool get disabled => _blink.BlinkHTMLMenuItemElement.instance.disabled_Getter_(unwrap_jso(this));
  
  @DomName('HTMLMenuItemElement.disabled')
  @DocsEditable()
  @Experimental() // untriaged
  set disabled(bool value) => _blink.BlinkHTMLMenuItemElement.instance.disabled_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLMenuItemElement.icon')
  @DocsEditable()
  @Experimental() // untriaged
  String get icon => _blink.BlinkHTMLMenuItemElement.instance.icon_Getter_(unwrap_jso(this));
  
  @DomName('HTMLMenuItemElement.icon')
  @DocsEditable()
  @Experimental() // untriaged
  set icon(String value) => _blink.BlinkHTMLMenuItemElement.instance.icon_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLMenuItemElement.label')
  @DocsEditable()
  @Experimental() // untriaged
  String get label => _blink.BlinkHTMLMenuItemElement.instance.label_Getter_(unwrap_jso(this));
  
  @DomName('HTMLMenuItemElement.label')
  @DocsEditable()
  @Experimental() // untriaged
  set label(String value) => _blink.BlinkHTMLMenuItemElement.instance.label_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLMenuItemElement.radiogroup')
  @DocsEditable()
  @Experimental() // untriaged
  String get radiogroup => _blink.BlinkHTMLMenuItemElement.instance.radiogroup_Getter_(unwrap_jso(this));
  
  @DomName('HTMLMenuItemElement.radiogroup')
  @DocsEditable()
  @Experimental() // untriaged
  set radiogroup(String value) => _blink.BlinkHTMLMenuItemElement.instance.radiogroup_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLMenuItemElement.type')
  @DocsEditable()
  @Experimental() // untriaged
  String get type => _blink.BlinkHTMLMenuItemElement.instance.type_Getter_(unwrap_jso(this));
  
  @DomName('HTMLMenuItemElement.type')
  @DocsEditable()
  @Experimental() // untriaged
  set type(String value) => _blink.BlinkHTMLMenuItemElement.instance.type_Setter_(unwrap_jso(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")
  static MessageChannel internalCreateMessageChannel() {
    return new MessageChannel._internalWrap();
  }

  factory MessageChannel._internalWrap() {
    return new MessageChannel.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  @DomName('MessageChannel.port1')
  @DocsEditable()
  MessagePort get port1 => wrap_jso(_blink.BlinkMessageChannel.instance.port1_Getter_(unwrap_jso(this)));
  
  @DomName('MessageChannel.port2')
  @DocsEditable()
  MessagePort get port2 => wrap_jso(_blink.BlinkMessageChannel.instance.port2_Getter_(unwrap_jso(this)));
  
}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.


@DomName('MessageEvent')
class MessageEvent extends Event {
  factory MessageEvent(String type,
      {bool canBubble: false, bool cancelable: false, Object data,
      String origin, String lastEventId,
      Window source, List messagePorts}) {
    if (source == null) {
      source = window;
    }
    var event = document._createEvent("MessageEvent");
    event._initMessageEvent(type, canBubble, cancelable, data, origin,
        lastEventId, source, messagePorts);
    return event;
  }

  // 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_(unwrap_jso(this)));



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


  @Deprecated("Internal Use Only")
  static MessageEvent internalCreateMessageEvent() {
    return new MessageEvent._internalWrap();
  }

  external factory MessageEvent._internalWrap();

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


  @DomName('MessageEvent.lastEventId')
  @DocsEditable()
  @Unstable()
  String get lastEventId => _blink.BlinkMessageEvent.instance.lastEventId_Getter_(unwrap_jso(this));
  
  @DomName('MessageEvent.origin')
  @DocsEditable()
  String get origin => _blink.BlinkMessageEvent.instance.origin_Getter_(unwrap_jso(this));
  
  @DomName('MessageEvent.source')
  @DocsEditable()
  EventTarget get source => wrap_jso(_blink.BlinkMessageEvent.instance.source_Getter_(unwrap_jso(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_(unwrap_jso(this), typeArg, canBubbleArg, cancelableArg, dataArg, originArg, lastEventIdArg, unwrap_jso(sourceArg), unwrap_jso(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")
  static MessagePort internalCreateMessagePort() {
    return new MessagePort._internalWrap();
  }

  external factory MessagePort._internalWrap();

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


  @DomName('MessagePort.close')
  @DocsEditable()
  void close() => _blink.BlinkMessagePort.instance.close_Callback_0_(unwrap_jso(this));
  
  void postMessage(Object message, [List<MessagePort> transfer]) {
    if (transfer != null) {
      _blink.BlinkMessagePort.instance.postMessage_Callback_2_(unwrap_jso(this), convertDartToNative_SerializedScriptValue(message), transfer);
      return;
    }
    _blink.BlinkMessagePort.instance.postMessage_Callback_1_(unwrap_jso(this), convertDartToNative_SerializedScriptValue(message));
    return;
  }

  @DomName('MessagePort.start')
  @DocsEditable()
  void start() => _blink.BlinkMessagePort.instance.start_Callback_0_(unwrap_jso(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")
  static MetaElement internalCreateMetaElement() {
    return new MetaElement._internalWrap();
  }

  external factory MetaElement._internalWrap();

  @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_(unwrap_jso(this));
  
  @DomName('HTMLMetaElement.content')
  @DocsEditable()
  set content(String value) => _blink.BlinkHTMLMetaElement.instance.content_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLMetaElement.httpEquiv')
  @DocsEditable()
  String get httpEquiv => _blink.BlinkHTMLMetaElement.instance.httpEquiv_Getter_(unwrap_jso(this));
  
  @DomName('HTMLMetaElement.httpEquiv')
  @DocsEditable()
  set httpEquiv(String value) => _blink.BlinkHTMLMetaElement.instance.httpEquiv_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLMetaElement.name')
  @DocsEditable()
  String get name => _blink.BlinkHTMLMetaElement.instance.name_Getter_(unwrap_jso(this));
  
  @DomName('HTMLMetaElement.name')
  @DocsEditable()
  set name(String value) => _blink.BlinkHTMLMetaElement.instance.name_Setter_(unwrap_jso(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")
  static Metadata internalCreateMetadata() {
    return new Metadata._internalWrap();
  }

  factory Metadata._internalWrap() {
    return new Metadata.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  @DomName('Metadata.modificationTime')
  @DocsEditable()
  DateTime get modificationTime => _blink.BlinkMetadata.instance.modificationTime_Getter_(unwrap_jso(this));
  
  @DomName('Metadata.size')
  @DocsEditable()
  int get size => _blink.BlinkMetadata.instance.size_Getter_(unwrap_jso(this));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of 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")
  static MeterElement internalCreateMeterElement() {
    return new MeterElement._internalWrap();
  }

  external factory MeterElement._internalWrap();

  @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_(unwrap_jso(this));
  
  @DomName('HTMLMeterElement.high')
  @DocsEditable()
  set high(num value) => _blink.BlinkHTMLMeterElement.instance.high_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLMeterElement.labels')
  @DocsEditable()
  @Unstable()
  List<Node> get labels => wrap_jso(_blink.BlinkHTMLMeterElement.instance.labels_Getter_(unwrap_jso(this)));
  
  @DomName('HTMLMeterElement.low')
  @DocsEditable()
  num get low => _blink.BlinkHTMLMeterElement.instance.low_Getter_(unwrap_jso(this));
  
  @DomName('HTMLMeterElement.low')
  @DocsEditable()
  set low(num value) => _blink.BlinkHTMLMeterElement.instance.low_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLMeterElement.max')
  @DocsEditable()
  num get max => _blink.BlinkHTMLMeterElement.instance.max_Getter_(unwrap_jso(this));
  
  @DomName('HTMLMeterElement.max')
  @DocsEditable()
  set max(num value) => _blink.BlinkHTMLMeterElement.instance.max_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLMeterElement.min')
  @DocsEditable()
  num get min => _blink.BlinkHTMLMeterElement.instance.min_Getter_(unwrap_jso(this));
  
  @DomName('HTMLMeterElement.min')
  @DocsEditable()
  set min(num value) => _blink.BlinkHTMLMeterElement.instance.min_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLMeterElement.optimum')
  @DocsEditable()
  num get optimum => _blink.BlinkHTMLMeterElement.instance.optimum_Getter_(unwrap_jso(this));
  
  @DomName('HTMLMeterElement.optimum')
  @DocsEditable()
  set optimum(num value) => _blink.BlinkHTMLMeterElement.instance.optimum_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLMeterElement.value')
  @DocsEditable()
  num get value => _blink.BlinkHTMLMeterElement.instance.value_Getter_(unwrap_jso(this));
  
  @DomName('HTMLMeterElement.value')
  @DocsEditable()
  set value(num value) => _blink.BlinkHTMLMeterElement.instance.value_Setter_(unwrap_jso(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")
  static MidiAccess internalCreateMidiAccess() {
    return new MidiAccess._internalWrap();
  }

  external factory MidiAccess._internalWrap();

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


  @DomName('MIDIAccess.inputs')
  @DocsEditable()
  MidiInputMap get inputs => wrap_jso(_blink.BlinkMIDIAccess.instance.inputs_Getter_(unwrap_jso(this)));
  
  @DomName('MIDIAccess.outputs')
  @DocsEditable()
  MidiOutputMap get outputs => wrap_jso(_blink.BlinkMIDIAccess.instance.outputs_Getter_(unwrap_jso(this)));
  
  @DomName('MIDIAccess.sysexEnabled')
  @DocsEditable()
  @Experimental() // untriaged
  bool get sysexEnabled => _blink.BlinkMIDIAccess.instance.sysexEnabled_Getter_(unwrap_jso(this));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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 wrap_jso(_blink.BlinkMIDIConnectionEvent.instance.constructorCallback_2_(type, eventInitDict_1));
    }
    return wrap_jso(_blink.BlinkMIDIConnectionEvent.instance.constructorCallback_1_(type));
  }


  @Deprecated("Internal Use Only")
  static MidiConnectionEvent internalCreateMidiConnectionEvent() {
    return new MidiConnectionEvent._internalWrap();
  }

  external factory MidiConnectionEvent._internalWrap();

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


  @DomName('MIDIConnectionEvent.port')
  @DocsEditable()
  MidiPort get port => wrap_jso(_blink.BlinkMIDIConnectionEvent.instance.port_Getter_(unwrap_jso(this)));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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")
  static MidiInput internalCreateMidiInput() {
    return new MidiInput._internalWrap();
  }

  external factory MidiInput._internalWrap();

  @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")
  static MidiInputMap internalCreateMidiInputMap() {
    return new MidiInputMap._internalWrap();
  }

  factory MidiInputMap._internalWrap() {
    return new MidiInputMap.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  @DomName('MIDIInputMap.size')
  @DocsEditable()
  @Experimental() // untriaged
  int get size => _blink.BlinkMIDIInputMap.instance.size_Getter_(unwrap_jso(this));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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 wrap_jso(_blink.BlinkMIDIMessageEvent.instance.constructorCallback_2_(type, eventInitDict_1));
    }
    return wrap_jso(_blink.BlinkMIDIMessageEvent.instance.constructorCallback_1_(type));
  }


  @Deprecated("Internal Use Only")
  static MidiMessageEvent internalCreateMidiMessageEvent() {
    return new MidiMessageEvent._internalWrap();
  }

  external factory MidiMessageEvent._internalWrap();

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


  @DomName('MIDIMessageEvent.data')
  @DocsEditable()
  Uint8List get data => wrap_jso(_blink.BlinkMIDIMessageEvent.instance.data_Getter_(unwrap_jso(this)));
  
  @DomName('MIDIMessageEvent.receivedTime')
  @DocsEditable()
  num get receivedTime => _blink.BlinkMIDIMessageEvent.instance.receivedTime_Getter_(unwrap_jso(this));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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")
  static MidiOutput internalCreateMidiOutput() {
    return new MidiOutput._internalWrap();
  }

  external factory MidiOutput._internalWrap();

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


  void send(Uint8List data, [num timestamp]) {
    if (timestamp != null) {
      _blink.BlinkMIDIOutput.instance.send_Callback_2_(unwrap_jso(this), unwrap_jso(data), timestamp);
      return;
    }
    _blink.BlinkMIDIOutput.instance.send_Callback_1_(unwrap_jso(this), unwrap_jso(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")
  static MidiOutputMap internalCreateMidiOutputMap() {
    return new MidiOutputMap._internalWrap();
  }

  factory MidiOutputMap._internalWrap() {
    return new MidiOutputMap.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  @DomName('MIDIOutputMap.size')
  @DocsEditable()
  @Experimental() // untriaged
  int get size => _blink.BlinkMIDIOutputMap.instance.size_Getter_(unwrap_jso(this));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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")
  static MidiPort internalCreateMidiPort() {
    return new MidiPort._internalWrap();
  }

  external factory MidiPort._internalWrap();

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


  @DomName('MIDIPort.connection')
  @DocsEditable()
  @Experimental() // untriaged
  String get connection => _blink.BlinkMIDIPort.instance.connection_Getter_(unwrap_jso(this));
  
  @DomName('MIDIPort.id')
  @DocsEditable()
  String get id => _blink.BlinkMIDIPort.instance.id_Getter_(unwrap_jso(this));
  
  @DomName('MIDIPort.manufacturer')
  @DocsEditable()
  String get manufacturer => _blink.BlinkMIDIPort.instance.manufacturer_Getter_(unwrap_jso(this));
  
  @DomName('MIDIPort.name')
  @DocsEditable()
  String get name => _blink.BlinkMIDIPort.instance.name_Getter_(unwrap_jso(this));
  
  @DomName('MIDIPort.state')
  @DocsEditable()
  @Experimental() // untriaged
  String get state => _blink.BlinkMIDIPort.instance.state_Getter_(unwrap_jso(this));
  
  @DomName('MIDIPort.type')
  @DocsEditable()
  String get type => _blink.BlinkMIDIPort.instance.type_Getter_(unwrap_jso(this));
  
  @DomName('MIDIPort.version')
  @DocsEditable()
  String get version => _blink.BlinkMIDIPort.instance.version_Getter_(unwrap_jso(this));
  
  @DomName('MIDIPort.close')
  @DocsEditable()
  @Experimental() // untriaged
  Future close() => wrap_jso(_blink.BlinkMIDIPort.instance.close_Callback_0_(unwrap_jso(this)));
  
  @DomName('MIDIPort.open')
  @DocsEditable()
  @Experimental() // untriaged
  Future open() => wrap_jso(_blink.BlinkMIDIPort.instance.open_Callback_0_(unwrap_jso(this)));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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")
  static MimeType internalCreateMimeType() {
    return new MimeType._internalWrap();
  }

  factory MimeType._internalWrap() {
    return new MimeType.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  @DomName('MimeType.description')
  @DocsEditable()
  String get description => _blink.BlinkMimeType.instance.description_Getter_(unwrap_jso(this));
  
  @DomName('MimeType.enabledPlugin')
  @DocsEditable()
  Plugin get enabledPlugin => wrap_jso(_blink.BlinkMimeType.instance.enabledPlugin_Getter_(unwrap_jso(this)));
  
  @DomName('MimeType.suffixes')
  @DocsEditable()
  String get suffixes => _blink.BlinkMimeType.instance.suffixes_Getter_(unwrap_jso(this));
  
  @DomName('MimeType.type')
  @DocsEditable()
  String get type => _blink.BlinkMimeType.instance.type_Getter_(unwrap_jso(this));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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")
  static MimeTypeArray internalCreateMimeTypeArray() {
    return new MimeTypeArray._internalWrap();
  }

  factory MimeTypeArray._internalWrap() {
    return new MimeTypeArray.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  @DomName('MimeTypeArray.length')
  @DocsEditable()
  int get length => _blink.BlinkMimeTypeArray.instance.length_Getter_(unwrap_jso(this));
  
  MimeType operator[](int index) {
    if (index < 0 || index >= length)
      throw new RangeError.index(index, this);
    return wrap_jso(_blink.BlinkMimeTypeArray.instance.item_Callback_1_(unwrap_jso(this), index));
  }

  MimeType _nativeIndexedGetter(int index) => wrap_jso(_blink.BlinkMimeTypeArray.instance.item_Callback_1_(unwrap_jso(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) => wrap_jso(_blink.BlinkMimeTypeArray.instance.item_Callback_1_(unwrap_jso(this), index));
  
  MimeType namedItem(String name) {
    if ((name is String || name == null)) {
      return wrap_jso(_blink.BlinkMimeTypeArray.instance.namedItem_Callback_1_(unwrap_jso(this), name));
    }
    if ((name is String || name == null)) {
      return wrap_jso(_blink.BlinkMimeTypeArray.instance.namedItem_Callback_1_(unwrap_jso(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")
  static ModElement internalCreateModElement() {
    return new ModElement._internalWrap();
  }

  external factory ModElement._internalWrap();

  @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_(unwrap_jso(this));
  
  @DomName('HTMLModElement.cite')
  @DocsEditable()
  set cite(String value) => _blink.BlinkHTMLModElement.instance.cite_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLModElement.dateTime')
  @DocsEditable()
  String get dateTime => _blink.BlinkHTMLModElement.instance.dateTime_Getter_(unwrap_jso(this));
  
  @DomName('HTMLModElement.dateTime')
  @DocsEditable()
  set dateTime(String value) => _blink.BlinkHTMLModElement.instance.dateTime_Setter_(unwrap_jso(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 wrap_jso(_blink.BlinkMouseEvent.instance.constructorCallback_2_(type, eventInitDict_1));
    }
    return wrap_jso(_blink.BlinkMouseEvent.instance.constructorCallback_1_(type));
  }


  @Deprecated("Internal Use Only")
  static MouseEvent internalCreateMouseEvent() {
    return new MouseEvent._internalWrap();
  }

  external factory MouseEvent._internalWrap();

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


  @DomName('MouseEvent.altKey')
  @DocsEditable()
  bool get altKey => _blink.BlinkMouseEvent.instance.altKey_Getter_(unwrap_jso(this));
  
  @DomName('MouseEvent.button')
  @DocsEditable()
  int get button => _blink.BlinkMouseEvent.instance.button_Getter_(unwrap_jso(this));
  
  @DomName('MouseEvent.buttons')
  @DocsEditable()
  @Experimental() // untriaged
  int get buttons => _blink.BlinkMouseEvent.instance.buttons_Getter_(unwrap_jso(this));
  
  @DomName('MouseEvent.clientX')
  @DocsEditable()
  int get _clientX => _blink.BlinkMouseEvent.instance.clientX_Getter_(unwrap_jso(this));
  
  @DomName('MouseEvent.clientY')
  @DocsEditable()
  int get _clientY => _blink.BlinkMouseEvent.instance.clientY_Getter_(unwrap_jso(this));
  
  @DomName('MouseEvent.ctrlKey')
  @DocsEditable()
  bool get ctrlKey => _blink.BlinkMouseEvent.instance.ctrlKey_Getter_(unwrap_jso(this));
  
  @DomName('MouseEvent.dataTransfer')
  @DocsEditable()
  @Unstable()
  DataTransfer get dataTransfer => wrap_jso(_blink.BlinkMouseEvent.instance.dataTransfer_Getter_(unwrap_jso(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 => wrap_jso(_blink.BlinkMouseEvent.instance.fromElement_Getter_(unwrap_jso(this)));
  
  @DomName('MouseEvent.layerX')
  @DocsEditable()
  @Experimental() // untriaged
  int get _layerX => _blink.BlinkMouseEvent.instance.layerX_Getter_(unwrap_jso(this));
  
  @DomName('MouseEvent.layerY')
  @DocsEditable()
  @Experimental() // untriaged
  int get _layerY => _blink.BlinkMouseEvent.instance.layerY_Getter_(unwrap_jso(this));
  
  @DomName('MouseEvent.metaKey')
  @DocsEditable()
  bool get metaKey => _blink.BlinkMouseEvent.instance.metaKey_Getter_(unwrap_jso(this));
  
  @DomName('MouseEvent.movementX')
  @DocsEditable()
  @Experimental() // untriaged
  int get _movementX => _blink.BlinkMouseEvent.instance.movementX_Getter_(unwrap_jso(this));
  
  @DomName('MouseEvent.movementY')
  @DocsEditable()
  @Experimental() // untriaged
  int get _movementY => _blink.BlinkMouseEvent.instance.movementY_Getter_(unwrap_jso(this));
  
  @DomName('MouseEvent.offsetX')
  @DocsEditable()
  @Unstable()
  int get _offsetX => _blink.BlinkMouseEvent.instance.offsetX_Getter_(unwrap_jso(this));
  
  @DomName('MouseEvent.offsetY')
  @DocsEditable()
  @Unstable()
  int get _offsetY => _blink.BlinkMouseEvent.instance.offsetY_Getter_(unwrap_jso(this));
  
  @DomName('MouseEvent.pageX')
  @DocsEditable()
  @Experimental() // untriaged
  int get _pageX => _blink.BlinkMouseEvent.instance.pageX_Getter_(unwrap_jso(this));
  
  @DomName('MouseEvent.pageY')
  @DocsEditable()
  @Experimental() // untriaged
  int get _pageY => _blink.BlinkMouseEvent.instance.pageY_Getter_(unwrap_jso(this));
  
  @DomName('MouseEvent.region')
  @DocsEditable()
  @Experimental() // untriaged
  String get region => _blink.BlinkMouseEvent.instance.region_Getter_(unwrap_jso(this));
  
  @DomName('MouseEvent.relatedTarget')
  @DocsEditable()
  EventTarget get relatedTarget => wrap_jso(_blink.BlinkMouseEvent.instance.relatedTarget_Getter_(unwrap_jso(this)));
  
  @DomName('MouseEvent.screenX')
  @DocsEditable()
  int get _screenX => _blink.BlinkMouseEvent.instance.screenX_Getter_(unwrap_jso(this));
  
  @DomName('MouseEvent.screenY')
  @DocsEditable()
  int get _screenY => _blink.BlinkMouseEvent.instance.screenY_Getter_(unwrap_jso(this));
  
  @DomName('MouseEvent.shiftKey')
  @DocsEditable()
  bool get shiftKey => _blink.BlinkMouseEvent.instance.shiftKey_Getter_(unwrap_jso(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 => wrap_jso(_blink.BlinkMouseEvent.instance.toElement_Getter_(unwrap_jso(this)));
  
  @DomName('MouseEvent.webkitMovementX')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  int get _webkitMovementX => _blink.BlinkMouseEvent.instance.webkitMovementX_Getter_(unwrap_jso(this));
  
  @DomName('MouseEvent.webkitMovementY')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  int get _webkitMovementY => _blink.BlinkMouseEvent.instance.webkitMovementY_Getter_(unwrap_jso(this));
  
  @DomName('MouseEvent.which')
  @DocsEditable()
  @Experimental() // untriaged
  int get _which => _blink.BlinkMouseEvent.instance.which_Getter_(unwrap_jso(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_(unwrap_jso(this), type, bubbles, cancelable, unwrap_jso(view), detail, screenX, screenY, clientX, clientY, ctrlKey, altKey, shiftKey, metaKey, button, unwrap_jso(relatedTarget));
  

  @deprecated
  int get clientX => client.x;
  @deprecated
  int get clientY => client.y;
  @deprecated
  int get offsetX => offset.x;
  @deprecated
  int get offsetY => offset.y;
  @deprecated
  int get movementX => movement.x;
  @deprecated
  int get movementY => movement.y;
  @deprecated
  int get screenX => screen.x;
  @deprecated
  int get screenY => screen.y;

  @DomName('MouseEvent.clientX')
  @DomName('MouseEvent.clientY')
  Point get client => new Point(_clientX, _clientY);

  @DomName('MouseEvent.movementX')
  @DomName('MouseEvent.movementY')
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  Point get movement => new Point(_webkitMovementX, _webkitMovementY);

  /**
   * The coordinates of the mouse pointer in target node coordinates.
   *
   * This value may vary between platforms if the target node moves
   * after the event has fired or if the element has CSS transforms affecting
   * it.
   */
  Point get offset => new Point(_offsetX, _offsetY);

  @DomName('MouseEvent.screenX')
  @DomName('MouseEvent.screenY')
  Point get screen => new Point(_screenX, _screenY);

  @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) => wrap_jso(_create(callback));

  @Deprecated("Internal Use Only")
  static MutationObserver internalCreateMutationObserver() {
    return new MutationObserver._internalWrap();
  }

  factory MutationObserver._internalWrap() {
    return new MutationObserver.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  @DomName('MutationObserver.disconnect')
  @DocsEditable()
  void disconnect() => _blink.BlinkMutationObserver.instance.disconnect_Callback_0_(unwrap_jso(this));
  
  @DomName('MutationObserver.observe')
  @DocsEditable()
  void _observe(Node target, Map options) => _blink.BlinkMutationObserver.instance.observe_Callback_2_(unwrap_jso(this), unwrap_jso(target), convertDartToNative_Dictionary(options));
  
  @DomName('MutationObserver.takeRecords')
  @DocsEditable()
  List<MutationRecord> takeRecords() => wrap_jso(_blink.BlinkMutationObserver.instance.takeRecords_Callback_0_(unwrap_jso(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) => wrap_jso(_blink.BlinkMutationObserver.instance.constructorCallback_1_((mutations, observer) {
    callback(wrap_jso(mutations), wrap_jso(observer));
  }));

  /**
   * 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")
  static MutationRecord internalCreateMutationRecord() {
    return new MutationRecord._internalWrap();
  }

  factory MutationRecord._internalWrap() {
    return new MutationRecord.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  @DomName('MutationRecord.addedNodes')
  @DocsEditable()
  List<Node> get addedNodes => wrap_jso(_blink.BlinkMutationRecord.instance.addedNodes_Getter_(unwrap_jso(this)));
  
  @DomName('MutationRecord.attributeName')
  @DocsEditable()
  String get attributeName => _blink.BlinkMutationRecord.instance.attributeName_Getter_(unwrap_jso(this));
  
  @DomName('MutationRecord.attributeNamespace')
  @DocsEditable()
  String get attributeNamespace => _blink.BlinkMutationRecord.instance.attributeNamespace_Getter_(unwrap_jso(this));
  
  @DomName('MutationRecord.nextSibling')
  @DocsEditable()
  Node get nextSibling => wrap_jso(_blink.BlinkMutationRecord.instance.nextSibling_Getter_(unwrap_jso(this)));
  
  @DomName('MutationRecord.oldValue')
  @DocsEditable()
  String get oldValue => _blink.BlinkMutationRecord.instance.oldValue_Getter_(unwrap_jso(this));
  
  @DomName('MutationRecord.previousSibling')
  @DocsEditable()
  Node get previousSibling => wrap_jso(_blink.BlinkMutationRecord.instance.previousSibling_Getter_(unwrap_jso(this)));
  
  @DomName('MutationRecord.removedNodes')
  @DocsEditable()
  List<Node> get removedNodes => wrap_jso(_blink.BlinkMutationRecord.instance.removedNodes_Getter_(unwrap_jso(this)));
  
  @DomName('MutationRecord.target')
  @DocsEditable()
  Node get target => wrap_jso(_blink.BlinkMutationRecord.instance.target_Getter_(unwrap_jso(this)));
  
  @DomName('MutationRecord.type')
  @DocsEditable()
  String get type => _blink.BlinkMutationRecord.instance.type_Getter_(unwrap_jso(this));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for 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")
  static Navigator internalCreateNavigator() {
    return new Navigator._internalWrap();
  }

  factory Navigator._internalWrap() {
    return new Navigator.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  @DomName('Navigator.bluetooth')
  @DocsEditable()
  @Experimental() // untriaged
  Bluetooth get bluetooth => wrap_jso(_blink.BlinkNavigator.instance.bluetooth_Getter_(unwrap_jso(this)));
  
  @DomName('Navigator.connection')
  @DocsEditable()
  @Experimental() // untriaged
  NetworkInformation get connection => wrap_jso(_blink.BlinkNavigator.instance.connection_Getter_(unwrap_jso(this)));
  
  @DomName('Navigator.credentials')
  @DocsEditable()
  @Experimental() // untriaged
  CredentialsContainer get credentials => wrap_jso(_blink.BlinkNavigator.instance.credentials_Getter_(unwrap_jso(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_(unwrap_jso(this));
  
  @DomName('Navigator.geolocation')
  @DocsEditable()
  @Unstable()
  Geolocation get geolocation => wrap_jso(_blink.BlinkNavigator.instance.geolocation_Getter_(unwrap_jso(this)));
  
  @DomName('Navigator.maxTouchPoints')
  @DocsEditable()
  @Experimental() // untriaged
  int get maxTouchPoints => _blink.BlinkNavigator.instance.maxTouchPoints_Getter_(unwrap_jso(this));
  
  @DomName('Navigator.mediaDevices')
  @DocsEditable()
  @Experimental() // untriaged
  MediaDevices get mediaDevices => wrap_jso(_blink.BlinkNavigator.instance.mediaDevices_Getter_(unwrap_jso(this)));
  
  @DomName('Navigator.mimeTypes')
  @DocsEditable()
  @Experimental() // nonstandard
  MimeTypeArray get mimeTypes => wrap_jso(_blink.BlinkNavigator.instance.mimeTypes_Getter_(unwrap_jso(this)));
  
  @DomName('Navigator.permissions')
  @DocsEditable()
  @Experimental() // untriaged
  Permissions get permissions => wrap_jso(_blink.BlinkNavigator.instance.permissions_Getter_(unwrap_jso(this)));
  
  @DomName('Navigator.presentation')
  @DocsEditable()
  @Experimental() // untriaged
  Presentation get presentation => wrap_jso(_blink.BlinkNavigator.instance.presentation_Getter_(unwrap_jso(this)));
  
  @DomName('Navigator.productSub')
  @DocsEditable()
  @Unstable()
  String get productSub => _blink.BlinkNavigator.instance.productSub_Getter_(unwrap_jso(this));
  
  @DomName('Navigator.serviceWorker')
  @DocsEditable()
  @Experimental() // untriaged
  ServiceWorkerContainer get serviceWorker => wrap_jso(_blink.BlinkNavigator.instance.serviceWorker_Getter_(unwrap_jso(this)));
  
  @DomName('Navigator.services')
  @DocsEditable()
  @Experimental() // untriaged
  ServicePortCollection get services => wrap_jso(_blink.BlinkNavigator.instance.services_Getter_(unwrap_jso(this)));
  
  @DomName('Navigator.storageQuota')
  @DocsEditable()
  @Experimental() // untriaged
  StorageQuota get storageQuota => wrap_jso(_blink.BlinkNavigator.instance.storageQuota_Getter_(unwrap_jso(this)));
  
  @DomName('Navigator.vendor')
  @DocsEditable()
  @Unstable()
  String get vendor => _blink.BlinkNavigator.instance.vendor_Getter_(unwrap_jso(this));
  
  @DomName('Navigator.vendorSub')
  @DocsEditable()
  @Unstable()
  String get vendorSub => _blink.BlinkNavigator.instance.vendorSub_Getter_(unwrap_jso(this));
  
  @DomName('Navigator.webkitPersistentStorage')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  // http://www.w3.org/TR/quota-api/#accessing-storagequota
  DeprecatedStorageQuota get persistentStorage => wrap_jso(_blink.BlinkNavigator.instance.webkitPersistentStorage_Getter_(unwrap_jso(this)));
  
  @DomName('Navigator.webkitTemporaryStorage')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  // http://www.w3.org/TR/quota-api/#accessing-storagequota
  DeprecatedStorageQuota get temporaryStorage => wrap_jso(_blink.BlinkNavigator.instance.webkitTemporaryStorage_Getter_(unwrap_jso(this)));
  
  @DomName('Navigator.getBattery')
  @DocsEditable()
  @Experimental() // untriaged
  Future getBattery() => wrap_jso(_blink.BlinkNavigator.instance.getBattery_Callback_0_(unwrap_jso(this)));
  
  @DomName('Navigator.getGamepads')
  @DocsEditable()
  @Experimental() // untriaged
  List<Gamepad> getGamepads() => wrap_jso(_blink.BlinkNavigator.instance.getGamepads_Callback_0_(unwrap_jso(this)));
  
  @DomName('Navigator.getVRDevices')
  @DocsEditable()
  @Experimental() // untriaged
  Future getVRDevices() => wrap_jso(_blink.BlinkNavigator.instance.getVRDevices_Callback_0_(unwrap_jso(this)));
  
  @DomName('Navigator.registerProtocolHandler')
  @DocsEditable()
  @Unstable()
  void registerProtocolHandler(String scheme, String url, String title) => _blink.BlinkNavigator.instance.registerProtocolHandler_Callback_3_(unwrap_jso(this), scheme, url, title);
  
  Future requestMidiAccess([Map options]) {
    if (options != null) {
      return wrap_jso(_blink.BlinkNavigator.instance.requestMIDIAccess_Callback_1_(unwrap_jso(this), convertDartToNative_Dictionary(options)));
    }
    return wrap_jso(_blink.BlinkNavigator.instance.requestMIDIAccess_Callback_0_(unwrap_jso(this)));
  }

  @DomName('Navigator.requestMediaKeySystemAccess')
  @DocsEditable()
  @Experimental() // untriaged
  Future requestMediaKeySystemAccess(String keySystem, List<Map> supportedConfigurations) => wrap_jso(_blink.BlinkNavigator.instance.requestMediaKeySystemAccess_Callback_2_(unwrap_jso(this), keySystem, supportedConfigurations));
  
  @DomName('Navigator.sendBeacon')
  @DocsEditable()
  @Experimental() // untriaged
  bool sendBeacon(String url, Object data) => _blink.BlinkNavigator.instance.sendBeacon_Callback_2_(unwrap_jso(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_(unwrap_jso(this), convertDartToNative_Dictionary(options), unwrap_jso((stream) => successCallback(wrap_jso(stream))), unwrap_jso((error) => errorCallback(wrap_jso(error))));
  
  @DomName('Navigator.hardwareConcurrency')
  @DocsEditable()
  @Experimental() // untriaged
  int get hardwareConcurrency => _blink.BlinkNavigator.instance.hardwareConcurrency_Getter_(unwrap_jso(this));
  
  @DomName('Navigator.appCodeName')
  @DocsEditable()
  @Experimental() // non-standard
  String get appCodeName => _blink.BlinkNavigator.instance.appCodeName_Getter_(unwrap_jso(this));
  
  @DomName('Navigator.appName')
  @DocsEditable()
  String get appName => _blink.BlinkNavigator.instance.appName_Getter_(unwrap_jso(this));
  
  @DomName('Navigator.appVersion')
  @DocsEditable()
  String get appVersion => _blink.BlinkNavigator.instance.appVersion_Getter_(unwrap_jso(this));
  
  @DomName('Navigator.dartEnabled')
  @DocsEditable()
  @Experimental() // untriaged
  bool get dartEnabled => _blink.BlinkNavigator.instance.dartEnabled_Getter_(unwrap_jso(this));
  
  @DomName('Navigator.platform')
  @DocsEditable()
  String get platform => _blink.BlinkNavigator.instance.platform_Getter_(unwrap_jso(this));
  
  @DomName('Navigator.product')
  @DocsEditable()
  @Unstable()
  String get product => _blink.BlinkNavigator.instance.product_Getter_(unwrap_jso(this));
  
  @DomName('Navigator.userAgent')
  @DocsEditable()
  String get userAgent => _blink.BlinkNavigator.instance.userAgent_Getter_(unwrap_jso(this));
  
  @DomName('Navigator.language')
  @DocsEditable()
  String get language => _blink.BlinkNavigator.instance.language_Getter_(unwrap_jso(this));
  
  @DomName('Navigator.languages')
  @DocsEditable()
  @Experimental() // untriaged
  List<String> get languages => _blink.BlinkNavigator.instance.languages_Getter_(unwrap_jso(this));
  
  @DomName('Navigator.onLine')
  @DocsEditable()
  @Unstable()
  bool get onLine => _blink.BlinkNavigator.instance.onLine_Getter_(unwrap_jso(this));
  
  @DomName('Navigator.cookieEnabled')
  @DocsEditable()
  @Unstable()
  bool get cookieEnabled => _blink.BlinkNavigator.instance.cookieEnabled_Getter_(unwrap_jso(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_(unwrap_jso(this));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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")
  static NavigatorStorageUtils internalCreateNavigatorStorageUtils() {
    return new NavigatorStorageUtils._internalWrap();
  }

  factory NavigatorStorageUtils._internalWrap() {
    return new NavigatorStorageUtils.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  @DomName('NavigatorStorageUtils.cookieEnabled')
  @DocsEditable()
  @Experimental() // untriaged
  bool get cookieEnabled => _blink.BlinkNavigatorStorageUtils.instance.cookieEnabled_Getter_(unwrap_jso(this));
  
  @DomName('NavigatorStorageUtils.getStorageUpdates')
  @DocsEditable()
  @Experimental() // untriaged
  void getStorageUpdates() => _blink.BlinkNavigatorStorageUtils.instance.getStorageUpdates_Callback_0_(unwrap_jso(this));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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")
  static NavigatorUserMediaError internalCreateNavigatorUserMediaError() {
    return new NavigatorUserMediaError._internalWrap();
  }

  factory NavigatorUserMediaError._internalWrap() {
    return new NavigatorUserMediaError.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  @DomName('NavigatorUserMediaError.constraintName')
  @DocsEditable()
  String get constraintName => _blink.BlinkNavigatorUserMediaError.instance.constraintName_Getter_(unwrap_jso(this));
  
  @DomName('NavigatorUserMediaError.message')
  @DocsEditable()
  String get message => _blink.BlinkNavigatorUserMediaError.instance.message_Getter_(unwrap_jso(this));
  
  @DomName('NavigatorUserMediaError.name')
  @DocsEditable()
  String get name => _blink.BlinkNavigatorUserMediaError.instance.name_Getter_(unwrap_jso(this));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of 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")
  static NetworkInformation internalCreateNetworkInformation() {
    return new NetworkInformation._internalWrap();
  }

  external factory NetworkInformation._internalWrap();

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


  @DomName('NetworkInformation.type')
  @DocsEditable()
  @Experimental() // untriaged
  String get type => _blink.BlinkNetworkInformation.instance.type_Getter_(unwrap_jso(this));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for 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() {
    // By this point blink_jsObject should be setup if it's not then we weren't
    // called by the registerElement createdCallback - probably created() was
    // called directly which is verboten.
    if (this.blink_jsObject == null) {
      throw new DomException.jsInterop("the created constructor cannot be called directly");
    }
  }

  /**
   * A modifiable list of this node's children.
   */
  List<Node> get nodes {
    return new _ChildNodeListLazy(this);
  }

  set nodes(Iterable<Node> value) {
    // Copy list first since we don't want liveness during iteration.
    // TODO(jacobr): there is a better way to do this.
    List copy = new List.from(value);
    text = '';
    for (Node node in copy) {
      append(node);
    }
  }

  /**
   * Removes this node from the DOM.
   */
  @DomName('Node.removeChild')
  void remove() {
    // TODO(jacobr): should we throw an exception if parent is already null?
    // TODO(vsm): Use the native remove when available.
    if (this.parentNode != null) {
      final Node parent = this.parentNode;
      parentNode._removeChild(this);
    }
  }

  /**
   * Replaces this node with another node.
   */
  @DomName('Node.replaceChild')
  Node replaceWith(Node otherNode) {
    try {
      final Node parent = this.parentNode;
      parent._replaceChild(otherNode, this);
    } catch (e) {

    };
    return this;
  }

  /**
   * Inserts all of the nodes into this node directly before refChild.
   *
   * See also:
   *
   * * [insertBefore]
   */
  Node insertAllBefore(Iterable<Node> newNodes, Node refChild) {
    if (newNodes is _ChildNodeListLazy) {
      _ChildNodeListLazy otherList = newNodes;
      if (identical(otherList._this, this)) {
        throw new ArgumentError(newNodes);
      }

      // Optimized route for copying between nodes.
      for (var i = 0, len = otherList.length; i < len; ++i) {
        this.insertBefore(otherList._this.firstChild, refChild);
      }
    } else {
      for (var node in newNodes) {
        this.insertBefore(node, refChild);
      }
    }
  }

  void _clearChildren() {
    while (firstChild != null) {
      _removeChild(firstChild);
    }
  }

  /**
   * Print out a String representation of this Node.
   */
  String toString() {
    String value = nodeValue;  // Fetch DOM Node property once.
    return value == null ? super.toString() : value;
  }

  /**
   * A list of this node's children.
   *
   * ## Other resources
   *
   * * [Node.childNodes](https://developer.mozilla.org/en-US/docs/Web/API/Node.childNodes)
   *   from MDN.
   */
  @DomName('Node.childNodes')
  @DocsEditable()
  List<Node> get childNodes => wrap_jso(_blink.BlinkNode.instance.childNodes_Getter_(unwrap_jso(this)));
  // To suppress missing implicit constructor warnings.
  factory Node._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  static Node internalCreateNode() {
    return new Node._internalWrap();
  }

  external factory Node._internalWrap();

  @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_(unwrap_jso(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 => wrap_jso(_blink.BlinkNode.instance.firstChild_Getter_(unwrap_jso(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 => wrap_jso(_blink.BlinkNode.instance.lastChild_Getter_(unwrap_jso(this)));
  
  @DomName('Node.localName')
  @DocsEditable()
  String get _localName => _blink.BlinkNode.instance.localName_Getter_(unwrap_jso(this));
  
  @DomName('Node.namespaceURI')
  @DocsEditable()
  String get _namespaceUri => _blink.BlinkNode.instance.namespaceURI_Getter_(unwrap_jso(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 => wrap_jso(_blink.BlinkNode.instance.nextSibling_Getter_(unwrap_jso(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_(unwrap_jso(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_(unwrap_jso(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_(unwrap_jso(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 => wrap_jso(_blink.BlinkNode.instance.ownerDocument_Getter_(unwrap_jso(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 => wrap_jso(_blink.BlinkNode.instance.parentElement_Getter_(unwrap_jso(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 => wrap_jso(_blink.BlinkNode.instance.parentNode_Getter_(unwrap_jso(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 => wrap_jso(_blink.BlinkNode.instance.previousSibling_Getter_(unwrap_jso(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_(unwrap_jso(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_(unwrap_jso(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) => wrap_jso(_blink.BlinkNode.instance.appendChild_Callback_1_(unwrap_jso(this), unwrap_jso(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) => wrap_jso(_blink.BlinkNode.instance.cloneNode_Callback_1_(unwrap_jso(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_(unwrap_jso(this), unwrap_jso(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_(unwrap_jso(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) => wrap_jso(_blink.BlinkNode.instance.insertBefore_Callback_2_(unwrap_jso(this), unwrap_jso(node), unwrap_jso(child)));
  
  @DomName('Node.removeChild')
  @DocsEditable()
  Node _removeChild(Node child) => wrap_jso(_blink.BlinkNode.instance.removeChild_Callback_1_(unwrap_jso(this), unwrap_jso(child)));
  
  @DomName('Node.replaceChild')
  @DocsEditable()
  Node _replaceChild(Node node, Node child) => wrap_jso(_blink.BlinkNode.instance.replaceChild_Callback_2_(unwrap_jso(this), unwrap_jso(node), unwrap_jso(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")
  static NodeFilter internalCreateNodeFilter() {
    return new NodeFilter._internalWrap();
  }

  factory NodeFilter._internalWrap() {
    return new NodeFilter.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  @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")
  static NodeIterator internalCreateNodeIterator() {
    return new NodeIterator._internalWrap();
  }

  factory NodeIterator._internalWrap() {
    return new NodeIterator.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  @DomName('NodeIterator.pointerBeforeReferenceNode')
  @DocsEditable()
  bool get pointerBeforeReferenceNode => _blink.BlinkNodeIterator.instance.pointerBeforeReferenceNode_Getter_(unwrap_jso(this));
  
  @DomName('NodeIterator.referenceNode')
  @DocsEditable()
  Node get referenceNode => wrap_jso(_blink.BlinkNodeIterator.instance.referenceNode_Getter_(unwrap_jso(this)));
  
  @DomName('NodeIterator.root')
  @DocsEditable()
  Node get root => wrap_jso(_blink.BlinkNodeIterator.instance.root_Getter_(unwrap_jso(this)));
  
  @DomName('NodeIterator.whatToShow')
  @DocsEditable()
  int get whatToShow => _blink.BlinkNodeIterator.instance.whatToShow_Getter_(unwrap_jso(this));
  
  @DomName('NodeIterator.detach')
  @DocsEditable()
  void detach() => _blink.BlinkNodeIterator.instance.detach_Callback_0_(unwrap_jso(this));
  
  @DomName('NodeIterator.nextNode')
  @DocsEditable()
  Node nextNode() => wrap_jso(_blink.BlinkNodeIterator.instance.nextNode_Callback_0_(unwrap_jso(this)));
  
  @DomName('NodeIterator.previousNode')
  @DocsEditable()
  Node previousNode() => wrap_jso(_blink.BlinkNodeIterator.instance.previousNode_Callback_0_(unwrap_jso(this)));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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")
  static NodeList internalCreateNodeList() {
    return new NodeList._internalWrap();
  }

  factory NodeList._internalWrap() {
    return new NodeList.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  @DomName('NodeList.length')
  @DocsEditable()
  int get length => _blink.BlinkNodeList.instance.length_Getter_(unwrap_jso(this));
  
  Node operator[](int index) {
    if (index < 0 || index >= length)
      throw new RangeError.index(index, this);
    return wrap_jso(_blink.BlinkNodeList.instance.item_Callback_1_(unwrap_jso(this), index));
  }

  Node _nativeIndexedGetter(int index) => wrap_jso(_blink.BlinkNodeList.instance.item_Callback_1_(unwrap_jso(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) => wrap_jso(_blink.BlinkNodeList.instance.item_Callback_1_(unwrap_jso(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")
  static NonDocumentTypeChildNode internalCreateNonDocumentTypeChildNode() {
    return new NonDocumentTypeChildNode._internalWrap();
  }

  factory NonDocumentTypeChildNode._internalWrap() {
    return new NonDocumentTypeChildNode.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  @DomName('NonDocumentTypeChildNode.nextElementSibling')
  @DocsEditable()
  @Experimental() // untriaged
  Element get nextElementSibling => wrap_jso(_blink.BlinkNonDocumentTypeChildNode.instance.nextElementSibling_Getter_(unwrap_jso(this)));
  
  @DomName('NonDocumentTypeChildNode.previousElementSibling')
  @DocsEditable()
  @Experimental() // untriaged
  Element get previousElementSibling => wrap_jso(_blink.BlinkNonDocumentTypeChildNode.instance.previousElementSibling_Getter_(unwrap_jso(this)));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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")
  static NonElementParentNode internalCreateNonElementParentNode() {
    return new NonElementParentNode._internalWrap();
  }

  factory NonElementParentNode._internalWrap() {
    return new NonElementParentNode.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  @DomName('NonElementParentNode.getElementById')
  @DocsEditable()
  @Experimental() // untriaged
  Element getElementById(String elementId) => wrap_jso(_blink.BlinkNonElementParentNode.instance.getElementById_Callback_1_(unwrap_jso(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 wrap_jso(_blink.BlinkNotification.instance.constructorCallback_2_(title, options_1));
    }
    return wrap_jso(_blink.BlinkNotification.instance.constructorCallback_1_(title));
  }


  @Deprecated("Internal Use Only")
  static Notification internalCreateNotification() {
    return new Notification._internalWrap();
  }

  external factory Notification._internalWrap();

  @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_(unwrap_jso(this));
  
  @DomName('Notification.data')
  @DocsEditable()
  @Experimental() // untriaged
  Object get data => wrap_jso(_blink.BlinkNotification.instance.data_Getter_(unwrap_jso(this)));
  
  @DomName('Notification.dir')
  @DocsEditable()
  @Experimental() // nonstandard
  String get dir => _blink.BlinkNotification.instance.dir_Getter_(unwrap_jso(this));
  
  @DomName('Notification.icon')
  @DocsEditable()
  @Experimental() // untriaged
  String get icon => _blink.BlinkNotification.instance.icon_Getter_(unwrap_jso(this));
  
  @DomName('Notification.lang')
  @DocsEditable()
  @Experimental() // untriaged
  String get lang => _blink.BlinkNotification.instance.lang_Getter_(unwrap_jso(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_(unwrap_jso(this));
  
  @DomName('Notification.tag')
  @DocsEditable()
  @Experimental() // nonstandard
  String get tag => _blink.BlinkNotification.instance.tag_Getter_(unwrap_jso(this));
  
  @DomName('Notification.title')
  @DocsEditable()
  @Experimental() // untriaged
  String get title => _blink.BlinkNotification.instance.title_Getter_(unwrap_jso(this));
  
  @DomName('Notification.vibrate')
  @DocsEditable()
  @Experimental() // untriaged
  List<int> get vibrate => _blink.BlinkNotification.instance.vibrate_Getter_(unwrap_jso(this));
  
  @DomName('Notification.close')
  @DocsEditable()
  void close() => _blink.BlinkNotification.instance.close_Callback_0_(unwrap_jso(this));
  
  static void _requestPermission([_NotificationPermissionCallback callback]) {
    if (callback != null) {
      _blink.BlinkNotification.instance.requestPermission_Callback_1_(unwrap_jso((permission) => callback(permission)));
      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 wrap_jso(_blink.BlinkNotificationEvent.instance.constructorCallback_2_(type, eventInitDict_1));
    }
    return wrap_jso(_blink.BlinkNotificationEvent.instance.constructorCallback_1_(type));
  }


  @Deprecated("Internal Use Only")
  static NotificationEvent internalCreateNotificationEvent() {
    return new NotificationEvent._internalWrap();
  }

  external factory NotificationEvent._internalWrap();

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


  @DomName('NotificationEvent.notification')
  @DocsEditable()
  @Experimental() // untriaged
  Notification get notification => wrap_jso(_blink.BlinkNotificationEvent.instance.notification_Getter_(unwrap_jso(this)));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of 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")
  static OListElement internalCreateOListElement() {
    return new OListElement._internalWrap();
  }

  external factory OListElement._internalWrap();

  @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_(unwrap_jso(this));
  
  @DomName('HTMLOListElement.reversed')
  @DocsEditable()
  set reversed(bool value) => _blink.BlinkHTMLOListElement.instance.reversed_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLOListElement.start')
  @DocsEditable()
  int get start => _blink.BlinkHTMLOListElement.instance.start_Getter_(unwrap_jso(this));
  
  @DomName('HTMLOListElement.start')
  @DocsEditable()
  set start(int value) => _blink.BlinkHTMLOListElement.instance.start_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLOListElement.type')
  @DocsEditable()
  String get type => _blink.BlinkHTMLOListElement.instance.type_Getter_(unwrap_jso(this));
  
  @DomName('HTMLOListElement.type')
  @DocsEditable()
  set type(String value) => _blink.BlinkHTMLOListElement.instance.type_Setter_(unwrap_jso(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")
  static ObjectElement internalCreateObjectElement() {
    return new ObjectElement._internalWrap();
  }

  external factory ObjectElement._internalWrap();

  @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_(unwrap_jso(this));
  
  @DomName('HTMLObjectElement.data')
  @DocsEditable()
  set data(String value) => _blink.BlinkHTMLObjectElement.instance.data_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLObjectElement.form')
  @DocsEditable()
  FormElement get form => wrap_jso(_blink.BlinkHTMLObjectElement.instance.form_Getter_(unwrap_jso(this)));
  
  @DomName('HTMLObjectElement.height')
  @DocsEditable()
  String get height => _blink.BlinkHTMLObjectElement.instance.height_Getter_(unwrap_jso(this));
  
  @DomName('HTMLObjectElement.height')
  @DocsEditable()
  set height(String value) => _blink.BlinkHTMLObjectElement.instance.height_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLObjectElement.name')
  @DocsEditable()
  String get name => _blink.BlinkHTMLObjectElement.instance.name_Getter_(unwrap_jso(this));
  
  @DomName('HTMLObjectElement.name')
  @DocsEditable()
  set name(String value) => _blink.BlinkHTMLObjectElement.instance.name_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLObjectElement.type')
  @DocsEditable()
  String get type => _blink.BlinkHTMLObjectElement.instance.type_Getter_(unwrap_jso(this));
  
  @DomName('HTMLObjectElement.type')
  @DocsEditable()
  set type(String value) => _blink.BlinkHTMLObjectElement.instance.type_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLObjectElement.useMap')
  @DocsEditable()
  String get useMap => _blink.BlinkHTMLObjectElement.instance.useMap_Getter_(unwrap_jso(this));
  
  @DomName('HTMLObjectElement.useMap')
  @DocsEditable()
  set useMap(String value) => _blink.BlinkHTMLObjectElement.instance.useMap_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLObjectElement.validationMessage')
  @DocsEditable()
  String get validationMessage => _blink.BlinkHTMLObjectElement.instance.validationMessage_Getter_(unwrap_jso(this));
  
  @DomName('HTMLObjectElement.validity')
  @DocsEditable()
  ValidityState get validity => wrap_jso(_blink.BlinkHTMLObjectElement.instance.validity_Getter_(unwrap_jso(this)));
  
  @DomName('HTMLObjectElement.width')
  @DocsEditable()
  String get width => _blink.BlinkHTMLObjectElement.instance.width_Getter_(unwrap_jso(this));
  
  @DomName('HTMLObjectElement.width')
  @DocsEditable()
  set width(String value) => _blink.BlinkHTMLObjectElement.instance.width_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLObjectElement.willValidate')
  @DocsEditable()
  bool get willValidate => _blink.BlinkHTMLObjectElement.instance.willValidate_Getter_(unwrap_jso(this));
  
  @DomName('HTMLObjectElement.__getter__')
  @DocsEditable()
  bool __getter__(index_OR_name) => _blink.BlinkHTMLObjectElement.instance.$__getter___Callback_1_(unwrap_jso(this), unwrap_jso(index_OR_name));
  
  @DomName('HTMLObjectElement.__setter__')
  @DocsEditable()
  void __setter__(index_OR_name, Node value) => _blink.BlinkHTMLObjectElement.instance.$__setter___Callback_2_(unwrap_jso(this), unwrap_jso(index_OR_name), unwrap_jso(value));
  
  @DomName('HTMLObjectElement.checkValidity')
  @DocsEditable()
  bool checkValidity() => _blink.BlinkHTMLObjectElement.instance.checkValidity_Callback_0_(unwrap_jso(this));
  
  @DomName('HTMLObjectElement.reportValidity')
  @DocsEditable()
  @Experimental() // untriaged
  bool reportValidity() => _blink.BlinkHTMLObjectElement.instance.reportValidity_Callback_0_(unwrap_jso(this));
  
  @DomName('HTMLObjectElement.setCustomValidity')
  @DocsEditable()
  void setCustomValidity(String error) => _blink.BlinkHTMLObjectElement.instance.setCustomValidity_Callback_1_(unwrap_jso(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")
  static OptGroupElement internalCreateOptGroupElement() {
    return new OptGroupElement._internalWrap();
  }

  external factory OptGroupElement._internalWrap();

  @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_(unwrap_jso(this));
  
  @DomName('HTMLOptGroupElement.disabled')
  @DocsEditable()
  set disabled(bool value) => _blink.BlinkHTMLOptGroupElement.instance.disabled_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLOptGroupElement.label')
  @DocsEditable()
  String get label => _blink.BlinkHTMLOptGroupElement.instance.label_Getter_(unwrap_jso(this));
  
  @DomName('HTMLOptGroupElement.label')
  @DocsEditable()
  set label(String value) => _blink.BlinkHTMLOptGroupElement.instance.label_Setter_(unwrap_jso(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 wrap_jso(_blink.BlinkHTMLOptionElement.instance.constructorCallback_4_(data, value, defaultSelected, selected));
    }
    if (defaultSelected != null) {
      return wrap_jso(_blink.BlinkHTMLOptionElement.instance.constructorCallback_3_(data, value, defaultSelected));
    }
    return wrap_jso(_blink.BlinkHTMLOptionElement.instance.constructorCallback_2_(data, value));
  }


  @Deprecated("Internal Use Only")
  static OptionElement internalCreateOptionElement() {
    return new OptionElement._internalWrap();
  }

  external factory OptionElement._internalWrap();

  @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_(unwrap_jso(this));
  
  @DomName('HTMLOptionElement.defaultSelected')
  @DocsEditable()
  set defaultSelected(bool value) => _blink.BlinkHTMLOptionElement.instance.defaultSelected_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLOptionElement.disabled')
  @DocsEditable()
  bool get disabled => _blink.BlinkHTMLOptionElement.instance.disabled_Getter_(unwrap_jso(this));
  
  @DomName('HTMLOptionElement.disabled')
  @DocsEditable()
  set disabled(bool value) => _blink.BlinkHTMLOptionElement.instance.disabled_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLOptionElement.form')
  @DocsEditable()
  FormElement get form => wrap_jso(_blink.BlinkHTMLOptionElement.instance.form_Getter_(unwrap_jso(this)));
  
  @DomName('HTMLOptionElement.index')
  @DocsEditable()
  int get index => _blink.BlinkHTMLOptionElement.instance.index_Getter_(unwrap_jso(this));
  
  @DomName('HTMLOptionElement.label')
  @DocsEditable()
  String get label => _blink.BlinkHTMLOptionElement.instance.label_Getter_(unwrap_jso(this));
  
  @DomName('HTMLOptionElement.label')
  @DocsEditable()
  set label(String value) => _blink.BlinkHTMLOptionElement.instance.label_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLOptionElement.selected')
  @DocsEditable()
  bool get selected => _blink.BlinkHTMLOptionElement.instance.selected_Getter_(unwrap_jso(this));
  
  @DomName('HTMLOptionElement.selected')
  @DocsEditable()
  set selected(bool value) => _blink.BlinkHTMLOptionElement.instance.selected_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLOptionElement.value')
  @DocsEditable()
  String get value => _blink.BlinkHTMLOptionElement.instance.value_Getter_(unwrap_jso(this));
  
  @DomName('HTMLOptionElement.value')
  @DocsEditable()
  set value(String value) => _blink.BlinkHTMLOptionElement.instance.value_Setter_(unwrap_jso(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")
  static OutputElement internalCreateOutputElement() {
    return new OutputElement._internalWrap();
  }

  external factory OutputElement._internalWrap();

  @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_(unwrap_jso(this));
  
  @DomName('HTMLOutputElement.defaultValue')
  @DocsEditable()
  set defaultValue(String value) => _blink.BlinkHTMLOutputElement.instance.defaultValue_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLOutputElement.form')
  @DocsEditable()
  FormElement get form => wrap_jso(_blink.BlinkHTMLOutputElement.instance.form_Getter_(unwrap_jso(this)));
  
  @DomName('HTMLOutputElement.htmlFor')
  @DocsEditable()
  DomSettableTokenList get htmlFor => wrap_jso(_blink.BlinkHTMLOutputElement.instance.htmlFor_Getter_(unwrap_jso(this)));
  
  @DomName('HTMLOutputElement.labels')
  @DocsEditable()
  @Unstable()
  List<Node> get labels => wrap_jso(_blink.BlinkHTMLOutputElement.instance.labels_Getter_(unwrap_jso(this)));
  
  @DomName('HTMLOutputElement.name')
  @DocsEditable()
  String get name => _blink.BlinkHTMLOutputElement.instance.name_Getter_(unwrap_jso(this));
  
  @DomName('HTMLOutputElement.name')
  @DocsEditable()
  set name(String value) => _blink.BlinkHTMLOutputElement.instance.name_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLOutputElement.type')
  @DocsEditable()
  String get type => _blink.BlinkHTMLOutputElement.instance.type_Getter_(unwrap_jso(this));
  
  @DomName('HTMLOutputElement.validationMessage')
  @DocsEditable()
  String get validationMessage => _blink.BlinkHTMLOutputElement.instance.validationMessage_Getter_(unwrap_jso(this));
  
  @DomName('HTMLOutputElement.validity')
  @DocsEditable()
  ValidityState get validity => wrap_jso(_blink.BlinkHTMLOutputElement.instance.validity_Getter_(unwrap_jso(this)));
  
  @DomName('HTMLOutputElement.value')
  @DocsEditable()
  String get value => _blink.BlinkHTMLOutputElement.instance.value_Getter_(unwrap_jso(this));
  
  @DomName('HTMLOutputElement.value')
  @DocsEditable()
  set value(String value) => _blink.BlinkHTMLOutputElement.instance.value_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLOutputElement.willValidate')
  @DocsEditable()
  bool get willValidate => _blink.BlinkHTMLOutputElement.instance.willValidate_Getter_(unwrap_jso(this));
  
  @DomName('HTMLOutputElement.checkValidity')
  @DocsEditable()
  bool checkValidity() => _blink.BlinkHTMLOutputElement.instance.checkValidity_Callback_0_(unwrap_jso(this));
  
  @DomName('HTMLOutputElement.reportValidity')
  @DocsEditable()
  @Experimental() // untriaged
  bool reportValidity() => _blink.BlinkHTMLOutputElement.instance.reportValidity_Callback_0_(unwrap_jso(this));
  
  @DomName('HTMLOutputElement.setCustomValidity')
  @DocsEditable()
  void setCustomValidity(String error) => _blink.BlinkHTMLOutputElement.instance.setCustomValidity_Callback_1_(unwrap_jso(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 wrap_jso(_blink.BlinkPageTransitionEvent.instance.constructorCallback_2_(type, eventInitDict_1));
    }
    return wrap_jso(_blink.BlinkPageTransitionEvent.instance.constructorCallback_1_(type));
  }


  @Deprecated("Internal Use Only")
  static PageTransitionEvent internalCreatePageTransitionEvent() {
    return new PageTransitionEvent._internalWrap();
  }

  external factory PageTransitionEvent._internalWrap();

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


  @DomName('PageTransitionEvent.persisted')
  @DocsEditable()
  bool get persisted => _blink.BlinkPageTransitionEvent.instance.persisted_Getter_(unwrap_jso(this));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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")
  static ParagraphElement internalCreateParagraphElement() {
    return new ParagraphElement._internalWrap();
  }

  external factory ParagraphElement._internalWrap();

  @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")
  static ParamElement internalCreateParamElement() {
    return new ParamElement._internalWrap();
  }

  external factory ParamElement._internalWrap();

  @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_(unwrap_jso(this));
  
  @DomName('HTMLParamElement.name')
  @DocsEditable()
  set name(String value) => _blink.BlinkHTMLParamElement.instance.name_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLParamElement.value')
  @DocsEditable()
  String get value => _blink.BlinkHTMLParamElement.instance.value_Getter_(unwrap_jso(this));
  
  @DomName('HTMLParamElement.value')
  @DocsEditable()
  set value(String value) => _blink.BlinkHTMLParamElement.instance.value_Setter_(unwrap_jso(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 wrap_jso(_blink.BlinkPasswordCredential.instance.constructorCallback_4_(id, password, name, iconURL));
    }
    if (name != null) {
      return wrap_jso(_blink.BlinkPasswordCredential.instance.constructorCallback_3_(id, password, name));
    }
    return wrap_jso(_blink.BlinkPasswordCredential.instance.constructorCallback_2_(id, password));
  }


  @Deprecated("Internal Use Only")
  static PasswordCredential internalCreatePasswordCredential() {
    return new PasswordCredential._internalWrap();
  }

  external factory PasswordCredential._internalWrap();

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


  @DomName('PasswordCredential.formData')
  @DocsEditable()
  @Experimental() // untriaged
  FormData get formData => wrap_jso(_blink.BlinkPasswordCredential.instance.formData_Getter_(unwrap_jso(this)));
  
  @DomName('PasswordCredential.password')
  @DocsEditable()
  @Experimental() // untriaged
  String get password => _blink.BlinkPasswordCredential.instance.password_Getter_(unwrap_jso(this));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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 wrap_jso(_blink.BlinkPath2D.instance.constructorCallback_0_());
    }
    if ((path_OR_text is Path2D || path_OR_text == null)) {
      return wrap_jso(_blink.BlinkPath2D.instance.constructorCallback_1_(path_OR_text));
    }
    if ((path_OR_text is String || path_OR_text == null)) {
      return wrap_jso(_blink.BlinkPath2D.instance.constructorCallback_1_(path_OR_text));
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }

  @Deprecated("Internal Use Only")
  static Path2D internalCreatePath2D() {
    return new Path2D._internalWrap();
  }

  factory Path2D._internalWrap() {
    return new Path2D.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  void addPath(Path2D path, [Matrix transform]) {
    if (transform != null) {
      _blink.BlinkPath2D.instance.addPath_Callback_2_(unwrap_jso(this), unwrap_jso(path), unwrap_jso(transform));
      return;
    }
    _blink.BlinkPath2D.instance.addPath_Callback_1_(unwrap_jso(this), unwrap_jso(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_(unwrap_jso(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_(unwrap_jso(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_(unwrap_jso(this), cp1x, cp1y, cp2x, cp2y, x, y);
  
  @DomName('Path2D.closePath')
  @DocsEditable()
  @Experimental() // untriaged
  void closePath() => _blink.BlinkPath2D.instance.closePath_Callback_0_(unwrap_jso(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_(unwrap_jso(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_(unwrap_jso(this), x, y);
  
  @DomName('Path2D.moveTo')
  @DocsEditable()
  @Experimental() // untriaged
  void moveTo(num x, num y) => _blink.BlinkPath2D.instance.moveTo_Callback_2_(unwrap_jso(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_(unwrap_jso(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_(unwrap_jso(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")
  static Performance internalCreatePerformance() {
    return new Performance._internalWrap();
  }

  external factory Performance._internalWrap();

  @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 => wrap_jso(_blink.BlinkPerformance.instance.memory_Getter_(unwrap_jso(this)));
  
  @DomName('Performance.navigation')
  @DocsEditable()
  PerformanceNavigation get navigation => wrap_jso(_blink.BlinkPerformance.instance.navigation_Getter_(unwrap_jso(this)));
  
  @DomName('Performance.timing')
  @DocsEditable()
  PerformanceTiming get timing => wrap_jso(_blink.BlinkPerformance.instance.timing_Getter_(unwrap_jso(this)));
  
  @DomName('Performance.clearFrameTimings')
  @DocsEditable()
  @Experimental() // untriaged
  void clearFrameTimings() => _blink.BlinkPerformance.instance.clearFrameTimings_Callback_0_(unwrap_jso(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_(unwrap_jso(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_(unwrap_jso(this), measureName);
  
  @DomName('Performance.getEntries')
  @DocsEditable()
  // http://www.w3.org/TR/performance-timeline/#sec-window.performance-attribute
  @Experimental()
  List<PerformanceEntry> getEntries() => wrap_jso(_blink.BlinkPerformance.instance.getEntries_Callback_0_(unwrap_jso(this)));
  
  @DomName('Performance.getEntriesByName')
  @DocsEditable()
  // http://www.w3.org/TR/performance-timeline/#sec-window.performance-attribute
  @Experimental()
  List<PerformanceEntry> getEntriesByName(String name, String entryType) => wrap_jso(_blink.BlinkPerformance.instance.getEntriesByName_Callback_2_(unwrap_jso(this), name, entryType));
  
  @DomName('Performance.getEntriesByType')
  @DocsEditable()
  // http://www.w3.org/TR/performance-timeline/#sec-window.performance-attribute
  @Experimental()
  List<PerformanceEntry> getEntriesByType(String entryType) => wrap_jso(_blink.BlinkPerformance.instance.getEntriesByType_Callback_1_(unwrap_jso(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_(unwrap_jso(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_(unwrap_jso(this), measureName, startMark, endMark);
  
  @DomName('Performance.now')
  @DocsEditable()
  num now() => _blink.BlinkPerformance.instance.now_Callback_0_(unwrap_jso(this));
  
  @DomName('Performance.setFrameTimingBufferSize')
  @DocsEditable()
  @Experimental() // untriaged
  void setFrameTimingBufferSize(int maxSize) => _blink.BlinkPerformance.instance.setFrameTimingBufferSize_Callback_1_(unwrap_jso(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_(unwrap_jso(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_(unwrap_jso(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")
  static PerformanceCompositeTiming internalCreatePerformanceCompositeTiming() {
    return new PerformanceCompositeTiming._internalWrap();
  }

  external factory PerformanceCompositeTiming._internalWrap();

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


  @DomName('PerformanceCompositeTiming.sourceFrame')
  @DocsEditable()
  @Experimental() // untriaged
  int get sourceFrame => _blink.BlinkPerformanceCompositeTiming.instance.sourceFrame_Getter_(unwrap_jso(this));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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")
  static PerformanceEntry internalCreatePerformanceEntry() {
    return new PerformanceEntry._internalWrap();
  }

  factory PerformanceEntry._internalWrap() {
    return new PerformanceEntry.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  @DomName('PerformanceEntry.duration')
  @DocsEditable()
  num get duration => _blink.BlinkPerformanceEntry.instance.duration_Getter_(unwrap_jso(this));
  
  @DomName('PerformanceEntry.entryType')
  @DocsEditable()
  String get entryType => _blink.BlinkPerformanceEntry.instance.entryType_Getter_(unwrap_jso(this));
  
  @DomName('PerformanceEntry.name')
  @DocsEditable()
  String get name => _blink.BlinkPerformanceEntry.instance.name_Getter_(unwrap_jso(this));
  
  @DomName('PerformanceEntry.startTime')
  @DocsEditable()
  num get startTime => _blink.BlinkPerformanceEntry.instance.startTime_Getter_(unwrap_jso(this));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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")
  static PerformanceMark internalCreatePerformanceMark() {
    return new PerformanceMark._internalWrap();
  }

  external factory PerformanceMark._internalWrap();

  @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")
  static PerformanceMeasure internalCreatePerformanceMeasure() {
    return new PerformanceMeasure._internalWrap();
  }

  external factory PerformanceMeasure._internalWrap();

  @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")
  static PerformanceNavigation internalCreatePerformanceNavigation() {
    return new PerformanceNavigation._internalWrap();
  }

  factory PerformanceNavigation._internalWrap() {
    return new PerformanceNavigation.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  @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_(unwrap_jso(this));
  
  @DomName('PerformanceNavigation.type')
  @DocsEditable()
  int get type => _blink.BlinkPerformanceNavigation.instance.type_Getter_(unwrap_jso(this));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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")
  static PerformanceRenderTiming internalCreatePerformanceRenderTiming() {
    return new PerformanceRenderTiming._internalWrap();
  }

  external factory PerformanceRenderTiming._internalWrap();

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


  @DomName('PerformanceRenderTiming.sourceFrame')
  @DocsEditable()
  @Experimental() // untriaged
  int get sourceFrame => _blink.BlinkPerformanceRenderTiming.instance.sourceFrame_Getter_(unwrap_jso(this));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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")
  static PerformanceResourceTiming internalCreatePerformanceResourceTiming() {
    return new PerformanceResourceTiming._internalWrap();
  }

  external factory PerformanceResourceTiming._internalWrap();

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


  @DomName('PerformanceResourceTiming.connectEnd')
  @DocsEditable()
  num get connectEnd => _blink.BlinkPerformanceResourceTiming.instance.connectEnd_Getter_(unwrap_jso(this));
  
  @DomName('PerformanceResourceTiming.connectStart')
  @DocsEditable()
  num get connectStart => _blink.BlinkPerformanceResourceTiming.instance.connectStart_Getter_(unwrap_jso(this));
  
  @DomName('PerformanceResourceTiming.domainLookupEnd')
  @DocsEditable()
  num get domainLookupEnd => _blink.BlinkPerformanceResourceTiming.instance.domainLookupEnd_Getter_(unwrap_jso(this));
  
  @DomName('PerformanceResourceTiming.domainLookupStart')
  @DocsEditable()
  num get domainLookupStart => _blink.BlinkPerformanceResourceTiming.instance.domainLookupStart_Getter_(unwrap_jso(this));
  
  @DomName('PerformanceResourceTiming.fetchStart')
  @DocsEditable()
  num get fetchStart => _blink.BlinkPerformanceResourceTiming.instance.fetchStart_Getter_(unwrap_jso(this));
  
  @DomName('PerformanceResourceTiming.initiatorType')
  @DocsEditable()
  String get initiatorType => _blink.BlinkPerformanceResourceTiming.instance.initiatorType_Getter_(unwrap_jso(this));
  
  @DomName('PerformanceResourceTiming.redirectEnd')
  @DocsEditable()
  num get redirectEnd => _blink.BlinkPerformanceResourceTiming.instance.redirectEnd_Getter_(unwrap_jso(this));
  
  @DomName('PerformanceResourceTiming.redirectStart')
  @DocsEditable()
  num get redirectStart => _blink.BlinkPerformanceResourceTiming.instance.redirectStart_Getter_(unwrap_jso(this));
  
  @DomName('PerformanceResourceTiming.requestStart')
  @DocsEditable()
  @Experimental() // nonstandard
  num get requestStart => _blink.BlinkPerformanceResourceTiming.instance.requestStart_Getter_(unwrap_jso(this));
  
  @DomName('PerformanceResourceTiming.responseEnd')
  @DocsEditable()
  @Experimental() // nonstandard
  num get responseEnd => _blink.BlinkPerformanceResourceTiming.instance.responseEnd_Getter_(unwrap_jso(this));
  
  @DomName('PerformanceResourceTiming.responseStart')
  @DocsEditable()
  @Experimental() // nonstandard
  num get responseStart => _blink.BlinkPerformanceResourceTiming.instance.responseStart_Getter_(unwrap_jso(this));
  
  @DomName('PerformanceResourceTiming.secureConnectionStart')
  @DocsEditable()
  num get secureConnectionStart => _blink.BlinkPerformanceResourceTiming.instance.secureConnectionStart_Getter_(unwrap_jso(this));
  
  @DomName('PerformanceResourceTiming.workerStart')
  @DocsEditable()
  @Experimental() // untriaged
  num get workerStart => _blink.BlinkPerformanceResourceTiming.instance.workerStart_Getter_(unwrap_jso(this));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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")
  static PerformanceTiming internalCreatePerformanceTiming() {
    return new PerformanceTiming._internalWrap();
  }

  factory PerformanceTiming._internalWrap() {
    return new PerformanceTiming.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  @DomName('PerformanceTiming.connectEnd')
  @DocsEditable()
  int get connectEnd => _blink.BlinkPerformanceTiming.instance.connectEnd_Getter_(unwrap_jso(this));
  
  @DomName('PerformanceTiming.connectStart')
  @DocsEditable()
  int get connectStart => _blink.BlinkPerformanceTiming.instance.connectStart_Getter_(unwrap_jso(this));
  
  @DomName('PerformanceTiming.domComplete')
  @DocsEditable()
  int get domComplete => _blink.BlinkPerformanceTiming.instance.domComplete_Getter_(unwrap_jso(this));
  
  @DomName('PerformanceTiming.domContentLoadedEventEnd')
  @DocsEditable()
  int get domContentLoadedEventEnd => _blink.BlinkPerformanceTiming.instance.domContentLoadedEventEnd_Getter_(unwrap_jso(this));
  
  @DomName('PerformanceTiming.domContentLoadedEventStart')
  @DocsEditable()
  int get domContentLoadedEventStart => _blink.BlinkPerformanceTiming.instance.domContentLoadedEventStart_Getter_(unwrap_jso(this));
  
  @DomName('PerformanceTiming.domInteractive')
  @DocsEditable()
  int get domInteractive => _blink.BlinkPerformanceTiming.instance.domInteractive_Getter_(unwrap_jso(this));
  
  @DomName('PerformanceTiming.domLoading')
  @DocsEditable()
  int get domLoading => _blink.BlinkPerformanceTiming.instance.domLoading_Getter_(unwrap_jso(this));
  
  @DomName('PerformanceTiming.domainLookupEnd')
  @DocsEditable()
  int get domainLookupEnd => _blink.BlinkPerformanceTiming.instance.domainLookupEnd_Getter_(unwrap_jso(this));
  
  @DomName('PerformanceTiming.domainLookupStart')
  @DocsEditable()
  int get domainLookupStart => _blink.BlinkPerformanceTiming.instance.domainLookupStart_Getter_(unwrap_jso(this));
  
  @DomName('PerformanceTiming.fetchStart')
  @DocsEditable()
  int get fetchStart => _blink.BlinkPerformanceTiming.instance.fetchStart_Getter_(unwrap_jso(this));
  
  @DomName('PerformanceTiming.loadEventEnd')
  @DocsEditable()
  int get loadEventEnd => _blink.BlinkPerformanceTiming.instance.loadEventEnd_Getter_(unwrap_jso(this));
  
  @DomName('PerformanceTiming.loadEventStart')
  @DocsEditable()
  int get loadEventStart => _blink.BlinkPerformanceTiming.instance.loadEventStart_Getter_(unwrap_jso(this));
  
  @DomName('PerformanceTiming.navigationStart')
  @DocsEditable()
  int get navigationStart => _blink.BlinkPerformanceTiming.instance.navigationStart_Getter_(unwrap_jso(this));
  
  @DomName('PerformanceTiming.redirectEnd')
  @DocsEditable()
  int get redirectEnd => _blink.BlinkPerformanceTiming.instance.redirectEnd_Getter_(unwrap_jso(this));
  
  @DomName('PerformanceTiming.redirectStart')
  @DocsEditable()
  int get redirectStart => _blink.BlinkPerformanceTiming.instance.redirectStart_Getter_(unwrap_jso(this));
  
  @DomName('PerformanceTiming.requestStart')
  @DocsEditable()
  int get requestStart => _blink.BlinkPerformanceTiming.instance.requestStart_Getter_(unwrap_jso(this));
  
  @DomName('PerformanceTiming.responseEnd')
  @DocsEditable()
  int get responseEnd => _blink.BlinkPerformanceTiming.instance.responseEnd_Getter_(unwrap_jso(this));
  
  @DomName('PerformanceTiming.responseStart')
  @DocsEditable()
  int get responseStart => _blink.BlinkPerformanceTiming.instance.responseStart_Getter_(unwrap_jso(this));
  
  @DomName('PerformanceTiming.secureConnectionStart')
  @DocsEditable()
  int get secureConnectionStart => _blink.BlinkPerformanceTiming.instance.secureConnectionStart_Getter_(unwrap_jso(this));
  
  @DomName('PerformanceTiming.unloadEventEnd')
  @DocsEditable()
  int get unloadEventEnd => _blink.BlinkPerformanceTiming.instance.unloadEventEnd_Getter_(unwrap_jso(this));
  
  @DomName('PerformanceTiming.unloadEventStart')
  @DocsEditable()
  int get unloadEventStart => _blink.BlinkPerformanceTiming.instance.unloadEventStart_Getter_(unwrap_jso(this));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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 wrap_jso(_blink.BlinkPeriodicSyncEvent.instance.constructorCallback_2_(type, init_1));
  }


  @Deprecated("Internal Use Only")
  static PeriodicSyncEvent internalCreatePeriodicSyncEvent() {
    return new PeriodicSyncEvent._internalWrap();
  }

  external factory PeriodicSyncEvent._internalWrap();

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


  @DomName('PeriodicSyncEvent.registration')
  @DocsEditable()
  @Experimental() // untriaged
  PeriodicSyncRegistration get registration => wrap_jso(_blink.BlinkPeriodicSyncEvent.instance.registration_Getter_(unwrap_jso(this)));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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")
  static PeriodicSyncManager internalCreatePeriodicSyncManager() {
    return new PeriodicSyncManager._internalWrap();
  }

  factory PeriodicSyncManager._internalWrap() {
    return new PeriodicSyncManager.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  @DomName('PeriodicSyncManager.minPossiblePeriod')
  @DocsEditable()
  @Experimental() // untriaged
  int get minPossiblePeriod => _blink.BlinkPeriodicSyncManager.instance.minPossiblePeriod_Getter_(unwrap_jso(this));
  
  @DomName('PeriodicSyncManager.getRegistration')
  @DocsEditable()
  @Experimental() // untriaged
  Future getRegistration(String tag) => wrap_jso(_blink.BlinkPeriodicSyncManager.instance.getRegistration_Callback_1_(unwrap_jso(this), tag));
  
  @DomName('PeriodicSyncManager.getRegistrations')
  @DocsEditable()
  @Experimental() // untriaged
  Future getRegistrations() => wrap_jso(_blink.BlinkPeriodicSyncManager.instance.getRegistrations_Callback_0_(unwrap_jso(this)));
  
  @DomName('PeriodicSyncManager.permissionState')
  @DocsEditable()
  @Experimental() // untriaged
  Future permissionState() => wrap_jso(_blink.BlinkPeriodicSyncManager.instance.permissionState_Callback_0_(unwrap_jso(this)));
  
  Future register([Map options]) {
    if (options != null) {
      return wrap_jso(_blink.BlinkPeriodicSyncManager.instance.register_Callback_1_(unwrap_jso(this), convertDartToNative_Dictionary(options)));
    }
    return wrap_jso(_blink.BlinkPeriodicSyncManager.instance.register_Callback_0_(unwrap_jso(this)));
  }

}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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")
  static PeriodicSyncRegistration internalCreatePeriodicSyncRegistration() {
    return new PeriodicSyncRegistration._internalWrap();
  }

  factory PeriodicSyncRegistration._internalWrap() {
    return new PeriodicSyncRegistration.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  @DomName('PeriodicSyncRegistration.minPeriod')
  @DocsEditable()
  @Experimental() // untriaged
  int get minPeriod => _blink.BlinkPeriodicSyncRegistration.instance.minPeriod_Getter_(unwrap_jso(this));
  
  @DomName('PeriodicSyncRegistration.networkState')
  @DocsEditable()
  @Experimental() // untriaged
  String get networkState => _blink.BlinkPeriodicSyncRegistration.instance.networkState_Getter_(unwrap_jso(this));
  
  @DomName('PeriodicSyncRegistration.powerState')
  @DocsEditable()
  @Experimental() // untriaged
  String get powerState => _blink.BlinkPeriodicSyncRegistration.instance.powerState_Getter_(unwrap_jso(this));
  
  @DomName('PeriodicSyncRegistration.tag')
  @DocsEditable()
  @Experimental() // untriaged
  String get tag => _blink.BlinkPeriodicSyncRegistration.instance.tag_Getter_(unwrap_jso(this));
  
  @DomName('PeriodicSyncRegistration.unregister')
  @DocsEditable()
  @Experimental() // untriaged
  Future unregister() => wrap_jso(_blink.BlinkPeriodicSyncRegistration.instance.unregister_Callback_0_(unwrap_jso(this)));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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")
  static PermissionStatus internalCreatePermissionStatus() {
    return new PermissionStatus._internalWrap();
  }

  external factory PermissionStatus._internalWrap();

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


  @DomName('PermissionStatus.state')
  @DocsEditable()
  @Experimental() // untriaged
  String get state => _blink.BlinkPermissionStatus.instance.state_Getter_(unwrap_jso(this));
  
  @DomName('PermissionStatus.status')
  @DocsEditable()
  @Experimental() // untriaged
  String get status => _blink.BlinkPermissionStatus.instance.status_Getter_(unwrap_jso(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")
  static Permissions internalCreatePermissions() {
    return new Permissions._internalWrap();
  }

  factory Permissions._internalWrap() {
    return new Permissions.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  @DomName('Permissions.query')
  @DocsEditable()
  @Experimental() // untriaged
  Future query(Object permission) => wrap_jso(_blink.BlinkPermissions.instance.query_Callback_1_(unwrap_jso(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")
  static PictureElement internalCreatePictureElement() {
    return new PictureElement._internalWrap();
  }

  external factory PictureElement._internalWrap();

  @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")
  static Plugin internalCreatePlugin() {
    return new Plugin._internalWrap();
  }

  factory Plugin._internalWrap() {
    return new Plugin.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  @DomName('Plugin.description')
  @DocsEditable()
  String get description => _blink.BlinkPlugin.instance.description_Getter_(unwrap_jso(this));
  
  @DomName('Plugin.filename')
  @DocsEditable()
  String get filename => _blink.BlinkPlugin.instance.filename_Getter_(unwrap_jso(this));
  
  @DomName('Plugin.length')
  @DocsEditable()
  int get length => _blink.BlinkPlugin.instance.length_Getter_(unwrap_jso(this));
  
  @DomName('Plugin.name')
  @DocsEditable()
  String get name => _blink.BlinkPlugin.instance.name_Getter_(unwrap_jso(this));
  
  @DomName('Plugin.item')
  @DocsEditable()
  MimeType item(int index) => wrap_jso(_blink.BlinkPlugin.instance.item_Callback_1_(unwrap_jso(this), index));
  
  MimeType namedItem(String name) {
    if ((name is String || name == null)) {
      return wrap_jso(_blink.BlinkPlugin.instance.namedItem_Callback_1_(unwrap_jso(this), name));
    }
    if ((name is String || name == null)) {
      return wrap_jso(_blink.BlinkPlugin.instance.namedItem_Callback_1_(unwrap_jso(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")
  static PluginArray internalCreatePluginArray() {
    return new PluginArray._internalWrap();
  }

  factory PluginArray._internalWrap() {
    return new PluginArray.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  @DomName('PluginArray.length')
  @DocsEditable()
  int get length => _blink.BlinkPluginArray.instance.length_Getter_(unwrap_jso(this));
  
  Plugin operator[](int index) {
    if (index < 0 || index >= length)
      throw new RangeError.index(index, this);
    return wrap_jso(_blink.BlinkPluginArray.instance.item_Callback_1_(unwrap_jso(this), index));
  }

  Plugin _nativeIndexedGetter(int index) => wrap_jso(_blink.BlinkPluginArray.instance.item_Callback_1_(unwrap_jso(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) => wrap_jso(_blink.BlinkPluginArray.instance.item_Callback_1_(unwrap_jso(this), index));
  
  Plugin namedItem(String name) {
    if ((name is String || name == null)) {
      return wrap_jso(_blink.BlinkPluginArray.instance.namedItem_Callback_1_(unwrap_jso(this), name));
    }
    if ((name is String || name == null)) {
      return wrap_jso(_blink.BlinkPluginArray.instance.namedItem_Callback_1_(unwrap_jso(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_(unwrap_jso(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")
  static PluginPlaceholderElement internalCreatePluginPlaceholderElement() {
    return new PluginPlaceholderElement._internalWrap();
  }

  external factory PluginPlaceholderElement._internalWrap();

  @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_(unwrap_jso(this));
  
  @DomName('PluginPlaceholderElement.closeable')
  @DocsEditable()
  @Experimental() // untriaged
  set closeable(bool value) => _blink.BlinkPluginPlaceholderElement.instance.closeable_Setter_(unwrap_jso(this), value);
  
  @DomName('PluginPlaceholderElement.message')
  @DocsEditable()
  @Experimental() // untriaged
  String get message => _blink.BlinkPluginPlaceholderElement.instance.message_Getter_(unwrap_jso(this));
  
  @DomName('PluginPlaceholderElement.message')
  @DocsEditable()
  @Experimental() // untriaged
  set message(String value) => _blink.BlinkPluginPlaceholderElement.instance.message_Setter_(unwrap_jso(this), value);
  
  @DomName('PluginPlaceholderElement.createdCallback')
  @DocsEditable()
  @Experimental() // untriaged
  void createdCallback() => _blink.BlinkPluginPlaceholderElement.instance.createdCallback_Callback_0_(unwrap_jso(this));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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 wrap_jso(_blink.BlinkPointerEvent.instance.constructorCallback_2_(type, eventInitDict_1));
    }
    return wrap_jso(_blink.BlinkPointerEvent.instance.constructorCallback_1_(type));
  }


  @Deprecated("Internal Use Only")
  static PointerEvent internalCreatePointerEvent() {
    return new PointerEvent._internalWrap();
  }

  external factory PointerEvent._internalWrap();

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


  @DomName('PointerEvent.height')
  @DocsEditable()
  @Experimental() // untriaged
  num get height => _blink.BlinkPointerEvent.instance.height_Getter_(unwrap_jso(this));
  
  @DomName('PointerEvent.isPrimary')
  @DocsEditable()
  @Experimental() // untriaged
  bool get isPrimary => _blink.BlinkPointerEvent.instance.isPrimary_Getter_(unwrap_jso(this));
  
  @DomName('PointerEvent.pointerId')
  @DocsEditable()
  @Experimental() // untriaged
  int get pointerId => _blink.BlinkPointerEvent.instance.pointerId_Getter_(unwrap_jso(this));
  
  @DomName('PointerEvent.pointerType')
  @DocsEditable()
  @Experimental() // untriaged
  String get pointerType => _blink.BlinkPointerEvent.instance.pointerType_Getter_(unwrap_jso(this));
  
  @DomName('PointerEvent.pressure')
  @DocsEditable()
  @Experimental() // untriaged
  num get pressure => _blink.BlinkPointerEvent.instance.pressure_Getter_(unwrap_jso(this));
  
  @DomName('PointerEvent.tiltX')
  @DocsEditable()
  @Experimental() // untriaged
  int get tiltX => _blink.BlinkPointerEvent.instance.tiltX_Getter_(unwrap_jso(this));
  
  @DomName('PointerEvent.tiltY')
  @DocsEditable()
  @Experimental() // untriaged
  int get tiltY => _blink.BlinkPointerEvent.instance.tiltY_Getter_(unwrap_jso(this));
  
  @DomName('PointerEvent.width')
  @DocsEditable()
  @Experimental() // untriaged
  num get width => _blink.BlinkPointerEvent.instance.width_Getter_(unwrap_jso(this));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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 wrap_jso(_blink.BlinkPopStateEvent.instance.constructorCallback_2_(type, eventInitDict_1));
    }
    return wrap_jso(_blink.BlinkPopStateEvent.instance.constructorCallback_1_(type));
  }


  @Deprecated("Internal Use Only")
  static PopStateEvent internalCreatePopStateEvent() {
    return new PopStateEvent._internalWrap();
  }

  external factory PopStateEvent._internalWrap();

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


  @DomName('PopStateEvent.state')
  @DocsEditable()
  Object get state => wrap_jso(_blink.BlinkPopStateEvent.instance.state_Getter_(unwrap_jso(this)));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of 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")
  static PositionError internalCreatePositionError() {
    return new PositionError._internalWrap();
  }

  factory PositionError._internalWrap() {
    return new PositionError.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  @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_(unwrap_jso(this));
  
  @DomName('PositionError.message')
  @DocsEditable()
  String get message => _blink.BlinkPositionError.instance.message_Getter_(unwrap_jso(this));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of 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")
  static PositionSensorVRDevice internalCreatePositionSensorVRDevice() {
    return new PositionSensorVRDevice._internalWrap();
  }

  external factory PositionSensorVRDevice._internalWrap();

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


  @DomName('PositionSensorVRDevice.getImmediateState')
  @DocsEditable()
  @Experimental() // untriaged
  VRPositionState getImmediateState() => wrap_jso(_blink.BlinkPositionSensorVRDevice.instance.getImmediateState_Callback_0_(unwrap_jso(this)));
  
  @DomName('PositionSensorVRDevice.getState')
  @DocsEditable()
  @Experimental() // untriaged
  VRPositionState getState() => wrap_jso(_blink.BlinkPositionSensorVRDevice.instance.getState_Callback_0_(unwrap_jso(this)));
  
  @DomName('PositionSensorVRDevice.resetSensor')
  @DocsEditable()
  @Experimental() // untriaged
  void resetSensor() => _blink.BlinkPositionSensorVRDevice.instance.resetSensor_Callback_0_(unwrap_jso(this));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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")
  static PreElement internalCreatePreElement() {
    return new PreElement._internalWrap();
  }

  external factory PreElement._internalWrap();

  @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")
  static Presentation internalCreatePresentation() {
    return new Presentation._internalWrap();
  }

  external factory Presentation._internalWrap();

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


  @DomName('Presentation.session')
  @DocsEditable()
  @Experimental() // untriaged
  PresentationSession get session => wrap_jso(_blink.BlinkPresentation.instance.session_Getter_(unwrap_jso(this)));
  
  @DomName('Presentation.getAvailability')
  @DocsEditable()
  @Experimental() // untriaged
  Future getAvailability(String url) => wrap_jso(_blink.BlinkPresentation.instance.getAvailability_Callback_1_(unwrap_jso(this), url));
  
  @DomName('Presentation.joinSession')
  @DocsEditable()
  @Experimental() // untriaged
  Future joinSession(String url, String presentationId) => wrap_jso(_blink.BlinkPresentation.instance.joinSession_Callback_2_(unwrap_jso(this), url, presentationId));
  
  @DomName('Presentation.startSession')
  @DocsEditable()
  @Experimental() // untriaged
  Future startSession(String url) => wrap_jso(_blink.BlinkPresentation.instance.startSession_Callback_1_(unwrap_jso(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")
  static PresentationAvailability internalCreatePresentationAvailability() {
    return new PresentationAvailability._internalWrap();
  }

  external factory PresentationAvailability._internalWrap();

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


  @DomName('PresentationAvailability.value')
  @DocsEditable()
  @Experimental() // untriaged
  bool get value => _blink.BlinkPresentationAvailability.instance.value_Getter_(unwrap_jso(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")
  static PresentationSession internalCreatePresentationSession() {
    return new PresentationSession._internalWrap();
  }

  external factory PresentationSession._internalWrap();

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


  @DomName('PresentationSession.binaryType')
  @DocsEditable()
  @Experimental() // untriaged
  String get binaryType => _blink.BlinkPresentationSession.instance.binaryType_Getter_(unwrap_jso(this));
  
  @DomName('PresentationSession.binaryType')
  @DocsEditable()
  @Experimental() // untriaged
  set binaryType(String value) => _blink.BlinkPresentationSession.instance.binaryType_Setter_(unwrap_jso(this), value);
  
  @DomName('PresentationSession.id')
  @DocsEditable()
  @Experimental() // untriaged
  String get id => _blink.BlinkPresentationSession.instance.id_Getter_(unwrap_jso(this));
  
  @DomName('PresentationSession.state')
  @DocsEditable()
  @Experimental() // untriaged
  String get state => _blink.BlinkPresentationSession.instance.state_Getter_(unwrap_jso(this));
  
  @DomName('PresentationSession.close')
  @DocsEditable()
  @Experimental() // untriaged
  void close() => _blink.BlinkPresentationSession.instance.close_Callback_0_(unwrap_jso(this));
  
  void send(data_OR_message) {
    if ((data_OR_message is String || data_OR_message == null)) {
      _blink.BlinkPresentationSession.instance.send_Callback_1_(unwrap_jso(this), unwrap_jso(data_OR_message));
      return;
    }
    if ((data_OR_message is Blob || data_OR_message == null)) {
      _blink.BlinkPresentationSession.instance.send_Callback_1_(unwrap_jso(this), unwrap_jso(data_OR_message));
      return;
    }
    if ((data_OR_message is TypedData || data_OR_message == null)) {
      _blink.BlinkPresentationSession.instance.send_Callback_1_(unwrap_jso(this), unwrap_jso(data_OR_message));
      return;
    }
    if ((data_OR_message is ByteBuffer || data_OR_message == null)) {
      _blink.BlinkPresentationSession.instance.send_Callback_1_(unwrap_jso(this), unwrap_jso(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")
  static ProcessingInstruction internalCreateProcessingInstruction() {
    return new ProcessingInstruction._internalWrap();
  }

  external factory ProcessingInstruction._internalWrap();

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


  @DomName('ProcessingInstruction.sheet')
  @DocsEditable()
  @Experimental() // non-standard
  StyleSheet get sheet => wrap_jso(_blink.BlinkProcessingInstruction.instance.sheet_Getter_(unwrap_jso(this)));
  
  @DomName('ProcessingInstruction.target')
  @DocsEditable()
  String get target => _blink.BlinkProcessingInstruction.instance.target_Getter_(unwrap_jso(this));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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")
  static ProgressElement internalCreateProgressElement() {
    return new ProgressElement._internalWrap();
  }

  external factory ProgressElement._internalWrap();

  @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 => wrap_jso(_blink.BlinkHTMLProgressElement.instance.labels_Getter_(unwrap_jso(this)));
  
  @DomName('HTMLProgressElement.max')
  @DocsEditable()
  num get max => _blink.BlinkHTMLProgressElement.instance.max_Getter_(unwrap_jso(this));
  
  @DomName('HTMLProgressElement.max')
  @DocsEditable()
  set max(num value) => _blink.BlinkHTMLProgressElement.instance.max_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLProgressElement.position')
  @DocsEditable()
  num get position => _blink.BlinkHTMLProgressElement.instance.position_Getter_(unwrap_jso(this));
  
  @DomName('HTMLProgressElement.value')
  @DocsEditable()
  num get value => _blink.BlinkHTMLProgressElement.instance.value_Getter_(unwrap_jso(this));
  
  @DomName('HTMLProgressElement.value')
  @DocsEditable()
  set value(num value) => _blink.BlinkHTMLProgressElement.instance.value_Setter_(unwrap_jso(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 wrap_jso(_blink.BlinkProgressEvent.instance.constructorCallback_2_(type, eventInitDict_1));
    }
    return wrap_jso(_blink.BlinkProgressEvent.instance.constructorCallback_1_(type));
  }


  @Deprecated("Internal Use Only")
  static ProgressEvent internalCreateProgressEvent() {
    return new ProgressEvent._internalWrap();
  }

  external factory ProgressEvent._internalWrap();

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


  @DomName('ProgressEvent.lengthComputable')
  @DocsEditable()
  bool get lengthComputable => _blink.BlinkProgressEvent.instance.lengthComputable_Getter_(unwrap_jso(this));
  
  @DomName('ProgressEvent.loaded')
  @DocsEditable()
  int get loaded => _blink.BlinkProgressEvent.instance.loaded_Getter_(unwrap_jso(this));
  
  @DomName('ProgressEvent.total')
  @DocsEditable()
  int get total => _blink.BlinkProgressEvent.instance.total_Getter_(unwrap_jso(this));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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 wrap_jso(_blink.BlinkPromiseRejectionEvent.instance.constructorCallback_2_(type, eventInitDict_1));
    }
    return wrap_jso(_blink.BlinkPromiseRejectionEvent.instance.constructorCallback_1_(type));
  }


  @Deprecated("Internal Use Only")
  static PromiseRejectionEvent internalCreatePromiseRejectionEvent() {
    return new PromiseRejectionEvent._internalWrap();
  }

  external factory PromiseRejectionEvent._internalWrap();

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


  @DomName('PromiseRejectionEvent.promise')
  @DocsEditable()
  @Experimental() // untriaged
  Future get promise => wrap_jso(_blink.BlinkPromiseRejectionEvent.instance.promise_Getter_(unwrap_jso(this)));
  
  @DomName('PromiseRejectionEvent.reason')
  @DocsEditable()
  @Experimental() // untriaged
  Object get reason => wrap_jso(_blink.BlinkPromiseRejectionEvent.instance.reason_Getter_(unwrap_jso(this)));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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 wrap_jso(_blink.BlinkPushEvent.instance.constructorCallback_2_(type, eventInitDict_1));
    }
    return wrap_jso(_blink.BlinkPushEvent.instance.constructorCallback_1_(type));
  }


  @Deprecated("Internal Use Only")
  static PushEvent internalCreatePushEvent() {
    return new PushEvent._internalWrap();
  }

  external factory PushEvent._internalWrap();

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


  @DomName('PushEvent.data')
  @DocsEditable()
  @Experimental() // untriaged
  PushMessageData get data => wrap_jso(_blink.BlinkPushEvent.instance.data_Getter_(unwrap_jso(this)));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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")
  static PushManager internalCreatePushManager() {
    return new PushManager._internalWrap();
  }

  factory PushManager._internalWrap() {
    return new PushManager.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  @DomName('PushManager.getSubscription')
  @DocsEditable()
  @Experimental() // untriaged
  Future getSubscription() => wrap_jso(_blink.BlinkPushManager.instance.getSubscription_Callback_0_(unwrap_jso(this)));
  
  Future permissionState([Map options]) {
    if (options != null) {
      return wrap_jso(_blink.BlinkPushManager.instance.permissionState_Callback_1_(unwrap_jso(this), convertDartToNative_Dictionary(options)));
    }
    return wrap_jso(_blink.BlinkPushManager.instance.permissionState_Callback_0_(unwrap_jso(this)));
  }

  Future subscribe([Map options]) {
    if (options != null) {
      return wrap_jso(_blink.BlinkPushManager.instance.subscribe_Callback_1_(unwrap_jso(this), convertDartToNative_Dictionary(options)));
    }
    return wrap_jso(_blink.BlinkPushManager.instance.subscribe_Callback_0_(unwrap_jso(this)));
  }

}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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 wrap_jso(_blink.BlinkPushMessageData.instance.constructorCallback_1_(message));
  }

  @Deprecated("Internal Use Only")
  static PushMessageData internalCreatePushMessageData() {
    return new PushMessageData._internalWrap();
  }

  factory PushMessageData._internalWrap() {
    return new PushMessageData.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  @DomName('PushMessageData.arrayBuffer')
  @DocsEditable()
  @Experimental() // untriaged
  ByteBuffer arrayBuffer() => wrap_jso(_blink.BlinkPushMessageData.instance.arrayBuffer_Callback_0_(unwrap_jso(this)));
  
  @DomName('PushMessageData.blob')
  @DocsEditable()
  @Experimental() // untriaged
  Blob blob() => wrap_jso(_blink.BlinkPushMessageData.instance.blob_Callback_0_(unwrap_jso(this)));
  
  @DomName('PushMessageData.json')
  @DocsEditable()
  @Experimental() // untriaged
  Object json() => wrap_jso(_blink.BlinkPushMessageData.instance.json_Callback_0_(unwrap_jso(this)));
  
  @DomName('PushMessageData.text')
  @DocsEditable()
  @Experimental() // untriaged
  String text() => _blink.BlinkPushMessageData.instance.text_Callback_0_(unwrap_jso(this));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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")
  static PushSubscription internalCreatePushSubscription() {
    return new PushSubscription._internalWrap();
  }

  factory PushSubscription._internalWrap() {
    return new PushSubscription.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  @DomName('PushSubscription.endpoint')
  @DocsEditable()
  @Experimental() // untriaged
  String get endpoint => _blink.BlinkPushSubscription.instance.endpoint_Getter_(unwrap_jso(this));
  
  @DomName('PushSubscription.unsubscribe')
  @DocsEditable()
  @Experimental() // untriaged
  Future unsubscribe() => wrap_jso(_blink.BlinkPushSubscription.instance.unsubscribe_Callback_0_(unwrap_jso(this)));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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")
  static QuoteElement internalCreateQuoteElement() {
    return new QuoteElement._internalWrap();
  }

  external factory QuoteElement._internalWrap();

  @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_(unwrap_jso(this));
  
  @DomName('HTMLQuoteElement.cite')
  @DocsEditable()
  set cite(String value) => _blink.BlinkHTMLQuoteElement.instance.cite_Setter_(unwrap_jso(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")
  static Range internalCreateRange() {
    return new Range._internalWrap();
  }

  factory Range._internalWrap() {
    return new Range.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  @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_(unwrap_jso(this));
  
  @DomName('Range.commonAncestorContainer')
  @DocsEditable()
  Node get commonAncestorContainer => wrap_jso(_blink.BlinkRange.instance.commonAncestorContainer_Getter_(unwrap_jso(this)));
  
  @DomName('Range.endContainer')
  @DocsEditable()
  Node get endContainer => wrap_jso(_blink.BlinkRange.instance.endContainer_Getter_(unwrap_jso(this)));
  
  @DomName('Range.endOffset')
  @DocsEditable()
  int get endOffset => _blink.BlinkRange.instance.endOffset_Getter_(unwrap_jso(this));
  
  @DomName('Range.startContainer')
  @DocsEditable()
  Node get startContainer => wrap_jso(_blink.BlinkRange.instance.startContainer_Getter_(unwrap_jso(this)));
  
  @DomName('Range.startOffset')
  @DocsEditable()
  int get startOffset => _blink.BlinkRange.instance.startOffset_Getter_(unwrap_jso(this));
  
  @DomName('Range.cloneContents')
  @DocsEditable()
  DocumentFragment cloneContents() => wrap_jso(_blink.BlinkRange.instance.cloneContents_Callback_0_(unwrap_jso(this)));
  
  @DomName('Range.cloneRange')
  @DocsEditable()
  Range cloneRange() => wrap_jso(_blink.BlinkRange.instance.cloneRange_Callback_0_(unwrap_jso(this)));
  
  void collapse([bool toStart]) {
    if (toStart != null) {
      _blink.BlinkRange.instance.collapse_Callback_1_(unwrap_jso(this), toStart);
      return;
    }
    _blink.BlinkRange.instance.collapse_Callback_0_(unwrap_jso(this));
    return;
  }

  @DomName('Range.compareBoundaryPoints')
  @DocsEditable()
  @Experimental() // untriaged
  int compareBoundaryPoints(int how, Range sourceRange) => _blink.BlinkRange.instance.compareBoundaryPoints_Callback_2_(unwrap_jso(this), how, unwrap_jso(sourceRange));
  
  @DomName('Range.comparePoint')
  @DocsEditable()
  int comparePoint(Node node, int offset) => _blink.BlinkRange.instance.comparePoint_Callback_2_(unwrap_jso(this), unwrap_jso(node), offset);
  
  @DomName('Range.createContextualFragment')
  @DocsEditable()
  DocumentFragment createContextualFragment(String fragment) => wrap_jso(_blink.BlinkRange.instance.createContextualFragment_Callback_1_(unwrap_jso(this), fragment));
  
  @DomName('Range.deleteContents')
  @DocsEditable()
  void deleteContents() => _blink.BlinkRange.instance.deleteContents_Callback_0_(unwrap_jso(this));
  
  @DomName('Range.detach')
  @DocsEditable()
  void detach() => _blink.BlinkRange.instance.detach_Callback_0_(unwrap_jso(this));
  
  @DomName('Range.expand')
  @DocsEditable()
  @Experimental() // non-standard
  void expand(String unit) => _blink.BlinkRange.instance.expand_Callback_1_(unwrap_jso(this), unit);
  
  @DomName('Range.extractContents')
  @DocsEditable()
  DocumentFragment extractContents() => wrap_jso(_blink.BlinkRange.instance.extractContents_Callback_0_(unwrap_jso(this)));
  
  @DomName('Range.getBoundingClientRect')
  @DocsEditable()
  Rectangle getBoundingClientRect() => make_dart_rectangle(_blink.BlinkRange.instance.getBoundingClientRect_Callback_0_(unwrap_jso(this)));
  
  @DomName('Range.getClientRects')
  @DocsEditable()
  List<Rectangle> getClientRects() => wrap_jso(_blink.BlinkRange.instance.getClientRects_Callback_0_(unwrap_jso(this)));
  
  @DomName('Range.insertNode')
  @DocsEditable()
  void insertNode(Node node) => _blink.BlinkRange.instance.insertNode_Callback_1_(unwrap_jso(this), unwrap_jso(node));
  
  @DomName('Range.isPointInRange')
  @DocsEditable()
  bool isPointInRange(Node node, int offset) => _blink.BlinkRange.instance.isPointInRange_Callback_2_(unwrap_jso(this), unwrap_jso(node), offset);
  
  @DomName('Range.selectNode')
  @DocsEditable()
  void selectNode(Node node) => _blink.BlinkRange.instance.selectNode_Callback_1_(unwrap_jso(this), unwrap_jso(node));
  
  @DomName('Range.selectNodeContents')
  @DocsEditable()
  void selectNodeContents(Node node) => _blink.BlinkRange.instance.selectNodeContents_Callback_1_(unwrap_jso(this), unwrap_jso(node));
  
  @DomName('Range.setEnd')
  @DocsEditable()
  void setEnd(Node node, int offset) => _blink.BlinkRange.instance.setEnd_Callback_2_(unwrap_jso(this), unwrap_jso(node), offset);
  
  @DomName('Range.setEndAfter')
  @DocsEditable()
  void setEndAfter(Node node) => _blink.BlinkRange.instance.setEndAfter_Callback_1_(unwrap_jso(this), unwrap_jso(node));
  
  @DomName('Range.setEndBefore')
  @DocsEditable()
  void setEndBefore(Node node) => _blink.BlinkRange.instance.setEndBefore_Callback_1_(unwrap_jso(this), unwrap_jso(node));
  
  @DomName('Range.setStart')
  @DocsEditable()
  void setStart(Node node, int offset) => _blink.BlinkRange.instance.setStart_Callback_2_(unwrap_jso(this), unwrap_jso(node), offset);
  
  @DomName('Range.setStartAfter')
  @DocsEditable()
  void setStartAfter(Node node) => _blink.BlinkRange.instance.setStartAfter_Callback_1_(unwrap_jso(this), unwrap_jso(node));
  
  @DomName('Range.setStartBefore')
  @DocsEditable()
  void setStartBefore(Node node) => _blink.BlinkRange.instance.setStartBefore_Callback_1_(unwrap_jso(this), unwrap_jso(node));
  
  @DomName('Range.surroundContents')
  @DocsEditable()
  void surroundContents(Node newParent) => _blink.BlinkRange.instance.surroundContents_Callback_1_(unwrap_jso(this), unwrap_jso(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")
  static ReadableByteStream internalCreateReadableByteStream() {
    return new ReadableByteStream._internalWrap();
  }

  factory ReadableByteStream._internalWrap() {
    return new ReadableByteStream.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  Future cancel([Object reason]) {
    if (reason != null) {
      return wrap_jso(_blink.BlinkReadableByteStream.instance.cancel_Callback_1_(unwrap_jso(this), reason));
    }
    return wrap_jso(_blink.BlinkReadableByteStream.instance.cancel_Callback_0_(unwrap_jso(this)));
  }

  @DomName('ReadableByteStream.getReader')
  @DocsEditable()
  @Experimental() // untriaged
  ReadableByteStreamReader getReader() => wrap_jso(_blink.BlinkReadableByteStream.instance.getReader_Callback_0_(unwrap_jso(this)));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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")
  static ReadableByteStreamReader internalCreateReadableByteStreamReader() {
    return new ReadableByteStreamReader._internalWrap();
  }

  factory ReadableByteStreamReader._internalWrap() {
    return new ReadableByteStreamReader.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  @DomName('ReadableByteStreamReader.closed')
  @DocsEditable()
  @Experimental() // untriaged
  Future get closed => wrap_jso(_blink.BlinkReadableByteStreamReader.instance.closed_Getter_(unwrap_jso(this)));
  
  Future cancel([Object reason]) {
    if (reason != null) {
      return wrap_jso(_blink.BlinkReadableByteStreamReader.instance.cancel_Callback_1_(unwrap_jso(this), reason));
    }
    return wrap_jso(_blink.BlinkReadableByteStreamReader.instance.cancel_Callback_0_(unwrap_jso(this)));
  }

  @DomName('ReadableByteStreamReader.read')
  @DocsEditable()
  @Experimental() // untriaged
  Future read() => wrap_jso(_blink.BlinkReadableByteStreamReader.instance.read_Callback_0_(unwrap_jso(this)));
  
  @DomName('ReadableByteStreamReader.releaseLock')
  @DocsEditable()
  @Experimental() // untriaged
  void releaseLock() => _blink.BlinkReadableByteStreamReader.instance.releaseLock_Callback_0_(unwrap_jso(this));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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")
  static ReadableStream internalCreateReadableStream() {
    return new ReadableStream._internalWrap();
  }

  factory ReadableStream._internalWrap() {
    return new ReadableStream.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  Future cancel([Object reason]) {
    if (reason != null) {
      return wrap_jso(_blink.BlinkReadableStream.instance.cancel_Callback_1_(unwrap_jso(this), reason));
    }
    return wrap_jso(_blink.BlinkReadableStream.instance.cancel_Callback_0_(unwrap_jso(this)));
  }

  @DomName('ReadableStream.getReader')
  @DocsEditable()
  @Experimental() // untriaged
  ReadableStreamReader getReader() => wrap_jso(_blink.BlinkReadableStream.instance.getReader_Callback_0_(unwrap_jso(this)));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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")
  static ReadableStreamReader internalCreateReadableStreamReader() {
    return new ReadableStreamReader._internalWrap();
  }

  factory ReadableStreamReader._internalWrap() {
    return new ReadableStreamReader.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  @DomName('ReadableStreamReader.closed')
  @DocsEditable()
  @Experimental() // untriaged
  Future get closed => wrap_jso(_blink.BlinkReadableStreamReader.instance.closed_Getter_(unwrap_jso(this)));
  
  Future cancel([Object reason]) {
    if (reason != null) {
      return wrap_jso(_blink.BlinkReadableStreamReader.instance.cancel_Callback_1_(unwrap_jso(this), reason));
    }
    return wrap_jso(_blink.BlinkReadableStreamReader.instance.cancel_Callback_0_(unwrap_jso(this)));
  }

  @DomName('ReadableStreamReader.read')
  @DocsEditable()
  @Experimental() // untriaged
  Future read() => wrap_jso(_blink.BlinkReadableStreamReader.instance.read_Callback_0_(unwrap_jso(this)));
  
  @DomName('ReadableStreamReader.releaseLock')
  @DocsEditable()
  @Experimental() // untriaged
  void releaseLock() => _blink.BlinkReadableStreamReader.instance.releaseLock_Callback_0_(unwrap_jso(this));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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 wrap_jso(_blink.BlinkRelatedEvent.instance.constructorCallback_2_(type, eventInitDict_1));
    }
    return wrap_jso(_blink.BlinkRelatedEvent.instance.constructorCallback_1_(type));
  }


  @Deprecated("Internal Use Only")
  static RelatedEvent internalCreateRelatedEvent() {
    return new RelatedEvent._internalWrap();
  }

  external factory RelatedEvent._internalWrap();

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


  @DomName('RelatedEvent.relatedTarget')
  @DocsEditable()
  @Experimental() // untriaged
  EventTarget get relatedTarget => wrap_jso(_blink.BlinkRelatedEvent.instance.relatedTarget_Getter_(unwrap_jso(this)));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.


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

// WARNING: Do not edit - generated code.


@DocsEditable()
@DomName('ResourceProgressEvent')
// https://chromiumcodereview.appspot.com/14773025/
@deprecated // experimental
class ResourceProgressEvent extends ProgressEvent {
  // To suppress missing implicit constructor warnings.
  factory ResourceProgressEvent._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  static ResourceProgressEvent internalCreateResourceProgressEvent() {
    return new ResourceProgressEvent._internalWrap();
  }

  external factory ResourceProgressEvent._internalWrap();

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


  @DomName('ResourceProgressEvent.url')
  @DocsEditable()
  String get url => _blink.BlinkResourceProgressEvent.instance.url_Getter_(unwrap_jso(this));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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")
  static RtcDataChannel internalCreateRtcDataChannel() {
    return new RtcDataChannel._internalWrap();
  }

  external factory RtcDataChannel._internalWrap();

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


  @DomName('RTCDataChannel.binaryType')
  @DocsEditable()
  String get binaryType => _blink.BlinkRTCDataChannel.instance.binaryType_Getter_(unwrap_jso(this));
  
  @DomName('RTCDataChannel.binaryType')
  @DocsEditable()
  set binaryType(String value) => _blink.BlinkRTCDataChannel.instance.binaryType_Setter_(unwrap_jso(this), value);
  
  @DomName('RTCDataChannel.bufferedAmount')
  @DocsEditable()
  int get bufferedAmount => _blink.BlinkRTCDataChannel.instance.bufferedAmount_Getter_(unwrap_jso(this));
  
  @DomName('RTCDataChannel.id')
  @DocsEditable()
  @Experimental() // untriaged
  int get id => _blink.BlinkRTCDataChannel.instance.id_Getter_(unwrap_jso(this));
  
  @DomName('RTCDataChannel.label')
  @DocsEditable()
  String get label => _blink.BlinkRTCDataChannel.instance.label_Getter_(unwrap_jso(this));
  
  @DomName('RTCDataChannel.maxRetransmitTime')
  @DocsEditable()
  @Experimental() // untriaged
  int get maxRetransmitTime => _blink.BlinkRTCDataChannel.instance.maxRetransmitTime_Getter_(unwrap_jso(this));
  
  @DomName('RTCDataChannel.maxRetransmits')
  @DocsEditable()
  @Experimental() // untriaged
  int get maxRetransmits => _blink.BlinkRTCDataChannel.instance.maxRetransmits_Getter_(unwrap_jso(this));
  
  @DomName('RTCDataChannel.negotiated')
  @DocsEditable()
  @Experimental() // untriaged
  bool get negotiated => _blink.BlinkRTCDataChannel.instance.negotiated_Getter_(unwrap_jso(this));
  
  @DomName('RTCDataChannel.ordered')
  @DocsEditable()
  @Experimental() // untriaged
  bool get ordered => _blink.BlinkRTCDataChannel.instance.ordered_Getter_(unwrap_jso(this));
  
  @DomName('RTCDataChannel.protocol')
  @DocsEditable()
  @Experimental() // untriaged
  String get protocol => _blink.BlinkRTCDataChannel.instance.protocol_Getter_(unwrap_jso(this));
  
  @DomName('RTCDataChannel.readyState')
  @DocsEditable()
  String get readyState => _blink.BlinkRTCDataChannel.instance.readyState_Getter_(unwrap_jso(this));
  
  @DomName('RTCDataChannel.reliable')
  @DocsEditable()
  bool get reliable => _blink.BlinkRTCDataChannel.instance.reliable_Getter_(unwrap_jso(this));
  
  @DomName('RTCDataChannel.close')
  @DocsEditable()
  void close() => _blink.BlinkRTCDataChannel.instance.close_Callback_0_(unwrap_jso(this));
  
  void send(data) {
    if ((data is String || data == null)) {
      _blink.BlinkRTCDataChannel.instance.send_Callback_1_(unwrap_jso(this), unwrap_jso(data));
      return;
    }
    if ((data is Blob || data == null)) {
      _blink.BlinkRTCDataChannel.instance.send_Callback_1_(unwrap_jso(this), unwrap_jso(data));
      return;
    }
    if ((data is TypedData || data == null)) {
      _blink.BlinkRTCDataChannel.instance.send_Callback_1_(unwrap_jso(this), unwrap_jso(data));
      return;
    }
    if ((data is ByteBuffer || data == null)) {
      _blink.BlinkRTCDataChannel.instance.send_Callback_1_(unwrap_jso(this), unwrap_jso(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_(unwrap_jso(this), unwrap_jso(data));
  
  @DomName('RTCDataChannel.sendByteBuffer')
  @DocsEditable()
  void sendByteBuffer(ByteBuffer data) => _blink.BlinkRTCDataChannel.instance.send_Callback_1_(unwrap_jso(this), unwrap_jso(data));
  
  @DomName('RTCDataChannel.sendString')
  @DocsEditable()
  void sendString(String data) => _blink.BlinkRTCDataChannel.instance.send_Callback_1_(unwrap_jso(this), data);
  
  @DomName('RTCDataChannel.sendTypedData')
  @DocsEditable()
  void sendTypedData(TypedData data) => _blink.BlinkRTCDataChannel.instance.send_Callback_1_(unwrap_jso(this), unwrap_jso(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")
  static RtcDataChannelEvent internalCreateRtcDataChannelEvent() {
    return new RtcDataChannelEvent._internalWrap();
  }

  external factory RtcDataChannelEvent._internalWrap();

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


  @DomName('RTCDataChannelEvent.channel')
  @DocsEditable()
  RtcDataChannel get channel => wrap_jso(_blink.BlinkRTCDataChannelEvent.instance.channel_Getter_(unwrap_jso(this)));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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")
  static RtcDtmfSender internalCreateRtcDtmfSender() {
    return new RtcDtmfSender._internalWrap();
  }

  external factory RtcDtmfSender._internalWrap();

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


  @DomName('RTCDTMFSender.canInsertDTMF')
  @DocsEditable()
  bool get canInsertDtmf => _blink.BlinkRTCDTMFSender.instance.canInsertDTMF_Getter_(unwrap_jso(this));
  
  @DomName('RTCDTMFSender.duration')
  @DocsEditable()
  int get duration => _blink.BlinkRTCDTMFSender.instance.duration_Getter_(unwrap_jso(this));
  
  @DomName('RTCDTMFSender.interToneGap')
  @DocsEditable()
  int get interToneGap => _blink.BlinkRTCDTMFSender.instance.interToneGap_Getter_(unwrap_jso(this));
  
  @DomName('RTCDTMFSender.toneBuffer')
  @DocsEditable()
  String get toneBuffer => _blink.BlinkRTCDTMFSender.instance.toneBuffer_Getter_(unwrap_jso(this));
  
  @DomName('RTCDTMFSender.track')
  @DocsEditable()
  MediaStreamTrack get track => wrap_jso(_blink.BlinkRTCDTMFSender.instance.track_Getter_(unwrap_jso(this)));
  
  void insertDtmf(String tones, [int duration, int interToneGap]) {
    if (interToneGap != null) {
      _blink.BlinkRTCDTMFSender.instance.insertDTMF_Callback_3_(unwrap_jso(this), tones, duration, interToneGap);
      return;
    }
    if (duration != null) {
      _blink.BlinkRTCDTMFSender.instance.insertDTMF_Callback_2_(unwrap_jso(this), tones, duration);
      return;
    }
    _blink.BlinkRTCDTMFSender.instance.insertDTMF_Callback_1_(unwrap_jso(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 wrap_jso(_blink.BlinkRTCDTMFToneChangeEvent.instance.constructorCallback_2_(type, eventInitDict_1));
  }


  @Deprecated("Internal Use Only")
  static RtcDtmfToneChangeEvent internalCreateRtcDtmfToneChangeEvent() {
    return new RtcDtmfToneChangeEvent._internalWrap();
  }

  external factory RtcDtmfToneChangeEvent._internalWrap();

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


  @DomName('RTCDTMFToneChangeEvent.tone')
  @DocsEditable()
  String get tone => _blink.BlinkRTCDTMFToneChangeEvent.instance.tone_Getter_(unwrap_jso(this));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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 wrap_jso(_blink.BlinkRTCIceCandidate.instance.constructorCallback_1_(candidateInitDict_1));
  }

  @Deprecated("Internal Use Only")
  static RtcIceCandidate internalCreateRtcIceCandidate() {
    return new RtcIceCandidate._internalWrap();
  }

  factory RtcIceCandidate._internalWrap() {
    return new RtcIceCandidate.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  @DomName('RTCIceCandidate.candidate')
  @DocsEditable()
  String get candidate => _blink.BlinkRTCIceCandidate.instance.candidate_Getter_(unwrap_jso(this));
  
  @DomName('RTCIceCandidate.candidate')
  @DocsEditable()
  set candidate(String value) => _blink.BlinkRTCIceCandidate.instance.candidate_Setter_(unwrap_jso(this), value);
  
  @DomName('RTCIceCandidate.sdpMLineIndex')
  @DocsEditable()
  int get sdpMLineIndex => _blink.BlinkRTCIceCandidate.instance.sdpMLineIndex_Getter_(unwrap_jso(this));
  
  @DomName('RTCIceCandidate.sdpMLineIndex')
  @DocsEditable()
  set sdpMLineIndex(int value) => _blink.BlinkRTCIceCandidate.instance.sdpMLineIndex_Setter_(unwrap_jso(this), value);
  
  @DomName('RTCIceCandidate.sdpMid')
  @DocsEditable()
  String get sdpMid => _blink.BlinkRTCIceCandidate.instance.sdpMid_Getter_(unwrap_jso(this));
  
  @DomName('RTCIceCandidate.sdpMid')
  @DocsEditable()
  set sdpMid(String value) => _blink.BlinkRTCIceCandidate.instance.sdpMid_Setter_(unwrap_jso(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")
  static RtcIceCandidateEvent internalCreateRtcIceCandidateEvent() {
    return new RtcIceCandidateEvent._internalWrap();
  }

  external factory RtcIceCandidateEvent._internalWrap();

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


  @DomName('RTCIceCandidateEvent.candidate')
  @DocsEditable()
  RtcIceCandidate get candidate => wrap_jso(_blink.BlinkRTCIceCandidateEvent.instance.candidate_Getter_(unwrap_jso(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 wrap_jso(_blink.BlinkRTCPeerConnection.instance.constructorCallback_2_(rtcConfiguration_1, mediaConstraints_2));
    }
    var rtcConfiguration_1 = convertDartToNative_Dictionary(rtcConfiguration);
    return wrap_jso(_blink.BlinkRTCPeerConnection.instance.constructorCallback_1_(rtcConfiguration_1));
  }


  @Deprecated("Internal Use Only")
  static RtcPeerConnection internalCreateRtcPeerConnection() {
    return new RtcPeerConnection._internalWrap();
  }

  external factory RtcPeerConnection._internalWrap();

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


  @DomName('RTCPeerConnection.iceConnectionState')
  @DocsEditable()
  String get iceConnectionState => _blink.BlinkRTCPeerConnection.instance.iceConnectionState_Getter_(unwrap_jso(this));
  
  @DomName('RTCPeerConnection.iceGatheringState')
  @DocsEditable()
  String get iceGatheringState => _blink.BlinkRTCPeerConnection.instance.iceGatheringState_Getter_(unwrap_jso(this));
  
  @DomName('RTCPeerConnection.localDescription')
  @DocsEditable()
  RtcSessionDescription get localDescription => wrap_jso(_blink.BlinkRTCPeerConnection.instance.localDescription_Getter_(unwrap_jso(this)));
  
  @DomName('RTCPeerConnection.remoteDescription')
  @DocsEditable()
  RtcSessionDescription get remoteDescription => wrap_jso(_blink.BlinkRTCPeerConnection.instance.remoteDescription_Getter_(unwrap_jso(this)));
  
  @DomName('RTCPeerConnection.signalingState')
  @DocsEditable()
  String get signalingState => _blink.BlinkRTCPeerConnection.instance.signalingState_Getter_(unwrap_jso(this));
  
  @DomName('RTCPeerConnection.addIceCandidate')
  @DocsEditable()
  void addIceCandidate(RtcIceCandidate candidate, VoidCallback successCallback, _RtcErrorCallback failureCallback) => _blink.BlinkRTCPeerConnection.instance.addIceCandidate_Callback_3_(unwrap_jso(this), unwrap_jso(candidate), unwrap_jso(() => successCallback()), unwrap_jso((errorInformation) => failureCallback(errorInformation)));
  
  void addStream(MediaStream stream, [Map mediaConstraints]) {
    if (mediaConstraints != null) {
      _blink.BlinkRTCPeerConnection.instance.addStream_Callback_2_(unwrap_jso(this), unwrap_jso(stream), convertDartToNative_Dictionary(mediaConstraints));
      return;
    }
    _blink.BlinkRTCPeerConnection.instance.addStream_Callback_1_(unwrap_jso(this), unwrap_jso(stream));
    return;
  }

  @DomName('RTCPeerConnection.close')
  @DocsEditable()
  void close() => _blink.BlinkRTCPeerConnection.instance.close_Callback_0_(unwrap_jso(this));
  
  void _createAnswer(_RtcSessionDescriptionCallback successCallback, [_RtcErrorCallback failureCallback, Map mediaConstraints]) {
    if (mediaConstraints != null) {
      _blink.BlinkRTCPeerConnection.instance.createAnswer_Callback_3_(unwrap_jso(this), unwrap_jso((sdp) => successCallback(wrap_jso(sdp))), unwrap_jso((errorInformation) => failureCallback(errorInformation)), convertDartToNative_Dictionary(mediaConstraints));
      return;
    }
    _blink.BlinkRTCPeerConnection.instance.createAnswer_Callback_2_(unwrap_jso(this), unwrap_jso((sdp) => successCallback(wrap_jso(sdp))), unwrap_jso((errorInformation) => failureCallback(errorInformation)));
    return;
  }

  @DomName('RTCPeerConnection.createDTMFSender')
  @DocsEditable()
  RtcDtmfSender createDtmfSender(MediaStreamTrack track) => wrap_jso(_blink.BlinkRTCPeerConnection.instance.createDTMFSender_Callback_1_(unwrap_jso(this), unwrap_jso(track)));
  
  RtcDataChannel createDataChannel(String label, [Map options]) {
    if (options != null) {
      return wrap_jso(_blink.BlinkRTCPeerConnection.instance.createDataChannel_Callback_2_(unwrap_jso(this), label, convertDartToNative_Dictionary(options)));
    }
    return wrap_jso(_blink.BlinkRTCPeerConnection.instance.createDataChannel_Callback_1_(unwrap_jso(this), label));
  }

  void _createOffer(_RtcSessionDescriptionCallback successCallback, [_RtcErrorCallback failureCallback, Map rtcOfferOptions]) {
    if (rtcOfferOptions != null) {
      _blink.BlinkRTCPeerConnection.instance.createOffer_Callback_3_(unwrap_jso(this), unwrap_jso((sdp) => successCallback(wrap_jso(sdp))), unwrap_jso((errorInformation) => failureCallback(errorInformation)), convertDartToNative_Dictionary(rtcOfferOptions));
      return;
    }
    _blink.BlinkRTCPeerConnection.instance.createOffer_Callback_2_(unwrap_jso(this), unwrap_jso((sdp) => successCallback(wrap_jso(sdp))), unwrap_jso((errorInformation) => failureCallback(errorInformation)));
    return;
  }

  @DomName('RTCPeerConnection.getLocalStreams')
  @DocsEditable()
  List<MediaStream> getLocalStreams() => wrap_jso(_blink.BlinkRTCPeerConnection.instance.getLocalStreams_Callback_0_(unwrap_jso(this)));
  
  @DomName('RTCPeerConnection.getRemoteStreams')
  @DocsEditable()
  List<MediaStream> getRemoteStreams() => wrap_jso(_blink.BlinkRTCPeerConnection.instance.getRemoteStreams_Callback_0_(unwrap_jso(this)));
  
  @DomName('RTCPeerConnection.getStats')
  @DocsEditable()
  void _getStats(RtcStatsCallback successCallback, MediaStreamTrack selector) => _blink.BlinkRTCPeerConnection.instance.getStats_Callback_2_(unwrap_jso(this), unwrap_jso((response) => successCallback(wrap_jso(response))), unwrap_jso(selector));
  
  @DomName('RTCPeerConnection.getStreamById')
  @DocsEditable()
  MediaStream getStreamById(String streamId) => wrap_jso(_blink.BlinkRTCPeerConnection.instance.getStreamById_Callback_1_(unwrap_jso(this), streamId));
  
  @DomName('RTCPeerConnection.removeStream')
  @DocsEditable()
  void removeStream(MediaStream stream) => _blink.BlinkRTCPeerConnection.instance.removeStream_Callback_1_(unwrap_jso(this), unwrap_jso(stream));
  
  @DomName('RTCPeerConnection.setLocalDescription')
  @DocsEditable()
  void _setLocalDescription(RtcSessionDescription description, [VoidCallback successCallback, _RtcErrorCallback failureCallback]) => _blink.BlinkRTCPeerConnection.instance.setLocalDescription_Callback_3_(unwrap_jso(this), unwrap_jso(description), unwrap_jso(() => successCallback()), unwrap_jso((errorInformation) => failureCallback(errorInformation)));
  
  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_(unwrap_jso(this), unwrap_jso(description), unwrap_jso(() => successCallback()), unwrap_jso((errorInformation) => failureCallback(errorInformation)));
  
  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_(unwrap_jso(this), convertDartToNative_Dictionary(configuration), convertDartToNative_Dictionary(mediaConstraints));
      return;
    }
    if (configuration != null) {
      _blink.BlinkRTCPeerConnection.instance.updateIce_Callback_1_(unwrap_jso(this), convertDartToNative_Dictionary(configuration));
      return;
    }
    _blink.BlinkRTCPeerConnection.instance.updateIce_Callback_0_(unwrap_jso(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 wrap_jso(_blink.BlinkRTCSessionDescription.instance.constructorCallback_1_(descriptionInitDict_1));
    }
    return wrap_jso(_blink.BlinkRTCSessionDescription.instance.constructorCallback_0_());
  }

  @Deprecated("Internal Use Only")
  static RtcSessionDescription internalCreateRtcSessionDescription() {
    return new RtcSessionDescription._internalWrap();
  }

  factory RtcSessionDescription._internalWrap() {
    return new RtcSessionDescription.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  @DomName('RTCSessionDescription.sdp')
  @DocsEditable()
  String get sdp => _blink.BlinkRTCSessionDescription.instance.sdp_Getter_(unwrap_jso(this));
  
  @DomName('RTCSessionDescription.sdp')
  @DocsEditable()
  set sdp(String value) => _blink.BlinkRTCSessionDescription.instance.sdp_Setter_(unwrap_jso(this), value);
  
  @DomName('RTCSessionDescription.type')
  @DocsEditable()
  String get type => _blink.BlinkRTCSessionDescription.instance.type_Getter_(unwrap_jso(this));
  
  @DomName('RTCSessionDescription.type')
  @DocsEditable()
  set type(String value) => _blink.BlinkRTCSessionDescription.instance.type_Setter_(unwrap_jso(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")
  static RtcStatsReport internalCreateRtcStatsReport() {
    return new RtcStatsReport._internalWrap();
  }

  factory RtcStatsReport._internalWrap() {
    return new RtcStatsReport.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  @DomName('RTCStatsReport.id')
  @DocsEditable()
  String get id => _blink.BlinkRTCStatsReport.instance.id_Getter_(unwrap_jso(this));
  
  @DomName('RTCStatsReport.timestamp')
  @DocsEditable()
  DateTime get timestamp => _blink.BlinkRTCStatsReport.instance.timestamp_Getter_(unwrap_jso(this));
  
  @DomName('RTCStatsReport.type')
  @DocsEditable()
  String get type => _blink.BlinkRTCStatsReport.instance.type_Getter_(unwrap_jso(this));
  
  @DomName('RTCStatsReport.names')
  @DocsEditable()
  List<String> names() => _blink.BlinkRTCStatsReport.instance.names_Callback_0_(unwrap_jso(this));
  
  @DomName('RTCStatsReport.stat')
  @DocsEditable()
  String stat(String name) => _blink.BlinkRTCStatsReport.instance.stat_Callback_1_(unwrap_jso(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")
  static RtcStatsResponse internalCreateRtcStatsResponse() {
    return new RtcStatsResponse._internalWrap();
  }

  factory RtcStatsResponse._internalWrap() {
    return new RtcStatsResponse.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  RtcStatsReport namedItem(String name) {
    if ((name is String || name == null)) {
      return wrap_jso(_blink.BlinkRTCStatsResponse.instance.namedItem_Callback_1_(unwrap_jso(this), name));
    }
    if ((name is String || name == null)) {
      return wrap_jso(_blink.BlinkRTCStatsResponse.instance.namedItem_Callback_1_(unwrap_jso(this), name));
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }

  @DomName('RTCStatsResponse.result')
  @DocsEditable()
  List<RtcStatsReport> result() => wrap_jso(_blink.BlinkRTCStatsResponse.instance.result_Callback_0_(unwrap_jso(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")
  static Screen internalCreateScreen() {
    return new Screen._internalWrap();
  }

  factory Screen._internalWrap() {
    return new Screen.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  @DomName('Screen.availHeight')
  @DocsEditable()
  int get _availHeight => _blink.BlinkScreen.instance.availHeight_Getter_(unwrap_jso(this));
  
  @DomName('Screen.availLeft')
  @DocsEditable()
  @Experimental() // nonstandard
  int get _availLeft => _blink.BlinkScreen.instance.availLeft_Getter_(unwrap_jso(this));
  
  @DomName('Screen.availTop')
  @DocsEditable()
  @Experimental() // nonstandard
  int get _availTop => _blink.BlinkScreen.instance.availTop_Getter_(unwrap_jso(this));
  
  @DomName('Screen.availWidth')
  @DocsEditable()
  int get _availWidth => _blink.BlinkScreen.instance.availWidth_Getter_(unwrap_jso(this));
  
  @DomName('Screen.colorDepth')
  @DocsEditable()
  int get colorDepth => _blink.BlinkScreen.instance.colorDepth_Getter_(unwrap_jso(this));
  
  @DomName('Screen.height')
  @DocsEditable()
  int get height => _blink.BlinkScreen.instance.height_Getter_(unwrap_jso(this));
  
  @DomName('Screen.orientation')
  @DocsEditable()
  @Experimental() // untriaged
  ScreenOrientation get orientation => wrap_jso(_blink.BlinkScreen.instance.orientation_Getter_(unwrap_jso(this)));
  
  @DomName('Screen.pixelDepth')
  @DocsEditable()
  int get pixelDepth => _blink.BlinkScreen.instance.pixelDepth_Getter_(unwrap_jso(this));
  
  @DomName('Screen.width')
  @DocsEditable()
  int get width => _blink.BlinkScreen.instance.width_Getter_(unwrap_jso(this));
  }
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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")
  static ScreenOrientation internalCreateScreenOrientation() {
    return new ScreenOrientation._internalWrap();
  }

  external factory ScreenOrientation._internalWrap();

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


  @DomName('ScreenOrientation.angle')
  @DocsEditable()
  @Experimental() // untriaged
  int get angle => _blink.BlinkScreenOrientation.instance.angle_Getter_(unwrap_jso(this));
  
  @DomName('ScreenOrientation.type')
  @DocsEditable()
  @Experimental() // untriaged
  String get type => _blink.BlinkScreenOrientation.instance.type_Getter_(unwrap_jso(this));
  
  @DomName('ScreenOrientation.lock')
  @DocsEditable()
  @Experimental() // untriaged
  Future lock(String orientation) => wrap_jso(_blink.BlinkScreenOrientation.instance.lock_Callback_1_(unwrap_jso(this), orientation));
  
  @DomName('ScreenOrientation.unlock')
  @DocsEditable()
  @Experimental() // untriaged
  void unlock() => _blink.BlinkScreenOrientation.instance.unlock_Callback_0_(unwrap_jso(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")
  static ScriptElement internalCreateScriptElement() {
    return new ScriptElement._internalWrap();
  }

  external factory ScriptElement._internalWrap();

  @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_(unwrap_jso(this));
  
  @DomName('HTMLScriptElement.async')
  @DocsEditable()
  set async(bool value) => _blink.BlinkHTMLScriptElement.instance.async_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLScriptElement.charset')
  @DocsEditable()
  String get charset => _blink.BlinkHTMLScriptElement.instance.charset_Getter_(unwrap_jso(this));
  
  @DomName('HTMLScriptElement.charset')
  @DocsEditable()
  set charset(String value) => _blink.BlinkHTMLScriptElement.instance.charset_Setter_(unwrap_jso(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_(unwrap_jso(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_(unwrap_jso(this), value);
  
  @DomName('HTMLScriptElement.defer')
  @DocsEditable()
  bool get defer => _blink.BlinkHTMLScriptElement.instance.defer_Getter_(unwrap_jso(this));
  
  @DomName('HTMLScriptElement.defer')
  @DocsEditable()
  set defer(bool value) => _blink.BlinkHTMLScriptElement.instance.defer_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLScriptElement.integrity')
  @DocsEditable()
  @Experimental() // untriaged
  String get integrity => _blink.BlinkHTMLScriptElement.instance.integrity_Getter_(unwrap_jso(this));
  
  @DomName('HTMLScriptElement.integrity')
  @DocsEditable()
  @Experimental() // untriaged
  set integrity(String value) => _blink.BlinkHTMLScriptElement.instance.integrity_Setter_(unwrap_jso(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_(unwrap_jso(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_(unwrap_jso(this), value);
  
  @DomName('HTMLScriptElement.src')
  @DocsEditable()
  String get src => _blink.BlinkHTMLScriptElement.instance.src_Getter_(unwrap_jso(this));
  
  @DomName('HTMLScriptElement.src')
  @DocsEditable()
  set src(String value) => _blink.BlinkHTMLScriptElement.instance.src_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLScriptElement.type')
  @DocsEditable()
  String get type => _blink.BlinkHTMLScriptElement.instance.type_Getter_(unwrap_jso(this));
  
  @DomName('HTMLScriptElement.type')
  @DocsEditable()
  set type(String value) => _blink.BlinkHTMLScriptElement.instance.type_Setter_(unwrap_jso(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 wrap_jso(_blink.BlinkScrollState.instance.constructorCallback_8_(deltaX, deltaY, deltaGranularity, velocityX, velocityY, inInertialPhase, isBeginning, isEnding));
    }
    if (isBeginning != null) {
      return wrap_jso(_blink.BlinkScrollState.instance.constructorCallback_7_(deltaX, deltaY, deltaGranularity, velocityX, velocityY, inInertialPhase, isBeginning));
    }
    if (inInertialPhase != null) {
      return wrap_jso(_blink.BlinkScrollState.instance.constructorCallback_6_(deltaX, deltaY, deltaGranularity, velocityX, velocityY, inInertialPhase));
    }
    if (velocityY != null) {
      return wrap_jso(_blink.BlinkScrollState.instance.constructorCallback_5_(deltaX, deltaY, deltaGranularity, velocityX, velocityY));
    }
    if (velocityX != null) {
      return wrap_jso(_blink.BlinkScrollState.instance.constructorCallback_4_(deltaX, deltaY, deltaGranularity, velocityX));
    }
    if (deltaGranularity != null) {
      return wrap_jso(_blink.BlinkScrollState.instance.constructorCallback_3_(deltaX, deltaY, deltaGranularity));
    }
    if (deltaY != null) {
      return wrap_jso(_blink.BlinkScrollState.instance.constructorCallback_2_(deltaX, deltaY));
    }
    if (deltaX != null) {
      return wrap_jso(_blink.BlinkScrollState.instance.constructorCallback_1_(deltaX));
    }
    return wrap_jso(_blink.BlinkScrollState.instance.constructorCallback_0_());
  }

  @Deprecated("Internal Use Only")
  static ScrollState internalCreateScrollState() {
    return new ScrollState._internalWrap();
  }

  factory ScrollState._internalWrap() {
    return new ScrollState.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  @DomName('ScrollState.deltaGranularity')
  @DocsEditable()
  @Experimental() // untriaged
  num get deltaGranularity => _blink.BlinkScrollState.instance.deltaGranularity_Getter_(unwrap_jso(this));
  
  @DomName('ScrollState.deltaX')
  @DocsEditable()
  @Experimental() // untriaged
  num get deltaX => _blink.BlinkScrollState.instance.deltaX_Getter_(unwrap_jso(this));
  
  @DomName('ScrollState.deltaY')
  @DocsEditable()
  @Experimental() // untriaged
  num get deltaY => _blink.BlinkScrollState.instance.deltaY_Getter_(unwrap_jso(this));
  
  @DomName('ScrollState.fromUserInput')
  @DocsEditable()
  @Experimental() // untriaged
  bool get fromUserInput => _blink.BlinkScrollState.instance.fromUserInput_Getter_(unwrap_jso(this));
  
  @DomName('ScrollState.inInertialPhase')
  @DocsEditable()
  @Experimental() // untriaged
  bool get inInertialPhase => _blink.BlinkScrollState.instance.inInertialPhase_Getter_(unwrap_jso(this));
  
  @DomName('ScrollState.isBeginning')
  @DocsEditable()
  @Experimental() // untriaged
  bool get isBeginning => _blink.BlinkScrollState.instance.isBeginning_Getter_(unwrap_jso(this));
  
  @DomName('ScrollState.isEnding')
  @DocsEditable()
  @Experimental() // untriaged
  bool get isEnding => _blink.BlinkScrollState.instance.isEnding_Getter_(unwrap_jso(this));
  
  @DomName('ScrollState.shouldPropagate')
  @DocsEditable()
  @Experimental() // untriaged
  bool get shouldPropagate => _blink.BlinkScrollState.instance.shouldPropagate_Getter_(unwrap_jso(this));
  
  @DomName('ScrollState.velocityX')
  @DocsEditable()
  @Experimental() // untriaged
  num get velocityX => _blink.BlinkScrollState.instance.velocityX_Getter_(unwrap_jso(this));
  
  @DomName('ScrollState.velocityY')
  @DocsEditable()
  @Experimental() // untriaged
  num get velocityY => _blink.BlinkScrollState.instance.velocityY_Getter_(unwrap_jso(this));
  
  @DomName('ScrollState.consumeDelta')
  @DocsEditable()
  @Experimental() // untriaged
  void consumeDelta(num x, num y) => _blink.BlinkScrollState.instance.consumeDelta_Callback_2_(unwrap_jso(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 wrap_jso(_blink.BlinkSecurityPolicyViolationEvent.instance.constructorCallback_2_(type, eventInitDict_1));
    }
    return wrap_jso(_blink.BlinkSecurityPolicyViolationEvent.instance.constructorCallback_1_(type));
  }


  @Deprecated("Internal Use Only")
  static SecurityPolicyViolationEvent internalCreateSecurityPolicyViolationEvent() {
    return new SecurityPolicyViolationEvent._internalWrap();
  }

  external factory SecurityPolicyViolationEvent._internalWrap();

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


  @DomName('SecurityPolicyViolationEvent.blockedURI')
  @DocsEditable()
  String get blockedUri => _blink.BlinkSecurityPolicyViolationEvent.instance.blockedURI_Getter_(unwrap_jso(this));
  
  @DomName('SecurityPolicyViolationEvent.columnNumber')
  @DocsEditable()
  int get columnNumber => _blink.BlinkSecurityPolicyViolationEvent.instance.columnNumber_Getter_(unwrap_jso(this));
  
  @DomName('SecurityPolicyViolationEvent.documentURI')
  @DocsEditable()
  String get documentUri => _blink.BlinkSecurityPolicyViolationEvent.instance.documentURI_Getter_(unwrap_jso(this));
  
  @DomName('SecurityPolicyViolationEvent.effectiveDirective')
  @DocsEditable()
  String get effectiveDirective => _blink.BlinkSecurityPolicyViolationEvent.instance.effectiveDirective_Getter_(unwrap_jso(this));
  
  @DomName('SecurityPolicyViolationEvent.lineNumber')
  @DocsEditable()
  int get lineNumber => _blink.BlinkSecurityPolicyViolationEvent.instance.lineNumber_Getter_(unwrap_jso(this));
  
  @DomName('SecurityPolicyViolationEvent.originalPolicy')
  @DocsEditable()
  String get originalPolicy => _blink.BlinkSecurityPolicyViolationEvent.instance.originalPolicy_Getter_(unwrap_jso(this));
  
  @DomName('SecurityPolicyViolationEvent.referrer')
  @DocsEditable()
  String get referrer => _blink.BlinkSecurityPolicyViolationEvent.instance.referrer_Getter_(unwrap_jso(this));
  
  @DomName('SecurityPolicyViolationEvent.sourceFile')
  @DocsEditable()
  String get sourceFile => _blink.BlinkSecurityPolicyViolationEvent.instance.sourceFile_Getter_(unwrap_jso(this));
  
  @DomName('SecurityPolicyViolationEvent.statusCode')
  @DocsEditable()
  @Experimental() // untriaged
  int get statusCode => _blink.BlinkSecurityPolicyViolationEvent.instance.statusCode_Getter_(unwrap_jso(this));
  
  @DomName('SecurityPolicyViolationEvent.violatedDirective')
  @DocsEditable()
  String get violatedDirective => _blink.BlinkSecurityPolicyViolationEvent.instance.violatedDirective_Getter_(unwrap_jso(this));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for 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")
  static SelectElement internalCreateSelectElement() {
    return new SelectElement._internalWrap();
  }

  external factory SelectElement._internalWrap();

  @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_(unwrap_jso(this));
  
  @DomName('HTMLSelectElement.autofocus')
  @DocsEditable()
  set autofocus(bool value) => _blink.BlinkHTMLSelectElement.instance.autofocus_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLSelectElement.disabled')
  @DocsEditable()
  bool get disabled => _blink.BlinkHTMLSelectElement.instance.disabled_Getter_(unwrap_jso(this));
  
  @DomName('HTMLSelectElement.disabled')
  @DocsEditable()
  set disabled(bool value) => _blink.BlinkHTMLSelectElement.instance.disabled_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLSelectElement.form')
  @DocsEditable()
  FormElement get form => wrap_jso(_blink.BlinkHTMLSelectElement.instance.form_Getter_(unwrap_jso(this)));
  
  @DomName('HTMLSelectElement.labels')
  @DocsEditable()
  @Unstable()
  List<Node> get labels => wrap_jso(_blink.BlinkHTMLSelectElement.instance.labels_Getter_(unwrap_jso(this)));
  
  @DomName('HTMLSelectElement.length')
  @DocsEditable()
  int get length => _blink.BlinkHTMLSelectElement.instance.length_Getter_(unwrap_jso(this));
  
  @DomName('HTMLSelectElement.length')
  @DocsEditable()
  set length(int value) => _blink.BlinkHTMLSelectElement.instance.length_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLSelectElement.multiple')
  @DocsEditable()
  bool get multiple => _blink.BlinkHTMLSelectElement.instance.multiple_Getter_(unwrap_jso(this));
  
  @DomName('HTMLSelectElement.multiple')
  @DocsEditable()
  set multiple(bool value) => _blink.BlinkHTMLSelectElement.instance.multiple_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLSelectElement.name')
  @DocsEditable()
  String get name => _blink.BlinkHTMLSelectElement.instance.name_Getter_(unwrap_jso(this));
  
  @DomName('HTMLSelectElement.name')
  @DocsEditable()
  set name(String value) => _blink.BlinkHTMLSelectElement.instance.name_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLSelectElement.required')
  @DocsEditable()
  bool get required => _blink.BlinkHTMLSelectElement.instance.required_Getter_(unwrap_jso(this));
  
  @DomName('HTMLSelectElement.required')
  @DocsEditable()
  set required(bool value) => _blink.BlinkHTMLSelectElement.instance.required_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLSelectElement.selectedIndex')
  @DocsEditable()
  int get selectedIndex => _blink.BlinkHTMLSelectElement.instance.selectedIndex_Getter_(unwrap_jso(this));
  
  @DomName('HTMLSelectElement.selectedIndex')
  @DocsEditable()
  set selectedIndex(int value) => _blink.BlinkHTMLSelectElement.instance.selectedIndex_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLSelectElement.size')
  @DocsEditable()
  int get size => _blink.BlinkHTMLSelectElement.instance.size_Getter_(unwrap_jso(this));
  
  @DomName('HTMLSelectElement.size')
  @DocsEditable()
  set size(int value) => _blink.BlinkHTMLSelectElement.instance.size_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLSelectElement.type')
  @DocsEditable()
  String get type => _blink.BlinkHTMLSelectElement.instance.type_Getter_(unwrap_jso(this));
  
  @DomName('HTMLSelectElement.validationMessage')
  @DocsEditable()
  String get validationMessage => _blink.BlinkHTMLSelectElement.instance.validationMessage_Getter_(unwrap_jso(this));
  
  @DomName('HTMLSelectElement.validity')
  @DocsEditable()
  ValidityState get validity => wrap_jso(_blink.BlinkHTMLSelectElement.instance.validity_Getter_(unwrap_jso(this)));
  
  @DomName('HTMLSelectElement.value')
  @DocsEditable()
  String get value => _blink.BlinkHTMLSelectElement.instance.value_Getter_(unwrap_jso(this));
  
  @DomName('HTMLSelectElement.value')
  @DocsEditable()
  set value(String value) => _blink.BlinkHTMLSelectElement.instance.value_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLSelectElement.willValidate')
  @DocsEditable()
  bool get willValidate => _blink.BlinkHTMLSelectElement.instance.willValidate_Getter_(unwrap_jso(this));
  
  @DomName('HTMLSelectElement.__setter__')
  @DocsEditable()
  void __setter__(int index, OptionElement option) => _blink.BlinkHTMLSelectElement.instance.$__setter___Callback_2_(unwrap_jso(this), index, unwrap_jso(option));
  
  @DomName('HTMLSelectElement.add')
  @DocsEditable()
  @Experimental() // untriaged
  void add(Object element, Object before) => _blink.BlinkHTMLSelectElement.instance.add_Callback_2_(unwrap_jso(this), element, before);
  
  @DomName('HTMLSelectElement.checkValidity')
  @DocsEditable()
  bool checkValidity() => _blink.BlinkHTMLSelectElement.instance.checkValidity_Callback_0_(unwrap_jso(this));
  
  @DomName('HTMLSelectElement.item')
  @DocsEditable()
  Element item(int index) => wrap_jso(_blink.BlinkHTMLSelectElement.instance.item_Callback_1_(unwrap_jso(this), index));
  
  @DomName('HTMLSelectElement.namedItem')
  @DocsEditable()
  OptionElement namedItem(String name) => wrap_jso(_blink.BlinkHTMLSelectElement.instance.namedItem_Callback_1_(unwrap_jso(this), name));
  
  @DomName('HTMLSelectElement.reportValidity')
  @DocsEditable()
  @Experimental() // untriaged
  bool reportValidity() => _blink.BlinkHTMLSelectElement.instance.reportValidity_Callback_0_(unwrap_jso(this));
  
  @DomName('HTMLSelectElement.setCustomValidity')
  @DocsEditable()
  void setCustomValidity(String error) => _blink.BlinkHTMLSelectElement.instance.setCustomValidity_Callback_1_(unwrap_jso(this), error);
  

  // Override default options, since IE returns SelectElement itself and it
  // does not operate as a List.
  List<OptionElement> get options {
    var options = this.querySelectorAll('option').where(
        (e) => e is OptionElement).toList();
    return new UnmodifiableListView(options);
  }

  List<OptionElement> get selectedOptions {
    // IE does not change the selected flag for single-selection items.
    if (this.multiple) {
      var options = this.options.where((o) => o.selected).toList();
      return new UnmodifiableListView(options);
    } else {
      return [this.options[this.selectedIndex]];
    }
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.


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

  @Deprecated("Internal Use Only")
  static Selection internalCreateSelection() {
    return new Selection._internalWrap();
  }

  factory Selection._internalWrap() {
    return new Selection.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  @DomName('Selection.anchorNode')
  @DocsEditable()
  Node get anchorNode => wrap_jso(_blink.BlinkSelection.instance.anchorNode_Getter_(unwrap_jso(this)));
  
  @DomName('Selection.anchorOffset')
  @DocsEditable()
  int get anchorOffset => _blink.BlinkSelection.instance.anchorOffset_Getter_(unwrap_jso(this));
  
  @DomName('Selection.baseNode')
  @DocsEditable()
  @Experimental() // non-standard
  Node get baseNode => wrap_jso(_blink.BlinkSelection.instance.baseNode_Getter_(unwrap_jso(this)));
  
  @DomName('Selection.baseOffset')
  @DocsEditable()
  @Experimental() // non-standard
  int get baseOffset => _blink.BlinkSelection.instance.baseOffset_Getter_(unwrap_jso(this));
  
  @DomName('Selection.extentNode')
  @DocsEditable()
  @Experimental() // non-standard
  Node get extentNode => wrap_jso(_blink.BlinkSelection.instance.extentNode_Getter_(unwrap_jso(this)));
  
  @DomName('Selection.extentOffset')
  @DocsEditable()
  @Experimental() // non-standard
  int get extentOffset => _blink.BlinkSelection.instance.extentOffset_Getter_(unwrap_jso(this));
  
  @DomName('Selection.focusNode')
  @DocsEditable()
  Node get focusNode => wrap_jso(_blink.BlinkSelection.instance.focusNode_Getter_(unwrap_jso(this)));
  
  @DomName('Selection.focusOffset')
  @DocsEditable()
  int get focusOffset => _blink.BlinkSelection.instance.focusOffset_Getter_(unwrap_jso(this));
  
  @DomName('Selection.isCollapsed')
  @DocsEditable()
  bool get isCollapsed => _blink.BlinkSelection.instance.isCollapsed_Getter_(unwrap_jso(this));
  
  @DomName('Selection.rangeCount')
  @DocsEditable()
  int get rangeCount => _blink.BlinkSelection.instance.rangeCount_Getter_(unwrap_jso(this));
  
  @DomName('Selection.type')
  @DocsEditable()
  @Experimental() // non-standard
  String get type => _blink.BlinkSelection.instance.type_Getter_(unwrap_jso(this));
  
  @DomName('Selection.addRange')
  @DocsEditable()
  void addRange(Range range) => _blink.BlinkSelection.instance.addRange_Callback_1_(unwrap_jso(this), unwrap_jso(range));
  
  void collapse(Node node, [int offset]) {
    if (offset != null) {
      _blink.BlinkSelection.instance.collapse_Callback_2_(unwrap_jso(this), unwrap_jso(node), offset);
      return;
    }
    _blink.BlinkSelection.instance.collapse_Callback_1_(unwrap_jso(this), unwrap_jso(node));
    return;
  }

  @DomName('Selection.collapseToEnd')
  @DocsEditable()
  void collapseToEnd() => _blink.BlinkSelection.instance.collapseToEnd_Callback_0_(unwrap_jso(this));
  
  @DomName('Selection.collapseToStart')
  @DocsEditable()
  void collapseToStart() => _blink.BlinkSelection.instance.collapseToStart_Callback_0_(unwrap_jso(this));
  
  @DomName('Selection.containsNode')
  @DocsEditable()
  @Experimental() // non-standard
  bool containsNode(Node node, bool allowPartialContainment) => _blink.BlinkSelection.instance.containsNode_Callback_2_(unwrap_jso(this), unwrap_jso(node), allowPartialContainment);
  
  @DomName('Selection.deleteFromDocument')
  @DocsEditable()
  void deleteFromDocument() => _blink.BlinkSelection.instance.deleteFromDocument_Callback_0_(unwrap_jso(this));
  
  @DomName('Selection.empty')
  @DocsEditable()
  @Experimental() // non-standard
  void empty() => _blink.BlinkSelection.instance.empty_Callback_0_(unwrap_jso(this));
  
  void extend(Node node, [int offset]) {
    if (offset != null) {
      _blink.BlinkSelection.instance.extend_Callback_2_(unwrap_jso(this), unwrap_jso(node), offset);
      return;
    }
    _blink.BlinkSelection.instance.extend_Callback_1_(unwrap_jso(this), unwrap_jso(node));
    return;
  }

  @DomName('Selection.getRangeAt')
  @DocsEditable()
  Range getRangeAt(int index) => wrap_jso(_blink.BlinkSelection.instance.getRangeAt_Callback_1_(unwrap_jso(this), index));
  
  @DomName('Selection.modify')
  @DocsEditable()
  @Experimental() // non-standard
  void modify(String alter, String direction, String granularity) => _blink.BlinkSelection.instance.modify_Callback_3_(unwrap_jso(this), alter, direction, granularity);
  
  @DomName('Selection.removeAllRanges')
  @DocsEditable()
  void removeAllRanges() => _blink.BlinkSelection.instance.removeAllRanges_Callback_0_(unwrap_jso(this));
  
  @DomName('Selection.selectAllChildren')
  @DocsEditable()
  void selectAllChildren(Node node) => _blink.BlinkSelection.instance.selectAllChildren_Callback_1_(unwrap_jso(this), unwrap_jso(node));
  
  @DomName('Selection.setBaseAndExtent')
  @DocsEditable()
  @Experimental() // non-standard
  void setBaseAndExtent(Node baseNode, int baseOffset, Node extentNode, int extentOffset) => _blink.BlinkSelection.instance.setBaseAndExtent_Callback_4_(unwrap_jso(this), unwrap_jso(baseNode), baseOffset, unwrap_jso(extentNode), extentOffset);
  
  void setPosition(Node node, [int offset]) {
    if (offset != null) {
      _blink.BlinkSelection.instance.setPosition_Callback_2_(unwrap_jso(this), unwrap_jso(node), offset);
      return;
    }
    _blink.BlinkSelection.instance.setPosition_Callback_1_(unwrap_jso(this), unwrap_jso(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")
  static ServicePort internalCreateServicePort() {
    return new ServicePort._internalWrap();
  }

  factory ServicePort._internalWrap() {
    return new ServicePort.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  @DomName('ServicePort.data')
  @DocsEditable()
  @Experimental() // untriaged
  Object get data => wrap_jso(_blink.BlinkServicePort.instance.data_Getter_(unwrap_jso(this)));
  
  @DomName('ServicePort.name')
  @DocsEditable()
  @Experimental() // untriaged
  String get name => _blink.BlinkServicePort.instance.name_Getter_(unwrap_jso(this));
  
  @DomName('ServicePort.targetURL')
  @DocsEditable()
  @Experimental() // untriaged
  String get targetUrl => _blink.BlinkServicePort.instance.targetURL_Getter_(unwrap_jso(this));
  
  @DomName('ServicePort.close')
  @DocsEditable()
  @Experimental() // untriaged
  void close() => _blink.BlinkServicePort.instance.close_Callback_0_(unwrap_jso(this));
  
  void postMessage(/*SerializedScriptValue*/ message, [List<MessagePort> transfer]) {
    if (transfer != null) {
      _blink.BlinkServicePort.instance.postMessage_Callback_2_(unwrap_jso(this), convertDartToNative_SerializedScriptValue(message), transfer);
      return;
    }
    _blink.BlinkServicePort.instance.postMessage_Callback_1_(unwrap_jso(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")
  static ServicePortCollection internalCreateServicePortCollection() {
    return new ServicePortCollection._internalWrap();
  }

  external factory ServicePortCollection._internalWrap();

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


  Future connect(String url, [Map options]) {
    if (options != null) {
      return wrap_jso(_blink.BlinkServicePortCollection.instance.connect_Callback_2_(unwrap_jso(this), url, convertDartToNative_Dictionary(options)));
    }
    return wrap_jso(_blink.BlinkServicePortCollection.instance.connect_Callback_1_(unwrap_jso(this), url));
  }

  @DomName('ServicePortCollection.match')
  @DocsEditable()
  @Experimental() // untriaged
  Future match(Map options) => wrap_jso(_blink.BlinkServicePortCollection.instance.match_Callback_1_(unwrap_jso(this), convertDartToNative_Dictionary(options)));
  
  Future matchAll([Map options]) {
    if (options != null) {
      return wrap_jso(_blink.BlinkServicePortCollection.instance.matchAll_Callback_1_(unwrap_jso(this), convertDartToNative_Dictionary(options)));
    }
    return wrap_jso(_blink.BlinkServicePortCollection.instance.matchAll_Callback_0_(unwrap_jso(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 wrap_jso(_blink.BlinkServicePortConnectEvent.instance.constructorCallback_2_(type, eventInitDict_1));
    }
    return wrap_jso(_blink.BlinkServicePortConnectEvent.instance.constructorCallback_1_(type));
  }


  @Deprecated("Internal Use Only")
  static ServicePortConnectEvent internalCreateServicePortConnectEvent() {
    return new ServicePortConnectEvent._internalWrap();
  }

  external factory ServicePortConnectEvent._internalWrap();

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


  @DomName('ServicePortConnectEvent.origin')
  @DocsEditable()
  @Experimental() // untriaged
  String get origin => _blink.BlinkServicePortConnectEvent.instance.origin_Getter_(unwrap_jso(this));
  
  @DomName('ServicePortConnectEvent.targetURL')
  @DocsEditable()
  @Experimental() // untriaged
  String get targetUrl => _blink.BlinkServicePortConnectEvent.instance.targetURL_Getter_(unwrap_jso(this));
  
  @DomName('ServicePortConnectEvent.respondWith')
  @DocsEditable()
  @Experimental() // untriaged
  Future respondWith(Future response) => wrap_jso(_blink.BlinkServicePortConnectEvent.instance.respondWith_Callback_1_(unwrap_jso(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")
  static ServiceWorkerContainer internalCreateServiceWorkerContainer() {
    return new ServiceWorkerContainer._internalWrap();
  }

  external factory ServiceWorkerContainer._internalWrap();

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


  @DomName('ServiceWorkerContainer.controller')
  @DocsEditable()
  @Experimental() // untriaged
  _ServiceWorker get controller => wrap_jso(_blink.BlinkServiceWorkerContainer.instance.controller_Getter_(unwrap_jso(this)));
  
  @DomName('ServiceWorkerContainer.ready')
  @DocsEditable()
  @Experimental() // untriaged
  Future get ready => wrap_jso(_blink.BlinkServiceWorkerContainer.instance.ready_Getter_(unwrap_jso(this)));
  
  Future getRegistration([String documentURL]) {
    if (documentURL != null) {
      return wrap_jso(_blink.BlinkServiceWorkerContainer.instance.getRegistration_Callback_1_(unwrap_jso(this), documentURL));
    }
    return wrap_jso(_blink.BlinkServiceWorkerContainer.instance.getRegistration_Callback_0_(unwrap_jso(this)));
  }

  @DomName('ServiceWorkerContainer.getRegistrations')
  @DocsEditable()
  @Experimental() // untriaged
  Future getRegistrations() => wrap_jso(_blink.BlinkServiceWorkerContainer.instance.getRegistrations_Callback_0_(unwrap_jso(this)));
  
  Future register(String url, [Map options]) {
    if (options != null) {
      return wrap_jso(_blink.BlinkServiceWorkerContainer.instance.register_Callback_2_(unwrap_jso(this), url, convertDartToNative_Dictionary(options)));
    }
    return wrap_jso(_blink.BlinkServiceWorkerContainer.instance.register_Callback_1_(unwrap_jso(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")
  static ServiceWorkerGlobalScope internalCreateServiceWorkerGlobalScope() {
    return new ServiceWorkerGlobalScope._internalWrap();
  }

  external factory ServiceWorkerGlobalScope._internalWrap();

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


  @DomName('ServiceWorkerGlobalScope.clients')
  @DocsEditable()
  @Experimental() // untriaged
  Clients get clients => wrap_jso(_blink.BlinkServiceWorkerGlobalScope.instance.clients_Getter_(unwrap_jso(this)));
  
  @DomName('ServiceWorkerGlobalScope.ports')
  @DocsEditable()
  @Experimental() // untriaged
  StashedPortCollection get ports => wrap_jso(_blink.BlinkServiceWorkerGlobalScope.instance.ports_Getter_(unwrap_jso(this)));
  
  @DomName('ServiceWorkerGlobalScope.registration')
  @DocsEditable()
  @Experimental() // untriaged
  ServiceWorkerRegistration get registration => wrap_jso(_blink.BlinkServiceWorkerGlobalScope.instance.registration_Getter_(unwrap_jso(this)));
  
  @DomName('ServiceWorkerGlobalScope.close')
  @DocsEditable()
  @Experimental() // untriaged
  void close() => _blink.BlinkServiceWorkerGlobalScope.instance.close_Callback_0_(unwrap_jso(this));
  
  Future _fetch(/*RequestInfo*/ input, [Map init]) {
    if (init != null) {
      return wrap_jso(_blink.BlinkServiceWorkerGlobalScope.instance.fetch_Callback_2_(unwrap_jso(this), input, convertDartToNative_Dictionary(init)));
    }
    return wrap_jso(_blink.BlinkServiceWorkerGlobalScope.instance.fetch_Callback_1_(unwrap_jso(this), input));
  }

  @DomName('ServiceWorkerGlobalScope.skipWaiting')
  @DocsEditable()
  @Experimental() // untriaged
  Future skipWaiting() => wrap_jso(_blink.BlinkServiceWorkerGlobalScope.instance.skipWaiting_Callback_0_(unwrap_jso(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_(unwrap_jso(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 wrap_jso(_blink.BlinkServiceWorkerMessageEvent.instance.constructorCallback_2_(type, eventInitDict_1));
    }
    return wrap_jso(_blink.BlinkServiceWorkerMessageEvent.instance.constructorCallback_1_(type));
  }


  @Deprecated("Internal Use Only")
  static ServiceWorkerMessageEvent internalCreateServiceWorkerMessageEvent() {
    return new ServiceWorkerMessageEvent._internalWrap();
  }

  external factory ServiceWorkerMessageEvent._internalWrap();

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


  @DomName('ServiceWorkerMessageEvent.lastEventId')
  @DocsEditable()
  @Experimental() // untriaged
  String get lastEventId => _blink.BlinkServiceWorkerMessageEvent.instance.lastEventId_Getter_(unwrap_jso(this));
  
  @DomName('ServiceWorkerMessageEvent.origin')
  @DocsEditable()
  @Experimental() // untriaged
  String get origin => _blink.BlinkServiceWorkerMessageEvent.instance.origin_Getter_(unwrap_jso(this));
  
  @DomName('ServiceWorkerMessageEvent.ports')
  @DocsEditable()
  @Experimental() // untriaged
  List<MessagePort> get ports => wrap_jso(_blink.BlinkServiceWorkerMessageEvent.instance.ports_Getter_(unwrap_jso(this)));
  
  @DomName('ServiceWorkerMessageEvent.source')
  @DocsEditable()
  @Experimental() // untriaged
  Object get source => wrap_jso(_blink.BlinkServiceWorkerMessageEvent.instance.source_Getter_(unwrap_jso(this)));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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")
  static ServiceWorkerRegistration internalCreateServiceWorkerRegistration() {
    return new ServiceWorkerRegistration._internalWrap();
  }

  external factory ServiceWorkerRegistration._internalWrap();

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


  @DomName('ServiceWorkerRegistration.active')
  @DocsEditable()
  @Experimental() // untriaged
  _ServiceWorker get active => wrap_jso(_blink.BlinkServiceWorkerRegistration.instance.active_Getter_(unwrap_jso(this)));
  
  @DomName('ServiceWorkerRegistration.geofencing')
  @DocsEditable()
  @Experimental() // untriaged
  Geofencing get geofencing => wrap_jso(_blink.BlinkServiceWorkerRegistration.instance.geofencing_Getter_(unwrap_jso(this)));
  
  @DomName('ServiceWorkerRegistration.installing')
  @DocsEditable()
  @Experimental() // untriaged
  _ServiceWorker get installing => wrap_jso(_blink.BlinkServiceWorkerRegistration.instance.installing_Getter_(unwrap_jso(this)));
  
  @DomName('ServiceWorkerRegistration.periodicSync')
  @DocsEditable()
  @Experimental() // untriaged
  PeriodicSyncManager get periodicSync => wrap_jso(_blink.BlinkServiceWorkerRegistration.instance.periodicSync_Getter_(unwrap_jso(this)));
  
  @DomName('ServiceWorkerRegistration.pushManager')
  @DocsEditable()
  @Experimental() // untriaged
  PushManager get pushManager => wrap_jso(_blink.BlinkServiceWorkerRegistration.instance.pushManager_Getter_(unwrap_jso(this)));
  
  @DomName('ServiceWorkerRegistration.scope')
  @DocsEditable()
  @Experimental() // untriaged
  String get scope => _blink.BlinkServiceWorkerRegistration.instance.scope_Getter_(unwrap_jso(this));
  
  @DomName('ServiceWorkerRegistration.sync')
  @DocsEditable()
  @Experimental() // untriaged
  SyncManager get sync => wrap_jso(_blink.BlinkServiceWorkerRegistration.instance.sync_Getter_(unwrap_jso(this)));
  
  @DomName('ServiceWorkerRegistration.waiting')
  @DocsEditable()
  @Experimental() // untriaged
  _ServiceWorker get waiting => wrap_jso(_blink.BlinkServiceWorkerRegistration.instance.waiting_Getter_(unwrap_jso(this)));
  
  Future getNotifications([Map filter]) {
    if (filter != null) {
      return wrap_jso(_blink.BlinkServiceWorkerRegistration.instance.getNotifications_Callback_1_(unwrap_jso(this), convertDartToNative_Dictionary(filter)));
    }
    return wrap_jso(_blink.BlinkServiceWorkerRegistration.instance.getNotifications_Callback_0_(unwrap_jso(this)));
  }

  Future showNotification(String title, [Map options]) {
    if (options != null) {
      return wrap_jso(_blink.BlinkServiceWorkerRegistration.instance.showNotification_Callback_2_(unwrap_jso(this), title, convertDartToNative_Dictionary(options)));
    }
    return wrap_jso(_blink.BlinkServiceWorkerRegistration.instance.showNotification_Callback_1_(unwrap_jso(this), title));
  }

  @DomName('ServiceWorkerRegistration.unregister')
  @DocsEditable()
  @Experimental() // untriaged
  Future unregister() => wrap_jso(_blink.BlinkServiceWorkerRegistration.instance.unregister_Callback_0_(unwrap_jso(this)));
  
  @DomName('ServiceWorkerRegistration.update')
  @DocsEditable()
  @Experimental() // untriaged
  void update() => _blink.BlinkServiceWorkerRegistration.instance.update_Callback_0_(unwrap_jso(this));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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")
  static ShadowElement internalCreateShadowElement() {
    return new ShadowElement._internalWrap();
  }

  external factory ShadowElement._internalWrap();

  @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() => wrap_jso(_blink.BlinkHTMLShadowElement.instance.getDistributedNodes_Callback_0_(unwrap_jso(this)));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of 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")
  static ShadowRoot internalCreateShadowRoot() {
    return new ShadowRoot._internalWrap();
  }

  external factory ShadowRoot._internalWrap();

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


  @DomName('ShadowRoot.activeElement')
  @DocsEditable()
  Element get activeElement => wrap_jso(_blink.BlinkShadowRoot.instance.activeElement_Getter_(unwrap_jso(this)));
  
  @DomName('ShadowRoot.delegatesFocus')
  @DocsEditable()
  @Experimental() // untriaged
  bool get delegatesFocus => _blink.BlinkShadowRoot.instance.delegatesFocus_Getter_(unwrap_jso(this));
  
  @DomName('ShadowRoot.host')
  @DocsEditable()
  @Experimental() // untriaged
  Element get host => wrap_jso(_blink.BlinkShadowRoot.instance.host_Getter_(unwrap_jso(this)));
  
  @DomName('ShadowRoot.innerHTML')
  @DocsEditable()
  String get innerHtml => _blink.BlinkShadowRoot.instance.innerHTML_Getter_(unwrap_jso(this));
  
  @DomName('ShadowRoot.innerHTML')
  @DocsEditable()
  set innerHtml(String value) => _blink.BlinkShadowRoot.instance.innerHTML_Setter_(unwrap_jso(this), value);
  
  @DomName('ShadowRoot.olderShadowRoot')
  @DocsEditable()
  @Experimental() // untriaged
  ShadowRoot get olderShadowRoot => wrap_jso(_blink.BlinkShadowRoot.instance.olderShadowRoot_Getter_(unwrap_jso(this)));
  
  @DomName('ShadowRoot.styleSheets')
  @DocsEditable()
  @Experimental() // untriaged
  List<StyleSheet> get styleSheets => wrap_jso(_blink.BlinkShadowRoot.instance.styleSheets_Getter_(unwrap_jso(this)));
  
  @DomName('ShadowRoot.cloneNode')
  @DocsEditable()
  Node clone(bool deep) => wrap_jso(_blink.BlinkShadowRoot.instance.cloneNode_Callback_1_(unwrap_jso(this), deep));
  
  @DomName('ShadowRoot.elementFromPoint')
  @DocsEditable()
  Element elementFromPoint(int x, int y) => wrap_jso(_blink.BlinkShadowRoot.instance.elementFromPoint_Callback_2_(unwrap_jso(this), x, y));
  
  @DomName('ShadowRoot.elementsFromPoint')
  @DocsEditable()
  @Experimental() // untriaged
  List<Element> elementsFromPoint(int x, int y) => wrap_jso(_blink.BlinkShadowRoot.instance.elementsFromPoint_Callback_2_(unwrap_jso(this), x, y));
  
  @DomName('ShadowRoot.getSelection')
  @DocsEditable()
  Selection getSelection() => wrap_jso(_blink.BlinkShadowRoot.instance.getSelection_Callback_0_(unwrap_jso(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")
  static SharedArrayBuffer internalCreateSharedArrayBuffer() {
    return new SharedArrayBuffer._internalWrap();
  }

  factory SharedArrayBuffer._internalWrap() {
    return new SharedArrayBuffer.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  @DomName('SharedArrayBuffer.byteLength')
  @DocsEditable()
  @Experimental() // untriaged
  int get byteLength => _blink.BlinkSharedArrayBuffer.instance.byteLength_Getter_(unwrap_jso(this));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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 wrap_jso(_blink.BlinkSharedWorker.instance.constructorCallback_2_(scriptURL, name));
  }


  @Deprecated("Internal Use Only")
  static SharedWorker internalCreateSharedWorker() {
    return new SharedWorker._internalWrap();
  }

  external factory SharedWorker._internalWrap();

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


  @DomName('SharedWorker.port')
  @DocsEditable()
  MessagePort get port => wrap_jso(_blink.BlinkSharedWorker.instance.port_Getter_(unwrap_jso(this)));
  
  @DomName('SharedWorker.workerStart')
  @DocsEditable()
  @Experimental() // untriaged
  num get workerStart => _blink.BlinkSharedWorker.instance.workerStart_Getter_(unwrap_jso(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")
  static SharedWorkerGlobalScope internalCreateSharedWorkerGlobalScope() {
    return new SharedWorkerGlobalScope._internalWrap();
  }

  external factory SharedWorkerGlobalScope._internalWrap();

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


  @DomName('SharedWorkerGlobalScope.name')
  @DocsEditable()
  @Experimental() // untriaged
  String get name => _blink.BlinkSharedWorkerGlobalScope.instance.name_Getter_(unwrap_jso(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")
  static SourceBuffer internalCreateSourceBuffer() {
    return new SourceBuffer._internalWrap();
  }

  external factory SourceBuffer._internalWrap();

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


  @DomName('SourceBuffer.appendWindowEnd')
  @DocsEditable()
  @Experimental() // untriaged
  num get appendWindowEnd => _blink.BlinkSourceBuffer.instance.appendWindowEnd_Getter_(unwrap_jso(this));
  
  @DomName('SourceBuffer.appendWindowEnd')
  @DocsEditable()
  @Experimental() // untriaged
  set appendWindowEnd(num value) => _blink.BlinkSourceBuffer.instance.appendWindowEnd_Setter_(unwrap_jso(this), value);
  
  @DomName('SourceBuffer.appendWindowStart')
  @DocsEditable()
  @Experimental() // untriaged
  num get appendWindowStart => _blink.BlinkSourceBuffer.instance.appendWindowStart_Getter_(unwrap_jso(this));
  
  @DomName('SourceBuffer.appendWindowStart')
  @DocsEditable()
  @Experimental() // untriaged
  set appendWindowStart(num value) => _blink.BlinkSourceBuffer.instance.appendWindowStart_Setter_(unwrap_jso(this), value);
  
  @DomName('SourceBuffer.buffered')
  @DocsEditable()
  TimeRanges get buffered => wrap_jso(_blink.BlinkSourceBuffer.instance.buffered_Getter_(unwrap_jso(this)));
  
  @DomName('SourceBuffer.mode')
  @DocsEditable()
  @Experimental() // untriaged
  String get mode => _blink.BlinkSourceBuffer.instance.mode_Getter_(unwrap_jso(this));
  
  @DomName('SourceBuffer.mode')
  @DocsEditable()
  @Experimental() // untriaged
  set mode(String value) => _blink.BlinkSourceBuffer.instance.mode_Setter_(unwrap_jso(this), value);
  
  @DomName('SourceBuffer.timestampOffset')
  @DocsEditable()
  num get timestampOffset => _blink.BlinkSourceBuffer.instance.timestampOffset_Getter_(unwrap_jso(this));
  
  @DomName('SourceBuffer.timestampOffset')
  @DocsEditable()
  set timestampOffset(num value) => _blink.BlinkSourceBuffer.instance.timestampOffset_Setter_(unwrap_jso(this), value);
  
  @DomName('SourceBuffer.trackDefaults')
  @DocsEditable()
  @Experimental() // untriaged
  TrackDefaultList get trackDefaults => wrap_jso(_blink.BlinkSourceBuffer.instance.trackDefaults_Getter_(unwrap_jso(this)));
  
  @DomName('SourceBuffer.trackDefaults')
  @DocsEditable()
  @Experimental() // untriaged
  set trackDefaults(TrackDefaultList value) => _blink.BlinkSourceBuffer.instance.trackDefaults_Setter_(unwrap_jso(this), unwrap_jso(value));
  
  @DomName('SourceBuffer.updating')
  @DocsEditable()
  @Experimental() // untriaged
  bool get updating => _blink.BlinkSourceBuffer.instance.updating_Getter_(unwrap_jso(this));
  
  @DomName('SourceBuffer.abort')
  @DocsEditable()
  void abort() => _blink.BlinkSourceBuffer.instance.abort_Callback_0_(unwrap_jso(this));
  
  @DomName('SourceBuffer.appendBuffer')
  @DocsEditable()
  @Experimental() // untriaged
  void appendBuffer(ByteBuffer data) => _blink.BlinkSourceBuffer.instance.appendBuffer_Callback_1_(unwrap_jso(this), unwrap_jso(data));
  
  void appendStream(FileStream stream, [int maxSize]) {
    if (maxSize != null) {
      _blink.BlinkSourceBuffer.instance.appendStream_Callback_2_(unwrap_jso(this), unwrap_jso(stream), maxSize);
      return;
    }
    _blink.BlinkSourceBuffer.instance.appendStream_Callback_1_(unwrap_jso(this), unwrap_jso(stream));
    return;
  }

  @DomName('SourceBuffer.appendTypedData')
  @DocsEditable()
  @Experimental() // untriaged
  void appendTypedData(TypedData data) => _blink.BlinkSourceBuffer.instance.appendBuffer_Callback_1_(unwrap_jso(this), unwrap_jso(data));
  
  @DomName('SourceBuffer.remove')
  @DocsEditable()
  @Experimental() // untriaged
  void remove(num start, num end) => _blink.BlinkSourceBuffer.instance.remove_Callback_2_(unwrap_jso(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")
  static SourceBufferList internalCreateSourceBufferList() {
    return new SourceBufferList._internalWrap();
  }

  external factory SourceBufferList._internalWrap();

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


  @DomName('SourceBufferList.length')
  @DocsEditable()
  int get length => _blink.BlinkSourceBufferList.instance.length_Getter_(unwrap_jso(this));
  
  SourceBuffer operator[](int index) {
    if (index < 0 || index >= length)
      throw new RangeError.index(index, this);
    return wrap_jso(_blink.BlinkSourceBufferList.instance.item_Callback_1_(unwrap_jso(this), index));
  }

  SourceBuffer _nativeIndexedGetter(int index) => wrap_jso(_blink.BlinkSourceBufferList.instance.item_Callback_1_(unwrap_jso(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) => wrap_jso(_blink.BlinkSourceBufferList.instance.item_Callback_1_(unwrap_jso(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")
  static SourceElement internalCreateSourceElement() {
    return new SourceElement._internalWrap();
  }

  external factory SourceElement._internalWrap();

  @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_(unwrap_jso(this));
  
  @DomName('HTMLSourceElement.media')
  @DocsEditable()
  set media(String value) => _blink.BlinkHTMLSourceElement.instance.media_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLSourceElement.sizes')
  @DocsEditable()
  @Experimental() // untriaged
  String get sizes => _blink.BlinkHTMLSourceElement.instance.sizes_Getter_(unwrap_jso(this));
  
  @DomName('HTMLSourceElement.sizes')
  @DocsEditable()
  @Experimental() // untriaged
  set sizes(String value) => _blink.BlinkHTMLSourceElement.instance.sizes_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLSourceElement.src')
  @DocsEditable()
  String get src => _blink.BlinkHTMLSourceElement.instance.src_Getter_(unwrap_jso(this));
  
  @DomName('HTMLSourceElement.src')
  @DocsEditable()
  set src(String value) => _blink.BlinkHTMLSourceElement.instance.src_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLSourceElement.srcset')
  @DocsEditable()
  @Experimental() // untriaged
  String get srcset => _blink.BlinkHTMLSourceElement.instance.srcset_Getter_(unwrap_jso(this));
  
  @DomName('HTMLSourceElement.srcset')
  @DocsEditable()
  @Experimental() // untriaged
  set srcset(String value) => _blink.BlinkHTMLSourceElement.instance.srcset_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLSourceElement.type')
  @DocsEditable()
  String get type => _blink.BlinkHTMLSourceElement.instance.type_Getter_(unwrap_jso(this));
  
  @DomName('HTMLSourceElement.type')
  @DocsEditable()
  set type(String value) => _blink.BlinkHTMLSourceElement.instance.type_Setter_(unwrap_jso(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")
  static SourceInfo internalCreateSourceInfo() {
    return new SourceInfo._internalWrap();
  }

  factory SourceInfo._internalWrap() {
    return new SourceInfo.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  @DomName('SourceInfo.facing')
  @DocsEditable()
  @Experimental() // untriaged
  String get facing => _blink.BlinkSourceInfo.instance.facing_Getter_(unwrap_jso(this));
  
  @DomName('SourceInfo.id')
  @DocsEditable()
  @Experimental() // untriaged
  String get id => _blink.BlinkSourceInfo.instance.id_Getter_(unwrap_jso(this));
  
  @DomName('SourceInfo.kind')
  @DocsEditable()
  @Experimental() // untriaged
  String get kind => _blink.BlinkSourceInfo.instance.kind_Getter_(unwrap_jso(this));
  
  @DomName('SourceInfo.label')
  @DocsEditable()
  @Experimental() // untriaged
  String get label => _blink.BlinkSourceInfo.instance.label_Getter_(unwrap_jso(this));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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")
  static SpanElement internalCreateSpanElement() {
    return new SpanElement._internalWrap();
  }

  external factory SpanElement._internalWrap();

  @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 wrap_jso(_blink.BlinkSpeechGrammar.instance.constructorCallback_0_());
  }

  @Deprecated("Internal Use Only")
  static SpeechGrammar internalCreateSpeechGrammar() {
    return new SpeechGrammar._internalWrap();
  }

  factory SpeechGrammar._internalWrap() {
    return new SpeechGrammar.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  @DomName('SpeechGrammar.src')
  @DocsEditable()
  String get src => _blink.BlinkSpeechGrammar.instance.src_Getter_(unwrap_jso(this));
  
  @DomName('SpeechGrammar.src')
  @DocsEditable()
  set src(String value) => _blink.BlinkSpeechGrammar.instance.src_Setter_(unwrap_jso(this), value);
  
  @DomName('SpeechGrammar.weight')
  @DocsEditable()
  num get weight => _blink.BlinkSpeechGrammar.instance.weight_Getter_(unwrap_jso(this));
  
  @DomName('SpeechGrammar.weight')
  @DocsEditable()
  set weight(num value) => _blink.BlinkSpeechGrammar.instance.weight_Setter_(unwrap_jso(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 wrap_jso(_blink.BlinkSpeechGrammarList.instance.constructorCallback_0_());
  }

  @Deprecated("Internal Use Only")
  static SpeechGrammarList internalCreateSpeechGrammarList() {
    return new SpeechGrammarList._internalWrap();
  }

  factory SpeechGrammarList._internalWrap() {
    return new SpeechGrammarList.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  @DomName('SpeechGrammarList.length')
  @DocsEditable()
  int get length => _blink.BlinkSpeechGrammarList.instance.length_Getter_(unwrap_jso(this));
  
  SpeechGrammar operator[](int index) {
    if (index < 0 || index >= length)
      throw new RangeError.index(index, this);
    return wrap_jso(_blink.BlinkSpeechGrammarList.instance.item_Callback_1_(unwrap_jso(this), index));
  }

  SpeechGrammar _nativeIndexedGetter(int index) => wrap_jso(_blink.BlinkSpeechGrammarList.instance.item_Callback_1_(unwrap_jso(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_(unwrap_jso(this), string, weight);
      return;
    }
    _blink.BlinkSpeechGrammarList.instance.addFromString_Callback_1_(unwrap_jso(this), string);
    return;
  }

  void addFromUri(String src, [num weight]) {
    if (weight != null) {
      _blink.BlinkSpeechGrammarList.instance.addFromUri_Callback_2_(unwrap_jso(this), src, weight);
      return;
    }
    _blink.BlinkSpeechGrammarList.instance.addFromUri_Callback_1_(unwrap_jso(this), src);
    return;
  }

  @DomName('SpeechGrammarList.item')
  @DocsEditable()
  SpeechGrammar item(int index) => wrap_jso(_blink.BlinkSpeechGrammarList.instance.item_Callback_1_(unwrap_jso(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 wrap_jso(_blink.BlinkSpeechRecognition.instance.constructorCallback_0_());
  }


  @Deprecated("Internal Use Only")
  static SpeechRecognition internalCreateSpeechRecognition() {
    return new SpeechRecognition._internalWrap();
  }

  external factory SpeechRecognition._internalWrap();

  @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 => wrap_jso(_blink.BlinkSpeechRecognition.instance.audioTrack_Getter_(unwrap_jso(this)));
  
  @DomName('SpeechRecognition.audioTrack')
  @DocsEditable()
  @Experimental() // untriaged
  set audioTrack(MediaStreamTrack value) => _blink.BlinkSpeechRecognition.instance.audioTrack_Setter_(unwrap_jso(this), unwrap_jso(value));
  
  @DomName('SpeechRecognition.continuous')
  @DocsEditable()
  bool get continuous => _blink.BlinkSpeechRecognition.instance.continuous_Getter_(unwrap_jso(this));
  
  @DomName('SpeechRecognition.continuous')
  @DocsEditable()
  set continuous(bool value) => _blink.BlinkSpeechRecognition.instance.continuous_Setter_(unwrap_jso(this), value);
  
  @DomName('SpeechRecognition.grammars')
  @DocsEditable()
  SpeechGrammarList get grammars => wrap_jso(_blink.BlinkSpeechRecognition.instance.grammars_Getter_(unwrap_jso(this)));
  
  @DomName('SpeechRecognition.grammars')
  @DocsEditable()
  set grammars(SpeechGrammarList value) => _blink.BlinkSpeechRecognition.instance.grammars_Setter_(unwrap_jso(this), unwrap_jso(value));
  
  @DomName('SpeechRecognition.interimResults')
  @DocsEditable()
  bool get interimResults => _blink.BlinkSpeechRecognition.instance.interimResults_Getter_(unwrap_jso(this));
  
  @DomName('SpeechRecognition.interimResults')
  @DocsEditable()
  set interimResults(bool value) => _blink.BlinkSpeechRecognition.instance.interimResults_Setter_(unwrap_jso(this), value);
  
  @DomName('SpeechRecognition.lang')
  @DocsEditable()
  String get lang => _blink.BlinkSpeechRecognition.instance.lang_Getter_(unwrap_jso(this));
  
  @DomName('SpeechRecognition.lang')
  @DocsEditable()
  set lang(String value) => _blink.BlinkSpeechRecognition.instance.lang_Setter_(unwrap_jso(this), value);
  
  @DomName('SpeechRecognition.maxAlternatives')
  @DocsEditable()
  int get maxAlternatives => _blink.BlinkSpeechRecognition.instance.maxAlternatives_Getter_(unwrap_jso(this));
  
  @DomName('SpeechRecognition.maxAlternatives')
  @DocsEditable()
  set maxAlternatives(int value) => _blink.BlinkSpeechRecognition.instance.maxAlternatives_Setter_(unwrap_jso(this), value);
  
  @DomName('SpeechRecognition.serviceURI')
  @DocsEditable()
  @Experimental() // untriaged
  String get serviceUri => _blink.BlinkSpeechRecognition.instance.serviceURI_Getter_(unwrap_jso(this));
  
  @DomName('SpeechRecognition.serviceURI')
  @DocsEditable()
  @Experimental() // untriaged
  set serviceUri(String value) => _blink.BlinkSpeechRecognition.instance.serviceURI_Setter_(unwrap_jso(this), value);
  
  @DomName('SpeechRecognition.abort')
  @DocsEditable()
  void abort() => _blink.BlinkSpeechRecognition.instance.abort_Callback_0_(unwrap_jso(this));
  
  @DomName('SpeechRecognition.start')
  @DocsEditable()
  void start() => _blink.BlinkSpeechRecognition.instance.start_Callback_0_(unwrap_jso(this));
  
  @DomName('SpeechRecognition.stop')
  @DocsEditable()
  void stop() => _blink.BlinkSpeechRecognition.instance.stop_Callback_0_(unwrap_jso(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")
  static SpeechRecognitionAlternative internalCreateSpeechRecognitionAlternative() {
    return new SpeechRecognitionAlternative._internalWrap();
  }

  factory SpeechRecognitionAlternative._internalWrap() {
    return new SpeechRecognitionAlternative.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  @DomName('SpeechRecognitionAlternative.confidence')
  @DocsEditable()
  num get confidence => _blink.BlinkSpeechRecognitionAlternative.instance.confidence_Getter_(unwrap_jso(this));
  
  @DomName('SpeechRecognitionAlternative.transcript')
  @DocsEditable()
  String get transcript => _blink.BlinkSpeechRecognitionAlternative.instance.transcript_Getter_(unwrap_jso(this));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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 wrap_jso(_blink.BlinkSpeechRecognitionError.instance.constructorCallback_2_(type, initDict_1));
    }
    return wrap_jso(_blink.BlinkSpeechRecognitionError.instance.constructorCallback_1_(type));
  }


  @Deprecated("Internal Use Only")
  static SpeechRecognitionError internalCreateSpeechRecognitionError() {
    return new SpeechRecognitionError._internalWrap();
  }

  external factory SpeechRecognitionError._internalWrap();

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


  @DomName('SpeechRecognitionError.error')
  @DocsEditable()
  String get error => _blink.BlinkSpeechRecognitionError.instance.error_Getter_(unwrap_jso(this));
  
  @DomName('SpeechRecognitionError.message')
  @DocsEditable()
  String get message => _blink.BlinkSpeechRecognitionError.instance.message_Getter_(unwrap_jso(this));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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 wrap_jso(_blink.BlinkSpeechRecognitionEvent.instance.constructorCallback_2_(type, initDict_1));
    }
    return wrap_jso(_blink.BlinkSpeechRecognitionEvent.instance.constructorCallback_1_(type));
  }


  @Deprecated("Internal Use Only")
  static SpeechRecognitionEvent internalCreateSpeechRecognitionEvent() {
    return new SpeechRecognitionEvent._internalWrap();
  }

  external factory SpeechRecognitionEvent._internalWrap();

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


  @DomName('SpeechRecognitionEvent.emma')
  @DocsEditable()
  Document get emma => wrap_jso(_blink.BlinkSpeechRecognitionEvent.instance.emma_Getter_(unwrap_jso(this)));
  
  @DomName('SpeechRecognitionEvent.interpretation')
  @DocsEditable()
  Document get interpretation => wrap_jso(_blink.BlinkSpeechRecognitionEvent.instance.interpretation_Getter_(unwrap_jso(this)));
  
  @DomName('SpeechRecognitionEvent.resultIndex')
  @DocsEditable()
  int get resultIndex => _blink.BlinkSpeechRecognitionEvent.instance.resultIndex_Getter_(unwrap_jso(this));
  
  @DomName('SpeechRecognitionEvent.results')
  @DocsEditable()
  List<SpeechRecognitionResult> get results => wrap_jso(_blink.BlinkSpeechRecognitionEvent.instance.results_Getter_(unwrap_jso(this)));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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")
  static SpeechRecognitionResult internalCreateSpeechRecognitionResult() {
    return new SpeechRecognitionResult._internalWrap();
  }

  factory SpeechRecognitionResult._internalWrap() {
    return new SpeechRecognitionResult.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  @DomName('SpeechRecognitionResult.isFinal')
  @DocsEditable()
  bool get isFinal => _blink.BlinkSpeechRecognitionResult.instance.isFinal_Getter_(unwrap_jso(this));
  
  @DomName('SpeechRecognitionResult.length')
  @DocsEditable()
  int get length => _blink.BlinkSpeechRecognitionResult.instance.length_Getter_(unwrap_jso(this));
  
  @DomName('SpeechRecognitionResult.item')
  @DocsEditable()
  SpeechRecognitionAlternative item(int index) => wrap_jso(_blink.BlinkSpeechRecognitionResult.instance.item_Callback_1_(unwrap_jso(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")
  static SpeechSynthesis internalCreateSpeechSynthesis() {
    return new SpeechSynthesis._internalWrap();
  }

  external factory SpeechSynthesis._internalWrap();

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


  @DomName('SpeechSynthesis.paused')
  @DocsEditable()
  bool get paused => _blink.BlinkSpeechSynthesis.instance.paused_Getter_(unwrap_jso(this));
  
  @DomName('SpeechSynthesis.pending')
  @DocsEditable()
  bool get pending => _blink.BlinkSpeechSynthesis.instance.pending_Getter_(unwrap_jso(this));
  
  @DomName('SpeechSynthesis.speaking')
  @DocsEditable()
  bool get speaking => _blink.BlinkSpeechSynthesis.instance.speaking_Getter_(unwrap_jso(this));
  
  @DomName('SpeechSynthesis.cancel')
  @DocsEditable()
  void cancel() => _blink.BlinkSpeechSynthesis.instance.cancel_Callback_0_(unwrap_jso(this));
  
  @DomName('SpeechSynthesis.getVoices')
  @DocsEditable()
  List<SpeechSynthesisVoice> getVoices() => wrap_jso(_blink.BlinkSpeechSynthesis.instance.getVoices_Callback_0_(unwrap_jso(this)));
  
  @DomName('SpeechSynthesis.pause')
  @DocsEditable()
  void pause() => _blink.BlinkSpeechSynthesis.instance.pause_Callback_0_(unwrap_jso(this));
  
  @DomName('SpeechSynthesis.resume')
  @DocsEditable()
  void resume() => _blink.BlinkSpeechSynthesis.instance.resume_Callback_0_(unwrap_jso(this));
  
  @DomName('SpeechSynthesis.speak')
  @DocsEditable()
  void speak(SpeechSynthesisUtterance utterance) => _blink.BlinkSpeechSynthesis.instance.speak_Callback_1_(unwrap_jso(this), unwrap_jso(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")
  static SpeechSynthesisEvent internalCreateSpeechSynthesisEvent() {
    return new SpeechSynthesisEvent._internalWrap();
  }

  external factory SpeechSynthesisEvent._internalWrap();

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


  @DomName('SpeechSynthesisEvent.charIndex')
  @DocsEditable()
  int get charIndex => _blink.BlinkSpeechSynthesisEvent.instance.charIndex_Getter_(unwrap_jso(this));
  
  @DomName('SpeechSynthesisEvent.elapsedTime')
  @DocsEditable()
  num get elapsedTime => _blink.BlinkSpeechSynthesisEvent.instance.elapsedTime_Getter_(unwrap_jso(this));
  
  @DomName('SpeechSynthesisEvent.name')
  @DocsEditable()
  String get name => _blink.BlinkSpeechSynthesisEvent.instance.name_Getter_(unwrap_jso(this));
  
  @DomName('SpeechSynthesisEvent.utterance')
  @DocsEditable()
  @Experimental() // untriaged
  SpeechSynthesisUtterance get utterance => wrap_jso(_blink.BlinkSpeechSynthesisEvent.instance.utterance_Getter_(unwrap_jso(this)));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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 wrap_jso(_blink.BlinkSpeechSynthesisUtterance.instance.constructorCallback_1_(text));
  }


  @Deprecated("Internal Use Only")
  static SpeechSynthesisUtterance internalCreateSpeechSynthesisUtterance() {
    return new SpeechSynthesisUtterance._internalWrap();
  }

  external factory SpeechSynthesisUtterance._internalWrap();

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


  @DomName('SpeechSynthesisUtterance.lang')
  @DocsEditable()
  String get lang => _blink.BlinkSpeechSynthesisUtterance.instance.lang_Getter_(unwrap_jso(this));
  
  @DomName('SpeechSynthesisUtterance.lang')
  @DocsEditable()
  set lang(String value) => _blink.BlinkSpeechSynthesisUtterance.instance.lang_Setter_(unwrap_jso(this), value);
  
  @DomName('SpeechSynthesisUtterance.pitch')
  @DocsEditable()
  num get pitch => _blink.BlinkSpeechSynthesisUtterance.instance.pitch_Getter_(unwrap_jso(this));
  
  @DomName('SpeechSynthesisUtterance.pitch')
  @DocsEditable()
  set pitch(num value) => _blink.BlinkSpeechSynthesisUtterance.instance.pitch_Setter_(unwrap_jso(this), value);
  
  @DomName('SpeechSynthesisUtterance.rate')
  @DocsEditable()
  num get rate => _blink.BlinkSpeechSynthesisUtterance.instance.rate_Getter_(unwrap_jso(this));
  
  @DomName('SpeechSynthesisUtterance.rate')
  @DocsEditable()
  set rate(num value) => _blink.BlinkSpeechSynthesisUtterance.instance.rate_Setter_(unwrap_jso(this), value);
  
  @DomName('SpeechSynthesisUtterance.text')
  @DocsEditable()
  String get text => _blink.BlinkSpeechSynthesisUtterance.instance.text_Getter_(unwrap_jso(this));
  
  @DomName('SpeechSynthesisUtterance.text')
  @DocsEditable()
  set text(String value) => _blink.BlinkSpeechSynthesisUtterance.instance.text_Setter_(unwrap_jso(this), value);
  
  @DomName('SpeechSynthesisUtterance.voice')
  @DocsEditable()
  SpeechSynthesisVoice get voice => wrap_jso(_blink.BlinkSpeechSynthesisUtterance.instance.voice_Getter_(unwrap_jso(this)));
  
  @DomName('SpeechSynthesisUtterance.voice')
  @DocsEditable()
  set voice(SpeechSynthesisVoice value) => _blink.BlinkSpeechSynthesisUtterance.instance.voice_Setter_(unwrap_jso(this), unwrap_jso(value));
  
  @DomName('SpeechSynthesisUtterance.volume')
  @DocsEditable()
  num get volume => _blink.BlinkSpeechSynthesisUtterance.instance.volume_Getter_(unwrap_jso(this));
  
  @DomName('SpeechSynthesisUtterance.volume')
  @DocsEditable()
  set volume(num value) => _blink.BlinkSpeechSynthesisUtterance.instance.volume_Setter_(unwrap_jso(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")
  static SpeechSynthesisVoice internalCreateSpeechSynthesisVoice() {
    return new SpeechSynthesisVoice._internalWrap();
  }

  factory SpeechSynthesisVoice._internalWrap() {
    return new SpeechSynthesisVoice.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  @DomName('SpeechSynthesisVoice.default')
  @DocsEditable()
  bool get defaultValue => _blink.BlinkSpeechSynthesisVoice.instance.default_Getter_(unwrap_jso(this));
  
  @DomName('SpeechSynthesisVoice.lang')
  @DocsEditable()
  String get lang => _blink.BlinkSpeechSynthesisVoice.instance.lang_Getter_(unwrap_jso(this));
  
  @DomName('SpeechSynthesisVoice.localService')
  @DocsEditable()
  bool get localService => _blink.BlinkSpeechSynthesisVoice.instance.localService_Getter_(unwrap_jso(this));
  
  @DomName('SpeechSynthesisVoice.name')
  @DocsEditable()
  String get name => _blink.BlinkSpeechSynthesisVoice.instance.name_Getter_(unwrap_jso(this));
  
  @DomName('SpeechSynthesisVoice.voiceURI')
  @DocsEditable()
  String get voiceUri => _blink.BlinkSpeechSynthesisVoice.instance.voiceURI_Getter_(unwrap_jso(this));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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")
  static StashedMessagePort internalCreateStashedMessagePort() {
    return new StashedMessagePort._internalWrap();
  }

  external factory StashedMessagePort._internalWrap();

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


  @DomName('StashedMessagePort.name')
  @DocsEditable()
  @Experimental() // untriaged
  String get name => _blink.BlinkStashedMessagePort.instance.name_Getter_(unwrap_jso(this));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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")
  static StashedPortCollection internalCreateStashedPortCollection() {
    return new StashedPortCollection._internalWrap();
  }

  external factory StashedPortCollection._internalWrap();

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


  @DomName('StashedPortCollection.add')
  @DocsEditable()
  @Experimental() // untriaged
  StashedMessagePort add(String name, MessagePort port) => wrap_jso(_blink.BlinkStashedPortCollection.instance.add_Callback_2_(unwrap_jso(this), name, unwrap_jso(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(String value) => values.any((e) => e == value);

  bool containsKey(String key) => _getItem(key) != null;

  String operator [](String key) => _getItem(key);

  void operator []=(String key, String value) { _setItem(key, value); }

  String putIfAbsent(String key, String ifAbsent()) {
    if (!containsKey(key)) this[key] = ifAbsent();
    return this[key];
  }

  String remove(String key) {
    final value = this[key];
    _removeItem(key);
    return value;
  }

  void clear() => _clear();

  void forEach(void f(String key, String value)) {
    for (var i = 0; true; i++) {
      final key = _key(i);
      if (key == null) return;

      f(key, this[key]);
    }
  }

  Iterable<String> get keys {
    final keys = [];
    forEach((k, v) => keys.add(k));
    return keys;
  }

  Iterable<String> get values {
    final values = [];
    forEach((k, v) => values.add(v));
    return values;
  }

  int get length => _length;

  bool get isEmpty => _key(0) == null;

  bool get isNotEmpty => !isEmpty;
  // To suppress missing implicit constructor warnings.
  factory Storage._() { throw new UnsupportedError("Not supported"); }

  @Deprecated("Internal Use Only")
  static Storage internalCreateStorage() {
    return new Storage._internalWrap();
  }

  factory Storage._internalWrap() {
    return new Storage.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  @DomName('Storage.length')
  @DocsEditable()
  int get _length => _blink.BlinkStorage.instance.length_Getter_(unwrap_jso(this));
  
  bool __delete__(index_OR_name) {
    if ((index_OR_name is int || index_OR_name == null)) {
      return _blink.BlinkStorage.instance.$__delete___Callback_1_(unwrap_jso(this), unwrap_jso(index_OR_name));
    }
    if ((index_OR_name is String || index_OR_name == null)) {
      return _blink.BlinkStorage.instance.$__delete___Callback_1_(unwrap_jso(this), unwrap_jso(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_(unwrap_jso(this), unwrap_jso(index_OR_name));
    }
    if ((index_OR_name is String || index_OR_name == null)) {
      return _blink.BlinkStorage.instance.$__getter___Callback_1_(unwrap_jso(this), unwrap_jso(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_(unwrap_jso(this), unwrap_jso(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_(unwrap_jso(this), unwrap_jso(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_(unwrap_jso(this));
  
  @DomName('Storage.getItem')
  @DocsEditable()
  String _getItem(String key) => _blink.BlinkStorage.instance.getItem_Callback_1_(unwrap_jso(this), key);
  
  @DomName('Storage.key')
  @DocsEditable()
  String _key(int index) => _blink.BlinkStorage.instance.key_Callback_1_(unwrap_jso(this), index);
  
  @DomName('Storage.removeItem')
  @DocsEditable()
  void _removeItem(String key) => _blink.BlinkStorage.instance.removeItem_Callback_1_(unwrap_jso(this), key);
  
  @DomName('Storage.setItem')
  @DocsEditable()
  void _setItem(String key, String data) => _blink.BlinkStorage.instance.setItem_Callback_2_(unwrap_jso(this), key, data);
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.


@DomName('StorageErrorCallback')
// http://www.w3.org/TR/quota-api/#storageerrorcallback-callback
@Experimental()
typedef void StorageErrorCallback(DomError error);
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.


@DomName('StorageEvent')
@Unstable()
class StorageEvent extends Event {
  factory StorageEvent(String type,
    {bool canBubble: false, bool cancelable: false, String key, String oldValue,
    String newValue, String url, Storage storageArea}) {

    var e = document._createEvent("StorageEvent");
    e._initStorageEvent(type, canBubble, cancelable, key, oldValue,
        newValue, url, storageArea);
    return e;
  }

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


  @Deprecated("Internal Use Only")
  static StorageEvent internalCreateStorageEvent() {
    return new StorageEvent._internalWrap();
  }

  external factory StorageEvent._internalWrap();

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


  @DomName('StorageEvent.key')
  @DocsEditable()
  String get key => _blink.BlinkStorageEvent.instance.key_Getter_(unwrap_jso(this));
  
  @DomName('StorageEvent.newValue')
  @DocsEditable()
  String get newValue => _blink.BlinkStorageEvent.instance.newValue_Getter_(unwrap_jso(this));
  
  @DomName('StorageEvent.oldValue')
  @DocsEditable()
  String get oldValue => _blink.BlinkStorageEvent.instance.oldValue_Getter_(unwrap_jso(this));
  
  @DomName('StorageEvent.storageArea')
  @DocsEditable()
  Storage get storageArea => wrap_jso(_blink.BlinkStorageEvent.instance.storageArea_Getter_(unwrap_jso(this)));
  
  @DomName('StorageEvent.url')
  @DocsEditable()
  String get url => _blink.BlinkStorageEvent.instance.url_Getter_(unwrap_jso(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_(unwrap_jso(this), typeArg, canBubbleArg, cancelableArg, keyArg, oldValueArg, newValueArg, urlArg, unwrap_jso(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")
  static StorageInfo internalCreateStorageInfo() {
    return new StorageInfo._internalWrap();
  }

  factory StorageInfo._internalWrap() {
    return new StorageInfo.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  @DomName('StorageInfo.quota')
  @DocsEditable()
  @Experimental() // untriaged
  int get quota => _blink.BlinkStorageInfo.instance.quota_Getter_(unwrap_jso(this));
  
  @DomName('StorageInfo.usage')
  @DocsEditable()
  @Experimental() // untriaged
  int get usage => _blink.BlinkStorageInfo.instance.usage_Getter_(unwrap_jso(this));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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")
  static StorageQuota internalCreateStorageQuota() {
    return new StorageQuota._internalWrap();
  }

  factory StorageQuota._internalWrap() {
    return new StorageQuota.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  @DomName('StorageQuota.supportedTypes')
  @DocsEditable()
  @Experimental() // untriaged
  List<String> get supportedTypes => wrap_jso(_blink.BlinkStorageQuota.instance.supportedTypes_Getter_(unwrap_jso(this)));
  
  @DomName('StorageQuota.queryInfo')
  @DocsEditable()
  @Experimental() // untriaged
  Future queryInfo(String type) => wrap_jso(_blink.BlinkStorageQuota.instance.queryInfo_Callback_1_(unwrap_jso(this), type));
  
  @DomName('StorageQuota.requestPersistentQuota')
  @DocsEditable()
  @Experimental() // untriaged
  Future requestPersistentQuota(int newQuota) => wrap_jso(_blink.BlinkStorageQuota.instance.requestPersistentQuota_Callback_1_(unwrap_jso(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")
  static StyleElement internalCreateStyleElement() {
    return new StyleElement._internalWrap();
  }

  external factory StyleElement._internalWrap();

  @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_(unwrap_jso(this));
  
  @DomName('HTMLStyleElement.disabled')
  @DocsEditable()
  set disabled(bool value) => _blink.BlinkHTMLStyleElement.instance.disabled_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLStyleElement.media')
  @DocsEditable()
  String get media => _blink.BlinkHTMLStyleElement.instance.media_Getter_(unwrap_jso(this));
  
  @DomName('HTMLStyleElement.media')
  @DocsEditable()
  set media(String value) => _blink.BlinkHTMLStyleElement.instance.media_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLStyleElement.sheet')
  @DocsEditable()
  StyleSheet get sheet => wrap_jso(_blink.BlinkHTMLStyleElement.instance.sheet_Getter_(unwrap_jso(this)));
  
  @DomName('HTMLStyleElement.type')
  @DocsEditable()
  String get type => _blink.BlinkHTMLStyleElement.instance.type_Getter_(unwrap_jso(this));
  
  @DomName('HTMLStyleElement.type')
  @DocsEditable()
  set type(String value) => _blink.BlinkHTMLStyleElement.instance.type_Setter_(unwrap_jso(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")
  static StyleMedia internalCreateStyleMedia() {
    return new StyleMedia._internalWrap();
  }

  factory StyleMedia._internalWrap() {
    return new StyleMedia.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  @DomName('StyleMedia.type')
  @DocsEditable()
  String get type => _blink.BlinkStyleMedia.instance.type_Getter_(unwrap_jso(this));
  
  @DomName('StyleMedia.matchMedium')
  @DocsEditable()
  bool matchMedium(String mediaquery) => _blink.BlinkStyleMedia.instance.matchMedium_Callback_1_(unwrap_jso(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")
  static StyleSheet internalCreateStyleSheet() {
    return new StyleSheet._internalWrap();
  }

  factory StyleSheet._internalWrap() {
    return new StyleSheet.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  @DomName('StyleSheet.disabled')
  @DocsEditable()
  bool get disabled => _blink.BlinkStyleSheet.instance.disabled_Getter_(unwrap_jso(this));
  
  @DomName('StyleSheet.disabled')
  @DocsEditable()
  set disabled(bool value) => _blink.BlinkStyleSheet.instance.disabled_Setter_(unwrap_jso(this), value);
  
  @DomName('StyleSheet.href')
  @DocsEditable()
  String get href => _blink.BlinkStyleSheet.instance.href_Getter_(unwrap_jso(this));
  
  @DomName('StyleSheet.media')
  @DocsEditable()
  MediaList get media => wrap_jso(_blink.BlinkStyleSheet.instance.media_Getter_(unwrap_jso(this)));
  
  @DomName('StyleSheet.ownerNode')
  @DocsEditable()
  Node get ownerNode => wrap_jso(_blink.BlinkStyleSheet.instance.ownerNode_Getter_(unwrap_jso(this)));
  
  @DomName('StyleSheet.parentStyleSheet')
  @DocsEditable()
  StyleSheet get parentStyleSheet => wrap_jso(_blink.BlinkStyleSheet.instance.parentStyleSheet_Getter_(unwrap_jso(this)));
  
  @DomName('StyleSheet.title')
  @DocsEditable()
  String get title => _blink.BlinkStyleSheet.instance.title_Getter_(unwrap_jso(this));
  
  @DomName('StyleSheet.type')
  @DocsEditable()
  String get type => _blink.BlinkStyleSheet.instance.type_Getter_(unwrap_jso(this));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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 wrap_jso(_blink.BlinkSyncEvent.instance.constructorCallback_2_(type, init_1));
  }


  @Deprecated("Internal Use Only")
  static SyncEvent internalCreateSyncEvent() {
    return new SyncEvent._internalWrap();
  }

  external factory SyncEvent._internalWrap();

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


  @DomName('SyncEvent.registration')
  @DocsEditable()
  @Experimental() // untriaged
  SyncRegistration get registration => wrap_jso(_blink.BlinkSyncEvent.instance.registration_Getter_(unwrap_jso(this)));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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")
  static SyncManager internalCreateSyncManager() {
    return new SyncManager._internalWrap();
  }

  factory SyncManager._internalWrap() {
    return new SyncManager.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  @DomName('SyncManager.getRegistration')
  @DocsEditable()
  @Experimental() // untriaged
  Future getRegistration(String tag) => wrap_jso(_blink.BlinkSyncManager.instance.getRegistration_Callback_1_(unwrap_jso(this), tag));
  
  @DomName('SyncManager.getRegistrations')
  @DocsEditable()
  @Experimental() // untriaged
  Future getRegistrations() => wrap_jso(_blink.BlinkSyncManager.instance.getRegistrations_Callback_0_(unwrap_jso(this)));
  
  @DomName('SyncManager.permissionState')
  @DocsEditable()
  @Experimental() // untriaged
  Future permissionState() => wrap_jso(_blink.BlinkSyncManager.instance.permissionState_Callback_0_(unwrap_jso(this)));
  
  Future register([Map options]) {
    if (options != null) {
      return wrap_jso(_blink.BlinkSyncManager.instance.register_Callback_1_(unwrap_jso(this), convertDartToNative_Dictionary(options)));
    }
    return wrap_jso(_blink.BlinkSyncManager.instance.register_Callback_0_(unwrap_jso(this)));
  }

}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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")
  static SyncRegistration internalCreateSyncRegistration() {
    return new SyncRegistration._internalWrap();
  }

  factory SyncRegistration._internalWrap() {
    return new SyncRegistration.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  @DomName('SyncRegistration.tag')
  @DocsEditable()
  @Experimental() // untriaged
  String get tag => _blink.BlinkSyncRegistration.instance.tag_Getter_(unwrap_jso(this));
  
  @DomName('SyncRegistration.unregister')
  @DocsEditable()
  @Experimental() // untriaged
  Future unregister() => wrap_jso(_blink.BlinkSyncRegistration.instance.unregister_Callback_0_(unwrap_jso(this)));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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")
  static TableCaptionElement internalCreateTableCaptionElement() {
    return new TableCaptionElement._internalWrap();
  }

  external factory TableCaptionElement._internalWrap();

  @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")
  static TableCellElement internalCreateTableCellElement() {
    return new TableCellElement._internalWrap();
  }

  external factory TableCellElement._internalWrap();

  @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_(unwrap_jso(this));
  
  @DomName('HTMLTableCellElement.colSpan')
  @DocsEditable()
  int get colSpan => _blink.BlinkHTMLTableCellElement.instance.colSpan_Getter_(unwrap_jso(this));
  
  @DomName('HTMLTableCellElement.colSpan')
  @DocsEditable()
  set colSpan(int value) => _blink.BlinkHTMLTableCellElement.instance.colSpan_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLTableCellElement.headers')
  @DocsEditable()
  String get headers => _blink.BlinkHTMLTableCellElement.instance.headers_Getter_(unwrap_jso(this));
  
  @DomName('HTMLTableCellElement.headers')
  @DocsEditable()
  set headers(String value) => _blink.BlinkHTMLTableCellElement.instance.headers_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLTableCellElement.rowSpan')
  @DocsEditable()
  int get rowSpan => _blink.BlinkHTMLTableCellElement.instance.rowSpan_Getter_(unwrap_jso(this));
  
  @DomName('HTMLTableCellElement.rowSpan')
  @DocsEditable()
  set rowSpan(int value) => _blink.BlinkHTMLTableCellElement.instance.rowSpan_Setter_(unwrap_jso(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")
  static TableColElement internalCreateTableColElement() {
    return new TableColElement._internalWrap();
  }

  external factory TableColElement._internalWrap();

  @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_(unwrap_jso(this));
  
  @DomName('HTMLTableColElement.span')
  @DocsEditable()
  set span(int value) => _blink.BlinkHTMLTableColElement.instance.span_Setter_(unwrap_jso(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")
  static TableElement internalCreateTableElement() {
    return new TableElement._internalWrap();
  }

  external factory TableElement._internalWrap();

  @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 => wrap_jso(_blink.BlinkHTMLTableElement.instance.caption_Getter_(unwrap_jso(this)));
  
  @DomName('HTMLTableElement.caption')
  @DocsEditable()
  set caption(TableCaptionElement value) => _blink.BlinkHTMLTableElement.instance.caption_Setter_(unwrap_jso(this), unwrap_jso(value));
  
  @DomName('HTMLTableElement.rows')
  @DocsEditable()
  List<Node> get _rows => wrap_jso(_blink.BlinkHTMLTableElement.instance.rows_Getter_(unwrap_jso(this)));
  
  @DomName('HTMLTableElement.tBodies')
  @DocsEditable()
  List<Node> get _tBodies => wrap_jso(_blink.BlinkHTMLTableElement.instance.tBodies_Getter_(unwrap_jso(this)));
  
  @DomName('HTMLTableElement.tFoot')
  @DocsEditable()
  TableSectionElement get tFoot => wrap_jso(_blink.BlinkHTMLTableElement.instance.tFoot_Getter_(unwrap_jso(this)));
  
  @DomName('HTMLTableElement.tFoot')
  @DocsEditable()
  set tFoot(TableSectionElement value) => _blink.BlinkHTMLTableElement.instance.tFoot_Setter_(unwrap_jso(this), unwrap_jso(value));
  
  @DomName('HTMLTableElement.tHead')
  @DocsEditable()
  TableSectionElement get tHead => wrap_jso(_blink.BlinkHTMLTableElement.instance.tHead_Getter_(unwrap_jso(this)));
  
  @DomName('HTMLTableElement.tHead')
  @DocsEditable()
  set tHead(TableSectionElement value) => _blink.BlinkHTMLTableElement.instance.tHead_Setter_(unwrap_jso(this), unwrap_jso(value));
  
  @DomName('HTMLTableElement.createCaption')
  @DocsEditable()
  HtmlElement _createCaption() => wrap_jso(_blink.BlinkHTMLTableElement.instance.createCaption_Callback_0_(unwrap_jso(this)));
  
  @DomName('HTMLTableElement.createTBody')
  @DocsEditable()
  HtmlElement _createTBody() => wrap_jso(_blink.BlinkHTMLTableElement.instance.createTBody_Callback_0_(unwrap_jso(this)));
  
  @DomName('HTMLTableElement.createTFoot')
  @DocsEditable()
  HtmlElement _createTFoot() => wrap_jso(_blink.BlinkHTMLTableElement.instance.createTFoot_Callback_0_(unwrap_jso(this)));
  
  @DomName('HTMLTableElement.createTHead')
  @DocsEditable()
  HtmlElement _createTHead() => wrap_jso(_blink.BlinkHTMLTableElement.instance.createTHead_Callback_0_(unwrap_jso(this)));
  
  @DomName('HTMLTableElement.deleteCaption')
  @DocsEditable()
  void deleteCaption() => _blink.BlinkHTMLTableElement.instance.deleteCaption_Callback_0_(unwrap_jso(this));
  
  @DomName('HTMLTableElement.deleteRow')
  @DocsEditable()
  void deleteRow(int index) => _blink.BlinkHTMLTableElement.instance.deleteRow_Callback_1_(unwrap_jso(this), index);
  
  @DomName('HTMLTableElement.deleteTFoot')
  @DocsEditable()
  void deleteTFoot() => _blink.BlinkHTMLTableElement.instance.deleteTFoot_Callback_0_(unwrap_jso(this));
  
  @DomName('HTMLTableElement.deleteTHead')
  @DocsEditable()
  void deleteTHead() => _blink.BlinkHTMLTableElement.instance.deleteTHead_Callback_0_(unwrap_jso(this));
  
  HtmlElement _insertRow([int index]) {
    if (index != null) {
      return wrap_jso(_blink.BlinkHTMLTableElement.instance.insertRow_Callback_1_(unwrap_jso(this), index));
    }
    return wrap_jso(_blink.BlinkHTMLTableElement.instance.insertRow_Callback_0_(unwrap_jso(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")
  static TableRowElement internalCreateTableRowElement() {
    return new TableRowElement._internalWrap();
  }

  external factory TableRowElement._internalWrap();

  @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 => wrap_jso(_blink.BlinkHTMLTableRowElement.instance.cells_Getter_(unwrap_jso(this)));
  
  @DomName('HTMLTableRowElement.rowIndex')
  @DocsEditable()
  int get rowIndex => _blink.BlinkHTMLTableRowElement.instance.rowIndex_Getter_(unwrap_jso(this));
  
  @DomName('HTMLTableRowElement.sectionRowIndex')
  @DocsEditable()
  int get sectionRowIndex => _blink.BlinkHTMLTableRowElement.instance.sectionRowIndex_Getter_(unwrap_jso(this));
  
  @DomName('HTMLTableRowElement.deleteCell')
  @DocsEditable()
  void deleteCell(int index) => _blink.BlinkHTMLTableRowElement.instance.deleteCell_Callback_1_(unwrap_jso(this), index);
  
  HtmlElement _insertCell([int index]) {
    if (index != null) {
      return wrap_jso(_blink.BlinkHTMLTableRowElement.instance.insertCell_Callback_1_(unwrap_jso(this), index));
    }
    return wrap_jso(_blink.BlinkHTMLTableRowElement.instance.insertCell_Callback_0_(unwrap_jso(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")
  static TableSectionElement internalCreateTableSectionElement() {
    return new TableSectionElement._internalWrap();
  }

  external factory TableSectionElement._internalWrap();

  @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 => wrap_jso(_blink.BlinkHTMLTableSectionElement.instance.rows_Getter_(unwrap_jso(this)));
  
  @DomName('HTMLTableSectionElement.deleteRow')
  @DocsEditable()
  void deleteRow(int index) => _blink.BlinkHTMLTableSectionElement.instance.deleteRow_Callback_1_(unwrap_jso(this), index);
  
  HtmlElement _insertRow([int index]) {
    if (index != null) {
      return wrap_jso(_blink.BlinkHTMLTableSectionElement.instance.insertRow_Callback_1_(unwrap_jso(this), index));
    }
    return wrap_jso(_blink.BlinkHTMLTableSectionElement.instance.insertRow_Callback_0_(unwrap_jso(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")
  static TemplateElement internalCreateTemplateElement() {
    return new TemplateElement._internalWrap();
  }

  external factory TemplateElement._internalWrap();

  @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 => wrap_jso(_blink.BlinkHTMLTemplateElement.instance.content_Getter_(unwrap_jso(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")
  static Text internalCreateText() {
    return new Text._internalWrap();
  }

  external factory Text._internalWrap();

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


  @DomName('Text.wholeText')
  @DocsEditable()
  String get wholeText => _blink.BlinkText.instance.wholeText_Getter_(unwrap_jso(this));
  
  @DomName('Text.getDestinationInsertionPoints')
  @DocsEditable()
  @Experimental() // untriaged
  List<Node> getDestinationInsertionPoints() => wrap_jso(_blink.BlinkText.instance.getDestinationInsertionPoints_Callback_0_(unwrap_jso(this)));
  
  @DomName('Text.splitText')
  @DocsEditable()
  Text splitText(int offset) => wrap_jso(_blink.BlinkText.instance.splitText_Callback_1_(unwrap_jso(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")
  static TextAreaElement internalCreateTextAreaElement() {
    return new TextAreaElement._internalWrap();
  }

  external factory TextAreaElement._internalWrap();

  @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_(unwrap_jso(this));
  
  @DomName('HTMLTextAreaElement.autocapitalize')
  @DocsEditable()
  @Experimental() // untriaged
  set autocapitalize(String value) => _blink.BlinkHTMLTextAreaElement.instance.autocapitalize_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLTextAreaElement.autofocus')
  @DocsEditable()
  bool get autofocus => _blink.BlinkHTMLTextAreaElement.instance.autofocus_Getter_(unwrap_jso(this));
  
  @DomName('HTMLTextAreaElement.autofocus')
  @DocsEditable()
  set autofocus(bool value) => _blink.BlinkHTMLTextAreaElement.instance.autofocus_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLTextAreaElement.cols')
  @DocsEditable()
  int get cols => _blink.BlinkHTMLTextAreaElement.instance.cols_Getter_(unwrap_jso(this));
  
  @DomName('HTMLTextAreaElement.cols')
  @DocsEditable()
  set cols(int value) => _blink.BlinkHTMLTextAreaElement.instance.cols_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLTextAreaElement.defaultValue')
  @DocsEditable()
  String get defaultValue => _blink.BlinkHTMLTextAreaElement.instance.defaultValue_Getter_(unwrap_jso(this));
  
  @DomName('HTMLTextAreaElement.defaultValue')
  @DocsEditable()
  set defaultValue(String value) => _blink.BlinkHTMLTextAreaElement.instance.defaultValue_Setter_(unwrap_jso(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_(unwrap_jso(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_(unwrap_jso(this), value);
  
  @DomName('HTMLTextAreaElement.disabled')
  @DocsEditable()
  bool get disabled => _blink.BlinkHTMLTextAreaElement.instance.disabled_Getter_(unwrap_jso(this));
  
  @DomName('HTMLTextAreaElement.disabled')
  @DocsEditable()
  set disabled(bool value) => _blink.BlinkHTMLTextAreaElement.instance.disabled_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLTextAreaElement.form')
  @DocsEditable()
  FormElement get form => wrap_jso(_blink.BlinkHTMLTextAreaElement.instance.form_Getter_(unwrap_jso(this)));
  
  @DomName('HTMLTextAreaElement.inputMode')
  @DocsEditable()
  @Experimental() // untriaged
  String get inputMode => _blink.BlinkHTMLTextAreaElement.instance.inputMode_Getter_(unwrap_jso(this));
  
  @DomName('HTMLTextAreaElement.inputMode')
  @DocsEditable()
  @Experimental() // untriaged
  set inputMode(String value) => _blink.BlinkHTMLTextAreaElement.instance.inputMode_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLTextAreaElement.labels')
  @DocsEditable()
  @Unstable()
  List<Node> get labels => wrap_jso(_blink.BlinkHTMLTextAreaElement.instance.labels_Getter_(unwrap_jso(this)));
  
  @DomName('HTMLTextAreaElement.maxLength')
  @DocsEditable()
  int get maxLength => _blink.BlinkHTMLTextAreaElement.instance.maxLength_Getter_(unwrap_jso(this));
  
  @DomName('HTMLTextAreaElement.maxLength')
  @DocsEditable()
  set maxLength(int value) => _blink.BlinkHTMLTextAreaElement.instance.maxLength_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLTextAreaElement.minLength')
  @DocsEditable()
  @Experimental() // untriaged
  int get minLength => _blink.BlinkHTMLTextAreaElement.instance.minLength_Getter_(unwrap_jso(this));
  
  @DomName('HTMLTextAreaElement.minLength')
  @DocsEditable()
  @Experimental() // untriaged
  set minLength(int value) => _blink.BlinkHTMLTextAreaElement.instance.minLength_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLTextAreaElement.name')
  @DocsEditable()
  String get name => _blink.BlinkHTMLTextAreaElement.instance.name_Getter_(unwrap_jso(this));
  
  @DomName('HTMLTextAreaElement.name')
  @DocsEditable()
  set name(String value) => _blink.BlinkHTMLTextAreaElement.instance.name_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLTextAreaElement.placeholder')
  @DocsEditable()
  String get placeholder => _blink.BlinkHTMLTextAreaElement.instance.placeholder_Getter_(unwrap_jso(this));
  
  @DomName('HTMLTextAreaElement.placeholder')
  @DocsEditable()
  set placeholder(String value) => _blink.BlinkHTMLTextAreaElement.instance.placeholder_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLTextAreaElement.readOnly')
  @DocsEditable()
  bool get readOnly => _blink.BlinkHTMLTextAreaElement.instance.readOnly_Getter_(unwrap_jso(this));
  
  @DomName('HTMLTextAreaElement.readOnly')
  @DocsEditable()
  set readOnly(bool value) => _blink.BlinkHTMLTextAreaElement.instance.readOnly_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLTextAreaElement.required')
  @DocsEditable()
  bool get required => _blink.BlinkHTMLTextAreaElement.instance.required_Getter_(unwrap_jso(this));
  
  @DomName('HTMLTextAreaElement.required')
  @DocsEditable()
  set required(bool value) => _blink.BlinkHTMLTextAreaElement.instance.required_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLTextAreaElement.rows')
  @DocsEditable()
  int get rows => _blink.BlinkHTMLTextAreaElement.instance.rows_Getter_(unwrap_jso(this));
  
  @DomName('HTMLTextAreaElement.rows')
  @DocsEditable()
  set rows(int value) => _blink.BlinkHTMLTextAreaElement.instance.rows_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLTextAreaElement.selectionDirection')
  @DocsEditable()
  String get selectionDirection => _blink.BlinkHTMLTextAreaElement.instance.selectionDirection_Getter_(unwrap_jso(this));
  
  @DomName('HTMLTextAreaElement.selectionDirection')
  @DocsEditable()
  set selectionDirection(String value) => _blink.BlinkHTMLTextAreaElement.instance.selectionDirection_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLTextAreaElement.selectionEnd')
  @DocsEditable()
  int get selectionEnd => _blink.BlinkHTMLTextAreaElement.instance.selectionEnd_Getter_(unwrap_jso(this));
  
  @DomName('HTMLTextAreaElement.selectionEnd')
  @DocsEditable()
  set selectionEnd(int value) => _blink.BlinkHTMLTextAreaElement.instance.selectionEnd_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLTextAreaElement.selectionStart')
  @DocsEditable()
  int get selectionStart => _blink.BlinkHTMLTextAreaElement.instance.selectionStart_Getter_(unwrap_jso(this));
  
  @DomName('HTMLTextAreaElement.selectionStart')
  @DocsEditable()
  set selectionStart(int value) => _blink.BlinkHTMLTextAreaElement.instance.selectionStart_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLTextAreaElement.textLength')
  @DocsEditable()
  int get textLength => _blink.BlinkHTMLTextAreaElement.instance.textLength_Getter_(unwrap_jso(this));
  
  @DomName('HTMLTextAreaElement.type')
  @DocsEditable()
  String get type => _blink.BlinkHTMLTextAreaElement.instance.type_Getter_(unwrap_jso(this));
  
  @DomName('HTMLTextAreaElement.validationMessage')
  @DocsEditable()
  String get validationMessage => _blink.BlinkHTMLTextAreaElement.instance.validationMessage_Getter_(unwrap_jso(this));
  
  @DomName('HTMLTextAreaElement.validity')
  @DocsEditable()
  ValidityState get validity => wrap_jso(_blink.BlinkHTMLTextAreaElement.instance.validity_Getter_(unwrap_jso(this)));
  
  @DomName('HTMLTextAreaElement.value')
  @DocsEditable()
  String get value => _blink.BlinkHTMLTextAreaElement.instance.value_Getter_(unwrap_jso(this));
  
  @DomName('HTMLTextAreaElement.value')
  @DocsEditable()
  set value(String value) => _blink.BlinkHTMLTextAreaElement.instance.value_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLTextAreaElement.willValidate')
  @DocsEditable()
  bool get willValidate => _blink.BlinkHTMLTextAreaElement.instance.willValidate_Getter_(unwrap_jso(this));
  
  @DomName('HTMLTextAreaElement.wrap')
  @DocsEditable()
  String get wrap => _blink.BlinkHTMLTextAreaElement.instance.wrap_Getter_(unwrap_jso(this));
  
  @DomName('HTMLTextAreaElement.wrap')
  @DocsEditable()
  set wrap(String value) => _blink.BlinkHTMLTextAreaElement.instance.wrap_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLTextAreaElement.checkValidity')
  @DocsEditable()
  bool checkValidity() => _blink.BlinkHTMLTextAreaElement.instance.checkValidity_Callback_0_(unwrap_jso(this));
  
  @DomName('HTMLTextAreaElement.reportValidity')
  @DocsEditable()
  @Experimental() // untriaged
  bool reportValidity() => _blink.BlinkHTMLTextAreaElement.instance.reportValidity_Callback_0_(unwrap_jso(this));
  
  @DomName('HTMLTextAreaElement.select')
  @DocsEditable()
  void select() => _blink.BlinkHTMLTextAreaElement.instance.select_Callback_0_(unwrap_jso(this));
  
  @DomName('HTMLTextAreaElement.setCustomValidity')
  @DocsEditable()
  void setCustomValidity(String error) => _blink.BlinkHTMLTextAreaElement.instance.setCustomValidity_Callback_1_(unwrap_jso(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_(unwrap_jso(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_(unwrap_jso(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_(unwrap_jso(this), start, end, direction);
      return;
    }
    _blink.BlinkHTMLTextAreaElement.instance.setSelectionRange_Callback_2_(unwrap_jso(this), start, end);
    return;
  }

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

// WARNING: Do not edit - generated code.


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


  @Deprecated("Internal Use Only")
  static TextEvent internalCreateTextEvent() {
    return new TextEvent._internalWrap();
  }

  external factory TextEvent._internalWrap();

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


  @DomName('TextEvent.data')
  @DocsEditable()
  String get data => _blink.BlinkTextEvent.instance.data_Getter_(unwrap_jso(this));
  
  @DomName('TextEvent.initTextEvent')
  @DocsEditable()
  void _initTextEvent(String typeArg, bool canBubbleArg, bool cancelableArg, Window viewArg, String dataArg) => _blink.BlinkTextEvent.instance.initTextEvent_Callback_5_(unwrap_jso(this), typeArg, canBubbleArg, cancelableArg, unwrap_jso(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")
  static TextMetrics internalCreateTextMetrics() {
    return new TextMetrics._internalWrap();
  }

  factory TextMetrics._internalWrap() {
    return new TextMetrics.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  @DomName('TextMetrics.actualBoundingBoxAscent')
  @DocsEditable()
  @Experimental() // untriaged
  num get actualBoundingBoxAscent => _blink.BlinkTextMetrics.instance.actualBoundingBoxAscent_Getter_(unwrap_jso(this));
  
  @DomName('TextMetrics.actualBoundingBoxDescent')
  @DocsEditable()
  @Experimental() // untriaged
  num get actualBoundingBoxDescent => _blink.BlinkTextMetrics.instance.actualBoundingBoxDescent_Getter_(unwrap_jso(this));
  
  @DomName('TextMetrics.actualBoundingBoxLeft')
  @DocsEditable()
  @Experimental() // untriaged
  num get actualBoundingBoxLeft => _blink.BlinkTextMetrics.instance.actualBoundingBoxLeft_Getter_(unwrap_jso(this));
  
  @DomName('TextMetrics.actualBoundingBoxRight')
  @DocsEditable()
  @Experimental() // untriaged
  num get actualBoundingBoxRight => _blink.BlinkTextMetrics.instance.actualBoundingBoxRight_Getter_(unwrap_jso(this));
  
  @DomName('TextMetrics.alphabeticBaseline')
  @DocsEditable()
  @Experimental() // untriaged
  num get alphabeticBaseline => _blink.BlinkTextMetrics.instance.alphabeticBaseline_Getter_(unwrap_jso(this));
  
  @DomName('TextMetrics.emHeightAscent')
  @DocsEditable()
  @Experimental() // untriaged
  num get emHeightAscent => _blink.BlinkTextMetrics.instance.emHeightAscent_Getter_(unwrap_jso(this));
  
  @DomName('TextMetrics.emHeightDescent')
  @DocsEditable()
  @Experimental() // untriaged
  num get emHeightDescent => _blink.BlinkTextMetrics.instance.emHeightDescent_Getter_(unwrap_jso(this));
  
  @DomName('TextMetrics.fontBoundingBoxAscent')
  @DocsEditable()
  @Experimental() // untriaged
  num get fontBoundingBoxAscent => _blink.BlinkTextMetrics.instance.fontBoundingBoxAscent_Getter_(unwrap_jso(this));
  
  @DomName('TextMetrics.fontBoundingBoxDescent')
  @DocsEditable()
  @Experimental() // untriaged
  num get fontBoundingBoxDescent => _blink.BlinkTextMetrics.instance.fontBoundingBoxDescent_Getter_(unwrap_jso(this));
  
  @DomName('TextMetrics.hangingBaseline')
  @DocsEditable()
  @Experimental() // untriaged
  num get hangingBaseline => _blink.BlinkTextMetrics.instance.hangingBaseline_Getter_(unwrap_jso(this));
  
  @DomName('TextMetrics.ideographicBaseline')
  @DocsEditable()
  @Experimental() // untriaged
  num get ideographicBaseline => _blink.BlinkTextMetrics.instance.ideographicBaseline_Getter_(unwrap_jso(this));
  
  @DomName('TextMetrics.width')
  @DocsEditable()
  num get width => _blink.BlinkTextMetrics.instance.width_Getter_(unwrap_jso(this));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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")
  static TextTrack internalCreateTextTrack() {
    return new TextTrack._internalWrap();
  }

  external factory TextTrack._internalWrap();

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


  @DomName('TextTrack.activeCues')
  @DocsEditable()
  TextTrackCueList get activeCues => wrap_jso(_blink.BlinkTextTrack.instance.activeCues_Getter_(unwrap_jso(this)));
  
  @DomName('TextTrack.cues')
  @DocsEditable()
  TextTrackCueList get cues => wrap_jso(_blink.BlinkTextTrack.instance.cues_Getter_(unwrap_jso(this)));
  
  @DomName('TextTrack.id')
  @DocsEditable()
  @Experimental() // untriaged
  String get id => _blink.BlinkTextTrack.instance.id_Getter_(unwrap_jso(this));
  
  @DomName('TextTrack.kind')
  @DocsEditable()
  String get kind => _blink.BlinkTextTrack.instance.kind_Getter_(unwrap_jso(this));
  
  @DomName('TextTrack.label')
  @DocsEditable()
  String get label => _blink.BlinkTextTrack.instance.label_Getter_(unwrap_jso(this));
  
  @DomName('TextTrack.language')
  @DocsEditable()
  String get language => _blink.BlinkTextTrack.instance.language_Getter_(unwrap_jso(this));
  
  @DomName('TextTrack.mode')
  @DocsEditable()
  String get mode => _blink.BlinkTextTrack.instance.mode_Getter_(unwrap_jso(this));
  
  @DomName('TextTrack.mode')
  @DocsEditable()
  set mode(String value) => _blink.BlinkTextTrack.instance.mode_Setter_(unwrap_jso(this), value);
  
  @DomName('TextTrack.regions')
  @DocsEditable()
  @Experimental() // untriaged
  VttRegionList get regions => wrap_jso(_blink.BlinkTextTrack.instance.regions_Getter_(unwrap_jso(this)));
  
  @DomName('TextTrack.addCue')
  @DocsEditable()
  void addCue(TextTrackCue cue) => _blink.BlinkTextTrack.instance.addCue_Callback_1_(unwrap_jso(this), unwrap_jso(cue));
  
  @DomName('TextTrack.addRegion')
  @DocsEditable()
  @Experimental() // untriaged
  void addRegion(VttRegion region) => _blink.BlinkTextTrack.instance.addRegion_Callback_1_(unwrap_jso(this), unwrap_jso(region));
  
  @DomName('TextTrack.removeCue')
  @DocsEditable()
  void removeCue(TextTrackCue cue) => _blink.BlinkTextTrack.instance.removeCue_Callback_1_(unwrap_jso(this), unwrap_jso(cue));
  
  @DomName('TextTrack.removeRegion')
  @DocsEditable()
  @Experimental() // untriaged
  void removeRegion(VttRegion region) => _blink.BlinkTextTrack.instance.removeRegion_Callback_1_(unwrap_jso(this), unwrap_jso(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")
  static TextTrackCue internalCreateTextTrackCue() {
    return new TextTrackCue._internalWrap();
  }

  external factory TextTrackCue._internalWrap();

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


  @DomName('TextTrackCue.endTime')
  @DocsEditable()
  num get endTime => _blink.BlinkTextTrackCue.instance.endTime_Getter_(unwrap_jso(this));
  
  @DomName('TextTrackCue.endTime')
  @DocsEditable()
  set endTime(num value) => _blink.BlinkTextTrackCue.instance.endTime_Setter_(unwrap_jso(this), value);
  
  @DomName('TextTrackCue.id')
  @DocsEditable()
  String get id => _blink.BlinkTextTrackCue.instance.id_Getter_(unwrap_jso(this));
  
  @DomName('TextTrackCue.id')
  @DocsEditable()
  set id(String value) => _blink.BlinkTextTrackCue.instance.id_Setter_(unwrap_jso(this), value);
  
  @DomName('TextTrackCue.pauseOnExit')
  @DocsEditable()
  bool get pauseOnExit => _blink.BlinkTextTrackCue.instance.pauseOnExit_Getter_(unwrap_jso(this));
  
  @DomName('TextTrackCue.pauseOnExit')
  @DocsEditable()
  set pauseOnExit(bool value) => _blink.BlinkTextTrackCue.instance.pauseOnExit_Setter_(unwrap_jso(this), value);
  
  @DomName('TextTrackCue.startTime')
  @DocsEditable()
  num get startTime => _blink.BlinkTextTrackCue.instance.startTime_Getter_(unwrap_jso(this));
  
  @DomName('TextTrackCue.startTime')
  @DocsEditable()
  set startTime(num value) => _blink.BlinkTextTrackCue.instance.startTime_Setter_(unwrap_jso(this), value);
  
  @DomName('TextTrackCue.track')
  @DocsEditable()
  TextTrack get track => wrap_jso(_blink.BlinkTextTrackCue.instance.track_Getter_(unwrap_jso(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")
  static TextTrackCueList internalCreateTextTrackCueList() {
    return new TextTrackCueList._internalWrap();
  }

  factory TextTrackCueList._internalWrap() {
    return new TextTrackCueList.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  @DomName('TextTrackCueList.length')
  @DocsEditable()
  int get length => _blink.BlinkTextTrackCueList.instance.length_Getter_(unwrap_jso(this));
  
  TextTrackCue operator[](int index) {
    if (index < 0 || index >= length)
      throw new RangeError.index(index, this);
    return wrap_jso(_blink.BlinkTextTrackCueList.instance.item_Callback_1_(unwrap_jso(this), index));
  }

  TextTrackCue _nativeIndexedGetter(int index) => wrap_jso(_blink.BlinkTextTrackCueList.instance.item_Callback_1_(unwrap_jso(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) => wrap_jso(_blink.BlinkTextTrackCueList.instance.getCueById_Callback_1_(unwrap_jso(this), id));
  
  @DomName('TextTrackCueList.item')
  @DocsEditable()
  TextTrackCue item(int index) => wrap_jso(_blink.BlinkTextTrackCueList.instance.item_Callback_1_(unwrap_jso(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")
  static TextTrackList internalCreateTextTrackList() {
    return new TextTrackList._internalWrap();
  }

  external factory TextTrackList._internalWrap();

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


  @DomName('TextTrackList.length')
  @DocsEditable()
  int get length => _blink.BlinkTextTrackList.instance.length_Getter_(unwrap_jso(this));
  
  TextTrack operator[](int index) {
    if (index < 0 || index >= length)
      throw new RangeError.index(index, this);
    return wrap_jso(_blink.BlinkTextTrackList.instance.item_Callback_1_(unwrap_jso(this), index));
  }

  TextTrack _nativeIndexedGetter(int index) => wrap_jso(_blink.BlinkTextTrackList.instance.item_Callback_1_(unwrap_jso(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) => wrap_jso(_blink.BlinkTextTrackList.instance.getTrackById_Callback_1_(unwrap_jso(this), id));
  
  @DomName('TextTrackList.item')
  @DocsEditable()
  TextTrack item(int index) => wrap_jso(_blink.BlinkTextTrackList.instance.item_Callback_1_(unwrap_jso(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")
  static TimeRanges internalCreateTimeRanges() {
    return new TimeRanges._internalWrap();
  }

  factory TimeRanges._internalWrap() {
    return new TimeRanges.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  @DomName('TimeRanges.length')
  @DocsEditable()
  int get length => _blink.BlinkTimeRanges.instance.length_Getter_(unwrap_jso(this));
  
  @DomName('TimeRanges.end')
  @DocsEditable()
  num end(int index) => _blink.BlinkTimeRanges.instance.end_Callback_1_(unwrap_jso(this), index);
  
  @DomName('TimeRanges.start')
  @DocsEditable()
  num start(int index) => _blink.BlinkTimeRanges.instance.start_Callback_1_(unwrap_jso(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")
  static TitleElement internalCreateTitleElement() {
    return new TitleElement._internalWrap();
  }

  external factory TitleElement._internalWrap();

  @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")
  static Touch internalCreateTouch() {
    return new Touch._internalWrap();
  }

  factory Touch._internalWrap() {
    return new Touch.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  @DomName('Touch.clientX')
  @DocsEditable()
  num get _clientX => _blink.BlinkTouch.instance.clientX_Getter_(unwrap_jso(this));
  
  @DomName('Touch.clientY')
  @DocsEditable()
  num get _clientY => _blink.BlinkTouch.instance.clientY_Getter_(unwrap_jso(this));
  
  @DomName('Touch.force')
  @DocsEditable()
  @Experimental() // untriaged
  num get force => _blink.BlinkTouch.instance.force_Getter_(unwrap_jso(this));
  
  @DomName('Touch.identifier')
  @DocsEditable()
  int get identifier => _blink.BlinkTouch.instance.identifier_Getter_(unwrap_jso(this));
  
  @DomName('Touch.pageX')
  @DocsEditable()
  num get _pageX => _blink.BlinkTouch.instance.pageX_Getter_(unwrap_jso(this));
  
  @DomName('Touch.pageY')
  @DocsEditable()
  num get _pageY => _blink.BlinkTouch.instance.pageY_Getter_(unwrap_jso(this));
  
  @DomName('Touch.radiusX')
  @DocsEditable()
  @Experimental() // untriaged
  num get _radiusX => _blink.BlinkTouch.instance.radiusX_Getter_(unwrap_jso(this));
  
  @DomName('Touch.radiusY')
  @DocsEditable()
  @Experimental() // untriaged
  num get _radiusY => _blink.BlinkTouch.instance.radiusY_Getter_(unwrap_jso(this));
  
  @DomName('Touch.rotationAngle')
  @DocsEditable()
  @Experimental() // untriaged
  num get rotationAngle => _blink.BlinkTouch.instance.rotationAngle_Getter_(unwrap_jso(this));
  
  @DomName('Touch.screenX')
  @DocsEditable()
  num get _screenX => _blink.BlinkTouch.instance.screenX_Getter_(unwrap_jso(this));
  
  @DomName('Touch.screenY')
  @DocsEditable()
  num get _screenY => _blink.BlinkTouch.instance.screenY_Getter_(unwrap_jso(this));
  
  @DomName('Touch.target')
  @DocsEditable()
  EventTarget get target => wrap_jso(_blink.BlinkTouch.instance.target_Getter_(unwrap_jso(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_(unwrap_jso(this)).round();
  int get __clientY => _blink.BlinkTouch.instance.clientY_Getter_(unwrap_jso(this)).round();
  int get __screenX => _blink.BlinkTouch.instance.screenX_Getter_(unwrap_jso(this)).round();
  int get __screenY => _blink.BlinkTouch.instance.screenY_Getter_(unwrap_jso(this)).round();
  int get __pageX => _blink.BlinkTouch.instance.pageX_Getter_(unwrap_jso(this)).round();
  int get __pageY => _blink.BlinkTouch.instance.pageY_Getter_(unwrap_jso(this)).round();
  int get __radiusX => _blink.BlinkTouch.instance.radiusX_Getter_(unwrap_jso(this)).round();
  int get __radiusY => _blink.BlinkTouch.instance.radiusY_Getter_(unwrap_jso(this)).round();

  @DomName('Touch.clientX')
  @DomName('Touch.clientY')
  Point get client => new Point(__clientX, __clientY);

  @DomName('Touch.pageX')
  @DomName('Touch.pageY')
  Point get page => new Point(__pageX, __pageY);

  @DomName('Touch.screenX')
  @DomName('Touch.screenY')
  Point get screen => new Point(__screenX, __screenY);

  @DomName('Touch.radiusX')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  int get radiusX => __radiusX;

  @DomName('Touch.radiusY')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  int get radiusY => __radiusY;

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

// WARNING: Do not edit - generated code.


@DomName('TouchEvent')
// http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
@Experimental()
class TouchEvent extends UIEvent {
  factory TouchEvent(TouchList touches, TouchList targetTouches,
      TouchList changedTouches, String type,
      {Window view, int screenX: 0, int screenY: 0, int clientX: 0,
      int clientY: 0, bool ctrlKey: false, bool altKey: false,
      bool shiftKey: false, bool metaKey: false}) {
    if (view == null) {
      view = window;
    }
    var e = document._createEvent("TouchEvent");
    e._initTouchEvent(touches, targetTouches, changedTouches, type, view,
        screenX, screenY, clientX, clientY, ctrlKey, altKey, shiftKey, metaKey);
    return e;
  }
  // To suppress missing implicit constructor warnings.
  factory TouchEvent._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  static TouchEvent internalCreateTouchEvent() {
    return new TouchEvent._internalWrap();
  }

  external factory TouchEvent._internalWrap();

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


  @DomName('TouchEvent.altKey')
  @DocsEditable()
  bool get altKey => _blink.BlinkTouchEvent.instance.altKey_Getter_(unwrap_jso(this));
  
  @DomName('TouchEvent.changedTouches')
  @DocsEditable()
  TouchList get changedTouches => wrap_jso(_blink.BlinkTouchEvent.instance.changedTouches_Getter_(unwrap_jso(this)));
  
  @DomName('TouchEvent.ctrlKey')
  @DocsEditable()
  bool get ctrlKey => _blink.BlinkTouchEvent.instance.ctrlKey_Getter_(unwrap_jso(this));
  
  @DomName('TouchEvent.metaKey')
  @DocsEditable()
  bool get metaKey => _blink.BlinkTouchEvent.instance.metaKey_Getter_(unwrap_jso(this));
  
  @DomName('TouchEvent.shiftKey')
  @DocsEditable()
  bool get shiftKey => _blink.BlinkTouchEvent.instance.shiftKey_Getter_(unwrap_jso(this));
  
  @DomName('TouchEvent.targetTouches')
  @DocsEditable()
  TouchList get targetTouches => wrap_jso(_blink.BlinkTouchEvent.instance.targetTouches_Getter_(unwrap_jso(this)));
  
  @DomName('TouchEvent.touches')
  @DocsEditable()
  TouchList get touches => wrap_jso(_blink.BlinkTouchEvent.instance.touches_Getter_(unwrap_jso(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_(unwrap_jso(this), unwrap_jso(touches), unwrap_jso(targetTouches), unwrap_jso(changedTouches), type, unwrap_jso(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")
  static TouchList internalCreateTouchList() {
    return new TouchList._internalWrap();
  }

  factory TouchList._internalWrap() {
    return new TouchList.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  /// 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_(unwrap_jso(this));
  
  Touch operator[](int index) {
    if (index < 0 || index >= length)
      throw new RangeError.index(index, this);
    return wrap_jso(_blink.BlinkTouchList.instance.item_Callback_1_(unwrap_jso(this), index));
  }

  Touch _nativeIndexedGetter(int index) => wrap_jso(_blink.BlinkTouchList.instance.item_Callback_1_(unwrap_jso(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) => wrap_jso(_blink.BlinkTouchList.instance.item_Callback_1_(unwrap_jso(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 wrap_jso(_blink.BlinkTrackDefault.instance.constructorCallback_5_(type, language, label, kinds_1, byteStreamTrackID));
    }
    List kinds_1 = convertDartToNative_StringArray(kinds);
    return wrap_jso(_blink.BlinkTrackDefault.instance.constructorCallback_4_(type, language, label, kinds_1));
  }

  @Deprecated("Internal Use Only")
  static TrackDefault internalCreateTrackDefault() {
    return new TrackDefault._internalWrap();
  }

  factory TrackDefault._internalWrap() {
    return new TrackDefault.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  @DomName('TrackDefault.byteStreamTrackID')
  @DocsEditable()
  @Experimental() // untriaged
  String get byteStreamTrackID => _blink.BlinkTrackDefault.instance.byteStreamTrackID_Getter_(unwrap_jso(this));
  
  @DomName('TrackDefault.kinds')
  @DocsEditable()
  @Experimental() // untriaged
  List<String> get kinds => _blink.BlinkTrackDefault.instance.kinds_Getter_(unwrap_jso(this));
  
  @DomName('TrackDefault.label')
  @DocsEditable()
  @Experimental() // untriaged
  String get label => _blink.BlinkTrackDefault.instance.label_Getter_(unwrap_jso(this));
  
  @DomName('TrackDefault.language')
  @DocsEditable()
  @Experimental() // untriaged
  String get language => _blink.BlinkTrackDefault.instance.language_Getter_(unwrap_jso(this));
  
  @DomName('TrackDefault.type')
  @DocsEditable()
  @Experimental() // untriaged
  String get type => _blink.BlinkTrackDefault.instance.type_Getter_(unwrap_jso(this));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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 wrap_jso(_blink.BlinkTrackDefaultList.instance.constructorCallback_1_(trackDefaults));
    }
    return wrap_jso(_blink.BlinkTrackDefaultList.instance.constructorCallback_0_());
  }

  @Deprecated("Internal Use Only")
  static TrackDefaultList internalCreateTrackDefaultList() {
    return new TrackDefaultList._internalWrap();
  }

  factory TrackDefaultList._internalWrap() {
    return new TrackDefaultList.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  @DomName('TrackDefaultList.length')
  @DocsEditable()
  @Experimental() // untriaged
  int get length => _blink.BlinkTrackDefaultList.instance.length_Getter_(unwrap_jso(this));
  
  @DomName('TrackDefaultList.item')
  @DocsEditable()
  @Experimental() // untriaged
  TrackDefault item(int index) => wrap_jso(_blink.BlinkTrackDefaultList.instance.item_Callback_1_(unwrap_jso(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")
  static TrackElement internalCreateTrackElement() {
    return new TrackElement._internalWrap();
  }

  external factory TrackElement._internalWrap();

  @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_(unwrap_jso(this));
  
  @DomName('HTMLTrackElement.default')
  @DocsEditable()
  set defaultValue(bool value) => _blink.BlinkHTMLTrackElement.instance.default_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLTrackElement.kind')
  @DocsEditable()
  String get kind => _blink.BlinkHTMLTrackElement.instance.kind_Getter_(unwrap_jso(this));
  
  @DomName('HTMLTrackElement.kind')
  @DocsEditable()
  set kind(String value) => _blink.BlinkHTMLTrackElement.instance.kind_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLTrackElement.label')
  @DocsEditable()
  String get label => _blink.BlinkHTMLTrackElement.instance.label_Getter_(unwrap_jso(this));
  
  @DomName('HTMLTrackElement.label')
  @DocsEditable()
  set label(String value) => _blink.BlinkHTMLTrackElement.instance.label_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLTrackElement.readyState')
  @DocsEditable()
  int get readyState => _blink.BlinkHTMLTrackElement.instance.readyState_Getter_(unwrap_jso(this));
  
  @DomName('HTMLTrackElement.src')
  @DocsEditable()
  String get src => _blink.BlinkHTMLTrackElement.instance.src_Getter_(unwrap_jso(this));
  
  @DomName('HTMLTrackElement.src')
  @DocsEditable()
  set src(String value) => _blink.BlinkHTMLTrackElement.instance.src_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLTrackElement.srclang')
  @DocsEditable()
  String get srclang => _blink.BlinkHTMLTrackElement.instance.srclang_Getter_(unwrap_jso(this));
  
  @DomName('HTMLTrackElement.srclang')
  @DocsEditable()
  set srclang(String value) => _blink.BlinkHTMLTrackElement.instance.srclang_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLTrackElement.track')
  @DocsEditable()
  TextTrack get track => wrap_jso(_blink.BlinkHTMLTrackElement.instance.track_Getter_(unwrap_jso(this)));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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 wrap_jso(_blink.BlinkTrackEvent.instance.constructorCallback_2_(type, eventInitDict_1));
    }
    return wrap_jso(_blink.BlinkTrackEvent.instance.constructorCallback_1_(type));
  }


  @Deprecated("Internal Use Only")
  static TrackEvent internalCreateTrackEvent() {
    return new TrackEvent._internalWrap();
  }

  external factory TrackEvent._internalWrap();

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


  @DomName('TrackEvent.track')
  @DocsEditable()
  Object get track => wrap_jso(_blink.BlinkTrackEvent.instance.track_Getter_(unwrap_jso(this)));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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 wrap_jso(_blink.BlinkTransitionEvent.instance.constructorCallback_2_(type, eventInitDict_1));
    }
    return wrap_jso(_blink.BlinkTransitionEvent.instance.constructorCallback_1_(type));
  }


  @Deprecated("Internal Use Only")
  static TransitionEvent internalCreateTransitionEvent() {
    return new TransitionEvent._internalWrap();
  }

  external factory TransitionEvent._internalWrap();

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


  @DomName('TransitionEvent.elapsedTime')
  @DocsEditable()
  num get elapsedTime => _blink.BlinkTransitionEvent.instance.elapsedTime_Getter_(unwrap_jso(this));
  
  @DomName('TransitionEvent.propertyName')
  @DocsEditable()
  String get propertyName => _blink.BlinkTransitionEvent.instance.propertyName_Getter_(unwrap_jso(this));
  
  @DomName('TransitionEvent.pseudoElement')
  @DocsEditable()
  String get pseudoElement => _blink.BlinkTransitionEvent.instance.pseudoElement_Getter_(unwrap_jso(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")
  static TreeWalker internalCreateTreeWalker() {
    return new TreeWalker._internalWrap();
  }

  factory TreeWalker._internalWrap() {
    return new TreeWalker.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  @DomName('TreeWalker.currentNode')
  @DocsEditable()
  Node get currentNode => wrap_jso(_blink.BlinkTreeWalker.instance.currentNode_Getter_(unwrap_jso(this)));
  
  @DomName('TreeWalker.currentNode')
  @DocsEditable()
  set currentNode(Node value) => _blink.BlinkTreeWalker.instance.currentNode_Setter_(unwrap_jso(this), unwrap_jso(value));
  
  @DomName('TreeWalker.filter')
  @DocsEditable()
  NodeFilter get filter => wrap_jso(_blink.BlinkTreeWalker.instance.filter_Getter_(unwrap_jso(this)));
  
  @DomName('TreeWalker.root')
  @DocsEditable()
  Node get root => wrap_jso(_blink.BlinkTreeWalker.instance.root_Getter_(unwrap_jso(this)));
  
  @DomName('TreeWalker.whatToShow')
  @DocsEditable()
  int get whatToShow => _blink.BlinkTreeWalker.instance.whatToShow_Getter_(unwrap_jso(this));
  
  @DomName('TreeWalker.firstChild')
  @DocsEditable()
  Node firstChild() => wrap_jso(_blink.BlinkTreeWalker.instance.firstChild_Callback_0_(unwrap_jso(this)));
  
  @DomName('TreeWalker.lastChild')
  @DocsEditable()
  Node lastChild() => wrap_jso(_blink.BlinkTreeWalker.instance.lastChild_Callback_0_(unwrap_jso(this)));
  
  @DomName('TreeWalker.nextNode')
  @DocsEditable()
  Node nextNode() => wrap_jso(_blink.BlinkTreeWalker.instance.nextNode_Callback_0_(unwrap_jso(this)));
  
  @DomName('TreeWalker.nextSibling')
  @DocsEditable()
  Node nextSibling() => wrap_jso(_blink.BlinkTreeWalker.instance.nextSibling_Callback_0_(unwrap_jso(this)));
  
  @DomName('TreeWalker.parentNode')
  @DocsEditable()
  Node parentNode() => wrap_jso(_blink.BlinkTreeWalker.instance.parentNode_Callback_0_(unwrap_jso(this)));
  
  @DomName('TreeWalker.previousNode')
  @DocsEditable()
  Node previousNode() => wrap_jso(_blink.BlinkTreeWalker.instance.previousNode_Callback_0_(unwrap_jso(this)));
  
  @DomName('TreeWalker.previousSibling')
  @DocsEditable()
  Node previousSibling() => wrap_jso(_blink.BlinkTreeWalker.instance.previousSibling_Callback_0_(unwrap_jso(this)));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.


@DomName('UIEvent')
class UIEvent extends Event {
  // In JS, canBubble and cancelable are technically required parameters to
  // init*Event. In practice, though, if they aren't provided they simply
  // default to false (since that's Boolean(undefined)).
  //
  // Contrary to JS, we default canBubble and cancelable to true, since that's
  // what people want most of the time anyway.
  factory UIEvent(String type,
      {Window view, int detail: 0, bool canBubble: true,
      bool cancelable: true}) {
    if (view == null) {
      view = window;
    }
    final e = document._createEvent("UIEvent");
    e._initUIEvent(type, canBubble, cancelable, view, detail);
    return e;
  }

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


  @Deprecated("Internal Use Only")
  static UIEvent internalCreateUIEvent() {
    return new UIEvent._internalWrap();
  }

  external factory UIEvent._internalWrap();

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


  @DomName('UIEvent.charCode')
  @DocsEditable()
  @Unstable()
  int get _charCode => _blink.BlinkUIEvent.instance.charCode_Getter_(unwrap_jso(this));
  
  @DomName('UIEvent.detail')
  @DocsEditable()
  int get detail => _blink.BlinkUIEvent.instance.detail_Getter_(unwrap_jso(this));
  
  @DomName('UIEvent.keyCode')
  @DocsEditable()
  @Unstable()
  int get _keyCode => _blink.BlinkUIEvent.instance.keyCode_Getter_(unwrap_jso(this));
  
  @DomName('UIEvent.sourceDevice')
  @DocsEditable()
  @Experimental() // untriaged
  InputDevice get sourceDevice => wrap_jso(_blink.BlinkUIEvent.instance.sourceDevice_Getter_(unwrap_jso(this)));
  
  @DomName('UIEvent.view')
  @DocsEditable()
  WindowBase get view => wrap_jso(_blink.BlinkUIEvent.instance.view_Getter_(unwrap_jso(this)));
  
  @DomName('UIEvent.which')
  @DocsEditable()
  @Unstable()
  int get _which => _blink.BlinkUIEvent.instance.which_Getter_(unwrap_jso(this));
  
  @DomName('UIEvent.initUIEvent')
  @DocsEditable()
  void _initUIEvent(String type, bool bubbles, bool cancelable, Window view, int detail) => _blink.BlinkUIEvent.instance.initUIEvent_Callback_5_(unwrap_jso(this), type, bubbles, cancelable, unwrap_jso(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")
  static UListElement internalCreateUListElement() {
    return new UListElement._internalWrap();
  }

  external factory UListElement._internalWrap();

  @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")
  static UnknownElement internalCreateUnknownElement() {
    return new UnknownElement._internalWrap();
  }

  external factory UnknownElement._internalWrap();

  @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")
  static Url internalCreateUrl() {
    return new Url._internalWrap();
  }

  factory Url._internalWrap() {
    return new Url.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  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_(unwrap_jso(blob_OR_source_OR_stream));
    }
    if ((blob_OR_source_OR_stream is MediaSource)) {
      return _blink.BlinkURL.instance.createObjectURL_Callback_1_(unwrap_jso(blob_OR_source_OR_stream));
    }
    if ((blob_OR_source_OR_stream is MediaStream)) {
      return _blink.BlinkURL.instance.createObjectURL_Callback_1_(unwrap_jso(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_(unwrap_jso(blob));
  
  @DomName('URL.createObjectUrlFromSource')
  @DocsEditable()
  static String createObjectUrlFromSource(MediaSource source) => _blink.BlinkURL.instance.createObjectURL_Callback_1_(unwrap_jso(source));
  
  @DomName('URL.createObjectUrlFromStream')
  @DocsEditable()
  static String createObjectUrlFromStream(MediaStream stream) => _blink.BlinkURL.instance.createObjectURL_Callback_1_(unwrap_jso(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_(unwrap_jso(this));
  
  @DomName('URL.hash')
  @DocsEditable()
  @Experimental() // untriaged
  set hash(String value) => _blink.BlinkURL.instance.hash_Setter_(unwrap_jso(this), value);
  
  @DomName('URL.host')
  @DocsEditable()
  @Experimental() // untriaged
  String get host => _blink.BlinkURL.instance.host_Getter_(unwrap_jso(this));
  
  @DomName('URL.host')
  @DocsEditable()
  @Experimental() // untriaged
  set host(String value) => _blink.BlinkURL.instance.host_Setter_(unwrap_jso(this), value);
  
  @DomName('URL.hostname')
  @DocsEditable()
  @Experimental() // untriaged
  String get hostname => _blink.BlinkURL.instance.hostname_Getter_(unwrap_jso(this));
  
  @DomName('URL.hostname')
  @DocsEditable()
  @Experimental() // untriaged
  set hostname(String value) => _blink.BlinkURL.instance.hostname_Setter_(unwrap_jso(this), value);
  
  @DomName('URL.href')
  @DocsEditable()
  @Experimental() // untriaged
  String get href => _blink.BlinkURL.instance.href_Getter_(unwrap_jso(this));
  
  @DomName('URL.href')
  @DocsEditable()
  @Experimental() // untriaged
  set href(String value) => _blink.BlinkURL.instance.href_Setter_(unwrap_jso(this), value);
  
  @DomName('URL.origin')
  @DocsEditable()
  @Experimental() // untriaged
  String get origin => _blink.BlinkURL.instance.origin_Getter_(unwrap_jso(this));
  
  @DomName('URL.password')
  @DocsEditable()
  @Experimental() // untriaged
  String get password => _blink.BlinkURL.instance.password_Getter_(unwrap_jso(this));
  
  @DomName('URL.password')
  @DocsEditable()
  @Experimental() // untriaged
  set password(String value) => _blink.BlinkURL.instance.password_Setter_(unwrap_jso(this), value);
  
  @DomName('URL.pathname')
  @DocsEditable()
  @Experimental() // untriaged
  String get pathname => _blink.BlinkURL.instance.pathname_Getter_(unwrap_jso(this));
  
  @DomName('URL.pathname')
  @DocsEditable()
  @Experimental() // untriaged
  set pathname(String value) => _blink.BlinkURL.instance.pathname_Setter_(unwrap_jso(this), value);
  
  @DomName('URL.port')
  @DocsEditable()
  @Experimental() // untriaged
  String get port => _blink.BlinkURL.instance.port_Getter_(unwrap_jso(this));
  
  @DomName('URL.port')
  @DocsEditable()
  @Experimental() // untriaged
  set port(String value) => _blink.BlinkURL.instance.port_Setter_(unwrap_jso(this), value);
  
  @DomName('URL.protocol')
  @DocsEditable()
  @Experimental() // untriaged
  String get protocol => _blink.BlinkURL.instance.protocol_Getter_(unwrap_jso(this));
  
  @DomName('URL.protocol')
  @DocsEditable()
  @Experimental() // untriaged
  set protocol(String value) => _blink.BlinkURL.instance.protocol_Setter_(unwrap_jso(this), value);
  
  @DomName('URL.search')
  @DocsEditable()
  @Experimental() // untriaged
  String get search => _blink.BlinkURL.instance.search_Getter_(unwrap_jso(this));
  
  @DomName('URL.search')
  @DocsEditable()
  @Experimental() // untriaged
  set search(String value) => _blink.BlinkURL.instance.search_Setter_(unwrap_jso(this), value);
  
  @DomName('URL.username')
  @DocsEditable()
  @Experimental() // untriaged
  String get username => _blink.BlinkURL.instance.username_Getter_(unwrap_jso(this));
  
  @DomName('URL.username')
  @DocsEditable()
  @Experimental() // untriaged
  set username(String value) => _blink.BlinkURL.instance.username_Setter_(unwrap_jso(this), value);
  
  @DomName('URL.toString')
  @DocsEditable()
  @Experimental() // untriaged
  String toString() => _blink.BlinkURL.instance.toString_Callback_0_(unwrap_jso(this));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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")
  static VRDevice internalCreateVRDevice() {
    return new VRDevice._internalWrap();
  }

  factory VRDevice._internalWrap() {
    return new VRDevice.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  @DomName('VRDevice.deviceId')
  @DocsEditable()
  @Experimental() // untriaged
  String get deviceId => _blink.BlinkVRDevice.instance.deviceId_Getter_(unwrap_jso(this));
  
  @DomName('VRDevice.deviceName')
  @DocsEditable()
  @Experimental() // untriaged
  String get deviceName => _blink.BlinkVRDevice.instance.deviceName_Getter_(unwrap_jso(this));
  
  @DomName('VRDevice.hardwareUnitId')
  @DocsEditable()
  @Experimental() // untriaged
  String get hardwareUnitId => _blink.BlinkVRDevice.instance.hardwareUnitId_Getter_(unwrap_jso(this));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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")
  static VREyeParameters internalCreateVREyeParameters() {
    return new VREyeParameters._internalWrap();
  }

  factory VREyeParameters._internalWrap() {
    return new VREyeParameters.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  @DomName('VREyeParameters.currentFieldOfView')
  @DocsEditable()
  @Experimental() // untriaged
  VRFieldOfView get currentFieldOfView => wrap_jso(_blink.BlinkVREyeParameters.instance.currentFieldOfView_Getter_(unwrap_jso(this)));
  
  @DomName('VREyeParameters.eyeTranslation')
  @DocsEditable()
  @Experimental() // untriaged
  DomPoint get eyeTranslation => wrap_jso(_blink.BlinkVREyeParameters.instance.eyeTranslation_Getter_(unwrap_jso(this)));
  
  @DomName('VREyeParameters.maximumFieldOfView')
  @DocsEditable()
  @Experimental() // untriaged
  VRFieldOfView get maximumFieldOfView => wrap_jso(_blink.BlinkVREyeParameters.instance.maximumFieldOfView_Getter_(unwrap_jso(this)));
  
  @DomName('VREyeParameters.minimumFieldOfView')
  @DocsEditable()
  @Experimental() // untriaged
  VRFieldOfView get minimumFieldOfView => wrap_jso(_blink.BlinkVREyeParameters.instance.minimumFieldOfView_Getter_(unwrap_jso(this)));
  
  @DomName('VREyeParameters.recommendedFieldOfView')
  @DocsEditable()
  @Experimental() // untriaged
  VRFieldOfView get recommendedFieldOfView => wrap_jso(_blink.BlinkVREyeParameters.instance.recommendedFieldOfView_Getter_(unwrap_jso(this)));
  
  @DomName('VREyeParameters.renderRect')
  @DocsEditable()
  @Experimental() // untriaged
  _DomRect get renderRect => wrap_jso(_blink.BlinkVREyeParameters.instance.renderRect_Getter_(unwrap_jso(this)));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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 wrap_jso(_blink.BlinkVRFieldOfView.instance.constructorCallback_1_(fov_1));
    }
    return wrap_jso(_blink.BlinkVRFieldOfView.instance.constructorCallback_0_());
  }

  @Deprecated("Internal Use Only")
  static VRFieldOfView internalCreateVRFieldOfView() {
    return new VRFieldOfView._internalWrap();
  }

  factory VRFieldOfView._internalWrap() {
    return new VRFieldOfView.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  @DomName('VRFieldOfView.downDegrees')
  @DocsEditable()
  @Experimental() // untriaged
  num get downDegrees => _blink.BlinkVRFieldOfView.instance.downDegrees_Getter_(unwrap_jso(this));
  
  @DomName('VRFieldOfView.downDegrees')
  @DocsEditable()
  @Experimental() // untriaged
  set downDegrees(num value) => _blink.BlinkVRFieldOfView.instance.downDegrees_Setter_(unwrap_jso(this), value);
  
  @DomName('VRFieldOfView.leftDegrees')
  @DocsEditable()
  @Experimental() // untriaged
  num get leftDegrees => _blink.BlinkVRFieldOfView.instance.leftDegrees_Getter_(unwrap_jso(this));
  
  @DomName('VRFieldOfView.leftDegrees')
  @DocsEditable()
  @Experimental() // untriaged
  set leftDegrees(num value) => _blink.BlinkVRFieldOfView.instance.leftDegrees_Setter_(unwrap_jso(this), value);
  
  @DomName('VRFieldOfView.rightDegrees')
  @DocsEditable()
  @Experimental() // untriaged
  num get rightDegrees => _blink.BlinkVRFieldOfView.instance.rightDegrees_Getter_(unwrap_jso(this));
  
  @DomName('VRFieldOfView.rightDegrees')
  @DocsEditable()
  @Experimental() // untriaged
  set rightDegrees(num value) => _blink.BlinkVRFieldOfView.instance.rightDegrees_Setter_(unwrap_jso(this), value);
  
  @DomName('VRFieldOfView.upDegrees')
  @DocsEditable()
  @Experimental() // untriaged
  num get upDegrees => _blink.BlinkVRFieldOfView.instance.upDegrees_Getter_(unwrap_jso(this));
  
  @DomName('VRFieldOfView.upDegrees')
  @DocsEditable()
  @Experimental() // untriaged
  set upDegrees(num value) => _blink.BlinkVRFieldOfView.instance.upDegrees_Setter_(unwrap_jso(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")
  static VRPositionState internalCreateVRPositionState() {
    return new VRPositionState._internalWrap();
  }

  factory VRPositionState._internalWrap() {
    return new VRPositionState.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  @DomName('VRPositionState.angularAcceleration')
  @DocsEditable()
  @Experimental() // untriaged
  DomPoint get angularAcceleration => wrap_jso(_blink.BlinkVRPositionState.instance.angularAcceleration_Getter_(unwrap_jso(this)));
  
  @DomName('VRPositionState.angularVelocity')
  @DocsEditable()
  @Experimental() // untriaged
  DomPoint get angularVelocity => wrap_jso(_blink.BlinkVRPositionState.instance.angularVelocity_Getter_(unwrap_jso(this)));
  
  @DomName('VRPositionState.linearAcceleration')
  @DocsEditable()
  @Experimental() // untriaged
  DomPoint get linearAcceleration => wrap_jso(_blink.BlinkVRPositionState.instance.linearAcceleration_Getter_(unwrap_jso(this)));
  
  @DomName('VRPositionState.linearVelocity')
  @DocsEditable()
  @Experimental() // untriaged
  DomPoint get linearVelocity => wrap_jso(_blink.BlinkVRPositionState.instance.linearVelocity_Getter_(unwrap_jso(this)));
  
  @DomName('VRPositionState.orientation')
  @DocsEditable()
  @Experimental() // untriaged
  DomPoint get orientation => wrap_jso(_blink.BlinkVRPositionState.instance.orientation_Getter_(unwrap_jso(this)));
  
  @DomName('VRPositionState.position')
  @DocsEditable()
  @Experimental() // untriaged
  DomPoint get position => wrap_jso(_blink.BlinkVRPositionState.instance.position_Getter_(unwrap_jso(this)));
  
  @DomName('VRPositionState.timeStamp')
  @DocsEditable()
  @Experimental() // untriaged
  num get timeStamp => _blink.BlinkVRPositionState.instance.timeStamp_Getter_(unwrap_jso(this));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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")
  static ValidityState internalCreateValidityState() {
    return new ValidityState._internalWrap();
  }

  factory ValidityState._internalWrap() {
    return new ValidityState.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  @DomName('ValidityState.badInput')
  @DocsEditable()
  bool get badInput => _blink.BlinkValidityState.instance.badInput_Getter_(unwrap_jso(this));
  
  @DomName('ValidityState.customError')
  @DocsEditable()
  bool get customError => _blink.BlinkValidityState.instance.customError_Getter_(unwrap_jso(this));
  
  @DomName('ValidityState.patternMismatch')
  @DocsEditable()
  bool get patternMismatch => _blink.BlinkValidityState.instance.patternMismatch_Getter_(unwrap_jso(this));
  
  @DomName('ValidityState.rangeOverflow')
  @DocsEditable()
  bool get rangeOverflow => _blink.BlinkValidityState.instance.rangeOverflow_Getter_(unwrap_jso(this));
  
  @DomName('ValidityState.rangeUnderflow')
  @DocsEditable()
  bool get rangeUnderflow => _blink.BlinkValidityState.instance.rangeUnderflow_Getter_(unwrap_jso(this));
  
  @DomName('ValidityState.stepMismatch')
  @DocsEditable()
  bool get stepMismatch => _blink.BlinkValidityState.instance.stepMismatch_Getter_(unwrap_jso(this));
  
  @DomName('ValidityState.tooLong')
  @DocsEditable()
  bool get tooLong => _blink.BlinkValidityState.instance.tooLong_Getter_(unwrap_jso(this));
  
  @DomName('ValidityState.tooShort')
  @DocsEditable()
  @Experimental() // untriaged
  bool get tooShort => _blink.BlinkValidityState.instance.tooShort_Getter_(unwrap_jso(this));
  
  @DomName('ValidityState.typeMismatch')
  @DocsEditable()
  bool get typeMismatch => _blink.BlinkValidityState.instance.typeMismatch_Getter_(unwrap_jso(this));
  
  @DomName('ValidityState.valid')
  @DocsEditable()
  bool get valid => _blink.BlinkValidityState.instance.valid_Getter_(unwrap_jso(this));
  
  @DomName('ValidityState.valueMissing')
  @DocsEditable()
  bool get valueMissing => _blink.BlinkValidityState.instance.valueMissing_Getter_(unwrap_jso(this));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for 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")
  static VideoElement internalCreateVideoElement() {
    return new VideoElement._internalWrap();
  }

  external factory VideoElement._internalWrap();

  @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_(unwrap_jso(this));
  
  @DomName('HTMLVideoElement.height')
  @DocsEditable()
  set height(int value) => _blink.BlinkHTMLVideoElement.instance.height_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLVideoElement.poster')
  @DocsEditable()
  String get poster => _blink.BlinkHTMLVideoElement.instance.poster_Getter_(unwrap_jso(this));
  
  @DomName('HTMLVideoElement.poster')
  @DocsEditable()
  set poster(String value) => _blink.BlinkHTMLVideoElement.instance.poster_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLVideoElement.videoHeight')
  @DocsEditable()
  int get videoHeight => _blink.BlinkHTMLVideoElement.instance.videoHeight_Getter_(unwrap_jso(this));
  
  @DomName('HTMLVideoElement.videoWidth')
  @DocsEditable()
  int get videoWidth => _blink.BlinkHTMLVideoElement.instance.videoWidth_Getter_(unwrap_jso(this));
  
  @DomName('HTMLVideoElement.webkitDecodedFrameCount')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  int get decodedFrameCount => _blink.BlinkHTMLVideoElement.instance.webkitDecodedFrameCount_Getter_(unwrap_jso(this));
  
  @DomName('HTMLVideoElement.webkitDroppedFrameCount')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  int get droppedFrameCount => _blink.BlinkHTMLVideoElement.instance.webkitDroppedFrameCount_Getter_(unwrap_jso(this));
  
  @DomName('HTMLVideoElement.width')
  @DocsEditable()
  int get width => _blink.BlinkHTMLVideoElement.instance.width_Getter_(unwrap_jso(this));
  
  @DomName('HTMLVideoElement.width')
  @DocsEditable()
  set width(int value) => _blink.BlinkHTMLVideoElement.instance.width_Setter_(unwrap_jso(this), value);
  
  @DomName('HTMLVideoElement.getVideoPlaybackQuality')
  @DocsEditable()
  @Experimental() // untriaged
  VideoPlaybackQuality getVideoPlaybackQuality() => wrap_jso(_blink.BlinkHTMLVideoElement.instance.getVideoPlaybackQuality_Callback_0_(unwrap_jso(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_(unwrap_jso(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_(unwrap_jso(this));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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")
  static VideoPlaybackQuality internalCreateVideoPlaybackQuality() {
    return new VideoPlaybackQuality._internalWrap();
  }

  factory VideoPlaybackQuality._internalWrap() {
    return new VideoPlaybackQuality.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  @DomName('VideoPlaybackQuality.corruptedVideoFrames')
  @DocsEditable()
  @Experimental() // untriaged
  int get corruptedVideoFrames => _blink.BlinkVideoPlaybackQuality.instance.corruptedVideoFrames_Getter_(unwrap_jso(this));
  
  @DomName('VideoPlaybackQuality.creationTime')
  @DocsEditable()
  @Experimental() // untriaged
  num get creationTime => _blink.BlinkVideoPlaybackQuality.instance.creationTime_Getter_(unwrap_jso(this));
  
  @DomName('VideoPlaybackQuality.droppedVideoFrames')
  @DocsEditable()
  @Experimental() // untriaged
  int get droppedVideoFrames => _blink.BlinkVideoPlaybackQuality.instance.droppedVideoFrames_Getter_(unwrap_jso(this));
  
  @DomName('VideoPlaybackQuality.totalVideoFrames')
  @DocsEditable()
  @Experimental() // untriaged
  int get totalVideoFrames => _blink.BlinkVideoPlaybackQuality.instance.totalVideoFrames_Getter_(unwrap_jso(this));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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")
  static VideoTrack internalCreateVideoTrack() {
    return new VideoTrack._internalWrap();
  }

  factory VideoTrack._internalWrap() {
    return new VideoTrack.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  @DomName('VideoTrack.id')
  @DocsEditable()
  @Experimental() // untriaged
  String get id => _blink.BlinkVideoTrack.instance.id_Getter_(unwrap_jso(this));
  
  @DomName('VideoTrack.kind')
  @DocsEditable()
  @Experimental() // untriaged
  String get kind => _blink.BlinkVideoTrack.instance.kind_Getter_(unwrap_jso(this));
  
  @DomName('VideoTrack.label')
  @DocsEditable()
  @Experimental() // untriaged
  String get label => _blink.BlinkVideoTrack.instance.label_Getter_(unwrap_jso(this));
  
  @DomName('VideoTrack.language')
  @DocsEditable()
  @Experimental() // untriaged
  String get language => _blink.BlinkVideoTrack.instance.language_Getter_(unwrap_jso(this));
  
  @DomName('VideoTrack.selected')
  @DocsEditable()
  @Experimental() // untriaged
  bool get selected => _blink.BlinkVideoTrack.instance.selected_Getter_(unwrap_jso(this));
  
  @DomName('VideoTrack.selected')
  @DocsEditable()
  @Experimental() // untriaged
  set selected(bool value) => _blink.BlinkVideoTrack.instance.selected_Setter_(unwrap_jso(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")
  static VideoTrackList internalCreateVideoTrackList() {
    return new VideoTrackList._internalWrap();
  }

  external factory VideoTrackList._internalWrap();

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


  @DomName('VideoTrackList.length')
  @DocsEditable()
  @Experimental() // untriaged
  int get length => _blink.BlinkVideoTrackList.instance.length_Getter_(unwrap_jso(this));
  
  @DomName('VideoTrackList.selectedIndex')
  @DocsEditable()
  @Experimental() // untriaged
  int get selectedIndex => _blink.BlinkVideoTrackList.instance.selectedIndex_Getter_(unwrap_jso(this));
  
  @DomName('VideoTrackList.__getter__')
  @DocsEditable()
  @Experimental() // untriaged
  VideoTrack __getter__(int index) => wrap_jso(_blink.BlinkVideoTrackList.instance.$__getter___Callback_1_(unwrap_jso(this), index));
  
  @DomName('VideoTrackList.getTrackById')
  @DocsEditable()
  @Experimental() // untriaged
  VideoTrack getTrackById(String id) => wrap_jso(_blink.BlinkVideoTrackList.instance.getTrackById_Callback_1_(unwrap_jso(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 wrap_jso(_blink.BlinkVTTCue.instance.constructorCallback_3_(startTime, endTime, text));
  }


  @Deprecated("Internal Use Only")
  static VttCue internalCreateVttCue() {
    return new VttCue._internalWrap();
  }

  external factory VttCue._internalWrap();

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


  @DomName('VTTCue.align')
  @DocsEditable()
  @Experimental() // untriaged
  String get align => _blink.BlinkVTTCue.instance.align_Getter_(unwrap_jso(this));
  
  @DomName('VTTCue.align')
  @DocsEditable()
  @Experimental() // untriaged
  set align(String value) => _blink.BlinkVTTCue.instance.align_Setter_(unwrap_jso(this), value);
  
  @DomName('VTTCue.line')
  @DocsEditable()
  @Experimental() // untriaged
  Object get line => wrap_jso(_blink.BlinkVTTCue.instance.line_Getter_(unwrap_jso(this)));
  
  @DomName('VTTCue.line')
  @DocsEditable()
  @Experimental() // untriaged
  set line(Object value) => _blink.BlinkVTTCue.instance.line_Setter_(unwrap_jso(this), unwrap_jso(value));
  
  @DomName('VTTCue.position')
  @DocsEditable()
  @Experimental() // untriaged
  Object get position => wrap_jso(_blink.BlinkVTTCue.instance.position_Getter_(unwrap_jso(this)));
  
  @DomName('VTTCue.position')
  @DocsEditable()
  @Experimental() // untriaged
  set position(Object value) => _blink.BlinkVTTCue.instance.position_Setter_(unwrap_jso(this), unwrap_jso(value));
  
  @DomName('VTTCue.regionId')
  @DocsEditable()
  @Experimental() // untriaged
  String get regionId => _blink.BlinkVTTCue.instance.regionId_Getter_(unwrap_jso(this));
  
  @DomName('VTTCue.regionId')
  @DocsEditable()
  @Experimental() // untriaged
  set regionId(String value) => _blink.BlinkVTTCue.instance.regionId_Setter_(unwrap_jso(this), value);
  
  @DomName('VTTCue.size')
  @DocsEditable()
  @Experimental() // untriaged
  num get size => _blink.BlinkVTTCue.instance.size_Getter_(unwrap_jso(this));
  
  @DomName('VTTCue.size')
  @DocsEditable()
  @Experimental() // untriaged
  set size(num value) => _blink.BlinkVTTCue.instance.size_Setter_(unwrap_jso(this), value);
  
  @DomName('VTTCue.snapToLines')
  @DocsEditable()
  @Experimental() // untriaged
  bool get snapToLines => _blink.BlinkVTTCue.instance.snapToLines_Getter_(unwrap_jso(this));
  
  @DomName('VTTCue.snapToLines')
  @DocsEditable()
  @Experimental() // untriaged
  set snapToLines(bool value) => _blink.BlinkVTTCue.instance.snapToLines_Setter_(unwrap_jso(this), value);
  
  @DomName('VTTCue.text')
  @DocsEditable()
  @Experimental() // untriaged
  String get text => _blink.BlinkVTTCue.instance.text_Getter_(unwrap_jso(this));
  
  @DomName('VTTCue.text')
  @DocsEditable()
  @Experimental() // untriaged
  set text(String value) => _blink.BlinkVTTCue.instance.text_Setter_(unwrap_jso(this), value);
  
  @DomName('VTTCue.vertical')
  @DocsEditable()
  @Experimental() // untriaged
  String get vertical => _blink.BlinkVTTCue.instance.vertical_Getter_(unwrap_jso(this));
  
  @DomName('VTTCue.vertical')
  @DocsEditable()
  @Experimental() // untriaged
  set vertical(String value) => _blink.BlinkVTTCue.instance.vertical_Setter_(unwrap_jso(this), value);
  
  @DomName('VTTCue.getCueAsHTML')
  @DocsEditable()
  @Experimental() // untriaged
  DocumentFragment getCueAsHtml() => wrap_jso(_blink.BlinkVTTCue.instance.getCueAsHTML_Callback_0_(unwrap_jso(this)));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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 wrap_jso(_blink.BlinkVTTRegion.instance.constructorCallback_0_());
  }

  @Deprecated("Internal Use Only")
  static VttRegion internalCreateVttRegion() {
    return new VttRegion._internalWrap();
  }

  factory VttRegion._internalWrap() {
    return new VttRegion.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  @DomName('VTTRegion.height')
  @DocsEditable()
  @Experimental() // untriaged
  int get height => _blink.BlinkVTTRegion.instance.height_Getter_(unwrap_jso(this));
  
  @DomName('VTTRegion.height')
  @DocsEditable()
  @Experimental() // untriaged
  set height(int value) => _blink.BlinkVTTRegion.instance.height_Setter_(unwrap_jso(this), value);
  
  @DomName('VTTRegion.id')
  @DocsEditable()
  @Experimental() // untriaged
  String get id => _blink.BlinkVTTRegion.instance.id_Getter_(unwrap_jso(this));
  
  @DomName('VTTRegion.id')
  @DocsEditable()
  @Experimental() // untriaged
  set id(String value) => _blink.BlinkVTTRegion.instance.id_Setter_(unwrap_jso(this), value);
  
  @DomName('VTTRegion.regionAnchorX')
  @DocsEditable()
  @Experimental() // untriaged
  num get regionAnchorX => _blink.BlinkVTTRegion.instance.regionAnchorX_Getter_(unwrap_jso(this));
  
  @DomName('VTTRegion.regionAnchorX')
  @DocsEditable()
  @Experimental() // untriaged
  set regionAnchorX(num value) => _blink.BlinkVTTRegion.instance.regionAnchorX_Setter_(unwrap_jso(this), value);
  
  @DomName('VTTRegion.regionAnchorY')
  @DocsEditable()
  @Experimental() // untriaged
  num get regionAnchorY => _blink.BlinkVTTRegion.instance.regionAnchorY_Getter_(unwrap_jso(this));
  
  @DomName('VTTRegion.regionAnchorY')
  @DocsEditable()
  @Experimental() // untriaged
  set regionAnchorY(num value) => _blink.BlinkVTTRegion.instance.regionAnchorY_Setter_(unwrap_jso(this), value);
  
  @DomName('VTTRegion.scroll')
  @DocsEditable()
  @Experimental() // untriaged
  String get scroll => _blink.BlinkVTTRegion.instance.scroll_Getter_(unwrap_jso(this));
  
  @DomName('VTTRegion.scroll')
  @DocsEditable()
  @Experimental() // untriaged
  set scroll(String value) => _blink.BlinkVTTRegion.instance.scroll_Setter_(unwrap_jso(this), value);
  
  @DomName('VTTRegion.track')
  @DocsEditable()
  @Experimental() // untriaged
  TextTrack get track => wrap_jso(_blink.BlinkVTTRegion.instance.track_Getter_(unwrap_jso(this)));
  
  @DomName('VTTRegion.viewportAnchorX')
  @DocsEditable()
  @Experimental() // untriaged
  num get viewportAnchorX => _blink.BlinkVTTRegion.instance.viewportAnchorX_Getter_(unwrap_jso(this));
  
  @DomName('VTTRegion.viewportAnchorX')
  @DocsEditable()
  @Experimental() // untriaged
  set viewportAnchorX(num value) => _blink.BlinkVTTRegion.instance.viewportAnchorX_Setter_(unwrap_jso(this), value);
  
  @DomName('VTTRegion.viewportAnchorY')
  @DocsEditable()
  @Experimental() // untriaged
  num get viewportAnchorY => _blink.BlinkVTTRegion.instance.viewportAnchorY_Getter_(unwrap_jso(this));
  
  @DomName('VTTRegion.viewportAnchorY')
  @DocsEditable()
  @Experimental() // untriaged
  set viewportAnchorY(num value) => _blink.BlinkVTTRegion.instance.viewportAnchorY_Setter_(unwrap_jso(this), value);
  
  @DomName('VTTRegion.width')
  @DocsEditable()
  @Experimental() // untriaged
  num get width => _blink.BlinkVTTRegion.instance.width_Getter_(unwrap_jso(this));
  
  @DomName('VTTRegion.width')
  @DocsEditable()
  @Experimental() // untriaged
  set width(num value) => _blink.BlinkVTTRegion.instance.width_Setter_(unwrap_jso(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")
  static VttRegionList internalCreateVttRegionList() {
    return new VttRegionList._internalWrap();
  }

  factory VttRegionList._internalWrap() {
    return new VttRegionList.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  @DomName('VTTRegionList.length')
  @DocsEditable()
  @Experimental() // untriaged
  int get length => _blink.BlinkVTTRegionList.instance.length_Getter_(unwrap_jso(this));
  
  @DomName('VTTRegionList.getRegionById')
  @DocsEditable()
  @Experimental() // untriaged
  VttRegion getRegionById(String id) => wrap_jso(_blink.BlinkVTTRegionList.instance.getRegionById_Callback_1_(unwrap_jso(this), id));
  
  @DomName('VTTRegionList.item')
  @DocsEditable()
  @Experimental() // untriaged
  VttRegion item(int index) => wrap_jso(_blink.BlinkVTTRegionList.instance.item_Callback_1_(unwrap_jso(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 wrap_jso(_blink.BlinkWebSocket.instance.constructorCallback_2_(url, protocols));
    }
    return wrap_jso(_blink.BlinkWebSocket.instance.constructorCallback_1_(url));
  }


  @Deprecated("Internal Use Only")
  static WebSocket internalCreateWebSocket() {
    return new WebSocket._internalWrap();
  }

  external factory WebSocket._internalWrap();

  @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_(unwrap_jso(this));
  
  @DomName('WebSocket.binaryType')
  @DocsEditable()
  set binaryType(String value) => _blink.BlinkWebSocket.instance.binaryType_Setter_(unwrap_jso(this), value);
  
  @DomName('WebSocket.bufferedAmount')
  @DocsEditable()
  int get bufferedAmount => _blink.BlinkWebSocket.instance.bufferedAmount_Getter_(unwrap_jso(this));
  
  @DomName('WebSocket.extensions')
  @DocsEditable()
  String get extensions => _blink.BlinkWebSocket.instance.extensions_Getter_(unwrap_jso(this));
  
  @DomName('WebSocket.protocol')
  @DocsEditable()
  String get protocol => _blink.BlinkWebSocket.instance.protocol_Getter_(unwrap_jso(this));
  
  @DomName('WebSocket.readyState')
  @DocsEditable()
  int get readyState => _blink.BlinkWebSocket.instance.readyState_Getter_(unwrap_jso(this));
  
  @DomName('WebSocket.url')
  @DocsEditable()
  String get url => _blink.BlinkWebSocket.instance.url_Getter_(unwrap_jso(this));
  
  void close([int code, String reason]) {
    if (reason != null) {
      _blink.BlinkWebSocket.instance.close_Callback_2_(unwrap_jso(this), code, reason);
      return;
    }
    if (code != null) {
      _blink.BlinkWebSocket.instance.close_Callback_1_(unwrap_jso(this), code);
      return;
    }
    _blink.BlinkWebSocket.instance.close_Callback_0_(unwrap_jso(this));
    return;
  }

  void send(data) {
    if ((data is String)) {
      _blink.BlinkWebSocket.instance.send_Callback_1_(unwrap_jso(this), unwrap_jso(data));
      return;
    }
    if ((data is Blob)) {
      _blink.BlinkWebSocket.instance.send_Callback_1_(unwrap_jso(this), unwrap_jso(data));
      return;
    }
    if ((data is TypedData)) {
      _blink.BlinkWebSocket.instance.send_Callback_1_(unwrap_jso(this), unwrap_jso(data));
      return;
    }
    if ((data is ByteBuffer)) {
      _blink.BlinkWebSocket.instance.send_Callback_1_(unwrap_jso(this), unwrap_jso(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_(unwrap_jso(this), unwrap_jso(data));
  
  @DomName('WebSocket.sendByteBuffer')
  @DocsEditable()
  void sendByteBuffer(ByteBuffer data) => _blink.BlinkWebSocket.instance.send_Callback_1_(unwrap_jso(this), unwrap_jso(data));
  
  @DomName('WebSocket.sendString')
  @DocsEditable()
  void sendString(String data) => _blink.BlinkWebSocket.instance.send_Callback_1_(unwrap_jso(this), data);
  
  @DomName('WebSocket.sendTypedData')
  @DocsEditable()
  void sendTypedData(TypedData data) => _blink.BlinkWebSocket.instance.send_Callback_1_(unwrap_jso(this), unwrap_jso(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 wrap_jso(_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 wrap_jso(_blink.BlinkWheelEvent.instance.constructorCallback_2_(type, eventInitDict_1));
    }
    return wrap_jso(_blink.BlinkWheelEvent.instance.constructorCallback_1_(type));
  }


  @Deprecated("Internal Use Only")
  static WheelEvent internalCreateWheelEvent() {
    return new WheelEvent._internalWrap();
  }

  external factory WheelEvent._internalWrap();

  @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_(unwrap_jso(this));
  
  @DomName('WheelEvent.deltaX')
  @DocsEditable()
  num get _deltaX => _blink.BlinkWheelEvent.instance.deltaX_Getter_(unwrap_jso(this));
  
  @DomName('WheelEvent.deltaY')
  @DocsEditable()
  num get _deltaY => _blink.BlinkWheelEvent.instance.deltaY_Getter_(unwrap_jso(this));
  
  @DomName('WheelEvent.deltaZ')
  @DocsEditable()
  num get deltaZ => _blink.BlinkWheelEvent.instance.deltaZ_Getter_(unwrap_jso(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")
  static Window internalCreateWindow() {
    return new Window._internalWrap();
  }

  external factory Window._internalWrap();

  @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 => wrap_jso(_blink.BlinkWindow.instance.applicationCache_Getter_(unwrap_jso(this)));
  
  @DomName('Window.caches')
  @DocsEditable()
  @Experimental() // untriaged
  CacheStorage get caches => wrap_jso(_blink.BlinkWindow.instance.caches_Getter_(unwrap_jso(this)));
  
  @DomName('Window.closed')
  @DocsEditable()
  bool get closed => _blink.BlinkWindow.instance.closed_Getter_(unwrap_jso(this));
  
  @DomName('Window.console')
  @DocsEditable()
  Console get console => wrap_jso(_blink.BlinkWindow.instance.console_Getter_(unwrap_jso(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 => wrap_jso(_blink.BlinkWindow.instance.crypto_Getter_(unwrap_jso(this)));
  
  /// *Deprecated*.
  @DomName('Window.defaultStatus')
  @DocsEditable()
  @Experimental() // non-standard
  String get defaultStatus => _blink.BlinkWindow.instance.defaultStatus_Getter_(unwrap_jso(this));
  
  /// *Deprecated*.
  @DomName('Window.defaultStatus')
  @DocsEditable()
  @Experimental() // non-standard
  set defaultStatus(String value) => _blink.BlinkWindow.instance.defaultStatus_Setter_(unwrap_jso(this), value);
  
  /// *Deprecated*.
  @DomName('Window.defaultstatus')
  @DocsEditable()
  @Experimental() // non-standard
  String get defaultstatus => _blink.BlinkWindow.instance.defaultstatus_Getter_(unwrap_jso(this));
  
  /// *Deprecated*.
  @DomName('Window.defaultstatus')
  @DocsEditable()
  @Experimental() // non-standard
  set defaultstatus(String value) => _blink.BlinkWindow.instance.defaultstatus_Setter_(unwrap_jso(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_(unwrap_jso(this));
  
  @DomName('Window.document')
  @DocsEditable()
  Document get document => wrap_jso(_blink.BlinkWindow.instance.document_Getter_(unwrap_jso(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 => wrap_jso(_blink.BlinkWindow.instance.history_Getter_(unwrap_jso(this)));
  
  @DomName('Window.indexedDB')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.FIREFOX, '15')
  @SupportedBrowser(SupportedBrowser.IE, '10')
  @Experimental()
  IdbFactory get indexedDB => wrap_jso(_blink.BlinkWindow.instance.indexedDB_Getter_(unwrap_jso(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_(unwrap_jso(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_(unwrap_jso(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 => wrap_jso(_blink.BlinkWindow.instance.localStorage_Getter_(unwrap_jso(this)));
  
  @DomName('Window.location')
  @DocsEditable()
  Location get location => wrap_jso(_blink.BlinkWindow.instance.location_Getter_(unwrap_jso(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 => wrap_jso(_blink.BlinkWindow.instance.locationbar_Getter_(unwrap_jso(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 => wrap_jso(_blink.BlinkWindow.instance.menubar_Getter_(unwrap_jso(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_(unwrap_jso(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_(unwrap_jso(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 => wrap_jso(_blink.BlinkWindow.instance.navigator_Getter_(unwrap_jso(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_(unwrap_jso(this));
  
  @DomName('Window.opener')
  @DocsEditable()
  WindowBase get opener => wrap_jso(_blink.BlinkWindow.instance.opener_Getter_(unwrap_jso(this)));
  
  @DomName('Window.opener')
  @DocsEditable()
  set opener(Window value) => _blink.BlinkWindow.instance.opener_Setter_(unwrap_jso(this), unwrap_jso(value));
  
  @DomName('Window.orientation')
  @DocsEditable()
  @Experimental() // untriaged
  int get orientation => _blink.BlinkWindow.instance.orientation_Getter_(unwrap_jso(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_(unwrap_jso(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_(unwrap_jso(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_(unwrap_jso(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_(unwrap_jso(this));
  
  @DomName('Window.parent')
  @DocsEditable()
  WindowBase get parent => wrap_jso(_blink.BlinkWindow.instance.parent_Getter_(unwrap_jso(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 => wrap_jso(_blink.BlinkWindow.instance.performance_Getter_(unwrap_jso(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 => wrap_jso(_blink.BlinkWindow.instance.screen_Getter_(unwrap_jso(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_(unwrap_jso(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_(unwrap_jso(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_(unwrap_jso(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_(unwrap_jso(this));
  
  @DomName('Window.scrollX')
  @DocsEditable()
  num get _scrollX => _blink.BlinkWindow.instance.scrollX_Getter_(unwrap_jso(this));
  
  @DomName('Window.scrollY')
  @DocsEditable()
  num get _scrollY => _blink.BlinkWindow.instance.scrollY_Getter_(unwrap_jso(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 => wrap_jso(_blink.BlinkWindow.instance.scrollbars_Getter_(unwrap_jso(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 => wrap_jso(_blink.BlinkWindow.instance.self_Getter_(unwrap_jso(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 => wrap_jso(_blink.BlinkWindow.instance.sessionStorage_Getter_(unwrap_jso(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 => wrap_jso(_blink.BlinkWindow.instance.speechSynthesis_Getter_(unwrap_jso(this)));
  
  /// *Deprecated*.
  @DomName('Window.status')
  @DocsEditable()
  String get status => _blink.BlinkWindow.instance.status_Getter_(unwrap_jso(this));
  
  /// *Deprecated*.
  @DomName('Window.status')
  @DocsEditable()
  set status(String value) => _blink.BlinkWindow.instance.status_Setter_(unwrap_jso(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 => wrap_jso(_blink.BlinkWindow.instance.statusbar_Getter_(unwrap_jso(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 => wrap_jso(_blink.BlinkWindow.instance.styleMedia_Getter_(unwrap_jso(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 => wrap_jso(_blink.BlinkWindow.instance.toolbar_Getter_(unwrap_jso(this)));
  
  @DomName('Window.top')
  @DocsEditable()
  WindowBase get top => wrap_jso(_blink.BlinkWindow.instance.top_Getter_(unwrap_jso(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 => wrap_jso(_blink.BlinkWindow.instance.window_Getter_(unwrap_jso(this)));
  
  WindowBase __getter__(index_OR_name) {
    if ((index_OR_name is int)) {
      return wrap_jso(_blink.BlinkWindow.instance.$__getter___Callback_1_(unwrap_jso(this), unwrap_jso(index_OR_name)));
    }
    if ((index_OR_name is String)) {
      return wrap_jso(_blink.BlinkWindow.instance.$__getter___Callback_1_(unwrap_jso(this), unwrap_jso(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_(unwrap_jso(this), message);
      return;
    }
    _blink.BlinkWindow.instance.alert_Callback_0_(unwrap_jso(this));
    return;
  }

  @DomName('Window.cancelAnimationFrame')
  @DocsEditable()
  void cancelAnimationFrame(int handle) => _blink.BlinkWindow.instance.cancelAnimationFrame_Callback_1_(unwrap_jso(this), handle);
  
  @DomName('Window.close')
  @DocsEditable()
  void close() => _blink.BlinkWindow.instance.close_Callback_0_(unwrap_jso(this));
  
  bool confirm([String message]) {
    if (message != null) {
      return _blink.BlinkWindow.instance.confirm_Callback_1_(unwrap_jso(this), message);
    }
    return _blink.BlinkWindow.instance.confirm_Callback_0_(unwrap_jso(this));
  }

  Future fetch(/*RequestInfo*/ input, [Map init]) {
    if (init != null) {
      return wrap_jso(_blink.BlinkWindow.instance.fetch_Callback_2_(unwrap_jso(this), input, convertDartToNative_Dictionary(init)));
    }
    return wrap_jso(_blink.BlinkWindow.instance.fetch_Callback_1_(unwrap_jso(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_(unwrap_jso(this), string, caseSensitive, backwards, wrap, wholeWord, searchInFrames, showDialog);
  
  @DomName('Window.getComputedStyle')
  @DocsEditable()
  CssStyleDeclaration _getComputedStyle(Element elt, String pseudoElt) => wrap_jso(_blink.BlinkWindow.instance.getComputedStyle_Callback_2_(unwrap_jso(this), unwrap_jso(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) => wrap_jso(_blink.BlinkWindow.instance.getMatchedCSSRules_Callback_2_(unwrap_jso(this), unwrap_jso(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() => wrap_jso(_blink.BlinkWindow.instance.getSelection_Callback_0_(unwrap_jso(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) => wrap_jso(_blink.BlinkWindow.instance.matchMedia_Callback_1_(unwrap_jso(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_(unwrap_jso(this), x, y);
  
  @DomName('Window.moveTo')
  @DocsEditable()
  void _moveTo(int x, int y) => _blink.BlinkWindow.instance.moveTo_Callback_2_(unwrap_jso(this), x, y);
  
  @DomName('Window.open')
  @DocsEditable()
  WindowBase open(String url, String target, [String features]) => wrap_jso(_blink.BlinkWindow.instance.open_Callback_3_(unwrap_jso(this), url, target, features));
  
  SqlDatabase openDatabase(String name, String version, String displayName, int estimatedSize, [DatabaseCallback creationCallback]) {
    if (creationCallback != null) {
      return wrap_jso(_blink.BlinkWindow.instance.openDatabase_Callback_5_(unwrap_jso(this), name, version, displayName, estimatedSize, unwrap_jso((database) => creationCallback(wrap_jso(database)))));
    }
    return wrap_jso(_blink.BlinkWindow.instance.openDatabase_Callback_4_(unwrap_jso(this), name, version, displayName, estimatedSize));
  }

  @DomName('Window.postMessage')
  @DocsEditable()
  void postMessage(Object message, String targetOrigin, [List<MessagePort> transfer]) => _blink.BlinkWindow.instance.postMessage_Callback_3_(unwrap_jso(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_(unwrap_jso(this));
  
  @DomName('Window.requestAnimationFrame')
  @DocsEditable()
  int _requestAnimationFrame(FrameRequestCallback callback) => _blink.BlinkWindow.instance.requestAnimationFrame_Callback_1_(unwrap_jso(this), unwrap_jso((highResTime) => callback(highResTime)));
  
  /**
   * 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_(unwrap_jso(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_(unwrap_jso(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_(unwrap_jso(this));
      return;
    }
    if ((options_OR_x is Map) && y == null && scrollOptions == null) {
      _blink.BlinkWindow.instance.scroll_Callback_1_(unwrap_jso(this), unwrap_jso(options_OR_x));
      return;
    }
    if ((y is num) && (options_OR_x is num) && scrollOptions == null) {
      _blink.BlinkWindow.instance.scroll_Callback_2_(unwrap_jso(this), unwrap_jso(options_OR_x), unwrap_jso(y));
      return;
    }
    if ((y is int) && (options_OR_x is int) && scrollOptions == null) {
      _blink.BlinkWindow.instance.scroll_Callback_2_(unwrap_jso(this), unwrap_jso(options_OR_x), unwrap_jso(y));
      return;
    }
    if ((scrollOptions is Map) && (y is int) && (options_OR_x is int)) {
      _blink.BlinkWindow.instance.scroll_Callback_3_(unwrap_jso(this), unwrap_jso(options_OR_x), unwrap_jso(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_(unwrap_jso(this));
      return;
    }
    if ((options_OR_x is Map) && y == null && scrollOptions == null) {
      _blink.BlinkWindow.instance.scrollBy_Callback_1_(unwrap_jso(this), unwrap_jso(options_OR_x));
      return;
    }
    if ((y is num) && (options_OR_x is num) && scrollOptions == null) {
      _blink.BlinkWindow.instance.scrollBy_Callback_2_(unwrap_jso(this), unwrap_jso(options_OR_x), unwrap_jso(y));
      return;
    }
    if ((y is int) && (options_OR_x is int) && scrollOptions == null) {
      _blink.BlinkWindow.instance.scrollBy_Callback_2_(unwrap_jso(this), unwrap_jso(options_OR_x), unwrap_jso(y));
      return;
    }
    if ((scrollOptions is Map) && (y is int) && (options_OR_x is int)) {
      _blink.BlinkWindow.instance.scrollBy_Callback_3_(unwrap_jso(this), unwrap_jso(options_OR_x), unwrap_jso(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_(unwrap_jso(this));
      return;
    }
    if ((options_OR_x is Map) && y == null && scrollOptions == null) {
      _blink.BlinkWindow.instance.scrollTo_Callback_1_(unwrap_jso(this), unwrap_jso(options_OR_x));
      return;
    }
    if ((y is num) && (options_OR_x is num) && scrollOptions == null) {
      _blink.BlinkWindow.instance.scrollTo_Callback_2_(unwrap_jso(this), unwrap_jso(options_OR_x), unwrap_jso(y));
      return;
    }
    if ((y is int) && (options_OR_x is int) && scrollOptions == null) {
      _blink.BlinkWindow.instance.scrollTo_Callback_2_(unwrap_jso(this), unwrap_jso(options_OR_x), unwrap_jso(y));
      return;
    }
    if ((scrollOptions is Map) && (y is int) && (options_OR_x is int)) {
      _blink.BlinkWindow.instance.scrollTo_Callback_3_(unwrap_jso(this), unwrap_jso(options_OR_x), unwrap_jso(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_(unwrap_jso(this));
  
  void __requestFileSystem(int type, int size, _FileSystemCallback successCallback, [_ErrorCallback errorCallback]) {
    if (errorCallback != null) {
      _blink.BlinkWindow.instance.webkitRequestFileSystem_Callback_4_(unwrap_jso(this), type, size, unwrap_jso((fileSystem) => successCallback(wrap_jso(fileSystem))), unwrap_jso((error) => errorCallback(wrap_jso(error))));
      return;
    }
    _blink.BlinkWindow.instance.webkitRequestFileSystem_Callback_3_(unwrap_jso(this), type, size, unwrap_jso((fileSystem) => successCallback(wrap_jso(fileSystem))));
    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_(unwrap_jso(this), url, unwrap_jso((entry) => successCallback(wrap_jso(entry))), unwrap_jso((error) => errorCallback(wrap_jso(error))));
      return;
    }
    _blink.BlinkWindow.instance.webkitResolveLocalFileSystemURL_Callback_2_(unwrap_jso(this), url, unwrap_jso((entry) => successCallback(wrap_jso(entry))));
    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_(unwrap_jso(this), atob);
  
  @DomName('Window.btoa')
  @DocsEditable()
  String btoa(String btoa) => _blink.BlinkWindow.instance.btoa_Callback_1_(unwrap_jso(this), btoa);
  
  int _setInterval_String(String handler, [int timeout, Object arguments]) {
    if (timeout != null) {
      return _blink.BlinkWindow.instance.setInterval_Callback_3_(unwrap_jso(this), handler, timeout, arguments);
    }
    return _blink.BlinkWindow.instance.setInterval_Callback_1_(unwrap_jso(this), handler);
  }

  int _setTimeout_String(String handler, [int timeout, Object arguments]) {
    if (timeout != null) {
      return _blink.BlinkWindow.instance.setTimeout_Callback_3_(unwrap_jso(this), handler, timeout, arguments);
    }
    return _blink.BlinkWindow.instance.setTimeout_Callback_1_(unwrap_jso(this), handler);
  }

  void _clearInterval([int handle]) {
    if (handle != null) {
      _blink.BlinkWindow.instance.clearInterval_Callback_1_(unwrap_jso(this), handle);
      return;
    }
    _blink.BlinkWindow.instance.clearInterval_Callback_0_(unwrap_jso(this));
    return;
  }

  void _clearTimeout([int handle]) {
    if (handle != null) {
      _blink.BlinkWindow.instance.clearTimeout_Callback_1_(unwrap_jso(this), handle);
      return;
    }
    _blink.BlinkWindow.instance.clearTimeout_Callback_0_(unwrap_jso(this));
    return;
  }

  int _setInterval(Object handler, [int timeout]) {
    if (timeout != null) {
      return _blink.BlinkWindow.instance.setInterval_Callback_2_(unwrap_jso(this), handler, timeout);
    }
    return _blink.BlinkWindow.instance.setInterval_Callback_1_(unwrap_jso(this), handler);
  }

  int _setTimeout(Object handler, [int timeout]) {
    if (timeout != null) {
      return _blink.BlinkWindow.instance.setTimeout_Callback_2_(unwrap_jso(this), handler, timeout);
    }
    return _blink.BlinkWindow.instance.setTimeout_Callback_1_(unwrap_jso(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_(unwrap_jso(this)).round();

  @DomName('Window.pageYOffset')
  @DocsEditable()
  int get pageYOffset => _blink.BlinkWindow.instance.pageYOffset_Getter_(unwrap_jso(this)).round();

  @DomName('Window.scrollX')
  @DocsEditable()
  int get scrollX => _blink.BlinkWindow.instance.scrollX_Getter_(unwrap_jso(this)).round();

  @DomName('Window.scrollY')
  @DocsEditable()
  int get scrollY => _blink.BlinkWindow.instance.scrollY_Getter_(unwrap_jso(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")
  static WindowClient internalCreateWindowClient() {
    return new WindowClient._internalWrap();
  }

  external factory WindowClient._internalWrap();

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


  @DomName('WindowClient.focused')
  @DocsEditable()
  @Experimental() // untriaged
  bool get focused => _blink.BlinkWindowClient.instance.focused_Getter_(unwrap_jso(this));
  
  @DomName('WindowClient.visibilityState')
  @DocsEditable()
  @Experimental() // untriaged
  String get visibilityState => _blink.BlinkWindowClient.instance.visibilityState_Getter_(unwrap_jso(this));
  
  @DomName('WindowClient.focus')
  @DocsEditable()
  @Experimental() // untriaged
  Future focus() => wrap_jso(_blink.BlinkWindowClient.instance.focus_Callback_0_(unwrap_jso(this)));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All 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 wrap_jso(_blink.BlinkWorker.instance.constructorCallback_1_(scriptUrl));
  }


  @Deprecated("Internal Use Only")
  static Worker internalCreateWorker() {
    return new Worker._internalWrap();
  }

  external factory Worker._internalWrap();

  @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_(unwrap_jso(this), convertDartToNative_SerializedScriptValue(message), transfer);
      return;
    }
    _blink.BlinkWorker.instance.postMessage_Callback_1_(unwrap_jso(this), convertDartToNative_SerializedScriptValue(message));
    return;
  }

  @DomName('Worker.terminate')
  @DocsEditable()
  void terminate() => _blink.BlinkWorker.instance.terminate_Callback_0_(unwrap_jso(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")
  static WorkerConsole internalCreateWorkerConsole() {
    return new WorkerConsole._internalWrap();
  }

  external factory WorkerConsole._internalWrap();

  @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")
  static WorkerGlobalScope internalCreateWorkerGlobalScope() {
    return new WorkerGlobalScope._internalWrap();
  }

  external factory WorkerGlobalScope._internalWrap();

  @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 => wrap_jso(_blink.BlinkWorkerGlobalScope.instance.caches_Getter_(unwrap_jso(this)));
  
  @DomName('WorkerGlobalScope.console')
  @DocsEditable()
  @Experimental() // untriaged
  WorkerConsole get console => wrap_jso(_blink.BlinkWorkerGlobalScope.instance.console_Getter_(unwrap_jso(this)));
  
  @DomName('WorkerGlobalScope.crypto')
  @DocsEditable()
  @Experimental() // untriaged
  Crypto get crypto => wrap_jso(_blink.BlinkWorkerGlobalScope.instance.crypto_Getter_(unwrap_jso(this)));
  
  @DomName('WorkerGlobalScope.indexedDB')
  @DocsEditable()
  @Experimental() // untriaged
  IdbFactory get indexedDB => wrap_jso(_blink.BlinkWorkerGlobalScope.instance.indexedDB_Getter_(unwrap_jso(this)));
  
  @DomName('WorkerGlobalScope.location')
  @DocsEditable()
  @Experimental() // untriaged
  _WorkerLocation get location => wrap_jso(_blink.BlinkWorkerGlobalScope.instance.location_Getter_(unwrap_jso(this)));
  
  @DomName('WorkerGlobalScope.navigator')
  @DocsEditable()
  @Experimental() // untriaged
  _WorkerNavigator get navigator => wrap_jso(_blink.BlinkWorkerGlobalScope.instance.navigator_Getter_(unwrap_jso(this)));
  
  @DomName('WorkerGlobalScope.performance')
  @DocsEditable()
  @Experimental() // untriaged
  WorkerPerformance get performance => wrap_jso(_blink.BlinkWorkerGlobalScope.instance.performance_Getter_(unwrap_jso(this)));
  
  @DomName('WorkerGlobalScope.self')
  @DocsEditable()
  @Experimental() // untriaged
  WorkerGlobalScope get self => wrap_jso(_blink.BlinkWorkerGlobalScope.instance.self_Getter_(unwrap_jso(this)));
  
  @DomName('WorkerGlobalScope.close')
  @DocsEditable()
  @Experimental() // untriaged
  void close() => _blink.BlinkWorkerGlobalScope.instance.close_Callback_0_(unwrap_jso(this));
  
  Future fetch(/*RequestInfo*/ input, [Map init]) {
    if (init != null) {
      return wrap_jso(_blink.BlinkWorkerGlobalScope.instance.fetch_Callback_2_(unwrap_jso(this), input, convertDartToNative_Dictionary(init)));
    }
    return wrap_jso(_blink.BlinkWorkerGlobalScope.instance.fetch_Callback_1_(unwrap_jso(this), input));
  }

  @DomName('WorkerGlobalScope.importScripts')
  @DocsEditable()
  @Experimental() // untriaged
  void importScripts(String urls) => _blink.BlinkWorkerGlobalScope.instance.importScripts_Callback_1_(unwrap_jso(this), urls);
  
  void _webkitRequestFileSystem(int type, int size, [_FileSystemCallback successCallback, _ErrorCallback errorCallback]) {
    if (errorCallback != null) {
      _blink.BlinkWorkerGlobalScope.instance.webkitRequestFileSystem_Callback_4_(unwrap_jso(this), type, size, unwrap_jso((fileSystem) => successCallback(wrap_jso(fileSystem))), unwrap_jso((error) => errorCallback(wrap_jso(error))));
      return;
    }
    if (successCallback != null) {
      _blink.BlinkWorkerGlobalScope.instance.webkitRequestFileSystem_Callback_3_(unwrap_jso(this), type, size, unwrap_jso((fileSystem) => successCallback(wrap_jso(fileSystem))));
      return;
    }
    _blink.BlinkWorkerGlobalScope.instance.webkitRequestFileSystem_Callback_2_(unwrap_jso(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) => wrap_jso(_blink.BlinkWorkerGlobalScope.instance.webkitRequestFileSystemSync_Callback_2_(unwrap_jso(this), type, size));
  
  @DomName('WorkerGlobalScope.webkitResolveLocalFileSystemSyncURL')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  @Experimental() // untriaged
  _EntrySync resolveLocalFileSystemSyncUrl(String url) => wrap_jso(_blink.BlinkWorkerGlobalScope.instance.webkitResolveLocalFileSystemSyncURL_Callback_1_(unwrap_jso(this), url));
  
  void _webkitResolveLocalFileSystemUrl(String url, _EntryCallback successCallback, [_ErrorCallback errorCallback]) {
    if (errorCallback != null) {
      _blink.BlinkWorkerGlobalScope.instance.webkitResolveLocalFileSystemURL_Callback_3_(unwrap_jso(this), url, unwrap_jso((entry) => successCallback(wrap_jso(entry))), unwrap_jso((error) => errorCallback(wrap_jso(error))));
      return;
    }
    _blink.BlinkWorkerGlobalScope.instance.webkitResolveLocalFileSystemURL_Callback_2_(unwrap_jso(this), url, unwrap_jso((entry) => successCallback(wrap_jso(entry))));
    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_(unwrap_jso(this), atob);
  
  @DomName('WorkerGlobalScope.btoa')
  @DocsEditable()
  @Experimental() // untriaged
  String btoa(String btoa) => _blink.BlinkWorkerGlobalScope.instance.btoa_Callback_1_(unwrap_jso(this), btoa);
  
  int _setInterval_String(String handler, [int timeout, Object arguments]) {
    if (timeout != null) {
      return _blink.BlinkWorkerGlobalScope.instance.setInterval_Callback_3_(unwrap_jso(this), handler, timeout, arguments);
    }
    return _blink.BlinkWorkerGlobalScope.instance.setInterval_Callback_1_(unwrap_jso(this), handler);
  }

  int _setTimeout_String(String handler, [int timeout, Object arguments]) {
    if (timeout != null) {
      return _blink.BlinkWorkerGlobalScope.instance.setTimeout_Callback_3_(unwrap_jso(this), handler, timeout, arguments);
    }
    return _blink.BlinkWorkerGlobalScope.instance.setTimeout_Callback_1_(unwrap_jso(this), handler);
  }

  void _clearInterval([int handle]) {
    if (handle != null) {
      _blink.BlinkWorkerGlobalScope.instance.clearInterval_Callback_1_(unwrap_jso(this), handle);
      return;
    }
    _blink.BlinkWorkerGlobalScope.instance.clearInterval_Callback_0_(unwrap_jso(this));
    return;
  }

  void _clearTimeout([int handle]) {
    if (handle != null) {
      _blink.BlinkWorkerGlobalScope.instance.clearTimeout_Callback_1_(unwrap_jso(this), handle);
      return;
    }
    _blink.BlinkWorkerGlobalScope.instance.clearTimeout_Callback_0_(unwrap_jso(this));
    return;
  }

  int _setInterval(Object handler, [int timeout]) {
    if (timeout != null) {
      return _blink.BlinkWorkerGlobalScope.instance.setInterval_Callback_2_(unwrap_jso(this), handler, timeout);
    }
    return _blink.BlinkWorkerGlobalScope.instance.setInterval_Callback_1_(unwrap_jso(this), handler);
  }

  int _setTimeout(Object handler, [int timeout]) {
    if (timeout != null) {
      return _blink.BlinkWorkerGlobalScope.instance.setTimeout_Callback_2_(unwrap_jso(this), handler, timeout);
    }
    return _blink.BlinkWorkerGlobalScope.instance.setTimeout_Callback_1_(unwrap_jso(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")
  static WorkerPerformance internalCreateWorkerPerformance() {
    return new WorkerPerformance._internalWrap();
  }

  external factory WorkerPerformance._internalWrap();

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


  @DomName('WorkerPerformance.memory')
  @DocsEditable()
  @Experimental() // untriaged
  MemoryInfo get memory => wrap_jso(_blink.BlinkWorkerPerformance.instance.memory_Getter_(unwrap_jso(this)));
  
  @DomName('WorkerPerformance.clearMarks')
  @DocsEditable()
  @Experimental() // untriaged
  void clearMarks(String markName) => _blink.BlinkWorkerPerformance.instance.clearMarks_Callback_1_(unwrap_jso(this), markName);
  
  @DomName('WorkerPerformance.clearMeasures')
  @DocsEditable()
  @Experimental() // untriaged
  void clearMeasures(String measureName) => _blink.BlinkWorkerPerformance.instance.clearMeasures_Callback_1_(unwrap_jso(this), measureName);
  
  @DomName('WorkerPerformance.getEntries')
  @DocsEditable()
  @Experimental() // untriaged
  List<PerformanceEntry> getEntries() => wrap_jso(_blink.BlinkWorkerPerformance.instance.getEntries_Callback_0_(unwrap_jso(this)));
  
  @DomName('WorkerPerformance.getEntriesByName')
  @DocsEditable()
  @Experimental() // untriaged
  List<PerformanceEntry> getEntriesByName(String name, String entryType) => wrap_jso(_blink.BlinkWorkerPerformance.instance.getEntriesByName_Callback_2_(unwrap_jso(this), name, entryType));
  
  @DomName('WorkerPerformance.getEntriesByType')
  @DocsEditable()
  @Experimental() // untriaged
  List<PerformanceEntry> getEntriesByType(String entryType) => wrap_jso(_blink.BlinkWorkerPerformance.instance.getEntriesByType_Callback_1_(unwrap_jso(this), entryType));
  
  @DomName('WorkerPerformance.mark')
  @DocsEditable()
  @Experimental() // untriaged
  void mark(String markName) => _blink.BlinkWorkerPerformance.instance.mark_Callback_1_(unwrap_jso(this), markName);
  
  @DomName('WorkerPerformance.measure')
  @DocsEditable()
  @Experimental() // untriaged
  void measure(String measureName, String startMark, String endMark) => _blink.BlinkWorkerPerformance.instance.measure_Callback_3_(unwrap_jso(this), measureName, startMark, endMark);
  
  @DomName('WorkerPerformance.now')
  @DocsEditable()
  @Experimental() // untriaged
  num now() => _blink.BlinkWorkerPerformance.instance.now_Callback_0_(unwrap_jso(this));
  
  @DomName('WorkerPerformance.webkitClearResourceTimings')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  @Experimental() // untriaged
  void clearResourceTimings() => _blink.BlinkWorkerPerformance.instance.webkitClearResourceTimings_Callback_0_(unwrap_jso(this));
  
  @DomName('WorkerPerformance.webkitSetResourceTimingBufferSize')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  @Experimental() // untriaged
  void setResourceTimingBufferSize(int maxSize) => _blink.BlinkWorkerPerformance.instance.webkitSetResourceTimingBufferSize_Callback_1_(unwrap_jso(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 wrap_jso(_blink.BlinkXPathEvaluator.instance.constructorCallback_0_());
  }

  @Deprecated("Internal Use Only")
  static XPathEvaluator internalCreateXPathEvaluator() {
    return new XPathEvaluator._internalWrap();
  }

  factory XPathEvaluator._internalWrap() {
    return new XPathEvaluator.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  @DomName('XPathEvaluator.createExpression')
  @DocsEditable()
  XPathExpression createExpression(String expression, XPathNSResolver resolver) => wrap_jso(_blink.BlinkXPathEvaluator.instance.createExpression_Callback_2_(unwrap_jso(this), expression, unwrap_jso(resolver)));
  
  @DomName('XPathEvaluator.createNSResolver')
  @DocsEditable()
  XPathNSResolver createNSResolver(Node nodeResolver) => wrap_jso(_blink.BlinkXPathEvaluator.instance.createNSResolver_Callback_1_(unwrap_jso(this), unwrap_jso(nodeResolver)));
  
  XPathResult evaluate(String expression, Node contextNode, XPathNSResolver resolver, [int type, Object inResult]) {
    if (type != null) {
      return wrap_jso(_blink.BlinkXPathEvaluator.instance.evaluate_Callback_5_(unwrap_jso(this), expression, unwrap_jso(contextNode), unwrap_jso(resolver), type, inResult));
    }
    return wrap_jso(_blink.BlinkXPathEvaluator.instance.evaluate_Callback_3_(unwrap_jso(this), expression, unwrap_jso(contextNode), unwrap_jso(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")
  static XPathExpression internalCreateXPathExpression() {
    return new XPathExpression._internalWrap();
  }

  factory XPathExpression._internalWrap() {
    return new XPathExpression.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  XPathResult evaluate(Node contextNode, [int type, Object inResult]) {
    if (type != null) {
      return wrap_jso(_blink.BlinkXPathExpression.instance.evaluate_Callback_3_(unwrap_jso(this), unwrap_jso(contextNode), type, inResult));
    }
    return wrap_jso(_blink.BlinkXPathExpression.instance.evaluate_Callback_1_(unwrap_jso(this), unwrap_jso(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")
  static XPathNSResolver internalCreateXPathNSResolver() {
    return new XPathNSResolver._internalWrap();
  }

  factory XPathNSResolver._internalWrap() {
    return new XPathNSResolver.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  @DomName('XPathNSResolver.lookupNamespaceURI')
  @DocsEditable()
  String lookupNamespaceUri(String prefix) => _blink.BlinkXPathNSResolver.instance.lookupNamespaceURI_Callback_1_(unwrap_jso(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")
  static XPathResult internalCreateXPathResult() {
    return new XPathResult._internalWrap();
  }

  factory XPathResult._internalWrap() {
    return new XPathResult.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  @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_(unwrap_jso(this));
  
  @DomName('XPathResult.invalidIteratorState')
  @DocsEditable()
  bool get invalidIteratorState => _blink.BlinkXPathResult.instance.invalidIteratorState_Getter_(unwrap_jso(this));
  
  @DomName('XPathResult.numberValue')
  @DocsEditable()
  num get numberValue => _blink.BlinkXPathResult.instance.numberValue_Getter_(unwrap_jso(this));
  
  @DomName('XPathResult.resultType')
  @DocsEditable()
  int get resultType => _blink.BlinkXPathResult.instance.resultType_Getter_(unwrap_jso(this));
  
  @DomName('XPathResult.singleNodeValue')
  @DocsEditable()
  Node get singleNodeValue => wrap_jso(_blink.BlinkXPathResult.instance.singleNodeValue_Getter_(unwrap_jso(this)));
  
  @DomName('XPathResult.snapshotLength')
  @DocsEditable()
  int get snapshotLength => _blink.BlinkXPathResult.instance.snapshotLength_Getter_(unwrap_jso(this));
  
  @DomName('XPathResult.stringValue')
  @DocsEditable()
  String get stringValue => _blink.BlinkXPathResult.instance.stringValue_Getter_(unwrap_jso(this));
  
  @DomName('XPathResult.iterateNext')
  @DocsEditable()
  Node iterateNext() => wrap_jso(_blink.BlinkXPathResult.instance.iterateNext_Callback_0_(unwrap_jso(this)));
  
  @DomName('XPathResult.snapshotItem')
  @DocsEditable()
  Node snapshotItem(int index) => wrap_jso(_blink.BlinkXPathResult.instance.snapshotItem_Callback_1_(unwrap_jso(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")
  static XmlDocument internalCreateXmlDocument() {
    return new XmlDocument._internalWrap();
  }

  external factory XmlDocument._internalWrap();

  @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 wrap_jso(_blink.BlinkXMLSerializer.instance.constructorCallback_0_());
  }

  @Deprecated("Internal Use Only")
  static XmlSerializer internalCreateXmlSerializer() {
    return new XmlSerializer._internalWrap();
  }

  factory XmlSerializer._internalWrap() {
    return new XmlSerializer.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  @DomName('XMLSerializer.serializeToString')
  @DocsEditable()
  String serializeToString(Node root) => _blink.BlinkXMLSerializer.instance.serializeToString_Callback_1_(unwrap_jso(this), unwrap_jso(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 wrap_jso(_blink.BlinkXSLTProcessor.instance.constructorCallback_0_());
  }

  @Deprecated("Internal Use Only")
  static XsltProcessor internalCreateXsltProcessor() {
    return new XsltProcessor._internalWrap();
  }

  factory XsltProcessor._internalWrap() {
    return new XsltProcessor.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  /// 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_(unwrap_jso(this));
  
  @DomName('XSLTProcessor.getParameter')
  @DocsEditable()
  String getParameter(String namespaceURI, String localName) => _blink.BlinkXSLTProcessor.instance.getParameter_Callback_2_(unwrap_jso(this), namespaceURI, localName);
  
  @DomName('XSLTProcessor.importStylesheet')
  @DocsEditable()
  void importStylesheet(Node style) => _blink.BlinkXSLTProcessor.instance.importStylesheet_Callback_1_(unwrap_jso(this), unwrap_jso(style));
  
  @DomName('XSLTProcessor.removeParameter')
  @DocsEditable()
  void removeParameter(String namespaceURI, String localName) => _blink.BlinkXSLTProcessor.instance.removeParameter_Callback_2_(unwrap_jso(this), namespaceURI, localName);
  
  @DomName('XSLTProcessor.reset')
  @DocsEditable()
  void reset() => _blink.BlinkXSLTProcessor.instance.reset_Callback_0_(unwrap_jso(this));
  
  @DomName('XSLTProcessor.setParameter')
  @DocsEditable()
  void setParameter(String namespaceURI, String localName, String value) => _blink.BlinkXSLTProcessor.instance.setParameter_Callback_3_(unwrap_jso(this), namespaceURI, localName, value);
  
  @DomName('XSLTProcessor.transformToDocument')
  @DocsEditable()
  Document transformToDocument(Node source) => wrap_jso(_blink.BlinkXSLTProcessor.instance.transformToDocument_Callback_1_(unwrap_jso(this), unwrap_jso(source)));
  
  @DomName('XSLTProcessor.transformToFragment')
  @DocsEditable()
  DocumentFragment transformToFragment(Node source, Document output) => wrap_jso(_blink.BlinkXSLTProcessor.instance.transformToFragment_Callback_2_(unwrap_jso(this), unwrap_jso(source), unwrap_jso(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")
  static _Attr internalCreate_Attr() {
    return new _Attr._internalWrap();
  }

  external factory _Attr._internalWrap();

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


  @DomName('Attr.localName')
  @DocsEditable()
  @Experimental() // untriaged
  String get _localName => _blink.BlinkAttr.instance.localName_Getter_(unwrap_jso(this));
  
  @DomName('Attr.name')
  @DocsEditable()
  String get name => _blink.BlinkAttr.instance.name_Getter_(unwrap_jso(this));
  
  @DomName('Attr.namespaceURI')
  @DocsEditable()
  @Experimental() // untriaged
  String get _namespaceUri => _blink.BlinkAttr.instance.namespaceURI_Getter_(unwrap_jso(this));
  
  @DomName('Attr.nodeValue')
  @DocsEditable()
  @Experimental() // untriaged
  String get nodeValue => _blink.BlinkAttr.instance.nodeValue_Getter_(unwrap_jso(this));
  
  @DomName('Attr.textContent')
  @DocsEditable()
  @Experimental() // untriaged
  String get text => _blink.BlinkAttr.instance.textContent_Getter_(unwrap_jso(this));
  
  @DomName('Attr.textContent')
  @DocsEditable()
  @Experimental() // untriaged
  set text(String value) => _blink.BlinkAttr.instance.textContent_Setter_(unwrap_jso(this), value);
  
  @DomName('Attr.value')
  @DocsEditable()
  String get value => _blink.BlinkAttr.instance.value_Getter_(unwrap_jso(this));
  
  @DomName('Attr.value')
  @DocsEditable()
  set value(String value) => _blink.BlinkAttr.instance.value_Setter_(unwrap_jso(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")
  static _Cache internalCreate_Cache() {
    return new _Cache._internalWrap();
  }

  factory _Cache._internalWrap() {
    return new _Cache.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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")
  static _ClientRect internalCreate_ClientRect() {
    return new _ClientRect._internalWrap();
  }

  factory _ClientRect._internalWrap() {
    return new _ClientRect.internal_();
  }

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


  @DomName('ClientRect.bottom')
  @DocsEditable()
  num get bottom => _blink.BlinkClientRect.instance.bottom_Getter_(unwrap_jso(this));
  
  @DomName('ClientRect.height')
  @DocsEditable()
  num get height => _blink.BlinkClientRect.instance.height_Getter_(unwrap_jso(this));
  
  @DomName('ClientRect.left')
  @DocsEditable()
  num get left => _blink.BlinkClientRect.instance.left_Getter_(unwrap_jso(this));
  
  @DomName('ClientRect.right')
  @DocsEditable()
  num get right => _blink.BlinkClientRect.instance.right_Getter_(unwrap_jso(this));
  
  @DomName('ClientRect.top')
  @DocsEditable()
  num get top => _blink.BlinkClientRect.instance.top_Getter_(unwrap_jso(this));
  
  @DomName('ClientRect.width')
  @DocsEditable()
  num get width => _blink.BlinkClientRect.instance.width_Getter_(unwrap_jso(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")
  static _ClientRectList internalCreate_ClientRectList() {
    return new _ClientRectList._internalWrap();
  }

  factory _ClientRectList._internalWrap() {
    return new _ClientRectList.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  @DomName('ClientRectList.length')
  @DocsEditable()
  int get length => _blink.BlinkClientRectList.instance.length_Getter_(unwrap_jso(this));
  
  Rectangle operator[](int index) {
    if (index < 0 || index >= length)
      throw new RangeError.index(index, this);
    return wrap_jso(_blink.BlinkClientRectList.instance.item_Callback_1_(unwrap_jso(this), index));
  }

  Rectangle _nativeIndexedGetter(int index) => wrap_jso(_blink.BlinkClientRectList.instance.item_Callback_1_(unwrap_jso(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_(unwrap_jso(this), index));
  
  @DomName('ClientRectList.item')
  @DocsEditable()
  Rectangle item(int index) => make_dart_rectangle(_blink.BlinkClientRectList.instance.item_Callback_1_(unwrap_jso(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")
  static _CssRuleList internalCreate_CssRuleList() {
    return new _CssRuleList._internalWrap();
  }

  factory _CssRuleList._internalWrap() {
    return new _CssRuleList.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  @DomName('CSSRuleList.length')
  @DocsEditable()
  int get length => _blink.BlinkCSSRuleList.instance.length_Getter_(unwrap_jso(this));
  
  CssRule operator[](int index) {
    if (index < 0 || index >= length)
      throw new RangeError.index(index, this);
    return wrap_jso(_blink.BlinkCSSRuleList.instance.item_Callback_1_(unwrap_jso(this), index));
  }

  CssRule _nativeIndexedGetter(int index) => wrap_jso(_blink.BlinkCSSRuleList.instance.item_Callback_1_(unwrap_jso(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) => wrap_jso(_blink.BlinkCSSRuleList.instance.item_Callback_1_(unwrap_jso(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")
  static _DOMFileSystemSync internalCreate_DOMFileSystemSync() {
    return new _DOMFileSystemSync._internalWrap();
  }

  factory _DOMFileSystemSync._internalWrap() {
    return new _DOMFileSystemSync.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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")
  static _DirectoryEntrySync internalCreate_DirectoryEntrySync() {
    return new _DirectoryEntrySync._internalWrap();
  }

  external factory _DirectoryEntrySync._internalWrap();

  @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")
  static _DirectoryReaderSync internalCreate_DirectoryReaderSync() {
    return new _DirectoryReaderSync._internalWrap();
  }

  factory _DirectoryReaderSync._internalWrap() {
    return new _DirectoryReaderSync.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All 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")
  static _DocumentType internalCreate_DocumentType() {
    return new _DocumentType._internalWrap();
  }

  external factory _DocumentType._internalWrap();

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


  // Override this methods for Dartium _DocumentType can't be abstract.
  Element get nextElementSibling => wrap_jso(_blink.BlinkDocumentType.instance.nextElementSibling_Getter_(unwrap_jso(this)));
  Element get previousElementSibling => wrap_jso(_blink.BlinkDocumentType.instance.previousElementSibling_Getter_(unwrap_jso(this)));
}

// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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 wrap_jso(_blink.BlinkDOMRect.instance.constructorCallback_4_(x, y, width, height));
    }
    if (width != null) {
      return wrap_jso(_blink.BlinkDOMRect.instance.constructorCallback_3_(x, y, width));
    }
    if (y != null) {
      return wrap_jso(_blink.BlinkDOMRect.instance.constructorCallback_2_(x, y));
    }
    if (x != null) {
      return wrap_jso(_blink.BlinkDOMRect.instance.constructorCallback_1_(x));
    }
    return wrap_jso(_blink.BlinkDOMRect.instance.constructorCallback_0_());
  }


  @Deprecated("Internal Use Only")
  static _DomRect internalCreate_DomRect() {
    return new _DomRect._internalWrap();
  }

  external factory _DomRect._internalWrap();

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


  @DomName('DOMRect.height')
  @DocsEditable()
  @Experimental() // untriaged
  num get height => _blink.BlinkDOMRect.instance.height_Getter_(unwrap_jso(this));
  
  @DomName('DOMRect.height')
  @DocsEditable()
  @Experimental() // untriaged
  set height(num value) => _blink.BlinkDOMRect.instance.height_Setter_(unwrap_jso(this), value);
  
  @DomName('DOMRect.width')
  @DocsEditable()
  @Experimental() // untriaged
  num get width => _blink.BlinkDOMRect.instance.width_Getter_(unwrap_jso(this));
  
  @DomName('DOMRect.width')
  @DocsEditable()
  @Experimental() // untriaged
  set width(num value) => _blink.BlinkDOMRect.instance.width_Setter_(unwrap_jso(this), value);
  
  @DomName('DOMRect.x')
  @DocsEditable()
  @Experimental() // untriaged
  num get x => _blink.BlinkDOMRect.instance.x_Getter_(unwrap_jso(this));
  
  @DomName('DOMRect.x')
  @DocsEditable()
  @Experimental() // untriaged
  set x(num value) => _blink.BlinkDOMRect.instance.x_Setter_(unwrap_jso(this), value);
  
  @DomName('DOMRect.y')
  @DocsEditable()
  @Experimental() // untriaged
  num get y => _blink.BlinkDOMRect.instance.y_Getter_(unwrap_jso(this));
  
  @DomName('DOMRect.y')
  @DocsEditable()
  @Experimental() // untriaged
  set y(num value) => _blink.BlinkDOMRect.instance.y_Setter_(unwrap_jso(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")
  static _EntrySync internalCreate_EntrySync() {
    return new _EntrySync._internalWrap();
  }

  factory _EntrySync._internalWrap() {
    return new _EntrySync.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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")
  static _FileEntrySync internalCreate_FileEntrySync() {
    return new _FileEntrySync._internalWrap();
  }

  external factory _FileEntrySync._internalWrap();

  @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 wrap_jso(_blink.BlinkFileReaderSync.instance.constructorCallback_0_());
  }

  @Deprecated("Internal Use Only")
  static _FileReaderSync internalCreate_FileReaderSync() {
    return new _FileReaderSync._internalWrap();
  }

  factory _FileReaderSync._internalWrap() {
    return new _FileReaderSync.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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")
  static _FileWriterSync internalCreate_FileWriterSync() {
    return new _FileWriterSync._internalWrap();
  }

  factory _FileWriterSync._internalWrap() {
    return new _FileWriterSync.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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")
  static _GamepadList internalCreate_GamepadList() {
    return new _GamepadList._internalWrap();
  }

  factory _GamepadList._internalWrap() {
    return new _GamepadList.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  @DomName('GamepadList.length')
  @DocsEditable()
  int get length => _blink.BlinkGamepadList.instance.length_Getter_(unwrap_jso(this));
  
  Gamepad operator[](int index) {
    if (index < 0 || index >= length)
      throw new RangeError.index(index, this);
    return wrap_jso(_blink.BlinkGamepadList.instance.item_Callback_1_(unwrap_jso(this), index));
  }

  Gamepad _nativeIndexedGetter(int index) => wrap_jso(_blink.BlinkGamepadList.instance.item_Callback_1_(unwrap_jso(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) => wrap_jso(_blink.BlinkGamepadList.instance.item_Callback_1_(unwrap_jso(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")
  static _HTMLAllCollection internalCreate_HTMLAllCollection() {
    return new _HTMLAllCollection._internalWrap();
  }

  factory _HTMLAllCollection._internalWrap() {
    return new _HTMLAllCollection.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  Element _item(int index) {
    if ((index is int || index == null)) {
      return wrap_jso(_blink.BlinkHTMLAllCollection.instance.item_Callback_1_(unwrap_jso(this), index));
    }
    if ((index is int || index == null)) {
      return wrap_jso(_blink.BlinkHTMLAllCollection.instance.item_Callback_1_(unwrap_jso(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")
  static _HTMLAppletElement internalCreate_HTMLAppletElement() {
    return new _HTMLAppletElement._internalWrap();
  }

  external factory _HTMLAppletElement._internalWrap();

  @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")
  static _HTMLDirectoryElement internalCreate_HTMLDirectoryElement() {
    return new _HTMLDirectoryElement._internalWrap();
  }

  external factory _HTMLDirectoryElement._internalWrap();

  @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")
  static _HTMLFontElement internalCreate_HTMLFontElement() {
    return new _HTMLFontElement._internalWrap();
  }

  external factory _HTMLFontElement._internalWrap();

  @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")
  static _HTMLFrameElement internalCreate_HTMLFrameElement() {
    return new _HTMLFrameElement._internalWrap();
  }

  external factory _HTMLFrameElement._internalWrap();

  @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")
  static _HTMLFrameSetElement internalCreate_HTMLFrameSetElement() {
    return new _HTMLFrameSetElement._internalWrap();
  }

  external factory _HTMLFrameSetElement._internalWrap();

  @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")
  static _HTMLMarqueeElement internalCreate_HTMLMarqueeElement() {
    return new _HTMLMarqueeElement._internalWrap();
  }

  external factory _HTMLMarqueeElement._internalWrap();

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


@DomName('MutationEvent')
// http://www.w3.org/TR/DOM-Level-3-Events/#events-mutationevents
@deprecated
class _MutationEvent extends Event {
  factory _MutationEvent(String type,
      {bool canBubble: false, bool cancelable: false, Node relatedNode,
      String prevValue, String newValue, String attrName, int attrChange: 0}) {

    var event = document._createEvent('MutationEvent');
    event._initMutationEvent(type, canBubble, cancelable, relatedNode,
        prevValue, newValue, attrName, attrChange);
    return event;
  }
  // To suppress missing implicit constructor warnings.
  factory _MutationEvent._() { throw new UnsupportedError("Not supported"); }


  @Deprecated("Internal Use Only")
  static _MutationEvent internalCreate_MutationEvent() {
    return new _MutationEvent._internalWrap();
  }

  external factory _MutationEvent._internalWrap();

  @Deprecated("Internal Use Only")
  _MutationEvent.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('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")
  static _NamedNodeMap internalCreate_NamedNodeMap() {
    return new _NamedNodeMap._internalWrap();
  }

  factory _NamedNodeMap._internalWrap() {
    return new _NamedNodeMap.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  @DomName('NamedNodeMap.length')
  @DocsEditable()
  int get length => _blink.BlinkNamedNodeMap.instance.length_Getter_(unwrap_jso(this));
  
  Node operator[](int index) {
    if (index < 0 || index >= length)
      throw new RangeError.index(index, this);
    return wrap_jso(_blink.BlinkNamedNodeMap.instance.item_Callback_1_(unwrap_jso(this), index));
  }

  Node _nativeIndexedGetter(int index) => wrap_jso(_blink.BlinkNamedNodeMap.instance.item_Callback_1_(unwrap_jso(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 wrap_jso(_blink.BlinkNamedNodeMap.instance.getNamedItem_Callback_1_(unwrap_jso(this), name));
    }
    if ((name is String)) {
      return wrap_jso(_blink.BlinkNamedNodeMap.instance.getNamedItem_Callback_1_(unwrap_jso(this), name));
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }

  @DomName('NamedNodeMap.getNamedItemNS')
  @DocsEditable()
  _Attr getNamedItemNS(String namespaceURI, String localName) => wrap_jso(_blink.BlinkNamedNodeMap.instance.getNamedItemNS_Callback_2_(unwrap_jso(this), namespaceURI, localName));
  
  @DomName('NamedNodeMap.item')
  @DocsEditable()
  _Attr item(int index) => wrap_jso(_blink.BlinkNamedNodeMap.instance.item_Callback_1_(unwrap_jso(this), index));
  
  @DomName('NamedNodeMap.removeNamedItem')
  @DocsEditable()
  _Attr removeNamedItem(String name) => wrap_jso(_blink.BlinkNamedNodeMap.instance.removeNamedItem_Callback_1_(unwrap_jso(this), name));
  
  @DomName('NamedNodeMap.removeNamedItemNS')
  @DocsEditable()
  _Attr removeNamedItemNS(String namespaceURI, String localName) => wrap_jso(_blink.BlinkNamedNodeMap.instance.removeNamedItemNS_Callback_2_(unwrap_jso(this), namespaceURI, localName));
  
  @DomName('NamedNodeMap.setNamedItem')
  @DocsEditable()
  _Attr setNamedItem(_Attr attr) => wrap_jso(_blink.BlinkNamedNodeMap.instance.setNamedItem_Callback_1_(unwrap_jso(this), unwrap_jso(attr)));
  
  @DomName('NamedNodeMap.setNamedItemNS')
  @DocsEditable()
  _Attr setNamedItemNS(_Attr attr) => wrap_jso(_blink.BlinkNamedNodeMap.instance.setNamedItemNS_Callback_1_(unwrap_jso(this), unwrap_jso(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")
  static _PagePopupController internalCreate_PagePopupController() {
    return new _PagePopupController._internalWrap();
  }

  factory _PagePopupController._internalWrap() {
    return new _PagePopupController.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

}
// 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")
  static _RadioNodeList internalCreate_RadioNodeList() {
    return new _RadioNodeList._internalWrap();
  }

  external factory _RadioNodeList._internalWrap();

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


  @DomName('RadioNodeList.item')
  @DocsEditable()
  @Experimental() // untriaged
  Node _item(int index) => wrap_jso(_blink.BlinkRadioNodeList.instance.item_Callback_1_(unwrap_jso(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 wrap_jso(_blink.BlinkRequest.instance.constructorCallback_2_(input, requestInitDict_1));
    }
    return wrap_jso(_blink.BlinkRequest.instance.constructorCallback_1_(input));
  }


  @Deprecated("Internal Use Only")
  static _Request internalCreate_Request() {
    return new _Request._internalWrap();
  }

  external factory _Request._internalWrap();

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


  @DomName('Request.context')
  @DocsEditable()
  @Experimental() // untriaged
  String get context => _blink.BlinkRequest.instance.context_Getter_(unwrap_jso(this));
  
  @DomName('Request.credentials')
  @DocsEditable()
  @Experimental() // untriaged
  String get credentials => _blink.BlinkRequest.instance.credentials_Getter_(unwrap_jso(this));
  
  @DomName('Request.headers')
  @DocsEditable()
  @Experimental() // untriaged
  Headers get headers => wrap_jso(_blink.BlinkRequest.instance.headers_Getter_(unwrap_jso(this)));
  
  @DomName('Request.mode')
  @DocsEditable()
  @Experimental() // untriaged
  String get mode => _blink.BlinkRequest.instance.mode_Getter_(unwrap_jso(this));
  
  @DomName('Request.referrer')
  @DocsEditable()
  @Experimental() // untriaged
  String get referrer => _blink.BlinkRequest.instance.referrer_Getter_(unwrap_jso(this));
  
  @DomName('Request.url')
  @DocsEditable()
  @Experimental() // untriaged
  String get url => _blink.BlinkRequest.instance.url_Getter_(unwrap_jso(this));
  
  @DomName('Request.clone')
  @DocsEditable()
  @Experimental() // untriaged
  _Request clone() => wrap_jso(_blink.BlinkRequest.instance.clone_Callback_0_(unwrap_jso(this)));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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 wrap_jso(_blink.BlinkResponse.instance.constructorCallback_2_(body, responseInitDict_1));
    }
    if (body != null) {
      return wrap_jso(_blink.BlinkResponse.instance.constructorCallback_1_(body));
    }
    return wrap_jso(_blink.BlinkResponse.instance.constructorCallback_0_());
  }


  @Deprecated("Internal Use Only")
  static _Response internalCreate_Response() {
    return new _Response._internalWrap();
  }

  external factory _Response._internalWrap();

  @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")
  static _ServiceWorker internalCreate_ServiceWorker() {
    return new _ServiceWorker._internalWrap();
  }

  external factory _ServiceWorker._internalWrap();

  @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")
  static _SpeechRecognitionResultList internalCreate_SpeechRecognitionResultList() {
    return new _SpeechRecognitionResultList._internalWrap();
  }

  factory _SpeechRecognitionResultList._internalWrap() {
    return new _SpeechRecognitionResultList.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  @DomName('SpeechRecognitionResultList.length')
  @DocsEditable()
  int get length => _blink.BlinkSpeechRecognitionResultList.instance.length_Getter_(unwrap_jso(this));
  
  SpeechRecognitionResult operator[](int index) {
    if (index < 0 || index >= length)
      throw new RangeError.index(index, this);
    return wrap_jso(_blink.BlinkSpeechRecognitionResultList.instance.item_Callback_1_(unwrap_jso(this), index));
  }

  SpeechRecognitionResult _nativeIndexedGetter(int index) => wrap_jso(_blink.BlinkSpeechRecognitionResultList.instance.item_Callback_1_(unwrap_jso(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) => wrap_jso(_blink.BlinkSpeechRecognitionResultList.instance.item_Callback_1_(unwrap_jso(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")
  static _StyleSheetList internalCreate_StyleSheetList() {
    return new _StyleSheetList._internalWrap();
  }

  factory _StyleSheetList._internalWrap() {
    return new _StyleSheetList.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  @DomName('StyleSheetList.length')
  @DocsEditable()
  int get length => _blink.BlinkStyleSheetList.instance.length_Getter_(unwrap_jso(this));
  
  StyleSheet operator[](int index) {
    if (index < 0 || index >= length)
      throw new RangeError.index(index, this);
    return wrap_jso(_blink.BlinkStyleSheetList.instance.item_Callback_1_(unwrap_jso(this), index));
  }

  StyleSheet _nativeIndexedGetter(int index) => wrap_jso(_blink.BlinkStyleSheetList.instance.item_Callback_1_(unwrap_jso(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) => wrap_jso(_blink.BlinkStyleSheetList.instance.$__getter___Callback_1_(unwrap_jso(this), name));
  
  @DomName('StyleSheetList.item')
  @DocsEditable()
  StyleSheet item(int index) => wrap_jso(_blink.BlinkStyleSheetList.instance.item_Callback_1_(unwrap_jso(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")
  static _SubtleCrypto internalCreate_SubtleCrypto() {
    return new _SubtleCrypto._internalWrap();
  }

  factory _SubtleCrypto._internalWrap() {
    return new _SubtleCrypto.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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 wrap_jso(_blink.BlinkWebKitCSSMatrix.instance.constructorCallback_1_(cssValue));
  }

  @Deprecated("Internal Use Only")
  static _WebKitCSSMatrix internalCreate_WebKitCSSMatrix() {
    return new _WebKitCSSMatrix._internalWrap();
  }

  factory _WebKitCSSMatrix._internalWrap() {
    return new _WebKitCSSMatrix.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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_(unwrap_jso(this), handler, timeout, arguments);
    }
    return _blink.BlinkWindowTimers.instance.setInterval_Callback_1_(unwrap_jso(this), handler);
  }

  int _setTimeout_String(String handler, [int timeout, Object arguments]) {
    if (timeout != null) {
      return _blink.BlinkWindowTimers.instance.setTimeout_Callback_3_(unwrap_jso(this), handler, timeout, arguments);
    }
    return _blink.BlinkWindowTimers.instance.setTimeout_Callback_1_(unwrap_jso(this), handler);
  }

  void _clearInterval([int handle]) {
    if (handle != null) {
      _blink.BlinkWindowTimers.instance.clearInterval_Callback_1_(unwrap_jso(this), handle);
      return;
    }
    _blink.BlinkWindowTimers.instance.clearInterval_Callback_0_(unwrap_jso(this));
    return;
  }

  void _clearTimeout([int handle]) {
    if (handle != null) {
      _blink.BlinkWindowTimers.instance.clearTimeout_Callback_1_(unwrap_jso(this), handle);
      return;
    }
    _blink.BlinkWindowTimers.instance.clearTimeout_Callback_0_(unwrap_jso(this));
    return;
  }

  int _setInterval(Object handler, [int timeout]) {
    if (timeout != null) {
      return _blink.BlinkWindowTimers.instance.setInterval_Callback_2_(unwrap_jso(this), handler, timeout);
    }
    return _blink.BlinkWindowTimers.instance.setInterval_Callback_1_(unwrap_jso(this), handler);
  }

  int _setTimeout(Object handler, [int timeout]) {
    if (timeout != null) {
      return _blink.BlinkWindowTimers.instance.setTimeout_Callback_2_(unwrap_jso(this), handler, timeout);
    }
    return _blink.BlinkWindowTimers.instance.setTimeout_Callback_1_(unwrap_jso(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")
  static _WorkerLocation internalCreate_WorkerLocation() {
    return new _WorkerLocation._internalWrap();
  }

  factory _WorkerLocation._internalWrap() {
    return new _WorkerLocation.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  // Override these methods for Dartium _WorkerLocation can't be abstract.
  String get hash => _blink.BlinkWorkerLocation.instance.hash_Getter_(unwrap_jso(this));
  String get host => _blink.BlinkWorkerLocation.instance.host_Getter_(unwrap_jso(this));
  String get hostname => _blink.BlinkWorkerLocation.instance.hostname_Getter_(unwrap_jso(this));
  String get href => _blink.BlinkWorkerLocation.instance.href_Getter_(unwrap_jso(this));
  String get origin => _blink.BlinkWorkerLocation.instance.origin_Getter_(unwrap_jso(this));
  String get pathname => _blink.BlinkWorkerLocation.instance.pathname_Getter_(unwrap_jso(this));
  String get port => _blink.BlinkWorkerLocation.instance.port_Getter_(unwrap_jso(this));
  String get protocol => _blink.BlinkWorkerLocation.instance.protocol_Getter_(unwrap_jso(this));
  String get search => _blink.BlinkWorkerLocation.instance.search_Getter_(unwrap_jso(this));
}

// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All 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")
  static _WorkerNavigator internalCreate_WorkerNavigator() {
    return new _WorkerNavigator._internalWrap();
  }

  factory _WorkerNavigator._internalWrap() {
    return new _WorkerNavigator.internal_();
  }

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

  bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || identical(this, other);
  int get hashCode => unwrap_jso(this).hashCode;

  // Override these methods for Dartium _WorkerNavigator can't be abstract.
  String get appCodeName => _blink.BlinkWorkerNavigator.instance.appCodeName_Getter_(unwrap_jso(this));
  String get appName => _blink.BlinkWorkerNavigator.instance.appCodeName_Getter_(unwrap_jso(this));
  String get appVersion => _blink.BlinkWorkerNavigator.instance.appVersion_Getter_(unwrap_jso(this));
  bool get dartEnabled => _blink.BlinkWorkerNavigator.instance.dartEnabled_Getter_(unwrap_jso(this));
  String get platform => _blink.BlinkWorkerNavigator.instance.platform_Getter_(unwrap_jso(this));
  String get product => _blink.BlinkWorkerNavigator.instance.product_Getter_(unwrap_jso(this));
  String get userAgent => _blink.BlinkWorkerNavigator.instance.userAgent_Getter_(unwrap_jso(this));
  int get hardwareConcurrency => _blink.BlinkWorkerNavigator.instance.hardwareConcurrency_Getter_(unwrap_jso(this));
  bool get onLine => _blink.BlinkWorkerNavigator.instance.onLine_Getter_(unwrap_jso(this));
}

// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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")
  static _XMLHttpRequestProgressEvent internalCreate_XMLHttpRequestProgressEvent() {
    return new _XMLHttpRequestProgressEvent._internalWrap();
  }

  external factory _XMLHttpRequestProgressEvent._internalWrap();

  @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(String value) {
    for (var v in this.values) {
      if (value == v) {
        return true;
      }
    }
    return false;
  }

  String putIfAbsent(String key, String ifAbsent()) {
    if (!containsKey(key)) {
      this[key] = ifAbsent();
    }
    return this[key];
  }

  void clear() {
    for (var key in keys) {
      remove(key);
    }
  }

  void forEach(void f(String key, String value)) {
    for (var key in keys) {
      var value = this[key];
      f(key, value);
    }
  }

  Iterable<String> get keys {
    // TODO: generate a lazy collection instead.
    var attributes = _element._attributes;
    var keys = new List<String>();
    for (int i = 0, len = attributes.length; i < len; i++) {
      if (_matches(attributes[i])) {
        keys.add(attributes[i].name);
      }
    }
    return keys;
  }

  Iterable<String> get values {
    // TODO: generate a lazy collection instead.
    var attributes = _element._attributes;
    var values = new List<String>();
    for (int i = 0, len = attributes.length; i < len; i++) {
      if (_matches(attributes[i])) {
        values.add(attributes[i].value);
      }
    }
    return values;
  }

  /**
   * Returns true if there is no {key, value} pair in the map.
   */
  bool get isEmpty {
    return length == 0;
  }

  /**
   * Returns true if there is at least one {key, value} pair in the map.
   */
  bool get isNotEmpty => !isEmpty;

  /**
   * Checks to see if the node should be included in this map.
   */
  bool _matches(Node node);
}

/**
 * Wrapper to expose [Element.attributes] as a typed map.
 */
class _ElementAttributeMap extends _AttributeMap {

  _ElementAttributeMap(Element element): super(element);

  bool containsKey(String key) {
    return _element._hasAttribute(key);
  }

  String operator [](String key) {
    return _element.getAttribute(key);
  }

  void operator []=(String key, String value) {
    _element.setAttribute(key, value);
  }

  String remove(String key) {
    String value = _element.getAttribute(key);
    _element._removeAttribute(key);
    return value;
  }

  /**
   * The number of {key, value} pairs in the map.
   */
  int get length {
    return keys.length;
  }

  bool _matches(Node node) => node._namespaceUri == null;
}

/**
 * Wrapper to expose namespaced attributes as a typed map.
 */
class _NamespacedAttributeMap extends _AttributeMap {

  final String _namespace;

  _NamespacedAttributeMap(Element element, this._namespace): super(element);

  bool containsKey(String key) {
    return _element._hasAttributeNS(_namespace, key);
  }

  String operator [](String key) {
    return _element.getAttributeNS(_namespace, key);
  }

  void operator []=(String key, String value) {
    _element.setAttributeNS(_namespace, key, value);
  }

  String remove(String key) {
    String value = this[key];
    _element._removeAttributeNS(_namespace, key);
    return value;
  }

  /**
   * The number of {key, value} pairs in the map.
   */
  int get length {
    return keys.length;
  }

  bool _matches(Node node) => node._namespaceUri == _namespace;
}


/**
 * Provides a Map abstraction on top of data-* attributes, similar to the
 * dataSet in the old DOM.
 */
class _DataAttributeMap implements Map<String, String> {

  final Map<String, String> _attributes;

  _DataAttributeMap(this._attributes);

  // interface Map

  void addAll(Map<String, String> other) {
    other.forEach((k, v) { this[k] = v; });
  }

  // TODO: Use lazy iterator when it is available on Map.
  bool containsValue(String value) => values.any((v) => v == value);

  bool containsKey(String key) => _attributes.containsKey(_attr(key));

  String operator [](String key) => _attributes[_attr(key)];

  void operator []=(String key, String value) {
    _attributes[_attr(key)] = value;
  }

  String putIfAbsent(String key, String ifAbsent()) =>
    _attributes.putIfAbsent(_attr(key), ifAbsent);

  String remove(String key) => _attributes.remove(_attr(key));

  void clear() {
    // Needs to operate on a snapshot since we are mutating the collection.
    for (String key in keys) {
      remove(key);
    }
  }

  void forEach(void f(String key, String value)) {
    _attributes.forEach((String key, String value) {
      if (_matches(key)) {
        f(_strip(key), value);
      }
    });
  }

  Iterable<String> get keys {
    final keys = new List<String>();
    _attributes.forEach((String key, String value) {
      if (_matches(key)) {
        keys.add(_strip(key));
      }
    });
    return keys;
  }

  Iterable<String> get values {
    final values = new List<String>();
    _attributes.forEach((String key, String value) {
      if (_matches(key)) {
        values.add(value);
      }
    });
    return values;
  }

  int get length => keys.length;

  // TODO: Use lazy iterator when it is available on Map.
  bool get isEmpty => length == 0;

  bool get isNotEmpty => !isEmpty;

  // Helpers.
  String _attr(String key) => 'data-${_toHyphenedName(key)}';
  bool _matches(String key) => key.startsWith('data-');
  String _strip(String key) => _toCamelCase(key.substring(5));

  /**
   * Converts a string name with hyphens into an identifier, by removing hyphens
   * and capitalizing the following letter. Optionally [startUppercase] to
   * captialize the first letter.
   */
  String _toCamelCase(String hyphenedName, {bool startUppercase: false}) {
    var segments = hyphenedName.split('-');
    int start = startUppercase ? 0 : 1;
    for (int i = start; i < segments.length; i++) {
      var segment = segments[i];
      if (segment.length > 0) {
        // Character between 'a'..'z' mapped to 'A'..'Z'
        segments[i] = '${segment[0].toUpperCase()}${segment.substring(1)}';
      }
    }
    return segments.join('');
  }

  /** Reverse of [toCamelCase]. */
  String _toHyphenedName(String word) {
    var sb = new StringBuffer();
    for (int i = 0; i < word.length; i++) {
      var lower = word[i].toLowerCase();
      if (word[i] != lower && i > 0) sb.write('-');
      sb.write(lower);
    }
    return sb.toString();
  }
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


/**
 * An object that can be drawn to a 2D canvas rendering context.
 *
 * The image drawn to the canvas depends on the type of this object:
 *
 * * If this object is an [ImageElement], then this element's image is
 * drawn to the canvas. If this element is an animated image, then this
 * element's poster frame is drawn. If this element has no poster frame, then
 * the first frame of animation is drawn.
 *
 * * If this object is a [VideoElement], then the frame at this element's current
 * playback position is drawn to the canvas.
 *
 * * If this object is a [CanvasElement], then this element's bitmap is drawn to
 * the canvas.
 *
 * **Note:** Currently all versions of Internet Explorer do not support
 * drawing a video element to a canvas. You may also encounter problems drawing
 * a video to a canvas in Firefox if the source of the video is a data URL.
 *
 * ## See also
 *
 * * [CanvasRenderingContext2D.drawImage]
 * * [CanvasRenderingContext2D.drawImageToRect]
 * * [CanvasRenderingContext2D.drawImageScaled]
 * * [CanvasRenderingContext2D.drawImageScaledFromSource]
 *
 * ## Other resources
 *
 * * [Image sources for 2D rendering
 *   contexts](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 messagePorts]);
}

abstract class LocationBase {
  void set href(String val);
}

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


/** A Set that stores the CSS class names for an element. */
abstract class CssClassSet implements Set<String> {

  /**
   * Adds the class [value] to the element if it is not on it, removes it if it
   * is.
   *
   * If [shouldAdd] is true, then we always add that [value] to the element. If
   * [shouldAdd] is false then we always remove [value] from the element.
   *
   * If this corresponds to one element, returns `true` if [value] is present
   * after the operation, and returns `false` if [value] is absent after the
   * operation.
   *
   * If this corresponds to many elements, `null` is always returned.
   *
   * [value] must be a valid 'token' representing a single class, i.e. a
   * non-empty string containing no whitespace.  To toggle multiple classes, use
   * [toggleAll].
   */
  bool toggle(String value, [bool shouldAdd]);

  /**
   * Returns [:true:] if classes cannot be added or removed from this
   * [:CssClassSet:].
   */
  bool get frozen;

  /**
   * Determine if this element contains the class [value].
   *
   * This is the Dart equivalent of jQuery's
   * [hasClass](http://api.jquery.com/hasClass/).
   *
   * [value] must be a valid 'token' representing a single class, i.e. a
   * non-empty string containing no whitespace.
   */
  bool contains(String value);

  /**
   * Add the class [value] to element.
   *
   * [add] and [addAll] are the Dart equivalent of jQuery's
   * [addClass](http://api.jquery.com/addClass/).
   *
   * If this CssClassSet corresponds to one element. Returns true if [value] was
   * added to the set, otherwise false.
   *
   * If this corresponds to many elements, `null` is always returned.
   *
   * [value] must be a valid 'token' representing a single class, i.e. a
   * non-empty string containing no whitespace.  To add multiple classes use
   * [addAll].
   */
  bool add(String value);

  /**
   * Remove the class [value] from element, and return true on successful
   * removal.
   *
   * [remove] and [removeAll] are the Dart equivalent of jQuery's
   * [removeClass](http://api.jquery.com/removeClass/).
   *
   * [value] must be a valid 'token' representing a single class, i.e. a
   * non-empty string containing no whitespace.  To remove multiple classes, use
   * [removeAll].
   */
  bool remove(Object value);

  /**
   * Add all classes specified in [iterable] to element.
   *
   * [add] and [addAll] are the Dart equivalent of jQuery's
   * [addClass](http://api.jquery.com/addClass/).
   *
   * Each element of [iterable] must be a valid 'token' representing a single
   * class, i.e. a non-empty string containing no whitespace.
   */
  void addAll(Iterable<String> iterable);

  /**
   * Remove all classes specified in [iterable] from element.
   *
   * [remove] and [removeAll] are the Dart equivalent of jQuery's
   * [removeClass](http://api.jquery.com/removeClass/).
   *
   * Each element of [iterable] must be a valid 'token' representing a single
   * class, i.e. a non-empty string containing no whitespace.
   */
  void removeAll(Iterable<String> iterable);

  /**
   * Toggles all classes specified in [iterable] on element.
   *
   * Iterate through [iterable]'s items, and add it if it is not on it, or
   * remove it if it is. This is the Dart equivalent of jQuery's
   * [toggleClass](http://api.jquery.com/toggleClass/).
   * If [shouldAdd] is true, then we always add all the classes in [iterable]
   * element. If [shouldAdd] is false then we always remove all the classes in
   * [iterable] from the element.
   *
   * Each element of [iterable] must be a valid 'token' representing a single
   * class, i.e. a non-empty string containing no whitespace.
   */
  void toggleAll(Iterable<String> iterable, [bool shouldAdd]);
}
// Copyright (c) 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) : super(element);

  num get height => _element.offsetHeight +
      _addOrSubtractToBoxModel(_HEIGHT, _CONTENT);

  num get width => _element.offsetWidth +
      _addOrSubtractToBoxModel(_WIDTH, _CONTENT);

  /**
   * Set the height to `newHeight`.
   *
   * newHeight can be either a [num] representing the height in pixels or a
   * [Dimension] object. Values of newHeight that are less than zero are
   * converted to effectively setting the height to 0. This is equivalent to the
   * `height` function in jQuery and the calculated `height` CSS value,
   * converted to a num in pixels.
   */
  set height(newHeight) {
    if (newHeight is Dimension) {
      if (newHeight.value < 0) newHeight = new Dimension.px(0);
      _element.style.height = newHeight.toString();
    } else {
      if (newHeight < 0) newHeight = 0;
      _element.style.height = '${newHeight}px';
    }
  }

  /**
   * Set the current computed width in pixels of this element.
   *
   * newWidth can be either a [num] representing the width in pixels or a
   * [Dimension] object. This is equivalent to the `width` function in jQuery
   * and the calculated
   * `width` CSS value, converted to a dimensionless num in pixels.
   */
  set width(newWidth) {
    if (newWidth is Dimension) {
      if (newWidth.value < 0) newWidth = new Dimension.px(0);
      _element.style.width = newWidth.toString();
    } else {
      if (newWidth < 0) newWidth = 0;
      _element.style.width = '${newWidth}px';
    }
  }

  num get left => _element.getBoundingClientRect().left -
      _addOrSubtractToBoxModel(['left'], _CONTENT);
  num get top => _element.getBoundingClientRect().top -
      _addOrSubtractToBoxModel(['top'], _CONTENT);
}

/**
 * A list of element content rectangles in the
 * [box model](http://www.w3.org/TR/CSS2/box.html).
 */
class _ContentCssListRect extends _ContentCssRect {
  List<Element> _elementList;

  _ContentCssListRect(elementList) : super(elementList.first) {
    _elementList = elementList;
  }

  /**
   * Set the height to `newHeight`.
   *
   * Values of newHeight that are less than zero are converted to effectively
   * setting the height to 0. This is equivalent to the `height`
   * function in jQuery and the calculated `height` CSS value, converted to a
   * num in pixels.
   */
  set height(newHeight) {
    _elementList.forEach((e) => e.contentEdge.height = newHeight);
  }

  /**
   * Set the current computed width in pixels of this element.
   *
   * This is equivalent to the `width` function in jQuery and the calculated
   * `width` CSS value, converted to a dimensionless num in pixels.
   */
  set width(newWidth) {
    _elementList.forEach((e) => e.contentEdge.width = newWidth);
  }
}

/**
 * A rectangle representing the dimensions of the space occupied by the
 * element's content + padding in the
 * [box model](http://www.w3.org/TR/CSS2/box.html).
 */
class _PaddingCssRect extends CssRect {
  _PaddingCssRect(element) : super(element);
  num get height => _element.offsetHeight +
      _addOrSubtractToBoxModel(_HEIGHT, _PADDING);
  num get width => _element.offsetWidth +
      _addOrSubtractToBoxModel(_WIDTH, _PADDING);

  num get left => _element.getBoundingClientRect().left -
      _addOrSubtractToBoxModel(['left'], _PADDING);
  num get top => _element.getBoundingClientRect().top -
      _addOrSubtractToBoxModel(['top'], _PADDING);
}

/**
 * A rectangle representing the dimensions of the space occupied by the
 * element's content + padding + border in the
 * [box model](http://www.w3.org/TR/CSS2/box.html).
 */
class _BorderCssRect extends CssRect {
  _BorderCssRect(element) : super(element);
  num get height => _element.offsetHeight;
  num get width => _element.offsetWidth;

  num get left => _element.getBoundingClientRect().left;
  num get top => _element.getBoundingClientRect().top;
}

/**
 * A rectangle representing the dimensions of the space occupied by the
 * element's content + padding + border + margin in the
 * [box model](http://www.w3.org/TR/CSS2/box.html).
 */
class _MarginCssRect extends CssRect {
  _MarginCssRect(element) : super(element);
  num get height => _element.offsetHeight +
      _addOrSubtractToBoxModel(_HEIGHT, _MARGIN);
  num get width =>
      _element.offsetWidth + _addOrSubtractToBoxModel(_WIDTH, _MARGIN);

  num get left => _element.getBoundingClientRect().left -
      _addOrSubtractToBoxModel(['left'], _MARGIN);
  num get top => _element.getBoundingClientRect().top -
      _addOrSubtractToBoxModel(['top'], _MARGIN);
}

/**
 * A class for representing CSS dimensions.
 *
 * In contrast to the more general purpose [Rectangle] class, this class's
 * values are mutable, so one can change the height of an element
 * programmatically.
 *
 * _Important_ _note_: use of these methods will perform CSS calculations that
 * can trigger a browser reflow. Therefore, use of these properties _during_ an
 * animation frame is discouraged. See also:
 * [Browser Reflow](https://developers.google.com/speed/articles/reflow)
 */
abstract class CssRect extends MutableRectangle<num> {
  Element _element;

  CssRect(this._element) : super(0, 0, 0, 0);

  num get left;

  num get top;

  /**
   * The height of this rectangle.
   *
   * This is equivalent to the `height` function in jQuery and the calculated
   * `height` CSS value, converted to a dimensionless num in pixels. Unlike
   * [getBoundingClientRect], `height` will return the same numerical width if
   * the element is hidden or not.
   */
  num get height;

  /**
   * The width of this rectangle.
   *
   * This is equivalent to the `width` function in jQuery and the calculated
   * `width` CSS value, converted to a dimensionless num in pixels. Unlike
   * [getBoundingClientRect], `width` will return the same numerical width if
   * the element is hidden or not.
   */
  num get width;

  /**
   * Set the height to `newHeight`.
   *
   * newHeight can be either a [num] representing the height in pixels or a
   * [Dimension] object. Values of newHeight that are less than zero are
   * converted to effectively setting the height to 0. This is equivalent to the
   * `height` function in jQuery and the calculated `height` CSS value,
   * converted to a num in pixels.
   *
   * Note that only the content height can actually be set via this method.
   */
  set height(newHeight) {
    throw new UnsupportedError("Can only set height for content rect.");
  }

  /**
   * Set the current computed width in pixels of this element.
   *
   * newWidth can be either a [num] representing the width in pixels or a
   * [Dimension] object. This is equivalent to the `width` function in jQuery
   * and the calculated
   * `width` CSS value, converted to a dimensionless num in pixels.
   *
   * Note that only the content width can be set via this method.
   */
  set width(newWidth) {
    throw new UnsupportedError("Can only set width for content rect.");
  }

  /**
   * Return a value that is used to modify the initial height or width
   * measurement of an element. Depending on the value (ideally an enum) passed
   * to augmentingMeasurement, we may need to add or subtract margin, padding,
   * or border values, depending on the measurement we're trying to obtain.
   */
  num _addOrSubtractToBoxModel(List<String> dimensions,
      String augmentingMeasurement) {
    // getComputedStyle always returns pixel values (hence, computed), so we're
    // always dealing with pixels in this method.
    var styles = _element.getComputedStyle();

    var val = 0;

    for (String measurement in dimensions) {
      // The border-box and default box model both exclude margin in the regular
      // height/width calculation, so add it if we want it for this measurement.
      if (augmentingMeasurement == _MARGIN) {
        val += new Dimension.css(styles.getPropertyValue(
            '$augmentingMeasurement-$measurement')).value;
      }

      // The border-box includes padding and border, so remove it if we want
      // just the content itself.
      if (augmentingMeasurement == _CONTENT) {
      	val -= new Dimension.css(
            styles.getPropertyValue('${_PADDING}-$measurement')).value;
      }

      // At this point, we don't wan't to augment with border or margin,
      // so remove border.
      if (augmentingMeasurement != _MARGIN) {
	      val -= new Dimension.css(styles.getPropertyValue(
            'border-${measurement}-width')).value;
      }
    }
    return val;
  }
}

final _HEIGHT = ['top', 'bottom'];
final _WIDTH = ['right', 'left'];
final _CONTENT = 'content';
final _PADDING = 'padding';
final _MARGIN = 'margin';

/**
 * Class representing a
 * [length measurement](https://developer.mozilla.org/en-US/docs/Web/CSS/length)
 * in CSS.
 */
@Experimental()
class Dimension {
  num _value;
  String _unit;

  /** Set this CSS Dimension to a percentage `value`. */
  Dimension.percent(this._value) : _unit = '%';

  /** Set this CSS Dimension to a pixel `value`. */
  Dimension.px(this._value) : _unit = 'px';

  /** Set this CSS Dimension to a pica `value`. */
  Dimension.pc(this._value) : _unit = 'pc';

  /** Set this CSS Dimension to a point `value`. */
  Dimension.pt(this._value) : _unit = 'pt';

  /** Set this CSS Dimension to an inch `value`. */
  Dimension.inch(this._value) : _unit = 'in';

  /** Set this CSS Dimension to a centimeter `value`. */
  Dimension.cm(this._value) : _unit = 'cm';

  /** Set this CSS Dimension to a millimeter `value`. */
  Dimension.mm(this._value) : _unit = 'mm';

  /**
   * Set this CSS Dimension to the specified number of ems.
   *
   * 1em is equal to the current font size. (So 2ems is equal to double the font
   * size). This is useful for producing website layouts that scale nicely with
   * the user's desired font size.
   */
  Dimension.em(this._value) : _unit = 'em';

  /**
   * Set this CSS Dimension to the specified number of x-heights.
   *
   * One ex is equal to the the x-height of a font's baseline to its mean line,
   * generally the height of the letter "x" in the font, which is usually about
   * half the font-size.
   */
  Dimension.ex(this._value) : _unit = 'ex';

  /**
   * Construct a Dimension object from the valid, simple CSS string `cssValue`
   * that represents a distance measurement.
   *
   * This constructor is intended as a convenience method for working with
   * simplistic CSS length measurements. Non-numeric values such as `auto` or
   * `inherit` or invalid CSS will cause this constructor to throw a
   * FormatError.
   */
  Dimension.css(String cssValue) {
    if (cssValue == '') cssValue = '0px';
    if (cssValue.endsWith('%')) {
      _unit = '%';
    } else {
      _unit = cssValue.substring(cssValue.length - 2);
    }
    if (cssValue.contains('.')) {
      _value = double.parse(cssValue.substring(0,
          cssValue.length - _unit.length));
    } else {
      _value = int.parse(cssValue.substring(0, cssValue.length - _unit.length));
    }
  }

  /** Print out the CSS String representation of this value. */
  String toString() {
    return '${_value}${_unit}';
  }

  /** Return a unitless, numerical value of this CSS value. */
  num get value => this._value;
}
// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


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


/**
 * A factory to expose DOM events as Streams.
 */
class EventStreamProvider<T extends Event> {
  final String _eventType;

  const EventStreamProvider(this._eventType);

  /**
   * Gets a [Stream] for this event type, on the specified target.
   *
   * This will always return a broadcast stream so multiple listeners can be
   * used simultaneously.
   *
   * This may be used to capture DOM events:
   *
   *     Element.keyDownEvent.forTarget(element, useCapture: true).listen(...);
   *
   *     // Alternate method:
   *     Element.keyDownEvent.forTarget(element).capture(...);
   *
   * Or for listening to an event which will bubble through the DOM tree:
   *
   *     MediaElement.pauseEvent.forTarget(document.body).listen(...);
   *
   * See also:
   *
   * [addEventListener](http://docs.webplatform.org/wiki/dom/methods/addEventListener)
   */
  Stream<T> forTarget(EventTarget e, {bool useCapture: false}) =>
    new _EventStream(e, _eventType, useCapture);

  /**
   * Gets an [ElementEventStream] for this event type, on the specified element.
   *
   * This will always return a broadcast stream so multiple listeners can be
   * used simultaneously.
   *
   * This may be used to capture DOM events:
   *
   *     Element.keyDownEvent.forElement(element, useCapture: true).listen(...);
   *
   *     // Alternate method:
   *     Element.keyDownEvent.forElement(element).capture(...);
   *
   * Or for listening to an event which will bubble through the DOM tree:
   *
   *     MediaElement.pauseEvent.forElement(document.body).listen(...);
   *
   * See also:
   *
   * [addEventListener](http://docs.webplatform.org/wiki/dom/methods/addEventListener)
   */
  ElementStream<T> forElement(Element e, {bool useCapture: false}) {
    return new _ElementEventStreamImpl(e, _eventType, useCapture);
  }

  /**
   * Gets an [ElementEventStream] for this event type, on the list of elements.
   *
   * This will always return a broadcast stream so multiple listeners can be
   * used simultaneously.
   *
   * This may be used to capture DOM events:
   *
   *     Element.keyDownEvent._forElementList(element, useCapture: true).listen(...);
   *
   * See also:
   *
   * [addEventListener](http://docs.webplatform.org/wiki/dom/methods/addEventListener)
   */
  ElementStream<T> _forElementList(ElementList e, {bool useCapture: false}) {
    return new _ElementListEventStreamImpl(e, _eventType, useCapture);
  }

  /**
   * Gets the type of the event which this would listen for on the specified
   * event target.
   *
   * The target is necessary because some browsers may use different event names
   * for the same purpose and the target allows differentiating browser support.
   */
  String getEventType(EventTarget target) {
    return _eventType;
  }
}

/** A specialized Stream available to [Element]s to enable event delegation. */
abstract class ElementStream<T extends Event> implements Stream<T> {
  /**
   * Return a stream that only fires when the particular event fires for
   * elements matching the specified CSS selector.
   *
   * This is the Dart equivalent to jQuery's
   * [delegate](http://api.jquery.com/delegate/).
   */
  Stream<T> matches(String selector);

  /**
   * Adds a capturing subscription to this stream.
   *
   * If the target of the event is a descendant of the element from which this
   * stream derives then [onData] is called before the event propagates down to
   * the target. This is the opposite of bubbling behavior, where the event
   * is first processed for the event target and then bubbles upward.
   *
   * ## Other resources
   *
   * * [Event Capture](http://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-flow-capture)
   *   from the W3C DOM Events specification.
   */
  StreamSubscription<T> capture(void onData(T event));
}

/**
 * Adapter for exposing DOM events as Dart streams.
 */
class _EventStream<T extends Event> extends Stream<T> {
  final EventTarget _target;
  final String _eventType;
  final bool _useCapture;

  _EventStream(this._target, this._eventType, this._useCapture);

  // DOM events are inherently multi-subscribers.
  Stream<T> asBroadcastStream({void onListen(StreamSubscription subscription),
                               void onCancel(StreamSubscription subscription)})
      => this;
  bool get isBroadcast => true;

  StreamSubscription<T> listen(void onData(T event),
      { Function onError,
        void onDone(),
        bool cancelOnError}) {

    return new _EventStreamSubscription<T>(
        this._target, this._eventType, onData, this._useCapture);
  }
}

/**
 * Adapter for exposing DOM Element events as streams, while also allowing
 * event delegation.
 */
class _ElementEventStreamImpl<T extends Event> extends _EventStream<T>
    implements ElementStream<T> {
  _ElementEventStreamImpl(target, eventType, useCapture) :
      super(target, eventType, useCapture);

  Stream<T> matches(String selector) => this.where(
      (event) => event.target.matchesWithAncestors(selector)).map((e) {
        e._selector = selector;
        return e;
      });

  StreamSubscription<T> capture(void onData(T event)) =>
    new _EventStreamSubscription<T>(
        this._target, this._eventType, onData, true);
}

/**
 * Adapter for exposing events on a collection of DOM Elements as streams,
 * while also allowing event delegation.
 */
class _ElementListEventStreamImpl<T extends Event> extends Stream<T>
    implements ElementStream<T> {
  final Iterable<Element> _targetList;
  final bool _useCapture;
  final String _eventType;

  _ElementListEventStreamImpl(
      this._targetList, this._eventType, this._useCapture);

  Stream<T> matches(String selector) => this.where(
      (event) => event.target.matchesWithAncestors(selector)).map((e) {
        e._selector = selector;
        return e;
      });

  // Delegate all regular Stream behavior to a wrapped Stream.
  StreamSubscription<T> listen(void onData(T event),
      { Function onError,
        void onDone(),
        bool cancelOnError}) {
    var pool = new _StreamPool.broadcast();
    for (var target in _targetList) {
      pool.add(new _EventStream(target, _eventType, _useCapture));
    }
    return pool.stream.listen(onData, onError: onError, onDone: onDone,
          cancelOnError: cancelOnError);
  }

  StreamSubscription<T> capture(void onData(T event)) {
    var pool = new _StreamPool.broadcast();
    for (var target in _targetList) {
      pool.add(new _EventStream(target, _eventType, true));
    }
    return pool.stream.listen(onData);
  }

  Stream<T> asBroadcastStream({void onListen(StreamSubscription subscription),
                               void onCancel(StreamSubscription subscription)})
      => this;
  bool get isBroadcast => true;
}

class _EventStreamSubscription<T extends Event> extends StreamSubscription<T> {
  int _pauseCount = 0;
  EventTarget _target;
  final String _eventType;
  var _onData;
  final bool _useCapture;

  _EventStreamSubscription(this._target, this._eventType, onData,
      this._useCapture) : _onData = _wrapZone(onData) {
    _tryResume();
  }

  Future cancel() {
    if (_canceled) return null;

    _unlisten();
    // Clear out the target to indicate this is complete.
    _target = null;
    _onData = null;
    return null;
  }

  bool get _canceled => _target == null;

  void onData(void handleData(T event)) {
    if (_canceled) {
      throw new StateError("Subscription has been canceled.");
    }
    // Remove current event listener.
    _unlisten();

    _onData = _wrapZone(handleData);
    _tryResume();
  }

  /// Has no effect.
  void onError(Function handleError) {}

  /// Has no effect.
  void onDone(void handleDone()) {}

  void pause([Future resumeSignal]) {
    if (_canceled) return;
    ++_pauseCount;
    _unlisten();

    if (resumeSignal != null) {
      resumeSignal.whenComplete(resume);
    }
  }

  bool get isPaused => _pauseCount > 0;

  void resume() {
    if (_canceled || !isPaused) return;
    --_pauseCount;
    _tryResume();
  }

  void _tryResume() {
    if (_onData != null && !isPaused) {
      _target.addEventListener(_eventType, _onData, _useCapture);
    }
  }

  void _unlisten() {
    if (_onData != null) {
      _target.removeEventListener(_eventType, _onData, _useCapture);
    }
  }

  Future asFuture([var futureValue]) {
    // We just need a future that will never succeed or fail.
    Completer completer = new Completer();
    return completer.future;
  }
}

/**
 * A stream of custom events, which enables the user to "fire" (add) their own
 * custom events to a stream.
 */
abstract class CustomStream<T extends Event> implements Stream<T> {
  /**
   * Add the following custom event to the stream for dispatching to interested
   * listeners.
   */
  void add(T event);
}

class _CustomEventStreamImpl<T extends Event> extends Stream<T>
    implements CustomStream<T> {
  StreamController<T> _streamController;
  /** The type of event this stream is providing (e.g. "keydown"). */
  String _type;

  _CustomEventStreamImpl(String type) {
    _type = type;
    _streamController = new StreamController.broadcast(sync: true);
  }

  // Delegate all regular Stream behavior to our wrapped Stream.
  StreamSubscription<T> listen(void onData(T event),
      { Function onError,
        void onDone(),
        bool cancelOnError}) {
    return _streamController.stream.listen(onData, onError: onError,
        onDone: onDone, cancelOnError: cancelOnError);
  }

  Stream<T> asBroadcastStream({void onListen(StreamSubscription subscription),
                               void onCancel(StreamSubscription subscription)})
      => _streamController.stream;

  bool get isBroadcast => true;

  void add(T event) {
    if (event.type == _type) _streamController.add(event);
  }
}

class _CustomKeyEventStreamImpl extends _CustomEventStreamImpl<KeyEvent>
    implements CustomStream<KeyEvent> {
  _CustomKeyEventStreamImpl(String type) : super(type);

  void add(KeyEvent event) {
    if (event.type == _type) {
      event.currentTarget.dispatchEvent(event._parent);
      _streamController.add(event);
    }
  }
}

/**
 * A pool of streams whose events are unified and emitted through a central
 * stream.
 */
// TODO (efortuna): Remove this when Issue 12218 is addressed.
class _StreamPool<T> {
  StreamController<T> _controller;

  /// Subscriptions to the streams that make up the pool.
  var _subscriptions = new Map<Stream<T>, StreamSubscription<T>>();

  /**
   * Creates a new stream pool where [stream] can be listened to more than
   * once.
   *
   * Any events from buffered streams in the pool will be emitted immediately,
   * regardless of whether [stream] has any subscribers.
   */
  _StreamPool.broadcast() {
    _controller = new StreamController<T>.broadcast(sync: true,
        onCancel: close);
  }

  /**
   * The stream through which all events from streams in the pool are emitted.
   */
  Stream<T> get stream => _controller.stream;

  /**
   * Adds [stream] as a member of this pool.
   *
   * Any events from [stream] will be emitted through [this.stream]. If
   * [stream] is sync, they'll be emitted synchronously; if [stream] is async,
   * they'll be emitted asynchronously.
   */
  void add(Stream<T> stream) {
    if (_subscriptions.containsKey(stream)) return;
    _subscriptions[stream] = stream.listen(_controller.add,
        onError: _controller.addError,
        onDone: () => remove(stream));
  }

  /** Removes [stream] as a member of this pool. */
  void remove(Stream<T> stream) {
    var subscription = _subscriptions.remove(stream);
    if (subscription != null) subscription.cancel();
  }

  /** Removes all streams from this pool and closes [stream]. */
  void close() {
    for (var subscription in _subscriptions.values) {
      subscription.cancel();
    }
    _subscriptions.clear();
    _controller.close();
  }
}

/**
 * A factory to expose DOM events as streams, where the DOM event name has to
 * be determined on the fly (for example, mouse wheel events).
 */
class _CustomEventStreamProvider<T extends Event>
    implements EventStreamProvider<T> {

  final _eventTypeGetter;
  const _CustomEventStreamProvider(this._eventTypeGetter);

  Stream<T> forTarget(EventTarget e, {bool useCapture: false}) {
    return new _EventStream(e, _eventTypeGetter(e), useCapture);
  }

  ElementStream<T> forElement(Element e, {bool useCapture: false}) {
    return new _ElementEventStreamImpl(e, _eventTypeGetter(e), useCapture);
  }

  ElementStream<T> _forElementList(ElementList e,
      {bool useCapture: false}) {
    return new _ElementListEventStreamImpl(e, _eventTypeGetter(e), useCapture);
  }

  String getEventType(EventTarget target) {
    return _eventTypeGetter(target);
  }

  String get _eventType =>
      throw new UnsupportedError('Access type through getEventType method.');
}
// DO NOT EDIT- this file is generated from running tool/generator.sh.

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


/**
 * A Dart DOM validator generated from Caja whitelists.
 *
 * This contains a whitelist of known HTML tagNames and attributes and will only
 * accept known good values.
 *
 * See also:
 *
 * * <https://code.google.com/p/google-caja/wiki/CajaWhitelists>
 */
class _Html5NodeValidator implements NodeValidator {

  static final Set<String> _allowedElements = new Set.from([
    'A',
    'ABBR',
    'ACRONYM',
    'ADDRESS',
    'AREA',
    'ARTICLE',
    'ASIDE',
    'AUDIO',
    'B',
    'BDI',
    'BDO',
    'BIG',
    'BLOCKQUOTE',
    'BR',
    'BUTTON',
    'CANVAS',
    'CAPTION',
    'CENTER',
    'CITE',
    'CODE',
    'COL',
    'COLGROUP',
    'COMMAND',
    'DATA',
    'DATALIST',
    'DD',
    'DEL',
    'DETAILS',
    'DFN',
    'DIR',
    'DIV',
    'DL',
    'DT',
    'EM',
    'FIELDSET',
    'FIGCAPTION',
    'FIGURE',
    'FONT',
    'FOOTER',
    'FORM',
    'H1',
    'H2',
    'H3',
    'H4',
    'H5',
    'H6',
    'HEADER',
    'HGROUP',
    'HR',
    'I',
    'IFRAME',
    'IMG',
    'INPUT',
    'INS',
    'KBD',
    'LABEL',
    'LEGEND',
    'LI',
    'MAP',
    'MARK',
    'MENU',
    'METER',
    'NAV',
    'NOBR',
    'OL',
    'OPTGROUP',
    'OPTION',
    'OUTPUT',
    'P',
    'PRE',
    'PROGRESS',
    'Q',
    'S',
    'SAMP',
    'SECTION',
    'SELECT',
    'SMALL',
    'SOURCE',
    'SPAN',
    'STRIKE',
    'STRONG',
    'SUB',
    'SUMMARY',
    'SUP',
    'TABLE',
    'TBODY',
    'TD',
    'TEXTAREA',
    'TFOOT',
    'TH',
    'THEAD',
    'TIME',
    'TR',
    'TRACK',
    'TT',
    'U',
    'UL',
    'VAR',
    'VIDEO',
    'WBR',
  ]);

  static const _standardAttributes = const <String>[
    '*::class',
    '*::dir',
    '*::draggable',
    '*::hidden',
    '*::id',
    '*::inert',
    '*::itemprop',
    '*::itemref',
    '*::itemscope',
    '*::lang',
    '*::spellcheck',
    '*::title',
    '*::translate',
    'A::accesskey',
    'A::coords',
    'A::hreflang',
    'A::name',
    'A::shape',
    'A::tabindex',
    'A::target',
    'A::type',
    'AREA::accesskey',
    'AREA::alt',
    'AREA::coords',
    'AREA::nohref',
    'AREA::shape',
    'AREA::tabindex',
    'AREA::target',
    'AUDIO::controls',
    'AUDIO::loop',
    'AUDIO::mediagroup',
    'AUDIO::muted',
    'AUDIO::preload',
    'BDO::dir',
    'BODY::alink',
    'BODY::bgcolor',
    'BODY::link',
    'BODY::text',
    'BODY::vlink',
    'BR::clear',
    'BUTTON::accesskey',
    'BUTTON::disabled',
    'BUTTON::name',
    'BUTTON::tabindex',
    'BUTTON::type',
    'BUTTON::value',
    'CANVAS::height',
    'CANVAS::width',
    'CAPTION::align',
    'COL::align',
    'COL::char',
    'COL::charoff',
    'COL::span',
    'COL::valign',
    'COL::width',
    'COLGROUP::align',
    'COLGROUP::char',
    'COLGROUP::charoff',
    'COLGROUP::span',
    'COLGROUP::valign',
    'COLGROUP::width',
    'COMMAND::checked',
    'COMMAND::command',
    'COMMAND::disabled',
    'COMMAND::label',
    'COMMAND::radiogroup',
    'COMMAND::type',
    'DATA::value',
    'DEL::datetime',
    'DETAILS::open',
    'DIR::compact',
    'DIV::align',
    'DL::compact',
    'FIELDSET::disabled',
    'FONT::color',
    'FONT::face',
    'FONT::size',
    'FORM::accept',
    'FORM::autocomplete',
    'FORM::enctype',
    'FORM::method',
    'FORM::name',
    'FORM::novalidate',
    'FORM::target',
    'FRAME::name',
    'H1::align',
    'H2::align',
    'H3::align',
    'H4::align',
    'H5::align',
    'H6::align',
    'HR::align',
    'HR::noshade',
    'HR::size',
    'HR::width',
    'HTML::version',
    'IFRAME::align',
    'IFRAME::frameborder',
    'IFRAME::height',
    'IFRAME::marginheight',
    'IFRAME::marginwidth',
    'IFRAME::width',
    'IMG::align',
    'IMG::alt',
    'IMG::border',
    'IMG::height',
    'IMG::hspace',
    'IMG::ismap',
    'IMG::name',
    'IMG::usemap',
    'IMG::vspace',
    'IMG::width',
    'INPUT::accept',
    'INPUT::accesskey',
    'INPUT::align',
    'INPUT::alt',
    'INPUT::autocomplete',
    'INPUT::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<KeyboardEvent> _keyDownList = <KeyboardEvent>[];

  /** The type of KeyEvent we are tracking (keyup, keydown, keypress). */
  final String _type;

  /** The element we are watching for events to happen on. */
  final EventTarget _target;

  // The distance to shift from upper case alphabet Roman letters to lower case.
  static final int _ROMAN_ALPHABET_OFFSET = "a".codeUnits[0] - "A".codeUnits[0];

  /** Custom Stream (Controller) to produce KeyEvents for the stream. */
  _CustomKeyEventStreamImpl _stream;

  static const _EVENT_TYPE = 'KeyEvent';

  /**
   * An enumeration of key identifiers currently part of the W3C draft for DOM3
   * and their mappings to keyCodes.
   * http://www.w3.org/TR/DOM-Level-3-Events/keyset.html#KeySet-Set
   */
  static const Map<String, int> _keyIdentifier = const {
    'Up': KeyCode.UP,
    'Down': KeyCode.DOWN,
    'Left': KeyCode.LEFT,
    'Right': KeyCode.RIGHT,
    'Enter': KeyCode.ENTER,
    'F1': KeyCode.F1,
    'F2': KeyCode.F2,
    'F3': KeyCode.F3,
    'F4': KeyCode.F4,
    'F5': KeyCode.F5,
    'F6': KeyCode.F6,
    'F7': KeyCode.F7,
    'F8': KeyCode.F8,
    'F9': KeyCode.F9,
    'F10': KeyCode.F10,
    'F11': KeyCode.F11,
    'F12': KeyCode.F12,
    'U+007F': KeyCode.DELETE,
    'Home': KeyCode.HOME,
    'End': KeyCode.END,
    'PageUp': KeyCode.PAGE_UP,
    'PageDown': KeyCode.PAGE_DOWN,
    'Insert': KeyCode.INSERT
  };

  /** Return a stream for KeyEvents for the specified target. */
  // Note: this actually functions like a factory constructor.
  CustomStream<KeyEvent> forTarget(EventTarget e, {bool useCapture: false}) {
    var handler = new _KeyboardEventHandler.initializeAllEventListeners(
        _type, e);
    return handler._stream;
  }

  /**
   * General constructor, performs basic initialization for our improved
   * KeyboardEvent controller.
   */
  _KeyboardEventHandler(this._type): super(_EVENT_TYPE),
      _stream = new _CustomKeyEventStreamImpl('event'), _target = null;

  /**
   * Hook up all event listeners under the covers so we can estimate keycodes
   * and charcodes when they are not provided.
   */
  _KeyboardEventHandler.initializeAllEventListeners(this._type, this._target) :
      super(_EVENT_TYPE) {
    Element.keyDownEvent.forTarget(_target, useCapture: true).listen(
        processKeyDown);
    Element.keyPressEvent.forTarget(_target, useCapture: true).listen(
        processKeyPress);
    Element.keyUpEvent.forTarget(_target, useCapture: true).listen(
        processKeyUp);
    _stream = new _CustomKeyEventStreamImpl(_type);
  }

  /** Determine if caps lock is one of the currently depressed keys. */
  bool get _capsLockOn =>
      _keyDownList.any((var element) => element.keyCode == KeyCode.CAPS_LOCK);

  /**
   * Given the previously recorded keydown key codes, see if we can determine
   * the keycode of this keypress [event]. (Generally browsers only provide
   * charCode information for keypress events, but with a little
   * reverse-engineering, we can also determine the keyCode.) Returns
   * KeyCode.UNKNOWN if the keycode could not be determined.
   */
  int _determineKeyCodeForKeypress(KeyboardEvent event) {
    // Note: This function is a work in progress. We'll expand this function
    // once we get more information about other keyboards.
    for (var prevEvent in _keyDownList) {
      if (prevEvent._shadowCharCode == event.charCode) {
        return prevEvent.keyCode;
      }
      if ((event.shiftKey || _capsLockOn) && event.charCode >= "A".codeUnits[0]
          && event.charCode <= "Z".codeUnits[0] && event.charCode +
          _ROMAN_ALPHABET_OFFSET == prevEvent._shadowCharCode) {
        return prevEvent.keyCode;
      }
    }
    return KeyCode.UNKNOWN;
  }

  /**
   * Given the charater code returned from a keyDown [event], try to ascertain
   * and return the corresponding charCode for the character that was pressed.
   * This information is not shown to the user, but used to help polyfill
   * keypress events.
   */
  int _findCharCodeKeyDown(KeyboardEvent event) {
    if (event.keyLocation == 3) { // Numpad keys.
      switch (event.keyCode) {
        case KeyCode.NUM_ZERO:
          // Even though this function returns _charCodes_, for some cases the
          // KeyCode == the charCode we want, in which case we use the keycode
          // constant for readability.
          return KeyCode.ZERO;
        case KeyCode.NUM_ONE:
          return KeyCode.ONE;
        case KeyCode.NUM_TWO:
          return KeyCode.TWO;
        case KeyCode.NUM_THREE:
          return KeyCode.THREE;
        case KeyCode.NUM_FOUR:
          return KeyCode.FOUR;
        case KeyCode.NUM_FIVE:
          return KeyCode.FIVE;
        case KeyCode.NUM_SIX:
          return KeyCode.SIX;
        case KeyCode.NUM_SEVEN:
          return KeyCode.SEVEN;
        case KeyCode.NUM_EIGHT:
          return KeyCode.EIGHT;
        case KeyCode.NUM_NINE:
          return KeyCode.NINE;
        case KeyCode.NUM_MULTIPLY:
          return 42; // Char code for *
        case KeyCode.NUM_PLUS:
          return 43; // +
        case KeyCode.NUM_MINUS:
          return 45; // -
        case KeyCode.NUM_PERIOD:
          return 46; // .
        case KeyCode.NUM_DIVISION:
          return 47; // /
      }
    } else if (event.keyCode >= 65 && event.keyCode <= 90) {
      // Set the "char code" for key down as the lower case letter. Again, this
      // will not show up for the user, but will be helpful in estimating
      // keyCode locations and other information during the keyPress event.
      return event.keyCode + _ROMAN_ALPHABET_OFFSET;
    }
    switch(event.keyCode) {
      case KeyCode.SEMICOLON:
        return KeyCode.FF_SEMICOLON;
      case KeyCode.EQUALS:
        return KeyCode.FF_EQUALS;
      case KeyCode.COMMA:
        return 44; // Ascii value for ,
      case KeyCode.DASH:
        return 45; // -
      case KeyCode.PERIOD:
        return 46; // .
      case KeyCode.SLASH:
        return 47; // /
      case KeyCode.APOSTROPHE:
        return 96; // `
      case KeyCode.OPEN_SQUARE_BRACKET:
        return 91; // [
      case KeyCode.BACKSLASH:
        return 92; // \
      case KeyCode.CLOSE_SQUARE_BRACKET:
        return 93; // ]
      case KeyCode.SINGLE_QUOTE:
        return 39; // '
    }
    return event.keyCode;
  }

  /**
   * Returns true if the key fires a keypress event in the current browser.
   */
  bool _firesKeyPressEvent(KeyEvent event) {
    if (!Device.isIE && !Device.isWebKit) {
      return true;
    }

    if (Device.userAgent.contains('Mac') && event.altKey) {
      return KeyCode.isCharacterKey(event.keyCode);
    }

    // Alt but not AltGr which is represented as Alt+Ctrl.
    if (event.altKey && !event.ctrlKey) {
      return false;
    }

    // Saves Ctrl or Alt + key for IE and WebKit, which won't fire keypress.
    if (!event.shiftKey &&
        (_keyDownList.last.keyCode == KeyCode.CTRL ||
         _keyDownList.last.keyCode == KeyCode.ALT ||
         Device.userAgent.contains('Mac') &&
         _keyDownList.last.keyCode == KeyCode.META)) {
      return false;
    }

    // Some keys with Ctrl/Shift do not issue keypress in WebKit.
    if (Device.isWebKit && event.ctrlKey && event.shiftKey && (
        event.keyCode == KeyCode.BACKSLASH ||
        event.keyCode == KeyCode.OPEN_SQUARE_BRACKET ||
        event.keyCode == KeyCode.CLOSE_SQUARE_BRACKET ||
        event.keyCode == KeyCode.TILDE ||
        event.keyCode == KeyCode.SEMICOLON || event.keyCode == KeyCode.DASH ||
        event.keyCode == KeyCode.EQUALS || event.keyCode == KeyCode.COMMA ||
        event.keyCode == KeyCode.PERIOD || event.keyCode == KeyCode.SLASH ||
        event.keyCode == KeyCode.APOSTROPHE ||
        event.keyCode == KeyCode.SINGLE_QUOTE)) {
      return false;
    }

    switch (event.keyCode) {
      case KeyCode.ENTER:
        // IE9 does not fire keypress on ENTER.
        return !Device.isIE;
      case KeyCode.ESC:
        return !Device.isWebKit;
    }

    return KeyCode.isCharacterKey(event.keyCode);
  }

  /**
   * Normalize the keycodes to the IE KeyCodes (this is what Chrome, IE, and
   * Opera all use).
   */
  int _normalizeKeyCodes(KeyboardEvent event) {
    // Note: This may change once we get input about non-US keyboards.
    if (Device.isFirefox) {
      switch(event.keyCode) {
        case KeyCode.FF_EQUALS:
          return KeyCode.EQUALS;
        case KeyCode.FF_SEMICOLON:
          return KeyCode.SEMICOLON;
        case KeyCode.MAC_FF_META:
          return KeyCode.META;
        case KeyCode.WIN_KEY_FF_LINUX:
          return KeyCode.WIN_KEY;
      }
    }
    return event.keyCode;
  }

  /** Handle keydown events. */
  void processKeyDown(KeyboardEvent e) {
    // Ctrl-Tab and Alt-Tab can cause the focus to be moved to another window
    // before we've caught a key-up event.  If the last-key was one of these
    // we reset the state.
    if (_keyDownList.length > 0 &&
        (_keyDownList.last.keyCode == KeyCode.CTRL && !e.ctrlKey ||
         _keyDownList.last.keyCode == KeyCode.ALT && !e.altKey ||
         Device.userAgent.contains('Mac') &&
         _keyDownList.last.keyCode == KeyCode.META && !e.metaKey)) {
      _keyDownList.clear();
    }

    var event = new KeyEvent.wrap(e);
    event._shadowKeyCode = _normalizeKeyCodes(event);
    // Technically a "keydown" event doesn't have a charCode. This is
    // calculated nonetheless to provide us with more information in giving
    // as much information as possible on keypress about keycode and also
    // charCode.
    event._shadowCharCode = _findCharCodeKeyDown(event);
    if (_keyDownList.length > 0 && event.keyCode != _keyDownList.last.keyCode &&
        !_firesKeyPressEvent(event)) {
      // Some browsers have quirks not firing keypress events where all other
      // browsers do. This makes them more consistent.
      processKeyPress(e);
    }
    _keyDownList.add(event);
    _stream.add(event);
  }

  /** Handle keypress events. */
  void processKeyPress(KeyboardEvent event) {
    var e = new KeyEvent.wrap(event);
    // IE reports the character code in the keyCode field for keypress events.
    // There are two exceptions however, Enter and Escape.
    if (Device.isIE) {
      if (e.keyCode == KeyCode.ENTER || e.keyCode == KeyCode.ESC) {
        e._shadowCharCode = 0;
      } else {
        e._shadowCharCode = e.keyCode;
      }
    } else if (Device.isOpera) {
      // Opera reports the character code in the keyCode field.
      e._shadowCharCode = KeyCode.isCharacterKey(e.keyCode) ? e.keyCode : 0;
    }
    // Now we guestimate about what the keycode is that was actually
    // pressed, given previous keydown information.
    e._shadowKeyCode = _determineKeyCodeForKeypress(e);

    // Correct the key value for certain browser-specific quirks.
    if (e._shadowKeyIdentifier != null &&
        _keyIdentifier.containsKey(e._shadowKeyIdentifier)) {
      // This is needed for Safari Windows because it currently doesn't give a
      // keyCode/which for non printable keys.
      e._shadowKeyCode = _keyIdentifier[e._shadowKeyIdentifier];
    }
    e._shadowAltKey = _keyDownList.any((var element) => element.altKey);
    _stream.add(e);
  }

  /** Handle keyup events. */
  void processKeyUp(KeyboardEvent event) {
    var e = new KeyEvent.wrap(event);
    KeyboardEvent toRemove = null;
    for (var key in _keyDownList) {
      if (key.keyCode == e.keyCode) {
        toRemove = key;
      }
    }
    if (toRemove != null) {
      _keyDownList.removeWhere((element) => element == toRemove);
    } else if (_keyDownList.length > 0) {
      // This happens when we've reached some international keyboard case we
      // haven't accounted for or we haven't correctly eliminated all browser
      // inconsistencies. Filing bugs on when this is reached is welcome!
      _keyDownList.removeLast();
    }
    _stream.add(e);
  }
}


/**
 * Records KeyboardEvents that occur on a particular element, and provides a
 * stream of outgoing KeyEvents with cross-browser consistent keyCode and
 * charCode values despite the fact that a multitude of browsers that have
 * varying keyboard default behavior.
 *
 * Example usage:
 *
 *     KeyboardEventStream.onKeyDown(document.body).listen(
 *         keydownHandlerTest);
 *
 * This class is very much a work in progress, and we'd love to get information
 * on how we can make this class work with as many international keyboards as
 * possible. Bugs welcome!
 */
class KeyboardEventStream {

  /** Named constructor to produce a stream for onKeyPress events. */
  static CustomStream<KeyEvent> onKeyPress(EventTarget target) =>
      new _KeyboardEventHandler('keypress').forTarget(target);

  /** Named constructor to produce a stream for onKeyUp events. */
  static CustomStream<KeyEvent> onKeyUp(EventTarget target) =>
      new _KeyboardEventHandler('keyup').forTarget(target);

  /** Named constructor to produce a stream for onKeyDown events. */
  static CustomStream<KeyEvent> onKeyDown(EventTarget target) =>
      new _KeyboardEventHandler('keydown').forTarget(target);
}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.



/**
 * Class which helps construct standard node validation policies.
 *
 * By default this will not accept anything, but the 'allow*' functions can be
 * used to expand what types of elements or attributes are allowed.
 *
 * All allow functions are additive- elements will be accepted if they are
 * accepted by any specific rule.
 *
 * It is important to remember that sanitization is not just intended to prevent
 * cross-site scripting attacks, but also to prevent information from being
 * displayed in unexpected ways. For example something displaying basic
 * formatted text may not expect `<video>` tags to appear. In this case an
 * empty NodeValidatorBuilder with just [allowTextElements] might be
 * appropriate.
 */
class NodeValidatorBuilder implements NodeValidator {

  final List<NodeValidator> _validators = <NodeValidator>[];

  NodeValidatorBuilder() {
  }

  /**
   * Creates a new NodeValidatorBuilder which accepts common constructs.
   *
   * By default this will accept HTML5 elements and attributes with the default
   * [UriPolicy] and templating elements.
   *
   * Notable syntax which is filtered:
   *
   * * Only known-good HTML5 elements and attributes are allowed.
   * * All URLs must be same-origin, use [allowNavigation] and [allowImages] to
   * specify additional URI policies.
   * * Inline-styles are not allowed.
   * * Custom element tags are disallowed, use [allowCustomElement].
   * * Custom tags extensions are disallowed, use [allowTagExtension].
   * * SVG Elements are not allowed, use [allowSvg].
   *
   * For scenarios where the HTML should only contain formatted text
   * [allowTextElements] is more appropriate.
   *
   * Use [allowSvg] to allow SVG elements.
   */
  NodeValidatorBuilder.common() {
    allowHtml5();
    allowTemplating();
  }

  /**
   * Allows navigation elements- Form and Anchor tags, along with common
   * attributes.
   *
   * The UriPolicy can be used to restrict the locations the navigation elements
   * are allowed to direct to. By default this will use the default [UriPolicy].
   */
  void allowNavigation([UriPolicy uriPolicy]) {
    if (uriPolicy == null) {
      uriPolicy = new UriPolicy();
    }
    add(new _SimpleNodeValidator.allowNavigation(uriPolicy));
  }

  /**
   * Allows image elements.
   *
   * The UriPolicy can be used to restrict the locations the images may be
   * loaded from. By default this will use the default [UriPolicy].
   */
  void allowImages([UriPolicy uriPolicy]) {
    if (uriPolicy == null) {
      uriPolicy = new UriPolicy();
    }
    add(new _SimpleNodeValidator.allowImages(uriPolicy));
  }

  /**
   * Allow basic text elements.
   *
   * This allows a subset of HTML5 elements, specifically just these tags and
   * no attributes.
   *
   * * B
   * * BLOCKQUOTE
   * * BR
   * * EM
   * * H1
   * * H2
   * * H3
   * * H4
   * * H5
   * * H6
   * * HR
   * * I
   * * LI
   * * OL
   * * P
   * * SPAN
   * * UL
   */
  void allowTextElements() {
    add(new _SimpleNodeValidator.allowTextElements());
  }

  /**
   * Allow inline styles on elements.
   *
   * If [tagName] is not specified then this allows inline styles on all
   * elements. Otherwise tagName limits the styles to the specified elements.
   */
  void allowInlineStyles({String tagName}) {
    if (tagName == null) {
      tagName = '*';
    } else {
      tagName = tagName.toUpperCase();
    }
    add(new _SimpleNodeValidator(null, allowedAttributes: ['$tagName::style']));
  }

  /**
   * Allow common safe HTML5 elements and attributes.
   *
   * This list is based off of the Caja whitelists at:
   * https://code.google.com/p/google-caja/wiki/CajaWhitelists.
   *
   * Common things which are not allowed are script elements, style attributes
   * and any script handlers.
   */
  void allowHtml5({UriPolicy uriPolicy}) {
    add(new _Html5NodeValidator(uriPolicy: uriPolicy));
  }

  /**
   * Allow SVG elements and attributes except for known bad ones.
   */
  void allowSvg() {
    add(new _SvgNodeValidator());
  }

  /**
   * Allow custom elements with the specified tag name and specified attributes.
   *
   * This will allow the elements as custom tags (such as <x-foo></x-foo>),
   * but will not allow tag extensions. Use [allowTagExtension] to allow
   * tag extensions.
   */
  void allowCustomElement(String tagName,
      {UriPolicy uriPolicy,
      Iterable<String> attributes,
      Iterable<String> uriAttributes}) {

    var tagNameUpper = tagName.toUpperCase();
    var attrs;
    if (attributes != null) {
      attrs =
          attributes.map((name) => '$tagNameUpper::${name.toLowerCase()}');
    }
    var uriAttrs;
    if (uriAttributes != null) {
      uriAttrs =
          uriAttributes.map((name) => '$tagNameUpper::${name.toLowerCase()}');
    }
    if (uriPolicy == null) {
      uriPolicy = new UriPolicy();
    }

    add(new _CustomElementNodeValidator(
        uriPolicy,
        [tagNameUpper],
        attrs,
        uriAttrs,
        false,
        true));
  }

  /**
   * Allow custom tag extensions with the specified type name and specified
   * attributes.
   *
   * This will allow tag extensions (such as <div is="x-foo"></div>),
   * but will not allow custom tags. Use [allowCustomElement] to allow
   * custom tags.
   */
  void allowTagExtension(String tagName, String baseName,
      {UriPolicy uriPolicy,
      Iterable<String> attributes,
      Iterable<String> uriAttributes}) {

    var baseNameUpper = baseName.toUpperCase();
    var tagNameUpper = tagName.toUpperCase();
    var attrs;
    if (attributes != null) {
      attrs =
          attributes.map((name) => '$baseNameUpper::${name.toLowerCase()}');
    }
    var uriAttrs;
    if (uriAttributes != null) {
      uriAttrs =
          uriAttributes.map((name) => '$baseNameUpper::${name.toLowerCase()}');
    }
    if (uriPolicy == null) {
      uriPolicy = new UriPolicy();
    }

    add(new _CustomElementNodeValidator(
        uriPolicy,
        [tagNameUpper, baseNameUpper],
        attrs,
        uriAttrs,
        true,
        false));
  }

  void allowElement(String tagName, {UriPolicy uriPolicy,
    Iterable<String> attributes,
    Iterable<String> uriAttributes}) {

    allowCustomElement(tagName, uriPolicy: uriPolicy,
        attributes: attributes,
        uriAttributes: uriAttributes);
  }

  /**
   * Allow templating elements (such as <template> and template-related
   * attributes.
   *
   * This still requires other validators to allow regular attributes to be
   * bound (such as [allowHtml5]).
   */
  void allowTemplating() {
    add(new _TemplatingNodeValidator());
  }

  /**
   * Add an additional validator to the current list of validators.
   *
   * Elements and attributes will be accepted if they are accepted by any
   * validators.
   */
  void add(NodeValidator validator) {
    _validators.add(validator);
  }

  bool allowsElement(Element element) {
    return _validators.any((v) => v.allowsElement(element));
  }

  bool allowsAttribute(Element element, String attributeName, String value) {
    return _validators.any(
        (v) => v.allowsAttribute(element, attributeName, value));
  }
}

class _SimpleNodeValidator implements NodeValidator {
  final Set<String> allowedElements = new Set<String>();
  final Set<String> allowedAttributes = new Set<String>();
  final Set<String> allowedUriAttributes = new Set<String>();
  final UriPolicy uriPolicy;

  factory _SimpleNodeValidator.allowNavigation(UriPolicy uriPolicy) {
    return new _SimpleNodeValidator(uriPolicy,
      allowedElements: const [
        'A',
        'FORM'],
      allowedAttributes: const [
        'A::accesskey',
        'A::coords',
        'A::hreflang',
        'A::name',
        'A::shape',
        'A::tabindex',
        'A::target',
        'A::type',
        'FORM::accept',
        'FORM::autocomplete',
        'FORM::enctype',
        'FORM::method',
        'FORM::name',
        'FORM::novalidate',
        'FORM::target',
      ],
      allowedUriAttributes: const [
        'A::href',
        'FORM::action',
      ]);
  }

  factory _SimpleNodeValidator.allowImages(UriPolicy uriPolicy) {
    return new _SimpleNodeValidator(uriPolicy,
      allowedElements: const [
        'IMG'
      ],
      allowedAttributes: const [
        'IMG::align',
        'IMG::alt',
        'IMG::border',
        'IMG::height',
        'IMG::hspace',
        'IMG::ismap',
        'IMG::name',
        'IMG::usemap',
        'IMG::vspace',
        'IMG::width',
      ],
      allowedUriAttributes: const [
        'IMG::src',
      ]);
  }

  factory _SimpleNodeValidator.allowTextElements() {
    return new _SimpleNodeValidator(null,
      allowedElements: const [
        'B',
        'BLOCKQUOTE',
        'BR',
        'EM',
        'H1',
        'H2',
        'H3',
        'H4',
        'H5',
        'H6',
        'HR',
        'I',
        'LI',
        'OL',
        'P',
        'SPAN',
        'UL',
      ]);
  }

  /**
   * Elements must be uppercased tag names. For example `'IMG'`.
   * Attributes must be uppercased tag name followed by :: followed by
   * lowercase attribute name. For example `'IMG:src'`.
   */
  _SimpleNodeValidator(this.uriPolicy,
      {Iterable<String> allowedElements, Iterable<String> allowedAttributes,
        Iterable<String> allowedUriAttributes}) {
    this.allowedElements.addAll(allowedElements ?? const []);
    allowedAttributes = allowedAttributes ?? const [];
    allowedUriAttributes = allowedUriAttributes ?? const [];
    var legalAttributes = allowedAttributes.where(
        (x) => !_Html5NodeValidator._uriAttributes.contains(x));
    var extraUriAttributes = allowedAttributes.where(
        (x) => _Html5NodeValidator._uriAttributes.contains(x));
    this.allowedAttributes.addAll(legalAttributes);
    this.allowedUriAttributes.addAll(allowedUriAttributes);
    this.allowedUriAttributes.addAll(extraUriAttributes);
  }

  bool allowsElement(Element element) {
    return allowedElements.contains(Element._safeTagName(element));
  }

  bool allowsAttribute(Element element, String attributeName, String value) {
    var tagName = Element._safeTagName(element);
    if (allowedUriAttributes.contains('$tagName::$attributeName')) {
      return uriPolicy.allowsUri(value);
    } else if (allowedUriAttributes.contains('*::$attributeName')) {
      return uriPolicy.allowsUri(value);
    } else if (allowedAttributes.contains('$tagName::$attributeName')) {
      return true;
    } else if (allowedAttributes.contains('*::$attributeName')) {
      return true;
    } else if (allowedAttributes.contains('$tagName::*')) {
      return true;
    } else if (allowedAttributes.contains('*::*')) {
      return true;
    }
    return false;
  }
}

class _CustomElementNodeValidator extends _SimpleNodeValidator {
  final bool allowTypeExtension;
  final bool allowCustomTag;

  _CustomElementNodeValidator(UriPolicy uriPolicy,
      Iterable<String> allowedElements,
      Iterable<String> allowedAttributes,
      Iterable<String> allowedUriAttributes,
      bool allowTypeExtension,
      bool allowCustomTag):

      super(uriPolicy,
          allowedElements: allowedElements,
          allowedAttributes: allowedAttributes,
          allowedUriAttributes: allowedUriAttributes),
      this.allowTypeExtension = allowTypeExtension == true,
      this.allowCustomTag = allowCustomTag == true;

  bool allowsElement(Element element) {
    if (allowTypeExtension) {
      var isAttr = element.attributes['is'];
      if (isAttr != null) {
        return allowedElements.contains(isAttr.toUpperCase()) &&
            allowedElements.contains(Element._safeTagName(element));
      }
    }
    return allowCustomTag && allowedElements.contains(Element._safeTagName(element));
  }

  bool allowsAttribute(Element element, String attributeName, String value) {
   if (allowsElement(element)) {
      if (allowTypeExtension && attributeName == 'is' &&
          allowedElements.contains(value.toUpperCase())) {
        return true;
      }
      return super.allowsAttribute(element, attributeName, value);
    }
    return false;
  }
}

class _TemplatingNodeValidator extends _SimpleNodeValidator {
  static const _TEMPLATE_ATTRS =
      const <String>['bind', 'if', 'ref', 'repeat', 'syntax'];

  final Set<String> _templateAttrs;

  _TemplatingNodeValidator():
      super(null,
          allowedElements: [
            'TEMPLATE'
          ],
          allowedAttributes: _TEMPLATE_ATTRS.map((attr) => 'TEMPLATE::$attr')),
      _templateAttrs = new Set<String>.from(_TEMPLATE_ATTRS) {
  }

  bool allowsAttribute(Element element, String attributeName, String value) {
    if (super.allowsAttribute(element, attributeName, value)) {
      return true;
    }

    if (attributeName == 'template' && value == "") {
      return true;
    }

    if (element.attributes['template'] == "" ) {
      return _templateAttrs.contains(attributeName);
    }
    return false;
  }
}


class _SvgNodeValidator implements NodeValidator {
  bool allowsElement(Element element) {
    if (element is svg.ScriptElement) {
      return false;
    }
    // Firefox 37 has issues with creating foreign elements inside a
    // foreignobject tag as SvgElement. We don't want foreignobject contents
    // anyway, so just remove the whole tree outright. And we can't rely
    // on IE recognizing the SvgForeignObject type, so go by tagName. Bug 23144
    if (element is svg.SvgElement && Element._safeTagName(element) == 'foreignObject') {
      return false;
    }
    if (element is svg.SvgElement) {
      return true;
    }
    return false;
  }

  bool allowsAttribute(Element element, String attributeName, String value) {
    if (attributeName == 'is' || attributeName.startsWith('on')) {
      return false;
    }
    return allowsElement(element);
  }
}
// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


/**
 * Contains the set of standard values returned by HTMLDocument.getReadyState.
 */
abstract class ReadyState {
  /**
   * Indicates the document is still loading and parsing.
   */
  static const String LOADING = "loading";

  /**
   * Indicates the document is finished parsing but is still loading
   * subresources.
   */
  static const String INTERACTIVE = "interactive";

  /**
   * Indicates the document and all subresources have been loaded.
   */
  static const String COMPLETE = "complete";
}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.



/**
 * Interface used to validate that only accepted elements and attributes are
 * allowed while parsing HTML strings into DOM nodes.
 *
 * In general, customization of validation behavior should be done via the
 * [NodeValidatorBuilder] class to mitigate the chances of incorrectly
 * implementing validation rules.
 */
abstract class NodeValidator {

  /**
   * Construct a default NodeValidator which only accepts whitelisted HTML5
   * elements and attributes.
   *
   * If a uriPolicy is not specified then the default uriPolicy will be used.
   */
  factory NodeValidator({UriPolicy uriPolicy}) =>
      new _Html5NodeValidator(uriPolicy: uriPolicy);

  factory NodeValidator.throws(NodeValidator base) =>
      new _ThrowsNodeValidator(base);

  /**
   * Returns true if the tagName is an accepted type.
   */
  bool allowsElement(Element element);

  /**
   * Returns true if the attribute is allowed.
   *
   * The attributeName parameter will always be in lowercase.
   *
   * See [allowsElement] for format of tagName.
   */
  bool allowsAttribute(Element element, String attributeName, String value);
}

/**
 * Performs sanitization of a node tree after construction to ensure that it
 * does not contain any disallowed elements or attributes.
 *
 * In general custom implementations of this class should not be necessary and
 * all validation customization should be done in custom NodeValidators, but
 * custom implementations of this class can be created to perform more complex
 * tree sanitization.
 */
abstract class NodeTreeSanitizer {

  /**
   * Constructs a default tree sanitizer which will remove all elements and
   * attributes which are not allowed by the provided validator.
   */
  factory NodeTreeSanitizer(NodeValidator validator) =>
      new _ValidatingTreeSanitizer(validator);

  /**
   * Called with the root of the tree which is to be sanitized.
   *
   * This method needs to walk the entire tree and either remove elements and
   * attributes which are not recognized as safe or throw an exception which
   * will mark the entire tree as unsafe.
   */
  void sanitizeTree(Node node);

  /**
   * A sanitizer for trees that we trust. It does no validation and allows
   * any elements. It is also more efficient, since it can pass the text
   * directly through to the underlying APIs without creating a document
   * fragment to be sanitized.
   */
  static const trusted = const _TrustedHtmlTreeSanitizer();
}

/**
 * A sanitizer for trees that we trust. It does no validation and allows
 * any elements.
 */
class _TrustedHtmlTreeSanitizer implements NodeTreeSanitizer {
  const _TrustedHtmlTreeSanitizer();

  sanitizeTree(Node node) {}
}

/**
 * Defines the policy for what types of uris are allowed for particular
 * attribute values.
 *
 * This can be used to provide custom rules such as allowing all http:// URIs
 * for image attributes but only same-origin URIs for anchor tags.
 */
abstract class UriPolicy {
  /**
   * Constructs the default UriPolicy which is to only allow Uris to the same
   * origin as the application was launched from.
   *
   * This will block all ftp: mailto: URIs. It will also block accessing
   * https://example.com if the app is running from http://example.com.
   */
  factory UriPolicy() => new _SameOriginUriPolicy();

  /**
   * Checks if the uri is allowed on the specified attribute.
   *
   * The uri provided may or may not be a relative path.
   */
  bool allowsUri(String uri);
}

/**
 * Allows URIs to the same origin as the current application was loaded from
 * (such as https://example.com:80).
 */
class _SameOriginUriPolicy implements UriPolicy {
  final AnchorElement _hiddenAnchor = new AnchorElement();
  final Location _loc = window.location;

  bool allowsUri(String uri) {
    _hiddenAnchor.href = uri;
    // IE leaves an empty hostname for same-origin URIs.
    return (_hiddenAnchor.hostname == _loc.hostname &&
        _hiddenAnchor.port == _loc.port &&
        _hiddenAnchor.protocol == _loc.protocol) ||
        (_hiddenAnchor.hostname == '' &&
        _hiddenAnchor.port == '' &&
        (_hiddenAnchor.protocol == ':' || _hiddenAnchor.protocol == ''));
  }
}


class _ThrowsNodeValidator implements NodeValidator {
  final NodeValidator validator;

  _ThrowsNodeValidator(this.validator) {}

  bool allowsElement(Element element) {
    if (!validator.allowsElement(element)) {
      throw new ArgumentError(Element._safeTagName(element));
    }
    return true;
  }

  bool allowsAttribute(Element element, String attributeName, String value) {
    if (!validator.allowsAttribute(element, attributeName, value)) {
      throw new ArgumentError('${Element._safeTagName(element)}[$attributeName="$value"]');
    }
  }
}


/**
 * Standard tree sanitizer which validates a node tree against the provided
 * validator and removes any nodes or attributes which are not allowed.
 */
class _ValidatingTreeSanitizer implements NodeTreeSanitizer {
  NodeValidator validator;
  _ValidatingTreeSanitizer(this.validator) {}

  void sanitizeTree(Node node) {
    void walk(Node node, Node parent) {
      sanitizeNode(node, parent);

      var child = node.lastChild;
      while (child != null) {
        // Child may be removed during the walk.
        var nextChild = child.previousNode;
        walk(child, node);
        child = nextChild;
      }
    }
    walk(node, null);
  }

  /// Aggressively try to remove node.
  void _removeNode(Node node, Node parent) {
    // If we have the parent, it's presumably already passed more sanitization
    // or is the fragment, so ask it to remove the child. And if that fails
    // try to set the outer html.
    if (parent == null) {
      node.remove();
    } else {
      parent._removeChild(node);
    }
  }

  /// Sanitize the element, assuming we can't trust anything about it.
  void _sanitizeUntrustedElement(/* Element */ element, Node parent) {
    // If the _hasCorruptedAttributes does not successfully return false,
    // then we consider it corrupted and remove.
    // TODO(alanknight): This is a workaround because on Firefox
    // embed/object
    // tags typeof is "function", not "object". We don't recognize them, and
    // can't call methods. This does mean that you can't explicitly allow an
    // embed tag. The only thing that will let it through is a null
    // sanitizer that doesn't traverse the tree at all. But sanitizing while
    // allowing embeds seems quite unlikely. This is also the reason that we
    // can't declare the type of element, as an embed won't pass any type
    // check in dart2js.
    var corrupted = true;
    var attrs;
    var isAttr;
    try {
      // If getting/indexing attributes throws, count that as corrupt.
      attrs = element.attributes;
      isAttr = attrs['is'];
      var corruptedTest1 = Element._hasCorruptedAttributes(element);

      // On IE, erratically, the hasCorruptedAttributes test can return false,
      // even though it clearly is corrupted. A separate copy of the test
      // inlining just the basic check seems to help.
      corrupted = corruptedTest1 ? true : Element._hasCorruptedAttributesAdditionalCheck(element);
    } catch(e) {}
    var elementText = 'element unprintable';
    try {
      elementText = element.toString();
    } catch(e) {}
    try {
      var elementTagName = Element._safeTagName(element);
      _sanitizeElement(element, parent, corrupted, elementText, elementTagName,
          attrs, isAttr);
    } on ArgumentError { // Thrown by _ThrowsNodeValidator
      rethrow;
    } catch(e) {  // Unexpected exception sanitizing -> remove
      _removeNode(element, parent);
      window.console.warn('Removing corrupted element $elementText');
    }
  }

  /// Having done basic sanity checking on the element, and computed the
  /// important attributes we want to check, remove it if it's not valid
  /// or not allowed, either as a whole or particular attributes.
  void _sanitizeElement(Element element, Node parent, bool corrupted,
      String text, String tag, Map attrs, String isAttr) {
    if (false != corrupted) {
       _removeNode(element, parent);
      window.console.warn(
          'Removing element due to corrupted attributes on <$text>');
       return;
    }
    if (!validator.allowsElement(element)) {
      _removeNode(element, parent);
      window.console.warn(
          'Removing disallowed element <$tag> from $parent');
      return;
    }

    if (isAttr != null) {
      if (!validator.allowsAttribute(element, 'is', isAttr)) {
        _removeNode(element, parent);
        window.console.warn('Removing disallowed type extension '
            '<$tag is="$isAttr">');
        return;
      }
    }

    // TODO(blois): Need to be able to get all attributes, irrespective of
    // XMLNS.
    var keys = attrs.keys.toList();
    for (var i = attrs.length - 1; i >= 0; --i) {
      var name = keys[i];
      if (!validator.allowsAttribute(element, name.toLowerCase(),
          attrs[name])) {
        window.console.warn('Removing disallowed attribute '
            '<$tag $name="${attrs[name]}">');
        attrs.remove(name);
      }
    }

    if (element is TemplateElement) {
      TemplateElement template = element;
      sanitizeTree(template.content);
     }
  }

  /// Sanitize the node and its children recursively.
  void sanitizeNode(Node node, Node parent) {
    switch (node.nodeType) {
      case Node.ELEMENT_NODE:
        _sanitizeUntrustedElement(node, parent);
        break;
      case Node.COMMENT_NODE:
      case Node.DOCUMENT_FRAGMENT_NODE:
      case Node.TEXT_NODE:
      case Node.CDATA_SECTION_NODE:
        break;
      default:
        _removeNode(node, parent);
    }
  }
}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


/**
 * A list which just wraps another list, for either intercepting list calls or
 * retyping the list (for example, from List<A> to List<B> where B extends A).
 */
class _WrappedList<E extends Node> extends ListBase<E>
    implements NodeListWrapper {
  final List _list;

  _WrappedList(this._list);

  // Iterable APIs

  Iterator<E> get iterator => new _WrappedIterator(_list.iterator);

  int get length => _list.length;

  // Collection APIs

  void add(E element) { _list.add(element); }

  bool remove(Object element) => _list.remove(element);

  void clear() { _list.clear(); }

  // List APIs

  E operator [](int index) => _list[index];

  void operator []=(int index, E value) { _list[index] = value; }

  set length(int newLength) { _list.length = newLength; }

  void sort([int compare(E a, E b)]) { _list.sort(compare); }

  int indexOf(Object element, [int start = 0]) => _list.indexOf(element, start);

  int lastIndexOf(Object element, [int start]) => _list.lastIndexOf(element, start);

  void insert(int index, E element) => _list.insert(index, element);

  E removeAt(int index) => _list.removeAt(index);

  void setRange(int start, int end, Iterable<E> iterable, [int skipCount = 0]) {
    _list.setRange(start, end, iterable, skipCount);
  }

  void removeRange(int start, int end) { _list.removeRange(start, end); }

  void replaceRange(int start, int end, Iterable<E> iterable) {
    _list.replaceRange(start, end, iterable);
  }

  void fillRange(int start, int end, [E fillValue]) {
    _list.fillRange(start, end, fillValue);
  }

  List<Node> get rawList => _list;
}

/**
 * Iterator wrapper for _WrappedList.
 */
class _WrappedIterator<E> implements Iterator<E> {
  Iterator _iterator;

  _WrappedIterator(this._iterator);

  bool moveNext() {
    return _iterator.moveNext();
  }

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


class _HttpRequestUtils {

  // Helper for factory HttpRequest.get
  static HttpRequest get(String url,
                            onComplete(HttpRequest request),
                            bool withCredentials) {
    final request = new HttpRequest();
    request.open('GET', url, async: true);

    request.withCredentials = withCredentials;

    request.onReadyStateChange.listen((e) {
      if (request.readyState == HttpRequest.DONE) {
        onComplete(request);
      }
    });

    request.send();

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


// Iterator for arrays with fixed size.
class FixedSizeListIterator<T> implements Iterator<T> {
  final List<T> _array;
  final int _length;  // Cache array length for faster access.
  int _position;
  T _current;
  
  FixedSizeListIterator(List<T> array)
      : _array = array,
        _position = -1,
        _length = array.length;

  bool moveNext() {
    int nextPosition = _position + 1;
    if (nextPosition < _length) {
      _current = _array[nextPosition];
      _position = nextPosition;
      return true;
    }
    _current = null;
    _position = _length;
    return false;
  }

  T get current => _current;
}

// Iterator for arrays with variable size.
class _VariableSizeListIterator<T> implements Iterator<T> {
  final List<T> _array;
  int _position;
  T _current;

  _VariableSizeListIterator(List<T> array)
      : _array = array,
        _position = -1;

  bool moveNext() {
    int nextPosition = _position + 1;
    if (nextPosition < _array.length) {
      _current = _array[nextPosition];
      _position = nextPosition;
      return true;
    }
    _current = null;
    _position = _array.length;
    return false;
  }

  T get current => _current;
}
// Copyright (c) 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) {
    var jsObject;
    var tag;
    var isNativeElementExtension = false;

    try {
      tag = _getCustomElementName(element);
    } catch (e) {
      isNativeElementExtension = element.localName == _extendsTag;
    }

    if (element.runtimeType == HtmlElement || element.runtimeType == TemplateElement) {
      if (tag != _extendsTag) {
        throw new UnsupportedError('$tag is not registered.');
      }
      jsObject = unwrap_jso(element);
    } else if (element.runtimeType == js.JsObject) {
      // It's a Polymer core element (written in JS).
      jsObject = element;
    } else if (isNativeElementExtension) {
      // Extending a native element.
      jsObject = element.blink_jsObject;

      // Element to extend is the real tag.
      tag = element.localName;
    } else if (tag != null && element.localName != tag) {
      throw new UnsupportedError('Element is incorrect type. Got ${element.runtimeType}, expected native Html or Svg element to extend.');
    } else if (tag == null) {
      throw new UnsupportedError('Element is incorrect type. Got ${element.runtimeType}, expected HtmlElement/JsObject.');
    }

    // Remember Dart class to tagName for any upgrading done in wrap_jso.
    addCustomElementType(tag, _type, _extendsTag);

    return _createCustomUpgrader(_type, jsObject);
  }
}

/// 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.
   *  TODO(terry): Consider making blink_jsObject private (add underscore) for
   *               all blink_jsObject.  Then needed private wrap/unwrap_jso
   *               functions that delegate to a public wrap/unwrap_jso.
   */
  @Deprecated("Internal Use Only")
  js.JsObject blink_jsObject;

  /** 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.
 */
class _WrappedEvent implements Event {
  /** Needed because KeyboardEvent is implements.
   *  TODO(terry): Consider making blink_jsObject private (add underscore) for
   *               all blink_jsObject.  Then needed private wrap/unwrap_jso
   *               functions that delegate to a public wrap/unwrap_jso.
   */
  js.JsObject blink_jsObject;

  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.


_wrapZone(callback(arg)) {
  // For performance reasons avoid wrapping if we are in the root zone.
  if (Zone.current == Zone.ROOT) return callback;
  if (callback == null) return null;
  return Zone.current.bindUnaryCallback(callback, runGuarded: true);
}

_wrapBinaryZone(callback(arg1, arg2)) {
  if (Zone.current == Zone.ROOT) return callback;
  if (callback == null) return null;
  return Zone.current.bindBinaryCallback(callback, runGuarded: true);
}

/**
 * Alias for [querySelector]. Note this function is deprecated because its
 * semantics will be changing in the future.
 */
@deprecated
@Experimental()
Element query(String relativeSelectors) => document.query(relativeSelectors);
/**
 * Alias for [querySelectorAll]. Note this function is deprecated because its
 * semantics will be changing in the future.
 */
@deprecated
@Experimental()
ElementList<Element> queryAll(String relativeSelectors) => document.queryAll(relativeSelectors);

/**
 * Finds the first descendant element of this document that matches the
 * specified group of selectors.
 *
 * Unless your webpage contains multiple documents, the top-level
 * [querySelector]
 * method behaves the same as this method, so you should use it instead to
 * save typing a few characters.
 *
 * [selectors] should be a string using CSS selector syntax.
 *
 *     var element1 = document.querySelector('.className');
 *     var element2 = document.querySelector('#id');
 *
 * For details about CSS selector syntax, see the
 * [CSS selector specification](http://www.w3.org/TR/css3-selectors/).
 */
Element querySelector(String selectors) => document.querySelector(selectors);

/**
 * Finds all descendant elements of this document that match the specified
 * group of selectors.
 *
 * Unless your webpage contains multiple documents, the top-level
 * [querySelectorAll]
 * method behaves the same as this method, so you should use it instead to
 * save typing a few characters.
 *
 * [selectors] should be a string using CSS selector syntax.
 *
 *     var items = document.querySelectorAll('.itemClassName');
 *
 * For details about CSS selector syntax, see the
 * [CSS selector specification](http://www.w3.org/TR/css3-selectors/).
 */
ElementList<Element> querySelectorAll(String selectors) => document.querySelectorAll(selectors);

/// A utility for changing the Dart wrapper type for elements.
abstract class ElementUpgrader {
  /// Upgrade the specified element to be of the Dart type this was created for.
  ///
  /// After upgrading the element passed in is invalid and the returned value
  /// should be used instead.
  Element upgrade(Element element);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


class _Property {
  _Property(this.name) :
      _hasValue = false,
      writable = false,
      isMethod = false,
      isOwn = true,
      wasThrown = false;

  bool get hasValue => _hasValue;
  get value => _value;
  set value(v) {
    _value = v;
    _hasValue = true;
  }

  final String name;
  Function setter;
  Function getter;
  var _value;
  bool _hasValue;
  bool writable;
  bool isMethod;
  bool isOwn;
  bool wasThrown;
}

class _ConsoleVariables {
  Map<String, Object> _data = new Map<String, Object>();

  /**
   * Forward member accesses to the backing JavaScript object.
   */
  noSuchMethod(Invocation invocation) {
    String member = MirrorSystem.getName(invocation.memberName);
    if (invocation.isGetter) {
      return _data[member];
    } else if (invocation.isSetter) {
      assert(member.endsWith('='));
      member = member.substring(0, member.length - 1);
      _data[member] = invocation.positionalArguments[0];
    } else {
      return Function.apply(_data[member], invocation.positionalArguments,
          invocation.namedArguments);
    }
  }

  void clear() => _data.clear();

  /**
   * List all variables currently defined.
   */
  List variables() => _data.keys.toList();

  void setVariable(String name, value) {
    _data[name] = value;
  }
}

/**
 * Base class for invocation trampolines used to closurize methods, getters
 * and setters.
 */
abstract class _Trampoline implements Function {
  final ObjectMirror _receiver;
  final MethodMirror _methodMirror;
  final Symbol _selector;

  _Trampoline(this._receiver, this._methodMirror, this._selector);
}

class _MethodTrampoline extends _Trampoline {
  _MethodTrampoline(ObjectMirror receiver, MethodMirror methodMirror,
      Symbol selector) :
      super(receiver, methodMirror, selector);

  noSuchMethod(Invocation msg) {
    if (msg.memberName != #call) return super.noSuchMethod(msg);
    return _receiver.invoke(_selector,
                            msg.positionalArguments,
                            msg.namedArguments).reflectee;
  }
}

/**
 * Invocation trampoline class used to closurize getters.
 */
class _GetterTrampoline extends _Trampoline {
  _GetterTrampoline(ObjectMirror receiver, MethodMirror methodMirror,
      Symbol selector) :
      super(receiver, methodMirror, selector);

  call() => _receiver.getField(_selector).reflectee;
}

/**
 * Invocation trampoline class used to closurize setters.
 */
class _SetterTrampoline extends _Trampoline {
  _SetterTrampoline(ObjectMirror receiver, MethodMirror methodMirror,
      Symbol selector) :
      super(receiver, methodMirror, selector);

  call(value) {
    _receiver.setField(_selector, value);
  }
}

class _Utils {
  static double dateTimeToDouble(DateTime dateTime) =>
      dateTime.millisecondsSinceEpoch.toDouble();
  static DateTime doubleToDateTime(double dateTime) {
    try {
      return new DateTime.fromMillisecondsSinceEpoch(dateTime.toInt());
    } catch(_) {
      // TODO(antonnm): treat exceptions properly in bindings and
      // find out how to treat NaNs.
      return null;
    }
  }

  static maybeUnwrapJso(obj) => unwrap_jso(obj);

  static List convertToList(List list) {
    // FIXME: [possible optimization]: do not copy the array if Dart_IsArray is fine w/ it.
    final length = list.length;
    List result = new List(length);
    result.setRange(0, length, list);
    return result;
  }

  static List convertMapToList(Map map) {
    List result = [];
    map.forEach((k, v) => result.addAll([k, v]));
    return result;
  }

  static int convertCanvasElementGetContextMap(Map map) {
    int result = 0;
    if (map['alpha'] == true) result |= 0x01;
    if (map['depth'] == true) result |= 0x02;
    if (map['stencil'] == true) result |= 0x4;
    if (map['antialias'] == true) result |= 0x08;
    if (map['premultipliedAlpha'] == true) result |= 0x10;
    if (map['preserveDrawingBuffer'] == true) result |= 0x20;

    return result;
  }

  static void populateMap(Map result, List list) {
    for (int i = 0; i < list.length; i += 2) {
      result[list[i]] = list[i + 1];
    }
  }

  static bool isMap(obj) => obj is Map;

  static List toListIfIterable(obj) => obj is Iterable ? obj.toList() : null;

  static Map createMap() => {};

  static parseJson(String jsonSource) => const JsonDecoder().convert(jsonSource);

  static makeUnimplementedError(String fileName, int lineNo) {
    return new UnsupportedError('[info: $fileName:$lineNo]');
  }

  static bool isTypeSubclassOf(Type type, Type other) {
    if (type == other) {
      return true;
    }
    var superclass = reflectClass(type).superclass;
    if (superclass != null) {
      return isTypeSubclassOf(superclass.reflectedType, other);
    }
    return false;
  }

  static Element getAndValidateNativeType(Type type, String tagName) {
    var element = new Element.tag(tagName);
    if (!isTypeSubclassOf(type, element.runtimeType)) {
      return null;
    }
    return element;
  }

  static window() => wrap_jso(js.context['window']);

  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>.
  static spawnDomUri(String uri) => wrap_jso(_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;
  }

  /**
   * Returns a list of completions to use if the receiver is o.
   */
  static List<String> getCompletions(o) {
    MirrorSystem system = currentMirrorSystem();
    var completions = new Set<String>();
    addAll(Map<Symbol, dynamic> map, bool isStatic) {
      map.forEach((symbol, mirror) {
        if (mirror.isStatic == isStatic && !mirror.isPrivate) {
          var name = MirrorSystem.getName(symbol);
          if (mirror is MethodMirror && mirror.isSetter)
            name = name.substring(0, name.length - 1);
          completions.add(name);
        }
      });
    }

    addForClass(ClassMirror mirror, bool isStatic) {
      if (mirror == null)
        return;
      addAll(mirror.declarations, isStatic);
      if (mirror.superclass != null)
        addForClass(mirror.superclass, isStatic);
      for (var interface in mirror.superinterfaces) {
        addForClass(interface, isStatic);
      }
    }

    if (o is Type) {
      addForClass(reflectClass(o), true);
    } else {
      addForClass(reflect(o).type, false);
    }
    return completions.toList(growable: false);
  }

  /**
   * Adds all candidate String completitions from [declarations] to [output]
   * filtering based on [staticContext] and [includePrivate].
   */
  static void _getCompletionsHelper(ClassMirror classMirror,
      bool staticContext, LibraryMirror libraryMirror, Set<String> output) {
    bool includePrivate = libraryMirror == classMirror.owner;
    classMirror.declarations.forEach((symbol, declaration) {
      if (!includePrivate && declaration.isPrivate) return;
      if (declaration is VariableMirror) {
        if (staticContext != declaration.isStatic) return;
      } else if (declaration is MethodMirror) {
        if (declaration.isOperator) return;
        if (declaration.isConstructor) {
          if (!staticContext) return;
          var name = MirrorSystem.getName(declaration.constructorName);
          if (name.isNotEmpty) output.add(name);
          return;
        }
        if (staticContext != declaration.isStatic) return;
      } else if (declaration is TypeMirror) {
        return;
      }
      output.add(_getShortSymbolName(symbol, declaration));
    });

    if (!staticContext) {
      for (var interface in classMirror.superinterfaces) {
        _getCompletionsHelper(interface, staticContext,
            libraryMirror, output);
      }
      if (classMirror.superclass != null) {
        _getCompletionsHelper(classMirror.superclass, staticContext,
            libraryMirror, output);
      }
    }
  }

  static void _getLibraryCompletionsHelper(
      LibraryMirror library, bool includePrivate, Set<String> output) {
    library.declarations.forEach((symbol, declaration) {
      if (!includePrivate && declaration.isPrivate) return;
      output.add(_getShortSymbolName(symbol, declaration));
    });
  }

  static LibraryMirror getLibraryMirror(String url) =>
      currentMirrorSystem().libraries[Uri.parse(url)];

  /**
   * Get code completions for [o] only showing privates from [libraryUrl].
   */
  static List<String> getObjectCompletions(o, String libraryUrl) {
    var classMirror;
    bool staticContext;
    if (o is Type) {
      classMirror = reflectClass(o);
      staticContext = true;
    } else {
      classMirror = reflect(o).type;
      staticContext = false;
    }
    var names = new Set<String>();
    getClassCompletions(classMirror, names, staticContext, libraryUrl);
    return names.toList()..sort();
  }

  static void getClassCompletions(ClassMirror classMirror, Set<String> names,
      bool staticContext, String libraryUrl) {
    LibraryMirror libraryMirror = getLibraryMirror(libraryUrl);
    _getCompletionsHelper(classMirror, staticContext, libraryMirror, names);
  }

  static List<String> getLibraryCompletions(String url) {
    var names = new Set<String>();
    _getLibraryCompletionsHelper(getLibraryMirror(url), true, names);
    return names.toList();
  }

  /**
   * Get valid code completitions from within a library and all libraries
   * imported by that library.
   */
  static List<String> getLibraryCompletionsIncludingImports(String url) {
    var names = new Set<String>();
    var libraryMirror = getLibraryMirror(url);
    _getLibraryCompletionsHelper(libraryMirror, true, names);
    for (var dependency in libraryMirror.libraryDependencies) {
      if (dependency.isImport) {
        if (dependency.prefix == null) {
          _getLibraryCompletionsHelper(dependency.targetLibrary, false, names);
        } else {
          names.add(MirrorSystem.getName(dependency.prefix));
        }
      }
    }
    return names.toList();
  }

  static final SIDE_EFFECT_FREE_LIBRARIES = new Set<String>()
      ..add('dart:html')
      ..add('dart:indexed_db')
      ..add('dart:svg')
      ..add('dart:typed_data')
      ..add('dart:web_audio')
      ..add('dart:web_gl')
      ..add('dart:web_sql');

  static LibraryMirror _getLibrary(MethodMirror methodMirror) {
    var owner = methodMirror.owner;
    if (owner is ClassMirror) {
      return owner;
    } else if (owner is LibraryMirror) {
      return owner;
    }
    return null;
  }

  /**
   * For parity with the JavaScript debugger, we treat some getters as if
   * they are fields so that users can see their values immediately.
   * This matches JavaScript's behavior for getters on DOM objects.
   * In the future we should consider adding an annotation to tag getters
   * in user libraries as side effect free.
   */
  static bool _isSideEffectFreeGetter(MethodMirror methodMirror,
      LibraryMirror libraryMirror) {
    // This matches JavaScript behavior. We should consider displaying
    // getters for all dart platform libraries rather than just the DOM
    // libraries.
    return libraryMirror.uri.scheme == 'dart' &&
        SIDE_EFFECT_FREE_LIBRARIES.contains(libraryMirror.uri.toString());
  }

  /**
   * Whether we should treat a property as a field for the purposes of the
   * debugger.
   */
  static bool treatPropertyAsField(MethodMirror methodMirror,
      LibraryMirror libraryMirror) {
    return (methodMirror.isGetter || methodMirror.isSetter) &&
          (methodMirror.isSynthetic ||
              _isSideEffectFreeGetter(methodMirror,libraryMirror));
  }

  // TODO(jacobr): generate more concise function descriptions instead of
  // dumping the entire function source.
  static String describeFunction(function) {
    if (function is _Trampoline) return function._methodMirror.source;
    try {
      var mirror = reflect(function);
      return mirror.function.source;
    } catch (e) {
      return function.toString();
    }
  }

  static List getInvocationTrampolineDetails(_Trampoline method) {
    var loc = method._methodMirror.location;
    return [loc.line, loc.column, loc.sourceUri.toString(),
        MirrorSystem.getName(method._selector)];
  }

  static List getLibraryProperties(String libraryUrl, bool ownProperties,
      bool accessorPropertiesOnly) {
    var properties = new Map<String, _Property>();
    var libraryMirror = getLibraryMirror(libraryUrl);
    _addInstanceMirrors(libraryMirror, libraryMirror,
        libraryMirror.declarations,
        ownProperties, accessorPropertiesOnly, false, false,
        properties);
    if (!accessorPropertiesOnly) {
      // We need to add class properties for all classes in the library.
      libraryMirror.declarations.forEach((symbol, declarationMirror) {
        if (declarationMirror is ClassMirror) {
          var name = MirrorSystem.getName(symbol);
          if (declarationMirror.hasReflectedType
              && !properties.containsKey(name)) {
            properties[name] = new _Property(name)
                ..value = declarationMirror.reflectedType;
          }
        }
      });
    }
    return packageProperties(properties);
  }

  static List getObjectProperties(o, bool ownProperties,
      bool accessorPropertiesOnly) {
    var properties = new Map<String, _Property>();
    var names = new Set<String>();
    var objectMirror = reflect(o);
    var classMirror = objectMirror.type;
    _addInstanceMirrors(objectMirror, classMirror.owner,
        classMirror.instanceMembers,
        ownProperties, accessorPropertiesOnly, false, true,
        properties);
    return packageProperties(properties);
  }

  static List getObjectClassProperties(o, bool ownProperties,
      bool accessorPropertiesOnly) {
    var properties = new Map<String, _Property>();
    var objectMirror = reflect(o);
    var classMirror = objectMirror.type;
    _addInstanceMirrors(objectMirror, classMirror.owner,
        classMirror.instanceMembers,
        ownProperties, accessorPropertiesOnly, true, false,
        properties);
    _addStatics(classMirror, properties, accessorPropertiesOnly);
    return packageProperties(properties);
  }

  static List getClassProperties(Type t, bool ownProperties,
      bool accessorPropertiesOnly) {
    var properties = new Map<String, _Property>();
    var classMirror = reflectClass(t);
    _addStatics(classMirror, properties, accessorPropertiesOnly);
    return packageProperties(properties);
  }

  static void _addStatics(ClassMirror classMirror,
                          Map<String, _Property> properties,
                          bool accessorPropertiesOnly) {
    var libraryMirror = classMirror.owner;
    classMirror.declarations.forEach((symbol, declaration) {
      var name = _getShortSymbolName(symbol, declaration);
      if (name.isEmpty) return;
      if (declaration is VariableMirror) {
        if (accessorPropertiesOnly) return;
        if (!declaration.isStatic) return;
        properties.putIfAbsent(name, () => new _Property(name))
            ..value = classMirror.getField(symbol).reflectee
            ..writable = !declaration.isFinal && !declaration.isConst;
      } else if (declaration is MethodMirror) {
        MethodMirror methodMirror = declaration;
        // FIXMEDART: should we display constructors?
        if (methodMirror.isConstructor) return;
        if (!methodMirror.isStatic) return;
        if (accessorPropertiesOnly) {
          if (methodMirror.isRegularMethod ||
              treatPropertyAsField(methodMirror, libraryMirror)) {
            return;
          }
        } else if (!methodMirror.isRegularMethod &&
            !treatPropertyAsField(methodMirror, libraryMirror)) {
          return;
        }
        var property = properties.putIfAbsent(name, () => new _Property(name));
        _fillMethodMirrorProperty(libraryMirror, classMirror, methodMirror,
            symbol, accessorPropertiesOnly, property);
      }
    });
  }

  static void _fillMethodMirrorProperty(LibraryMirror libraryMirror,
        methodOwner, MethodMirror methodMirror, Symbol symbol,
        bool accessorPropertiesOnly, _Property property) {
    if (methodMirror.isRegularMethod) {
      property
          ..value = new _MethodTrampoline(methodOwner, methodMirror, symbol)
          ..isMethod = true;
    } else if (methodMirror.isGetter) {
      if (treatPropertyAsField(methodMirror, libraryMirror)) {
        try {
          property.value = methodOwner.getField(symbol).reflectee;
        } catch (e) {
          property
              ..wasThrown = true
              ..value = e;
        }
      } else if (accessorPropertiesOnly) {
        property.getter = new _GetterTrampoline(methodOwner,
            methodMirror, symbol);
      }
    } else if (methodMirror.isSetter) {
      if (accessorPropertiesOnly &&
          !treatPropertyAsField(methodMirror, libraryMirror)) {
        property.setter = new _SetterTrampoline(methodOwner,
            methodMirror, MirrorSystem.getSymbol(property.name, libraryMirror));
      }
      property.writable = true;
    }
  }

  /**
   * Helper method that handles collecting up properties from classes
   * or libraries using the filters [ownProperties], [accessorPropertiesOnly],
   * [hideFields], and [hideMethods] to determine which properties are
   * collected. [accessorPropertiesOnly] specifies whether all properties
   * should be returned or just accessors. [hideFields] specifies whether
   * fields should be hidden. hideMethods specifies whether methods should be
   * shown or hidden. [ownProperties] is not currently used but is part of the
   * Blink devtools API for enumerating properties.
   */
  static void _addInstanceMirrors(
      ObjectMirror objectMirror,
      LibraryMirror libraryMirror,
      Map<Symbol, Mirror> declarations,
      bool ownProperties, bool accessorPropertiesOnly,
      bool hideFields, bool hideMethods,
      Map<String, _Property> properties) {
    declarations.forEach((symbol, declaration) {
      if (declaration is TypedefMirror || declaration is ClassMirror) return;
      var name = _getShortSymbolName(symbol, declaration);
      if (name.isEmpty) return;
      bool isField = declaration is VariableMirror ||
          (declaration is MethodMirror &&
              treatPropertyAsField(declaration, libraryMirror));
      if ((isField && hideFields) || (hideMethods && !isField)) return;
      if (accessorPropertiesOnly) {
        if (declaration is VariableMirror || declaration.isRegularMethod ||
            isField) {
          return;
        }
      } else if (declaration is MethodMirror &&
          (declaration.isGetter || declaration.isSetter) &&
          !treatPropertyAsField(declaration, libraryMirror)) {
        return;
      }
      var property = properties.putIfAbsent(name, () => new _Property(name));
      if (declaration is VariableMirror) {
        property
            ..value = objectMirror.getField(symbol).reflectee
            ..writable = !declaration.isFinal && !declaration.isConst;
        return;
      }
      _fillMethodMirrorProperty(libraryMirror, objectMirror, declaration,
          symbol, accessorPropertiesOnly, property);
    });
  }

  /**
   * Flatten down the properties data structure into a List that is easy to
   * access from native code.
   */
  static List packageProperties(Map<String, _Property> properties) {
    var ret = [];
    for (var property in properties.values) {
      ret.addAll([property.name,
                  property.setter,
                  property.getter,
                  property.value,
                  property.hasValue,
                  property.writable,
                  property.isMethod,
                  property.isOwn,
                  property.wasThrown]);
    }
    return ret;
  }

  /**
   * Get a property, returning null if the property does not exist.
   * For private property names, we attempt to resolve the property in the
   * context of each library that the property name could be associated with.
   */
  static getObjectPropertySafe(o, String propertyName) {
    var objectMirror = reflect(o);
    var classMirror = objectMirror.type;
    if (propertyName.startsWith("_")) {
      var attemptedLibraries = new Set<LibraryMirror>();
      while (classMirror != null) {
        LibraryMirror library = classMirror.owner;
        if (!attemptedLibraries.contains(library)) {
          try {
            return objectMirror.getField(
                MirrorSystem.getSymbol(propertyName, library)).reflectee;
          } catch (e) { }
          attemptedLibraries.add(library);
        }
        classMirror = classMirror.superclass;
      }
      return null;
    }
    try {
      return objectMirror.getField(
          MirrorSystem.getSymbol(propertyName)).reflectee;
    } catch (e) {
      return null;
    }
  }

  /**
   * Helper to wrap the inspect method on InjectedScriptHost to provide the
   * inspect method required for the
   */
  static List consoleApi(host) {
    return [
        "inspect",
        (o) {
          host.callMethod("_inspect", [unwrap_jso(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(unwrap_jso(document), tag, customType, extendsTagName);

  static Element createElement(Document document, String tagName) =>
      wrap_jso(_blink.Blink_Utils.createElement(unwrap_jso(document), tagName));

  static Element changeElementWrapper(HtmlElement element, Type type) =>
      wrap_jso(_blink.Blink_Utils.changeElementWrapper(unwrap_jso(element), type));
}

class _DOMWindowCrossFrame extends DartHtmlDomObject implements
    WindowBase {
  /** Needed because KeyboardEvent is implements.
   *  TODO(terry): Consider making blink_jsObject private (add underscore) for
   *               all blink_jsObject.  Then needed private wrap/unwrap_jso
   *               functions that delegate to a public wrap/unwrap_jso.
   */
  js.JsObject blink_jsObject;

  _DOMWindowCrossFrame.internal();

  // Fields.
  HistoryBase get history => wrap_jso(_blink.Blink_DOMWindowCrossFrame.get_history(unwrap_jso(this)));
  LocationBase get location => wrap_jso(_blink.Blink_DOMWindowCrossFrame.get_location(unwrap_jso(this)));
  bool get closed => wrap_jso(_blink.Blink_DOMWindowCrossFrame.get_closed(unwrap_jso(this)));
  WindowBase get opener => wrap_jso(_blink.Blink_DOMWindowCrossFrame.get_opener(unwrap_jso(this)));
  WindowBase get parent => wrap_jso(_blink.Blink_DOMWindowCrossFrame.get_parent(unwrap_jso(this)));
  WindowBase get top => wrap_jso(_blink.Blink_DOMWindowCrossFrame.get_top(unwrap_jso(this)));

  // Methods.
  void close() => _blink.Blink_DOMWindowCrossFrame.close(unwrap_jso(this));
  void postMessage(/*SerializedScriptValue*/ message, String targetOrigin, [List messagePorts]) =>
      _blink.Blink_DOMWindowCrossFrame.postMessage(unwrap_jso(this),
         convertDartToNative_SerializedScriptValue(message), targetOrigin, messagePorts);

  // Implementation support.
  String get typeName => "Window";

  // TODO(efortuna): Remove this method. dartbug.com/16814
  Events get on => throw new UnsupportedError(
    'You can only attach EventListeners to your own window.');
  // TODO(efortuna): Remove this method. dartbug.com/16814
  void _addEventListener([String type, EventListener listener, bool useCapture])
      => throw new UnsupportedError(
    'You can only attach EventListeners to your own window.');
  // TODO(efortuna): Remove this method. dartbug.com/16814
  void addEventListener(String type, EventListener listener, [bool useCapture])
      => throw new UnsupportedError(
    'You can only attach EventListeners to your own window.');
  // TODO(efortuna): Remove this method. dartbug.com/16814
  bool dispatchEvent(Event event) => throw new UnsupportedError(
    'You can only attach EventListeners to your own window.');
  // TODO(efortuna): Remove this method. dartbug.com/16814
  void _removeEventListener([String type, EventListener listener,
      bool useCapture]) => throw new UnsupportedError(
    'You can only attach EventListeners to your own window.');
  // TODO(efortuna): Remove this method. dartbug.com/16814
  void removeEventListener(String type, EventListener listener,
      [bool useCapture]) => throw new UnsupportedError(
    'You can only attach EventListeners to your own window.');
}

class _HistoryCrossFrame extends DartHtmlDomObject implements HistoryBase {
  _HistoryCrossFrame.internal();

  // Methods.
  void back() => _blink.Blink_HistoryCrossFrame.back(unwrap_jso(this));
  void forward() => _blink.Blink_HistoryCrossFrame.forward(unwrap_jso(this));
  void go(int distance) => _blink.Blink_HistoryCrossFrame.go(unwrap_jso(this), distance);

  // Implementation support.
  String get typeName => "History";
}

class _LocationCrossFrame extends DartHtmlDomObject implements LocationBase {
  _LocationCrossFrame.internal();

  // Fields.
  set href(String h) => _blink.Blink_LocationCrossFrame.set_href(unwrap_jso(this), h);

  // 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 {
}
