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

};

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

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

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

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

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

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

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

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

  return null;
}

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

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

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

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

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

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

// FIXME: Can we make this private?
@Deprecated("Internal Use Only")
final htmlBlinkFunctionMap = {
  'Animation': () => Animation.internalCreateAnimation,
  'AnimationEffect': () => AnimationEffect.internalCreateAnimationEffect,
  'AnimationNode': () => AnimationNode.internalCreateAnimationNode,
  'AnimationPlayer': () => AnimationPlayer.internalCreateAnimationPlayer,
  'AnimationPlayerEvent': () => AnimationPlayerEvent.internalCreateAnimationPlayerEvent,
  'AnimationTimeline': () => AnimationTimeline.internalCreateAnimationTimeline,
  '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,
  'BeforeUnloadEvent': () => BeforeUnloadEvent.internalCreateBeforeUnloadEvent,
  'Blob': () => Blob.internalCreateBlob,
  'Body': () => Body.internalCreateBody,
  'CDATASection': () => CDataSection.internalCreateCDataSection,
  'CSS': () => Css.internalCreateCss,
  'CSSCharsetRule': () => CssCharsetRule.internalCreateCssCharsetRule,
  'CSSFontFaceRule': () => CssFontFaceRule.internalCreateCssFontFaceRule,
  'CSSImportRule': () => CssImportRule.internalCreateCssImportRule,
  'CSSKeyframeRule': () => CssKeyframeRule.internalCreateCssKeyframeRule,
  'CSSKeyframesRule': () => CssKeyframesRule.internalCreateCssKeyframesRule,
  'CSSMediaRule': () => CssMediaRule.internalCreateCssMediaRule,
  'CSSPageRule': () => CssPageRule.internalCreateCssPageRule,
  'CSSPrimitiveValue': () => _CSSPrimitiveValue.internalCreate_CSSPrimitiveValue,
  'CSSRule': () => CssRule.internalCreateCssRule,
  'CSSRuleList': () => _CssRuleList.internalCreate_CssRuleList,
  'CSSStyleDeclaration': () => CssStyleDeclaration.internalCreateCssStyleDeclaration,
  'CSSStyleRule': () => CssStyleRule.internalCreateCssStyleRule,
  'CSSStyleSheet': () => CssStyleSheet.internalCreateCssStyleSheet,
  'CSSSupportsRule': () => CssSupportsRule.internalCreateCssSupportsRule,
  'CSSUnknownRule': () => _CSSUnknownRule.internalCreate_CSSUnknownRule,
  'CSSValue': () => _CSSValue.internalCreate_CSSValue,
  'CSSValueList': () => _CssValueList.internalCreate_CssValueList,
  'CSSViewportRule': () => CssViewportRule.internalCreateCssViewportRule,
  'Cache': () => _Cache.internalCreate_Cache,
  'CacheStorage': () => CacheStorage.internalCreateCacheStorage,
  'Canvas2DContextAttributes': () => Canvas2DContextAttributes.internalCreateCanvas2DContextAttributes,
  'CanvasGradient': () => CanvasGradient.internalCreateCanvasGradient,
  'CanvasPattern': () => CanvasPattern.internalCreateCanvasPattern,
  'CanvasRenderingContext2D': () => CanvasRenderingContext2D.internalCreateCanvasRenderingContext2D,
  'CharacterData': () => CharacterData.internalCreateCharacterData,
  'CircularGeofencingRegion': () => CircularGeofencingRegion.internalCreateCircularGeofencingRegion,
  'ClientRect': () => _ClientRect.internalCreate_ClientRect,
  'ClientRectList': () => _ClientRectList.internalCreate_ClientRectList,
  'CloseEvent': () => CloseEvent.internalCreateCloseEvent,
  'Comment': () => Comment.internalCreateComment,
  'CompositionEvent': () => CompositionEvent.internalCreateCompositionEvent,
  'Console': () => Console.internalCreateConsole,
  'ConsoleBase': () => ConsoleBase.internalCreateConsoleBase,
  'Coordinates': () => Coordinates.internalCreateCoordinates,
  'Counter': () => _Counter.internalCreate_Counter,
  'Credential': () => Credential.internalCreateCredential,
  'CredentialsContainer': () => CredentialsContainer.internalCreateCredentialsContainer,
  '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,
  '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,
  '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,
  'GeofencingRegion': () => GeofencingRegion.internalCreateGeofencingRegion,
  'Geolocation': () => Geolocation.internalCreateGeolocation,
  'Geoposition': () => Geoposition.internalCreateGeoposition,
  '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,
  'InputMethodContext': () => InputMethodContext.internalCreateInputMethodContext,
  'InstallEvent': () => InstallEvent.internalCreateInstallEvent,
  'Iterator': () => DomIterator.internalCreateDomIterator,
  'KeyboardEvent': () => KeyboardEvent.internalCreateKeyboardEvent,
  'LocalCredential': () => LocalCredential.internalCreateLocalCredential,
  '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,
  'MediaError': () => MediaError.internalCreateMediaError,
  'MediaKeyError': () => MediaKeyError.internalCreateMediaKeyError,
  'MediaKeyEvent': () => MediaKeyEvent.internalCreateMediaKeyEvent,
  'MediaKeyMessageEvent': () => MediaKeyMessageEvent.internalCreateMediaKeyMessageEvent,
  'MediaKeyNeededEvent': () => MediaKeyNeededEvent.internalCreateMediaKeyNeededEvent,
  'MediaKeySession': () => MediaKeySession.internalCreateMediaKeySession,
  'MediaKeys': () => MediaKeys.internalCreateMediaKeys,
  'MediaList': () => MediaList.internalCreateMediaList,
  'MediaQueryList': () => MediaQueryList.internalCreateMediaQueryList,
  'MediaQueryListEvent': () => MediaQueryListEvent.internalCreateMediaQueryListEvent,
  '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,
  'NavigatorUserMediaError': () => NavigatorUserMediaError.internalCreateNavigatorUserMediaError,
  'NetworkInformation': () => NetworkInformation.internalCreateNetworkInformation,
  'Node': () => Node.internalCreateNode,
  'NodeFilter': () => NodeFilter.internalCreateNodeFilter,
  'NodeIterator': () => NodeIterator.internalCreateNodeIterator,
  'NodeList': () => NodeList.internalCreateNodeList,
  'Notification': () => Notification.internalCreateNotification,
  'OverflowEvent': () => OverflowEvent.internalCreateOverflowEvent,
  'PagePopupController': () => _PagePopupController.internalCreate_PagePopupController,
  'PageTransitionEvent': () => PageTransitionEvent.internalCreatePageTransitionEvent,
  'Path2D': () => Path2D.internalCreatePath2D,
  'Performance': () => Performance.internalCreatePerformance,
  'PerformanceEntry': () => PerformanceEntry.internalCreatePerformanceEntry,
  'PerformanceMark': () => PerformanceMark.internalCreatePerformanceMark,
  'PerformanceMeasure': () => PerformanceMeasure.internalCreatePerformanceMeasure,
  'PerformanceNavigation': () => PerformanceNavigation.internalCreatePerformanceNavigation,
  'PerformanceResourceTiming': () => PerformanceResourceTiming.internalCreatePerformanceResourceTiming,
  'PerformanceTiming': () => PerformanceTiming.internalCreatePerformanceTiming,
  'Plugin': () => Plugin.internalCreatePlugin,
  'PluginArray': () => PluginArray.internalCreatePluginArray,
  'PluginPlaceholderElement': () => PluginPlaceholderElement.internalCreatePluginPlaceholderElement,
  'PopStateEvent': () => PopStateEvent.internalCreatePopStateEvent,
  'PositionError': () => PositionError.internalCreatePositionError,
  'Presentation': () => Presentation.internalCreatePresentation,
  'ProcessingInstruction': () => ProcessingInstruction.internalCreateProcessingInstruction,
  'ProgressEvent': () => ProgressEvent.internalCreateProgressEvent,
  'PushEvent': () => PushEvent.internalCreatePushEvent,
  'PushManager': () => PushManager.internalCreatePushManager,
  'PushRegistration': () => PushRegistration.internalCreatePushRegistration,
  'RGBColor': () => _RGBColor.internalCreate_RGBColor,
  '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,
  'ReadableStream': () => ReadableStream.internalCreateReadableStream,
  'Rect': () => _Rect.internalCreate_Rect,
  'RelatedEvent': () => RelatedEvent.internalCreateRelatedEvent,
  'Request': () => _Request.internalCreate_Request,
  'ResourceProgressEvent': () => ResourceProgressEvent.internalCreateResourceProgressEvent,
  'Response': () => _Response.internalCreate_Response,
  'Screen': () => Screen.internalCreateScreen,
  'ScreenOrientation': () => ScreenOrientation.internalCreateScreenOrientation,
  'SecurityPolicyViolationEvent': () => SecurityPolicyViolationEvent.internalCreateSecurityPolicyViolationEvent,
  'Selection': () => Selection.internalCreateSelection,
  'ServiceWorker': () => _ServiceWorker.internalCreate_ServiceWorker,
  'ServiceWorkerClient': () => ServiceWorkerClient.internalCreateServiceWorkerClient,
  'ServiceWorkerClients': () => ServiceWorkerClients.internalCreateServiceWorkerClients,
  'ServiceWorkerContainer': () => ServiceWorkerContainer.internalCreateServiceWorkerContainer,
  'ServiceWorkerGlobalScope': () => ServiceWorkerGlobalScope.internalCreateServiceWorkerGlobalScope,
  'ServiceWorkerRegistration': () => ServiceWorkerRegistration.internalCreateServiceWorkerRegistration,
  'ShadowRoot': () => ShadowRoot.internalCreateShadowRoot,
  '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,
  '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,
  'Text': () => Text.internalCreateText,
  'TextEvent': () => TextEvent.internalCreateTextEvent,
  'TextMetrics': () => TextMetrics.internalCreateTextMetrics,
  'TextTrack': () => TextTrack.internalCreateTextTrack,
  'TextTrackCue': () => TextTrackCue.internalCreateTextTrackCue,
  'TextTrackCueList': () => TextTrackCueList.internalCreateTextTrackCueList,
  'TextTrackList': () => TextTrackList.internalCreateTextTrackList,
  'TimeRanges': () => TimeRanges.internalCreateTimeRanges,
  'Timing': () => Timing.internalCreateTiming,
  'Touch': () => Touch.internalCreateTouch,
  'TouchEvent': () => TouchEvent.internalCreateTouchEvent,
  'TouchList': () => TouchList.internalCreateTouchList,
  'TrackEvent': () => TrackEvent.internalCreateTrackEvent,
  'TransitionEvent': () => TransitionEvent.internalCreateTransitionEvent,
  'TreeWalker': () => TreeWalker.internalCreateTreeWalker,
  'UIEvent': () => UIEvent.internalCreateUIEvent,
  'URL': () => Url.internalCreateUrl,
  'VTTCue': () => VttCue.internalCreateVttCue,
  'VTTRegion': () => VttRegion.internalCreateVttRegion,
  'VTTRegionList': () => VttRegionList.internalCreateVttRegionList,
  'ValidityState': () => ValidityState.internalCreateValidityState,
  'VideoPlaybackQuality': () => VideoPlaybackQuality.internalCreateVideoPlaybackQuality,
  'VideoTrack': () => VideoTrack.internalCreateVideoTrack,
  'VideoTrackList': () => VideoTrackList.internalCreateVideoTrackList,
  'WebKitAnimationEvent': () => AnimationEvent.internalCreateAnimationEvent,
  'WebKitCSSFilterRule': () => CssFilterRule.internalCreateCssFilterRule,
  'WebKitCSSFilterValue': () => _WebKitCSSFilterValue.internalCreate_WebKitCSSFilterValue,
  'WebKitCSSMatrix': () => _WebKitCSSMatrix.internalCreate_WebKitCSSMatrix,
  'WebKitCSSTransformValue': () => _WebKitCSSTransformValue.internalCreate_WebKitCSSTransformValue,
  'WebSocket': () => WebSocket.internalCreateWebSocket,
  'WheelEvent': () => WheelEvent.internalCreateWheelEvent,
  'Window': () => Window.internalCreateWindow,
  '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.JsObjectImpl) {
    // 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/JsObjectImpl.');
  }

  return tag;
}

/// An abstract class for all DOM objects we wrap in dart:html and related
///  libraries.
///
/// ** Internal Use Only **
@Deprecated("Internal Use Only")
class DartHtmlDomObject {

  /// The underlying JS DOM object.
  @Deprecated("Internal Use Only")
  js.JsObject blink_jsObject;

}

/// Upgrade a Dart HtmlElement to the user's Dart custom element class.
_upgradeHtmlElement(dartInstance) {
  // Only try upgrading HtmlElement (Dart class) if there is a failure then
  // don't try it again - one failure is enough.
  if (dartInstance.runtimeType == HtmlElement && !dartInstance.isBadUpgrade) {
    // Must be exactly HtmlElement not something derived from it.

    var customElementClass = getCustomElementType(dartInstance);

    // Custom Element to upgrade.
    if (customElementClass != null) {
      var jsObject = dartInstance.blink_jsObject;
      try {
        dartInstance = _blink.Blink_Utils.constructElement(customElementClass, jsObject);
      } catch (e) {
        dartInstance._badUpgrade();
      } finally {
        dartInstance.blink_jsObject = jsObject;
        js.setDartHtmlWrapperFor(jsObject, dartInstance);
     }
   }
  }

  return dartInstance;
}

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

// TODO(terry): Manage JS interop JsFunctions for each listener used for add/
//              removeEventListener.  These JsFunctions will leak look at
//              fixing with weak-refs in C++.  The key are the hashcodes of the
//              user's this (this is needed for futures) and listener function.
Map<int, Map<int, js.JsFunction>> _knownListeners = {};

@Deprecated("Internal Use Only")
js.JsFunction wrap_event_listener(theObject, Function listener) {
  var thisHashCode = theObject.hashCode;
  var listenerHashCode = identityHashCode(listener);

  _knownListeners.putIfAbsent(thisHashCode, () => new Map<int, js.JsFunction>());
  _knownListeners[thisHashCode].putIfAbsent(listenerHashCode, () =>
    new js.JsFunction.withThis((theObject, event) => listener(wrap_jso(event))));

  return _knownListeners[thisHashCode][listenerHashCode];
}

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

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

  @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.integrity')
  @DocsEditable()
  @Experimental() // untriaged
  String get integrity => _blink.BlinkHTMLAnchorElement.instance.integrity_Getter_(unwrap_jso(this));
  
  @DomName('HTMLAnchorElement.integrity')
  @DocsEditable()
  @Experimental() // untriaged
  set integrity(String value) => _blink.BlinkHTMLAnchorElement.instance.integrity_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 AnimationNode {
  // To suppress missing implicit constructor warnings.
  factory Animation._() { throw new UnsupportedError("Not supported"); }

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


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

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

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

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

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

  @Deprecated("Internal Use Only")
  AnimationEffect.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('WebKitAnimationEvent')
@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.SAFARI)
@Experimental()
class AnimationEvent extends Event {
  // To suppress missing implicit constructor warnings.
  factory AnimationEvent._() { throw new UnsupportedError("Not supported"); }


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

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

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


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

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

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

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

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

  @DomName('AnimationNode.activeDuration')
  @DocsEditable()
  @Experimental() // untriaged
  num get activeDuration => _blink.BlinkAnimationNode.instance.activeDuration_Getter_(unwrap_jso(this));
  
  @DomName('AnimationNode.currentIteration')
  @DocsEditable()
  @Experimental() // untriaged
  int get currentIteration => _blink.BlinkAnimationNode.instance.currentIteration_Getter_(unwrap_jso(this));
  
  @DomName('AnimationNode.duration')
  @DocsEditable()
  @Experimental() // untriaged
  num get duration => _blink.BlinkAnimationNode.instance.duration_Getter_(unwrap_jso(this));
  
  @DomName('AnimationNode.endTime')
  @DocsEditable()
  @Experimental() // untriaged
  num get endTime => _blink.BlinkAnimationNode.instance.endTime_Getter_(unwrap_jso(this));
  
  @DomName('AnimationNode.localTime')
  @DocsEditable()
  @Experimental() // untriaged
  num get localTime => _blink.BlinkAnimationNode.instance.localTime_Getter_(unwrap_jso(this));
  
  @DomName('AnimationNode.player')
  @DocsEditable()
  @Experimental() // untriaged
  AnimationPlayer get player => wrap_jso(_blink.BlinkAnimationNode.instance.player_Getter_(unwrap_jso(this)));
  
  @DomName('AnimationNode.startTime')
  @DocsEditable()
  @Experimental() // untriaged
  num get startTime => _blink.BlinkAnimationNode.instance.startTime_Getter_(unwrap_jso(this));
  
  @DomName('AnimationNode.timing')
  @DocsEditable()
  @Experimental() // untriaged
  Timing get timing => wrap_jso(_blink.BlinkAnimationNode.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('AnimationPlayer')
@Experimental() // untriaged
class AnimationPlayer extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory AnimationPlayer._() { throw new UnsupportedError("Not supported"); }


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

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

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


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

  @DomName('AnimationPlayer.currentTime')
  @DocsEditable()
  @Experimental() // untriaged
  num get currentTime => _blink.BlinkAnimationPlayer.instance.currentTime_Getter_(unwrap_jso(this));
  
  @DomName('AnimationPlayer.currentTime')
  @DocsEditable()
  @Experimental() // untriaged
  set currentTime(num value) => _blink.BlinkAnimationPlayer.instance.currentTime_Setter_(unwrap_jso(this), value);
  
  @DomName('AnimationPlayer.playState')
  @DocsEditable()
  @Experimental() // untriaged
  String get playState => _blink.BlinkAnimationPlayer.instance.playState_Getter_(unwrap_jso(this));
  
  @DomName('AnimationPlayer.playbackRate')
  @DocsEditable()
  @Experimental() // untriaged
  num get playbackRate => _blink.BlinkAnimationPlayer.instance.playbackRate_Getter_(unwrap_jso(this));
  
  @DomName('AnimationPlayer.playbackRate')
  @DocsEditable()
  @Experimental() // untriaged
  set playbackRate(num value) => _blink.BlinkAnimationPlayer.instance.playbackRate_Setter_(unwrap_jso(this), value);
  
  @DomName('AnimationPlayer.source')
  @DocsEditable()
  @Experimental() // untriaged
  AnimationNode get source => wrap_jso(_blink.BlinkAnimationPlayer.instance.source_Getter_(unwrap_jso(this)));
  
  @DomName('AnimationPlayer.source')
  @DocsEditable()
  @Experimental() // untriaged
  set source(AnimationNode value) => _blink.BlinkAnimationPlayer.instance.source_Setter_(unwrap_jso(this), unwrap_jso(value));
  
  @DomName('AnimationPlayer.startTime')
  @DocsEditable()
  @Experimental() // untriaged
  num get startTime => _blink.BlinkAnimationPlayer.instance.startTime_Getter_(unwrap_jso(this));
  
  @DomName('AnimationPlayer.startTime')
  @DocsEditable()
  @Experimental() // untriaged
  set startTime(num value) => _blink.BlinkAnimationPlayer.instance.startTime_Setter_(unwrap_jso(this), value);
  
  @DomName('AnimationPlayer.cancel')
  @DocsEditable()
  @Experimental() // untriaged
  void cancel() => _blink.BlinkAnimationPlayer.instance.cancel_Callback_0_(unwrap_jso(this));
  
  @DomName('AnimationPlayer.finish')
  @DocsEditable()
  @Experimental() // untriaged
  void finish() => _blink.BlinkAnimationPlayer.instance.finish_Callback_0_(unwrap_jso(this));
  
  @DomName('AnimationPlayer.pause')
  @DocsEditable()
  @Experimental() // untriaged
  void pause() => _blink.BlinkAnimationPlayer.instance.pause_Callback_0_(unwrap_jso(this));
  
  @DomName('AnimationPlayer.play')
  @DocsEditable()
  @Experimental() // untriaged
  void play() => _blink.BlinkAnimationPlayer.instance.play_Callback_0_(unwrap_jso(this));
  
  @DomName('AnimationPlayer.reverse')
  @DocsEditable()
  @Experimental() // untriaged
  void reverse() => _blink.BlinkAnimationPlayer.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('AnimationPlayerEvent')
@Experimental() // untriaged
class AnimationPlayerEvent extends Event {
  // To suppress missing implicit constructor warnings.
  factory AnimationPlayerEvent._() { throw new UnsupportedError("Not supported"); }


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

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

  @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.getAnimationPlayers')
  @DocsEditable()
  @Experimental() // untriaged
  List<AnimationPlayer> getAnimationPlayers() => wrap_jso(_blink.BlinkAnimationTimeline.instance.getAnimationPlayers_Callback_0_(unwrap_jso(this)));
  
  @DomName('AnimationTimeline.play')
  @DocsEditable()
  @Experimental() // untriaged
  AnimationPlayer play(AnimationNode 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()
/**
 * 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();
  }

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

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


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

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

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

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

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

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

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

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

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


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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  @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.create')
  @DocsEditable()
  @Experimental() // untriaged
  Future create(String cacheName) => wrap_jso(_blink.BlinkCacheStorage.instance.create_Callback_1_(unwrap_jso(this), cacheName));
  
  @DomName('CacheStorage.delete')
  @DocsEditable()
  @Experimental() // untriaged
  Future delete(String cacheName) => wrap_jso(_blink.BlinkCacheStorage.instance.delete_Callback_1_(unwrap_jso(this), cacheName));
  
  @DomName('CacheStorage.get')
  @DocsEditable()
  @Experimental() // untriaged
  Future get(String cacheName) => wrap_jso(_blink.BlinkCacheStorage.instance.get_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)));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.


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

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

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

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

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

  @DomName('Canvas2DContextAttributes.alpha')
  @DocsEditable()
  bool get alpha => _blink.BlinkCanvas2DContextAttributes.instance.alpha_Getter_(unwrap_jso(this));
  
  @DomName('Canvas2DContextAttributes.alpha')
  @DocsEditable()
  set alpha(bool value) => _blink.BlinkCanvas2DContextAttributes.instance.alpha_Setter_(unwrap_jso(this), value);
  
  @DomName('Canvas2DContextAttributes.storage')
  @DocsEditable()
  @Experimental() // untriaged
  String get storage => _blink.BlinkCanvas2DContextAttributes.instance.storage_Getter_(unwrap_jso(this));
  
  @DomName('Canvas2DContextAttributes.storage')
  @DocsEditable()
  @Experimental() // untriaged
  set storage(String value) => _blink.BlinkCanvas2DContextAttributes.instance.storage_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('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();
  }

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

  @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);
  
  @DomName('HTMLCanvasElement.getContext')
  @DocsEditable()
  Object getContext(String contextId, [Map attrs]) => wrap_jso(_blink.BlinkHTMLCanvasElement.instance.getContext_Callback_2_(unwrap_jso(this), contextId, convertDartToNative_Dictionary(attrs)));
  
  @DomName('HTMLCanvasElement.toDataURL')
  @DocsEditable()
  String _toDataUrl(String type, [num quality]) => _blink.BlinkHTMLCanvasElement.instance.toDataURL_Callback_2_(unwrap_jso(this), type, quality);
  
  /// Stream of `webglcontextlost` events handled by this [CanvasElement].
  @DomName('HTMLCanvasElement.onwebglcontextlost')
  @DocsEditable()
  ElementStream<gl.ContextEvent> get onWebGlContextLost => webGlContextLostEvent.forElement(this);

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

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

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

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

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

// WARNING: Do not edit - generated code.


@DocsEditable()
/**
 * An opaque canvas object representing a gradient.
 *
 * Created by calling [createLinearGradient] or [createRadialGradient] on a
 * [CanvasRenderingContext2D] object.
 *
 * Example usage:
 *
 *     var canvas = new CanvasElement(width: 600, height: 600);
 *     var ctx = canvas.context2D;
 *     ctx.clearRect(0, 0, 600, 600);
 *     ctx.save();
 *     // Create radial gradient.
 *     CanvasGradient gradient = ctx.createRadialGradient(0, 0, 0, 0, 0, 600);
 *     gradient.addColorStop(0, '#000');
 *     gradient.addColorStop(1, 'rgb(255, 255, 255)');
 *     // Assign gradients to fill.
 *     ctx.fillStyle = gradient;
 *     // Draw a rectangle with a gradient fill.
 *     ctx.fillRect(0, 0, 600, 600);
 *     ctx.save();
 *     document.body.children.add(canvas);
 *
 * See also:
 *
 * * [CanvasGradient](https://developer.mozilla.org/en-US/docs/DOM/CanvasGradient) from MDN.
 * * [CanvasGradient](http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#canvasgradient) from whatwg.
 * * [CanvasGradient](http://www.w3.org/TR/2010/WD-2dcontext-20100304/#canvasgradient) from W3C.
 */
@DomName('CanvasGradient')
class CanvasGradient extends 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](http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#canvaspattern) from whatwg.
 * * [CanvasPattern](http://www.w3.org/TR/2010/WD-2dcontext-20100304/#canvaspattern) from W3C.
 */
@DomName('CanvasPattern')
class CanvasPattern extends 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.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]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#image-smoothing)
   * from WHATWG.
   */
  @DomName('CanvasRenderingContext2D.imageSmoothingEnabled')
  @DocsEditable()
  @Experimental() // untriaged
  bool get imageSmoothingEnabled => _blink.BlinkCanvasRenderingContext2D.instance.imageSmoothingEnabled_Getter_(unwrap_jso(this));
  
  /**
   * Whether images and patterns on this canvas will be smoothed when this
   * canvas is scaled.
   *
   * ## Other resources
   *
   * * [Image smoothing]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#image-smoothing)
   * from WHATWG.
   */
  @DomName('CanvasRenderingContext2D.imageSmoothingEnabled')
  @DocsEditable()
  @Experimental() // untriaged
  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");
  }

  @DomName('CanvasRenderingContext2D.createImageData')
  @DocsEditable()
  ImageData createImageData(num sw, num sh) => wrap_jso(_blink.BlinkCanvasRenderingContext2D.instance.createImageData_Callback_2_(unwrap_jso(this), sw, sh));
  
  @DomName('CanvasRenderingContext2D.createImageDataFromImageData')
  @DocsEditable()
  ImageData createImageDataFromImageData(ImageData imagedata) => wrap_jso(_blink.BlinkCanvasRenderingContext2D.instance.createImageData_Callback_1_(unwrap_jso(this), unwrap_jso(imagedata)));
  
  @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));
  
