Skip to content

Commit aeba121

Browse files
author
OleksiiKachan
committed
[Fix] no-unknown-property: allow abbr on <th> and <td>
1 parent 8aa023a commit aeba121

File tree

3 files changed

+51
-12
lines changed

3 files changed

+51
-12
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ This change log adheres to standards from [Keep a CHANGELOG](https://keepachange
1010
* [`no-unknown-property`]: add `noModule` on `script` ([#3414][] @ljharb)
1111
* [`no-unknown-property`]: allow `onLoad` on `<object>` ([#3415][] @OleksiiKachan)
1212
* [`no-multi-comp`]: do not detect a function property returning only null as a component ([#3412][] @ljharb)
13+
* [`no-unknown-property`]: allow `abbr` on `<th>` and `<td>` ([#3415][] @OleksiiKachan)
1314

1415
### Changed
1516

lib/rules/no-unknown-property.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ const DOM_ATTRIBUTE_NAMES = {
2828
};
2929

3030
const ATTRIBUTE_TAGS_MAP = {
31+
abbr: ['th', 'td'],
3132
checked: ['input'],
3233
// image is required for SVG support, all other tags are HTML.
3334
crossOrigin: ['script', 'img', 'video', 'audio', 'link', 'image'],

tests/lib/rules/no-unknown-property.js

Lines changed: 49 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -46,29 +46,41 @@ ruleTester.run('no-unknown-property', rule, {
4646
{ code: '<div onMouseDown={this._onMouseDown}></div>;' },
4747
{ code: '<a href="someLink" download="foo">Read more</a>' },
4848
{ code: '<area download="foo" />' },
49-
{ code: '<img src="cat_keyboard.jpeg" alt="A cat sleeping on a keyboard" />' },
49+
{
50+
code: '<img src="cat_keyboard.jpeg" alt="A cat sleeping on a keyboard" />',
51+
},
5052
{ code: '<input type="password" required />' },
5153
{ code: '<input ref={this.input} type="radio" />' },
5254
{ code: '<div children="anything" />' },
5355
{ code: '<iframe scrolling="?" onLoad={a} onError={b} />' },
5456
{ code: '<input key="bar" type="radio" />' },
5557
{ code: '<button disabled>You cannot click me</button>;' },
56-
{ 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>' },
58+
{
59+
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>',
60+
},
5761
{ code: '<g fill="#7B82A0" fillRule="evenodd"></g>' },
5862
{ code: '<mask fill="#7B82A0"></mask>' },
5963
{ code: '<meta property="og:type" content="website" />' },
60-
{ code: '<input type="checkbox" checked={checked} disabled={disabled} id={id} onChange={onChange} />' },
64+
{
65+
code: '<input type="checkbox" checked={checked} disabled={disabled} id={id} onChange={onChange} />',
66+
},
6167
{ code: '<video playsInline />' },
6268
{ code: '<img onError={foo} onLoad={bar} />' },
6369
{ code: '<picture onError={foo} onLoad={bar} />' },
6470
{ code: '<iframe onError={foo} onLoad={bar} />' },
6571
{ code: '<script onLoad={bar} onError={foo} />' },
6672
{ code: '<source onError={foo} />' },
6773
{ code: '<link onLoad={bar} onError={foo} />' },
68-
{ code: '<link rel="preload" as="image" href="someHref" imageSrcSet="someImageSrcSet" imageSizes="someImageSizes" />' },
74+
{
75+
code: '<link rel="preload" as="image" href="someHref" imageSrcSet="someImageSrcSet" imageSizes="someImageSizes" />',
76+
},
6977
{ code: '<object onLoad={bar} />' },
70-
{ code: '<div allowFullScreen webkitAllowFullScreen mozAllowFullScreen />' },
78+
{
79+
code: '<div allowFullScreen webkitAllowFullScreen mozAllowFullScreen />',
80+
},
7181
{ code: '<table border="1" />' },
82+
{ code: '<th abbr="abbr" />' },
83+
{ code: '<td abbr="abbr" />' },
7284
{
7385
code: '<div allowTransparency="true" />',
7486
settings: {
@@ -78,7 +90,9 @@ ruleTester.run('no-unknown-property', rule, {
7890
// React related attributes
7991
{ code: '<div onPointerDown={this.onDown} onPointerUp={this.onUp} />' },
8092
{ code: '<input type="checkbox" defaultChecked={this.state.checkbox} />' },
81-
{ code: '<div onTouchStart={this.startAnimation} onTouchEnd={this.stopAnimation} onTouchCancel={this.cancel} onTouchMove={this.move} onMouseMoveCapture={this.capture} onTouchCancelCapture={this.log} />' },
93+
{
94+
code: '<div onTouchStart={this.startAnimation} onTouchEnd={this.stopAnimation} onTouchCancel={this.cancel} onTouchMove={this.move} onMouseMoveCapture={this.capture} onTouchCancelCapture={this.log} />',
95+
},
8296
// Case ignored attributes, for `charset` discussion see https://github.com/jsx-eslint/eslint-plugin-react/pull/1863
8397
{ code: '<meta charset="utf-8" />;' },
8498
{ code: '<meta charSet="utf-8" />;' },
@@ -115,12 +129,20 @@ ruleTester.run('no-unknown-property', rule, {
115129
{ code: '<audio crossOrigin />' },
116130
{ code: '<svg focusable><image crossOrigin /></svg>' },
117131
{ code: '<details onToggle={this.onToggle}>Some details</details>' },
118-
{ 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>' },
132+
{
133+
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>',
134+
},
119135
{ code: '<line fill="pink" x1="0" y1="80" x2="100" y2="20"></line>' },
120136
{ code: '<link as="audio">Audio content</link>' },
121-
{ code: '<video controlsList="nodownload" controls={this.controls} loop={true} muted={false} src={this.videoSrc} playsInline={true}></video>' },
122-
{ 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>' },
123-
{ code: '<marker id={markerId} viewBox="0 0 2 2" refX="1" refY="1" markerWidth="1" markerHeight="1" orient="auto" />' },
137+
{
138+
code: '<video controlsList="nodownload" controls={this.controls} loop={true} muted={false} src={this.videoSrc} playsInline={true}></video>',
139+
},
140+
{
141+
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>',
142+
},
143+
{
144+
code: '<marker id={markerId} viewBox="0 0 2 2" refX="1" refY="1" markerWidth="1" markerHeight="1" orient="auto" />',
145+
},
124146
{
125147
code: `
126148
<table>
@@ -431,7 +453,8 @@ ruleTester.run('no-unknown-property', rule, {
431453
data: {
432454
name: 'onError',
433455
tagName: 'div',
434-
allowedTags: 'audio, video, img, link, source, script, picture, iframe',
456+
allowedTags:
457+
'audio, video, img, link, source, script, picture, iframe',
435458
},
436459
},
437460
],
@@ -457,7 +480,8 @@ ruleTester.run('no-unknown-property', rule, {
457480
data: {
458481
name: 'fill',
459482
tagName: 'div',
460-
allowedTags: 'altGlyph, circle, ellipse, g, line, mask, path, polygon, polyline, rect, svg, text, textPath, tref, tspan, use, animate, animateColor, animateMotion, animateTransform, set',
483+
allowedTags:
484+
'altGlyph, circle, ellipse, g, line, mask, path, polygon, polyline, rect, svg, text, textPath, tref, tspan, use, animate, animateColor, animateMotion, animateTransform, set',
461485
},
462486
},
463487
],
@@ -549,5 +573,18 @@ ruleTester.run('no-unknown-property', rule, {
549573
},
550574
],
551575
},
576+
{
577+
code: '<div abbr="abbr" />',
578+
errors: [
579+
{
580+
messageId: 'invalidPropOnTag',
581+
data: {
582+
name: 'abbr',
583+
tagName: 'div',
584+
allowedTags: 'th, td',
585+
},
586+
},
587+
],
588+
},
552589
]),
553590
});

0 commit comments

Comments
 (0)