Support Promise to Future for both DDC and dart2js.
APIs in the newer Chrome IDLs support more JS style promises. The Dart web libraries now hookup those promises and return a Dart Future.
Additionally, a new type maplike is exposed in the IDL this is exposed too.
Change-Id: I44175877eb95f4d910586d42c0139fb182483f82
Reviewed-on: https://dart-review.googlesource.com/49800
Commit-Queue: Terry Lucas <terry@google.com>
Reviewed-by: Stephen Adams <sra@google.com>
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 3cee860..440f2f4 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,4 +1,21 @@
## 2.0.0-dev.XX.0
+
+* Support Javascript Promise APIs as a Dart Future. In Javascript a Promise has two
+ callbacks one for success and one for failure. For success the Future returns the
+ value e.g.,
+
+BackgroundFetchManager.get is exposed as:
+
+```dart
+ Future<BackgroundFetchRegistration> get(String id)
+```
+
+usage could be:
+
+ BackgroundFetchRegistration result = await fetchMgr.get('abc');
+
+ The underlying JS Promise to Future mechanism will be exposed as a public API in a future checkin.
+
(Add new changes here, and they will be copied to the
change section for the next dev version)
diff --git a/sdk/lib/html/dart2js/html_dart2js.dart b/sdk/lib/html/dart2js/html_dart2js.dart
index 1f622c4..c440394 100644
--- a/sdk/lib/html/dart2js/html_dart2js.dart
+++ b/sdk/lib/html/dart2js/html_dart2js.dart
@@ -101,6 +101,46 @@
HtmlDocument get document =>
JS('returns:HtmlDocument;depends:none;effects:none;gvn:true', 'document');
+// Supoort to convert JS Promise to a Dart Future.
+Future<T> promiseToFuture<T>(thePromise) {
+ var completer = new Completer<T>();
+
+ var thenSuccessCode = (promiseValue) => completer.complete(promiseValue);
+ var thenErrorCode = (promiseError) => completer.completeError(promiseError);
+
+ JS("", "#.then(#, #)", thePromise, convertDartClosureToJS(thenSuccessCode, 1),
+ convertDartClosureToJS(thenErrorCode, 1));
+
+ return completer.future;
+}
+
+// Supoort to convert JS Promise to a Dart Future that returns a MapLike (Class with Map mixin).
+Future promiseToFutureMap(thePromise) {
+ var completer = new Completer();
+
+ var thenSuccessCode = (promiseValue) => completer.complete(promiseValue);
+ var thenErrorCode = (promiseError) => completer.completeError(promiseError);
+
+ JS("", "#.then(#, #)", thePromise, convertDartClosureToJS(thenSuccessCode, 1),
+ convertDartClosureToJS(thenErrorCode, 1));
+
+ return completer.future;
+}
+
+// Supoort to convert JS Promise to a Dart Future that returns a Dictionary as a Dart Map.
+Future<Map> promiseToFutureDictionary(thePromise) {
+ var completer = new Completer<Map>();
+
+ var thenSuccessCode = (promiseValue) =>
+ completer.complete(convertNativeToDart_Dictionary(promiseValue));
+ var thenErrorCode = (promiseError) => completer.completeError(promiseError);
+
+ JS("", "#.then(#, #)", thePromise, convertDartClosureToJS(thenSuccessCode, 1),
+ convertDartClosureToJS(thenErrorCode, 1));
+
+ return completer.future;
+}
+
// Workaround for tags like <cite> that lack their own Element subclass --
// Dart issue 1990.
@Native("HTMLElement")
@@ -129,7 +169,6 @@
@Experimental() // untriaged
typedef void FontFaceSetForEachCallback(
FontFace fontFace, FontFace fontFaceAgain, FontFaceSet set);
-
// 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.
@@ -1810,12 +1849,15 @@
@DomName('BackgroundFetchManager.get')
@DocsEditable()
@Experimental() // untriaged
- Future get(String id) native;
+ Future<BackgroundFetchRegistration> get(String id) =>
+ promiseToFuture<BackgroundFetchRegistration>(
+ JS("", "#.get(#)", this, id));
@DomName('BackgroundFetchManager.getIds')
@DocsEditable()
@Experimental() // untriaged
- Future getIds() native;
+ Future<List<String>> getIds() =>
+ promiseToFuture<List<String>>(JS("", "#.getIds()", this));
}
// 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
@@ -1869,7 +1911,7 @@
@DomName('BackgroundFetchRegistration.abort')
@DocsEditable()
@Experimental() // untriaged
- Future abort() native;
+ Future<bool> abort() => promiseToFuture<bool>(JS("", "#.abort()", this));
}
// 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
@@ -1932,7 +1974,8 @@
@DomName('BackgroundFetchedEvent.updateUI')
@DocsEditable()
@Experimental() // untriaged
- Future updateUI(String title) native;
+ Future updateUI(String title) =>
+ promiseToFuture(JS("", "#.updateUI(#)", this, title));
}
// 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
@@ -1978,7 +2021,9 @@
@DomName('BarcodeDetector.detect')
@DocsEditable()
@Experimental() // untriaged
- Future detect(/*ImageBitmapSource*/ image) native;
+ Future<List<DetectedBarcode>> detect(/*ImageBitmapSource*/ image) =>
+ promiseToFuture<List<DetectedBarcode>>(
+ JS("", "#.detect(#)", this, image));
}
// 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
@@ -2090,7 +2135,7 @@
@DomName('BeforeInstallPromptEvent.prompt')
@DocsEditable()
@Experimental() // untriaged
- Future prompt() native;
+ Future prompt() => promiseToFuture(JS("", "#.prompt()", this));
}
// 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
@@ -2231,12 +2276,13 @@
@DomName('BluetoothRemoteGATTDescriptor.readValue')
@DocsEditable()
@Experimental() // untriaged
- Future readValue() native;
+ Future readValue() => promiseToFuture(JS("", "#.readValue()", this));
@DomName('BluetoothRemoteGATTDescriptor.writeValue')
@DocsEditable()
@Experimental() // untriaged
- Future writeValue(/*BufferSource*/ value) native;
+ Future writeValue(/*BufferSource*/ value) =>
+ promiseToFuture(JS("", "#.writeValue(#)", this, value));
}
// 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
@@ -2260,27 +2306,28 @@
@DomName('Body.arrayBuffer')
@DocsEditable()
@Experimental() // untriaged
- Future arrayBuffer() native;
+ Future arrayBuffer() => promiseToFuture(JS("", "#.arrayBuffer()", this));
@DomName('Body.blob')
@DocsEditable()
@Experimental() // untriaged
- Future blob() native;
+ Future<Blob> blob() => promiseToFuture<Blob>(JS("", "#.blob()", this));
@DomName('Body.formData')
@DocsEditable()
@Experimental() // untriaged
- Future formData() native;
+ Future<FormData> formData() =>
+ promiseToFuture<FormData>(JS("", "#.formData()", this));
@DomName('Body.json')
@DocsEditable()
@Experimental() // untriaged
- Future json() native;
+ Future json() => promiseToFuture(JS("", "#.json()", this));
@DomName('Body.text')
@DocsEditable()
@Experimental() // untriaged
- Future text() native;
+ Future<String> text() => promiseToFuture<String>(JS("", "#.text()", this));
}
// 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
@@ -2719,17 +2766,19 @@
@DomName('CacheStorage.delete')
@DocsEditable()
@Experimental() // untriaged
- Future delete(String cacheName) native;
+ Future delete(String cacheName) =>
+ promiseToFuture(JS("", "#.delete(#)", this, cacheName));
@DomName('CacheStorage.has')
@DocsEditable()
@Experimental() // untriaged
- Future has(String cacheName) native;
+ Future has(String cacheName) =>
+ promiseToFuture(JS("", "#.has(#)", this, cacheName));
@DomName('CacheStorage.keys')
@DocsEditable()
@Experimental() // untriaged
- Future keys() native;
+ Future keys() => promiseToFuture(JS("", "#.keys()", this));
@DomName('CacheStorage.match')
@DocsEditable()
@@ -2756,7 +2805,8 @@
@DomName('CacheStorage.open')
@DocsEditable()
@Experimental() // untriaged
- Future open(String cacheName) native;
+ Future open(String cacheName) =>
+ promiseToFuture(JS("", "#.open(#)", this, cacheName));
}
// 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
@@ -4031,12 +4081,12 @@
@DomName('Clients.claim')
@DocsEditable()
@Experimental() // untriaged
- Future claim() native;
+ Future claim() => promiseToFuture(JS("", "#.claim()", this));
@DomName('Clients.get')
@DocsEditable()
@Experimental() // untriaged
- Future get(String id) native;
+ Future get(String id) => promiseToFuture(JS("", "#.get(#)", this, id));
@DomName('Clients.matchAll')
@DocsEditable()
@@ -4063,7 +4113,8 @@
@DomName('Clients.openWindow')
@DocsEditable()
@Experimental() // untriaged
- Future openWindow(String url) native;
+ Future<WindowClient> openWindow(String url) =>
+ promiseToFuture<WindowClient>(JS("", "#.openWindow(#)", this, url));
}
// 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
@@ -4457,17 +4508,20 @@
@DomName('CredentialsContainer.preventSilentAccess')
@DocsEditable()
@Experimental() // untriaged
- Future preventSilentAccess() native;
+ Future preventSilentAccess() =>
+ promiseToFuture(JS("", "#.preventSilentAccess()", this));
@DomName('CredentialsContainer.requireUserMediation')
@DocsEditable()
@Experimental() // untriaged
- Future requireUserMediation() native;
+ Future requireUserMediation() =>
+ promiseToFuture(JS("", "#.requireUserMediation()", this));
@DomName('CredentialsContainer.store')
@DocsEditable()
@Experimental() // untriaged
- Future store(Credential credential) native;
+ Future store(Credential credential) =>
+ promiseToFuture(JS("", "#.store(#)", this, credential));
}
// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
@@ -10270,7 +10324,8 @@
@DomName('CustomElementRegistry.whenDefined')
@DocsEditable()
@Experimental() // untriaged
- Future whenDefined(String name) native;
+ Future whenDefined(String name) =>
+ promiseToFuture(JS("", "#.whenDefined(#)", this, name));
}
// 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
@@ -19259,7 +19314,8 @@
@DomName('FaceDetector.detect')
@DocsEditable()
@Experimental() // untriaged
- Future detect(/*ImageBitmapSource*/ image) native;
+ Future<List<DetectedFace>> detect(/*ImageBitmapSource*/ image) =>
+ promiseToFuture<List<DetectedFace>>(JS("", "#.detect(#)", this, image));
}
// 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
@@ -20099,7 +20155,8 @@
@DomName('FontFace.load')
@DocsEditable()
@Experimental() // untriaged
- Future load() native;
+ Future<FontFace> load() =>
+ promiseToFuture<FontFace>(JS("", "#.load()", this));
}
// 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
@@ -23312,17 +23369,21 @@
@DomName('ImageCapture.getPhotoCapabilities')
@DocsEditable()
@Experimental() // untriaged
- Future getPhotoCapabilities() native;
+ Future<PhotoCapabilities> getPhotoCapabilities() =>
+ promiseToFuture<PhotoCapabilities>(
+ JS("", "#.getPhotoCapabilities()", this));
@DomName('ImageCapture.getPhotoSettings')
@DocsEditable()
@Experimental() // untriaged
- Future getPhotoSettings() native;
+ Future<Map> getPhotoSettings() =>
+ promiseToFutureDictionary(JS("", "#.getPhotoSettings()", this));
@DomName('ImageCapture.grabFrame')
@DocsEditable()
@Experimental() // untriaged
- Future grabFrame() native;
+ Future<ImageBitmap> grabFrame() =>
+ promiseToFuture<ImageBitmap>(JS("", "#.grabFrame()", this));
@DomName('ImageCapture.setOptions')
@DocsEditable()
@@ -23504,7 +23565,7 @@
@DomName('HTMLImageElement.decode')
@DocsEditable()
@Experimental() // untriaged
- Future decode() native;
+ Future decode() => promiseToFuture(JS("", "#.decode()", this));
}
// 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
@@ -25360,7 +25421,9 @@
@DomName('MediaDevices.enumerateDevices')
@DocsEditable()
@Experimental() // untriaged
- Future enumerateDevices() native;
+ Future<List<MediaDeviceInfo>> enumerateDevices() =>
+ promiseToFuture<List<MediaDeviceInfo>>(
+ JS("", "#.enumerateDevices()", this));
@DomName('MediaDevices.getSupportedConstraints')
@DocsEditable()
@@ -25615,17 +25678,19 @@
@DomName('HTMLMediaElement.play')
@DocsEditable()
- Future play() native;
+ Future play() => promiseToFuture(JS("", "#.play()", this));
@DomName('HTMLMediaElement.setMediaKeys')
@DocsEditable()
@Experimental() // untriaged
- Future setMediaKeys(MediaKeys mediaKeys) native;
+ Future setMediaKeys(MediaKeys mediaKeys) =>
+ promiseToFuture(JS("", "#.setMediaKeys(#)", this, mediaKeys));
@DomName('HTMLMediaElement.setSinkId')
@DocsEditable()
@Experimental() // untriaged
- Future setSinkId(String sinkId) native;
+ Future setSinkId(String sinkId) =>
+ promiseToFuture(JS("", "#.setSinkId(#)", this, sinkId));
}
// 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
@@ -25785,22 +25850,25 @@
@DomName('MediaKeySession.close')
@DocsEditable()
- Future close() native;
+ Future close() => promiseToFuture(JS("", "#.close()", this));
@DomName('MediaKeySession.generateRequest')
@DocsEditable()
@Experimental() // untriaged
- Future generateRequest(String initDataType, /*BufferSource*/ initData) native;
+ Future generateRequest(String initDataType, /*BufferSource*/ initData) =>
+ promiseToFuture(
+ JS("", "#.generateRequest(#, #)", this, initDataType, initData));
@DomName('MediaKeySession.load')
@DocsEditable()
@Experimental() // untriaged
- Future load(String sessionId) native;
+ Future load(String sessionId) =>
+ promiseToFuture(JS("", "#.load(#)", this, sessionId));
@DomName('MediaKeySession.remove')
@DocsEditable()
@Experimental() // untriaged
- Future remove() native;
+ Future remove() => promiseToFuture(JS("", "#.remove()", this));
@JSName('update')
@DomName('MediaKeySession.update')
@@ -25863,7 +25931,8 @@
@DomName('MediaKeySystemAccess.createMediaKeys')
@DocsEditable()
@Experimental() // untriaged
- Future createMediaKeys() native;
+ Future createMediaKeys() =>
+ promiseToFuture(JS("", "#.createMediaKeys()", this));
@DomName('MediaKeySystemAccess.getConfiguration')
@DocsEditable()
@@ -25901,12 +25970,15 @@
@DomName('MediaKeys.getStatusForPolicy')
@DocsEditable()
@Experimental() // untriaged
- Future getStatusForPolicy(MediaKeysPolicy policy) native;
+ Future getStatusForPolicy(MediaKeysPolicy policy) =>
+ promiseToFuture(JS("", "#.getStatusForPolicy(#)", this, policy));
@DomName('MediaKeys.setServerCertificate')
@DocsEditable()
@Experimental() // untriaged
- Future setServerCertificate(/*BufferSource*/ serverCertificate) native;
+ Future setServerCertificate(/*BufferSource*/ serverCertificate) =>
+ promiseToFuture(
+ JS("", "#.setServerCertificate(#)", this, serverCertificate));
}
// 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
@@ -27241,11 +27313,68 @@
@DomName('MIDIInputMap')
@Experimental() // untriaged
@Native("MIDIInputMap")
-class MidiInputMap extends Interceptor {
+class MidiInputMap extends Interceptor with MapMixin<String, dynamic> {
// To suppress missing implicit constructor warnings.
factory MidiInputMap._() {
throw new UnsupportedError("Not supported");
}
+
+ Map _getItem(String key) =>
+ convertNativeToDart_Dictionary(JS('', '#.get(#)', this, key));
+
+ void addAll(Map<String, dynamic> other) {
+ throw new UnsupportedError("Not supported");
+ }
+
+ bool containsValue(dynamic value) => values.any((e) => e == value);
+
+ bool containsKey(dynamic key) => _getItem(key) != null;
+
+ Map operator [](dynamic key) => _getItem(key);
+
+ void forEach(void f(String key, dynamic value)) {
+ var entries = JS('', '#.entries()', this);
+ while (true) {
+ var entry = JS('', '#.next()', entries);
+ if (JS('bool', '#.done', entry)) return;
+ f(JS('String', '#.value[0]', entry),
+ convertNativeToDart_Dictionary(JS('', '#.value[1]', entry)));
+ }
+ }
+
+ Iterable<String> get keys {
+ final keys = <String>[];
+ forEach((k, v) => keys.add(k));
+ return keys;
+ }
+
+ Iterable<Map> get values {
+ final values = <Map>[];
+ forEach((k, v) => values.add(v));
+ return values;
+ }
+
+ int get length => JS('int', '#.size', this);
+
+ bool get isEmpty => length == 0;
+
+ bool get isNotEmpty => !isEmpty;
+
+ void operator []=(String key, dynamic value) {
+ throw new UnsupportedError("Not supported");
+ }
+
+ dynamic putIfAbsent(String key, dynamic ifAbsent()) {
+ throw new UnsupportedError("Not supported");
+ }
+
+ String remove(dynamic key) {
+ throw new UnsupportedError("Not supported");
+ }
+
+ void clear() {
+ throw new UnsupportedError("Not supported");
+ }
}
// 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
@@ -27307,11 +27436,68 @@
@DomName('MIDIOutputMap')
@Experimental() // untriaged
@Native("MIDIOutputMap")
-class MidiOutputMap extends Interceptor {
+class MidiOutputMap extends Interceptor with MapMixin<String, dynamic> {
// To suppress missing implicit constructor warnings.
factory MidiOutputMap._() {
throw new UnsupportedError("Not supported");
}
+
+ Map _getItem(String key) =>
+ convertNativeToDart_Dictionary(JS('', '#.get(#)', this, key));
+
+ void addAll(Map<String, dynamic> other) {
+ throw new UnsupportedError("Not supported");
+ }
+
+ bool containsValue(dynamic value) => values.any((e) => e == value);
+
+ bool containsKey(dynamic key) => _getItem(key) != null;
+
+ Map operator [](dynamic key) => _getItem(key);
+
+ void forEach(void f(String key, dynamic value)) {
+ var entries = JS('', '#.entries()', this);
+ while (true) {
+ var entry = JS('', '#.next()', entries);
+ if (JS('bool', '#.done', entry)) return;
+ f(JS('String', '#.value[0]', entry),
+ convertNativeToDart_Dictionary(JS('', '#.value[1]', entry)));
+ }
+ }
+
+ Iterable<String> get keys {
+ final keys = <String>[];
+ forEach((k, v) => keys.add(k));
+ return keys;
+ }
+
+ Iterable<Map> get values {
+ final values = <Map>[];
+ forEach((k, v) => values.add(v));
+ return values;
+ }
+
+ int get length => JS('int', '#.size', this);
+
+ bool get isEmpty => length == 0;
+
+ bool get isNotEmpty => !isEmpty;
+
+ void operator []=(String key, dynamic value) {
+ throw new UnsupportedError("Not supported");
+ }
+
+ dynamic putIfAbsent(String key, dynamic ifAbsent()) {
+ throw new UnsupportedError("Not supported");
+ }
+
+ String remove(dynamic key) {
+ throw new UnsupportedError("Not supported");
+ }
+
+ void clear() {
+ throw new UnsupportedError("Not supported");
+ }
}
// 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
@@ -27361,12 +27547,12 @@
@DomName('MIDIPort.close')
@DocsEditable()
@Experimental() // untriaged
- Future close() native;
+ Future close() => promiseToFuture(JS("", "#.close()", this));
@DomName('MIDIPort.open')
@DocsEditable()
@Experimental() // untriaged
- Future open() native;
+ Future open() => promiseToFuture(JS("", "#.open()", this));
}
// 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
@@ -28057,17 +28243,18 @@
@DomName('NavigationPreloadManager.disable')
@DocsEditable()
@Experimental() // untriaged
- Future disable() native;
+ Future disable() => promiseToFuture(JS("", "#.disable()", this));
@DomName('NavigationPreloadManager.enable')
@DocsEditable()
@Experimental() // untriaged
- Future enable() native;
+ Future enable() => promiseToFuture(JS("", "#.enable()", this));
@DomName('NavigationPreloadManager.getState')
@DocsEditable()
@Experimental() // untriaged
- Future getState() native;
+ Future<Map> getState() =>
+ promiseToFutureDictionary(JS("", "#.getState()", this));
}
// 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
@@ -28307,7 +28494,7 @@
@DomName('Navigator.getBattery')
@DocsEditable()
@Experimental() // untriaged
- Future getBattery() native;
+ Future getBattery() => promiseToFuture(JS("", "#.getBattery()", this));
@JSName('getGamepads')
@DomName('Navigator.getGamepads')
@@ -28320,12 +28507,14 @@
@DomName('Navigator.getInstalledRelatedApps')
@DocsEditable()
@Experimental() // untriaged
- Future getInstalledRelatedApps() native;
+ Future<RelatedApplication> getInstalledRelatedApps() =>
+ promiseToFuture<RelatedApplication>(
+ JS("", "#.getInstalledRelatedApps()", this));
@DomName('Navigator.getVRDisplays')
@DocsEditable()
@Experimental() // untriaged
- Future getVRDisplays() native;
+ Future getVRDisplays() => promiseToFuture(JS("", "#.getVRDisplays()", this));
@DomName('Navigator.registerProtocolHandler')
@DocsEditable()
@@ -28380,7 +28569,9 @@
@DocsEditable()
@Experimental() // untriaged
Future requestMediaKeySystemAccess(
- String keySystem, List<Map> supportedConfigurations) native;
+ String keySystem, List<Map> supportedConfigurations) =>
+ promiseToFuture(JS("", "#.requestMediaKeySystemAccess(#, #)", this,
+ keySystem, supportedConfigurations));
@DomName('Navigator.sendBeacon')
@DocsEditable()
@@ -30139,7 +30330,7 @@
@DomName('OffscreenCanvasRenderingContext2D.commit')
@DocsEditable()
@Experimental() // untriaged
- Future commit() native;
+ Future commit() => promiseToFuture(JS("", "#.commit()", this));
@DomName('OffscreenCanvasRenderingContext2D.createImageData')
@DocsEditable()
@@ -31380,27 +31571,31 @@
@DomName('PaymentInstruments.clear')
@DocsEditable()
@Experimental() // untriaged
- Future clear() native;
+ Future clear() => promiseToFuture(JS("", "#.clear()", this));
@DomName('PaymentInstruments.delete')
@DocsEditable()
@Experimental() // untriaged
- Future delete(String instrumentKey) native;
+ Future<bool> delete(String instrumentKey) =>
+ promiseToFuture<bool>(JS("", "#.delete(#)", this, instrumentKey));
@DomName('PaymentInstruments.get')
@DocsEditable()
@Experimental() // untriaged
- Future get(String instrumentKey) native;
+ Future<Map> get(String instrumentKey) =>
+ promiseToFutureDictionary(JS("", "#.get(#)", this, instrumentKey));
@DomName('PaymentInstruments.has')
@DocsEditable()
@Experimental() // untriaged
- Future has(String instrumentKey) native;
+ Future has(String instrumentKey) =>
+ promiseToFuture(JS("", "#.has(#)", this, instrumentKey));
@DomName('PaymentInstruments.keys')
@DocsEditable()
@Experimental() // untriaged
- Future keys() native;
+ Future<List<String>> keys() =>
+ promiseToFuture<List<String>>(JS("", "#.keys()", this));
@DomName('PaymentInstruments.set')
@DocsEditable()
@@ -31500,17 +31695,19 @@
@DomName('PaymentRequest.abort')
@DocsEditable()
@Experimental() // untriaged
- Future abort() native;
+ Future abort() => promiseToFuture(JS("", "#.abort()", this));
@DomName('PaymentRequest.canMakePayment')
@DocsEditable()
@Experimental() // untriaged
- Future canMakePayment() native;
+ Future<bool> canMakePayment() =>
+ promiseToFuture<bool>(JS("", "#.canMakePayment()", this));
@DomName('PaymentRequest.show')
@DocsEditable()
@Experimental() // untriaged
- Future show() native;
+ Future<PaymentResponse> show() =>
+ promiseToFuture<PaymentResponse>(JS("", "#.show()", this));
}
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
@@ -31577,7 +31774,8 @@
@DomName('PaymentRequestEvent.openWindow')
@DocsEditable()
@Experimental() // untriaged
- Future openWindow(String url) native;
+ Future<WindowClient> openWindow(String url) =>
+ promiseToFuture<WindowClient>(JS("", "#.openWindow(#)", this, url));
@DomName('PaymentRequestEvent.respondWith')
@DocsEditable()
@@ -31677,7 +31875,8 @@
@DomName('PaymentResponse.complete')
@DocsEditable()
@Experimental() // untriaged
- Future complete([String paymentResult]) native;
+ Future complete([String paymentResult]) =>
+ promiseToFuture(JS("", "#.complete(#)", this, paymentResult));
}
// 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
@@ -32347,7 +32546,9 @@
@DomName('Permissions.requestAll')
@DocsEditable()
@Experimental() // untriaged
- Future requestAll(List<Map> permissions) native;
+ Future<PermissionStatus> requestAll(List<Map> permissions) =>
+ promiseToFuture<PermissionStatus>(
+ JS("", "#.requestAll(#)", this, permissions));
@DomName('Permissions.revoke')
@DocsEditable()
@@ -32984,17 +33185,22 @@
@DomName('PresentationRequest.getAvailability')
@DocsEditable()
@Experimental() // untriaged
- Future getAvailability() native;
+ Future<PresentationAvailability> getAvailability() =>
+ promiseToFuture<PresentationAvailability>(
+ JS("", "#.getAvailability()", this));
@DomName('PresentationRequest.reconnect')
@DocsEditable()
@Experimental() // untriaged
- Future reconnect(String id) native;
+ Future<PresentationConnection> reconnect(String id) =>
+ promiseToFuture<PresentationConnection>(
+ JS("", "#.reconnect(#)", this, id));
@DomName('PresentationRequest.start')
@DocsEditable()
@Experimental() // untriaged
- Future start() native;
+ Future<PresentationConnection> start() =>
+ promiseToFuture<PresentationConnection>(JS("", "#.start()", this));
}
// 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
@@ -33221,7 +33427,8 @@
@DomName('PushManager.getSubscription')
@DocsEditable()
@Experimental() // untriaged
- Future getSubscription() native;
+ Future<PushSubscription> getSubscription() =>
+ promiseToFuture<PushSubscription>(JS("", "#.getSubscription()", this));
@DomName('PushManager.permissionState')
@DocsEditable()
@@ -33338,7 +33545,8 @@
@DomName('PushSubscription.unsubscribe')
@DocsEditable()
@Experimental() // untriaged
- Future unsubscribe() native;
+ Future<bool> unsubscribe() =>
+ promiseToFuture<bool>(JS("", "#.unsubscribe()", this));
}
// 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
@@ -33687,17 +33895,19 @@
@DomName('RemotePlayback.cancelWatchAvailability')
@DocsEditable()
@Experimental() // untriaged
- Future cancelWatchAvailability([int id]) native;
+ Future cancelWatchAvailability([int id]) =>
+ promiseToFuture(JS("", "#.cancelWatchAvailability(#)", this, id));
@DomName('RemotePlayback.prompt')
@DocsEditable()
@Experimental() // untriaged
- Future prompt() native;
+ Future prompt() => promiseToFuture(JS("", "#.prompt()", this));
@DomName('RemotePlayback.watchAvailability')
@DocsEditable()
@Experimental() // untriaged
- Future watchAvailability(RemotePlaybackAvailabilityCallback callback) native;
+ Future<int> watchAvailability(RemotePlaybackAvailabilityCallback callback) =>
+ promiseToFuture<int>(JS("", "#.watchAvailability(#)", this, callback));
}
// 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
@@ -34301,15 +34511,6 @@
return completer.future;
}
- @DomName('RTCPeerConnection.getStats')
- Future<RtcStatsResponse> getStats(MediaStreamTrack selector) {
- var completer = new Completer<RtcStatsResponse>();
- _getStats((value) {
- completer.complete(value);
- }, selector);
- return completer.future;
- }
-
@DomName('RTCPeerConnection.generateCertificate')
@DocsEditable()
@Experimental() // untriaged
@@ -34422,8 +34623,10 @@
@DomName('RTCPeerConnection.addIceCandidate')
@DocsEditable()
Future addIceCandidate(Object candidate,
- [VoidCallback successCallback,
- RtcPeerConnectionErrorCallback failureCallback]) native;
+ [VoidCallback successCallback,
+ RtcPeerConnectionErrorCallback failureCallback]) =>
+ promiseToFuture(JS("", "#.addIceCandidate(#, #, #)", this, candidate,
+ successCallback, failureCallback));
@DomName('RTCPeerConnection.addStream')
@DocsEditable()
@@ -34601,11 +34804,9 @@
@Experimental() // untriaged
List<RtcRtpSender> getSenders() native;
- @JSName('getStats')
@DomName('RTCPeerConnection.getStats')
@DocsEditable()
- Future _getStats(
- [RtcStatsCallback successCallback, MediaStreamTrack selector]) native;
+ Future getStats() => promiseToFutureMap(JS("", "#.getStats()", this));
@DomName('RTCPeerConnection.removeStream')
@DocsEditable()
@@ -34876,11 +35077,68 @@
// http://dev.w3.org/2011/webrtc/editor/webrtc.html#idl-def-RTCStatsReport
@Experimental()
@Native("RTCStatsReport")
-class RtcStatsReport extends Interceptor {
+class RtcStatsReport extends Interceptor with MapMixin<String, dynamic> {
// To suppress missing implicit constructor warnings.
factory RtcStatsReport._() {
throw new UnsupportedError("Not supported");
}
+
+ Map _getItem(String key) =>
+ convertNativeToDart_Dictionary(JS('', '#.get(#)', this, key));
+
+ void addAll(Map<String, dynamic> other) {
+ throw new UnsupportedError("Not supported");
+ }
+
+ bool containsValue(dynamic value) => values.any((e) => e == value);
+
+ bool containsKey(dynamic key) => _getItem(key) != null;
+
+ Map operator [](dynamic key) => _getItem(key);
+
+ void forEach(void f(String key, dynamic value)) {
+ var entries = JS('', '#.entries()', this);
+ while (true) {
+ var entry = JS('', '#.next()', entries);
+ if (JS('bool', '#.done', entry)) return;
+ f(JS('String', '#.value[0]', entry),
+ convertNativeToDart_Dictionary(JS('', '#.value[1]', entry)));
+ }
+ }
+
+ Iterable<String> get keys {
+ final keys = <String>[];
+ forEach((k, v) => keys.add(k));
+ return keys;
+ }
+
+ Iterable<Map> get values {
+ final values = <Map>[];
+ forEach((k, v) => values.add(v));
+ return values;
+ }
+
+ int get length => JS('int', '#.size', this);
+
+ bool get isEmpty => length == 0;
+
+ bool get isNotEmpty => !isEmpty;
+
+ void operator []=(String key, dynamic value) {
+ throw new UnsupportedError("Not supported");
+ }
+
+ dynamic putIfAbsent(String key, dynamic ifAbsent()) {
+ throw new UnsupportedError("Not supported");
+ }
+
+ String remove(dynamic key) {
+ throw new UnsupportedError("Not supported");
+ }
+
+ void clear() {
+ throw new UnsupportedError("Not supported");
+ }
}
// 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
@@ -35043,7 +35301,8 @@
@DomName('ScreenOrientation.lock')
@DocsEditable()
@Experimental() // untriaged
- Future lock(String orientation) native;
+ Future lock(String orientation) =>
+ promiseToFuture(JS("", "#.lock(#)", this, orientation));
@DomName('ScreenOrientation.unlock')
@DocsEditable()
@@ -35771,12 +36030,16 @@
@DomName('ServiceWorkerContainer.getRegistration')
@DocsEditable()
@Experimental() // untriaged
- Future getRegistration([String documentURL]) native;
+ Future<ServiceWorkerRegistration> getRegistration([String documentURL]) =>
+ promiseToFuture<ServiceWorkerRegistration>(
+ JS("", "#.getRegistration(#)", this, documentURL));
@DomName('ServiceWorkerContainer.getRegistrations')
@DocsEditable()
@Experimental() // untriaged
- Future getRegistrations() native;
+ Future<List<ServiceWorkerRegistration>> getRegistrations() =>
+ promiseToFuture<List<ServiceWorkerRegistration>>(
+ JS("", "#.getRegistrations()", this));
@DomName('ServiceWorkerContainer.register')
@DocsEditable()
@@ -35862,7 +36125,7 @@
@DomName('ServiceWorkerGlobalScope.skipWaiting')
@DocsEditable()
@Experimental() // untriaged
- Future skipWaiting() native;
+ Future skipWaiting() => promiseToFuture(JS("", "#.skipWaiting()", this));
@DomName('ServiceWorkerGlobalScope.onactivate')
@DocsEditable()
@@ -35996,12 +36259,13 @@
@DomName('ServiceWorkerRegistration.unregister')
@DocsEditable()
@Experimental() // untriaged
- Future unregister() native;
+ Future<bool> unregister() =>
+ promiseToFuture<bool>(JS("", "#.unregister()", this));
@DomName('ServiceWorkerRegistration.update')
@DocsEditable()
@Experimental() // untriaged
- Future update() native;
+ Future update() => promiseToFuture(JS("", "#.update()", this));
}
// 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
@@ -37639,17 +37903,19 @@
@DomName('StorageManager.estimate')
@DocsEditable()
@Experimental() // untriaged
- Future estimate() native;
+ Future<Map> estimate() =>
+ promiseToFutureDictionary(JS("", "#.estimate()", this));
@DomName('StorageManager.persist')
@DocsEditable()
@Experimental() // untriaged
- Future persist() native;
+ Future<bool> persist() => promiseToFuture<bool>(JS("", "#.persist()", this));
@DomName('StorageManager.persisted')
@DocsEditable()
@Experimental() // untriaged
- Future persisted() native;
+ Future<bool> persisted() =>
+ promiseToFuture<bool>(JS("", "#.persisted()", this));
}
// 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
@@ -37892,12 +38158,14 @@
@DomName('SyncManager.getTags')
@DocsEditable()
@Experimental() // untriaged
- Future getTags() native;
+ Future<List<String>> getTags() =>
+ promiseToFuture<List<String>>(JS("", "#.getTags()", this));
@DomName('SyncManager.register')
@DocsEditable()
@Experimental() // untriaged
- Future register(String tag) native;
+ Future register(String tag) =>
+ promiseToFuture(JS("", "#.register(#)", this, tag));
}
// 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
@@ -38591,7 +38859,8 @@
@DomName('TextDetector.detect')
@DocsEditable()
@Experimental() // untriaged
- Future detect(/*ImageBitmapSource*/ image) native;
+ Future<List<DetectedText>> detect(/*ImageBitmapSource*/ image) =>
+ promiseToFuture<List<DetectedText>>(JS("", "#.detect(#)", this, image));
}
// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
@@ -39863,7 +40132,8 @@
@DomName('UnderlyingSourceBase.cancel')
@DocsEditable()
@Experimental() // untriaged
- Future cancel(Object reason) native;
+ Future cancel(Object reason) =>
+ promiseToFuture(JS("", "#.cancel(#)", this, reason));
@DomName('UnderlyingSourceBase.notifyLockAcquired')
@DocsEditable()
@@ -39878,12 +40148,13 @@
@DomName('UnderlyingSourceBase.pull')
@DocsEditable()
@Experimental() // untriaged
- Future pull() native;
+ Future pull() => promiseToFuture(JS("", "#.pull()", this));
@DomName('UnderlyingSourceBase.start')
@DocsEditable()
@Experimental() // untriaged
- Future start(Object stream) native;
+ Future start(Object stream) =>
+ promiseToFuture(JS("", "#.start(#)", this, stream));
}
// 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
@@ -40107,7 +40378,7 @@
@DomName('VR.getDevices')
@DocsEditable()
@Experimental() // untriaged
- Future getDevices() native;
+ Future getDevices() => promiseToFuture(JS("", "#.getDevices()", this));
}
// 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
@@ -40281,7 +40552,7 @@
@DomName('VRDisplay.exitPresent')
@DocsEditable()
@Experimental() // untriaged
- Future exitPresent() native;
+ Future exitPresent() => promiseToFuture(JS("", "#.exitPresent()", this));
@DomName('VRDisplay.getEyeParameters')
@DocsEditable()
@@ -40306,7 +40577,8 @@
@DomName('VRDisplay.requestPresent')
@DocsEditable()
@Experimental() // untriaged
- Future requestPresent(List<Map> layers) native;
+ Future requestPresent(List<Map> layers) =>
+ promiseToFuture(JS("", "#.requestPresent(#)", this, layers));
@DomName('VRDisplay.submitFrame')
@DocsEditable()
@@ -40577,7 +40849,7 @@
@DomName('VRSession.end')
@DocsEditable()
@Experimental() // untriaged
- Future end() native;
+ Future end() => promiseToFuture(JS("", "#.end()", this));
@DomName('VRSession.requestFrameOfReference')
@DocsEditable()
@@ -43905,12 +44177,14 @@
@DomName('WindowClient.focus')
@DocsEditable()
@Experimental() // untriaged
- Future focus() native;
+ Future<WindowClient> focus() =>
+ promiseToFuture<WindowClient>(JS("", "#.focus()", this));
@DomName('WindowClient.navigate')
@DocsEditable()
@Experimental() // untriaged
- Future navigate(String url) native;
+ Future<WindowClient> navigate(String url) =>
+ promiseToFuture<WindowClient>(JS("", "#.navigate(#)", this, url));
}
// 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
@@ -44787,17 +45061,20 @@
@DomName('BudgetService.getBudget')
@DocsEditable()
@Experimental() // untriaged
- Future getBudget() native;
+ Future<BudgetState> getBudget() =>
+ promiseToFuture<BudgetState>(JS("", "#.getBudget()", this));
@DomName('BudgetService.getCost')
@DocsEditable()
@Experimental() // untriaged
- Future getCost(String operation) native;
+ Future<double> getCost(String operation) =>
+ promiseToFuture<double>(JS("", "#.getCost(#)", this, operation));
@DomName('BudgetService.reserve')
@DocsEditable()
@Experimental() // untriaged
- Future reserve(String operation) native;
+ Future<bool> reserve(String operation) =>
+ promiseToFuture<bool>(JS("", "#.reserve(#)", this, operation));
}
// 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
@@ -44842,22 +45119,26 @@
@DomName('Clipboard.read')
@DocsEditable()
@Experimental() // untriaged
- Future read() native;
+ Future<DataTransfer> read() =>
+ promiseToFuture<DataTransfer>(JS("", "#.read()", this));
@DomName('Clipboard.readText')
@DocsEditable()
@Experimental() // untriaged
- Future readText() native;
+ Future<String> readText() =>
+ promiseToFuture<String>(JS("", "#.readText()", this));
@DomName('Clipboard.write')
@DocsEditable()
@Experimental() // untriaged
- Future write(DataTransfer data) native;
+ Future write(DataTransfer data) =>
+ promiseToFuture(JS("", "#.write(#)", this, data));
@DomName('Clipboard.writeText')
@DocsEditable()
@Experimental() // untriaged
- Future writeText(String data) native;
+ Future writeText(String data) =>
+ promiseToFuture(JS("", "#.writeText(#)", this, data));
}
// 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
diff --git a/sdk/lib/svg/dart2js/svg_dart2js.dart b/sdk/lib/svg/dart2js/svg_dart2js.dart
index 16ba803..23c0a70 100644
--- a/sdk/lib/svg/dart2js/svg_dart2js.dart
+++ b/sdk/lib/svg/dart2js/svg_dart2js.dart
@@ -2683,7 +2683,7 @@
@DomName('SVGImageElement.decode')
@DocsEditable()
@Experimental() // untriaged
- Future decode() native;
+ Future decode() => promiseToFuture(JS("", "#.decode()", this));
// From SVGURIReference
diff --git a/sdk/lib/web_audio/dart2js/web_audio_dart2js.dart b/sdk/lib/web_audio/dart2js/web_audio_dart2js.dart
index c927559..c12fe76 100644
--- a/sdk/lib/web_audio/dart2js/web_audio_dart2js.dart
+++ b/sdk/lib/web_audio/dart2js/web_audio_dart2js.dart
@@ -240,7 +240,7 @@
@DomName('AudioContext.close')
@DocsEditable()
@Experimental() // untriaged
- Future close() native;
+ Future close() => promiseToFuture(JS("", "#.close()", this));
@DomName('AudioContext.getOutputTimestamp')
@DocsEditable()
@@ -258,7 +258,7 @@
@DomName('AudioContext.suspend')
@DocsEditable()
@Experimental() // untriaged
- Future suspend() native;
+ Future suspend() => promiseToFuture(JS("", "#.suspend()", this));
factory AudioContext() => JS('AudioContext',
'new (window.AudioContext || window.webkitAudioContext)()');
@@ -534,11 +534,68 @@
@DomName('AudioParamMap')
@Experimental() // untriaged
@Native("AudioParamMap")
-class AudioParamMap extends Interceptor {
+class AudioParamMap extends Interceptor with MapMixin<String, dynamic> {
// To suppress missing implicit constructor warnings.
factory AudioParamMap._() {
throw new UnsupportedError("Not supported");
}
+
+ Map _getItem(String key) =>
+ convertNativeToDart_Dictionary(JS('', '#.get(#)', this, key));
+
+ void addAll(Map<String, dynamic> other) {
+ throw new UnsupportedError("Not supported");
+ }
+
+ bool containsValue(dynamic value) => values.any((e) => e == value);
+
+ bool containsKey(dynamic key) => _getItem(key) != null;
+
+ Map operator [](dynamic key) => _getItem(key);
+
+ void forEach(void f(String key, dynamic value)) {
+ var entries = JS('', '#.entries()', this);
+ while (true) {
+ var entry = JS('', '#.next()', entries);
+ if (JS('bool', '#.done', entry)) return;
+ f(JS('String', '#.value[0]', entry),
+ convertNativeToDart_Dictionary(JS('', '#.value[1]', entry)));
+ }
+ }
+
+ Iterable<String> get keys {
+ final keys = <String>[];
+ forEach((k, v) => keys.add(k));
+ return keys;
+ }
+
+ Iterable<Map> get values {
+ final values = <Map>[];
+ forEach((k, v) => values.add(v));
+ return values;
+ }
+
+ int get length => JS('int', '#.size', this);
+
+ bool get isEmpty => length == 0;
+
+ bool get isNotEmpty => !isEmpty;
+
+ void operator []=(String key, dynamic value) {
+ throw new UnsupportedError("Not supported");
+ }
+
+ dynamic putIfAbsent(String key, dynamic ifAbsent()) {
+ throw new UnsupportedError("Not supported");
+ }
+
+ String remove(dynamic key) {
+ throw new UnsupportedError("Not supported");
+ }
+
+ void clear() {
+ throw new UnsupportedError("Not supported");
+ }
}
// 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
@@ -955,14 +1012,16 @@
@DomName('BaseAudioContext.decodeAudioData')
@DocsEditable()
@Experimental() // untriaged
- Future decodeAudioData(ByteBuffer audioData,
- [DecodeSuccessCallback successCallback,
- DecodeErrorCallback errorCallback]) native;
+ Future<AudioBuffer> decodeAudioData(ByteBuffer audioData,
+ [DecodeSuccessCallback successCallback,
+ DecodeErrorCallback errorCallback]) =>
+ promiseToFuture<AudioBuffer>(JS("", "#.decodeAudioData(#, #, #)", this,
+ audioData, successCallback, errorCallback));
@DomName('BaseAudioContext.resume')
@DocsEditable()
@Experimental() // untriaged
- Future resume() native;
+ Future resume() => promiseToFuture(JS("", "#.resume()", this));
}
// 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
@@ -1481,13 +1540,15 @@
@DomName('OfflineAudioContext.startRendering')
@DocsEditable()
@Experimental() // untriaged
- Future startRendering() native;
+ Future<AudioBuffer> startRendering() =>
+ promiseToFuture<AudioBuffer>(JS("", "#.startRendering()", this));
@JSName('suspend')
@DomName('OfflineAudioContext.suspend')
@DocsEditable()
@Experimental() // untriaged
- Future suspendFor(num suspendTime) native;
+ Future suspendFor(num suspendTime) =>
+ promiseToFuture(JS("", "#.suspendFor(#)", this, suspendTime));
}
// 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
diff --git a/sdk/lib/web_gl/dart2js/web_gl_dart2js.dart b/sdk/lib/web_gl/dart2js/web_gl_dart2js.dart
index 657d0a8..b3d8ba3 100644
--- a/sdk/lib/web_gl/dart2js/web_gl_dart2js.dart
+++ b/sdk/lib/web_gl/dart2js/web_gl_dart2js.dart
@@ -1387,7 +1387,9 @@
@DocsEditable()
@Experimental() // untriaged
Future getBufferSubDataAsync(int target, int srcByteOffset, TypedData dstData,
- [int dstOffset, int length]) native;
+ [int dstOffset, int length]) =>
+ promiseToFuture(JS("", "#.getBufferSubDataAsync(#, #, #, #, #)", this,
+ target, srcByteOffset, dstData, dstOffset, length));
}
// 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
@@ -2895,7 +2897,7 @@
@DomName('WebGLRenderingContext.commit')
@DocsEditable()
@Experimental() // untriaged
- Future commit() native;
+ Future commit() => promiseToFuture(JS("", "#.commit()", this));
@DomName('WebGLRenderingContext.compileShader')
@DocsEditable()
@@ -6709,7 +6711,7 @@
@DomName('WebGL2RenderingContext.commit')
@DocsEditable()
@Experimental() // untriaged
- Future commit() native;
+ Future commit() => promiseToFuture(JS("", "#.commit()", this));
@DomName('WebGL2RenderingContext.compileShader')
@DocsEditable()
diff --git a/tests/lib_2/html/interactive_media_test.dart b/tests/lib_2/html/interactive_media_test.dart
index 1ad71c0..25d43d4 100644
--- a/tests/lib_2/html/interactive_media_test.dart
+++ b/tests/lib_2/html/interactive_media_test.dart
@@ -6,14 +6,31 @@
import 'dart:async';
import 'dart:html';
-import 'package:unittest/unittest.dart';
-import 'package:unittest/html_individual_config.dart';
-import 'utils.dart';
-main() {
- useHtmlIndividualConfiguration();
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
+import 'package:async_helper/async_helper.dart';
+
+// NOTE: To test enable chrome://flags/#enable-experimental-web-platform-features
+
+main() async {
+ useHtmlConfiguration();
if (MediaStream.supported) {
+ test('getUserMedia audio', () async {
+ var mediaStream = await window.navigator.getUserMedia(audio: true);
+ expect(mediaStream, isNotNull);
+ expect(mediaStream is MediaStream, true);
+ var devices = window.navigator.mediaDevices;
+ var enumDevices = await devices.enumerateDevices();
+ expect(enumDevices.length > 1, true);
+ for (var device in enumDevices) {
+ var goodDevLabel = device.label.endsWith('Built-in Output') ||
+ device.label.endsWith('Built-in Microphone');
+ expect(goodDevLabel, true);
+ }
+ });
+
test('getUserMedia', () {
return window.navigator.getUserMedia(video: true).then((stream) {
expect(stream, isNotNull);
diff --git a/tests/lib_2/html/storage_promise_test.dart b/tests/lib_2/html/storage_promise_test.dart
new file mode 100644
index 0000000..b1e1b13
--- /dev/null
+++ b/tests/lib_2/html/storage_promise_test.dart
@@ -0,0 +1,42 @@
+// Copyright (c) 2013, 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.
+
+library interactive_test;
+
+import 'dart:async';
+import 'dart:html';
+
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
+import 'package:async_helper/async_helper.dart';
+
+main() async {
+ useHtmlConfiguration();
+
+ bool thenEstimateBefore, thenEstimateAfter, thenEstimateDone = false;
+ Map thenEstimate;
+ test('Basic Promise Test', () async {
+ try {
+ thenEstimateBefore = true;
+ window.navigator.storage.estimate().then((value) {
+ thenEstimate = value;
+ thenEstimateDone = true;
+ });
+ thenEstimateAfter = true;
+ } catch (msg) {
+ fail("StorageManger failed: $msg");
+ }
+
+ Map estimate = await window.navigator.storage.estimate();
+
+ expect(thenEstimate['usage'] >= 0, true);
+ expect(thenEstimate['quota'] > 1, true);
+ expect(thenEstimate['usage'], estimate['usage']);
+ expect(thenEstimate['quota'], estimate['quota']);
+
+ expect(thenEstimateBefore, true);
+ expect(thenEstimateAfter, true);
+ expect(thenEstimateDone, true);
+ });
+}
diff --git a/tests/lib_2/lib_2_dart2js.status b/tests/lib_2/lib_2_dart2js.status
index 9177102..2c9460f 100644
--- a/tests/lib_2/lib_2_dart2js.status
+++ b/tests/lib_2/lib_2_dart2js.status
@@ -293,6 +293,7 @@
html/shadow_dom_test: RuntimeError
html/shadowroot_test: RuntimeError
html/speechrecognition_test: RuntimeError
+html/storage_promise_test: RuntimeError
html/storage_test: RuntimeError
html/streams_test: RuntimeError
html/svg_test: RuntimeError
@@ -341,7 +342,7 @@
html/fontface_loaded_test: RuntimeError
html/html_mock_test: RuntimeError # Issue 31038
html/input_element_attributes_test: RuntimeError
-html/interactive_media_test: RuntimeError
+html/interactive_media_test: RuntimeError # # See NOTE in test on how to run.
html/js_dart_functions_test: RuntimeError # does not implement Dart 2 implicit `.call` tearoff
html/js_extend_class_test: RuntimeError
diff --git a/tests/lib_2/lib_2_dartdevc.status b/tests/lib_2/lib_2_dartdevc.status
index c9e3342..e2910bb 100644
--- a/tests/lib_2/lib_2_dartdevc.status
+++ b/tests/lib_2/lib_2_dartdevc.status
@@ -26,7 +26,7 @@
[ $system == linux && ($compiler == dartdevc || $compiler == dartdevk) ]
html/interactive_geolocation_test: Skip # Requires allowing geo location.
-html/interactive_media_test: RuntimeError
+html/interactive_media_test: RuntimeError # # See NOTE in test on how to run.
[ $system == macos && ($compiler == dartdevc || $compiler == dartdevk) ]
html/client_rect_test: Pass, RuntimeError # Issue 31019
@@ -85,7 +85,7 @@
html/element_classes_svg_test: RuntimeError # Issue 29922
html/element_classes_test: RuntimeError # Issue 29922
html/fontface_loaded_test: RuntimeError
-html/interactive_media_test: Skip # requests interactive permissions (camera, geolocation)
+html/interactive_media_test: RuntimeError # See NOTE in test on how to run and interactive permissions (camera, geolocation)
html/isolates_test: RuntimeError # Issue 29922
html/js_typed_interop_default_arg_test/default_value: MissingCompileTimeError # Issue 29922
html/js_typed_interop_side_cast_exp_test/01: RuntimeError # Requires --experimental-trust-js-interop-type-annotations flag.
diff --git a/tools/dom/dom.json b/tools/dom/dom.json
index 92995fc..cf6254c 100644
--- a/tools/dom/dom.json
+++ b/tools/dom/dom.json
@@ -14628,6 +14628,9 @@
"support_level": "untriaged"
},
"getStats": {},
+ "getStats2": {
+ "support_level": "untriaged"
+ },
"getStreamById": {},
"iceConnectionState": {},
"iceGatheringState": {},
diff --git a/tools/dom/idl/dart/dart.idl b/tools/dom/idl/dart/dart.idl
index 6773b11..a713b78 100644
--- a/tools/dom/idl/dart/dart.idl
+++ b/tools/dom/idl/dart/dart.idl
@@ -133,6 +133,9 @@
[DartSupplemental]
interface RTCPeerConnection {
[DartSuppress, RaisesException] void addIceCandidate(RTCIceCandidate candidate);
+ [DartSuppress] Promise<void> getStats(RTCStatsCallback successCallback, optional MediaStreamTrack? selector);
+ [DartSuppress] Promise<void> setLocalDescription(RTCSessionDescriptionInit description);
+ [DartSuppress] Promise<void> setRemoteDescription(RTCSessionDescriptionInit description);
};
// See implementation in tools/dom/templates for canvas and offscreenCanvas.
@@ -565,12 +568,6 @@
[DartName=inch] readonly attribute double? in;
};
-[DartSupplemental]
-interface RTCPeerConnection {
- [DartSuppress] Promise<void> setLocalDescription(RTCSessionDescriptionInit description);
- [DartSuppress] Promise<void> setRemoteDescription(RTCSessionDescriptionInit description);
-};
-
[DartSuppress]
interface DragEvent {};
diff --git a/tools/dom/scripts/htmlrenamer.py b/tools/dom/scripts/htmlrenamer.py
index cde90fb..d0cb493 100644
--- a/tools/dom/scripts/htmlrenamer.py
+++ b/tools/dom/scripts/htmlrenamer.py
@@ -187,7 +187,7 @@
html_interface_renames[interface] = '_' + interface
convert_to_future_members = monitored.Set(
- 'htmlrenamer.converted_to_future_members', [
+ 'htmlrenamer.converted_to_future_members', [
'DataTransferItem.getAsString',
'DirectoryEntry.getDirectory',
'DirectoryEntry.getFile',
@@ -425,7 +425,6 @@
'Range.getClientRects',
'RTCPeerConnection.createAnswer',
'RTCPeerConnection.createOffer',
- 'RTCPeerConnection.getStats',
'Screen.availHeight',
'Screen.availLeft',
'Screen.availTop',
diff --git a/tools/dom/scripts/idlnode.py b/tools/dom/scripts/idlnode.py
index a9b7fd7..b2e06d2 100644
--- a/tools/dom/scripts/idlnode.py
+++ b/tools/dom/scripts/idlnode.py
@@ -854,6 +854,13 @@
if not (self._find_first(ast, 'Partial') is None):
self.is_supplemental = True
self.ext_attrs['DartSupplemental'] = None
+ self.isMaplike = False
+ self.isMaplike_ro = False
+ self.maplike_key_value = [None, None]
+ if ast is not None and ast.maplike is not None:
+ self.isMaplike = True
+ self.isMaplike_ro = ast.maplike.is_read_only
+ self.maplike_key_value = [IDLType(ast.maplike.key_type), IDLType(ast.maplike.value_type)]
self.operations = self._convert_all(ast, 'Operation',
lambda ast: IDLOperation(ast, self.doc_js_name))
diff --git a/tools/dom/scripts/systemhtml.py b/tools/dom/scripts/systemhtml.py
index e100908..036b320 100644
--- a/tools/dom/scripts/systemhtml.py
+++ b/tools/dom/scripts/systemhtml.py
@@ -666,6 +666,14 @@
self._interface.id == 'CSSStyleDeclaration')):
base_class = 'DartHtmlDomObject'
+ maplikeKeyType = ''
+ maplikeValueType = ''
+ if self._interface.isMaplike:
+ maplikeKeyType = self._type_registry.\
+ _TypeInfo(self._interface.maplike_key_value[0].id).dart_type()
+ maplikeValueType = 'dynamic'
+ mixins_str = " with MapMixin<%s, %s>" % (maplikeKeyType, maplikeValueType)
+
implementation_members_emitter = implementation_emitter.Emit(
self._backend.ImplementationTemplate(),
LIBRARYNAME='dart.dom.%s' % self._library_name,
@@ -676,7 +684,9 @@
IMPLEMENTS=implements_str,
MIXINS=mixins_str,
DOMNAME=self._interface.doc_js_name,
- NATIVESPEC=native_spec)
+ NATIVESPEC=native_spec,
+ KEYTYPE=maplikeKeyType,
+ VALUETYPE=maplikeValueType)
stream_getter_signatures_emitter = None
element_stream_getters_emitter = None
if type(implementation_members_emitter) == tuple:
@@ -753,6 +763,102 @@
# ------------------------------------------------------------------------------
+''' TODO(terry): Current idl_parser (Chrome) doesn't keep the Promise type e.g.,
+ Promise<T> in the AST so there is no way to pull this out. Need
+ to investigate getting the Chrome folks to fix. However, they
+ don't use this in the C++ code generation and don't have a need
+ for this feature. For now I have a table that maps to the
+ parameterized Promise type.
+'''
+promise_attributes = monitored.Dict('systemhtml.promise_attr_type', {
+ "Animation.finished": {"type": "Animation"},
+ "Animation.ready": {"type": "Animation"},
+ "FontFace.loaded": {"type": "FontFace"},
+ "FontFaceSet.ready": {"type": "FontFaceSet"},
+ "PresentationReceiver.connectionList": {"type": "PresentationConnectionList"},
+ "ServiceWorkerContainer.ready": {"type": "ServiceWorkerRegistration"},
+})
+
+promise_operations = monitored.Dict('systemhtml.promise_oper_type', {
+ "Clipboard.read": { "type": "DataTransfer" },
+ "Clipboard.readText": { "type": "String" },
+ "FontFace.load": { "type": "FontFace"},
+ "FontFaceSet.load": { "type": "List<FontFace>" },
+ "OffscreenCanvas.load": { "type": "Blob" },
+ "BackgroundFetchManager.fetch": { "type": "BackgroundFetchRegistration" },
+ "BackgroundFetchManager.get": { "type": "BackgroundFetchRegistration" },
+ "BackgroundFetchManager.getIds": { "type": "List<String>" },
+ "BackgroundFetchRegistration.abort": { "type": "bool" },
+ "SyncManager.getTags": { "type": "List<String>" },
+ "BudgetService.getCost": { "type": "double" },
+ "BudgetService.getBudget": { "type": "BudgetState" },
+ "BudgetService.reserve": { "type": "bool" },
+ "Body.blob": { "type": "Blob" },
+ "Body.formData": { "type": "FormData" },
+ "Body.text": { "type": "String" },
+ "ImageCapture.getPhotoCapabilities": { "type": "PhotoCapabilities" },
+ "ImageCapture.getPhotoSettings": { "type": "dictionary" },
+ "ImageCapture.takePhoto": { "type": "Blob" },
+ "ImageCapture.grabFrame": { "type": "ImageBitmap" },
+ "Navigator.getInstalledRelatedApps": { "type": "RelatedApplication" },
+ "MediaCapabilities.decodingInfo": { "type": "MediaCapabilitiesInfo" },
+ "MediaCapabilities.encodingInfo": { "type": "MediaCapabilitiesInfo" },
+ "MediaDevices.enumerateDevices": { "type": "List<MediaDeviceInfo>" },
+ "MediaDevices.getUserMedia": { "type": "MediaStream" },
+ "MediaStreamTrack.applyConstraints": { "type": "MediaTrackConstraints" },
+ "ServiceWorkerRegistration.getNotifications": { "type": "List<Notification>" },
+ "PaymentInstruments.delete": { "type": "bool" },
+ "PaymentInstruments.get": { "type": "dictionary" },
+ "PaymentInstruments.keys": { "type": "List<String>" },
+ "PaymentInstrumentshas.": { "type": "bool" },
+ "PaymentRequest.show": { "type": "PaymentResponse" },
+ "PaymentRequest.canMakePayment": { "type": "bool" },
+ "PaymentRequestEvent.openWindow": { "type": "WindowClient" },
+ "RTCPeerConnection.createOffer": { "type": "RtcSessionDescription" },
+ "RTCPeerConnection.createAnswer": { "type": "RtcSessionDescription" },
+ "RTCPeerConnection.getStats": { "type": "dictionary", "maplike": "RTCStatsReport"},
+ "RTCPeerConnection.generateCertificate": { "type": "RtcCertificate" },
+ "Permissions.query": { "type": "PermissionStatus" },
+ "Permissions.request": { "type": "PermissionStatus" },
+ "Permissions.revoke": { "type": "PermissionStatus" },
+ "Permissions.requestAll": { "type": "PermissionStatus" },
+ "PresentationRequest.start": { "type": "PresentationConnection" },
+ "PresentationRequest.reconnect": { "type": "PresentationConnection" },
+ "PresentationRequest.getAvailability": { "type": "PresentationAvailability" },
+ "PushManager.subscribe": { "type": "PushSubscription" },
+ "PushManager.getSubscription": { "type": "PushSubscription" },
+ "PushSubscription.unsubscribe": { "type": "bool" },
+ "StorageManager.persisted": { "type": "bool" },
+ "StorageManager.persist": { "type": "bool" },
+ "StorageManager.estimate": { "type": "dictionary" },
+ "RemotePlayback.watchAvailability": { "type": "int" },
+ "Clients.matchAll": { "type": "List<Client>" },
+ "Clients.openWindow": { "type": "WindowClient" },
+ "NavigationPreloadManager.getState": { "type": "dictionary" },
+ "ServiceWorkerContainer.register": { "type": "ServiceWorkerRegistration" },
+ "ServiceWorkerContainer.getRegistration": { "type": "ServiceWorkerRegistration" },
+ "ServiceWorkerContainer.getRegistrations": { "type": "List<ServiceWorkerRegistration>" },
+ "ServiceWorkerGlobalScope.fetch": { "type": "Response" },
+ "ServiceWorkerRegistration.unregister": { "type": "bool" },
+ "WindowClient.focus": { "type": "WindowClient" },
+ "WindowClient.navigate": { "type": "WindowClient" },
+ "BarcodeDetector.detect": { "type": "List<DetectedBarcode>" },
+ "FaceDetector.detect": { "type": "List<DetectedFace>" },
+ "TextDetector.detect": { "type": "List<DetectedText>" },
+ "BaseAudioContext.decodeAudioData": { "type": "AudioBuffer" },
+ "OfflineAudioContext.startRendering": { "type": "AudioBuffer" },
+})
+
+def _GetPromiseOperationType(interface_operation):
+ if interface_operation in promise_operations:
+ return promise_operations[interface_operation]
+ return None
+
+def _GetPromiseAttributeType(interface_operation):
+ if interface_operation in promise_attributes:
+ return promise_attributes[interface_operation]
+ return None
+
class Dart2JSBackend(HtmlDartGenerator):
"""Generates a dart2js class for the dart:html library from a DOM IDL
interface.
@@ -792,8 +898,14 @@
def ImplementationTemplate(self):
template_file = ('impl_%s.darttemplate' %
self._interface.doc_js_name)
- return (self._template_loader.TryLoad(template_file) or
- self._template_loader.Load('dart2js_impl.darttemplate'))
+ template_file_content = self._template_loader.TryLoad(template_file)
+ if not(template_file_content):
+ if self._interface.isMaplike and self._interface.isMaplike_ro:
+ # TODO(terry): There are no mutable maplikes yet.
+ template_file_content = self._template_loader.Load('dart2js_maplike_impl.darttemplate')
+ else:
+ template_file_content = self._template_loader.Load('dart2js_impl.darttemplate')
+ return template_file_content
def StartInterface(self, members_emitter):
self._members_emitter = members_emitter
@@ -1150,13 +1262,61 @@
resultType = 'Function'
return resultType
+ def _zeroArgs(self, argsNames):
+ return 'JS("", "#.$NAME()", this)'
+
+ def _manyArgs(self, numberArgs, argsNames):
+ argsPound = "#" if numberArgs == 1 else ("#, " * numberArgs)[:-2]
+ return ' JS("", "#.$NAME(%s)", this, %s)' % (argsPound, argsNames)
+
+ def _promiseToFutureCode(self, argsNames):
+ numberArgs = argsNames.count(',') + 1
+ jsCall = self._zeroArgs(argsNames) if len(argsNames) == 0 else \
+ self._manyArgs(numberArgs, argsNames)
+
+ futureTemplate = [
+ '\n'
+ ' $RENAME$METADATA$MODIFIERS $TYPE $NAME($PARAMS) => $PROMISE_CALL(',
+ jsCall,
+ ');\n'
+ ]
+ return "".join(futureTemplate)
def _AddDirectNativeOperation(self, info, html_name):
force_optional = True if html_name.startswith('_') else False
-
resultType = self._computeResultType(info.type_name)
- self._members_emitter.Emit(
+ if info.type_name == 'Promise' and not(force_optional):
+ lookupOp = "%s.%s" % (self._interface.id, html_name)
+ promiseFound = _GetPromiseOperationType(lookupOp)
+ promiseType = 'Future'
+ promiseCall = 'promiseToFuture'
+ if promiseFound is not(None):
+ if 'maplike' in promiseFound:
+ promiseCall = 'promiseToFutureMap'
+ promiseType = 'Future'
+ elif promiseFound['type'] == 'dictionary':
+ # It's a dictionary so return as a Map.
+ promiseCall = 'promiseToFutureDictionary'
+ promiseType = 'Future<Map>'
+ else:
+ paramType = promiseFound['type']
+ promiseCall = 'promiseToFuture<%s>' % paramType
+ promiseType = 'Future<%s>' % paramType
+
+ argsNames = info.ParametersAsArgumentList()
+ codeTemplate = self._promiseToFutureCode(argsNames)
+ self._members_emitter.Emit(codeTemplate,
+ RENAME=self._RenamingAnnotation(info.declared_name, html_name),
+ METADATA=self._Metadata(info.type_name, info.declared_name,
+ self.SecureOutputType(info.type_name)),
+ MODIFIERS='static ' if info.IsStatic() else '',
+ TYPE=promiseType,
+ PROMISE_CALL=promiseCall,
+ NAME=html_name,
+ PARAMS=info.ParametersAsDeclaration(self._NarrowInputType, force_optional))
+ else:
+ self._members_emitter.Emit(
'\n'
' $RENAME$METADATA$MODIFIERS$TYPE $NAME($PARAMS) native;\n',
RENAME=self._RenamingAnnotation(info.declared_name, html_name),
diff --git a/tools/dom/templates/dart2js_maplike_impl.darttemplate b/tools/dom/templates/dart2js_maplike_impl.darttemplate
new file mode 100644
index 0000000..c2f8f91
--- /dev/null
+++ b/tools/dom/templates/dart2js_maplike_impl.darttemplate
@@ -0,0 +1,67 @@
+// 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.
+
+part of $LIBRARYNAME;
+
+@DocsEditable()
+$(ANNOTATIONS)$(NATIVESPEC)$(CLASS_MODIFIERS)class $CLASSNAME$EXTENDS$MIXINS$IMPLEMENTS {
+$!MEMBERS
+
+ Map _getItem($KEYTYPE key) =>
+ convertNativeToDart_Dictionary(JS('', '#.get(#)', this, key));
+
+ void addAll(Map<$KEYTYPE, $VALUETYPE> other) {
+ throw new UnsupportedError("Not supported");
+ }
+
+ bool containsValue($VALUETYPE value) => values.any((e) => e == value);
+
+ bool containsKey($VALUETYPE key) => _getItem(key) != null;
+
+ Map operator []($VALUETYPE key) => _getItem(key);
+
+ void forEach(void f($KEYTYPE key, $VALUETYPE value)) {
+ var entries = JS('', '#.entries()', this);
+ while (true) {
+ var entry = JS('', '#.next()', entries);
+ if (JS('bool', '#.done', entry)) return;
+ f(JS('$KEYTYPE', '#.value[0]', entry),
+ convertNativeToDart_Dictionary(JS('', '#.value[1]', entry)));
+ }
+ }
+
+ Iterable<$KEYTYPE> get keys {
+ final keys = <$KEYTYPE>[];
+ forEach((k, v) => keys.add(k));
+ return keys;
+ }
+
+ Iterable<Map> get values {
+ final values = <Map>[];
+ forEach((k, v) => values.add(v));
+ return values;
+ }
+
+ int get length => JS('int', '#.size', this);
+
+ bool get isEmpty => length == 0;
+
+ bool get isNotEmpty => !isEmpty;
+
+ void operator []=($KEYTYPE key, $VALUETYPE value) {
+ throw new UnsupportedError("Not supported");
+ }
+
+ dynamic putIfAbsent($KEYTYPE key, $VALUETYPE ifAbsent()) {
+ throw new UnsupportedError("Not supported");
+ }
+
+ $KEYTYPE remove($VALUETYPE key) {
+ throw new UnsupportedError("Not supported");
+ }
+
+ void clear() {
+ throw new UnsupportedError("Not supported");
+ }
+}
diff --git a/tools/dom/templates/html/dart2js/html_dart2js.darttemplate b/tools/dom/templates/html/dart2js/html_dart2js.darttemplate
index 2baac67..2f5c1e9 100644
--- a/tools/dom/templates/html/dart2js/html_dart2js.darttemplate
+++ b/tools/dom/templates/html/dart2js/html_dart2js.darttemplate
@@ -121,6 +121,45 @@
HtmlDocument get document =>
JS('returns:HtmlDocument;depends:none;effects:none;gvn:true', 'document');
+// Supoort to convert JS Promise to a Dart Future.
+Future<T> promiseToFuture<T>(thePromise) {
+ var completer = new Completer<T>();
+
+ var thenSuccessCode = (promiseValue) => completer.complete(promiseValue);
+ var thenErrorCode = (promiseError) => completer.completeError(promiseError);
+
+ JS("", "#.then(#, #)", thePromise, convertDartClosureToJS(thenSuccessCode, 1), convertDartClosureToJS(thenErrorCode, 1));
+
+ return completer.future;
+}
+
+// Supoort to convert JS Promise to a Dart Future that returns a MapLike (Class with Map mixin).
+Future promiseToFutureMap(thePromise) {
+ var completer = new Completer();
+
+ var thenSuccessCode = (promiseValue) => completer.complete(promiseValue);
+ var thenErrorCode = (promiseError) => completer.completeError(promiseError);
+
+ JS("", "#.then(#, #)", thePromise, convertDartClosureToJS(thenSuccessCode, 1),
+ convertDartClosureToJS(thenErrorCode, 1));
+
+ return completer.future;
+}
+
+// Supoort to convert JS Promise to a Dart Future that returns a Dictionary as a Dart Map.
+Future<Map> promiseToFutureDictionary(thePromise) {
+ var completer = new Completer<Map>();
+
+ var thenSuccessCode = (promiseValue) =>
+ completer.complete(convertNativeToDart_Dictionary(promiseValue));
+ var thenErrorCode = (promiseError) => completer.completeError(promiseError);
+
+ JS("", "#.then(#, #)", thePromise, convertDartClosureToJS(thenSuccessCode, 1),
+ convertDartClosureToJS(thenErrorCode, 1));
+
+ return completer.future;
+}
+
// Workaround for tags like <cite> that lack their own Element subclass --
// Dart issue 1990.
@Native("HTMLElement")
@@ -147,4 +186,3 @@
@Experimental() // untriaged
typedef void FontFaceSetForEachCallback(
FontFace fontFace, FontFace fontFaceAgain, FontFaceSet set);
-
diff --git a/tools/dom/templates/html/impl/impl_RTCPeerConnection.darttemplate b/tools/dom/templates/html/impl/impl_RTCPeerConnection.darttemplate
index ae468155..c1ed25a 100644
--- a/tools/dom/templates/html/impl/impl_RTCPeerConnection.darttemplate
+++ b/tools/dom/templates/html/impl/impl_RTCPeerConnection.darttemplate
@@ -50,13 +50,6 @@
return completer.future;
}
- @DomName('RTCPeerConnection.getStats')
- Future<RtcStatsResponse> getStats(MediaStreamTrack selector) {
- var completer = new Completer<RtcStatsResponse>();
- _getStats((value) { completer.complete(value); }, selector);
- return completer.future;
- }
-
@DomName('RTCPeerConnection.generateCertificate')
@DocsEditable()
@Experimental() // untriaged