eslint-plugin-html
Advanced tools
Comparing version 3.0.0 to 3.1.0
@@ -0,1 +1,4 @@ | ||
2017-07-11 v3.1.0 | ||
* Remap messages "source" property to fix custom formatters support #69 | ||
2017-06-12 v3.0.0 [migration guide](MIGRATION_TO_V3.md) | ||
@@ -2,0 +5,0 @@ * **Breaking: lint script tags separately** #49 #55 #56 |
{ | ||
"name": "eslint-plugin-html", | ||
"version": "3.0.0", | ||
"version": "3.1.0", | ||
"description": "A ESLint plugin to lint and fix inline scripts contained in HTML files.", | ||
@@ -5,0 +5,0 @@ "license": "ISC", |
@@ -107,2 +107,15 @@ /*eslint-env es6*/ | ||
it("trim last line spaces ignoring CDATA", () => { | ||
test({ | ||
input: ` | ||
some html | ||
<script><![CDATA[ | ||
var foo = 1; | ||
]]></script> | ||
other | ||
`, | ||
xmlMode: true, | ||
}) | ||
}) | ||
it("extract script containing 'lower than' characters correctly (#1)", () => { | ||
@@ -109,0 +122,0 @@ test({ |
@@ -450,2 +450,14 @@ "use strict" | ||
it("removes white space at the end of scripts ending with CDATA", () => { | ||
const messages = execute("cdata.xhtml", { | ||
rules: { | ||
"no-console": "off", | ||
"no-trailing-spaces": "error", | ||
"eol-last": "error", | ||
}, | ||
}) | ||
expect(messages.length).toBe(0) | ||
}) | ||
it("should support self closing script tags", () => { | ||
@@ -615,1 +627,20 @@ let messages | ||
}) | ||
it("should report correct eol-last message position", () => { | ||
const messages = execute("eol-last.html", { | ||
rules: { | ||
"eol-last": "error", | ||
}, | ||
}) | ||
expect(messages.length).toBe(1) | ||
expect(messages[0].ruleId).toBe("eol-last") | ||
expect(messages[0].line).toBe(6) | ||
if (isESLintVersion("> 2")) { | ||
expect(messages[0].column).toBe(42) | ||
} | ||
else { | ||
expect(messages[0].column).toBe(12) | ||
} | ||
}) |
@@ -88,2 +88,12 @@ "use strict" | ||
}) | ||
it("should return the last index of the last block if the index is after the end", () => { | ||
const ts = new TransformableString("abcd") | ||
ts.replace(2, 4, "X") | ||
expect(ts.toString()).toBe("abX") | ||
expect(ts.originalIndex(0)).toBe(0) // a | ||
expect(ts.originalIndex(1)).toBe(1) // b | ||
expect(ts.originalIndex(2)).toBe(undefined) | ||
expect(ts.originalIndex(3)).toBe(3) // c | ||
}) | ||
}) | ||
@@ -145,1 +155,12 @@ | ||
}) | ||
describe("getOriginalLine", () => { | ||
it("returns original lines", () => { | ||
const ts = new TransformableString("aa\nbb\r\ncc") | ||
expect(() => ts.getOriginalLine(0)).toThrow() | ||
expect(ts.getOriginalLine(1)).toEqual("aa") | ||
expect(ts.getOriginalLine(2)).toEqual("bb") | ||
expect(ts.getOriginalLine(3)).toEqual("cc") | ||
expect(() => ts.getOriginalLine(4)).toThrow() | ||
}) | ||
}) |
@@ -13,29 +13,9 @@ "use strict" | ||
let inScript = false | ||
let nextType = null | ||
let nextEnd = null | ||
let cdata = [] | ||
function emitChunk(type, end, lastChunk) { | ||
// Ignore empty chunks | ||
if (index !== end) { | ||
// Keep concatenating same type chunks | ||
if (nextType !== null && nextType !== type) { | ||
onChunk({ | ||
type: nextType, | ||
start: index, | ||
end: nextEnd, | ||
}) | ||
index = nextEnd | ||
} | ||
nextType = type | ||
nextEnd = end | ||
if (lastChunk) { | ||
onChunk({ | ||
type: nextType, | ||
start: index, | ||
end: nextEnd, | ||
}) | ||
} | ||
} | ||
const chunks = [] | ||
function pushChunk(type, end) { | ||
chunks.push({ type, start: index, end, cdata }) | ||
cdata = [] | ||
index = end | ||
} | ||
@@ -56,11 +36,16 @@ | ||
inScript = true | ||
emitChunk("html", parser.endIndex + 1) | ||
pushChunk("html", parser.endIndex + 1) | ||
}, | ||
oncdatastart() { | ||
if (inScript) { | ||
emitChunk("cdata start", parser.startIndex + 9) | ||
emitChunk("script", parser.endIndex - 2) | ||
emitChunk("cdata end", parser.endIndex + 1) | ||
} | ||
cdata.push( | ||
{ | ||
start: parser.startIndex, | ||
end: parser.startIndex + 9, | ||
}, | ||
{ | ||
start: parser.endIndex - 2, | ||
end: parser.endIndex + 1, | ||
} | ||
) | ||
}, | ||
@@ -75,3 +60,3 @@ | ||
if (parser.startIndex < nextEnd) { | ||
if (parser.startIndex < chunks[chunks.length - 1].end) { | ||
// The parser didn't move its index after the previous chunk emited. It occurs on | ||
@@ -82,6 +67,3 @@ // self-closing tags (xml mode). Just ignore this script. | ||
const endSpaces = code | ||
.slice(index, parser.startIndex) | ||
.match(/[ \t]*$/)[0].length | ||
emitChunk("script", parser.startIndex - endSpaces) | ||
pushChunk("script", parser.startIndex) | ||
}, | ||
@@ -94,3 +76,3 @@ | ||
emitChunk("script", parser.endIndex + 1) | ||
pushChunk("script", parser.endIndex + 1) | ||
}, | ||
@@ -105,3 +87,27 @@ }, | ||
emitChunk("html", parser.endIndex + 1, true) | ||
pushChunk("html", parser.endIndex + 1) | ||
{ | ||
const emitChunk = () => { | ||
const cdata = [] | ||
for (let i = startChunkIndex; i < index; i += 1) { | ||
cdata.push(...chunks[i].cdata) | ||
} | ||
onChunk({ | ||
type: chunks[startChunkIndex].type, | ||
start: chunks[startChunkIndex].start, | ||
end: chunks[index - 1].end, | ||
cdata, | ||
}) | ||
} | ||
let startChunkIndex = 0 | ||
let index | ||
for (index = 1; index < chunks.length; index += 1) { | ||
if (chunks[startChunkIndex].type === chunks[index].type) continue | ||
emitChunk() | ||
startChunkIndex = index | ||
} | ||
emitChunk() | ||
} | ||
} | ||
@@ -125,2 +131,3 @@ | ||
const re = /(\r\n|\n|\r)([ \t]*)(.*)/g | ||
let lastIndex = 0 | ||
@@ -145,6 +152,7 @@ while (true) { | ||
if (!badIndentation) { | ||
lastIndex = match.index + newLine.length + indent.length | ||
yield { | ||
type: "dedent", | ||
from: match.index + newLine.length, | ||
to: match.index + newLine.length + indent.length, | ||
to: lastIndex, | ||
} | ||
@@ -167,2 +175,11 @@ } | ||
} | ||
const endSpaces = slice.slice(lastIndex).match(/[ \t]*$/)[0].length | ||
if (endSpaces) { | ||
yield { | ||
type: "dedent", | ||
from: slice.length - endSpaces, | ||
to: slice.length, | ||
} | ||
} | ||
} | ||
@@ -178,19 +195,21 @@ | ||
const slice = code.slice(chunk.start, chunk.end) | ||
if ( | ||
chunk.type === "html" || | ||
chunk.type === "cdata start" || | ||
chunk.type === "cdata end" | ||
) { | ||
if (chunk.type === "html") { | ||
const match = slice.match(/\r\n|\n|\r/g) | ||
if (match) lineNumber += match.length | ||
if (chunk.type === "html") previousHTML = slice | ||
previousHTML = slice | ||
} | ||
else if (chunk.type === "script") { | ||
const transformedCode = new TransformableString(code) | ||
let indentSlice = slice | ||
for (const cdata of chunk.cdata) { | ||
transformedCode.replace(cdata.start, cdata.end, "") | ||
if (cdata.end === chunk.end) { | ||
indentSlice = code.slice(chunk.start, cdata.start) | ||
} | ||
} | ||
transformedCode.replace(0, chunk.start, "") | ||
transformedCode.replace(chunk.end, code.length, "") | ||
for (const action of dedent( | ||
computeIndent(indentDescriptor, previousHTML, slice), | ||
slice | ||
computeIndent(indentDescriptor, previousHTML, indentSlice), | ||
indentSlice | ||
)) { | ||
@@ -197,0 +216,0 @@ lineNumber += 1 |
@@ -165,3 +165,6 @@ "use strict" | ||
for (const message of messages) { | ||
const location = code.originalLocation(message) | ||
const location = code.originalLocation({ | ||
line: message.line, | ||
column: message.column, | ||
}) | ||
@@ -171,2 +174,3 @@ // Ignore messages if they were in transformed code | ||
Object.assign(message, location) | ||
message.source = code.getOriginalLine(location.line) | ||
@@ -173,0 +177,0 @@ // Map fix range |
"use strict" | ||
const lineEndingsRe = /\r\n|\r|\n/g | ||
function lineStarts(str) { | ||
const result = [0] | ||
const re = /\r\n|\r|\n/g | ||
lineEndingsRe.lastIndex = 0 | ||
while (true) { | ||
const match = re.exec(str) | ||
const match = lineEndingsRe.exec(str) | ||
if (!match) break | ||
result.push(re.lastIndex) | ||
result.push(lineEndingsRe.lastIndex) | ||
} | ||
@@ -65,2 +66,11 @@ return result | ||
getOriginalLine(n) { | ||
if (n < 1 || n > this._lineStarts.length) { | ||
throw new Error("Invalid line number") | ||
} | ||
return this._original | ||
.slice(this._lineStarts[n - 1], this._lineStarts[n]) | ||
.replace(lineEndingsRe, "") | ||
} | ||
toString() { | ||
@@ -90,3 +100,4 @@ return this._compute().result | ||
originalIndex(index) { | ||
for (const block of this._blocks) { | ||
let block | ||
for (block of this._blocks) { | ||
if (index < block.from) break | ||
@@ -104,2 +115,8 @@ | ||
} | ||
if (index == this._original.length) { | ||
if (block.to && block.to === this._original.length) { | ||
return block.from + block.str.length | ||
} | ||
return this._original.length | ||
} | ||
return index | ||
@@ -112,6 +129,5 @@ } | ||
if (originalIndex !== undefined) { | ||
const originalLocation = indexToLocation(originalIndex, this._lineStarts) | ||
return originalLocation | ||
return indexToLocation(originalIndex, this._lineStarts) | ||
} | ||
} | ||
} |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
58929
26
1558