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

Implement stricter whitespace rules

Andreas Svensson committed Dec 4, 2013 at 22:55 UTC c16b5659a0323572b2cd404f6356c7b38e38b038
3 files changed +64 -119
src/core/__tests__/ReactRenderDocument-test.js
+5 -5
@@ -67,7 +67,7 @@ describe('rendering React components at document', function() {
67 React.renderComponentToString(<Root />, function(markup) {
68 testDocument = getTestDocument(markup);
69 var component = React.renderComponent(<Root />, testDocument);
70 - expect(testDocument.body.innerHTML).toBe(' Hello world ');
70 + expect(testDocument.body.innerHTML).toBe('Hello world');
71
72 var componentID = ReactMount.getReactRootID(testDocument);
73 expect(componentID).toBe(component._rootNodeID);
@@ -95,13 +95,13 @@ describe('rendering React components at document', function() {
95 React.renderComponentToString(<Root />, function(markup) {
96 testDocument = getTestDocument(markup);
97 React.renderComponent(<Root />, testDocument);
98 - expect(testDocument.body.innerHTML).toBe(' Hello world ');
98 + expect(testDocument.body.innerHTML).toBe('Hello world');
99
100 expect(function() {
101 React.unmountComponentAtNode(testDocument);
102 }).toThrow(UNMOUNT_INVARIANT_MESSAGE);
103
104 - expect(testDocument.body.innerHTML).toBe(' Hello world ');
104 + expect(testDocument.body.innerHTML).toBe('Hello world');
105 });
106 });
107
@@ -143,14 +143,14 @@ describe('rendering React components at document', function() {
143
144 React.renderComponent(<Component />, testDocument);
145
146 - expect(testDocument.body.innerHTML).toBe(' Hello world ');
146 + expect(testDocument.body.innerHTML).toBe('Hello world');
147
148 // Reactive update
149 expect(function() {
150 React.renderComponent(<Component2 />, testDocument);
151 }).toThrow(UNMOUNT_INVARIANT_MESSAGE);
152
153 - expect(testDocument.body.innerHTML).toBe(' Hello world ');
153 + expect(testDocument.body.innerHTML).toBe('Hello world');
154 });
155 });
156
vendor/fbtransform/transforms/react.js
+7 -9
@@ -68,10 +68,6 @@ function visitReactTag(traverse, object, path, state) {
68
69 utils.move(object.name.range[1], state);
70
71 - var childrenToRender = object.children.filter(function(child) {
72 - return !(child.type === Syntax.Literal && !child.value.match(/\S/));
73 - });
74 -
71 // if we don't have any attributes, pass in null
72 if (object.attributes.length === 0) {
73 utils.append('null', state);
@@ -131,16 +127,18 @@ function visitReactTag(traverse, object, path, state) {
127 }
128
129 // filter out whitespace
130 + var childrenToRender = object.children.filter(function(child) {
131 + return !(child.type === Syntax.Literal &&
132 + child.value.match(/^[ \t]*[\r\n][ \t\r\n]*$/));
133 + });
134 +
135 if (childrenToRender.length > 0) {
136 utils.append(', ', state);
137
137 - object.children.forEach(function(child) {
138 - if (child.type === Syntax.Literal && !child.value.match(/\S/)) {
139 - return;
140 - }
138 + childrenToRender.forEach(function(child, index) {
139 utils.catchup(child.range[0], state);
140
143 - var isLast = child === childrenToRender[childrenToRender.length - 1];
141 + var isLast = index === childrenToRender.length - 1;
142
143 if (child.type === Syntax.Literal) {
144 renderXJSLiteral(child, isLast, state);
vendor/fbtransform/transforms/xjs.js
+52 -105
@@ -149,118 +149,65 @@ var knownTags = {
149 wbr: true
150 };
151
152 -function safeTrim(string) {
153 - return string.replace(/^[ \t]+/, '').replace(/[ \t]+$/, '');
154 -}
155 -
156 -// Replace all trailing whitespace characters with a single space character
157 -function trimWithSingleSpace(string) {
158 - return string.replace(/^[ \t\xA0]{2,}/, ' ').
159 - replace(/[ \t\xA0]{2,}$/, ' ').replace(/^\s+$/, '');
160 -}
161 -
162 -/**
163 - * Special handling for multiline string literals
164 - * print lines:
165 - *
166 - * line
167 - * line
168 - *
169 - * as:
170 - *
171 - * "line "+
172 - * "line"
173 - */
152 function renderXJSLiteral(object, isLast, state, start, end) {
175 - /** Added blank check filtering and triming*/
176 - var trimmedChildValue = safeTrim(object.value);
177 - var hasFinalNewLine = false;
178 -
179 - if (trimmedChildValue) {
180 - // head whitespace
181 - utils.append(object.value.match(/^[\t ]*/)[0], state);
182 - if (start) {
183 - utils.append(start, state);
153 + var lines = object.value.split(/\r\n|\n|\r/);
154 +
155 + if (start) {
156 + utils.append(start, state);
157 + }
158 +
159 + var lastNonEmptyLine = 0;
160 +
161 + lines.forEach(function (line, index) {
162 + if (line.match(/[^ \t]/)) {
163 + lastNonEmptyLine = index;
164 }
185 -
186 - var trimmedChildValueWithSpace = trimWithSingleSpace(object.value);
187 -
188 - /**
189 - */
190 - var initialLines = trimmedChildValue.split(/\r\n|\n|\r/);
191 -
192 - var lines = initialLines.filter(function(line) {
193 - return safeTrim(line).length > 0;
194 - });
195 -
196 - var hasInitialNewLine = initialLines[0] !== lines[0];
197 - hasFinalNewLine =
198 - initialLines[initialLines.length - 1] !== lines[lines.length - 1];
199 -
200 - var numLines = lines.length;
201 - lines.forEach(function (line, ii) {
202 - var lastLine = ii === numLines - 1;
203 - var trimmedLine = safeTrim(line);
204 - if (trimmedLine === '' && !lastLine) {
205 - utils.append(line, state);
206 - } else {
207 - var preString = '';
208 - var postString = '';
209 - var leading = line.match(/^[ \t]*/)[0];
210 -
211 - if (ii === 0) {
212 - if (hasInitialNewLine) {
213 - preString = ' ';
214 - leading = '\n' + leading;
215 - }
216 - if (trimmedChildValueWithSpace.substring(0, 1) === ' ') {
217 - // If this is the first line, and the original content starts with
218 - // whitespace, place a single space at the beginning.
219 - preString = ' ';
220 - }
165 + });
166 +
167 + lines.forEach(function (line, index) {
168 + var isFirstLine = index === 0;
169 + var isLastLine = index === lines.length - 1;
170 + var isLastNonEmptyLine = index === lastNonEmptyLine;
171 +
172 + // replace rendered whitespace tabs with spaces
173 + var trimmedLine = line.replace(/\t/g, ' ');
174 +
175 + // trim whitespace touching a newline
176 + if (!isFirstLine) {
177 + trimmedLine = trimmedLine.replace(/^[ ]+/, '');
178 + }
179 + if (!isLastLine) {
180 + trimmedLine = trimmedLine.replace(/[ ]+$/, '');
181 + }
182 +
183 + utils.append(line.match(/^[ \t]*/)[0], state);
184 +
185 + if (trimmedLine || isLastNonEmptyLine) {
186 + utils.append(
187 + JSON.stringify(trimmedLine) +
188 + (!isLastNonEmptyLine ? "+' '+" : ''),
189 + state);
190 +
191 + if (isLastNonEmptyLine) {
192 + if (end) {
193 + utils.append(end, state);
194 }
222 - if (!lastLine || trimmedChildValueWithSpace.substr(
223 - trimmedChildValueWithSpace.length - 1, 1) === ' ' ||
224 - hasFinalNewLine
225 - ) {
226 - // If either not on the last line, or the original content ends with
227 - // whitespace, place a single character at the end.
228 - postString = ' ';
195 + if (!isLast) {
196 + utils.append(',', state);
197 }
230 -
231 - utils.append(
232 - leading +
233 - JSON.stringify(
234 - preString + trimmedLine + postString
235 - ) +
236 - (lastLine ? '' : '+') +
237 - line.match(/[ \t]*$/)[0],
238 - state);
198 }
240 - if (!lastLine) {
241 - utils.append('\n', state);
199 +
200 + // only restore tail whitespace if line had literals
201 + if (trimmedLine) {
202 + utils.append(line.match(/[ \t]*$/)[0], state);
203 }
243 - });
244 - } else {
245 - if (start) {
246 - utils.append(start, state);
204 }
248 - utils.append('""', state);
249 - }
250 - if (end) {
251 - utils.append(end, state);
252 - }
253 -
254 - // add comma before trailing whitespace
255 - if (!isLast) {
256 - utils.append(',', state);
257 - }
258 -
259 - // tail whitespace
260 - if (hasFinalNewLine) {
261 - utils.append('\n', state);
262 - }
263 - utils.append(object.value.match(/[ \t]*$/)[0], state);
205 +
206 + if (!isLastLine) {
207 + utils.append('\n', state);
208 + }
209 + });
210 +
211 utils.move(object.range[1], state);
212 }
213