@html-eslint/eslint-plugin
Advanced tools
Comparing version 0.25.0 to 0.26.0
@@ -23,5 +23,9 @@ /** | ||
EXTRA_BEFORE: "unexpectedBefore", | ||
EXTRA_BEFORE_CLOSE: "unexpectedBeforeClose", | ||
MISSING_BEFORE: "missingBefore", | ||
MISSING_BEFORE_SELF_CLOSE: "missingBeforeSelfClose", | ||
EXTRA_BEFORE_SELF_CLOSE: "unexpectedBeforeSelfClose", | ||
EXTRA_TAB_BEFORE: "unexpectedTabBefore", | ||
EXTRA_TAB_BEFORE_SELF_CLOSE: "unexpectedTabBeforeSelfClose", | ||
EXTRA_TAB_BETWEEN: "unexpectedTabBetween", | ||
}; | ||
@@ -50,2 +54,5 @@ | ||
}, | ||
disallowTabs: { | ||
type: "boolean", | ||
}, | ||
enforceBeforeSelfClose: { | ||
@@ -61,2 +68,3 @@ type: "boolean", | ||
[MESSAGE_IDS.EXTRA_BEFORE]: "Unexpected space before attribute", | ||
[MESSAGE_IDS.EXTRA_BEFORE_CLOSE]: "Unexpected space before closing", | ||
[MESSAGE_IDS.MISSING_BEFORE_SELF_CLOSE]: | ||
@@ -67,2 +75,8 @@ "Missing space before self closing", | ||
[MESSAGE_IDS.MISSING_BEFORE]: "Missing space before attribute", | ||
[MESSAGE_IDS.EXTRA_TAB_BEFORE]: | ||
"Unexpected tab before attribute; use space instead", | ||
[MESSAGE_IDS.EXTRA_TAB_BEFORE_SELF_CLOSE]: | ||
"Unexpected tab before self closing; use space instead", | ||
[MESSAGE_IDS.EXTRA_TAB_BETWEEN]: | ||
"Unexpected tab between attributes; use space instead", | ||
}, | ||
@@ -74,3 +88,6 @@ }, | ||
const disallowMissing = !!(context.options[0] || {}).disallowMissing; | ||
const disallowTabs = !!(context.options[0] || {}).disallowTabs; | ||
const sourceCode = context.getSourceCode().text; | ||
/** | ||
@@ -106,2 +123,15 @@ * @param {AttributeNode[]} attrs | ||
}); | ||
} else if (disallowTabs) { | ||
if (sourceCode[current.range[1]] === `\t`) { | ||
context.report({ | ||
loc: getLocBetween(current, after), | ||
messageId: MESSAGE_IDS.EXTRA_TAB_BETWEEN, | ||
fix(fixer) { | ||
return fixer.replaceTextRange( | ||
[current.range[1], current.range[1] + 1], | ||
` ` | ||
); | ||
}, | ||
}); | ||
} | ||
} | ||
@@ -112,40 +142,2 @@ }); | ||
/** | ||
* @param {OpenTagEndNode | OpenScriptTagEndNode | OpenStyleTagEndNode} openEnd | ||
* @param {AttributeNode} lastAttr | ||
* @param {boolean} isSelfClosed | ||
* @returns {void} | ||
*/ | ||
function checkExtraSpaceAfter(openEnd, lastAttr, isSelfClosed) { | ||
if (openEnd.loc.end.line !== lastAttr.loc.end.line) { | ||
// skip the attribute on the different line with the start tag | ||
return; | ||
} | ||
const limit = isSelfClosed && enforceBeforeSelfClose ? 1 : 0; | ||
const spacesBetween = openEnd.loc.start.column - lastAttr.loc.end.column; | ||
if (spacesBetween > limit) { | ||
context.report({ | ||
loc: getLocBetween(lastAttr, openEnd), | ||
messageId: MESSAGE_IDS.EXTRA_AFTER, | ||
fix(fixer) { | ||
return fixer.removeRange([ | ||
lastAttr.range[1], | ||
lastAttr.range[1] + spacesBetween - limit, | ||
]); | ||
}, | ||
}); | ||
} | ||
if (isSelfClosed && enforceBeforeSelfClose && spacesBetween < 1) { | ||
context.report({ | ||
loc: getLocBetween(lastAttr, openEnd), | ||
messageId: MESSAGE_IDS.MISSING_BEFORE_SELF_CLOSE, | ||
fix(fixer) { | ||
return fixer.insertTextAfter(lastAttr, " "); | ||
}, | ||
}); | ||
} | ||
} | ||
/** | ||
* @param {OpenScriptTagStartNode | OpenTagStartNode | OpenStyleTagStartNode} node | ||
@@ -174,41 +166,18 @@ * @param {AttributeNode} firstAttr | ||
}); | ||
} else if (disallowTabs) { | ||
if (sourceCode[firstAttr.range[0] - 1] === `\t`) { | ||
context.report({ | ||
loc: firstAttr.loc, | ||
messageId: MESSAGE_IDS.EXTRA_TAB_BEFORE, | ||
fix(fixer) { | ||
return fixer.replaceTextRange( | ||
[firstAttr.range[0] - 1, firstAttr.range[0]], | ||
` ` | ||
); | ||
}, | ||
}); | ||
} | ||
} | ||
} | ||
/** | ||
* @param {AnyNode} beforeSelfClosing | ||
* @param {OpenTagEndNode | OpenScriptTagEndNode | OpenStyleTagEndNode} openEnd | ||
* @returns | ||
*/ | ||
function checkSpaceBeforeSelfClosing(beforeSelfClosing, openEnd) { | ||
if (beforeSelfClosing.loc.start.line !== openEnd.loc.start.line) { | ||
// skip the attribute on the different line with the start tag | ||
return; | ||
} | ||
const spacesBetween = | ||
openEnd.loc.start.column - beforeSelfClosing.loc.end.column; | ||
const locBetween = getLocBetween(beforeSelfClosing, openEnd); | ||
if (spacesBetween > 1) { | ||
context.report({ | ||
loc: locBetween, | ||
messageId: MESSAGE_IDS.EXTRA_BEFORE_SELF_CLOSE, | ||
fix(fixer) { | ||
return fixer.removeRange([ | ||
beforeSelfClosing.range[1] + 1, | ||
openEnd.range[0], | ||
]); | ||
}, | ||
}); | ||
} else if (spacesBetween < 1) { | ||
context.report({ | ||
loc: locBetween, | ||
messageId: MESSAGE_IDS.MISSING_BEFORE_SELF_CLOSE, | ||
fix(fixer) { | ||
return fixer.insertTextAfter(beforeSelfClosing, " "); | ||
}, | ||
}); | ||
} | ||
} | ||
return { | ||
@@ -227,20 +196,85 @@ /** | ||
} | ||
if (node.openEnd) { | ||
checkExtraSpacesBetweenAttrs(node.attributes); | ||
const lastAttr = node.attributes[node.attributes.length - 1]; | ||
const nodeBeforeEnd = | ||
node.attributes.length === 0 ? node.openStart : lastAttr; | ||
if (nodeBeforeEnd.loc.end.line !== node.openEnd.loc.start.line) { | ||
return; | ||
} | ||
const isSelfClosing = node.openEnd.value === "/>"; | ||
if (node.attributes && node.attributes.length > 0) { | ||
checkExtraSpaceAfter( | ||
node.openEnd, | ||
node.attributes[node.attributes.length - 1], | ||
isSelfClosing | ||
); | ||
const spacesBetween = | ||
node.openEnd.loc.start.column - nodeBeforeEnd.loc.end.column; | ||
const locBetween = getLocBetween(nodeBeforeEnd, node.openEnd); | ||
if (isSelfClosing && enforceBeforeSelfClose) { | ||
if (spacesBetween < 1) { | ||
context.report({ | ||
loc: locBetween, | ||
messageId: MESSAGE_IDS.MISSING_BEFORE_SELF_CLOSE, | ||
fix(fixer) { | ||
return fixer.insertTextAfter(nodeBeforeEnd, " "); | ||
}, | ||
}); | ||
} else if (spacesBetween === 1) { | ||
if ( | ||
disallowTabs && | ||
sourceCode[node.openEnd.range[0] - 1] === `\t` | ||
) { | ||
context.report({ | ||
loc: node.openEnd.loc, | ||
messageId: MESSAGE_IDS.EXTRA_TAB_BEFORE_SELF_CLOSE, | ||
fix(fixer) { | ||
return fixer.replaceTextRange( | ||
[node.openEnd.range[0] - 1, node.openEnd.range[0]], | ||
` ` | ||
); | ||
}, | ||
}); | ||
} | ||
} else { | ||
context.report({ | ||
loc: locBetween, | ||
messageId: MESSAGE_IDS.EXTRA_BEFORE_SELF_CLOSE, | ||
fix(fixer) { | ||
return fixer.removeRange([ | ||
nodeBeforeEnd.range[1] + 1, | ||
node.openEnd.range[0], | ||
]); | ||
}, | ||
}); | ||
} | ||
return; | ||
} | ||
checkExtraSpacesBetweenAttrs(node.attributes); | ||
if ( | ||
node.attributes.length === 0 && | ||
isSelfClosing && | ||
enforceBeforeSelfClose | ||
) { | ||
checkSpaceBeforeSelfClosing(node.openStart, node.openEnd); | ||
if (spacesBetween > 0) { | ||
if (node.attributes.length > 0) { | ||
context.report({ | ||
loc: locBetween, | ||
messageId: MESSAGE_IDS.EXTRA_AFTER, | ||
fix(fixer) { | ||
return fixer.removeRange([ | ||
lastAttr.range[1], | ||
node.openEnd.range[0], | ||
]); | ||
}, | ||
}); | ||
} else { | ||
context.report({ | ||
loc: locBetween, | ||
messageId: MESSAGE_IDS.EXTRA_BEFORE_CLOSE, | ||
fix(fixer) { | ||
return fixer.removeRange([ | ||
node.openStart.range[1], | ||
node.openEnd.range[0], | ||
]); | ||
}, | ||
}); | ||
} | ||
} | ||
@@ -247,0 +281,0 @@ } |
{ | ||
"name": "@html-eslint/eslint-plugin", | ||
"version": "0.25.0", | ||
"version": "0.26.0", | ||
"description": "ESLint plugin for html", | ||
@@ -48,3 +48,3 @@ "author": "yeonjuan", | ||
"devDependencies": { | ||
"@html-eslint/parser": "^0.25.0", | ||
"@html-eslint/parser": "^0.26.0", | ||
"@types/eslint": "^8.56.2", | ||
@@ -55,3 +55,3 @@ "@types/estree": "^0.0.47", | ||
}, | ||
"gitHead": "315631a66e9c626655c243ccb6a46319736383cf" | ||
"gitHead": "34d55c3b5be5a29cc416063b4b4375cb89b3a519" | ||
} |
144942
151
4433