Skip to content

Commit d452ea7

Browse files
committed
[Fix] add touch and media event related properties
1 parent 2cf0917 commit d452ea7

File tree

2 files changed

+76
-1
lines changed

2 files changed

+76
-1
lines changed

lib/rules/no-unknown-property.js

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,30 @@ const ATTRIBUTE_TAGS_MAP = {
4040
property: ['meta'],
4141
viewBox: ['svg'],
4242
as: ['link'],
43+
// Media events allowed only on audio and video tags, see https://github.com/facebook/react/blob/256aefbea1449869620fb26f6ec695536ab453f5/CHANGELOG.md#notable-enhancements
44+
onAbort: ['audio', 'video'],
45+
onCanPlay: ['audio', 'video'],
46+
onCanPlayThrough: ['audio', 'video'],
47+
onDurationChange: ['audio', 'video'],
48+
onEmptied: ['audio', 'video'],
49+
onEncrypted: ['audio', 'video'],
50+
onEnded: ['audio', 'video'],
51+
onError: ['audio', 'video'],
52+
onLoadedData: ['audio', 'video'],
53+
onLoadedMetadata: ['audio', 'video'],
54+
onLoadStart: ['audio', 'video'],
55+
onPause: ['audio', 'video'],
56+
onPlay: ['audio', 'video'],
57+
onPlaying: ['audio', 'video'],
58+
onProgress: ['audio', 'video'],
59+
onRateChange: ['audio', 'video'],
60+
onSeeked: ['audio', 'video'],
61+
onSeeking: ['audio', 'video'],
62+
onStalled: ['audio', 'video'],
63+
onSuspend: ['audio', 'video'],
64+
onTimeUpdate: ['audio', 'video'],
65+
onVolumeChange: ['audio', 'video'],
66+
onWaiting: ['audio', 'video'],
4367
};
4468

4569
const SVGDOM_ATTRIBUTE_NAMES = {
@@ -211,7 +235,11 @@ const DOM_PROPERTY_NAMES_TWO_WORDS = [
211235
'autoCorrect', // https://stackoverflow.com/questions/47985384/html-autocorrect-for-text-input-is-not-working
212236
'autoSave', // https://stackoverflow.com/questions/25456396/what-is-autosave-attribute-supposed-to-do-how-do-i-use-it
213237
// React specific attributes https://reactjs.org/docs/dom-elements.html#differences-in-attributes
214-
'className', 'dangerouslySetInnerHTML', 'defaultValue', 'defaultChecked', 'htmlFor', 'onChange', 'suppressContentEditableWarning', 'suppressHydrationWarning',
238+
'className', 'dangerouslySetInnerHTML', 'defaultValue', 'defaultChecked', 'htmlFor', 'onChange',
239+
'onInvalid', 'onReset', 'onTouchCancel', 'onTouchEnd', 'onTouchMove', 'onTouchStart', 'suppressContentEditableWarning', 'suppressHydrationWarning',
240+
'onAbort', 'onCanPlay', 'onCanPlayThrough', 'onDurationChange', 'onEmptied', 'onEncrypted', 'onEnded',
241+
'onLoadedData', 'onLoadedMetadata', 'onLoadStart', 'onPause', 'onPlay', 'onPlaying', 'onProgress', 'onRateChange',
242+
'onSeeked', 'onSeeking', 'onStalled', 'onSuspend', 'onTimeUpdate', 'onVolumeChange', 'onWaiting',
215243
];
216244

217245
const DOM_PROPERTIES_IGNORE_CASE = ['charset'];

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

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

0 commit comments

Comments
 (0)