mirror of
https://github.com/danog/sass-site.git
synced 2024-11-27 04:24:50 +01:00
Avoid an unstyled rendering moment with the tables of contents
Tables of contents are now statically rendered in their appropriately open/closed states, rather than updated via JavaScript, so they render correctly on the first page load. In order to make the "page sections" table still usable without JS, this adds a stylesheet in a <noscript> tag that forces the sections into an open state.
This commit is contained in:
parent
ce9244b504
commit
e7ffef4fc9
15
config.rb
15
config.rb
@ -58,12 +58,11 @@ before_render do |body, page, _, template_class|
|
|||||||
if current_page.data.table_of_contents &&
|
if current_page.data.table_of_contents &&
|
||||||
template_class == Middleman::Renderers::RedcarpetTemplate
|
template_class == Middleman::Renderers::RedcarpetTemplate
|
||||||
markdown = Redcarpet::Markdown.new(Redcarpet::Render::HTML_TOC.new)
|
markdown = Redcarpet::Markdown.new(Redcarpet::Render::HTML_TOC.new)
|
||||||
toc = markdown.render(body).sub(/<ul( |>)/, '<ul class="table-of-contents"\1')
|
fragment = Nokogiri::HTML::DocumentFragment.parse(markdown.render(body))
|
||||||
|
|
||||||
# The JS API's header names are uniquely large and difficult to break up
|
# The JS API's header names are uniquely large and difficult to break up
|
||||||
# effectively. We do some post-processing to clean them up.
|
# effectively. We do some post-processing to clean them up.
|
||||||
if page.start_with?("js-api.")
|
if page.start_with?("js-api.")
|
||||||
fragment = Nokogiri::HTML::DocumentFragment.parse(toc)
|
|
||||||
fragment.css("a code").each do |code|
|
fragment.css("a code").each do |code|
|
||||||
code.content = code.content.
|
code.content = code.content.
|
||||||
gsub(/^types\.[A-Za-z]+\./, '').
|
gsub(/^types\.[A-Za-z]+\./, '').
|
||||||
@ -71,10 +70,18 @@ before_render do |body, page, _, template_class|
|
|||||||
gsub(/^new types\./, 'new ').
|
gsub(/^new types\./, 'new ').
|
||||||
gsub(/\(.+\)$/, '()')
|
gsub(/\(.+\)$/, '()')
|
||||||
end
|
end
|
||||||
toc = fragment.to_html
|
|
||||||
end
|
end
|
||||||
|
|
||||||
current_page.add_metadata(table_of_contents: toc)
|
# Modify the default Markdown table of contents to have overview links and
|
||||||
|
# section classes.
|
||||||
|
fragment.css("li > ul").each do |ul|
|
||||||
|
a = ul.parent.elements.first
|
||||||
|
a.add_class("section")
|
||||||
|
ul.elements.before('<li class="overview"><a>Overview</a></li>')
|
||||||
|
ul.elements.first.elements.first['href'] = a['href']
|
||||||
|
end
|
||||||
|
|
||||||
|
current_page.add_metadata(table_of_contents: fragment.to_html)
|
||||||
body
|
body
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -52,21 +52,34 @@ module SassHelpers
|
|||||||
end
|
end
|
||||||
|
|
||||||
def documentation_toc
|
def documentation_toc
|
||||||
_toc_level(data.documentation.toc)
|
_toc_level(nil, data.documentation.toc)
|
||||||
end
|
end
|
||||||
|
|
||||||
def _toc_level(links)
|
def _toc_level(parent_href, links)
|
||||||
content_tag(:ul, links.map do |link|
|
if parent_href
|
||||||
children = link[:children]
|
overview = content_tag(:li,
|
||||||
text = link.keys.reject {|k| k == :children}.first
|
content_tag(:a, "Overview", href: parent_href,
|
||||||
href = link[text]
|
class: ("selected" if current_page.url == parent_href + ".html")),
|
||||||
|
class: "overview")
|
||||||
|
end
|
||||||
|
|
||||||
content_tag(:li, [
|
content_tag(:ul, [
|
||||||
content_tag(:a, text, href: href,
|
overview,
|
||||||
class: ("open selected" if current_page.url.start_with?(href))),
|
*links.map do |link|
|
||||||
(_toc_level(children) if children)
|
children = link[:children]
|
||||||
].compact)
|
text = link.keys.reject {|k| k == :children}.first
|
||||||
end)
|
href = link[text]
|
||||||
|
|
||||||
|
content_tag(:li, [
|
||||||
|
content_tag(:a, text, href: href,
|
||||||
|
class: [
|
||||||
|
("section" if children),
|
||||||
|
("open selected" if current_page.url.start_with?(href))
|
||||||
|
].compact.join(" ")),
|
||||||
|
(_toc_level(href, children) if children)
|
||||||
|
].compact)
|
||||||
|
end
|
||||||
|
].compact)
|
||||||
end
|
end
|
||||||
|
|
||||||
# Renders a code example.
|
# Renders a code example.
|
||||||
|
@ -51,14 +51,15 @@
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
|
|
||||||
&:hover { background-color: $sl-color--dawn-pink; }
|
&:hover { background-color: $sl-color--dawn-pink; }
|
||||||
&.overview {
|
}
|
||||||
font-size: $sl-font-size--small;
|
|
||||||
&:not(.selected) { color: transparentize($sl-color--midnight-blue, 0.5); }
|
li.overview a {
|
||||||
}
|
font-size: $sl-font-size--small;
|
||||||
|
&:not(.selected) { color: transparentize($sl-color--midnight-blue, 0.5); }
|
||||||
}
|
}
|
||||||
|
|
||||||
li a {
|
li a {
|
||||||
&:not([href]) {
|
&.section {
|
||||||
&::after {
|
&::after {
|
||||||
content: "▶";
|
content: "▶";
|
||||||
float: right;
|
float: right;
|
||||||
@ -77,7 +78,7 @@
|
|||||||
|
|
||||||
&.selected {
|
&.selected {
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
&[href] { background-color: $sl-color--dawn-pink; }
|
&:not(.section) { background-color: $sl-color--dawn-pink; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
10
source/assets/css/noscript.scss
Normal file
10
source/assets/css/noscript.scss
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
// Styles that are included only when JavaScript is disabled. These override the
|
||||||
|
// default styles to make them work better without JS.
|
||||||
|
|
||||||
|
// Make the in-page table of contents fully open by default, since we can't
|
||||||
|
// dynamically expand it.
|
||||||
|
.page-sections li a.section {
|
||||||
|
&::after { transform: rotate(90deg); }
|
||||||
|
+ ul {display: block; }
|
||||||
|
}
|
||||||
|
|
@ -115,18 +115,11 @@ $(function() {
|
|||||||
|
|
||||||
$(function() {
|
$(function() {
|
||||||
$(".sl-c-list-navigation-wrapper--collapsible li > ul")
|
$(".sl-c-list-navigation-wrapper--collapsible li > ul")
|
||||||
.parent().children("a").each(function() {
|
.parent()
|
||||||
var overview = $('<li><a class="overview">Overview</a></li>\n');
|
.children("a")
|
||||||
var link = overview.children().first().attr("href", $(this).attr("href"));
|
.removeAttr("href")
|
||||||
|
.click(function() {
|
||||||
if ($(this).hasClass("selected") &&
|
$(this).toggleClass("open");
|
||||||
link[0].pathname == window.location.pathname) {
|
return false;
|
||||||
link.addClass("selected");
|
});
|
||||||
}
|
|
||||||
|
|
||||||
$(this).parent().children("ul").prepend(overview);
|
|
||||||
$(this).removeAttr("href");
|
|
||||||
}).click(function() {
|
|
||||||
$(this).toggleClass("open");
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
= stylesheet_link_tag 'https://cdn.jsdelivr.net/npm/docsearch.js@2/dist/cdn/docsearch.min.css'
|
= stylesheet_link_tag 'https://cdn.jsdelivr.net/npm/docsearch.js@2/dist/cdn/docsearch.min.css'
|
||||||
= stylesheet_link_tag 'sass'
|
= stylesheet_link_tag 'sass'
|
||||||
= yield_content :css
|
= yield_content :css
|
||||||
|
%noscript= stylesheet_link_tag 'noscript'
|
||||||
|
|
||||||
-# Old version of analytics (https://developers.google.com/analytics/devguides/collection/gajs/).
|
-# Old version of analytics (https://developers.google.com/analytics/devguides/collection/gajs/).
|
||||||
:javascript
|
:javascript
|
||||||
|
@ -8,5 +8,5 @@
|
|||||||
- content_for :complementary do
|
- content_for :complementary do
|
||||||
%h3 Page Sections
|
%h3 Page Sections
|
||||||
|
|
||||||
%nav.sl-c-list-navigation-wrapper.sl-c-list-navigation-wrapper--collapsible
|
%nav.page-sections.sl-c-list-navigation-wrapper.sl-c-list-navigation-wrapper--collapsible
|
||||||
= current_page.metadata[:table_of_contents]
|
= current_page.metadata[:table_of_contents]
|
||||||
|
Loading…
Reference in New Issue
Block a user