Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(axe.sansPolyfills): add axe version without polyfills #2067

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
86 changes: 59 additions & 27 deletions Gruntfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ module.exports = function(grunt) {
{
expand: true,
cwd: 'lib/core',
src: ['**/*.js', '!imports/index.js'],
src: ['**/*.js', '!imports/index.js', '!polyfills/index.js'],
dest: 'tmp/core'
}
]
Expand Down Expand Up @@ -131,6 +131,30 @@ module.exports = function(grunt) {
};
})
},
engineSansPolyfills: {
options: {
process: true
},
coreFiles: [
'tmp/core/index.js',
'tmp/core/*/index.js',
'tmp/core/**/index.js',
'tmp/core/**/*.js',
'!tmp/core/polyfills/index.js'
],
files: langs.map(function(lang, i) {
return {
src: [
'lib/intro.stub',
'<%= concat.engineSansPolyfills.coreFiles %>',
// include rules / checks / commons
'<%= configure.rules.files[' + i + '].dest.auto %>',
'lib/outro.stub'
],
dest: 'axe.sansPolyfills' + lang + '.js'
};
})
},
commons: {
src: [
'lib/commons/intro.stub',
Expand Down Expand Up @@ -195,43 +219,49 @@ module.exports = function(grunt) {
}
},
uglify: {
beautify: {
files: langs.map(function(lang, i) {
return {
src: ['<%= concat.engine.files[' + i + '].dest %>'],
dest: '<%= concat.engine.files[' + i + '].dest %>'
};
}),
engine: {
options: {
mangle: false,
compress: false,
beautify: {
beautify: true,
ascii_only: true,
indent_level: 2,
braces: true,
quote_style: 1
},
output: {
comments: /^\/*! axe/
},
mangle: {
reserved: ['commons', 'utils', 'axe', 'window', 'document']
}
}
},
files: langs.map(function(lang) {
return [
{
expand: true,
src: 'axe' + lang + '.js',
dest: '.',
rename: function(dst, src) {
return dst + '/' + src.replace('.js', '.min.js');
}
}
];
})
},
minify: {
files: langs.map(function(lang, i) {
return {
src: ['<%= concat.engine.files[' + i + '].dest %>'],
dest: './axe' + lang + '.min.js'
};
}),
engineSansPolyfills: {
options: {
output: {
comments: /^\/*! axe/
},
mangle: {
reserved: ['commons', 'utils', 'axe', 'window', 'document']
}
}
},
files: langs.map(function(lang) {
return [
{
expand: true,
src: 'axe.sansPolyfills' + lang + '.js',
dest: '.',
rename: function(dst, src) {
return dst + '/' + src.replace('.js', '.min.js');
}
}
];
})
}
},
'file-exists': {
Expand Down Expand Up @@ -361,7 +391,9 @@ module.exports = function(grunt) {
'configure',
'babel',
'concat:engine',
'uglify',
'concat:engineSansPolyfills',
'uglify:engine',
'uglify:engineSansPolyfills',
'aria-supported'
]);
grunt.registerTask('prepare', [
Expand Down
54 changes: 22 additions & 32 deletions build/imports-generator.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,37 +3,27 @@ const browserify = require('browserify');
const derequire = require('derequire');
const createFile = require('./shared/create-file');

const inputFile = path.join(
__dirname,
'..',
'lib',
'core',
'imports',
'index.js'
);
const outputFile = path.join(
__dirname,
'..',
'tmp',
'core',
'imports',
'index.js'
);
const filePaths = ['core/imports/index.js', 'core/polyfills/index.js'];

async function run() {
browserify(inputFile).bundle(async (err, result) => {
if (err) {
throw new Error('Cannot browserify axe.imports', err);
}
try {
// Replace `require` calls with `_dereq_` in order not to confuse Cypress.js
result = derequire(result);
await createFile(outputFile, result);
} catch (error) {
throw new Error('Cannot write browserify generated axe.imports', error);
}
});
}
filePaths.forEach(filePath => {
const inputFile = path.join(__dirname, '../lib', filePath);
const outputFile = path.join(__dirname, '../tmp', filePath);

// exec
run();
async function run() {
browserify(inputFile).bundle(async (err, result) => {
if (err) {
throw new Error(`Cannot browserify ${filePath}`, err);
}
try {
// Replace `require` calls with `_dereq_` in order not to confuse Cypress.js
result = derequire(result);
await createFile(outputFile, result);
} catch (error) {
throw new Error(`Cannot write browserify generated ${filePath}`, error);
}
});
}

// exec
run();
});
30 changes: 0 additions & 30 deletions lib/core/imports/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,36 +6,6 @@
* See - './build/imports-generator'
*/

/**
* Polyfill `Promise`
* Reference: https://www.npmjs.com/package/es6-promise
*/
if (!('Promise' in window)) {
require('es6-promise').polyfill();
}

/**
* Polyfill required TypedArray and functions
* Reference https://github.com/zloirock/core-js/
*/
if (!('Uint32Array' in window)) {
require('core-js/features/typed-array/uint32-array');
}
if (window.Uint32Array) {
if (!('some' in window.Uint32Array.prototype)) {
require('core-js/features/typed-array/some');
}
if (!('reduce' in window.Uint32Array.prototype)) {
require('core-js/features/typed-array/reduce');
}
}

/**
* Polyfill `WeakMap`
* Reference: https://github.com/polygonplanet/weakmap-polyfill
*/
require('weakmap-polyfill');

/**
* Namespace `axe.imports` which holds required external dependencies
*
Expand Down
83 changes: 83 additions & 0 deletions lib/core/polyfills/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
/**
* Note:
* This file is run via browserify to pull in the required dependencies.
* See - './build/imports-generator'
*/

/**
* Polyfill Object.assign
* Reference https://github.com/zloirock/core-js/
*/
if (typeof Object.assign !== 'function') {
require('core-js/features/object/assign');
}

/**
* Polyfill Array.prototype.find
* Reference https://github.com/zloirock/core-js/
*/
if (!Array.prototype.find) {
require('core-js/features/array/find');
}

/**
* Polyfill Array.prototype.includes
* Reference https://github.com/zloirock/core-js/
*/
if (!Array.prototype.includes) {
require('core-js/features/array/includes');
}

/**
* Polyfill Array.prototype.some
* Reference https://github.com/zloirock/core-js/
*/
if (!Array.prototype.some) {
require('core-js/features/array/some');
}

/**
* Polyfill Array.from
* Reference https://github.com/zloirock/core-js/
*/
if (!Array.from) {
require('core-js/features/array/from');
}

/**
* Polyfill String.prototype.includes
* Reference https://github.com/zloirock/core-js/
*/
if (!String.prototype.includes) {
require('core-js/features/string/includes');
}

/**
* Polyfill required TypedArray and functions
* Reference https://github.com/zloirock/core-js/
*/
if (!('Uint32Array' in window)) {
require('core-js/features/typed-array/uint32-array');
}
if (window.Uint32Array) {
if (!('some' in window.Uint32Array.prototype)) {
require('core-js/features/typed-array/some');
}
if (!('reduce' in window.Uint32Array.prototype)) {
require('core-js/features/typed-array/reduce');
}
}

/**
* Polyfill `Promise`
* Reference: https://www.npmjs.com/package/es6-promise
*/
if (!('Promise' in window)) {
require('es6-promise').polyfill();
}

/**
* Polyfill `WeakMap`
* Reference: https://github.com/polygonplanet/weakmap-polyfill
*/
require('weakmap-polyfill');
79 changes: 79 additions & 0 deletions lib/core/utils/elements-from-point.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
/**
* Polyfill documents.elementsFromPoint
*/
axe.utils.pollyfillElementsFromPoint = function() {
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 = axe.utils.pollyfillElementsFromPoint();
}
Loading