Skip to content

Commit d0e2ead

Browse files
Replace navigation tree
The current navigation tree suffers from several problems: * From a UX perspective, when a navigation tree has many levels, interacting with the tree becomes tedious. Likewise, when a tree is very long, scanning becomes more difficult and it is easy to lose track of where you are in the hierarchy. For projects like Rails, the navigation tree has many levels and is very long. * The navigation tree uses JavaScript to navigate to pages instead of actual links. From a UX perspective, this can be frustrating when the user expects the entries to behave like links, such as when right-clicking or Ctrl+clicking. From an SEO perspective, it can be harmful because search engines cannot crawl the entries. * The CSS for the navigation tree is very brittle. The tree uses a repeating background image to achieve its striping effect, and requires entries to be a specific height to align with the background. This makes it difficult to change anything related to size, such as font size or even font family. * In terms of page rendering costs, the navigation tree can be very heavy for large projects. For Rails, the navigation tree adds several thousand nodes to the DOM. Furthermore, the tree is rendered entirely via JavaScript -- no static HTML -- which compounds the cost. This commit replaces the navigation tree with a static sidebar per page. For the main page, the sidebar will display a list of top-level modules and a heading-based outline for the main page content. For other prose files (such as `README` files), the sidebar will similarly display a heading-based outline. For modules, the sidebar will display a list of their methods, as well as a heading-based outline if the module has a top-level comment that includes headings. The `filter.svg` file is from [Feather icons][feather] v4.29.0, and is [licensed under the MIT license][license]. [feather]: https://feathericons.com/ [license]: https://github.com/feathericons/feather/blob/v4.29.0/LICENSE
1 parent 8e3384e commit d0e2ead

24 files changed

+375
-724
lines changed

lib/rdoc/generator/template/rails/_context.rhtml

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -42,26 +42,6 @@
4242
</ul>
4343
<% end %>
4444

45-
<% unless @context.method_list.empty? %>
46-
<!-- Method ref -->
47-
<div class="content__divider">Methods</div>
48-
<dl class="methods">
49-
<% group_by_first_letter(@context.method_list).each do |letter, methods| %>
50-
<dt><%= letter %></dt>
51-
<dd>
52-
<ul>
53-
<% methods.each_with_index do |method, i| %>
54-
<%
55-
comma = methods.size == i+1 ? '' : ','
56-
%>
57-
<li><%= link_to short_name(method), method %><%= comma %></li>
58-
<% end %>
59-
</ul>
60-
</dd>
61-
<% end %>
62-
</dl>
63-
<% end %>
64-
6545

6646

6747
<% @context.each_section do |section, constants, attributes| %>
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<% if @context.text? %>
2+
<div class="nav__outline">
3+
<%= outline(@context) %>
4+
</div>
5+
<% else %>
6+
<ul class="nav__list">
7+
<% @context.each_classmodule do |rdoc_module| %>
8+
<li><%= button_to_search rdoc_module %></li>
9+
<% end %>
10+
</ul>
11+
<% end %>

lib/rdoc/generator/template/rails/_head.rhtml

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,11 @@
11
<%= base_tag_for_context(@context) %>
22

3-
<link rel="stylesheet" href="/css/panel.css" type="text/css" media="screen" />
43
<link rel="stylesheet" href="/css/main.css" type="text/css" media="screen" />
54
<link rel="stylesheet" href="/css/highlight.css" type="text/css" media="screen" />
65

76
<script src="/js/jquery-3.5.1.min.js" type="text/javascript"></script>
87
<script src="/js/main.js" type="module"></script>
98
<script src="/js/@hotwired--turbo.js" type="module"></script>
10-
<script src="/panel/tree.js" type="text/javascript"></script>
11-
<script src="/js/searchdoc.js" type="text/javascript"></script>
12-
<meta name="data-tree-keys" content='<%= tree_keys %>'>
139

1410
<% if canonical = canonical_url(@context) %>
1511
<link rel="canonical" href="<%= canonical %>" />
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<div class="nav__outline">
2+
<%= outline(@context) %>
3+
</div>
4+
5+
<div class="nav__heading">Modules</div>
6+
<ul class="nav__list">
7+
<% top_modules(@context.store).each do |rdoc_module| %>
8+
<li><%= link_to rdoc_module %></li>
9+
<% end %>
10+
</ul>
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<%= button_to_search @context, display_name: short_name(@context) %>
2+
3+
<% if outline = outline(@context) %>
4+
<div class="nav__outline">
5+
<%= outline %>
6+
</div>
7+
<% end %>
8+
9+
<% unless (methods = module_methods(@context)).empty? %>
10+
<div class="nav__heading">Methods</div>
11+
<ul class="nav__list">
12+
<% methods.each do |rdoc_method| %>
13+
<li><%= link_to short_name(rdoc_method), rdoc_method,
14+
class: "nav__method-link#{"--singleton" if rdoc_method.singleton}" %></li>
15+
<% end %>
16+
</ul>
17+
<% end %>

