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

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/dartium_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/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;
  }
$if DARTIUM
$if JSINTEROP
  _window = wrap_jso(js.JsNative.getProperty(js.context, 'window'));
$else
  _window = _Utils.window();
$endif
$endif
  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,
$!TYPE_MAP
};

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

$if JSINTEROP
// FIXME: Can we make this private?
@Deprecated("Internal Use Only")
final htmlBlinkFunctionMap = {
$!TYPE_FUNCTION_MAP
};

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

}

@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) {
    // Did the dartClass get allocated but the created failed?  Otherwise, other
    // components inside of this failed somewhere (could be JS custom element).
    if (dartClass != null) {
      // Yes, mark as didn't upgrade.
      dartClass._badUpgrade();
    }
    throw e;
  } finally {
    // Need to remember the Dart class that was created for this custom so
    // return it and setup the blink_jsObject to the $this that we'll be working
    // with as we talk to blink.
    js.setDartHtmlWrapperFor($this, dartClass);
  }

  return dartClass;
}

$else
class DartHtmlDomObject extends NativeFieldWrapperClass2 {}

_createCustomUpgrader(Type customElementClass, $this) => $this;

$endif
