Skip to content

Commit 076a97a

Browse files
committed
Support arbitrary attributes on elements with dashes in the tag name.
1 parent c7e4f55 commit 076a97a

File tree

3 files changed

+60
-3
lines changed

3 files changed

+60
-3
lines changed

src/browser/ui/ReactDOMComponent.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -235,7 +235,7 @@ ReactDOMComponent.Mixin = {
235235
propValue = CSSPropertyOperations.createMarkupForStyles(propValue);
236236
}
237237
var markup =
238-
DOMPropertyOperations.createMarkupForProperty(propKey, propValue);
238+
DOMPropertyOperations.createMarkupForProperty(this._tag, propKey, propValue);
239239
if (markup) {
240240
ret += ' ' + markup;
241241
}

src/browser/ui/dom/DOMPropertyOperations.js

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,11 +84,12 @@ var DOMPropertyOperations = {
8484
/**
8585
* Creates markup for a property.
8686
*
87+
* @param {string} tagName
8788
* @param {string} name
8889
* @param {*} value
8990
* @return {?string} Markup string, or null if the property was invalid.
9091
*/
91-
createMarkupForProperty: function(name, value) {
92+
createMarkupForProperty: function(tagName, name, value) {
9293
if (DOMProperty.isStandardName.hasOwnProperty(name) &&
9394
DOMProperty.isStandardName[name]) {
9495
if (shouldIgnoreValue(name, value)) {
@@ -105,6 +106,11 @@ var DOMPropertyOperations = {
105106
return '';
106107
}
107108
return name + '=' + quoteAttributeValueForBrowser(value);
109+
} else if (tagName != null && tagName.indexOf('-') >= 0) {
110+
if (value == null) {
111+
return '';
112+
}
113+
return name + '=' + quoteAttributeValueForBrowser(value);
108114
} else if (__DEV__) {
109115
warnUnknownProperty(name);
110116
}
@@ -119,7 +125,14 @@ var DOMPropertyOperations = {
119125
* @param {*} value
120126
*/
121127
setValueForProperty: function(node, name, value) {
122-
if (DOMProperty.isStandardName.hasOwnProperty(name) &&
128+
if (node.tagName.indexOf('-') >= 0) {
129+
if (value == null) {
130+
node.removeAttribute(name);
131+
} else {
132+
node.setAttribute(name, '' + value);
133+
}
134+
}
135+
else if (DOMProperty.isStandardName.hasOwnProperty(name) &&
123136
DOMProperty.isStandardName[name]) {
124137
var mutationMethod = DOMProperty.getMutationMethod[name];
125138
if (mutationMethod) {

src/browser/ui/dom/__tests__/DOMPropertyOperations-test.js

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,23 +32,27 @@ describe('DOMPropertyOperations', function() {
3232

3333
it('should create markup for simple properties', function() {
3434
expect(DOMPropertyOperations.createMarkupForProperty(
35+
'div',
3536
'name',
3637
'simple'
3738
)).toBe('name="simple"');
3839

3940
expect(DOMPropertyOperations.createMarkupForProperty(
41+
'div',
4042
'name',
4143
false
4244
)).toBe('name="false"');
4345

4446
expect(DOMPropertyOperations.createMarkupForProperty(
47+
'div',
4548
'name',
4649
null
4750
)).toBe('');
4851
});
4952

5053
it('should work with the id attribute', function() {
5154
expect(DOMPropertyOperations.createMarkupForProperty(
55+
'div',
5256
'id',
5357
'simple'
5458
)).toBe('id="simple"');
@@ -57,6 +61,7 @@ describe('DOMPropertyOperations', function() {
5761
it('should warn about incorrect casing', function() {
5862
spyOn(console, 'warn');
5963
expect(DOMPropertyOperations.createMarkupForProperty(
64+
'div',
6065
'tabindex',
6166
'1'
6267
)).toBe(null);
@@ -67,6 +72,7 @@ describe('DOMPropertyOperations', function() {
6772
it('should warn about class', function() {
6873
spyOn(console, 'warn');
6974
expect(DOMPropertyOperations.createMarkupForProperty(
75+
'div',
7076
'class',
7177
'muffins'
7278
)).toBe(null);
@@ -76,102 +82,134 @@ describe('DOMPropertyOperations', function() {
7682

7783
it('should create markup for boolean properties', function() {
7884
expect(DOMPropertyOperations.createMarkupForProperty(
85+
'div',
7986
'checked',
8087
'simple'
8188
)).toBe('checked');
8289

8390
expect(DOMPropertyOperations.createMarkupForProperty(
91+
'div',
8492
'checked',
8593
true
8694
)).toBe('checked');
8795

8896
expect(DOMPropertyOperations.createMarkupForProperty(
97+
'div',
8998
'checked',
9099
false
91100
)).toBe('');
92101
});
93102

94103
it('should create markup for booleanish properties', function() {
95104
expect(DOMPropertyOperations.createMarkupForProperty(
105+
'div',
96106
'download',
97107
'simple'
98108
)).toBe('download="simple"');
99109

100110
expect(DOMPropertyOperations.createMarkupForProperty(
111+
'div',
101112
'download',
102113
true
103114
)).toBe('download');
104115

105116
expect(DOMPropertyOperations.createMarkupForProperty(
117+
'div',
106118
'download',
107119
'true'
108120
)).toBe('download="true"');
109121

110122
expect(DOMPropertyOperations.createMarkupForProperty(
123+
'div',
111124
'download',
112125
false
113126
)).toBe('');
114127

115128
expect(DOMPropertyOperations.createMarkupForProperty(
129+
'div',
116130
'download',
117131
'false'
118132
)).toBe('download="false"');
119133

120134
expect(DOMPropertyOperations.createMarkupForProperty(
135+
'div',
121136
'download',
122137
undefined
123138
)).toBe('');
124139

125140
expect(DOMPropertyOperations.createMarkupForProperty(
141+
'div',
126142
'download',
127143
null
128144
)).toBe('');
129145

130146
expect(DOMPropertyOperations.createMarkupForProperty(
147+
'div',
131148
'download',
132149
0
133150
)).toBe('download="0"');
134151
});
135152

136153
it('should create markup for custom attributes', function() {
137154
expect(DOMPropertyOperations.createMarkupForProperty(
155+
'div',
138156
'aria-label',
139157
'simple'
140158
)).toBe('aria-label="simple"');
141159

142160
expect(DOMPropertyOperations.createMarkupForProperty(
161+
'div',
143162
'aria-label',
144163
false
145164
)).toBe('aria-label="false"');
146165

147166
expect(DOMPropertyOperations.createMarkupForProperty(
167+
'div',
148168
'aria-label',
149169
null
150170
)).toBe('');
151171
});
152172

153173
it('should create markup for numeric properties', function() {
154174
expect(DOMPropertyOperations.createMarkupForProperty(
175+
'div',
155176
'start',
156177
5
157178
)).toBe('start="5"');
158179

159180
expect(DOMPropertyOperations.createMarkupForProperty(
181+
'div',
160182
'start',
161183
0
162184
)).toBe('start="0"');
163185

164186
expect(DOMPropertyOperations.createMarkupForProperty(
187+
'div',
165188
'size',
166189
0
167190
)).toBe('');
168191

169192
expect(DOMPropertyOperations.createMarkupForProperty(
193+
'div',
170194
'size',
171195
1
172196
)).toBe('size="1"');
173197
});
174198

199+
it('should allow custom properties on web components', function() {
200+
expect(DOMPropertyOperations.createMarkupForProperty(
201+
'x-my-webcomponent',
202+
'awesomeness',
203+
5
204+
)).toBe('awesomeness="5"');
205+
206+
expect(DOMPropertyOperations.createMarkupForProperty(
207+
'x-my-webcomponent',
208+
'dev',
209+
'jim'
210+
)).toBe('dev="jim"');
211+
});
212+
175213
});
176214

177215
describe('setValueForProperty', function() {
@@ -296,12 +334,14 @@ describe('DOMPropertyOperations', function() {
296334
it('should support custom attributes', function() {
297335
// foobar does not exist yet
298336
expect(DOMPropertyOperations.createMarkupForProperty(
337+
'div',
299338
'foobar',
300339
'simple'
301340
)).toBe(null);
302341

303342
// foo-* does not exist yet
304343
expect(DOMPropertyOperations.createMarkupForProperty(
344+
'div',
305345
'foo-xyz',
306346
'simple'
307347
)).toBe(null);
@@ -316,22 +356,26 @@ describe('DOMPropertyOperations', function() {
316356

317357
// Ensure old attributes still work
318358
expect(DOMPropertyOperations.createMarkupForProperty(
359+
'div',
319360
'name',
320361
'simple'
321362
)).toBe('name="simple"');
322363
expect(DOMPropertyOperations.createMarkupForProperty(
364+
'div',
323365
'data-name',
324366
'simple'
325367
)).toBe('data-name="simple"');
326368

327369
// foobar should work
328370
expect(DOMPropertyOperations.createMarkupForProperty(
371+
'div',
329372
'foobar',
330373
'simple'
331374
)).toBe('foobar="simple"');
332375

333376
// foo-* should work
334377
expect(DOMPropertyOperations.createMarkupForProperty(
378+
'div',
335379
'foo-xyz',
336380
'simple'
337381
)).toBe('foo-xyz="simple"');

0 commit comments

Comments
 (0)