lib/rdoc/generator/template/rails/_panel.rhtml

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,18 +13,16 @@
1313

1414
<input id="panel__state" type="checkbox">
1515

16-
<div id="panel__tray" class="panel__tray" data-turbo-permanent>
16+
<div class="panel__tray">
1717
<input id="search" class="panel__search" type="text"
1818
tabindex="-1" autocomplete="off" autosave="searchdoc"
19-
placeholder="Search (/) for a class, method, ...">
19+
placeholder="Search (/) for a class, method, ..."
20+
data-turbo-permanent>
2021

21-
<div id="results" class="panel__results"></div>
22+
<div id="results" class="panel__results" data-turbo-permanent></div>
2223

23-
<div class="panel__tree">
24-
<div class="tree">
25-
<ul>
26-
</ul>
27-
</div>
24+
<div class="panel__nav content">
25+
<% yield if block_given? %>
2826
</div>
2927

3028
<a id="links" href="/panel/file_links.html">index</a>

lib/rdoc/generator/template/rails/class.rhtml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
<meta charset="<%= @options.charset %>">
55
<title><%= page_title @context.full_name %></title>
66
<meta name="viewport" content="width=device-width,initial-scale=1">
7-
<% inline "_head.rhtml", { :tree_keys => @context.full_name.split('::') } %>
7+
<% inline "_head.rhtml" %>
88

99
<meta property="og:title" value="<%= og_title @context.full_name %>">
1010
</head>
@@ -13,9 +13,9 @@
1313
<a class="sr-only sr-only-focusable" href="#context" data-turbo="false">Skip to Content</a>
1414
<a class="sr-only sr-only-focusable" href="#search" data-turbo="false">Skip to Search</a>
1515

16-
<% inline "_panel.rhtml" %>
16+
<% inline("_panel.rhtml") { inline("_module_nav.rhtml") } %>
1717

18-
<main id="content">
18+
<main id="content" class="content">
1919
<hgroup class="content__title">
2020
<h1><span class="kind"><%= @context.type %></span> <%= module_breadcrumbs @context %></h1>
2121
</hgroup>

lib/rdoc/generator/template/rails/file.rhtml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
<meta charset="<%= @options.charset %>">
55
<title><%= page_title @context.name %></title>
66
<meta name="viewport" content="width=device-width,initial-scale=1">
7-
<% inline "_head.rhtml", { :tree_keys => [] } %>
7+
<% inline "_head.rhtml" %>
88

99
<meta property="og:title" value="<%= og_title @context.name %>">
1010
</head>
@@ -13,9 +13,9 @@
1313
<a class="sr-only sr-only-focusable" href="#context" data-turbo="false">Skip to Content</a>
1414
<a class="sr-only sr-only-focusable" href="#search" data-turbo="false">Skip to Search</a>
1515

16-
<% inline "_panel.rhtml" %>
16+
<% inline("_panel.rhtml") { inline("_file_nav.rhtml") } %>
1717

18-
<main id="content">
18+
<main id="content" class="content">
1919
<div class="content__title">
2020
<%= "<h1>" if @context.comment.empty? %>
2121
<%= full_name @context %>

lib/rdoc/generator/template/rails/index.rhtml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,16 @@
44
<meta charset="<%= @options.charset %>">
55
<title><%= page_title %></title>
66
<meta name="viewport" content="width=device-width,initial-scale=1">
7-
<% inline "_head.rhtml", {tree_keys: []} %>
7+
<% inline "_head.rhtml" %>
88
</head>
99

1010
<body>
1111
<a class="sr-only sr-only-focusable" href="#context" data-turbo="false">Skip to Content</a>
1212
<a class="sr-only sr-only-focusable" href="#search" data-turbo="false">Skip to Search</a>
1313

14-
<% inline "_panel.rhtml" %>
14+
<% inline("_panel.rhtml") { inline("_index_nav.rhtml") } %>
1515

16-
<main id="content">
16+
<main id="content" class="content">
1717
<% inline "_context.rhtml" %>
1818
</main>
1919
</body>

lib/rdoc/generator/template/rails/resources/css/main.css

Lines changed: 95 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,27 @@ a code {
6767
background-size: 1.1em;
6868
}
6969

70+
.query-button {
71+
border: none;
72+
text-align: left;
73+
font-family: inherit;
74+
font-size: 1em;
75+
76+
background: url('../i/filter.svg') no-repeat;
77+
background-position-y: 1px;
78+
background-size: 1.1em;
79+
padding: 0 0 0 1.3em;
80+
color: var(--link-color);
81+
82+
word-break: break-word;
83+
}
84+
85+
@media (hover: hover) {
86+
.query-button:hover {
87+
color: var(--link-hover-color);
88+
}
89+
}
90+
7091
.kind {
7192
font-family: monospace;
7293
}
@@ -89,30 +110,6 @@ th
89110
font-weight: bold;
90111
}
91112

