Refactored JavaScript into components
@ -42,7 +42,6 @@
|
||||
"rules": {
|
||||
"array-callback-return": 2,
|
||||
"array-bracket-spacing": 2,
|
||||
"arrow-body-style": [2, "always"],
|
||||
"arrow-parens": [2, "as-needed"],
|
||||
"arrow-spacing": 2,
|
||||
"block-scoped-var": 2,
|
||||
|
@ -11,7 +11,7 @@ installed, which is a generic syntax highlighter with support for over
|
||||
[300 languages][], CodeHilite will also highlight the code block. Pygments can
|
||||
be installed with the following command:
|
||||
|
||||
``` bash
|
||||
``` sh
|
||||
pip install pygments
|
||||
```
|
||||
|
||||
@ -158,7 +158,7 @@ over [300 languages][], so the following list of examples is just an excerpt.
|
||||
### Bash
|
||||
|
||||
``` bash
|
||||
#!/bin/sh
|
||||
#!/bin/bash
|
||||
|
||||
for OPT in "$@"
|
||||
do
|
||||
|
3
docs/extensions/metadata.md
Normal file
@ -0,0 +1,3 @@
|
||||
# Metadata
|
||||
|
||||
Foobar
|
@ -1,17 +1,17 @@
|
||||
# Permalinks
|
||||
|
||||
Permalinks are a feature of the [Table of Contents][] extension, which is part
|
||||
of the standard Markdown library. The extension inserts a link at the end of
|
||||
of the standard Markdown library. The extension inserts an anchor at the end of
|
||||
each headline, which makes it possible to directly link to a subpart of the
|
||||
document.
|
||||
|
||||
## Installation
|
||||
|
||||
To enable Permalinks, add the following to your `mkdocs.yml`:
|
||||
To enable permalinks, add the following to your `mkdocs.yml`:
|
||||
|
||||
``` markdown
|
||||
- toc:
|
||||
permalink: true
|
||||
``` yaml
|
||||
markdown_extensions:
|
||||
- toc(permalink=true)
|
||||
```
|
||||
|
||||
This will add a link containing the paragraph symbol "¶" at the end of each
|
||||
@ -20,8 +20,8 @@ Material theme will make appear on hover. In order to change the text of the
|
||||
permalink, a string can be passed, e.g.:
|
||||
|
||||
``` markdown
|
||||
- toc:
|
||||
permalink: "Permalink"
|
||||
markdown_extensions:
|
||||
- toc(permalink=Link)
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
0
docs/extensions/pymdown/markup.md
Normal file
37
docs/extensions/pymdown/overview.md
Normal file
@ -0,0 +1,37 @@
|
||||
# PyMdown Extensions
|
||||
|
||||
[PyMdown Extensions][] is a collection of Markdown extensions that add some
|
||||
great and missing features to the standard Markdown library. For this reason,
|
||||
the **installation of this package is highly recommended** as it's
|
||||
well-integrated with the Material theme.
|
||||
|
||||
## Installation
|
||||
|
||||
The Pymdown Extensions can be installed with the following command:
|
||||
|
||||
``` sh
|
||||
pip install pymdown-extensions
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
### Improvements on existing Markdown
|
||||
|
||||
- BetterEm
|
||||
- SuperFences
|
||||
- MagicLink
|
||||
- SmartSymbols
|
||||
|
||||
### New Syntax for...
|
||||
|
||||
- Caret
|
||||
- Mark
|
||||
- Tilde
|
||||
|
||||
### New features
|
||||
|
||||
- Arithmatex
|
||||
- Inlinehilite
|
||||
- Tasklist
|
||||
|
||||
[PyMdown Extensions]: http://facelessuser.github.io/pymdown-extensions/
|
0
docs/extensions/pymdown/tasklist.md
Normal file
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="352" height="448" viewBox="0 0 352 448"><path d="M203.75 214.75q2 15.75-12.625 25.25t-27.875 1.5q-9.75-4.25-13.375-14.5t-.125-20.5 13-14.5q9-4.5 18.125-3t16 8.875 6.875 16.875zm27.75-5.25q-3.5-26.75-28.25-41T154 165.25q-15.75 7-25.125 22.125t-8.625 32.375q1 22.75 19.375 38.75t41.375 14q22.75-2 38-21t12.5-42zM291.25 74q-5-6.75-14-11.125t-14.5-5.5T245 54.25q-72.75-11.75-141.5.5-10.75 1.75-16.5 3t-13.75 5.5T60.75 74q7.5 7 19 11.375t18.375 5.5T120 93.75Q177 101 232 94q15.75-2 22.375-3t18.125-5.375T291.25 74zm14.25 258.75q-2 6.5-3.875 19.125t-3.5 21-7.125 17.5-14.5 14.125q-21.5 12-47.375 17.875t-50.5 5.5-50.375-4.625q-11.5-2-20.375-4.5T88.75 412 70.5 401.125t-13-15.375q-6.25-24-14.25-73l1.5-4 4.5-2.25q55.75 37 126.625 37t126.875-37q5.25 1.5 6 5.75t-1.25 11.25-2 9.25zM350.75 92.5q-6.5 41.75-27.75 163.75-1.25 7.5-6.75 14t-10.875 10T291.75 288q-63 31.5-152.5 22-62-6.75-98.5-34.75-3.75-3-6.375-6.625t-4.25-8.75-2.25-8.5-1.5-9.875T25 232.75q-2.25-12.5-6.625-37.5t-7-40.375T5.5 118 0 78.5Q.75 72 4.375 66.375T12.25 57t11.25-7.5T35 43.875t12-4.625q31.25-11.5 78.25-16 94.75-9.25 169 12.5Q333 47.25 348 66.25q4 5 4.125 12.75t-1.375 13.5z"/></svg>
|
After Width: | Height: | Size: 1.2 KiB |
@ -1,20 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="352" height="448"
|
||||
viewBox="0 0 352 448">
|
||||
<path d="M203.75 214.75q2 15.75-12.625 25.25t-27.875
|
||||
1.5q-9.75-4.25-13.375-14.5t-0.125-20.5 13-14.5q9-4.5 18.125-3t16 8.875
|
||||
6.875 16.875zM231.5 209.5q-3.5-26.75-28.25-41t-49.25-3.25q-15.75
|
||||
7-25.125 22.125t-8.625 32.375q1 22.75 19.375 38.75t41.375 14q22.75-2
|
||||
38-21t12.5-42zM291.25
|
||||
74q-5-6.75-14-11.125t-14.5-5.5-17.75-3.125q-72.75-11.75-141.5 0.5-10.75
|
||||
1.75-16.5 3t-13.75 5.5-12.5 10.75q7.5 7 19 11.375t18.375 5.5 21.875
|
||||
2.875q57 7.25 112 0.25 15.75-2 22.375-3t18.125-5.375 18.75-11.625zM305.5
|
||||
332.75q-2 6.5-3.875 19.125t-3.5 21-7.125 17.5-14.5 14.125q-21.5
|
||||
12-47.375 17.875t-50.5 5.5-50.375-4.625q-11.5-2-20.375-4.5t-19.125-6.75-18.25-10.875-13-15.375q-6.25-24-14.25-73l1.5-4
|
||||
4.5-2.25q55.75 37 126.625 37t126.875-37q5.25 1.5 6 5.75t-1.25 11.25-2
|
||||
9.25zM350.75 92.5q-6.5 41.75-27.75 163.75-1.25 7.5-6.75 14t-10.875
|
||||
10-13.625 7.75q-63 31.5-152.5
|
||||
22-62-6.75-98.5-34.75-3.75-3-6.375-6.625t-4.25-8.75-2.25-8.5-1.5-9.875-1.375-8.75q-2.25-12.5-6.625-37.5t-7-40.375-5.875-36.875-5.5-39.5q0.75-6.5
|
||||
4.375-12.125t7.875-9.375 11.25-7.5 11.5-5.625 12-4.625q31.25-11.5
|
||||
78.25-16 94.75-9.25 169 12.5 38.75 11.5 53.75 30.5 4 5 4.125
|
||||
12.75t-1.375 13.5z" />
|
||||
</svg>
|
Before Width: | Height: | Size: 1.3 KiB |
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="352" height="448" viewBox="0 0 352 448"><path d="M203.75 214.75q2 15.75-12.625 25.25t-27.875 1.5q-9.75-4.25-13.375-14.5t-.125-20.5 13-14.5q9-4.5 18.125-3t16 8.875 6.875 16.875zm27.75-5.25q-3.5-26.75-28.25-41T154 165.25q-15.75 7-25.125 22.125t-8.625 32.375q1 22.75 19.375 38.75t41.375 14q22.75-2 38-21t12.5-42zM291.25 74q-5-6.75-14-11.125t-14.5-5.5T245 54.25q-72.75-11.75-141.5.5-10.75 1.75-16.5 3t-13.75 5.5T60.75 74q7.5 7 19 11.375t18.375 5.5T120 93.75Q177 101 232 94q15.75-2 22.375-3t18.125-5.375T291.25 74zm14.25 258.75q-2 6.5-3.875 19.125t-3.5 21-7.125 17.5-14.5 14.125q-21.5 12-47.375 17.875t-50.5 5.5-50.375-4.625q-11.5-2-20.375-4.5T88.75 412 70.5 401.125t-13-15.375q-6.25-24-14.25-73l1.5-4 4.5-2.25q55.75 37 126.625 37t126.875-37q5.25 1.5 6 5.75t-1.25 11.25-2 9.25zM350.75 92.5q-6.5 41.75-27.75 163.75-1.25 7.5-6.75 14t-10.875 10T291.75 288q-63 31.5-152.5 22-62-6.75-98.5-34.75-3.75-3-6.375-6.625t-4.25-8.75-2.25-8.5-1.5-9.875T25 232.75q-2.25-12.5-6.625-37.5t-7-40.375T5.5 118 0 78.5Q.75 72 4.375 66.375T12.25 57t11.25-7.5T35 43.875t12-4.625q31.25-11.5 78.25-16 94.75-9.25 169 12.5Q333 47.25 348 66.25q4 5 4.125 12.75t-1.375 13.5z" fill="#fff"/></svg>
|
After Width: | Height: | Size: 1.2 KiB |
@ -1,20 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="352" height="448"
|
||||
viewBox="0 0 352 448">
|
||||
<path d="M203.75 214.75q2 15.75-12.625 25.25t-27.875
|
||||
1.5q-9.75-4.25-13.375-14.5t-0.125-20.5 13-14.5q9-4.5 18.125-3t16 8.875
|
||||
6.875 16.875zM231.5 209.5q-3.5-26.75-28.25-41t-49.25-3.25q-15.75
|
||||
7-25.125 22.125t-8.625 32.375q1 22.75 19.375 38.75t41.375 14q22.75-2
|
||||
38-21t12.5-42zM291.25
|
||||
74q-5-6.75-14-11.125t-14.5-5.5-17.75-3.125q-72.75-11.75-141.5 0.5-10.75
|
||||
1.75-16.5 3t-13.75 5.5-12.5 10.75q7.5 7 19 11.375t18.375 5.5 21.875
|
||||
2.875q57 7.25 112 0.25 15.75-2 22.375-3t18.125-5.375 18.75-11.625zM305.5
|
||||
332.75q-2 6.5-3.875 19.125t-3.5 21-7.125 17.5-14.5 14.125q-21.5
|
||||
12-47.375 17.875t-50.5 5.5-50.375-4.625q-11.5-2-20.375-4.5t-19.125-6.75-18.25-10.875-13-15.375q-6.25-24-14.25-73l1.5-4
|
||||
4.5-2.25q55.75 37 126.625 37t126.875-37q5.25 1.5 6 5.75t-1.25 11.25-2
|
||||
9.25zM350.75 92.5q-6.5 41.75-27.75 163.75-1.25 7.5-6.75 14t-10.875
|
||||
10-13.625 7.75q-63 31.5-152.5
|
||||
22-62-6.75-98.5-34.75-3.75-3-6.375-6.625t-4.25-8.75-2.25-8.5-1.5-9.875-1.375-8.75q-2.25-12.5-6.625-37.5t-7-40.375-5.875-36.875-5.5-39.5q0.75-6.5
|
||||
4.375-12.125t7.875-9.375 11.25-7.5 11.5-5.625 12-4.625q31.25-11.5
|
||||
78.25-16 94.75-9.25 169 12.5 38.75 11.5 53.75 30.5 4 5 4.125
|
||||
12.75t-1.375 13.5z" fill="white" />
|
||||
</svg>
|
Before Width: | Height: | Size: 1.3 KiB |
1
material/assets/images/icons/github-black-da331b3ec4.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="416" height="448" viewBox="0 0 416 448"><path d="M160 304q0 10-3.125 20.5t-10.75 19T128 352t-18.125-8.5-10.75-19T96 304t3.125-20.5 10.75-19T128 256t18.125 8.5 10.75 19T160 304zm160 0q0 10-3.125 20.5t-10.75 19T288 352t-18.125-8.5-10.75-19T256 304t3.125-20.5 10.75-19T288 256t18.125 8.5 10.75 19T320 304zm40 0q0-30-17.25-51T296 232q-10.25 0-48.75 5.25Q229.5 240 208 240t-39.25-2.75Q130.75 232 120 232q-29.5 0-46.75 21T56 304q0 22 8 38.375t20.25 25.75 30.5 15 35 7.375 37.25 1.75h42q20.5 0 37.25-1.75t35-7.375 30.5-15 20.25-25.75T360 304zm56-44q0 51.75-15.25 82.75-9.5 19.25-26.375 33.25t-35.25 21.5-42.5 11.875-42.875 5.5T212 416q-19.5 0-35.5-.75t-36.875-3.125-38.125-7.5-34.25-12.875T37 371.5t-21.5-28.75Q0 312 0 260q0-59.25 34-99-6.75-20.5-6.75-42.5 0-29 12.75-54.5 27 0 47.5 9.875t47.25 30.875Q171.5 96 212 96q37 0 70 8 26.25-20.5 46.75-30.25T376 64q12.75 25.5 12.75 54.5 0 21.75-6.75 42 34 40 34 99.5z"/></svg>
|
After Width: | Height: | Size: 959 B |
@ -1,18 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="416" height="448"
|
||||
viewBox="0 0 416 448">
|
||||
<path d="M160 304q0 10-3.125 20.5t-10.75 19-18.125
|
||||
8.5-18.125-8.5-10.75-19-3.125-20.5 3.125-20.5 10.75-19 18.125-8.5
|
||||
18.125 8.5 10.75 19 3.125 20.5zM320 304q0 10-3.125 20.5t-10.75
|
||||
19-18.125 8.5-18.125-8.5-10.75-19-3.125-20.5 3.125-20.5 10.75-19
|
||||
18.125-8.5 18.125 8.5 10.75 19 3.125 20.5zM360
|
||||
304q0-30-17.25-51t-46.75-21q-10.25 0-48.75 5.25-17.75 2.75-39.25
|
||||
2.75t-39.25-2.75q-38-5.25-48.75-5.25-29.5 0-46.75 21t-17.25 51q0 22 8
|
||||
38.375t20.25 25.75 30.5 15 35 7.375 37.25 1.75h42q20.5 0
|
||||
37.25-1.75t35-7.375 30.5-15 20.25-25.75 8-38.375zM416 260q0 51.75-15.25
|
||||
82.75-9.5 19.25-26.375 33.25t-35.25 21.5-42.5 11.875-42.875 5.5-41.75
|
||||
1.125q-19.5 0-35.5-0.75t-36.875-3.125-38.125-7.5-34.25-12.875-30.25-20.25-21.5-28.75q-15.5-30.75-15.5-82.75
|
||||
0-59.25 34-99-6.75-20.5-6.75-42.5 0-29 12.75-54.5 27 0 47.5 9.875t47.25
|
||||
30.875q36.75-8.75 77.25-8.75 37 0 70 8 26.25-20.5
|
||||
46.75-30.25t47.25-9.75q12.75 25.5 12.75 54.5 0 21.75-6.75 42 34 40 34
|
||||
99.5z" />
|
||||
</svg>
|
Before Width: | Height: | Size: 1.1 KiB |
1
material/assets/images/icons/github-white-1cfc8ff99e.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="416" height="448" viewBox="0 0 416 448"><path d="M160 304q0 10-3.125 20.5t-10.75 19T128 352t-18.125-8.5-10.75-19T96 304t3.125-20.5 10.75-19T128 256t18.125 8.5 10.75 19T160 304zm160 0q0 10-3.125 20.5t-10.75 19T288 352t-18.125-8.5-10.75-19T256 304t3.125-20.5 10.75-19T288 256t18.125 8.5 10.75 19T320 304zm40 0q0-30-17.25-51T296 232q-10.25 0-48.75 5.25Q229.5 240 208 240t-39.25-2.75Q130.75 232 120 232q-29.5 0-46.75 21T56 304q0 22 8 38.375t20.25 25.75 30.5 15 35 7.375 37.25 1.75h42q20.5 0 37.25-1.75t35-7.375 30.5-15 20.25-25.75T360 304zm56-44q0 51.75-15.25 82.75-9.5 19.25-26.375 33.25t-35.25 21.5-42.5 11.875-42.875 5.5T212 416q-19.5 0-35.5-.75t-36.875-3.125-38.125-7.5-34.25-12.875T37 371.5t-21.5-28.75Q0 312 0 260q0-59.25 34-99-6.75-20.5-6.75-42.5 0-29 12.75-54.5 27 0 47.5 9.875t47.25 30.875Q171.5 96 212 96q37 0 70 8 26.25-20.5 46.75-30.25T376 64q12.75 25.5 12.75 54.5 0 21.75-6.75 42 34 40 34 99.5z" fill="#fff"/></svg>
|
After Width: | Height: | Size: 971 B |
@ -1,18 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="416" height="448"
|
||||
viewBox="0 0 416 448">
|
||||
<path d="M160 304q0 10-3.125 20.5t-10.75 19-18.125
|
||||
8.5-18.125-8.5-10.75-19-3.125-20.5 3.125-20.5 10.75-19 18.125-8.5
|
||||
18.125 8.5 10.75 19 3.125 20.5zM320 304q0 10-3.125 20.5t-10.75
|
||||
19-18.125 8.5-18.125-8.5-10.75-19-3.125-20.5 3.125-20.5 10.75-19
|
||||
18.125-8.5 18.125 8.5 10.75 19 3.125 20.5zM360
|
||||
304q0-30-17.25-51t-46.75-21q-10.25 0-48.75 5.25-17.75 2.75-39.25
|
||||
2.75t-39.25-2.75q-38-5.25-48.75-5.25-29.5 0-46.75 21t-17.25 51q0 22 8
|
||||
38.375t20.25 25.75 30.5 15 35 7.375 37.25 1.75h42q20.5 0
|
||||
37.25-1.75t35-7.375 30.5-15 20.25-25.75 8-38.375zM416 260q0 51.75-15.25
|
||||
82.75-9.5 19.25-26.375 33.25t-35.25 21.5-42.5 11.875-42.875 5.5-41.75
|
||||
1.125q-19.5 0-35.5-0.75t-36.875-3.125-38.125-7.5-34.25-12.875-30.25-20.25-21.5-28.75q-15.5-30.75-15.5-82.75
|
||||
0-59.25 34-99-6.75-20.5-6.75-42.5 0-29 12.75-54.5 27 0 47.5 9.875t47.25
|
||||
30.875q36.75-8.75 77.25-8.75 37 0 70 8 26.25-20.5
|
||||
46.75-30.25t47.25-9.75q12.75 25.5 12.75 54.5 0 21.75-6.75 42 34 40 34
|
||||
99.5z" fill="white" />
|
||||
</svg>
|
Before Width: | Height: | Size: 1.1 KiB |
1
material/assets/images/icons/gitlab-black-81ba4a278f.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="500" height="500" viewBox="0 0 500 500"><path d="M249.865 474.507l90.684-279.097H159.18l90.684 279.097z"/><path d="M249.864 474.506L159.18 195.41H32.088l217.776 279.095z" opacity=".7"/><path d="M32.089 195.41l-27.56 84.816a18.773 18.773 0 0 0 6.822 20.99l238.514 173.29L32.089 195.41z" opacity=".5"/><path d="M32.089 195.412H159.18L104.56 27.314c-2.81-8.65-15.046-8.65-17.855 0L32.089 195.412z"/><path d="M249.865 474.506l90.684-279.095H467.64L249.865 474.506z" opacity=".7"/><path d="M467.641 195.41l27.56 84.816a18.772 18.772 0 0 1-6.822 20.99l-238.515 173.29L467.641 195.41z" opacity=".5"/><path d="M467.64 195.412H340.55l54.618-168.098c2.81-8.65 15.047-8.65 17.856 0l54.618 168.098z"/></svg>
|
After Width: | Height: | Size: 742 B |
@ -1,31 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="500" height="500"
|
||||
viewBox="0 0 500 500">
|
||||
<g transform="translate(156.197863, 1.160267)">
|
||||
<path d="M93.667,473.347L93.667,473.347l90.684-279.097H2.983L93.667,
|
||||
473.347L93.667,473.347z" />
|
||||
</g>
|
||||
<g transform="translate(28.531199, 1.160800)" opacity="0.7">
|
||||
<path d="M221.333,473.345L130.649,194.25H3.557L221.333,473.345L221.333,
|
||||
473.345z" />
|
||||
</g>
|
||||
<g transform="translate(0.088533, 0.255867)" opacity="0.5">
|
||||
<path d="M32,195.155L32,195.155L4.441,279.97c-2.513,7.735,0.24,16.21,6.821,
|
||||
20.99l238.514,173.29 L32,195.155L32,195.155z" />
|
||||
</g>
|
||||
<g transform="translate(29.421866, 280.255593)">
|
||||
<path d="M2.667-84.844h127.092L75.14-252.942c-2.811-8.649-15.047-8.649-17.856,
|
||||
0L2.667-84.844 L2.667-84.844z" />
|
||||
</g>
|
||||
<g transform="translate(247.197860, 1.160800)" opacity="0.7">
|
||||
<path d="M2.667,473.345L93.351,194.25h127.092L2.667,473.345L2.667,
|
||||
473.345z" />
|
||||
</g>
|
||||
<g transform="translate(246.307061, 0.255867)" opacity="0.5">
|
||||
<path d="M221.334,195.155L221.334,195.155l27.559,84.815c2.514,7.735-0.24,
|
||||
16.21-6.821,20.99 L3.557,474.25L221.334,195.155L221.334,195.155z" />
|
||||
</g>
|
||||
<g transform="translate(336.973725, 280.255593)">
|
||||
<path d="M130.667-84.844H3.575l54.618-168.098c2.811-8.649,15.047-8.649,
|
||||
17.856,0L130.667-84.844 L130.667-84.844z" />
|
||||
</g>
|
||||
</svg>
|
Before Width: | Height: | Size: 1.4 KiB |
1
material/assets/images/icons/gitlab-white-d65054b8fe.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="500" height="500" viewBox="0 0 500 500"><path d="M249.865 474.507l90.684-279.097H159.18l90.684 279.097z" fill="#fff"/><path d="M249.864 474.506L159.18 195.41H32.088l217.776 279.095z" fill="#fff" opacity=".7"/><path d="M32.089 195.41l-27.56 84.816a18.773 18.773 0 0 0 6.822 20.99l238.514 173.29L32.089 195.41z" fill="#fff" opacity=".5"/><path d="M32.089 195.412H159.18L104.56 27.314c-2.81-8.65-15.046-8.65-17.855 0L32.089 195.412z" fill="#fff"/><path d="M249.865 474.506l90.684-279.095H467.64L249.865 474.506z" fill="#fff" opacity=".7"/><path d="M467.641 195.41l27.56 84.816a18.772 18.772 0 0 1-6.822 20.99l-238.515 173.29L467.641 195.41z" fill="#fff" opacity=".5"/><path d="M467.64 195.412H340.55l54.618-168.098c2.81-8.65 15.047-8.65 17.856 0l54.618 168.098z" fill="#fff"/></svg>
|
After Width: | Height: | Size: 826 B |
@ -1,32 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="500" height="500"
|
||||
viewBox="0 0 500 500">
|
||||
<g transform="translate(156.197863, 1.160267)">
|
||||
<path d="M93.667,473.347L93.667,473.347l90.684-279.097H2.983L93.667,
|
||||
473.347L93.667,473.347z" fill="white" />
|
||||
</g>
|
||||
<g transform="translate(28.531199, 1.160800)" opacity="0.7">
|
||||
<path d="M221.333,473.345L130.649,194.25H3.557L221.333,473.345L221.333,
|
||||
473.345z" fill="white" />
|
||||
</g>
|
||||
<g transform="translate(0.088533, 0.255867)" opacity="0.5">
|
||||
<path d="M32,195.155L32,195.155L4.441,279.97c-2.513,7.735,0.24,16.21,6.821,
|
||||
20.99l238.514,173.29 L32,195.155L32,195.155z" fill="white" />
|
||||
</g>
|
||||
<g transform="translate(29.421866, 280.255593)">
|
||||
<path d="M2.667-84.844h127.092L75.14-252.942c-2.811-8.649-15.047-8.649-17.856,
|
||||
0L2.667-84.844 L2.667-84.844z" fill="white" />
|
||||
</g>
|
||||
<g transform="translate(247.197860, 1.160800)" opacity="0.7">
|
||||
<path d="M2.667,473.345L93.351,194.25h127.092L2.667,473.345L2.667,
|
||||
473.345z" fill="white" />
|
||||
</g>
|
||||
<g transform="translate(246.307061, 0.255867)" opacity="0.5">
|
||||
<path d="M221.334,195.155L221.334,195.155l27.559,84.815c2.514,7.735-0.24,
|
||||
16.21-6.821,20.99 L3.557,474.25L221.334,195.155L221.334,195.155z"
|
||||
fill="white" />
|
||||
</g>
|
||||
<g transform="translate(336.973725, 280.255593)">
|
||||
<path d="M130.667-84.844H3.575l54.618-168.098c2.811-8.649,15.047-8.649,
|
||||
17.856,0L130.667-84.844 L130.667-84.844z" fill="white" />
|
||||
</g>
|
||||
</svg>
|
Before Width: | Height: | Size: 1.5 KiB |
58
material/assets/javascripts/application-d59af56763.js
Normal file
1
material/assets/javascripts/modernizr-dede1352ed.js
Normal file
1
material/assets/stylesheets/application-9cd3c99a66.css
Normal file
@ -20,11 +20,11 @@
|
||||
<meta name="author" content="{{ site_author }}">
|
||||
{% endif %}
|
||||
<meta name="generator" content="mkdocs+mkdocs-material#0.2.1">
|
||||
<script src="{{ base_url }}/assets/javascripts/modernizr.js"></script>
|
||||
<script src="{{ base_url }}/assets/javascripts/modernizr-dede1352ed.js"></script>
|
||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,400,400i,700">
|
||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto+Mono:400">
|
||||
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
|
||||
<link rel="stylesheet" href="{{ base_url }}/assets/stylesheets/application.css">
|
||||
<link rel="stylesheet" href="{{ base_url }}/assets/stylesheets/application-9cd3c99a66.css">
|
||||
{% for path in extra_css %}
|
||||
<link rel="stylesheet" href="{{ path }}">
|
||||
{% endfor %}
|
||||
|
@ -8,7 +8,7 @@
|
||||
<label class="md-nav__link" for="{{ path }}">
|
||||
{{ nav_item.title }}
|
||||
</label>
|
||||
<nav class="md-nav">
|
||||
<nav class="md-nav" data-md-collapse>
|
||||
<label class="md-nav__title" for="{{ path }}">
|
||||
{{ nav_item.title }}
|
||||
</label>
|
||||
|
16
mkdocs.yml
@ -51,9 +51,18 @@ markdown_extensions:
|
||||
- markdown.extensions.codehilite(guess_lang=false)
|
||||
- markdown.extensions.footnotes
|
||||
- markdown.extensions.meta
|
||||
- markdown.extensions.toc:
|
||||
permalink: '¶'
|
||||
- markdown.extensions.toc(permalink=true)
|
||||
- pymdownx.betterem
|
||||
- pymdownx.caret
|
||||
- pymdownx.critic
|
||||
- pymdownx.inlinehilite
|
||||
- pymdownx.magiclink
|
||||
- pymdownx.mark
|
||||
- pymdownx.smartsymbols
|
||||
- pymdownx.superfences
|
||||
- pymdownx.tasklist(custom_checkbox=true)
|
||||
- pymdownx.tilde
|
||||
|
||||
|
||||
# Page tree
|
||||
pages:
|
||||
@ -63,7 +72,10 @@ pages:
|
||||
- Admonition: extensions/admonition.md
|
||||
- Codehilite: extensions/codehilite.md
|
||||
- Footnotes: extensions/footnotes.md
|
||||
- Metadata: extensions/metadata.md
|
||||
- Permalinks: extensions/permalinks.md
|
||||
- PyMdown:
|
||||
- Overview: extensions/pymdown/overview.md
|
||||
- Specimen: specimen.md
|
||||
- Customization: customization.md
|
||||
- License: license.md
|
||||
|
@ -25,7 +25,6 @@
|
||||
* ------------------------------------------------------------------------- */
|
||||
|
||||
import FastClick from "fastclick"
|
||||
import lunr from "lunr"
|
||||
|
||||
// import Expander from "./components/expander"
|
||||
|
||||
@ -48,23 +47,108 @@ class Application {
|
||||
* @return {void}
|
||||
*/
|
||||
constructor(config) {
|
||||
this.config = config
|
||||
this.config_ = config
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {void}
|
||||
* Initialize all components
|
||||
*/
|
||||
initialize() {
|
||||
const material = new Material()
|
||||
material.initialize()
|
||||
|
||||
/* Initialize sticky sidebars */
|
||||
this.initializeSidebar("[data-md-sidebar=primary]", "(min-width: 1200px)")
|
||||
this.initializeSidebar("[data-md-sidebar=secondary]")
|
||||
|
||||
/* Initialize navigation style modifiers */
|
||||
this.initializeNavBlur("[data-md-sidebar=secondary] .md-nav__link")
|
||||
this.initializeNavCollapse("[data-md-collapse]", "(min-width: 1200px)")
|
||||
|
||||
// TODO
|
||||
if (this.hasGithubRepo()) {
|
||||
const githubSource = new GithubSourceFacts(
|
||||
this.config.storage,
|
||||
this.config.repo.url
|
||||
this.config_.storage,
|
||||
this.config_.repo.url
|
||||
)
|
||||
githubSource.initialize()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize sidebar within optional media query range
|
||||
*
|
||||
* @param {(string|HTMLElement)} el - Selector or HTML element
|
||||
* @param {string} [query] - Media query
|
||||
*/
|
||||
initializeSidebar(el, query = null) {
|
||||
const sidebar = new Material.Sidebar(el)
|
||||
const listeners = [
|
||||
new Material.Listener.Viewport.Offset(() => sidebar.update()),
|
||||
new Material.Listener.Viewport.Resize(() => sidebar.update())
|
||||
]
|
||||
|
||||
/* Initialize depending on media query */
|
||||
if (typeof query === "string" && query.length) {
|
||||
new Material.Listener.Viewport.Media(query, media => {
|
||||
if (media.matches) {
|
||||
sidebar.update()
|
||||
for (const listener of listeners)
|
||||
listener.listen()
|
||||
} else {
|
||||
sidebar.reset()
|
||||
for (const listener of listeners)
|
||||
listener.unlisten()
|
||||
}
|
||||
}).listen()
|
||||
|
||||
/* Initialize without media query */
|
||||
} else {
|
||||
sidebar.update()
|
||||
for (const listener of listeners)
|
||||
listener.listen()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize blurring of anchors above page y-offset
|
||||
*
|
||||
* @param {(string|NodeList<HTMLElement>)} els - Selector or HTML elements
|
||||
*/
|
||||
initializeNavBlur(els) {
|
||||
const blur = new Material.Nav.Blur(els)
|
||||
const listeners = [
|
||||
new Material.Listener.Viewport.Offset(() => blur.update())
|
||||
]
|
||||
|
||||
/* Initialize blur and listeners */
|
||||
blur.update()
|
||||
for (const listener of listeners)
|
||||
listener.listen()
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize collapsible nested navigation elements
|
||||
*
|
||||
* @param {(string|NodeList<HTMLElement>)} els - Selector or HTML elements
|
||||
* @param {string} [query] - Media query
|
||||
*/
|
||||
initializeNavCollapse(els, query = null) {
|
||||
const collapsibles = document.querySelectorAll(els)
|
||||
for (const collapsible of collapsibles) {
|
||||
const collapse = new Material.Nav.Collapse(collapsible)
|
||||
const listener = new Material.Listener.Toggle(
|
||||
collapsible.previousElementSibling, () => collapse.update())
|
||||
|
||||
/* Initialize depending on media query */
|
||||
new Material.Listener.Viewport.Media(query, media => {
|
||||
if (media.matches) {
|
||||
listener.listen()
|
||||
} else {
|
||||
collapse.reset()
|
||||
listener.unlisten()
|
||||
}
|
||||
}).listen()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -73,13 +157,40 @@ class Application {
|
||||
* @return {bool} - true if `repo.icon` or `repo.url` contains 'github'
|
||||
*/
|
||||
hasGithubRepo() {
|
||||
return this.config.repo.icon === "github"
|
||||
|| this.config.repo.url.includes("github")
|
||||
return this.config_.repo.icon === "github"
|
||||
|| this.config_.repo.url.includes("github")
|
||||
}
|
||||
}
|
||||
|
||||
export default Application
|
||||
|
||||
// const consume = reader => {
|
||||
// let total = 0, body = ""
|
||||
// return new Promise((resolve, reject) => {
|
||||
// function pump() {
|
||||
// reader.read().then(({ done, value }) => {
|
||||
// if (done) {
|
||||
// console.log(body)
|
||||
// resolve()
|
||||
// return
|
||||
// }
|
||||
// total += value.byteLength
|
||||
// // value +=
|
||||
// body += value
|
||||
// console.log(`received ${value.byteLength}, total: ${total}`)
|
||||
// pump()
|
||||
// })
|
||||
// .catch(reject)
|
||||
// }
|
||||
// pump()
|
||||
// })
|
||||
// }
|
||||
//
|
||||
// fetch("/mkdocs/search_index.json")
|
||||
// .then(res => consume(res.body.getReader()))
|
||||
// .then(() => console.log("consumed entire body"))
|
||||
// .catch(e => console.log(e))
|
||||
|
||||
// TODO: wrap in function call
|
||||
// application module export
|
||||
|
||||
@ -99,61 +210,13 @@ document.addEventListener("DOMContentLoaded", () => {
|
||||
/* Attack FastClick to mitigate 300ms delay on touch devices */
|
||||
FastClick.attach(document.body)
|
||||
|
||||
const query = document.getElementById("query")
|
||||
// query.addEventListener("focus", () => {
|
||||
// document.querySelector(".md-search").dataset.mdLocked = ""
|
||||
// })
|
||||
|
||||
/* Intercept click on search mode toggle */
|
||||
// const offset = 0
|
||||
// const toggle = document.getElementById("search")
|
||||
// toggle.addEventListener("click", () => {
|
||||
// const list = document.body // classList md bla
|
||||
// const lock = !matchMedia("only screen and (min-width: 960px)").matches
|
||||
//
|
||||
// /* Exiting search mode */
|
||||
// if (list.dataset.mdLocked) {
|
||||
// delete list.dataset.mdLocked
|
||||
//
|
||||
// /* Scroll to former position, but wait for 100ms to prevent flashes
|
||||
// on iOS. A short timeout seems to do the trick */
|
||||
// if (lock)
|
||||
// setTimeout(() => {
|
||||
// window.scrollTo(0, offset)
|
||||
// }, 100)
|
||||
//
|
||||
// /* Entering search mode */
|
||||
// } else {
|
||||
// offset = window.scrollY
|
||||
//
|
||||
// /* First timeout: scroll to top after transition, to omit flickering */
|
||||
// if (lock)
|
||||
// setTimeout(() => {
|
||||
// window.scrollTo(0, 0)
|
||||
// }, 400)
|
||||
//
|
||||
// /* Second timeout: Lock body after finishing transition and scrolling
|
||||
// to top and focus input field. Sadly, the focus event is not
|
||||
// dispatched on iOS Safari and there's nothing we can do about it. */
|
||||
// setTimeout(() => {
|
||||
//
|
||||
// /* This additional check is necessary to handle fast subsequent
|
||||
// clicks on the toggle and the timeout to lock the body must be
|
||||
// cancelled */
|
||||
// // if (ev.target.checked) {
|
||||
// if (lock)
|
||||
// list.dataset.mdLocked = ""
|
||||
// setTimeout(() => {
|
||||
// document.getElementById("query").focus()
|
||||
// }, 200)
|
||||
// // }
|
||||
// }, 450)
|
||||
// }
|
||||
// })
|
||||
|
||||
// TODO: only do this on MOBILE and TABLET
|
||||
// const toggleSearchClose = document.querySelector(".md-search__icon")
|
||||
// toggleSearchClose.setAttribute("for", "search") // TODO: override query with search, when on mobile!!!
|
||||
// TODO: this needs to be abstracted...
|
||||
document.getElementById("query").addEventListener("focus", () => {
|
||||
document.getElementById("search").checked = true
|
||||
})
|
||||
@ -176,177 +239,6 @@ document.addEventListener("DOMContentLoaded", () => {
|
||||
// search.checked = false
|
||||
// })
|
||||
|
||||
// var toc = new Sidebar('.md-sidebar--secondary');
|
||||
// toc.listen();
|
||||
|
||||
const toggles =
|
||||
document.querySelectorAll(".md-nav__item--nested > .md-nav__link");
|
||||
[].forEach.call(toggles, togglex => {
|
||||
const nav = togglex.nextElementSibling
|
||||
|
||||
// 1.
|
||||
|
||||
nav.style.maxHeight = `${nav.getBoundingClientRect().height}px`
|
||||
|
||||
togglex.addEventListener("click", () => {
|
||||
const first = nav.getBoundingClientRect().height
|
||||
if (first) {
|
||||
// console.log('closing');
|
||||
nav.style.maxHeight = `${first}px` // reset!
|
||||
requestAnimationFrame(() => {
|
||||
|
||||
nav.classList.add("md-nav--transitioning")
|
||||
nav.style.maxHeight = "0px"
|
||||
})
|
||||
} else {
|
||||
// console.log('opening');
|
||||
|
||||
/* Toggle and read height */
|
||||
nav.style.maxHeight = ""
|
||||
|
||||
nav.classList.add("md-nav--toggled")
|
||||
const last = nav.getBoundingClientRect().height
|
||||
nav.classList.remove("md-nav--toggled")
|
||||
|
||||
// Initial state
|
||||
nav.style.maxHeight = "0px"
|
||||
|
||||
/* Enable animations */
|
||||
requestAnimationFrame(() => {
|
||||
nav.classList.add("md-nav--transitioning")
|
||||
nav.style.maxHeight = `${last}px`
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
// Capture the end with transitionend
|
||||
nav.addEventListener("transitionend", ev => {
|
||||
ev.target.classList.remove("md-nav--transitioning")
|
||||
if (ev.target.getBoundingClientRect().height > 0) {
|
||||
ev.target.style.maxHeight = "100%"
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
// setTimeout(function() {
|
||||
fetch("/mkdocs/search_index.json") // TODO: prepend BASE URL!!!
|
||||
.then(response => {
|
||||
return response.json()
|
||||
})
|
||||
.then(data => {
|
||||
// console.log(data)
|
||||
|
||||
/* Create index */
|
||||
const index = lunr(function() {
|
||||
/* eslint-disable no-invalid-this, lines-around-comment */
|
||||
this.field("title", { boost: 10 })
|
||||
this.field("text")
|
||||
this.ref("location")
|
||||
/* eslint-enable no-invalid-this, lines-around-comment */
|
||||
})
|
||||
|
||||
/* Index articles */
|
||||
const articles = {}
|
||||
data.docs.forEach(article => {
|
||||
|
||||
// TODO: match for two whitespaces, then replace unnecessary whitespace after string
|
||||
article.text = article.text.replace(/\s(\.,\:)\s/gi, (string, g1) => {
|
||||
return `${g1} `
|
||||
})
|
||||
// TODO: window.baseUrl sucks...
|
||||
article.location = window.baseUrl + article.location
|
||||
articles[article.location] = article
|
||||
index.add(article)
|
||||
})
|
||||
|
||||
/* Register keyhandler to execute search on key up */
|
||||
const queryx = document.getElementById("query")
|
||||
queryx.addEventListener("keyup", () => {
|
||||
const container = document.querySelector(".md-search-result__list")
|
||||
while (container.firstChild)
|
||||
container.removeChild(container.firstChild)
|
||||
|
||||
// /* Abort, if the query is empty */
|
||||
// var bar = document.querySelector('.bar.search');
|
||||
// if (!query.value.length) {
|
||||
// while (meta.firstChild)
|
||||
// meta.removeChild(meta.firstChild);
|
||||
//
|
||||
// /* Restore state */
|
||||
// bar.classList.remove('non-empty');
|
||||
// return;
|
||||
// }
|
||||
|
||||
/* Show reset button */
|
||||
// bar.classList.add('non-empty');
|
||||
|
||||
/* Execute search */
|
||||
const results = index.search(query.value)
|
||||
results.forEach(result => {
|
||||
const article = articles[result.ref]
|
||||
|
||||
/* Create a link referring to the article */
|
||||
const link = document.createElement("a")
|
||||
link.classList.add("md-search-result__link")
|
||||
link.href = article.location
|
||||
|
||||
// /* Create article container */
|
||||
const li = document.createElement("li")
|
||||
li.classList.add("md-search-result__item")
|
||||
li.appendChild(link)
|
||||
|
||||
/* Create title element */
|
||||
const title = document.createElement("div")
|
||||
title.classList.add("md-search-result__title")
|
||||
|
||||
// article.title.split(//)
|
||||
|
||||
title.innerHTML = article.title
|
||||
link.appendChild(title)
|
||||
|
||||
/* Truncate a string after the given number of characters */
|
||||
const truncate = function(string, n) {
|
||||
let i = n
|
||||
if (string.length > i) {
|
||||
while (string[i] !== " " && --i > 0);
|
||||
return `${string.substring(0, i)}…`
|
||||
}
|
||||
return string
|
||||
}
|
||||
|
||||
/* Create text element */
|
||||
const text = document.createElement("p")
|
||||
text.classList.add("md-search-result__description")
|
||||
text.innerHTML = truncate(article.text) // .truncate(140);
|
||||
text.innerHTML = truncate(article.text, 140) // .truncate(140);
|
||||
link.appendChild(text)
|
||||
|
||||
container.appendChild(li)
|
||||
})
|
||||
|
||||
/* Show number of search results */
|
||||
// var number = document.createElement('strong');
|
||||
|
||||
const meta = document.querySelector(".md-search-result__meta")
|
||||
meta.innerHTML = `${results.length} search result${
|
||||
results.length !== 1
|
||||
? "s"
|
||||
: ""}`
|
||||
|
||||
/* Update number */
|
||||
// while (meta.firstChild)
|
||||
// meta.removeChild(meta.firstChild);
|
||||
// meta.appendChild(number);
|
||||
})
|
||||
|
||||
// setTimeout(function() {
|
||||
// li.classList.remove('md-source__fact--hidden');
|
||||
// }, 100);
|
||||
|
||||
})
|
||||
.catch(() => {
|
||||
// console.log("parsing failed", ex)
|
||||
})
|
||||
// }, 1000);
|
||||
|
||||
fetch(
|
||||
|
@ -84,25 +84,27 @@ class GithubSourceFacts {
|
||||
static paint({ stars, forks }) {
|
||||
const lists = document.querySelectorAll(".md-source__facts"); // TODO 2x list in drawer and header
|
||||
|
||||
// TODO: use ... of ...
|
||||
[].forEach.call(lists, list => {
|
||||
|
||||
let li = document.createElement("li")
|
||||
li.className = "md-source__fact md-source__fact--hidden"
|
||||
li.innerText = `${stars} Stars`
|
||||
list.appendChild(li)
|
||||
|
||||
setTimeout(lix => {
|
||||
lix.classList.remove("md-source__fact--hidden")
|
||||
let li = (
|
||||
<li class="md-source__fact md-source__fact--hidden">
|
||||
{stars} Stars
|
||||
</li>
|
||||
)
|
||||
setTimeout(fact => {
|
||||
fact.classList.remove("md-source__fact--hidden")
|
||||
}, 100, li)
|
||||
|
||||
li = document.createElement("li")
|
||||
li.className = "md-source__fact md-source__fact--hidden"
|
||||
li.innerText = `${forks} Forks`
|
||||
list.appendChild(li)
|
||||
|
||||
setTimeout(lix => {
|
||||
lix.classList.remove("md-source__fact--hidden")
|
||||
li = (
|
||||
<li class="md-source__fact md-source__fact--hidden">
|
||||
{forks} Forks
|
||||
</li>
|
||||
)
|
||||
setTimeout(fact => {
|
||||
fact.classList.remove("md-source__fact--hidden")
|
||||
}, 500, li)
|
||||
list.appendChild(li)
|
||||
})
|
||||
}
|
||||
}
|
@ -20,54 +20,56 @@
|
||||
* IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
import Nav from "./Material/Nav"
|
||||
import Search from "./Material/Search"
|
||||
import Listener from "./Material/Listener"
|
||||
import Sidebar from "./Material/Sidebar"
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
* Material application
|
||||
* Module
|
||||
* ------------------------------------------------------------------------- */
|
||||
|
||||
export default
|
||||
class Material {
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @constructor
|
||||
*/
|
||||
// constructor() {
|
||||
//
|
||||
// }
|
||||
|
||||
/**
|
||||
* @return {void}
|
||||
*/
|
||||
initialize() {
|
||||
|
||||
// class AnchorMarker extends PageYOffsetListener
|
||||
// class SidebarConstrainer extends PageYOffsetListener
|
||||
|
||||
// MatchMedia!?
|
||||
|
||||
const width = window.matchMedia("(min-width: 1200px)")
|
||||
|
||||
// separate function in application.js --> initSidebar()
|
||||
const sidebar = new Sidebar.Position("[data-md-sidebar=primary]")
|
||||
const handler = function() {
|
||||
if (width.matches) {
|
||||
sidebar.listen()
|
||||
} else {
|
||||
sidebar.unlisten()
|
||||
}
|
||||
}
|
||||
handler() // check listen!
|
||||
|
||||
const toc = new Sidebar.Position("[data-md-sidebar=secondary]")
|
||||
toc.listen()
|
||||
|
||||
window.addEventListener("resize", handler) // TODO: orientation change etc...
|
||||
|
||||
const marker =
|
||||
new Sidebar.Marker("[data-md-sidebar=secondary] .md-nav__link")
|
||||
marker.listen()
|
||||
}
|
||||
export default {
|
||||
Nav,
|
||||
Search,
|
||||
Listener,
|
||||
Sidebar
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
* Definition
|
||||
* ------------------------------------------------------------------------- */
|
||||
|
||||
// export default class Material {
|
||||
//
|
||||
|
||||
//
|
||||
|
||||
//
|
||||
// static initializeSearch() {
|
||||
//
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Initialize all components
|
||||
// */
|
||||
// static initialize() {
|
||||
//
|
||||
// const search = new Search.Lock("#search", () => {
|
||||
// document.getElementById("query").focus()
|
||||
// })
|
||||
// search.listen() // TODO when this is commented out, focusing the search somehow breaks things...
|
||||
//
|
||||
// const searchx = document.getElementById("search")
|
||||
// const initialize = () => {
|
||||
// const foo = new Search.Index()
|
||||
// console.log(foo)
|
||||
//
|
||||
// searchx.removeEventListener("change", initialize)
|
||||
// }
|
||||
// searchx.addEventListener("change", initialize)
|
||||
// console.log(searchx)
|
||||
//
|
||||
// // TODO nav bar is blurry until 959px, when expanded...
|
||||
// }
|
||||
// }
|
||||
|
33
src/assets/javascripts/components/Material/Listener.js
Normal file
@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Martin Donath <martin.donath@squidfunk.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to
|
||||
* deal in the Software without restriction, including without limitation the
|
||||
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
* sell copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
import Toggle from "./Listener/Toggle"
|
||||
import Viewport from "./Listener/Viewport"
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
* Module
|
||||
* ------------------------------------------------------------------------- */
|
||||
|
||||
export default {
|
||||
Toggle,
|
||||
Viewport
|
||||
}
|
@ -27,61 +27,42 @@
|
||||
export default class Abstract {
|
||||
|
||||
/**
|
||||
* Dispatch update on next repaint
|
||||
* Abstract listener
|
||||
*
|
||||
* @constructor
|
||||
* @param {(string|HTMLElement)} el - Selector or HTML element
|
||||
* @param {Array.<string>} events - Event names to listen on
|
||||
* @param {Function} handler - Event handler to execute
|
||||
*/
|
||||
constructor() {
|
||||
constructor(el, events, handler) {
|
||||
if (this === Abstract)
|
||||
throw new TypeError("Cannot construct abstract instance")
|
||||
throw new Error("Cannot construct abstract instance")
|
||||
|
||||
/* Dispatch update on next repaint */
|
||||
this.handler_ = ev => {
|
||||
window.requestAnimationFrame(() => {
|
||||
this.update(ev)
|
||||
})
|
||||
}
|
||||
}
|
||||
/* Resolve element */
|
||||
this.el_ = (typeof el === "string")
|
||||
? document.querySelector(el)
|
||||
: el
|
||||
|
||||
/**
|
||||
* Update state
|
||||
*
|
||||
* @abstract
|
||||
*/
|
||||
update() {
|
||||
throw new Error("update(): not implemented")
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset state
|
||||
*
|
||||
* @abstract
|
||||
*/
|
||||
reset() {
|
||||
throw new Error("reset(): not implemented")
|
||||
/* Set event names and handler */
|
||||
this.events_ = events
|
||||
this.handler_ = handler
|
||||
}
|
||||
|
||||
/**
|
||||
* Register listener for all relevant events
|
||||
*/
|
||||
listen() {
|
||||
["scroll", "resize", "orientationchange"].forEach(name => {
|
||||
window.addEventListener(name, this.handler_, false)
|
||||
this.events_.forEach(name => {
|
||||
this.el_.addEventListener(name, this.handler_, false)
|
||||
})
|
||||
|
||||
/* Initial update */
|
||||
this.update()
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregister listener for all relevant events
|
||||
*/
|
||||
unlisten() {
|
||||
["scroll", "resize", "orientationchange"].forEach(name => {
|
||||
window.removeEventListener(name, this.handler_, false)
|
||||
this.events_.forEach(name => {
|
||||
this.el_.removeEventListener(name, this.handler_, false)
|
||||
})
|
||||
|
||||
/* Final reset */
|
||||
this.reset()
|
||||
}
|
||||
}
|
@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Martin Donath <martin.donath@squidfunk.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to
|
||||
* deal in the Software without restriction, including without limitation the
|
||||
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
* sell copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
import Abstract from "./Abstract"
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
* Definition
|
||||
* ------------------------------------------------------------------------- */
|
||||
|
||||
export default class Toggle extends Abstract {
|
||||
|
||||
/**
|
||||
* Listener which monitors state changes of a toggle
|
||||
*
|
||||
* @constructor
|
||||
* @param {(string|HTMLElement)} el - Selector or HTML element
|
||||
* @param {Function} handler - Event handler to execute
|
||||
*/
|
||||
constructor(el, handler) {
|
||||
super(el, ["click"], handler)
|
||||
}
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Martin Donath <martin.donath@squidfunk.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to
|
||||
* deal in the Software without restriction, including without limitation the
|
||||
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
* sell copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
import Media from "./Viewport/Media"
|
||||
import Offset from "./Viewport/Offset"
|
||||
import Resize from "./Viewport/Resize"
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
* Module
|
||||
* ------------------------------------------------------------------------- */
|
||||
|
||||
export default {
|
||||
Media,
|
||||
Offset,
|
||||
Resize
|
||||
}
|
@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Martin Donath <martin.donath@squidfunk.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to
|
||||
* deal in the Software without restriction, including without limitation the
|
||||
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
* sell copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
* Definition
|
||||
* ------------------------------------------------------------------------- */
|
||||
|
||||
export default class Media {
|
||||
|
||||
/**
|
||||
* Listener which checks for media queries on dimension changes
|
||||
*
|
||||
* @constructor
|
||||
* @param {string} query - Media query
|
||||
* @param {Function} handler - Event handler to execute
|
||||
*/
|
||||
constructor(query, handler) {
|
||||
this.media_ = window.matchMedia(query)
|
||||
this.handler_ = media => {
|
||||
handler(media)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Register listener for media query check
|
||||
*/
|
||||
listen() {
|
||||
this.media_.addListener(this.handler_)
|
||||
this.handler_(this.media_)
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregister listener for media query check
|
||||
*/
|
||||
unlisten() {
|
||||
this.media_.removeListener(this.handler_)
|
||||
}
|
||||
}
|
@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Martin Donath <martin.donath@squidfunk.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to
|
||||
* deal in the Software without restriction, including without limitation the
|
||||
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
* sell copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
import Abstract from "../Abstract"
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
* Definition
|
||||
* ------------------------------------------------------------------------- */
|
||||
|
||||
export default class Offset extends Abstract {
|
||||
|
||||
/**
|
||||
* Listener which monitors changes to the offset of the viewport
|
||||
*
|
||||
* @constructor
|
||||
* @param {Function} handler - Event handler to execute
|
||||
*/
|
||||
constructor(handler) {
|
||||
super(window, ["scroll"], handler)
|
||||
}
|
||||
}
|
@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Martin Donath <martin.donath@squidfunk.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to
|
||||
* deal in the Software without restriction, including without limitation the
|
||||
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
* sell copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
import Abstract from "../Abstract"
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
* Definition
|
||||
* ------------------------------------------------------------------------- */
|
||||
|
||||
export default class Resize extends Abstract {
|
||||
|
||||
/**
|
||||
* Listener which monitors changes to the dimensions of the viewport
|
||||
*
|
||||
* @constructor
|
||||
* @param {Function} handler - Event handler to execute
|
||||
*/
|
||||
constructor(handler) {
|
||||
super(window, ["resize", "orientationchange"], handler)
|
||||
}
|
||||
}
|
33
src/assets/javascripts/components/Material/Nav.js
Normal file
@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Martin Donath <martin.donath@squidfunk.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to
|
||||
* deal in the Software without restriction, including without limitation the
|
||||
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
* sell copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
import Blur from "./Nav/Blur"
|
||||
import Collapse from "./Nav/Collapse"
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
* Module
|
||||
* ------------------------------------------------------------------------- */
|
||||
|
||||
export default {
|
||||
Blur,
|
||||
Collapse
|
||||
}
|
@ -20,24 +20,19 @@
|
||||
* IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
import Abstract from "./Abstract"
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
* Definition
|
||||
* ------------------------------------------------------------------------- */
|
||||
|
||||
export default class Marker extends Abstract {
|
||||
export default class Blur {
|
||||
|
||||
/**
|
||||
* Mark anchors within the table of contents above current page y-offset
|
||||
* Blur anchors within the navigation above current page y-offset
|
||||
*
|
||||
* @constructor
|
||||
* @param {(string|NodeList<HTMLElement>)} els - Selector or HTML elements
|
||||
*/
|
||||
constructor(els) {
|
||||
super()
|
||||
|
||||
/* Resolve elements */
|
||||
this.els_ = (typeof els === "string")
|
||||
? document.querySelectorAll(els)
|
||||
: els
|
||||
@ -54,8 +49,6 @@ export default class Marker extends Abstract {
|
||||
|
||||
/**
|
||||
* Update anchor states
|
||||
*
|
||||
* @param {Event} ev - Event (omitted)
|
||||
*/
|
||||
update() {
|
||||
const offset = window.pageYOffset
|
||||
@ -65,7 +58,7 @@ export default class Marker extends Abstract {
|
||||
for (let i = this.index_ + 1; i < this.els_.length; i++) {
|
||||
if (this.anchors_[i].offsetTop <= offset) {
|
||||
if (i > 0)
|
||||
this.els_[i - 1].dataset.mdMarked = ""
|
||||
this.els_[i - 1].dataset.mdBlurred = ""
|
||||
this.index_ = i
|
||||
} else {
|
||||
break
|
||||
@ -77,7 +70,7 @@ export default class Marker extends Abstract {
|
||||
for (let i = this.index_; i >= 0; i--) {
|
||||
if (this.anchors_[i].offsetTop > offset) {
|
||||
if (i > 0)
|
||||
delete this.els_[i - 1].dataset.mdMarked
|
||||
delete this.els_[i - 1].dataset.mdBlurred
|
||||
} else {
|
||||
this.index_ = i
|
||||
break
|
||||
@ -94,7 +87,7 @@ export default class Marker extends Abstract {
|
||||
*/
|
||||
reset() {
|
||||
[].forEach.call(this.els_, el => {
|
||||
delete el.dataset.mdMarked
|
||||
delete el.dataset.mdBlurred
|
||||
})
|
||||
}
|
||||
}
|
@ -20,79 +20,71 @@
|
||||
* IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
import Abstract from "./Abstract"
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
* Definition
|
||||
* ------------------------------------------------------------------------- */
|
||||
|
||||
export default class Position extends Abstract {
|
||||
export default class Collapse {
|
||||
|
||||
/**
|
||||
* Set sidebars to locked state and limit height to parent node
|
||||
* Expand or collapse navigation on toggle
|
||||
*
|
||||
* @constructor
|
||||
* @param {(string|HTMLElement)} el - Selector or HTML element
|
||||
*/
|
||||
constructor(el) {
|
||||
super()
|
||||
|
||||
/* Resolve elements */
|
||||
this.el_ = (typeof el === "string")
|
||||
? document.querySelector(el)
|
||||
: el
|
||||
|
||||
/* Index inner and outer container */
|
||||
const inner = this.el_.parentNode
|
||||
const outer = this.el_.parentNode.parentNode
|
||||
|
||||
/* Get top and bottom bounds */
|
||||
this.offset_ = outer.offsetTop
|
||||
this.bounds_ = {
|
||||
top: inner.offsetTop,
|
||||
bottom: inner.offsetTop + inner.offsetHeight
|
||||
}
|
||||
|
||||
/* Initialize current height */
|
||||
this.height_ = 0
|
||||
}
|
||||
|
||||
/**
|
||||
* Update locked state and height
|
||||
*
|
||||
* @param {Event} ev - Event (omitted)
|
||||
* Make expand and collapse transition smoothly
|
||||
*/
|
||||
update() {
|
||||
const scroll = window.pageYOffset
|
||||
const expand = window.innerHeight
|
||||
const current = this.el_.getBoundingClientRect().height
|
||||
|
||||
/* Calculate new bounds */
|
||||
const offset = this.bounds_.top - scroll
|
||||
const height = expand
|
||||
- Math.max(0, scroll + expand - this.bounds_.bottom)
|
||||
- Math.max(offset, this.offset_)
|
||||
/* Expanded, so collapse */
|
||||
if (current) {
|
||||
this.el_.style.maxHeight = `${current}px`
|
||||
requestAnimationFrame(() => {
|
||||
this.el_.dataset.mdAnimated = ""
|
||||
this.el_.style.maxHeight = "0px"
|
||||
})
|
||||
|
||||
/* If height changed, update element */
|
||||
if (height !== this.height_)
|
||||
this.el_.style.height = `${this.height_ = height}px`
|
||||
/* Collapsed, so expand */
|
||||
} else {
|
||||
this.el_.style.maxHeight = ""
|
||||
this.el_.dataset.mdExpanded = ""
|
||||
|
||||
/* Sidebar should be locked, as we're below parent offset */
|
||||
if (offset < this.offset_) {
|
||||
if (!this.el_.dataset.mdLocked)
|
||||
this.el_.dataset.mdLocked = ""
|
||||
/* Read height and unset pseudo-toggled state */
|
||||
const height = this.el_.getBoundingClientRect().height
|
||||
delete this.el_.dataset.mdExpanded
|
||||
|
||||
/* Sidebar should be unlocked, if locked */
|
||||
} else if (typeof this.el_.dataset.mdLocked === "string") {
|
||||
delete this.el_.dataset.mdLocked
|
||||
/* Set initial state and animate */
|
||||
this.el_.style.maxHeight = "0px"
|
||||
requestAnimationFrame(() => {
|
||||
this.el_.dataset.mdAnimated = ""
|
||||
this.el_.style.maxHeight = `${height}px`
|
||||
})
|
||||
}
|
||||
|
||||
/* Remove state on end of transition */
|
||||
const end = function(ev) {
|
||||
delete ev.target.dataset.mdAnimated
|
||||
ev.target.style.maxHeight = ""
|
||||
|
||||
/* Only fire once, so remove event listener again */
|
||||
ev.target.removeEventListener("transitionend", end, false)
|
||||
}
|
||||
this.el_.addEventListener("transitionend", end, false)
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset locked state and height
|
||||
* Nothing to reset
|
||||
*/
|
||||
reset() {
|
||||
delete this.el_.dataset.mdLocked
|
||||
this.el_.style.height = ""
|
||||
this.height_ = 0
|
||||
this.el_.style.maxHeight = ""
|
||||
delete this.el_.dataset.mdToggled
|
||||
}
|
||||
}
|
33
src/assets/javascripts/components/Material/Search.js
Normal file
@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Martin Donath <martin.donath@squidfunk.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to
|
||||
* deal in the Software without restriction, including without limitation the
|
||||
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
* sell copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
import Index from "./Search/Index"
|
||||
import Lock from "./Search/Lock"
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
* Module
|
||||
* ------------------------------------------------------------------------- */
|
||||
|
||||
export default {
|
||||
Index,
|
||||
Lock
|
||||
}
|
152
src/assets/javascripts/components/Material/Search/Index.jsx
Normal file
@ -0,0 +1,152 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Martin Donath <martin.donath@squidfunk.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to
|
||||
* deal in the Software without restriction, including without limitation the
|
||||
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
* sell copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
import lunr from "lunr"
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
* Definition
|
||||
* ------------------------------------------------------------------------- */
|
||||
|
||||
export default class Index {
|
||||
|
||||
/**
|
||||
* // TODO: just copy+pasted
|
||||
*
|
||||
* @constructor
|
||||
*/
|
||||
constructor() {
|
||||
const query = document.getElementById("query")
|
||||
// TODO: put this in search index class...
|
||||
// setTimeout(function() {
|
||||
|
||||
// indexed percentage!
|
||||
|
||||
fetch("/mkdocs/search_index.json") // TODO: prepend BASE URL!!!
|
||||
.then(response => {
|
||||
return response.json()
|
||||
})
|
||||
.then(data => {
|
||||
|
||||
/* Create index */
|
||||
const index = lunr(function() {
|
||||
/* eslint-disable no-invalid-this, lines-around-comment */
|
||||
this.field("title", { boost: 10 })
|
||||
this.field("text")
|
||||
this.ref("location")
|
||||
/* eslint-enable no-invalid-this, lines-around-comment */
|
||||
})
|
||||
|
||||
/* Index articles */
|
||||
const articles = {}
|
||||
data.docs.forEach((article, i) => {
|
||||
// console.log(`indexing...${i}`)
|
||||
const meta = document.querySelector(".md-search-result__meta")
|
||||
meta.innerHTML = `Indexing: ${(i + 1) / data.docs.length}%`
|
||||
|
||||
// TODO: match for two whitespaces, then replace unnecessary whitespace after string
|
||||
article.text = article.text.replace(/\s(\.,\:)\s/gi, (string, g1) => {
|
||||
return `${g1} `
|
||||
})
|
||||
// TODO: window.baseUrl sucks...
|
||||
article.location = window.baseUrl + article.location
|
||||
articles[article.location] = article
|
||||
index.add(article)
|
||||
})
|
||||
|
||||
/* Truncate a string after the given number of characters */
|
||||
const truncate = function(string, n) {
|
||||
let i = n
|
||||
if (string.length > i) {
|
||||
while (string[i] !== " " && --i > 0);
|
||||
return `${string.substring(0, i)}…`
|
||||
}
|
||||
return string
|
||||
}
|
||||
|
||||
/* Register keyhandler to execute search on key up */
|
||||
const queryx = document.getElementById("query")
|
||||
queryx.addEventListener("keyup", () => {
|
||||
const container = document.querySelector(".md-search-result__list")
|
||||
while (container.firstChild)
|
||||
container.removeChild(container.firstChild)
|
||||
|
||||
// /* Abort, if the query is empty */
|
||||
// var bar = document.querySelector('.bar.search');
|
||||
// if (!query.value.length) {
|
||||
// while (meta.firstChild)
|
||||
// meta.removeChild(meta.firstChild);
|
||||
//
|
||||
// /* Restore state */
|
||||
// bar.classList.remove('non-empty');
|
||||
// return;
|
||||
// }
|
||||
|
||||
/* Show reset button */
|
||||
// bar.classList.add('non-empty');
|
||||
|
||||
/* Execute search */
|
||||
const results = index.search(query.value)
|
||||
results.forEach(result => {
|
||||
const article = articles[result.ref]
|
||||
|
||||
container.appendChild(
|
||||
<li class="md-search-result__item">
|
||||
<a href={article.location} title={article.title}
|
||||
class="md-search-result__link">
|
||||
<article class="md-search-result__article">
|
||||
<h1 class="md-search-result__title">
|
||||
{article.title}
|
||||
</h1>
|
||||
<p class="md-search-result__teaser">
|
||||
{truncate(article.text, 140)}
|
||||
</p>
|
||||
</article>
|
||||
</a>
|
||||
</li>
|
||||
)
|
||||
})
|
||||
|
||||
/* Show number of search results */
|
||||
// var number = document.createElement('strong');
|
||||
|
||||
const meta = document.querySelector(".md-search-result__meta")
|
||||
meta.innerHTML = `${results.length} search result${
|
||||
results.length !== 1
|
||||
? "s"
|
||||
: ""}`
|
||||
|
||||
/* Update number */
|
||||
// while (meta.firstChild)
|
||||
// meta.removeChild(meta.firstChild);
|
||||
// meta.appendChild(number);
|
||||
})
|
||||
|
||||
// setTimeout(function() {
|
||||
// li.classList.remove('md-source__fact--hidden');
|
||||
// }, 100);
|
||||
|
||||
})
|
||||
.catch(() => {
|
||||
// console.log("parsing failed", ex)
|
||||
})
|
||||
}
|
||||
}
|
122
src/assets/javascripts/components/Material/Search/Lock.js
Normal file
@ -0,0 +1,122 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Martin Donath <martin.donath@squidfunk.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to
|
||||
* deal in the Software without restriction, including without limitation the
|
||||
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
* sell copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
* Definition
|
||||
* ------------------------------------------------------------------------- */
|
||||
|
||||
export default class Lock {
|
||||
|
||||
/**
|
||||
* Lock body for full-screen search bar
|
||||
*
|
||||
* @constructor
|
||||
* @param {(string|HTMLElement)} el - Selector or HTML element
|
||||
* @param {Function} handler - Callback to execute in active search mode
|
||||
*/
|
||||
constructor(el, handler) {
|
||||
this.el_ = (typeof el === "string")
|
||||
? document.querySelector(el)
|
||||
: el
|
||||
|
||||
/* Initialize page y-offset and callback */
|
||||
this.offset_ = 0
|
||||
this.handler_ = handler
|
||||
|
||||
/* Dispatch update on next repaint */
|
||||
this.handler_ = ev => {
|
||||
this.update(ev)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update state
|
||||
*
|
||||
* @param {Event} ev - Event
|
||||
*/
|
||||
update(ev) {
|
||||
|
||||
/* Entering search mode */
|
||||
if (ev.target.checked) {
|
||||
this.offset_ = window.scrollY
|
||||
|
||||
/* First timeout: scroll to top after transition, to omit flickering */
|
||||
setTimeout(() => {
|
||||
window.scrollTo(0, 0)
|
||||
}, 400)
|
||||
|
||||
/* Second timeout: Lock body after finishing transition and scrolling
|
||||
to top and focus input field. Sadly, the focus event is not dispatched
|
||||
on iOS Safari and there's nothing we can do about it. */
|
||||
setTimeout(() => {
|
||||
|
||||
/* This additional check is necessary to handle fast subsequent clicks
|
||||
on the toggle and the timeout to lock the body must be cancelled */
|
||||
if (ev.target.checked) {
|
||||
document.body.dataset.mdLocked = ""
|
||||
setTimeout(this.handler_, 200)
|
||||
}
|
||||
}, 400)
|
||||
|
||||
/* Exiting search mode */
|
||||
} else {
|
||||
delete document.body.dataset.mdLocked
|
||||
|
||||
/* Scroll to former position, but wait for 100ms to prevent flashes on
|
||||
iOS. A short timeout seems to do the trick */
|
||||
setTimeout(() => {
|
||||
window.scrollTo(0, this.offset_)
|
||||
}, 100)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset state
|
||||
*
|
||||
* @param {Event} ev - Event
|
||||
*/
|
||||
reset() {
|
||||
delete document.body.dataset.mdLocked
|
||||
window.scrollTo(0, this.offset_)
|
||||
}
|
||||
|
||||
/**
|
||||
* Register listener for all relevant events
|
||||
*/
|
||||
listen() {
|
||||
["change"].forEach(name => {
|
||||
this.el_.addEventListener(name, this.handler_, false)
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregister listener for all relevant events
|
||||
*/
|
||||
unlisten() {
|
||||
["change"].forEach(name => {
|
||||
this.el_.removeEventListener(name, this.handler_, false)
|
||||
})
|
||||
|
||||
/* Final reset */
|
||||
this.reset()
|
||||
}
|
||||
}
|
@ -20,14 +20,72 @@
|
||||
* IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
import Marker from "./Sidebar/Marker"
|
||||
import Position from "./Sidebar/Position"
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
* Definition
|
||||
* ------------------------------------------------------------------------- */
|
||||
|
||||
export default {
|
||||
Marker,
|
||||
Position
|
||||
export default class Sidebar {
|
||||
|
||||
/**
|
||||
* Set sidebars to locked state and limit height to parent node
|
||||
*
|
||||
* @constructor
|
||||
* @param {(string|HTMLElement)} el - Selector or HTML element
|
||||
*/
|
||||
constructor(el) {
|
||||
this.el_ = (typeof el === "string")
|
||||
? document.querySelector(el)
|
||||
: el
|
||||
|
||||
/* Index inner and outer container */
|
||||
const inner = this.el_.parentNode
|
||||
const outer = this.el_.parentNode.parentNode
|
||||
|
||||
/* Get top and bottom bounds */
|
||||
this.offset_ = outer.offsetTop
|
||||
this.bounds_ = {
|
||||
top: inner.offsetTop,
|
||||
bottom: inner.offsetTop + inner.offsetHeight
|
||||
}
|
||||
|
||||
/* Initialize current height */
|
||||
this.height_ = 0
|
||||
}
|
||||
|
||||
/**
|
||||
* Update locked state and height
|
||||
*/
|
||||
update() {
|
||||
const scroll = window.pageYOffset
|
||||
const expand = window.innerHeight
|
||||
|
||||
/* Calculate new bounds */
|
||||
const offset = this.bounds_.top - scroll
|
||||
const height = expand
|
||||
- Math.max(0, scroll + expand - this.bounds_.bottom)
|
||||
- Math.max(offset, this.offset_)
|
||||
|
||||
/* If height changed, update element */
|
||||
if (height !== this.height_)
|
||||
this.el_.style.height = `${this.height_ = height}px`
|
||||
|
||||
/* Sidebar should be locked, as we're below parent offset */
|
||||
if (offset < this.offset_) {
|
||||
if (!this.el_.dataset.mdLocked)
|
||||
this.el_.dataset.mdLocked = ""
|
||||
|
||||
/* Sidebar should be unlocked, if locked */
|
||||
} else if (typeof this.el_.dataset.mdLocked === "string") {
|
||||
delete this.el_.dataset.mdLocked
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset locked state and height
|
||||
*/
|
||||
reset() {
|
||||
delete this.el_.dataset.mdLocked
|
||||
this.el_.style.height = ""
|
||||
this.height_ = 0
|
||||
}
|
||||
}
|
||||
|
@ -25,10 +25,10 @@
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// TODO today:
|
||||
// 1. refactor search JavaScript (production-ready, namespacing not important)
|
||||
// x refactor search JavaScript (production-ready, namespacing not important)
|
||||
// x refactor footnotes extension
|
||||
// 2. include table styles
|
||||
// 3. make nav bar production ready (webkit overflow scrolling)
|
||||
// 4. refactor footnotes extension
|
||||
// TODO: Indexing... meta search result, always show!
|
||||
// TODO: offset error in table of contents on specimen on checklists stuff
|
||||
// --> breaks on multiple <a> tags
|
||||
@ -104,106 +104,31 @@
|
||||
// @include z-depth(1);
|
||||
// }
|
||||
|
||||
|
||||
// // add light border for more contrast
|
||||
// .md-typeset pre {
|
||||
// border: 1px solid rgba(0,0,0,0.0125);
|
||||
// }
|
||||
|
||||
|
||||
// .md-search__suggest {
|
||||
// .checklist {
|
||||
//
|
||||
//
|
||||
// background: $md-color-white;
|
||||
// border-radius: 0 0 0.3rem 0.3rem;
|
||||
// color: #000000;
|
||||
// text-align: left;
|
||||
// border-top: 0.1rem solid $md-color-black--lightest;
|
||||
// display: none; // TODO: doesnt work due to display: none;
|
||||
// opacity: 0;
|
||||
//
|
||||
// // overflow: auto;
|
||||
// transition: opacity .3s;
|
||||
// // pointer-events: none;
|
||||
//
|
||||
//
|
||||
// .md-search__input:focus ~ & {
|
||||
// // animation: anima .3s;
|
||||
// display: block;
|
||||
// opacity: 1;
|
||||
// }
|
||||
// }
|
||||
|
||||
// TODO: only on tablet and bind to search active state!
|
||||
// .md-search__input:focus {
|
||||
// border-radius: 0.3rem 0.3rem 0 0;
|
||||
// }
|
||||
|
||||
// @include break-to-device(mobile landscape) {
|
||||
//
|
||||
// .md-search__suggest {
|
||||
// li {
|
||||
// position: relative;
|
||||
// z-index: 2;
|
||||
// list-style-type: none;
|
||||
//
|
||||
// &::before {
|
||||
// @extend %md-icon;
|
||||
//
|
||||
// position: absolute;
|
||||
// appearance: none;
|
||||
// color: blue;
|
||||
//
|
||||
// content: "check_box";
|
||||
// font-size: 2.4rem;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// input[type="checkbox"]:checked {
|
||||
// width: 20px;
|
||||
// // & ~ .checklist li::after {
|
||||
// // color: red;
|
||||
// // }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// .md-search-term {
|
||||
// position: relative;
|
||||
// padding: 0 0.8rem 0 4.8rem;
|
||||
// line-height: 4.0rem; // don't use line height????
|
||||
// font-size: 1.6rem;
|
||||
//
|
||||
// &::before {
|
||||
// @extend %md-icon;
|
||||
//
|
||||
// position: absolute;
|
||||
//
|
||||
// content: "access_time";
|
||||
// font-size: 2.4rem;
|
||||
// line-height: 4.0rem; // this sucks...
|
||||
// left: 1.2rem;
|
||||
// color: $md-color-black--lighter;
|
||||
// }
|
||||
// transition: background .25s;
|
||||
// cursor: pointer;
|
||||
// &:hover {
|
||||
// background: mix($md-color-white, $md-color-primary, 90%);
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
.checklist {
|
||||
|
||||
li {
|
||||
position: relative;
|
||||
list-style-type: none;
|
||||
|
||||
&::before {
|
||||
@extend %md-icon;
|
||||
|
||||
position: absolute;
|
||||
appearance: none;
|
||||
color: blue;
|
||||
|
||||
content: "check_box";
|
||||
font-size: 2.4rem;
|
||||
}
|
||||
}
|
||||
|
||||
input[type="checkbox"]:checked {
|
||||
width: 20px;
|
||||
// & ~ .checklist li::after {
|
||||
// color: red;
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
// Inline code blocks
|
||||
ins.critic, del.critic, mark {
|
||||
@ -286,43 +211,49 @@ mark {
|
||||
}
|
||||
|
||||
.task-list-item {
|
||||
list-style-type: none;
|
||||
}
|
||||
|
||||
.task-list-item input {
|
||||
margin: 0 4px 0.25em -20px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
//
|
||||
//
|
||||
//
|
||||
.task-list-item {
|
||||
position: relative;
|
||||
list-style-type: none !important;
|
||||
}
|
||||
|
||||
.task-list-item input[type="checkbox"] {
|
||||
opacity: 0;
|
||||
margin: 0 4px 0.25em -20px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.task-list-item input[type="checkbox"] + label {
|
||||
display: block;
|
||||
.task-list-control {
|
||||
display: inline; /* Ensure label is inline incase theme sets it to block.*/
|
||||
}
|
||||
|
||||
.task-list-control {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
color: #555;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.task-list-control input[type="checkbox"] {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: -24px;
|
||||
width: 16px;
|
||||
margin-top: -8px;
|
||||
height: 16px;
|
||||
border-radius: 2px;
|
||||
background: #CCC;
|
||||
opacity: 0;
|
||||
z-index: -1; /* Put the input behind the label so it doesn't overlay text */
|
||||
}
|
||||
|
||||
.task-list-item input[type="checkbox"]:checked + label::before {
|
||||
.task-list-indicator {
|
||||
position: absolute;
|
||||
top: -8px;
|
||||
left: -18px;
|
||||
display: block;
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
color: #eee;
|
||||
background-color: #eee;
|
||||
border-radius: .25rem;
|
||||
}
|
||||
|
||||
.task-list-control input[type="checkbox"]:checked + .task-list-indicator::before {
|
||||
display: block;
|
||||
margin-top: -4px;
|
||||
margin-left: 2px;
|
||||
font-size: 1.2em;
|
||||
font-size: 16px;
|
||||
line-height: 1;
|
||||
border-radius: 2px;
|
||||
content: "✔";
|
||||
color: #1EBB52;
|
||||
}
|
||||
|
@ -55,4 +55,7 @@
|
||||
@import "extensions/footnotes";
|
||||
@import "extensions/permalinks";
|
||||
|
||||
@import "extensions/pymdown/critic";
|
||||
@import "extensions/pymdown/tasklist";
|
||||
|
||||
@import "shame";
|
||||
|
@ -210,7 +210,7 @@ $codehilite-whitespace: transparent;
|
||||
// Rules: layout
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// Scoped in typesetted content for greater specificity
|
||||
// Scoped in typesetted content to match specificity of regular content
|
||||
.md-typeset {
|
||||
|
||||
// If code blocks are wrapped with codehilite, the styles must be adjusted
|
||||
|
@ -24,7 +24,7 @@
|
||||
// Rules
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// Scoped in typesetted content for greater specificity
|
||||
// Scoped in typesetted content to match specificity of regular content
|
||||
.md-typeset {
|
||||
|
||||
// Footnotes extension
|
||||
|
@ -24,7 +24,7 @@
|
||||
// Rules
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// Scoped in typesetted content for greater specificity
|
||||
// Scoped in typesetted content to match specificity of regular content
|
||||
.md-typeset {
|
||||
|
||||
// Permalinks extension
|
||||
|
@ -112,8 +112,8 @@
|
||||
}
|
||||
}
|
||||
|
||||
// Marked item
|
||||
&[data-md-marked] {
|
||||
// Blurred item
|
||||
&[data-md-blurred] {
|
||||
color: $md-color-black--light;
|
||||
}
|
||||
|
||||
@ -334,7 +334,7 @@
|
||||
|
||||
// Animation is only possible if JavaScript is available, as the max-height
|
||||
// property must be calculated before transitioning
|
||||
&.md-nav--transitioning {
|
||||
&[data-md-animated] {
|
||||
transition: max-height 0.25s cubic-bezier(0.86, 0.0, 0.07, 1.0);
|
||||
}
|
||||
|
||||
@ -346,7 +346,7 @@
|
||||
|
||||
// Expand nested navigation, if toggle is checked
|
||||
.md-nav__toggle:checked ~ &,
|
||||
&.md-nav--toggled {
|
||||
&[data-md-expanded] {
|
||||
max-height: 100%;
|
||||
}
|
||||
|
||||
|
@ -42,12 +42,6 @@
|
||||
top: 5.6rem;
|
||||
}
|
||||
|
||||
// Omit repaint of whole page by promoting primary sidebar to a separate
|
||||
// layer, but not the secondary sidebar to omit jittering
|
||||
&--primary {
|
||||
backface-visibility: hidden;
|
||||
}
|
||||
|
||||
// [tablet -]: Convert navigation to drawer
|
||||
@include break-to-device(tablet) {
|
||||
|
||||
|
@ -37,7 +37,7 @@
|
||||
<label class="md-nav__link" for="{{ path }}">
|
||||
{{ nav_item.title }}
|
||||
</label>
|
||||
<nav class="md-nav">
|
||||
<nav class="md-nav" data-md-collapse>
|
||||
<label class="md-nav__title" for="{{ path }}">
|
||||
{{ nav_item.title }}
|
||||
</label>
|
||||
|
@ -23,7 +23,7 @@
|
||||
import chai from "chai"
|
||||
|
||||
import Marker from
|
||||
"../../src/assets/javascripts/components/Material/Sidebar/Marker"
|
||||
"../../src/assets/javascripts/components/Material/Nav/Blur"
|
||||
|
||||
describe("Karma test runner", function() {
|
||||
chai.should()
|
||||
@ -54,23 +54,22 @@ describe("Karma test runner", function() {
|
||||
})
|
||||
|
||||
// iframe?
|
||||
function shouldCompileJSXCorrectly(cb) {
|
||||
function shouldCompileJSXCorrectly(done) {
|
||||
const marker = new Marker("a")
|
||||
marker.listen()
|
||||
|
||||
// window.location.hash = "#_5"
|
||||
// window.addEventListener("hashchange", function(e) {
|
||||
// console.log(document.querySelectorAll("[data-md-marked]"))
|
||||
// cb()
|
||||
// console.log(document.querySelectorAll("[data-md-blurred]"))
|
||||
// done()
|
||||
// })
|
||||
window.scrollTo(200, 200)
|
||||
setTimeout(() => {
|
||||
console.log(document.querySelectorAll("[data-md-marked]"))
|
||||
cb()
|
||||
console.log(document.querySelectorAll("[data-md-blurred]"))
|
||||
done()
|
||||
}, 100)
|
||||
|
||||
// console.log(marker)
|
||||
// return true
|
||||
|
||||
}
|
||||
|