Skip to content

Commit 7d4fe18

Browse files
sjarvaljharb
authored andcommitted
[Fix] no-unknown-property: add touch and media event related properties
1 parent be4e93c commit 7d4fe18

File tree

3 files changed

+77
-1
lines changed

3 files changed

+77
-1
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ This change log adheres to standards from [Keep a CHANGELOG](https://keepachange
88
### Fixed
99
* [`no-unknown-property`]: add properties `onToggle`, `fill`, `as`, and pointer events ([#3385][] @sjarva)
1010
* [`no-unknown-property`]: add `defaultChecked` property ([#3385][] @sjarva)
11+
* [`no-unknown-property`]: add touch and media event related properties ([#3385][] @sjarva)
1112

1213
[#3385]: https://github.com/jsx-eslint/eslint-plugin-react/issues/3385
1314

lib/rules/no-unknown-property.js

+29-1
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,30 @@ const ATTRIBUTE_TAGS_MAP = {
5555
property: ['meta'],
5656
viewBox: ['svg'],
5757
as: ['link'],
58+
// Media events allowed only on audio and video tags, see https://github.com/facebook/react/blob/256aefbea1449869620fb26f6ec695536ab453f5/CHANGELOG.md#notable-enhancements
59+
onAbort: ['audio', 'video'],
60+
onCanPlay: ['audio', 'video'],
61+
onCanPlayThrough: ['audio', 'video'],
62+
onDurationChange: ['audio', 'video'],
63+
onEmptied: ['audio', 'video'],
64+
onEncrypted: ['audio', 'video'],
65+
onEnded: ['audio', 'video'],
66+
onError: ['audio', 'video'],
67+
onLoadedData: ['audio', 'video'],
68+
onLoadedMetadata: ['audio', 'video'],
69+
onLoadStart: ['audio', 'video'],
70+
onPause: ['audio', 'video'],
71+
onPlay: ['audio', 'video'],
72+
onPlaying: ['audio', 'video'],
73+
onProgress: ['audio', 'video'],
74+
onRateChange: ['audio', 'video'],
75+
onSeeked: ['audio', 'video'],
76+
onSeeking: ['audio', 'video'],
77+
onStalled: ['audio', 'video'],
78+
onSuspend: ['audio', 'video'],
79+
onTimeUpdate: ['audio', 'video'],
80+
onVolumeChange: ['audio', 'video'],
81+
onWaiting: ['audio', 'video'],
5882
};
5983

6084
const SVGDOM_ATTRIBUTE_NAMES = {
@@ -226,7 +250,11 @@ const DOM_PROPERTY_NAMES_TWO_WORDS = [
226250
'autoCorrect', // https://stackoverflow.com/questions/47985384/html-autocorrect-for-text-input-is-not-working
227251
'autoSave', // https://stackoverflow.com/questions/25456396/what-is-autosave-attribute-supposed-to-do-how-do-i-use-it
228252
// React specific attributes https://reactjs.org/docs/dom-elements.html#differences-in-attributes
229-
'className', 'dangerouslySetInnerHTML', 'defaultValue', 'defaultChecked', 'htmlFor', 'onChange', 'suppressContentEditableWarning', 'suppressHydrationWarning',
253+
'className', 'dangerouslySetInnerHTML', 'defaultValue', 'defaultChecked', 'htmlFor', 'onChange',
254+
'onInvalid', 'onReset', 'onTouchCancel', 'onTouchEnd', 'onTouchMove', 'onTouchStart', 'suppressContentEditableWarning', 'suppressHydrationWarning',
255+
'onAbort', 'onCanPlay', 'onCanPlayThrough', 'onDurationChange', 'onEmptied', 'onEncrypted', 'onEnded',
256+
'onLoadedData', 'onLoadedMetadata', 'onLoadStart', 'onPause', 'onPlay', 'onPlaying', 'onProgress', 'onRateChange',
257+
'onSeeked', 'onSeeking', 'onStalled', 'onSuspend', 'onTimeUpdate', 'onVolumeChange', 'onWaiting',
230258
];
231259

232260
const DOM_PROPERTIES_IGNORE_CASE = ['charset'];

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

+47
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ ruleTester.run('no-unknown-property', rule, {
5757
// React related attributes
5858
{ code: '<div onPointerDown={this.onDown} onPointerUp={this.onUp} />' },
5959
{ code: '<input type="checkbox" defaultChecked={this.state.checkbox} />' },
60+
{ code: '<div onTouchStart={this.startAnimation} onTouchEnd={this.stopAnimation} onTouchCancel={this.cancel} onTouchMove={this.move} />' },
6061
// Case ignored attributes, for `charset` discussion see https://github.com/jsx-eslint/eslint-plugin-react/pull/1863
6162
{ code: '<meta charset="utf-8" />;' },
6263
{ code: '<meta charSet="utf-8" />;' },
@@ -89,6 +90,7 @@ ruleTester.run('no-unknown-property', rule, {
8990
{ code: '<details onToggle={this.onToggle}>Some details</details>' },
9091
{ 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>' },
9192
{ code: '<link as="audio">Audio content</link>' },
93+
{ code: '<audio onAbort={this.abort} onDurationChange={this.durationChange} onEmptied={this.emptied} onEnded={this.end} onError={this.error}></audio>' },
9294
]),
9395
invalid: parsers.all([
9496
{
@@ -318,5 +320,50 @@ ruleTester.run('no-unknown-property', rule, {
318320
},
319321
],
320322
},
323+
{
324+
code: '<div onAbort={this.abort} onDurationChange={this.durationChange} onEmptied={this.emptied} onEnded={this.end} onError={this.error} />',
325+
errors: [
326+
{
327+
messageId: 'invalidPropOnTag',
328+
data: {
329+
name: 'onAbort',
330+
tagName: 'div',
331+
allowedTags: 'audio, video',
332+
},
333+
},
334+
{
335+
messageId: 'invalidPropOnTag',
336+
data: {
337+
name: 'onDurationChange',
338+
tagName: 'div',
339+
allowedTags: 'audio, video',
340+
},
341+
},
342+
{
343+
messageId: 'invalidPropOnTag',
344+
data: {
345+
name: 'onEmptied',
346+
tagName: 'div',
347+
allowedTags: 'audio, video',
348+
},
349+
},
350+
{
351+
messageId: 'invalidPropOnTag',
352+
data: {
353+
name: 'onEnded',
354+
tagName: 'div',
355+
allowedTags: 'audio, video',
356+
},
357+
},
358+
{
359+
messageId: 'invalidPropOnTag',
360+
data: {
361+
name: 'onError',
362+
tagName: 'div',
363+
allowedTags: 'audio, video',
364+
},
365+
},
366+
],
367+
},
321368
]),
322369
});

0 commit comments

Comments
 (0)