1
0
mirror of https://github.com/dart-lang/sdk synced 2024-07-05 09:20:04 +00:00

[html] Fix nested JS Map to Dart assignment

Added check to convertNativeToDart_Dictionary to recursively convert native objects within a map to their Dart equivalent.

Fixes: https://github.com/dart-lang/sdk/issues/44319
Change-Id: I80a2bc0541454900b1c7d9635debaf72d7c120f2
Bug: 44319
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/201200
Commit-Queue: Gabriel Castro <gabrielmcastro@google.com>
Reviewed-by: Nicholas Shahan <nshahan@google.com>
Reviewed-by: Srujan Gaddam <srujzs@google.com>
This commit is contained in:
Gabriel Castro 2021-06-14 21:18:08 +00:00 committed by commit-bot@chromium.org
parent 06811b2594
commit 820ba59dda
4 changed files with 105 additions and 3 deletions

View File

@ -2,6 +2,14 @@
### Core libraries
### `dart:html`
* [#44319][]: `convertNativeToDart_Dictionary()` now converts objects
recursively, this fixes APIs like MediaStreamTrack.getCapabilities
that convert between Maps and browser Dictionaries.
[44319]: (https://github.com/dart-lang/sdk/issues/44319)
#### `dart:async`
* The uncaught error handlers of `Zone`s are now run in the parent zone

View File

@ -1,14 +1,36 @@
part of html_common;
/// Converts a JavaScript object with properties into a Dart Map.
/// Not suitable for nested objects.
/// Converts native values to their Dart equivalent
///
/// This includes other maps, lists, or values that don't need a conversion e.g.
/// bool, String.
_convertNativeToDart_Value(value) {
if (value == null) return value;
if (value is String || value is num || value is bool) return value;
if (isJavaScriptSimpleObject(value)) {
return convertNativeToDart_Dictionary(value);
}
if (JS('bool', 'Array.isArray(#)', value)) {
List values = [];
for (var i = 0; i < JS<int>('int', '#.length', value); i++) {
values.add(_convertNativeToDart_Value(JS('var', '#[#]', value, i)));
}
return values;
}
return value;
}
/// Recursively converts a JavaScript object with properties into a Dart Map.
/// This includes maps, lists, and other values that don't need a conversion.
Map<String, dynamic>? convertNativeToDart_Dictionary(object) {
if (object == null) return null;
var dict = <String, dynamic>{};
var keys = JS<JSExtendableArray>(
'JSExtendableArray', 'Object.getOwnPropertyNames(#)', object);
for (final key in keys) {
dict[key] = JS('var', '#[#]', object, key);
dict[JS('String', '#', key)] =
_convertNativeToDart_Value(JS('var', '#[#]', object, key));
}
return dict;
}

View File

@ -0,0 +1,36 @@
// Copyright (c) 2021, 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:html_common';
import 'package:expect/expect.dart';
import 'package:expect/minitest.dart';
var obj = {
'val1': 'hello',
'val2': 'there',
'val3': {
'sub1': 'general kenobi',
'sub2': 'you are',
'sub3': 'a bold one',
'sub4': {
'nilval': null,
'boolval': false,
}
},
'val4': [
'execute',
'order',
'66',
{'number': 33}
]
};
main() {
test('dart to native -> native to dart', () {
var toNative = convertDartToNative_Dictionary(obj);
var toDart = convertNativeToDart_Dictionary(toNative);
Expect.deepEquals(obj, toDart);
});
}

View File

@ -0,0 +1,36 @@
// Copyright (c) 2021, 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:html_common';
import 'package:expect/expect.dart';
import 'package:expect/minitest.dart';
var obj = {
'val1': 'hello',
'val2': 'there',
'val3': {
'sub1': 'general kenobi',
'sub2': 'you are',
'sub3': 'a bold one',
'sub4': {
'nilval': null,
'boolval': false,
}
},
'val4': [
'execute',
'order',
'66',
{'number': 33}
]
};
main() {
test('dart to native -> native to dart', () {
var toNative = convertDartToNative_Dictionary(obj);
var toDart = convertNativeToDart_Dictionary(toNative);
Expect.deepEquals(obj, toDart);
});
}