mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-10-05 07:39:16 +00:00
LibWebView: Generate hyperlinks for attributes that represent links
On the view-source page, generate anchor tags for any 'href' or 'src' attribute value we come across. This handles both when the attribute contains an absolute URL and a URL relative to the page. This requires sending the document's base URL over IPC to resolve relative URLs.
This commit is contained in:
parent
0703ba118b
commit
1aab7b51ea
Notes:
github-actions[bot]
2024-10-20 06:50:51 +00:00
Author: https://github.com/trflynn89
Commit: 1aab7b51ea
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/1861
10 changed files with 60 additions and 26 deletions
|
@ -11,6 +11,7 @@
|
|||
#include <LibURL/URL.h>
|
||||
#include <LibWeb/CSS/Parser/Token.h>
|
||||
#include <LibWeb/CSS/SyntaxHighlighter/SyntaxHighlighter.h>
|
||||
#include <LibWeb/DOMURL/DOMURL.h>
|
||||
#include <LibWeb/HTML/SyntaxHighlighter/SyntaxHighlighter.h>
|
||||
#include <LibWebView/SourceHighlighter.h>
|
||||
|
||||
|
@ -113,10 +114,10 @@ void SourceHighlighterClient::highlighter_did_set_folding_regions(Vector<Syntax:
|
|||
document().set_folding_regions(move(folding_regions));
|
||||
}
|
||||
|
||||
String highlight_source(String const& url, StringView source, Syntax::Language language, HighlightOutputMode mode)
|
||||
String highlight_source(URL::URL const& url, URL::URL const& base_url, StringView source, Syntax::Language language, HighlightOutputMode mode)
|
||||
{
|
||||
SourceHighlighterClient highlighter_client { source, language };
|
||||
return highlighter_client.to_html_string(url, mode);
|
||||
return highlighter_client.to_html_string(url, base_url, mode);
|
||||
}
|
||||
|
||||
StringView SourceHighlighterClient::class_for_token(u64 token_type) const
|
||||
|
@ -232,7 +233,7 @@ StringView SourceHighlighterClient::class_for_token(u64 token_type) const
|
|||
}
|
||||
}
|
||||
|
||||
String SourceHighlighterClient::to_html_string(String const& url, HighlightOutputMode mode) const
|
||||
String SourceHighlighterClient::to_html_string(URL::URL const& url, URL::URL const& base_url, HighlightOutputMode mode) const
|
||||
{
|
||||
StringBuilder builder;
|
||||
|
||||
|
@ -266,7 +267,7 @@ String SourceHighlighterClient::to_html_string(String const& url, HighlightOutpu
|
|||
<head>
|
||||
<meta name="color-scheme" content="dark light">)~~~"sv);
|
||||
|
||||
builder.appendff("<title>View Source - {}</title>", escape_html_entities(url));
|
||||
builder.appendff("<title>View Source - {}</title>", escape_html_entities(url.serialize_for_display()));
|
||||
builder.appendff("<style type=\"text/css\">{}</style>", HTML_HIGHLIGHTER_STYLE);
|
||||
builder.append(R"~~~(
|
||||
</head>
|
||||
|
@ -274,6 +275,22 @@ String SourceHighlighterClient::to_html_string(String const& url, HighlightOutpu
|
|||
}
|
||||
builder.append("<pre class=\"html\">"sv);
|
||||
|
||||
static constexpr auto href = to_array<u32>({ 'h', 'r', 'e', 'f' });
|
||||
static constexpr auto src = to_array<u32>({ 's', 'r', 'c' });
|
||||
bool linkify_attribute = false;
|
||||
|
||||
auto resolve_url_for_attribute = [&](Utf32View const& attribute_value) -> Optional<URL::URL> {
|
||||
if (!linkify_attribute)
|
||||
return {};
|
||||
|
||||
auto attribute_url = MUST(String::formatted("{}", attribute_value));
|
||||
auto attribute_url_without_quotes = attribute_url.bytes_as_string_view().trim("\""sv);
|
||||
|
||||
if (auto resolved = Web::DOMURL::parse(attribute_url_without_quotes, base_url); resolved.is_valid())
|
||||
return resolved;
|
||||
return {};
|
||||
};
|
||||
|
||||
size_t span_index = 0;
|
||||
for (size_t line_index = 0; line_index < document().line_count(); ++line_index) {
|
||||
auto& line = document().line(line_index);
|
||||
|
@ -286,11 +303,27 @@ String SourceHighlighterClient::to_html_string(String const& url, HighlightOutpu
|
|||
size_t length = end - start;
|
||||
if (length == 0)
|
||||
return;
|
||||
|
||||
auto text = line_view.substring_view(start, length);
|
||||
|
||||
if (span.has_value()) {
|
||||
bool append_anchor_close = false;
|
||||
|
||||
if (span->data == to_underlying(Web::HTML::AugmentedTokenKind::AttributeName)) {
|
||||
linkify_attribute = text == Utf32View { href } || text == Utf32View { src };
|
||||
} else if (span->data == to_underlying(Web::HTML::AugmentedTokenKind::AttributeValue)) {
|
||||
if (auto href = resolve_url_for_attribute(text); href.has_value()) {
|
||||
builder.appendff("<a href=\"{}\">", *href);
|
||||
append_anchor_close = true;
|
||||
}
|
||||
}
|
||||
|
||||
start_token(span->data);
|
||||
append_escaped(text);
|
||||
end_token();
|
||||
|
||||
if (append_anchor_close)
|
||||
builder.append("</a>"sv);
|
||||
} else {
|
||||
append_escaped(text);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue