Skip to content

Commit

Permalink
fix(dropdown): support closest for HTMLDocument in EdgeHTML (#3786)
Browse files Browse the repository at this point in the history
When autoclosing a dropdown by clicking the scrollbar, an error would be
thrown in Edge 44.18362.449.0. This was due to the HTMLDocument not
supporting `Element.prototype.closest`.

By emulating `Element.prototype.closest` for this specific node, this
commit circumvents the issue.

Fixes #3783.
  • Loading branch information
Istanful authored and maxokorokov committed Jul 8, 2020
1 parent 6e1610d commit d11530a
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 2 deletions.
34 changes: 33 additions & 1 deletion src/util/util.spec.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,39 @@
import {toInteger, toString, getValueInRange, isInteger, isString, hasClassName} from './util';
import {toInteger, toString, getValueInRange, isInteger, isString, hasClassName, closest} from './util';

describe('util', () => {

describe('closest', () => {
describe('when no selector is provided', () => {

it('should return null', () => {
const element = document.createElement('div');

expect(closest(element)).toBeNull();
});

});

describe('when selector is provided', () => {

it('should return the closest element', () => {
const element = document.body;

expect(closest(element, 'html')).toEqual(document.documentElement);
});

});

describe('when HTMLDocument is provided', () => {

it('should return null if selector is not matching document', () => {
const element = document.documentElement;

expect(closest(element, 'body')).toBeNull();
});

});
});

describe('toInteger', () => {

it('should be noop for integers', () => {
Expand Down
15 changes: 14 additions & 1 deletion src/util/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,10 +66,23 @@ if (typeof Element !== 'undefined' && !Element.prototype.closest) {
};
}

export function closest(element: HTMLElement, selector): HTMLElement | null {
export function closest(element: HTMLElement, selector?: string): HTMLElement | null {
if (!selector) {
return null;
}

/*
* In certain browsers (e.g. Edge 44.18362.449.0) HTMLDocument does
* not support `Element.prototype.closest`. To emulate the correct behaviour
* we return null when the method is missing.
*
* Note that in evergreen browsers `closest(document.documentElement, 'html')`
* will return the document element whilst in Edge null will be returned. This
* compromise was deemed good enough.
*/
if (typeof element.closest === 'undefined') {
return null;
}

return element.closest(selector);
}

0 comments on commit d11530a

Please sign in to comment.