Skip to content

Commit

Permalink
fix: prevent attribute-duplicate reporting non-attributes: ESP toke…
Browse files Browse the repository at this point in the history
…ns, comments etc
  • Loading branch information
revelt committed Mar 5, 2021
1 parent 5b82c6b commit 110d1f4
Show file tree
Hide file tree
Showing 10 changed files with 148 additions and 81 deletions.
2 changes: 1 addition & 1 deletion packages/emlint/coverage/coverage-summary.json
@@ -1 +1 @@
{"total":{"lines":{"total":2516,"covered":2451,"skipped":0,"pct":97.42},"statements":{"total":2805,"covered":2740,"skipped":0,"pct":97.68},"functions":{"total":1003,"covered":996,"skipped":0,"pct":99.3},"branches":{"total":2116,"covered":1995,"skipped":0,"pct":94.28}}}
{"total":{"lines":{"total":2518,"covered":2454,"skipped":0,"pct":97.46},"statements":{"total":2807,"covered":2743,"skipped":0,"pct":97.72},"functions":{"total":1003,"covered":996,"skipped":0,"pct":99.3},"branches":{"total":2121,"covered":2002,"skipped":0,"pct":94.39}}}
12 changes: 8 additions & 4 deletions packages/emlint/dist/emlint.cjs.js
Expand Up @@ -3754,6 +3754,10 @@ var attributeDuplicate = function attributeDuplicate(context) {

for (var i = 0, len = node.attribs.length; i < len; i++) {

if (node.attribs[i].attribName === undefined) {
continue;
}

if (!attrsGatheredSoFar.has(node.attribs[i].attribName)) {
attrsGatheredSoFar.add(node.attribs[i].attribName);
} else if (!attributesWhichCanBeMerged.has(node.attribs[i].attribName) || Array.isArray(node.attribs[i].attribValue) && node.attribs[i].attribValue.length && node.attribs[i].attribValue.some(function (obj) {
Expand Down Expand Up @@ -3858,7 +3862,7 @@ function attributeMalformed(context) {
attribute: function attribute(node) { // if Levenshtein distance is 1 and it's not among known attribute names,
// it's definitely mis-typed

if (!node.attribNameRecognised && !node.attribName.startsWith("xmlns:") && !blacklist.includes(node.parent.tagName)) {
if (!node.attribNameRecognised && node.attribName && !node.attribName.startsWith("xmlns:") && !blacklist.includes(node.parent.tagName)) {
var somethingMatched = false;

for (var _iterator = _createForOfIteratorHelperLoose__default['default'](htmlAllKnownAttributes.allHtmlAttribs.values()), _step; !(_step = _iterator()).done;) {
Expand Down Expand Up @@ -3925,7 +3929,7 @@ function attributeMalformed(context) {


if ( // value starts with a quote
(node.attribValueRaw.startsWith("\"") || node.attribValueRaw.startsWith("'")) && node.attribValueStartsAt && node.attribOpeningQuoteAt && context.str[node.attribValueStartsAt] === context.str[node.attribOpeningQuoteAt]) {
node.attribValueRaw && (node.attribValueRaw.startsWith("\"") || node.attribValueRaw.startsWith("'")) && node.attribValueStartsAt && node.attribOpeningQuoteAt && context.str[node.attribValueStartsAt] === context.str[node.attribOpeningQuoteAt]) {
var _message = "Delete repeated opening quotes.";
context.report({
ruleId: "attribute-malformed",
Expand All @@ -3940,8 +3944,8 @@ function attributeMalformed(context) {
} // repeated closing quotes


if ( // value ends with a quote
(node.attribValueRaw.endsWith("\"") || node.attribValueRaw.endsWith("'")) && node.attribValueEndsAt && node.attribClosingQuoteAt && context.str[node.attribValueEndsAt] === context.str[node.attribClosingQuoteAt]) {
if (node.attribValueRaw && ( // value ends with a quote
node.attribValueRaw.endsWith("\"") || node.attribValueRaw.endsWith("'")) && node.attribValueEndsAt && node.attribClosingQuoteAt && context.str[node.attribValueEndsAt] === context.str[node.attribClosingQuoteAt]) {
var _message2 = "Delete repeated closing quotes.";
context.report({
ruleId: "attribute-malformed",
Expand Down
12 changes: 8 additions & 4 deletions packages/emlint/dist/emlint.dev.umd.js
Expand Up @@ -22135,6 +22135,10 @@ var attributeDuplicate = function attributeDuplicate(context) {

for (var i = 0, len = node.attribs.length; i < len; i++) {

if (node.attribs[i].attribName === undefined) {
continue;
}

if (!attrsGatheredSoFar.has(node.attribs[i].attribName)) {
attrsGatheredSoFar.add(node.attribs[i].attribName);
} else if (!attributesWhichCanBeMerged.has(node.attribs[i].attribName) || Array.isArray(node.attribs[i].attribValue) && node.attribs[i].attribValue.length && node.attribs[i].attribValue.some(function (obj) {
Expand Down Expand Up @@ -22239,7 +22243,7 @@ function attributeMalformed(context) {
attribute: function attribute(node) { // if Levenshtein distance is 1 and it's not among known attribute names,
// it's definitely mis-typed

if (!node.attribNameRecognised && !node.attribName.startsWith("xmlns:") && !blacklist.includes(node.parent.tagName)) {
if (!node.attribNameRecognised && node.attribName && !node.attribName.startsWith("xmlns:") && !blacklist.includes(node.parent.tagName)) {
var somethingMatched = false;

for (var _iterator = _createForOfIteratorHelperLoose(allHtmlAttribs.values()), _step; !(_step = _iterator()).done;) {
Expand Down Expand Up @@ -22306,7 +22310,7 @@ function attributeMalformed(context) {


if ( // value starts with a quote
(node.attribValueRaw.startsWith("\"") || node.attribValueRaw.startsWith("'")) && node.attribValueStartsAt && node.attribOpeningQuoteAt && context.str[node.attribValueStartsAt] === context.str[node.attribOpeningQuoteAt]) {
node.attribValueRaw && (node.attribValueRaw.startsWith("\"") || node.attribValueRaw.startsWith("'")) && node.attribValueStartsAt && node.attribOpeningQuoteAt && context.str[node.attribValueStartsAt] === context.str[node.attribOpeningQuoteAt]) {
var _message = "Delete repeated opening quotes.";
context.report({
ruleId: "attribute-malformed",
Expand All @@ -22321,8 +22325,8 @@ function attributeMalformed(context) {
} // repeated closing quotes


if ( // value ends with a quote
(node.attribValueRaw.endsWith("\"") || node.attribValueRaw.endsWith("'")) && node.attribValueEndsAt && node.attribClosingQuoteAt && context.str[node.attribValueEndsAt] === context.str[node.attribClosingQuoteAt]) {
if (node.attribValueRaw && ( // value ends with a quote
node.attribValueRaw.endsWith("\"") || node.attribValueRaw.endsWith("'")) && node.attribValueEndsAt && node.attribClosingQuoteAt && context.str[node.attribValueEndsAt] === context.str[node.attribClosingQuoteAt]) {
var _message2 = "Delete repeated closing quotes.";
context.report({
ruleId: "attribute-malformed",
Expand Down
12 changes: 8 additions & 4 deletions packages/emlint/dist/emlint.esm.js
Expand Up @@ -3832,6 +3832,10 @@ const attributeDuplicate = context => {

for (let i = 0, len = node.attribs.length; i < len; i++) {

if (node.attribs[i].attribName === undefined) {
continue;
}

if (!attrsGatheredSoFar.has(node.attribs[i].attribName)) {
attrsGatheredSoFar.add(node.attribs[i].attribName);
} else if (!attributesWhichCanBeMerged.has(node.attribs[i].attribName) || Array.isArray(node.attribs[i].attribValue) && node.attribs[i].attribValue.length && node.attribs[i].attribValue.some(obj => obj.value && (obj.value.includes(`'`) || obj.value.includes(`"`)))) {
Expand Down Expand Up @@ -3929,7 +3933,7 @@ function attributeMalformed(context) {
attribute(node) { // if Levenshtein distance is 1 and it's not among known attribute names,
// it's definitely mis-typed

if (!node.attribNameRecognised && !node.attribName.startsWith("xmlns:") && !blacklist.includes(node.parent.tagName)) {
if (!node.attribNameRecognised && node.attribName && !node.attribName.startsWith("xmlns:") && !blacklist.includes(node.parent.tagName)) {
let somethingMatched = false;

for (const oneOfAttribs of allHtmlAttribs.values()) {
Expand Down Expand Up @@ -3994,7 +3998,7 @@ function attributeMalformed(context) {


if ( // value starts with a quote
(node.attribValueRaw.startsWith(`"`) || node.attribValueRaw.startsWith(`'`)) && node.attribValueStartsAt && node.attribOpeningQuoteAt && context.str[node.attribValueStartsAt] === context.str[node.attribOpeningQuoteAt]) {
node.attribValueRaw && (node.attribValueRaw.startsWith(`"`) || node.attribValueRaw.startsWith(`'`)) && node.attribValueStartsAt && node.attribOpeningQuoteAt && context.str[node.attribValueStartsAt] === context.str[node.attribOpeningQuoteAt]) {
const message = `Delete repeated opening quotes.`;
context.report({
ruleId: "attribute-malformed",
Expand All @@ -4009,8 +4013,8 @@ function attributeMalformed(context) {
} // repeated closing quotes


if ( // value ends with a quote
(node.attribValueRaw.endsWith(`"`) || node.attribValueRaw.endsWith(`'`)) && node.attribValueEndsAt && node.attribClosingQuoteAt && context.str[node.attribValueEndsAt] === context.str[node.attribClosingQuoteAt]) {
if (node.attribValueRaw && ( // value ends with a quote
node.attribValueRaw.endsWith(`"`) || node.attribValueRaw.endsWith(`'`)) && node.attribValueEndsAt && node.attribClosingQuoteAt && context.str[node.attribValueEndsAt] === context.str[node.attribClosingQuoteAt]) {
const message = `Delete repeated closing quotes.`;
context.report({
ruleId: "attribute-malformed",
Expand Down
2 changes: 1 addition & 1 deletion packages/emlint/dist/emlint.mjs

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion packages/emlint/dist/emlint.umd.js

Large diffs are not rendered by default.

50 changes: 28 additions & 22 deletions packages/emlint/src/rules/attribute/attribute-duplicate.ts
Expand Up @@ -81,11 +81,17 @@ const attributeDuplicate: AttributeDuplicate = (context) => {
4
)}`
);
if (node.attribs[i].attribName === undefined) {
console.log(
`086 attributeDuplicate(): skip ${node.attribs[i]} because it's not an attribute`
);
continue;
}
if (!attrsGatheredSoFar.has(node.attribs[i].attribName)) {
attrsGatheredSoFar.add(node.attribs[i].attribName);
console.log(
`087 attributeDuplicate(): attrsGatheredSoFar = ${JSON.stringify(
attrsGatheredSoFar,
`093 attributeDuplicate(): attrsGatheredSoFar = ${JSON.stringify(
[...attrsGatheredSoFar],
null,
4
)}`
Expand All @@ -101,7 +107,7 @@ const attributeDuplicate: AttributeDuplicate = (context) => {
))
) {
console.log(
`104 attributeDuplicate(): RAISE ERROR FOR "${node.attribs[i].attribName}"`
`110 attributeDuplicate(): RAISE ERROR FOR "${node.attribs[i].attribName}"`
);
context.report({
ruleId: "attribute-duplicate",
Expand All @@ -113,7 +119,7 @@ const attributeDuplicate: AttributeDuplicate = (context) => {
} else {
mergeableAttrsCaught.add(node.attribs[i].attribName);
console.log(
`116 attributeDuplicate(): ${`\u001b[${32}m${`PUSH`}\u001b[${39}m`} ${`\u001b[${33}m${`mergeableAttrsCaught`}\u001b[${39}m`} now = ${JSON.stringify(
`122 attributeDuplicate(): ${`\u001b[${32}m${`PUSH`}\u001b[${39}m`} ${`\u001b[${33}m${`mergeableAttrsCaught`}\u001b[${39}m`} now = ${JSON.stringify(
mergeableAttrsCaught,
null,
4
Expand All @@ -127,7 +133,7 @@ const attributeDuplicate: AttributeDuplicate = (context) => {
console.log(` `);
console.log(` `);
console.log(` `);
console.log(`130 PROCESS EACH MERGEABLE ATTRIBUTE SEPARATELY`);
console.log(`136 PROCESS EACH MERGEABLE ATTRIBUTE SEPARATELY`);
console.log(` `);
console.log(` `);
console.log(` `);
Expand All @@ -136,7 +142,7 @@ const attributeDuplicate: AttributeDuplicate = (context) => {
console.log(` ====== `);
console.log(` `);
console.log(
`139 attributeDuplicate(): ${`\u001b[${32}m${`PROCESS`}\u001b[${39}m`} ${`\u001b[${33}m${`attrNameBeingMerged`}\u001b[${39}m`} = ${JSON.stringify(
`145 attributeDuplicate(): ${`\u001b[${32}m${`PROCESS`}\u001b[${39}m`} ${`\u001b[${33}m${`attrNameBeingMerged`}\u001b[${39}m`} = ${JSON.stringify(
attrNameBeingMerged,
null,
4
Expand All @@ -157,7 +163,7 @@ const attributeDuplicate: AttributeDuplicate = (context) => {
for (let i = 0, len = node.attribs.length; i < len; i++) {
if (node.attribs[i].attribName === attrNameBeingMerged) {
console.log(
`160 attributeDuplicate(): ███ node.attribs[${i}] = ${JSON.stringify(
`166 attributeDuplicate(): ███ node.attribs[${i}] = ${JSON.stringify(
node.attribs[i],
null,
4
Expand Down Expand Up @@ -188,15 +194,15 @@ const attributeDuplicate: AttributeDuplicate = (context) => {
]);
}

console.log(`191 attributeDuplicate(): check value`);
console.log(`197 attributeDuplicate(): check value`);
if (node.attribs[i].attribValueStartsAt) {
console.log(`193 attributeDuplicate(): split by whitespace`);
console.log(`199 attributeDuplicate(): split by whitespace`);
// either way, extract the values, split by whitespace
splitByWhitespace(
node.attribs[i].attribValueRaw,
([from, to]) => {
console.log(
`199 attributeDuplicate(): * incoming: ${`\u001b[${33}m${`[${from}, ${to}]`}\u001b[${39}m`} ("${node.attribs[
`205 attributeDuplicate(): * incoming: ${`\u001b[${33}m${`[${from}, ${to}]`}\u001b[${39}m`} ("${node.attribs[
i
].attribValueRaw.slice(from, to)}")`
);
Expand All @@ -210,21 +216,21 @@ const attributeDuplicate: AttributeDuplicate = (context) => {
}

console.log(
`213 attributeDuplicate(): ${`\u001b[${35}m${`theFirstRange`}\u001b[${39}m`} = ${JSON.stringify(
`219 attributeDuplicate(): ${`\u001b[${35}m${`theFirstRange`}\u001b[${39}m`} = ${JSON.stringify(
theFirstRange,
null,
4
)}`
);
console.log(
`220 attributeDuplicate(): ${`\u001b[${35}m${`extractedValues`}\u001b[${39}m`} = ${JSON.stringify(
`226 attributeDuplicate(): ${`\u001b[${35}m${`extractedValues`}\u001b[${39}m`} = ${JSON.stringify(
extractedValues,
null,
4
)}`
);
console.log(
`227 attributeDuplicate(): ${`\u001b[${35}m${`allOtherRanges`}\u001b[${39}m`} = ${JSON.stringify(
`233 attributeDuplicate(): ${`\u001b[${35}m${`allOtherRanges`}\u001b[${39}m`} = ${JSON.stringify(
allOtherRanges,
null,
4
Expand All @@ -234,21 +240,21 @@ const attributeDuplicate: AttributeDuplicate = (context) => {
const mergedValue = extractedValues.sort().join(" ");

console.log(
`237 attributeDuplicate(): ${`\u001b[${33}m${`mergedValue`}\u001b[${39}m`} = ${JSON.stringify(
`243 attributeDuplicate(): ${`\u001b[${33}m${`mergedValue`}\u001b[${39}m`} = ${JSON.stringify(
mergedValue,
null,
4
)}`
);
console.log(
`244 attributeDuplicate(): ${`\u001b[${33}m${`theFirstRange`}\u001b[${39}m`} = ${JSON.stringify(
`250 attributeDuplicate(): ${`\u001b[${33}m${`theFirstRange`}\u001b[${39}m`} = ${JSON.stringify(
theFirstRange,
null,
4
)}`
);
console.log(
`251 attributeDuplicate(): ${`\u001b[${33}m${`allOtherRanges`}\u001b[${39}m`} = ${JSON.stringify(
`257 attributeDuplicate(): ${`\u001b[${33}m${`allOtherRanges`}\u001b[${39}m`} = ${JSON.stringify(
allOtherRanges,
null,
4
Expand All @@ -257,18 +263,18 @@ const attributeDuplicate: AttributeDuplicate = (context) => {

// finally, raise the error:
console.log(
`260 attributeDuplicate(): RAISE ERROR FOR "${attrNameBeingMerged}"`
`266 attributeDuplicate(): RAISE ERROR FOR "${attrNameBeingMerged}"`
);
console.log(
`263 attributeDuplicate(): REPORT RANGES: ${JSON.stringify(
`269 attributeDuplicate(): REPORT RANGES: ${JSON.stringify(
[[...theFirstRange, mergedValue], ...allOtherRanges],
null,
4
)}`
);
if (mergedValue && mergedValue.length) {
console.log(
`271 attributeDuplicate(): merged value will be used`
`277 attributeDuplicate(): merged value will be used`
);

const ranges = prepLast(
Expand All @@ -281,7 +287,7 @@ const attributeDuplicate: AttributeDuplicate = (context) => {
]) as Range[]
);
console.log(
`284 attributeDuplicate(): ${`\u001b[${33}m${`ranges`}\u001b[${39}m`} = ${JSON.stringify(
`290 attributeDuplicate(): ${`\u001b[${33}m${`ranges`}\u001b[${39}m`} = ${JSON.stringify(
ranges,
null,
4
Expand All @@ -298,14 +304,14 @@ const attributeDuplicate: AttributeDuplicate = (context) => {
},
});
} else {
console.log(`301 attributeDuplicate(): no value to use!`);
console.log(`307 attributeDuplicate(): no value to use!`);
// remove all attributes of this kind

const ranges = prepLast(
rMerge([[...theFirstRange], ...allOtherRanges]) as Range[]
);
console.log(
`308 attributeDuplicate(): ${`\u001b[${33}m${`ranges`}\u001b[${39}m`} = ${JSON.stringify(
`314 attributeDuplicate(): ${`\u001b[${33}m${`ranges`}\u001b[${39}m`} = ${JSON.stringify(
ranges,
null,
4
Expand Down

0 comments on commit 110d1f4

Please sign in to comment.