Added support for members of type Promise.
Fixes #31046 R=sra@google.com Change-Id: Id1e8d415b91a842bd8e2f50c6064c24aaaed9d98 Reviewed-on: https://dart-review.googlesource.com/59460 Reviewed-by: Stephen Adams <sra@google.com> Commit-Queue: Terry Lucas <terry@google.com>
This commit is contained in:
committed by
commit-bot@chromium.org
parent
1e91c62d4b
commit
eea2dff20d
@@ -870,7 +870,8 @@ class Animation extends EventTarget {
|
||||
@DomName('Animation.finished')
|
||||
@DocsEditable()
|
||||
@Experimental() // untriaged
|
||||
final Future finished;
|
||||
Future<Animation> get finished =>
|
||||
promiseToFuture<Animation>(JS("", "#.finished", this));
|
||||
|
||||
@DomName('Animation.id')
|
||||
@DocsEditable()
|
||||
@@ -890,7 +891,8 @@ class Animation extends EventTarget {
|
||||
@DomName('Animation.ready')
|
||||
@DocsEditable()
|
||||
@Experimental() // untriaged
|
||||
final Future ready;
|
||||
Future<Animation> get ready =>
|
||||
promiseToFuture<Animation>(JS("", "#.ready", this));
|
||||
|
||||
@DomName('Animation.startTime')
|
||||
@DocsEditable()
|
||||
@@ -2118,7 +2120,8 @@ class BeforeInstallPromptEvent extends Event {
|
||||
@DomName('BeforeInstallPromptEvent.userChoice')
|
||||
@DocsEditable()
|
||||
@Experimental() // untriaged
|
||||
final Future userChoice;
|
||||
Future<Map<String, dynamic>> get userChoice =>
|
||||
promiseToFutureAsMap(JS("", "#.userChoice", this));
|
||||
|
||||
@DomName('BeforeInstallPromptEvent.prompt')
|
||||
@DocsEditable()
|
||||
@@ -19387,7 +19390,8 @@ class FetchEvent extends ExtendableEvent {
|
||||
@DomName('FetchEvent.preloadResponse')
|
||||
@DocsEditable()
|
||||
@Experimental() // untriaged
|
||||
final Future preloadResponse;
|
||||
Future get preloadResponse =>
|
||||
promiseToFuture(JS("", "#.preloadResponse", this));
|
||||
|
||||
@DomName('FetchEvent.request')
|
||||
@DocsEditable()
|
||||
@@ -20108,7 +20112,8 @@ class FontFace extends Interceptor {
|
||||
@DomName('FontFace.loaded')
|
||||
@DocsEditable()
|
||||
@Experimental() // untriaged
|
||||
final Future loaded;
|
||||
Future<FontFace> get loaded =>
|
||||
promiseToFuture<FontFace>(JS("", "#.loaded", this));
|
||||
|
||||
@DomName('FontFace.status')
|
||||
@DocsEditable()
|
||||
@@ -25820,7 +25825,7 @@ class MediaKeySession extends EventTarget {
|
||||
@DomName('MediaKeySession.closed')
|
||||
@DocsEditable()
|
||||
@Experimental() // untriaged
|
||||
final Future closed;
|
||||
Future<void> get closed => promiseToFuture<void>(JS("", "#.closed", this));
|
||||
|
||||
@DomName('MediaKeySession.expiration')
|
||||
@DocsEditable()
|
||||
@@ -33137,7 +33142,9 @@ class PresentationReceiver extends Interceptor {
|
||||
@DomName('PresentationReceiver.connectionList')
|
||||
@DocsEditable()
|
||||
@Experimental() // untriaged
|
||||
final Future connectionList;
|
||||
Future<PresentationConnectionList> get connectionList =>
|
||||
promiseToFuture<PresentationConnectionList>(
|
||||
JS("", "#.connectionList", 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
|
||||
@@ -33330,7 +33337,7 @@ class PromiseRejectionEvent extends Event {
|
||||
@DomName('PromiseRejectionEvent.promise')
|
||||
@DocsEditable()
|
||||
@Experimental() // untriaged
|
||||
final Future promise;
|
||||
Future get promise => promiseToFuture(JS("", "#.promise", this));
|
||||
|
||||
@DomName('PromiseRejectionEvent.reason')
|
||||
@DocsEditable()
|
||||
@@ -36013,7 +36020,8 @@ class ServiceWorkerContainer extends EventTarget {
|
||||
@DomName('ServiceWorkerContainer.ready')
|
||||
@DocsEditable()
|
||||
@Experimental() // untriaged
|
||||
final Future ready;
|
||||
Future<ServiceWorkerRegistration> get ready =>
|
||||
promiseToFuture<ServiceWorkerRegistration>(JS("", "#.ready", this));
|
||||
|
||||
@DomName('ServiceWorkerContainer.getRegistration')
|
||||
@DocsEditable()
|
||||
|
||||
@@ -401,7 +401,6 @@ websql_test: Pass # Triage, seen some double reporting on windows.
|
||||
|
||||
[ $compiler == dart2js && $browser ]
|
||||
custom/created_callback_test: Fail # Support for created constructor. Issue 14835
|
||||
fontface_loaded_test: Fail # Support for promises.
|
||||
|
||||
[ $compiler == dart2js && $browser && $csp ]
|
||||
custom/element_upgrade_test: Fail # Issue 17298
|
||||
|
||||
@@ -32,22 +32,28 @@ main() {
|
||||
treeSanitizer: new NullTreeSanitizer());
|
||||
document.head.append(style);
|
||||
|
||||
test('document fonts - temporary', () {
|
||||
test('document fonts - temporary', () async {
|
||||
var atLeastOneFont = false;
|
||||
var loaded = <Future>[];
|
||||
document.fonts.forEach((FontFace fontFace, _, __) {
|
||||
var loaded = <Future<FontFace>>[];
|
||||
document.fonts.forEach((FontFace fontFace, _, __) async {
|
||||
atLeastOneFont = true;
|
||||
Future f1 = fontFace.loaded;
|
||||
Future f2 = fontFace.loaded;
|
||||
var f1 = fontFace.loaded;
|
||||
var f2 = fontFace.loaded;
|
||||
loaded.add(fontFace.load());
|
||||
loaded.add(f1);
|
||||
loaded.add(f2);
|
||||
});
|
||||
expect(atLeastOneFont, isTrue);
|
||||
return Future.wait(loaded).then(expectAsync((_) {
|
||||
return Future.wait(loaded).then(expectAsync((_) async {
|
||||
document.fonts.forEach((fontFace, _, __) {
|
||||
expect(fontFace.status, 'loaded');
|
||||
});
|
||||
expect(loaded.length, 3);
|
||||
for (var loadedEntry in loaded) {
|
||||
var fontFace = await loadedEntry;
|
||||
expect(fontFace.status, 'loaded');
|
||||
expect(fontFace.family, 'Ahem');
|
||||
}
|
||||
}));
|
||||
});
|
||||
}
|
||||
|
||||
@@ -186,6 +186,7 @@ html/fileapi_supported_test: RuntimeError
|
||||
html/fileapi_supported_throws_test: RuntimeError
|
||||
html/filereader_test: RuntimeError
|
||||
html/filteredelementlist_test: RuntimeError
|
||||
html/fontface_loaded_test: RuntimeError
|
||||
html/fontface_test: RuntimeError
|
||||
html/form_data_test: RuntimeError
|
||||
html/form_element_test: RuntimeError
|
||||
@@ -339,7 +340,6 @@ js/prototype_access_test: RuntimeError
|
||||
collection/list_test: RuntimeError
|
||||
|
||||
[ $compiler == dart2js && $runtime != d8 && $runtime != jsshell ]
|
||||
html/fontface_loaded_test: RuntimeError
|
||||
html/html_mock_test: RuntimeError # Issue 31038
|
||||
html/input_element_attributes_test: RuntimeError
|
||||
html/js_dart_functions_test: RuntimeError # does not implement Dart 2 implicit `.call` tearoff
|
||||
@@ -474,7 +474,6 @@ html/xhr_test: RuntimeError
|
||||
|
||||
[ $compiler == dart2js && $browser ]
|
||||
html/custom/created_callback_test: RuntimeError
|
||||
html/fontface_loaded_test: Fail # Support for promises.
|
||||
html/js_typed_interop_lazy_test/01: RuntimeError
|
||||
html/notification_permission_test: Timeout, Pass # Issue 32002
|
||||
html/private_extension_member_test: RuntimeError
|
||||
@@ -688,7 +687,6 @@ html/js_typed_interop_test: RuntimeError
|
||||
[ $compiler == dart2js && $fasta && $host_checked ]
|
||||
html/custom/mirrors_2_test: Crash # 'file:*/pkg/compiler/lib/src/common_elements.dart': Failed assertion: line 405 pos 12: 'element.name == '=='': is not true.
|
||||
html/custom/mirrors_test: Crash # 'file:*/pkg/compiler/lib/src/common_elements.dart': Failed assertion: line 405 pos 12: 'element.name == '=='': is not true.
|
||||
html/fontface_loaded_test: RuntimeError # TypeError: Cannot read property 'createFragment$3$treeSanitizer$validator' of undefined
|
||||
html/indexeddb_3_test: Crash # 'file:*/pkg/compiler/lib/src/common_elements.dart': Failed assertion: line 405 pos 12: 'element.name == '=='': is not true.
|
||||
html/indexeddb_5_test: Crash # 'file:*/pkg/compiler/lib/src/common_elements.dart': Failed assertion: line 405 pos 12: 'element.name == '=='': is not true.
|
||||
html/js_array_test: CompileTimeError
|
||||
@@ -725,7 +723,6 @@ html/element_types_keygen_test: RuntimeError # Issue 29922
|
||||
html/event_customevent_test: RuntimeError
|
||||
html/file_sample_test: RuntimeError
|
||||
html/fileapi_entry_test: RuntimeError
|
||||
html/fontface_loaded_test: RuntimeError
|
||||
html/indexeddb_1_test/functional: RuntimeError
|
||||
html/indexeddb_2_test: RuntimeError
|
||||
html/indexeddb_3_test: RuntimeError
|
||||
|
||||
@@ -82,7 +82,6 @@ html/custom_elements_23127_test: Skip # Issue 29922
|
||||
html/custom_elements_test: Skip # Issue 29922
|
||||
html/deferred_multi_app_htmltest: Skip # Issue 29919
|
||||
html/element_classes_test: RuntimeError # Issue 29922
|
||||
html/fontface_loaded_test: RuntimeError
|
||||
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.
|
||||
|
||||
@@ -771,12 +771,14 @@ class HtmlDartInterfaceGenerator(object):
|
||||
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"},
|
||||
"Animation.finished": {"type": "Animation"},
|
||||
"Animation.ready": {"type": "Animation"},
|
||||
"BeforeInstallPromptEvent.userChoice": {"type": "dictionary"},
|
||||
"FontFace.loaded": {"type": "FontFace"},
|
||||
"FontFaceSet.ready": {"type": "FontFaceSet"},
|
||||
"MediaKeySession.closed": {"type": "void"},
|
||||
"PresentationReceiver.connectionList": {"type": "PresentationConnectionList"},
|
||||
"ServiceWorkerContainer.ready": {"type": "ServiceWorkerRegistration"},
|
||||
})
|
||||
|
||||
promise_operations = monitored.Dict('systemhtml.promise_oper_type', {
|
||||
@@ -1125,6 +1127,8 @@ class Dart2JSBackend(HtmlDartGenerator):
|
||||
metadata = self._Metadata(attribute.type.id, attribute.id, output_type)
|
||||
rename = self._RenamingAnnotation(attribute.id, html_name)
|
||||
if not read_only:
|
||||
if attribute.type.id == 'Promise':
|
||||
_logger.warn('R/W member is a Promise: %s.%s' % (self._interface.id, html_name))
|
||||
self._members_emitter.Emit(
|
||||
'\n $RENAME$METADATA$TYPE $NAME;'
|
||||
'\n',
|
||||
@@ -1134,17 +1138,44 @@ class Dart2JSBackend(HtmlDartGenerator):
|
||||
TYPE=output_type)
|
||||
else:
|
||||
template = '\n $RENAME$(ANNOTATIONS)final $TYPE $NAME;\n'
|
||||
# Need to use a getter for list.length properties so we can add a
|
||||
# setter which throws an exception, satisfying List API.
|
||||
if self._interface_type_info.list_item_type() and html_name == 'length':
|
||||
template = ('\n $RENAME$(ANNOTATIONS)$TYPE get $NAME => ' +
|
||||
'JS("$TYPE", "#.$NAME", this);\n')
|
||||
self._members_emitter.Emit(
|
||||
template,
|
||||
RENAME=rename,
|
||||
ANNOTATIONS=metadata,
|
||||
NAME=html_name,
|
||||
TYPE=input_type if output_type == 'double' else output_type)
|
||||
if attribute.type.id == 'Promise':
|
||||
lookupOp = "%s.%s" % (self._interface.id, html_name)
|
||||
promiseFound = _GetPromiseAttributeType(lookupOp)
|
||||
promiseType = 'Future'
|
||||
promiseCall = 'promiseToFuture'
|
||||
if promiseFound is not (None):
|
||||
if 'maplike' in promiseFound:
|
||||
promiseCall = 'promiseToFuture<dynamic>'
|
||||
promiseType = 'Future'
|
||||
elif promiseFound['type'] == 'dictionary':
|
||||
# It's a dictionary so return as a Map.
|
||||
promiseCall = 'promiseToFutureAsMap'
|
||||
promiseType = 'Future<Map<String, dynamic>>'
|
||||
else:
|
||||
paramType = promiseFound['type']
|
||||
promiseCall = 'promiseToFuture<%s>' % paramType
|
||||
promiseType = 'Future<%s>' % paramType
|
||||
|
||||
template = '\n $RENAME$(ANNOTATIONS)$TYPE get $NAME => $PROMISE_CALL(JS("", "#.$NAME", this));\n'
|
||||
|
||||
self._members_emitter.Emit(template,
|
||||
RENAME=rename,
|
||||
ANNOTATIONS=metadata,
|
||||
TYPE=promiseType,
|
||||
PROMISE_CALL=promiseCall,
|
||||
NAME=html_name)
|
||||
else:
|
||||
# Need to use a getter for list.length properties so we can add a
|
||||
# setter which throws an exception, satisfying List API.
|
||||
if self._interface_type_info.list_item_type() and html_name == 'length':
|
||||
template = ('\n $RENAME$(ANNOTATIONS)$TYPE get $NAME => ' +
|
||||
'JS("$TYPE", "#.$NAME", this);\n')
|
||||
self._members_emitter.Emit(
|
||||
template,
|
||||
RENAME=rename,
|
||||
ANNOTATIONS=metadata,
|
||||
NAME=html_name,
|
||||
TYPE=input_type if output_type == 'double' else output_type)
|
||||
|
||||
def _AddAttributeUsingProperties(self, attribute, html_name, read_only):
|
||||
self._AddRenamingGetter(attribute, html_name)
|
||||
|
||||
Reference in New Issue
Block a user