Skip to content

Commit

Permalink
[Fix] no-unknown-property: allow abbr on <th> and <td>
Browse files Browse the repository at this point in the history
  • Loading branch information
OleksiiKachan committed Sep 7, 2022
1 parent 8aa023a commit aeba121
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 12 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Expand Up @@ -10,6 +10,7 @@ This change log adheres to standards from [Keep a CHANGELOG](https://keepachange
* [`no-unknown-property`]: add `noModule` on `script` ([#3414][] @ljharb)
* [`no-unknown-property`]: allow `onLoad` on `<object>` ([#3415][] @OleksiiKachan)
* [`no-multi-comp`]: do not detect a function property returning only null as a component ([#3412][] @ljharb)
* [`no-unknown-property`]: allow `abbr` on `<th>` and `<td>` ([#3415][] @OleksiiKachan)

### Changed

Expand Down
1 change: 1 addition & 0 deletions lib/rules/no-unknown-property.js
Expand Up @@ -28,6 +28,7 @@ const DOM_ATTRIBUTE_NAMES = {
};

const ATTRIBUTE_TAGS_MAP = {
abbr: ['th', 'td'],
checked: ['input'],
// image is required for SVG support, all other tags are HTML.
crossOrigin: ['script', 'img', 'video', 'audio', 'link', 'image'],
Expand Down
61 changes: 49 additions & 12 deletions tests/lib/rules/no-unknown-property.js
Expand Up @@ -46,29 +46,41 @@ ruleTester.run('no-unknown-property', rule, {
{ code: '<div onMouseDown={this._onMouseDown}></div>;' },
{ code: '<a href="someLink" download="foo">Read more</a>' },
{ code: '<area download="foo" />' },
{ code: '<img src="cat_keyboard.jpeg" alt="A cat sleeping on a keyboard" />' },
{
code: '<img src="cat_keyboard.jpeg" alt="A cat sleeping on a keyboard" />',
},
{ code: '<input type="password" required />' },
{ code: '<input ref={this.input} type="radio" />' },
{ code: '<div children="anything" />' },
{ code: '<iframe scrolling="?" onLoad={a} onError={b} />' },
{ code: '<input key="bar" type="radio" />' },
{ code: '<button disabled>You cannot click me</button>;' },
{ code: '<svg key="lock" viewBox="box" fill={10} d="d" stroke={1} strokeWidth={2} strokeLinecap={3} strokeLinejoin={4} transform="something" clipRule="else" x1={5} x2="6" y1="7" y2="8"></svg>' },
{
code: '<svg key="lock" viewBox="box" fill={10} d="d" stroke={1} strokeWidth={2} strokeLinecap={3} strokeLinejoin={4} transform="something" clipRule="else" x1={5} x2="6" y1="7" y2="8"></svg>',
},
{ code: '<g fill="#7B82A0" fillRule="evenodd"></g>' },
{ code: '<mask fill="#7B82A0"></mask>' },
{ code: '<meta property="og:type" content="website" />' },
{ code: '<input type="checkbox" checked={checked} disabled={disabled} id={id} onChange={onChange} />' },
{
code: '<input type="checkbox" checked={checked} disabled={disabled} id={id} onChange={onChange} />',
},
{ code: '<video playsInline />' },
{ code: '<img onError={foo} onLoad={bar} />' },
{ code: '<picture onError={foo} onLoad={bar} />' },
{ code: '<iframe onError={foo} onLoad={bar} />' },
{ code: '<script onLoad={bar} onError={foo} />' },
{ code: '<source onError={foo} />' },
{ code: '<link onLoad={bar} onError={foo} />' },
{ code: '<link rel="preload" as="image" href="someHref" imageSrcSet="someImageSrcSet" imageSizes="someImageSizes" />' },
{
code: '<link rel="preload" as="image" href="someHref" imageSrcSet="someImageSrcSet" imageSizes="someImageSizes" />',
},
{ code: '<object onLoad={bar} />' },
{ code: '<div allowFullScreen webkitAllowFullScreen mozAllowFullScreen />' },
{
code: '<div allowFullScreen webkitAllowFullScreen mozAllowFullScreen />',
},
{ code: '<table border="1" />' },
{ code: '<th abbr="abbr" />' },
{ code: '<td abbr="abbr" />' },
{
code: '<div allowTransparency="true" />',
settings: {
Expand All @@ -78,7 +90,9 @@ ruleTester.run('no-unknown-property', rule, {
// React related attributes
{ code: '<div onPointerDown={this.onDown} onPointerUp={this.onUp} />' },
{ code: '<input type="checkbox" defaultChecked={this.state.checkbox} />' },
{ code: '<div onTouchStart={this.startAnimation} onTouchEnd={this.stopAnimation} onTouchCancel={this.cancel} onTouchMove={this.move} onMouseMoveCapture={this.capture} onTouchCancelCapture={this.log} />' },
{
code: '<div onTouchStart={this.startAnimation} onTouchEnd={this.stopAnimation} onTouchCancel={this.cancel} onTouchMove={this.move} onMouseMoveCapture={this.capture} onTouchCancelCapture={this.log} />',
},
// Case ignored attributes, for `charset` discussion see https://github.com/jsx-eslint/eslint-plugin-react/pull/1863
{ code: '<meta charset="utf-8" />;' },
{ code: '<meta charSet="utf-8" />;' },
Expand Down Expand Up @@ -115,12 +129,20 @@ ruleTester.run('no-unknown-property', rule, {
{ code: '<audio crossOrigin />' },
{ code: '<svg focusable><image crossOrigin /></svg>' },
{ code: '<details onToggle={this.onToggle}>Some details</details>' },
{ code: '<path fill="pink" d="M 10,30 A 20,20 0,0,1 50,30 A 20,20 0,0,1 90,30 Q 90,60 50,90 Q 10,60 10,30 z"></path>' },
{
code: '<path fill="pink" d="M 10,30 A 20,20 0,0,1 50,30 A 20,20 0,0,1 90,30 Q 90,60 50,90 Q 10,60 10,30 z"></path>',
},
{ code: '<line fill="pink" x1="0" y1="80" x2="100" y2="20"></line>' },
{ code: '<link as="audio">Audio content</link>' },
{ code: '<video controlsList="nodownload" controls={this.controls} loop={true} muted={false} src={this.videoSrc} playsInline={true}></video>' },
{ code: '<audio controlsList="nodownload" controls={this.controls} crossOrigin="anonymous" disableRemotePlayback loop muted preload="none" src="something" onAbort={this.abort} onDurationChange={this.durationChange} onEmptied={this.emptied} onEnded={this.end} onError={this.error}></audio>' },
{ code: '<marker id={markerId} viewBox="0 0 2 2" refX="1" refY="1" markerWidth="1" markerHeight="1" orient="auto" />' },
{
code: '<video controlsList="nodownload" controls={this.controls} loop={true} muted={false} src={this.videoSrc} playsInline={true}></video>',
},
{
code: '<audio controlsList="nodownload" controls={this.controls} crossOrigin="anonymous" disableRemotePlayback loop muted preload="none" src="something" onAbort={this.abort} onDurationChange={this.durationChange} onEmptied={this.emptied} onEnded={this.end} onError={this.error}></audio>',
},
{
code: '<marker id={markerId} viewBox="0 0 2 2" refX="1" refY="1" markerWidth="1" markerHeight="1" orient="auto" />',
},
{
code: `
<table>
Expand Down Expand Up @@ -431,7 +453,8 @@ ruleTester.run('no-unknown-property', rule, {
data: {
name: 'onError',
tagName: 'div',
allowedTags: 'audio, video, img, link, source, script, picture, iframe',
allowedTags:
'audio, video, img, link, source, script, picture, iframe',
},
},
],
Expand All @@ -457,7 +480,8 @@ ruleTester.run('no-unknown-property', rule, {
data: {
name: 'fill',
tagName: 'div',
allowedTags: 'altGlyph, circle, ellipse, g, line, mask, path, polygon, polyline, rect, svg, text, textPath, tref, tspan, use, animate, animateColor, animateMotion, animateTransform, set',
allowedTags:
'altGlyph, circle, ellipse, g, line, mask, path, polygon, polyline, rect, svg, text, textPath, tref, tspan, use, animate, animateColor, animateMotion, animateTransform, set',
},
},
],
Expand Down Expand Up @@ -549,5 +573,18 @@ ruleTester.run('no-unknown-property', rule, {
},
],
},
{
code: '<div abbr="abbr" />',
errors: [
{
messageId: 'invalidPropOnTag',
data: {
name: 'abbr',
tagName: 'div',
allowedTags: 'th, td',
},
},
],
},
]),
});

0 comments on commit aeba121

Please sign in to comment.