Skip to content

Commit

Permalink
fix: do not fail on empty # and #top fragments
Browse files Browse the repository at this point in the history
The empty "#" and "#top" fragments are always valid without related HTML element. Browser will scroll to the top of the page. Hence lychee must not fail on those.

Credits go to @thiru-appitap for initial attempt and helping to find missing parts of the implementation.

Solves: lycheeverse#1599

Signed-off-by: MichaIng <micha@dietpi.com>
  • Loading branch information
MichaIng committed Jan 13, 2025
1 parent a11d515 commit f8a0b1d
Show file tree
Hide file tree
Showing 4 changed files with 19 additions and 9 deletions.
2 changes: 2 additions & 0 deletions fixtures/fragments/file.html
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
<a href="#Upper-ÄÖö">back to Upper-ÄÖö</a><br>
<a href="#Upper-%C3%84%C3%96%C3%B6">back to öüä encoded</a><br>
<a href="#in-the-end">doesn't exist</a><br>
<a href="#">To the top</a><br>
<a href="#top">To the top alt</a><br>
</section>
</body>
</html>
8 changes: 8 additions & 0 deletions fixtures/fragments/file1.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,4 +54,12 @@ Therefore we put the test into a code block for now to prevent false positives.
[Link to umlauts wrong case](#fünf-sÜße-Äpfel)
[Link to umlauts with percent encoding](#f%C3%BCnf-s%C3%BC%C3%9Fe-%C3%A4pfel)

# To top fragments

The empty "#" and "#top" fragments are always valid
without related HTML element. Browser will scroll to the top of the page.

[Link to top of file2](file2.md#)
[Alternative link to top of file2](file2.md#top)

##### Lets wear a hat: être
6 changes: 4 additions & 2 deletions lychee-bin/tests/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1834,8 +1834,10 @@ mod cli {
.stderr(contains(
"fixtures/fragments/file1.md#kebab-case-fragment-1",
))
.stdout(contains("21 Total"))
.stdout(contains("17 OK"))
.stderr(contains("fixtures/fragments/file.html#top"))
.stderr(contains("fixtures/fragments/file2.md#top"))
.stdout(contains("25 Total"))
.stdout(contains("21 OK"))
// 4 failures because of missing fragments
.stdout(contains("4 Errors"));
}
Expand Down
12 changes: 5 additions & 7 deletions lychee-lib/src/utils/fragment_checker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,19 +59,17 @@ impl FragmentChecker {
if file_type == FileType::Markdown {
fragment_decoded = fragment_decoded.to_lowercase().into();
}
// Empty # and #top fragments are always valid, triggering the browser to scroll to top.
let is_emtpty_or_top_fragment = fragment.is_empty() || fragment.eq_ignore_ascii_case("top");
match self.cache.lock().await.entry(url_without_frag) {
Entry::Vacant(entry) => {
let content = fs::read_to_string(path).await?;
let file_frags = extractor(&content);
let contains_fragment =
file_frags.contains(fragment) || file_frags.contains(&fragment_decoded as &str);
entry.insert(file_frags);
Ok(contains_fragment)
}
Entry::Occupied(entry) => {
Ok(entry.get().contains(fragment)
|| entry.get().contains(&fragment_decoded as &str))
}
Ok(is_emtpty_or_top_fragment
|| entry.get().contains(fragment)
|| entry.get().contains(&fragment_decoded as &str)),
}
}

Expand Down

0 comments on commit f8a0b1d

Please sign in to comment.