mirror of
https://github.com/facebook/react.git
synced 2025-11-01 09:12:30 +00:00
Merge pull request #480 from syranide/whitespace
JSX whitespace coalescing rules
This commit is contained in:
@@ -67,7 +67,7 @@ describe('rendering React components at document', function() {
|
||||
React.renderComponentToString(<Root />, function(markup) {
|
||||
testDocument = getTestDocument(markup);
|
||||
var component = React.renderComponent(<Root />, testDocument);
|
||||
expect(testDocument.body.innerHTML).toBe(' Hello world ');
|
||||
expect(testDocument.body.innerHTML).toBe('Hello world');
|
||||
|
||||
var componentID = ReactMount.getReactRootID(testDocument);
|
||||
expect(componentID).toBe(component._rootNodeID);
|
||||
@@ -95,13 +95,13 @@ describe('rendering React components at document', function() {
|
||||
React.renderComponentToString(<Root />, function(markup) {
|
||||
testDocument = getTestDocument(markup);
|
||||
React.renderComponent(<Root />, testDocument);
|
||||
expect(testDocument.body.innerHTML).toBe(' Hello world ');
|
||||
expect(testDocument.body.innerHTML).toBe('Hello world');
|
||||
|
||||
expect(function() {
|
||||
React.unmountComponentAtNode(testDocument);
|
||||
}).toThrow(UNMOUNT_INVARIANT_MESSAGE);
|
||||
|
||||
expect(testDocument.body.innerHTML).toBe(' Hello world ');
|
||||
expect(testDocument.body.innerHTML).toBe('Hello world');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -143,14 +143,14 @@ describe('rendering React components at document', function() {
|
||||
|
||||
React.renderComponent(<Component />, testDocument);
|
||||
|
||||
expect(testDocument.body.innerHTML).toBe(' Hello world ');
|
||||
expect(testDocument.body.innerHTML).toBe('Hello world');
|
||||
|
||||
// Reactive update
|
||||
expect(function() {
|
||||
React.renderComponent(<Component2 />, testDocument);
|
||||
}).toThrow(UNMOUNT_INVARIANT_MESSAGE);
|
||||
|
||||
expect(testDocument.body.innerHTML).toBe(' Hello world ');
|
||||
expect(testDocument.body.innerHTML).toBe('Hello world');
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
+7
-9
@@ -68,10 +68,6 @@ function visitReactTag(traverse, object, path, state) {
|
||||
|
||||
utils.move(object.name.range[1], state);
|
||||
|
||||
var childrenToRender = object.children.filter(function(child) {
|
||||
return !(child.type === Syntax.Literal && !child.value.match(/\S/));
|
||||
});
|
||||
|
||||
// if we don't have any attributes, pass in null
|
||||
if (object.attributes.length === 0) {
|
||||
utils.append('null', state);
|
||||
@@ -131,16 +127,18 @@ function visitReactTag(traverse, object, path, state) {
|
||||
}
|
||||
|
||||
// filter out whitespace
|
||||
var childrenToRender = object.children.filter(function(child) {
|
||||
return !(child.type === Syntax.Literal &&
|
||||
child.value.match(/^[ \t]*[\r\n][ \t\r\n]*$/));
|
||||
});
|
||||
|
||||
if (childrenToRender.length > 0) {
|
||||
utils.append(', ', state);
|
||||
|
||||
object.children.forEach(function(child) {
|
||||
if (child.type === Syntax.Literal && !child.value.match(/\S/)) {
|
||||
return;
|
||||
}
|
||||
childrenToRender.forEach(function(child, index) {
|
||||
utils.catchup(child.range[0], state);
|
||||
|
||||
var isLast = child === childrenToRender[childrenToRender.length - 1];
|
||||
var isLast = index === childrenToRender.length - 1;
|
||||
|
||||
if (child.type === Syntax.Literal) {
|
||||
renderXJSLiteral(child, isLast, state);
|
||||
|
||||
Vendored
+56
-109
@@ -149,118 +149,65 @@ var knownTags = {
|
||||
wbr: true
|
||||
};
|
||||
|
||||
function safeTrim(string) {
|
||||
return string.replace(/^[ \t]+/, '').replace(/[ \t]+$/, '');
|
||||
}
|
||||
|
||||
// Replace all trailing whitespace characters with a single space character
|
||||
function trimWithSingleSpace(string) {
|
||||
return string.replace(/^[ \t\xA0]{2,}/, ' ').
|
||||
replace(/[ \t\xA0]{2,}$/, ' ').replace(/^\s+$/, '');
|
||||
}
|
||||
|
||||
/**
|
||||
* Special handling for multiline string literals
|
||||
* print lines:
|
||||
*
|
||||
* line
|
||||
* line
|
||||
*
|
||||
* as:
|
||||
*
|
||||
* "line "+
|
||||
* "line"
|
||||
*/
|
||||
function renderXJSLiteral(object, isLast, state, start, end) {
|
||||
/** Added blank check filtering and triming*/
|
||||
var trimmedChildValue = safeTrim(object.value);
|
||||
var hasFinalNewLine = false;
|
||||
|
||||
if (trimmedChildValue) {
|
||||
// head whitespace
|
||||
utils.append(object.value.match(/^[\t ]*/)[0], state);
|
||||
if (start) {
|
||||
utils.append(start, state);
|
||||
var lines = object.value.split(/\r\n|\n|\r/);
|
||||
|
||||
if (start) {
|
||||
utils.append(start, state);
|
||||
}
|
||||
|
||||
var lastNonEmptyLine = 0;
|
||||
|
||||
lines.forEach(function (line, index) {
|
||||
if (line.match(/[^ \t]/)) {
|
||||
lastNonEmptyLine = index;
|
||||
}
|
||||
|
||||
var trimmedChildValueWithSpace = trimWithSingleSpace(object.value);
|
||||
|
||||
/**
|
||||
*/
|
||||
var initialLines = trimmedChildValue.split(/\r\n|\n|\r/);
|
||||
|
||||
var lines = initialLines.filter(function(line) {
|
||||
return safeTrim(line).length > 0;
|
||||
});
|
||||
|
||||
var hasInitialNewLine = initialLines[0] !== lines[0];
|
||||
hasFinalNewLine =
|
||||
initialLines[initialLines.length - 1] !== lines[lines.length - 1];
|
||||
|
||||
var numLines = lines.length;
|
||||
lines.forEach(function (line, ii) {
|
||||
var lastLine = ii === numLines - 1;
|
||||
var trimmedLine = safeTrim(line);
|
||||
if (trimmedLine === '' && !lastLine) {
|
||||
utils.append(line, state);
|
||||
} else {
|
||||
var preString = '';
|
||||
var postString = '';
|
||||
var leading = line.match(/^[ \t]*/)[0];
|
||||
|
||||
if (ii === 0) {
|
||||
if (hasInitialNewLine) {
|
||||
preString = ' ';
|
||||
leading = '\n' + leading;
|
||||
}
|
||||
if (trimmedChildValueWithSpace.substring(0, 1) === ' ') {
|
||||
// If this is the first line, and the original content starts with
|
||||
// whitespace, place a single space at the beginning.
|
||||
preString = ' ';
|
||||
}
|
||||
}
|
||||
if (!lastLine || trimmedChildValueWithSpace.substr(
|
||||
trimmedChildValueWithSpace.length - 1, 1) === ' ' ||
|
||||
hasFinalNewLine
|
||||
) {
|
||||
// If either not on the last line, or the original content ends with
|
||||
// whitespace, place a single character at the end.
|
||||
postString = ' ';
|
||||
}
|
||||
|
||||
utils.append(
|
||||
leading +
|
||||
JSON.stringify(
|
||||
preString + trimmedLine + postString
|
||||
) +
|
||||
(lastLine ? '' : '+') +
|
||||
line.match(/[ \t]*$/)[0],
|
||||
state);
|
||||
}
|
||||
if (!lastLine) {
|
||||
utils.append('\n', state);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
if (start) {
|
||||
utils.append(start, state);
|
||||
});
|
||||
|
||||
lines.forEach(function (line, index) {
|
||||
var isFirstLine = index === 0;
|
||||
var isLastLine = index === lines.length - 1;
|
||||
var isLastNonEmptyLine = index === lastNonEmptyLine;
|
||||
|
||||
// replace rendered whitespace tabs with spaces
|
||||
var trimmedLine = line.replace(/\t/g, ' ');
|
||||
|
||||
// trim whitespace touching a newline
|
||||
if (!isFirstLine) {
|
||||
trimmedLine = trimmedLine.replace(/^[ ]+/, '');
|
||||
}
|
||||
utils.append('""', state);
|
||||
}
|
||||
if (end) {
|
||||
utils.append(end, state);
|
||||
}
|
||||
|
||||
// add comma before trailing whitespace
|
||||
if (!isLast) {
|
||||
utils.append(',', state);
|
||||
}
|
||||
|
||||
// tail whitespace
|
||||
if (hasFinalNewLine) {
|
||||
utils.append('\n', state);
|
||||
}
|
||||
utils.append(object.value.match(/[ \t]*$/)[0], state);
|
||||
if (!isLastLine) {
|
||||
trimmedLine = trimmedLine.replace(/[ ]+$/, '');
|
||||
}
|
||||
|
||||
utils.append(line.match(/^[ \t]*/)[0], state);
|
||||
|
||||
if (trimmedLine || isLastNonEmptyLine) {
|
||||
utils.append(
|
||||
JSON.stringify(trimmedLine) +
|
||||
(!isLastNonEmptyLine ? "+' '+" : ''),
|
||||
state);
|
||||
|
||||
if (isLastNonEmptyLine) {
|
||||
if (end) {
|
||||
utils.append(end, state);
|
||||
}
|
||||
if (!isLast) {
|
||||
utils.append(',', state);
|
||||
}
|
||||
}
|
||||
|
||||
// only restore tail whitespace if line had literals
|
||||
if (trimmedLine) {
|
||||
utils.append(line.match(/[ \t]*$/)[0], state);
|
||||
}
|
||||
}
|
||||
|
||||
if (!isLastLine) {
|
||||
utils.append('\n', state);
|
||||
}
|
||||
});
|
||||
|
||||
utils.move(object.range[1], state);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user