jekyll-theme-docsteer 1.0.0 → 1.1.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 -0
- data/_includes/doc-footer.html +13 -1
- data/_includes/head.html +1 -1
- data/_includes/navbar.html +1 -1
- data/_includes/scripts.html +3 -3
- data/_includes/sidebar.html +28 -1
- data/_layouts/default.html +14 -1
- data/_layouts/doc.html +11 -2
- data/_sass/docsteer/_content.scss +9 -0
- data/_sass/docsteer/_home.scss +26 -0
- data/_sass/docsteer/_lightbox.scss +9 -0
- data/_sass/docsteer/_navbar.scss +16 -1
- data/_sass/docsteer/_sidebar.scss +22 -0
- data/assets/js/search.js +41 -26
- metadata +3 -6
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: efd8a4dee01456dd316c9a4ba45f0762ebed0255b192413774687b8f6ce7143e
|
|
4
|
+
data.tar.gz: 7fc1744dcf4232e345625ad934ed9d9fd4468f705ca5099fe79d4233e980331a
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 66657360820626321676e5100f51c159ba900fb00de2b22c253f68036889120bc9a00c8c19f9079f74ca7db6c9cdf7d84fa2e33c5669273e36f511cf250a839e
|
|
7
|
+
data.tar.gz: 39543eee91a6f6c3ed311941e5e5ab953bc7f9e0dabd8ef9feec253bd8933dc386f4924912d05aaf5ade2615b7a0d8ecef81a0b1db4828a07c96c52b1650e9e9
|
data/README.md
CHANGED
|
@@ -100,6 +100,12 @@ GitHub Pages (via Actions), Netlify, Vercel, Cloudflare Pages — see
|
|
|
100
100
|
(`footer.show_credit: false` to remove it).
|
|
101
101
|
Font Awesome is under its own [Free License](https://fontawesome.com/license/free).
|
|
102
102
|
|
|
103
|
+
## Roadmap
|
|
104
|
+
|
|
105
|
+
Planned work, deferred decisions and the release checklist live in
|
|
106
|
+
[`ROADMAP.md`](ROADMAP.md). Released changes are in
|
|
107
|
+
[`CHANGELOG.md`](CHANGELOG.md).
|
|
108
|
+
|
|
103
109
|
## Support
|
|
104
110
|
|
|
105
111
|
If DocSteer saved you time, you can
|
data/_includes/doc-footer.html
CHANGED
|
@@ -33,6 +33,18 @@
|
|
|
33
33
|
|
|
34
34
|
{% if page.tags and page.tags.size > 0 %}
|
|
35
35
|
<div class="doc-tags">
|
|
36
|
-
{
|
|
36
|
+
{%- comment -%}
|
|
37
|
+
Tags are already in search.json, so a tag is a search the reader has not run
|
|
38
|
+
yet: the button hands the term to the modal. With search off there is
|
|
39
|
+
nothing to hand it to, so it stays the inert badge it was.
|
|
40
|
+
{%- endcomment -%}
|
|
41
|
+
{% for t in page.tags %}
|
|
42
|
+
{%- if site.docsteer.search.enabled -%}
|
|
43
|
+
<button type="button" class="badge badge--soft doc-tag"
|
|
44
|
+
data-search-open="{{ t }}" aria-label="Search for {{ t }}">#{{ t }}</button>
|
|
45
|
+
{%- else -%}
|
|
46
|
+
<span class="badge badge--soft">#{{ t }}</span>
|
|
47
|
+
{%- endif -%}
|
|
48
|
+
{% endfor %}
|
|
37
49
|
</div>
|
|
38
50
|
{% endif %}
|
data/_includes/head.html
CHANGED
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
{% endif %}
|
|
40
40
|
{% endif %}
|
|
41
41
|
|
|
42
|
-
<link rel="stylesheet" href="{{ '/assets/css/main.css' | relative_url }}">
|
|
42
|
+
<link rel="stylesheet" href="{{ '/assets/css/main.css' | relative_url }}?v={{ ds_version }}">
|
|
43
43
|
|
|
44
44
|
{% if site.feed.path %}
|
|
45
45
|
<link rel="alternate" type="application/atom+xml" title="{{ site.title }}" href="{{ '/feed.xml' | relative_url }}">
|
data/_includes/navbar.html
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{%- assign cfg = site.docsteer -%}
|
|
2
2
|
<header class="navbar" id="navbar">
|
|
3
3
|
<div class="navbar__inner">
|
|
4
|
-
<button class="navbar__burger" id="sidebarToggle" aria-label="Open menu" aria-expanded="false">
|
|
4
|
+
<button class="navbar__burger" id="sidebarToggle" aria-controls="sidebar" aria-label="Open menu" aria-expanded="false">
|
|
5
5
|
<i class="fa-solid fa-bars" aria-hidden="true"></i>
|
|
6
6
|
</button>
|
|
7
7
|
|
data/_includes/scripts.html
CHANGED
|
@@ -17,6 +17,6 @@
|
|
|
17
17
|
}
|
|
18
18
|
};
|
|
19
19
|
</script>
|
|
20
|
-
<script src="{{ '/assets/js/main.js' | relative_url }}" defer></script>
|
|
21
|
-
{% if cfg.search.enabled %}<script src="{{ '/assets/js/search.js' | relative_url }}" defer></script>{% endif %}
|
|
22
|
-
{% if cfg.lightbox.enabled %}<script src="{{ '/assets/js/lightbox.js' | relative_url }}" defer></script>{% endif %}
|
|
20
|
+
<script src="{{ '/assets/js/main.js' | relative_url }}?v={{ ds_version }}" defer></script>
|
|
21
|
+
{% if cfg.search.enabled %}<script src="{{ '/assets/js/search.js' | relative_url }}?v={{ ds_version }}" defer></script>{% endif %}
|
|
22
|
+
{% if cfg.lightbox.enabled %}<script src="{{ '/assets/js/lightbox.js' | relative_url }}?v={{ ds_version }}" defer></script>{% endif %}
|
data/_includes/sidebar.html
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
{%- assign cfg = site.docsteer -%}
|
|
2
|
-
|
|
2
|
+
{%- comment -%}
|
|
3
|
+
Rendered on EVERY page, because the navbar burger is shown on every page at
|
|
4
|
+
mobile widths and has to open something. `include.docs` says whether this
|
|
5
|
+
page also gets the documentation tree; when it is false the aside exists
|
|
6
|
+
only as the mobile drawer (see .sidebar--drawer-only).
|
|
7
|
+
{%- endcomment -%}
|
|
8
|
+
{%- assign show_docs = include.docs -%}
|
|
9
|
+
<aside class="sidebar{% unless show_docs %} sidebar--drawer-only{% endunless %}{% if cfg.sidebar.sticky and show_docs %} is-sticky{% endif %}"
|
|
10
|
+
id="sidebar" aria-label="Site navigation">
|
|
3
11
|
<div class="sidebar__inner">
|
|
4
12
|
|
|
5
13
|
{% if cfg.search.enabled %}
|
|
@@ -9,6 +17,24 @@
|
|
|
9
17
|
</button>
|
|
10
18
|
{% endif %}
|
|
11
19
|
|
|
20
|
+
{%- comment -%}
|
|
21
|
+
The navbar's primary links are hidden below 960px, so the drawer carries
|
|
22
|
+
them. Hidden again on desktop, where the navbar shows them itself.
|
|
23
|
+
{%- endcomment -%}
|
|
24
|
+
<nav class="sidebar__primary" aria-label="Primary">
|
|
25
|
+
<a href="{{ '/' | relative_url }}"
|
|
26
|
+
class="sidebar__link{% if page.url == '/' %} is-active{% endif %}">
|
|
27
|
+
<i class="fa-solid fa-house" aria-hidden="true"></i>Home
|
|
28
|
+
</a>
|
|
29
|
+
{% for item in site.data.navigation.main %}
|
|
30
|
+
<a href="{{ item.url | relative_url }}"
|
|
31
|
+
class="sidebar__link{% if page.url contains item.url and item.url != '/' %} is-active{% endif %}">
|
|
32
|
+
{% if item.icon %}<i class="{{ item.icon }}" aria-hidden="true"></i>{% endif %}{{ item.title }}
|
|
33
|
+
</a>
|
|
34
|
+
{% endfor %}
|
|
35
|
+
</nav>
|
|
36
|
+
|
|
37
|
+
{% if show_docs %}
|
|
12
38
|
<nav class="sidebar__nav">
|
|
13
39
|
{% for group in site.data.navigation.sidebar %}
|
|
14
40
|
{%- assign group_active = false -%}
|
|
@@ -40,6 +66,7 @@
|
|
|
40
66
|
</div>
|
|
41
67
|
{% endfor %}
|
|
42
68
|
</nav>
|
|
69
|
+
{% endif %}
|
|
43
70
|
|
|
44
71
|
{% if cfg.buy_me_a_coffee.username and cfg.buy_me_a_coffee.show_in contains "sidebar" %}
|
|
45
72
|
<div class="sidebar__coffee">{% include buy-me-a-coffee.html %}</div>
|
data/_layouts/default.html
CHANGED
|
@@ -2,6 +2,13 @@
|
|
|
2
2
|
{%- assign cfg = site.docsteer -%}
|
|
3
3
|
{%- assign skin = cfg.skin | default: "aqua" -%}
|
|
4
4
|
{%- assign mode = cfg.mode | default: "auto" -%}
|
|
5
|
+
{%- comment -%}
|
|
6
|
+
Cache-busting token for the theme's own CSS and JS. Bumped with spec.version
|
|
7
|
+
in jekyll-theme-docsteer.gemspec: keyed to the theme's version rather than to
|
|
8
|
+
site.time so a content-only rebuild does not force every visitor to
|
|
9
|
+
re-download assets that did not change.
|
|
10
|
+
{%- endcomment -%}
|
|
11
|
+
{%- assign ds_version = "1.1.0" -%}
|
|
5
12
|
<html lang="{{ site.lang | default: 'en' }}"
|
|
6
13
|
data-skin="{{ skin }}"
|
|
7
14
|
{% if mode != "auto" %}data-mode="{{ mode }}"{% endif %}>
|
|
@@ -24,8 +31,14 @@
|
|
|
24
31
|
{%- assign show_sidebar = true -%}
|
|
25
32
|
{%- endif -%}
|
|
26
33
|
|
|
34
|
+
{%- comment -%}
|
|
35
|
+
The aside is rendered on every page: below 960px it is the drawer the
|
|
36
|
+
navbar burger opens, and a page with no drawer leaves the burger dead and
|
|
37
|
+
the primary nav unreachable. Only `has-sidebar` — the desktop grid column —
|
|
38
|
+
is conditional.
|
|
39
|
+
{%- endcomment -%}
|
|
27
40
|
<div class="page-shell{% if show_sidebar %} has-sidebar{% endif %}">
|
|
28
|
-
{%
|
|
41
|
+
{% include sidebar.html docs=show_sidebar %}
|
|
29
42
|
|
|
30
43
|
<main id="main" class="page-main{% if show_sidebar %} has-sidebar{% endif %}" tabindex="-1">
|
|
31
44
|
{{ content }}
|
data/_layouts/doc.html
CHANGED
|
@@ -10,9 +10,18 @@ layout: default
|
|
|
10
10
|
{% if page.description %}<p class="doc-head__lead">{{ page.description }}</p>{% endif %}
|
|
11
11
|
|
|
12
12
|
<div class="doc-head__meta">
|
|
13
|
-
{
|
|
13
|
+
{%- comment -%}
|
|
14
|
+
`last_modified_at` is the field jekyll-seo-tag reads for dateModified,
|
|
15
|
+
so using it here keeps this row and the structured data on one source.
|
|
16
|
+
`updated` is kept as a fallback for pages written against DocSteer 1.0.
|
|
17
|
+
`page.date` is last on purpose: Jekyll invents one equal to the build
|
|
18
|
+
time for collection documents that have none, so it is a date only in
|
|
19
|
+
the sense that it parses.
|
|
20
|
+
{%- endcomment -%}
|
|
21
|
+
{%- assign doc_date = page.last_modified_at | default: page.updated | default: page.date -%}
|
|
22
|
+
{% if doc_date %}
|
|
14
23
|
<span><i class="fa-regular fa-clock" aria-hidden="true"></i>
|
|
15
|
-
Updated {{
|
|
24
|
+
Updated {{ doc_date | date: "%b %-d, %Y" }}</span>
|
|
16
25
|
{% endif %}
|
|
17
26
|
{% if page.read_time %}
|
|
18
27
|
<span><i class="fa-regular fa-file-lines" aria-hidden="true"></i> {{ page.read_time }} min read</span>
|
|
@@ -293,6 +293,15 @@ h4:hover > .heading-anchor, .heading-anchor:focus-visible { opacity: 1; }
|
|
|
293
293
|
.doc-pager__title { font-weight: 600; color: var(--brand); line-height: 1.4; }
|
|
294
294
|
|
|
295
295
|
.doc-tags { margin-top: var(--sp-6); display: flex; flex-wrap: wrap; gap: var(--sp-2); }
|
|
296
|
+
.doc-tag {
|
|
297
|
+
transition: color var(--dur) var(--ease), background var(--dur) var(--ease),
|
|
298
|
+
border-color var(--dur) var(--ease);
|
|
299
|
+
}
|
|
300
|
+
.doc-tag:hover {
|
|
301
|
+
color: var(--brand-contrast);
|
|
302
|
+
background: var(--brand);
|
|
303
|
+
border-color: transparent;
|
|
304
|
+
}
|
|
296
305
|
|
|
297
306
|
@media (max-width: 560px) {
|
|
298
307
|
.doc-pager { grid-template-columns: 1fr; }
|
data/_sass/docsteer/_home.scss
CHANGED
|
@@ -182,3 +182,29 @@
|
|
|
182
182
|
.hero { padding-block: var(--sp-7) var(--sp-6); }
|
|
183
183
|
.hero__search { margin-top: var(--sp-6); }
|
|
184
184
|
}
|
|
185
|
+
|
|
186
|
+
@media (max-width: 560px) {
|
|
187
|
+
// Narrow enough that .link-section__grid has collapsed to one column. A
|
|
188
|
+
// full-width tile with the icon stacked above two short lines is mostly
|
|
189
|
+
// empty space, so the icon moves into a left column and the tile becomes as
|
|
190
|
+
// short as its text. Tiles configured without an icon keep the stacked
|
|
191
|
+
// layout — there is no first column for them to fill.
|
|
192
|
+
// Tiles this short need the gap between them to read as bigger than the gap
|
|
193
|
+
// between a tile's own two lines, or the column reads as one block.
|
|
194
|
+
.link-section__grid { gap: var(--sp-4); }
|
|
195
|
+
|
|
196
|
+
.link-tile:has(> i) {
|
|
197
|
+
grid-template-columns: auto minmax(0, 1fr);
|
|
198
|
+
align-items: center;
|
|
199
|
+
column-gap: var(--sp-4);
|
|
200
|
+
row-gap: var(--sp-1);
|
|
201
|
+
padding: var(--sp-4);
|
|
202
|
+
}
|
|
203
|
+
.link-tile:has(> i) > i {
|
|
204
|
+
grid-row: 1 / span 2;
|
|
205
|
+
margin-bottom: 0;
|
|
206
|
+
font-size: 1.05rem;
|
|
207
|
+
}
|
|
208
|
+
.link-tile:has(> i) > .link-tile__title,
|
|
209
|
+
.link-tile:has(> i) > .link-tile__text { grid-column: 2; }
|
|
210
|
+
}
|
|
@@ -28,6 +28,15 @@
|
|
|
28
28
|
box-shadow: 0 24px 80px hsl(0 0% 0% / .5);
|
|
29
29
|
animation: pop .18s var(--ease);
|
|
30
30
|
}
|
|
31
|
+
// An SVG carrying only a viewBox has no intrinsic size, so the rules above —
|
|
32
|
+
// which cap, never grow — leave it at the browser's 300x150 default: it would
|
|
33
|
+
// open SMALLER than it appears in the page. Raster images are deliberately not
|
|
34
|
+
// covered, since stretching them would just upscale a small screenshot into a
|
|
35
|
+
// blurry mess. Authors can also avoid this by putting width/height on the SVG.
|
|
36
|
+
.lightbox__img[src$=".svg"] {
|
|
37
|
+
width: min(1100px, 94vw);
|
|
38
|
+
height: auto;
|
|
39
|
+
}
|
|
31
40
|
.lightbox__caption { color: hsl(0 0% 100% / .82); font-size: .88rem; text-align: center; }
|
|
32
41
|
|
|
33
42
|
.lightbox__btn {
|
data/_sass/docsteer/_navbar.scss
CHANGED
|
@@ -164,6 +164,21 @@
|
|
|
164
164
|
.navbar__links { display: none; }
|
|
165
165
|
}
|
|
166
166
|
@media (max-width: 560px) {
|
|
167
|
-
.brand__name { display: none; }
|
|
168
167
|
.navbar__inner { gap: var(--sp-1); padding-inline: var(--sp-4); }
|
|
168
|
+
|
|
169
|
+
// The navbar is the only place on a phone that names the site — the hero
|
|
170
|
+
// headline is the page's title, not the project's. So the name stays and the
|
|
171
|
+
// brand is the one thing allowed to give way: the icon buttons hold their
|
|
172
|
+
// size, and a title too long for the row truncates instead of disappearing.
|
|
173
|
+
.brand { min-width: 0; }
|
|
174
|
+
.brand__name {
|
|
175
|
+
min-width: 0;
|
|
176
|
+
overflow: hidden;
|
|
177
|
+
text-overflow: ellipsis;
|
|
178
|
+
white-space: nowrap;
|
|
179
|
+
}
|
|
180
|
+
.navbar__burger,
|
|
181
|
+
.brand__mark,
|
|
182
|
+
.brand__logo,
|
|
183
|
+
.navbar__tools { flex: none; }
|
|
169
184
|
}
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
// (and runs the border the whole height of the page, which looks better).
|
|
9
9
|
align-self: stretch;
|
|
10
10
|
}
|
|
11
|
+
.sidebar--drawer-only { display: none; }
|
|
11
12
|
.sidebar.is-sticky .sidebar__inner {
|
|
12
13
|
position: sticky;
|
|
13
14
|
top: var(--nav-h);
|
|
@@ -53,6 +54,11 @@
|
|
|
53
54
|
}
|
|
54
55
|
.sidebar__search i { font-size: .85em; }
|
|
55
56
|
|
|
57
|
+
// ── Primary nav (drawer only) ─────────────────────
|
|
58
|
+
// The navbar hides its own links below 960px, so the drawer carries them.
|
|
59
|
+
// Above that the navbar shows them and this would only be a duplicate.
|
|
60
|
+
.sidebar__primary { display: none; }
|
|
61
|
+
|
|
56
62
|
// ── Groups ───────────────────────────────────────────────────
|
|
57
63
|
.sidebar__nav { display: grid; gap: var(--sp-1); }
|
|
58
64
|
|
|
@@ -156,4 +162,20 @@
|
|
|
156
162
|
.sidebar.is-sticky .sidebar__inner { position: static; max-height: none; }
|
|
157
163
|
.sidebar__inner { padding-top: calc(var(--nav-h) + var(--sp-4)); height: 100%; }
|
|
158
164
|
.sidebar__link { min-height: 38px; }
|
|
165
|
+
|
|
166
|
+
// Pages with no documentation tree still render the aside, purely so the
|
|
167
|
+
// burger has a drawer to open. It exists only at drawer widths.
|
|
168
|
+
.sidebar--drawer-only { display: block; }
|
|
169
|
+
|
|
170
|
+
.sidebar__primary { display: grid; gap: 2px; }
|
|
171
|
+
.sidebar__primary .sidebar__link { gap: var(--sp-3); font-size: var(--fs-md); }
|
|
172
|
+
.sidebar__primary .sidebar__link > i { width: 1.1em; text-align: center; opacity: .8; }
|
|
173
|
+
// The active rail is drawn on the group's border-left, which this nav has no
|
|
174
|
+
// list to hang off — the marker would float in the padding.
|
|
175
|
+
.sidebar__primary .sidebar__link.is-active::before { content: none; }
|
|
176
|
+
.sidebar__primary + .sidebar__nav {
|
|
177
|
+
margin-top: var(--sp-5);
|
|
178
|
+
padding-top: var(--sp-5);
|
|
179
|
+
border-top: 1px solid var(--border);
|
|
180
|
+
}
|
|
159
181
|
}
|
data/assets/js/search.js
CHANGED
|
@@ -17,14 +17,16 @@
|
|
|
17
17
|
|
|
18
18
|
var MAX = parseInt(list.dataset.max, 10) || DocSteer.search.max || 8;
|
|
19
19
|
var index = null;
|
|
20
|
-
var
|
|
20
|
+
var indexPromise = null;
|
|
21
21
|
var activeIdx = -1;
|
|
22
22
|
var lastFocus = null;
|
|
23
23
|
|
|
24
|
+
// The in-flight promise is what gets cached, not a boolean: a second caller
|
|
25
|
+
// arriving mid-fetch has to wait for the same request, and the old `loading`
|
|
26
|
+
// flag resolved it with a null index instead.
|
|
24
27
|
function loadIndex() {
|
|
25
|
-
if (
|
|
26
|
-
|
|
27
|
-
return fetch(list.dataset.endpoint || DocSteer.search.endpoint)
|
|
28
|
+
if (indexPromise) return indexPromise;
|
|
29
|
+
indexPromise = fetch(list.dataset.endpoint || DocSteer.search.endpoint)
|
|
28
30
|
.then(function (r) { return r.json(); })
|
|
29
31
|
.then(function (data) {
|
|
30
32
|
index = data.map(function (d) {
|
|
@@ -37,10 +39,10 @@
|
|
|
37
39
|
(d.category || "") + " " + (d.content || "")).toLowerCase()
|
|
38
40
|
};
|
|
39
41
|
});
|
|
40
|
-
loading = false;
|
|
41
42
|
return index;
|
|
42
43
|
})
|
|
43
|
-
.catch(function () {
|
|
44
|
+
.catch(function () { indexPromise = null; return []; });
|
|
45
|
+
return indexPromise;
|
|
44
46
|
}
|
|
45
47
|
|
|
46
48
|
function scoreItem(item, terms, raw) {
|
|
@@ -118,37 +120,47 @@
|
|
|
118
120
|
});
|
|
119
121
|
}
|
|
120
122
|
|
|
123
|
+
function runSearch(raw) {
|
|
124
|
+
if (raw.length < 2) {
|
|
125
|
+
list.innerHTML = "";
|
|
126
|
+
empty.hidden = true;
|
|
127
|
+
hint.hidden = false;
|
|
128
|
+
input.setAttribute("aria-expanded", "false");
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
loadIndex().then(function (idx) {
|
|
132
|
+
var terms = raw.split(/\s+/);
|
|
133
|
+
var scored = [];
|
|
134
|
+
for (var i = 0; i < idx.length; i++) {
|
|
135
|
+
var s = scoreItem(idx[i], terms, raw);
|
|
136
|
+
if (s > 0) scored.push({ item: idx[i], s: s });
|
|
137
|
+
}
|
|
138
|
+
scored.sort(function (a, b) { return b.s - a.s; });
|
|
139
|
+
render(scored.slice(0, MAX).map(function (x) { return x.item; }), terms);
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
|
|
121
143
|
var debounce;
|
|
122
144
|
function onInput() {
|
|
123
145
|
clearTimeout(debounce);
|
|
124
146
|
debounce = setTimeout(function () {
|
|
125
|
-
|
|
126
|
-
if (raw.length < 2) {
|
|
127
|
-
list.innerHTML = "";
|
|
128
|
-
empty.hidden = true;
|
|
129
|
-
hint.hidden = false;
|
|
130
|
-
input.setAttribute("aria-expanded", "false");
|
|
131
|
-
return;
|
|
132
|
-
}
|
|
133
|
-
loadIndex().then(function (idx) {
|
|
134
|
-
var terms = raw.split(/\s+/);
|
|
135
|
-
var scored = [];
|
|
136
|
-
for (var i = 0; i < idx.length; i++) {
|
|
137
|
-
var s = scoreItem(idx[i], terms, raw);
|
|
138
|
-
if (s > 0) scored.push({ item: idx[i], s: s });
|
|
139
|
-
}
|
|
140
|
-
scored.sort(function (a, b) { return b.s - a.s; });
|
|
141
|
-
render(scored.slice(0, MAX).map(function (x) { return x.item; }), terms);
|
|
142
|
-
});
|
|
147
|
+
runSearch(input.value.trim().toLowerCase());
|
|
143
148
|
}, 90);
|
|
144
149
|
}
|
|
145
150
|
|
|
146
|
-
|
|
151
|
+
// `query` opens the modal on a term rather than on an empty field — the doc
|
|
152
|
+
// footer's tags use it, so a tag lands on its results instead of on a blank
|
|
153
|
+
// search. select() leaves it highlighted, so typing still replaces it.
|
|
154
|
+
function open(query) {
|
|
147
155
|
lastFocus = document.activeElement;
|
|
148
156
|
modal.classList.add("is-open");
|
|
149
157
|
modal.setAttribute("aria-hidden", "false");
|
|
150
158
|
document.body.style.overflow = "hidden";
|
|
151
159
|
loadIndex();
|
|
160
|
+
if (query) {
|
|
161
|
+
input.value = query;
|
|
162
|
+
runSearch(query.trim().toLowerCase());
|
|
163
|
+
}
|
|
152
164
|
setTimeout(function () { input.focus(); input.select(); }, 20);
|
|
153
165
|
}
|
|
154
166
|
function close() {
|
|
@@ -159,7 +171,10 @@
|
|
|
159
171
|
}
|
|
160
172
|
|
|
161
173
|
$$("[data-search-open]").forEach(function (b) {
|
|
162
|
-
b.addEventListener("click", function (e) {
|
|
174
|
+
b.addEventListener("click", function (e) {
|
|
175
|
+
e.preventDefault();
|
|
176
|
+
open(b.getAttribute("data-search-open"));
|
|
177
|
+
});
|
|
163
178
|
});
|
|
164
179
|
$$("[data-search-close]").forEach(function (b) {
|
|
165
180
|
b.addEventListener("click", close);
|
metadata
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: jekyll-theme-docsteer
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.1.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Cristian Castellari
|
|
8
|
-
autorequire:
|
|
9
8
|
bindir: bin
|
|
10
9
|
cert_chain: []
|
|
11
|
-
date:
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
12
11
|
dependencies:
|
|
13
12
|
- !ruby/object:Gem::Dependency
|
|
14
13
|
name: jekyll
|
|
@@ -168,7 +167,6 @@ metadata:
|
|
|
168
167
|
plugin_type: theme
|
|
169
168
|
source_code_uri: https://github.com/Skyflash/docsteer
|
|
170
169
|
bug_tracker_uri: https://github.com/Skyflash/docsteer/issues
|
|
171
|
-
post_install_message:
|
|
172
170
|
rdoc_options: []
|
|
173
171
|
require_paths:
|
|
174
172
|
- lib
|
|
@@ -183,8 +181,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
183
181
|
- !ruby/object:Gem::Version
|
|
184
182
|
version: '0'
|
|
185
183
|
requirements: []
|
|
186
|
-
rubygems_version: 3.
|
|
187
|
-
signing_key:
|
|
184
|
+
rubygems_version: 3.6.9
|
|
188
185
|
specification_version: 4
|
|
189
186
|
summary: Simple, searchable docs and knowledge bases for teams.
|
|
190
187
|
test_files: []
|