| // Copyright (c) 2022, 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. | |
| import 'dart:js_interop'; | |
| import 'dart:js_interop_unsafe'; | |
| extension type Window(EventTarget _) implements EventTarget { | |
| @pragma('dart2js:as:trust') | |
| Window get parent => getProperty('parent'.toJS) as Window; | |
| external Location get location; | |
| Console get console => getProperty('console'.toJS) as Console; | |
| CSSStyleDeclaration? getComputedStyle(Element elt, [String? pseudoElt]) => | |
| callMethodVarArgs('getComputedStyle'.toJS, <JSAny?>[ | |
| elt, | |
| if (pseudoElt != null) pseudoElt.toJS, | |
| ]) | |
| as CSSStyleDeclaration?; | |
| external Navigator get navigator; | |
| void postMessage( | |
| Object message, | |
| String targetOrigin, [ | |
| List<MessagePort>? messagePorts, | |
| ]) => callMethodVarArgs('postMessage'.toJS, <JSAny?>[ | |
| message.jsify(), | |
| targetOrigin.toJS, | |
| if (messagePorts != null) messagePorts.toJS, | |
| ]); | |
| } | |
| @JS('window') | |
| external Window get window; | |
| extension type Console(JSObject _) implements JSObject { | |
| external void log(JSAny? object); | |
| external void warn(JSAny? object); | |
| } | |
| extension type Document(Node _) implements Node { | |
| external Element? querySelector(String selectors); | |
| Element createElement(String name, [Object? options]) => | |
| callMethodVarArgs('createElement'.toJS, <JSAny?>[ | |
| name.toJS, | |
| if (options != null) options.jsify(), | |
| ]) | |
| as Element; | |
| } | |
| extension type HTMLDocument(Document _) implements Document { | |
| external HTMLBodyElement? get body; | |
| external String? get title; | |
| } | |
| @JS('document') | |
| external HTMLDocument get document; | |
| extension type Navigator(JSObject _) implements JSObject { | |
| external String get userAgent; | |
| } | |
| extension type Element(Node _) implements Node { | |
| external DomTokenList get classList; | |
| } | |
| extension type HTMLElement(Element _) implements Element {} | |
| extension type HTMLBodyElement(HTMLElement _) implements HTMLElement {} | |
| extension type Node(EventTarget _) implements EventTarget { | |
| external Node appendChild(Node node); | |
| void remove() { | |
| if (parentNode != null) { | |
| final parent = parentNode!; | |
| parent.removeChild(this); | |
| } | |
| } | |
| external Node removeChild(Node child); | |
| external Node? get parentNode; | |
| } | |
| extension type EventTarget(JSObject _) implements JSObject { | |
| void addEventListener( | |
| String type, | |
| EventListener? listener, [ | |
| bool? useCapture, | |
| ]) { | |
| if (listener != null) { | |
| callMethodVarArgs('addEventListener'.toJS, <JSAny?>[ | |
| type.toJS, | |
| listener.toJS, | |
| if (useCapture != null) useCapture.toJS, | |
| ]); | |
| } | |
| } | |
| void removeEventListener( | |
| String type, | |
| EventListener? listener, [ | |
| bool? useCapture, | |
| ]) { | |
| if (listener != null) { | |
| callMethodVarArgs('removeEventListener'.toJS, <JSAny?>[ | |
| type.toJS, | |
| listener.toJS, | |
| if (useCapture != null) useCapture.toJS, | |
| ]); | |
| } | |
| } | |
| } | |
| typedef EventListener = void Function(Event event); | |
| extension type Event(JSObject _) implements JSObject { | |
| external void stopPropagation(); | |
| } | |
| extension type MessageEvent(Event _) implements Event { | |
| dynamic get data => getProperty('data'.toJS).dartify(); | |
| external String get origin; | |
| List<MessagePort> get ports => | |
| getProperty<JSArray>('ports'.toJS).toDart.cast<MessagePort>(); | |
| /// The source may be a `WindowProxy`, a `MessagePort`, or a `ServiceWorker`. | |
| /// | |
| /// When a message is sent from an iframe through `window.parent.postMessage` | |
| /// the source will be a `WindowProxy` which has the same methods as [Window]. | |
| @pragma('dart2js:as:trust') | |
| MessageEventSource get source => | |
| getProperty('source'.toJS) as MessageEventSource; | |
| } | |
| extension type MessageEventSource(JSObject _) implements JSObject { | |
| @pragma('dart2js:as:trust') | |
| MessageEventSourceLocation? get location => | |
| getProperty('location'.toJS) as MessageEventSourceLocation; | |
| } | |
| extension type MessageEventSourceLocation(JSObject _) implements JSObject { | |
| external String? get href; | |
| } | |
| extension type Location(JSObject _) implements JSObject { | |
| external String get href; | |
| external String get origin; | |
| } | |
| extension type MessagePort(EventTarget _) implements EventTarget { | |
| void postMessage(Object? message) => callMethodVarArgs( | |
| 'postMessage'.toJS, | |
| <JSAny?>[if (message != null) message.jsify()], | |
| ); | |
| external void start(); | |
| } | |
| extension type CSSStyleDeclaration(JSObject _) implements JSObject {} | |
| extension type HTMLScriptElement(HTMLElement _) implements HTMLElement { | |
| external set src(String value); | |
| } | |
| HTMLScriptElement createHTMLScriptElement() => | |
| document.createElement('script') as HTMLScriptElement; | |
| extension type DomTokenList(JSObject _) implements JSObject { | |
| external void add(String value); | |
| external void remove(String value); | |
| external bool contains(String token); | |
| } | |
| extension type HTMLIFrameElement(HTMLElement _) implements HTMLElement { | |
| external String? get src; | |
| external set src(String? value); | |
| external Window get contentWindow; | |
| } | |
| HTMLIFrameElement createHTMLIFrameElement() => | |
| document.createElement('iframe') as HTMLIFrameElement; | |
| extension type WebSocket(EventTarget _) implements EventTarget { | |
| external void send(JSAny? data); | |
| } | |
| WebSocket createWebSocket(String url) => | |
| _callConstructor('WebSocket', <JSAny?>[url.toJS])! as WebSocket; | |
| extension type MessageChannel(JSObject _) implements JSObject { | |
| external MessagePort get port1; | |
| external MessagePort get port2; | |
| } | |
| MessageChannel createMessageChannel() => | |
| _callConstructor('MessageChannel', <JSAny?>[])! as MessageChannel; | |
| Object? _callConstructor(String constructorName, List<JSAny?> args) { | |
| final constructor = window.getProperty(constructorName.toJS) as JSFunction?; | |
| if (constructor == null) { | |
| return null; | |
| } | |
| return constructor.callAsConstructorVarArgs(args); | |
| } | |
| class Subscription { | |
| final String type; | |
| final EventTarget target; | |
| final EventListener listener; | |
| Subscription(this.target, this.type, this.listener) { | |
| target.addEventListener(type, listener); | |
| } | |
| void cancel() => target.removeEventListener(type, listener); | |
| } |