@@ -26,8 +26,6 @@ void _trySetStackTrace(Object error, StackTrace stackTrace) {
2626 }
2727}
2828
29- typedef _ScheduleImmediateFn = void Function (void Function ());
30-
3129@patch
3230class _AsyncRun {
3331 @patch
@@ -36,33 +34,78 @@ class _AsyncRun {
3634 }
3735
3836 // Lazily initialized.
39- static final _ScheduleImmediateFn _scheduleImmediateClosure =
37+ static final Function _scheduleImmediateClosure =
4038 _initializeScheduleImmediate ();
4139
42- static _ScheduleImmediateFn _initializeScheduleImmediate () {
40+ static Function _initializeScheduleImmediate () {
4341 requiresPreamble ();
4442 if (JS ('' , 'self.scheduleImmediate' ) != null ) {
4543 return _scheduleImmediateJsOverride;
4644 }
45+ if (JS ('' , 'self.MutationObserver' ) != null &&
46+ JS ('' , 'self.document' ) != null ) {
47+ // Use mutationObservers.
48+ var div = JS ('' , 'self.document.createElement("div")' );
49+ var span = JS ('' , 'self.document.createElement("span")' );
50+ void Function ()? storedCallback;
51+
52+ internalCallback (_) {
53+ var f = storedCallback;
54+ storedCallback = null ;
55+ f !();
56+ }
4757
48- if (JS ('' , 'typeof self.queueMicrotask == "function"' )) {
49- return _scheduleImmediateWithQueueMicrotask;
58+ var observer = JS (
59+ '' ,
60+ 'new self.MutationObserver(#)' ,
61+ convertDartClosureToJS (internalCallback, 1 ),
62+ );
63+ JS ('' , '#.observe(#, { childList: true })' , observer, div);
64+
65+ return (void callback ()) {
66+ assert (storedCallback == null );
67+ storedCallback = callback;
68+ // Because of a broken shadow-dom polyfill we have to change the
69+ // children instead a cheap property.
70+ JS (
71+ '' ,
72+ '#.firstChild ? #.removeChild(#): #.appendChild(#)' ,
73+ div,
74+ div,
75+ span,
76+ div,
77+ span,
78+ );
79+ };
80+ } else if (JS ('' , 'self.setImmediate' ) != null ) {
81+ return _scheduleImmediateWithSetImmediate;
5082 }
51-
52- // The fallback is not quite right as it uses the macro task queue.
83+ // TODO(20055): We should use DOM promises when available.
5384 return _scheduleImmediateWithTimer;
5485 }
5586
5687 static void _scheduleImmediateJsOverride (void callback ()) {
57- JS ('' , 'self.scheduleImmediate(#)' , convertDartClosureToJS (callback, 0 ));
88+ internalCallback () {
89+ callback ();
90+ }
91+
92+ JS (
93+ 'void' ,
94+ 'self.scheduleImmediate(#)' ,
95+ convertDartClosureToJS (internalCallback, 0 ),
96+ );
5897 }
5998
60- /// `queueMicrotask` is available in all supported browsers in
61- /// [windows] (https://developer.mozilla.org/en-US/docs/Web/API/Window/queueMicrotask#browser_compatibility)
62- /// and
63- /// [workers] (https://developer.mozilla.org/en-US/docs/Web/API/WorkerGlobalScope/queueMicrotask#browser_compatibility).
64- static void _scheduleImmediateWithQueueMicrotask (void callback ()) {
65- JS ('' , 'self.queueMicrotask(#)' , convertDartClosureToJS (callback, 0 ));
99+ static void _scheduleImmediateWithSetImmediate (void callback ()) {
100+ internalCallback () {
101+ callback ();
102+ }
103+
104+ JS (
105+ 'void' ,
106+ 'self.setImmediate(#)' ,
107+ convertDartClosureToJS (internalCallback, 0 ),
108+ );
66109 }
67110
68111 static void _scheduleImmediateWithTimer (void callback ()) {
0 commit comments