diff --git a/lib/rules/jsx-closing-bracket-location.js b/lib/rules/jsx-closing-bracket-location.js
index f4959cc124..50a9e1f1b7 100644
--- a/lib/rules/jsx-closing-bracket-location.js
+++ b/lib/rules/jsx-closing-bracket-location.js
@@ -142,25 +142,35 @@ module.exports = function(context) {
};
}
- var lastAttributeEndPos;
- var lastAttributeStartPos;
+ /**
+ * Get an unique ID for a given JSXOpeningElement
+ *
+ * @param {ASTNode} node The AST node being checked.
+ * @returns {String} Unique ID (based on its range)
+ */
+ function getOpeningElementId(node) {
+ return node.range.join(':');
+ }
+
+ var lastAttributeNode = {};
return {
JSXAttribute: function(node) {
- lastAttributeEndPos = node.end;
- lastAttributeStartPos = node.start;
+ lastAttributeNode[getOpeningElementId(node.parent)] = node;
+ },
+
+ JSXSpreadAttribute: function(node) {
+ lastAttributeNode[getOpeningElementId(node.parent)] = node;
},
'JSXOpeningElement:exit': function(node) {
- var cachedLastAttributeEndPos = lastAttributeEndPos;
- var cachedLastAttributeStartPos = lastAttributeStartPos;
+ var attributeNode = lastAttributeNode[getOpeningElementId(node)];
+ var cachedLastAttributeEndPos = attributeNode ? attributeNode.end : null;
+ var cachedLastAttributeStartPos = attributeNode ? attributeNode.start : null;
var expectedNextLine;
var tokens = getTokensLocations(node);
var expectedLocation = getExpectedLocation(tokens);
- lastAttributeStartPos = null;
- lastAttributeEndPos = null;
-
if (hasCorrectLocation(tokens, expectedLocation)) {
return;
}
@@ -188,8 +198,8 @@ module.exports = function(context) {
return fixer.replaceTextRange([cachedLastAttributeEndPos, node.end],
(expectedNextLine ? '\n' : '') + closingTag);
}
- return fixer.replaceTextRange([node.name.loc.end.column + 1, node.end],
- (expectedNextLine ? '\n' : '') + closingTag);
+ return fixer.replaceTextRange([node.name.range[1], node.end],
+ (expectedNextLine ? '\n' : ' ') + closingTag);
case 'after-props':
return fixer.replaceTextRange([cachedLastAttributeEndPos, node.end],
(expectedNextLine ? '\n' : '') + closingTag);
@@ -198,7 +208,7 @@ module.exports = function(context) {
return fixer.replaceTextRange([cachedLastAttributeEndPos, node.end],
'\n' + spaces.join(' ') + closingTag);
case 'tag-aligned':
- var tagSpaces = new Array(node.start);
+ var tagSpaces = new Array(+correctColumn + 1);
return fixer.replaceTextRange([cachedLastAttributeEndPos, node.end],
'\n' + tagSpaces.join(' ') + closingTag);
case 'line-aligned':
diff --git a/tests/lib/rules/jsx-closing-bracket-location.js b/tests/lib/rules/jsx-closing-bracket-location.js
index 8c4e374235..e28f25053e 100644
--- a/tests/lib/rules/jsx-closing-bracket-location.js
+++ b/tests/lib/rules/jsx-closing-bracket-location.js
@@ -564,6 +564,11 @@ ruleTester.run('jsx-closing-bracket-location', rule, {
' foo',
' >'
].join('\n'),
+ output: [
+ '