From 5ea03792e8439c5b9dac8f151afb6bf585ee6180 Mon Sep 17 00:00:00 2001 From: Piotr Gejgalis Date: Mon, 11 May 2015 13:00:33 +0200 Subject: [PATCH] Updated polyfill to fix IE10 issue https://github.com/webcomponents/webcomponentsjs/commit/feef1883d19c80072c411b332cf97e3e99c11941 --- index.js | 34 ++++++++++++++++++++++++++-------- 1 file changed, 26 insertions(+), 8 deletions(-) diff --git a/index.js b/index.js index bbc7ced..c0a6b0f 100644 --- a/index.js +++ b/index.js @@ -49,11 +49,30 @@ if (typeof WeakMap === 'undefined') { var registrationsTable = new WeakMap(); -// We use setImmediate or postMessage for our future callback. -var setImmediate = window.msSetImmediate; - -// Use post message to emulate setImmediate. -if (!setImmediate) { +var 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|Edge/.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) { @@ -542,7 +561,6 @@ Registration.prototype = { // Fall through. case 'DOMNodeInserted': // http://dom.spec.whatwg.org/#concept-mo-queue-childlist - var target = e.relatedNode; var changedNode = e.target; var addedNodes, removedNodes; if (e.type === 'DOMNodeInserted') { @@ -557,13 +575,13 @@ Registration.prototype = { var nextSibling = changedNode.nextSibling; // 1. - var record = getRecord('childList', target); + var record = getRecord('childList', e.target.parentNode); record.addedNodes = addedNodes; record.removedNodes = removedNodes; record.previousSibling = previousSibling; record.nextSibling = nextSibling; - forEachAncestorAndObserverEnqueueRecord(target, function(options) { + forEachAncestorAndObserverEnqueueRecord(e.relatedNode, function(options) { // 2.1, 3.2 if (!options.childList) return;