just-the-docs 0.5.4 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 986143230e171f827a5a5b1305f3e3f90483b528098811ea2abe8732dcf0ea55
4
- data.tar.gz: f47ff09e5cbf500df3b411b496dd478a1e0f89d62daf01cab1ca7bb33a48940a
3
+ metadata.gz: d446ba90f56256475c5081e27d1a5f344210001ae32a51b180946ce22a2981ae
4
+ data.tar.gz: c77e78250f79451b833b4b5482069a978c92933e89079f0efcc67fa6f161fa38
5
5
  SHA512:
6
- metadata.gz: 38aa0de5e1e0d5c32c5769fdc4fc8cba569799c179688c755c4d33b84707a66e7546983d9e915677a74a2c57307e13c2436f62f9f4d21e4463bcee807bfeea5d
7
- data.tar.gz: 31125488864c34d27ef32875b478f642cfdb9fac73131788b1933ac47a952ea3e842990dcc55c5c282eefa5b3b4261c848c727d10be80a75e6c403f0f98a7be8
6
+ metadata.gz: 99744850f76f7660bc97b00d6fcbf2acd9f9495c466fc7c3f0a65474fcea05c94e5448f8b16be0d90f39a76e6e7f1c08bd8b64348924179421a46a40a9767c7f
7
+ data.tar.gz: 9ea114f0cd183928b053e40ba2a6474fe2936b4bfcc34b2956643ff5e6ef1c11db0b2fcb9265f830467af1e697b076a53b0e90eb24699bbdc11182a9ce67d8fb
data/CHANGELOG.md CHANGED
@@ -15,16 +15,69 @@ The project underwent a major maintenance shift in March 2022.
15
15
  {: .note }
16
16
  This website is built from the `HEAD` of the `main` branch of the theme repository.
17
17
 
18
- {: .warning }
19
- This website includes docs for some new features that are not available in `v0.5.2`!
20
-
21
18
  Code changes to `main` that are *not* in the latest release:
22
19
 
23
20
  - N/A
24
21
 
25
- Docs changes in `main` that are *not* in the latest release:
22
+ ## Release v0.6.0
26
23
 
