From 2d54c1182aefd3ec9d8250fda76290971f5d7166 Mon Sep 17 00:00:00 2001 From: Federico Brigante Date: Tue, 9 Oct 2018 01:26:30 +0800 Subject: [PATCH] Simplify closest polyfill 1. It should not secretly polyfill .matches 2. It now uses MDN's polyfill https://developer.mozilla.org/en-US/docs/Web/API/Element/closest#Polyfill 3. Drops test that no longer necessary Signed-off-by: Federico Brigante --- src/closest.js | 28 ++++++++++------------------ test/closest.js | 14 -------------- 2 files changed, 10 insertions(+), 32 deletions(-) diff --git a/src/closest.js b/src/closest.js index 842ea07..96840a8 100644 --- a/src/closest.js +++ b/src/closest.js @@ -1,17 +1,11 @@ -var DOCUMENT_NODE_TYPE = 9; - /** - * A polyfill for Element.matches() + * Local polyfills for Element.matches() and Element.closest() */ -if (typeof Element !== 'undefined' && !Element.prototype.matches) { - var proto = Element.prototype; - proto.matches = proto.matchesSelector || - proto.mozMatchesSelector || - proto.msMatchesSelector || - proto.oMatchesSelector || - proto.webkitMatchesSelector; -} +var matches = Element.prototype.matches || + Element.prototype.msMatchesSelector || + Element.prototype.webkitMatchesSelector; + /** * Finds the closest parent that matches a selector. @@ -21,13 +15,11 @@ if (typeof Element !== 'undefined' && !Element.prototype.matches) { * @return {Function} */ function closest (element, selector) { - while (element && element.nodeType !== DOCUMENT_NODE_TYPE) { - if (typeof element.matches === 'function' && - element.matches(selector)) { - return element; - } - element = element.parentNode; - } + do { + if (matches.call(element, selector)) return element; + element = element.parentElement || element.parentNode; + } while (element !== null && element.nodeType === 1); + return null; } module.exports = closest; diff --git a/test/closest.js b/test/closest.js index 6a9e25f..8ca0123 100644 --- a/test/closest.js +++ b/test/closest.js @@ -28,18 +28,4 @@ describe('closest', function() { it('should return itself if the same selector is passed', function() { assert.ok(closest(document.body, 'body'), document.body); }); - - it('should not throw on elements without matches()', function() { - var fakeElement = { - nodeType: -1, // anything but DOCUMENT_NODE_TYPE - parentNode: null, - matches: undefined // undefined to emulate Elements without this function - }; - - try { - closest(fakeElement, '#a') - } catch (err) { - assert.fail(); - } - }); });