Allowed HTML Attributes to be passed via props

This fix still needs some work, as certain attributes could be passed to Uppy or as an HTML attribute, such as target

When this is fixed, this will resolve #2403
This commit is contained in:
Andrew Kachnic 2020-07-30 08:34:53 -04:00
parent b34e3dac93
commit d7f8076fb3
No known key found for this signature in database
GPG key ID: A6A8DA5501F52C6F
6 changed files with 206 additions and 5 deletions

View file

@ -1,6 +1,7 @@
const React = require('react')
const DashboardPlugin = require('@uppy/dashboard')
const basePropTypes = require('./propTypes').dashboard
const { findValidProps } = require('./common')
const h = React.createElement
@ -10,6 +11,11 @@ const h = React.createElement
*/
class Dashboard extends React.Component {
constructor (props) {
super(props)
this.validProps = findValidProps(props)
}
componentDidMount () {
this.installPlugin()
}
@ -48,7 +54,8 @@ class Dashboard extends React.Component {
return h('div', {
ref: (container) => {
this.container = container
}
},
...this.validProps
})
}
}

View file

@ -2,6 +2,7 @@ const React = require('react')
const PropTypes = require('prop-types')
const DashboardPlugin = require('@uppy/dashboard')
const basePropTypes = require('./propTypes').dashboard
const { findValidProps } = require('./common')
const h = React.createElement
@ -11,6 +12,11 @@ const h = React.createElement
*/
class DashboardModal extends React.Component {
constructor (props) {
super(props)
this.validProps = findValidProps(props)
}
componentDidMount () {
this.installPlugin()
}
@ -64,7 +70,8 @@ class DashboardModal extends React.Component {
return h('div', {
ref: (container) => {
this.container = container
}
},
...this.validProps
})
}
}

View file

@ -1,6 +1,7 @@
const React = require('react')
const DragDropPlugin = require('@uppy/drag-drop')
const propTypes = require('./propTypes')
const { findValidProps } = require('./common')
const h = React.createElement
@ -10,6 +11,11 @@ const h = React.createElement
*/
class DragDrop extends React.Component {
constructor (props) {
super(props)
this.validProps = findValidProps(props)
}
componentDidMount () {
this.installPlugin()
}
@ -49,7 +55,8 @@ class DragDrop extends React.Component {
return h('div', {
ref: (container) => {
this.container = container
}
},
...this.validProps
})
}
}

View file

@ -2,6 +2,7 @@ const React = require('react')
const PropTypes = require('prop-types')
const ProgressBarPlugin = require('@uppy/progress-bar')
const uppyPropType = require('./propTypes').uppy
const { findValidProps } = require('./common')
const h = React.createElement
@ -10,6 +11,11 @@ const h = React.createElement
*/
class ProgressBar extends React.Component {
constructor (props) {
super(props)
this.validProps = findValidProps(props)
}
componentDidMount () {
this.installPlugin()
}
@ -49,7 +55,8 @@ class ProgressBar extends React.Component {
return h('div', {
ref: (container) => {
this.container = container
}
},
...this.validProps
})
}
}

View file

@ -2,6 +2,7 @@ const React = require('react')
const PropTypes = require('prop-types')
const StatusBarPlugin = require('@uppy/status-bar')
const uppyPropType = require('./propTypes').uppy
const { findValidProps } = require('./common')
const h = React.createElement
@ -11,6 +12,11 @@ const h = React.createElement
*/
class StatusBar extends React.Component {
constructor (props) {
super(props)
this.validProps = findValidProps(props)
}
componentDidMount () {
this.installPlugin()
}
@ -50,7 +56,8 @@ class StatusBar extends React.Component {
return h('div', {
ref: (container) => {
this.container = container
}
},
...this.validProps
})
}
}

View file

