Skip to content

Commit 41f3b22

Browse files
committed
fix: correctly ignore class values in HTML
Signed-off-by: Joseph Kato <joseph@jdkato.io> #1086
1 parent 046a128 commit 41f3b22

File tree

7 files changed

+395
-26
lines changed

7 files changed

+395
-26
lines changed

internal/lint/walk.go

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,13 +34,18 @@ type walker struct {
3434

3535
begin int
3636
end int
37+
38+
// ext holds the file extension of the current file.
39+
ext string
3740
}
3841

3942
func newWalker(f *core.File, raw []byte, offset int) *walker {
4043
return &walker{
4144
lines: len(f.Lines) + offset,
4245
context: string2ByteSlice(f.Content),
43-
z: html.NewTokenizer(bytes.NewReader(raw))}
46+
z: html.NewTokenizer(bytes.NewReader(raw)),
47+
ext: f.NormedExt,
48+
}
4449
}
4550

4651
func (w *walker) sub(sub string, char rune) bool {
@@ -137,10 +142,20 @@ func (w *walker) walk() (html.TokenType, html.Token, string) {
137142

138143
func (w *walker) replaceToks(tok html.Token) {
139144
tags := core.StringInSlice(tok.Data, []string{
140-
"img", "a", "p", "script", "h1", "h2", "h3", "h4", "h5", "h6"})
145+
"img", "a", "p", "script", "h1", "h2", "h3", "h4", "h5", "h6", "span"})
141146
if tags {
147+
names := []string{"href", "id", "src", "alt"}
148+
if w.ext == ".html" {
149+
// We need to handle cases in which inline tags include `class` attributes, which may
150+
// contain substrings that match our actual findings. The challenge is that many of our
151+
// supported formats inject these *after* converting to HTML, so we can't find them in
152+
// the original text.
153+
//
154+
// See testdata/fixtures/patterns/{test2.rst, test3.html} for examples.
155+
names = append(names, "class")
156+
}
142157
for _, a := range tok.Attr {
143-
if core.StringInSlice(a.Key, []string{"href", "id", "src", "alt"}) {
158+
if core.StringInSlice(a.Key, names) {
144159
if a.Key == "href" {
145160
a.Val, _ = url.QueryUnescape(a.Val)
146161
}

testdata/features/patterns.feature

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,17 @@ Feature: IgnorePatterns
5353
When I test patterns for "test.html"
5454
Then the output should contain exactly:
5555
"""
56-
test.html:22:11:Vale.Repetition:'bye' is repeated!
56+
test.html:22:13:Vale.Repetition:'bye' is repeated!
57+
"""
58+
And the exit status should be 1
59+
60+
Scenario: HTML with Ignored Classes
61+
When I test patterns for "test3.html"
62+
Then the output should contain exactly:
63+
"""
64+
test3.html:30:75:write-good.We:Try to avoid using first-person plural like 'us'.
65+
test3.html:32:98:Vale.Spelling:Did you really mean 'hasChildren'?
66+
test3.html:33:64:write-good.We:Try to avoid using first-person plural like 'us'.
5767
"""
5868
And the exit status should be 1
5969

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,14 @@ MinAlertLevel = suggestion
44
IgnoredScopes = code, tt, strong, text.comment.line
55
IgnoredClasses = metrics, blurb, alignedsummary
66

7-
[*]
7+
[*.{md,rst,adoc,org,html,py}]
88
BasedOnStyles = Vale
99

10-
[*.{md,rst,adoc,org,mdx}]
10+
[test3.html]
11+
write-good.We = YES
12+
Vale.Repetition = NO
13+
14+
[*.{md,rst,adoc,org,mdx,py}]
1115
TokenIgnores = (\$+?[^\d][^\n$]+\$+?), (<http[^\n]+>+?)
1216
IgnorePatterns = (?s) *({{< ?file(?:-excerpt)? [^>]* ?>}}.*?{{< ?/file(?:-excerpt)? ?>}})
1317

testdata/fixtures/patterns/test.html

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -13,29 +13,29 @@
1313
</div>
1414

1515
<div class="blurb">
16-
<svg>...</svg>
17-
Thanks! bye bye
16+
<svg>...</svg>
17+
Thanks! bye bye
1818
</div>
1919

2020
<div class="okay">
21-
<svg>...</svg>
22-
Thanks! bye bye
21+
<svg>...</svg>
22+
Thanks! bye bye
2323
</div>
2424

2525
<table class="blurb">
26-
<tr>
27-
<th>Company</th>
28-
<th>Contact</th>
29-
<th>Country</th>
30-
</tr>
31-
<tr>
32-
<td>Alfreds Futterkiste</td>
33-
<td>Maria Anders</td>
34-
<td>Germany</td>
35-
</tr>
36-
<tr>
37-
<td>Centro comercial Moctezuma</td>
38-
<td>Francisco Chang</td>
39-
<td>Mexico</td>
40-
</tr>
41-
</table>
26+
<tr>
27+
<th>Company</th>
28+
<th>Contact</th>
29+
<th>Country</th>
30+
</tr>
31+
<tr>
32+
<td>Alfreds Futterkiste</td>
33+
<td>Maria Anders</td>
34+
<td>Germany</td>
35+
</tr>
36+
<tr>
37+
<td>Centro comercial Moctezuma</td>
38+
<td>Francisco Chang</td>
39+
<td>Mexico</td>
40+
</tr>
41+
</table>
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
<html lang="en">
2+
3+
<body class="qt-design-system" style="background:var(--content-bg-color)" onload="prettyPrint()">
4+
<div data-global-resource-path="qt-design-system/components/b-sidebar.html">
5+
<div class="b-sidebar b-sidebar--full-width">
6+
<div class="b-sidebar__content">
7+
<div class="b-sidebar__content__wrapper">
8+
<article class="b-sidebar__content__left">
9+
<div class="context mainContent" style="margin: 0;padding: 0; background: 0;">
10+
11+
12+
<div class="context">
13+
14+
<div class="table">
15+
<table class="alignedsummary requisites" translate="no">
16+
<tr>
17+
<td class="memItemRight bottomAlign"><span
18+
class="status preliminary"></span></td>
19+
</tr>
20+
</table>
21+
</div>
22+
23+
<div>
24+
<p><a href="">data</a>
25+
<a href="">at</a> <a href="">data</a>, <a href="">at</a>
26+
<a href="">at</a>
27+
</p>
28+
</div>
29+
30+
<p>Iterating over the mutable rows allows us to modify individual items.</p>
31+
<p>When iterating over a tree, the row wrapper has two additional member functions,
32+
<a href="qrangemodeladapter.html#hasChildren" translate="no">hasChildren</a>()
33+
and children(), that allow us to traverse the entire tree using iterators.
34+
</p>
35+
36+
</div>
37+
38+
</article>
39+
40+
</div>
41+
</div>
42+
</div>
43+
</div>
44+
45+
</body>
46+
47+
</html>

0 commit comments

Comments
 (0)