92-
.methods dt
93-
{
94-
width: 1em;
95-
font-size: 1.5em;
96-
color:#AAA;
97-
position: absolute;
98-
}
99-
100-
.methods dd
101-
{
102-
margin-top: var(--space);
103-
min-height: 1.8em;
104-
-height: 1.8em;
105-
}
106-
107-
108-
.methods ul li
109-
{
110-
margin-right: 0.7em;
111-
margin-left: 0;
112-
list-style: none;
113-
display: inline;
114-
}
115-
116113
.attr-rw {
117114
padding-right: 1em;
118115
text-align: center;
@@ -289,7 +286,7 @@ html {
289286
box-shadow: 1px 1px 4px color-mix(in srgb, currentColor 50%, transparent) inset;
290287
}
291288

292-
.panel__results, .panel__tree {
289+
.panel__results, .panel__nav {
293290
position: relative;
294291
height: calc(100dvh - var(--banner-height) - var(--search-height));
295292
width: var(--panel-width);
@@ -300,7 +297,7 @@ html {
300297
}
301298

302299
/* Force scrolling in order to always contain scroll events (on mobile) */
303-
:is(.panel__results, .panel__tree)::after {
300+
:is(.panel__results, .panel__nav)::after {
304301
content: "";
305302
height: 1px;
306303
width: 1px;
@@ -311,7 +308,7 @@ html {
311308

312309
.panel__results:not(.active),
313310
.panel__search:placeholder-shown ~ .panel__results,
314-
.panel__search:not(:placeholder-shown) ~ .panel__results.active ~ .panel__tree {
311+
.panel__search:not(:placeholder-shown) ~ .panel__results.active ~ .panel__nav {
315312
/* `display: none` disables animations, so simulate it instead */
316313
max-height: 0;
317314
max-width: 0;
@@ -320,10 +317,6 @@ html {
320317
opacity: 0;
321318
}
322319

323-
.panel__tree {
324-
overflow-x: hidden;
325-
}
326-
327320

328321
/*
329322
* Navigation panel - Search results
@@ -388,6 +381,69 @@ html {
388381
}
389382

390383

384+
/*
385+
* Navigation panel - Page nav
386+
*/
387+
388+
.panel__nav {
389+
padding: var(--space);
390+
font-size: 0.95em;
391+
line-height: calc(0.85 * var(--line-height));
392+
}
393+
394+
395+
* + .nav__outline {
396+
margin-top: var(--space-lg);
397+
}
398+
399+
.nav__outline ul {
400+
margin-top: var(--space-sm);
401+
padding-left: 1em;
402+
}
403+
404+
.nav__outline ul ul ul {
405+
display: none; /* Only show two levels deep */
406+
}
407+
408+
.nav__outline li {
409+
word-break: break-word;
410+
}
411+
412+
.nav__outline a {
413+
text-decoration: underline;
414+
}
415+
416+
417+
.nav__heading {
418+
margin-top: var(--space-lg);
419+
font-size: 1.3em;
420+
}
421+
422+
.nav__heading + .nav__list {
423+
margin-top: var(--space-sm);
424+
}
425+
426+
427+
.nav__list {
428+
padding: 0;
429+
list-style: none;
430+
}
431+
432+
.nav__list li {
433+
overflow: hidden;
434+
text-overflow: ellipsis;
435+
}
436+
437+
438+
.nav__method-link code::before {
439+
content: "#";
440+
}
441+
442+
.nav__method-link--singleton code::before {
443+
content: "::";
444+
}
445+
446+
391447
/*
392448
* Navigation panel on desktop
393449
*/
@@ -411,7 +467,7 @@ html {
411467
width: 60ch;
412468
}
413469

414-
:is(.panel__results, .panel__tree)::after {
470+
:is(.panel__results, .panel__nav)::after {
415471
display: none;
416472
}
417473
}
@@ -434,29 +490,29 @@ html {
434490
}
435491
}
436492

437-
:where(#content) *,
438-
:where(#content) :is(br, wbr) {
493+
:where(.content) *,
494+
:where(.content) :is(br, wbr) {
439495
margin: 0;
440496
}
441497

442-
:where(#content) * + * {
498+
:where(.content) * + * {
443499
margin-top: var(--space);
444500
}
445501

446-
:where(#content) :is(ol, ul, dd) {
502+
:where(.content) :is(ol, ul, dd) {
447503
padding: 0 0 0 1.25em;
448504
}
449505

450-
:where(#content) * + :is(li, dd) {
506+
:where(.content) * + :is(li, dd) {
451507
margin-top: var(--space-sm);
452508
}
453509

454510
/* Increase top margin for list items when any item has more than one paragraph */
455-
:where(#content :is(ol, ul):has(> li > p:not(:only-child))) * + li {
511+
:where(.content :is(ol, ul):has(> li > p:not(:only-child))) * + li {
456512
margin-top: var(--space);
457513
}
458514

459-
:where(#content) code {
515+
:where(.content) code {
460516
font-style: normal;
461517
}
462518

0 commit comments

Comments
 (0)