0
0
mirror of https://github.com/sveltejs/svelte.git synced 2024-12-01 17:30:59 +01:00

anchor-has-content

This commit is contained in:
Rich Harris 2017-09-03 14:42:09 -04:00
parent 51c2e0581b
commit bacbaef868
5 changed files with 62 additions and 27 deletions

50
src/validate/html/a11y.ts Normal file
View File

@ -0,0 +1,50 @@
import * as namespaces from '../../utils/namespaces';
import validateEventHandler from './validateEventHandler';
import { Validator } from '../index';
import { Node } from '../../interfaces';
export default function a11y(
validator: Validator,
node: Node,
elementStack: Node[]
) {
if (node.type === 'Text') {
// accessible-emoji
return;
}
if (node.type !== 'Element') return;
const attributeMap = new Map();
node.attributes.forEach((attribute: Node) => {
attributeMap.set(attribute.name, attribute);
});
if (node.name === 'a') {
if (!attributeMap.has('href')) {
validator.warn(`A11y: <a> element should have an href attribute`, node.start);
}
if (!node.children.length) {
validator.warn(`A11y: <a> element should have child content`, node.start);
}
}
if (node.name === 'img' && !attributeMap.has('alt')) {
validator.warn(`A11y: <img> element should have an alt attribute`, node.start);
}
if (node.name === 'figcaption') {
const parent = elementStack[elementStack.length - 1];
if (parent) {
if (parent.name !== 'figure') {
validator.warn(`A11y: <figcaption> must be an immediate child of <figure>`, node.start);
} else {
const index = parent.children.indexOf(node);
if (index !== 0 && index !== parent.children.length - 1) {
validator.warn(`A11y: <figcaption> must be first or last child of <figure>`, node.start);
}
}
}
}
}

View File

@ -1,5 +1,6 @@
import validateElement from './validateElement';
import validateWindow from './validateWindow';
import a11y from './a11y';
import fuzzymatch from '../utils/fuzzymatch'
import flattenReference from '../../utils/flattenReference';
import { Validator } from '../index';
@ -13,6 +14,8 @@ export default function validateHtml(validator: Validator, html: Node) {
const elementStack: Node[] = [];
function visit(node: Node) {
a11y(validator, node, elementStack);
if (node.type === 'Element') {
if (meta.has(node.name)) {
return meta.get(node.name)(validator, node, refs, refCallees);

View File

@ -60,8 +60,6 @@ export default function validateElement(
let hasOutro: boolean;
let hasTransition: boolean;
const attributeMap: Map<string, Node> = new Map();
node.attributes.forEach((attribute: Node) => {
if (attribute.type === 'Ref') {
if (!refs.has(attribute.name)) refs.set(attribute.name, []);
@ -179,8 +177,6 @@ export default function validateElement(
);
}
} else if (attribute.type === 'Attribute') {
attributeMap.set(attribute.name, attribute);
if (attribute.name === 'value' && node.name === 'textarea') {
if (node.children.length) {
validator.error(
@ -198,29 +194,6 @@ export default function validateElement(
}
}
});
// a11y
if (node.name === 'a' && !attributeMap.has('href')) {
validator.warn(`A11y: <a> element should have an href attribute`, node.start);
}
if (node.name === 'img' && !attributeMap.has('alt')) {
validator.warn(`A11y: <img> element should have an alt attribute`, node.start);
}
if (node.name === 'figcaption') {
const parent = elementStack[elementStack.length - 1];
if (parent) {
if (parent.name !== 'figure') {
validator.warn(`A11y: <figcaption> must be an immediate child of <figure>`, node.start);
} else {
const index = parent.children.indexOf(node);
if (index !== 0 && index !== parent.children.length - 1) {
validator.warn(`A11y: <figcaption> must be first or last child of <figure>`, node.start);
}
}
}
}
}
function checkTypeAttribute(validator: Validator, node: Node) {

View File

@ -0,0 +1 @@
<a href='/foo'></a>

View File

@ -0,0 +1,8 @@
[{
"message": "A11y: <a> element should have child content",
"loc": {
"line": 1,
"column": 0
},
"pos": 0
}]