Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

a11y-checker

Package Overview
Dependencies
Maintainers
1
Versions
6
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

a11y-checker - npm Package Compare versions

Comparing version 2.0.1 to 2.1.1

4

package.json
{
"name": "a11y-checker",
"version": "2.0.1",
"version": "2.1.1",
"description": "Identifies accessibility issues in your code.",
"main": "a11y.js",
"main": "./src/a11y.js",
"scripts": {

@@ -7,0 +7,0 @@ "start": "npm-run-all --parallel dev:server lint:watch",

@@ -0,8 +1,26 @@

# How to use
## Install
```bash
npm install --save a11y-checker
```
## Usage
- Import a11yChecker
```js
import a11yChecker from 'a11y-checker';
```
- Call it after page loads:
```js
a11yChecker();
```
## Contribute
* clone project
```bash
git clone git@github.com:Muhnad/a11y-checker.git
git clone git@github.com:Muhnad/a11y-checker.git
```

@@ -18,5 +36,4 @@ * `cd a11y-checker/`

- body: for check everything happens inside `<body>`
- dist: for production usage.
## Rules
[Docs](https://github.com/Muhnad/a11y-checker/tree/master/docs)
import * as head from './head';
import * as body from './body';
const a11yChecker = (() => {
head.hasDocumentType();
head.hasDocumentTitle();
head.hasDocumentLanguage();
head.hasDocumentMetaCharset();
head.hasDocumentScalable();
const a11yChecker = () => {
head.hasDocumentType();
head.hasDocumentTitle();
head.hasDocumentLanguage();
head.hasDocumentMetaCharset();
head.hasDocumentScalable();
body.hasHeadingOnce();
body.hasImagesAlt();
body.hasLinksText();
body.hasLinksHref();
body.hasLinksTarget();
body.hasButtonsText();
body.hasSVGRole();
body.hasIframeTitle();
body.hasFormsLabel();
body.hasForLabel();
body.hasVideoTrack();
body.hasAudioTrack();
body.hasPositiveTabIndex();
body.hasDuplicateIds();
})();
body.hasHeadingOnce();
body.hasImagesAlt();
body.hasLinksText();
body.hasLinksHref();
body.hasLinksTarget();
body.hasButtonsText();
body.hasSVGRole();
body.hasIframeTitle();
body.hasFormsLabel();
body.hasForLabel();
body.hasVideoTrack();
body.hasAudioTrack();
body.hasPositiveTabIndex();
body.hasDuplicateIds();
};
export default a11yChecker;

@@ -10,6 +10,6 @@ import {Warning} from '../utils/warn';

const hasHeadingOnce = () => {
const H1 = getElements('h1');
const hasMultiHeading = H1.length > 1;
const H1 = getElements('h1');
const hasMultiHeading = H1.length > 1;
if (hasMultiHeading) Warning('Page has Multi <h1> tag. Fix: use only one <h1> in the page.');
if (hasMultiHeading) Warning('Page has Multi <h1> tag. Fix: use only one <h1> in the page.');
};

@@ -19,18 +19,18 @@

const hasImagesAlt = () => {
const IMGS = [...getElements('img')];
const imagesWithoutAlt = IMGS.filter(img => !hasAttribute(img, 'alt'));
const hasMissingAlt = imagesWithoutAlt.length > 0;
const withoutAltWarning = imagesWithoutAlt.forEach(image => Warning(`Image Alt is missing. Fix: Add alt="IMAGE WELL DESCRIBED" to ${image.outerHTML}`));
const IMGS = [...getElements('img')];
const imagesWithoutAlt = IMGS.filter(img => !hasAttribute(img, 'alt'));
const hasMissingAlt = imagesWithoutAlt.length > 0;
const withoutAltWarning = imagesWithoutAlt.forEach(image => Warning(`Image Alt is missing. Fix: Add alt="IMAGE WELL DESCRIBED" to ${image.outerHTML}`));
if (hasMissingAlt) withoutAltWarning;
if (hasMissingAlt) withoutAltWarning;
};
const hasLinksText = () => {
const LINKS = [...getElements('a')];
const warningMessage = 'Link text is missing. Fix: DESCRIBE PURPOSE OF LINK';
const linksWithoutText = LINKS.filter(link => isEmpty(link.textContent) && !hasAccessibileText(link));
const hasMissingText = linksWithoutText.length > 0;
const withoutTextWarning = linksWithoutText.forEach(link => Warning(`${warningMessage} to ${link.outerHTML}`));
const LINKS = [...getElements('a')];
const warningMessage = 'Link text is missing. Fix: DESCRIBE PURPOSE OF LINK';
const linksWithoutText = LINKS.filter(link => isEmpty(link.textContent) && !hasAccessibileText(link));
const hasMissingText = linksWithoutText.length > 0;
const withoutTextWarning = linksWithoutText.forEach(link => Warning(`${warningMessage} to ${link.outerHTML}`));
if (hasMissingText) withoutTextWarning;
if (hasMissingText) withoutTextWarning;
};

@@ -40,8 +40,8 @@

const hasLinksHref = () => {
const LINKS = [...getElements('a')];
const linksWithoutHref = LINKS.filter(link => (isEmpty(getAttribute(link, 'href')) || !hasAttribute(link, 'href')) && !hasAttribute(link, 'role'));
const hasMissingHref = linksWithoutHref.length > 0;
const withoutHrefWarning = linksWithoutHref.forEach(link => Warning(`Link Href is missing. Fix: Add href="LINK URL" to ${link.outerHTML}`));
const LINKS = [...getElements('a')];
const linksWithoutHref = LINKS.filter(link => (isEmpty(getAttribute(link, 'href')) || !hasAttribute(link, 'href')) && !hasAttribute(link, 'role'));
const hasMissingHref = linksWithoutHref.length > 0;
const withoutHrefWarning = linksWithoutHref.forEach(link => Warning(`Link Href is missing. Fix: Add href="LINK URL" to ${link.outerHTML}`));
if (hasMissingHref) withoutHrefWarning;
if (hasMissingHref) withoutHrefWarning;
};

@@ -51,9 +51,9 @@

const hasLinksTarget = () => {
const LINKS = [...getElements('a')];
const warningMessage = 'Hint message is missing. Should add hint message to recognize this link will open in new tab. Fix: Add aria-describedby="ELEMENT ID"';
const linksWithTarget = LINKS.filter(link => getAttribute(link, 'target') === '_blank' && !hasAttribute(link, 'aria-describedby'));
const hasTarget = linksWithTarget.length > 0;
const missingTargetHint = linksWithTarget.forEach(link => Warning(`${warningMessage} to ${link.outerHTML}`));
const LINKS = [...getElements('a')];
const warningMessage = 'Hint message is missing. Should add hint message to recognize this link will open in new tab. Fix: Add aria-describedby="ELEMENT ID"';
const linksWithTarget = LINKS.filter(link => getAttribute(link, 'target') === '_blank' && !hasAttribute(link, 'aria-describedby'));
const hasTarget = linksWithTarget.length > 0;
const missingTargetHint = linksWithTarget.forEach(link => Warning(`${warningMessage} to ${link.outerHTML}`));
if (hasTarget) missingTargetHint;
if (hasTarget) missingTargetHint;
};

@@ -63,9 +63,9 @@

const hasButtonsText = () => {
const BUTTONS = [...getElements('button')];
const warningMessage = 'Button text or aria-label is missing. Fix: Add aria-label="VALUE" or <button>VALUE</button>';
const buttonsWithoutText = BUTTONS.filter(button => isEmpty(button.textContent) && !hasAccessibileText(button));
const hasMissingText = buttonsWithoutText.length > 0;
const withoutTextWarning = buttonsWithoutText.forEach(button => Warning(`${warningMessage} to ${button.outerHTML}`));
const BUTTONS = [...getElements('button')];
const warningMessage = 'Button text or aria-label is missing. Fix: Add aria-label="VALUE" or <button>VALUE</button>';
const buttonsWithoutText = BUTTONS.filter(button => isEmpty(button.textContent) && !hasAccessibileText(button));
const hasMissingText = buttonsWithoutText.length > 0;
const withoutTextWarning = buttonsWithoutText.forEach(button => Warning(`${warningMessage} to ${button.outerHTML}`));
if (hasMissingText) withoutTextWarning;
if (hasMissingText) withoutTextWarning;
};

@@ -75,10 +75,10 @@

const hasForLabel = () => {
const LABELS = [...getElements('label')];
const isLabeld = label => {
if (!hasAttribute(label, 'for') || isEmpty(getAttribute(label, 'for')))
Warning(`For is missing in label. Fix: Add for="INPUT ID" to ${label.outerHTML}`);
};
const missingForLabel = LABELS.forEach(isLabeld);
const LABELS = [...getElements('label')];
const isLabeld = label => {
if (!hasAttribute(label, 'for') || isEmpty(getAttribute(label, 'for')))
Warning(`For is missing in label. Fix: Add for="INPUT ID" to ${label.outerHTML}`);
};
const missingForLabel = LABELS.forEach(isLabeld);
return missingForLabel;
return missingForLabel;
};

@@ -88,6 +88,6 @@

const hasSVGRole = () => {
const SVGS = [...getElements('SVG')];
const hasMissingRole = SVGS.some(svg => getAttribute(svg, 'aria-hidden') !== 'true' && !hasAttribute(svg, 'role'));
const SVGS = [...getElements('SVG')];
const hasMissingRole = SVGS.some(svg => getAttribute(svg, 'aria-hidden') !== 'true' && !hasAttribute(svg, 'role') && !getAttribute(svg, 'id'));
if (hasMissingRole) Warning('SVG Role is missing. Fix: Add role="img" or (aria-hidden="true" if you need to hide element from SR).');
if (hasMissingRole) Warning('SVG Role is missing. Fix: Add role="img" or (aria-hidden="true" if you need to hide element from SR).');
};

@@ -97,6 +97,6 @@

const hasIframeTitle = () => {
const IFRAMES = [...getElements('iframe')];
const iframeWithoutTitle = IFRAMES.some(ifrmae => !hasAttribute(ifrmae, 'title'));
const IFRAMES = [...getElements('iframe')];
const iframeWithoutTitle = IFRAMES.some(ifrmae => !hasAttribute(ifrmae, 'title'));
if (iframeWithoutTitle) Warning('Title is missing in iframe. Fix: Add title="DESCRIBE CONTENT OF FRAME" to <iframe>');
if (iframeWithoutTitle) Warning('Title is missing in iframe. Fix: Add title="DESCRIBE CONTENT OF FRAME" to <iframe>');
};

@@ -106,6 +106,6 @@

const hasVideoTrack = () => {
const VIDEOS = [...getElements('video')];
const videoWithoutTrack = VIDEOS.some(hasTrack);
const VIDEOS = [...getElements('video')];
const videoWithoutTrack = VIDEOS.some(hasTrack);
if (videoWithoutTrack) Warning('Video track is missing. Fix: Add <track> element with subtitles, captions to >video>');
if (videoWithoutTrack) Warning('Video track is missing. Fix: Add <track> element with subtitles, captions to >video>');
};

@@ -115,6 +115,6 @@

const hasAudioTrack = () => {
const AUDIOS = [...getElements('audio')];
const audioWithoutTrack = AUDIOS.some(hasTrack);
const AUDIOS = [...getElements('audio')];
const audioWithoutTrack = AUDIOS.some(hasTrack);
if (audioWithoutTrack) Warning('Audio track is missing. Fix: Add <track> element with subtitles, captions to <audio>');
if (audioWithoutTrack) Warning('Audio track is missing. Fix: Add <track> element with subtitles, captions to <audio>');
};

@@ -124,6 +124,6 @@

const hasFormsLabel = () => {
const FORMS = [...getElements('form')];
const formsWithoutLabels = FORMS.some(video => !hasAccessibileText(video));
const FORMS = [...getElements('form')];
const formsWithoutLabels = FORMS.some(video => !hasAccessibileText(video));
if (formsWithoutLabels) Warning('Forms Label is missing. Fix: Add aria-label, aria-labelledby to <form>');
if (formsWithoutLabels) Warning('Forms Label is missing. Fix: Add aria-label, aria-labelledby to <form>');
};

@@ -133,7 +133,7 @@

const hasPositiveTabIndex = () => {
const ALLELEMENTS = [...getElements('*')];
const elementsWithTabindex = ALLELEMENTS.filter(element => getAttribute(element, 'tabindex') > 0);
const hasPositiveindex = elementsWithTabindex.length > 0;
const ALLELEMENTS = [...getElements('*')];
const elementsWithTabindex = ALLELEMENTS.filter(element => getAttribute(element, 'tabindex') > 0);
const hasPositiveindex = elementsWithTabindex.length > 0;
if (hasPositiveindex) Warning('Avoid using positive integer values for tabindex. Fix: Remove/Replace tabindex=">0" ');
if (hasPositiveindex) Warning('Avoid using positive integer values for tabindex. Fix: Remove/Replace tabindex=">0" ');
};

@@ -143,10 +143,10 @@

const hasDuplicateIds = () => {
const ALLELEMENTS = [...getElements('*')];
const elementsWithId = ALLELEMENTS
.map(element => getAttribute(element, 'id'))
.filter(el => !isNull(el));
const uniqueIds = [...new Set(elementsWithId)];
const hasDuplicate = elementsWithId.length > uniqueIds.length;
const ALLELEMENTS = [...getElements('*')];
const elementsWithId = ALLELEMENTS
.map(element => getAttribute(element, 'id'))
.filter(el => !isNull(el));
const uniqueIds = [...new Set(elementsWithId)];
const hasDuplicate = elementsWithId.length > uniqueIds.length;
if (hasDuplicate) Warning('Avoid duplicate ids, ID must be unique. Fix: Remove/Replace duplicate id');
if (hasDuplicate) Warning('Avoid duplicate ids, ID must be unique. Fix: Remove/Replace duplicate id');
};

@@ -153,0 +153,0 @@

@@ -11,3 +11,3 @@ import {Warning} from '../utils/warn';

const hasDocumentType = () => {
if (!doctype) Warning('Doctype is missing. Fix: Add <!DOCTYPE html>');
if (!doctype) Warning('Doctype is missing. Fix: Add <!DOCTYPE html>');
};

@@ -17,3 +17,3 @@

const hasDocumentTitle = () => {
if (isEmpty(title)) Warning('Title is missing. Fix: <title>WELL DESCRIBED TITLE</title>');
if (isEmpty(title)) Warning('Title is missing. Fix: <title>WELL DESCRIBED TITLE</title>');
};

@@ -23,13 +23,13 @@

const hasDocumentLanguage = () => {
const HTML = getElement('html');
const hasLanguageAttr = hasAttribute(HTML, 'lang');
const HTML = getElement('html');
const hasLanguageAttr = hasAttribute(HTML, 'lang');
if (hasLanguageAttr) {
const getLanguageValue = getAttribute(HTML, 'lang');
const isLanguageValueNotExist = isEmpty(getLanguageValue);
if (hasLanguageAttr) {
const getLanguageValue = getAttribute(HTML, 'lang');
const isLanguageValueNotExist = isEmpty(getLanguageValue);
if (isLanguageValueNotExist) Warning('Language value is missing in HTML element. Fix: Add lang="LANGUAGE VALUE" to <html>');
} else {
Warning('Language is missing in HTML element. Fix: Add lang="LANGUAGE VALUE" to <html>');
}
if (isLanguageValueNotExist) Warning('Language value is missing in HTML element. Fix: Add lang="LANGUAGE VALUE" to <html>');
} else {
Warning('Language is missing in HTML element. Fix: Add lang="LANGUAGE VALUE" to <html>');
}
};

@@ -39,6 +39,6 @@

const hasDocumentMetaCharset = () => {
const META = [...getElements('meta')];
const hasMetaCharset = META.some(tag => hasAttribute(tag, 'charset'));
const META = [...getElements('meta')];
const hasMetaCharset = META.some(tag => hasAttribute(tag, 'charset'));
if (!hasMetaCharset) Warning('Document encoding is missing. Fix: Add <meta charset="utf-8"/>');
if (!hasMetaCharset) Warning('Document encoding is missing. Fix: Add <meta charset="utf-8"/>');
};

@@ -48,6 +48,6 @@

const hasDocumentScalable = () => {
const META = [...getElements('meta')];
const hasMetaScalable = META.some(el => getAttribute(el, 'user-scalable') === 'no');
const META = [...getElements('meta')];
const hasMetaScalable = META.some(el => getAttribute(el, 'user-scalable') === 'no');
if (hasMetaScalable) Warning('Document must not use the user-scalable=no. Fix: Remove user-scalable=no from <meta name=viewport>');
if (hasMetaScalable) Warning('Document must not use the user-scalable=no. Fix: Remove user-scalable=no from <meta name=viewport>');
};

@@ -54,0 +54,0 @@

module.exports = {
entry: __dirname + '/src/a11y.js',
output: {
path: __dirname + '/dist',
publicPath: '/dist/',
filename: 'a11y.js',
library: 'a11yChecker',
libraryTarget: 'umd',
umdNamedDefine: true
},
module: {
rules: [{
test: /\.js$/,
exclude: /node_modules/,
use: 'babel-loader'
}]
}
entry: __dirname + '/src/a11y.js',
output: {
path: __dirname + '/dist',
publicPath: '/dist/',
filename: 'a11y.js',
library: 'a11yChecker',
libraryTarget: 'umd',
umdNamedDefine: true
},
module: {
rules: [{
test: /\.js$/,
exclude: /node_modules/,
use: 'babel-loader'
}]
}
};

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc