Merge pull request #8 from Polymer/ie10-wb

Fix for IE10 flaking. Fixes #5
This commit is contained in:
Ian MacLeod
2014-10-24 11:48:54 -07:00
3 changed files with 86 additions and 5 deletions

View File

@@ -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) {

View File

@@ -33,7 +33,7 @@
};
} else {
timerFunc = window.setImmediate || window.setTimeout;
timerFunc = window.setTimeout;
}
function setEndOfMicrotask(func) {

View File

@@ -0,0 +1,62 @@
<!doctype html>
<!--
Test setup borrowed from Code for Hire's research into this subject:
http://codeforhire.com/2013/09/21/setimmediate-and-messagechannel-broken-on-internet-explorer-10/
-->
<html>
<head>
<title>MutationObserver</title>
<script src="../src/WeakMap/WeakMap.js"></script>
<script src="../src/MutationObserver/MutationObserver.js"></script>
</head>
<body style="font-family: sans-serif">
<h3>MutationObserver test page</h3>
<p>Clicking start will schedule two self-restarting functions:</p>
<ul>
<li><strong>runSetTimeout</strong> uses setTimeout(fn, 0) for queueing itself</li>
<li><strong>runMutation</strong> uses a MutationObserver for queueing itself</li>
</ul>
<p>
After starting the test, move your mouse so that it is hovering over the top line of output.
<p>
<p>
If the browser is behaving, you should see runSetTimeout calls interleaved with runMutation calls (either 2:1 or 1:1, depending).
</p>
<p>
On IE10, if our MutationObserver polyfill uses setImmediate, postMessage, or MessageQueue, the runMutation line will become erratic, and eventually not fire at all.
</p>
<input type="button" value="Start" onclick="doStart(); return false;">
<div id="log"></div>
<script>
var logElement = document.getElementById('log');
var iterations = 0;
var twiddle = document.createTextNode('');
var observer = new MutationObserver(runMutation).observe(twiddle, {characterData: true});
function runMutation() {
setTimeout(function() {
twiddle.textContent = iterations++;
}, 0);
logElement.innerHTML = "<p>runMutation called: " + Date.now() + "</p>" + logElement.innerHTML;
}
function runSetTimeout() {
setTimeout(runSetTimeout, 0);
logElement.innerHTML = "<p>runSetTimeout called: " + Date.now() + "</p>" + logElement.innerHTML;
}
function doStart() {
setTimeout(runSetTimeout, 0);
twiddle.textContent = iterations++;
}
</script>
</body>
</html>