monoholic 1.2.0 → 1.3.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 +77 -2
- data/_includes/menu.html +30 -23
- data/_layouts/default.html +8 -0
- data/_layouts/home.html +2 -0
- data/_sass/_base.scss +2 -0
- data/_sass/_content.scss +31 -9
- data/assets/js/content-scroll.js +109 -0
- data/robots.txt +8 -0
- metadata +18 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 944d762c5b588ea620fe59093575adf3fe51488e84a04cbb31dd5b34619d9aed
|
|
4
|
+
data.tar.gz: 1ba6737b6d4e3b1e6e207f4cebadb2b51ea7f8608ff89cb139e89d1de8c25561
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 2051528bae7940745198bb450bf329d07f0e203230e05226735625a8da40d6b73bf726a58452f3d016fdefb4a052bd2d38e61655d07c828ec7d5c2adedef313a
|
|
7
|
+
data.tar.gz: 650a541107d5966c16485b3c483654ab3c5f9fa3ca7897401d92f00b423d8eadd4722107b8c97844bbf389879af30966c58a9649d625dc4dc082d52c5a3c3237
|
data/README.md
CHANGED
|
@@ -48,16 +48,17 @@ plugins:
|
|
|
48
48
|
- jekyll-remote-theme
|
|
49
49
|
- jekyll-feed
|
|
50
50
|
- jekyll-seo-tag
|
|
51
|
+
- jekyll-sitemap
|
|
51
52
|
```
|
|
52
53
|
|
|
53
|
-
`jekyll-remote-theme` fetches the theme on Pages; `jekyll-feed` and `jekyll-seo-tag` are required by the theme's `head.html` (`{% feed_meta %}`, `{% seo %}`). For project sites, also set `baseurl` (e.g. `/your-repo`) and `url` (e.g. `https://<user>.github.io`). To pin a release: `remote_theme: stiermid/monoholic@v1.
|
|
54
|
+
`jekyll-remote-theme` fetches the theme on Pages; `jekyll-feed` and `jekyll-seo-tag` are required by the theme's `head.html` (`{% feed_meta %}`, `{% seo %}`), and `jekyll-sitemap` generates `sitemap.xml` referenced by the theme's `robots.txt`. For project sites, also set `baseurl` (e.g. `/your-repo`) and `url` (e.g. `https://<user>.github.io`). To pin a release: `remote_theme: stiermid/monoholic@v1.3.0`.
|
|
54
55
|
|
|
55
56
|
> **Pages note:** Native GitHub Pages builds run Jekyll 3.9. The `monoholic` RubyGem requires Jekyll 4.4, so on GitHub Pages use `remote_theme` only (not `theme:` + `gem "monoholic"`). SCSS intentionally uses `@import` for 3.9 compatibility.
|
|
56
57
|
|
|
57
58
|
| Install method | Jekyll | How |
|
|
58
59
|
| -------------------------------------------------------- | ------------- | --------------------------- |
|
|
59
60
|
| RubyGems (`theme: monoholic`) | 4.4 | local / CI / non-Pages host |
|
|
60
|
-
| GitHub Pages (`remote_theme: stiermid/monoholic@v1.
|
|
61
|
+
| GitHub Pages (`remote_theme: stiermid/monoholic@v1.3.0`) | 3.9 via Pages | Pages only |
|
|
61
62
|
|
|
62
63
|
Or, simply fork this repository, adapt the `_config.yml` according to your needs, and you're good to go!
|
|
63
64
|
|
|
@@ -67,6 +68,8 @@ Or, simply fork this repository, adapt the `_config.yml` according to your needs
|
|
|
67
68
|
|
|
68
69
|
Once installed, build your site using the provided layouts (`default`, `home`, `page`, `post`).
|
|
69
70
|
|
|
71
|
+
On pages using the `home` layout, page content appears before the sections defined in `_data/menu.yml`.
|
|
72
|
+
|
|
70
73
|
### Configuration
|
|
71
74
|
|
|
72
75
|
Override the default settings in your `_config.yml`. Key theme configuration options:
|
|
@@ -133,6 +136,15 @@ entries:
|
|
|
133
136
|
|
|
134
137
|
Nesting can go as deep as needed — `menu.html` includes itself recursively for each `entries` array it encounters.
|
|
135
138
|
|
|
139
|
+
Top-level titles use `h2`. Each titled parent advances its children by one heading level, capped at `h6`. Entries with missing, empty, or whitespace-only titles are unlabelled groups: they render no heading and do not advance the heading level. Later siblings always retain their own level, regardless of the depth of earlier branches.
|
|
140
|
+
|
|
141
|
+
Each titled section is labelled by its heading. Heading IDs include the ancestor path and sibling index, so repeated titles remain distinct. When including multiple copies of a menu on the same page, give each copy a distinct `id_prefix` to avoid overlapping IDs:
|
|
142
|
+
|
|
143
|
+
```liquid
|
|
144
|
+
{% include menu.html collection=site.data.menu.entries level=2 id_prefix='primary' %}
|
|
145
|
+
{% include menu.html collection=site.data.menu.entries level=2 id_prefix='secondary' %}
|
|
146
|
+
```
|
|
147
|
+
|
|
136
148
|
#### Using External Content Files
|
|
137
149
|
|
|
138
150
|
You can reference external markdown files instead of inline content:
|
|
@@ -171,6 +183,23 @@ Note: the theme uses `@import` (not `@use`) to stay compatible with GitHub Pages
|
|
|
171
183
|
|
|
172
184
|
To override CSS custom properties (colors, spacing, fonts) without touching SCSS, redeclare the variables in your own stylesheet — they are exposed under `:root` in `_sass/_variables.scss`.
|
|
173
185
|
|
|
186
|
+
### Responsive Content
|
|
187
|
+
|
|
188
|
+
Long words, URLs, and inline code wrap when necessary. Plain and highlighted code blocks preserve indentation and source lines, scrolling horizontally inside the block instead of expanding the page.
|
|
189
|
+
|
|
190
|
+
The small, dependency-free `assets/js/content-scroll.js` script progressively enhances tables with scroll containers while preserving native table semantics. Overflowing tables and code blocks receive a keyboard tab stop, an accessible name, and a visible scrolling hint. These are updated when the viewport, content dimensions, or fonts change; fitting content does not add automatic tab stops.
|
|
191
|
+
|
|
192
|
+
Table captions are used as accessible names when available. Existing author-provided labels, descriptions, and tab indices are preserved. You can translate the default labels and hint in `_config.yml`:
|
|
193
|
+
|
|
194
|
+
```yaml
|
|
195
|
+
theme_config:
|
|
196
|
+
table_scroll_label: "Table"
|
|
197
|
+
code_scroll_label: "Code block"
|
|
198
|
+
scroll_hint: "Scroll horizontally to see more."
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
Without JavaScript, tables use fixed-layout, wrapping cells, and code blocks still scroll. For especially wide tables that should scroll even without JavaScript, supply a `.table-scroll` wrapper with `tabindex="0"`, `role="region"`, and an accessible name (`aria-label` or `aria-labelledby`). The enhancement reuses that wrapper rather than nesting another one.
|
|
202
|
+
|
|
174
203
|
### Per-Page JavaScript
|
|
175
204
|
|
|
176
205
|
To load custom JavaScript files on a specific page, add a `custom_js` list to the page's front matter:
|
|
@@ -188,6 +217,52 @@ Each entry is a filename (without `.js`) relative to `assets/js/`. The example a
|
|
|
188
217
|
|
|
189
218
|
## Contributing
|
|
190
219
|
|
|
220
|
+
### Running Tests
|
|
221
|
+
|
|
222
|
+
```sh
|
|
223
|
+
bundle install
|
|
224
|
+
npm ci
|
|
225
|
+
npx playwright install --with-deps chromium firefox webkit
|
|
226
|
+
bundle exec ruby _tests/release_workflow_test.rb
|
|
227
|
+
bundle exec ruby _tests/release_tag_test.rb
|
|
228
|
+
bundle exec ruby _tests/home_layout_test.rb
|
|
229
|
+
bundle exec ruby _tests/menu_layout_test.rb
|
|
230
|
+
JEKYLL_SAFE=1 bundle exec ruby _tests/menu_layout_test.rb
|
|
231
|
+
npm run test:browser
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
Browser tests build and serve an isolated fixture site. They cover Chromium, Firefox, and WebKit at 320px, 375px, 768px, and 1280px, including long text, plain and highlighted code, Markdown and HTML tables, keyboard scrolling, resizing, and JavaScript-disabled layouts. External fonts are blocked so the tests do not depend on Google Fonts being available.
|
|
235
|
+
|
|
236
|
+
Menu rendering checks cover branching recursion, deep nesting, untitled groups, repeated titles, unique IDs, escaped labels, and independent menu instances in normal and Jekyll safe mode. Browser tests also verify native heading and section semantics with JavaScript disabled.
|
|
237
|
+
|
|
238
|
+
To run one browser, use `npm run test:browser -- --project=chromium`. You can also set `PLAYWRIGHT_CHROMIUM_EXECUTABLE_PATH` to use a locally installed Chromium binary. Generated sites, screenshots, and traces are ignored by Git; CI retains failure diagnostics for seven days.
|
|
239
|
+
|
|
240
|
+
### Release Validation
|
|
241
|
+
|
|
242
|
+
Both pull requests and release-tag pushes run the build and test checks. Publishing depends on all checks succeeding and is restricted to pushed `v*` tags; pull requests never publish. The tag must be `v` followed by the exact gem version in `monoholic.gemspec`, including any RubyGems prerelease suffix. Update the version metadata and lockfiles together before tagging.
|
|
243
|
+
|
|
244
|
+
CI builds the gem once and installs it into a temporary gem home. A clean consumer site uses that installed package with the existing lockfile dependencies, without downloading gems or falling back to repository theme files. The checks build root and `/blog` sites and verify layouts, compiled CSS, scripts, favicons, feeds, and URLs. Negative tests reject broken packages and invalid versions.
|
|
245
|
+
|
|
246
|
+
After validation, tag runs upload the gem and its SHA-256 manifest as a seven-day artifact. The publishing job downloads those same bytes, verifies the checksum and package name/version, and pushes the same gem to GitHub Packages and RubyGems—without checking out or rebuilding the source. Rerunning validation replaces the artifact only after checks succeed; if it has expired, rerun validation rather than just the publishing job.
|
|
247
|
+
|
|
248
|
+
Publishing keeps the existing authentication: `GITHUB_TOKEN` with package-write permission for GitHub Packages, and the repository's `RUBYGEMS_API_KEY` secret for RubyGems. Validation has read-only repository permissions; registry credentials are used only by publishing steps.
|
|
249
|
+
|
|
250
|
+
To exercise package checks locally without publishing (publisher verification requires Bash and `sha256sum` from GNU coreutils, matching the Linux CI runner):
|
|
251
|
+
|
|
252
|
+
```sh
|
|
253
|
+
mkdir -p _tests/.release
|
|
254
|
+
bundle exec gem build monoholic.gemspec --output _tests/.release/monoholic.gem
|
|
255
|
+
bundle exec ruby _tests/package_consumer_test.rb _tests/.release/monoholic.gem
|
|
256
|
+
bundle exec ruby _tests/package_consumer_negative_test.rb _tests/.release/monoholic.gem
|
|
257
|
+
(
|
|
258
|
+
cd _tests/.release
|
|
259
|
+
sha256sum monoholic.gem > monoholic.gem.sha256
|
|
260
|
+
)
|
|
261
|
+
bundle exec ruby _tests/package_integrity_test.rb _tests/.release/monoholic.gem _tests/.release/monoholic.gem.sha256
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
`package_integrity_test.rb` exercises the actual publisher verification recipe with valid, tampered, missing, and malformed inputs, plus a mismatched release tag. It never runs registry publishing commands. Release outputs are ignored by Git, and temporary package installations are removed after the checks finish.
|
|
265
|
+
|
|
191
266
|
Bug reports and pull requests are welcome on GitHub at [https://github.com/stiermid/monoholic](https://github.com/stiermid/monoholic). This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](https://www.contributor-covenant.org/) code of conduct.
|
|
192
267
|
|
|
193
268
|
## License
|
data/_includes/menu.html
CHANGED
|
@@ -1,21 +1,25 @@
|
|
|
1
|
-
{%- assign _level = include.level | default: 2 | plus: 0 -%}
|
|
2
|
-
{%- if _level < 2 -%}
|
|
3
|
-
{%- assign _level = 2 -%}
|
|
4
|
-
{%- elsif _level > 6 -%}
|
|
5
|
-
{%- assign _level = 6 -%}
|
|
6
|
-
{%- endif -%}
|
|
7
|
-
{%- assign _next_level = _level | plus: 1 -%}
|
|
8
|
-
{%- if _next_level > 6 -%}
|
|
9
|
-
{%- assign _next_level = 6 -%}
|
|
10
|
-
{%- endif -%}
|
|
11
1
|
{%- for item in include.collection -%}
|
|
2
|
+
{%- comment -%}
|
|
3
|
+
Liquid assigns are shared across recursive includes. Recompute each entry
|
|
4
|
+
from the scoped include parameters before rendering its heading or children.
|
|
5
|
+
{%- endcomment -%}
|
|
6
|
+
{%- assign _level = include.level | default: 2 | plus: 0 -%}
|
|
7
|
+
{%- if _level < 2 -%}
|
|
8
|
+
{%- assign _level = 2 -%}
|
|
9
|
+
{%- elsif _level > 6 -%}
|
|
10
|
+
{%- assign _level = 6 -%}
|
|
11
|
+
{%- endif -%}
|
|
12
12
|
{%- assign _title_stripped = item.title | strip -%}
|
|
13
13
|
{%- assign _has_title = true -%}
|
|
14
|
-
{%- if item.title ==
|
|
14
|
+
{%- if item.title == null or _title_stripped == empty -%}
|
|
15
15
|
{%- assign _has_title = false -%}
|
|
16
16
|
{%- endif -%}
|
|
17
|
+
{%- assign _next_level = _level -%}
|
|
18
|
+
{%- if _has_title and _level < 6 -%}
|
|
19
|
+
{%- assign _next_level = _level | plus: 1 -%}
|
|
20
|
+
{%- endif -%}
|
|
17
21
|
{%- assign _title_slug = item.title | slugify -%}
|
|
18
|
-
{%- if _title_slug == empty or _title_slug ==
|
|
22
|
+
{%- if _title_slug == empty or _title_slug == null -%}
|
|
19
23
|
{%- assign _title_slug = 'section' -%}
|
|
20
24
|
{%- endif -%}
|
|
21
25
|
{%- if include.parent_id -%}
|
|
@@ -38,32 +42,34 @@
|
|
|
38
42
|
| append: forloop.index
|
|
39
43
|
-%}
|
|
40
44
|
{%- endif -%}
|
|
41
|
-
|
|
42
|
-
|
|
45
|
+
<section
|
|
46
|
+
{% if _has_title %}
|
|
47
|
+
aria-labelledby="{{ _heading_id | escape }}"
|
|
48
|
+
{% endif %}
|
|
49
|
+
>
|
|
50
|
+
{%- if _has_title -%}
|
|
43
51
|
{%- if _level == 3 -%}
|
|
44
|
-
<h3 class="section-title" id="{{ _heading_id }}">
|
|
52
|
+
<h3 class="section-title" id="{{ _heading_id | escape }}">
|
|
45
53
|
{{ item.title | escape }}
|
|
46
54
|
</h3>
|
|
47
55
|
{%- elsif _level == 4 -%}
|
|
48
|
-
<h4 class="section-title" id="{{ _heading_id }}">
|
|
56
|
+
<h4 class="section-title" id="{{ _heading_id | escape }}">
|
|
49
57
|
{{ item.title | escape }}
|
|
50
58
|
</h4>
|
|
51
59
|
{%- elsif _level == 5 -%}
|
|
52
|
-
<h5 class="section-title" id="{{ _heading_id }}">
|
|
60
|
+
<h5 class="section-title" id="{{ _heading_id | escape }}">
|
|
53
61
|
{{ item.title | escape }}
|
|
54
62
|
</h5>
|
|
55
63
|
{%- elsif _level >= 6 -%}
|
|
56
|
-
<h6 class="section-title" id="{{ _heading_id }}">
|
|
64
|
+
<h6 class="section-title" id="{{ _heading_id | escape }}">
|
|
57
65
|
{{ item.title | escape }}
|
|
58
66
|
</h6>
|
|
59
67
|
{%- else -%}
|
|
60
|
-
<h2 class="section-title" id="{{ _heading_id }}">
|
|
68
|
+
<h2 class="section-title" id="{{ _heading_id | escape }}">
|
|
61
69
|
{{ item.title | escape }}
|
|
62
70
|
</h2>
|
|
63
71
|
{%- endif -%}
|
|
64
|
-
|
|
65
|
-
<section>
|
|
66
|
-
{%- endif -%}
|
|
72
|
+
{%- endif -%}
|
|
67
73
|
{%- if item.content_file -%}
|
|
68
74
|
{%- assign _menu_page = site.pages
|
|
69
75
|
| where: 'path', item.content_file
|
|
@@ -77,7 +83,8 @@
|
|
|
77
83
|
{%- endif -%}
|
|
78
84
|
{%- if item.post_list -%}{%- include post_list.html -%}{%- endif -%}
|
|
79
85
|
{%- if item.entries -%}
|
|
80
|
-
{%-
|
|
86
|
+
{%-
|
|
87
|
+
include menu.html
|
|
81
88
|
collection=item.entries
|
|
82
89
|
level=_next_level
|
|
83
90
|
parent_id=_heading_id
|
data/_layouts/default.html
CHANGED
|
@@ -16,6 +16,14 @@
|
|
|
16
16
|
{%- include footer.html -%}
|
|
17
17
|
{%- endunless -%}
|
|
18
18
|
|
|
19
|
+
<script
|
|
20
|
+
defer
|
|
21
|
+
src="{{ '/assets/js/content-scroll.js' | relative_url }}"
|
|
22
|
+
data-table-label="{{ site.theme_config.table_scroll_label | default: 'Table' | escape }}"
|
|
23
|
+
data-code-label="{{ site.theme_config.code_scroll_label | default: 'Code block' | escape }}"
|
|
24
|
+
data-scroll-hint="{{ site.theme_config.scroll_hint | default: 'Scroll horizontally to see more.' | escape }}"
|
|
25
|
+
></script>
|
|
26
|
+
|
|
19
27
|
{% if page.custom_js %}
|
|
20
28
|
{% for js_file in page.custom_js %}
|
|
21
29
|
<script
|
data/_layouts/home.html
CHANGED
data/_sass/_base.scss
CHANGED
data/_sass/_content.scss
CHANGED
|
@@ -4,20 +4,22 @@
|
|
|
4
4
|
color: var(--bg-color);
|
|
5
5
|
}
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
7
|
+
.page-content pre {
|
|
8
|
+
max-width: 100%;
|
|
9
|
+
overflow-x: auto;
|
|
10
|
+
// Keep indentation and source lines intact; scroll the block, not the page.
|
|
11
|
+
white-space: pre;
|
|
12
|
+
overflow-wrap: normal;
|
|
13
|
+
}
|
|
13
14
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
}
|
|
15
|
+
div.highlighter-rouge pre.highlight {
|
|
16
|
+
padding: var(--space-md);
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
table {
|
|
20
20
|
width: 100%;
|
|
21
|
+
// Readable wrapping is the fallback when scripts are unavailable.
|
|
22
|
+
table-layout: fixed;
|
|
21
23
|
margin-bottom: var(--space-md);
|
|
22
24
|
|
|
23
25
|
&,
|
|
@@ -29,6 +31,26 @@ table {
|
|
|
29
31
|
}
|
|
30
32
|
}
|
|
31
33
|
|
|
34
|
+
.table-scroll {
|
|
35
|
+
max-width: 100%;
|
|
36
|
+
overflow-x: auto;
|
|
37
|
+
margin-bottom: var(--space-md);
|
|
38
|
+
|
|
39
|
+
table {
|
|
40
|
+
// Keep native table layout and semantics inside the scroll container.
|
|
41
|
+
table-layout: auto;
|
|
42
|
+
overflow-wrap: normal;
|
|
43
|
+
margin-bottom: 0;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
.scroll-hint {
|
|
48
|
+
color: var(--meta-color);
|
|
49
|
+
font-size: var(--font-size-sm);
|
|
50
|
+
margin-top: calc(-1 * var(--space-sm));
|
|
51
|
+
margin-bottom: var(--space-md);
|
|
52
|
+
}
|
|
53
|
+
|
|
32
54
|
blockquote {
|
|
33
55
|
font-style: italic;
|
|
34
56
|
border: thin solid var(--border-color);
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
(() => {
|
|
2
|
+
const settings = document.currentScript?.dataset || {};
|
|
3
|
+
const updates = [];
|
|
4
|
+
let hintIndex = 0;
|
|
5
|
+
|
|
6
|
+
const updateAll = () => updates.forEach((update) => update());
|
|
7
|
+
const observer =
|
|
8
|
+
typeof ResizeObserver === "function" ? new ResizeObserver(updateAll) : null;
|
|
9
|
+
const contentObserver =
|
|
10
|
+
typeof MutationObserver === "function"
|
|
11
|
+
? new MutationObserver(updateAll)
|
|
12
|
+
: null;
|
|
13
|
+
|
|
14
|
+
function enhance(region, content, hintAnchor, label, labelledBy) {
|
|
15
|
+
// Also respect author-provided wrappers and repeated script inclusion.
|
|
16
|
+
if (region.hasAttribute("data-scroll-enhanced")) return;
|
|
17
|
+
region.setAttribute("data-scroll-enhanced", "");
|
|
18
|
+
const originalAttributes = new Set(region.getAttributeNames());
|
|
19
|
+
const hint = document.createElement("p");
|
|
20
|
+
do {
|
|
21
|
+
hint.id = `monoholic-scroll-hint-${++hintIndex}`;
|
|
22
|
+
} while (document.getElementById(hint.id));
|
|
23
|
+
hint.className = "scroll-hint";
|
|
24
|
+
hint.textContent =
|
|
25
|
+
settings.scrollHint || "Scroll horizontally to see more.";
|
|
26
|
+
hint.hidden = true;
|
|
27
|
+
hintAnchor.after(hint);
|
|
28
|
+
|
|
29
|
+
function setAutomaticAttribute(name, value) {
|
|
30
|
+
if (originalAttributes.has(name)) return;
|
|
31
|
+
if (value === null) region.removeAttribute(name);
|
|
32
|
+
else region.setAttribute(name, value);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function update() {
|
|
36
|
+
const overflows = region.scrollWidth > region.clientWidth + 1;
|
|
37
|
+
hint.hidden = !overflows;
|
|
38
|
+
setAutomaticAttribute("tabindex", overflows ? "0" : null);
|
|
39
|
+
setAutomaticAttribute("role", overflows ? "region" : null);
|
|
40
|
+
if (
|
|
41
|
+
!originalAttributes.has("aria-label") &&
|
|
42
|
+
!originalAttributes.has("aria-labelledby")
|
|
43
|
+
) {
|
|
44
|
+
setAutomaticAttribute(
|
|
45
|
+
labelledBy ? "aria-labelledby" : "aria-label",
|
|
46
|
+
overflows ? labelledBy || label : null,
|
|
47
|
+
);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// Preserve descriptions supplied by the author or other scripts.
|
|
51
|
+
const descriptions = new Set(
|
|
52
|
+
(region.getAttribute("aria-describedby") || "")
|
|
53
|
+
.split(/\s+/)
|
|
54
|
+
.filter(Boolean),
|
|
55
|
+
);
|
|
56
|
+
if (overflows) descriptions.add(hint.id);
|
|
57
|
+
else descriptions.delete(hint.id);
|
|
58
|
+
if (descriptions.size) {
|
|
59
|
+
region.setAttribute("aria-describedby", [...descriptions].join(" "));
|
|
60
|
+
} else {
|
|
61
|
+
region.removeAttribute("aria-describedby");
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
updates.push(update);
|
|
66
|
+
update();
|
|
67
|
+
observer?.observe(region);
|
|
68
|
+
if (content !== region) observer?.observe(content);
|
|
69
|
+
contentObserver?.observe(content, {
|
|
70
|
+
childList: true,
|
|
71
|
+
characterData: true,
|
|
72
|
+
subtree: true,
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
document.querySelectorAll(".page-content table").forEach((table) => {
|
|
77
|
+
let wrapper = table.parentElement;
|
|
78
|
+
if (!wrapper.classList.contains("table-scroll")) {
|
|
79
|
+
wrapper = document.createElement("div");
|
|
80
|
+
wrapper.className = "table-scroll";
|
|
81
|
+
table.before(wrapper);
|
|
82
|
+
wrapper.append(table);
|
|
83
|
+
}
|
|
84
|
+
const label =
|
|
85
|
+
table.getAttribute("aria-label") ||
|
|
86
|
+
table.caption?.textContent.trim() ||
|
|
87
|
+
settings.tableLabel ||
|
|
88
|
+
"Table";
|
|
89
|
+
enhance(
|
|
90
|
+
wrapper,
|
|
91
|
+
table,
|
|
92
|
+
wrapper,
|
|
93
|
+
label,
|
|
94
|
+
table.getAttribute("aria-labelledby"),
|
|
95
|
+
);
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
document.querySelectorAll(".page-content pre").forEach((block) => {
|
|
99
|
+
const hintAnchor = block.closest("div.highlighter-rouge") || block;
|
|
100
|
+
enhance(block, block, hintAnchor, settings.codeLabel || "Code block");
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
window.addEventListener("resize", updateAll);
|
|
104
|
+
// A font swap can change overflow without resizing the container itself.
|
|
105
|
+
if (document.fonts) {
|
|
106
|
+
document.fonts.ready.then(updateAll);
|
|
107
|
+
document.fonts.addEventListener("loadingdone", updateAll);
|
|
108
|
+
}
|
|
109
|
+
})();
|
data/robots.txt
ADDED
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: monoholic
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.3.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Agil Mammadov
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-
|
|
11
|
+
date: 2026-10-15 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: jekyll
|
|
@@ -66,6 +66,20 @@ dependencies:
|
|
|
66
66
|
- - "~>"
|
|
67
67
|
- !ruby/object:Gem::Version
|
|
68
68
|
version: '2.8'
|
|
69
|
+
- !ruby/object:Gem::Dependency
|
|
70
|
+
name: jekyll-sitemap
|
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
|
72
|
+
requirements:
|
|
73
|
+
- - "~>"
|
|
74
|
+
- !ruby/object:Gem::Version
|
|
75
|
+
version: '1.4'
|
|
76
|
+
type: :runtime
|
|
77
|
+
prerelease: false
|
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
79
|
+
requirements:
|
|
80
|
+
- - "~>"
|
|
81
|
+
- !ruby/object:Gem::Version
|
|
82
|
+
version: '1.4'
|
|
69
83
|
description:
|
|
70
84
|
email:
|
|
71
85
|
- mammadovagil@proton.me
|
|
@@ -96,6 +110,8 @@ files:
|
|
|
96
110
|
- assets/favicon.ico
|
|
97
111
|
- assets/favicon.svg
|
|
98
112
|
- assets/js/.keep
|
|
113
|
+
- assets/js/content-scroll.js
|
|
114
|
+
- robots.txt
|
|
99
115
|
homepage: https://github.com/stiermid/monoholic
|
|
100
116
|
licenses:
|
|
101
117
|
- GPL-3.0-only
|