Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download
81159 views
1
/**
2
* Copyright 2013-2014, Facebook, Inc.
3
* All rights reserved.
4
*
5
* This source code is licensed under the BSD-style license found in the
6
* LICENSE file in the root directory of this source tree. An additional grant
7
* of patent rights can be found in the PATENTS file in the same directory.
8
*
9
* @providesModule DOMPropertyOperations
10
* @typechecks static-only
11
*/
12
13
"use strict";
14
15
var DOMProperty = require('DOMProperty');
16
17
var escapeTextForBrowser = require('escapeTextForBrowser');
18
var memoizeStringOnly = require('memoizeStringOnly');
19
var warning = require('warning');
20
21
function shouldIgnoreValue(name, value) {
22
return value == null ||
23
(DOMProperty.hasBooleanValue[name] && !value) ||
24
(DOMProperty.hasNumericValue[name] && isNaN(value)) ||
25
(DOMProperty.hasPositiveNumericValue[name] && (value < 1)) ||
26
(DOMProperty.hasOverloadedBooleanValue[name] && value === false);
27
}
28
29
var processAttributeNameAndPrefix = memoizeStringOnly(function(name) {
30
return escapeTextForBrowser(name) + '="';
31
});
32
33
if (__DEV__) {
34
var reactProps = {
35
children: true,
36
dangerouslySetInnerHTML: true,
37
key: true,
38
ref: true
39
};
40
var warnedProperties = {};
41
42
var warnUnknownProperty = function(name) {
43
if (reactProps.hasOwnProperty(name) && reactProps[name] ||
44
warnedProperties.hasOwnProperty(name) && warnedProperties[name]) {
45
return;
46
}
47
48
warnedProperties[name] = true;
49
var lowerCasedName = name.toLowerCase();
50
51
// data-* attributes should be lowercase; suggest the lowercase version
52
var standardName = (
53
DOMProperty.isCustomAttribute(lowerCasedName) ?
54
lowerCasedName :
55
DOMProperty.getPossibleStandardName.hasOwnProperty(lowerCasedName) ?
56
DOMProperty.getPossibleStandardName[lowerCasedName] :
57
null
58
);
59
60
// For now, only warn when we have a suggested correction. This prevents
61
// logging too much when using transferPropsTo.
62
warning(
63
standardName == null,
64
'Unknown DOM property ' + name + '. Did you mean ' + standardName + '?'
65
);
66
67
};
68
}
69
70
/**
71
* Operations for dealing with DOM properties.
72
*/
73
var DOMPropertyOperations = {
74
75
/**
76
* Creates markup for the ID property.
77
*
78
* @param {string} id Unescaped ID.
79
* @return {string} Markup string.
80
*/
81
createMarkupForID: function(id) {
82
return processAttributeNameAndPrefix(DOMProperty.ID_ATTRIBUTE_NAME) +
83
escapeTextForBrowser(id) + '"';
84
},
85
86
/**
87
* Creates markup for a property.
88
*
89
* @param {string} name
90
* @param {*} value
91
* @return {?string} Markup string, or null if the property was invalid.
92
*/
93
createMarkupForProperty: function(name, value) {
94
if (DOMProperty.isStandardName.hasOwnProperty(name) &&
95
DOMProperty.isStandardName[name]) {
96
if (shouldIgnoreValue(name, value)) {
97
return '';
98
}
99
var attributeName = DOMProperty.getAttributeName[name];
100
if (DOMProperty.hasBooleanValue[name] ||
101
(DOMProperty.hasOverloadedBooleanValue[name] && value === true)) {
102
return escapeTextForBrowser(attributeName);
103
}
104
return processAttributeNameAndPrefix(attributeName) +
105
escapeTextForBrowser(value) + '"';
106
} else if (DOMProperty.isCustomAttribute(name)) {
107
if (value == null) {
108
return '';
109
}
110
return processAttributeNameAndPrefix(name) +
111
escapeTextForBrowser(value) + '"';
112
} else if (__DEV__) {
113
warnUnknownProperty(name);
114
}
115
return null;
116
},
117
118
/**
119
* Sets the value for a property on a node.
120
*
121
* @param {DOMElement} node
122
* @param {string} name
123
* @param {*} value
124
*/
125
setValueForProperty: function(node, name, value) {
126
if (DOMProperty.isStandardName.hasOwnProperty(name) &&
127
DOMProperty.isStandardName[name]) {
128
var mutationMethod = DOMProperty.getMutationMethod[name];
129
if (mutationMethod) {
130
mutationMethod(node, value);
131
} else if (shouldIgnoreValue(name, value)) {
132
this.deleteValueForProperty(node, name);
133
} else if (DOMProperty.mustUseAttribute[name]) {
134
// `setAttribute` with objects becomes only `[object]` in IE8/9,
135
// ('' + value) makes it output the correct toString()-value.
136
node.setAttribute(DOMProperty.getAttributeName[name], '' + value);
137
} else {
138
var propName = DOMProperty.getPropertyName[name];
139
// Must explicitly cast values for HAS_SIDE_EFFECTS-properties to the
140
// property type before comparing; only `value` does and is string.
141
if (!DOMProperty.hasSideEffects[name] ||
142
('' + node[propName]) !== ('' + value)) {
143
// Contrary to `setAttribute`, object properties are properly
144
// `toString`ed by IE8/9.
145
node[propName] = value;
146
}
147
}
148
} else if (DOMProperty.isCustomAttribute(name)) {
149
if (value == null) {
150
node.removeAttribute(name);
151
} else {
152
node.setAttribute(name, '' + value);
153
}
154
} else if (__DEV__) {
155
warnUnknownProperty(name);
156
}
157
},
158
159
/**
160
* Deletes the value for a property on a node.
161
*
162
* @param {DOMElement} node
163
* @param {string} name
164
*/
165
deleteValueForProperty: function(node, name) {
166
if (DOMProperty.isStandardName.hasOwnProperty(name) &&
167
DOMProperty.isStandardName[name]) {
168
var mutationMethod = DOMProperty.getMutationMethod[name];
169
if (mutationMethod) {
170
mutationMethod(node, undefined);
171
} else if (DOMProperty.mustUseAttribute[name]) {
172
node.removeAttribute(DOMProperty.getAttributeName[name]);
173
} else {
174
var propName = DOMProperty.getPropertyName[name];
175
var defaultValue = DOMProperty.getDefaultValueForProperty(
176
node.nodeName,
177
propName
178
);
179
if (!DOMProperty.hasSideEffects[name] ||
180
('' + node[propName]) !== defaultValue) {
181
node[propName] = defaultValue;
182
}
183
}
184
} else if (DOMProperty.isCustomAttribute(name)) {
185
node.removeAttribute(name);
186
} else if (__DEV__) {
187
warnUnknownProperty(name);
188
}
189
}
190
191
};
192
193
module.exports = DOMPropertyOperations;
194
195