jekyll-vitepress-theme 1.4.3 → 1.5.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 +4 -4
- data/README.md +6 -4
- data/_includes/doc_footer.html +11 -3
- data/_includes/github_sponsor_button.html +45 -0
- data/_includes/github_star_button.html +41 -0
- data/_includes/local_nav.html +2 -2
- data/_includes/nav.html +9 -9
- data/_includes/rubygems_downloads_button.html +53 -0
- data/assets/css/vitepress-overrides.css +218 -32
- data/assets/js/vitepress-theme.js +348 -23
- data/lib/jekyll/vitepress_theme/version.rb +1 -1
- metadata +5 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 39b278e0794a067003ad3429adb3ff6069023850168c8fea94a41c97e0e02aaa
|
|
4
|
+
data.tar.gz: c19f3340ff9d10dbd175daff50bfcbe6800ada67f8922eac7217b2882e853d75
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 6fe07bde949fe99f69ea54a28736b0a3742e4608c548e34d1969df70f80119c4833437696c0bc22ada0e8b9d37ff089f36db52c15db64aba2a69c2a043043ebf
|
|
7
|
+
data.tar.gz: cc5f979de2a06f80e598cc1b98fbd4767e4a15be238a638f5932e0f8d799757169431043ab7922709c51a0503d1cd294203251fac2582d5c5639a7966a0cb5c7
|
data/README.md
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
# Jekyll VitePress Theme
|
|
6
6
|
|
|
7
|
-
<strong>Ruby deserves beautiful docs. Jekyll VitePress Theme brings VitePress-level polish to Jekyll.</strong>
|
|
7
|
+
<strong>Ruby deserves beautiful docs. Jekyll VitePress Theme brings VitePress-level polish to Jekyll, then goes beyond it.</strong>
|
|
8
8
|
|
|
9
9
|
[](https://rubygems.org/gems/jekyll-vitepress-theme)
|
|
10
10
|
[](https://github.com/crmne/jekyll-vitepress-theme/actions/workflows/main.yml)
|
|
@@ -17,16 +17,16 @@
|
|
|
17
17
|
|
|
18
18
|
Ruby projects should not need to leave Ruby just to get documentation that feels designed.
|
|
19
19
|
|
|
20
|
-
`jekyll-vitepress-theme` brings VitePress-level documentation polish to Jekyll: a product-like homepage, familiar navigation, sidebars, outlines, search, dark mode, code blocks, callouts, and doc footers, packaged as a Ruby gem.
|
|
20
|
+
`jekyll-vitepress-theme` brings VitePress-level documentation polish to Jekyll: a product-like homepage, familiar navigation, sidebars, outlines, search, dark mode, code blocks, callouts, and doc footers, packaged as a Ruby gem. It targets [VitePress parity](https://jekyll-vitepress.dev/vitepress-parity/) for the core docs experience and adds [extensions to VitePress](https://jekyll-vitepress.dev/extensions-to-vitepress/) for Jekyll-first workflows.
|
|
21
21
|
|
|
22
22
|
The unusual part is navigation. Jekyll VitePress uses Turbo Frames like a Rails app, swapping only the content frame while the nav, sidebar, and shell stay in place. Page changes feel instant, while the output remains plain Jekyll: Markdown, Liquid, YAML, Ruby, and static files.
|
|
23
23
|
|
|
24
24
|
## Why Use It
|
|
25
25
|
|
|
26
|
-
- **VitePress polish for Jekyll:**
|
|
26
|
+
- **[VitePress polish for Jekyll](https://jekyll-vitepress.dev/vitepress-parity/):** match VitePress for the docs homepage, sidebar, outline, search, dark mode, callouts, code blocks, and doc footers.
|
|
27
27
|
- **Jekyll-native setup:** keep your Markdown, Liquid, YAML, and static hosting. Add the gem, set a few options, and publish.
|
|
28
28
|
- **Fast docs navigation:** Turbo Frames update the content area while the nav, sidebar, and shell stay mounted.
|
|
29
|
-
- **More than VitePress:** add GitHub Star and Sponsor buttons, versions, generated local search, and Copy Page/View as Markdown for LLM workflows.
|
|
29
|
+
- **[More than VitePress](https://jekyll-vitepress.dev/extensions-to-vitepress/):** add GitHub Star and Sponsor buttons, RubyGems downloads, versions, labels, generated local search, and Copy Page/View as Markdown for LLM workflows.
|
|
30
30
|
- **Static Ruby output:** build with Jekyll and deploy the generated HTML to GitHub Pages, any CDN, or any static host.
|
|
31
31
|
|
|
32
32
|
## Quick Start
|
|
@@ -95,6 +95,8 @@ Start here:
|
|
|
95
95
|
- [Navigation and Layout](https://jekyll-vitepress.dev/navigation-layout/)
|
|
96
96
|
- [Search and Outline](https://jekyll-vitepress.dev/search-and-outline/)
|
|
97
97
|
- [Configuration Reference](https://jekyll-vitepress.dev/configuration-reference/)
|
|
98
|
+
- [VitePress Parity](https://jekyll-vitepress.dev/vitepress-parity/)
|
|
99
|
+
- [Extensions to VitePress](https://jekyll-vitepress.dev/extensions-to-vitepress/)
|
|
98
100
|
|
|
99
101
|
## Development
|
|
100
102
|
|
data/_includes/doc_footer.html
CHANGED
|
@@ -34,12 +34,20 @@
|
|
|
34
34
|
{% assign last_updated_text = last_updated_config.text %}
|
|
35
35
|
{% endif %}
|
|
36
36
|
|
|
37
|
-
{% assign last_updated_format = '
|
|
37
|
+
{% assign last_updated_format = 'vitepress' %}
|
|
38
38
|
{% if last_updated_config and last_updated_config.format %}
|
|
39
39
|
{% assign last_updated_format = last_updated_config.format %}
|
|
40
40
|
{% endif %}
|
|
41
|
+
{% assign last_updated_uses_vitepress_format = false %}
|
|
42
|
+
{% if last_updated_format == 'vitepress' %}
|
|
43
|
+
{% assign last_updated_uses_vitepress_format = true %}
|
|
44
|
+
{% assign last_updated_format = '%b %-d, %Y, %-I:%M:%S %p' %}
|
|
45
|
+
{% endif %}
|
|
41
46
|
|
|
42
|
-
{% assign last_updated_at =
|
|
47
|
+
{% assign last_updated_at = page.last_updated_at | default: nil %}
|
|
48
|
+
{% if page_theme.last_updated_at %}
|
|
49
|
+
{% assign last_updated_at = page_theme.last_updated_at %}
|
|
50
|
+
{% endif %}
|
|
43
51
|
{% assign show_last_updated = false %}
|
|
44
52
|
{% if last_updated_enabled and last_updated_at %}
|
|
45
53
|
{% assign show_last_updated = true %}
|
|
@@ -175,7 +183,7 @@
|
|
|
175
183
|
{% endif %}
|
|
176
184
|
{% if show_last_updated %}
|
|
177
185
|
<div class="last-updated">
|
|
178
|
-
<p class="VPLastUpdated">{{ last_updated_text }}: <time datetime="{{ last_updated_at | date_to_xmlschema }}" lang="{{ site.lang | default: 'en-US' }}">{{ last_updated_at | date: last_updated_format }}</time></p>
|
|
186
|
+
<p class="VPLastUpdated">{{ last_updated_text }}: <time datetime="{{ last_updated_at | date_to_xmlschema }}" lang="{{ site.lang | default: 'en-US' }}"{% if last_updated_uses_vitepress_format %} data-vp-last-updated{% endif %}>{{ last_updated_at | date: last_updated_format }}</time></p>
|
|
179
187
|
</div>
|
|
180
188
|
{% endif %}
|
|
181
189
|
</div>
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
{% assign theme = site.jekyll_vitepress %}
|
|
2
|
+
{% assign config = theme.github_sponsor %}
|
|
3
|
+
{% assign explicit_sponsor_user = include.user | default: include.username | default: include.account %}
|
|
4
|
+
{% assign explicit_button_url = include.url %}
|
|
5
|
+
{% assign sponsor_user = explicit_sponsor_user %}
|
|
6
|
+
{% assign button_url = explicit_button_url %}
|
|
7
|
+
{% assign button_text = include.text %}
|
|
8
|
+
{% assign button_label = include.label %}
|
|
9
|
+
{% assign button_enabled = true %}
|
|
10
|
+
{% if config and config != false %}
|
|
11
|
+
{% if config.enabled == false %}
|
|
12
|
+
{% unless explicit_sponsor_user or explicit_button_url %}
|
|
13
|
+
{% assign button_enabled = false %}
|
|
14
|
+
{% endunless %}
|
|
15
|
+
{% endif %}
|
|
16
|
+
{% unless sponsor_user %}
|
|
17
|
+
{% assign sponsor_user = config.user | default: config.username | default: config.account %}
|
|
18
|
+
{% endunless %}
|
|
19
|
+
{% unless button_url %}
|
|
20
|
+
{% assign button_url = config.url %}
|
|
21
|
+
{% endunless %}
|
|
22
|
+
{% unless button_text %}
|
|
23
|
+
{% assign button_text = config.text %}
|
|
24
|
+
{% endunless %}
|
|
25
|
+
{% unless button_label %}
|
|
26
|
+
{% assign button_label = config.label %}
|
|
27
|
+
{% endunless %}
|
|
28
|
+
{% endif %}
|
|
29
|
+
{% assign button_text = button_text | default: 'Sponsor' %}
|
|
30
|
+
{% assign button_label = button_label | default: 'Sponsor on GitHub' %}
|
|
31
|
+
{% unless button_url %}
|
|
32
|
+
{% if sponsor_user %}
|
|
33
|
+
{% assign button_url = 'https://github.com/sponsors/' | append: sponsor_user %}
|
|
34
|
+
{% endif %}
|
|
35
|
+
{% endunless %}
|
|
36
|
+
{% if button_enabled and button_url %}
|
|
37
|
+
<a class="VPMetricButton VPMetricButtonSponsor no-icon" href="{{ button_url }}" aria-label="{{ button_label | escape }}" target="_blank" rel="noreferrer noopener">
|
|
38
|
+
<span class="VPMetricButtonIcon VPMetricButtonSponsorIcon" aria-hidden="true">
|
|
39
|
+
<svg viewBox="0 0 16 16" focusable="false">
|
|
40
|
+
<path d="M7.655 14.916v-.001h-.002l-.006-.003-.018-.01a22.066 22.066 0 0 1-3.744-2.584C2.045 10.731 0 8.35 0 5.5 0 2.836 2.086 1 4.25 1 5.797 1 7.153 1.802 8 3.02 8.847 1.802 10.203 1 11.75 1 13.914 1 16 2.836 16 5.5c0 2.85-2.044 5.231-3.886 6.818a22.094 22.094 0 0 1-3.433 2.414 7.152 7.152 0 0 1-.31.17l-.018.01-.008.004a.75.75 0 0 1-.69 0Z"></path>
|
|
41
|
+
</svg>
|
|
42
|
+
</span>
|
|
43
|
+
<span class="VPMetricButtonText">{{ button_text }}</span>
|
|
44
|
+
</a>
|
|
45
|
+
{% endif %}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
{% assign theme = site.jekyll_vitepress %}
|
|
2
|
+
{% assign config = theme.github_star %}
|
|
3
|
+
{% assign explicit_repository = include.repository | default: include.repo %}
|
|
4
|
+
{% assign explicit_button_url = include.url %}
|
|
5
|
+
{% assign repository = explicit_repository %}
|
|
6
|
+
{% assign button_text = include.text %}
|
|
7
|
+
{% assign show_count = include.show_count %}
|
|
8
|
+
{% assign button_enabled = true %}
|
|
9
|
+
{% if config and config != false %}
|
|
10
|
+
{% if config.enabled == false %}
|
|
11
|
+
{% unless explicit_repository or explicit_button_url %}
|
|
12
|
+
{% assign button_enabled = false %}
|
|
13
|
+
{% endunless %}
|
|
14
|
+
{% endif %}
|
|
15
|
+
{% unless repository %}
|
|
16
|
+
{% assign repository = config.repository | default: config.repo %}
|
|
17
|
+
{% endunless %}
|
|
18
|
+
{% unless button_text %}
|
|
19
|
+
{% assign button_text = config.text %}
|
|
20
|
+
{% endunless %}
|
|
21
|
+
{% if show_count == nil %}
|
|
22
|
+
{% assign show_count = config.show_count %}
|
|
23
|
+
{% endif %}
|
|
24
|
+
{% endif %}
|
|
25
|
+
{% assign button_text = button_text | default: 'Star' %}
|
|
26
|
+
{% if show_count == nil %}
|
|
27
|
+
{% assign show_count = true %}
|
|
28
|
+
{% endif %}
|
|
29
|
+
{% assign button_url = explicit_button_url %}
|
|
30
|
+
{% unless button_url %}
|
|
31
|
+
{% if repository %}
|
|
32
|
+
{% assign button_url = 'https://github.com/' | append: repository %}
|
|
33
|
+
{% endif %}
|
|
34
|
+
{% endunless %}
|
|
35
|
+
{% if button_enabled and repository and button_url %}
|
|
36
|
+
<a class="VPMetricButton VPMetricButtonGithub no-icon" href="{{ button_url }}" aria-label="Star {{ repository }} on GitHub" target="_blank" rel="noreferrer noopener" data-github-star-repo="{{ repository | escape }}" data-github-star-show-count="{{ show_count }}">
|
|
37
|
+
<span class="VPMetricButtonIcon vpi-social-github" aria-hidden="true"></span>
|
|
38
|
+
<span class="VPMetricButtonText">{{ button_text }}</span>
|
|
39
|
+
<span class="VPMetricButtonCount" data-vp-github-star-count aria-hidden="true"{% unless show_count %} hidden{% endunless %}>{% if show_count %}...{% endif %}</span>
|
|
40
|
+
</a>
|
|
41
|
+
{% endif %}
|
data/_includes/local_nav.html
CHANGED
|
@@ -7,11 +7,11 @@
|
|
|
7
7
|
</button>
|
|
8
8
|
|
|
9
9
|
<div class="VPLocalNavOutlineDropdown" id="vp-local-outline-dropdown">
|
|
10
|
-
<button type="button" id="vp-local-outline-button">
|
|
10
|
+
<button type="button" id="vp-local-outline-button" aria-expanded="false" aria-controls="vp-local-outline-items">
|
|
11
11
|
<span class="menu-text">{{ labels.outline | default: 'On this page' }}</span>
|
|
12
12
|
<span class="vpi-chevron-right icon"></span>
|
|
13
13
|
</button>
|
|
14
|
-
<div class="items" hidden>
|
|
14
|
+
<div class="items" id="vp-local-outline-items" hidden>
|
|
15
15
|
<div class="header">
|
|
16
16
|
<a class="top-link" href="#top" id="vp-local-top-link">{{ labels.return_to_top | default: 'Return to top' }}</a>
|
|
17
17
|
</div>
|
data/_includes/nav.html
CHANGED
|
@@ -168,7 +168,7 @@
|
|
|
168
168
|
{% if github_star_enabled %}
|
|
169
169
|
<div class="VPNavBarStar">
|
|
170
170
|
<a class="VPLink link no-icon VPNavBarStarLink" href="{{ github_star_url }}" aria-label="Star {{ github_star_repository }} on GitHub" target="_blank" rel="noreferrer noopener" data-github-star-repo="{{ github_star_repository | escape }}" data-github-star-show-count="{{ github_star_show_count }}">
|
|
171
|
-
<span class="vpi-social-github" aria-hidden="true"></span>
|
|
171
|
+
<span class="VPNavBarStarIcon vpi-social-github" aria-hidden="true"></span>
|
|
172
172
|
<span class="VPNavBarStarText">{{ github_star_text }}</span>
|
|
173
173
|
<span class="VPNavBarStarCount" aria-hidden="true"{% unless github_star_show_count %} hidden{% endunless %}>{% if github_star_show_count %}...{% endif %}</span>
|
|
174
174
|
</a>
|
|
@@ -177,9 +177,9 @@
|
|
|
177
177
|
{% if github_sponsor_enabled %}
|
|
178
178
|
<div class="VPNavBarStar VPNavBarSponsor">
|
|
179
179
|
<a class="VPLink link no-icon VPNavBarStarLink VPNavBarSponsorLink" href="{{ github_sponsor_url }}" aria-label="{{ github_sponsor_label | escape }}" target="_blank" rel="noreferrer noopener">
|
|
180
|
-
<span class="VPNavBarSponsorIcon" aria-hidden="true">
|
|
180
|
+
<span class="VPNavBarStarIcon VPNavBarSponsorIcon" aria-hidden="true">
|
|
181
181
|
<svg viewBox="0 0 16 16" focusable="false">
|
|
182
|
-
<path d="
|
|
182
|
+
<path d="M7.655 14.916v-.001h-.002l-.006-.003-.018-.01a22.066 22.066 0 0 1-3.744-2.584C2.045 10.731 0 8.35 0 5.5 0 2.836 2.086 1 4.25 1 5.797 1 7.153 1.802 8 3.02 8.847 1.802 10.203 1 11.75 1 13.914 1 16 2.836 16 5.5c0 2.85-2.044 5.231-3.886 6.818a22.094 22.094 0 0 1-3.433 2.414 7.152 7.152 0 0 1-.31.17l-.018.01-.008.004a.75.75 0 0 1-.69 0Z"></path>
|
|
183
183
|
</svg>
|
|
184
184
|
</span>
|
|
185
185
|
<span class="VPNavBarStarText">{{ github_sponsor_text }}</span>
|
|
@@ -225,7 +225,7 @@
|
|
|
225
225
|
{% if github_star_enabled %}
|
|
226
226
|
<div class="VPNavBarStar" id="vp-nav-star">
|
|
227
227
|
<a class="VPLink link no-icon VPNavBarStarLink" href="{{ github_star_url }}" aria-label="Star {{ github_star_repository }} on GitHub" target="_blank" rel="noreferrer noopener" data-github-star-repo="{{ github_star_repository | escape }}" data-github-star-show-count="{{ github_star_show_count }}">
|
|
228
|
-
<span class="vpi-social-github" aria-hidden="true"></span>
|
|
228
|
+
<span class="VPNavBarStarIcon vpi-social-github" aria-hidden="true"></span>
|
|
229
229
|
<span class="VPNavBarStarText">{{ github_star_text }}</span>
|
|
230
230
|
<span class="VPNavBarStarCount" aria-hidden="true"{% unless github_star_show_count %} hidden{% endunless %}>{% if github_star_show_count %}...{% endif %}</span>
|
|
231
231
|
</a>
|
|
@@ -234,9 +234,9 @@
|
|
|
234
234
|
{% if github_sponsor_enabled %}
|
|
235
235
|
<div class="VPNavBarStar VPNavBarSponsor" id="vp-nav-sponsor">
|
|
236
236
|
<a class="VPLink link no-icon VPNavBarStarLink VPNavBarSponsorLink" href="{{ github_sponsor_url }}" aria-label="{{ github_sponsor_label | escape }}" target="_blank" rel="noreferrer noopener">
|
|
237
|
-
<span class="VPNavBarSponsorIcon" aria-hidden="true">
|
|
237
|
+
<span class="VPNavBarStarIcon VPNavBarSponsorIcon" aria-hidden="true">
|
|
238
238
|
<svg viewBox="0 0 16 16" focusable="false">
|
|
239
|
-
<path d="
|
|
239
|
+
<path d="M7.655 14.916v-.001h-.002l-.006-.003-.018-.01a22.066 22.066 0 0 1-3.744-2.584C2.045 10.731 0 8.35 0 5.5 0 2.836 2.086 1 4.25 1 5.797 1 7.153 1.802 8 3.02 8.847 1.802 10.203 1 11.75 1 13.914 1 16 2.836 16 5.5c0 2.85-2.044 5.231-3.886 6.818a22.094 22.094 0 0 1-3.433 2.414 7.152 7.152 0 0 1-.31.17l-.018.01-.008.004a.75.75 0 0 1-.69 0Z"></path>
|
|
240
240
|
</svg>
|
|
241
241
|
</span>
|
|
242
242
|
<span class="VPNavBarStarText">{{ github_sponsor_text }}</span>
|
|
@@ -345,7 +345,7 @@
|
|
|
345
345
|
{% if github_star_enabled %}
|
|
346
346
|
<div class="VPNavBarStar VPNavScreenStar">
|
|
347
347
|
<a class="VPLink link no-icon VPNavBarStarLink VPNavScreenStarLink" href="{{ github_star_url }}" aria-label="Star {{ github_star_repository }} on GitHub" target="_blank" rel="noreferrer noopener" data-github-star-repo="{{ github_star_repository | escape }}" data-github-star-show-count="{{ github_star_show_count }}">
|
|
348
|
-
<span class="vpi-social-github" aria-hidden="true"></span>
|
|
348
|
+
<span class="VPNavBarStarIcon vpi-social-github" aria-hidden="true"></span>
|
|
349
349
|
<span class="VPNavBarStarText">{{ github_star_text }}</span>
|
|
350
350
|
<span class="VPNavBarStarCount" aria-hidden="true"{% unless github_star_show_count %} hidden{% endunless %}>{% if github_star_show_count %}...{% endif %}</span>
|
|
351
351
|
</a>
|
|
@@ -354,9 +354,9 @@
|
|
|
354
354
|
{% if github_sponsor_enabled %}
|
|
355
355
|
<div class="VPNavBarStar VPNavScreenStar VPNavBarSponsor">
|
|
356
356
|
<a class="VPLink link no-icon VPNavBarStarLink VPNavScreenStarLink VPNavBarSponsorLink" href="{{ github_sponsor_url }}" aria-label="{{ github_sponsor_label | escape }}" target="_blank" rel="noreferrer noopener">
|
|
357
|
-
<span class="VPNavBarSponsorIcon" aria-hidden="true">
|
|
357
|
+
<span class="VPNavBarStarIcon VPNavBarSponsorIcon" aria-hidden="true">
|
|
358
358
|
<svg viewBox="0 0 16 16" focusable="false">
|
|
359
|
-
<path d="
|
|
359
|
+
<path d="M7.655 14.916v-.001h-.002l-.006-.003-.018-.01a22.066 22.066 0 0 1-3.744-2.584C2.045 10.731 0 8.35 0 5.5 0 2.836 2.086 1 4.25 1 5.797 1 7.153 1.802 8 3.02 8.847 1.802 10.203 1 11.75 1 13.914 1 16 2.836 16 5.5c0 2.85-2.044 5.231-3.886 6.818a22.094 22.094 0 0 1-3.433 2.414 7.152 7.152 0 0 1-.31.17l-.018.01-.008.004a.75.75 0 0 1-.69 0Z"></path>
|
|
360
360
|
</svg>
|
|
361
361
|
</span>
|
|
362
362
|
<span class="VPNavBarStarText">{{ github_sponsor_text }}</span>
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
{% assign theme = site.jekyll_vitepress %}
|
|
2
|
+
{% assign config = theme.gem_downloads %}
|
|
3
|
+
{% assign explicit_gem_name = include.gem | default: include.name %}
|
|
4
|
+
{% assign explicit_button_url = include.url %}
|
|
5
|
+
{% assign gem_name = explicit_gem_name %}
|
|
6
|
+
{% assign button_url = explicit_button_url %}
|
|
7
|
+
{% assign button_text = include.text %}
|
|
8
|
+
{% assign button_label = include.label %}
|
|
9
|
+
{% assign show_count = include.show_count %}
|
|
10
|
+
{% assign button_enabled = true %}
|
|
11
|
+
{% if config and config != false %}
|
|
12
|
+
{% if config.enabled == false %}
|
|
13
|
+
{% unless explicit_gem_name or explicit_button_url %}
|
|
14
|
+
{% assign button_enabled = false %}
|
|
15
|
+
{% endunless %}
|
|
16
|
+
{% endif %}
|
|
17
|
+
{% unless gem_name %}
|
|
18
|
+
{% assign gem_name = config.gem | default: config.name %}
|
|
19
|
+
{% endunless %}
|
|
20
|
+
{% unless button_url %}
|
|
21
|
+
{% assign button_url = config.url %}
|
|
22
|
+
{% endunless %}
|
|
23
|
+
{% unless button_text %}
|
|
24
|
+
{% assign button_text = config.text %}
|
|
25
|
+
{% endunless %}
|
|
26
|
+
{% unless button_label %}
|
|
27
|
+
{% assign button_label = config.label %}
|
|
28
|
+
{% endunless %}
|
|
29
|
+
{% if show_count == nil %}
|
|
30
|
+
{% assign show_count = config.show_count %}
|
|
31
|
+
{% endif %}
|
|
32
|
+
{% endif %}
|
|
33
|
+
{% assign button_text = button_text | default: 'Downloads' %}
|
|
34
|
+
{% assign button_label = button_label | default: 'View gem downloads' %}
|
|
35
|
+
{% if show_count == nil %}
|
|
36
|
+
{% assign show_count = true %}
|
|
37
|
+
{% endif %}
|
|
38
|
+
{% unless button_url %}
|
|
39
|
+
{% if gem_name %}
|
|
40
|
+
{% assign button_url = 'https://rubygems.org/gems/' | append: gem_name %}
|
|
41
|
+
{% endif %}
|
|
42
|
+
{% endunless %}
|
|
43
|
+
{% if button_enabled and gem_name and button_url %}
|
|
44
|
+
<a class="VPMetricButton VPMetricButtonDownloads no-icon" href="{{ button_url }}" aria-label="{{ button_label | escape }}" target="_blank" rel="noreferrer noopener" data-rubygems-downloads-gem="{{ gem_name | escape }}" data-rubygems-downloads-show-count="{{ show_count }}" data-rubygems-downloads-label="{{ button_label | escape }}">
|
|
45
|
+
<span class="VPMetricButtonIcon VPMetricButtonDownloadsIcon" aria-hidden="true">
|
|
46
|
+
<svg viewBox="0 0 16 16" focusable="false">
|
|
47
|
+
<path d="M8 1.75a.75.75 0 0 1 .75.75v5.19l1.72-1.72a.75.75 0 1 1 1.06 1.06l-3 3a.75.75 0 0 1-1.06 0l-3-3a.75.75 0 0 1 1.06-1.06l1.72 1.72V2.5A.75.75 0 0 1 8 1.75ZM3.75 11a.75.75 0 0 1 .75.75v1h7v-1a.75.75 0 0 1 1.5 0v1.5a1 1 0 0 1-1 1H4a1 1 0 0 1-1-1v-1.5a.75.75 0 0 1 .75-.75Z"></path>
|
|
48
|
+
</svg>
|
|
49
|
+
</span>
|
|
50
|
+
<span class="VPMetricButtonText"{% if show_count %} hidden{% endif %}>{{ button_text }}</span>
|
|
51
|
+
<strong class="VPMetricButtonCount" data-vp-rubygems-downloads-count{% unless show_count %} hidden{% endunless %}>{% if show_count %}... downloads{% endif %}</strong>
|
|
52
|
+
</a>
|
|
53
|
+
{% endif %}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
html,
|
|
4
4
|
body {
|
|
5
|
-
overflow-x:
|
|
5
|
+
overflow-x: clip;
|
|
6
6
|
}
|
|
7
7
|
|
|
8
8
|
/* Keep appearance transitions visually consistent across key UI surfaces. */
|
|
@@ -296,16 +296,14 @@ body.vp-nav-screen-open .VPNav {
|
|
|
296
296
|
transition: color 0.25s;
|
|
297
297
|
}
|
|
298
298
|
|
|
299
|
-
.
|
|
300
|
-
width: 20px;
|
|
301
|
-
height: 20px;
|
|
302
|
-
color: currentcolor;
|
|
303
|
-
}
|
|
304
|
-
|
|
305
|
-
.VPNavBarSponsorIcon {
|
|
299
|
+
.VPNavBarStarIcon {
|
|
306
300
|
display: inline-flex;
|
|
301
|
+
flex: 0 0 auto;
|
|
302
|
+
align-items: center;
|
|
303
|
+
justify-content: center;
|
|
307
304
|
width: 20px;
|
|
308
305
|
height: 20px;
|
|
306
|
+
line-height: 0;
|
|
309
307
|
color: currentcolor;
|
|
310
308
|
}
|
|
311
309
|
|
|
@@ -347,12 +345,7 @@ body.vp-nav-screen-open .VPNav {
|
|
|
347
345
|
background: var(--vp-c-bg-elv);
|
|
348
346
|
}
|
|
349
347
|
|
|
350
|
-
.
|
|
351
|
-
width: 14px;
|
|
352
|
-
height: 14px;
|
|
353
|
-
}
|
|
354
|
-
|
|
355
|
-
.VPNavBarSponsorIcon {
|
|
348
|
+
.VPNavBarStarIcon {
|
|
356
349
|
width: 14px;
|
|
357
350
|
height: 14px;
|
|
358
351
|
}
|
|
@@ -512,12 +505,7 @@ body.vp-nav-screen-open .VPNav {
|
|
|
512
505
|
background: var(--vp-c-bg-elv);
|
|
513
506
|
}
|
|
514
507
|
|
|
515
|
-
.VPNavScreenSocialLinks .
|
|
516
|
-
width: 14px;
|
|
517
|
-
height: 14px;
|
|
518
|
-
}
|
|
519
|
-
|
|
520
|
-
.VPNavScreenSocialLinks .VPNavBarSponsorIcon {
|
|
508
|
+
.VPNavScreenSocialLinks .VPNavBarStarIcon {
|
|
521
509
|
width: 14px;
|
|
522
510
|
height: 14px;
|
|
523
511
|
}
|
|
@@ -643,21 +631,14 @@ body.vp-search-open {
|
|
|
643
631
|
color: var(--vp-c-text-2);
|
|
644
632
|
}
|
|
645
633
|
|
|
646
|
-
.VPDocFooter .last-updated {
|
|
647
|
-
margin-top: 8px;
|
|
648
|
-
}
|
|
649
|
-
|
|
650
634
|
.VPDocFooter .VPLastUpdated {
|
|
651
635
|
margin: 0;
|
|
652
|
-
line-height:
|
|
653
|
-
font-size:
|
|
636
|
+
line-height: 24px;
|
|
637
|
+
font-size: 14px;
|
|
638
|
+
font-weight: 500;
|
|
654
639
|
color: var(--vp-c-text-2);
|
|
655
640
|
}
|
|
656
641
|
|
|
657
|
-
.VPDocFooter .VPLastUpdated time {
|
|
658
|
-
color: var(--vp-c-text-1);
|
|
659
|
-
}
|
|
660
|
-
|
|
661
642
|
.VPFooter .footer-brand-links {
|
|
662
643
|
display: inline-flex;
|
|
663
644
|
align-items: center;
|
|
@@ -698,8 +679,10 @@ body.vp-search-open {
|
|
|
698
679
|
}
|
|
699
680
|
|
|
700
681
|
@media (min-width: 640px) {
|
|
701
|
-
.VPDocFooter .
|
|
702
|
-
|
|
682
|
+
.VPDocFooter .VPLastUpdated {
|
|
683
|
+
line-height: 32px;
|
|
684
|
+
font-size: 14px;
|
|
685
|
+
font-weight: 500;
|
|
703
686
|
}
|
|
704
687
|
}
|
|
705
688
|
|
|
@@ -1085,6 +1068,66 @@ body.vp-search-open {
|
|
|
1085
1068
|
background-color: var(--vp-button-sponsor-active-bg);
|
|
1086
1069
|
}
|
|
1087
1070
|
|
|
1071
|
+
.VPMetricButton {
|
|
1072
|
+
display: inline-flex;
|
|
1073
|
+
align-items: center;
|
|
1074
|
+
gap: 8px;
|
|
1075
|
+
min-height: 30px;
|
|
1076
|
+
border: 1px solid var(--vp-c-divider);
|
|
1077
|
+
border-radius: 999px;
|
|
1078
|
+
padding: 0 12px;
|
|
1079
|
+
color: var(--vp-c-text-2);
|
|
1080
|
+
background: var(--vp-c-bg-soft);
|
|
1081
|
+
font-size: 13px;
|
|
1082
|
+
font-weight: 600;
|
|
1083
|
+
line-height: 1;
|
|
1084
|
+
white-space: nowrap;
|
|
1085
|
+
text-decoration: none !important;
|
|
1086
|
+
transition: color 0.25s, border-color 0.25s, background-color 0.25s;
|
|
1087
|
+
vertical-align: middle;
|
|
1088
|
+
}
|
|
1089
|
+
|
|
1090
|
+
.VPMetricButton:hover {
|
|
1091
|
+
border-color: var(--vp-c-brand-1);
|
|
1092
|
+
color: var(--vp-c-text-1);
|
|
1093
|
+
background: var(--vp-c-bg-elv);
|
|
1094
|
+
}
|
|
1095
|
+
|
|
1096
|
+
.VPMetricButtonIcon {
|
|
1097
|
+
display: inline-flex;
|
|
1098
|
+
flex: 0 0 auto;
|
|
1099
|
+
align-items: center;
|
|
1100
|
+
justify-content: center;
|
|
1101
|
+
width: 14px;
|
|
1102
|
+
height: 14px;
|
|
1103
|
+
color: currentcolor;
|
|
1104
|
+
line-height: 0;
|
|
1105
|
+
}
|
|
1106
|
+
|
|
1107
|
+
.VPMetricButtonIcon svg {
|
|
1108
|
+
display: block;
|
|
1109
|
+
width: 100%;
|
|
1110
|
+
height: 100%;
|
|
1111
|
+
fill: currentcolor;
|
|
1112
|
+
}
|
|
1113
|
+
|
|
1114
|
+
.VPMetricButtonCount {
|
|
1115
|
+
color: var(--vp-c-text-1);
|
|
1116
|
+
font-weight: 600;
|
|
1117
|
+
font-variant-numeric: tabular-nums;
|
|
1118
|
+
}
|
|
1119
|
+
|
|
1120
|
+
.VPMetricButtonText[hidden],
|
|
1121
|
+
.VPMetricButtonCount[hidden] {
|
|
1122
|
+
display: none !important;
|
|
1123
|
+
}
|
|
1124
|
+
|
|
1125
|
+
.vp-doc p:has(> .VPMetricButton) {
|
|
1126
|
+
display: inline-block;
|
|
1127
|
+
margin: 8px 8px 8px 0;
|
|
1128
|
+
line-height: 1;
|
|
1129
|
+
}
|
|
1130
|
+
|
|
1088
1131
|
.VPFeatures {
|
|
1089
1132
|
position: relative;
|
|
1090
1133
|
padding: 0 24px;
|
|
@@ -1695,6 +1738,149 @@ html.dark .only-light {
|
|
|
1695
1738
|
background: var(--vp-c-danger-soft);
|
|
1696
1739
|
}
|
|
1697
1740
|
|
|
1741
|
+
.vp-doc .d-inline-block {
|
|
1742
|
+
display: inline-block;
|
|
1743
|
+
}
|
|
1744
|
+
|
|
1745
|
+
.vp-doc :is(h1, h2, h3, h4, h5, h6).d-inline-block {
|
|
1746
|
+
margin-bottom: 0;
|
|
1747
|
+
vertical-align: middle;
|
|
1748
|
+
}
|
|
1749
|
+
|
|
1750
|
+
.vp-doc :is(p, span).label {
|
|
1751
|
+
display: inline-block;
|
|
1752
|
+
margin: 0 0 0 8px;
|
|
1753
|
+
border-radius: 999px;
|
|
1754
|
+
padding: 0 10px;
|
|
1755
|
+
min-height: 22px;
|
|
1756
|
+
color: #fff;
|
|
1757
|
+
background: var(--vp-c-brand-1);
|
|
1758
|
+
font-size: 13px;
|
|
1759
|
+
font-weight: 700;
|
|
1760
|
+
line-height: 22px;
|
|
1761
|
+
vertical-align: middle;
|
|
1762
|
+
}
|
|
1763
|
+
|
|
1764
|
+
.vp-doc .label.label-blue {
|
|
1765
|
+
background: var(--vp-c-brand-1);
|
|
1766
|
+
}
|
|
1767
|
+
|
|
1768
|
+
.vp-doc .label.label-green {
|
|
1769
|
+
background: var(--vp-c-green-1);
|
|
1770
|
+
}
|
|
1771
|
+
|
|
1772
|
+
.vp-doc .label.label-purple {
|
|
1773
|
+
background: var(--vp-c-indigo-1);
|
|
1774
|
+
}
|
|
1775
|
+
|
|
1776
|
+
.vp-doc .label.label-yellow {
|
|
1777
|
+
color: var(--vp-c-text-1);
|
|
1778
|
+
background: var(--vp-c-warning-2);
|
|
1779
|
+
}
|
|
1780
|
+
|
|
1781
|
+
.vp-doc .label.label-red {
|
|
1782
|
+
background: var(--vp-c-danger-1);
|
|
1783
|
+
}
|
|
1784
|
+
|
|
1785
|
+
.vp-doc :is(h1, h2, h3, h4, h5, h6).d-inline-block + p.label {
|
|
1786
|
+
margin-left: 8px;
|
|
1787
|
+
}
|
|
1788
|
+
|
|
1789
|
+
.vp-doc :is(p, blockquote):is(.info, .note, .tip, .important, .warning, .danger, .caution) {
|
|
1790
|
+
border: 1px solid transparent;
|
|
1791
|
+
border-radius: 8px;
|
|
1792
|
+
padding: 16px;
|
|
1793
|
+
line-height: 24px;
|
|
1794
|
+
font-size: var(--vp-custom-block-font-size);
|
|
1795
|
+
}
|
|
1796
|
+
|
|
1797
|
+
.vp-doc :is(p, blockquote):is(.info, .note, .tip, .important, .warning, .danger, .caution)::before {
|
|
1798
|
+
display: block;
|
|
1799
|
+
margin-bottom: 8px;
|
|
1800
|
+
font-weight: 600;
|
|
1801
|
+
}
|
|
1802
|
+
|
|
1803
|
+
.vp-doc :is(p, blockquote).info {
|
|
1804
|
+
border-color: var(--vp-custom-block-info-border);
|
|
1805
|
+
color: var(--vp-custom-block-info-text);
|
|
1806
|
+
background-color: var(--vp-custom-block-info-bg);
|
|
1807
|
+
}
|
|
1808
|
+
|
|
1809
|
+
.vp-doc :is(p, blockquote).info::before {
|
|
1810
|
+
content: "INFO";
|
|
1811
|
+
}
|
|
1812
|
+
|
|
1813
|
+
.vp-doc :is(p, blockquote).note {
|
|
1814
|
+
border-color: var(--vp-custom-block-note-border);
|
|
1815
|
+
color: var(--vp-custom-block-note-text);
|
|
1816
|
+
background-color: var(--vp-custom-block-note-bg);
|
|
1817
|
+
}
|
|
1818
|
+
|
|
1819
|
+
.vp-doc :is(p, blockquote).note::before {
|
|
1820
|
+
content: "NOTE";
|
|
1821
|
+
}
|
|
1822
|
+
|
|
1823
|
+
.vp-doc :is(p, blockquote).tip {
|
|
1824
|
+
border-color: var(--vp-custom-block-tip-border);
|
|
1825
|
+
color: var(--vp-custom-block-tip-text);
|
|
1826
|
+
background-color: var(--vp-custom-block-tip-bg);
|
|
1827
|
+
}
|
|
1828
|
+
|
|
1829
|
+
.vp-doc :is(p, blockquote).tip::before {
|
|
1830
|
+
content: "TIP";
|
|
1831
|
+
}
|
|
1832
|
+
|
|
1833
|
+
.vp-doc :is(p, blockquote).important {
|
|
1834
|
+
border-color: var(--vp-custom-block-important-border);
|
|
1835
|
+
color: var(--vp-custom-block-important-text);
|
|
1836
|
+
background-color: var(--vp-custom-block-important-bg);
|
|
1837
|
+
}
|
|
1838
|
+
|
|
1839
|
+
.vp-doc :is(p, blockquote).important::before {
|
|
1840
|
+
content: "IMPORTANT";
|
|
1841
|
+
}
|
|
1842
|
+
|
|
1843
|
+
.vp-doc :is(p, blockquote).warning {
|
|
1844
|
+
border-color: var(--vp-custom-block-warning-border);
|
|
1845
|
+
color: var(--vp-custom-block-warning-text);
|
|
1846
|
+
background-color: var(--vp-custom-block-warning-bg);
|
|
1847
|
+
}
|
|
1848
|
+
|
|
1849
|
+
.vp-doc :is(p, blockquote).warning::before {
|
|
1850
|
+
content: "WARNING";
|
|
1851
|
+
}
|
|
1852
|
+
|
|
1853
|
+
.vp-doc :is(p, blockquote).danger {
|
|
1854
|
+
border-color: var(--vp-custom-block-danger-border);
|
|
1855
|
+
color: var(--vp-custom-block-danger-text);
|
|
1856
|
+
background-color: var(--vp-custom-block-danger-bg);
|
|
1857
|
+
}
|
|
1858
|
+
|
|
1859
|
+
.vp-doc :is(p, blockquote).danger::before {
|
|
1860
|
+
content: "DANGER";
|
|
1861
|
+
}
|
|
1862
|
+
|
|
1863
|
+
.vp-doc :is(p, blockquote).caution {
|
|
1864
|
+
border-color: var(--vp-custom-block-caution-border);
|
|
1865
|
+
color: var(--vp-custom-block-caution-text);
|
|
1866
|
+
background-color: var(--vp-custom-block-caution-bg);
|
|
1867
|
+
}
|
|
1868
|
+
|
|
1869
|
+
.vp-doc :is(p, blockquote).caution::before {
|
|
1870
|
+
content: "CAUTION";
|
|
1871
|
+
}
|
|
1872
|
+
|
|
1873
|
+
.vp-doc blockquote:is(.info, .note, .tip, .important, .warning, .danger, .caution) > p {
|
|
1874
|
+
margin: 0;
|
|
1875
|
+
color: inherit;
|
|
1876
|
+
line-height: 24px;
|
|
1877
|
+
font-size: var(--vp-custom-block-font-size);
|
|
1878
|
+
}
|
|
1879
|
+
|
|
1880
|
+
.vp-doc :is(p, blockquote):is(.info, .note, .tip, .important, .warning, .danger, .caution) a {
|
|
1881
|
+
font-weight: 600;
|
|
1882
|
+
}
|
|
1883
|
+
|
|
1698
1884
|
|
|
1699
1885
|
@media (max-width: 1279px) {
|
|
1700
1886
|
.VPDoc.has-aside .content-container {
|
|
@@ -112,6 +112,31 @@
|
|
|
112
112
|
});
|
|
113
113
|
}
|
|
114
114
|
|
|
115
|
+
function formatLastUpdatedTimes(rootElement) {
|
|
116
|
+
var rootNode = rootElement || document;
|
|
117
|
+
var language = navigator.language || document.documentElement.getAttribute('lang') || undefined;
|
|
118
|
+
|
|
119
|
+
rootNode.querySelectorAll('.VPLastUpdated time[data-vp-last-updated][datetime]').forEach(function (time) {
|
|
120
|
+
var date = new Date(time.getAttribute('datetime'));
|
|
121
|
+
if (Number.isNaN(date.getTime())) {
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
try {
|
|
126
|
+
time.textContent = new Intl.DateTimeFormat(language, {
|
|
127
|
+
dateStyle: 'medium',
|
|
128
|
+
timeStyle: 'medium'
|
|
129
|
+
}).format(date);
|
|
130
|
+
|
|
131
|
+
if (language) {
|
|
132
|
+
time.setAttribute('lang', language);
|
|
133
|
+
}
|
|
134
|
+
} catch (error) {
|
|
135
|
+
// Keep the server-rendered fallback if Intl formatting is unavailable.
|
|
136
|
+
}
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
|
|
115
140
|
window.__vpAppearance = {
|
|
116
141
|
getMode: function () {
|
|
117
142
|
return mode;
|
|
@@ -240,6 +265,14 @@
|
|
|
240
265
|
});
|
|
241
266
|
}
|
|
242
267
|
|
|
268
|
+
function formatExactCount(value) {
|
|
269
|
+
try {
|
|
270
|
+
return new Intl.NumberFormat('en-US').format(value);
|
|
271
|
+
} catch (error) {
|
|
272
|
+
return String(value);
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
|
|
243
276
|
function formatGitHubStarCount(value) {
|
|
244
277
|
var count = Number(value);
|
|
245
278
|
if (!Number.isFinite(count) || count < 0) {
|
|
@@ -264,7 +297,7 @@
|
|
|
264
297
|
return;
|
|
265
298
|
}
|
|
266
299
|
|
|
267
|
-
var countElement = button.querySelector('.VPNavBarStarCount');
|
|
300
|
+
var countElement = button.querySelector('.VPNavBarStarCount, .VPMetricButtonCount[data-vp-github-star-count]');
|
|
268
301
|
if (!countElement) {
|
|
269
302
|
return;
|
|
270
303
|
}
|
|
@@ -276,9 +309,20 @@
|
|
|
276
309
|
|
|
277
310
|
countElement.textContent = formatted;
|
|
278
311
|
countElement.hidden = false;
|
|
312
|
+
|
|
313
|
+
if (button.classList.contains('VPMetricButton')) {
|
|
314
|
+
var repository = button.getAttribute('data-github-star-repo');
|
|
315
|
+
var exactCount = formatExactCount(value);
|
|
316
|
+
button.title = exactCount + ' GitHub stars';
|
|
317
|
+
if (repository) {
|
|
318
|
+
button.setAttribute('aria-label', 'Star ' + repository + ' on GitHub: ' + exactCount + ' stars');
|
|
319
|
+
}
|
|
320
|
+
}
|
|
279
321
|
}
|
|
280
322
|
|
|
281
323
|
var githubStarCacheTtlMs = 6 * 60 * 60 * 1000;
|
|
324
|
+
var rubygemsDownloadsCacheTtlMs = 6 * 60 * 60 * 1000;
|
|
325
|
+
var pendingRubyGemsDownloads = {};
|
|
282
326
|
|
|
283
327
|
function readCachedGitHubStarCount(repository) {
|
|
284
328
|
if (!repository || !window.localStorage) {
|
|
@@ -374,9 +418,169 @@
|
|
|
374
418
|
});
|
|
375
419
|
}
|
|
376
420
|
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
421
|
+
function formatRubyGemsDownloads(value) {
|
|
422
|
+
var count = Number(value);
|
|
423
|
+
if (!Number.isFinite(count) || count < 0) {
|
|
424
|
+
return null;
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
if (count >= 1000000) {
|
|
428
|
+
var millions = (count / 1000000).toFixed(count >= 10000000 ? 0 : 1);
|
|
429
|
+
return millions.replace(/\.0$/, '') + 'M';
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
if (count >= 1000) {
|
|
433
|
+
var thousands = (count / 1000).toFixed(count >= 100000 ? 0 : 1);
|
|
434
|
+
return thousands.replace(/\.0$/, '') + 'K';
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
return String(Math.round(count));
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
function setRubyGemsDownloads(button, value) {
|
|
441
|
+
if (!button) {
|
|
442
|
+
return;
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
var countElement = button.querySelector('.VPMetricButtonCount[data-vp-rubygems-downloads-count]');
|
|
446
|
+
if (!countElement) {
|
|
447
|
+
return;
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
var formatted = formatRubyGemsDownloads(value);
|
|
451
|
+
if (!formatted) {
|
|
452
|
+
return;
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
var exactCount = formatExactCount(value);
|
|
456
|
+
var textElement = button.querySelector('.VPMetricButtonText');
|
|
457
|
+
countElement.textContent = formatted + ' downloads';
|
|
458
|
+
countElement.hidden = false;
|
|
459
|
+
if (textElement) {
|
|
460
|
+
textElement.hidden = true;
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
var label = button.getAttribute('data-rubygems-downloads-label') || 'View gem downloads';
|
|
464
|
+
button.title = exactCount + ' downloads on RubyGems';
|
|
465
|
+
button.setAttribute('aria-label', label + ': ' + exactCount + ' downloads');
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
function readCachedRubyGemsDownloads(gemName) {
|
|
469
|
+
if (!gemName || !window.localStorage) {
|
|
470
|
+
return null;
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
try {
|
|
474
|
+
var valueKey = 'vp-rubygems-downloads:value:' + gemName;
|
|
475
|
+
var tsKey = 'vp-rubygems-downloads:ts:' + gemName;
|
|
476
|
+
|
|
477
|
+
var rawValue = localStorage.getItem(valueKey);
|
|
478
|
+
var rawTs = localStorage.getItem(tsKey);
|
|
479
|
+
if (!rawValue || !rawTs) {
|
|
480
|
+
return null;
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
var downloads = Number(rawValue);
|
|
484
|
+
var cachedAt = Number(rawTs);
|
|
485
|
+
if (!Number.isFinite(downloads) || !Number.isFinite(cachedAt)) {
|
|
486
|
+
return null;
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
if (Date.now() - cachedAt > rubygemsDownloadsCacheTtlMs) {
|
|
490
|
+
return null;
|
|
491
|
+
}
|
|
492
|
+
|
|
493
|
+
return { downloads: downloads, cachedAt: cachedAt };
|
|
494
|
+
} catch (error) {
|
|
495
|
+
return null;
|
|
496
|
+
}
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
function writeCachedRubyGemsDownloads(gemName, downloads) {
|
|
500
|
+
if (!gemName || !window.localStorage) {
|
|
501
|
+
return;
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
try {
|
|
505
|
+
var valueKey = 'vp-rubygems-downloads:value:' + gemName;
|
|
506
|
+
var tsKey = 'vp-rubygems-downloads:ts:' + gemName;
|
|
507
|
+
localStorage.setItem(valueKey, String(downloads));
|
|
508
|
+
localStorage.setItem(tsKey, String(Date.now()));
|
|
509
|
+
} catch (error) {
|
|
510
|
+
// Ignore storage errors.
|
|
511
|
+
}
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
function fetchRubyGemsDownloads(gemName) {
|
|
515
|
+
if (!pendingRubyGemsDownloads[gemName]) {
|
|
516
|
+
pendingRubyGemsDownloads[gemName] = fetch('https://rubygems.org/api/v1/gems/' + encodeURIComponent(gemName) + '.json', {
|
|
517
|
+
credentials: 'omit',
|
|
518
|
+
headers: { Accept: 'application/json' }
|
|
519
|
+
})
|
|
520
|
+
.then(function (response) {
|
|
521
|
+
if (!response.ok) {
|
|
522
|
+
throw new Error('RubyGems API request failed');
|
|
523
|
+
}
|
|
524
|
+
return response.json();
|
|
525
|
+
})
|
|
526
|
+
.then(function (data) {
|
|
527
|
+
var downloads = Number(data && data.downloads);
|
|
528
|
+
if (!Number.isFinite(downloads)) {
|
|
529
|
+
throw new Error('RubyGems response missing downloads');
|
|
530
|
+
}
|
|
531
|
+
writeCachedRubyGemsDownloads(gemName, downloads);
|
|
532
|
+
return downloads;
|
|
533
|
+
})
|
|
534
|
+
.catch(function () {
|
|
535
|
+
return null;
|
|
536
|
+
});
|
|
537
|
+
}
|
|
538
|
+
|
|
539
|
+
return pendingRubyGemsDownloads[gemName];
|
|
540
|
+
}
|
|
541
|
+
|
|
542
|
+
function loadRubyGemsDownloads(button) {
|
|
543
|
+
if (!button) {
|
|
544
|
+
return;
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
var showCount = button.getAttribute('data-rubygems-downloads-show-count') !== 'false';
|
|
548
|
+
if (!showCount) {
|
|
549
|
+
return;
|
|
550
|
+
}
|
|
551
|
+
|
|
552
|
+
var gemName = button.getAttribute('data-rubygems-downloads-gem');
|
|
553
|
+
if (!gemName) {
|
|
554
|
+
return;
|
|
555
|
+
}
|
|
556
|
+
|
|
557
|
+
var cached = readCachedRubyGemsDownloads(gemName);
|
|
558
|
+
if (cached && typeof cached.downloads === 'number') {
|
|
559
|
+
setRubyGemsDownloads(button, cached.downloads);
|
|
560
|
+
return;
|
|
561
|
+
}
|
|
562
|
+
|
|
563
|
+
fetchRubyGemsDownloads(gemName).then(function (downloads) {
|
|
564
|
+
if (downloads !== null) {
|
|
565
|
+
setRubyGemsDownloads(button, downloads);
|
|
566
|
+
}
|
|
567
|
+
});
|
|
568
|
+
}
|
|
569
|
+
|
|
570
|
+
function loadMetricButtons(rootElement) {
|
|
571
|
+
var rootNode = rootElement || document;
|
|
572
|
+
|
|
573
|
+
rootNode.querySelectorAll('.VPNavBarStarLink[data-github-star-repo], .VPMetricButton[data-github-star-repo]').forEach(function (button) {
|
|
574
|
+
loadGitHubStarCount(button);
|
|
575
|
+
});
|
|
576
|
+
|
|
577
|
+
rootNode.querySelectorAll('.VPMetricButton[data-rubygems-downloads-gem]').forEach(function (button) {
|
|
578
|
+
loadRubyGemsDownloads(button);
|
|
579
|
+
});
|
|
580
|
+
}
|
|
581
|
+
|
|
582
|
+
loadMetricButtons(document);
|
|
583
|
+
formatLastUpdatedTimes(document);
|
|
380
584
|
|
|
381
585
|
function syncMobileMenus() {
|
|
382
586
|
var anyOpen = navScreenOpen || sidebarOpen;
|
|
@@ -1478,20 +1682,90 @@
|
|
|
1478
1682
|
}
|
|
1479
1683
|
|
|
1480
1684
|
var localOutlineOpen = false;
|
|
1685
|
+
var localOutlineTransitionTimer = null;
|
|
1686
|
+
|
|
1687
|
+
function clearLocalOutlineTransition() {
|
|
1688
|
+
if (localOutlineTransitionTimer) {
|
|
1689
|
+
window.clearTimeout(localOutlineTransitionTimer);
|
|
1690
|
+
localOutlineTransitionTimer = null;
|
|
1691
|
+
}
|
|
1481
1692
|
|
|
1482
|
-
function closeLocalOutline() {
|
|
1483
|
-
localOutlineOpen = false;
|
|
1484
1693
|
if (localOutlineItems) {
|
|
1485
|
-
localOutlineItems.
|
|
1694
|
+
localOutlineItems.classList.remove(
|
|
1695
|
+
'flyout-enter-active',
|
|
1696
|
+
'flyout-enter-from',
|
|
1697
|
+
'flyout-leave-active',
|
|
1698
|
+
'flyout-leave-to'
|
|
1699
|
+
);
|
|
1486
1700
|
}
|
|
1701
|
+
}
|
|
1702
|
+
|
|
1703
|
+
function setLocalOutlineOpen(open, animate) {
|
|
1704
|
+
localOutlineOpen = open;
|
|
1705
|
+
|
|
1487
1706
|
if (localOutlineButton) {
|
|
1488
|
-
localOutlineButton.classList.
|
|
1489
|
-
localOutlineButton.setAttribute('aria-expanded',
|
|
1707
|
+
localOutlineButton.classList.toggle('open', open);
|
|
1708
|
+
localOutlineButton.setAttribute('aria-expanded', String(open));
|
|
1709
|
+
}
|
|
1710
|
+
|
|
1711
|
+
if (!localOutlineItems) {
|
|
1712
|
+
return;
|
|
1490
1713
|
}
|
|
1714
|
+
|
|
1715
|
+
clearLocalOutlineTransition();
|
|
1716
|
+
|
|
1717
|
+
if (open) {
|
|
1718
|
+
localOutlineItems.hidden = false;
|
|
1719
|
+
if (animate !== false) {
|
|
1720
|
+
localOutlineItems.classList.add('flyout-enter-active', 'flyout-enter-from');
|
|
1721
|
+
window.requestAnimationFrame(function () {
|
|
1722
|
+
if (!localOutlineOpen || !localOutlineItems) {
|
|
1723
|
+
return;
|
|
1724
|
+
}
|
|
1725
|
+
|
|
1726
|
+
localOutlineItems.classList.remove('flyout-enter-from');
|
|
1727
|
+
localOutlineTransitionTimer = window.setTimeout(function () {
|
|
1728
|
+
if (localOutlineItems) {
|
|
1729
|
+
localOutlineItems.classList.remove('flyout-enter-active');
|
|
1730
|
+
}
|
|
1731
|
+
localOutlineTransitionTimer = null;
|
|
1732
|
+
}, 200);
|
|
1733
|
+
});
|
|
1734
|
+
}
|
|
1735
|
+
return;
|
|
1736
|
+
}
|
|
1737
|
+
|
|
1738
|
+
if (animate === false || localOutlineItems.hidden) {
|
|
1739
|
+
localOutlineItems.hidden = true;
|
|
1740
|
+
return;
|
|
1741
|
+
}
|
|
1742
|
+
|
|
1743
|
+
localOutlineItems.classList.add('flyout-leave-active');
|
|
1744
|
+
window.requestAnimationFrame(function () {
|
|
1745
|
+
if (localOutlineOpen || !localOutlineItems) {
|
|
1746
|
+
return;
|
|
1747
|
+
}
|
|
1748
|
+
|
|
1749
|
+
localOutlineItems.classList.add('flyout-leave-to');
|
|
1750
|
+
localOutlineTransitionTimer = window.setTimeout(function () {
|
|
1751
|
+
if (localOutlineItems && !localOutlineOpen) {
|
|
1752
|
+
localOutlineItems.hidden = true;
|
|
1753
|
+
localOutlineItems.classList.remove('flyout-leave-active', 'flyout-leave-to');
|
|
1754
|
+
}
|
|
1755
|
+
localOutlineTransitionTimer = null;
|
|
1756
|
+
}, 150);
|
|
1757
|
+
});
|
|
1758
|
+
}
|
|
1759
|
+
|
|
1760
|
+
function closeLocalOutline() {
|
|
1761
|
+
setLocalOutlineOpen(false, true);
|
|
1491
1762
|
}
|
|
1492
1763
|
|
|
1493
1764
|
if (localOutlineButton) {
|
|
1494
1765
|
localOutlineButton.setAttribute('aria-expanded', 'false');
|
|
1766
|
+
if (localOutlineItems && localOutlineItems.id) {
|
|
1767
|
+
localOutlineButton.setAttribute('aria-controls', localOutlineItems.id);
|
|
1768
|
+
}
|
|
1495
1769
|
|
|
1496
1770
|
localOutlineButton.addEventListener('click', function () {
|
|
1497
1771
|
if (!hasOutline) {
|
|
@@ -1499,12 +1773,7 @@
|
|
|
1499
1773
|
return;
|
|
1500
1774
|
}
|
|
1501
1775
|
|
|
1502
|
-
localOutlineOpen
|
|
1503
|
-
if (localOutlineItems) {
|
|
1504
|
-
localOutlineItems.hidden = !localOutlineOpen;
|
|
1505
|
-
}
|
|
1506
|
-
localOutlineButton.classList.toggle('open', localOutlineOpen);
|
|
1507
|
-
localOutlineButton.setAttribute('aria-expanded', String(localOutlineOpen));
|
|
1776
|
+
setLocalOutlineOpen(!localOutlineOpen, true);
|
|
1508
1777
|
});
|
|
1509
1778
|
}
|
|
1510
1779
|
|
|
@@ -1799,6 +2068,8 @@
|
|
|
1799
2068
|
return value || '/';
|
|
1800
2069
|
}
|
|
1801
2070
|
|
|
2071
|
+
var pendingDocFrameHash = null;
|
|
2072
|
+
|
|
1802
2073
|
function shouldTargetDocFrameLink(link) {
|
|
1803
2074
|
if (!link) {
|
|
1804
2075
|
return false;
|
|
@@ -1839,6 +2110,52 @@
|
|
|
1839
2110
|
return true;
|
|
1840
2111
|
}
|
|
1841
2112
|
|
|
2113
|
+
function rememberDocFrameHash(event) {
|
|
2114
|
+
if (event.defaultPrevented || (typeof event.button === 'number' && event.button !== 0) ||
|
|
2115
|
+
event.metaKey || event.ctrlKey || event.shiftKey || event.altKey) {
|
|
2116
|
+
return;
|
|
2117
|
+
}
|
|
2118
|
+
|
|
2119
|
+
var link = event.currentTarget;
|
|
2120
|
+
if (!shouldTargetDocFrameLink(link)) {
|
|
2121
|
+
return;
|
|
2122
|
+
}
|
|
2123
|
+
|
|
2124
|
+
var url;
|
|
2125
|
+
try {
|
|
2126
|
+
url = new URL(link.getAttribute('href'), window.location.href);
|
|
2127
|
+
} catch (error) {
|
|
2128
|
+
pendingDocFrameHash = null;
|
|
2129
|
+
return;
|
|
2130
|
+
}
|
|
2131
|
+
|
|
2132
|
+
pendingDocFrameHash = url.hash || null;
|
|
2133
|
+
}
|
|
2134
|
+
|
|
2135
|
+
function consumePendingDocFrameHash() {
|
|
2136
|
+
var hash = pendingDocFrameHash;
|
|
2137
|
+
pendingDocFrameHash = null;
|
|
2138
|
+
|
|
2139
|
+
if (!hash || !getHashTarget(hash)) {
|
|
2140
|
+
return null;
|
|
2141
|
+
}
|
|
2142
|
+
|
|
2143
|
+
return hash;
|
|
2144
|
+
}
|
|
2145
|
+
|
|
2146
|
+
function restoreLocationHash(hash) {
|
|
2147
|
+
if (!hash || window.location.hash === hash) {
|
|
2148
|
+
return;
|
|
2149
|
+
}
|
|
2150
|
+
|
|
2151
|
+
if (window.history && typeof window.history.replaceState === 'function') {
|
|
2152
|
+
window.history.replaceState(window.history.state, '', window.location.pathname + window.location.search + hash);
|
|
2153
|
+
return;
|
|
2154
|
+
}
|
|
2155
|
+
|
|
2156
|
+
window.location.hash = hash;
|
|
2157
|
+
}
|
|
2158
|
+
|
|
1842
2159
|
function enhanceDocFrameLinks() {
|
|
1843
2160
|
document.querySelectorAll('.vp-doc a[href], .VPDocFooter .pager-link').forEach(function (link) {
|
|
1844
2161
|
if (!shouldTargetDocFrameLink(link)) {
|
|
@@ -1847,6 +2164,10 @@
|
|
|
1847
2164
|
link.setAttribute('data-turbo', 'true');
|
|
1848
2165
|
link.setAttribute('data-turbo-frame', 'vp-content-frame');
|
|
1849
2166
|
link.setAttribute('data-turbo-action', 'advance');
|
|
2167
|
+
if (!link.hasAttribute('data-vp-frame-hash-bound')) {
|
|
2168
|
+
link.setAttribute('data-vp-frame-hash-bound', 'true');
|
|
2169
|
+
link.addEventListener('click', rememberDocFrameHash);
|
|
2170
|
+
}
|
|
1850
2171
|
});
|
|
1851
2172
|
}
|
|
1852
2173
|
|
|
@@ -1971,6 +2292,7 @@
|
|
|
1971
2292
|
marker = document.getElementById('vp-outline-marker');
|
|
1972
2293
|
hasOutline = headings.length > 0;
|
|
1973
2294
|
localOutlineOpen = false;
|
|
2295
|
+
syncLocalOutlineViewportHeight();
|
|
1974
2296
|
|
|
1975
2297
|
if (!hasOutline) {
|
|
1976
2298
|
replaceOutline('.VPDocAsideOutline .VPDocOutlineItem.root', [], true);
|
|
@@ -2021,13 +2343,10 @@
|
|
|
2021
2343
|
replaceOutline('#vp-local-outline-dropdown .outline .VPDocOutlineItem', tree, true);
|
|
2022
2344
|
}
|
|
2023
2345
|
|
|
2024
|
-
|
|
2025
|
-
localOutlineButton.classList.remove('open');
|
|
2026
|
-
localOutlineButton.setAttribute('aria-expanded', 'false');
|
|
2027
|
-
}
|
|
2346
|
+
setLocalOutlineOpen(false, false);
|
|
2028
2347
|
|
|
2029
|
-
if (localOutlineItems) {
|
|
2030
|
-
localOutlineItems.
|
|
2348
|
+
if (localOutlineButton && localOutlineItems && localOutlineItems.id) {
|
|
2349
|
+
localOutlineButton.setAttribute('aria-controls', localOutlineItems.id);
|
|
2031
2350
|
}
|
|
2032
2351
|
|
|
2033
2352
|
bindHashLinkHandlers();
|
|
@@ -2063,8 +2382,14 @@
|
|
|
2063
2382
|
|
|
2064
2383
|
syncPersistentNavState();
|
|
2065
2384
|
refreshDocPageState();
|
|
2066
|
-
|
|
2067
|
-
|
|
2385
|
+
loadMetricButtons(event.target);
|
|
2386
|
+
formatLastUpdatedTimes(event.target);
|
|
2387
|
+
|
|
2388
|
+
var pendingHash = consumePendingDocFrameHash();
|
|
2389
|
+
if (pendingHash) {
|
|
2390
|
+
restoreLocationHash(pendingHash);
|
|
2391
|
+
scrollToHash(pendingHash, false);
|
|
2392
|
+
} else if (window.location.hash) {
|
|
2068
2393
|
scrollToHash(window.location.hash, false);
|
|
2069
2394
|
} else {
|
|
2070
2395
|
window.scrollTo({ top: 0, left: 0, behavior: 'auto' });
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: jekyll-vitepress-theme
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.5.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Carmine Paolino
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-
|
|
11
|
+
date: 2026-06-06 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: jekyll
|
|
@@ -63,6 +63,8 @@ files:
|
|
|
63
63
|
- _includes/alert.html
|
|
64
64
|
- _includes/copy_page_button.html
|
|
65
65
|
- _includes/doc_footer.html
|
|
66
|
+
- _includes/github_sponsor_button.html
|
|
67
|
+
- _includes/github_star_button.html
|
|
66
68
|
- _includes/head.html
|
|
67
69
|
- _includes/home.html
|
|
68
70
|
- _includes/jekyll_vitepress/doc_footer_end.html
|
|
@@ -70,6 +72,7 @@ files:
|
|
|
70
72
|
- _includes/jekyll_vitepress/layout_end.html
|
|
71
73
|
- _includes/local_nav.html
|
|
72
74
|
- _includes/nav.html
|
|
75
|
+
- _includes/rubygems_downloads_button.html
|
|
73
76
|
- _includes/search.html
|
|
74
77
|
- _includes/sidebar.html
|
|
75
78
|
- _layouts/default.html
|