| // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| // for details. All rights reserved. Use of 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 |
| } |
| } |