@ -0,0 +1,166 @@
const possibleStandardNames = {
accept: 'accept',
acceptcharset: 'acceptCharset',
'accept-charset': 'acceptCharset',
accesskey: 'accessKey',
action: 'action',
allowfullscreen: 'allowFullScreen',
alt: 'alt',
as: 'as',
async: 'async',
autocapitalize: 'autoCapitalize',
autocomplete: 'autoComplete',
autocorrect: 'autoCorrect',
autofocus: 'autoFocus',
autoplay: 'autoPlay',
autosave: 'autoSave',
capture: 'capture',
cellpadding: 'cellPadding',
cellspacing: 'cellSpacing',
challenge: 'challenge',
charset: 'charSet',
checked: 'checked',
children: 'children',
cite: 'cite',
class: 'className',
classid: 'classID',
classname: 'className',
cols: 'cols',
colspan: 'colSpan',
content: 'content',
contenteditable: 'contentEditable',
contextmenu: 'contextMenu',
controls: 'controls',
controlslist: 'controlsList',
coords: 'coords',
crossorigin: 'crossOrigin',
dangerouslysetinnerhtml: 'dangerouslySetInnerHTML',
data: 'data',
datetime: 'dateTime',
default: 'default',
defaultchecked: 'defaultChecked',
defaultvalue: 'defaultValue',
defer: 'defer',
dir: 'dir',
disabled: 'disabled',
disablepictureinpicture: 'disablePictureInPicture',
disableremoteplayback: 'disableRemotePlayback',
download: 'download',
draggable: 'draggable',
enctype: 'encType',
enterkeyhint: 'enterKeyHint',
for: 'htmlFor',
form: 'form',
formmethod: 'formMethod',
formaction: 'formAction',
formenctype: 'formEncType',
formnovalidate: 'formNoValidate',
formtarget: 'formTarget',
frameborder: 'frameBorder',
headers: 'headers',
height: 'height',
hidden: 'hidden',
high: 'high',
href: 'href',
hreflang: 'hrefLang',
htmlfor: 'htmlFor',
httpequiv: 'httpEquiv',
'http-equiv': 'httpEquiv',
icon: 'icon',
id: 'id',
innerhtml: 'innerHTML',
inputmode: 'inputMode',
integrity: 'integrity',
is: 'is',
itemid: 'itemID',
itemprop: 'itemProp',
itemref: 'itemRef',
itemscope: 'itemScope',
itemtype: 'itemType',
keyparams: 'keyParams',
keytype: 'keyType',
kind: 'kind',
label: 'label',
lang: 'lang',
list: 'list',
loop: 'loop',
low: 'low',
manifest: 'manifest',
marginwidth: 'marginWidth',
marginheight: 'marginHeight',
max: 'max',
maxlength: 'maxLength',
media: 'media',
mediagroup: 'mediaGroup',
method: 'method',
min: 'min',
minlength: 'minLength',
multiple: 'multiple',
muted: 'muted',
name: 'name',
nomodule: 'noModule',
nonce: 'nonce',
novalidate: 'noValidate',
open: 'open',
optimum: 'optimum',
pattern: 'pattern',
placeholder: 'placeholder',
playsinline: 'playsInline',
poster: 'poster',
preload: 'preload',
profile: 'profile',
radiogroup: 'radioGroup',
readonly: 'readOnly',
referrerpolicy: 'referrerPolicy',
rel: 'rel',
required: 'required',
reversed: 'reversed',
role: 'role',
rows: 'rows',
rowspan: 'rowSpan',
sandbox: 'sandbox',
scope: 'scope',
scoped: 'scoped',
scrolling: 'scrolling',
seamless: 'seamless',
selected: 'selected',
shape: 'shape',
size: 'size',
sizes: 'sizes',
span: 'span',
spellcheck: 'spellCheck',
src: 'src',
srcdoc: 'srcDoc',
srclang: 'srcLang',
srcset: 'srcSet',
start: 'start',
step: 'step',
style: 'style',
summary: 'summary',
tabindex: 'tabIndex',
target: 'target',
title: 'title',
type: 'type',
usemap: 'useMap',
value: 'value',
width: 'width',
wmode: 'wmode',
wrap: 'wrap'
}
const getEntries = (object) => {
// eslint-disable-next-line compat/compat
return Object.entries ? Object.entries : Object.keys(object).map(key => [key, object[key]])
}
const getValues = (object) => {
// eslint-disable-next-line compat/compat
return Object.values ? Object.values : Object.keys(object).map(key => object[key])
}
const findValidProps = (props) => {
const validReactHTMLAttributes = getValues(possibleStandardNames)
const reducer = (acc, [key, value]) => validReactHTMLAttributes.includes(key) ? { ...acc, [key]: value } : acc
return getEntries(props).reduce(reducer, {})
}
module.exports = {
findValidProps
}