mirror of
https://github.com/jlengrand/webcomponentsjs.git
synced 2026-03-10 08:51:22 +00:00
Merge pull request #8 from Polymer/ie10-wb
Fix for IE10 flaking. Fixes #5
This commit is contained in:
@@ -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) {
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
};
|
||||
|
||||
} else {
|
||||
timerFunc = window.setImmediate || window.setTimeout;
|
||||
timerFunc = window.setTimeout;
|
||||
}
|
||||
|
||||
function setEndOfMicrotask(func) {
|
||||
|
||||
62
workbench/ie10-task-flaking.html
Normal file
62
workbench/ie10-task-flaking.html
Normal 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>
|
||||
Reference in New Issue
Block a user