Shortened generated "data-reactid"
Andreas Svensson committed
Jan 18, 2014 at 03:06 UTC
559cd46181a80bb9519e3359f4d9c6745bd3a36c
10 files changed
+101
-73
src/addons/transitions/__tests__/ReactTransitionKeySet-test.js
+4
-4
@@ -36,8 +36,8 @@ describe('ReactTransitionKeySet', function() {
36
var component = <div>{one}{two}</div>;
37
expect(ReactTransitionKeySet.getChildMapping(component.props.children))
38
.toEqual({
39
- '{one}': one,
40
- '{two}': two
39
+ '.$one': one,
40
+ '.$two': two
41
});
42
});
43
@@ -48,8 +48,8 @@ describe('ReactTransitionKeySet', function() {
48
var two = <div key="two" />;
49
var component = <div>{one}{two}</div>;
50
expect(ReactTransitionKeySet.getKeySet(component.props.children)).toEqual({
51
- '{one}': true,
52
- '{two}': true
51
+ '.$one': true,
52
+ '.$two': true
53
});
54
});
55
src/core/ReactInstanceHandles.js
+7
-4
@@ -39,7 +39,7 @@ var MAX_TREE_DEPTH = 100;
39
* @internal
40
*/
41
function getReactRootIDString(index) {
42
- return SEPARATOR + 'r[' + index.toString(36) + ']';
42
+ return SEPARATOR + index.toString(36);
43
}
44
45
/**
@@ -241,7 +241,7 @@ var ReactInstanceHandles = {
241
* @internal
242
*/
243
createReactID: function(rootID, name) {
244
- return rootID + SEPARATOR + name;
244
+ return rootID + name;
245
},
246
247
/**
@@ -253,8 +253,11 @@ var ReactInstanceHandles = {
253
* @internal
254
*/
255
getReactRootIDFromNodeID: function(id) {
256
- var regexResult = /\.r\[[^\]]+\]/.exec(id);
257
- return regexResult && regexResult[0];
256
+ if (id && id.charAt(0) === SEPARATOR && id.length > 1) {
257
+ var index = id.indexOf(SEPARATOR, 1);
258
+ return index > -1 ? id.substr(0, index) : id;
259
+ }
260
+ return null;
261
},
262
263
/**
src/core/ReactMultiChild.js
+2
-2
@@ -193,7 +193,7 @@ var ReactMultiChild = {
193
var child = children[name];
194
if (children.hasOwnProperty(name)) {
195
// Inlined for performance, see `ReactInstanceHandles.createReactID`.
196
- var rootID = this._rootNodeID + '.' + name;
196
+ var rootID = this._rootNodeID + name;
197
var mountImage = child.mountComponent(
198
rootID,
199
transaction,
@@ -385,7 +385,7 @@ var ReactMultiChild = {
385
*/
386
_mountChildByNameAtIndex: function(child, name, index, transaction) {
387
// Inlined for performance, see `ReactInstanceHandles.createReactID`.
388
- var rootID = this._rootNodeID + '.' + name;
388
+ var rootID = this._rootNodeID + name;
389
var mountImage = child.mountComponent(
390
rootID,
391
transaction,
src/core/__tests__/ReactIdentity-test.js
+17
-15
@@ -34,7 +34,7 @@ describe('ReactIdentity', function() {
34
ReactMount = require('ReactMount');
35
});
36
37
- var idExp = /^\.r\[.+?\](.*)$/;
37
+ var idExp = /^\.[^.]+(.*)$/;
38
function checkId(child, expectedId) {
39
var actual = idExp.exec(ReactMount.getID(child));
40
var expected = idExp.exec(expectedId);
@@ -55,8 +55,8 @@ describe('ReactIdentity', function() {
55
React.renderComponent(instance, document.createElement('div'));
56
var node = instance.getDOMNode();
57
reactComponentExpect(instance).toBeDOMComponentWithChildCount(2);
58
- checkId(node.childNodes[0], '.r[0].{first}[0]');
59
- checkId(node.childNodes[1], '.r[0].{second}[0]');
58
+ checkId(node.childNodes[0], '.0.$first:0');
59
+ checkId(node.childNodes[1], '.0.$second:0');
60
});
61
62
it('should allow key property to express identity', function() {
@@ -71,10 +71,10 @@ describe('ReactIdentity', function() {
71
React.renderComponent(instance, document.createElement('div'));
72
var node = instance.getDOMNode();
73
reactComponentExpect(instance).toBeDOMComponentWithChildCount(4);
74
- checkId(node.childNodes[0], '.r[0].{apple}');
75
- checkId(node.childNodes[1], '.r[0].{banana}');
76
- checkId(node.childNodes[2], '.r[0].{0}');
77
- checkId(node.childNodes[3], '.r[0].{123}');
74
+ checkId(node.childNodes[0], '.0.$apple');
75
+ checkId(node.childNodes[1], '.0.$banana');
76
+ checkId(node.childNodes[2], '.0.$0');
77
+ checkId(node.childNodes[3], '.0.$123');
78
});
79
80
it('should use instance identity', function() {
@@ -96,12 +96,12 @@ describe('ReactIdentity', function() {
96
var node = instance.getDOMNode();
97
reactComponentExpect(instance).toBeDOMComponentWithChildCount(3);
98
99
- checkId(node.childNodes[0], '.r[0].{wrap1}');
100
- checkId(node.childNodes[0].firstChild, '.r[0].{wrap1}.{squirrel}');
101
- checkId(node.childNodes[1], '.r[0].{wrap2}');
102
- checkId(node.childNodes[1].firstChild, '.r[0].{wrap2}.{bunny}');
103
- checkId(node.childNodes[2], '.r[0].[2]');
104
- checkId(node.childNodes[2].firstChild, '.r[0].[2].{chipmunk}');
99
+ checkId(node.childNodes[0], '.0.$wrap1');
100
+ checkId(node.childNodes[0].firstChild, '.0.$wrap1.$squirrel');
101
+ checkId(node.childNodes[1], '.0.$wrap2');
102
+ checkId(node.childNodes[1].firstChild, '.0.$wrap2.$bunny');
103
+ checkId(node.childNodes[2], '.0.2');
104
+ checkId(node.childNodes[2].firstChild, '.0.2.$chipmunk');
105
});
106
107
function renderAComponentWithKeyIntoContainer(key, container) {
@@ -116,8 +116,10 @@ describe('ReactIdentity', function() {
116
expect(span1.getDOMNode()).not.toBe(null);
117
expect(span2.getDOMNode()).not.toBe(null);
118
119
- checkId(span1.getDOMNode(), '.r[0].{' + key + '}');
120
- checkId(span2.getDOMNode(), '.r[0].[1]{' + key + '}[0]');
119
+ key = key.replace(/=/g, '=0');
120
+
121
+ checkId(span1.getDOMNode(), '.0.$' + key);
122
+ checkId(span2.getDOMNode(), '.0.1:$' + key + ':0');
123
}
124
125
it('should allow any character as a key, in a detached parent', function() {
src/core/__tests__/ReactInstanceHandles-test.js
+14
-2
@@ -154,13 +154,25 @@ describe('ReactInstanceHandles', function() {
154
155
describe('getReactRootIDFromNodeID', function() {
156
it('should support strings', function() {
157
- var test = '.r[s_0_1][0]..[1]';
158
- var expected = '.r[s_0_1]';
157
+ var test = '.s_0_1.0..1';
158
+ var expected = '.s_0_1';
159
var actual = ReactInstanceHandles.getReactRootIDFromNodeID(test);
160
expect(actual).toEqual(expected);
161
});
162
});
163
164
+ describe('getReactRootIDFromNodeID', function() {
165
+ it('should return null for invalid IDs', function() {
166
+ var getReactRootIDFromNodeID = (
167
+ ReactInstanceHandles.getReactRootIDFromNodeID
168
+ );
169
+
170
+ expect(getReactRootIDFromNodeID(null)).toEqual(null);
171
+ expect(getReactRootIDFromNodeID('.')).toEqual(null);
172
+ expect(getReactRootIDFromNodeID('#')).toEqual(null);
173
+ });
174
+ });
175
+
176
describe('traverseTwoPhase', function() {
177
it("should not traverse when traversing outside DOM", function() {
178
var targetID = '';
src/core/__tests__/ReactMultiChildReconcile-test.js
+3
-1
@@ -46,7 +46,9 @@ var stripEmptyValues = function(obj) {
46
* here. This relies on an implementation detail of the rendering system.
47
*/
48
var getOriginalKey = function(childName) {
49
- return childName.slice('{'.length, childName.length - '}[0]'.length);
49
+ var match = childName.match(/^\.\$([^.]+)\:0$/);
50
+ expect(match).not.toBeNull();
51
+ return match[1];
52
};
53
54
/**
src/utils/__tests__/ReactChildren-test.js
+11
-11
@@ -92,7 +92,7 @@ describe('ReactChildren', function() {
92
expect(mappedKeys.length).toBe(1);
93
expect(mappedChildren[mappedKeys[0]]).not.toBe(simpleKid);
94
expect(mappedChildren[mappedKeys[0]].props.children).toBe(simpleKid);
95
- expect(mappedKeys[0]).toBe('{simple}');
95
+ expect(mappedKeys[0]).toBe('.$simple');
96
});
97
98
it('should invoke callback with the right context', function() {
@@ -162,7 +162,7 @@ describe('ReactChildren', function() {
162
expect(mappedKeys.length).toBe(5);
163
// Keys default to indices.
164
expect(mappedKeys).toEqual(
165
- ['{keyZero}', '[1]', '{keyTwo}', '[3]', '{keyFour}']
165
+ ['.$keyZero', '.1', '.$keyTwo', '.3', '.$keyFour']
166
);
167
168
expect(callback).toHaveBeenCalledWith(zero, 0);
@@ -235,12 +235,12 @@ describe('ReactChildren', function() {
235
expect(mappedKeys.length).toBe(6);
236
// Keys default to indices.
237
expect(mappedKeys).toEqual([
238
- '[0]{firstHalfKey}[0]{keyZero}',
239
- '[0]{firstHalfKey}[0][1]',
240
- '[0]{firstHalfKey}[0]{keyTwo}',
241
- '[0]{secondHalfKey}[0][0]',
242
- '[0]{secondHalfKey}[0]{keyFour}',
243
- '[0]{keyFive}{keyFiveInner}'
238
+ '.0:$firstHalfKey:0:$keyZero',
239
+ '.0:$firstHalfKey:0:1',
240
+ '.0:$firstHalfKey:0:$keyTwo',
241
+ '.0:$secondHalfKey:0:0',
242
+ '.0:$secondHalfKey:0:$keyFour',
243
+ '.0:$keyFive:$keyFiveInner'
244
]);
245
246
expect(callback).toHaveBeenCalledWith(zero, 0);
@@ -282,15 +282,15 @@ describe('ReactChildren', function() {
282
</div>
283
);
284
285
- var expectedForcedKeys = ['{keyZero}', '{keyOne}'];
285
+ var expectedForcedKeys = ['.$keyZero', '.$keyOne'];
286
var mappedChildrenForcedKeys =
287
ReactChildren.map(forcedKeys.props.children, mapFn);
288
var mappedForcedKeys = Object.keys(mappedChildrenForcedKeys);
289
expect(mappedForcedKeys).toEqual(expectedForcedKeys);
290
291
var expectedRemappedForcedKeys = [
292
- '{{keyZero^C}{giraffe}',
293
- '{{keyOne^C}[0]'
292
+ '.$=1$keyZero:$giraffe',
293
+ '.$=1$keyOne:0'
294
];
295
var remappedChildrenForcedKeys =
296
ReactChildren.map(mappedChildrenForcedKeys, mapFn);
src/utils/__tests__/sliceChildren-test.js
+7
-7
@@ -68,9 +68,9 @@ describe('sliceChildren', function() {
68
];
69
var children = renderAndSlice(fullSet, 0);
70
expect(children).toEqual({
71
- '{A}': fullSet[0],
72
- '{B}': fullSet[1],
73
- '{C}': fullSet[2]
71
+ '.$A': fullSet[0],
72
+ '.$B': fullSet[1],
73
+ '.$C': fullSet[2]
74
});
75
});
76
@@ -82,8 +82,8 @@ describe('sliceChildren', function() {
82
];
83
var children = renderAndSlice(fullSet, 1);
84
expect(children).toEqual({
85
- '{B}': fullSet[1],
86
- '{C}': fullSet[2]
85
+ '.$B': fullSet[1],
86
+ '.$C': fullSet[2]
87
});
88
});
89
@@ -96,7 +96,7 @@ describe('sliceChildren', function() {
96
];
97
var children = renderAndSlice(fullSet, 1, 2);
98
expect(children).toEqual({
99
- '{B}': fullSet[1]
99
+ '.$B': fullSet[1]
100
});
101
});
102
@@ -112,7 +112,7 @@ describe('sliceChildren', function() {
112
.instance();
113
114
expect(rendered.props.children).toEqual({
115
- '[1]': b
115
+ '.1': b
116
});
117
});
118
src/utils/__tests__/traverseAllChildren-test.js
+16
-16
@@ -43,7 +43,7 @@ describe('traverseAllChildren', function() {
43
expect(traverseFn).toHaveBeenCalledWith(
44
traverseContext,
45
simpleKid,
46
- '{simple}',
46
+ '.$simple',
47
0
48
);
49
expect(traverseContext.length).toEqual(1);
@@ -62,7 +62,7 @@ describe('traverseAllChildren', function() {
62
expect(traverseFn).toHaveBeenCalledWith(
63
traverseContext,
64
simpleKid,
65
- '[0]',
65
+ '.0',
66
0
67
);
68
expect(traverseContext.length).toEqual(1);
@@ -81,7 +81,7 @@ describe('traverseAllChildren', function() {
81
expect(traverseFn).toHaveBeenCalledWith(
82
traverseContext,
83
simpleKid,
84
- '[0]',
84
+ '.0',
85
0
86
);
87
expect(traverseContext.length).toEqual(1);
@@ -114,21 +114,21 @@ describe('traverseAllChildren', function() {
114
expect(traverseFn).toHaveBeenCalledWith(
115
traverseContext,
116
zero,
117
- '{keyZero}',
117
+ '.$keyZero',
118
0
119
);
120
- expect(traverseFn).toHaveBeenCalledWith(traverseContext, one, '[1]', 1);
120
+ expect(traverseFn).toHaveBeenCalledWith(traverseContext, one, '.1', 1);
121
expect(traverseFn).toHaveBeenCalledWith(
122
traverseContext,
123
two,
124
- '{keyTwo}',
124
+ '.$keyTwo',
125
2
126
);
127
- expect(traverseFn).toHaveBeenCalledWith(traverseContext, three, '[3]', 3);
127
+ expect(traverseFn).toHaveBeenCalledWith(traverseContext, three, '.3', 3);
128
expect(traverseFn).toHaveBeenCalledWith(
129
traverseContext,
130
four,
131
- '{keyFour}',
131
+ '.$keyFour',
132
4
133
);
134
});
@@ -171,38 +171,38 @@ describe('traverseAllChildren', function() {
171
expect(traverseFn).toHaveBeenCalledWith(
172
traverseContext,
173
zero,
174
- '[0]{firstHalfKey}[0]{keyZero}',
174
+ '.0:$firstHalfKey:0:$keyZero',
175
0
176
);
177
178
expect(traverseFn)
179
- .toHaveBeenCalledWith(traverseContext, one, '[0]{firstHalfKey}[0][1]', 1);
179
+ .toHaveBeenCalledWith(traverseContext, one, '.0:$firstHalfKey:0:1', 1);
180
181
expect(traverseFn).toHaveBeenCalledWith(
182
traverseContext,
183
two,
184
- '[0]{firstHalfKey}[0]{keyTwo}',
184
+ '.0:$firstHalfKey:0:$keyTwo',
185
2
186
);
187
188
expect(traverseFn).toHaveBeenCalledWith(
189
traverseContext,
190
three,
191
- '[0]{secondHalfKey}[0][0]',
191
+ '.0:$secondHalfKey:0:0',
192
3
193
);
194
195
expect(traverseFn).toHaveBeenCalledWith(
196
traverseContext,
197
four,
198
- '[0]{secondHalfKey}[0]{keyFour}',
198
+ '.0:$secondHalfKey:0:$keyFour',
199
4
200
);
201
202
expect(traverseFn).toHaveBeenCalledWith(
203
traverseContext,
204
five,
205
- '[0]{keyFive}{keyFiveInner}',
205
+ '.0:$keyFive:$keyFiveInner',
206
5
207
);
208
});
@@ -228,13 +228,13 @@ describe('traverseAllChildren', function() {
228
expect(traverseFn).toHaveBeenCalledWith(
229
traverseContext,
230
zeroForceKey,
231
- '{keyZero}',
231
+ '.$keyZero',
232
0
233
);
234
expect(traverseFn).toHaveBeenCalledWith(
235
traverseContext,
236
oneForceKey,
237
- '{keyOne}',
237
+ '.$keyOne',
238
1
239
);
240
});
src/utils/traverseAllChildren.js
+20
-11
@@ -18,10 +18,14 @@
18
19
"use strict";
20
21
+var ReactInstanceHandles = require('ReactInstanceHandles');
22
var ReactTextComponent = require('ReactTextComponent');
23
24
var invariant = require('invariant');
25
26
+var SEPARATOR = ReactInstanceHandles.SEPARATOR;
27
+var SUBSEPARATOR = ':';
28
+
29
/**
30
* TODO: Test that:
31
* 1. `mapChildren` transforms strings and numbers into `ReactTextComponent`.
@@ -31,12 +35,12 @@ var invariant = require('invariant');
35
*/
36
37
var userProvidedKeyEscaperLookup = {
34
- '^': '^X',
35
- '.': '^D',
36
- '}': '^C'
38
+ '=': '=0',
39
+ '.': '=1',
40
+ ':': '=2'
41
};
42
39
-var userProvidedKeyEscapeRegex = /[.^}]/g;
43
+var userProvidedKeyEscapeRegex = /[=.:]/g;
44
45
function userProvidedKeyEscaper(match) {
46
return userProvidedKeyEscaperLookup[match];
@@ -55,7 +59,7 @@ function getComponentKey(component, index) {
59
return wrapUserProvidedKey(component.props.key);
60
}
61
// Implicit key determined by the index in the set
58
- return '[' + index + ']';
62
+ return index.toString(36);
63
}
64
65
/**
@@ -79,7 +83,7 @@ function escapeUserProvidedKey(text) {
83
* @return {string}
84
*/
85
function wrapUserProvidedKey(key) {
82
- return '{' + escapeUserProvidedKey(key) + '}';
86
+ return '$' + escapeUserProvidedKey(key);
87
}
88
89
/**
@@ -97,7 +101,11 @@ var traverseAllChildrenImpl =
101
if (Array.isArray(children)) {
102
for (var i = 0; i < children.length; i++) {
103
var child = children[i];
100
- var nextName = nameSoFar + getComponentKey(child, i);
104
+ var nextName = (
105
+ nameSoFar +
106
+ (nameSoFar ? SUBSEPARATOR : SEPARATOR) +
107
+ getComponentKey(child, i)
108
+ );
109
var nextIndex = indexSoFar + subtreeCount;
110
subtreeCount += traverseAllChildrenImpl(
111
child,
@@ -112,8 +120,9 @@ var traverseAllChildrenImpl =
120
var isOnlyChild = nameSoFar === '';
121
// If it's the only child, treat the name as if it was wrapped in an array
122
// so that it's consistent if the number of children grows
115
- var storageName = isOnlyChild ? getComponentKey(children, 0) : nameSoFar;
116
- if (children === null || children === undefined || type === 'boolean') {
123
+ var storageName =
124
+ isOnlyChild ? SEPARATOR + getComponentKey(children, 0) : nameSoFar;
125
+ if (children == null || type === 'boolean') {
126
// All of the above are perceived as null.
127
callback(traverseContext, null, storageName, indexSoFar);
128
subtreeCount = 1;
@@ -132,8 +141,8 @@ var traverseAllChildrenImpl =
141
subtreeCount += traverseAllChildrenImpl(
142
children[key],
143
(
135
- nameSoFar +
136
- wrapUserProvidedKey(key) +
144
+ nameSoFar + (nameSoFar ? SUBSEPARATOR : SEPARATOR) +
145
+ wrapUserProvidedKey(key) + SUBSEPARATOR +
146
getComponentKey(children[key], 0)
147
),
148
indexSoFar + subtreeCount,