@samitouri / QOS-React-2 / commits / e060eabb01

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 }