Skip to content

Commit 1d1b1ec

Browse files
committed
Strip whitelist. Move casing warnings to dev tools
Configures DOMPropertyOperations to allow all attributes to pass through. It maintains the whitelist only for attributes that need special behavior. - Lowercase props during static markup generation
1 parent c78464f commit 1d1b1ec

File tree

8 files changed

+114
-374
lines changed

8 files changed

+114
-374
lines changed

src/renderers/dom/shared/DOMProperty.js

Lines changed: 27 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,23 @@
1313

1414
var invariant = require('invariant');
1515

16+
var RESERVED_PROPS = {
17+
children: true,
18+
dangerouslySetInnerHTML: true,
19+
key: true,
20+
ref: true,
21+
22+
autoFocus: true,
23+
defaultValue: true,
24+
valueLink: true,
25+
defaultChecked: true,
26+
checkedLink: true,
27+
innerHTML: true,
28+
suppressContentEditableWarning: true,
29+
onFocusIn: true,
30+
onFocusOut: true,
31+
};
32+
1633
function checkMask(value, bitmask) {
1734
return (value & bitmask) === bitmask;
1835
}
@@ -32,11 +49,6 @@ var DOMPropertyInjection = {
3249
* Inject some specialized knowledge about the DOM. This takes a config object
3350
* with the following properties:
3451
*
35-
* isCustomAttribute: function that given an attribute name will return true
36-
* if it can be inserted into the DOM verbatim. Useful for data-* or aria-*
37-
* attributes where it's impossible to enumerate all of the possible
38-
* attribute names,
39-
*
4052
* Properties: object mapping DOM property name to one of the
4153
* DOMPropertyInjection constants or null. If your attribute isn't in here,
4254
* it won't get written to the DOM.
@@ -64,12 +76,6 @@ var DOMPropertyInjection = {
6476
var DOMPropertyNames = domPropertyConfig.DOMPropertyNames || {};
6577
var DOMMutationMethods = domPropertyConfig.DOMMutationMethods || {};
6678

67-
if (domPropertyConfig.isCustomAttribute) {
68-
DOMProperty._isCustomAttributeFunctions.push(
69-
domPropertyConfig.isCustomAttribute
70-
);
71-
}
72-
7379
for (var propName in Properties) {
7480
invariant(
7581
!DOMProperty.properties.hasOwnProperty(propName),
@@ -197,26 +203,20 @@ var DOMProperty = {
197203
*/
198204
getPossibleStandardName: __DEV__ ? {} : null,
199205

200-
/**
201-
* All of the isCustomAttribute() functions that have been injected.
202-
*/
203-
_isCustomAttributeFunctions: [],
206+
injection: DOMPropertyInjection,
204207

205208
/**
206-
* Checks whether a property name is a custom attribute.
207-
* @method
209+
* Checks to see if a property name is within the list of properties
210+
* reserved for internal React operations. These properties should
211+
* not be set on an HTML element.
212+
*
213+
* @private
214+
* @param {string} name
215+
* @return {boolean} If the name is within reserved props
208216
*/
209-
isCustomAttribute: function(attributeName) {
210-
for (var i = 0; i < DOMProperty._isCustomAttributeFunctions.length; i++) {
211-
var isCustomAttributeFn = DOMProperty._isCustomAttributeFunctions[i];
212-
if (isCustomAttributeFn(attributeName)) {
213-
return true;
214-
}
215-
}
216-
return false;
217+
isReservedProp(name) {
218+
return RESERVED_PROPS.hasOwnProperty(name);
217219
},
218-
219-
injection: DOMPropertyInjection,
220220
};
221221

222222
module.exports = DOMProperty;

src/renderers/dom/shared/DOMPropertyOperations.js

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -100,11 +100,11 @@ var DOMPropertyOperations = {
100100
return attributeName + '=""';
101101
}
102102
return attributeName + '=' + quoteAttributeValueForBrowser(value);
103-
} else if (DOMProperty.isCustomAttribute(name)) {
103+
} else {
104104
if (value == null) {
105105
return '';
106106
}
107-
return name + '=' + quoteAttributeValueForBrowser(value);
107+
return name.toLowerCase() + '=' + quoteAttributeValueForBrowser(value);
108108
}
109109
return null;
110110
},
@@ -158,7 +158,7 @@ var DOMPropertyOperations = {
158158
node.setAttribute(attributeName, '' + value);
159159
}
160160
}
161-
} else if (DOMProperty.isCustomAttribute(name)) {
161+
} else {
162162
DOMPropertyOperations.setValueForAttribute(node, name, value);
163163
return;
164164
}
@@ -178,6 +178,7 @@ var DOMPropertyOperations = {
178178
if (!isAttributeNameSafe(name)) {
179179
return;
180180
}
181+
181182
if (value == null) {
182183
node.removeAttribute(name);
183184
} else {
@@ -235,7 +236,7 @@ var DOMPropertyOperations = {
235236
} else {
236237
node.removeAttribute(propertyInfo.attributeName);
237238
}
238-
} else if (DOMProperty.isCustomAttribute(name)) {
239+
} else {
239240
node.removeAttribute(name);
240241
}
241242

src/renderers/dom/shared/HTMLDOMPropertyConfig.js

Lines changed: 7 additions & 142 deletions
Original file line numberDiff line numberDiff line change
@@ -22,186 +22,51 @@ var HAS_OVERLOADED_BOOLEAN_VALUE =
2222
DOMProperty.injection.HAS_OVERLOADED_BOOLEAN_VALUE;
2323

2424
var HTMLDOMPropertyConfig = {
25-
isCustomAttribute: RegExp.prototype.test.bind(
26-
new RegExp('^(data|aria)-[' + DOMProperty.ATTRIBUTE_NAME_CHAR + ']*$')
27-
),
2825
Properties: {
2926
/**
3027
* Standard Properties
3128
*/
32-
accept: 0,
33-
acceptCharset: 0,
34-
accessKey: 0,
35-
action: 0,
3629
allowFullScreen: HAS_BOOLEAN_VALUE,
37-
allowTransparency: 0,
38-
alt: 0,
39-
// specifies target context for links with `preload` type
40-
as: 0,
4130
async: HAS_BOOLEAN_VALUE,
42-
autoComplete: 0,
4331
// autoFocus is polyfilled/normalized by AutoFocusUtils
4432
// autoFocus: HAS_BOOLEAN_VALUE,
4533
autoPlay: HAS_BOOLEAN_VALUE,
4634
capture: HAS_BOOLEAN_VALUE,
47-
cellPadding: 0,
48-
cellSpacing: 0,
49-
charSet: 0,
50-
challenge: 0,
5135
checked: MUST_USE_PROPERTY | HAS_BOOLEAN_VALUE,
52-
cite: 0,
53-
classID: 0,
54-
className: 0,
5536
cols: HAS_POSITIVE_NUMERIC_VALUE,
56-
colSpan: 0,
57-
content: 0,
58-
contentEditable: 0,
59-
contextMenu: 0,
6037
controls: HAS_BOOLEAN_VALUE,
61-
coords: 0,
62-
crossOrigin: 0,
63-
data: 0, // For `<object />` acts as `src`.
64-
dateTime: 0,
6538
default: HAS_BOOLEAN_VALUE,
6639
defer: HAS_BOOLEAN_VALUE,
67-
dir: 0,
6840
disabled: HAS_BOOLEAN_VALUE,
6941
download: HAS_OVERLOADED_BOOLEAN_VALUE,
70-
draggable: 0,
71-
encType: 0,
72-
form: 0,
73-
formAction: 0,
74-
formEncType: 0,
75-
formMethod: 0,
7642
formNoValidate: HAS_BOOLEAN_VALUE,
77-
formTarget: 0,
78-
frameBorder: 0,
79-
headers: 0,
80-
height: 0,
8143
hidden: HAS_BOOLEAN_VALUE,
82-
high: 0,
83-
href: 0,
84-
hrefLang: 0,
85-
htmlFor: 0,
86-
httpEquiv: 0,
87-
id: 0,
88-
inputMode: 0,
89-
integrity: 0,
90-
is: 0,
91-
keyParams: 0,
92-
keyType: 0,
93-
kind: 0,
94-
label: 0,
95-
lang: 0,
96-
list: 0,
9744
loop: HAS_BOOLEAN_VALUE,
98-
low: 0,
99-
manifest: 0,
100-
marginHeight: 0,
101-
marginWidth: 0,
102-
max: 0,
103-
maxLength: 0,
104-
media: 0,
105-
mediaGroup: 0,
106-
method: 0,
107-
min: 0,
108-
minLength: 0,
10945
// Caution; `option.selected` is not updated if `select.multiple` is
11046
// disabled with `removeAttribute`.
11147
multiple: MUST_USE_PROPERTY | HAS_BOOLEAN_VALUE,
11248
muted: MUST_USE_PROPERTY | HAS_BOOLEAN_VALUE,
113-
name: 0,
114-
nonce: 0,
11549
noValidate: HAS_BOOLEAN_VALUE,
11650
open: HAS_BOOLEAN_VALUE,
117-
optimum: 0,
118-
pattern: 0,
119-
placeholder: 0,
120-
playsInline: HAS_BOOLEAN_VALUE,
121-
poster: 0,
122-
preload: 0,
123-
profile: 0,
124-
radioGroup: 0,
12551
readOnly: HAS_BOOLEAN_VALUE,
126-
referrerPolicy: 0,
127-
rel: 0,
12852
required: HAS_BOOLEAN_VALUE,
12953
reversed: HAS_BOOLEAN_VALUE,
130-
role: 0,
13154
rows: HAS_POSITIVE_NUMERIC_VALUE,
13255
rowSpan: HAS_NUMERIC_VALUE,
133-
sandbox: 0,
134-
scope: 0,
13556
scoped: HAS_BOOLEAN_VALUE,
136-
scrolling: 0,
13757
seamless: HAS_BOOLEAN_VALUE,
13858
selected: MUST_USE_PROPERTY | HAS_BOOLEAN_VALUE,
139-
shape: 0,
14059
size: HAS_POSITIVE_NUMERIC_VALUE,
141-
sizes: 0,
14260
span: HAS_POSITIVE_NUMERIC_VALUE,
143-
spellCheck: 0,
144-
src: 0,
145-
srcDoc: 0,
146-
srcLang: 0,
147-
srcSet: 0,
14861
start: HAS_NUMERIC_VALUE,
149-
step: 0,
150-
style: 0,
151-
summary: 0,
152-
tabIndex: 0,
153-
target: 0,
154-
title: 0,
155-
// Setting .type throws on non-<input> tags
156-
type: 0,
157-
useMap: 0,
158-
value: 0,
159-
width: 0,
160-
wmode: 0,
161-
wrap: 0,
162-
163-
/**
164-
* RDFa Properties
165-
*/
166-
about: 0,
167-
datatype: 0,
168-
inlist: 0,
169-
prefix: 0,
170-
// property is also supported for OpenGraph in meta tags.
171-
property: 0,
172-
resource: 0,
173-
typeof: 0,
174-
vocab: 0,
175-
176-
/**
177-
* Non-standard Properties
178-
*/
179-
// autoCapitalize and autoCorrect are supported in Mobile Safari for
180-
// keyboard hints.
181-
autoCapitalize: 0,
182-
autoCorrect: 0,
183-
// autoSave allows WebKit/Blink to persist values of input fields on page reloads
184-
autoSave: 0,
185-
// color is for Safari mask-icon link
186-
color: 0,
187-
// itemProp, itemScope, itemType are for
188-
// Microdata support. See http://schema.org/docs/gs.html
189-
itemProp: 0,
19062
itemScope: HAS_BOOLEAN_VALUE,
191-
itemType: 0,
192-
// itemID and itemRef are for Microdata support as well but
193-
// only specified in the WHATWG spec document. See
194-
// https://html.spec.whatwg.org/multipage/microdata.html#microdata-dom-api
195-
itemID: 0,
196-
itemRef: 0,
197-
// results show looking glass icon and recent searches on input
198-
// search fields in WebKit/Blink
199-
results: 0,
200-
// IE-only attribute that specifies security restrictions on an iframe
201-
// as an alternative to the sandbox attribute on IE<10
202-
security: 0,
203-
// IE-only attribute that controls focus behavior
204-
unselectable: 0,
63+
64+
// These properties are necessary as exceptions for names.
65+
// They should match DOMAttributeNames
66+
acceptCharset: 0,
67+
className: 0,
68+
htmlFor: 0,
69+
httpEquiv: 0,
20570
},
20671
DOMAttributeNames: {
20772
acceptCharset: 'accept-charset',

0 commit comments

Comments
 (0)