Add HAS_POSITIVE_NUMERIC_VALUE to DOMProperty and normalize behavior of null values
Uniformly remove null values, rather than sometimes set/remove, could potentially assign 'null' or 'undefined'
Andreas Svensson committed
Nov 12, 2013 at 11:03 UTC
e060eabb0116e80ab516c3483027e5938bbb8410
2 files changed
+62
-23
src/dom/DOMProperty.js
+28
-12
@@ -29,9 +29,10 @@ var DOMPropertyInjection = {
29
* specifies how the associated DOM property should be accessed or rendered.
30
*/
31
MUST_USE_ATTRIBUTE: 0x1,
32
- MUST_USE_PROPERTY: 0x2,
33
- HAS_BOOLEAN_VALUE: 0x4,
34
- HAS_SIDE_EFFECTS: 0x8,
32
+ MUST_USE_PROPERTY: 0x2,
33
+ HAS_SIDE_EFFECTS: 0x4,
34
+ HAS_BOOLEAN_VALUE: 0x8,
35
+ HAS_POSITIVE_NUMERIC_VALUE: 0x10,
36
37
/**
38
* Inject some specialized knowledge about the DOM. This takes a config object
@@ -105,15 +106,17 @@ var DOMPropertyInjection = {
106
propConfig & DOMPropertyInjection.MUST_USE_ATTRIBUTE;
107
DOMProperty.mustUseProperty[propName] =
108
propConfig & DOMPropertyInjection.MUST_USE_PROPERTY;
108
- DOMProperty.hasBooleanValue[propName] =
109
- propConfig & DOMPropertyInjection.HAS_BOOLEAN_VALUE;
109
DOMProperty.hasSideEffects[propName] =
110
propConfig & DOMPropertyInjection.HAS_SIDE_EFFECTS;
112
-
111
+ DOMProperty.hasBooleanValue[propName] =
112
+ propConfig & DOMPropertyInjection.HAS_BOOLEAN_VALUE;
113
+ DOMProperty.hasPositiveNumericValue[propName] =
114
+ propConfig & DOMPropertyInjection.HAS_POSITIVE_NUMERIC_VALUE;
115
+
116
invariant(
117
!DOMProperty.mustUseAttribute[propName] ||
118
!DOMProperty.mustUseProperty[propName],
116
- 'DOMProperty: Cannot use require using both attribute and property: %s',
119
+ 'DOMProperty: Cannot require using both attribute and property: %s',
120
propName
121
);
122
invariant(
@@ -122,6 +125,12 @@ var DOMPropertyInjection = {
125
'DOMProperty: Properties that have side effects must use property: %s',
126
propName
127
);
128
+ invariant(
129
+ !DOMProperty.hasBooleanValue[propName] ||
130
+ !DOMProperty.hasPositiveNumericValue[propName],
131
+ 'DOMProperty: Cannot have both boolean and positive numeric value: %s',
132
+ propName
133
+ );
134
}
135
}
136
};
@@ -189,6 +198,14 @@ var DOMProperty = {
198
*/
199
mustUseProperty: {},
200
201
+ /**
202
+ * Whether or not setting a value causes side effects such as triggering
203
+ * resources to be loaded or text selection changes. We must ensure that
204
+ * the value is only set if it has changed.
205
+ * @type {Object}
206
+ */
207
+ hasSideEffects: {},
208
+
209
/**
210
* Whether the property should be removed when set to a falsey value.
211
* @type {Object}
@@ -196,13 +213,12 @@ var DOMProperty = {
213
hasBooleanValue: {},
214
215
/**
199
- * Whether or not setting a value causes side effects such as triggering
200
- * resources to be loaded or text selection changes. We must ensure that
201
- * the value is only set if it has changed.
216
+ * Whether the property must be positive numeric or parse as a positive
217
+ * numeric and should be removed when set to a falsey value.
218
* @type {Object}
219
*/
204
- hasSideEffects: {},
205
-
220
+ hasPositiveNumericValue: {},
221
+
222
/**
223
* All of the isCustomAttribute() functions that have been injected.
224
*/
src/dom/DOMPropertyOperations.js
+34
-11
@@ -74,7 +74,10 @@ var DOMPropertyOperations = {
74
*/
75
createMarkupForProperty: function(name, value) {
76
if (DOMProperty.isStandardName[name]) {
77
- if (value == null || DOMProperty.hasBooleanValue[name] && !value) {
77
+ if (value == null ||
78
+ DOMProperty.hasBooleanValue[name] && !value ||
79
+ DOMProperty.hasPositiveNumericValue[name] &&
80
+ (isNaN(+value) || +value < 1)) {
81
return '';
82
}
83
var attributeName = DOMProperty.getAttributeName[name];
@@ -104,20 +107,40 @@ var DOMPropertyOperations = {
107
var mutationMethod = DOMProperty.getMutationMethod[name];
108
if (mutationMethod) {
109
mutationMethod(node, value);
107
- } else if (DOMProperty.mustUseAttribute[name]) {
108
- if (DOMProperty.hasBooleanValue[name] && !value) {
109
- node.removeAttribute(DOMProperty.getAttributeName[name]);
110
- } else {
111
- node.setAttribute(DOMProperty.getAttributeName[name], '' + value);
112
- }
110
} else {
114
- var propName = DOMProperty.getPropertyName[name];
115
- if (!DOMProperty.hasSideEffects[name] || node[propName] !== value) {
116
- node[propName] = value;
111
+ if (value == null ||
112
+ DOMProperty.hasBooleanValue[name] && !value ||
113
+ DOMProperty.hasPositiveNumericValue[name] &&
114
+ (isNaN(+value) || +value < 1)) {
115
+ if (DOMProperty.mustUseAttribute[name]) {
116
+ node.removeAttribute(DOMProperty.getAttributeName[name]);
117
+ } else {
118
+ var propName = DOMProperty.getPropertyName[name];
119
+ value = DOMProperty.getDefaultValueForProperty(
120
+ node.nodeName,
121
+ name
122
+ );
123
+ if (!DOMProperty.hasSideEffects[name] ||
124
+ node[propName] !== value) {
125
+ node[propName] = value;
126
+ }
127
+ }
128
+ } else if (DOMProperty.mustUseAttribute[name]) {
129
+ node.setAttribute(DOMProperty.getAttributeName[name], '' + value);
130
+ } else {
131
+ var propName = DOMProperty.getPropertyName[name];
132
+ if (!DOMProperty.hasSideEffects[name] ||
133
+ node[propName] !== value) {
134
+ node[propName] = value;
135
+ }
136
}
137
}
138
} else if (DOMProperty.isCustomAttribute(name)) {
120
- node.setAttribute(name, '' + value);
139
+ if (value == null) {
140
+ node.removeAttribute(DOMProperty.getAttributeName[name]);
141
+ } else {
142
+ node.setAttribute(name, '' + value);
143
+ }
144
} else if (__DEV__) {
145
warnUnknownProperty(name);
146
}