From 5762a166d014079a187337f246f1bbe5d67e3c8b Mon Sep 17 00:00:00 2001 From: Ian MacLeod Date: Wed, 22 Oct 2014 17:31:46 -0700 Subject: [PATCH 1/2] example to test IE10 task flaking. --- workbench/ie10-task-flaking.html | 58 ++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 workbench/ie10-task-flaking.html diff --git a/workbench/ie10-task-flaking.html b/workbench/ie10-task-flaking.html new file mode 100644 index 0000000..a266618 --- /dev/null +++ b/workbench/ie10-task-flaking.html @@ -0,0 +1,58 @@ + + + + + MutationObserver + + + + + +

MutationObserver test page

+ +

Clicking start will schedule two self-restarting functions:

+ + +

+After starting the test, move your mouse so that it is hovering over the top line of output. +

+ +

+On IE10, the runMutation line will become erratic, and eventually not fire at all. +

+ + +
+ + + + + From 78462d87b8c611d1c87fd29867aebfbf1ee09ac8 Mon Sep 17 00:00:00 2001 From: Ian MacLeod Date: Wed, 22 Oct 2014 17:48:55 -0700 Subject: [PATCH 2/2] Fix a heinous IE10 (and below) bug where it may drop events on the floor for MutationObserver & friends. --- src/MutationObserver/MutationObserver.js | 27 ++++++++++++++++++++---- src/ShadowDOM/microtask.js | 2 +- workbench/ie10-task-flaking.html | 8 +++++-- 3 files changed, 30 insertions(+), 7 deletions(-) diff --git a/src/MutationObserver/MutationObserver.js b/src/MutationObserver/MutationObserver.js index be7dda9..833ac53 100644 --- a/src/MutationObserver/MutationObserver.js +++ b/src/MutationObserver/MutationObserver.js @@ -8,11 +8,30 @@ var registrationsTable = new WeakMap(); - // We use setImmediate or postMessage for our future callback. - var setImmediate = window.msSetImmediate; + var setImmediate; - // Use post message to emulate setImmediate. - if (!setImmediate) { + // As much as we would like to use the native implementation, IE + // (all versions) suffers a rather annoying bug where it will drop or defer + // callbacks when heavy DOM operations are being performed concurrently. + // + // For a thorough discussion on this, see: + // http://codeforhire.com/2013/09/21/setimmediate-and-messagechannel-broken-on-internet-explorer-10/ + if (/Trident/.test(navigator.userAgent)) { + // Sadly, this bug also affects postMessage and MessageQueues. + // + // We would like to use the onreadystatechange hack for IE <= 10, but it is + // dangerous in the polyfilled environment due to requiring that the + // observed script element be in the document. + setImmediate = setTimeout; + + // If some other browser ever implements it, let's prefer their native + // implementation: + } else if (window.setImmediate) { + setImmediate = window.setImmediate; + + // Otherwise, we fall back to postMessage as a means of emulating the next + // task semantics of setImmediate. + } else { var setImmediateQueue = []; var sentinel = String(Math.random()); window.addEventListener('message', function(e) { diff --git a/src/ShadowDOM/microtask.js b/src/ShadowDOM/microtask.js index c0e35b7..11ad4de 100644 --- a/src/ShadowDOM/microtask.js +++ b/src/ShadowDOM/microtask.js @@ -33,7 +33,7 @@ }; } else { - timerFunc = window.setImmediate || window.setTimeout; + timerFunc = window.setTimeout; } function setEndOfMicrotask(func) { diff --git a/workbench/ie10-task-flaking.html b/workbench/ie10-task-flaking.html index a266618..b723d2b 100644 --- a/workbench/ie10-task-flaking.html +++ b/workbench/ie10-task-flaking.html @@ -16,7 +16,7 @@ http://codeforhire.com/2013/09/21/setimmediate-and-messagechannel-broken-on-inte

Clicking start will schedule two self-restarting functions:

@@ -24,7 +24,11 @@ After starting the test, move your mouse so that it is hovering over the top lin

-On IE10, the runMutation line will become erratic, and eventually not fire at all. +If the browser is behaving, you should see runSetTimeout calls interleaved with runMutation calls (either 2:1 or 1:1, depending). +

+ +

+On IE10, if our MutationObserver polyfill uses setImmediate, postMessage, or MessageQueue, the runMutation line will become erratic, and eventually not fire at all.