Skip to content

Commit

Permalink
Add ref-link CSS class for undecorated ref links
Browse files Browse the repository at this point in the history
Using the "Bitter" font for body text changes the height at which text
decoration is rendered for links.  Thus the Firefox-specific hack to
hide underlines for code ref links no longer works.

This commit uses postprocessing to add a `ref-link` CSS class to code
ref links.  The `link_to` helper now also sets `ref-link` as the default
CSS class when given an `RDoc::CodeObject`.  The `ref-link` class is
styled with `text-decoration: none`.  Thus code ref links will have no
underline in all browsers.
  • Loading branch information
jonathanhefner committed Oct 18, 2023
1 parent ffa5ac5 commit 23dbe52
Show file tree
Hide file tree
Showing 7 changed files with 64 additions and 29 deletions.
2 changes: 1 addition & 1 deletion lib/rdoc/generator/template/rails/_module_nav.rhtml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
<ul class="nav__list">
<% methods.each do |rdoc_method| %>
<li><%= link_to short_name(rdoc_method), rdoc_method,
class: "nav__method-link#{"--singleton" if rdoc_method.singleton}" %></li>
class: "ref-link nav__method-link#{"--singleton" if rdoc_method.singleton}" %></li>
<% end %>
</ul>
<% end %>
26 changes: 4 additions & 22 deletions lib/rdoc/generator/template/rails/resources/css/main.css
Original file line number Diff line number Diff line change
Expand Up @@ -112,23 +112,16 @@ a {
}
}

a:has(> code):not(:has(> :not(code))) {
text-decoration: none;
}

/* TODO: Remove this hack when Firefox supports `:has()` */
@supports not selector(:has(*)) {
a code {
text-decoration: underline var(--body-bg);
}
}

.external-link {
padding-left: 1.3em;
background: url('../i/external-link.svg') no-repeat;
background-size: 1.1em;
}

.ref-link {
text-decoration: none;
}

.query-button {
border: none;
text-align: left;
Expand Down Expand Up @@ -302,13 +295,6 @@ th
border-radius: 3px;
}

/* TODO: Remove this hack when Firefox supports `:has()` */
@supports not selector(:has(*)) {
.description a code {
text-decoration: underline var(--code-bg);
}
}

@media (hover: hover) {
.description a:hover code {
box-shadow: 0 0 0 1px;
Expand Down Expand Up @@ -630,10 +616,6 @@ html {
word-break: break-word;
}

.nav__outline a {
text-decoration: underline;
}


.nav__list {
padding: 0;
Expand Down
2 changes: 1 addition & 1 deletion lib/rdoc/generator/template/rails/resources/js/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ document.addEventListener("turbo:load", () => {
const searchOutput = document.getElementById("results");
const search = new Search(searchInput, searchOutput, (url, module, method, summary) =>
`<div class="results__result">
<a class="result__link" href="${url}">
<a class="ref-link result__link" href="${url}">
<code class="result__module">${module.replaceAll("::", "::<wbr>")}</code>
<code class="result__method">${method || ""}</code>
</a>
Expand Down
16 changes: 11 additions & 5 deletions lib/sdoc/helpers.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,19 @@ module SDoc::Helpers
def link_to(text, url = nil, html_attributes = {})
url, html_attributes = nil, url if url.is_a?(Hash)
url ||= text
attribute_string = html_attributes.map { |name, value| %( #{name}="#{h value}") }.join

%(<a href="#{_link_url url}"#{attribute_string}>#{_link_body text}</a>)
end
text = _link_body(text)

if url.is_a?(RDoc::CodeObject)
url = "/#{url.path}"
default_class = "ref-link" if text.start_with?("<code>") && text.end_with?("</code>")
end

def _link_url(url)
h(url.is_a?(RDoc::CodeObject) ? "/#{url.path}" : url)
html_attributes = html_attributes.transform_keys(&:to_s)
html_attributes = { "href" => url, "class" => default_class }.compact.merge(html_attributes)

attribute_string = html_attributes.map { |name, value| %( #{name}="#{h value}") }.join
%(<a#{attribute_string}>#{text}</a>)
end

def _link_body(text)
Expand Down
9 changes: 9 additions & 0 deletions lib/sdoc/postprocessor.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ def process(rendered)

rebase_urls!(document)
version_rails_guides_urls!(document)
add_ref_link_classes!(document)
unify_h1_headings!(document)
highlight_code_blocks!(document)

Expand Down Expand Up @@ -70,6 +71,14 @@ def version_url(url, version)
uri.to_s
end

def add_ref_link_classes!(document)
document.css(".description a code").each do |element|
if element.parent.children.one?
element.parent.add_class("ref-link")
end
end
end

def unify_h1_headings!(document)
if h1 = document.at_css("#context > .description h1:first-child")
if hgroup = document.at_css("#content > hgroup")
Expand Down
18 changes: 18 additions & 0 deletions spec/helpers_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,24 @@ module Foo; class Bar; def qux; end; end; end
must_equal %(<a href="/#{code_object.path}">text</a>)
end
end

it "uses .ref-link as the default class when creating a <code> link to an RDoc::CodeObject" do
rdoc_module = rdoc_top_level_for(<<~RUBY).find_module_named("Foo::Bar")
module Foo; module Bar; end
RUBY

_(@helpers.link_to(rdoc_module)).
must_equal %(<a href="/#{rdoc_module.path}" class="ref-link">#{@helpers.full_name(rdoc_module)}</a>)

_(@helpers.link_to("<code>Bar</code>", rdoc_module)).
must_equal %(<a href="/#{rdoc_module.path}" class="ref-link"><code>Bar</code></a>)

_(@helpers.link_to("<code>Bar</code>", rdoc_module, class: "other")).
must_equal %(<a href="/#{rdoc_module.path}" class="other"><code>Bar</code></a>)

_(@helpers.link_to("Jump to <code>Bar</code>", rdoc_module)).
must_equal %(<a href="/#{rdoc_module.path}">Jump to <code>Bar</code></a>)
end
end

describe "#link_to_if" do
Expand Down
20 changes: 20 additions & 0 deletions spec/postprocessor_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,26 @@
end
end

it "adds .ref-link class to code ref links" do
rendered = <<~HTML
<div class="description">
<a href="classes/Foo.html"><code>Foo</code></a>
<a href="classes/Foo.html">not ref link</a>
<a href="classes/Foo.html">not <code>ref</code> link</a>
</div>
HTML

expected = <<~HTML
<div class="description">
<a href="classes/Foo.html" class="ref-link"><code>Foo</code></a>
<a href="classes/Foo.html">not ref link</a>
<a href="classes/Foo.html">not <code>ref</code> link</a>
</div>
HTML

_(SDoc::Postprocessor.process(rendered)).must_include expected
end

it "unifies <h1> headings for a context" do
rendered = <<~HTML
<div id="content">
Expand Down

0 comments on commit 23dbe52

Please sign in to comment.