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