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

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

import 'dart:async';
import 'dart:collection';
import 'dart:_internal' hide Symbol, deprecated;
import 'dart:html_common';
import 'dart:indexed_db';
import 'dart:indexed_db' show indexed_dbBlinkMap;
import 'dart:isolate';
import 'dart:js' as js;
import "dart:convert";
import 'dart:math';
// TODO(vsm): Remove this when we can do the proper checking in
// native code for custom elements.
import 'dart:mirrors';
import 'dart:nativewrappers';
import 'dart:typed_data';
import 'dart:web_gl' as gl;
import 'dart:web_gl' show web_glBlinkMap;
import 'dart:web_sql';
// Not actually used, but imported since dart:html can generate these objects.
import 'dart:svg' as svg;
import 'dart:svg' show svgBlinkMap;
import 'dart:svg' show Matrix;
import 'dart:svg' show SvgSvgElement;
import 'dart:web_audio' as web_audio;
import 'dart:web_audio' show web_audioBlinkMap;
import 'dart:_blink' as _blink;

export 'dart:math' show Rectangle, Point;

$!GENERATED_DART_FILES

// Issue 14721, order important for WrappedEvent.
part '$AUXILIARY_DIR/AttributeMap.dart';
part '$AUXILIARY_DIR/CanvasImageSource.dart';
part '$AUXILIARY_DIR/CrossFrameTypes.dart';
part '$AUXILIARY_DIR/CssClassSet.dart';
part '$AUXILIARY_DIR/CssRectangle.dart';
part '$AUXILIARY_DIR/Dimension.dart';
part '$AUXILIARY_DIR/EventListener.dart';
part '$AUXILIARY_DIR/EventStreamProvider.dart';
part '$AUXILIARY_DIR/Html5NodeValidator.dart';
part '$AUXILIARY_DIR/ImmutableListMixin.dart';
part '$AUXILIARY_DIR/KeyCode.dart';
part '$AUXILIARY_DIR/KeyLocation.dart';
part '$AUXILIARY_DIR/KeyName.dart';
part '$AUXILIARY_DIR/KeyboardEventStream.dart';
part '$AUXILIARY_DIR/NodeValidatorBuilder.dart';
part '$AUXILIARY_DIR/ReadyState.dart';
part '$AUXILIARY_DIR/Validators.dart';
part '$AUXILIARY_DIR/WrappedList.dart';
part '$AUXILIARY_DIR/_HttpRequestUtils.dart';
part '$AUXILIARY_DIR/_ListIterators.dart';
part '$AUXILIARY_DIR/dartium_CustomElementSupport.dart';
part '$AUXILIARY_DIR/dartium_KeyEvent.dart';
part '$AUXILIARY_DIR/dartium_Platform.dart';
part '$AUXILIARY_DIR/dartium_WrappedEvent.dart';
part '$AUXILIARY_DIR/shared_html.dart';

part '$AUXILIARY_DIR/html_native_DOMImplementation.dart';

Window _window;

/**
 * Top-level container for a web page, which is usually a browser tab or window.
 *
 * Each web page loaded in the browser has its own [Window], which is a
 * container for the web page.
 *
 * If the web page has any `<iframe>` elements, then each `<iframe>` has its own
 * [Window] object, which is accessible only to that `<iframe>`.
 *
 * See also:
 *
 *   * [Window](https://developer.mozilla.org/en-US/docs/Web/API/window) from MDN.
 */
Window get window {
  if (_window != null) {
    return _window;
  }
  _window = _Utils.window();
  return _window;
}

HtmlDocument _document;

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

/**
 * Spawn a DOM isolate using the given URI in the same window.
 * This isolate is not concurrent.  It runs on the browser thread
 * with full access to the DOM.
 * Note: this API is still evolving and may move to dart:isolate.
 */
@Experimental()
Future<Isolate> spawnDomUri(Uri uri, List<String> args, message) {
  // TODO(17738): Plumb arguments and return value through.
  return _Utils.spawnDomUri(uri.toString());
}
// FIXME: Can we make this private?
final htmlBlinkMap = {
  '_HistoryCrossFrame': () => _HistoryCrossFrame,
  '_LocationCrossFrame': () => _LocationCrossFrame,
  '_DOMWindowCrossFrame': () => _DOMWindowCrossFrame,
  // FIXME: Move these to better locations.
  'DateTime': () => DateTime,
  'JsObject': () => js.JsObject,
  'JsFunction': () => js.JsFunction,
  'JsArray': () => js.JsArray,
$!TYPE_MAP
  // FIXME: Temporary workaround.  The Blink name matches the Dart name
  // post Chrome 35.  We still generate the old mapping from 'Clipboard'.
  'DataTransfer': () => DataTransfer,
};

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