Protect against race in setCapture() polyfill

It might take a long time for a timer to fire, long enough for a
new grab to be initiated. Clearing out the capture element would
then cause a crash.
This commit is contained in:
Pierre Ossman 2017-02-23 14:26:50 +01:00
parent a7ca8e5c1a
commit 90ecc739df
1 changed files with 10 additions and 3 deletions

View File

@ -514,6 +514,8 @@ Util._captureElemChanged = function() {
}; };
Util._captureObserver = new MutationObserver(Util._captureElemChanged); Util._captureObserver = new MutationObserver(Util._captureElemChanged);
Util._captureIndex = 0;
Util.setCapture = function (elem) { Util.setCapture = function (elem) {
if (elem.setCapture) { if (elem.setCapture) {
@ -565,6 +567,7 @@ Util.setCapture = function (elem) {
} }
Util._captureElem = elem; Util._captureElem = elem;
Util._captureIndex++;
// Track cursor and get initial cursor // Track cursor and get initial cursor
Util._captureObserver.observe(elem, {attributes:true}); Util._captureObserver.observe(elem, {attributes:true});
@ -594,9 +597,13 @@ Util.releaseCapture = function () {
// There might be events already queued, so we need to wait for // There might be events already queued, so we need to wait for
// them to flush. E.g. contextmenu in Microsoft Edge // them to flush. E.g. contextmenu in Microsoft Edge
// window.setTimeout(function(expected) {
// FIXME: What happens if setCapture is called before this fires? // Only clear it if it's the expected grab (i.e. no one
window.setTimeout(function() { Util._captureElem = null; }); // else has initiated a new grab)
if (Util._captureIndex === expected) {
Util._captureElem = null;
}
}, 0, Util._captureIndex);
Util._captureObserver.disconnect(); Util._captureObserver.disconnect();