Skip to content

Commit f057e25

Browse files
fishythefishcommit-bot@chromium.org
authored andcommitted
[dart2js] Extended structured clone algorithm to JSObject.
Change-Id: I0d8b20184f1b88e4bb24f67c2237b2095370118d Bug: #37438 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/114043 Commit-Queue: Mayank Patke <[email protected]> Reviewed-by: Stephen Adams <[email protected]>
1 parent b699852 commit f057e25

File tree

4 files changed

+82
-1
lines changed

4 files changed

+82
-1
lines changed

sdk/lib/html/html_common/conversions.dart

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,9 @@ abstract class _StructuredClone {
7676

7777
cleanupSlots() {} // Will be needed if we mark objects with a property.
7878
bool cloneNotRequired(object);
79+
JSObject newJsObject();
80+
void forEachObjectKey(object, action(key, value));
81+
void putIntoObject(object, key, value);
7982
newJsMap();
8083
List newJsList(length);
8184
void putIntoMap(map, key, value);
@@ -134,6 +137,19 @@ abstract class _StructuredClone {
134137
return copy;
135138
}
136139

140+
if (e is JSObject) {
141+
var slot = findSlot(e);
142+
var copy = readSlot(slot);
143+
if (copy != null) return copy;
144+
copy = newJsObject();
145+
writeSlot(slot, copy);
146+
// TODO: Consider inlining this so we don't allocate a closure.
147+
forEachObjectKey(e, (key, value) {
148+
putIntoObject(copy, key, walk(value));
149+
});
150+
return copy;
151+
}
152+
137153
throw new UnimplementedError('structured clone of other type');
138154
}
139155

sdk/lib/html/html_common/conversions_dart2js.dart

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,18 @@ convertNativeToDart_AcceptStructuredClone(object, {mustCopy: false}) =>
5353
.convertNativeToDart_AcceptStructuredClone(object, mustCopy: mustCopy);
5454

5555
class _StructuredCloneDart2Js extends _StructuredClone {
56+
JSObject newJsObject() => JS('JSObject', '{}');
57+
58+
void forEachObjectKey(object, action(key, value)) {
59+
for (final key
60+
in JS('returns:JSExtendableArray;new:true', 'Object.keys(#)', object)) {
61+
action(key, JS('var', '#[#]', object, key));
62+
}
63+
}
64+
65+
void putIntoObject(object, key, value) =>
66+
JS('void', '#[#] = #', object, key, value);
67+
5668
newJsMap() => JS('var', '{}');
5769
putIntoMap(map, key, value) => JS('void', '#[#] = #', map, key, value);
5870
newJsList(length) => JS('JSExtendableArray', 'new Array(#)', length);

sdk/lib/html/html_common/html_common_dart2js.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import 'dart:typed_data';
1313
import 'dart:_native_typed_data';
1414
import 'dart:_js_helper' show Creates, Returns, convertDartClosureToJS;
1515
import 'dart:_foreign_helper' show JS;
16-
import 'dart:_interceptors' show Interceptor, JSExtendableArray;
16+
import 'dart:_interceptors' show Interceptor, JSExtendableArray, JSObject;
1717

1818
import 'dart:_metadata';
1919
export 'dart:_metadata';
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
@JS()
6+
library postmessage_anonymous_test;
7+
8+
import 'dart:async';
9+
import 'dart:html';
10+
import 'package:expect/expect.dart';
11+
import 'package:js/js.dart';
12+
13+
const String JS_CODE = """
14+
window.addEventListener('message', handler);
15+
function handler(e) {
16+
var data = e.data;
17+
if (typeof data == 'string') return;
18+
if (data.recipient != 'JS') return;
19+
var response = {recipient: 'DART', msg: data.msg};
20+
window.removeEventListener('message', handler);
21+
window.postMessage(response, '*');
22+
}
23+
""";
24+
25+
const String TEST_MSG = "hello world";
26+
27+
@JS()
28+
@anonymous
29+
class Message {
30+
external String get recipient;
31+
external String get msg;
32+
external factory Message({String recipient, String msg});
33+
}
34+
35+
main() {
36+
var subscription;
37+
subscription = window.onMessage.listen((e) {
38+
var data = e.data;
39+
if (data is String) return;
40+
if (data['recipient'] != 'DART') return;
41+
subscription.cancel();
42+
Expect.equals(TEST_MSG, data['msg']);
43+
});
44+
injectSource(JS_CODE);
45+
window.postMessage(Message(recipient: 'JS', msg: TEST_MSG), '*');
46+
}
47+
48+
void injectSource(String code) {
49+
final script = new ScriptElement();
50+
script.type = 'text/javascript';
51+
script.innerHtml = code;
52+
document.body.append(script);
53+
}

0 commit comments

Comments
 (0)