  CanvasPattern createPattern(canvas_OR_image, String repetitionType) {
    if ((repetitionType is String || repetitionType == null) && (canvas_OR_image is CanvasElement)) {
      return wrap_jso(_blink.BlinkCanvasRenderingContext2D.instance.createPattern_Callback_2_(unwrap_jso(this), unwrap_jso(canvas_OR_image), repetitionType));
    }
    if ((repetitionType is String || repetitionType == null) && (canvas_OR_image is VideoElement)) {
      return wrap_jso(_blink.BlinkCanvasRenderingContext2D.instance.createPattern_Callback_2_(unwrap_jso(this), unwrap_jso(canvas_OR_image), repetitionType));
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }

  @DomName('CanvasRenderingContext2D.createPatternFromImage')
  @DocsEditable()
  CanvasPattern createPatternFromImage(ImageElement image, String repetitionType) => wrap_jso(_blink.BlinkCanvasRenderingContext2D.instance.createPattern_Callback_2_(unwrap_jso(this), unwrap_jso(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(canvas_OR_image_OR_imageBitmap_OR_video, num sx_OR_x, num sy_OR_y, [num sw_OR_width, num height_OR_sh, num dx, num dy, num dw, num dh]) {
    if ((sy_OR_y is num) && (sx_OR_x is num) && (canvas_OR_image_OR_imageBitmap_OR_video is ImageElement) && sw_OR_width == null && height_OR_sh == null && dx == null && dy == null && dw == null && dh == null) {
      _blink.BlinkCanvasRenderingContext2D.instance.drawImage_Callback_3_(unwrap_jso(this), unwrap_jso(canvas_OR_image_OR_imageBitmap_OR_video), sx_OR_x, sy_OR_y);
      return;
    }
    if ((height_OR_sh is num) && (sw_OR_width is num) && (sy_OR_y is num) && (sx_OR_x is num) && (canvas_OR_image_OR_imageBitmap_OR_video is ImageElement) && dx == null && dy == null && dw == null && dh == null) {
      _blink.BlinkCanvasRenderingContext2D.instance.drawImage_Callback_5_(unwrap_jso(this), unwrap_jso(canvas_OR_image_OR_imageBitmap_OR_video), sx_OR_x, sy_OR_y, sw_OR_width, height_OR_sh);
      return;
    }
    if ((dh is num) && (dw is num) && (dy is num) && (dx is num) && (height_OR_sh is num) && (sw_OR_width is num) && (sy_OR_y is num) && (sx_OR_x is num) && (canvas_OR_image_OR_imageBitmap_OR_video is ImageElement)) {
      _blink.BlinkCanvasRenderingContext2D.instance.drawImage_Callback_9_(unwrap_jso(this), unwrap_jso(canvas_OR_image_OR_imageBitmap_OR_video), sx_OR_x, sy_OR_y, sw_OR_width, height_OR_sh, dx, dy, dw, dh);
      return;
    }
    if ((sy_OR_y is num) && (sx_OR_x is num) && (canvas_OR_image_OR_imageBitmap_OR_video is CanvasElement) && sw_OR_width == null && height_OR_sh == null && dx == null && dy == null && dw == null && dh == null) {
      _blink.BlinkCanvasRenderingContext2D.instance.drawImage_Callback_3_(unwrap_jso(this), unwrap_jso(canvas_OR_image_OR_imageBitmap_OR_video), sx_OR_x, sy_OR_y);
      return;
    }
    if ((height_OR_sh is num) && (sw_OR_width is num) && (sy_OR_y is num) && (sx_OR_x is num) && (canvas_OR_image_OR_imageBitmap_OR_video is CanvasElement) && dx == null && dy == null && dw == null && dh == null) {
      _blink.BlinkCanvasRenderingContext2D.instance.drawImage_Callback_5_(unwrap_jso(this), unwrap_jso(canvas_OR_image_OR_imageBitmap_OR_video), sx_OR_x, sy_OR_y, sw_OR_width, height_OR_sh);
      return;
    }
    if ((dh is num) && (dw is num) && (dy is num) && (dx is num) && (height_OR_sh is num) && (sw_OR_width is num) && (sy_OR_y is num) && (sx_OR_x is num) && (canvas_OR_image_OR_imageBitmap_OR_video is CanvasElement)) {
      _blink.BlinkCanvasRenderingContext2D.instance.drawImage_Callback_9_(unwrap_jso(this), unwrap_jso(canvas_OR_image_OR_imageBitmap_OR_video), sx_OR_x, sy_OR_y, sw_OR_width, height_OR_sh, dx, dy, dw, dh);
      return;
    }
    if ((sy_OR_y is num) && (sx_OR_x is num) && (canvas_OR_image_OR_imageBitmap_OR_video is VideoElement) && sw_OR_width == null && height_OR_sh == null && dx == null && dy == null && dw == null && dh == null) {
      _blink.BlinkCanvasRenderingContext2D.instance.drawImage_Callback_3_(unwrap_jso(this), unwrap_jso(canvas_OR_image_OR_imageBitmap_OR_video), sx_OR_x, sy_OR_y);
      return;
    }
    if ((height_OR_sh is num) && (sw_OR_width is num) && (sy_OR_y is num) && (sx_OR_x is num) && (canvas_OR_image_OR_imageBitmap_OR_video is VideoElement) && dx == null && dy == null && dw == null && dh == null) {
      _blink.BlinkCanvasRenderingContext2D.instance.drawImage_Callback_5_(unwrap_jso(this), unwrap_jso(canvas_OR_image_OR_imageBitmap_OR_video), sx_OR_x, sy_OR_y, sw_OR_width, height_OR_sh);
      return;
    }
    if ((dh is num) && (dw is num) && (dy is num) && (dx is num) && (height_OR_sh is num) && (sw_OR_width is num) && (sy_OR_y is num) && (sx_OR_x is num) && (canvas_OR_image_OR_imageBitmap_OR_video is VideoElement)) {
      _blink.BlinkCanvasRenderingContext2D.instance.drawImage_Callback_9_(unwrap_jso(this), unwrap_jso(canvas_OR_image_OR_imageBitmap_OR_video), sx_OR_x, sy_OR_y, sw_OR_width, height_OR_sh, dx, dy, dw, dh);
      return;
    }
    if ((sy_OR_y is num) && (sx_OR_x is num) && (canvas_OR_image_OR_imageBitmap_OR_video is ImageBitmap) && sw_OR_width == null && height_OR_sh == null && dx == null && dy == null && dw == null && dh == null) {
      _blink.BlinkCanvasRenderingContext2D.instance.drawImage_Callback_3_(unwrap_jso(this), unwrap_jso(canvas_OR_image_OR_imageBitmap_OR_video), sx_OR_x, sy_OR_y);
      return;
    }
    if ((height_OR_sh is num) && (sw_OR_width is num) && (sy_OR_y is num) && (sx_OR_x is num) && (canvas_OR_image_OR_imageBitmap_OR_video is ImageBitmap) && dx == null && dy == null && dw == null && dh == null) {
      _blink.BlinkCanvasRenderingContext2D.instance.drawImage_Callback_5_(unwrap_jso(this), unwrap_jso(canvas_OR_image_OR_imageBitmap_OR_video), sx_OR_x, sy_OR_y, sw_OR_width, height_OR_sh);
      return;
    }
    if ((dh is num) && (dw is num) && (dy is num) && (dx is num) && (height_OR_sh is num) && (sw_OR_width is num) && (sy_OR_y is num) && (sx_OR_x is num) && (canvas_OR_image_OR_imageBitmap_OR_video is ImageBitmap)) {
      _blink.BlinkCanvasRenderingContext2D.instance.drawImage_Callback_9_(unwrap_jso(this), unwrap_jso(canvas_OR_image_OR_imageBitmap_OR_video), sx_OR_x, sy_OR_y, sw_OR_width, height_OR_sh, dx, dy, dw, dh);
      return;
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }

  void fill([path_OR_winding, String winding]) {
    if (path_OR_winding == null && winding == null) {
      _blink.BlinkCanvasRenderingContext2D.instance.fill_Callback_0_(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()
  Canvas2DContextAttributes getContextAttributes() => 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);
  

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

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

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

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

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

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

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

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

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

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

  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @SupportedBrowser(SupportedBrowser.IE, '11')
  @Unstable()
  @DomName('CanvasRenderingContext2D.getLineDash')
  List<num> getLineDash() {
    // TODO(14316): Firefox has this functionality with mozDash, but it's a bit
    // different.
    var result = _getLineDash();
    if (result == null) {
      result = [];
    }
    return result;
  }



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

// WARNING: Do not edit - generated code.


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


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

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

  @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 length) => _blink.BlinkCharacterData.instance.deleteData_Callback_2_(unwrap_jso(this), offset, length);
  
  @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 length, String data) => _blink.BlinkCharacterData.instance.replaceData_Callback_3_(unwrap_jso(this), offset, length, data);
  
  @DomName('CharacterData.substringData')
  @DocsEditable()
  String substringData(int offset, int length) => _blink.BlinkCharacterData.instance.substringData_Callback_2_(unwrap_jso(this), offset, length);
  
  @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.nextElementSibling')
  @DocsEditable()
  @Experimental() // untriaged
  Element get nextElementSibling;

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

  @DomName('ChildNode.remove')
  @DocsEditable()
  @Experimental() // untriaged
  void remove();

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

// WARNING: Do not edit - generated code.


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

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

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


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

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

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

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

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

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


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

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

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


  @DomName('CompositionEvent.activeSegmentEnd')
  @DocsEditable()
  @Experimental() // untriaged
  int get activeSegmentEnd => _blink.BlinkCompositionEvent.instance.activeSegmentEnd_Getter_(unwrap_jso(this));
  
  @DomName('CompositionEvent.activeSegmentStart')
  @DocsEditable()
  @Experimental() // untriaged
  int get activeSegmentStart => _blink.BlinkCompositionEvent.instance.activeSegmentStart_Getter_(unwrap_jso(this));
  
  @DomName('CompositionEvent.data')
  @DocsEditable()
  String get data => _blink.BlinkCompositionEvent.instance.data_Getter_(unwrap_jso(this));
  
  @DomName('CompositionEvent.getSegments')
  @DocsEditable()
  @Experimental() // untriaged
  List<int> getSegments() => _blink.BlinkCompositionEvent.instance.getSegments_Callback_0_(unwrap_jso(this));
  
  @DomName('CompositionEvent.initCompositionEvent')
  @DocsEditable()
  void _initCompositionEvent(String typeArg, bool canBubbleArg, bool cancelableArg, Window viewArg, String dataArg) => _blink.BlinkCompositionEvent.instance.initCompositionEvent_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('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();
  }

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

  @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)));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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.assertCondition')
  @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();
  }

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

  @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.avatarURL')
  @DocsEditable()
  @Experimental() // untriaged
  String get avatarUrl => _blink.BlinkCredential.instance.avatarURL_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));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source 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.notifyFailedSignIn')
  @DocsEditable()
  @Experimental() // untriaged
  Future notifyFailedSignIn(Credential credential) => wrap_jso(_blink.BlinkCredentialsContainer.instance.notifyFailedSignIn_Callback_1_(unwrap_jso(this), unwrap_jso(credential)));
  
  @DomName('CredentialsContainer.notifySignedIn')
  @DocsEditable()
  @Experimental() // untriaged
  Future notifySignedIn(Credential credential) => wrap_jso(_blink.BlinkCredentialsContainer.instance.notifySignedIn_Callback_1_(unwrap_jso(this), unwrap_jso(credential)));
  
  @DomName('CredentialsContainer.notifySignedOut')
  @DocsEditable()
  @Experimental() // untriaged
  Future notifySignedOut() => wrap_jso(_blink.BlinkCredentialsContainer.instance.notifySignedOut_Callback_0_(unwrap_jso(this)));
  
  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)));
  }

}
// 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()
  bool supports(String property, String value) => _blink.BlinkCSS.instance.supports_Callback_2_(unwrap_jso(this), property, value);
  
  @DomName('CSS.supportsCondition')
  @DocsEditable()
  bool supportsCondition(String conditionText) => _blink.BlinkCSS.instance.supports_Callback_1_(unwrap_jso(this), conditionText);
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.


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


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

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

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


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

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

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


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

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

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

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

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

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

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

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

  @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.deleteRule')
  @DocsEditable()
  @Experimental() // untriaged
  void deleteRule(String key) => _blink.BlinkCSSKeyframesRule.instance.deleteRule_Callback_1_(unwrap_jso(this), key);
  
  @DomName('CSSKeyframesRule.findRule')
  @DocsEditable()
  @Experimental() // untriaged
  CssKeyframeRule findRule(String key) => wrap_jso(_blink.BlinkCSSKeyframesRule.instance.findRule_Callback_1_(unwrap_jso(this), key));
  
  @DomName('CSSKeyframesRule.insertRule')
  @DocsEditable()
  @Experimental() // untriaged
  void appendRule(String rule) => _blink.BlinkCSSKeyframesRule.instance.insertRule_Callback_1_(unwrap_jso(this), rule);
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.


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


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

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

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


  @DomName('CSSMediaRule.cssRules')
  @DocsEditable()
  List<CssRule> get cssRules => wrap_jso(_blink.BlinkCSSMediaRule.instance.cssRules_Getter_(unwrap_jso(this)));
  
  @DomName('CSSMediaRule.media')
  @DocsEditable()
  MediaList get media => wrap_jso(_blink.BlinkCSSMediaRule.instance.media_Getter_(unwrap_jso(this)));
  
  @DomName('CSSMediaRule.deleteRule')
  @DocsEditable()
  void deleteRule(int index) => _blink.BlinkCSSMediaRule.instance.deleteRule_Callback_1_(unwrap_jso(this), index);
  
  @DomName('CSSMediaRule.insertRule')
  @DocsEditable()
  int insertRule(String rule, int index) => _blink.BlinkCSSMediaRule.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('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();
  }

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

  @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_FILTER_RULE')
  @DocsEditable()
  // http://www.w3.org/TR/filter-effects/
  @Experimental()
  static const int WEBKIT_FILTER_RULE = 17;

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

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

  @DomName('CSSRule.cssText')
  @DocsEditable()
  String get cssText => _blink.BlinkCSSRule.instance.cssText_Getter_(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.__getter__')
  @DocsEditable()
  @Experimental() // untriaged
  Object __getter__(String name) => wrap_jso(_blink.BlinkCSSStyleDeclaration.instance.$__getter___Callback_1_(unwrap_jso(this), name));
  
  @DomName('CSSStyleDeclaration.__propertyQuery__')
  @DocsEditable()
  @Experimental() // untriaged
  bool __propertyQuery__(String name) => _blink.BlinkCSSStyleDeclaration.instance.$__propertyQuery___Callback_1_(unwrap_jso(this), name);
  
  @DomName('CSSStyleDeclaration.__setter__')
  @DocsEditable()
  void __setter__(String propertyName, String propertyValue) => _blink.BlinkCSSStyleDeclaration.instance.$__setter___Callback_2_(unwrap_jso(this), propertyName, propertyValue);
  
  @DomName('CSSStyleDeclaration.getPropertyPriority')
  @DocsEditable()
  String getPropertyPriority(String propertyName) => _blink.BlinkCSSStyleDeclaration.instance.getPropertyPriority_Callback_1_(unwrap_jso(this), propertyName);
  
  @DomName('CSSStyleDeclaration.getPropertyValue')
  @DocsEditable()
  String _getPropertyValue(String propertyName) => _blink.BlinkCSSStyleDeclaration.instance.getPropertyValue_Callback_1_(unwrap_jso(this), propertyName);
  
  @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 propertyName) => _blink.BlinkCSSStyleDeclaration.instance.removeProperty_Callback_1_(unwrap_jso(this), propertyName);
  
  @DomName('CSSStyleDeclaration.setProperty')
  @DocsEditable()
  void _setProperty(String propertyName, String value, String priority) => _blink.BlinkCSSStyleDeclaration.instance.setProperty_Callback_3_(unwrap_jso(this), propertyName, value, priority);
  
}

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

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

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

  void setProperty(String propertyName, String value, [String priority]) {
    _elementCssStyleDeclarationSetIterable.forEach((e) =>
        e.setProperty(propertyName, value, priority));
  }



  // Important note: CssStyleDeclarationSet does NOT implement every method
  // available in CssStyleDeclaration. Some of the methods don't make so much
  // sense in terms of having a resonable value to return when you're
  // considering a list of Elements. You will need to manually add any of the
  // items in the MEMBERS set if you want that functionality.
}

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

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

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

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

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

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

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

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

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


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

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

  @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 typeArg, bool canBubbleArg, bool cancelableArg, Object detailArg) => _blink.BlinkCustomEvent.instance.initCustomEvent_Callback_4_(unwrap_jso(this), typeArg, canBubbleArg, cancelableArg, detailArg);
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.


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

  @DomName('HTMLDListElement.HTMLDListElement')
  @DocsEditable()
  factory DListElement() => document.createElement("dl");


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

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

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

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

  @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 type]) {
    if (type != null) {
      _blink.BlinkDataTransfer.instance.clearData_Callback_1_(unwrap_jso(this), type);
      return;
    }
    _blink.BlinkDataTransfer.instance.clearData_Callback_0_(unwrap_jso(this));
    return;
  }

  @DomName('DataTransfer.getData')
  @DocsEditable()
  @Experimental() // untriaged
  String getData(String type) => _blink.BlinkDataTransfer.instance.getData_Callback_1_(unwrap_jso(this), type);
  
  @DomName('DataTransfer.setData')
  @DocsEditable()
  @Experimental() // untriaged
  void setData(String type, String data) => _blink.BlinkDataTransfer.instance.setData_Callback_2_(unwrap_jso(this), type, 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));
  
  @DomName('DataTransferItemList.__getter__')
  @DocsEditable()
  @Experimental() // untriaged
  DataTransferItem __getter__(int index) => wrap_jso(_blink.BlinkDataTransferItemList.instance.$__getter___Callback_1_(unwrap_jso(this), index));
  
  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.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();
  }

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

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


  @DomName('DedicatedWorkerGlobalScope.postMessage')
  @DocsEditable()
  @Experimental() // untriaged
  void postMessage(Object message, [List<MessagePort> transfer]) => _blink.BlinkDedicatedWorkerGlobalScope.instance.postMessage_Callback_2_(unwrap_jso(this), message, transfer);
  
  /// Stream of `message` events handled by this [DedicatedWorkerGlobalScope].
  @DomName('DedicatedWorkerGlobalScope.onmessage')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<MessageEvent> get onMessage => messageEvent.forTarget(this);

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

// WARNING: Do not edit - generated code.


@DocsEditable()
@DomName('DeprecatedStorageInfo')
@Experimental() // untriaged
class DeprecatedStorageInfo extends 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();
  }

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

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


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

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

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

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

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

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

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

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

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

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

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

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

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

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

  @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.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.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 webkitRadiusX, num webkitRadiusY, num webkitRotationAngle, num webkitForce) => wrap_jso(_blink.BlinkDocument.instance.createTouch_Callback_11_(unwrap_jso(this), unwrap_jso(window), unwrap_jso(target), identifier, pageX, pageY, screenX, screenY, webkitRadiusX, webkitRadiusY, webkitRotationAngle, webkitForce));
  
  @DomName('Document.createTouchList')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  TouchList _createTouchList(Touch touches) => 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.execCommand')
  @DocsEditable()
  bool execCommand(String command, bool userInterface, String value) => _blink.BlinkDocument.instance.execCommand_Callback_3_(unwrap_jso(this), command, userInterface, value);
  
  @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.getElementById')
  @DocsEditable()
  Element getElementById(String elementId) => wrap_jso(_blink.BlinkDocument.instance.getElementById_Callback_1_(unwrap_jso(this), elementId));
  
  @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 command) => _blink.BlinkDocument.instance.queryCommandEnabled_Callback_1_(unwrap_jso(this), command);
  
  @DomName('Document.queryCommandIndeterm')
  @DocsEditable()
  bool queryCommandIndeterm(String command) => _blink.BlinkDocument.instance.queryCommandIndeterm_Callback_1_(unwrap_jso(this), command);
  
  @DomName('Document.queryCommandState')
  @DocsEditable()
  bool queryCommandState(String command) => _blink.BlinkDocument.instance.queryCommandState_Callback_1_(unwrap_jso(this), command);
  
  @DomName('Document.queryCommandSupported')
  @DocsEditable()
  bool queryCommandSupported(String command) => _blink.BlinkDocument.instance.queryCommandSupported_Callback_1_(unwrap_jso(this), command);
  
  @DomName('Document.queryCommandValue')
  @DocsEditable()
  String queryCommandValue(String command) => _blink.BlinkDocument.instance.queryCommandValue_Callback_1_(unwrap_jso(this), command);
  
  @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.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<Event> get onCopy => Element.copyEvent.forTarget(this);

  /// Stream of `cut` events handled by this [Document].
  @DomName('Document.oncut')
  @DocsEditable()
  Stream<Event> get onCut => Element.cutEvent.forTarget(this);

  /// Stream of `doubleclick` events handled by this [Document].
  @DomName('Document.ondblclick')
  @DocsEditable()
  Stream<Event> get onDoubleClick => Element.doubleClickEvent.forTarget(this);

  /// Stream of `drag` events handled by this [Document].
  @DomName('Document.ondrag')
  @DocsEditable()
  Stream<MouseEvent> get onDrag => Element.dragEvent.forTarget(this);

  /// Stream of `dragend` events handled by this [Document].
  @DomName('Document.ondragend')
  @DocsEditable()
  Stream<MouseEvent> get onDragEnd => Element.dragEndEvent.forTarget(this);

  /// Stream of `dragenter` events handled by this [Document].
  @DomName('Document.ondragenter')
  @DocsEditable()
  Stream<MouseEvent> get onDragEnter => Element.dragEnterEvent.forTarget(this);

  /// Stream of `dragleave` events handled by this [Document].
  @DomName('Document.ondragleave')
  @DocsEditable()
  Stream<MouseEvent> get onDragLeave => Element.dragLeaveEvent.forTarget(this);

  /// Stream of `dragover` events handled by this [Document].
  @DomName('Document.ondragover')
  @DocsEditable()
  Stream<MouseEvent> get onDragOver => Element.dragOverEvent.forTarget(this);

  /// Stream of `dragstart` events handled by this [Document].
  @DomName('Document.ondragstart')
  @DocsEditable()
  Stream<MouseEvent> get onDragStart => Element.dragStartEvent.forTarget(this);

  /// Stream of `drop` events handled by this [Document].
  @DomName('Document.ondrop')
  @DocsEditable()
  Stream<MouseEvent> get onDrop => Element.dropEvent.forTarget(this);

  @DomName('Document.ondurationchange')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onDurationChange => Element.durationChangeEvent.forTarget(this);

  @DomName('Document.onemptied')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onEmptied => Element.emptiedEvent.forTarget(this);

  @DomName('Document.onended')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onEnded => Element.endedEvent.forTarget(this);

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

  /// Stream of `focus` events handled by this [Document].
  @DomName('Document.onfocus')
  @DocsEditable()
  Stream<Event> get onFocus => Element.focusEvent.forTarget(this);

  /// Stream of `input` events handled by this [Document].
  @DomName('Document.oninput')
  @DocsEditable()
  Stream<Event> get onInput => Element.inputEvent.forTarget(this);

  /// Stream of `invalid` events handled by this [Document].
  @DomName('Document.oninvalid')
  @DocsEditable()
  Stream<Event> get onInvalid => Element.invalidEvent.forTarget(this);

  /// Stream of `keydown` events handled by this [Document].
  @DomName('Document.onkeydown')
  @DocsEditable()
  Stream<KeyboardEvent> get onKeyDown => Element.keyDownEvent.forTarget(this);

  /// Stream of `keypress` events handled by this [Document].
  @DomName('Document.onkeypress')
  @DocsEditable()
  Stream<KeyboardEvent> get onKeyPress => Element.keyPressEvent.forTarget(this);

  /// Stream of `keyup` events handled by this [Document].
  @DomName('Document.onkeyup')
  @DocsEditable()
  Stream<KeyboardEvent> get onKeyUp => Element.keyUpEvent.forTarget(this);

  /// Stream of `load` events handled by this [Document].
  @DomName('Document.onload')
  @DocsEditable()
  Stream<Event> get onLoad => Element.loadEvent.forTarget(this);

  @DomName('Document.onloadeddata')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onLoadedData => Element.loadedDataEvent.forTarget(this);

  @DomName('Document.onloadedmetadata')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onLoadedMetadata => Element.loadedMetadataEvent.forTarget(this);

  /// Stream of `mousedown` events handled by this [Document].
  @DomName('Document.onmousedown')
  @DocsEditable()
  Stream<MouseEvent> get onMouseDown => Element.mouseDownEvent.forTarget(this);

  /// Stream of `mouseenter` events handled by this [Document].
  @DomName('Document.onmouseenter')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<MouseEvent> get onMouseEnter => Element.mouseEnterEvent.forTarget(this);

  /// Stream of `mouseleave` events handled by this [Document].
  @DomName('Document.onmouseleave')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<MouseEvent> get onMouseLeave => Element.mouseLeaveEvent.forTarget(this);

  /// Stream of `mousemove` events handled by this [Document].
  @DomName('Document.onmousemove')
  @DocsEditable()
  Stream<MouseEvent> get onMouseMove => Element.mouseMoveEvent.forTarget(this);

  /// Stream of `mouseout` events handled by this [Document].
  @DomName('Document.onmouseout')
  @DocsEditable()
  Stream<MouseEvent> get onMouseOut => Element.mouseOutEvent.forTarget(this);

  /// Stream of `mouseover` events handled by this [Document].
  @DomName('Document.onmouseover')
  @DocsEditable()
  Stream<MouseEvent> get onMouseOver => Element.mouseOverEvent.forTarget(this);

  /// Stream of `mouseup` events handled by this [Document].
  @DomName('Document.onmouseup')
  @DocsEditable()
  Stream<MouseEvent> get onMouseUp => Element.mouseUpEvent.forTarget(this);

  /// Stream of `mousewheel` events handled by this [Document].
  @DomName('Document.onmousewheel')
  @DocsEditable()
  Stream<WheelEvent> get onMouseWheel => Element.mouseWheelEvent.forTarget(this);

  /// Stream of `paste` events handled by this [Document].
  @DomName('Document.onpaste')
  @DocsEditable()
  Stream<Event> get onPaste => Element.pasteEvent.forTarget(this);

  @DomName('Document.onpause')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onPause => Element.pauseEvent.forTarget(this);

  @DomName('Document.onplay')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onPlay => Element.playEvent.forTarget(this);

  @DomName('Document.onplaying')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onPlaying => Element.playingEvent.forTarget(this);

  @DomName('Document.onpointerlockchange')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onPointerLockChange => pointerLockChangeEvent.forTarget(this);

  @DomName('Document.onpointerlockerror')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onPointerLockError => pointerLockErrorEvent.forTarget(this);

  @DomName('Document.onratechange')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onRateChange => Element.rateChangeEvent.forTarget(this);

  /// Stream of `readystatechange` events handled by this [Document].
  @DomName('Document.onreadystatechange')
  @DocsEditable()
  Stream<Event> get onReadyStateChange => readyStateChangeEvent.forTarget(this);

  /// Stream of `reset` events handled by this [Document].
  @DomName('Document.onreset')
  @DocsEditable()
  Stream<Event> get onReset => Element.resetEvent.forTarget(this);

  @DomName('Document.onresize')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onResize => Element.resizeEvent.forTarget(this);

  /// Stream of `scroll` events handled by this [Document].
  @DomName('Document.onscroll')
  @DocsEditable()
  Stream<Event> get onScroll => Element.scrollEvent.forTarget(this);

  /// Stream of `search` events handled by this [Document].
  @DomName('Document.onsearch')
  @DocsEditable()
  // http://www.w3.org/TR/html-markup/input.search.html
  @Experimental()
  Stream<Event> get onSearch => Element.searchEvent.forTarget(this);

  /// Stream of `securitypolicyviolation` events handled by this [Document].
  @DomName('Document.onsecuritypolicyviolation')
  @DocsEditable()
  // https://dvcs.w3.org/hg/content-security-policy/raw-file/tip/csp-specification.dev.html#widl-Document-onsecuritypolicyviolation
  @Experimental()
  Stream<SecurityPolicyViolationEvent> get onSecurityPolicyViolation => securityPolicyViolationEvent.forTarget(this);

  @DomName('Document.onseeked')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onSeeked => Element.seekedEvent.forTarget(this);

  @DomName('Document.onseeking')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onSeeking => Element.seekingEvent.forTarget(this);

  /// Stream of `select` events handled by this [Document].
  @DomName('Document.onselect')
  @DocsEditable()
  Stream<Event> get onSelect => Element.selectEvent.forTarget(this);

  /// Stream of `selectionchange` events handled by this [Document].
  @DomName('Document.onselectionchange')
  @DocsEditable()
  Stream<Event> get onSelectionChange => selectionChangeEvent.forTarget(this);

  /// Stream of `selectstart` events handled by this [Document].
  @DomName('Document.onselectstart')
  @DocsEditable()
  Stream<Event> get onSelectStart => Element.selectStartEvent.forTarget(this);

  @DomName('Document.onstalled')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onStalled => Element.stalledEvent.forTarget(this);

  /// Stream of `submit` events handled by this [Document].
  @DomName('Document.onsubmit')
  @DocsEditable()
  Stream<Event> get onSubmit => Element.submitEvent.forTarget(this);

  @DomName('Document.onsuspend')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onSuspend => Element.suspendEvent.forTarget(this);

  @DomName('Document.ontimeupdate')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onTimeUpdate => Element.timeUpdateEvent.forTarget(this);

  /// Stream of `touchcancel` events handled by this [Document].
  @DomName('Document.ontouchcancel')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  Stream<TouchEvent> get onTouchCancel => Element.touchCancelEvent.forTarget(this);

  /// Stream of `touchend` events handled by this [Document].
  @DomName('Document.ontouchend')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  Stream<TouchEvent> get onTouchEnd => Element.touchEndEvent.forTarget(this);

  /// Stream of `touchmove` events handled by this [Document].
  @DomName('Document.ontouchmove')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  Stream<TouchEvent> get onTouchMove => Element.touchMoveEvent.forTarget(this);

  /// Stream of `touchstart` events handled by this [Document].
  @DomName('Document.ontouchstart')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  Stream<TouchEvent> get onTouchStart => Element.touchStartEvent.forTarget(this);

  @DomName('Document.onvolumechange')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onVolumeChange => Element.volumeChangeEvent.forTarget(this);

  @DomName('Document.onwaiting')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onWaiting => Element.waitingEvent.forTarget(this);

  /// Stream of `fullscreenchange` events handled by this [Document].
  @DomName('Document.onwebkitfullscreenchange')
  @DocsEditable()
  // https://dvcs.w3.org/hg/fullscreen/raw-file/tip/Overview.html
  @Experimental()
  Stream<Event> get onFullscreenChange => Element.fullscreenChangeEvent.forTarget(this);

  /// Stream of `fullscreenerror` events handled by this [Document].
  @DomName('Document.onwebkitfullscreenerror')
  @DocsEditable()
  // https://dvcs.w3.org/hg/fullscreen/raw-file/tip/Overview.html
  @Experimental()
  Stream<Event> get onFullscreenError => Element.fullscreenErrorEvent.forTarget(this);

  /**
   * Finds all descendant elements of this document that match the specified
   * group of selectors.
   *
   * Unless your webpage contains multiple documents, the top-level
   * [querySelectorAll]
   * method behaves the same as this method, so you should use it instead to
   * save typing a few characters.
   *
   * [selectors] should be a string using CSS selector syntax.
   *
   *     var items = document.querySelectorAll('.itemClassName');
   *
   * For details about CSS selector syntax, see the
   * [CSS selector specification](http://www.w3.org/TR/css3-selectors/).
   */
  ElementList<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 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();
  }

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

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

  @Deprecated("Internal Use Only")
  js.JsObject blink_jsObject;

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

  @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(String feature, String version) => _blink.BlinkDOMImplementation.instance.hasFeature_Callback_2_(unwrap_jso(this), feature, version);
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.


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

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

  @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 ox, num oy, num oz]) {
    if (oz != null) {
      return wrap_jso(_blink.BlinkDOMMatrix.instance.scale3dSelf_Callback_4_(unwrap_jso(this), scale, ox, oy, oz));
    }
    if (oy != null) {
      return wrap_jso(_blink.BlinkDOMMatrix.instance.scale3dSelf_Callback_3_(unwrap_jso(this), scale, ox, oy));
    }
    if (ox != null) {
      return wrap_jso(_blink.BlinkDOMMatrix.instance.scale3dSelf_Callback_2_(unwrap_jso(this), scale, ox));
    }
    return wrap_jso(_blink.BlinkDOMMatrix.instance.scale3dSelf_Callback_1_(unwrap_jso(this), scale));
  }

  DomMatrix scaleNonUniformSelf(num sx, [num sy, num sz, num ox, num oy, num oz]) {
    if (oz != null) {
      return wrap_jso(_blink.BlinkDOMMatrix.instance.scaleNonUniformSelf_Callback_6_(unwrap_jso(this), sx, sy, sz, ox, oy, oz));
    }
    if (oy != null) {
      return wrap_jso(_blink.BlinkDOMMatrix.instance.scaleNonUniformSelf_Callback_5_(unwrap_jso(this), sx, sy, sz, ox, oy));
    }
    if (ox != null) {
      return wrap_jso(_blink.BlinkDOMMatrix.instance.scaleNonUniformSelf_Callback_4_(unwrap_jso(this), sx, sy, sz, ox));
    }
    if (sz != null) {
      return wrap_jso(_blink.BlinkDOMMatrix.instance.scaleNonUniformSelf_Callback_3_(unwrap_jso(this), sx, sy, sz));
    }
    if (sy != null) {
      return wrap_jso(_blink.BlinkDOMMatrix.instance.scaleNonUniformSelf_Callback_2_(unwrap_jso(this), sx, sy));
    }
    return wrap_jso(_blink.BlinkDOMMatrix.instance.scaleNonUniformSelf_Callback_1_(unwrap_jso(this), sx));
  }

  DomMatrix scaleSelf(num scale, [num ox, num oy]) {
    if (oy != null) {
      return wrap_jso(_blink.BlinkDOMMatrix.instance.scaleSelf_Callback_3_(unwrap_jso(this), scale, ox, oy));
    }
    if (ox != null) {
      return wrap_jso(_blink.BlinkDOMMatrix.instance.scaleSelf_Callback_2_(unwrap_jso(this), scale, ox));
    }
    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 ox, num oy]) {
    if (oy != null) {
      return wrap_jso(_blink.BlinkDOMMatrixReadOnly.instance.scale_Callback_3_(unwrap_jso(this), scale, ox, oy));
    }
    if (ox != null) {
      return wrap_jso(_blink.BlinkDOMMatrixReadOnly.instance.scale_Callback_2_(unwrap_jso(this), scale, ox));
    }
    return wrap_jso(_blink.BlinkDOMMatrixReadOnly.instance.scale_Callback_1_(unwrap_jso(this), scale));
  }

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

  DomMatrix scaleNonUniform(num sx, [num sy, num sz, num ox, num oy, num oz]) {
    if (oz != null) {
      return wrap_jso(_blink.BlinkDOMMatrixReadOnly.instance.scaleNonUniform_Callback_6_(unwrap_jso(this), sx, sy, sz, ox, oy, oz));
    }
    if (oy != null) {
      return wrap_jso(_blink.BlinkDOMMatrixReadOnly.instance.scaleNonUniform_Callback_5_(unwrap_jso(this), sx, sy, sz, ox, oy));
    }
    if (ox != null) {
      return wrap_jso(_blink.BlinkDOMMatrixReadOnly.instance.scaleNonUniform_Callback_4_(unwrap_jso(this), sx, sy, sz, ox));
    }
    if (sz != null) {
      return wrap_jso(_blink.BlinkDOMMatrixReadOnly.instance.scaleNonUniform_Callback_3_(unwrap_jso(this), sx, sy, sz));
    }
    if (sy != null) {
      return wrap_jso(_blink.BlinkDOMMatrixReadOnly.instance.scaleNonUniform_Callback_2_(unwrap_jso(this), sx, sy));
    }
    return wrap_jso(_blink.BlinkDOMMatrixReadOnly.instance.scaleNonUniform_Callback_1_(unwrap_jso(this), sx));
  }

  @DomName('DOMMatrixReadOnly.toFloat32Array')
  @DocsEditable()
  @Experimental() // untriaged
  Float32List toFloat32Array() => _blink.BlinkDOMMatrixReadOnly.instance.toFloat32Array_Callback_0_(unwrap_jso(this));
  
  @DomName('DOMMatrixReadOnly.toFloat64Array')
  @DocsEditable()
  @Experimental() // untriaged
  Float64List toFloat64Array() => _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 contentType) => wrap_jso(_blink.BlinkDOMParser.instance.parseFromString_Callback_2_(unwrap_jso(this), str, contentType));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.


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

  @DomName('DOMPoint.DOMPoint')
  @DocsEditable()
  factory DomPoint([point_OR_x, num y, num z, num w]) {
    if (point_OR_x == null && y == null && z == null && w == null) {
      return wrap_jso(_blink.BlinkDOMPoint.instance.constructorCallback_0_());
    }
    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 ((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();
  }

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

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

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

  @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.__getter__')
  @DocsEditable()
  String __getter__(int index) => _blink.BlinkDOMSettableTokenList.instance.$__getter___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.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"); }

  bool __delete__(index_OR_name) {
    if ((index_OR_name is int || index_OR_name == null)) {
      return _blink.BlinkDOMStringMap.instance.$__delete___Callback_1_(unwrap_jso(this), unwrap_jso(index_OR_name));
    }
    if ((index_OR_name is String || index_OR_name == null)) {
      return _blink.BlinkDOMStringMap.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.BlinkDOMStringMap.instance.$__getter___Callback_1_(unwrap_jso(this), unwrap_jso(index_OR_name));
    }
    if ((index_OR_name is String || index_OR_name == null)) {
      return _blink.BlinkDOMStringMap.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.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 String || 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");
  }

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


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<Event> get onCopy;

  /// Stream of `cut` events handled by this [Element].
  @DomName('Element.oncut')
  @DocsEditable()
  ElementStream<Event> get onCut;

  /// Stream of `doubleclick` events handled by this [Element].
  @DomName('Element.ondblclick')
  @DocsEditable()
  ElementStream<Event> get onDoubleClick;

  /**
   * A stream of `drag` events fired when this element currently being dragged.
   *
   * A `drag` event is added to this stream as soon as the drag begins.
   * A `drag` event is also added to this stream at intervals while the drag
   * operation is still ongoing.
   *
   * ## Other resources
   *
   * * [Drag and drop sample]
   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   * from HTML5Rocks.
   * * [Drag and drop specification]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
   * from WHATWG.
   */
  @DomName('Element.ondrag')
  @DocsEditable()
  ElementStream<MouseEvent> get onDrag;

  /**
   * A stream of `dragend` events fired when this element completes a drag
   * operation.
   *
   * ## Other resources
   *
   * * [Drag and drop sample]
   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   * from HTML5Rocks.
   * * [Drag and drop specification]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
   * from WHATWG.
   */
  @DomName('Element.ondragend')
  @DocsEditable()
  ElementStream<MouseEvent> get onDragEnd;

  /**
   * A stream of `dragenter` events fired when a dragged object is first dragged
   * over this element.
   *
   * ## Other resources
   *
   * * [Drag and drop sample]
   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   * from HTML5Rocks.
   * * [Drag and drop specification]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
   * from WHATWG.
   */
  @DomName('Element.ondragenter')
  @DocsEditable()
  ElementStream<MouseEvent> get onDragEnter;

  /**
   * A stream of `dragleave` events fired when an object being dragged over this
   * element leaves this element's target area.
   *
   * ## Other resources
   *
   * * [Drag and drop sample]
   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   * from HTML5Rocks.
   * * [Drag and drop specification]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
   * from WHATWG.
   */
  @DomName('Element.ondragleave')
  @DocsEditable()
  ElementStream<MouseEvent> get onDragLeave;

  /**
   * A stream of `dragover` events fired when a dragged object is currently
   * being dragged over this element.
   *
   * ## Other resources
   *
   * * [Drag and drop sample]
   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   * from HTML5Rocks.
   * * [Drag and drop specification]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
   * from WHATWG.
   */
  @DomName('Element.ondragover')
  @DocsEditable()
  ElementStream<MouseEvent> get onDragOver;

  /**
   * A stream of `dragstart` events fired when this element starts being
   * dragged.
   *
   * ## Other resources
   *
   * * [Drag and drop sample]
   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   * from HTML5Rocks.
   * * [Drag and drop specification]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
   * from WHATWG.
   */
  @DomName('Element.ondragstart')
  @DocsEditable()
  ElementStream<MouseEvent> get onDragStart;

  /**
   * A stream of `drop` events fired when a dragged object is dropped on this
   * element.
   *
   * ## Other resources
   *
   * * [Drag and drop sample]
   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   * from HTML5Rocks.
   * * [Drag and drop specification]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
   * from WHATWG.
   */
  @DomName('Element.ondrop')
  @DocsEditable()
  ElementStream<MouseEvent> get onDrop;

  @DomName('Element.ondurationchange')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onDurationChange;

  @DomName('Element.onemptied')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onEmptied;

  @DomName('Element.onended')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onEnded;

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

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

  /// Stream of `input` events handled by this [Element].
  @DomName('Element.oninput')
  @DocsEditable()
  ElementStream<Event> get onInput;

  /// Stream of `invalid` events handled by this [Element].
  @DomName('Element.oninvalid')
  @DocsEditable()
  ElementStream<Event> get onInvalid;

  /// Stream of `keydown` events handled by this [Element].
  @DomName('Element.onkeydown')
  @DocsEditable()
  ElementStream<KeyboardEvent> get onKeyDown;

  /// Stream of `keypress` events handled by this [Element].
  @DomName('Element.onkeypress')
  @DocsEditable()
  ElementStream<KeyboardEvent> get onKeyPress;

  /// Stream of `keyup` events handled by this [Element].
  @DomName('Element.onkeyup')
  @DocsEditable()
  ElementStream<KeyboardEvent> get onKeyUp;

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

  @DomName('Element.onloadeddata')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onLoadedData;

  @DomName('Element.onloadedmetadata')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onLoadedMetadata;

  /// Stream of `mousedown` events handled by this [Element].
  @DomName('Element.onmousedown')
  @DocsEditable()
  ElementStream<MouseEvent> get onMouseDown;

  /// Stream of `mouseenter` events handled by this [Element].
  @DomName('Element.onmouseenter')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<MouseEvent> get onMouseEnter;

  /// Stream of `mouseleave` events handled by this [Element].
  @DomName('Element.onmouseleave')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<MouseEvent> get onMouseLeave;

  /// Stream of `mousemove` events handled by this [Element].
  @DomName('Element.onmousemove')
  @DocsEditable()
  ElementStream<MouseEvent> get onMouseMove;

  /// Stream of `mouseout` events handled by this [Element].
  @DomName('Element.onmouseout')
  @DocsEditable()
  ElementStream<MouseEvent> get onMouseOut;

  /// Stream of `mouseover` events handled by this [Element].
  @DomName('Element.onmouseover')
  @DocsEditable()
  ElementStream<MouseEvent> get onMouseOver;

  /// Stream of `mouseup` events handled by this [Element].
  @DomName('Element.onmouseup')
  @DocsEditable()
  ElementStream<MouseEvent> get onMouseUp;

  /// Stream of `mousewheel` events handled by this [Element].
  @DomName('Element.onmousewheel')
  @DocsEditable()
  // http://www.w3.org/TR/DOM-Level-3-Events/#events-wheelevents
  @Experimental() // non-standard
  ElementStream<WheelEvent> get onMouseWheel;

  /// Stream of `paste` events handled by this [Element].
  @DomName('Element.onpaste')
  @DocsEditable()
  ElementStream<Event> get onPaste;

  @DomName('Element.onpause')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onPause;

  @DomName('Element.onplay')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onPlay;

  @DomName('Element.onplaying')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onPlaying;

  @DomName('Element.onratechange')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onRateChange;

  /// Stream of `reset` events handled by this [Element].
  @DomName('Element.onreset')
  @DocsEditable()
  ElementStream<Event> get onReset;

  @DomName('Element.onresize')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onResize;

  /// Stream of `scroll` events handled by this [Element].
  @DomName('Element.onscroll')
  @DocsEditable()
  ElementStream<Event> get onScroll;

  /// Stream of `search` events handled by this [Element].
  @DomName('Element.onsearch')
  @DocsEditable()
  // http://www.w3.org/TR/html-markup/input.search.html
  @Experimental()
  ElementStream<Event> get onSearch;

  @DomName('Element.onseeked')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onSeeked;

  @DomName('Element.onseeking')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onSeeking;

  /// Stream of `select` events handled by this [Element].
  @DomName('Element.onselect')
  @DocsEditable()
  ElementStream<Event> get onSelect;

  /// Stream of `selectstart` events handled by this [Element].
  @DomName('Element.onselectstart')
  @DocsEditable()
  @Experimental() // nonstandard
  ElementStream<Event> get onSelectStart;

  @DomName('Element.onstalled')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onStalled;

  /// Stream of `submit` events handled by this [Element].
  @DomName('Element.onsubmit')
  @DocsEditable()
  ElementStream<Event> get onSubmit;

  @DomName('Element.onsuspend')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onSuspend;

  @DomName('Element.ontimeupdate')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onTimeUpdate;

  /// Stream of `touchcancel` events handled by this [Element].
  @DomName('Element.ontouchcancel')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  ElementStream<TouchEvent> get onTouchCancel;

  /// Stream of `touchend` events handled by this [Element].
  @DomName('Element.ontouchend')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  ElementStream<TouchEvent> get onTouchEnd;

  /// Stream of `touchenter` events handled by this [Element].
  @DomName('Element.ontouchenter')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  ElementStream<TouchEvent> get onTouchEnter;

  /// Stream of `touchleave` events handled by this [Element].
  @DomName('Element.ontouchleave')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  ElementStream<TouchEvent> get onTouchLeave;

  /// Stream of `touchmove` events handled by this [Element].
  @DomName('Element.ontouchmove')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  ElementStream<TouchEvent> get onTouchMove;

  /// Stream of `touchstart` events handled by this [Element].
  @DomName('Element.ontouchstart')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  ElementStream<TouchEvent> get onTouchStart;

  /// Stream of `transitionend` events handled by this [Element].
  @DomName('Element.ontransitionend')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.FIREFOX)
  @SupportedBrowser(SupportedBrowser.IE, '10')
  @SupportedBrowser(SupportedBrowser.SAFARI)
  ElementStream<TransitionEvent> get onTransitionEnd;

  @DomName('Element.onvolumechange')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onVolumeChange;

  @DomName('Element.onwaiting')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onWaiting;

  /// Stream of `fullscreenchange` events handled by this [Element].
  @DomName('Element.onwebkitfullscreenchange')
  @DocsEditable()
  // https://dvcs.w3.org/hg/fullscreen/raw-file/tip/Overview.html
  @Experimental()
  ElementStream<Event> get onFullscreenChange;

  /// Stream of `fullscreenerror` events handled by this [Element].
  @DomName('Element.onwebkitfullscreenerror')
  @DocsEditable()
  // https://dvcs.w3.org/hg/fullscreen/raw-file/tip/Overview.html
  @Experimental()
  ElementStream<Event> get onFullscreenError;

}

// Wrapper over an immutable NodeList to make it implement ElementList.
//
// Clients are {`Document`, `DocumentFragment`}.`querySelectorAll` which are
// declared to return `ElementList`.  This provides all the static analysis
// benefit so there is no need for this class have a constrained type parameter.
//
class _FrozenElementList extends ListBase
    implements ElementList, NodeListWrapper {
  final List<Node> _nodeList;

  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<Event> get onCopy => Element.copyEvent._forElementList(this);

  /// Stream of `cut` events handled by this [Element].
  @DomName('Element.oncut')
  @DocsEditable()
  ElementStream<Event> get onCut => Element.cutEvent._forElementList(this);

  /// Stream of `doubleclick` events handled by this [Element].
  @DomName('Element.ondblclick')
  @DocsEditable()
  ElementStream<Event> get onDoubleClick => Element.doubleClickEvent._forElementList(this);

  /**
   * A stream of `drag` events fired when this element currently being dragged.
   *
   * A `drag` event is added to this stream as soon as the drag begins.
   * A `drag` event is also added to this stream at intervals while the drag
   * operation is still ongoing.
   *
   * ## Other resources
   *
   * * [Drag and drop sample]
   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   * from HTML5Rocks.
   * * [Drag and drop specification]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
   * from WHATWG.
   */
  @DomName('Element.ondrag')
  @DocsEditable()
  ElementStream<MouseEvent> get onDrag => Element.dragEvent._forElementList(this);

  /**
   * A stream of `dragend` events fired when this element completes a drag
   * operation.
   *
   * ## Other resources
   *
   * * [Drag and drop sample]
   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   * from HTML5Rocks.
   * * [Drag and drop specification]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
   * from WHATWG.
   */
  @DomName('Element.ondragend')
  @DocsEditable()
  ElementStream<MouseEvent> get onDragEnd => Element.dragEndEvent._forElementList(this);

  /**
   * A stream of `dragenter` events fired when a dragged object is first dragged
   * over this element.
   *
   * ## Other resources
   *
   * * [Drag and drop sample]
   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   * from HTML5Rocks.
   * * [Drag and drop specification]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
   * from WHATWG.
   */
  @DomName('Element.ondragenter')
  @DocsEditable()
  ElementStream<MouseEvent> get onDragEnter => Element.dragEnterEvent._forElementList(this);

  /**
   * A stream of `dragleave` events fired when an object being dragged over this
   * element leaves this element's target area.
   *
   * ## Other resources
   *
   * * [Drag and drop sample]
   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   * from HTML5Rocks.
   * * [Drag and drop specification]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
   * from WHATWG.
   */
  @DomName('Element.ondragleave')
  @DocsEditable()
  ElementStream<MouseEvent> get onDragLeave => Element.dragLeaveEvent._forElementList(this);

  /**
   * A stream of `dragover` events fired when a dragged object is currently
   * being dragged over this element.
   *
   * ## Other resources
   *
   * * [Drag and drop sample]
   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   * from HTML5Rocks.
   * * [Drag and drop specification]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
   * from WHATWG.
   */
  @DomName('Element.ondragover')
  @DocsEditable()
  ElementStream<MouseEvent> get onDragOver => Element.dragOverEvent._forElementList(this);

  /**
   * A stream of `dragstart` events fired when this element starts being
   * dragged.
   *
   * ## Other resources
   *
   * * [Drag and drop sample]
   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   * from HTML5Rocks.
   * * [Drag and drop specification]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
   * from WHATWG.
   */
  @DomName('Element.ondragstart')
  @DocsEditable()
  ElementStream<MouseEvent> get onDragStart => Element.dragStartEvent._forElementList(this);

  /**
   * A stream of `drop` events fired when a dragged object is dropped on this
   * element.
   *
   * ## Other resources
   *
   * * [Drag and drop sample]
   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   * from HTML5Rocks.
   * * [Drag and drop specification]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
   * from WHATWG.
   */
  @DomName('Element.ondrop')
  @DocsEditable()
  ElementStream<MouseEvent> get onDrop => Element.dropEvent._forElementList(this);

  @DomName('Element.ondurationchange')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onDurationChange => Element.durationChangeEvent._forElementList(this);

  @DomName('Element.onemptied')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onEmptied => Element.emptiedEvent._forElementList(this);

  @DomName('Element.onended')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onEnded => Element.endedEvent._forElementList(this);

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

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

  /// Stream of `input` events handled by this [Element].
  @DomName('Element.oninput')
  @DocsEditable()
  ElementStream<Event> get onInput => Element.inputEvent._forElementList(this);

  /// Stream of `invalid` events handled by this [Element].
  @DomName('Element.oninvalid')
  @DocsEditable()
  ElementStream<Event> get onInvalid => Element.invalidEvent._forElementList(this);

  /// Stream of `keydown` events handled by this [Element].
  @DomName('Element.onkeydown')
  @DocsEditable()
  ElementStream<KeyboardEvent> get onKeyDown => Element.keyDownEvent._forElementList(this);

  /// Stream of `keypress` events handled by this [Element].
  @DomName('Element.onkeypress')
  @DocsEditable()
  ElementStream<KeyboardEvent> get onKeyPress => Element.keyPressEvent._forElementList(this);

  /// Stream of `keyup` events handled by this [Element].
  @DomName('Element.onkeyup')
  @DocsEditable()
  ElementStream<KeyboardEvent> get onKeyUp => Element.keyUpEvent._forElementList(this);

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

  @DomName('Element.onloadeddata')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onLoadedData => Element.loadedDataEvent._forElementList(this);

  @DomName('Element.onloadedmetadata')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onLoadedMetadata => Element.loadedMetadataEvent._forElementList(this);

  /// Stream of `mousedown` events handled by this [Element].
  @DomName('Element.onmousedown')
  @DocsEditable()
  ElementStream<MouseEvent> get onMouseDown => Element.mouseDownEvent._forElementList(this);

  /// Stream of `mouseenter` events handled by this [Element].
  @DomName('Element.onmouseenter')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<MouseEvent> get onMouseEnter => Element.mouseEnterEvent._forElementList(this);

  /// Stream of `mouseleave` events handled by this [Element].
  @DomName('Element.onmouseleave')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<MouseEvent> get onMouseLeave => Element.mouseLeaveEvent._forElementList(this);

  /// Stream of `mousemove` events handled by this [Element].
  @DomName('Element.onmousemove')
  @DocsEditable()
  ElementStream<MouseEvent> get onMouseMove => Element.mouseMoveEvent._forElementList(this);

  /// Stream of `mouseout` events handled by this [Element].
  @DomName('Element.onmouseout')
  @DocsEditable()
  ElementStream<MouseEvent> get onMouseOut => Element.mouseOutEvent._forElementList(this);

  /// Stream of `mouseover` events handled by this [Element].
  @DomName('Element.onmouseover')
  @DocsEditable()
  ElementStream<MouseEvent> get onMouseOver => Element.mouseOverEvent._forElementList(this);

  /// Stream of `mouseup` events handled by this [Element].
  @DomName('Element.onmouseup')
  @DocsEditable()
  ElementStream<MouseEvent> get onMouseUp => Element.mouseUpEvent._forElementList(this);

  /// Stream of `mousewheel` events handled by this [Element].
  @DomName('Element.onmousewheel')
  @DocsEditable()
  // http://www.w3.org/TR/DOM-Level-3-Events/#events-wheelevents
  @Experimental() // non-standard
  ElementStream<WheelEvent> get onMouseWheel => Element.mouseWheelEvent._forElementList(this);

  /// Stream of `paste` events handled by this [Element].
  @DomName('Element.onpaste')
  @DocsEditable()
  ElementStream<Event> get onPaste => Element.pasteEvent._forElementList(this);

  @DomName('Element.onpause')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onPause => Element.pauseEvent._forElementList(this);

  @DomName('Element.onplay')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onPlay => Element.playEvent._forElementList(this);

  @DomName('Element.onplaying')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onPlaying => Element.playingEvent._forElementList(this);

  @DomName('Element.onratechange')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onRateChange => Element.rateChangeEvent._forElementList(this);

  /// Stream of `reset` events handled by this [Element].
  @DomName('Element.onreset')
  @DocsEditable()
  ElementStream<Event> get onReset => Element.resetEvent._forElementList(this);

  @DomName('Element.onresize')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onResize => Element.resizeEvent._forElementList(this);

  /// Stream of `scroll` events handled by this [Element].
  @DomName('Element.onscroll')
  @DocsEditable()
  ElementStream<Event> get onScroll => Element.scrollEvent._forElementList(this);

  /// Stream of `search` events handled by this [Element].
  @DomName('Element.onsearch')
  @DocsEditable()
  // http://www.w3.org/TR/html-markup/input.search.html
  @Experimental()
  ElementStream<Event> get onSearch => Element.searchEvent._forElementList(this);

  @DomName('Element.onseeked')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onSeeked => Element.seekedEvent._forElementList(this);

  @DomName('Element.onseeking')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onSeeking => Element.seekingEvent._forElementList(this);

  /// Stream of `select` events handled by this [Element].
  @DomName('Element.onselect')
  @DocsEditable()
  ElementStream<Event> get onSelect => Element.selectEvent._forElementList(this);

  /// Stream of `selectstart` events handled by this [Element].
  @DomName('Element.onselectstart')
  @DocsEditable()
  @Experimental() // nonstandard
  ElementStream<Event> get onSelectStart => Element.selectStartEvent._forElementList(this);

  @DomName('Element.onstalled')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onStalled => Element.stalledEvent._forElementList(this);

  /// Stream of `submit` events handled by this [Element].
  @DomName('Element.onsubmit')
  @DocsEditable()
  ElementStream<Event> get onSubmit => Element.submitEvent._forElementList(this);

  @DomName('Element.onsuspend')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onSuspend => Element.suspendEvent._forElementList(this);

  @DomName('Element.ontimeupdate')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onTimeUpdate => Element.timeUpdateEvent._forElementList(this);

  /// Stream of `touchcancel` events handled by this [Element].
  @DomName('Element.ontouchcancel')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  ElementStream<TouchEvent> get onTouchCancel => Element.touchCancelEvent._forElementList(this);

  /// Stream of `touchend` events handled by this [Element].
  @DomName('Element.ontouchend')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  ElementStream<TouchEvent> get onTouchEnd => Element.touchEndEvent._forElementList(this);

  /// Stream of `touchenter` events handled by this [Element].
  @DomName('Element.ontouchenter')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  ElementStream<TouchEvent> get onTouchEnter => Element.touchEnterEvent._forElementList(this);

  /// Stream of `touchleave` events handled by this [Element].
  @DomName('Element.ontouchleave')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  ElementStream<TouchEvent> get onTouchLeave => Element.touchLeaveEvent._forElementList(this);

  /// Stream of `touchmove` events handled by this [Element].
  @DomName('Element.ontouchmove')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  ElementStream<TouchEvent> get onTouchMove => Element.touchMoveEvent._forElementList(this);

  /// Stream of `touchstart` events handled by this [Element].
  @DomName('Element.ontouchstart')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  ElementStream<TouchEvent> get onTouchStart => Element.touchStartEvent._forElementList(this);

  /// Stream of `transitionend` events handled by this [Element].
  @DomName('Element.ontransitionend')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.FIREFOX)
  @SupportedBrowser(SupportedBrowser.IE, '10')
  @SupportedBrowser(SupportedBrowser.SAFARI)
  ElementStream<TransitionEvent> get onTransitionEnd => Element.transitionEndEvent._forElementList(this);

  @DomName('Element.onvolumechange')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onVolumeChange => Element.volumeChangeEvent._forElementList(this);

  @DomName('Element.onwaiting')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onWaiting => Element.waitingEvent._forElementList(this);

  /// Stream of `fullscreenchange` events handled by this [Element].
  @DomName('Element.onwebkitfullscreenchange')
  @DocsEditable()
  // https://dvcs.w3.org/hg/fullscreen/raw-file/tip/Overview.html
  @Experimental()
  ElementStream<Event> get onFullscreenChange => Element.fullscreenChangeEvent._forElementList(this);

  /// Stream of `fullscreenerror` events handled by this [Element].
  @DomName('Element.onwebkitfullscreenerror')
  @DocsEditable()
  // https://dvcs.w3.org/hg/fullscreen/raw-file/tip/Overview.html
  @Experimental()
  ElementStream<Event> get onFullscreenError => Element.fullscreenErrorEvent._forElementList(this);

}

