Skip to content

Commit 3eac28c

Browse files
committed
Registration-based approach to cross frame support.
This approach installs all Dart extension types onto a window whenever that window is accessed. See #28326 [email protected] Review-Url: https://codereview.chromium.org/2980853002 .
1 parent a291803 commit 3eac28c

File tree

15 files changed

+3332
-3224
lines changed

15 files changed

+3332
-3224
lines changed

pkg/dev_compiler/lib/js/amd/dart_sdk.js

Lines changed: 797 additions & 778 deletions
Large diffs are not rendered by default.

pkg/dev_compiler/lib/js/amd/dart_sdk.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pkg/dev_compiler/lib/js/common/dart_sdk.js

Lines changed: 797 additions & 778 deletions
Large diffs are not rendered by default.

pkg/dev_compiler/lib/js/common/dart_sdk.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pkg/dev_compiler/lib/js/es6/dart_sdk.js

Lines changed: 797 additions & 778 deletions
Large diffs are not rendered by default.

pkg/dev_compiler/lib/js/es6/dart_sdk.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pkg/dev_compiler/lib/js/legacy/dart_sdk.js

Lines changed: 797 additions & 778 deletions
Large diffs are not rendered by default.

pkg/dev_compiler/lib/js/legacy/dart_sdk.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pkg/dev_compiler/lib/sdk/ddc_sdk.sum

496 Bytes
Binary file not shown.

pkg/dev_compiler/lib/src/compiler/code_generator.dart

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1785,11 +1785,8 @@ class CodeGenerator extends Object
17851785
void _registerExtensionType(
17861786
ClassElement classElem, String jsPeerName, List<JS.Statement> body) {
17871787
if (jsPeerName != null) {
1788-
body.add(_callHelperStatement('registerExtension(#.global.#, #);', [
1789-
_runtimeModule,
1790-
_propertyName(jsPeerName),
1791-
_emitTopLevelName(classElem)
1792-
]));
1788+
body.add(_callHelperStatement('registerExtension(#, #);',
1789+
[js.string(jsPeerName), _emitTopLevelName(classElem)]));
17931790
}
17941791
}
17951792

