blob: 0a0ff4c67eb00b0c0c5a5615eca7cc11313214d2 [file] [log] [blame]
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
// WARNING: Do not edit - generated code.
part of $LIBRARYNAME;
$(ANNOTATIONS)$(NATIVESPEC)$(CLASS_MODIFIERS)class $CLASSNAME$EXTENDS$IMPLEMENTS {
$!MEMBERS
$if DART2JS
@DomName('Document.body')
BodyElement body;
$else
@DomName('Document.body')
BodyElement get body => _body;
@DomName('Document.body')
set body(BodyElement value) {
_body = value;
}
$endif
@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]
*/
$if DART2JS
static bool get supportsCssCanvasContext =>
JS('bool', '!!(document.getCSSCanvasContext)');
$else
static bool get supportsCssCanvasContext => true;
$endif
/**
* 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()
$if DART2JS
String get visibilityState => JS('String',
'(#.visibilityState || #.mozVisibilityState || #.msVisibilityState ||'
'#.webkitVisibilityState)', this, this, this, this);
$else
String get visibilityState => _webkitVisibilityState;
$endif
$if DARTIUM
/**
* 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 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;
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) {
// 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 classMirror;
}
}
}
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?.replaceAll('\n', ' ');
RegExp regExp = new RegExp(r":(.*?)(;|}|\n)");
var match = regExp.firstMatch(createdSource);
superCreatedCalled = match.input.substring(match.start,match.end).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;
}
$endif
@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}) {
$if DART2JS
_registerCustomElement(JS('', 'window'), this, tag, customElementClass,
extendsTag);
$else
// TODO(terry): Need to handle the extendsTag.
// Figure out which DOM class is being extended from the user's Dart class.
var classMirror = reflectClass(customElementClass);
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.");
}
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.context[jsClassName];
if (baseElement == null) {
// Couldn't find the HTML element so use a generic one.
baseElement = js.context['HTMLElement'];
}
var elemProto = js.context['Object'].callMethod("create", [baseElement['prototype']]);
// 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;
elemProto['createdCallback'] = new js.JsFunction.withThis(($this) {
if (_getJSClassName(reflectClass(customElementClass).superclass) != null && creating < 2) {
creating++;
var dartClass;
try {
dartClass = _blink.Blink_Utils.constructElement(customElementClass, $this);
} catch (e) {
dartClass = HtmlElement.internalCreateHtmlElement();
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;
creating--;
}
}
});
elemProto['attributeChangedCallback'] = new js.JsFunction.withThis(($this, attrName, oldVal, newVal) {
if ($this["dart_class"] != null && $this['dart_class'].attributeChanged != null) {
$this['dart_class'].attributeChanged(attrName, oldVal, newVal);
}
});
elemProto['attachedCallback'] = new js.JsFunction.withThis(($this) {
if ($this["dart_class"] != null && $this['dart_class'].attached != null) {
$this['dart_class'].attached();
}
});
elemProto['detachedCallback'] = new js.JsFunction.withThis(($this) {
if ($this["dart_class"] != null && $this['dart_class'].detached != null) {
$this['dart_class'].detached();
}
});
// document.registerElement('x-foo', {prototype: elemProto, extends: extendsTag});
var jsMap = new js.JsObject.jsify({'prototype': elemProto, 'extends': extendsTag});
js.context['document'].callMethod('registerElement', [tag, jsMap]);
}
$endif
}
/** *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) {
$if DART2JS
if (JS('bool', '(typeof #.hidden !== "undefined")', e)) {
// Opera 12.10 and Firefox 18 and later support
return 'visibilitychange';
} else if (JS('bool', '(typeof #.mozHidden !== "undefined")', e)) {
return 'mozvisibilitychange';
} else if (JS('bool', '(typeof #.msHidden !== "undefined")', e)) {
return 'msvisibilitychange';
} else if (JS('bool', '(typeof #.webkitHidden !== "undefined")', e)) {
return 'webkitvisibilitychange';
}
return 'visibilitychange';
$else
return 'webkitvisibilitychange';
$endif
}
@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}) {
$if DART2JS
return new _JSElementUpgrader(this, type, extendsTag);
$else
return new _VMElementUpgrader(this, type, extendsTag);
$endif
}
}