27
- - N/A
24
+ Hi all, this is a minor release that introduces performance improvements for build times on large sites, correctly sets the `color-scheme` property, and fixes invalid HTML. However, it introduces some potentially-breaking *internal* changes to undocumented features of the theme.
25
+
26
+ ### Migrating to `v0.6.0`
27
+
28
+ **Migration**: users will need to migrate if:
29
+
30
+ - they have an existing `_includes` file named `favicon.html`, `head_nav.html`, or `css/activation.scss.liquid`
31
+ - they have code that refers to `#main-content-wrap`
32
+ - they override the default `light` theme's code, or the theme-loading logic
33
+ - they have different favicons for different pages
34
+
35
+ For more, refer to the [migration guide](https://just-the-docs.com/MIGRATION/).
36
+
37
+ ### Using Release `v0.6.0`
38
+
39
+ Users who have not pinned the theme version will be **automatically upgraded to `v0.6.0` the next time they build their site**.
40
+
41
+ To use this release explicitly as a remote theme:
42
+
43
+ ```yml
44
+ remote_theme: just-the-docs/just-the-docs@v0.6.0
45
+ ```
46
+
47
+ To use this version explicitly as a gem-based theme, pin the version in your `Gemfile` and re-run `bundle install` or `bundle update just-the-docs`:
48
+
49
+ ```ruby
50
+ gem "just-the-docs", "0.6.0"
51
+ ```
52
+
53
+ To use and pin a previous version of the theme, replace the `0.6.0` with the desired release tag.
54
+
55
+ ### New Features and Bugfixes
56
+
57
+ - Added: `$color-scheme` theme variable to specify `color-scheme` for `:root` by [@sigv] in [#1280]
58
+ - Fixed: build times for large sites by [@pdmosses] in [#1244]
59
+ - Fixed: missing closing `</button>` tag in `sidebar.html` by [@mattxwang] in [#1304]
60
+ - Fixed: removed duplicate `#main-content-wrap` minimal and default layouts by [@mattxwang] in [#1305]
61
+
62
+ ### Documentation
63
+
64
+ {: .warning }
65
+ The theme docs are unversioned, and already reflect the above changes.
66
+
67
+ Docs changes:
68
+
69
+ - A [footnote]({% link docs/configuration.md %}#fn:js-disabled) in the configuration docs explains how disabling JavaScript affects the display of navigation links when browsing folded collections.
70
+ - Invalid HTML has been removed from most documentation examples.
71
+
72
+ ### New Contributors
73
+
74
+ - [@sigv] made their first contribution in [#1280]
75
+
76
+ [@sigv]: https://github.com/sigv
77
+ [#1244]: https://github.com/just-the-docs/just-the-docs/pull/1244
78
+ [#1280]: https://github.com/just-the-docs/just-the-docs/pull/1280
79
+ [#1304]: https://github.com/just-the-docs/just-the-docs/pull/1304
80
+ [#1305]: https://github.com/just-the-docs/just-the-docs/pull/1305
28
81
 
29
82
  ## Release v0.5.4
30
83
 
@@ -1,9 +1,21 @@
1
+ {%- comment -%}
2
+ Include as: {%- include components/sidebar.html -%}
3
+ Depends on: page(?), site.
4
+ Results in: HTML for the side bar.
5
+ Includes:
6
+ title.html, nav.html, nav_footer_custom.html
7
+ Overwrites:
8
+ pages_top_size, collections_size, collection_entry,
9
+ collection_key, collection_value, collection, nav_footer_custom.
10
+ Should not be cached, because nav_footer_custom.html might depend on page.
11
+ {%- endcomment -%}
12
+
1
13
  <div class="side-bar">
2
14
  <div class="site-header" role="banner">
3
15
  <a href="{{ '/' | relative_url }}" class="site-title lh-tight">{% include title.html %}</a>
4
16
  <button id="menu-button" class="site-button btn-reset" aria-label="Toggle menu" aria-pressed="false">
5
17
  <svg viewBox="0 0 24 24" class="icon" aria-hidden="true"><use xlink:href="#svg-menu"></use></svg>
6
- </a>
18
+ </button>
7
19
  </div>
8
20
  <nav aria-label="Main" id="site-nav" class="site-nav">
9
21
  {% assign pages_top_size = site.html_pages
@@ -12,7 +24,7 @@
12
24
  | where_exp:"item", "item.nav_exclude != true"
13
25
  | size %}
14
26
  {% if pages_top_size > 0 %}
15
- {% include nav.html pages=site.html_pages key=nil %}
27
+ {% include_cached nav.html pages=site.html_pages %}
16
28
  {% endif %}
17
29
  {%- if site.nav_external_links -%}
18
30
  <ul class="nav-list">
@@ -43,15 +55,15 @@
43
55
  </button>
44
56
  {%- endif -%}
45
57
  <div class="nav-category">{{ collection_value.name }}</div>
46
- {% include nav.html pages=collection key=collection_key %}
58
+ {% include_cached nav.html pages=collection %}
47
59
  </li>
48
60
  </ul>
49
61
  {% else %}
50
62
  <div class="nav-category">{{ collection_value.name }}</div>
51
- {% include nav.html pages=collection key=collection_key %}
63
+ {% include_cached nav.html pages=collection %}
52
64
  {% endif %}
53
65
  {% else %}
54
- {% include nav.html pages=collection key=collection_key %}
66
+ {% include_cached nav.html pages=collection %}
55
67
  {% endif %}
56
68
  {% endif %}
57
69
  {% endfor %}
@@ -0,0 +1,173 @@
1
+ {%- comment -%}
2
+ Include as: {%- include css/activation.scss.liquid -%}
3
+ Depends on: page, site.
4
+ Results in: page-dependent SCSS rules for inclusion in a head style element.
5
+ Includes:
6
+ sorted_pages.html.
7
+ Overwrites:
8
+ activation_pages, activation_pages_top_size, activation_page, activation_title,
9
+ activation_first_level, activation_second_level, activation_third_level,
10
+ activation_first_level_reversed, activation_second_level_reversed,
11
+ activation_first_level_index, activation_second_level_index, activation_third_level_index.
12
+ Should not be cached, because it depends on page.
13
+ (For a site with only top-level pages, the rendering of this file is always empty.
14
+ This property could be detected, and might halve the build time for such sites.)
15
+ {%- endcomment -%}
16
+
17
+ {%- unless page.title == nil or page.nav_exclude == true -%}
18
+
19
+ {%- assign activation_pages = site[page.collection]
20
+ | default: site.html_pages
21
+ | where_exp: "item", "item.title != nil"
22
+ | where_exp: "item", "item.nav_exclude != true" -%}
23
+
24
+ {%- assign activation_first_level_index = nil -%}
25
+ {%- assign activation_second_level_index = nil -%}
26
+ {%- assign activation_third_level_index = nil -%}
27
+ {%- assign activation_first_level_reversed = nil -%}
28
+ {%- assign activation_second_level_reversed = nil -%}
29
+
30
+ {%- assign activation_title = page.grand_parent | default: page.parent | default: page.title -%}
31
+ {%- assign activation_first_level = activation_pages
32
+ | where_exp: "item", "item.parent == nil" -%}
33
+ {%- include sorted_pages.html pages = activation_first_level -%}
34
+ {%- for activation_page in sorted_pages -%}
35
+ {%- if activation_page.title == activation_title -%}
36
+ {%- assign activation_first_level_index = forloop.index -%}
37
+ {%- assign activation_first_level_reversed = activation_page.child_nav_order -%}
38
+ {%- break -%}
39
+ {%- endif -%}
40
+ {%- endfor -%}
41
+
42
+ {%- unless activation_first_level_index == nil -%}
43
+
44
+ {%- if page.grand_parent -%}
45
+ {%- assign activation_title = page.parent -%}
46
+ {%- assign activation_second_level = activation_pages
47
+ | where_exp: "item", "item.grand_parent == nil"
48
+ | where_exp: "item", "item.parent == page.grand_parent" -%}
49
+ {%- elsif page.parent -%}
50
+ {%- assign activation_title = page.title -%}
51
+ {%- assign activation_second_level = activation_pages
52
+ | where_exp: "item", "item.grand_parent == nil"
53
+ | where_exp: "item", "item.parent == page.parent" -%}
54
+ {%- endif -%}
55
+ {%- if page.parent -%}
56
+ {%- include sorted_pages.html pages = activation_second_level -%}
57
+ {%- for activation_page in sorted_pages -%}
58
+ {%- if activation_page.title == activation_title -%}
59
+ {%- assign activation_second_level_index = forloop.index -%}
60
+ {%- assign activation_second_level_reversed = activation_page.child_nav_order -%}
61
+ {%- if activation_first_level_reversed -%}
62
+ {%- assign activation_second_level_index = sorted_pages | size | plus: 1 | minus: activation_second_level_index -%}
63
+ {%- endif -%}
64
+ {%- break -%}
65
+ {%- endif -%}
66
+ {%- endfor -%}
67
+ {%- endif -%}
68
+
69
+ {%- if page.grand_parent -%}
70
+ {%- assign activation_third_level = activation_pages
71
+ | where_exp: "item", "item.parent == page.parent"
72
+ | where_exp: "item", "item.grand_parent == page.grand_parent" -%}
73
+ {%- include sorted_pages.html pages = activation_third_level -%}
74
+ {%- assign activation_third_level = sorted_pages -%}
75
+ {%- for activation_page in sorted_pages -%}
76
+ {%- if activation_page.title == page.title -%}
77
+ {%- assign activation_third_level_index = forloop.index -%}
78
+ {%- if activation_second_level_reversed -%}
79
+ {%- assign activation_third_level_index = sorted_pages | size | plus: 1 | minus: activation_third_level_index -%}
80
+ {%- endif -%}
81
+ {%- break -%}
82
+ {%- endif -%}
83
+ {%- endfor -%}
84
+ {%- endif -%}
85
+
86
+ {%- unless activation_second_level_index == nil and activation_third_level_index -%}
87
+
88
+ {%- if page.collection == nil -%}
89
+
90
+ {%- capture activation_collection_prefix -%}
91
+ .site-nav > .nav-list:nth-child(1):not(.nav-category-list)
92
+ {%- endcapture -%}
93
+
94
+ {%- else -%}
95
+
96
+ {%- for activation_collection in site.just_the_docs.collections -%}
97
+ {%- if activation_collection[0] == page.collection -%}
98
+ {%- assign activation_collection_index = forloop.index -%}
99
+ {%- break -%}
100
+ {%- endif -%}
101
+ {%- endfor -%}
102
+ {%- assign activation_index = activation_collection_index -%}
103
+ {%- assign activation_pages_top_size = site.html_pages
104
+ | where_exp:"item", "item.title != nil"
105
+ | where_exp:"item", "item.parent == nil"
106
+ | where_exp:"item", "item.nav_exclude != true"
107
+ | size -%}
108
+ {%- if activation_pages_top_size > 0 -%}
109
+ {%- assign activation_index = activation_index | plus: 1 -%}
110
+ {%- endif -%}
111
+ {%- if site.nav_external_links -%}
112
+ {%- assign activation_index = activation_index | plus: 1 -%}
113
+ {%- endif -%}
114
+ {%- capture activation_collection_prefix -%}
115
+ .site-nav > .nav-list:nth-of-type({{ activation_index }}){% if site.just_the_docs.collections[page.collection].nav_fold == true %} > .nav-list-item > .nav-list{% endif %}
116
+ {%- endcapture -%}
117
+
118
+ {%- endif -%}
119
+
120
+ // Styling for the nav-list-link to the current page:
121
+ {{ activation_collection_prefix }} {
122
+ > .nav-list-item:not(.external):nth-child({{ activation_first_level_index }}){%- if activation_second_level_index %} > .nav-list > .nav-list-item:nth-child({{ activation_second_level_index }}){%- if activation_third_level_index %} > .nav-list > .nav-list-item:nth-child({{ activation_third_level_index }}){% endif %}{% endif %} {
123
+ > .nav-list-link {
124
+ display: block;
125
+ font-weight: 600;
126
+ text-decoration: none;
127
+ background-image: linear-gradient(
128
+ -90deg,
129
+ rgba($feedback-color, 1) 0%,
130
+ rgba($feedback-color, 0.8) 80%,
131
+ rgba($feedback-color, 0) 100%
132
+ );
133
+ }
134
+ }
135
+ }
136
+
137
+ // Styling for nav-list-expanders at first and second levels,
138
+ // suppressed when a click has deactivated the expander (making the nav-list-item .passive):
139
+ {{ activation_collection_prefix }} {
140
+ > .nav-list-item:not(.passive):nth-child({{ activation_first_level_index }}){%- if activation_second_level_index %},
141
+ > .nav-list-item:not(.passive):nth-child({{ activation_first_level_index }}) > .nav-list > .nav-list-item:not(.passive):nth-child({{ activation_second_level_index }}){% endif %} {
142
+ > .nav-list-expander svg {
143
+ @if $nav-list-expander-right {
144
+ transform: rotate(-90deg);
145
+ } @else {
146
+ transform: rotate(90deg);
147
+ }
148
+ }
149
+
150
+ > .nav-list {
151
+ display: block;
152
+ }
153
+ }
154
+ }
155
+
156
+ // Styling for nav-list-expander for categories:
157
+ .site-nav > .nav-category-list > .nav-list-item:not(.passive) {
158
+ > .nav-list-expander svg {
159
+ @if $nav-list-expander-right {
160
+ transform: rotate(-90deg);
161
+ } @else {
162
+ transform: rotate(90deg);
163
+ }
164
+ }
165
+
166
+ > .nav-list {
167
+ display: block;
168
+ }
169
+ }
170
+
171
+ {%- endunless -%}
172
+ {%- endunless -%}
173
+ {%- endunless -%}
@@ -0,0 +1,23 @@
1
+ {%- comment -%}
2
+ Include as: {%- include_cached favicon.html -%}
3
+ Depends on: site.static_files.
4
+ Results in: HTML for a link to an existing `favicon.ico` file.
5
+ Overwrites:
6
+ file.
7
+
8
+ The endoflife.date site has 226 pages and 3410 static files. @marcwrobel pointed
9
+ out that the time taken by evaluating the code in this file on every page when
10
+ building that site was significant, and suggested making it optional. As it is
11
+ page-independent, it can easily be cached. Doing that reduced the time taken by
12
+ rendering `_includes/head.html` from 15.294s to 10.760s, thereby reducing the
13
+ total build time from 26.074s to 21.656s -- a saving of about 17%.
14
+ {%- endcomment -%}
15
+
16
+ {% for file in site.static_files %}
17
+ {% if file.path == site.favicon_ico or file.path == '/favicon.ico' %}
18
+ {% assign favicon = true %}
19
+ {% endif %}
20
+ {% endfor %}
21
+ {% if favicon %}
22
+ <link rel="icon" href="{{ site.favicon_ico | default: '/favicon.ico' | relative_url }}" type="image/x-icon">
23
+ {% endif %}
data/_includes/head.html CHANGED
@@ -1,8 +1,22 @@
1
+ {%- comment -%}
2
+ Include as: {%- include head.html -%}
3
+ Depends on: site.ga_tracking, site.ga_tracking_anonymize_ip,
4
+ site.search_enabled, site.static_files, site.favicon_ico.
5
+ Results in: HTML for the head element.
6
+ Includes:
7
+ head_nav.html, head_custom.html.
8
+ Overwrites:
9
+ ga_tracking_ids, ga_property, file, favicon.
10
+ Should not be cached, because included files depend on page.
11
+ {%- endcomment -%}
12
+
1
13
  <head>
2
14
  <meta charset="UTF-8">
3
15
  <meta http-equiv="X-UA-Compatible" content="IE=Edge">
4
16
 
5
17
  <link rel="stylesheet" href="{{ '/assets/css/just-the-docs-default.css' | relative_url }}">
18
+
19
+ {% include head_nav.html %}
6
20
 
7
21
  {% if site.ga_tracking != nil %}
8
22
  {% assign ga_tracking_ids = site.ga_tracking | split: "," %}
@@ -26,14 +40,7 @@
26
40
 
27
41
  <meta name="viewport" content="width=device-width, initial-scale=1">
28
42
 
29
- {% for file in site.static_files %}
30
- {% if file.path == site.favicon_ico or file.path == '/favicon.ico' %}
31
- {% assign favicon = true %}
32
- {% endif %}
33
- {% endfor %}
34
- {% if favicon %}
35
- <link rel="icon" href="{{ site.favicon_ico | default: '/favicon.ico' | relative_url }}" type="image/x-icon">
36
- {% endif %}
43
+ {% include_cached favicon.html %}
37
44
 
38
45
  {% seo %}
39
46
 
@@ -0,0 +1,48 @@
1
+ {%- comment -%}
2
+ Include as: {%- include head_nav.html -%}
3
+ Depends on: site.color_scheme.
4
+ Results in: HTML for a page-specific style element.
5
+ Includes:
6
+ css/activation.scss.liquid.
7
+ Overwrites:
8
+ activation, test_scss, scss, css, index, count.
9
+ Should not be cached, because css/activation.scss.liquid depends on page.
10
+ {%- endcomment -%}
11
+
12
+ {% capture activation %}
13
+ {% include css/activation.scss.liquid %}
14
+ {%- endcapture -%}
15
+
16
+ {% capture test_scss %}
17
+ @import "./support/support";
18
+ @import "./color_schemes/light";
19
+ {{ activation }}
20
+ {%- endcapture -%}
21
+
22
+ {%- capture scss -%}
23
+ @import "./support/support";
24
+ @import "./custom/setup";
25
+ {% if site.color_scheme and site.color_scheme != "nil" -%}
26
+ {%- assign color_scheme = site.color_scheme -%}
27
+ {%- else -%}
28
+ {%- assign color_scheme = "light" -%}
29
+ {%- endif %}
30
+ @import "./color_schemes/light";
31
+ {% unless color_scheme == "light" %}
32
+ @import "./color_schemes/{{ color_scheme }}";
33
+ {% endunless %}
34
+ {{ activation }}
35
+ {%- endcapture -%}
36
+
37
+ {%- comment -%}
38
+ Convert to CSS, then remove the color_scheme import rules to avoid duplication.
39
+ The value of count is page-dependent, but independent of custom color schemes.
40
+ {%- endcomment -%}
41
+ {%- assign count = test_scss | scssify | split: ".site-nav" | size -%}
42
+ {%- unless count == 1 %}
43
+ {%- assign index = 1 | minus: count -%}
44
+ {%- assign css = scss | scssify | split: ".site-nav" | slice: index, count | join: ".site-nav" -%}
45
+ <style type="text/css">
46
+ {{ css | prepend: ".site-nav" }}
47
+ </style>
48
+ {%- endunless %}
data/_includes/nav.html CHANGED
@@ -1,6 +1,6 @@
1
1
  {%- comment -%}
2
- Include as: {%- include nav.html pages = pages key = key -%}
3
- Depends on: include.pages, include.key, page, site.
2
+ Include as: {%- include_cached nav.html pages=pages -%}
3
+ Depends on: include.pages.
4
4
  Results in: HTML for the navigation panel.
5
5
  Includes:
6
6
  sorted_pages.html
@@ -15,6 +15,10 @@
15
15
 
16
16
  {%- include sorted_pages.html pages = nav_pages -%}
17
17
 
18
+ {%- comment -%}
19
+ It might be more efficient to sort the pages at each level separately.
20
+ {%- endcomment -%}
21
+
18
22
  {%- assign first_level_pages = sorted_pages
19
23
  | where_exp: "item", "item.parent == nil" -%}
20
24
  {%- assign second_level_pages = sorted_pages
@@ -23,84 +27,49 @@
23
27
  {%- assign third_level_pages = sorted_pages
24
28
  | where_exp: "item", "item.grand_parent != nil" -%}
25
29
 
26
- {%- comment -%}
27
- The order of sibling pages in `sorted_pages` determines the order of display of
28
- links to them in lists of navigation links.
29
-
30
- Note that Liquid evaluates conditions from right to left (and it does not allow
31
- the use of parentheses). Some conditions are not so easy to express clearly...
32
-
33
- For example, consider the following condition:
34
-
35
- C: page.collection = = include.key and
36
- page.url = = node.url or
37
- page.grand_parent = = node.title or
38
- page.parent = = node.title and
39
- page.grand_parent = = nil
40
-
41
- Here, `node` is a first-level page. The last part of the condition
42
- -- namely: `page.parent = = node.title and page.grand_parent = = nil` --
43
- is evaluated first; it holds if and only if `page` is a child of `node`.
44
-
45
- The condition `page.grand_parent = = node.title or ...` holds when
46
- `page` is a grandchild of node, OR `...` holds.
47
-
48
- The condition `page.url = = node.url or ...` holds when
49
- `page` is `node`, OR `...` holds.
50
-
51
- The condition C: `page.collection = = include.key and ...` holds when we are
52
- generating the nav links for a collection that includes `page`, AND `...` holds.
53
- {%- endcomment -%}
54
-
55
30
  <ul class="nav-list">
56
31
  {%- for node in first_level_pages -%}
57
- {%- unless node.nav_exclude -%}
58
- <li class="nav-list-item{% if page.collection == include.key and page.url == node.url or page.grand_parent == node.title or page.parent == node.title and page.grand_parent == nil %} active{% endif %}">
59
- {%- if node.has_children -%}
60
- <button class="nav-list-expander btn-reset" aria-label="toggle items in {{ node.title }} category" aria-pressed="{% if page.collection == include.key and page.url == node.url or page.grand_parent == node.title or page.parent == node.title and page.grand_parent == nil %}true{% else %}false{% endif %}">
61
- <svg viewBox="0 0 24 24" aria-hidden="true"><use xlink:href="#svg-arrow-right"></use></svg>
62
- </button>
63
- {%- endif -%}
64
- <a href="{{ node.url | relative_url }}" class="nav-list-link{% if page.url == node.url %} active{% endif %}">{{ node.title }}</a>
65
- {%- if node.has_children -%}
66
- {%- assign children_list = second_level_pages
67
- | where: "parent", node.title -%}
68
- {%- if node.child_nav_order == 'desc' or node.child_nav_order == 'reversed' -%}
69
- {%- assign children_list = children_list | reverse -%}
32
+ <li class="nav-list-item">
33
+ {%- if node.has_children -%}
34
+ <button class="nav-list-expander btn-reset" aria-label="toggle items in {{ node.title }} category" aria-pressed="false">
35
+ <svg viewBox="0 0 24 24" aria-hidden="true"><use xlink:href="#svg-arrow-right"></use></svg>
36
+ </button>
37
+ {%- endif -%}
38
+ <a href="{{ node.url | relative_url }}" class="nav-list-link">{{ node.title }}</a>
39
+ {%- if node.has_children -%}
40
+ {%- assign children_list = second_level_pages
41
+ | where: "parent", node.title -%}
42
+ {%- if node.child_nav_order == 'desc' or node.child_nav_order == 'reversed' -%}
43
+ {%- assign children_list = children_list | reverse -%}
44
+ {%- endif -%}
45
+ <ul class="nav-list">
46
+ {%- for child in children_list -%}
47
+ <li class="nav-list-item">
48
+ {%- if child.has_children -%}
49
+ <button class="nav-list-expander btn-reset" aria-label="toggle items in {{ child.title }} category" aria-pressed="false">
50
+ <svg viewBox="0 0 24 24" aria-hidden="true"><use xlink:href="#svg-arrow-right"></use></svg>
51
+ </button>
52
+ {%- endif -%}
53
+ <a href="{{ child.url | relative_url }}" class="nav-list-link">{{ child.title }}</a>
54
+ {%- if child.has_children -%}
55
+ {%- assign grand_children_list = third_level_pages
56
+ | where: "parent", child.title
57
+ | where: "grand_parent", node.title -%}
58
+ {%- if child.child_nav_order == 'desc' or child.child_nav_order == 'reversed' -%}
59
+ {%- assign grand_children_list = grand_children_list | reverse -%}
60
+ {%- endif -%}
61
+ <ul class="nav-list">
62
+ {%- for grand_child in grand_children_list -%}
63
+ <li class="nav-list-item">
64
+ <a href="{{ grand_child.url | relative_url }}" class="nav-list-link">{{ grand_child.title }}</a>
65
+ </li>
66
+ {%- endfor -%}
67
+ </ul>
70
68
  {%- endif -%}
71
- <ul class="nav-list">
72
- {%- for child in children_list -%}
73
- {%- unless child.nav_exclude -%}
74
- <li class="nav-list-item {% if page.url == child.url or page.parent == child.title %} active{% endif %}">
75
- {%- if child.has_children -%}
76
- <button class="nav-list-expander btn-reset" aria-label="toggle items in {{ child.title }} category" aria-pressed="{% if page.url == child.url or page.parent == child.title %}true{% else %}false{% endif %}">
77
- <svg viewBox="0 0 24 24" aria-hidden="true"><use xlink:href="#svg-arrow-right"></use></svg>
78
- </button>
79
- {%- endif -%}
80
- <a href="{{ child.url | relative_url }}" class="nav-list-link{% if page.url == child.url %} active{% endif %}">{{ child.title }}</a>
81
- {%- if child.has_children -%}
82
- {%- assign grand_children_list = third_level_pages
83
- | where: "parent", child.title
84
- | where: "grand_parent", node.title -%}
85
- {%- if child.child_nav_order == 'desc' or child.child_nav_order == 'reversed' -%}
86
- {%- assign grand_children_list = grand_children_list | reverse -%}
87
- {%- endif -%}
88
- <ul class="nav-list">
89
- {%- for grand_child in grand_children_list -%}
90
- {%- unless grand_child.nav_exclude -%}
91
- <li class="nav-list-item {% if page.url == grand_child.url %} active{% endif %}">
92
- <a href="{{ grand_child.url | relative_url }}" class="nav-list-link{% if page.url == grand_child.url %} active{% endif %}">{{ grand_child.title }}</a>
93
- </li>
94
- {%- endunless -%}
95
- {%- endfor -%}
96
- </ul>
97
- {%- endif -%}
98
- </li>
99
- {%- endunless -%}
100
- {%- endfor -%}
101
- </ul>
102
- {%- endif -%}
103
- </li>
104
- {%- endunless -%}
69
+ </li>
70
+ {%- endfor -%}
71
+ </ul>
72
+ {%- endif -%}
73
+ </li>
105
74
  {%- endfor -%}
106
75
  </ul>
@@ -1,9 +1,9 @@
1
1
  {%- comment -%}
2
- Include as: {%- include sorted_pages.html pages = pages -%}
2
+ Include as: {%- include sorted_pages.html pages=array_of_pages -%}
3
3
  Depends on: include.pages.
4
4
  Assigns to: sorted_pages.
5
5
  Overwrites:
6
- nav_order_pages, title_order_pages,
6
+ nav_order_pages, title_order_pages, double_quote, empty_array,
7
7
  nav_number_pages, nav_string_pages, nav_order_groups, group,
8
8
  title_number_pages, title_string_pages, title_order_groups.
9
9
  {%- endcomment -%}
@@ -29,29 +29,55 @@
29
29
  {%- endcomment -%}
30
30
 
31
31
  {%- assign nav_order_pages = include.pages
32
- | where_exp: "item", "item.nav_order != nil" -%}
32
+ | where_exp: "item", "item.nav_order != nil" -%}
33
33
  {%- assign title_order_pages = include.pages
34
- | where_exp: "item", "item.nav_order == nil" -%}
34
+ | where_exp: "item", "item.nav_order == nil" -%}
35
35
 
36
36
  {%- comment -%}
37
- Divide the arrays of `nav_order_pages` and `title_order_pages` according to
38
- the type of value.
37
+ First, filter `nav_order_pages` and `title_order_pages` according to the type
38
+ of value to be used for sorting.
39
39
 
40
- The first character of the result of `jsonify` is `"` only for strings.
41
- Grouping by a single character also ensures the number of groups is small.
40
+ The first character of the result of filtering with `jsonify` is `"` only for
41
+ strings. Removing `"` from its `slice : 0` has size 0 for strings and 1 for
42
+ numbers, so grouping the pages gives at most two groups.
42
43
  {%- endcomment -%}
43
44
 
44
- {%- assign nav_number_pages = "" | split: "" -%}
45
- {%- assign nav_string_pages = "" | split: "" -%}
46
- {%- assign nav_order_groups = nav_order_pages
47
- | group_by_exp: "item", "item.nav_order | jsonify | slice: 0" -%}
48
- {%- for group in nav_order_groups -%}
49
- {%- if group.name == '"' -%}
50
- {%- assign nav_string_pages = group.items -%}
51
- {%- else -%}
52
- {%- assign nav_number_pages = nav_number_pages | concat: group.items -%}
53
- {%- endif -%}
54
- {%- endfor -%}
45
+ {%- assign double_quote = '"' -%}
46
+ {%- assign empty_array = "" | split: "" -%}
47
+
48
+ {%- assign nav_string_pages = empty_array -%}
49
+ {%- assign nav_number_pages = empty_array -%}
50
+ {%- unless nav_order_pages == empty -%}
51
+ {%- assign nav_order_groups = nav_order_pages
52
+ | group_by_exp: "item",
53
+ "item.nav_order | jsonify | slice: 0 | remove: double_quote | size" -%}
54
+ {%- for group in nav_order_groups -%}
55
+ {%- if group.name == 0 -%}
56
+ {%- assign nav_string_pages = group.items -%}
57
+ {%- elsif group.name == 1 -%}
58
+ {%- assign nav_number_pages = group.items -%}
59
+ {%- endif -%}
60
+ {%- endfor -%}
61
+ {%- endunless -%}
62
+
63
+ {%- assign title_string_pages = empty_array -%}
64
+ {%- assign title_number_pages = empty_array -%}
65
+ {%- unless title_order_pages == empty -%}
66
+ {%- assign title_order_groups = title_order_pages
67
+ | group_by_exp: "item",
68
+ "item.title | jsonify | slice: 0 | remove: double_quote | size" -%}
69
+ {%- for group in title_order_groups -%}
70
+ {%- if group.name == 0 -%}
71
+ {%- assign title_string_pages = group.items -%}
72
+ {%- elsif group.name == 1 -%}
73
+ {%- assign title_number_pages = group.items -%}
74
+ {%- endif -%}
75
+ {%- endfor -%}
76
+ {%- endunless -%}
77
+
78
+ {%- comment -%}
79
+ Now sort each array of pages separately, then concatenate the sorted arrays.
80
+ {%- endcomment -%}
55
81
 
56
82
  {%- unless nav_number_pages == empty -%}
57
83
  {%- assign nav_number_pages = nav_number_pages | sort: "nav_order" -%}
@@ -65,18 +91,6 @@
65
91
  {%- endif -%}
66
92
  {%- endunless -%}
67
93
 
68
- {%- assign title_number_pages = "" | split: "" -%}
69
- {%- assign title_string_pages = "" | split: "" -%}
70
- {%- assign title_order_groups = title_order_pages
71
- | group_by_exp: "item", "item.title | jsonify | slice: 0" -%}
72
- {%- for group in title_order_groups -%}
73
- {%- if group.name == '"' -%}
74
- {%- assign title_string_pages = group.items -%}
75
- {%- else -%}
76
- {%- assign title_number_pages = title_number_pages | concat: group.items -%}
77
- {%- endif -%}
78
- {%- endfor -%}
79
-
80
94
  {%- unless title_number_pages == empty -%}
81
95
  {%- assign title_number_pages = title_number_pages | sort: "title" -%}
82
96
  {%- endunless -%}
@@ -90,6 +104,6 @@
90
104
  {%- endunless -%}
91
105
 
92
106
  {%- assign sorted_pages = nav_number_pages
93
- | concat: nav_string_pages
94
- | concat: title_number_pages
95
- | concat: title_string_pages -%}
107
+ | concat: nav_string_pages
108
+ | concat: title_number_pages
109
+ | concat: title_string_pages -%}
@@ -12,7 +12,7 @@ layout: table_wrappers
12
12
  {% include components/sidebar.html %}
13
13
  <div class="main" id="top">
14
14
  {% include components/header.html %}
15
- <div id="main-content-wrap" class="main-content-wrap">
15
+ <div class="main-content-wrap">
16
16
  {% include components/breadcrumbs.html %}
17
17
  <div id="main-content" class="main-content">
18
18
  <main>
@@ -9,7 +9,7 @@ layout: table_wrappers
9
9
  <body>
10
10
  <a class="skip-to-main" href="#main-content">Skip to main content</a>
11
11
  {% include icons/icons.html %}
12
- <div id="main-content-wrap" class="main-content-wrap" id="top">
12
+ <div class="main-content-wrap" id="top">
13
13
  {% include components/breadcrumbs.html %}
14
14
  <div id="main-content" class="main-content" role="main">
15
15
  {% if site.heading_anchors != false %}
data/_sass/base.scss CHANGED
@@ -1,6 +1,10 @@
1
1
  // Base element style overrides
2
2
  // stylelint-disable selector-no-type, selector-max-type, selector-max-specificity, selector-max-id
3
3
 
4
+ :root {
5
+ color-scheme: $color-scheme;
6
+ }
7
+
4
8
  * {
5
9
  box-sizing: border-box;
6
10
  }
data/_sass/buttons.scss CHANGED
@@ -17,7 +17,9 @@
17
17
  background-color: $base-button-color;
18
18
  border-width: 0;
19
19
  border-radius: $border-radius;
20
- box-shadow: 0 1px 2px rgba(0, 0, 0, 0.12), 0 3px 10px rgba(0, 0, 0, 0.08);
20
+ box-shadow:
21
+ 0 1px 2px rgba(0, 0, 0, 0.12),
22
+ 0 3px 10px rgba(0, 0, 0, 0.08);
21
23
  appearance: none;
22
24
 
23
25
  &:focus {
@@ -87,7 +89,9 @@
87
89
  &:focus {
88
90
  text-decoration: none;
89
91
  outline: none;
90
- box-shadow: inset 0 0 0 2px $grey-dk-100, 0 0 0 3px rgba(blue, 0.25);
92
+ box-shadow:
93
+ inset 0 0 0 2px $grey-dk-100,
94
+ 0 0 0 3px rgba(blue, 0.25);
91
95
  }
92
96
 
93
97
  &:focus:hover,
@@ -1,3 +1,4 @@
1
+ $color-scheme: dark;
1
2
  $body-background-color: $grey-dk-300;
2
3
  $body-heading-color: $grey-lt-000;
3
4
  $body-text-color: $grey-lt-300;
@@ -1,3 +1,4 @@
1
+ $color-scheme: light !default;
1
2
  $body-background-color: $white !default;
2
3
  $body-heading-color: $grey-dk-300 !default;
3
4
  $body-text-color: $grey-dk-100 !default;
data/_sass/search.scss CHANGED
@@ -23,7 +23,9 @@
23
23
  height: $sp-8;
24
24
  overflow: hidden;
25
25
  border-radius: $border-radius;
26
- box-shadow: 0 1px 2px rgba(0, 0, 0, 0.12), 0 3px 10px rgba(0, 0, 0, 0.08);
26
+ box-shadow:
27
+ 0 1px 2px rgba(0, 0, 0, 0.12),
28
+ 0 3px 10px rgba(0, 0, 0, 0.08);
27
29
  transition: height linear #{$transition-duration * 0.5};
28
30
 
29
31
  @include mq(md) {
@@ -96,7 +98,9 @@
96
98
  background-color: $search-background-color;
97
99
  border-bottom-right-radius: $border-radius;
98
100
  border-bottom-left-radius: $border-radius;
99
- box-shadow: 0 1px 2px rgba(0, 0, 0, 0.12), 0 3px 10px rgba(0, 0, 0, 0.08);
101
+ box-shadow:
102
+ 0 1px 2px rgba(0, 0, 0, 0.12),
103
+ 0 3px 10px rgba(0, 0, 0, 0.08);
100
104
 
101
105
  @include mq(md) {
102
106
  top: 100%;
@@ -230,7 +234,9 @@
230
234
  background-color: $search-background-color;
231
235
  border: 1px solid rgba($link-color, 0.3);
232
236
  border-radius: #{$sp-9 * 0.5};
233
- box-shadow: 0 1px 2px rgba(0, 0, 0, 0.12), 0 3px 10px rgba(0, 0, 0, 0.08);
237
+ box-shadow:
238
+ 0 1px 2px rgba(0, 0, 0, 0.12),
239
+ 0 3px 10px rgba(0, 0, 0, 0.08);
234
240
  align-items: center;
235
241
  justify-content: center;
236
242
  }
@@ -244,7 +250,9 @@
244
250
  height: 0;
245
251
  background-color: rgba(0, 0, 0, 0.3);
246
252
  opacity: 0;
247
- transition: opacity ease $transition-duration, width 0s $transition-duration,
253
+ transition:
254
+ opacity ease $transition-duration,
255
+ width 0s $transition-duration,
248
256
  height 0s $transition-duration;
249
257
  }
250
258
 
@@ -264,7 +272,9 @@
264
272
 
265
273
  @include mq(md) {
266
274
  width: $search-results-width;
267
- box-shadow: 0 1px 2px rgba(0, 0, 0, 0.12), 0 3px 10px rgba(0, 0, 0, 0.08);
275
+ box-shadow:
276
+ 0 1px 2px rgba(0, 0, 0, 0.12),
277
+ 0 3px 10px rgba(0, 0, 0, 0.08);
268
278
  }
269
279
  }
270
280
 
@@ -290,7 +300,10 @@
290
300
  width: 100%;
291
301
  height: 100%;
292
302
  opacity: 1;
293
- transition: opacity ease $transition-duration, width 0s, height 0s;
303
+ transition:
304
+ opacity ease $transition-duration,
305
+ width 0s,
306
+ height 0s;
294
307
  }
295
308
 
296
309
  @include mq(md) {
@@ -1,5 +1,6 @@
1
1
  // Typography
2
2
 
3
+ // prettier-ignore
3
4
  $body-font-family: system-ui, -apple-system, blinkmacsystemfont, "Segoe UI",
4
5
  roboto, "Helvetica Neue", arial, sans-serif !default;
5
6
  $mono-font-family: "SFMono-Regular", menlo, consolas, monospace !default;
@@ -4,7 +4,9 @@
4
4
  color: $fg;
5
5
  background-color: darken($bg, 2%);
6
6
  background-image: linear-gradient(lighten($bg, 5%), darken($bg, 2%));
7
- box-shadow: 0 1px 3px rgba(0, 0, 0, 0.25), 0 4px 10px rgba(0, 0, 0, 0.12);
7
+ box-shadow:
8
+ 0 1px 3px rgba(0, 0, 0, 0.25),
9
+ 0 4px 10px rgba(0, 0, 0, 0.12);
8
10
 
9
11
  &:hover,
10
12
  &.zeroclipboard-is-hover {
data/_sass/tables.scss CHANGED
@@ -8,7 +8,9 @@
8
8
  margin-bottom: $sp-5;
9
9
  overflow-x: auto;
10
10
  border-radius: $border-radius;
11
- box-shadow: 0 1px 2px rgba(0, 0, 0, 0.12), 0 3px 10px rgba(0, 0, 0, 0.08);
11
+ box-shadow:
12
+ 0 1px 2px rgba(0, 0, 0, 0.12),
13
+ 0 3px 10px rgba(0, 0, 0, 0.08);
12
14
  }
13
15
 
14
16
  table {
@@ -31,13 +31,18 @@ function initNav() {
31
31
  }
32
32
  if (target) {
33
33
  e.preventDefault();
34
- target.ariaPressed = target.parentNode.classList.toggle('active');
34
+ const active = target.parentNode.classList.toggle('active');
35
+ const passive = target.parentNode.classList.toggle('passive');
36
+ if (active && passive) target.parentNode.classList.toggle('passive');
37
+ target.ariaPressed = active;
35
38
  }
36
39
  });
37
40
 
38
41
  const siteNav = document.getElementById('site-nav');
39
42
  const mainHeader = document.getElementById('main-header');
40
43
  const menuButton = document.getElementById('menu-button');
44
+
45
+ disableHeadStyleSheet();
41
46
 
42
47
  jtd.addEvent(menuButton, 'click', function(e){
43
48
  e.preventDefault();
@@ -66,6 +71,14 @@ function initNav() {
66
71
  {%- endif %}
67
72
  }
68
73
 
74
+ // The page-specific <style> in the <head> is needed only when JS is disabled.
75
+ // Moreover, it incorrectly overrides dynamic stylesheets set by setTheme(theme).
76
+ // The page-specific stylesheet is assumed to have index 1 in the list of stylesheets.
77
+
78
+ function disableHeadStyleSheet() {
79
+ document.styleSheets[1].disabled = true;
80
+ }
81
+
69
82
  {%- if site.search_enabled != false %}
70
83
  // Site search
71
84
 
@@ -461,15 +474,55 @@ jtd.setTheme = function(theme) {
461
474
  cssFile.setAttribute('href', '{{ "assets/css/just-the-docs-" | relative_url }}' + theme + '.css');
462
475
  }
463
476
 
477
+ // Note: pathname can have a trailing slash on a local jekyll server
478
+ // and not have the slash on GitHub Pages
479
+
480
+ function navLink() {
481
+ var href = document.location.pathname;
482
+ if (href.endsWith('/') && href != '/') {
483
+ href = href.slice(0, -1);
484
+ }
485
+ return document.getElementById('site-nav').querySelector('a[href="' + href + '"], a[href="' + href + '/"]');
486
+ }
487
+
464
488
  // Scroll site-nav to ensure the link to the current page is visible
465
489
 
466
490
  function scrollNav() {
467
- const href = document.location.pathname;
468
- const siteNav = document.getElementById('site-nav');
469
- const targetLink = siteNav.querySelector('a[href="' + href + '"], a[href="' + href + '/"]');
470
- if(targetLink){
491
+ const targetLink = navLink();
492
+ if (targetLink) {
471
493
  const rect = targetLink.getBoundingClientRect();
472
- siteNav.scrollBy(0, rect.top - 3*rect.height);
494
+ document.getElementById('site-nav').scrollBy(0, rect.top - 3*rect.height);
495
+ }
496
+ }
497
+
498
+ // Find the nav-list-link that refers to the current page
499
+ // then make it and all enclosing nav-list-item elements active,
500
+ // and make all other folded collections passive
501
+
502
+ function activateNav() {
503
+ var target = navLink();
504
+ if (target) {
505
+ target.classList.toggle('active', true);
506
+ }
507
+ while (target) {
508
+ while (target && !(target.classList && target.classList.contains('nav-list-item'))) {
509
+ target = target.parentNode;
510
+ }
511
+ if (target) {
512
+ target.classList.toggle('active', true);
513
+ target = target.parentNode;
514
+ }
515
+ }
516
+ const elements = document.getElementsByClassName("nav-category-list");
517
+ for (const element of elements) {
518
+ const item = element.children[0];
519
+ const active = item.classList.toggle('active');
520
+ if (active) {
521
+ item.classList.toggle('active', false);
522
+ item.classList.toggle('passive', true);
523
+ } else {
524
+ item.classList.toggle('active', true);
525
+ }
473
526
  }
474
527
  }
475
528
 
@@ -480,6 +533,7 @@ jtd.onReady(function(){
480
533
  {%- if site.search_enabled != false %}
481
534
  initSearch();
482
535
  {%- endif %}
536
+ activateNav();
483
537
  scrollNav();
484
538
  });
485
539
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: just-the-docs
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.4
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Patrick Marsceill
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2023-07-05 00:00:00.000000000 Z
12
+ date: 2023-08-20 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: bundler
@@ -53,6 +53,20 @@ dependencies:
53
53
  - - ">="
54
54
  - !ruby/object:Gem::Version
55
55
  version: '2.0'
56
+ - !ruby/object:Gem::Dependency
57
+ name: jekyll-include-cache
58
+ requirement: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - ">="
61
+ - !ruby/object:Gem::Version
62
+ version: '0'
63
+ type: :runtime
64
+ prerelease: false
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - ">="
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
56
70
  - !ruby/object:Gem::Dependency
57
71
  name: rake
58
72
  requirement: !ruby/object:Gem::Requirement
@@ -89,13 +103,16 @@ files:
89
103
  - _includes/components/search_footer.html
90
104
  - _includes/components/search_header.html
91
105
  - _includes/components/sidebar.html
106
+ - _includes/css/activation.scss.liquid
92
107
  - _includes/css/callouts.scss.liquid
93
108
  - _includes/css/custom.scss.liquid
94
109
  - _includes/css/just-the-docs.scss.liquid
110
+ - _includes/favicon.html
95
111
  - _includes/fix_linenos.html
96
112
  - _includes/footer_custom.html
97
113
  - _includes/head.html
98
114
  - _includes/head_custom.html
115
+ - _includes/head_nav.html
99
116
  - _includes/header_custom.html
100
117
  - _includes/icons/code_copy.html
101
118
  - _includes/icons/document.html