pkg/dev_compiler/tool/input_sdk/lib/html/dart2js/html_dart2js.dart

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,8 @@ import 'dart:_js_helper'
6363
ForceInline,
6464
findDispatchTagForInterceptorClass,
6565
setNativeSubclassDispatchRecord,
66-
makeLeafDispatchRecord;
66+
makeLeafDispatchRecord,
67+
registerGlobalObject;
6768
import 'dart:_interceptors'
6869
show
6970
Interceptor,
@@ -4301,15 +4302,11 @@ class CssStyleDeclaration extends Interceptor with CssStyleDeclarationBase {
43014302
/// Please note the property name uses camelCase, not-hyphens.
43024303
String getPropertyValue(String propertyName) {
43034304
var propValue = _getPropertyValueHelper(propertyName);
4304-
return propValue != null ? propValue : '';
4305+
return propValue ?? '';
43054306
}
43064307

43074308
String _getPropertyValueHelper(String propertyName) {
4308-
if (_supportsProperty(_camelCase(propertyName))) {
4309-
return _getPropertyValue(propertyName);
4310-
} else {
4311-
return _getPropertyValue(Device.cssPrefix + propertyName);
4312-
}
4309+
return _getPropertyValue(_browserPropertyName(propertyName));
43134310
}
43144311

43154312
/**
@@ -4322,7 +4319,7 @@ class CssStyleDeclaration extends Interceptor with CssStyleDeclarationBase {
43224319
*/
43234320
bool supportsProperty(String propertyName) {
43244321
return _supportsProperty(propertyName) ||
4325-
_supportsProperty(_camelCase(Device.cssPrefix + propertyName));
4322+
_supportsProperty(_camelCase("${Device.cssPrefix}$propertyName"));
43264323
}
43274324

43284325
bool _supportsProperty(String propertyName) {
@@ -4338,15 +4335,23 @@ class CssStyleDeclaration extends Interceptor with CssStyleDeclarationBase {
43384335
String _browserPropertyName(String propertyName) {
43394336
String name = _readCache(propertyName);
43404337
if (name is String) return name;
4341-
if (_supportsProperty(_camelCase(propertyName))) {
4342-
name = propertyName;
4343-
} else {
4344-
name = Device.cssPrefix + propertyName;
4345-
}
4338+
name = _supportedBrowserPropertyName(propertyName);
43464339
_writeCache(propertyName, name);
43474340
return name;
43484341
}
43494342

4343+
String _supportedBrowserPropertyName(String propertyName) {
4344+
if (_supportsProperty(_camelCase(propertyName))) {
4345+
return propertyName;
4346+
}
4347+
var prefixed = "${Device.cssPrefix}$propertyName";
4348+
if (_supportsProperty(prefixed)) {
4349+
return prefixed;
4350+
}
4351+
// May be a CSS variable, just use it as provided.
4352+
return propertyName;
4353+
}
4354+
43504355
static final _propertyCache = JS('', '{}');
43514356
static String _readCache(String key) =>
43524357
JS('String|Null', '#[#]', _propertyCache, key);
@@ -45868,6 +45873,7 @@ class _DOMWindowCrossFrame implements WindowBase {
4586845873
return w;
4586945874
} else {
4587045875
// TODO(vsm): Cache or implement equality.
45876+
registerGlobalObject(w);
4587145877
return new _DOMWindowCrossFrame(w);
4587245878
}
4587345879
}

pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/classes.dart

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -439,14 +439,13 @@ void _installPropertiesForObject(jsProto) {
439439
}
440440
}
441441

442-
/// Copy symbols from the prototype of the source to destination.
443-
/// These are the only properties safe to copy onto an existing public
444-
/// JavaScript class.
445-
registerExtension(jsType, dartExtType) => JS(
442+
final _extensionMap = JS('', 'new Map()');
443+
444+
_applyExtension(jsType, dartExtType) => JS(
446445
'',
447446
'''(() => {
448447
// TODO(vsm): Not all registered js types are real.
449-
if (!jsType) return;
448+
if (!$jsType) return;
450449
451450
let jsProto = $jsType.prototype;
452451
@@ -471,6 +470,22 @@ registerExtension(jsType, dartExtType) => JS(
471470
updateSig($_setterSig);
472471
})()''');
473472

473+
/// Apply all registered extensions to a window. This is intended for
474+
/// different frames, where registrations need to be reapplied.
475+
applyAllExtensions(global) {
476+
JS('', '#.forEach((dartExtType, name) => #(#[name], dartExtType))',
477+
_extensionMap, _applyExtension, global);
478+
}
479+
480+
/// Copy symbols from the prototype of the source to destination.
481+
/// These are the only properties safe to copy onto an existing public
482+
/// JavaScript class.
483+
registerExtension(name, dartExtType) {
484+
JS('', '#.set(#, #)', _extensionMap, name, dartExtType);
485+
var jsType = JS('', '#[#]', global_, name);
486+
_applyExtension(jsType, dartExtType);
487+
}
488+
474489
///
475490
/// Mark a concrete type as implementing extension methods.
476491
/// For example: `class MyIter implements Iterable`.

pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/runtime.dart

Lines changed: 60 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -36,69 +36,79 @@ part 'utils.dart';
3636
// TODO(vsm): Move polyfill code to dart:html.
3737
// Note, native extensions are registered onto types in dart.global.
3838
// This polyfill needs to run before the corresponding dart:html code is run.
39-
@JSExportName('global')
40-
final global_ = JS(
39+
final polyfill = JS(
4140
'',
4241
'''
43-
function () {
44-
if (typeof NodeList !== "undefined") {
45-
// TODO(vsm): Do we still need these?
46-
NodeList.prototype.get = function(i) { return this[i]; };
47-
NamedNodeMap.prototype.get = function(i) { return this[i]; };
48-
DOMTokenList.prototype.get = function(i) { return this[i]; };
49-
HTMLCollection.prototype.get = function(i) { return this[i]; };
42+
function (window) {
43+
if (typeof window.NodeList !== "undefined") {
44+
// TODO(vsm): Do we still need these?
45+
window.NodeList.prototype.get = function(i) { return this[i]; };
46+
window.NamedNodeMap.prototype.get = function(i) { return this[i]; };
47+
window.DOMTokenList.prototype.get = function(i) { return this[i]; };
48+
window.HTMLCollection.prototype.get = function(i) { return this[i]; };
5049
51-
// Expose constructors for DOM types dart:html needs to assume are
52-
// available on window.
53-
if (typeof PannerNode == "undefined") {
54-
let audioContext;
55-
if (typeof AudioContext == "undefined" &&
56-
(typeof webkitAudioContext != "undefined")) {
57-
audioContext = new webkitAudioContext();
58-
} else {
59-
audioContext = new AudioContext();
60-
window.StereoPannerNode =
61-
audioContext.createStereoPanner().constructor;
62-
}
63-
window.PannerNode = audioContext.createPanner().constructor;
64-
}
65-
if (typeof AudioSourceNode == "undefined") {
66-
window.AudioSourceNode = MediaElementAudioSourceNode.__proto__;
67-
}
68-
if (typeof FontFaceSet == "undefined") {
69-
// CSS Font Loading is not supported on Edge.
70-
if (typeof document.fonts != "undefined") {
71-
window.FontFaceSet = document.fonts.__proto__.constructor;
72-
}
73-
}
74-
if (typeof MemoryInfo == "undefined") {
75-
if (typeof window.performance.memory != "undefined") {
76-
window.MemoryInfo = window.performance.memory.constructor;
77-
}
50+
// Expose constructors for DOM types dart:html needs to assume are
51+
// available on window.
52+
if (typeof window.PannerNode == "undefined") {
53+
let audioContext;
54+
if (typeof window.AudioContext == "undefined" &&
55+
(typeof window.webkitAudioContext != "undefined")) {
56+
audioContext = new window.webkitAudioContext();
57+
} else {
58+
audioContext = new window.AudioContext();
59+
window.StereoPannerNode =
60+
audioContext.createStereoPanner().constructor;
7861
}
79-
if (typeof Geolocation == "undefined") {
80-
navigator.geolocation.constructor;
81-
}
82-
if (typeof Animation == "undefined") {
83-
let d = document.createElement('div');
84-
if (typeof d.animate != "undefined") {
85-
window.Animation = d.animate(d).constructor;
86-
}
62+
window.PannerNode = audioContext.createPanner().constructor;
63+
}
64+
if (typeof window.AudioSourceNode == "undefined") {
65+
window.AudioSourceNode = MediaElementAudioSourceNode.__proto__;
66+
}
67+
if (typeof window.FontFaceSet == "undefined") {
68+
// CSS Font Loading is not supported on Edge.
69+
if (typeof window.document.fonts != "undefined") {
70+
window.FontFaceSet = window.document.fonts.__proto__.constructor;
8771
}
88-
if (typeof SourceBufferList == "undefined") {
89-
window.SourceBufferList = new MediaSource().sourceBuffers.constructor;
72+
}
73+
if (typeof window.MemoryInfo == "undefined") {
74+
if (typeof window.performance.memory != "undefined") {
75+
window.MemoryInfo = window.performance.memory.constructor;
9076
}
91-
if (typeof SpeechRecognition == "undefined") {
92-
window.SpeechRecognition = window.webkitSpeechRecognition;
93-
window.SpeechRecognitionError = window.webkitSpeechRecognitionError;
94-
window.SpeechRecognitionEvent = window.webkitSpeechRecognitionEvent;
77+
}
78+
if (typeof window.Geolocation == "undefined") {
79+
window.Geolocation == window.navigator.geolocation.constructor;
80+
}
81+
if (typeof window.Animation == "undefined") {
82+
let d = window.document.createElement('div');
83+
if (typeof d.animate != "undefined") {
84+
window.Animation = d.animate(d).constructor;
9585
}
9686
}
87+
if (typeof window.SourceBufferList == "undefined") {
88+
window.SourceBufferList =
89+
new window.MediaSource().sourceBuffers.constructor;
90+
}
91+
if (typeof window.SpeechRecognition == "undefined") {
92+
window.SpeechRecognition = window.webkitSpeechRecognition;
93+
window.SpeechRecognitionError = window.webkitSpeechRecognitionError;
94+
window.SpeechRecognitionEvent = window.webkitSpeechRecognitionEvent;
95+
}
96+
}
97+
}
98+
''');
9799

100+
@JSExportName('global')
101+
final global_ = JS(
102+
'',
103+
'''
104+
function () {
105+
// Find global object.
98106
var globalState = (typeof window != "undefined") ? window
99107
: (typeof global != "undefined") ? global
100108
: (typeof self != "undefined") ? self : {};
101109
110+
$polyfill(globalState);
111+
102112
// These settings must be configured before the application starts so that
103113
// user code runs with the correct configuration.
104114
let settings = 'ddcSettings' in globalState ? globalState.ddcSettings : {};

pkg/dev_compiler/tool/input_sdk/private/js_helper.dart

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -907,5 +907,9 @@ class BooleanConversionAssertionError extends AssertionError {
907907
toString() => 'Failed assertion: boolean expression must not be null';
908908
}
909909

910-
// Hook to register new global object.
911-
void registerGlobalObject(object) {}
910+
// Hook to register new global object. This is invoked from dart:html
911+
// whenever a new window is accessed for the first time.
912+
void registerGlobalObject(object) {
913+
dart.polyfill(object);
914+
dart.applyAllExtensions(object);
915+
}

pkg/dev_compiler/tool/sdk_expected_errors.txt

Lines changed: 33 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,36 @@
1-
[warning] The final variable 'origin' must be initialized. (dart:html, line 192, col 3)
2-
[warning] The final variable 'origin' must be initialized. (dart:html, line 862, col 3)
3-
[warning] The final variables 'form', 'labels' and '3' more must be initialized. (dart:html, line 1678, col 3)
4-
[warning] The final variable 'options' must be initialized. (dart:html, line 8974, col 3)
5-
[warning] The final variables '_attributes', '_childElementCount' and '19' more must be initialized. (dart:html, line 13234, col 3)
6-
[warning] The final variables 'elements', 'form' and '4' more must be initialized. (dart:html, line 17110, col 3)
7-
[warning] The final variable 'length' must be initialized. (dart:html, line 18060, col 3)
8-
[warning] The final variables '_get_contentWindow' and 'sandbox' must be initialized. (dart:html, line 20772, col 3)
9-
[warning] The final variables 'complete', 'currentSrc' and '2' more must be initialized. (dart:html, line 20979, col 3)
10-
[warning] The final variables '_get_valueAsDate', 'entries' and '6' more must be initialized. (dart:html, line 21144, col 3)
11-
[warning] The final variables 'form', 'labels' and '4' more must be initialized. (dart:html, line 22354, col 3)
12-
[warning] The final variables 'control' and 'form' must be initialized. (dart:html, line 22501, col 3)
13-
[warning] The final variable 'form' must be initialized. (dart:html, line 22540, col 3)
14-
[warning] The final variables 'import', 'relList' and '2' more must be initialized. (dart:html, line 22629, col 3)
15-
[warning] The final variable 'areas' must be initialized. (dart:html, line 22792, col 3)
16-
[warning] The final variables 'audioDecodedByteCount', 'audioTracks' and '16' more must be initialized. (dart:html, line 23093, col 3)
17-
[warning] The final variable 'labels' must be initialized. (dart:html, line 24687, col 3)
18-
[warning] The final variables 'baseUri', 'childNodes' and '11' more must be initialized. (dart:html, line 26231, col 3)
19-
[warning] The final variables 'form', 'validationMessage' and '2' more must be initialized. (dart:html, line 27183, col 3)
20-
[warning] The final variables 'form' and 'index' must be initialized. (dart:html, line 27365, col 3)
21-
[warning] The final variables 'form', 'htmlFor' and '5' more must be initialized. (dart:html, line 27419, col 3)
22-
[warning] The final variables 'labels' and 'position' must be initialized. (dart:html, line 28981, col 3)
23-
[warning] The final variables 'form', 'labels' and '4' more must be initialized. (dart:html, line 30910, col 3)
24-
[warning] The final variable 'sheet' must be initialized. (dart:html, line 33385, col 3)
25-
[warning] The final variable 'cellIndex' must be initialized. (dart:html, line 33650, col 3)
26-
[warning] The final variables '_rows' and '_tBodies' must be initialized. (dart:html, line 33769, col 3)
27-
[warning] The final variables '_cells', 'rowIndex' and '1' more must be initialized. (dart:html, line 33886, col 3)
28-
[warning] The final variable '_rows' must be initialized. (dart:html, line 33955, col 3)
29-
[warning] The final variable 'content' must be initialized. (dart:html, line 33999, col 3)
30-
[warning] The final variables 'form', 'labels' and '5' more must be initialized. (dart:html, line 34088, col 3)
31-
[warning] The final variables 'readyState' and 'track' must be initialized. (dart:html, line 35148, col 3)
32-
[warning] The final variables 'decodedFrameCount', 'droppedFrameCount' and '2' more must be initialized. (dart:html, line 36055, col 3)
33-
[warning] The final variable 'sourceCapabilities' must be initialized. (dart:html, line 46032, col 3)
1+
[warning] The final variable 'origin' must be initialized. (dart:html, line 193, col 3)
2+
[warning] The final variable 'origin' must be initialized. (dart:html, line 863, col 3)
3+
[warning] The final variables 'form', 'labels' and '3' more must be initialized. (dart:html, line 1679, col 3)
4+
[warning] The final variable 'options' must be initialized. (dart:html, line 8979, col 3)
5+
[warning] The final variables '_attributes', '_childElementCount' and '19' more must be initialized. (dart:html, line 13239, col 3)
6+
[warning] The final variables 'elements', 'form' and '4' more must be initialized. (dart:html, line 17115, col 3)
7+
[warning] The final variable 'length' must be initialized. (dart:html, line 18065, col 3)
8+
[warning] The final variables '_get_contentWindow' and 'sandbox' must be initialized. (dart:html, line 20777, col 3)
9+
[warning] The final variables 'complete', 'currentSrc' and '2' more must be initialized. (dart:html, line 20984, col 3)
10+
[warning] The final variables '_get_valueAsDate', 'entries' and '6' more must be initialized. (dart:html, line 21149, col 3)
11+
[warning] The final variables 'form', 'labels' and '4' more must be initialized. (dart:html, line 22359, col 3)
12+
[warning] The final variables 'control' and 'form' must be initialized. (dart:html, line 22506, col 3)
13+
[warning] The final variable 'form' must be initialized. (dart:html, line 22545, col 3)
14+
[warning] The final variables 'import', 'relList' and '2' more must be initialized. (dart:html, line 22634, col 3)
15+
[warning] The final variable 'areas' must be initialized. (dart:html, line 22797, col 3)
16+
[warning] The final variables 'audioDecodedByteCount', 'audioTracks' and '16' more must be initialized. (dart:html, line 23098, col 3)
17+
[warning] The final variable 'labels' must be initialized. (dart:html, line 24692, col 3)
18+
[warning] The final variables 'baseUri', 'childNodes' and '11' more must be initialized. (dart:html, line 26236, col 3)
19+
[warning] The final variables 'form', 'validationMessage' and '2' more must be initialized. (dart:html, line 27188, col 3)
20+
[warning] The final variables 'form' and 'index' must be initialized. (dart:html, line 27370, col 3)
21+
[warning] The final variables 'form', 'htmlFor' and '5' more must be initialized. (dart:html, line 27424, col 3)
22+
[warning] The final variables 'labels' and 'position' must be initialized. (dart:html, line 28986, col 3)
23+
[warning] The final variables 'form', 'labels' and '4' more must be initialized. (dart:html, line 30915, col 3)
24+
[warning] The final variable 'sheet' must be initialized. (dart:html, line 33390, col 3)
25+
[warning] The final variable 'cellIndex' must be initialized. (dart:html, line 33655, col 3)
26+
[warning] The final variables '_rows' and '_tBodies' must be initialized. (dart:html, line 33774, col 3)
27+
[warning] The final variables '_cells', 'rowIndex' and '1' more must be initialized. (dart:html, line 33891, col 3)
28+
[warning] The final variable '_rows' must be initialized. (dart:html, line 33960, col 3)
29+
[warning] The final variable 'content' must be initialized. (dart:html, line 34004, col 3)
30+
[warning] The final variables 'form', 'labels' and '5' more must be initialized. (dart:html, line 34093, col 3)
31+
[warning] The final variables 'readyState' and 'track' must be initialized. (dart:html, line 35153, col 3)
32+
[warning] The final variables 'decodedFrameCount', 'droppedFrameCount' and '2' more must be initialized. (dart:html, line 36060, col 3)
33+
[warning] The final variable 'sourceCapabilities' must be initialized. (dart:html, line 46038, col 3)
3434
[warning] The final variables 'href' and 'target' must be initialized. (dart:svg, line 56, col 3)
3535
[warning] The final variables 'requiredExtensions', 'requiredFeatures' and '2' more must be initialized. (dart:svg, line 512, col 3)
3636
[warning] The final variables 'cx', 'cy' and '1' more must be initialized. (dart:svg, line 583, col 3)

0 commit comments

Comments
 (0)