@DocsEditable()
/**
 * An abstract class, which all HTML elements extend.
 */
@DomName('Element')
class Element extends Node implements GlobalEventHandlers, ParentNode, ChildNode {

  /**
   * Creates an HTML element from a valid fragment of HTML.
   *
   *     var element = new Element.html('<div class="foo">content</div>');
   *
   * The HTML fragment should contain only one single root element, any
   * leading or trailing text nodes will be removed.
   *
   * The HTML fragment is parsed as if it occurred within the context of a
   * `<body>` tag, this means that special elements such as `<caption>` which
   * must be parsed within the scope of a `<table>` element will be dropped. Use
   * [createFragment] to parse contextual HTML fragments.
   *
   * Unless a validator is provided this will perform the default validation
   * and remove all scriptable elements and attributes.
   *
   * See also:
   *
   * * [NodeValidator]
   *
   */
  factory Element.html(String html,
      {NodeValidator validator, NodeTreeSanitizer treeSanitizer}) {
    var fragment = document.body.createFragment(html, validator: validator,
        treeSanitizer: treeSanitizer);

    return fragment.nodes.where((e) => e is Element).single;
  }

  /**
   * Custom element creation constructor.
   *
   * This constructor is used by the DOM when a custom element has been
   * created. It can only be invoked by subclasses of Element from
   * that classes created constructor.
   *
   *     class CustomElement extends Element {
   *       factory CustomElement() => new Element.tag('x-custom');
   *
   *       CustomElement.created() : super.created() {
   *          // Perform any element initialization.
   *       }
   *     }
   *     document.registerElement('x-custom', CustomElement);
   */
  Element.created() : super._created();

  /**
   * 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://www.w3.org/TR/html5/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 AnimationPlayer 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')
  AnimationPlayer 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.offsetHeight')
  @DocsEditable()
  int get offsetHeight => _blink.BlinkElement.instance.offsetHeight_Getter_(unwrap_jso(this)).round();

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

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

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

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

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

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

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

  @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<Event> copyEvent = const EventStreamProvider<Event>('copy');

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

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

  /**
   * A stream of `drag` events fired when an element is currently being dragged.
   *
   * A `drag` event is added to this stream as soon as the drag begins.
   * A `drag` event is also added to this stream at intervals while the drag
   * operation is still ongoing.
   *
   * ## Other resources
   *
   * * [Drag and drop sample]
   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   * from HTML5Rocks.
   * * [Drag and drop specification]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
   * from WHATWG.
   */
  @DomName('Element.dragEvent')
  @DocsEditable()
  static const EventStreamProvider<MouseEvent> dragEvent = const EventStreamProvider<MouseEvent>('drag');

  /**
   * A stream of `dragend` events fired when an element completes a drag
   * operation.
   *
   * ## Other resources
   *
   * * [Drag and drop sample]
   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   * from HTML5Rocks.
   * * [Drag and drop specification]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
   * from WHATWG.
   */
  @DomName('Element.dragendEvent')
  @DocsEditable()
  static const EventStreamProvider<MouseEvent> dragEndEvent = const EventStreamProvider<MouseEvent>('dragend');

  /**
   * A stream of `dragenter` events fired when a dragged object is first dragged
   * over an element.
   *
   * ## Other resources
   *
   * * [Drag and drop sample]
   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   * from HTML5Rocks.
   * * [Drag and drop specification]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
   * from WHATWG.
   */
  @DomName('Element.dragenterEvent')
  @DocsEditable()
  static const EventStreamProvider<MouseEvent> dragEnterEvent = const EventStreamProvider<MouseEvent>('dragenter');

  /**
   * A stream of `dragleave` events fired when an object being dragged over an
   * element leaves the element's target area.
   *
   * ## Other resources
   *
   * * [Drag and drop sample]
   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   * from HTML5Rocks.
   * * [Drag and drop specification]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
   * from WHATWG.
   */
  @DomName('Element.dragleaveEvent')
  @DocsEditable()
  static const EventStreamProvider<MouseEvent> dragLeaveEvent = const EventStreamProvider<MouseEvent>('dragleave');

  /**
   * A stream of `dragover` events fired when a dragged object is currently
   * being dragged over an element.
   *
   * ## Other resources
   *
   * * [Drag and drop sample]
   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   * from HTML5Rocks.
   * * [Drag and drop specification]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
   * from WHATWG.
   */
  @DomName('Element.dragoverEvent')
  @DocsEditable()
  static const EventStreamProvider<MouseEvent> dragOverEvent = const EventStreamProvider<MouseEvent>('dragover');

  /**
   * A stream of `dragstart` events for a dragged element whose drag has begun.
   *
   * ## Other resources
   *
   * * [Drag and drop sample]
   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   * from HTML5Rocks.
   * * [Drag and drop specification]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
   * from WHATWG.
   */
  @DomName('Element.dragstartEvent')
  @DocsEditable()
  static const EventStreamProvider<MouseEvent> dragStartEvent = const EventStreamProvider<MouseEvent>('dragstart');

  /**
   * A stream of `drop` events fired when a dragged object is dropped on an
   * element.
   *
   * ## Other resources
   *
   * * [Drag and drop sample]
   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   * from HTML5Rocks.
   * * [Drag and drop specification]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
   * from WHATWG.
   */
  @DomName('Element.dropEvent')
  @DocsEditable()
  static const EventStreamProvider<MouseEvent> dropEvent = const EventStreamProvider<MouseEvent>('drop');

  @DomName('Element.durationchangeEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> durationChangeEvent = const EventStreamProvider<Event>('durationchange');

  @DomName('Element.emptiedEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> emptiedEvent = const EventStreamProvider<Event>('emptied');

  @DomName('Element.endedEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> endedEvent = const EventStreamProvider<Event>('ended');

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

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

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

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

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

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

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

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

  @DomName('Element.loadeddataEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> loadedDataEvent = const EventStreamProvider<Event>('loadeddata');

  @DomName('Element.loadedmetadataEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> loadedMetadataEvent = const EventStreamProvider<Event>('loadedmetadata');

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

  /**
   * Static factory designed to expose `mouseenter` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Element.mouseenterEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<MouseEvent> mouseEnterEvent = const EventStreamProvider<MouseEvent>('mouseenter');

  /**
   * Static factory designed to expose `mouseleave` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Element.mouseleaveEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<MouseEvent> mouseLeaveEvent = const EventStreamProvider<MouseEvent>('mouseleave');

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

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

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

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

  @DomName('Element.mousewheelEvent')
  @DocsEditable()
  // http://www.w3.org/TR/DOM-Level-3-Events/#events-wheelevents
  @Experimental() // non-standard
  static const EventStreamProvider<WheelEvent> mouseWheelEvent = const EventStreamProvider<WheelEvent>('mousewheel');

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

  @DomName('Element.pauseEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> pauseEvent = const EventStreamProvider<Event>('pause');

  @DomName('Element.playEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> playEvent = const EventStreamProvider<Event>('play');

  @DomName('Element.playingEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> playingEvent = const EventStreamProvider<Event>('playing');

  @DomName('Element.ratechangeEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> rateChangeEvent = const EventStreamProvider<Event>('ratechange');

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

  @DomName('Element.resizeEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> resizeEvent = const EventStreamProvider<Event>('resize');

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

  /**
   * Static factory designed to expose `search` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Element.searchEvent')
  @DocsEditable()
  // http://www.w3.org/TR/html-markup/input.search.html
  @Experimental()
  static const EventStreamProvider<Event> searchEvent = const EventStreamProvider<Event>('search');

  @DomName('Element.seekedEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> seekedEvent = const EventStreamProvider<Event>('seeked');

  @DomName('Element.seekingEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> seekingEvent = const EventStreamProvider<Event>('seeking');

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

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

  @DomName('Element.stalledEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> stalledEvent = const EventStreamProvider<Event>('stalled');

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

  @DomName('Element.suspendEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> suspendEvent = const EventStreamProvider<Event>('suspend');

  @DomName('Element.timeupdateEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> timeUpdateEvent = const EventStreamProvider<Event>('timeupdate');

  /**
   * Static factory designed to expose `touchcancel` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Element.touchcancelEvent')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  static const EventStreamProvider<TouchEvent> touchCancelEvent = const EventStreamProvider<TouchEvent>('touchcancel');

  /**
   * Static factory designed to expose `touchend` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Element.touchendEvent')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  static const EventStreamProvider<TouchEvent> touchEndEvent = const EventStreamProvider<TouchEvent>('touchend');

  /**
   * Static factory designed to expose `touchenter` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Element.touchenterEvent')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  static const EventStreamProvider<TouchEvent> touchEnterEvent = const EventStreamProvider<TouchEvent>('touchenter');

  /**
   * Static factory designed to expose `touchleave` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Element.touchleaveEvent')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  static const EventStreamProvider<TouchEvent> touchLeaveEvent = const EventStreamProvider<TouchEvent>('touchleave');

  /**
   * Static factory designed to expose `touchmove` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Element.touchmoveEvent')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  static const EventStreamProvider<TouchEvent> touchMoveEvent = const EventStreamProvider<TouchEvent>('touchmove');

  /**
   * Static factory designed to expose `touchstart` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Element.touchstartEvent')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  static const EventStreamProvider<TouchEvent> touchStartEvent = const EventStreamProvider<TouchEvent>('touchstart');

  @DomName('Element.transitionendEvent')
  @DocsEditable()
  static const EventStreamProvider<TransitionEvent> transitionEndEvent = const EventStreamProvider<TransitionEvent>('transitionend');

  @DomName('Element.volumechangeEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> volumeChangeEvent = const EventStreamProvider<Event>('volumechange');

  @DomName('Element.waitingEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> waitingEvent = const EventStreamProvider<Event>('waiting');

  /**
   * Static factory designed to expose `fullscreenchange` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Element.webkitfullscreenchangeEvent')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  // https://dvcs.w3.org/hg/fullscreen/raw-file/tip/Overview.html
  static const EventStreamProvider<Event> fullscreenChangeEvent = const EventStreamProvider<Event>('webkitfullscreenchange');

  /**
   * Static factory designed to expose `fullscreenerror` events to event
   * handlers that are not necessarily instances of [Element].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Element.webkitfullscreenerrorEvent')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  // https://dvcs.w3.org/hg/fullscreen/raw-file/tip/Overview.html
  static const EventStreamProvider<Event> fullscreenErrorEvent = const EventStreamProvider<Event>('webkitfullscreenerror');


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

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

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


  String contentEditable;

  MenuElement contextMenu;

  String dir;

  bool draggable;

  bool hidden;

  String lang;

  bool spellcheck;

  int tabIndex;

  String title;

  bool translate;

  String dropzone;

  @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.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.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.offsetParent')
  @DocsEditable()
  Element get offsetParent => wrap_jso(_blink.BlinkElement.instance.offsetParent_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.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.style')
  @DocsEditable()
  CssStyleDeclaration get style => wrap_jso(_blink.BlinkElement.instance.style_Getter_(unwrap_jso(this)));
  
  @DomName('Element.tagName')
  @DocsEditable()
  String get tagName => _blink.BlinkElement.instance.tagName_Getter_(unwrap_jso(this));
  
  @DomName('Element.animate')
  @DocsEditable()
  @Experimental() // untriaged
  AnimationPlayer _animate(Object effect, [Object timing]) => wrap_jso(_blink.BlinkElement.instance.animate_Callback_2_(unwrap_jso(this), effect, timing));
  
  @DomName('Element.blur')
  @DocsEditable()
  void blur() => _blink.BlinkElement.instance.blur_Callback_0_(unwrap_jso(this));
  
  @DomName('Element.createShadowRoot')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME, '25')
  @Experimental()
  // https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/shadow/index.html#api-shadow-aware-create-shadow-root
  ShadowRoot createShadowRoot() => wrap_jso(_blink.BlinkElement.instance.createShadowRoot_Callback_0_(unwrap_jso(this)));
  
  @DomName('Element.focus')
  @DocsEditable()
  void focus() => _blink.BlinkElement.instance.focus_Callback_0_(unwrap_jso(this));
  
  @DomName('Element.getAnimationPlayers')
  @DocsEditable()
  @Experimental() // untriaged
  List<AnimationPlayer> getAnimationPlayers() => wrap_jso(_blink.BlinkElement.instance.getAnimationPlayers_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 name) => wrap_jso(_blink.BlinkElement.instance.getElementsByTagName_Callback_1_(unwrap_jso(this), name));
  
  @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 where, String html) => _blink.BlinkElement.instance.insertAdjacentHTML_Callback_2_(unwrap_jso(this), where, html);
  
  @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 _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;
  }

  @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 qualifiedName, String value) => _blink.BlinkElement.instance.setAttributeNS_Callback_3_(unwrap_jso(this), namespaceURI, qualifiedName, value);
  
  @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.remove')
  @DocsEditable()
  void remove() => _blink.BlinkElement.instance.remove_Callback_0_(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<Event> get onCopy => copyEvent.forElement(this);

  /// Stream of `cut` events handled by this [Element].
  @DomName('Element.oncut')
  @DocsEditable()
  ElementStream<Event> get onCut => cutEvent.forElement(this);

  /// Stream of `doubleclick` events handled by this [Element].
  @DomName('Element.ondblclick')
  @DocsEditable()
  ElementStream<Event> get onDoubleClick => doubleClickEvent.forElement(this);

  /**
   * A stream of `drag` events fired when this element currently being dragged.
   *
   * A `drag` event is added to this stream as soon as the drag begins.
   * A `drag` event is also added to this stream at intervals while the drag
   * operation is still ongoing.
   *
   * ## Other resources
   *
   * * [Drag and drop sample]
   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   * from HTML5Rocks.
   * * [Drag and drop specification]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
   * from WHATWG.
   */
  @DomName('Element.ondrag')
  @DocsEditable()
  ElementStream<MouseEvent> get onDrag => dragEvent.forElement(this);

  /**
   * A stream of `dragend` events fired when this element completes a drag
   * operation.
   *
   * ## Other resources
   *
   * * [Drag and drop sample]
   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   * from HTML5Rocks.
   * * [Drag and drop specification]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
   * from WHATWG.
   */
  @DomName('Element.ondragend')
  @DocsEditable()
  ElementStream<MouseEvent> get onDragEnd => dragEndEvent.forElement(this);

  /**
   * A stream of `dragenter` events fired when a dragged object is first dragged
   * over this element.
   *
   * ## Other resources
   *
   * * [Drag and drop sample]
   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   * from HTML5Rocks.
   * * [Drag and drop specification]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
   * from WHATWG.
   */
  @DomName('Element.ondragenter')
  @DocsEditable()
  ElementStream<MouseEvent> get onDragEnter => dragEnterEvent.forElement(this);

  /**
   * A stream of `dragleave` events fired when an object being dragged over this
   * element leaves this element's target area.
   *
   * ## Other resources
   *
   * * [Drag and drop sample]
   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   * from HTML5Rocks.
   * * [Drag and drop specification]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
   * from WHATWG.
   */
  @DomName('Element.ondragleave')
  @DocsEditable()
  ElementStream<MouseEvent> get onDragLeave => dragLeaveEvent.forElement(this);

  /**
   * A stream of `dragover` events fired when a dragged object is currently
   * being dragged over this element.
   *
   * ## Other resources
   *
   * * [Drag and drop sample]
   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   * from HTML5Rocks.
   * * [Drag and drop specification]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
   * from WHATWG.
   */
  @DomName('Element.ondragover')
  @DocsEditable()
  ElementStream<MouseEvent> get onDragOver => dragOverEvent.forElement(this);

  /**
   * A stream of `dragstart` events fired when this element starts being
   * dragged.
   *
   * ## Other resources
   *
   * * [Drag and drop sample]
   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   * from HTML5Rocks.
   * * [Drag and drop specification]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
   * from WHATWG.
   */
  @DomName('Element.ondragstart')
  @DocsEditable()
  ElementStream<MouseEvent> get onDragStart => dragStartEvent.forElement(this);

  /**
   * A stream of `drop` events fired when a dragged object is dropped on this
   * element.
   *
   * ## Other resources
   *
   * * [Drag and drop sample]
   * (https://github.com/dart-lang/dart-samples/tree/master/web/html5/dnd/basics)
   * based on [the tutorial](http://www.html5rocks.com/en/tutorials/dnd/basics/)
   * from HTML5Rocks.
   * * [Drag and drop specification]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd)
   * from WHATWG.
   */
  @DomName('Element.ondrop')
  @DocsEditable()
  ElementStream<MouseEvent> get onDrop => dropEvent.forElement(this);

  @DomName('Element.ondurationchange')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onDurationChange => durationChangeEvent.forElement(this);

  @DomName('Element.onemptied')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onEmptied => emptiedEvent.forElement(this);

  @DomName('Element.onended')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onEnded => endedEvent.forElement(this);

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

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

  /// Stream of `input` events handled by this [Element].
  @DomName('Element.oninput')
  @DocsEditable()
  ElementStream<Event> get onInput => inputEvent.forElement(this);

  /// Stream of `invalid` events handled by this [Element].
  @DomName('Element.oninvalid')
  @DocsEditable()
  ElementStream<Event> get onInvalid => invalidEvent.forElement(this);

  /// Stream of `keydown` events handled by this [Element].
  @DomName('Element.onkeydown')
  @DocsEditable()
  ElementStream<KeyboardEvent> get onKeyDown => keyDownEvent.forElement(this);

  /// Stream of `keypress` events handled by this [Element].
  @DomName('Element.onkeypress')
  @DocsEditable()
  ElementStream<KeyboardEvent> get onKeyPress => keyPressEvent.forElement(this);

  /// Stream of `keyup` events handled by this [Element].
  @DomName('Element.onkeyup')
  @DocsEditable()
  ElementStream<KeyboardEvent> get onKeyUp => keyUpEvent.forElement(this);

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

  @DomName('Element.onloadeddata')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onLoadedData => loadedDataEvent.forElement(this);

  @DomName('Element.onloadedmetadata')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onLoadedMetadata => loadedMetadataEvent.forElement(this);

  /// Stream of `mousedown` events handled by this [Element].
  @DomName('Element.onmousedown')
  @DocsEditable()
  ElementStream<MouseEvent> get onMouseDown => mouseDownEvent.forElement(this);

  /// Stream of `mouseenter` events handled by this [Element].
  @DomName('Element.onmouseenter')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<MouseEvent> get onMouseEnter => mouseEnterEvent.forElement(this);

  /// Stream of `mouseleave` events handled by this [Element].
  @DomName('Element.onmouseleave')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<MouseEvent> get onMouseLeave => mouseLeaveEvent.forElement(this);

  /// Stream of `mousemove` events handled by this [Element].
  @DomName('Element.onmousemove')
  @DocsEditable()
  ElementStream<MouseEvent> get onMouseMove => mouseMoveEvent.forElement(this);

  /// Stream of `mouseout` events handled by this [Element].
  @DomName('Element.onmouseout')
  @DocsEditable()
  ElementStream<MouseEvent> get onMouseOut => mouseOutEvent.forElement(this);

  /// Stream of `mouseover` events handled by this [Element].
  @DomName('Element.onmouseover')
  @DocsEditable()
  ElementStream<MouseEvent> get onMouseOver => mouseOverEvent.forElement(this);

  /// Stream of `mouseup` events handled by this [Element].
  @DomName('Element.onmouseup')
  @DocsEditable()
  ElementStream<MouseEvent> get onMouseUp => mouseUpEvent.forElement(this);

  /// Stream of `mousewheel` events handled by this [Element].
  @DomName('Element.onmousewheel')
  @DocsEditable()
  // http://www.w3.org/TR/DOM-Level-3-Events/#events-wheelevents
  @Experimental() // non-standard
  ElementStream<WheelEvent> get onMouseWheel => mouseWheelEvent.forElement(this);

  /// Stream of `paste` events handled by this [Element].
  @DomName('Element.onpaste')
  @DocsEditable()
  ElementStream<Event> get onPaste => pasteEvent.forElement(this);

  @DomName('Element.onpause')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onPause => pauseEvent.forElement(this);

  @DomName('Element.onplay')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onPlay => playEvent.forElement(this);

  @DomName('Element.onplaying')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onPlaying => playingEvent.forElement(this);

  @DomName('Element.onratechange')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onRateChange => rateChangeEvent.forElement(this);

  /// Stream of `reset` events handled by this [Element].
  @DomName('Element.onreset')
  @DocsEditable()
  ElementStream<Event> get onReset => resetEvent.forElement(this);

  @DomName('Element.onresize')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onResize => resizeEvent.forElement(this);

  /// Stream of `scroll` events handled by this [Element].
  @DomName('Element.onscroll')
  @DocsEditable()
  ElementStream<Event> get onScroll => scrollEvent.forElement(this);

  /// Stream of `search` events handled by this [Element].
  @DomName('Element.onsearch')
  @DocsEditable()
  // http://www.w3.org/TR/html-markup/input.search.html
  @Experimental()
  ElementStream<Event> get onSearch => searchEvent.forElement(this);

  @DomName('Element.onseeked')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onSeeked => seekedEvent.forElement(this);

  @DomName('Element.onseeking')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onSeeking => seekingEvent.forElement(this);

  /// Stream of `select` events handled by this [Element].
  @DomName('Element.onselect')
  @DocsEditable()
  ElementStream<Event> get onSelect => selectEvent.forElement(this);

  /// Stream of `selectstart` events handled by this [Element].
  @DomName('Element.onselectstart')
  @DocsEditable()
  @Experimental() // nonstandard
  ElementStream<Event> get onSelectStart => selectStartEvent.forElement(this);

  @DomName('Element.onstalled')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onStalled => stalledEvent.forElement(this);

  /// Stream of `submit` events handled by this [Element].
  @DomName('Element.onsubmit')
  @DocsEditable()
  ElementStream<Event> get onSubmit => submitEvent.forElement(this);

  @DomName('Element.onsuspend')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onSuspend => suspendEvent.forElement(this);

  @DomName('Element.ontimeupdate')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onTimeUpdate => timeUpdateEvent.forElement(this);

  /// Stream of `touchcancel` events handled by this [Element].
  @DomName('Element.ontouchcancel')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  ElementStream<TouchEvent> get onTouchCancel => touchCancelEvent.forElement(this);

  /// Stream of `touchend` events handled by this [Element].
  @DomName('Element.ontouchend')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  ElementStream<TouchEvent> get onTouchEnd => touchEndEvent.forElement(this);

  /// Stream of `touchenter` events handled by this [Element].
  @DomName('Element.ontouchenter')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  ElementStream<TouchEvent> get onTouchEnter => touchEnterEvent.forElement(this);

  /// Stream of `touchleave` events handled by this [Element].
  @DomName('Element.ontouchleave')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  ElementStream<TouchEvent> get onTouchLeave => touchLeaveEvent.forElement(this);

  /// Stream of `touchmove` events handled by this [Element].
  @DomName('Element.ontouchmove')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  ElementStream<TouchEvent> get onTouchMove => touchMoveEvent.forElement(this);

  /// Stream of `touchstart` events handled by this [Element].
  @DomName('Element.ontouchstart')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  ElementStream<TouchEvent> get onTouchStart => touchStartEvent.forElement(this);

  /// Stream of `transitionend` events handled by this [Element].
  @DomName('Element.ontransitionend')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.FIREFOX)
  @SupportedBrowser(SupportedBrowser.IE, '10')
  @SupportedBrowser(SupportedBrowser.SAFARI)
  ElementStream<TransitionEvent> get onTransitionEnd => transitionEndEvent.forElement(this);

  @DomName('Element.onvolumechange')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onVolumeChange => volumeChangeEvent.forElement(this);

  @DomName('Element.onwaiting')
  @DocsEditable()
  @Experimental() // untriaged
  ElementStream<Event> get onWaiting => waitingEvent.forElement(this);

  /// Stream of `fullscreenchange` events handled by this [Element].
  @DomName('Element.onwebkitfullscreenchange')
  @DocsEditable()
  // https://dvcs.w3.org/hg/fullscreen/raw-file/tip/Overview.html
  @Experimental()
  ElementStream<Event> get onFullscreenChange => fullscreenChangeEvent.forElement(this);

  /// Stream of `fullscreenerror` events handled by this [Element].
  @DomName('Element.onwebkitfullscreenerror')
  @DocsEditable()
  // https://dvcs.w3.org/hg/fullscreen/raw-file/tip/Overview.html
  @Experimental()
  ElementStream<Event> get onFullscreenError => fullscreenErrorEvent.forElement(this);

}


class _ElementFactoryProvider {

  @DomName('Document.createElement')
  static Element createElement_tag(String tag, String typeExtension) =>
      document.createElement(tag, typeExtension);
}


/**
 * Options for Element.scrollIntoView.
 */
class ScrollAlignment {
  final _value;
  const ScrollAlignment._internal(this._value);
  toString() => 'ScrollAlignment.$_value';

  /// Attempt to align the element to the top of the scrollable area.
  static const TOP = const ScrollAlignment._internal('TOP');
  /// Attempt to center the element in the scrollable area.
  static const CENTER = const ScrollAlignment._internal('CENTER');
  /// Attempt to align the element to the bottom of the scrollable area.
  static const BOTTOM = const ScrollAlignment._internal('BOTTOM');
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.


@DocsEditable()
@DomName('HTMLEmbedElement')
@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.IE)
@SupportedBrowser(SupportedBrowser.SAFARI)
@Unstable()
class EmbedElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory EmbedElement._() { throw new UnsupportedError("Not supported"); }

  @DomName('HTMLEmbedElement.HTMLEmbedElement')
  @DocsEditable()
  factory EmbedElement() => document.createElement("embed");


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

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

  @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.integrity')
  @DocsEditable()
  @Experimental() // untriaged
  String get integrity => _blink.BlinkHTMLEmbedElement.instance.integrity_Getter_(unwrap_jso(this));
  
  @DomName('HTMLEmbedElement.integrity')
  @DocsEditable()
  @Experimental() // untriaged
  set integrity(String value) => _blink.BlinkHTMLEmbedElement.instance.integrity_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"); }


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

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

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

  @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));
  
  /**
   * Access to the system's clipboard data during copy, cut, and paste events.
   *
   * ## Other resources
   *
   * * [clipboardData specification]
   * (http://www.w3.org/TR/clipboard-apis/#attributes) from W3C.
   */
  @DomName('Event.clipboardData')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.FIREFOX)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  // Part of copy/paste
  @Experimental() // nonstandard
  DataTransfer get clipboardData => wrap_jso(_blink.BlinkEvent.instance.clipboardData_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<Node> 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 eventTypeArg, bool canBubbleArg, bool cancelableArg) => _blink.BlinkEvent.instance.initEvent_Callback_3_(unwrap_jso(this), eventTypeArg, canBubbleArg, cancelableArg);
  
