Skip to content

Commit

Permalink
fix: add Object.values polyfill for node <=6 (#4274)
Browse files Browse the repository at this point in the history
* fix: add Object.values polyfill for node <=6

* rename file

* forgot to commit eslint
  • Loading branch information
straker committed Dec 18, 2023
1 parent 9968aa9 commit b39b0e6
Show file tree
Hide file tree
Showing 5 changed files with 120 additions and 110 deletions.
5 changes: 4 additions & 1 deletion .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,10 @@ module.exports = {
},
{
// polyfills are mostly copy-pasted from sources so we don't control their styling
files: ['lib/core/utils/pollyfills.js'],
files: [
'lib/core/imports/polyfills.js',
'lib/core/utils/pollyfill-elements-from-point.js'
],
env: {
browser: false
},
Expand Down
35 changes: 3 additions & 32 deletions lib/core/imports/index.js
Original file line number Diff line number Diff line change
@@ -1,45 +1,16 @@
import './polyfills';

// some of these imports require polyfills to be loaded first
import { CssSelectorParser } from 'css-selector-parser';
import doT from '@deque/dot';
import emojiRegexText from 'emoji-regex';
import memoize from 'memoizee';
import Color from 'colorjs.io';

import es6promise from 'es6-promise';
import { Uint32Array } from 'typedarray';
import 'weakmap-polyfill';
import hasOwn from 'core-js-pure/actual/object/has-own';

if (!('hasOwn' in Object)) {
Object.hasOwn = hasOwn;
}

// prevent striping newline characters from strings (e.g. failure
// summaries). value must be synced with build/configure.js
doT.templateSettings.strip = false;

if (!('Promise' in window)) {
es6promise.polyfill();
}

if (!('Uint32Array' in window)) {
window.Uint32Array = Uint32Array;
}
if (window.Uint32Array) {
// @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/some
if (!('some' in window.Uint32Array.prototype)) {
Object.defineProperty(window.Uint32Array.prototype, 'some', {
value: Array.prototype.some
});
}

if (!('reduce' in window.Uint32Array.prototype)) {
// @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/reduce
Object.defineProperty(window.Uint32Array.prototype, 'reduce', {
value: Array.prototype.reduce
});
}
}

/**
* Namespace `axe.imports` which holds required external dependencies
*
Expand Down
115 changes: 39 additions & 76 deletions lib/core/utils/pollyfills.js → lib/core/imports/polyfills.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,45 @@
import es6promise from 'es6-promise';
import { Uint32Array } from 'typedarray';
import 'weakmap-polyfill';
import hasOwn from 'core-js-pure/actual/object/has-own';
import values from 'core-js-pure/actual/object/values';

if (!('hasOwn' in Object)) {
Object.hasOwn = hasOwn;
}

if (!('values' in Object)) {
Object.values = values;
}

if (!('Promise' in window)) {
es6promise.polyfill();
}

if (!('Uint32Array' in window)) {
window.Uint32Array = Uint32Array;
}
if (window.Uint32Array) {
// @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/some
if (!('some' in window.Uint32Array.prototype)) {
Object.defineProperty(window.Uint32Array.prototype, 'some', {
value: Array.prototype.some
});
}

if (!('reduce' in window.Uint32Array.prototype)) {
// @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/reduce
Object.defineProperty(window.Uint32Array.prototype, 'reduce', {
value: Array.prototype.reduce
});
}
}

/*
These polyfills came directly from the ES Specification itself
Contained within:
- Object.assign
- Array.prototype.find
- Object.assign
- Array.prototype.find
*/
if (typeof Object.assign !== 'function') {
(function () {
Expand Down Expand Up @@ -76,80 +113,6 @@ if (!Array.prototype.findIndex) {
});
}

// Spelled incorrectly intentionally (backwards compatibility).
export function pollyfillElementsFromPoint() {
if (document.elementsFromPoint) return document.elementsFromPoint;
if (document.msElementsFromPoint) return document.msElementsFromPoint;

var usePointer = (function () {
var element = document.createElement('x');
element.style.cssText = 'pointer-events:auto';
return element.style.pointerEvents === 'auto';
})();

var cssProp = usePointer ? 'pointer-events' : 'visibility';
var cssDisableVal = usePointer ? 'none' : 'hidden';

var style = document.createElement('style');
style.innerHTML = usePointer
? '* { pointer-events: all }'
: '* { visibility: visible }';

return function (x, y) {
var current, i, d;
var elements = [];
var previousPointerEvents = [];

// startup
document.head.appendChild(style);

while (
(current = document.elementFromPoint(x, y)) &&
elements.indexOf(current) === -1
) {
// push the element and its current style
elements.push(current);

previousPointerEvents.push({
value: current.style.getPropertyValue(cssProp),
priority: current.style.getPropertyPriority(cssProp)
});

// add "pointer-events: none", to get to the underlying element
current.style.setProperty(cssProp, cssDisableVal, 'important');
}

// Due to negative index, documentElement could actually not be the last,
// so we'll simply move it to the end
if (elements.indexOf(document.documentElement) < elements.length - 1) {
elements.splice(elements.indexOf(document.documentElement), 1);
elements.push(document.documentElement);
}

// restore the previous pointer-events values
for (
i = previousPointerEvents.length;
!!(d = previousPointerEvents[--i]);

) {
elements[i].style.setProperty(
cssProp,
d.value ? d.value : '',
d.priority
);
}

// teardown;
document.head.removeChild(style);

return elements;
};
}

if (typeof window.addEventListener === 'function') {
document.elementsFromPoint = pollyfillElementsFromPoint();
}

if (!Array.prototype.includes) {
Object.defineProperty(Array.prototype, 'includes', {
value: function (searchElement) {
Expand Down
2 changes: 1 addition & 1 deletion lib/core/utils/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ export { default as parseCrossOriginStylesheet } from './parse-crossorigin-style
export { default as parseSameOriginStylesheet } from './parse-sameorigin-stylesheet';
export { default as parseStylesheet } from './parse-stylesheet';
export { default as performanceTimer } from './performance-timer';
export { pollyfillElementsFromPoint } from './pollyfills';
export { pollyfillElementsFromPoint } from './pollyfill-elements-from-point';
export { default as preloadCssom } from './preload-cssom';
export { default as preloadMedia } from './preload-media';
export { default as preload, shouldPreload, getPreloadConfig } from './preload';
Expand Down
73 changes: 73 additions & 0 deletions lib/core/utils/pollyfill-elements-from-point.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
// Spelled incorrectly intentionally (backwards compatibility).
export function pollyfillElementsFromPoint() {
if (document.elementsFromPoint) return document.elementsFromPoint;
if (document.msElementsFromPoint) return document.msElementsFromPoint;

var usePointer = (function () {
var element = document.createElement('x');
element.style.cssText = 'pointer-events:auto';
return element.style.pointerEvents === 'auto';
})();

var cssProp = usePointer ? 'pointer-events' : 'visibility';
var cssDisableVal = usePointer ? 'none' : 'hidden';

var style = document.createElement('style');
style.innerHTML = usePointer
? '* { pointer-events: all }'
: '* { visibility: visible }';

return function (x, y) {
var current, i, d;
var elements = [];
var previousPointerEvents = [];

// startup
document.head.appendChild(style);

while (
(current = document.elementFromPoint(x, y)) &&
elements.indexOf(current) === -1
) {
// push the element and its current style
elements.push(current);

previousPointerEvents.push({
value: current.style.getPropertyValue(cssProp),
priority: current.style.getPropertyPriority(cssProp)
});

// add "pointer-events: none", to get to the underlying element
current.style.setProperty(cssProp, cssDisableVal, 'important');
}

// Due to negative index, documentElement could actually not be the last,
// so we'll simply move it to the end
if (elements.indexOf(document.documentElement) < elements.length - 1) {
elements.splice(elements.indexOf(document.documentElement), 1);
elements.push(document.documentElement);
}

// restore the previous pointer-events values
for (
i = previousPointerEvents.length;
!!(d = previousPointerEvents[--i]);

) {
elements[i].style.setProperty(
cssProp,
d.value ? d.value : '',
d.priority
);
}

// teardown;
document.head.removeChild(style);

return elements;
};
}

if (typeof window.addEventListener === 'function') {
document.elementsFromPoint = pollyfillElementsFromPoint();
}

0 comments on commit b39b0e6

Please sign in to comment.