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

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.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?
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?
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.
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                    **********
 **********                                                          **********
 ******************************************************************************/

// List of known tagName to DartClass for custom elements, used for upgrade.
var _knownCustomeElements = new Map<String, Type>();

Rectangle make_dart_rectangle(r) =>
    r == null ? null : new Rectangle(r['left'], r['top'], r['width'], r['height']);

// Need a default constructor for constructing classes with mixins that are
// also extending NativeFieldWrapperClass2.  Defining JsoNativeFieldWrapper
// extending NativeFieldWrapperClass2 creates a default constructor.
class JsoNativeFieldWrapper extends NativeFieldWrapperClass2 {}

// Flag to disable JS interop asserts.  Setting to false will speed up the
// wrap_jso calls.
bool __interop_checks = true;

/** Expando for JsObject, used by every Dart class associated with a Javascript
 *  class (e.g., DOM, WebAudio, etc.).
 */

/**
 * Return the JsObject associated with a Dart class [dartClass_instance].
 */
unwrap_jso(dartClass_instance) => js.unwrap_jso(dartClass_instance);

/**
 * Create Dart class that maps to the JS Type, add the JsObject as an expando
 * on the Dart class and return the created Dart class.
 */
wrap_jso(jsObject) {
  try {
    if (jsObject is! js.JsObject || jsObject == null) {
      // JS Interop converted the object to a Dart class e.g., Uint8ClampedList.
      // or it's a simple type.
      return jsObject;
    }

    // TODO(alanknight): With upgraded custom elements this causes a failure because
    // we need a new wrapper after the type changes. We could possibly invalidate this
    // if the constructor name didn't match?
    var wrapper = js.getDartHtmlWrapperFor(jsObject);
    if (wrapper != null) {
      return wrapper;
    }

    if (jsObject is js.JsArray) {
      var wrappingList = new _DartHtmlWrappingList(jsObject);
      js.setDartHtmlWrapperFor(jsObject, wrappingList);
      return wrappingList;
    }

    // Try the most general type conversions on it.
    // TODO(alanknight): We may be able to do better. This maintains identity,
    // which is useful, but expensive. And if we nest something that only
    // this conversion handles, how does that work? e.g. a list of maps of elements.
    var converted = convertNativeToDart_SerializedScriptValue(jsObject);
    if (!identical(converted, jsObject)) {
      return converted;
    }
    var constructor = jsObject['constructor'];
    if (__interop_checks) {
      debug_or_assert("constructor != null", constructor != null);
    }
    var jsTypeName = constructor['name'];
    if (__interop_checks) {
      debug_or_assert("constructor != null && jsTypeName.length > 0", constructor != null && jsTypeName.length > 0);
    }

    var dartClass_instance;
    if (jsObject.hasProperty('dart_class')) {
      // Got a dart_class (it's a custom element) use it it's already set up.
      dartClass_instance = jsObject['dart_class'];
    } else {
      var localName = jsObject['localName'];
      var customElementClass = _knownCustomeElements[localName];
      // Custom Element to upgrade.
      if (jsTypeName == 'HTMLElement' && customElementClass != null) {
        try {
          dartClass_instance = _blink.Blink_Utils.constructElement(customElementClass, jsObject);
        } finally {
          dartClass_instance.blink_jsObject = jsObject;
          jsObject['dart_class'] = dartClass_instance;
          js.setDartHtmlWrapperFor(jsObject, dartClass_instance);
       }
      } else {
        var func = getHtmlCreateFunction(jsTypeName);
        if (func != null) {
          dartClass_instance = func();
          dartClass_instance.blink_jsObject = jsObject;
          js.setDartHtmlWrapperFor(jsObject, dartClass_instance);
        }
      }
    }
    return dartClass_instance;
  } catch(e, stacktrace){
    if (__interop_checks) {
      if (e is DebugAssertException)
        window.console.log("${e.message}\n ${stacktrace}");
      else
        window.console.log("${stacktrace}");
    }
  }

  return null;
}

/**
 * Create Dart class that maps to the JS Type that is the JS type being
 * extended using JS interop createCallback (we need the base type of the
 * custom element) not the Dart created constructor.
 */
wrap_jso_custom_element(jsObject) {
  try {
    if (jsObject is! js.JsObject) {
      // JS Interop converted the object to a Dart class e.g., Uint8ClampedList.
      return jsObject;
    }

    // Find out what object we're extending.
    var objectName = jsObject.toString();
    // Expect to see something like '[object HTMLElement]'.
    if (!objectName.startsWith('[object ')) {
      return jsObject;
    }

    var extendsClass = objectName.substring(8, objectName.length - 1);
    var func = getHtmlCreateFunction(extendsClass);
    if (__interop_checks)
      debug_or_assert("func != null name = ${extendsClass}", func != null);
    var dartClass_instance = func();
    dartClass_instance.blink_jsObject = jsObject;
    return dartClass_instance;
  } catch(e, stacktrace){
    if (__interop_checks) {
      if (e is DebugAssertException)
        window.console.log("${e.message}\n ${stacktrace}");
      else
        window.console.log("${stacktrace}");
    }

    // Problem?
    return null;
  }
}

class DebugAssertException implements Exception {
  String message;
  DebugAssertException(this.message);
}

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 = {};

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

Map<String, dynamic> convertNativeObjectToDartMap(js.JsObject jsObject) {
  var result = new Map();
  var keys = js.context['Object'].callMethod('keys', [jsObject]);
  for (var key in keys) {
    result[key] = wrap_jso(jsObject[key]);
  }
  return result;
}

// Converts a flat Dart map into a JavaScript object with properties this is
// is the Dartium only version it uses dart:js.
// TODO(alanknight): This could probably be unified with the dart2js conversions
// code in html_common and be more general.
convertDartToNative_Dictionary(Map dict) {
  if (dict == null) return null;
  var jsObject = new js.JsObject(js.context['Object']);
  dict.forEach((String key, value) {
    if (value is List) {
      var jsArray = new js.JsArray();
      value.forEach((elem) {
        jsArray.add(elem is Map ? convertDartToNative_Dictionary(elem): elem);
      });
      jsObject[key] = jsArray;
    } else {
      jsObject[key] = value;
    }
  });
  return jsObject;
}

// Converts a Dart list into a JsArray. For the Dartium version only.
convertDartToNative_List(List input) => new js.JsArray()..addAll(input);

// Conversion function place holder (currently not used in dart2js or dartium).
List convertDartToNative_StringArray(List<String> input) => input;

/**
 * Wraps a JsArray and will call wrap_jso on its entries.
 */
class _DartHtmlWrappingList extends ListBase {
  _DartHtmlWrappingList(this._basicList);

  final js.JsArray _basicList;

  operator [](int index) => wrap_jso(_basicList[index]);

  operator []=(int index, value) => _basicList[index] = unwrap_jso(value);

  int get length => _basicList.length;
  int set length(int newLength) => _basicList.length = newLength;
}

/**
 * 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) {
    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. 
    $this['dart_class'] = dartClass;
  }

  return dartClass;
}

$else
class JsoNativeFieldWrapper extends NativeFieldWrapperClass2 {}

unwrap_jso(dartClass_instance) => dartClass_instance;
wrap_jso(jsObject) => jsObject;
make_dart_rectangle(r) => r;
convertDartToNative_Dictionary(Map dict) => dict;
List convertDartToNative_StringArray(List<String> input) => input;
convertDartToNative_List(List input) => input;
createCustomUpgrader(Type customElementClass, $this) => $this;

$endif
