Refactored JavaScript architecture
@ -76,7 +76,8 @@
|
|||||||
"var": 2,
|
"var": 2,
|
||||||
"let": 2,
|
"let": 2,
|
||||||
"const": 3
|
"const": 3
|
||||||
}
|
},
|
||||||
|
"SwitchCase": 1
|
||||||
}],
|
}],
|
||||||
"init-declarations": 2,
|
"init-declarations": 2,
|
||||||
"key-spacing": 2,
|
"key-spacing": 2,
|
||||||
@ -115,7 +116,7 @@
|
|||||||
"max": 1
|
"max": 1
|
||||||
}],
|
}],
|
||||||
"no-nested-ternary": 2,
|
"no-nested-ternary": 2,
|
||||||
"no-new": 2,
|
"no-new": 0,
|
||||||
"no-new-object": 2,
|
"no-new-object": 2,
|
||||||
"no-param-reassign": 2,
|
"no-param-reassign": 2,
|
||||||
"no-prototype-builtins": 2,
|
"no-prototype-builtins": 2,
|
||||||
@ -142,7 +143,6 @@
|
|||||||
"no-whitespace-before-property": 2,
|
"no-whitespace-before-property": 2,
|
||||||
"no-with": 2,
|
"no-with": 2,
|
||||||
"object-curly-spacing": [2, "always"],
|
"object-curly-spacing": [2, "always"],
|
||||||
"object-property-newline": 2,
|
|
||||||
"object-shorthand": 2,
|
"object-shorthand": 2,
|
||||||
"one-var-declaration-per-line": 2,
|
"one-var-declaration-per-line": 2,
|
||||||
"operator-assignment": 2,
|
"operator-assignment": 2,
|
||||||
|
@ -21,6 +21,8 @@
|
|||||||
files:
|
files:
|
||||||
ignore:
|
ignore:
|
||||||
- node_modules/**
|
- node_modules/**
|
||||||
|
- src/assets/stylesheets/extensions/pymdown/_arithmatex.scss
|
||||||
|
- src/assets/stylesheets/extensions/pymdown/_inlinehilite.scss
|
||||||
- src/assets/stylesheets/_shame.scss
|
- src/assets/stylesheets/_shame.scss
|
||||||
|
|
||||||
options:
|
options:
|
||||||
|
@ -130,7 +130,7 @@ gulp.task("assets:images:clean",
|
|||||||
load("assets/images/clean"))
|
load("assets/images/clean"))
|
||||||
|
|
||||||
/* ----------------------------------------------------------------------------
|
/* ----------------------------------------------------------------------------
|
||||||
* Javascripts
|
* JavaScript
|
||||||
* ------------------------------------------------------------------------- */
|
* ------------------------------------------------------------------------- */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -161,13 +161,13 @@ gulp.task("assets:javascripts:build", (args.clean ? [
|
|||||||
})
|
})
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Clean javascripts generated by build
|
* Clean JavaScript generated by build
|
||||||
*/
|
*/
|
||||||
gulp.task("assets:javascripts:clean",
|
gulp.task("assets:javascripts:clean",
|
||||||
load("assets/javascripts/clean"))
|
load("assets/javascripts/clean"))
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Lint javascripts
|
* Lint JavaScript
|
||||||
*/
|
*/
|
||||||
gulp.task("assets:javascripts:lint",
|
gulp.task("assets:javascripts:lint",
|
||||||
load("assets/javascripts/lint"))
|
load("assets/javascripts/lint"))
|
||||||
@ -321,7 +321,7 @@ gulp.task("watch", [
|
|||||||
`${config.assets.src}/stylesheets/**/*.scss`
|
`${config.assets.src}/stylesheets/**/*.scss`
|
||||||
], ["assets:stylesheets:build"])
|
], ["assets:stylesheets:build"])
|
||||||
|
|
||||||
/* Rebuild javascripts */
|
/* Rebuild JavaScript */
|
||||||
gulp.watch([
|
gulp.watch([
|
||||||
`${config.assets.src}/javascripts/**/*.{js,jsx}`
|
`${config.assets.src}/javascripts/**/*.{js,jsx}`
|
||||||
], ["assets:javascripts:build:application"])
|
], ["assets:javascripts:build:application"])
|
||||||
|
@ -85,7 +85,8 @@ paragraphs and other blocks – except code blocks, because the parser from the
|
|||||||
standard Markdown library does not account for those.
|
standard Markdown library does not account for those.
|
||||||
|
|
||||||
However, the [PyMdown Extensions][] package adds an extension called
|
However, the [PyMdown Extensions][] package adds an extension called
|
||||||
`superfences`, which makes it possible to nest code blocks within other blocks.
|
[SuperFences][], which makes it possible to nest code blocks within other
|
||||||
|
blocks.
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
@ -310,3 +311,4 @@ Qualifiers:
|
|||||||
|
|
||||||
[Admonition]: https://pythonhosted.org/Markdown/extensions/admonition.html
|
[Admonition]: https://pythonhosted.org/Markdown/extensions/admonition.html
|
||||||
[PyMdown Extensions]: https://facelessuser.github.io/pymdown-extensions
|
[PyMdown Extensions]: https://facelessuser.github.io/pymdown-extensions
|
||||||
|
[SuperFences]: https://facelessuser.github.io/pymdown-extensions/extensions/superfences/
|
||||||
|
@ -6,8 +6,8 @@ executed during compilation of the Markdown file.
|
|||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
CodeHilite parses code blocks and wraps them in `pre` tags. If [Pygments][] is
|
CodeHilite parses code blocks and wraps them in `<pre>` tags. If [Pygments][]
|
||||||
installed, which is a generic syntax highlighter with support for over
|
is installed, which is a generic syntax highlighter with support for over
|
||||||
[300 languages][], CodeHilite will also highlight the code block. Pygments can
|
[300 languages][], CodeHilite will also highlight the code block. Pygments can
|
||||||
be installed with the following command:
|
be installed with the following command:
|
||||||
|
|
||||||
|
@ -1,3 +1 @@
|
|||||||
# Metadata
|
# Metadata
|
||||||
|
|
||||||
Foobar
|
|
||||||
|
@ -14,7 +14,7 @@ markdown_extensions:
|
|||||||
- toc(permalink=true)
|
- toc(permalink=true)
|
||||||
```
|
```
|
||||||
|
|
||||||
This will add a link containing the paragraph symbol "¶" at the end of each
|
This will add a link containing the paragraph symbol `¶` at the end of each
|
||||||
headline (exactly like on the page you're currently viewing), which the
|
headline (exactly like on the page you're currently viewing), which the
|
||||||
Material theme will make appear on hover. In order to change the text of the
|
Material theme will make appear on hover. In order to change the text of the
|
||||||
permalink, a string can be passed, e.g.:
|
permalink, a string can be passed, e.g.:
|
||||||
|
@ -0,0 +1,63 @@
|
|||||||
|
# Arithmatex <small>MathJax</small>
|
||||||
|
|
||||||
|
[Arithmatex][] integrates [MathJax][] with Markdown and is included in the
|
||||||
|
[PyMdown Extensions][] package. It parses block-style and inline equations
|
||||||
|
written in TeX markup and outputs them in mathematical notation.
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
Make sure that the PyMdown Extensions package [is installed][] and add the
|
||||||
|
following lines to your `mkdocs.yml`:
|
||||||
|
|
||||||
|
``` yaml
|
||||||
|
markdown_extensions:
|
||||||
|
- pymdownx.arithmatex
|
||||||
|
```
|
||||||
|
|
||||||
|
The MathJax runtime is automatically included if the extension is enabled, so
|
||||||
|
there is no need for extra JavaScript.
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
MathJax searches for `:::tex $$...$$` (blocks) and `:::tex $...$` (inline)
|
||||||
|
equations, parses their contents and renders them in mathematical notation.
|
||||||
|
See [this thread][] on StackExchange for a short introduction and quick
|
||||||
|
reference on how to write equations in TeX syntax.
|
||||||
|
|
||||||
|
### Blocks
|
||||||
|
|
||||||
|
Blocks are enclosed in `:::tex $$...$$` which are placed on separate lines.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
``` tex
|
||||||
|
$$
|
||||||
|
\frac{n!}{k!(n-k)!} = \binom{n}{k}
|
||||||
|
$$
|
||||||
|
```
|
||||||
|
|
||||||
|
Result:
|
||||||
|
|
||||||
|
$$
|
||||||
|
\frac{n!}{k!(n-k)!} = \binom{n}{k}
|
||||||
|
$$
|
||||||
|
|
||||||
|
### Inline
|
||||||
|
|
||||||
|
Inline equations need to be enclosed in `:::tex $...$`:
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
``` tex
|
||||||
|
Lorem ipsum dolor sit amet: $p(x|y) = \frac{p(y|x)p(x)}{p(y)}$
|
||||||
|
```
|
||||||
|
|
||||||
|
Result:
|
||||||
|
|
||||||
|
Lorem ipsum dolor sit amet: $p(x|y) = \frac{p(y|x)p(x)}{p(y)}$
|
||||||
|
|
||||||
|
[Arithmatex]: https://facelessuser.github.io/pymdown-extensions/extensions/arithmatex/
|
||||||
|
[MathJax]: https://www.mathjax.org/
|
||||||
|
[PyMdown Extensions]: https://facelessuser.github.io/pymdown-extensions
|
||||||
|
[is installed]: /extensions/pymdown/overview/#installation
|
||||||
|
[this thread]: http://meta.math.stackexchange.com/questions/5020/
|
@ -1,37 +1,93 @@
|
|||||||
# PyMdown Extensions
|
# PyMdown Extensions
|
||||||
|
|
||||||
[PyMdown Extensions][] is a collection of Markdown extensions that add some
|
[PyMdown Extensions][] is a collection of Markdown extensions that add some
|
||||||
great and missing features to the standard Markdown library. For this reason,
|
great features to the standard Markdown library. For this reason, the
|
||||||
the **installation of this package is highly recommended** as it's
|
**installation of this package is highly recommended** as it's well-integrated
|
||||||
well-integrated with the Material theme.
|
with the Material theme.
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
The Pymdown Extensions can be installed with the following command:
|
The PyMdown Extensions package can be installed with the following command:
|
||||||
|
|
||||||
``` sh
|
``` sh
|
||||||
pip install pymdown-extensions
|
pip install pymdown-extensions
|
||||||
```
|
```
|
||||||
|
|
||||||
## Usage
|
## Extensions
|
||||||
|
|
||||||
### Improvements on existing Markdown
|
### GitHub Flavored Markdown
|
||||||
|
|
||||||
- BetterEm
|
Most of the extensions included in the PyMdown Extensions package try to bring
|
||||||
- SuperFences
|
the Markdown experience closer to GitHub Flavored Markdown (GFM):
|
||||||
- MagicLink
|
|
||||||
|
- [BetterEm][] improves the handling of emphasis markup (**bold** and *italic*)
|
||||||
|
within Markdown by providing a more sophisticated parser for better detecting
|
||||||
|
start and end tokens. Read the documentation for usage notes.
|
||||||
|
|
||||||
|
- [MagicLink][] detects links in Markdown and auto-generates the necessary
|
||||||
|
markup, so no special syntax is required. It auto-links HTTP(S) and FTP
|
||||||
|
links, as well as references to email addresses.
|
||||||
|
|
||||||
|
- [GitHub Emoji][] adds the ability to insert emojis, which does not only
|
||||||
|
include the :octocat: emojis, but also a :shit:-load of emojis that we use in
|
||||||
|
our daily lives. See the [Emoji Cheat Sheet][] for a list of all available
|
||||||
|
emojis. Happy scrolling :tada:
|
||||||
|
|
||||||
|
- [SuperFences][] provides the ability to nest code blocks under blockquotes,
|
||||||
|
lists and other block elements, which the [Fenced Code Blocks][] extension
|
||||||
|
from the standard Markdown library doesn't parse correctly.
|
||||||
|
|
||||||
|
- [Tasklist][] adds support for styled checkbox lists. This is useful for
|
||||||
|
keeping track of tasks and showing what has been done and has yet to be done.
|
||||||
|
The usage of this extension is documented [here][].
|
||||||
|
|
||||||
|
- [Tilde][] provides an easy way to ~~strike through~~ cross out text.
|
||||||
|
The portion of text that should be erased must be enclosed in two tildes
|
||||||
|
`~~...~~`, and the extension will take care of the rest.
|
||||||
|
|
||||||
|
The PyMdown Extensions package adds a shorthand to enable all of the included
|
||||||
|
extensions that provide the GFM experience. However, usage of the shorthand is
|
||||||
|
discouraged, because some extensions are not supported, as the Material theme
|
||||||
|
uses the counterparts included in the standard Markdown library.
|
||||||
|
|
||||||
|
To enable all extensions add the following lines to your `mkdocs.yml`:
|
||||||
|
|
||||||
|
``` yaml
|
||||||
|
markdown_extensions:
|
||||||
|
- pymdownx.betterem
|
||||||
|
- pymdownx.githubemoji
|
||||||
|
- pymdownx.magiclink
|
||||||
|
- pymdownx.superfences
|
||||||
|
- pymdownx.tasklist(custom_checkbox=true)
|
||||||
|
- pymdownx.tilde
|
||||||
|
```
|
||||||
|
|
||||||
|
### Syntactic Sugar
|
||||||
|
|
||||||
|
There are three other extensions that add further syntactic sugar:
|
||||||
|
|
||||||
|
- [Caret][] is the sister extension of [Tilde][] and makes it possible to
|
||||||
|
highlight ^^inserted text^^. The portion of text that should be marked as
|
||||||
|
added must be enclosed in two carets `^^...^^`, the extension will do the
|
||||||
|
rest.
|
||||||
|
|
||||||
|
- [Mark][] add the ability to ==mark text==.
|
||||||
- SmartSymbols
|
- SmartSymbols
|
||||||
|
|
||||||
### New Syntax for...
|
- Inlinehilite --- own documentation file
|
||||||
|
- Critic --- own documentation file
|
||||||
|
|
||||||
- Caret
|
|
||||||
- Mark
|
|
||||||
- Tilde
|
|
||||||
|
|
||||||
### New features
|
|
||||||
|
|
||||||
- Arithmatex
|
|
||||||
- Inlinehilite
|
|
||||||
- Tasklist
|
|
||||||
|
|
||||||
[PyMdown Extensions]: http://facelessuser.github.io/pymdown-extensions/
|
[PyMdown Extensions]: http://facelessuser.github.io/pymdown-extensions/
|
||||||
|
[usage notes]: https://facelessuser.github.io/pymdown-extensions/usage_notes/
|
||||||
|
[BetterEm]: https://facelessuser.github.io/pymdown-extensions/extensions/betterem/
|
||||||
|
[MagicLink]: https://facelessuser.github.io/pymdown-extensions/extensions/magiclink/
|
||||||
|
[GitHub Emoji]: https://facelessuser.github.io/pymdown-extensions/extensions/githubemoji/
|
||||||
|
[Emoji Cheat Sheet]: http://www.webpagefx.com/tools/emoji-cheat-sheet/
|
||||||
|
[SuperFences]: https://facelessuser.github.io/pymdown-extensions/extensions/superfences/
|
||||||
|
[Fenced Code Blocks]: https://pythonhosted.org/Markdown/extensions/fenced_code_blocks.html
|
||||||
|
[Tasklist]: https://facelessuser.github.io/pymdown-extensions/extensions/tasklist/
|
||||||
|
[here]: /extensions/pymdown/tasklist
|
||||||
|
[Tilde]: https://facelessuser.github.io/pymdown-extensions/extensions/tilde/
|
||||||
|
[Caret]: https://facelessuser.github.io/pymdown-extensions/extensions/caret/
|
||||||
|
[Mark]: https://facelessuser.github.io/pymdown-extensions/extensions/mark/
|
||||||
|
@ -24,7 +24,7 @@ import clean from "del"
|
|||||||
import vinyl from "vinyl-paths"
|
import vinyl from "vinyl-paths"
|
||||||
|
|
||||||
/* ----------------------------------------------------------------------------
|
/* ----------------------------------------------------------------------------
|
||||||
* Task: clean javascripts generated by build
|
* Task: clean JavaScript generated by build
|
||||||
* ------------------------------------------------------------------------- */
|
* ------------------------------------------------------------------------- */
|
||||||
|
|
||||||
export default (gulp, config) => {
|
export default (gulp, config) => {
|
||||||
|
@ -1 +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-.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>
|
|
Before Width: | Height: | Size: 1.2 KiB |
20
material/assets/images/icons/bitbucket-black.svg
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
<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>
|
After Width: | Height: | Size: 1.3 KiB |
@ -1 +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-.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>
|
|
Before Width: | Height: | Size: 1.2 KiB |
20
material/assets/images/icons/bitbucket-white.svg
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
<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>
|
After Width: | Height: | Size: 1.3 KiB |
@ -1 +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 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>
|
|
Before Width: | Height: | Size: 959 B |
18
material/assets/images/icons/github-black.svg
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
<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>
|
After Width: | Height: | Size: 1.1 KiB |
@ -1 +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 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>
|
|
Before Width: | Height: | Size: 971 B |
18
material/assets/images/icons/github-white.svg
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
<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>
|
After Width: | Height: | Size: 1.1 KiB |
@ -1 +0,0 @@
|
|||||||
<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>
|
|
Before Width: | Height: | Size: 742 B |
31
material/assets/images/icons/gitlab-black.svg
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
<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>
|
After Width: | Height: | Size: 1.4 KiB |
@ -1 +0,0 @@
|
|||||||
<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>
|
|
Before Width: | Height: | Size: 826 B |
32
material/assets/images/icons/gitlab-white.svg
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
<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>
|
After Width: | Height: | Size: 1.5 KiB |
5407
material/assets/javascripts/application.js
Normal file
1286
material/assets/javascripts/modernizr.js
Normal file
1736
material/assets/stylesheets/application.css
Normal file
@ -20,19 +20,19 @@
|
|||||||
<meta name="author" content="{{ site_author }}">
|
<meta name="author" content="{{ site_author }}">
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<meta name="generator" content="mkdocs+mkdocs-material#0.2.1">
|
<meta name="generator" content="mkdocs+mkdocs-material#0.2.1">
|
||||||
<script src="{{ base_url }}/assets/javascripts/modernizr-dede1352ed.js"></script>
|
<script src="{{ base_url }}/assets/javascripts/modernizr.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: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/css?family=Roboto+Mono:400">
|
||||||
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
|
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
|
||||||
<link rel="stylesheet" href="{{ base_url }}/assets/stylesheets/application-9cd3c99a66.css">
|
<link rel="stylesheet" href="{{ base_url }}/assets/stylesheets/application.css">
|
||||||
{% for path in extra_css %}
|
{% for path in extra_css %}
|
||||||
<link rel="stylesheet" href="{{ path }}">
|
<link rel="stylesheet" href="{{ path }}">
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<input class="md-toggle md-toggle--drawer" type="checkbox" id="drawer">
|
<input class="md-toggle" data-md-toggle="drawer" type="checkbox" id="drawer">
|
||||||
<input class="md-toggle md-toggle--search" type="checkbox" id="search">
|
<input class="md-toggle" data-md-toggle="search" type="checkbox" id="search">
|
||||||
<label class="md-overlay" for="drawer"></label>
|
<label class="md-overlay" data-md-overlay for="drawer"></label>
|
||||||
{% include "partials/header.html" %}
|
{% include "partials/header.html" %}
|
||||||
<div class="md-container">
|
<div class="md-container">
|
||||||
<main class="md-main">
|
<main class="md-main">
|
||||||
@ -87,6 +87,12 @@
|
|||||||
</main>
|
</main>
|
||||||
{% include "partials/footer.html" %}
|
{% include "partials/footer.html" %}
|
||||||
</div>
|
</div>
|
||||||
|
{% for extension in config.markdown_extensions %}
|
||||||
|
{% if extension == "pymdownx.arithmatex" %}
|
||||||
|
{% set path = "mathjax/latest/MathJax.js?config=TeX-MML-AM_CHTML" %}
|
||||||
|
<script src="https://cdn.mathjax.org/{{ path }}"></script>
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
<script src="{{ base_url }}/assets/javascripts/application.js"></script>
|
<script src="{{ base_url }}/assets/javascripts/application.js"></script>
|
||||||
<script>
|
<script>
|
||||||
/* Configuration for application */
|
/* Configuration for application */
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
{% if nav_item.children %}
|
{% if nav_item.children %}
|
||||||
<li class="md-nav__item md-nav__item--nested">
|
<li class="md-nav__item md-nav__item--nested">
|
||||||
{% if nav_item.active %}
|
{% if nav_item.active %}
|
||||||
<input class="md-toggle md-nav__toggle" type="checkbox" id="{{ path }}" checked>
|
<input class="md-toggle md-nav__toggle" data-md-toggle="{{ path }}" type="checkbox" id="{{ path }}" checked>
|
||||||
{% else %}
|
{% else %}
|
||||||
<input class="md-toggle md-nav__toggle" type="checkbox" id="{{ path }}">
|
<input class="md-toggle md-nav__toggle" data-md-toggle="{{ path }}" type="checkbox" id="{{ path }}">
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<label class="md-nav__link" for="{{ path }}">
|
<label class="md-nav__link" for="{{ path }}">
|
||||||
{{ nav_item.title }}
|
{{ nav_item.title }}
|
||||||
@ -24,7 +24,7 @@
|
|||||||
</li>
|
</li>
|
||||||
{% elif nav_item == current_page %}
|
{% elif nav_item == current_page %}
|
||||||
<li class="md-nav__item">
|
<li class="md-nav__item">
|
||||||
<input class="md-toggle md-nav__toggle" type="checkbox" id="toc">
|
<input class="md-toggle md-nav__toggle" data-md-toggle="toc" type="checkbox" id="toc">
|
||||||
<label class="md-nav__link md-nav__link--active" for="toc">
|
<label class="md-nav__link md-nav__link--active" for="toc">
|
||||||
{{ nav_item.title }}
|
{{ nav_item.title }}
|
||||||
</label>
|
</label>
|
||||||
|
@ -1,18 +1,13 @@
|
|||||||
<div class="md-search">
|
<div class="md-search" data-md-search>
|
||||||
<div class="md-search__overlay"></div>
|
<div class="md-search__overlay"></div>
|
||||||
<div class="md-search__inner">
|
<div class="md-search__inner">
|
||||||
<form class="md-search__form">
|
<form class="md-search__form" name="search">
|
||||||
<input type="text" class="md-search__input" placeholder="Search" autocapitalize="off" autocorrect="off" autocomplete="off" spellcheck="false" id="query">
|
<input type="text" class="md-search__input" name="query" placeholder="Search" autocapitalize="off" autocorrect="off" autocomplete="off" spellcheck="false">
|
||||||
<label class="md-icon md-search__icon" for="search"></label>
|
<label class="md-icon md-search__icon" for="search"></label>
|
||||||
</form>
|
</form>
|
||||||
<div class="md-search__output">
|
<div class="md-search__output">
|
||||||
<div class="md-search__scrollwrap">
|
<div class="md-search__scrollwrap">
|
||||||
<div class="md-search-result">
|
<div class="md-search-result" data-md-search-result></div>
|
||||||
<div class="md-search-result__meta">
|
|
||||||
Indexing
|
|
||||||
</div>
|
|
||||||
<ol class="md-search-result__list"></ol>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,20 +1,19 @@
|
|||||||
{% set platform = config.extra.repo_icon or repo_url %}
|
{% set platform = config.extra.repo_icon or repo_url %}
|
||||||
{% if "github" in platform %}
|
{% if "github" in platform %}
|
||||||
|
{% set repo_type = "github" %}
|
||||||
{% set repo_icon = "md-source--github" %}
|
{% set repo_icon = "md-source--github" %}
|
||||||
{% elif "gitlab" in platform %}
|
{% elif "gitlab" in platform %}
|
||||||
|
{% set repo_type = "gitlab" %}
|
||||||
{% set repo_icon = "md-source--gitlab" %}
|
{% set repo_icon = "md-source--gitlab" %}
|
||||||
{% elif "bitbucket" in platform %}
|
{% elif "bitbucket" in platform %}
|
||||||
|
{% set repo_type = "bitbucket" %}
|
||||||
{% set repo_icon = "md-source--bitbucket" %}
|
{% set repo_icon = "md-source--bitbucket" %}
|
||||||
{% else %}
|
{% else %}
|
||||||
|
{% set repo_type = "" %}
|
||||||
{% set repo_icon = "" %}
|
{% set repo_icon = "" %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<a href="{{ repo_url }}" title="Go to repository" class="md-source {{ repo_icon }}">
|
<a href="{{ repo_url }}" title="Go to repository" class="md-source {{ repo_icon }}" data-md-source="{{ repo_type }}">
|
||||||
<div class="md-source__repository">
|
<div class="md-source__repository">
|
||||||
{{ repo_name }}
|
{{ repo_name }}
|
||||||
<ul class="md-source__facts">
|
|
||||||
{% if config.extra.version %}
|
|
||||||
<li class="md-source__fact">v{{ config.extra.version }}</li>
|
|
||||||
{% endif %}
|
|
||||||
</ul>
|
|
||||||
</div>
|
</div>
|
||||||
</a>
|
</a>
|
||||||
|
@ -52,9 +52,11 @@ markdown_extensions:
|
|||||||
- markdown.extensions.footnotes
|
- markdown.extensions.footnotes
|
||||||
- markdown.extensions.meta
|
- markdown.extensions.meta
|
||||||
- markdown.extensions.toc(permalink=true)
|
- markdown.extensions.toc(permalink=true)
|
||||||
- pymdownx.betterem
|
- pymdownx.arithmatex
|
||||||
|
- pymdownx.betterem(smart_enable=all)
|
||||||
- pymdownx.caret
|
- pymdownx.caret
|
||||||
- pymdownx.critic
|
- pymdownx.critic
|
||||||
|
- pymdownx.githubemoji
|
||||||
- pymdownx.inlinehilite
|
- pymdownx.inlinehilite
|
||||||
- pymdownx.magiclink
|
- pymdownx.magiclink
|
||||||
- pymdownx.mark
|
- pymdownx.mark
|
||||||
@ -76,6 +78,7 @@ pages:
|
|||||||
- Permalinks: extensions/permalinks.md
|
- Permalinks: extensions/permalinks.md
|
||||||
- PyMdown:
|
- PyMdown:
|
||||||
- Overview: extensions/pymdown/overview.md
|
- Overview: extensions/pymdown/overview.md
|
||||||
|
- Arithmatex: extensions/pymdown/arithmatex.md
|
||||||
- Tasklist: extensions/pymdown/tasklist.md
|
- Tasklist: extensions/pymdown/tasklist.md
|
||||||
- Specimen: specimen.md
|
- Specimen: specimen.md
|
||||||
- Customization: customization.md
|
- Customization: customization.md
|
||||||
|
@ -31,6 +31,7 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"fastclick": "^1.0.6",
|
"fastclick": "^1.0.6",
|
||||||
|
"js-cookie": "^2.1.3",
|
||||||
"lunr": "^0.7.1",
|
"lunr": "^0.7.1",
|
||||||
"material-design-color": "^2.3.1",
|
"material-design-color": "^2.3.1",
|
||||||
"material-shadows": "^3.0.0",
|
"material-shadows": "^3.0.0",
|
||||||
|
@ -20,234 +20,180 @@
|
|||||||
* IN THE SOFTWARE.
|
* IN THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* ----------------------------------------------------------------------------
|
|
||||||
* Imports
|
|
||||||
* ------------------------------------------------------------------------- */
|
|
||||||
|
|
||||||
import FastClick from "fastclick"
|
import FastClick from "fastclick"
|
||||||
|
|
||||||
// import Expander from "./components/expander"
|
|
||||||
|
|
||||||
import GithubSourceFacts from "./components/GithubSourceFacts"
|
|
||||||
import Material from "./components/Material"
|
import Material from "./components/Material"
|
||||||
|
|
||||||
// import Search from './components/search';
|
|
||||||
|
|
||||||
/* ----------------------------------------------------------------------------
|
/* ----------------------------------------------------------------------------
|
||||||
* Application
|
* Application
|
||||||
* ------------------------------------------------------------------------- */
|
* ------------------------------------------------------------------------- */
|
||||||
|
|
||||||
class Application {
|
export default class Application {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor.
|
* Create the application
|
||||||
*
|
*
|
||||||
* @constructor
|
* @constructor
|
||||||
* @param {object} config Configuration object
|
* @param {object} config Configuration object
|
||||||
* @return {void}
|
|
||||||
*/
|
*/
|
||||||
constructor(config) {
|
constructor(config) {
|
||||||
this.config_ = config
|
this.config_ = config
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize all components
|
* Initialize all components and listeners
|
||||||
*/
|
*/
|
||||||
initialize() {
|
initialize() {
|
||||||
|
|
||||||
/* Initialize sticky sidebars */
|
/* Initialize Modernizr and Fastclick */
|
||||||
this.initializeSidebar("[data-md-sidebar=primary]", "(min-width: 1200px)")
|
new Material.Event.Listener(document, "DOMContentLoaded", () => {
|
||||||
this.initializeSidebar("[data-md-sidebar=secondary]")
|
|
||||||
|
|
||||||
/* Initialize navigation style modifiers */
|
/* Test for iOS */
|
||||||
this.initializeNavBlur("[data-md-sidebar=secondary] .md-nav__link")
|
Modernizr.addTest("ios", () => {
|
||||||
this.initializeNavCollapse("[data-md-collapse]", "(min-width: 1200px)")
|
return !!navigator.userAgent.match(/(iPad|iPhone|iPod)/g)
|
||||||
|
})
|
||||||
|
|
||||||
// TODO
|
/* Test for web application context */
|
||||||
if (this.hasGithubRepo()) {
|
Modernizr.addTest("standalone", () => {
|
||||||
const githubSource = new GithubSourceFacts(
|
return !!navigator.standalone
|
||||||
this.config_.storage,
|
})
|
||||||
this.config_.repo.url
|
|
||||||
)
|
/* Attack FastClick to mitigate 300ms delay on touch devices */
|
||||||
githubSource.initialize()
|
FastClick.attach(document.body)
|
||||||
|
}).listen()
|
||||||
|
|
||||||
|
/* Cross-browser helper to dispatch/fire an event */
|
||||||
|
const dispatch = (el, event) => {
|
||||||
|
return document.createEvent
|
||||||
|
? el.dispatchEvent(new Event(event))
|
||||||
|
: el.fireEvent(`on${event}`, document.createEventObject())
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
/* Truncate a string after the given number of characters - this is not
|
||||||
|
a reasonable approach, since the summaries kind of suck. It would be
|
||||||
|
better to create something more intelligent, highlighting the search
|
||||||
|
occurrences and making a better summary out of it */
|
||||||
|
const truncate = function(string, n) {
|
||||||
|
let i = n
|
||||||
|
if (string.length > i) {
|
||||||
|
while (string[i] !== " " && --i > 0);
|
||||||
|
return `${string.substring(0, i)}...`
|
||||||
|
}
|
||||||
|
return string
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/* Component: sidebar with navigation */
|
||||||
* Initialize sidebar within optional media query range
|
new Material.Event.MatchMedia("(min-width: 1200px)",
|
||||||
*
|
new Material.Event.Listener(window, [
|
||||||
* @param {(string|HTMLElement)} el - Selector or HTML element
|
"scroll", "resize", "orientationchange"
|
||||||
* @param {string} [query] - Media query
|
], new Material.Sidebar("[data-md-sidebar=primary]")))
|
||||||
*/
|
|
||||||
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 */
|
/* Component: sidebar with table of contents */
|
||||||
if (typeof query === "string" && query.length) {
|
new Material.Event.MatchMedia("(min-width: 960px)",
|
||||||
new Material.Listener.Viewport.Media(query, media => {
|
new Material.Event.Listener(window, [
|
||||||
if (media.matches) {
|
"scroll", "resize", "orientationchange"
|
||||||
sidebar.update()
|
], new Material.Sidebar("[data-md-sidebar=secondary]")))
|
||||||
for (const listener of listeners)
|
|
||||||
listener.listen()
|
/* Component: link blurring for table of contents */
|
||||||
} else {
|
new Material.Event.MatchMedia("(min-width: 960px)",
|
||||||
sidebar.reset()
|
new Material.Event.Listener(window, "scroll",
|
||||||
for (const listener of listeners)
|
new Material.Nav.Blur("[data-md-sidebar=secondary] .md-nav__link")))
|
||||||
listener.unlisten()
|
|
||||||
|
/* Component: collapsible elements for navigation */
|
||||||
|
const collapsibles = document.querySelectorAll("[data-md-collapse]")
|
||||||
|
for (const collapse of collapsibles)
|
||||||
|
new Material.Event.MatchMedia("(min-width: 1200px)",
|
||||||
|
new Material.Event.Listener(collapse.previousElementSibling, "click",
|
||||||
|
new Material.Nav.Collapse(collapse)))
|
||||||
|
|
||||||
|
/* Component: search body lock for mobile */
|
||||||
|
new Material.Event.MatchMedia("(max-width: 959px)",
|
||||||
|
new Material.Event.Listener("[data-md-toggle=search]", "change",
|
||||||
|
new Material.Search.Lock("[data-md-toggle=search]")))
|
||||||
|
|
||||||
|
/* Component: search results */
|
||||||
|
new Material.Event.Listener(document.forms.search.query, [
|
||||||
|
"focus", "keyup"
|
||||||
|
], new Material.Search.Result("[data-md-search-result]", () => {
|
||||||
|
return fetch(`${this.config_.url.base}/mkdocs/search_index.json`)
|
||||||
|
.then(response => response.json())
|
||||||
|
.then(data => {
|
||||||
|
return data.docs.map(doc => {
|
||||||
|
doc.location = this.config_.url.base + doc.location
|
||||||
|
doc.text = truncate(doc.text, 140)
|
||||||
|
return doc
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})).listen()
|
||||||
|
|
||||||
|
/* Listener: prevent touches on overlay if navigation is active */
|
||||||
|
new Material.Event.MatchMedia("(max-width: 1199px)",
|
||||||
|
new Material.Event.Listener("[data-md-overlay]", "touchstart",
|
||||||
|
ev => ev.preventDefault()))
|
||||||
|
|
||||||
|
/* Listener: close drawer when anchor links are clicked */
|
||||||
|
new Material.Event.MatchMedia("(max-width: 959px)",
|
||||||
|
new Material.Event.Listener("[data-md-sidebar=primary] [href^='#']",
|
||||||
|
"click", () => {
|
||||||
|
const toggle = document.querySelector("[data-md-toggle=drawer]")
|
||||||
|
if (toggle.checked) {
|
||||||
|
toggle.checked = false
|
||||||
|
dispatch(toggle, "change")
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
|
||||||
|
/* Listener: focus input after activating search */
|
||||||
|
new Material.Event.Listener("[data-md-toggle=search]", "change", ev => {
|
||||||
|
setTimeout(toggle => {
|
||||||
|
const query = document.forms.search.query
|
||||||
|
if (toggle.checked)
|
||||||
|
query.focus()
|
||||||
|
}, 400, ev.target)
|
||||||
|
}).listen()
|
||||||
|
|
||||||
|
/* Listener: activate search on focus */
|
||||||
|
new Material.Event.MatchMedia("(min-width: 960px)",
|
||||||
|
new Material.Event.Listener(document.forms.search.query, "focus", () => {
|
||||||
|
const toggle = document.querySelector("[data-md-toggle=search]")
|
||||||
|
if (!toggle.checked) {
|
||||||
|
toggle.checked = true
|
||||||
|
dispatch(toggle, "change")
|
||||||
}
|
}
|
||||||
}).listen()
|
}))
|
||||||
|
|
||||||
/* Initialize without media query */
|
/* Listener: disable search when clicking outside */
|
||||||
} else {
|
new Material.Event.MatchMedia("(min-width: 960px)",
|
||||||
sidebar.update()
|
new Material.Event.Listener(document.body, "click", () => {
|
||||||
for (const listener of listeners)
|
const toggle = document.querySelector("[data-md-toggle=search]")
|
||||||
listener.listen()
|
if (toggle.checked) {
|
||||||
}
|
toggle.checked = false
|
||||||
}
|
dispatch(toggle, "change")
|
||||||
|
|
||||||
/**
|
|
||||||
* 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()
|
}))
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/* Listener: fix unclickable toggle due to blur handler */
|
||||||
* Is this application about a Github repository?
|
new Material.Event.MatchMedia("(min-width: 960px)",
|
||||||
*
|
new Material.Event.Listener("[data-md-toggle=search]", "click",
|
||||||
* @return {bool} - true if `repo.icon` or `repo.url` contains 'github'
|
ev => ev.stopPropagation()))
|
||||||
*/
|
|
||||||
hasGithubRepo() {
|
/* Listener: prevent search from closing when clicking */
|
||||||
return this.config_.repo.icon === "github"
|
new Material.Event.MatchMedia("(min-width: 960px)",
|
||||||
|| this.config_.repo.url.includes("github")
|
new Material.Event.Listener("[data-md-search]", "click",
|
||||||
|
ev => ev.stopPropagation()))
|
||||||
|
|
||||||
|
/* Retrieve the facts for the given repository type */
|
||||||
|
;(() => {
|
||||||
|
const el = document.querySelector("[data-md-source]")
|
||||||
|
switch (el.dataset.mdSource) {
|
||||||
|
case "github": return new Material.Source.Adapter.GitHub(el).fetch()
|
||||||
|
default: return Promise.resolve([])
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Render repository source information */
|
||||||
|
})().then(facts => {
|
||||||
|
const sources = document.querySelectorAll("[data-md-source]")
|
||||||
|
for (const source of sources)
|
||||||
|
new Material.Source.Repository(source)
|
||||||
|
.initialize(facts)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
/* Initialize application upon DOM ready */
|
|
||||||
document.addEventListener("DOMContentLoaded", () => {
|
|
||||||
|
|
||||||
/* Test for iOS */
|
|
||||||
Modernizr.addTest("ios", () => {
|
|
||||||
return !!navigator.userAgent.match(/(iPad|iPhone|iPod)/g)
|
|
||||||
})
|
|
||||||
|
|
||||||
/* Test for web application context */
|
|
||||||
Modernizr.addTest("standalone", () => {
|
|
||||||
return !!navigator.standalone
|
|
||||||
})
|
|
||||||
|
|
||||||
/* Attack FastClick to mitigate 300ms delay on touch devices */
|
|
||||||
FastClick.attach(document.body)
|
|
||||||
|
|
||||||
// query.addEventListener("focus", () => {
|
|
||||||
// document.querySelector(".md-search").dataset.mdLocked = ""
|
|
||||||
// })
|
|
||||||
|
|
||||||
/* Intercept click on search mode toggle */
|
|
||||||
|
|
||||||
// TODO: this needs to be abstracted...
|
|
||||||
document.getElementById("query").addEventListener("focus", () => {
|
|
||||||
document.getElementById("search").checked = true
|
|
||||||
})
|
|
||||||
|
|
||||||
// should be registered on body, but leads to problems
|
|
||||||
document.querySelector(".md-container").addEventListener("click", () => {
|
|
||||||
if (document.getElementById("search").checked)
|
|
||||||
document.getElementById("search").checked = false
|
|
||||||
})
|
|
||||||
|
|
||||||
// stop propagation, if search is active...
|
|
||||||
document.querySelector(".md-search").addEventListener("click", ev => {
|
|
||||||
ev.stopPropagation()
|
|
||||||
})
|
|
||||||
// toggleSearchClose.addEventListener("click", ev => {
|
|
||||||
// ev.preventDefault()
|
|
||||||
// // ev.target
|
|
||||||
//
|
|
||||||
// const search = document.getElementById("search")
|
|
||||||
// search.checked = false
|
|
||||||
// })
|
|
||||||
|
|
||||||
// }, 1000);
|
|
||||||
|
|
||||||
fetch(
|
|
||||||
"https://api.github.com/repos/squidfunk/mkdocs-material/releases/latest")
|
|
||||||
.then(response => {
|
|
||||||
return response.json()
|
|
||||||
})
|
|
||||||
// .then(data => {
|
|
||||||
// // console.log(data)
|
|
||||||
// })
|
|
||||||
|
|
||||||
})
|
|
||||||
|
@ -1,110 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* ----------------------------------------------------------------------------
|
|
||||||
* Github Source
|
|
||||||
* ------------------------------------------------------------------------- */
|
|
||||||
|
|
||||||
export default
|
|
||||||
class GithubSourceFacts {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructor.
|
|
||||||
*
|
|
||||||
* @constructor
|
|
||||||
* @param {object} storage - Accessor to storage, eg. `window.sessionStorage`
|
|
||||||
* @param {string} repoUrl - URL to Github repository
|
|
||||||
*/
|
|
||||||
constructor(storage, repoUrl) {
|
|
||||||
this.storage = storage
|
|
||||||
this.storageKey = "github-source-facts"
|
|
||||||
this.apiRepoUrl = repoUrl.replace("github.com/", "api.github.com/repos/")
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieve stars and fork counts for the repository before invoking
|
|
||||||
* `GithubSourceFacts.paint`.
|
|
||||||
*
|
|
||||||
* @return {void}
|
|
||||||
*/
|
|
||||||
initialize() {
|
|
||||||
const facts = this.storage.getItem(this.storageKey)
|
|
||||||
|
|
||||||
// Retrieve the facts, then invoke paint
|
|
||||||
if (!facts) {
|
|
||||||
fetch(this.apiRepoUrl)
|
|
||||||
.then(response => {
|
|
||||||
return response.json()
|
|
||||||
})
|
|
||||||
.then(data => {
|
|
||||||
const repoFacts = {
|
|
||||||
stars: data.stargazers_count,
|
|
||||||
forks: data.forks_count
|
|
||||||
}
|
|
||||||
|
|
||||||
this.storage.setItem(this.storageKey, JSON.stringify(repoFacts))
|
|
||||||
|
|
||||||
GithubSourceFacts.paint(repoFacts)
|
|
||||||
})
|
|
||||||
.catch(() => {
|
|
||||||
// console.log("parsing failed", ex)
|
|
||||||
})
|
|
||||||
// Use the cached facts
|
|
||||||
} else {
|
|
||||||
GithubSourceFacts.paint(JSON.parse(facts))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Populates `.md-source__facts` with star and fork counts.
|
|
||||||
*
|
|
||||||
* @param {integer} options.stars - Stars count for the repo
|
|
||||||
* @param {integer} options.forks - Fork count for the repo
|
|
||||||
* @return {void}
|
|
||||||
*/
|
|
||||||
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 = (
|
|
||||||
<li class="md-source__fact md-source__fact--hidden">
|
|
||||||
{stars} Stars
|
|
||||||
</li>
|
|
||||||
)
|
|
||||||
setTimeout(fact => {
|
|
||||||
fact.classList.remove("md-source__fact--hidden")
|
|
||||||
}, 100, li)
|
|
||||||
list.appendChild(li)
|
|
||||||
|
|
||||||
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,56 +20,20 @@
|
|||||||
* IN THE SOFTWARE.
|
* IN THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import Event from "./Material/Event"
|
||||||
import Nav from "./Material/Nav"
|
import Nav from "./Material/Nav"
|
||||||
import Search from "./Material/Search"
|
import Search from "./Material/Search"
|
||||||
import Listener from "./Material/Listener"
|
|
||||||
import Sidebar from "./Material/Sidebar"
|
import Sidebar from "./Material/Sidebar"
|
||||||
|
import Source from "./Material/Source"
|
||||||
|
|
||||||
/* ----------------------------------------------------------------------------
|
/* ----------------------------------------------------------------------------
|
||||||
* Module
|
* Module
|
||||||
* ------------------------------------------------------------------------- */
|
* ------------------------------------------------------------------------- */
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
Event,
|
||||||
Nav,
|
Nav,
|
||||||
Search,
|
Search,
|
||||||
Listener,
|
Sidebar,
|
||||||
Sidebar
|
Source
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ----------------------------------------------------------------------------
|
|
||||||
* 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...
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
@ -20,16 +20,14 @@
|
|||||||
* IN THE SOFTWARE.
|
* IN THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import Media from "./Viewport/Media"
|
import Listener from "./Event/Listener"
|
||||||
import Offset from "./Viewport/Offset"
|
import MatchMedia from "./Event/MatchMedia"
|
||||||
import Resize from "./Viewport/Resize"
|
|
||||||
|
|
||||||
/* ----------------------------------------------------------------------------
|
/* ----------------------------------------------------------------------------
|
||||||
* Module
|
* Module
|
||||||
* ------------------------------------------------------------------------- */
|
* ------------------------------------------------------------------------- */
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
Media,
|
Listener,
|
||||||
Offset,
|
MatchMedia
|
||||||
Resize
|
|
||||||
}
|
}
|
77
src/assets/javascripts/components/Material/Event/Listener.js
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* ----------------------------------------------------------------------------
|
||||||
|
* Class
|
||||||
|
* ------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
export default class Listener {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generic event listener
|
||||||
|
*
|
||||||
|
* @constructor
|
||||||
|
* @param {(string|NodeList<HTMLElement>)} els - Selector or HTML elements
|
||||||
|
* @param {Array.<string>} events - Event names
|
||||||
|
* @param {(object|function)} handler - Handler to be invoked
|
||||||
|
*/
|
||||||
|
constructor(els, events, handler) {
|
||||||
|
this.els_ = (typeof els === "string")
|
||||||
|
? document.querySelectorAll(els)
|
||||||
|
: [].concat(els)
|
||||||
|
|
||||||
|
/* Set handler as function or directly as object */
|
||||||
|
this.handler_ = typeof handler === "function"
|
||||||
|
? { update: handler }
|
||||||
|
: handler
|
||||||
|
|
||||||
|
/* Initialize event names and update handler */
|
||||||
|
this.events_ = [].concat(events)
|
||||||
|
this.update_ = ev => this.handler_.update(ev)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register listener for all relevant events
|
||||||
|
*/
|
||||||
|
listen() {
|
||||||
|
for (const el of this.els_)
|
||||||
|
for (const event of this.events_)
|
||||||
|
el.addEventListener(event, this.update_, false)
|
||||||
|
|
||||||
|
/* Execute setup handler, if implemented */
|
||||||
|
if (typeof this.handler_.setup === "function")
|
||||||
|
this.handler_.setup()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unregister listener for all relevant events
|
||||||
|
*/
|
||||||
|
unlisten() {
|
||||||
|
for (const el of this.els_)
|
||||||
|
for (const event of this.events_)
|
||||||
|
el.removeEventListener(event, this.update_)
|
||||||
|
|
||||||
|
/* Execute reset handler, if implemented */
|
||||||
|
if (typeof this.handler_.reset === "function")
|
||||||
|
this.handler_.reset()
|
||||||
|
}
|
||||||
|
}
|
@ -21,37 +21,34 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/* ----------------------------------------------------------------------------
|
/* ----------------------------------------------------------------------------
|
||||||
* Definition
|
* Class
|
||||||
* ------------------------------------------------------------------------- */
|
* ------------------------------------------------------------------------- */
|
||||||
|
|
||||||
export default class Media {
|
export default class MatchMedia {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Listener which checks for media queries on dimension changes
|
* Media query listener
|
||||||
|
*
|
||||||
|
* This class listens for state changes of media queries and automatically
|
||||||
|
* switches the given listeners on or off.
|
||||||
*
|
*
|
||||||
* @constructor
|
* @constructor
|
||||||
* @param {string} query - Media query
|
* @param {string} query - Media query to test for
|
||||||
* @param {Function} handler - Event handler to execute
|
* @param {Listener} listener - Event listener
|
||||||
*/
|
*/
|
||||||
constructor(query, handler) {
|
constructor(query, listener) {
|
||||||
this.media_ = window.matchMedia(query)
|
this.handler_ = mq => {
|
||||||
this.handler_ = media => {
|
if (mq.matches)
|
||||||
handler(media)
|
listener.listen()
|
||||||
|
else
|
||||||
|
listener.unlisten()
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/* Initialize media query listener */
|
||||||
* Register listener for media query check
|
const media = window.matchMedia(query)
|
||||||
*/
|
media.addListener(this.handler_)
|
||||||
listen() {
|
|
||||||
this.media_.addListener(this.handler_)
|
|
||||||
this.handler_(this.media_)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/* Always check at initialization */
|
||||||
* Unregister listener for media query check
|
this.handler_(media)
|
||||||
*/
|
|
||||||
unlisten() {
|
|
||||||
this.media_.removeListener(this.handler_)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,40 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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)
|
|
||||||
}
|
|
||||||
}
|
|
@ -21,7 +21,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/* ----------------------------------------------------------------------------
|
/* ----------------------------------------------------------------------------
|
||||||
* Definition
|
* Class
|
||||||
* ------------------------------------------------------------------------- */
|
* ------------------------------------------------------------------------- */
|
||||||
|
|
||||||
export default class Blur {
|
export default class Blur {
|
||||||
@ -47,6 +47,13 @@ export default class Blur {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize anchor states
|
||||||
|
*/
|
||||||
|
setup() {
|
||||||
|
this.update()
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update anchor states
|
* Update anchor states
|
||||||
*/
|
*/
|
||||||
@ -58,7 +65,7 @@ export default class Blur {
|
|||||||
for (let i = this.index_ + 1; i < this.els_.length; i++) {
|
for (let i = this.index_ + 1; i < this.els_.length; i++) {
|
||||||
if (this.anchors_[i].offsetTop <= offset) {
|
if (this.anchors_[i].offsetTop <= offset) {
|
||||||
if (i > 0)
|
if (i > 0)
|
||||||
this.els_[i - 1].dataset.mdBlurred = ""
|
this.els_[i - 1].dataset.mdState = "blur"
|
||||||
this.index_ = i
|
this.index_ = i
|
||||||
} else {
|
} else {
|
||||||
break
|
break
|
||||||
@ -70,7 +77,7 @@ export default class Blur {
|
|||||||
for (let i = this.index_; i >= 0; i--) {
|
for (let i = this.index_; i >= 0; i--) {
|
||||||
if (this.anchors_[i].offsetTop > offset) {
|
if (this.anchors_[i].offsetTop > offset) {
|
||||||
if (i > 0)
|
if (i > 0)
|
||||||
delete this.els_[i - 1].dataset.mdBlurred
|
delete this.els_[i - 1].dataset.mdState
|
||||||
} else {
|
} else {
|
||||||
this.index_ = i
|
this.index_ = i
|
||||||
break
|
break
|
||||||
@ -86,8 +93,11 @@ export default class Blur {
|
|||||||
* Reset anchor states
|
* Reset anchor states
|
||||||
*/
|
*/
|
||||||
reset() {
|
reset() {
|
||||||
[].forEach.call(this.els_, el => {
|
for (const el of this.els_)
|
||||||
delete el.dataset.mdBlurred
|
delete el.dataset.mdState
|
||||||
})
|
|
||||||
|
/* Reset index and page y-offset */
|
||||||
|
this.index_ = 0
|
||||||
|
this.offset_ = window.pageYOffset
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -21,7 +21,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/* ----------------------------------------------------------------------------
|
/* ----------------------------------------------------------------------------
|
||||||
* Definition
|
* Class
|
||||||
* ------------------------------------------------------------------------- */
|
* ------------------------------------------------------------------------- */
|
||||||
|
|
||||||
export default class Collapse {
|
export default class Collapse {
|
||||||
@ -39,7 +39,7 @@ export default class Collapse {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Make expand and collapse transition smoothly
|
* Animate expand and collapse smoothly
|
||||||
*/
|
*/
|
||||||
update() {
|
update() {
|
||||||
const current = this.el_.getBoundingClientRect().height
|
const current = this.el_.getBoundingClientRect().height
|
||||||
@ -48,43 +48,43 @@ export default class Collapse {
|
|||||||
if (current) {
|
if (current) {
|
||||||
this.el_.style.maxHeight = `${current}px`
|
this.el_.style.maxHeight = `${current}px`
|
||||||
requestAnimationFrame(() => {
|
requestAnimationFrame(() => {
|
||||||
this.el_.dataset.mdAnimated = ""
|
this.el_.dataset.mdState = "animate"
|
||||||
this.el_.style.maxHeight = "0px"
|
this.el_.style.maxHeight = "0px"
|
||||||
})
|
})
|
||||||
|
|
||||||
/* Collapsed, so expand */
|
/* Collapsed, so expand */
|
||||||
} else {
|
} else {
|
||||||
|
this.el_.dataset.mdState = "expand"
|
||||||
this.el_.style.maxHeight = ""
|
this.el_.style.maxHeight = ""
|
||||||
this.el_.dataset.mdExpanded = ""
|
|
||||||
|
|
||||||
/* Read height and unset pseudo-toggled state */
|
/* Read height and unset pseudo-toggled state */
|
||||||
const height = this.el_.getBoundingClientRect().height
|
const height = this.el_.getBoundingClientRect().height
|
||||||
delete this.el_.dataset.mdExpanded
|
delete this.el_.dataset.mdState
|
||||||
|
|
||||||
/* Set initial state and animate */
|
/* Set initial state and animate */
|
||||||
this.el_.style.maxHeight = "0px"
|
this.el_.style.maxHeight = "0px"
|
||||||
requestAnimationFrame(() => {
|
requestAnimationFrame(() => {
|
||||||
this.el_.dataset.mdAnimated = ""
|
this.el_.dataset.mdState = "animate"
|
||||||
this.el_.style.maxHeight = `${height}px`
|
this.el_.style.maxHeight = `${height}px`
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Remove state on end of transition */
|
/* Remove state on end of transition */
|
||||||
const end = function(ev) {
|
const end = function(ev) {
|
||||||
delete ev.target.dataset.mdAnimated
|
delete ev.target.dataset.mdState
|
||||||
ev.target.style.maxHeight = ""
|
ev.target.style.maxHeight = ""
|
||||||
|
|
||||||
/* Only fire once, so remove event listener again */
|
/* Only fire once, so directly remove event listener */
|
||||||
ev.target.removeEventListener("transitionend", end, false)
|
ev.target.removeEventListener("transitionend", end, false)
|
||||||
}
|
}
|
||||||
this.el_.addEventListener("transitionend", end, false)
|
this.el_.addEventListener("transitionend", end, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Nothing to reset
|
* Reset height and pseudo-toggled state
|
||||||
*/
|
*/
|
||||||
reset() {
|
reset() {
|
||||||
|
delete this.el_.dataset.mdState
|
||||||
this.el_.style.maxHeight = ""
|
this.el_.style.maxHeight = ""
|
||||||
delete this.el_.dataset.mdToggled
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,14 +20,14 @@
|
|||||||
* IN THE SOFTWARE.
|
* IN THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import Index from "./Search/Index"
|
|
||||||
import Lock from "./Search/Lock"
|
import Lock from "./Search/Lock"
|
||||||
|
import Result from "./Search/Result"
|
||||||
|
|
||||||
/* ----------------------------------------------------------------------------
|
/* ----------------------------------------------------------------------------
|
||||||
* Module
|
* Module
|
||||||
* ------------------------------------------------------------------------- */
|
* ------------------------------------------------------------------------- */
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
Index,
|
Lock,
|
||||||
Lock
|
Result
|
||||||
}
|
}
|
||||||
|
@ -1,152 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
@ -21,102 +21,68 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/* ----------------------------------------------------------------------------
|
/* ----------------------------------------------------------------------------
|
||||||
* Definition
|
* Class
|
||||||
* ------------------------------------------------------------------------- */
|
* ------------------------------------------------------------------------- */
|
||||||
|
|
||||||
export default class Lock {
|
export default class Lock {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Lock body for full-screen search bar
|
* Lock body for full-screen search modal
|
||||||
*
|
*
|
||||||
* @constructor
|
* @constructor
|
||||||
* @param {(string|HTMLElement)} el - Selector or HTML element
|
* @param {(string|HTMLElement)} el - Selector or HTML element
|
||||||
* @param {Function} handler - Callback to execute in active search mode
|
|
||||||
*/
|
*/
|
||||||
constructor(el, handler) {
|
constructor(el) {
|
||||||
this.el_ = (typeof el === "string")
|
this.el_ = (typeof el === "string")
|
||||||
? document.querySelector(el)
|
? document.querySelector(el)
|
||||||
: 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
|
* Setup locked state
|
||||||
*
|
|
||||||
* @param {Event} ev - Event
|
|
||||||
*/
|
*/
|
||||||
update(ev) {
|
setup() {
|
||||||
|
this.update()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update locked state
|
||||||
|
*/
|
||||||
|
update() {
|
||||||
|
|
||||||
/* Entering search mode */
|
/* Entering search mode */
|
||||||
if (ev.target.checked) {
|
if (this.el_.checked) {
|
||||||
this.offset_ = window.scrollY
|
this.offset_ = window.pageYOffset
|
||||||
|
|
||||||
/* First timeout: scroll to top after transition, to omit flickering */
|
/* Scroll to top after transition, to omit flickering */
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
window.scrollTo(0, 0)
|
window.scrollTo(0, 0)
|
||||||
}, 400)
|
|
||||||
|
|
||||||
/* Second timeout: Lock body after finishing transition and scrolling
|
/* Lock body after finishing transition */
|
||||||
to top and focus input field. Sadly, the focus event is not dispatched
|
if (this.el_.checked) {
|
||||||
on iOS Safari and there's nothing we can do about it. */
|
document.body.dataset.mdState = "lock"
|
||||||
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)
|
}, 400)
|
||||||
|
|
||||||
/* Exiting search mode */
|
/* Exiting search mode */
|
||||||
} else {
|
} else {
|
||||||
delete document.body.dataset.mdLocked
|
delete document.body.dataset.mdState
|
||||||
|
|
||||||
/* Scroll to former position, but wait for 100ms to prevent flashes on
|
/* Scroll to former position, but wait for 100ms to prevent flashes on
|
||||||
iOS. A short timeout seems to do the trick */
|
iOS. A short timeout seems to do the trick */
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
window.scrollTo(0, this.offset_)
|
if (typeof this.offset_ !== "undefined")
|
||||||
|
window.scrollTo(0, this.offset_)
|
||||||
}, 100)
|
}, 100)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reset state
|
* Reset locked state and page y-offset
|
||||||
*
|
|
||||||
* @param {Event} ev - Event
|
|
||||||
*/
|
*/
|
||||||
reset() {
|
reset() {
|
||||||
delete document.body.dataset.mdLocked
|
if (document.body.dataset.mdState)
|
||||||
window.scrollTo(0, this.offset_)
|
window.scrollTo(0, this.offset_)
|
||||||
}
|
delete document.body.dataset.mdState
|
||||||
|
|
||||||
/**
|
|
||||||
* 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()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
125
src/assets/javascripts/components/Material/Search/Result.jsx
Normal file
@ -0,0 +1,125 @@
|
|||||||
|
/*
|
||||||
|
* 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"
|
||||||
|
|
||||||
|
/* ----------------------------------------------------------------------------
|
||||||
|
* Class
|
||||||
|
* ------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
export default class Result {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Perform search and update results on keyboard events
|
||||||
|
*
|
||||||
|
* @constructor
|
||||||
|
* @param {(string|HTMLElement)} el - Selector or HTML element
|
||||||
|
* @param {(Array.<object>|Function)} data - Promise or array providing data
|
||||||
|
*/
|
||||||
|
constructor(el, data) {
|
||||||
|
this.el_ = (typeof el === "string")
|
||||||
|
? document.querySelector(el)
|
||||||
|
: el
|
||||||
|
|
||||||
|
/* Set data and create metadata and list elements */
|
||||||
|
this.data_ = data
|
||||||
|
this.meta_ = (
|
||||||
|
<div class="md-search-result__meta">
|
||||||
|
Type to start searching
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
this.list_ = (
|
||||||
|
<ol class="md-search-result__list"></ol>
|
||||||
|
)
|
||||||
|
|
||||||
|
/* Inject created elements */
|
||||||
|
this.el_.appendChild(this.meta_)
|
||||||
|
this.el_.appendChild(this.list_)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update search results
|
||||||
|
*
|
||||||
|
* @param {Event} ev - Input or focus event
|
||||||
|
*/
|
||||||
|
update(ev) {
|
||||||
|
|
||||||
|
/* Initialize index, if this has not be done yet */
|
||||||
|
if (ev.type === "focus" && !this.index_) {
|
||||||
|
|
||||||
|
/* Initialize index */
|
||||||
|
const init = data => {
|
||||||
|
this.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 documents */
|
||||||
|
this.data_ = data.reduce((docs, doc) => {
|
||||||
|
this.index_.add(doc)
|
||||||
|
docs[doc.location] = doc
|
||||||
|
return docs
|
||||||
|
}, {})
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Initialize index after short timeout to account for transition */
|
||||||
|
setTimeout(() => {
|
||||||
|
return typeof this.data_ === "function"
|
||||||
|
? this.data_().then(init)
|
||||||
|
: init(this.data_)
|
||||||
|
}, 250)
|
||||||
|
|
||||||
|
/* Execute search on new input event after clearing current list */
|
||||||
|
} else if (ev.type === "keyup") {
|
||||||
|
while (this.list_.firstChild)
|
||||||
|
this.list_.removeChild(this.list_.firstChild)
|
||||||
|
|
||||||
|
/* Perform search on index and render documents */
|
||||||
|
const result = this.index_.search(ev.target.value)
|
||||||
|
for (const item of result) {
|
||||||
|
const doc = this.data_[item.ref]
|
||||||
|
this.list_.appendChild(
|
||||||
|
<li class="md-search-result__item">
|
||||||
|
<a href={doc.location} title={doc.title}
|
||||||
|
class="md-search-result__link">
|
||||||
|
<article class="md-search-result__article">
|
||||||
|
<h1 class="md-search-result__title">
|
||||||
|
{doc.title}
|
||||||
|
</h1>
|
||||||
|
<p class="md-search-result__teaser">
|
||||||
|
{doc.text}
|
||||||
|
</p>
|
||||||
|
</article>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Update search metadata */
|
||||||
|
this.meta_.textContent =
|
||||||
|
`${result.length} search result${result.length !== 1 ? "s" : ""}`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -21,7 +21,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/* ----------------------------------------------------------------------------
|
/* ----------------------------------------------------------------------------
|
||||||
* Definition
|
* Class
|
||||||
* ------------------------------------------------------------------------- */
|
* ------------------------------------------------------------------------- */
|
||||||
|
|
||||||
export default class Sidebar {
|
export default class Sidebar {
|
||||||
@ -37,7 +37,7 @@ export default class Sidebar {
|
|||||||
? document.querySelector(el)
|
? document.querySelector(el)
|
||||||
: el
|
: el
|
||||||
|
|
||||||
/* Index inner and outer container */
|
/* Retrieve inner and outer container */
|
||||||
const inner = this.el_.parentNode
|
const inner = this.el_.parentNode
|
||||||
const outer = this.el_.parentNode.parentNode
|
const outer = this.el_.parentNode.parentNode
|
||||||
|
|
||||||
@ -52,6 +52,13 @@ export default class Sidebar {
|
|||||||
this.height_ = 0
|
this.height_ = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize sidebar state
|
||||||
|
*/
|
||||||
|
setup() {
|
||||||
|
this.update()
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update locked state and height
|
* Update locked state and height
|
||||||
*/
|
*/
|
||||||
@ -71,12 +78,12 @@ export default class Sidebar {
|
|||||||
|
|
||||||
/* Sidebar should be locked, as we're below parent offset */
|
/* Sidebar should be locked, as we're below parent offset */
|
||||||
if (offset < this.offset_) {
|
if (offset < this.offset_) {
|
||||||
if (!this.el_.dataset.mdLocked)
|
if (this.el_.dataset.mdState !== "lock")
|
||||||
this.el_.dataset.mdLocked = ""
|
this.el_.dataset.mdState = "lock"
|
||||||
|
|
||||||
/* Sidebar should be unlocked, if locked */
|
/* Sidebar should be unlocked, if locked */
|
||||||
} else if (typeof this.el_.dataset.mdLocked === "string") {
|
} else if (this.el_.dataset.mdState === "lock") {
|
||||||
delete this.el_.dataset.mdLocked
|
delete this.el_.dataset.mdState
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -84,7 +91,7 @@ export default class Sidebar {
|
|||||||
* Reset locked state and height
|
* Reset locked state and height
|
||||||
*/
|
*/
|
||||||
reset() {
|
reset() {
|
||||||
delete this.el_.dataset.mdLocked
|
delete this.el_.dataset.mdState
|
||||||
this.el_.style.height = ""
|
this.el_.style.height = ""
|
||||||
this.height_ = 0
|
this.height_ = 0
|
||||||
}
|
}
|
||||||
|
@ -20,19 +20,14 @@
|
|||||||
* IN THE SOFTWARE.
|
* IN THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import Adapter from "./Source/Adapter"
|
||||||
|
import Repository from "./Source/Repository"
|
||||||
|
|
||||||
/* ----------------------------------------------------------------------------
|
/* ----------------------------------------------------------------------------
|
||||||
* Definition
|
* Module
|
||||||
* ------------------------------------------------------------------------- */
|
* ------------------------------------------------------------------------- */
|
||||||
|
|
||||||
export default
|
export default {
|
||||||
class Abstract {
|
Adapter,
|
||||||
|
Repository
|
||||||
/**
|
|
||||||
* Dispatch update on next repaint
|
|
||||||
*
|
|
||||||
* @constructor
|
|
||||||
*/
|
|
||||||
// constructor() {
|
|
||||||
//
|
|
||||||
// }
|
|
||||||
}
|
}
|
@ -20,14 +20,12 @@
|
|||||||
* IN THE SOFTWARE.
|
* IN THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import Toggle from "./Listener/Toggle"
|
import GitHub from "./Adapter/GitHub"
|
||||||
import Viewport from "./Listener/Viewport"
|
|
||||||
|
|
||||||
/* ----------------------------------------------------------------------------
|
/* ----------------------------------------------------------------------------
|
||||||
* Module
|
* Module
|
||||||
* ------------------------------------------------------------------------- */
|
* ------------------------------------------------------------------------- */
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
Toggle,
|
GitHub
|
||||||
Viewport
|
|
||||||
}
|
}
|
@ -20,49 +20,71 @@
|
|||||||
* IN THE SOFTWARE.
|
* IN THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import Cookies from "js-cookie"
|
||||||
|
|
||||||
/* ----------------------------------------------------------------------------
|
/* ----------------------------------------------------------------------------
|
||||||
* Definition
|
* Class
|
||||||
* ------------------------------------------------------------------------- */
|
* ------------------------------------------------------------------------- */
|
||||||
|
|
||||||
export default class Abstract {
|
export default class Abstract {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Abstract listener
|
* Retrieve source information
|
||||||
*
|
*
|
||||||
* @constructor
|
* @constructor
|
||||||
* @param {(string|HTMLElement)} el - Selector or HTML element
|
* @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(el, events, handler) {
|
constructor(el) {
|
||||||
if (this === Abstract)
|
|
||||||
throw new Error("Cannot construct abstract instance")
|
|
||||||
|
|
||||||
/* Resolve element */
|
|
||||||
this.el_ = (typeof el === "string")
|
this.el_ = (typeof el === "string")
|
||||||
? document.querySelector(el)
|
? document.querySelector(el)
|
||||||
: el
|
: el
|
||||||
|
|
||||||
/* Set event names and handler */
|
/* Retrieve base URL */
|
||||||
this.events_ = events
|
this.base_ = this.el_.href
|
||||||
this.handler_ = handler
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Register listener for all relevant events
|
* Retrieve data from Cookie or fetch from respective API
|
||||||
|
*
|
||||||
|
* @return {Promise} Promise that returns an array of facts
|
||||||
*/
|
*/
|
||||||
listen() {
|
fetch() {
|
||||||
this.events_.forEach(name => {
|
return new Promise(resolve => {
|
||||||
this.el_.addEventListener(name, this.handler_, false)
|
const cached = Cookies.getJSON(".cache-source")
|
||||||
|
if (typeof cached !== "undefined") {
|
||||||
|
resolve(cached)
|
||||||
|
|
||||||
|
/* If the data is not cached in a cookie, invoke fetch */
|
||||||
|
} else {
|
||||||
|
this.fetch_().then(data => {
|
||||||
|
Cookies.set(".cache-source", data)
|
||||||
|
resolve(data)
|
||||||
|
})
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Unregister listener for all relevant events
|
* Abstract private function that fetches relevant repository information
|
||||||
|
*
|
||||||
|
* @abstract
|
||||||
|
* @return {Promise} Promise that provides the facts in an array
|
||||||
*/
|
*/
|
||||||
unlisten() {
|
fetch_() {
|
||||||
this.events_.forEach(name => {
|
throw new Error("fetch_(): Not implemented")
|
||||||
this.el_.removeEventListener(name, this.handler_, false)
|
}
|
||||||
})
|
|
||||||
|
/**
|
||||||
|
* Format a number with suffix
|
||||||
|
*
|
||||||
|
* @param {Number} number - Number to format
|
||||||
|
* @return {Number} Formatted number
|
||||||
|
*/
|
||||||
|
format_(number) {
|
||||||
|
if (number > 10000)
|
||||||
|
return `${(number / 1000).toFixed(0)}k`
|
||||||
|
else if (number > 1000)
|
||||||
|
return `${(number / 1000).toFixed(1)}k`
|
||||||
|
return number
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -20,21 +20,40 @@
|
|||||||
* IN THE SOFTWARE.
|
* IN THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import Abstract from "../Abstract"
|
import Abstract from "./Abstract"
|
||||||
|
|
||||||
/* ----------------------------------------------------------------------------
|
/* ----------------------------------------------------------------------------
|
||||||
* Definition
|
* Class
|
||||||
* ------------------------------------------------------------------------- */
|
* ------------------------------------------------------------------------- */
|
||||||
|
|
||||||
export default class Offset extends Abstract {
|
export default class GitHub extends Abstract {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Listener which monitors changes to the offset of the viewport
|
* Retrieve source information from GitHub
|
||||||
*
|
*
|
||||||
* @constructor
|
* @constructor
|
||||||
* @param {Function} handler - Event handler to execute
|
* @param {(string|HTMLElement)} el - Selector or HTML element
|
||||||
*/
|
*/
|
||||||
constructor(handler) {
|
constructor(el) {
|
||||||
super(window, ["scroll"], handler)
|
super(el)
|
||||||
|
|
||||||
|
/* Adjust base URL to reach API endpoints */
|
||||||
|
this.base_ = this.base_.replace("github.com/", "api.github.com/repos/")
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetch relevant source information from GitHub
|
||||||
|
*
|
||||||
|
* @return {function} Promise returning an array of facts
|
||||||
|
*/
|
||||||
|
fetch_() {
|
||||||
|
return fetch(this.base_)
|
||||||
|
.then(response => response.json())
|
||||||
|
.then(data => {
|
||||||
|
return [
|
||||||
|
`${this.format_(data.stargazers_count)} Stars`,
|
||||||
|
`${this.format_(data.forks_count)} Forks`
|
||||||
|
]
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -20,22 +20,39 @@
|
|||||||
* IN THE SOFTWARE.
|
* IN THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import Abstract from "./Abstract"
|
import Cookies from "js-cookie"
|
||||||
|
|
||||||
/* ----------------------------------------------------------------------------
|
/* ----------------------------------------------------------------------------
|
||||||
* Definition
|
* Class
|
||||||
* ------------------------------------------------------------------------- */
|
* ------------------------------------------------------------------------- */
|
||||||
|
|
||||||
export default class Toggle extends Abstract {
|
export default class Repository {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Listener which monitors state changes of a toggle
|
* Render repository information
|
||||||
*
|
*
|
||||||
* @constructor
|
* @constructor
|
||||||
* @param {(string|HTMLElement)} el - Selector or HTML element
|
* @param {(string|HTMLElement)} el - Selector or HTML element
|
||||||
* @param {Function} handler - Event handler to execute
|
|
||||||
*/
|
*/
|
||||||
constructor(el, handler) {
|
constructor(el) {
|
||||||
super(el, ["click"], handler)
|
this.el_ = (typeof el === "string")
|
||||||
|
? document.querySelector(el)
|
||||||
|
: el
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize the source repository
|
||||||
|
*
|
||||||
|
* @param {Array.<string>} facts - Facts to be rendered
|
||||||
|
*/
|
||||||
|
initialize(facts) {
|
||||||
|
this.el_.children[0].appendChild(
|
||||||
|
<ul class="md-source__facts">
|
||||||
|
{facts.map(fact => <li class="md-source__fact">{fact}</li>)}
|
||||||
|
</ul>
|
||||||
|
)
|
||||||
|
|
||||||
|
/* Finish rendering with animation */
|
||||||
|
this.el_.dataset.mdState = "done"
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -55,7 +55,10 @@
|
|||||||
@import "extensions/footnotes";
|
@import "extensions/footnotes";
|
||||||
@import "extensions/permalinks";
|
@import "extensions/permalinks";
|
||||||
|
|
||||||
|
@import "extensions/pymdown/arithmatex";
|
||||||
@import "extensions/pymdown/critic";
|
@import "extensions/pymdown/critic";
|
||||||
|
@import "extensions/pymdown/emoji";
|
||||||
|
@import "extensions/pymdown/inlinehilite";
|
||||||
@import "extensions/pymdown/tasklist";
|
@import "extensions/pymdown/tasklist";
|
||||||
|
|
||||||
@import "shame";
|
@import "shame";
|
||||||
|
@ -24,21 +24,16 @@
|
|||||||
// Rules
|
// Rules
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
// Enfore correct box model - the prefixed versions are necessary for older
|
// Enfore correct box model
|
||||||
// browsers, i.e. Chrome < 10, Firefox < 29, Safari < 6 and Android < 4
|
|
||||||
html {
|
html {
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
-moz-box-sizing: border-box;
|
|
||||||
-webkit-box-sizing: border-box;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// All elements shall inherit the document default
|
// All elements shall inherit the document default
|
||||||
*,
|
*,
|
||||||
*::before,
|
*::before,
|
||||||
*::after {
|
*::after {
|
||||||
box-sizing: inherit;
|
box-sizing: inherit;
|
||||||
-moz-box-sizing: inherit;
|
|
||||||
-webkit-box-sizing: inherit;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Prevent adjustments of font size after orientation changes in IE and iOS
|
// Prevent adjustments of font size after orientation changes in IE and iOS
|
||||||
@ -51,19 +46,6 @@ body {
|
|||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add correct display property in IE < 9
|
|
||||||
article,
|
|
||||||
aside,
|
|
||||||
figcaption,
|
|
||||||
figure,
|
|
||||||
footer,
|
|
||||||
header,
|
|
||||||
main,
|
|
||||||
nav,
|
|
||||||
section {
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Reset horizontal rules in FF
|
// Reset horizontal rules in FF
|
||||||
hr {
|
hr {
|
||||||
overflow: visible;
|
overflow: visible;
|
||||||
@ -82,7 +64,7 @@ a {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove gaps in links underline in iOS >= 8 and Safari >= 8
|
// Remove gaps in underlined links in iOS >= 8 and Safari >= 8
|
||||||
a {
|
a {
|
||||||
-webkit-text-decoration-skip: objects;
|
-webkit-text-decoration-skip: objects;
|
||||||
}
|
}
|
||||||
|
@ -226,15 +226,15 @@ kbd {
|
|||||||
&::-webkit-scrollbar {
|
&::-webkit-scrollbar {
|
||||||
width: 0.4rem;
|
width: 0.4rem;
|
||||||
height: 0.4rem;
|
height: 0.4rem;
|
||||||
|
}
|
||||||
|
|
||||||
// Style scrollbar thumb
|
// Style scrollbar thumb
|
||||||
&-thumb {
|
&::-webkit-scrollbar-thumb {
|
||||||
background-color: $md-color-black--lighter;
|
background-color: $md-color-black--lighter;
|
||||||
|
|
||||||
// Hovered scrollbar thumb
|
// Hovered scrollbar thumb
|
||||||
&:hover {
|
&:hover {
|
||||||
background-color: $md-color-accent;
|
background-color: $md-color-accent;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -229,15 +229,15 @@ $codehilite-whitespace: transparent;
|
|||||||
&::-webkit-scrollbar {
|
&::-webkit-scrollbar {
|
||||||
width: 0.4rem;
|
width: 0.4rem;
|
||||||
height: 0.4rem;
|
height: 0.4rem;
|
||||||
|
}
|
||||||
|
|
||||||
// Style scrollbar thumb
|
// Style scrollbar thumb
|
||||||
&-thumb {
|
&::-webkit-scrollbar-thumb {
|
||||||
background-color: $md-color-black--lighter;
|
background-color: $md-color-black--lighter;
|
||||||
|
|
||||||
// Hovered scrollbar thumb
|
// Hovered scrollbar thumb
|
||||||
&:hover {
|
&:hover {
|
||||||
background-color: $md-color-accent;
|
background-color: $md-color-accent;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,7 +63,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Correct anchor offset of headlines
|
// Correct anchor offset of active targets
|
||||||
@each $level, $delta in (
|
@each $level, $delta in (
|
||||||
h1: 3.0rem,
|
h1: 3.0rem,
|
||||||
h2: 0.2rem,
|
h2: 0.2rem,
|
||||||
@ -72,7 +72,7 @@
|
|||||||
h5: 1.0rem,
|
h5: 1.0rem,
|
||||||
h6: 1.0rem
|
h6: 1.0rem
|
||||||
) {
|
) {
|
||||||
#{$level}[id]::before {
|
#{$level}[id]:target::before {
|
||||||
display: block;
|
display: block;
|
||||||
margin-top: -(5.6rem + 2.4rem + $delta);
|
margin-top: -(5.6rem + 2.4rem + $delta);
|
||||||
padding-top: (5.6rem + 2.4rem + $delta);
|
padding-top: (5.6rem + 2.4rem + $delta);
|
||||||
|
51
src/assets/stylesheets/extensions/pymdown/_arithmatex.scss
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
////
|
||||||
|
/// 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
|
||||||
|
////
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// Rules
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Scoped in typesetted content to match specificity of regular content
|
||||||
|
.md-typeset {
|
||||||
|
|
||||||
|
// MathJax integration - add padding to omit vertical scrollbar
|
||||||
|
.MJXc-display {
|
||||||
|
margin: 0.75em 0;
|
||||||
|
padding: 0.25em 0;
|
||||||
|
overflow: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Stretch top-level containers
|
||||||
|
> p > .MJXc-display {
|
||||||
|
|
||||||
|
// [mobile -]: Stretch to whole width
|
||||||
|
@include break-to-device(mobile) {
|
||||||
|
margin: 0.75em -1.6rem;
|
||||||
|
padding: 0.25em 1.6rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove outline on tab index
|
||||||
|
.MathJax_CHTML {
|
||||||
|
outline: 0;
|
||||||
|
}
|
||||||
|
}
|
30
src/assets/stylesheets/extensions/pymdown/_emoji.scss
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
////
|
||||||
|
/// 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
|
||||||
|
////
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// Rules
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Correct alignment of emojis
|
||||||
|
.emoji {
|
||||||
|
vertical-align: text-top;
|
||||||
|
}
|
37
src/assets/stylesheets/extensions/pymdown/_inlinehilite.scss
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
////
|
||||||
|
/// 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
|
||||||
|
////
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// Rules
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Scoped in typesetted content to match specificity of regular content
|
||||||
|
.md-typeset {
|
||||||
|
|
||||||
|
// Qualified class selector to distinguish inline code from code blocks
|
||||||
|
code.codehilite {
|
||||||
|
$correct: 1 / 0.85;
|
||||||
|
|
||||||
|
margin: 0 0.25em * $correct;
|
||||||
|
padding: 0.0625em * $correct 0;
|
||||||
|
}
|
||||||
|
}
|
@ -49,10 +49,10 @@
|
|||||||
@extend %md-icon;
|
@extend %md-icon;
|
||||||
|
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0.15em;
|
top: 0.05em;
|
||||||
left: -1.25em;
|
left: -1.25em;
|
||||||
color: $md-color-black--lighter;
|
color: $md-color-black--lighter;
|
||||||
font-size: 1.25em;
|
font-size: 1.5em;
|
||||||
content: "check_box_outline_blank";
|
content: "check_box_outline_blank";
|
||||||
vertical-align: -0.25em;
|
vertical-align: -0.25em;
|
||||||
}
|
}
|
||||||
|
@ -50,7 +50,7 @@ body {
|
|||||||
@include break-to-device(tablet portrait) {
|
@include break-to-device(tablet portrait) {
|
||||||
|
|
||||||
// Lock body to viewport height (e.g. in search mode)
|
// Lock body to viewport height (e.g. in search mode)
|
||||||
&[data-md-locked] {
|
&[data-md-state="lock"] {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
@ -117,7 +117,7 @@ hr {
|
|||||||
@include break-to-device(tablet) {
|
@include break-to-device(tablet) {
|
||||||
|
|
||||||
// Expanded drawer
|
// Expanded drawer
|
||||||
.md-toggle--drawer:checked ~ & {
|
[data-md-toggle="drawer"]:checked ~ & {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
transition:
|
transition:
|
||||||
|
@ -113,7 +113,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Blurred item
|
// Blurred item
|
||||||
&[data-md-blurred] {
|
&[data-md-state="blur"] {
|
||||||
color: $md-color-black--light;
|
color: $md-color-black--light;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -334,7 +334,7 @@
|
|||||||
|
|
||||||
// Animation is only possible if JavaScript is available, as the max-height
|
// Animation is only possible if JavaScript is available, as the max-height
|
||||||
// property must be calculated before transitioning
|
// property must be calculated before transitioning
|
||||||
&[data-md-animated] {
|
&[data-md-state="animate"] {
|
||||||
transition: max-height 0.25s cubic-bezier(0.86, 0.0, 0.07, 1.0);
|
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
|
// Expand nested navigation, if toggle is checked
|
||||||
.md-nav__toggle:checked ~ &,
|
.md-nav__toggle:checked ~ &,
|
||||||
&[data-md-expanded] {
|
&[data-md-state="expand"] {
|
||||||
max-height: 100%;
|
max-height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,7 +62,7 @@
|
|||||||
z-index: 1;
|
z-index: 1;
|
||||||
|
|
||||||
// Expanded overlay
|
// Expanded overlay
|
||||||
.md-toggle--search:checked ~ .md-header & {
|
[data-md-toggle="search"]:checked ~ .md-header & {
|
||||||
transition:
|
transition:
|
||||||
transform 0.4s,
|
transform 0.4s,
|
||||||
opacity 0.1s;
|
opacity 0.1s;
|
||||||
@ -71,7 +71,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Set scale factors
|
// Set scale factors
|
||||||
.md-toggle--search:checked ~ .md-header & {
|
[data-md-toggle="search"]:checked ~ .md-header & {
|
||||||
|
|
||||||
// [mobile portrait -]: Scale up 45 times
|
// [mobile portrait -]: Scale up 45 times
|
||||||
@include break-to-device(mobile portrait) {
|
@include break-to-device(mobile portrait) {
|
||||||
@ -109,7 +109,7 @@
|
|||||||
z-index: 2;
|
z-index: 2;
|
||||||
|
|
||||||
// Active search modal
|
// Active search modal
|
||||||
.md-toggle--search:checked ~ .md-header & {
|
[data-md-toggle="search"]:checked ~ .md-header & {
|
||||||
left: 0;
|
left: 0;
|
||||||
transform: translateX(0);
|
transform: translateX(0);
|
||||||
transition:
|
transition:
|
||||||
@ -144,7 +144,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Set maximum width
|
// Set maximum width
|
||||||
.md-toggle--search:checked ~ .md-header & {
|
[data-md-toggle="search"]:checked ~ .md-header & {
|
||||||
|
|
||||||
// [tablet landscape]: Do not overlay title
|
// [tablet landscape]: Do not overlay title
|
||||||
@include break-at-device(tablet landscape) {
|
@include break-at-device(tablet landscape) {
|
||||||
@ -204,7 +204,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Set light background on active search field
|
// Set light background on active search field
|
||||||
.md-toggle--search:checked ~ .md-header & {
|
[data-md-toggle="search"]:checked ~ .md-header & {
|
||||||
border-radius: 0.2rem 0.2rem 0 0;
|
border-radius: 0.2rem 0.2rem 0 0;
|
||||||
background: $md-color-white;
|
background: $md-color-white;
|
||||||
color: $md-color-black;
|
color: $md-color-black;
|
||||||
@ -269,7 +269,7 @@
|
|||||||
opacity: 0;
|
opacity: 0;
|
||||||
|
|
||||||
// Show search output in active state
|
// Show search output in active state
|
||||||
.md-toggle--search:checked ~ .md-header & {
|
[data-md-toggle="search"]:checked ~ .md-header & {
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -299,12 +299,22 @@
|
|||||||
box-shadow: 0 0.1rem 0 $md-color-black--lightest inset;
|
box-shadow: 0 0.1rem 0 $md-color-black--lightest inset;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
|
|
||||||
|
// [tablet landscape]: Set absolute width to omit unnecessary reflow
|
||||||
|
@include break-at-device(tablet landscape) {
|
||||||
|
width: 46.8rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
// [screen +]: Set absolute width to omit unnecessary reflow
|
||||||
|
@include break-from-device(screen) {
|
||||||
|
width: 66.8rem;
|
||||||
|
}
|
||||||
|
|
||||||
// [tablet landscape +]: Limit height to viewport
|
// [tablet landscape +]: Limit height to viewport
|
||||||
@include break-from-device(tablet landscape) {
|
@include break-from-device(tablet landscape) {
|
||||||
max-height: 0;
|
max-height: 0;
|
||||||
|
|
||||||
// Expand in active state
|
// Expand in active state
|
||||||
.md-toggle--search:checked ~ .md-header & {
|
[data-md-toggle="search"]:checked ~ .md-header & {
|
||||||
max-height: 75vh;
|
max-height: 75vh;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -37,7 +37,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Lock sidebar to container height (account for fixed header)
|
// Lock sidebar to container height (account for fixed header)
|
||||||
&[data-md-locked] {
|
&[data-md-state="lock"] {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
top: 5.6rem;
|
top: 5.6rem;
|
||||||
}
|
}
|
||||||
@ -65,7 +65,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Expanded drawer
|
// Expanded drawer
|
||||||
.md-toggle--drawer:checked ~ .md-container & {
|
[data-md-toggle="drawer"]:checked ~ .md-container & {
|
||||||
@include z-depth(8);
|
@include z-depth(8);
|
||||||
|
|
||||||
transform: translateX(24.2rem);
|
transform: translateX(24.2rem);
|
||||||
@ -93,7 +93,7 @@
|
|||||||
float: right;
|
float: right;
|
||||||
|
|
||||||
// Hack: align right in case of locked sidebar
|
// Hack: align right in case of locked sidebar
|
||||||
&[data-md-locked] {
|
&[data-md-state="lock"] {
|
||||||
margin-left: 100%;
|
margin-left: 100%;
|
||||||
transform: translate(-100%, 0);
|
transform: translate(-100%, 0);
|
||||||
|
|
||||||
|
@ -24,6 +24,40 @@
|
|||||||
// Rules
|
// Rules
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Show source facts
|
||||||
|
@keyframes md-source__facts--done {
|
||||||
|
|
||||||
|
0% {
|
||||||
|
height: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
100% {
|
||||||
|
height: 1.3rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Show source fact
|
||||||
|
@keyframes md-source__fact--done {
|
||||||
|
|
||||||
|
0% {
|
||||||
|
transform: translateY(100%);
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
50% {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
100% {
|
||||||
|
transform: translateY(0%);
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// Rules
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
// Source container
|
// Source container
|
||||||
.md-source {
|
.md-source {
|
||||||
display: block;
|
display: block;
|
||||||
@ -98,25 +132,25 @@
|
|||||||
font-size: 1.1rem;
|
font-size: 1.1rem;
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
opacity: 0.75;
|
opacity: 0.75;
|
||||||
|
overflow: auto;
|
||||||
list-style-type: none;
|
list-style-type: none;
|
||||||
|
|
||||||
|
// Show after the data was loaded
|
||||||
|
[data-md-state="done"] & {
|
||||||
|
animation: md-source__facts--done 0.25s ease-in;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fact
|
// Fact
|
||||||
&__fact {
|
&__fact {
|
||||||
float: left;
|
float: left;
|
||||||
transform: translateY(0%);
|
|
||||||
transition:
|
|
||||||
transform 0.25s cubic-bezier(0.1, 0.7, 0.1, 1.0),
|
|
||||||
opacity 0.25s;
|
|
||||||
opacity: 1;
|
|
||||||
|
|
||||||
// Facts are hidden by default
|
// Show after the data was loaded
|
||||||
&--hidden {
|
[data-md-state="done"] & {
|
||||||
transform: translateY(100%);
|
animation: md-source__fact--done 0.4s ease-out;
|
||||||
opacity: 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Middle dots before fact
|
// Middle dot before fact
|
||||||
&::before {
|
&::before {
|
||||||
margin: 0 0.2rem;
|
margin: 0 0.2rem;
|
||||||
content: "\00B7";
|
content: "\00B7";
|
||||||
|
@ -79,11 +79,13 @@
|
|||||||
<body>
|
<body>
|
||||||
|
|
||||||
<!-- State toggles -->
|
<!-- State toggles -->
|
||||||
<input class="md-toggle md-toggle--drawer" type="checkbox" id="drawer" />
|
<input class="md-toggle" data-md-toggle="drawer"
|
||||||
<input class="md-toggle md-toggle--search" type="checkbox" id="search" />
|
type="checkbox" id="drawer" />
|
||||||
|
<input class="md-toggle" data-md-toggle="search"
|
||||||
|
type="checkbox" id="search" />
|
||||||
|
|
||||||
<!-- Overlay for expanded drawer -->
|
<!-- Overlay for expanded drawer -->
|
||||||
<label class="md-overlay" for="drawer"></label>
|
<label class="md-overlay" data-md-overlay for="drawer"></label>
|
||||||
|
|
||||||
<!-- Application header -->
|
<!-- Application header -->
|
||||||
{% include "partials/header.html" %}
|
{% include "partials/header.html" %}
|
||||||
@ -170,7 +172,17 @@
|
|||||||
{% include "partials/footer.html" %}
|
{% include "partials/footer.html" %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Theme-related and custom javascripts -->
|
<!-- Extension-related JavaScript -->
|
||||||
|
{% for extension in config.markdown_extensions %}
|
||||||
|
|
||||||
|
<!-- MathJax integration -->
|
||||||
|
{% if extension == "pymdownx.arithmatex" %}
|
||||||
|
{% set path = "mathjax/latest/MathJax.js?config=TeX-MML-AM_CHTML" %}
|
||||||
|
<script src="https://cdn.mathjax.org/{{ path }}"></script>
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
<!-- Theme-related and custom JavaScript -->
|
||||||
<script src="{{ base_url }}/assets/javascripts/application.js"></script>
|
<script src="{{ base_url }}/assets/javascripts/application.js"></script>
|
||||||
<script>
|
<script>
|
||||||
|
|
||||||
|
@ -26,11 +26,11 @@
|
|||||||
|
|
||||||
<!-- Active checkbox expands items contained within nested section -->
|
<!-- Active checkbox expands items contained within nested section -->
|
||||||
{% if nav_item.active %}
|
{% if nav_item.active %}
|
||||||
<input class="md-toggle md-nav__toggle" type="checkbox"
|
<input class="md-toggle md-nav__toggle" data-md-toggle="{{ path }}"
|
||||||
id="{{ path }}" checked />
|
type="checkbox" id="{{ path }}" checked />
|
||||||
{% else %}
|
{% else %}
|
||||||
<input class="md-toggle md-nav__toggle" type="checkbox"
|
<input class="md-toggle md-nav__toggle" data-md-toggle="{{ path }}"
|
||||||
id="{{ path }}" />
|
type="checkbox" id="{{ path }}" />
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
<!-- Expand active pages -->
|
<!-- Expand active pages -->
|
||||||
@ -54,12 +54,13 @@
|
|||||||
</nav>
|
</nav>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
<!-- Main navigation item with nested items -->
|
<!-- Current navigation item -->
|
||||||
{% elif nav_item == current_page %}
|
{% elif nav_item == current_page %}
|
||||||
<li class="md-nav__item">
|
<li class="md-nav__item">
|
||||||
|
|
||||||
<!-- Active checkbox expands items contained within nested section -->
|
<!-- Active checkbox expands items contained within nested section -->
|
||||||
<input class="md-toggle md-nav__toggle" type="checkbox" id="toc" />
|
<input class="md-toggle md-nav__toggle" data-md-toggle="toc"
|
||||||
|
type="checkbox" id="toc" />
|
||||||
|
|
||||||
<!-- Expand active pages -->
|
<!-- Expand active pages -->
|
||||||
<label class="md-nav__link md-nav__link--active" for="toc">
|
<label class="md-nav__link md-nav__link--active" for="toc">
|
||||||
|
@ -21,23 +21,18 @@
|
|||||||
-->
|
-->
|
||||||
|
|
||||||
<!-- Search interface -->
|
<!-- Search interface -->
|
||||||
<div class="md-search">
|
<div class="md-search" data-md-search>
|
||||||
<div class="md-search__overlay"></div>
|
<div class="md-search__overlay"></div>
|
||||||
<div class="md-search__inner">
|
<div class="md-search__inner">
|
||||||
<form class="md-search__form">
|
<form class="md-search__form" name="search">
|
||||||
<input type="text" class="md-search__input"
|
<input type="text" class="md-search__input" name="query"
|
||||||
placeholder="Search" autocapitalize="off" autocorrect="off"
|
placeholder="Search" autocapitalize="off" autocorrect="off"
|
||||||
autocomplete="off" spellcheck="false" id="query" />
|
autocomplete="off" spellcheck="false" />
|
||||||
<label class="md-icon md-search__icon" for="search"></label>
|
<label class="md-icon md-search__icon" for="search"></label>
|
||||||
</form>
|
</form>
|
||||||
<div class="md-search__output">
|
<div class="md-search__output">
|
||||||
<div class="md-search__scrollwrap">
|
<div class="md-search__scrollwrap">
|
||||||
<div class="md-search-result">
|
<div class="md-search-result" data-md-search-result></div>
|
||||||
<div class="md-search-result__meta">
|
|
||||||
Indexing
|
|
||||||
</div>
|
|
||||||
<ol class="md-search-result__list"></ol>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -26,24 +26,23 @@
|
|||||||
-->
|
-->
|
||||||
{% set platform = config.extra.repo_icon or repo_url %}
|
{% set platform = config.extra.repo_icon or repo_url %}
|
||||||
{% if "github" in platform %}
|
{% if "github" in platform %}
|
||||||
{% set repo_icon = "md-source--github" %}
|
{% set repo_type = "github" %}
|
||||||
|
{% set repo_icon = "md-source--github" %} <!-- TODO: remove this in favor of type -->
|
||||||
{% elif "gitlab" in platform %}
|
{% elif "gitlab" in platform %}
|
||||||
|
{% set repo_type = "gitlab" %}
|
||||||
{% set repo_icon = "md-source--gitlab" %}
|
{% set repo_icon = "md-source--gitlab" %}
|
||||||
{% elif "bitbucket" in platform %}
|
{% elif "bitbucket" in platform %}
|
||||||
|
{% set repo_type = "bitbucket" %}
|
||||||
{% set repo_icon = "md-source--bitbucket" %}
|
{% set repo_icon = "md-source--bitbucket" %}
|
||||||
{% else %}
|
{% else %}
|
||||||
|
{% set repo_type = "" %}
|
||||||
{% set repo_icon = "" %}
|
{% set repo_icon = "" %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
<!-- Repository containing source -->
|
<!-- Repository containing source -->
|
||||||
<a href="{{ repo_url }}" title="Go to repository"
|
<a href="{{ repo_url }}" title="Go to repository"
|
||||||
class="md-source {{ repo_icon }}">
|
class="md-source {{ repo_icon }}" data-md-source="{{ repo_type }}"> <!-- use <> for custom / private repo -->
|
||||||
<div class="md-source__repository">
|
<div class="md-source__repository">
|
||||||
{{ repo_name }}
|
{{ repo_name }}
|
||||||
<ul class="md-source__facts">
|
|
||||||
{% if config.extra.version %}
|
|
||||||
<li class="md-source__fact">v{{ config.extra.version }}</li>
|
|
||||||
{% endif %}
|
|
||||||
</ul>
|
|
||||||
</div>
|
</div>
|
||||||
</a>
|
</a>
|
||||||
|