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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  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) {
    return __getter__(index);
  }

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

// WARNING: Do not edit - generated code.


@DomName('DatabaseCallback')
// http://www.w3.org/TR/webdatabase/#databasecallback
@Experimental() // deprecated
typedef void DatabaseCallback(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_();
  }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  js.JsObject blink_jsObject;

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

  DomException.internal_() { }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  _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.
   */
  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 {
}
