From 5fa14b371e40f4b62aaf2ede22414f18c9c717f8 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Mon, 10 Sep 2018 21:33:34 -0400 Subject: [PATCH] a few more --- src/compile/nodes/Element.ts | 41 ++++++++++++++++++- src/validate/html/a11y.ts | 4 -- src/validate/html/validateElement.ts | 59 ---------------------------- 3 files changed, 39 insertions(+), 65 deletions(-) delete mode 100644 src/validate/html/validateElement.ts diff --git a/src/compile/nodes/Element.ts b/src/compile/nodes/Element.ts index c4949e20cc..325e93c7cf 100644 --- a/src/compile/nodes/Element.ts +++ b/src/compile/nodes/Element.ts @@ -250,6 +250,32 @@ export default class Element extends Node { }); } + if (this.name === 'figcaption') { + if (this.parent.name !== 'figure') { + this.component.warn(this, { + code: `a11y-structure`, + message: `A11y:
must be an immediate child of
` + }); + } + } + + if (this.name === 'figure') { + const children = this.children.filter(node => { + if (node.type === 'Comment') return false; + if (node.type === 'Text') return /\S/.test(node.data); + return true; + }); + + const index = children.findIndex(child => child.name === 'figcaption'); + + if (index !== -1 && (index !== 0 && index !== children.length - 1)) { + this.component.warn(children[index], { + code: `a11y-structure`, + message: `A11y:
must be first or last child of
` + }); + } + } + this.validateAttributes(); this.validateBindings(); this.validateContent(); @@ -352,7 +378,7 @@ export default class Element extends Node { }); } - let ancestor = parent; + let ancestor = this.parent; do { if (ancestor.type === 'InlineComponent') break; if (ancestor.type === 'Element' && /-/.test(ancestor.name)) break; @@ -366,7 +392,7 @@ export default class Element extends Node { message }); } - } while (ancestor); + } while (ancestor = ancestor.parent); if (!ancestor) { component.error(attribute, { @@ -409,6 +435,17 @@ export default class Element extends Node { shouldHaveAttribute(this, requiredAttributes); } } + + if (this.name === 'input') { + const type = attributeMap.get('type'); + if (type && type.getStaticValue() === 'image') { + shouldHaveAttribute( + this, + ['alt', 'aria-label', 'aria-labelledby'], + 'input type="image"' + ); + } + } } } diff --git a/src/validate/html/a11y.ts b/src/validate/html/a11y.ts index df0ff17351..88f7dbe51d 100644 --- a/src/validate/html/a11y.ts +++ b/src/validate/html/a11y.ts @@ -37,10 +37,6 @@ export default function a11y( } } - if (node.name === 'input' && getStaticAttributeValue(node, 'type') === 'image') { - shouldHaveAttribute(['alt', 'aria-label', 'aria-labelledby'], 'input type="image"'); - } - if (/^h[1-6]$/.test(node.name)) { if (attributeMap.has('aria-hidden')) { validator.warn(attributeMap.get('aria-hidden'), { diff --git a/src/validate/html/validateElement.ts b/src/validate/html/validateElement.ts deleted file mode 100644 index 59f250f877..0000000000 --- a/src/validate/html/validateElement.ts +++ /dev/null @@ -1,59 +0,0 @@ -import * as namespaces from '../../utils/namespaces'; -import validateEventHandler from './validateEventHandler'; -import { Node } from '../../interfaces'; -import { dimensions } from '../../utils/patterns'; -import isVoidElementName from '../../utils/isVoidElementName'; -import isValidIdentifier from '../../utils/isValidIdentifier'; -import Component from '../../compile/Component'; - -const svg = /^(?:altGlyph|altGlyphDef|altGlyphItem|animate|animateColor|animateMotion|animateTransform|circle|clipPath|color-profile|cursor|defs|desc|discard|ellipse|feBlend|feColorMatrix|feComponentTransfer|feComposite|feConvolveMatrix|feDiffuseLighting|feDisplacementMap|feDistantLight|feDropShadow|feFlood|feFuncA|feFuncB|feFuncG|feFuncR|feGaussianBlur|feImage|feMerge|feMergeNode|feMorphology|feOffset|fePointLight|feSpecularLighting|feSpotLight|feTile|feTurbulence|filter|font|font-face|font-face-format|font-face-name|font-face-src|font-face-uri|foreignObject|g|glyph|glyphRef|hatch|hatchpath|hkern|image|line|linearGradient|marker|mask|mesh|meshgradient|meshpatch|meshrow|metadata|missing-glyph|mpath|path|pattern|polygon|polyline|radialGradient|rect|set|solidcolor|stop|switch|symbol|text|textPath|tref|tspan|unknown|use|view|vkern)$/; - -export default function validateElement( - component: Component, - node: Node, - refs: Map, - refCallees: Node[], - stack: Node[], - elementStack: Node[] -) { - node.attributes.forEach((attribute: Node) => { - if (attribute.type === 'Attribute') { - if (attribute.name === 'value' && node.name === 'textarea') { - if (node.children.length) { - component.error(attribute, { - code: `textarea-duplicate-value`, - message: `A