  @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 eventSourceInit]) {
    if (eventSourceInit != null) {
      var eventSourceInit_1 = convertDartToNative_Dictionary(eventSourceInit);
      return wrap_jso(_blink.BlinkEventSource.instance.constructorCallback_2_(url, eventSourceInit_1));
    }
    return wrap_jso(_blink.BlinkEventSource.instance.constructorCallback_1_(url));
  }


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

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

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

  void _addEventListener([String type, EventListener listener, bool useCapture]) {
    if (useCapture != null) {
      _blink.BlinkEventTarget.instance.addEventListener_Callback_3_(unwrap_jso(this), type, wrap_event_listener(this, listener), useCapture);
      return;
    }
    if (listener != null) {
      _blink.BlinkEventTarget.instance.addEventListener_Callback_2_(unwrap_jso(this), type, wrap_event_listener(this, listener));
      return;
    }
    if (type != null) {
      _blink.BlinkEventTarget.instance.addEventListener_Callback_1_(unwrap_jso(this), type);
      return;
    }
    _blink.BlinkEventTarget.instance.addEventListener_Callback_0_(unwrap_jso(this));
    return;
  }

  @DomName('EventTarget.dispatchEvent')
  @DocsEditable()
  bool dispatchEvent(Event event) => _blink.BlinkEventTarget.instance.dispatchEvent_Callback_1_(unwrap_jso(this), unwrap_jso(event));
  
  void _removeEventListener([String type, EventListener listener, bool useCapture]) {
    if (useCapture != null) {
      _blink.BlinkEventTarget.instance.removeEventListener_Callback_3_(unwrap_jso(this), type, _knownListeners[this.hashCode][identityHashCode(listener)], useCapture);
      return;
    }
    if (listener != null) {
      _blink.BlinkEventTarget.instance.removeEventListener_Callback_2_(unwrap_jso(this), type, _knownListeners[this.hashCode][identityHashCode(listener)]);
      return;
    }
    if (type != null) {
      _blink.BlinkEventTarget.instance.removeEventListener_Callback_1_(unwrap_jso(this), type);
      return;
    }
    _blink.BlinkEventTarget.instance.removeEventListener_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('ExtendableEvent')
@Experimental() // untriaged
class ExtendableEvent extends Event {
  // To suppress missing implicit constructor warnings.
  factory ExtendableEvent._() { throw new UnsupportedError("Not supported"); }


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

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

  @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(String id, String name, String avatarURL, String federation) {
    return wrap_jso(_blink.BlinkFederatedCredential.instance.constructorCallback_4_(id, name, avatarURL, federation));
  }


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

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

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


  @DomName('FederatedCredential.federation')
  @DocsEditable()
  @Experimental() // untriaged
  String get federation => _blink.BlinkFederatedCredential.instance.federation_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 Event {
  // To suppress missing implicit constructor warnings.
  factory FetchEvent._() { throw new UnsupportedError("Not supported"); }


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

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

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

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

  @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()
  List<Node> 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.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"); }


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

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

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

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

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

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

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

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

  @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 encoding]) {
    if (encoding != null) {
      _blink.BlinkFileReader.instance.readAsText_Callback_2_(unwrap_jso(this), unwrap_jso(blob), encoding);
      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();
  }

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

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


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

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

  @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, source, [Map descriptors]) {
    if ((source is String || source == null) && (family is String || family == null) && descriptors == null) {
      return wrap_jso(_blink.BlinkFontFace.instance.constructorCallback_2_(family, source));
    }
    if ((descriptors is Map || descriptors == null) && (source is String || source == null) && (family is String || family == null)) {
      var descriptors_1 = convertDartToNative_Dictionary(descriptors);
      return wrap_jso(_blink.BlinkFontFace.instance.constructorCallback_3_(family, source, descriptors_1));
    }
    if ((source is TypedData || source == null) && (family is String || family == null) && descriptors == null) {
      return wrap_jso(_blink.BlinkFontFace.instance.constructorCallback_2_(family, source));
    }
    if ((descriptors is Map || descriptors == null) && (source is TypedData || source == null) && (family is String || family == null)) {
      var descriptors_1 = convertDartToNative_Dictionary(descriptors);
      return wrap_jso(_blink.BlinkFontFace.instance.constructorCallback_3_(family, source, descriptors_1));
    }
    if ((source is ByteBuffer || source == null) && (family is String || family == null) && descriptors == null) {
      return wrap_jso(_blink.BlinkFontFace.instance.constructorCallback_2_(family, source));
    }
    if ((descriptors is Map || descriptors == null) && (source is ByteBuffer || source == null) && (family is String || family == null)) {
      var descriptors_1 = convertDartToNative_Dictionary(descriptors);
      return wrap_jso(_blink.BlinkFontFace.instance.constructorCallback_3_(family, source, descriptors_1));
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }

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

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

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

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

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

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

  @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);
  
  Element __getter__(index_OR_name) {
    if ((index_OR_name is int || index_OR_name == null)) {
      return wrap_jso(_blink.BlinkHTMLFormElement.instance.$__getter___Callback_1_(unwrap_jso(this), unwrap_jso(index_OR_name)));
    }
    if ((index_OR_name is String || index_OR_name == null)) {
      return wrap_jso(_blink.BlinkHTMLFormElement.instance.$__getter___Callback_1_(unwrap_jso(this), unwrap_jso(index_OR_name)));
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }

  @DomName('HTMLFormElement.checkValidity')
  @DocsEditable()
  bool checkValidity() => _blink.BlinkHTMLFormElement.instance.checkValidity_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.


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


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

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

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


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

  @DomName('GlobalEventHandlers.abortEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> abortEvent = const EventStreamProvider<Event>('abort');

  @DomName('GlobalEventHandlers.blurEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> blurEvent = const EventStreamProvider<Event>('blur');

  @DomName('GlobalEventHandlers.canplayEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> canPlayEvent = const EventStreamProvider<Event>('canplay');

  @DomName('GlobalEventHandlers.canplaythroughEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> canPlayThroughEvent = const EventStreamProvider<Event>('canplaythrough');

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

  @DomName('GlobalEventHandlers.clickEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<MouseEvent> clickEvent = const EventStreamProvider<MouseEvent>('click');

  @DomName('GlobalEventHandlers.contextmenuEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<MouseEvent> contextMenuEvent = const EventStreamProvider<MouseEvent>('contextmenu');

  @DomName('GlobalEventHandlers.dblclickEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> doubleClickEvent = const EventStreamProvider<Event>('dblclick');

  @DomName('GlobalEventHandlers.dragEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<MouseEvent> dragEvent = const EventStreamProvider<MouseEvent>('drag');

  @DomName('GlobalEventHandlers.dragendEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<MouseEvent> dragEndEvent = const EventStreamProvider<MouseEvent>('dragend');

  @DomName('GlobalEventHandlers.dragenterEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<MouseEvent> dragEnterEvent = const EventStreamProvider<MouseEvent>('dragenter');

  @DomName('GlobalEventHandlers.dragleaveEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<MouseEvent> dragLeaveEvent = const EventStreamProvider<MouseEvent>('dragleave');

  @DomName('GlobalEventHandlers.dragoverEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<MouseEvent> dragOverEvent = const EventStreamProvider<MouseEvent>('dragover');

  @DomName('GlobalEventHandlers.dragstartEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<MouseEvent> dragStartEvent = const EventStreamProvider<MouseEvent>('dragstart');

  @DomName('GlobalEventHandlers.dropEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<MouseEvent> dropEvent = const EventStreamProvider<MouseEvent>('drop');

  @DomName('GlobalEventHandlers.durationchangeEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> durationChangeEvent = const EventStreamProvider<Event>('durationchange');

  @DomName('GlobalEventHandlers.emptiedEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> emptiedEvent = const EventStreamProvider<Event>('emptied');

  @DomName('GlobalEventHandlers.endedEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> endedEvent = const EventStreamProvider<Event>('ended');

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

  @DomName('GlobalEventHandlers.focusEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> focusEvent = const EventStreamProvider<Event>('focus');

  @DomName('GlobalEventHandlers.inputEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> inputEvent = const EventStreamProvider<Event>('input');

  @DomName('GlobalEventHandlers.invalidEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> invalidEvent = const EventStreamProvider<Event>('invalid');

  @DomName('GlobalEventHandlers.keydownEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<KeyboardEvent> keyDownEvent = const EventStreamProvider<KeyboardEvent>('keydown');

  @DomName('GlobalEventHandlers.keypressEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<KeyboardEvent> keyPressEvent = const EventStreamProvider<KeyboardEvent>('keypress');

  @DomName('GlobalEventHandlers.keyupEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<KeyboardEvent> keyUpEvent = const EventStreamProvider<KeyboardEvent>('keyup');

  @DomName('GlobalEventHandlers.loadEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> loadEvent = const EventStreamProvider<Event>('load');

  @DomName('GlobalEventHandlers.loadeddataEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> loadedDataEvent = const EventStreamProvider<Event>('loadeddata');

  @DomName('GlobalEventHandlers.loadedmetadataEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> loadedMetadataEvent = const EventStreamProvider<Event>('loadedmetadata');

  @DomName('GlobalEventHandlers.mousedownEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<MouseEvent> mouseDownEvent = const EventStreamProvider<MouseEvent>('mousedown');

  @DomName('GlobalEventHandlers.mouseenterEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<MouseEvent> mouseEnterEvent = const EventStreamProvider<MouseEvent>('mouseenter');

  @DomName('GlobalEventHandlers.mouseleaveEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<MouseEvent> mouseLeaveEvent = const EventStreamProvider<MouseEvent>('mouseleave');

  @DomName('GlobalEventHandlers.mousemoveEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<MouseEvent> mouseMoveEvent = const EventStreamProvider<MouseEvent>('mousemove');

  @DomName('GlobalEventHandlers.mouseoutEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<MouseEvent> mouseOutEvent = const EventStreamProvider<MouseEvent>('mouseout');

  @DomName('GlobalEventHandlers.mouseoverEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<MouseEvent> mouseOverEvent = const EventStreamProvider<MouseEvent>('mouseover');

  @DomName('GlobalEventHandlers.mouseupEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<MouseEvent> mouseUpEvent = const EventStreamProvider<MouseEvent>('mouseup');

  @DomName('GlobalEventHandlers.mousewheelEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<WheelEvent> mouseWheelEvent = const EventStreamProvider<WheelEvent>('mousewheel');

  @DomName('GlobalEventHandlers.pauseEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> pauseEvent = const EventStreamProvider<Event>('pause');

  @DomName('GlobalEventHandlers.playEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> playEvent = const EventStreamProvider<Event>('play');

  @DomName('GlobalEventHandlers.playingEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> playingEvent = const EventStreamProvider<Event>('playing');

  @DomName('GlobalEventHandlers.ratechangeEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> rateChangeEvent = const EventStreamProvider<Event>('ratechange');

  @DomName('GlobalEventHandlers.resetEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> resetEvent = const EventStreamProvider<Event>('reset');

  @DomName('GlobalEventHandlers.resizeEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> resizeEvent = const EventStreamProvider<Event>('resize');

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

  @DomName('GlobalEventHandlers.seekedEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> seekedEvent = const EventStreamProvider<Event>('seeked');

  @DomName('GlobalEventHandlers.seekingEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> seekingEvent = const EventStreamProvider<Event>('seeking');

  @DomName('GlobalEventHandlers.selectEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> selectEvent = const EventStreamProvider<Event>('select');

  @DomName('GlobalEventHandlers.stalledEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> stalledEvent = const EventStreamProvider<Event>('stalled');

  @DomName('GlobalEventHandlers.submitEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> submitEvent = const EventStreamProvider<Event>('submit');

  @DomName('GlobalEventHandlers.suspendEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> suspendEvent = const EventStreamProvider<Event>('suspend');

  @DomName('GlobalEventHandlers.timeupdateEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> timeUpdateEvent = const EventStreamProvider<Event>('timeupdate');

  @DomName('GlobalEventHandlers.volumechangeEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> volumeChangeEvent = const EventStreamProvider<Event>('volumechange');

  @DomName('GlobalEventHandlers.waitingEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> waitingEvent = const EventStreamProvider<Event>('waiting');

  @DomName('GlobalEventHandlers.onabort')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onAbort => abortEvent.forTarget(this);

  @DomName('GlobalEventHandlers.onblur')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onBlur => blurEvent.forTarget(this);

  @DomName('GlobalEventHandlers.oncanplay')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onCanPlay => canPlayEvent.forTarget(this);

  @DomName('GlobalEventHandlers.oncanplaythrough')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onCanPlayThrough => canPlayThroughEvent.forTarget(this);

  @DomName('GlobalEventHandlers.onchange')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onChange => changeEvent.forTarget(this);

  @DomName('GlobalEventHandlers.onclick')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<MouseEvent> get onClick => clickEvent.forTarget(this);

  @DomName('GlobalEventHandlers.oncontextmenu')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<MouseEvent> get onContextMenu => contextMenuEvent.forTarget(this);

  @DomName('GlobalEventHandlers.ondblclick')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onDoubleClick => doubleClickEvent.forTarget(this);

  @DomName('GlobalEventHandlers.ondrag')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<MouseEvent> get onDrag => dragEvent.forTarget(this);

  @DomName('GlobalEventHandlers.ondragend')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<MouseEvent> get onDragEnd => dragEndEvent.forTarget(this);

  @DomName('GlobalEventHandlers.ondragenter')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<MouseEvent> get onDragEnter => dragEnterEvent.forTarget(this);

  @DomName('GlobalEventHandlers.ondragleave')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<MouseEvent> get onDragLeave => dragLeaveEvent.forTarget(this);

  @DomName('GlobalEventHandlers.ondragover')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<MouseEvent> get onDragOver => dragOverEvent.forTarget(this);

  @DomName('GlobalEventHandlers.ondragstart')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<MouseEvent> get onDragStart => dragStartEvent.forTarget(this);

  @DomName('GlobalEventHandlers.ondrop')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<MouseEvent> get onDrop => dropEvent.forTarget(this);

  @DomName('GlobalEventHandlers.ondurationchange')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onDurationChange => durationChangeEvent.forTarget(this);

  @DomName('GlobalEventHandlers.onemptied')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onEmptied => emptiedEvent.forTarget(this);

  @DomName('GlobalEventHandlers.onended')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onEnded => endedEvent.forTarget(this);

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

  @DomName('GlobalEventHandlers.onfocus')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onFocus => focusEvent.forTarget(this);

  @DomName('GlobalEventHandlers.oninput')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onInput => inputEvent.forTarget(this);

  @DomName('GlobalEventHandlers.oninvalid')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onInvalid => invalidEvent.forTarget(this);

  @DomName('GlobalEventHandlers.onkeydown')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<KeyboardEvent> get onKeyDown => keyDownEvent.forTarget(this);

  @DomName('GlobalEventHandlers.onkeypress')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<KeyboardEvent> get onKeyPress => keyPressEvent.forTarget(this);

  @DomName('GlobalEventHandlers.onkeyup')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<KeyboardEvent> get onKeyUp => keyUpEvent.forTarget(this);

  @DomName('GlobalEventHandlers.onload')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onLoad => loadEvent.forTarget(this);

  @DomName('GlobalEventHandlers.onloadeddata')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onLoadedData => loadedDataEvent.forTarget(this);

  @DomName('GlobalEventHandlers.onloadedmetadata')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onLoadedMetadata => loadedMetadataEvent.forTarget(this);

  @DomName('GlobalEventHandlers.onmousedown')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<MouseEvent> get onMouseDown => mouseDownEvent.forTarget(this);

  @DomName('GlobalEventHandlers.onmouseenter')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<MouseEvent> get onMouseEnter => mouseEnterEvent.forTarget(this);

  @DomName('GlobalEventHandlers.onmouseleave')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<MouseEvent> get onMouseLeave => mouseLeaveEvent.forTarget(this);

  @DomName('GlobalEventHandlers.onmousemove')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<MouseEvent> get onMouseMove => mouseMoveEvent.forTarget(this);

  @DomName('GlobalEventHandlers.onmouseout')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<MouseEvent> get onMouseOut => mouseOutEvent.forTarget(this);

  @DomName('GlobalEventHandlers.onmouseover')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<MouseEvent> get onMouseOver => mouseOverEvent.forTarget(this);

  @DomName('GlobalEventHandlers.onmouseup')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<MouseEvent> get onMouseUp => mouseUpEvent.forTarget(this);

  @DomName('GlobalEventHandlers.onmousewheel')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<WheelEvent> get onMouseWheel => mouseWheelEvent.forTarget(this);

  @DomName('GlobalEventHandlers.onpause')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onPause => pauseEvent.forTarget(this);

  @DomName('GlobalEventHandlers.onplay')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onPlay => playEvent.forTarget(this);

  @DomName('GlobalEventHandlers.onplaying')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onPlaying => playingEvent.forTarget(this);

  @DomName('GlobalEventHandlers.onratechange')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onRateChange => rateChangeEvent.forTarget(this);

  @DomName('GlobalEventHandlers.onreset')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onReset => resetEvent.forTarget(this);

  @DomName('GlobalEventHandlers.onresize')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onResize => resizeEvent.forTarget(this);

  @DomName('GlobalEventHandlers.onscroll')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onScroll => scrollEvent.forTarget(this);

  @DomName('GlobalEventHandlers.onseeked')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onSeeked => seekedEvent.forTarget(this);

  @DomName('GlobalEventHandlers.onseeking')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onSeeking => seekingEvent.forTarget(this);

  @DomName('GlobalEventHandlers.onselect')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onSelect => selectEvent.forTarget(this);

  @DomName('GlobalEventHandlers.onstalled')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onStalled => stalledEvent.forTarget(this);

  @DomName('GlobalEventHandlers.onsubmit')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onSubmit => submitEvent.forTarget(this);

  @DomName('GlobalEventHandlers.onsuspend')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onSuspend => suspendEvent.forTarget(this);

  @DomName('GlobalEventHandlers.ontimeupdate')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onTimeUpdate => timeUpdateEvent.forTarget(this);

  @DomName('GlobalEventHandlers.onvolumechange')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onVolumeChange => volumeChangeEvent.forTarget(this);

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

// WARNING: Do not edit - generated code.


@DocsEditable()
/**
 * An `<hr>` tag.
 */
@DomName('HTMLHRElement')
class HRElement extends HtmlElement {
  // To suppress missing implicit constructor warnings.
  factory HRElement._() { throw new UnsupportedError("Not supported"); }

  @DomName('HTMLHRElement.HTMLHRElement')
  @DocsEditable()
  factory HRElement() => document.createElement("hr");


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

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

  @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}) {
    var event = document._createEvent("HashChangeEvent");
    event._initHashChangeEvent(type, canBubble, cancelable, oldUrl, newUrl);
    return event;
  }
  // To suppress missing implicit constructor warnings.
  factory HashChangeEvent._() { throw new UnsupportedError("Not supported"); }


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

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

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

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

  @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 || input == null)) {
      return wrap_jso(_blink.BlinkHeaders.instance.constructorCallback_1_(input));
    }
    if ((input is Map || input == null)) {
      var input_1 = convertDartToNative_Dictionary(input);
      return wrap_jso(_blink.BlinkHeaders.instance.constructorCallback_1_(input_1));
    }
    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;

  @DomName('Headers.size')
  @DocsEditable()
  @Experimental() // untriaged
  int get size => _blink.BlinkHeaders.instance.size_Getter_(unwrap_jso(this));
  
  void forEach(HeadersForEachCallback callback, [Object thisArg]) {
    if (thisArg != null) {
      _blink.BlinkHeaders.instance.forEach_Callback_2_(unwrap_jso(this), unwrap_jso((String value, String key, map) => callback(value, key, wrap_jso(map))), thisArg);
      return;
    }
    _blink.BlinkHeaders.instance.forEach_Callback_1_(unwrap_jso(this), unwrap_jso((String value, String key, map) => callback(value, key, wrap_jso(map))));
    return;
  }

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

// WARNING: Do not edit - generated code.


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

// WARNING: Do not edit - generated code.


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

  @DomName('HTMLHeadingElement.HTMLHeadingElement')
  @DocsEditable()
  factory HeadingElement.h1() => document.createElement("h1");

  @DomName('HTMLHeadingElement.HTMLHeadingElement')
  @DocsEditable()
  factory HeadingElement.h2() => document.createElement("h2");

  @DomName('HTMLHeadingElement.HTMLHeadingElement')
  @DocsEditable()
  factory HeadingElement.h3() => document.createElement("h3");

  @DomName('HTMLHeadingElement.HTMLHeadingElement')
  @DocsEditable()
  factory HeadingElement.h4() => document.createElement("h4");

  @DomName('HTMLHeadingElement.HTMLHeadingElement')
  @DocsEditable()
  factory HeadingElement.h5() => document.createElement("h5");

  @DomName('HTMLHeadingElement.HTMLHeadingElement')
  @DocsEditable()
  factory HeadingElement.h6() => document.createElement("h6");


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

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

  @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.state')
  @DocsEditable()
  dynamic get state => _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));
  
  @DomName('History.go')
  @DocsEditable()
  void go(int distance) => _blink.BlinkHistory.instance.go_Callback_1_(unwrap_jso(this), distance);
  
  @DomName('History.pushState')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.FIREFOX)
  @SupportedBrowser(SupportedBrowser.IE, '10')
  @SupportedBrowser(SupportedBrowser.SAFARI)
  void pushState(Object data, String title, [String url]) => _blink.BlinkHistory.instance.pushState_Callback_3_(unwrap_jso(this), data, title, url);
  
  @DomName('History.replaceState')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.FIREFOX)
  @SupportedBrowser(SupportedBrowser.IE, '10')
  @SupportedBrowser(SupportedBrowser.SAFARI)
  void replaceState(Object data, String title, [String url]) => _blink.BlinkHistory.instance.replaceState_Callback_3_(unwrap_jso(this), data, title, url);
  }
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.


@DocsEditable()
@DomName('HTMLCollection')
class HtmlCollection extends 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();
  }

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

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



  @DomName('Document.body')
  BodyElement get body => _body;

  @DomName('Document.body')
  set body(BodyElement value) {
    _body = value;
  }

  @DomName('Document.caretRangeFromPoint')
  Range caretRangeFromPoint(int x, int y) {
    return _caretRangeFromPoint(x, y);
  }

  @DomName('Document.elementFromPoint')
  Element elementFromPoint(int x, int y) {
    return _elementFromPoint(x, y);
  }

  /**
   * Checks if the getCssCanvasContext API is supported on the current platform.
   *
   * See also:
   *
   * * [getCssCanvasContext]
   */
  static bool get supportsCssCanvasContext => true;


  /**
   * Gets a CanvasRenderingContext which can be used as the CSS background of an
   * element.
   *
   * CSS:
   *
   *     background: -webkit-canvas(backgroundCanvas)
   *
   * Generate the canvas:
   *
   *     var context = document.getCssCanvasContext('2d', 'backgroundCanvas',
   *         100, 100);
   *     context.fillStyle = 'red';
   *     context.fillRect(0, 0, 100, 100);
   *
   * See also:
   *
   * * [supportsCssCanvasContext]
   * * [CanvasElement.getContext]
   */
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  @DomName('Document.getCSSCanvasContext')
  CanvasRenderingContext getCssCanvasContext(String contextId, String name,
      int width, int height) {
    return _getCssCanvasContext(contextId, name, width, height);
  }

  @DomName('Document.head')
  HeadElement get head => _head;

  @DomName('Document.lastModified')
  String get lastModified => _lastModified;

  @DomName('Document.preferredStylesheetSet')
  String get preferredStylesheetSet => _preferredStylesheetSet;

  @DomName('Document.referrer')
  String get referrer => _referrer;

  @DomName('Document.selectedStylesheetSet')
  String get selectedStylesheetSet => _selectedStylesheetSet;
  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;
          });
        }

        // Get the created constructor source and look at the initializer;
        // Must call super.created() if not its as an error.
        var createdSource = methodMirror.source;
        superCreatedCalled = createdSource.contains("super.created(");
      }

      if (!superCreatedCalled) {
        throw new DomException.jsInterop('created constructor initializer must call super.created()');
      } else 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();
  }

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

  @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.inputMethodContext')
  @DocsEditable()
  @Experimental() // untriaged
  InputMethodContext get inputMethodContext => wrap_jso(_blink.BlinkHTMLElement.instance.inputMethodContext_Getter_(unwrap_jso(this)));
  
  @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.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.click')
  @DocsEditable()
  void click() => _blink.BlinkHTMLElement.instance.click_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();
  }

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

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


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

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

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

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

  @Deprecated("Internal Use Only")
  HtmlOptionsCollection.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.


 /**
  * 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() => wrap_jso(_create());

  @DocsEditable()
  static HttpRequest _create() => wrap_jso(_blink.BlinkXMLHttpRequest.instance.constructorCallback_0_());


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

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

  @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/DOM/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/DOM/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#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#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](http://en.wikipedia.org/wiki/List_of_HTTP_header_fields#Responses)
   * for a list of common response headers.
   */
  @DomName('XMLHttpRequest.getAllResponseHeaders')
  @DocsEditable()
  @Unstable()
  String getAllResponseHeaders() => _blink.BlinkXMLHttpRequest.instance.getAllResponseHeaders_Callback_0_(unwrap_jso(this));
  
  /**
   * Return the response header named `header`, or null if not found.
   *
   * See also [HTTP response headers](http://en.wikipedia.org/wiki/List_of_HTTP_header_fields#Responses)
   * for a list of common response headers.
   */
  @DomName('XMLHttpRequest.getResponseHeader')
  @DocsEditable()
  @Unstable()
  String getResponseHeader(String header) => _blink.BlinkXMLHttpRequest.instance.getResponseHeader_Callback_1_(unwrap_jso(this), header);
  
  /**
   * Specify a particular MIME type (such as `text/xml`) desired for the
   * response.
   *
   * This value must be set before the request has been sent. See also the list
   * of [common MIME types](http://en.wikipedia.org/wiki/Internet_media_type#List_of_common_media_types)
   */
  @DomName('XMLHttpRequest.overrideMimeType')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.FIREFOX)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  void overrideMimeType(String override) => _blink.BlinkXMLHttpRequest.instance.overrideMimeType_Callback_1_(unwrap_jso(this), override);
  
  /**
   * Send the request with any given `data`.
   *
   * Note: Most simple HTTP requests can be accomplished using the [getString],
   * [request], [requestCrossOrigin], or [postFormData] methods. Use of this
   * `send` method is intended only for more complext HTTP requests where
   * finer-grained control is needed.
   *
   * ## Other resources
   *
   * * [XMLHttpRequest.send]
   * (https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest#send%28%29)
   * from MDN.
   */
  @DomName('XMLHttpRequest.send')
  @DocsEditable()
  void send([data]) => _blink.BlinkXMLHttpRequest.instance.send_Callback_1_(unwrap_jso(this), unwrap_jso(data));
  
  /**
   * Sets the value of an HTTP requst header.
   *
   * This method should be called after the request is opened, but before
   * the request is sent.
   *
   * Multiple calls with the same header will combine all their values into a
   * single header.
   *
   * ## Other resources
   *
   * * [XMLHttpRequest.setRequestHeader]
   * (https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest#send%28%29)
   * from MDN.
   * * [The setRequestHeader() method]
   * (http://www.w3.org/TR/XMLHttpRequest/#the-setrequestheader()-method) from
   * W3C.
   */
  @DomName('XMLHttpRequest.setRequestHeader')
  @DocsEditable()
  void setRequestHeader(String header, String value) => _blink.BlinkXMLHttpRequest.instance.setRequestHeader_Callback_2_(unwrap_jso(this), header, value);
  
  /// Stream of `readystatechange` events handled by this [HttpRequest].
/**
   * Event listeners to be notified every time the [HttpRequest]
   * object's `readyState` changes values.
   */
  @DomName('XMLHttpRequest.onreadystatechange')
  @DocsEditable()
  Stream<ProgressEvent> get onReadyStateChange => readyStateChangeEvent.forTarget(this);

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

// WARNING: Do not edit - generated code.


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

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

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

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

  /**
   * Static factory designed to expose `loadend` events to event
   * handlers that are not necessarily instances of [HttpRequestEventTarget].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('XMLHttpRequestEventTarget.loadendEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<ProgressEvent> loadEndEvent = const EventStreamProvider<ProgressEvent>('loadend');

  /**
   * Static factory designed to expose `loadstart` events to event
   * handlers that are not necessarily instances of [HttpRequestEventTarget].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('XMLHttpRequestEventTarget.loadstartEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<ProgressEvent> loadStartEvent = const EventStreamProvider<ProgressEvent>('loadstart');

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

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


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

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

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

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

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

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

  @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.integrity')
  @DocsEditable()
  @Experimental() // untriaged
  String get integrity => _blink.BlinkHTMLIFrameElement.instance.integrity_Getter_(unwrap_jso(this));
  
  @DomName('HTMLIFrameElement.integrity')
  @DocsEditable()
  @Experimental() // untriaged
  set integrity(String value) => _blink.BlinkHTMLIFrameElement.instance.integrity_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()
  String get sandbox => _blink.BlinkHTMLIFrameElement.instance.sandbox_Getter_(unwrap_jso(this));
  
  @DomName('HTMLIFrameElement.sandbox')
  @DocsEditable()
  set sandbox(String value) => _blink.BlinkHTMLIFrameElement.instance.sandbox_Setter_(unwrap_jso(this), value);
  
  @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_width, int height_OR_width, [int height]) {
    if ((height_OR_width is int || height_OR_width == null) && (data_OR_width is int || data_OR_width == null) && height == null) {
      return wrap_jso(_blink.BlinkImageData.instance.constructorCallback_2_(data_OR_width, height_OR_width));
    }
    if ((height is int || height == null) && (height_OR_width is int || height_OR_width == null) && (data_OR_width is Uint8ClampedList || data_OR_width == null)) {
      return wrap_jso(_blink.BlinkImageData.instance.constructorCallback_3_(data_OR_width, height_OR_width, height));
    }
    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 => _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();
  }

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

  @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.integrity')
  @DocsEditable()
  @Experimental() // untriaged
  String get integrity => _blink.BlinkHTMLImageElement.instance.integrity_Getter_(unwrap_jso(this));
  
  @DomName('HTMLImageElement.integrity')
  @DocsEditable()
  @Experimental() // untriaged
  set integrity(String value) => _blink.BlinkHTMLImageElement.instance.integrity_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.


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

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

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

// WARNING: Do not edit - generated code.


@DocsEditable()
@DomName('InputMethodContext')
// http://www.w3.org/TR/ime-api/#idl-def-InputMethodContext
@Experimental()
class InputMethodContext extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory InputMethodContext._() { throw new UnsupportedError("Not supported"); }


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

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

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


  @DomName('InputMethodContext.compositionEndOffset')
  @DocsEditable()
  @Experimental() // untriaged
  int get compositionEndOffset => _blink.BlinkInputMethodContext.instance.compositionEndOffset_Getter_(unwrap_jso(this));
  
  @DomName('InputMethodContext.compositionStartOffset')
  @DocsEditable()
  @Experimental() // untriaged
  int get compositionStartOffset => _blink.BlinkInputMethodContext.instance.compositionStartOffset_Getter_(unwrap_jso(this));
  
  @DomName('InputMethodContext.locale')
  @DocsEditable()
  String get locale => _blink.BlinkInputMethodContext.instance.locale_Getter_(unwrap_jso(this));
  
  @DomName('InputMethodContext.target')
  @DocsEditable()
  @Experimental() // untriaged
  HtmlElement get target => wrap_jso(_blink.BlinkInputMethodContext.instance.target_Getter_(unwrap_jso(this)));
  
  @DomName('InputMethodContext.confirmComposition')
  @DocsEditable()
  void confirmComposition() => _blink.BlinkInputMethodContext.instance.confirmComposition_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('InstallEvent')
@Experimental() // untriaged
class InstallEvent extends ExtendableEvent {
  // To suppress missing implicit constructor warnings.
  factory InstallEvent._() { throw new UnsupportedError("Not supported"); }


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

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

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


  @DomName('InstallEvent.reloadAll')
  @DocsEditable()
  @Experimental() // untriaged
  Future reloadAll() => wrap_jso(_blink.BlinkInstallEvent.instance.reloadAll_Callback_0_(unwrap_jso(this)));
  
  @DomName('InstallEvent.replace')
  @DocsEditable()
  @Experimental() // untriaged
  void replace() => _blink.BlinkInstallEvent.instance.replace_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.


@DomName('KeyboardEvent')
class KeyboardEvent extends UIEvent {

  factory KeyboardEvent(String type,
      {Window view, bool canBubble: true, bool cancelable: true,
      int keyLocation: 1, bool ctrlKey: false,
      bool altKey: false, bool shiftKey: false, bool metaKey: false}) {
    if (view == null) {
      view = window;
    }
    final e = document._createEvent("KeyboardEvent");
    e._initKeyboardEvent(type, canBubble, cancelable, view, "",
        keyLocation, ctrlKey, altKey, shiftKey, metaKey);
    return e;
  }

  @DomName('KeyboardEvent.keyCode')
  int get keyCode => _keyCode;

  @DomName('KeyboardEvent.charCode')
  int get charCode => _charCode;
  // To suppress missing implicit constructor warnings.
  factory KeyboardEvent._() { throw new UnsupportedError("Not supported"); }


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

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

  @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.ctrlKey')
  @DocsEditable()
  bool get ctrlKey => _blink.BlinkKeyboardEvent.instance.ctrlKey_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 keyArgument) => _blink.BlinkKeyboardEvent.instance.getModifierState_Callback_1_(unwrap_jso(this), keyArgument);
  
  @DomName('KeyboardEvent.initKeyboardEvent')
  @DocsEditable()
  void _initKeyboardEvent(String type, bool canBubble, bool cancelable, Window view, String keyIdentifier, int location, bool ctrlKey, bool altKey, bool shiftKey, bool metaKey) => _blink.BlinkKeyboardEvent.instance.initKeyboardEvent_Callback_10_(unwrap_jso(this), type, canBubble, 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('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();
  }

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

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

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

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

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

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

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

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

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

  @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) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.


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

  @DomName('LocalCredential.LocalCredential')
  @DocsEditable()
  factory LocalCredential(String id, String name, String avatarURL, String password) {
    return wrap_jso(_blink.BlinkLocalCredential.instance.constructorCallback_4_(id, name, avatarURL, password));
  }


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

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

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


  @DomName('LocalCredential.password')
  @DocsEditable()
  @Experimental() // untriaged
  String get password => _blink.BlinkLocalCredential.instance.password_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('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.


@DomName('MIDIErrorCallback')
// http://webaudio.github.io/web-midi-api/#midierrorcallback
@Experimental()
typedef void MidiErrorCallback(DomError error);
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.


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

// WARNING: Do not edit - generated code.


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

  @DomName('HTMLMapElement.HTMLMapElement')
  @DocsEditable()
  factory MapElement() => document.createElement("map");


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

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

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

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

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


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

// WARNING: Do not edit - generated code.


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

  /**
   * Static factory designed to expose `keyadded` events to event
   * handlers that are not necessarily instances of [MediaElement].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('HTMLMediaElement.webkitkeyaddedEvent')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  // https://dvcs.w3.org/hg/html-media/raw-file/eme-v0.1/encrypted-media/encrypted-media.html#dom-keyadded
  static const EventStreamProvider<MediaKeyEvent> keyAddedEvent = const EventStreamProvider<MediaKeyEvent>('webkitkeyadded');

  /**
   * Static factory designed to expose `keyerror` events to event
   * handlers that are not necessarily instances of [MediaElement].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('HTMLMediaElement.webkitkeyerrorEvent')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  // https://dvcs.w3.org/hg/html-media/raw-file/eme-v0.1/encrypted-media/encrypted-media.html#dom-keyadded
  static const EventStreamProvider<MediaKeyEvent> keyErrorEvent = const EventStreamProvider<MediaKeyEvent>('webkitkeyerror');

  /**
   * Static factory designed to expose `keymessage` events to event
   * handlers that are not necessarily instances of [MediaElement].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('HTMLMediaElement.webkitkeymessageEvent')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  // https://dvcs.w3.org/hg/html-media/raw-file/eme-v0.1/encrypted-media/encrypted-media.html#dom-keyadded
  static const EventStreamProvider<MediaKeyEvent> keyMessageEvent = const EventStreamProvider<MediaKeyEvent>('webkitkeymessage');

  /**
   * Static factory designed to expose `needkey` events to event
   * handlers that are not necessarily instances of [MediaElement].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('HTMLMediaElement.webkitneedkeyEvent')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  // https://dvcs.w3.org/hg/html-media/raw-file/eme-v0.1/encrypted-media/encrypted-media.html#dom-keyadded
  static const EventStreamProvider<MediaKeyEvent> needKeyEvent = const EventStreamProvider<MediaKeyEvent>('webkitneedkey');


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

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

  @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.integrity')
  @DocsEditable()
  @Experimental() // untriaged
  String get integrity => _blink.BlinkHTMLMediaElement.instance.integrity_Getter_(unwrap_jso(this));
  
  @DomName('HTMLMediaElement.integrity')
  @DocsEditable()
  @Experimental() // untriaged
  set integrity(String value) => _blink.BlinkHTMLMediaElement.instance.integrity_Setter_(unwrap_jso(this), value);
  
  @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.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 (keySystem != null) {
      return _blink.BlinkHTMLMediaElement.instance.canPlayType_Callback_2_(unwrap_jso(this), type, keySystem);
    }
    return _blink.BlinkHTMLMediaElement.instance.canPlayType_Callback_1_(unwrap_jso(this), type);
  }

  @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)));
  
  void addKey(String keySystem, Uint8List key, [Uint8List initData, String sessionId]) {
    if (initData != null) {
      _blink.BlinkHTMLMediaElement.instance.webkitAddKey_Callback_4_(unwrap_jso(this), keySystem, key, initData, sessionId);
      return;
    }
    _blink.BlinkHTMLMediaElement.instance.webkitAddKey_Callback_2_(unwrap_jso(this), keySystem, key);
    return;
  }

  @DomName('HTMLMediaElement.webkitCancelKeyRequest')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  // https://dvcs.w3.org/hg/html-media/raw-file/eme-v0.1/encrypted-media/encrypted-media.html#extensions
  void cancelKeyRequest(String keySystem, String sessionId) => _blink.BlinkHTMLMediaElement.instance.webkitCancelKeyRequest_Callback_2_(unwrap_jso(this), keySystem, sessionId);
  
  void generateKeyRequest(String keySystem, [Uint8List initData]) {
    if (initData != null) {
      _blink.BlinkHTMLMediaElement.instance.webkitGenerateKeyRequest_Callback_2_(unwrap_jso(this), keySystem, 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('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_ENCRYPTED')
  @DocsEditable()
  // https://dvcs.w3.org/hg/html-media/raw-file/eme-v0.1/encrypted-media/encrypted-media.html#error-codes
  @Experimental()
  static const int MEDIA_ERR_ENCRYPTED = 5;

  @DomName('MediaError.MEDIA_ERR_NETWORK')
  @DocsEditable()
  static const int MEDIA_ERR_NETWORK = 2;

  @DomName('MediaError.MEDIA_ERR_SRC_NOT_SUPPORTED')
  @DocsEditable()
  static const int MEDIA_ERR_SRC_NOT_SUPPORTED = 4;

  @DomName('MediaError.code')
  @DocsEditable()
  int get code => _blink.BlinkMediaError.instance.code_Getter_(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"); }


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

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

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


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

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

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


  @DomName('MediaKeyMessageEvent.destinationURL')
  @DocsEditable()
  String get destinationUrl => _blink.BlinkMediaKeyMessageEvent.instance.destinationURL_Getter_(unwrap_jso(this));
  
  @DomName('MediaKeyMessageEvent.message')
  @DocsEditable()
  ByteBuffer get message => _blink.BlinkMediaKeyMessageEvent.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('MediaKeyNeededEvent')
// https://dvcs.w3.org/hg/html-media/raw-file/eme-v0.1/encrypted-media/encrypted-media.html#dom-mediakeyneededevent
@Experimental()
class MediaKeyNeededEvent extends Event {
  // To suppress missing implicit constructor warnings.
  factory MediaKeyNeededEvent._() { throw new UnsupportedError("Not supported"); }


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

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

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


  @DomName('MediaKeyNeededEvent.contentType')
  @DocsEditable()
  @Experimental() // untriaged
  String get contentType => _blink.BlinkMediaKeyNeededEvent.instance.contentType_Getter_(unwrap_jso(this));
  
  @DomName('MediaKeyNeededEvent.initData')
  @DocsEditable()
  Uint8List get initData => _blink.BlinkMediaKeyNeededEvent.instance.initData_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();
  }

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

  @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.error')
  @DocsEditable()
  MediaKeyError get error => wrap_jso(_blink.BlinkMediaKeySession.instance.error_Getter_(unwrap_jso(this)));
  
  @DomName('MediaKeySession.keySystem')
  @DocsEditable()
  String get keySystem => _blink.BlinkMediaKeySession.instance.keySystem_Getter_(unwrap_jso(this));
  
  @DomName('MediaKeySession.sessionId')
  @DocsEditable()
  String get sessionId => _blink.BlinkMediaKeySession.instance.sessionId_Getter_(unwrap_jso(this));
  
  Future generateRequest(String initDataType, initData) {
    if ((initData is TypedData) && (initDataType is String)) {
      return wrap_jso(_blink.BlinkMediaKeySession.instance.generateRequest_Callback_2_(unwrap_jso(this), initDataType, unwrap_jso(initData)));
    }
    if ((initData is ByteBuffer) && (initDataType is String)) {
      return wrap_jso(_blink.BlinkMediaKeySession.instance.generateRequest_Callback_2_(unwrap_jso(this), initDataType, unwrap_jso(initData)));
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }

  @DomName('MediaKeySession.release')
  @DocsEditable()
  @Experimental() // untriaged
  Future release() => wrap_jso(_blink.BlinkMediaKeySession.instance.release_Callback_0_(unwrap_jso(this)));
  
  Future _update(response) {
    if ((response is TypedData)) {
      return wrap_jso(_blink.BlinkMediaKeySession.instance.update_Callback_1_(unwrap_jso(this), unwrap_jso(response)));
    }
    if ((response is ByteBuffer)) {
      return wrap_jso(_blink.BlinkMediaKeySession.instance.update_Callback_1_(unwrap_jso(this), unwrap_jso(response)));
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }

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

// WARNING: Do not edit - generated code.


@DocsEditable()
@DomName('MediaKeys')
// https://dvcs.w3.org/hg/html-media/raw-file/eme-v0.1/encrypted-media/encrypted-media.html
@Experimental()
class MediaKeys extends 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;

  @DomName('MediaKeys.keySystem')
  @DocsEditable()
  String get keySystem => _blink.BlinkMediaKeys.instance.keySystem_Getter_(unwrap_jso(this));
  
  @DomName('MediaKeys.create')
  @DocsEditable()
  @Experimental() // untriaged
  static Future create(String keySystem) => wrap_jso(_blink.BlinkMediaKeys.instance.create_Callback_1_(keySystem));
  
  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.isTypeSupported')
  @DocsEditable()
  @Experimental() // untriaged
  static bool isTypeSupported(String keySystem, String contentType) => _blink.BlinkMediaKeys.instance.isTypeSupported_Callback_2_(keySystem, contentType);
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.


@DocsEditable()
@DomName('MediaList')
@Unstable()
class MediaList extends 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 newMedium) => _blink.BlinkMediaList.instance.appendMedium_Callback_1_(unwrap_jso(this), newMedium);
  
  @DomName('MediaList.deleteMedium')
  @DocsEditable()
  void deleteMedium(String oldMedium) => _blink.BlinkMediaList.instance.deleteMedium_Callback_1_(unwrap_jso(this), oldMedium);
  
  @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();
  }

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

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


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

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

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

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

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

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

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


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


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

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

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

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

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

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

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

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

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

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

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


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

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

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


  @DomName('MessageEvent.data')
  @DocsEditable()
  Object get data => wrap_jso(_blink.BlinkMessageEvent.instance.data_Getter_(unwrap_jso(this)));
  
  @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> messagePorts) => _blink.BlinkMessageEvent.instance.initMessageEvent_Callback_8_(unwrap_jso(this), typeArg, canBubbleArg, cancelableArg, dataArg, originArg, lastEventIdArg, unwrap_jso(sourceArg), unwrap_jso(messagePorts));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.


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

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


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

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

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


  @DomName('MessagePort.close')
  @DocsEditable()
  void close() => _blink.BlinkMessagePort.instance.close_Callback_0_(unwrap_jso(this));
  
  @DomName('MessagePort.postMessage')
  @DocsEditable()
  void postMessage(Object message, [List<MessagePort> transfer]) => _blink.BlinkMessagePort.instance.postMessage_Callback_2_(unwrap_jso(this), convertDartToNative_SerializedScriptValue(message), transfer);
  
  @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();
  }

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

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

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

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

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

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


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

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

  @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));
  
  /// Stream of `connect` events handled by this [MidiAccess].
  @DomName('MIDIAccess.onconnect')
  @DocsEditable()
  Stream<MidiConnectionEvent> get onConnect => connectEvent.forTarget(this);

  /// Stream of `disconnect` events handled by this [MidiAccess].
  @DomName('MIDIAccess.ondisconnect')
  @DocsEditable()
  Stream<MidiConnectionEvent> get onDisconnect => disconnectEvent.forTarget(this);

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

// WARNING: Do not edit - generated code.


@DocsEditable()
@DomName('MIDIConnectionEvent')
// http://webaudio.github.io/web-midi-api/#midiconnectionevent-interface
@Experimental()
class MidiConnectionEvent extends Event {
  // To suppress missing implicit constructor warnings.
  factory MidiConnectionEvent._() { throw new UnsupportedError("Not supported"); }


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

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

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

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

  @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));
  
  @DomName('MIDIInputMap.entries')
  @DocsEditable()
  @Experimental() // untriaged
  DomIterator entries() => wrap_jso(_blink.BlinkMIDIInputMap.instance.entries_Callback_0_(unwrap_jso(this)));
  
  @DomName('MIDIInputMap.get')
  @DocsEditable()
  @Experimental() // untriaged
  Object get(String id) => wrap_jso(_blink.BlinkMIDIInputMap.instance.get_Callback_1_(unwrap_jso(this), id));
  
  @DomName('MIDIInputMap.has')
  @DocsEditable()
  @Experimental() // untriaged
  bool has(String key) => _blink.BlinkMIDIInputMap.instance.has_Callback_1_(unwrap_jso(this), key);
  
  @DomName('MIDIInputMap.keys')
  @DocsEditable()
  @Experimental() // untriaged
  DomIterator keys() => wrap_jso(_blink.BlinkMIDIInputMap.instance.keys_Callback_0_(unwrap_jso(this)));
  
  @DomName('MIDIInputMap.values')
  @DocsEditable()
  @Experimental() // untriaged
  DomIterator values() => wrap_jso(_blink.BlinkMIDIInputMap.instance.values_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('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"); }


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

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

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


  @DomName('MIDIMessageEvent.data')
  @DocsEditable()
  Uint8List get data => _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();
  }

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

  @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), data, timestamp);
      return;
    }
    _blink.BlinkMIDIOutput.instance.send_Callback_1_(unwrap_jso(this), data);
    return;
  }

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

// WARNING: Do not edit - generated code.


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

  @Deprecated("Internal Use Only")
  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));
  
  @DomName('MIDIOutputMap.entries')
  @DocsEditable()
  @Experimental() // untriaged
  DomIterator entries() => wrap_jso(_blink.BlinkMIDIOutputMap.instance.entries_Callback_0_(unwrap_jso(this)));
  
  @DomName('MIDIOutputMap.get')
  @DocsEditable()
  @Experimental() // untriaged
  Object get(String id) => wrap_jso(_blink.BlinkMIDIOutputMap.instance.get_Callback_1_(unwrap_jso(this), id));
  
  @DomName('MIDIOutputMap.has')
  @DocsEditable()
  @Experimental() // untriaged
  bool has(String key) => _blink.BlinkMIDIOutputMap.instance.has_Callback_1_(unwrap_jso(this), key);
  
  @DomName('MIDIOutputMap.keys')
  @DocsEditable()
  @Experimental() // untriaged
  DomIterator keys() => wrap_jso(_blink.BlinkMIDIOutputMap.instance.keys_Callback_0_(unwrap_jso(this)));
  
  @DomName('MIDIOutputMap.values')
  @DocsEditable()
  @Experimental() // untriaged
  DomIterator values() => wrap_jso(_blink.BlinkMIDIOutputMap.instance.values_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('MIDIPort')
// http://webaudio.github.io/web-midi-api/#idl-def-MIDIPort
@Experimental()
class MidiPort extends EventTarget {
  // To suppress missing implicit constructor warnings.
  factory MidiPort._() { throw new UnsupportedError("Not supported"); }

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


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

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

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


  @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.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));
  
  /// Stream of `disconnect` events handled by this [MidiPort].
  @DomName('MIDIPort.ondisconnect')
  @DocsEditable()
  Stream<MidiConnectionEvent> get onDisconnect => disconnectEvent.forTarget(this);

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

// WARNING: Do not edit - generated code.


@DocsEditable()
@DomName('MimeType')
@Experimental() // non-standard
class MimeType extends 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.__getter__')
  @DocsEditable()
  MimeType __getter__(String name) => wrap_jso(_blink.BlinkMimeTypeArray.instance.$__getter___Callback_1_(unwrap_jso(this), name));
  
  @DomName('MimeTypeArray.item')
  @DocsEditable()
  MimeType item(int index) => wrap_jso(_blink.BlinkMimeTypeArray.instance.item_Callback_1_(unwrap_jso(this), index));
  
  @DomName('MimeTypeArray.namedItem')
  @DocsEditable()
  MimeType namedItem(String name) => wrap_jso(_blink.BlinkMimeTypeArray.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('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();
  }

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

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


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

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

  @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.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.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.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.initMouseEvent')
  @DocsEditable()
  void _initMouseEvent(String type, bool canBubble, bool cancelable, Window view, int detail, int screenX, int screenY, int clientX, int clientY, bool ctrlKey, bool altKey, bool shiftKey, bool metaKey, int button, EventTarget relatedTarget) => _blink.BlinkMouseEvent.instance.initMouseEvent_Callback_15_(unwrap_jso(this), type, canBubble, 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);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of 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 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.connection')
  @DocsEditable()
  @Experimental() // untriaged
  NetworkInformation get connection => wrap_jso(_blink.BlinkNavigator.instance.connection_Getter_(unwrap_jso(this)));
  
  @DomName('Navigator.cookieEnabled')
  @DocsEditable()
  @Unstable()
  bool get cookieEnabled => _blink.BlinkNavigator.instance.cookieEnabled_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.geofencing')
  @DocsEditable()
  @Experimental() // untriaged
  Geofencing get geofencing => wrap_jso(_blink.BlinkNavigator.instance.geofencing_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.mimeTypes')
  @DocsEditable()
  @Experimental() // nonstandard
  MimeTypeArray get mimeTypes => wrap_jso(_blink.BlinkNavigator.instance.mimeTypes_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.push')
  @DocsEditable()
  @Experimental() // untriaged
  PushManager get push => wrap_jso(_blink.BlinkNavigator.instance.push_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.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.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));
  
  @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);
  
  bool sendBeacon(String url, data) {
    if ((data is String || data == null) && (url is String || url == null)) {
      return _blink.BlinkNavigator.instance.sendBeacon_Callback_2_(unwrap_jso(this), url, unwrap_jso(data));
    }
    if ((data is TypedData || data == null) && (url is String || url == null)) {
      return _blink.BlinkNavigator.instance.sendBeacon_Callback_2_(unwrap_jso(this), url, unwrap_jso(data));
    }
    if ((data is FormData || data == null) && (url is String || url == null)) {
      return _blink.BlinkNavigator.instance.sendBeacon_Callback_2_(unwrap_jso(this), url, unwrap_jso(data));
    }
    if ((data is Blob || data == null) && (url is String || url == null)) {
      return _blink.BlinkNavigator.instance.sendBeacon_Callback_2_(unwrap_jso(this), url, unwrap_jso(data));
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }

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

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

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

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

  @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 newChild) => wrap_jso(_blink.BlinkNode.instance.appendChild_Callback_1_(unwrap_jso(this), unwrap_jso(newChild)));
  
  /**
   * Returns a copy of this node.
   *
   * If [deep] is `true`, then all of this node's children and decendents are
   * copied as well. If [deep] is `false`, then only this node is copied.
   *
   * ## Other resources
   *
   * * [Node.cloneNode]
   * (https://developer.mozilla.org/en-US/docs/Web/API/Node.cloneNode) from
   * MDN.
   */
  @DomName('Node.cloneNode')
  @DocsEditable()
  Node clone(bool deep) => 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 newChild, Node refChild) => wrap_jso(_blink.BlinkNode.instance.insertBefore_Callback_2_(unwrap_jso(this), unwrap_jso(newChild), unwrap_jso(refChild)));
  
  @DomName('Node.removeChild')
  @DocsEditable()
  Node _removeChild(Node oldChild) => wrap_jso(_blink.BlinkNode.instance.removeChild_Callback_1_(unwrap_jso(this), unwrap_jso(oldChild)));
  
  @DomName('Node.replaceChild')
  @DocsEditable()
  Node _replaceChild(Node newChild, Node oldChild) => wrap_jso(_blink.BlinkNode.instance.replaceChild_Callback_2_(unwrap_jso(this), unwrap_jso(newChild), unwrap_jso(oldChild)));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.


@DocsEditable()
@DomName('NodeFilter')
@Unstable()
class NodeFilter extends 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 = 0x00000080;

  @DomName('NodeFilter.SHOW_DOCUMENT')
  @DocsEditable()
  static const int SHOW_DOCUMENT = 0x00000100;

  @DomName('NodeFilter.SHOW_DOCUMENT_FRAGMENT')
  @DocsEditable()
  static const int SHOW_DOCUMENT_FRAGMENT = 0x00000400;

  @DomName('NodeFilter.SHOW_DOCUMENT_TYPE')
  @DocsEditable()
  static const int SHOW_DOCUMENT_TYPE = 0x00000200;

  @DomName('NodeFilter.SHOW_ELEMENT')
  @DocsEditable()
  static const int SHOW_ELEMENT = 0x00000001;

  @DomName('NodeFilter.SHOW_PROCESSING_INSTRUCTION')
  @DocsEditable()
  static const int SHOW_PROCESSING_INSTRUCTION = 0x00000040;

  @DomName('NodeFilter.SHOW_TEXT')
  @DocsEditable()
  static const int SHOW_TEXT = 0x00000004;

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


@DomName('NodeIterator')
@Unstable()
class NodeIterator extends 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) 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();
  }

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

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


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

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

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

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

  @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.integrity')
  @DocsEditable()
  @Experimental() // untriaged
  String get integrity => _blink.BlinkHTMLObjectElement.instance.integrity_Getter_(unwrap_jso(this));
  
  @DomName('HTMLObjectElement.integrity')
  @DocsEditable()
  @Experimental() // untriaged
  set integrity(String value) => _blink.BlinkHTMLObjectElement.instance.integrity_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.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();
  }

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

  @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]) {
    return wrap_jso(_blink.BlinkHTMLOptionElement.instance.constructorCallback_4_(data, value, defaultSelected, selected));
  }


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

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

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

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

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


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

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

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


  @DomName('OverflowEvent.BOTH')
  @DocsEditable()
  static const int BOTH = 2;

  @DomName('OverflowEvent.HORIZONTAL')
  @DocsEditable()
  static const int HORIZONTAL = 0;

  @DomName('OverflowEvent.VERTICAL')
  @DocsEditable()
  static const int VERTICAL = 1;

  @DomName('OverflowEvent.horizontalOverflow')
  @DocsEditable()
  bool get horizontalOverflow => _blink.BlinkOverflowEvent.instance.horizontalOverflow_Getter_(unwrap_jso(this));
  
  @DomName('OverflowEvent.orient')
  @DocsEditable()
  int get orient => _blink.BlinkOverflowEvent.instance.orient_Getter_(unwrap_jso(this));
  
  @DomName('OverflowEvent.verticalOverflow')
  @DocsEditable()
  bool get verticalOverflow => _blink.BlinkOverflowEvent.instance.verticalOverflow_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('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"); }


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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  @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.__getter__')
  @DocsEditable()
  MimeType __getter__(String name) => wrap_jso(_blink.BlinkPlugin.instance.$__getter___Callback_1_(unwrap_jso(this), name));
  
  @DomName('Plugin.item')
  @DocsEditable()
  MimeType item(int index) => wrap_jso(_blink.BlinkPlugin.instance.item_Callback_1_(unwrap_jso(this), index));
  
  @DomName('Plugin.namedItem')
  @DocsEditable()
  MimeType namedItem(String name) => wrap_jso(_blink.BlinkPlugin.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('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.__getter__')
  @DocsEditable()
  Plugin __getter__(String name) => wrap_jso(_blink.BlinkPluginArray.instance.$__getter___Callback_1_(unwrap_jso(this), name));
  
  @DomName('PluginArray.item')
  @DocsEditable()
  Plugin item(int index) => wrap_jso(_blink.BlinkPluginArray.instance.item_Callback_1_(unwrap_jso(this), index));
  
  @DomName('PluginArray.namedItem')
  @DocsEditable()
  Plugin namedItem(String name) => wrap_jso(_blink.BlinkPluginArray.instance.namedItem_Callback_1_(unwrap_jso(this), name));
  
  @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();
  }

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

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


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

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

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

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

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

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

  @Deprecated("Internal Use Only")
  Presentation.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('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();
  }

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

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

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

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


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

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

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


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

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

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


  @DomName('PushEvent.data')
  @DocsEditable()
  @Experimental() // untriaged
  String get data => _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.register')
  @DocsEditable()
  @Experimental() // untriaged
  Future register(String senderId) => wrap_jso(_blink.BlinkPushManager.instance.register_Callback_1_(unwrap_jso(this), senderId));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.


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

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

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

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

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

  @DomName('PushRegistration.pushEndpoint')
  @DocsEditable()
  @Experimental() // untriaged
  String get pushEndpoint => _blink.BlinkPushRegistration.instance.pushEndpoint_Getter_(unwrap_jso(this));
  
  @DomName('PushRegistration.pushRegistrationId')
  @DocsEditable()
  @Experimental() // untriaged
  String get pushRegistrationId => _blink.BlinkPushRegistration.instance.pushRegistrationId_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('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();
  }

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

  @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.NODE_AFTER')
  @DocsEditable()
  @Experimental() // nonstandard
  static const int NODE_AFTER = 1;

  @DomName('Range.NODE_BEFORE')
  @DocsEditable()
  @Experimental() // nonstandard
  static const int NODE_BEFORE = 0;

  @DomName('Range.NODE_BEFORE_AND_AFTER')
  @DocsEditable()
  @Experimental() // nonstandard
  static const int NODE_BEFORE_AND_AFTER = 2;

  @DomName('Range.NODE_INSIDE')
  @DocsEditable()
  @Experimental() // nonstandard
  static const int NODE_INSIDE = 3;

  @DomName('Range.START_TO_END')
  @DocsEditable()
  static const int START_TO_END = 1;

  @DomName('Range.START_TO_START')
  @DocsEditable()
  static const int START_TO_START = 0;

  @DomName('Range.collapsed')
  @DocsEditable()
  bool get collapsed => _blink.BlinkRange.instance.collapsed_Getter_(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 refNode, int offset) => _blink.BlinkRange.instance.comparePoint_Callback_2_(unwrap_jso(this), unwrap_jso(refNode), offset);
  
  @DomName('Range.createContextualFragment')
  @DocsEditable()
  DocumentFragment createContextualFragment(String html) => wrap_jso(_blink.BlinkRange.instance.createContextualFragment_Callback_1_(unwrap_jso(this), html));
  
  @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 newNode) => _blink.BlinkRange.instance.insertNode_Callback_1_(unwrap_jso(this), unwrap_jso(newNode));
  
  @DomName('Range.isPointInRange')
  @DocsEditable()
  bool isPointInRange(Node refNode, int offset) => _blink.BlinkRange.instance.isPointInRange_Callback_2_(unwrap_jso(this), unwrap_jso(refNode), offset);
  
  @DomName('Range.selectNode')
  @DocsEditable()
  void selectNode(Node refNode) => _blink.BlinkRange.instance.selectNode_Callback_1_(unwrap_jso(this), unwrap_jso(refNode));
  
  @DomName('Range.selectNodeContents')
  @DocsEditable()
  void selectNodeContents(Node refNode) => _blink.BlinkRange.instance.selectNodeContents_Callback_1_(unwrap_jso(this), unwrap_jso(refNode));
  
  @DomName('Range.setEnd')
  @DocsEditable()
  void setEnd(Node refNode, int offset) => _blink.BlinkRange.instance.setEnd_Callback_2_(unwrap_jso(this), unwrap_jso(refNode), offset);
  
  @DomName('Range.setEndAfter')
  @DocsEditable()
  void setEndAfter(Node refNode) => _blink.BlinkRange.instance.setEndAfter_Callback_1_(unwrap_jso(this), unwrap_jso(refNode));
  
  @DomName('Range.setEndBefore')
  @DocsEditable()
  void setEndBefore(Node refNode) => _blink.BlinkRange.instance.setEndBefore_Callback_1_(unwrap_jso(this), unwrap_jso(refNode));
  
  @DomName('Range.setStart')
  @DocsEditable()
  void setStart(Node refNode, int offset) => _blink.BlinkRange.instance.setStart_Callback_2_(unwrap_jso(this), unwrap_jso(refNode), offset);
  
  @DomName('Range.setStartAfter')
  @DocsEditable()
  void setStartAfter(Node refNode) => _blink.BlinkRange.instance.setStartAfter_Callback_1_(unwrap_jso(this), unwrap_jso(refNode));
  
  @DomName('Range.setStartBefore')
  @DocsEditable()
  void setStartBefore(Node refNode) => _blink.BlinkRange.instance.setStartBefore_Callback_1_(unwrap_jso(this), unwrap_jso(refNode));
  
  @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('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;

  @DomName('ReadableStream.closed')
  @DocsEditable()
  @Experimental() // untriaged
  Future get closed => wrap_jso(_blink.BlinkReadableStream.instance.closed_Getter_(unwrap_jso(this)));
  
  @DomName('ReadableStream.state')
  @DocsEditable()
  @Experimental() // untriaged
  String get state => _blink.BlinkReadableStream.instance.state_Getter_(unwrap_jso(this));
  
  @DomName('ReadableStream.cancel')
  @DocsEditable()
  @Experimental() // untriaged
  Future cancel(Object reason) => wrap_jso(_blink.BlinkReadableStream.instance.cancel_Callback_1_(unwrap_jso(this), reason));
  
  @DomName('ReadableStream.read')
  @DocsEditable()
  @Experimental() // untriaged
  Object read() => wrap_jso(_blink.BlinkReadableStream.instance.read_Callback_0_(unwrap_jso(this)));
  
  @DomName('ReadableStream.wait')
  @DocsEditable()
  @Experimental() // untriaged
  Future wait() => wrap_jso(_blink.BlinkReadableStream.instance.wait_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"); }


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

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

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

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

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

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

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

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

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

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

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


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

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

  @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 dictionary) {
    var dictionary_1 = convertDartToNative_Dictionary(dictionary);
    return wrap_jso(_blink.BlinkRTCIceCandidate.instance.constructorCallback_1_(dictionary_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();
  }

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

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

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

  @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.local')
  @DocsEditable()
  RtcStatsReport get local => wrap_jso(_blink.BlinkRTCStatsReport.instance.local_Getter_(unwrap_jso(this)));
  
  @DomName('RTCStatsReport.remote')
  @DocsEditable()
  RtcStatsReport get remote => wrap_jso(_blink.BlinkRTCStatsReport.instance.remote_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;

  @DomName('RTCStatsResponse.__getter__')
  @DocsEditable()
  RtcStatsReport __getter__(String name) => wrap_jso(_blink.BlinkRTCStatsResponse.instance.$__getter___Callback_1_(unwrap_jso(this), name));
  
  @DomName('RTCStatsResponse.namedItem')
  @DocsEditable()
  RtcStatsReport namedItem(String name) => wrap_jso(_blink.BlinkRTCStatsResponse.instance.namedItem_Callback_1_(unwrap_jso(this), name));
  
  @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();
  }

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

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

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

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


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

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

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

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

  @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 value) => _blink.BlinkHTMLSelectElement.instance.$__setter___Callback_2_(unwrap_jso(this), index, unwrap_jso(value));
  
  @DomName('HTMLSelectElement.add')
  @DocsEditable()
  @Experimental() // untriaged
  void add(HtmlElement element, int before) => _blink.BlinkHTMLSelectElement.instance.add_Callback_2_(unwrap_jso(this), unwrap_jso(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()
  Element namedItem(String name) => wrap_jso(_blink.BlinkHTMLSelectElement.instance.namedItem_Callback_1_(unwrap_jso(this), name));
  
  @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 allowPartial) => _blink.BlinkSelection.instance.containsNode_Callback_2_(unwrap_jso(this), unwrap_jso(node), allowPartial);
  
  @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('ServiceWorkerClient')
@Experimental() // untriaged
class ServiceWorkerClient extends DartHtmlDomObject {
  // To suppress missing implicit constructor warnings.
  factory ServiceWorkerClient._() { throw new UnsupportedError("Not supported"); }

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

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

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

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

  @DomName('ServiceWorkerClient.id')
  @DocsEditable()
  @Experimental() // untriaged
  int get id => _blink.BlinkServiceWorkerClient.instance.id_Getter_(unwrap_jso(this));
  
  @DomName('ServiceWorkerClient.postMessage')
  @DocsEditable()
  @Experimental() // untriaged
  void postMessage(/*SerializedScriptValue*/ message, [List<MessagePort> transfer]) => _blink.BlinkServiceWorkerClient.instance.postMessage_Callback_2_(unwrap_jso(this), message, transfer);
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.


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

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

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

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

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

  Future getAll([Map options]) {
    if (options != null) {
      return wrap_jso(_blink.BlinkServiceWorkerClients.instance.getAll_Callback_1_(unwrap_jso(this), convertDartToNative_Dictionary(options)));
    }
    return wrap_jso(_blink.BlinkServiceWorkerClients.instance.getAll_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('ServiceWorkerContainer')
@Experimental() // untriaged
class ServiceWorkerContainer extends DartHtmlDomObject {
  // To suppress missing implicit constructor warnings.
  factory ServiceWorkerContainer._() { throw new UnsupportedError("Not supported"); }

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

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

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

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

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

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

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

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

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


  @DomName('ServiceWorkerGlobalScope.caches')
  @DocsEditable()
  @Experimental() // untriaged
  CacheStorage get caches => wrap_jso(_blink.BlinkServiceWorkerGlobalScope.instance.caches_Getter_(unwrap_jso(this)));
  
  @DomName('ServiceWorkerGlobalScope.clients')
  @DocsEditable()
  @Experimental() // untriaged
  ServiceWorkerClients get clients => wrap_jso(_blink.BlinkServiceWorkerGlobalScope.instance.clients_Getter_(unwrap_jso(this)));
  
  @DomName('ServiceWorkerGlobalScope.scope')
  @DocsEditable()
  @Experimental() // untriaged
  String get scope => _blink.BlinkServiceWorkerGlobalScope.instance.scope_Getter_(unwrap_jso(this));
  
  @DomName('ServiceWorkerGlobalScope.close')
  @DocsEditable()
  @Experimental() // untriaged
  void close() => _blink.BlinkServiceWorkerGlobalScope.instance.close_Callback_0_(unwrap_jso(this));
  
  Future _fetch(request, [Map requestInitDict]) {
    if ((request is String || request == null) && requestInitDict == null) {
      return wrap_jso(_blink.BlinkServiceWorkerGlobalScope.instance.fetch_Callback_1_(unwrap_jso(this), unwrap_jso(request)));
    }
    if ((requestInitDict is Map || requestInitDict == null) && (request is String || request == null)) {
      return wrap_jso(_blink.BlinkServiceWorkerGlobalScope.instance.fetch_Callback_2_(unwrap_jso(this), unwrap_jso(request), convertDartToNative_Dictionary(requestInitDict)));
    }
    if ((request is _Request || request == null) && requestInitDict == null) {
      return wrap_jso(_blink.BlinkServiceWorkerGlobalScope.instance.fetch_Callback_1_(unwrap_jso(this), unwrap_jso(request)));
    }
    if ((requestInitDict is Map || requestInitDict == null) && (request is _Request || request == null)) {
      return wrap_jso(_blink.BlinkServiceWorkerGlobalScope.instance.fetch_Callback_2_(unwrap_jso(this), unwrap_jso(request), convertDartToNative_Dictionary(requestInitDict)));
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }

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

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

// WARNING: Do not edit - generated code.


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


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

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

  @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.installing')
  @DocsEditable()
  @Experimental() // untriaged
  _ServiceWorker get installing => wrap_jso(_blink.BlinkServiceWorkerRegistration.instance.installing_Getter_(unwrap_jso(this)));
  
  @DomName('ServiceWorkerRegistration.scope')
  @DocsEditable()
  @Experimental() // untriaged
  String get scope => _blink.BlinkServiceWorkerRegistration.instance.scope_Getter_(unwrap_jso(this));
  
  @DomName('ServiceWorkerRegistration.waiting')
  @DocsEditable()
  @Experimental() // untriaged
  _ServiceWorker get waiting => wrap_jso(_blink.BlinkServiceWorkerRegistration.instance.waiting_Getter_(unwrap_jso(this)));
  
  @DomName('ServiceWorkerRegistration.unregister')
  @DocsEditable()
  @Experimental() // untriaged
  Future unregister() => wrap_jso(_blink.BlinkServiceWorkerRegistration.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('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();
  }

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

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

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

  @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.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.getElementById')
  @DocsEditable()
  Element getElementById(String elementId) => wrap_jso(_blink.BlinkShadowRoot.instance.getElementById_Callback_1_(unwrap_jso(this), elementId));
  
  @DomName('ShadowRoot.getElementsByClassName')
  @DocsEditable()
  List<Node> getElementsByClassName(String className) => wrap_jso(_blink.BlinkShadowRoot.instance.getElementsByClassName_Callback_1_(unwrap_jso(this), className));
  
  @DomName('ShadowRoot.getElementsByTagName')
  @DocsEditable()
  List<Node> getElementsByTagName(String tagName) => wrap_jso(_blink.BlinkShadowRoot.instance.getElementsByTagName_Callback_1_(unwrap_jso(this), tagName));
  
  @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('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();
  }

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

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

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

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

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

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

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

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

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

  @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.integrity')
  @DocsEditable()
  @Experimental() // untriaged
  String get integrity => _blink.BlinkHTMLSourceElement.instance.integrity_Getter_(unwrap_jso(this));
  
  @DomName('HTMLSourceElement.integrity')
  @DocsEditable()
  @Experimental() // untriaged
  set integrity(String value) => _blink.BlinkHTMLSourceElement.instance.integrity_Setter_(unwrap_jso(this), value);
  
  @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();
  }

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

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

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

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


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

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

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


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

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

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

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

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

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

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

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

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


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


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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  @DomName('Timing.delay')
  @DocsEditable()
  @Experimental() // untriaged
  num get delay => _blink.BlinkTiming.instance.delay_Getter_(unwrap_jso(this));
  
  @DomName('Timing.delay')
  @DocsEditable()
  @Experimental() // untriaged
  set delay(num value) => _blink.BlinkTiming.instance.delay_Setter_(unwrap_jso(this), value);
  
  @DomName('Timing.direction')
  @DocsEditable()
  @Experimental() // untriaged
  String get direction => _blink.BlinkTiming.instance.direction_Getter_(unwrap_jso(this));
  
  @DomName('Timing.direction')
  @DocsEditable()
  @Experimental() // untriaged
  set direction(String value) => _blink.BlinkTiming.instance.direction_Setter_(unwrap_jso(this), value);
  
  @DomName('Timing.easing')
  @DocsEditable()
  @Experimental() // untriaged
  String get easing => _blink.BlinkTiming.instance.easing_Getter_(unwrap_jso(this));
  
  @DomName('Timing.easing')
  @DocsEditable()
  @Experimental() // untriaged
  set easing(String value) => _blink.BlinkTiming.instance.easing_Setter_(unwrap_jso(this), value);
  
  @DomName('Timing.endDelay')
  @DocsEditable()
  @Experimental() // untriaged
  num get endDelay => _blink.BlinkTiming.instance.endDelay_Getter_(unwrap_jso(this));
  
  @DomName('Timing.endDelay')
  @DocsEditable()
  @Experimental() // untriaged
  set endDelay(num value) => _blink.BlinkTiming.instance.endDelay_Setter_(unwrap_jso(this), value);
  
  @DomName('Timing.fill')
  @DocsEditable()
  @Experimental() // untriaged
  String get fill => _blink.BlinkTiming.instance.fill_Getter_(unwrap_jso(this));
  
  @DomName('Timing.fill')
  @DocsEditable()
  @Experimental() // untriaged
  set fill(String value) => _blink.BlinkTiming.instance.fill_Setter_(unwrap_jso(this), value);
  
  @DomName('Timing.iterationStart')
  @DocsEditable()
  @Experimental() // untriaged
  num get iterationStart => _blink.BlinkTiming.instance.iterationStart_Getter_(unwrap_jso(this));
  
  @DomName('Timing.iterationStart')
  @DocsEditable()
  @Experimental() // untriaged
  set iterationStart(num value) => _blink.BlinkTiming.instance.iterationStart_Setter_(unwrap_jso(this), value);
  
  @DomName('Timing.iterations')
  @DocsEditable()
  @Experimental() // untriaged
  num get iterations => _blink.BlinkTiming.instance.iterations_Getter_(unwrap_jso(this));
  
  @DomName('Timing.iterations')
  @DocsEditable()
  @Experimental() // untriaged
  set iterations(num value) => _blink.BlinkTiming.instance.iterations_Setter_(unwrap_jso(this), value);
  
  @DomName('Timing.playbackRate')
  @DocsEditable()
  @Experimental() // untriaged
  num get playbackRate => _blink.BlinkTiming.instance.playbackRate_Getter_(unwrap_jso(this));
  
  @DomName('Timing.playbackRate')
  @DocsEditable()
  @Experimental() // untriaged
  set playbackRate(num value) => _blink.BlinkTiming.instance.playbackRate_Setter_(unwrap_jso(this), value);
  
  @DomName('Timing.__getter__')
  @DocsEditable()
  @Experimental() // untriaged
  Object __getter__(String name) => wrap_jso(_blink.BlinkTiming.instance.$__getter___Callback_1_(unwrap_jso(this), name));
  
  @DomName('Timing.__setter__')
  @DocsEditable()
  @Experimental() // untriaged
  void __setter__(String name, num duration) => _blink.BlinkTiming.instance.$__setter___Callback_2_(unwrap_jso(this), name, duration);
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.


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

  @DomName('HTMLTitleElement.HTMLTitleElement')
  @DocsEditable()
  factory TitleElement() => document.createElement("title");


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

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

  @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.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)));
  
  @DomName('Touch.webkitRotationAngle')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  num get rotationAngle => _blink.BlinkTouch.instance.webkitRotationAngle_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();
  }

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

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

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

  @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.integrity')
  @DocsEditable()
  @Experimental() // untriaged
  String get integrity => _blink.BlinkHTMLTrackElement.instance.integrity_Getter_(unwrap_jso(this));
  
  @DomName('HTMLTrackElement.integrity')
  @DocsEditable()
  @Experimental() // untriaged
  set integrity(String value) => _blink.BlinkHTMLTrackElement.instance.integrity_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"); }


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

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

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


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

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

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


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

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

  @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.layerX')
  @DocsEditable()
  // http://dev.w3.org/2006/webapi/DOM-Level-3-Events/html/DOM3-Events.html#events-mouseevents
  @Experimental() // nonstandard
  int get _layerX => _blink.BlinkUIEvent.instance.layerX_Getter_(unwrap_jso(this));
  
  @DomName('UIEvent.layerY')
  @DocsEditable()
  // http://dev.w3.org/2006/webapi/DOM-Level-3-Events/html/DOM3-Events.html#events-mouseevents
  @Experimental() // nonstandard
  int get _layerY => _blink.BlinkUIEvent.instance.layerY_Getter_(unwrap_jso(this));
  
  @DomName('UIEvent.pageX')
  @DocsEditable()
  // http://dev.w3.org/2006/webapi/DOM-Level-3-Events/html/DOM3-Events.html#events-mouseevents
  @Experimental() // nonstandard
  int get _pageX => _blink.BlinkUIEvent.instance.pageX_Getter_(unwrap_jso(this));
  
  @DomName('UIEvent.pageY')
  @DocsEditable()
  // http://dev.w3.org/2006/webapi/DOM-Level-3-Events/html/DOM3-Events.html#events-mouseevents
  @Experimental() // nonstandard
  int get _pageY => _blink.BlinkUIEvent.instance.pageY_Getter_(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 canBubble, bool cancelable, Window view, int detail) => _blink.BlinkUIEvent.instance.initUIEvent_Callback_5_(unwrap_jso(this), type, canBubble, cancelable, unwrap_jso(view), detail);
  

  @DomName('UIEvent.layerX')
  @DomName('UIEvent.layerY')
  Point get layer => new Point(_layerX, _layerY);

  @DomName('UIEvent.pageX')
  @DomName('UIEvent.pageY')
  Point get page => new Point(_pageX, _pageY);
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.


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

  @DomName('HTMLUListElement.HTMLUListElement')
  @DocsEditable()
  factory UListElement() => document.createElement("ul");


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

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

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

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

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

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

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

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

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

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

  @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
  int get line => _blink.BlinkVTTCue.instance.line_Getter_(unwrap_jso(this));
  
  @DomName('VTTCue.line')
  @DocsEditable()
  @Experimental() // untriaged
  set line(int value) => _blink.BlinkVTTCue.instance.line_Setter_(unwrap_jso(this), value);
  
  @DomName('VTTCue.position')
  @DocsEditable()
  @Experimental() // untriaged
  int get position => _blink.BlinkVTTCue.instance.position_Getter_(unwrap_jso(this));
  
  @DomName('VTTCue.position')
  @DocsEditable()
  @Experimental() // untriaged
  set position(int value) => _blink.BlinkVTTCue.instance.position_Setter_(unwrap_jso(this), 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
  int get size => _blink.BlinkVTTCue.instance.size_Getter_(unwrap_jso(this));
  
  @DomName('VTTCue.size')
  @DocsEditable()
  @Experimental() // untriaged
  set size(int 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, [protocol_OR_protocols]) {
    if ((url is String || url == null) && protocol_OR_protocols == null) {
      return wrap_jso(_blink.BlinkWebSocket.instance.constructorCallback_1_(url));
    }
    if ((protocol_OR_protocols is String || protocol_OR_protocols == null) && (url is String || url == null)) {
      return wrap_jso(_blink.BlinkWebSocket.instance.constructorCallback_2_(url, protocol_OR_protocols));
    }
    if ((protocol_OR_protocols is List<String> || protocol_OR_protocols == null) && (url is String || url == null)) {
      List protocols_1 = convertDartToNative_StringArray(protocol_OR_protocols);
      return wrap_jso(_blink.BlinkWebSocket.instance.constructorCallback_2_(url, protocols_1));
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }


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

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

  @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 || data == null)) {
      _blink.BlinkWebSocket.instance.send_Callback_1_(unwrap_jso(this), unwrap_jso(data));
      return;
    }
    if ((data is Blob || data == null)) {
      _blink.BlinkWebSocket.instance.send_Callback_1_(unwrap_jso(this), unwrap_jso(data));
      return;
    }
    if ((data is TypedData || data == null)) {
      _blink.BlinkWebSocket.instance.send_Callback_1_(unwrap_jso(this), unwrap_jso(data));
      return;
    }
    if ((data is ByteBuffer || data == null)) {
      _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), 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)));
  }

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


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

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

  @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(RequestAnimationFrameCallback callback) {
    return _requestAnimationFrame(_wrapZone(callback));
  }

  /**
   * Access a sandboxed file system of the specified `size`. If `persistent` is
   * true, the application will request permission from the user to create
   * lasting storage. This storage cannot be freed without the user's
   * permission. Returns a [Future] whose value stores a reference to the
   * sandboxed file system for use. Because the file system is sandboxed,
   * applications cannot access file systems created in other web pages.
   */
  Future<FileSystem> requestFileSystem(int size, {bool persistent: false}) {
    return _requestFileSystem(persistent? 1 : 0, size);
  }

  /**
   * convertPointFromNodeToPage and convertPointFromPageToNode are removed.
   * see http://dev.w3.org/csswg/cssom-view/#geometry
   */
  static bool get supportsPointConversions => DomPoint.supported;
  // To suppress missing implicit constructor warnings.
  factory Window._() { throw new UnsupportedError("Not supported"); }

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

  /**
   * Static factory designed to expose `devicemotion` events to event
   * handlers that are not necessarily instances of [Window].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Window.devicemotionEvent')
  @DocsEditable()
  // http://dev.w3.org/geo/api/spec-source-orientation.html#devicemotion
  @Experimental()
  static const EventStreamProvider<DeviceMotionEvent> deviceMotionEvent = const EventStreamProvider<DeviceMotionEvent>('devicemotion');

  /**
   * Static factory designed to expose `deviceorientation` events to event
   * handlers that are not necessarily instances of [Window].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Window.deviceorientationEvent')
  @DocsEditable()
  // http://dev.w3.org/geo/api/spec-source-orientation.html#devicemotion
  @Experimental()
  static const EventStreamProvider<DeviceOrientationEvent> deviceOrientationEvent = const EventStreamProvider<DeviceOrientationEvent>('deviceorientation');

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

  @DomName('Window.loadstartEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> loadStartEvent = const EventStreamProvider<Event>('loadstart');

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

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

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

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

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

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

  @DomName('Window.progressEvent')
  @DocsEditable()
  static const EventStreamProvider<Event> progressEvent = const EventStreamProvider<Event>('progress');

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

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

  /**
   * Static factory designed to expose `animationend` events to event
   * handlers that are not necessarily instances of [Window].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Window.webkitAnimationEndEvent')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  static const EventStreamProvider<AnimationEvent> animationEndEvent = const EventStreamProvider<AnimationEvent>('webkitAnimationEnd');

  /**
   * Static factory designed to expose `animationiteration` events to event
   * handlers that are not necessarily instances of [Window].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Window.webkitAnimationIterationEvent')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  static const EventStreamProvider<AnimationEvent> animationIterationEvent = const EventStreamProvider<AnimationEvent>('webkitAnimationIteration');

  /**
   * Static factory designed to expose `animationstart` events to event
   * handlers that are not necessarily instances of [Window].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Window.webkitAnimationStartEvent')
  @DocsEditable()
  @SupportedBrowser(SupportedBrowser.CHROME)
  @SupportedBrowser(SupportedBrowser.SAFARI)
  @Experimental()
  static const EventStreamProvider<AnimationEvent> animationStartEvent = const EventStreamProvider<AnimationEvent>('webkitAnimationStart');


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

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

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

  /**
   * Entrypoint for CSS-related functions.
   *
   * ## Other resources
   *
   * * [The CSS interface](http://dev.w3.org/csswg/css-conditional/#the-css-interface) from W3C.
   */
  @DomName('Window.CSS')
  @DocsEditable()
  Css get css => wrap_jso(_blink.BlinkWindow.instance.CSS_Getter_(unwrap_jso(this)));
  
  /**
   * The application cache for this window.
   *
   * ## Other resources
   *
   * * [A beginner's guide to using the application cache]
   * (http://www.html5rocks.com/en/tutorials/appcache/beginner) from HTML5Rocks.
   * * [Application cache API]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/offline.html#application-cache-api)
   * from WHATWG.
   */
  @DomName('Window.applicationCache')
  @DocsEditable()
  ApplicationCache get applicationCache => wrap_jso(_blink.BlinkWindow.instance.applicationCache_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]
   * (http://www.whatwg.org/specs/web-apps/current-work/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]
   * (http://www.whatwg.org/specs/web-apps/current-work/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]
   * (http://www.whatwg.org/specs/web-apps/current-work/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]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/timers.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]
   * (http://www.whatwg.org/specs/web-apps/current-work/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]
   * (http://www.whatwg.org/specs/web-apps/current-work/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/StyleMedia/StyleMedia.html)
   * from Safari Developer Library.
   */
  @DomName('Window.styleMedia')
  @DocsEditable()
  // http://developer.apple.com/library/safari/#documentation/SafariDOMAdditions/Reference/StyleMedia/StyleMedia/StyleMedia.html
  @Experimental() // nonstandard
  StyleMedia get styleMedia => wrap_jso(_blink.BlinkWindow.instance.styleMedia_Getter_(unwrap_jso(this)));
  
  /**
   * This window's tool bar.
   *
   * ## Other resources
   *
   * * [Browser interface elements]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/browsers.html#browser-interface-elements)
   * from WHATWG.
   */
  @DomName('Window.toolbar')
  @DocsEditable()
  BarProp get toolbar => 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 id) => _blink.BlinkWindow.instance.cancelAnimationFrame_Callback_1_(unwrap_jso(this), id);
  
  @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));
  }

  /**
   * 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 element, String pseudoElement) => wrap_jso(_blink.BlinkWindow.instance.getComputedStyle_Callback_2_(unwrap_jso(this), unwrap_jso(element), pseudoElement));
  
  /**
   * Returns all CSS rules that apply to the element's pseudo-element.
   */
  @DomName('Window.getMatchedCSSRules')
  @DocsEditable()
  @Experimental() // non-standard
  List<CssRule> getMatchedCssRules(Element element, String pseudoElement) => 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(num x, num y) => _blink.BlinkWindow.instance.moveBy_Callback_2_(unwrap_jso(this), x, y);
  
  @DomName('Window.moveTo')
  @DocsEditable()
  void _moveTo(num x, num y) => _blink.BlinkWindow.instance.moveTo_Callback_2_(unwrap_jso(this), x, y);
  
  @DomName('Window.open')
  @DocsEditable()
  WindowBase open(String url, String name, [String options]) => wrap_jso(_blink.BlinkWindow.instance.open_Callback_3_(unwrap_jso(this), url, name, options));
  
  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(/*SerializedScriptValue*/ 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(RequestAnimationFrameCallback 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(num x, num 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(num width, num height) => _blink.BlinkWindow.instance.resizeTo_Callback_2_(unwrap_jso(this), width, height);
  
  void scroll(x, y, [Map scrollOptions]) {
    if ((y is num) && (x is num) && scrollOptions == null) {
      _blink.BlinkWindow.instance.scroll_Callback_2_(unwrap_jso(this), unwrap_jso(x), unwrap_jso(y));
      return;
    }
    if ((scrollOptions is Map) && (y is num) && (x is num)) {
      _blink.BlinkWindow.instance.scroll_Callback_3_(unwrap_jso(this), unwrap_jso(x), unwrap_jso(y), convertDartToNative_Dictionary(scrollOptions));
      return;
    }
    if ((y is int) && (x is int) && scrollOptions == null) {
      _blink.BlinkWindow.instance.scroll_Callback_2_(unwrap_jso(this), unwrap_jso(x), unwrap_jso(y));
      return;
    }
    if ((scrollOptions is Map) && (y is int) && (x is int)) {
      _blink.BlinkWindow.instance.scroll_Callback_3_(unwrap_jso(this), unwrap_jso(x), unwrap_jso(y), convertDartToNative_Dictionary(scrollOptions));
      return;
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }

  void scrollBy(x, y, [Map scrollOptions]) {
    if ((y is num) && (x is num) && scrollOptions == null) {
      _blink.BlinkWindow.instance.scrollBy_Callback_2_(unwrap_jso(this), unwrap_jso(x), unwrap_jso(y));
      return;
    }
    if ((scrollOptions is Map) && (y is num) && (x is num)) {
      _blink.BlinkWindow.instance.scrollBy_Callback_3_(unwrap_jso(this), unwrap_jso(x), unwrap_jso(y), convertDartToNative_Dictionary(scrollOptions));
      return;
    }
    if ((y is int) && (x is int) && scrollOptions == null) {
      _blink.BlinkWindow.instance.scrollBy_Callback_2_(unwrap_jso(this), unwrap_jso(x), unwrap_jso(y));
      return;
    }
    if ((scrollOptions is Map) && (y is int) && (x is int)) {
      _blink.BlinkWindow.instance.scrollBy_Callback_3_(unwrap_jso(this), unwrap_jso(x), unwrap_jso(y), convertDartToNative_Dictionary(scrollOptions));
      return;
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }

  void scrollTo(x, y, [Map scrollOptions]) {
    if ((y is num) && (x is num) && scrollOptions == null) {
      _blink.BlinkWindow.instance.scrollTo_Callback_2_(unwrap_jso(this), unwrap_jso(x), unwrap_jso(y));
      return;
    }
    if ((scrollOptions is Map) && (y is num) && (x is num)) {
      _blink.BlinkWindow.instance.scrollTo_Callback_3_(unwrap_jso(this), unwrap_jso(x), unwrap_jso(y), convertDartToNative_Dictionary(scrollOptions));
      return;
    }
    if ((y is int) && (x is int) && scrollOptions == null) {
      _blink.BlinkWindow.instance.scrollTo_Callback_2_(unwrap_jso(this), unwrap_jso(x), unwrap_jso(y));
      return;
    }
    if ((scrollOptions is Map) && (y is int) && (x is int)) {
      _blink.BlinkWindow.instance.scrollTo_Callback_3_(unwrap_jso(this), unwrap_jso(x), unwrap_jso(y), convertDartToNative_Dictionary(scrollOptions));
      return;
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }

  /**
   * Opens a new page as a modal dialog.
   *
   * ## Other resources
   *
   * * [Dialogs implemented using separate documents]
   * (http://www.w3.org/html/wg/drafts/html/master/webappapis.html#dialogs-implemented-using-separate-documents)
   * from W3C.
   */
  @DomName('Window.showModalDialog')
  @DocsEditable()
  Object showModalDialog(String url, [Object dialogArgs, String featureArgs]) => wrap_jso(_blink.BlinkWindow.instance.showModalDialog_Callback_3_(unwrap_jso(this), url, dialogArgs, featureArgs));
  
  /**
   * Stops the window from loading.
   *
   * ## Other resources
   *
   * * [The Window object]
   * (http://www.w3.org/html/wg/drafts/html/master/browsers.html#the-window-object)
   * from W3C.
   */
  @DomName('Window.stop')
  @DocsEditable()
  void stop() => _blink.BlinkWindow.instance.stop_Callback_0_(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 string) => _blink.BlinkWindow.instance.atob_Callback_1_(unwrap_jso(this), string);
  
  @DomName('Window.btoa')
  @DocsEditable()
  String btoa(String string) => _blink.BlinkWindow.instance.btoa_Callback_1_(unwrap_jso(this), string);
  
  @DomName('Window.clearInterval')
  @DocsEditable()
  void _clearInterval(int handle) => _blink.BlinkWindow.instance.clearInterval_Callback_1_(unwrap_jso(this), handle);
  
  @DomName('Window.clearTimeout')
  @DocsEditable()
  void _clearTimeout(int handle) => _blink.BlinkWindow.instance.clearTimeout_Callback_1_(unwrap_jso(this), handle);
  
  @DomName('Window.setInterval')
  @DocsEditable()
  int _setInterval(Object handler, int timeout) => _blink.BlinkWindow.instance.setInterval_Callback_2_(unwrap_jso(this), handler, timeout);
  
  @DomName('Window.setTimeout')
  @DocsEditable()
  int _setTimeout(Object handler, int timeout) => _blink.BlinkWindow.instance.setTimeout_Callback_2_(unwrap_jso(this), handler, timeout);
  
  /// Stream of `contentloaded` events handled by this [Window].
  @DomName('Window.onDOMContentLoaded')
  @DocsEditable()
  Stream<Event> get onContentLoaded => contentLoadedEvent.forTarget(this);

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

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

  @DomName('Window.oncanplay')
  @DocsEditable()
  Stream<Event> get onCanPlay => Element.canPlayEvent.forTarget(this);

  @DomName('Window.oncanplaythrough')
  @DocsEditable()
  Stream<Event> get onCanPlayThrough => Element.canPlayThroughEvent.forTarget(this);

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

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

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

  /// Stream of `doubleclick` events handled by this [Window].
  @DomName('Window.ondblclick')
  @DocsEditable()
  Stream<Event> get onDoubleClick => Element.doubleClickEvent.forTarget(this);

  /// Stream of `devicemotion` events handled by this [Window].
  @DomName('Window.ondevicemotion')
  @DocsEditable()
  // http://dev.w3.org/geo/api/spec-source-orientation.html#devicemotion
  @Experimental()
  Stream<DeviceMotionEvent> get onDeviceMotion => deviceMotionEvent.forTarget(this);

  /// Stream of `deviceorientation` events handled by this [Window].
  @DomName('Window.ondeviceorientation')
  @DocsEditable()
  // http://dev.w3.org/geo/api/spec-source-orientation.html#devicemotion
  @Experimental()
  Stream<DeviceOrientationEvent> get onDeviceOrientation => deviceOrientationEvent.forTarget(this);

  /// Stream of `drag` events handled by this [Window].
  @DomName('Window.ondrag')
  @DocsEditable()
  Stream<MouseEvent> get onDrag => Element.dragEvent.forTarget(this);

  /// Stream of `dragend` events handled by this [Window].
  @DomName('Window.ondragend')
  @DocsEditable()
  Stream<MouseEvent> get onDragEnd => Element.dragEndEvent.forTarget(this);

  /// Stream of `dragenter` events handled by this [Window].
  @DomName('Window.ondragenter')
  @DocsEditable()
  Stream<MouseEvent> get onDragEnter => Element.dragEnterEvent.forTarget(this);

  /// Stream of `dragleave` events handled by this [Window].
  @DomName('Window.ondragleave')
  @DocsEditable()
  Stream<MouseEvent> get onDragLeave => Element.dragLeaveEvent.forTarget(this);

  /// Stream of `dragover` events handled by this [Window].
  @DomName('Window.ondragover')
  @DocsEditable()
  Stream<MouseEvent> get onDragOver => Element.dragOverEvent.forTarget(this);

  /// Stream of `dragstart` events handled by this [Window].
  @DomName('Window.ondragstart')
  @DocsEditable()
  Stream<MouseEvent> get onDragStart => Element.dragStartEvent.forTarget(this);

  /// Stream of `drop` events handled by this [Window].
  @DomName('Window.ondrop')
  @DocsEditable()
  Stream<MouseEvent> get onDrop => Element.dropEvent.forTarget(this);

  @DomName('Window.ondurationchange')
  @DocsEditable()
  Stream<Event> get onDurationChange => Element.durationChangeEvent.forTarget(this);

  @DomName('Window.onemptied')
  @DocsEditable()
  Stream<Event> get onEmptied => Element.emptiedEvent.forTarget(this);

  @DomName('Window.onended')
  @DocsEditable()
  Stream<Event> get onEnded => Element.endedEvent.forTarget(this);

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

  /// Stream of `focus` events handled by this [Window].
  @DomName('Window.onfocus')
  @DocsEditable()
  Stream<Event> get onFocus => Element.focusEvent.forTarget(this);

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

  /// Stream of `input` events handled by this [Window].
  @DomName('Window.oninput')
  @DocsEditable()
  Stream<Event> get onInput => Element.inputEvent.forTarget(this);

  /// Stream of `invalid` events handled by this [Window].
  @DomName('Window.oninvalid')
  @DocsEditable()
  Stream<Event> get onInvalid => Element.invalidEvent.forTarget(this);

  /// Stream of `keydown` events handled by this [Window].
  @DomName('Window.onkeydown')
  @DocsEditable()
  Stream<KeyboardEvent> get onKeyDown => Element.keyDownEvent.forTarget(this);

  /// Stream of `keypress` events handled by this [Window].
  @DomName('Window.onkeypress')
  @DocsEditable()
  Stream<KeyboardEvent> get onKeyPress => Element.keyPressEvent.forTarget(this);

  /// Stream of `keyup` events handled by this [Window].
  @DomName('Window.onkeyup')
  @DocsEditable()
  Stream<KeyboardEvent> get onKeyUp => Element.keyUpEvent.forTarget(this);

  /// Stream of `load` events handled by this [Window].
  @DomName('Window.onload')
  @DocsEditable()
  Stream<Event> get onLoad => Element.loadEvent.forTarget(this);

  @DomName('Window.onloadeddata')
  @DocsEditable()
  Stream<Event> get onLoadedData => Element.loadedDataEvent.forTarget(this);

  @DomName('Window.onloadedmetadata')
  @DocsEditable()
  Stream<Event> get onLoadedMetadata => Element.loadedMetadataEvent.forTarget(this);

  @DomName('Window.onloadstart')
  @DocsEditable()
  Stream<Event> get onLoadStart => loadStartEvent.forTarget(this);

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

  /// Stream of `mousedown` events handled by this [Window].
  @DomName('Window.onmousedown')
  @DocsEditable()
  Stream<MouseEvent> get onMouseDown => Element.mouseDownEvent.forTarget(this);

  /// Stream of `mouseenter` events handled by this [Window].
  @DomName('Window.onmouseenter')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<MouseEvent> get onMouseEnter => Element.mouseEnterEvent.forTarget(this);

  /// Stream of `mouseleave` events handled by this [Window].
  @DomName('Window.onmouseleave')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<MouseEvent> get onMouseLeave => Element.mouseLeaveEvent.forTarget(this);

  /// Stream of `mousemove` events handled by this [Window].
  @DomName('Window.onmousemove')
  @DocsEditable()
  Stream<MouseEvent> get onMouseMove => Element.mouseMoveEvent.forTarget(this);

  /// Stream of `mouseout` events handled by this [Window].
  @DomName('Window.onmouseout')
  @DocsEditable()
  Stream<MouseEvent> get onMouseOut => Element.mouseOutEvent.forTarget(this);

  /// Stream of `mouseover` events handled by this [Window].
  @DomName('Window.onmouseover')
  @DocsEditable()
  Stream<MouseEvent> get onMouseOver => Element.mouseOverEvent.forTarget(this);

  /// Stream of `mouseup` events handled by this [Window].
  @DomName('Window.onmouseup')
  @DocsEditable()
  Stream<MouseEvent> get onMouseUp => Element.mouseUpEvent.forTarget(this);

  /// Stream of `mousewheel` events handled by this [Window].
  @DomName('Window.onmousewheel')
  @DocsEditable()
  Stream<WheelEvent> get onMouseWheel => Element.mouseWheelEvent.forTarget(this);

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

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

  /// Stream of `pagehide` events handled by this [Window].
  @DomName('Window.onpagehide')
  @DocsEditable()
  Stream<Event> get onPageHide => pageHideEvent.forTarget(this);

  /// Stream of `pageshow` events handled by this [Window].
  @DomName('Window.onpageshow')
  @DocsEditable()
  Stream<Event> get onPageShow => pageShowEvent.forTarget(this);

  @DomName('Window.onpause')
  @DocsEditable()
  Stream<Event> get onPause => Element.pauseEvent.forTarget(this);

  @DomName('Window.onplay')
  @DocsEditable()
  Stream<Event> get onPlay => Element.playEvent.forTarget(this);

  @DomName('Window.onplaying')
  @DocsEditable()
  Stream<Event> get onPlaying => Element.playingEvent.forTarget(this);

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

  @DomName('Window.onprogress')
  @DocsEditable()
  Stream<Event> get onProgress => progressEvent.forTarget(this);

  @DomName('Window.onratechange')
  @DocsEditable()
  Stream<Event> get onRateChange => Element.rateChangeEvent.forTarget(this);

  /// Stream of `reset` events handled by this [Window].
  @DomName('Window.onreset')
  @DocsEditable()
  Stream<Event> get onReset => Element.resetEvent.forTarget(this);

  /// Stream of `resize` events handled by this [Window].
  @DomName('Window.onresize')
  @DocsEditable()
  Stream<Event> get onResize => Element.resizeEvent.forTarget(this);

  /// Stream of `scroll` events handled by this [Window].
  @DomName('Window.onscroll')
  @DocsEditable()
  Stream<Event> get onScroll => Element.scrollEvent.forTarget(this);

  /// Stream of `search` events handled by this [Window].
  @DomName('Window.onsearch')
  @DocsEditable()
  // http://www.w3.org/TR/html-markup/input.search.html
  @Experimental()
  Stream<Event> get onSearch => Element.searchEvent.forTarget(this);

  @DomName('Window.onseeked')
  @DocsEditable()
  Stream<Event> get onSeeked => Element.seekedEvent.forTarget(this);

  @DomName('Window.onseeking')
  @DocsEditable()
  Stream<Event> get onSeeking => Element.seekingEvent.forTarget(this);

  /// Stream of `select` events handled by this [Window].
  @DomName('Window.onselect')
  @DocsEditable()
  Stream<Event> get onSelect => Element.selectEvent.forTarget(this);

  @DomName('Window.onstalled')
  @DocsEditable()
  Stream<Event> get onStalled => Element.stalledEvent.forTarget(this);

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

  /// Stream of `submit` events handled by this [Window].
  @DomName('Window.onsubmit')
  @DocsEditable()
  Stream<Event> get onSubmit => Element.submitEvent.forTarget(this);

  @DomName('Window.onsuspend')
  @DocsEditable()
  Stream<Event> get onSuspend => Element.suspendEvent.forTarget(this);

  @DomName('Window.ontimeupdate')
  @DocsEditable()
  Stream<Event> get onTimeUpdate => Element.timeUpdateEvent.forTarget(this);

  /// Stream of `touchcancel` events handled by this [Window].
  @DomName('Window.ontouchcancel')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  Stream<TouchEvent> get onTouchCancel => Element.touchCancelEvent.forTarget(this);

  /// Stream of `touchend` events handled by this [Window].
  @DomName('Window.ontouchend')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  Stream<TouchEvent> get onTouchEnd => Element.touchEndEvent.forTarget(this);

  /// Stream of `touchmove` events handled by this [Window].
  @DomName('Window.ontouchmove')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  Stream<TouchEvent> get onTouchMove => Element.touchMoveEvent.forTarget(this);

  /// Stream of `touchstart` events handled by this [Window].
  @DomName('Window.ontouchstart')
  @DocsEditable()
  // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
  @Experimental()
  Stream<TouchEvent> get onTouchStart => Element.touchStartEvent.forTarget(this);

  /// Stream of `transitionend` events handled by this [Window].
  @DomName('Window.ontransitionend')
  @DocsEditable()
  Stream<TransitionEvent> get onTransitionEnd => Element.transitionEndEvent.forTarget(this);

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

  @DomName('Window.onvolumechange')
  @DocsEditable()
  Stream<Event> get onVolumeChange => Element.volumeChangeEvent.forTarget(this);

  @DomName('Window.onwaiting')
  @DocsEditable()
  Stream<Event> get onWaiting => Element.waitingEvent.forTarget(this);

  /// Stream of `animationend` events handled by this [Window].
  @DomName('Window.onwebkitAnimationEnd')
  @DocsEditable()
  @Experimental()
  Stream<AnimationEvent> get onAnimationEnd => animationEndEvent.forTarget(this);

  /// Stream of `animationiteration` events handled by this [Window].
  @DomName('Window.onwebkitAnimationIteration')
  @DocsEditable()
  @Experimental()
  Stream<AnimationEvent> get onAnimationIteration => animationIterationEvent.forTarget(this);

  /// Stream of `animationstart` events handled by this [Window].
  @DomName('Window.onwebkitAnimationStart')
  @DocsEditable()
  @Experimental()
  Stream<AnimationEvent> get onAnimationStart => animationStartEvent.forTarget(this);


  /**
   * Static factory designed to expose `beforeunload` events to event
   * handlers that are not necessarily instances of [Window].
   *
   * See [EventStreamProvider] for usage information.
   */
  @DomName('Window.beforeunloadEvent')
  static const EventStreamProvider<BeforeUnloadEvent> beforeUnloadEvent =
      const _BeforeUnloadEventStreamProvider('beforeunload');

  /// Stream of `beforeunload` events handled by this [Window].
  @DomName('Window.onbeforeunload')
  Stream<Event> get onBeforeUnload => beforeUnloadEvent.forTarget(this);

  /**
   * Moves this window to a specific position.
   *
   * x and y can be negative.
   *
   * ## Other resources
   *
   * * [Window.moveTo]
   * (https://developer.mozilla.org/en-US/docs/Web/API/Window.moveTo) from MDN.
   * * [Window.moveTo]
   * (http://dev.w3.org/csswg/cssom-view/#dom-window-moveto) from W3C.
   */
  void moveTo(Point p) {
    _moveTo(p.x, p.y);
  }

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

  @DomName('WindowBase64.btoa')
  @DocsEditable()
  @Experimental() // untriaged
  String btoa(String string);

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


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

  @DomName('WindowEventHandlers.hashchangeEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> hashChangeEvent = const EventStreamProvider<Event>('hashchange');

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

  @DomName('WindowEventHandlers.offlineEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> offlineEvent = const EventStreamProvider<Event>('offline');

  @DomName('WindowEventHandlers.onlineEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> onlineEvent = const EventStreamProvider<Event>('online');

  @DomName('WindowEventHandlers.popstateEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<PopStateEvent> popStateEvent = const EventStreamProvider<PopStateEvent>('popstate');

  @DomName('WindowEventHandlers.storageEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<StorageEvent> storageEvent = const EventStreamProvider<StorageEvent>('storage');

  @DomName('WindowEventHandlers.unloadEvent')
  @DocsEditable()
  @Experimental() // untriaged
  static const EventStreamProvider<Event> unloadEvent = const EventStreamProvider<Event>('unload');

  @DomName('WindowEventHandlers.onhashchange')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onHashChange => hashChangeEvent.forTarget(this);

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

  @DomName('WindowEventHandlers.onoffline')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onOffline => offlineEvent.forTarget(this);

  @DomName('WindowEventHandlers.ononline')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onOnline => onlineEvent.forTarget(this);

  @DomName('WindowEventHandlers.onpopstate')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<PopStateEvent> get onPopState => popStateEvent.forTarget(this);

  @DomName('WindowEventHandlers.onstorage')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<StorageEvent> get onStorage => storageEvent.forTarget(this);

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

// WARNING: Do not edit - generated code.


@DocsEditable()
@DomName('Worker')
@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.FIREFOX)
@SupportedBrowser(SupportedBrowser.IE, '10')
@SupportedBrowser(SupportedBrowser.SAFARI)
// http://www.whatwg.org/specs/web-apps/current-work/multipage/workers.html#worker
@Experimental() // stable
class Worker extends EventTarget implements AbstractWorker {
  // To suppress missing implicit constructor warnings.
  factory Worker._() { throw new UnsupportedError("Not supported"); }

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

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

  @DomName('Worker.Worker')
  @DocsEditable()
  factory Worker(String scriptUrl) {
    return wrap_jso(_blink.BlinkWorker.instance.constructorCallback_1_(scriptUrl));
  }


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

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

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


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

  @DomName('Worker.postMessage')
  @DocsEditable()
  void postMessage(/*SerializedScriptValue*/ message, [List<MessagePort> transfer]) => _blink.BlinkWorker.instance.postMessage_Callback_2_(unwrap_jso(this), message, transfer);
  
  @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();
  }

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

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

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

  @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.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));
  
  @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 string) => _blink.BlinkWorkerGlobalScope.instance.atob_Callback_1_(unwrap_jso(this), string);
  
  @DomName('WorkerGlobalScope.btoa')
  @DocsEditable()
  @Experimental() // untriaged
  String btoa(String string) => _blink.BlinkWorkerGlobalScope.instance.btoa_Callback_1_(unwrap_jso(this), string);
  
  @DomName('WorkerGlobalScope.clearInterval')
  @DocsEditable()
  @Experimental() // untriaged
  void _clearInterval(int handle) => _blink.BlinkWorkerGlobalScope.instance.clearInterval_Callback_1_(unwrap_jso(this), handle);
  
  @DomName('WorkerGlobalScope.clearTimeout')
  @DocsEditable()
  @Experimental() // untriaged
  void _clearTimeout(int handle) => _blink.BlinkWorkerGlobalScope.instance.clearTimeout_Callback_1_(unwrap_jso(this), handle);
  
  @DomName('WorkerGlobalScope.setInterval')
  @DocsEditable()
  @Experimental() // untriaged
  int _setInterval(Object handler, int timeout) => _blink.BlinkWorkerGlobalScope.instance.setInterval_Callback_2_(unwrap_jso(this), handler, timeout);
  
  @DomName('WorkerGlobalScope.setTimeout')
  @DocsEditable()
  @Experimental() // untriaged
  int _setTimeout(Object handler, int timeout) => _blink.BlinkWorkerGlobalScope.instance.setTimeout_Callback_2_(unwrap_jso(this), handler, timeout);
  
  /// Stream of `error` events handled by this [WorkerGlobalScope].
  @DomName('WorkerGlobalScope.onerror')
  @DocsEditable()
  @Experimental() // untriaged
  Stream<Event> get onError => errorEvent.forTarget(this);

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

// WARNING: Do not edit - generated code.


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

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

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

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

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

  @DomName('WorkerPerformance.memory')
  @DocsEditable()
  @Experimental() // untriaged
  MemoryInfo get memory => wrap_jso(_blink.BlinkWorkerPerformance.instance.memory_Getter_(unwrap_jso(this)));
  
  @DomName('WorkerPerformance.now')
  @DocsEditable()
  @Experimental() // untriaged
  num now() => _blink.BlinkWorkerPerformance.instance.now_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('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)));
  
  @DomName('XPathEvaluator.evaluate')
  @DocsEditable()
  XPathResult evaluate(String expression, Node contextNode, XPathNSResolver resolver, int type, XPathResult inResult) => wrap_jso(_blink.BlinkXPathEvaluator.instance.evaluate_Callback_5_(unwrap_jso(this), expression, unwrap_jso(contextNode), unwrap_jso(resolver), type, unwrap_jso(inResult)));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.


@DocsEditable()
@DomName('XPathExpression')
// http://www.w3.org/TR/DOM-Level-3-XPath/xpath.html#XPathExpression
@deprecated // experimental
class XPathExpression extends 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;

  @DomName('XPathExpression.evaluate')
  @DocsEditable()
  XPathResult evaluate(Node contextNode, int type, XPathResult inResult) => wrap_jso(_blink.BlinkXPathExpression.instance.evaluate_Callback_3_(unwrap_jso(this), unwrap_jso(contextNode), type, unwrap_jso(inResult)));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.


@DocsEditable()
@DomName('XPathNSResolver')
// http://www.w3.org/TR/DOM-Level-3-XPath/xpath.html#XPathNSResolver
@deprecated // experimental
class XPathNSResolver extends 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();
  }

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

  @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 node) => _blink.BlinkXMLSerializer.instance.serializeToString_Callback_1_(unwrap_jso(this), unwrap_jso(node));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.


@DocsEditable()
@DomName('XSLTProcessor')
@SupportedBrowser(SupportedBrowser.CHROME)
@SupportedBrowser(SupportedBrowser.FIREFOX)
@SupportedBrowser(SupportedBrowser.SAFARI)
@deprecated // nonstandard
class XsltProcessor extends 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 stylesheet) => _blink.BlinkXSLTProcessor.instance.importStylesheet_Callback_1_(unwrap_jso(this), unwrap_jso(stylesheet));
  
  @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 docVal) => wrap_jso(_blink.BlinkXSLTProcessor.instance.transformToFragment_Callback_2_(unwrap_jso(this), unwrap_jso(source), unwrap_jso(docVal)));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.


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


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

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

  @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('CSSPrimitiveValue')
// http://dev.w3.org/csswg/cssom/#the-cssstyledeclaration-interface
@deprecated // deprecated
class _CSSPrimitiveValue extends _CSSValue {
  // To suppress missing implicit constructor warnings.
  factory _CSSPrimitiveValue._() { throw new UnsupportedError("Not supported"); }


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

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

  @Deprecated("Internal Use Only")
  _CSSPrimitiveValue.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('CSSUnknownRule')
// http://dev.w3.org/csswg/cssom/#the-cssstylesheet-interface
@deprecated // deprecated
class _CSSUnknownRule extends CssRule {
  // To suppress missing implicit constructor warnings.
  factory _CSSUnknownRule._() { throw new UnsupportedError("Not supported"); }


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

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

  @Deprecated("Internal Use Only")
  _CSSUnknownRule.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('CSSValue')
// http://dev.w3.org/csswg/cssom/
@deprecated // deprecated
class _CSSValue extends DartHtmlDomObject {
  // To suppress missing implicit constructor warnings.
  factory _CSSValue._() { throw new UnsupportedError("Not supported"); }

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

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

  @Deprecated("Internal Use Only")
  _CSSValue.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('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.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('Counter')
// http://dev.w3.org/csswg/cssom/
@deprecated // deprecated
class _Counter extends DartHtmlDomObject {
  // To suppress missing implicit constructor warnings.
  factory _Counter._() { throw new UnsupportedError("Not supported"); }

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

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

  @Deprecated("Internal Use Only")
  _Counter.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('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('CSSValueList')
// http://dev.w3.org/csswg/cssom/
@deprecated // deprecated
class _CssValueList extends _CSSValue with ListMixin<_CSSValue>, ImmutableListMixin<_CSSValue> implements List<_CSSValue> {
  // To suppress missing implicit constructor warnings.
  factory _CssValueList._() { throw new UnsupportedError("Not supported"); }


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

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

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


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

  _CSSValue _nativeIndexedGetter(int index) => wrap_jso(_blink.BlinkCSSValueList.instance.item_Callback_1_(unwrap_jso(this), index));

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


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

  _CSSValue get first {
    if (this.length > 0) {
      return _nativeIndexedGetter(0);
    }
    throw new StateError("No elements");
  }

  _CSSValue get last {
    int len = this.length;
    if (len > 0) {
      return _nativeIndexedGetter(len - 1);
    }
    throw new StateError("No elements");
  }

  _CSSValue get single {
    int len = this.length;
    if (len == 1) {
      return _nativeIndexedGetter(0);
    }
    if (len == 0) throw new StateError("No elements");
    throw new StateError("More than one element");
  }

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

  @DomName('CSSValueList.item')
  @DocsEditable()
  _CSSValue item(int index) => wrap_jso(_blink.BlinkCSSValueList.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();
  }

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

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

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

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

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

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

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

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

  @DomName('HTMLAllCollection.item')
  @DocsEditable()
  Element _item(int index) => wrap_jso(_blink.BlinkHTMLAllCollection.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('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();
  }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  @DomName('NamedNodeMap.__getter__')
  @DocsEditable()
  Node __getter__(String name) => wrap_jso(_blink.BlinkNamedNodeMap.instance.$__getter___Callback_1_(unwrap_jso(this), name));
  
  @DomName('NamedNodeMap.getNamedItem')
  @DocsEditable()
  Node getNamedItem(String name) => wrap_jso(_blink.BlinkNamedNodeMap.instance.getNamedItem_Callback_1_(unwrap_jso(this), name));
  
  @DomName('NamedNodeMap.getNamedItemNS')
  @DocsEditable()
  Node getNamedItemNS(String namespaceURI, String localName) => wrap_jso(_blink.BlinkNamedNodeMap.instance.getNamedItemNS_Callback_2_(unwrap_jso(this), namespaceURI, localName));
  
  @DomName('NamedNodeMap.item')
  @DocsEditable()
  Node item(int index) => wrap_jso(_blink.BlinkNamedNodeMap.instance.item_Callback_1_(unwrap_jso(this), index));
  
  @DomName('NamedNodeMap.removeNamedItem')
  @DocsEditable()
  Node removeNamedItem(String name) => wrap_jso(_blink.BlinkNamedNodeMap.instance.removeNamedItem_Callback_1_(unwrap_jso(this), name));
  
  @DomName('NamedNodeMap.removeNamedItemNS')
  @DocsEditable()
  Node removeNamedItemNS(String namespaceURI, String localName) => wrap_jso(_blink.BlinkNamedNodeMap.instance.removeNamedItemNS_Callback_2_(unwrap_jso(this), namespaceURI, localName));
  
  @DomName('NamedNodeMap.setNamedItem')
  @DocsEditable()
  Node setNamedItem(Node node) => wrap_jso(_blink.BlinkNamedNodeMap.instance.setNamedItem_Callback_1_(unwrap_jso(this), unwrap_jso(node)));
  
  @DomName('NamedNodeMap.setNamedItemNS')
  @DocsEditable()
  Node setNamedItemNS(Node node) => wrap_jso(_blink.BlinkNamedNodeMap.instance.setNamedItemNS_Callback_1_(unwrap_jso(this), unwrap_jso(node)));
  
}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.


@DocsEditable()
@DomName('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) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// WARNING: Do not edit - generated code.


@DocsEditable()
@DomName('RGBColor')
// http://dev.w3.org/csswg/cssom/
@deprecated // deprecated
class _RGBColor extends DartHtmlDomObject {
  // To suppress missing implicit constructor warnings.
  factory _RGBColor._() { throw new UnsupportedError("Not supported"); }

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

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

  @Deprecated("Internal Use Only")
  _RGBColor.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();
  }

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

  @Deprecated("Internal Use Only")
  _RadioNodeList.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('Rect')
// http://dev.w3.org/csswg/cssom/
@deprecated // deprecated
class _Rect extends DartHtmlDomObject {
  // To suppress missing implicit constructor warnings.
  factory _Rect._() { throw new UnsupportedError("Not supported"); }

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

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

  @Deprecated("Internal Use Only")
  _Rect.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('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(input, [Map requestInitDict]) {
    if ((input is String || input == null) && requestInitDict == null) {
      return wrap_jso(_blink.BlinkRequest.instance.constructorCallback_1_(input));
    }
    if ((requestInitDict is Map || requestInitDict == null) && (input is String || input == null)) {
      var requestInitDict_1 = convertDartToNative_Dictionary(requestInitDict);
      return wrap_jso(_blink.BlinkRequest.instance.constructorCallback_2_(input, requestInitDict_1));
    }
    if ((input is _Request || input == null) && requestInitDict == null) {
      return wrap_jso(_blink.BlinkRequest.instance.constructorCallback_1_(input));
    }
    if ((requestInitDict is Map || requestInitDict == null) && (input is _Request || input == null)) {
      var requestInitDict_1 = convertDartToNative_Dictionary(requestInitDict);
      return wrap_jso(_blink.BlinkRequest.instance.constructorCallback_2_(input, requestInitDict_1));
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }


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

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

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


  @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(body_OR_input, [Map requestInitDict_OR_responseInitDict]) {
    if ((body_OR_input is String || body_OR_input == null) && requestInitDict_OR_responseInitDict == null) {
      return wrap_jso(_blink.BlinkResponse.instance.constructorCallback_1_(body_OR_input));
    }
    if ((requestInitDict_OR_responseInitDict is Map || requestInitDict_OR_responseInitDict == null) && (body_OR_input is String || body_OR_input == null)) {
      var responseInitDict_1 = convertDartToNative_Dictionary(requestInitDict_OR_responseInitDict);
      return wrap_jso(_blink.BlinkResponse.instance.constructorCallback_2_(body_OR_input, responseInitDict_1));
    }
    if ((body_OR_input is Blob || body_OR_input == null) && requestInitDict_OR_responseInitDict == null) {
      return wrap_jso(_blink.BlinkResponse.instance.constructorCallback_1_(body_OR_input));
    }
    if ((requestInitDict_OR_responseInitDict is Map || requestInitDict_OR_responseInitDict == null) && (body_OR_input is Blob || body_OR_input == null)) {
      var responseInitDict_1 = convertDartToNative_Dictionary(requestInitDict_OR_responseInitDict);
      return wrap_jso(_blink.BlinkResponse.instance.constructorCallback_2_(body_OR_input, responseInitDict_1));
    }
    if ((body_OR_input is TypedData || body_OR_input == null) && requestInitDict_OR_responseInitDict == null) {
      return wrap_jso(_blink.BlinkResponse.instance.constructorCallback_1_(body_OR_input));
    }
    if ((requestInitDict_OR_responseInitDict is Map || requestInitDict_OR_responseInitDict == null) && (body_OR_input is TypedData || body_OR_input == null)) {
      var requestInitDict_1 = convertDartToNative_Dictionary(requestInitDict_OR_responseInitDict);
      return wrap_jso(_blink.BlinkResponse.instance.constructorCallback_2_(body_OR_input, requestInitDict_1));
    }
    if ((body_OR_input is ByteBuffer || body_OR_input == null) && requestInitDict_OR_responseInitDict == null) {
      return wrap_jso(_blink.BlinkResponse.instance.constructorCallback_1_(body_OR_input));
    }
    if ((requestInitDict_OR_responseInitDict is Map || requestInitDict_OR_responseInitDict == null) && (body_OR_input is ByteBuffer || body_OR_input == null)) {
      var requestInitDict_1 = convertDartToNative_Dictionary(requestInitDict_OR_responseInitDict);
      return wrap_jso(_blink.BlinkResponse.instance.constructorCallback_2_(body_OR_input, requestInitDict_1));
    }
    throw new ArgumentError("Incorrect number or type of arguments");
  }


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

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

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

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

  @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('WebKitCSSFilterValue')
// http://dev.w3.org/csswg/cssom/
@deprecated // deprecated
class _WebKitCSSFilterValue extends _CssValueList {
  // To suppress missing implicit constructor warnings.
  factory _WebKitCSSFilterValue._() { throw new UnsupportedError("Not supported"); }


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

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

  @Deprecated("Internal Use Only")
  _WebKitCSSFilterValue.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('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('WebKitCSSTransformValue')
// http://dev.w3.org/csswg/cssom/
@deprecated // deprecated
class _WebKitCSSTransformValue extends _CssValueList {
  // To suppress missing implicit constructor warnings.
  factory _WebKitCSSTransformValue._() { throw new UnsupportedError("Not supported"); }


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

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

  @Deprecated("Internal Use Only")
  _WebKitCSSTransformValue.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('WindowTimers')
@Experimental() // untriaged
abstract class _WindowTimers extends DartHtmlDomObject {
  // To suppress missing implicit constructor warnings.
  factory _WindowTimers._() { throw new UnsupportedError("Not supported"); }

  @DomName('WindowTimers.clearInterval')
  @DocsEditable()
  @Experimental() // untriaged
  void _clearInterval(int handle);

  @DomName('WindowTimers.clearTimeout')
  @DocsEditable()
  @Experimental() // untriaged
  void _clearTimeout(int handle);

  @DomName('WindowTimers.setInterval')
  @DocsEditable()
  @Experimental() // untriaged
  int _setInterval(Object handler, int timeout);

  @DomName('WindowTimers.setTimeout')
  @DocsEditable()
  @Experimental() // untriaged
  int _setTimeout(Object handler, int timeout);

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


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

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

  @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]
 * (http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#image-sources-for-2d-rendering-contexts)
 * from WHATWG.
 * * [Drawing images]
 * (http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-drawimage)
 * from WHATWG.
 */
abstract class CanvasImageSource {}
// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


/**
 * Top-level container for a browser tab or window.
 *
 * In a web browser, a [WindowBase] object represents any browser window. This
 * object contains the window's state and its relation to other
 * windows, such as which window opened this window.
 *
 * **Note:** This class represents any window, while [Window] is
 * used to access the properties and content of the current window or tab.
 *
 * ## See also
 *
 * * [Window]
 *
 * ## Other resources
 *
 * * [DOM Window](https://developer.mozilla.org/en-US/docs/DOM/window) from MDN.
 * * [Window](http://www.w3.org/TR/Window/) from the W3C.
 */
abstract class WindowBase implements EventTarget {
  // Fields.

  /**
   * The current location of this window.
   *
   *     Location currentLocation = window.location;
   *     print(currentLocation.href); // 'http://www.example.com:80/'
   */
  LocationBase get location;

  /**
   * The current session history for this window.
   *
   * ## Other resources
   *
   * * [Session history and navigation specification]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/history.html)
   * from WHATWG.
   */
  HistoryBase get history;

  /**
   * Indicates whether this window has been closed.
   *
   *     print(window.closed); // 'false'
   *     window.close();
   *     print(window.closed); // 'true'
   */
  bool get closed;

  /**
   * A reference to the window that opened this one.
   *
   *     Window thisWindow = window;
   *     WindowBase otherWindow = thisWindow.open('http://www.example.com/', 'foo');
   *     print(otherWindow.opener == thisWindow); // 'true'
   */
  WindowBase get opener;

  /**
   * A reference to the parent of this window.
   *
   * If this [WindowBase] has no parent, [parent] will return a reference to
   * the [WindowBase] itself.
   *
   *     IFrameElement myIFrame = new IFrameElement();
   *     window.document.body.elements.add(myIFrame);
   *     print(myIframe.contentWindow.parent == window) // 'true'
   *
   *     print(window.parent == window) // 'true'
   */
  WindowBase get parent;

  /**
   * A reference to the topmost window in the window hierarchy.
   *
   * If this [WindowBase] is the topmost [WindowBase], [top] will return a
   * reference to the [WindowBase] itself.
   *
   *     // Add an IFrame to the current window.
   *     IFrameElement myIFrame = new IFrameElement();
   *     window.document.body.elements.add(myIFrame);
   *
   *     // Add an IFrame inside of the other IFrame.
   *     IFrameElement innerIFrame = new IFrameElement();
   *     myIFrame.elements.add(innerIFrame);
   *
   *     print(myIframe.contentWindow.top == window) // 'true'
   *     print(innerIFrame.contentWindow.top == window) // 'true'
   *
   *     print(window.top == window) // 'true'
   */
  WindowBase get top;

  // Methods.
  /**
   * Closes the window.
   *
   * This method should only succeed if the [WindowBase] object is
   * **script-closeable** and the window calling [close] is allowed to navigate
   * the window.
   *
   * A window is script-closeable if it is either a window
   * that was opened by another window, or if it is a window with only one
   * document in its history.
   *
   * A window might not be allowed to navigate, and therefore close, another
   * window due to browser security features.
   *
   *     var other = window.open('http://www.example.com', 'foo');
   *     // Closes other window, as it is script-closeable.
   *     other.close();
   *     print(other.closed()); // 'true'
   *
   *     window.location('http://www.mysite.com', 'foo');
   *     // Does not close this window, as the history has changed.
   *     window.close();
   *     print(window.closed()); // 'false'
   *
   * See also:
   *
   * * [Window close discussion](http://www.w3.org/TR/html5/browsers.html#dom-window-close) from the W3C
   */
  void close();

  /**
   * Sends a cross-origin message.
   *
   * ## Other resources
   *
   * * [window.postMessage]
   * (https://developer.mozilla.org/en-US/docs/Web/API/Window.postMessage) from
   * MDN.
   * * [Cross-document messaging]
   * (http://www.whatwg.org/specs/web-apps/current-work/multipage/web-messaging.html)
   * from WHATWG.
   */
  void postMessage(var message, String targetOrigin, [List messagePorts]);
}

abstract class LocationBase {
  void set href(String val);
}

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


/** A Set that stores the CSS class names for an element. */
abstract class CssClassSet implements Set<String> {

  /**
   * Adds the class [value] to the element if it is not on it, removes it if it
   * is.
   *
   * If [shouldAdd] is true, then we always add that [value] to the element. If
   * [shouldAdd] is false then we always remove [value] from the element.
   *
   * 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::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.JsObjectImpl) {
      // 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/JsObjectImpl.');
    }

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

  /** Caculated value of what the estimated charCode is for this event. */
  int _shadowCharCode;

  /** Caculated value of what the estimated keyCode is for this event. */
  int _shadowKeyCode;

  /** Caculated value of what the estimated keyCode is for this event. */
  int get keyCode => _shadowKeyCode;

  /** Caculated value of what the estimated charCode is for this event. */
  int get charCode => this.type == 'keypress' ? _shadowCharCode : 0;

  /** Caculated value of whether the alt key is pressed is for this event. */
  bool get altKey => _shadowAltKey;

  /** Caculated value of what the estimated keyCode is for this event. */
  int get which => keyCode;

  /** Accessor to the underlying keyCode value is the parent event. */
  int get _realKeyCode => _parent.keyCode;

  /** Accessor to the underlying charCode value is the parent event. */
  int get _realCharCode => _parent.charCode;

  /** Accessor to the underlying altKey value is the parent event. */
  bool get _realAltKey => _parent.altKey;

  /** Shadows on top of the parent's currentTarget. */
  EventTarget _currentTarget;

  /** Construct a KeyEvent with [parent] as the event we're emulating. */
  KeyEvent.wrap(KeyboardEvent parent): super(parent) {
    _parent = parent;
    _shadowAltKey = _realAltKey;
    _shadowCharCode = _realCharCode;
    _shadowKeyCode = _realKeyCode;
    _currentTarget = _parent.currentTarget == null? window :
        _parent.currentTarget;
  }

  /** Programmatically create a new KeyEvent (and KeyboardEvent). */
   factory KeyEvent(String type,
      {Window view, bool canBubble: true, bool cancelable: true, int keyCode: 0,
      int charCode: 0, int keyLocation: 1, bool ctrlKey: false,
      bool altKey: false, bool shiftKey: false, bool metaKey: false,
       EventTarget currentTarget}) {
     var parent = new KeyboardEvent(type, view: view, canBubble: canBubble,
        cancelable: cancelable, keyLocation: keyLocation, ctrlKey: ctrlKey,
        altKey: altKey, shiftKey: shiftKey, metaKey: metaKey);
     var keyEvent = new KeyEvent.wrap(parent);
     keyEvent._shadowAltKey = altKey;
     keyEvent._shadowCharCode = charCode;
     keyEvent._shadowKeyCode = keyCode;
     keyEvent._currentTarget = currentTarget == null ? window : currentTarget;
     return keyEvent;
   }

  /** Accessor to provide a stream of KeyEvents on the desired target. */
  static EventStreamProvider<KeyEvent> keyDownEvent =
    new _KeyboardEventHandler('keydown');
  /** Accessor to provide a stream of KeyEvents on the desired target. */
  static EventStreamProvider<KeyEvent> keyUpEvent =
    new _KeyboardEventHandler('keyup');
  /** Accessor to provide a stream of KeyEvents on the desired target. */
  static EventStreamProvider<KeyEvent> keyPressEvent =
    new _KeyboardEventHandler('keypress');

  /** The currently registered target for this event. */
  EventTarget get currentTarget => _currentTarget;

  /** Accessor to the clipboardData available for this event. */
  DataTransfer get clipboardData => _parent.clipboardData;
  /** True if the ctrl key is pressed during this event. */
  bool get ctrlKey => _parent.ctrlKey;
  int get detail => _parent.detail;
  /**
   * Accessor to the part of the keyboard that the key was pressed from (one of
   * KeyLocation.STANDARD, KeyLocation.RIGHT, KeyLocation.LEFT,
   * KeyLocation.NUMPAD, KeyLocation.MOBILE, KeyLocation.JOYSTICK).
   */
  int get keyLocation => _parent.keyLocation;
  Point get layer => _parent.layer;
  /** True if the Meta (or Mac command) key is pressed during this event. */
  bool get metaKey => _parent.metaKey;
  Point get page => _parent.page;
  /** True if the shift key was pressed during this event. */
  bool get shiftKey => _parent.shiftKey;
  Window get view => _parent.view;
  void _initUIEvent(String type, bool canBubble, bool cancelable,
      Window view, int detail) {
    throw new UnsupportedError("Cannot initialize a UI Event from a KeyEvent.");
  }
  String get _shadowKeyIdentifier => _parent._keyIdentifier;

  int get _charCode => charCode;
  int get _keyCode => keyCode;
  String get _keyIdentifier {
    throw new UnsupportedError("keyIdentifier is unsupported.");
  }
  void _initKeyboardEvent(String type, bool canBubble, bool cancelable,
      Window view, String keyIdentifier, int keyLocation, bool ctrlKey,
      bool altKey, bool shiftKey, bool metaKey) {
    throw new UnsupportedError(
        "Cannot initialize a KeyboardEvent from a KeyEvent.");
  }
  int get _layerX => throw new UnsupportedError('Not applicable to KeyEvent');
  int get _layerY => throw new UnsupportedError('Not applicable to KeyEvent');
  int get _pageX => throw new UnsupportedError('Not applicable to KeyEvent');
  int get _pageY => throw new UnsupportedError('Not applicable to KeyEvent');
  @Experimental() // untriaged
  bool getModifierState(String keyArgument) => throw new UnimplementedError();
  @Experimental() // untriaged
  int get location => throw new UnimplementedError();
  @Experimental() // untriaged
  bool get repeat => throw new UnimplementedError();
  dynamic get _get_view => throw new UnimplementedError();
}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


class Platform {
  /**
   * Returns true if dart:typed_data types are supported on this
   * browser.  If false, using these types will generate a runtime
   * error.
   */
  static final supportsTypedData = true;

  /**
   * Returns true if SIMD types in dart:typed_data types are supported
   * on this browser.  If false, using these types will generate a runtime
   * error.
   */
  static final supportsSimd = true;
}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


/**
 * Helper class to implement custom events which wrap DOM events.
 */
class _WrappedEvent implements Event {
  /** 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;

  DataTransfer get clipboardData => wrapped.clipboardData;

  EventTarget get currentTarget => wrapped.currentTarget;

  bool get defaultPrevented => wrapped.defaultPrevented;

  int get eventPhase => wrapped.eventPhase;

  EventTarget get target => wrapped.target;

  int get timeStamp => wrapped.timeStamp;

  String get type => wrapped.type;

  void _initEvent(String eventTypeArg, bool canBubbleArg,
      bool cancelableArg) {
    throw new UnsupportedError(
        'Cannot initialize this Event.');
  }

  void preventDefault() {
    wrapped.preventDefault();
  }

  void stopImmediatePropagation() {
    wrapped.stopImmediatePropagation();
  }

  void stopPropagation() {
    wrapped.stopPropagation();
  }

  /**
   * A pointer to the element whose CSS selector matched within which an event
   * was fired. If this Event was not associated with any Event delegation,
   * accessing this value will throw an [UnsupportedError].
   */
  Element get matchingTarget {
    if (_selector == null) {
      throw new UnsupportedError('Cannot call matchingTarget if this Event did'
          ' not arise as a result of event delegation.');
    }
    var currentTarget = this.currentTarget;
    var target = this.target;
    var matchedTarget;
    do {
      if (target.matches(_selector)) return target;
      target = target.parent;
    } while (target != null && target != currentTarget.parent);
    throw new StateError('No selector matched for populating matchedTarget.');
  }

  /**
   * This event's path, taking into account shadow DOM.
   *
   * ## Other resources
   *
   * * [Shadow DOM extensions to Event]
   * (http://w3c.github.io/webcomponents/spec/shadow/#extensions-to-event) from
   * W3C.
   */
  // https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/shadow/index.html#extensions-to-event
  @Experimental()
  List<Node> get path => wrapped.path;
}
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.


_wrapZone(callback(arg)) {
  // For performance reasons avoid wrapping if we are in the root zone.
  if (Zone.current == Zone.ROOT) return callback;
  if (callback == null) return null;
  return Zone.current.bindUnaryCallback(callback, runGuarded: true);
}

_wrapBinaryZone(callback(arg1, arg2)) {
  if (Zone.current == Zone.ROOT) return callback;
  if (callback == null) return null;
  return Zone.current.bindBinaryCallback(callback, runGuarded: true);
}

/**
 * Alias for [querySelector]. Note this function is deprecated because its
 * semantics will be changing in the future.
 */
@deprecated
@Experimental()
Element query(String relativeSelectors) => document.query(relativeSelectors);
/**
 * Alias for [querySelectorAll]. Note this function is deprecated because its
 * semantics will be changing in the future.
 */
@deprecated
@Experimental()
ElementList<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) => _blink.Blink_Utils.spawnDomUri(uri);

  // The following methods were added for debugger integration to make working
  // with the Dart C mirrors API simpler.
  // TODO(jacobr): consider moving them to a separate library.
  // If Dart supported dynamic code injection, we would only inject this code
  // when the debugger is invoked.

  /**
   * Strips the private secret prefix from member names of the form
   * someName@hash.
   */
  static String stripMemberName(String name) {
    int endIndex = name.indexOf('@');
    return endIndex > 0 ? name.substring(0, endIndex) : name;
  }

  /**
   * Takes a list containing variable names and corresponding values and
   * returns a map from normalized names to values. Variable names are assumed
   * to have list offsets 2*n values at offset 2*n+1. This method is required
   * because Dart_GetLocalVariables returns a list instead of an object that
   * can be queried to lookup names and values.
   */
  static Map<String, dynamic> createLocalVariablesMap(List localVariables) {
    var map = {};
    for (int i = 0; i < localVariables.length; i+=2) {
      map[stripMemberName(localVariables[i])] = localVariables[i+1];
    }
    return map;
  }

  static _ConsoleVariables _consoleTempVariables = new _ConsoleVariables();

  /**
   * Takes an [expression] and a list of [local] variable and returns an
   * expression for a closure with a body matching the original expression
   * where locals are passed in as arguments. Returns a list containing the
   * String expression for the closure and the list of arguments that should
   * be passed to it. The expression should then be evaluated using
   * Dart_EvaluateExpr which will generate a closure that should be invoked
   * with the list of arguments passed to this method.
   *
   * For example:
   * <code>
   * _consoleTempVariables = {'a' : someValue, 'b': someOtherValue}
   * wrapExpressionAsClosure("foo + bar + a", ["bar", 40, "foo", 2], true)
   * </code>
   * will return:
   * <code>
   * ["""(final $consoleVariables, final bar, final foo, final a, final b) =>
   * (foo + bar + a
   * )""",
   * [_consoleTempVariables, 40, 2, someValue, someOtherValue]]
   * </code>
   */
  static List wrapExpressionAsClosure(String expression, List locals,
      bool includeCommandLineAPI) {
    var args = {};
    var sb = new StringBuffer("(");
    addArg(arg, value) {
      arg = stripMemberName(arg);
      if (args.containsKey(arg)) return;
      // We ignore arguments with the name 'this' rather than throwing an
      // exception because Dart_GetLocalVariables includes 'this' and it
      // is more convenient to filter it out here than from C++ code.
      // 'this' needs to be handled by calling Dart_EvaluateExpr with
      // 'this' as the target rather than by passing it as an argument.
      if (arg == 'this') return;
      if (args.isNotEmpty) {
        sb.write(", ");
      }
      sb.write("final $arg");
      args[arg] = value;
    }

    if (includeCommandLineAPI) {
      addArg("\$consoleVariables", _consoleTempVariables);

      // FIXME: use a real Dart tokenizer. The following regular expressions
      // only allow setting variables at the immediate start of the expression
      // to limit the number of edge cases we have to handle.

      // Match expressions that start with "var x"
      final _VARIABLE_DECLARATION = new RegExp("^(\\s*)var\\s+(\\w+)");
      // Match expressions that start with "someExistingConsoleVar ="
      final _SET_VARIABLE = new RegExp("^(\\s*)(\\w+)(\\s*=)");
      // Match trailing semicolons.
      final _ENDING_SEMICOLONS = new RegExp("(;\\s*)*\$");
      expression = expression.replaceAllMapped(_VARIABLE_DECLARATION,
          (match) {
            var variableName = match[2];
            // Set the console variable if it isn't already set.
            if (!_consoleTempVariables._data.containsKey(variableName)) {
              _consoleTempVariables._data[variableName] = null;
            }
            return "${match[1]}\$consoleVariables.${variableName}";
          });

      expression = expression.replaceAllMapped(_SET_VARIABLE,
          (match) {
            var variableName = match[2];
            // Only rewrite if the name matches an existing console variable.
            if (_consoleTempVariables._data.containsKey(variableName)) {
              return "${match[1]}\$consoleVariables.${variableName}${match[3]}";
            } else {
              return match[0];
            }
          });

      // We only allow dart expressions not Dart statements. Silently remove
      // trailing semicolons the user might have added by accident to reduce the
      // number of spurious compile errors.
      expression = expression.replaceFirst(_ENDING_SEMICOLONS, "");
    }

    if (locals != null) {
      for (int i = 0; i < locals.length; i+= 2) {
        addArg(locals[i], locals[i+1]);
      }
    }
    // Inject all the already defined console variables.
    _consoleTempVariables._data.forEach(addArg);

    // TODO(jacobr): remove the parentheses around the expresson once
    // dartbug.com/13723 is fixed. Currently we wrap expression in parentheses
    // to ensure only valid Dart expressions are allowed. Otherwise the DartVM
    // quietly ignores trailing Dart statements resulting in user confusion
    // when part of an invalid expression they entered is ignored.
    sb..write(') => (\n$expression\n)');
    return [sb.toString(), args.values.toList(growable: false)];
  }

  static String _getShortSymbolName(Symbol symbol,
                                    DeclarationMirror declaration) {
    var name = MirrorSystem.getName(symbol);
    if (declaration is MethodMirror) {
      if (declaration.isSetter && name[name.length-1] == "=") {
        return name.substring(0, name.length-1);
      }
      if (declaration.isConstructor) {
        return name.substring(name.indexOf('.') + 1);
      }
    }
    return name;
  }

  /**
   * Returns a list of completions to use if the receiver is o.
   */
  static List<String> getCompletions(o) {
    MirrorSystem system = currentMirrorSystem();
    var completions = new Set<String>();
    addAll(Map<Symbol, dynamic> map, bool isStatic) {
      map.forEach((symbol, mirror) {
        if (mirror.isStatic == isStatic && !mirror.isPrivate) {
          var name = MirrorSystem.getName(symbol);
          if (mirror is MethodMirror && mirror.isSetter)
            name = name.substring(0, name.length - 1);
          completions.add(name);
        }
      });
    }

    addForClass(ClassMirror mirror, bool isStatic) {
      if (mirror == null)
        return;
      addAll(mirror.declarations, isStatic);
      if (mirror.superclass != null)
        addForClass(mirror.superclass, isStatic);
      for (var interface in mirror.superinterfaces) {
        addForClass(interface, isStatic);
      }
    }

    if (o is Type) {
      addForClass(reflectClass(o), true);
    } else {
      addForClass(reflect(o).type, false);
    }
    return completions.toList(growable: false);
  }

  /**
   * Adds all candidate String completitions from [declarations] to [output]
   * filtering based on [staticContext] and [includePrivate].
   */
  static void _getCompletionsHelper(ClassMirror classMirror,
      bool staticContext, LibraryMirror libraryMirror, Set<String> output) {
    bool includePrivate = libraryMirror == classMirror.owner;
    classMirror.declarations.forEach((symbol, declaration) {
      if (!includePrivate && declaration.isPrivate) return;
      if (declaration is VariableMirror) {
        if (staticContext != declaration.isStatic) return;
      } else if (declaration is MethodMirror) {
        if (declaration.isOperator) return;
        if (declaration.isConstructor) {
          if (!staticContext) return;
          var name = MirrorSystem.getName(declaration.constructorName);
          if (name.isNotEmpty) output.add(name);
          return;
        }
        if (staticContext != declaration.isStatic) return;
      } else if (declaration is TypeMirror) {
        return;
      }
      output.add(_getShortSymbolName(symbol, declaration));
    });

    if (!staticContext) {
      for (var interface in classMirror.superinterfaces) {
        _getCompletionsHelper(interface, staticContext,
            libraryMirror, output);
      }
      if (classMirror.superclass != null) {
        _getCompletionsHelper(classMirror.superclass, staticContext,
            libraryMirror, output);
      }
    }
  }

  static void _getLibraryCompletionsHelper(
      LibraryMirror library, bool includePrivate, Set<String> output) {
    library.declarations.forEach((symbol, declaration) {
      if (!includePrivate && declaration.isPrivate) return;
      output.add(_getShortSymbolName(symbol, declaration));
    });
  }

  static LibraryMirror getLibraryMirror(String url) =>
      currentMirrorSystem().libraries[Uri.parse(url)];

  /**
   * Get code completions for [o] only showing privates from [libraryUrl].
   */
  static List<String> getObjectCompletions(o, String libraryUrl) {
    var classMirror;
    bool staticContext;
    if (o is Type) {
      classMirror = reflectClass(o);
      staticContext = true;
    } else {
      classMirror = reflect(o).type;
      staticContext = false;
    }
    var names = new Set<String>();
    getClassCompletions(classMirror, names, staticContext, libraryUrl);
    return names.toList()..sort();
  }

  static void getClassCompletions(ClassMirror classMirror, Set<String> names,
      bool staticContext, String libraryUrl) {
    LibraryMirror libraryMirror = getLibraryMirror(libraryUrl);
    _getCompletionsHelper(classMirror, staticContext, libraryMirror, names);
  }

  static List<String> getLibraryCompletions(String url) {
    var names = new Set<String>();
    _getLibraryCompletionsHelper(getLibraryMirror(url), true, names);
    return names.toList();
  }

  /**
   * Get valid code completitions from within a library and all libraries
   * imported by that library.
   */
  static List<String> getLibraryCompletionsIncludingImports(String url) {
    var names = new Set<String>();
    var libraryMirror = getLibraryMirror(url);
    _getLibraryCompletionsHelper(libraryMirror, true, names);
    for (var dependency in libraryMirror.libraryDependencies) {
      if (dependency.isImport) {
        if (dependency.prefix == null) {
          _getLibraryCompletionsHelper(dependency.targetLibrary, false, names);
        } else {
          names.add(MirrorSystem.getName(dependency.prefix));
        }
      }
    }
    return names.toList();
  }

  static final SIDE_EFFECT_FREE_LIBRARIES = new Set<String>()
      ..add('dart:html')
      ..add('dart:indexed_db')
      ..add('dart:svg')
      ..add('dart:typed_data')
      ..add('dart:web_audio')
      ..add('dart:web_gl')
      ..add('dart:web_sql');

  static LibraryMirror _getLibrary(MethodMirror methodMirror) {
    var owner = methodMirror.owner;
    if (owner is ClassMirror) {
      return owner;
    } else if (owner is LibraryMirror) {
      return owner;
    }
    return null;
  }

  /**
   * For parity with the JavaScript debugger, we treat some getters as if
   * they are fields so that users can see their values immediately.
   * This matches JavaScript's behavior for getters on DOM objects.
   * In the future we should consider adding an annotation to tag getters
   * in user libraries as side effect free.
   */
  static bool _isSideEffectFreeGetter(MethodMirror methodMirror,
      LibraryMirror libraryMirror) {
    // This matches JavaScript behavior. We should consider displaying
    // getters for all dart platform libraries rather than just the DOM
    // libraries.
    return libraryMirror.uri.scheme == 'dart' &&
        SIDE_EFFECT_FREE_LIBRARIES.contains(libraryMirror.uri.toString());
  }

  /**
   * Whether we should treat a property as a field for the purposes of the
   * debugger.
   */
  static bool treatPropertyAsField(MethodMirror methodMirror,
      LibraryMirror libraryMirror) {
    return (methodMirror.isGetter || methodMirror.isSetter) &&
          (methodMirror.isSynthetic ||
              _isSideEffectFreeGetter(methodMirror,libraryMirror));
  }

  // TODO(jacobr): generate more concise function descriptions instead of
  // dumping the entire function source.
  static String describeFunction(function) {
    if (function is _Trampoline) return function._methodMirror.source;
    try {
      var mirror = reflect(function);
      return mirror.function.source;
    } catch (e) {
      return function.toString();
    }
  }

  static List getInvocationTrampolineDetails(_Trampoline method) {
    var loc = method._methodMirror.location;
    return [loc.line, loc.column, loc.sourceUri.toString(),
        MirrorSystem.getName(method._selector)];
  }

  static List getLibraryProperties(String libraryUrl, bool ownProperties,
      bool accessorPropertiesOnly) {
    var properties = new Map<String, _Property>();
    var libraryMirror = getLibraryMirror(libraryUrl);
    _addInstanceMirrors(libraryMirror, libraryMirror,
        libraryMirror.declarations,
        ownProperties, accessorPropertiesOnly, false, false,
        properties);
    if (!accessorPropertiesOnly) {
      // We need to add class properties for all classes in the library.
      libraryMirror.declarations.forEach((symbol, declarationMirror) {
        if (declarationMirror is ClassMirror) {
          var name = MirrorSystem.getName(symbol);
          if (declarationMirror.hasReflectedType
              && !properties.containsKey(name)) {
            properties[name] = new _Property(name)
                ..value = declarationMirror.reflectedType;
          }
        }
      });
    }
    return packageProperties(properties);
  }

  static List getObjectProperties(o, bool ownProperties,
      bool accessorPropertiesOnly) {
    var properties = new Map<String, _Property>();
    var names = new Set<String>();
    var objectMirror = reflect(o);
    var classMirror = objectMirror.type;
    _addInstanceMirrors(objectMirror, classMirror.owner,
        classMirror.instanceMembers,
        ownProperties, accessorPropertiesOnly, false, true,
        properties);
    return packageProperties(properties);
  }

  static List getObjectClassProperties(o, bool ownProperties,
      bool accessorPropertiesOnly) {
    var properties = new Map<String, _Property>();
    var objectMirror = reflect(o);
    var classMirror = objectMirror.type;
    _addInstanceMirrors(objectMirror, classMirror.owner,
        classMirror.instanceMembers,
        ownProperties, accessorPropertiesOnly, true, false,
        properties);
    _addStatics(classMirror, properties, accessorPropertiesOnly);
    return packageProperties(properties);
  }

  static List getClassProperties(Type t, bool ownProperties,
      bool accessorPropertiesOnly) {
    var properties = new Map<String, _Property>();
    var classMirror = reflectClass(t);
    _addStatics(classMirror, properties, accessorPropertiesOnly);
    return packageProperties(properties);
  }

  static void _addStatics(ClassMirror classMirror,
                          Map<String, _Property> properties,
                          bool accessorPropertiesOnly) {
    var libraryMirror = classMirror.owner;
    classMirror.declarations.forEach((symbol, declaration) {
      var name = _getShortSymbolName(symbol, declaration);
      if (name.isEmpty) return;
      if (declaration is VariableMirror) {
        if (accessorPropertiesOnly) return;
        if (!declaration.isStatic) return;
        properties.putIfAbsent(name, () => new _Property(name))
            ..value = classMirror.getField(symbol).reflectee
            ..writable = !declaration.isFinal && !declaration.isConst;
      } else if (declaration is MethodMirror) {
        MethodMirror methodMirror = declaration;
        // FIXMEDART: should we display constructors?
        if (methodMirror.isConstructor) return;
        if (!methodMirror.isStatic) return;
        if (accessorPropertiesOnly) {
          if (methodMirror.isRegularMethod ||
              treatPropertyAsField(methodMirror, libraryMirror)) {
            return;
          }
        } else if (!methodMirror.isRegularMethod &&
            !treatPropertyAsField(methodMirror, libraryMirror)) {
          return;
        }
        var property = properties.putIfAbsent(name, () => new _Property(name));
        _fillMethodMirrorProperty(libraryMirror, classMirror, methodMirror,
            symbol, accessorPropertiesOnly, property);
      }
    });
  }

  static void _fillMethodMirrorProperty(LibraryMirror libraryMirror,
        methodOwner, MethodMirror methodMirror, Symbol symbol,
        bool accessorPropertiesOnly, _Property property) {
    if (methodMirror.isRegularMethod) {
      property
          ..value = new _MethodTrampoline(methodOwner, methodMirror, symbol)
          ..isMethod = true;
    } else if (methodMirror.isGetter) {
      if (treatPropertyAsField(methodMirror, libraryMirror)) {
        try {
          property.value = methodOwner.getField(symbol).reflectee;
        } catch (e) {
          property
              ..wasThrown = true
              ..value = e;
        }
      } else if (accessorPropertiesOnly) {
        property.getter = new _GetterTrampoline(methodOwner,
            methodMirror, symbol);
      }
    } else if (methodMirror.isSetter) {
      if (accessorPropertiesOnly &&
          !treatPropertyAsField(methodMirror, libraryMirror)) {
        property.setter = new _SetterTrampoline(methodOwner,
            methodMirror, MirrorSystem.getSymbol(property.name, libraryMirror));
      }
      property.writable = true;
    }
  }

  /**
   * Helper method that handles collecting up properties from classes
   * or libraries using the filters [ownProperties], [accessorPropertiesOnly],
   * [hideFields], and [hideMethods] to determine which properties are
   * collected. [accessorPropertiesOnly] specifies whether all properties
   * should be returned or just accessors. [hideFields] specifies whether
   * fields should be hidden. hideMethods specifies whether methods should be
   * shown or hidden. [ownProperties] is not currently used but is part of the
   * Blink devtools API for enumerating properties.
   */
  static void _addInstanceMirrors(
      ObjectMirror objectMirror,
      LibraryMirror libraryMirror,
      Map<Symbol, Mirror> declarations,
      bool ownProperties, bool accessorPropertiesOnly,
      bool hideFields, bool hideMethods,
      Map<String, _Property> properties) {
    declarations.forEach((symbol, declaration) {
      if (declaration is TypedefMirror || declaration is ClassMirror) return;
      var name = _getShortSymbolName(symbol, declaration);
      if (name.isEmpty) return;
      bool isField = declaration is VariableMirror ||
          (declaration is MethodMirror &&
              treatPropertyAsField(declaration, libraryMirror));
      if ((isField && hideFields) || (hideMethods && !isField)) return;
      if (accessorPropertiesOnly) {
        if (declaration is VariableMirror || declaration.isRegularMethod ||
            isField) {
          return;
        }
      } else if (declaration is MethodMirror &&
          (declaration.isGetter || declaration.isSetter) &&
          !treatPropertyAsField(declaration, libraryMirror)) {
        return;
      }
      var property = properties.putIfAbsent(name, () => new _Property(name));
      if (declaration is VariableMirror) {
        property
            ..value = objectMirror.getField(symbol).reflectee
            ..writable = !declaration.isFinal && !declaration.isConst;
        return;
      }
      _fillMethodMirrorProperty(libraryMirror, objectMirror, declaration,
          symbol, accessorPropertiesOnly, property);
    });
  }

  /**
   * Flatten down the properties data structure into a List that is easy to
   * access from native code.
   */
  static List packageProperties(Map<String, _Property> properties) {
    var ret = [];
    for (var property in properties.values) {
      ret.addAll([property.name,
                  property.setter,
                  property.getter,
                  property.value,
                  property.hasValue,
                  property.writable,
                  property.isMethod,
                  property.isOwn,
                  property.wasThrown]);
    }
    return ret;
  }

  /**
   * Get a property, returning null if the property does not exist.
   * For private property names, we attempt to resolve the property in the
   * context of each library that the property name could be associated with.
   */
  static getObjectPropertySafe(o, String propertyName) {
    var objectMirror = reflect(o);
    var classMirror = objectMirror.type;
    if (propertyName.startsWith("_")) {
      var attemptedLibraries = new Set<LibraryMirror>();
      while (classMirror != null) {
        LibraryMirror library = classMirror.owner;
        if (!attemptedLibraries.contains(library)) {
          try {
            return objectMirror.getField(
                MirrorSystem.getSymbol(propertyName, library)).reflectee;
          } catch (e) { }
          attemptedLibraries.add(library);
        }
        classMirror = classMirror.superclass;
      }
      return null;
    }
    try {
      return objectMirror.getField(
          MirrorSystem.getSymbol(propertyName)).reflectee;
    } catch (e) {
      return null;
    }
  }

  /**
   * Helper to wrap the inspect method on InjectedScriptHost to provide the
   * inspect method required for the
   */
  static List consoleApi(host) {
    return [
        "inspect",
        (o) {
          host.callMethod("inspect", [o]);
          return o;
        },
        "dir",
        window().console.dir,
        "dirxml",
        window().console.dirxml
        // FIXME: add copy method.
        ];
  }

  static List getMapKeyList(Map map) => map.keys.toList();

  static bool isNoSuchMethodError(obj) => obj is NoSuchMethodError;

  static void register(Document document, String tag, Type type,
      String extendsTagName) {
    var nativeClass = _validateCustomType(type);

    if (extendsTagName == null) {
      if (nativeClass.reflectedType != HtmlElement) {
        throw new UnsupportedError('Class must provide extendsTag if base '
            'native class is not HTMLElement');
      }
    }

    _register(document, tag, type, extendsTagName);
  }

  static void _register(Document document, String tag, Type customType,
    String extendsTagName) => _blink.Blink_Utils.register(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) =>
    _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 => _blink.Blink_DOMWindowCrossFrame.get_history(this);
  LocationBase get location => _blink.Blink_DOMWindowCrossFrame.get_location(this);
  bool get closed => _blink.Blink_DOMWindowCrossFrame.get_closed(this);
  WindowBase get opener => _blink.Blink_DOMWindowCrossFrame.get_opener(this);
  WindowBase get parent => _blink.Blink_DOMWindowCrossFrame.get_parent(this);
  WindowBase get top => _blink.Blink_DOMWindowCrossFrame.get_top(this);

  // Methods.
  void close() => _blink.Blink_DOMWindowCrossFrame.close(this);
  void postMessage(/*SerializedScriptValue*/ message, String targetOrigin, [List messagePorts]) =>
    _blink.Blink_DOMWindowCrossFrame.postMessage(this, message, targetOrigin, messagePorts);

  // Implementation support.
  String get typeName => "Window";

  // TODO(efortuna): Remove this method. dartbug.com/16814
  Events get on => throw new UnsupportedError(
    'You can only attach EventListeners to your own window.');
  // TODO(efortuna): Remove this method. dartbug.com/16814
  void _addEventListener([String type, EventListener listener, bool useCapture])
      => throw new UnsupportedError(
    'You can only attach EventListeners to your own window.');
  // TODO(efortuna): Remove this method. dartbug.com/16814
  void addEventListener(String type, EventListener listener, [bool useCapture])
      => throw new UnsupportedError(
    'You can only attach EventListeners to your own window.');
  // TODO(efortuna): Remove this method. dartbug.com/16814
  bool dispatchEvent(Event event) => throw new UnsupportedError(
    'You can only attach EventListeners to your own window.');
  // TODO(efortuna): Remove this method. dartbug.com/16814
  void _removeEventListener([String type, EventListener listener,
      bool useCapture]) => throw new UnsupportedError(
    'You can only attach EventListeners to your own window.');
  // TODO(efortuna): Remove this method. dartbug.com/16814
  void removeEventListener(String type, EventListener listener,
      [bool useCapture]) => throw new UnsupportedError(
    'You can only attach EventListeners to your own window.');
}

class _HistoryCrossFrame extends DartHtmlDomObject implements HistoryBase {
  _HistoryCrossFrame.internal();

  // Methods.
  void back() => _blink.Blink_HistoryCrossFrame.back(this);
  void forward() => _blink.Blink_HistoryCrossFrame.forward(this);
  void go(int distance) => _blink.Blink_HistoryCrossFrame.go(this, distance);

  // Implementation support.
  String get typeName => "History";
}

class _LocationCrossFrame extends DartHtmlDomObject implements LocationBase {
  _LocationCrossFrame.internal();

  // Fields.
  set href(String h) => _blink.Blink_LocationCrossFrame.set_href(this, h);

  // Implementation support.
  String get typeName => "Location";
}

class _DOMStringMap extends DartHtmlDomObject implements Map<String, String> {
  _DOMStringMap.internal();

  bool containsValue(String value) => Maps.containsValue(this, value);
  bool containsKey(String key) => _blink.Blink_DOMStringMap.containsKey(this, key);
  String operator [](String key) => _blink.Blink_DOMStringMap.item(this, key);
  void operator []=(String key, String value) => _blink.Blink_DOMStringMap.setItem(this, key, value);
  String putIfAbsent(String key, String ifAbsent()) => Maps.putIfAbsent(this, key, ifAbsent);
  String remove(String key) => _blink.Blink_DOMStringMap.remove(this, key);
  void clear() => Maps.clear(this);
  void forEach(void f(String key, String value)) => Maps.forEach(this, f);
  Iterable<String> get keys => _blink.Blink_DOMStringMap.get_keys(this);
  Iterable<String> get values => Maps.getValues(this);
  int get length => Maps.length(this);
  bool get isEmpty => Maps.isEmpty(this);
  bool get isNotEmpty => Maps.isNotEmpty(this);
  void addAll(Map<String, String> other) {
    other.forEach((key, value) => this[key] = value);
  }
}

// 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 {
}
