Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8f5aa8ad5f | ||
|
|
4927e57c88 | ||
|
|
9b471c682f | ||
|
|
18262ce8d2 | ||
|
|
769727e886 | ||
|
|
99bc558d5c | ||
|
|
b33a92e37b | ||
|
|
eadce61e75 | ||
|
|
13ab32f631 | ||
|
|
e483055e17 | ||
|
|
c890255c39 | ||
|
|
5e5b680fa0 | ||
|
|
0975c7d1be | ||
|
|
31836391e1 | ||
|
|
c9a7019333 | ||
|
|
b6b5904a7a | ||
|
|
80fe7e010d | ||
|
|
7c36b5c4ef | ||
|
|
099799cdf5 | ||
|
|
854663ff03 | ||
|
|
885053bfbd | ||
|
|
0cfee35151 | ||
|
|
89c68b03f0 | ||
|
|
ee198dd6d2 | ||
|
|
401b512dda | ||
|
|
4fc2a6c02e | ||
|
|
7199f7ad6c | ||
|
|
8792079cb3 | ||
|
|
26d2ae36e3 | ||
|
|
2b0b90c5e9 | ||
|
|
c8ffa5203a | ||
|
|
f1ee7add1c | ||
|
|
78d7cdaf0b | ||
|
|
9028461c72 | ||
|
|
d75aec1b7e | ||
|
|
0beec63367 | ||
|
|
57871449ea | ||
|
|
038288d489 | ||
|
|
3e2fa37250 | ||
|
|
7e601d485a | ||
|
|
0bff78cd1b | ||
|
|
1fc01efe8b | ||
|
|
641b4ca13d | ||
|
|
cbb8567c76 | ||
|
|
70154b6047 | ||
|
|
d78e4e6a0b | ||
|
|
52a3761d65 | ||
|
|
07329f4304 | ||
|
|
f40585f528 | ||
|
|
9e3403ee4f | ||
|
|
76a383fb1b | ||
|
|
d4c796c73e | ||
|
|
64bd1d141a | ||
|
|
551138e7c1 | ||
|
|
7d94975960 | ||
|
|
8a7d9001fd | ||
|
|
55cae2d1f1 | ||
|
|
4fe26f24db | ||
|
|
87c440c003 | ||
|
|
ef7b07a90e | ||
|
|
17808d964d | ||
|
|
7d46ed2a85 | ||
|
|
3783eceb09 | ||
|
|
8f46cc6f09 | ||
|
|
0eb24a04ae | ||
|
|
4997d1f63c | ||
|
|
cae45a60b3 | ||
|
|
758ae36c92 | ||
|
|
c3231f1a9e | ||
|
|
b04c3d1354 | ||
|
|
b09e334f3f | ||
|
|
f71359ce65 | ||
|
|
80be8bb1ec | ||
|
|
38f0099fc8 | ||
|
|
4186b7b7f8 | ||
|
|
bb9e1eb3df | ||
|
|
32ffc58d12 | ||
|
|
2e228af92d | ||
|
|
28d024af2f | ||
|
|
21f2617c9c | ||
|
|
203087bcb1 | ||
|
|
680725ed3a | ||
|
|
1e61603b4e | ||
|
|
f51f3c453d | ||
|
|
61533af0ef | ||
|
|
62ff9d0ac0 | ||
|
|
460164b560 | ||
|
|
9d24e6880b | ||
|
|
ceea88e066 | ||
|
|
ed1ae7226a | ||
|
|
f81a0c578a | ||
|
|
96168d05d8 | ||
|
|
c691fff501 | ||
|
|
c101debc8c | ||
|
|
65d725f260 | ||
|
|
040d3a303c | ||
|
|
823b24aa9c | ||
|
|
e3ac58a7c6 | ||
|
|
e0855d4002 | ||
|
|
b54813ffd8 | ||
|
|
5593f99c14 | ||
|
|
a463798593 | ||
|
|
c55cf5cba9 | ||
|
|
5257fe67a6 | ||
|
|
180da60770 | ||
|
|
7fd5811bf1 | ||
|
|
eea4ebdaf4 | ||
|
|
7b653fac4e | ||
|
|
7178bb4180 | ||
|
|
87bc1c8ef9 | ||
|
|
99b057a9ae | ||
|
|
9633f69b74 | ||
|
|
7661631e3e | ||
|
|
2ba776bb0e | ||
|
|
e37f517240 | ||
|
|
c0fe88004a | ||
|
|
6f324afb37 | ||
|
|
cf17f3b71e | ||
|
|
9ecc9aa8c9 | ||
|
|
e68f54c79f | ||
|
|
4086c2c973 |
@@ -2,9 +2,6 @@
|
||||
"presets": ["es2015"],
|
||||
"plugins": [
|
||||
"add-module-exports",
|
||||
"babel-root-import",
|
||||
["transform-react-jsx", {
|
||||
"pragma": "JSX.createElement"
|
||||
}]
|
||||
"babel-root-import"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -18,7 +18,11 @@
|
||||
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
# IN THE SOFTWARE.
|
||||
|
||||
# Build files
|
||||
# Files generated by build
|
||||
/build
|
||||
/material
|
||||
/site
|
||||
|
||||
# Files generated by visual tests
|
||||
/gemini-report
|
||||
/tests/visual/data
|
||||
|
||||
@@ -25,6 +25,6 @@ CHANGED="$(git diff-tree -r --name-only --no-commit-id ORIG_HEAD HEAD)"
|
||||
|
||||
# Perform install and prune of NPM dependencies if package.json changed
|
||||
if $(echo "$CHANGED" | grep --quiet package.json); then
|
||||
echo "Hook[post-merge]: Updating dependencies..."
|
||||
echo "Hook[post-merge]: Updating dependencies"
|
||||
npm install && npm prune
|
||||
fi
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Copyright (c) 2016-2017 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.
|
||||
|
||||
# Determine current branch
|
||||
BRANCH=$(git rev-parse --abbrev-ref HEAD)
|
||||
echo "Hook[pre-commit]: Checking branch"
|
||||
|
||||
# If we're on master, abort commit
|
||||
if [[ "$BRANCH" == "master" ]]; then
|
||||
echo "Commits on master are only allowed via Pull Requests. Aborting."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# We're good
|
||||
exit 0
|
||||
@@ -46,6 +46,6 @@ FILES=$(git diff --cached --name-only --diff-filter=ACMR | \
|
||||
|
||||
# Run the check and print indicator
|
||||
if [ "$FILES" ]; then
|
||||
echo "Hook[pre-commit]: Running linter..."
|
||||
echo "Hook[pre-commit]: Running linter"
|
||||
npm run lint --silent || exit 1
|
||||
fi
|
||||
|
||||
@@ -18,11 +18,17 @@
|
||||
|
||||
### Package versions
|
||||
|
||||
- Python: `python --version`
|
||||
- MkDocs: `mkdocs --version`
|
||||
- Material: `pip show mkdocs-material | grep -E ^Version`
|
||||
* Python: `python --version`
|
||||
* MkDocs: `mkdocs --version`
|
||||
* Material: `pip show mkdocs-material | grep -E ^Version`
|
||||
|
||||
### Project configuration
|
||||
|
||||
``` yaml
|
||||
The contents of your mkdocs.yml
|
||||
```
|
||||
|
||||
### System information
|
||||
|
||||
- OS: [The operating system you're running]
|
||||
- Browser: [The browser used, if relevant]
|
||||
* OS: [The operating system you're running]
|
||||
* Browser: [The browser used, if relevant]
|
||||
|
||||
@@ -23,14 +23,19 @@
|
||||
|
||||
# NPM-related
|
||||
/node_modules
|
||||
/npm-debug.log
|
||||
/npm-debug.log*
|
||||
|
||||
# Build files
|
||||
# Files generated by build
|
||||
/build
|
||||
/manifest.json
|
||||
/MANIFEST
|
||||
/site
|
||||
|
||||
# Files generated by visual tests
|
||||
/gemini-report
|
||||
/tests/visual/baseline/local
|
||||
/tests/visual/data
|
||||
|
||||
# Distribution files
|
||||
/dist
|
||||
/mkdocs_material.egg-info
|
||||
|
||||
@@ -180,7 +180,6 @@
|
||||
"z-index"
|
||||
],
|
||||
"property-no-vendor-prefix": true,
|
||||
"root-no-standard-properties": true,
|
||||
"selector-class-pattern": "^[a-z0-9]+(-[a-z0-9]+)*(__[a-z]+)?(--[a-z]+)?$",
|
||||
"selector-descendant-combinator-no-non-space": null,
|
||||
"string-quotes": "double",
|
||||
|
||||
@@ -23,19 +23,48 @@ sudo: false
|
||||
|
||||
# Node.js versions
|
||||
node_js:
|
||||
- 4
|
||||
- 5
|
||||
- 6
|
||||
- 7
|
||||
|
||||
# Build visual tests separately - temporary disabled until tests are stable
|
||||
# matrix:
|
||||
# include:
|
||||
# - node_js: 5
|
||||
# addons:
|
||||
# artifacts:
|
||||
# paths:
|
||||
# - gemini-report
|
||||
# apt:
|
||||
# sources:
|
||||
# - ubuntu-toolchain-r-test
|
||||
# packages:
|
||||
# - gcc-4.8
|
||||
# - g++-4.8
|
||||
# env:
|
||||
# - CXX=g++-4.8
|
||||
# install: yarn install
|
||||
# script: yarn run test:visual:run
|
||||
|
||||
# Limit clone depth to 5, to speed up build
|
||||
git:
|
||||
depth: 5
|
||||
|
||||
# Cache dependencies
|
||||
cache:
|
||||
pip: true
|
||||
yarn: true
|
||||
directories:
|
||||
- node_modules
|
||||
|
||||
# Install yarn as Travis doesn't support it out of the box
|
||||
before_install: npm install -g yarn
|
||||
|
||||
# Do not install optional dependencies by default
|
||||
install: yarn install --ignore-optional
|
||||
|
||||
# Install dependencies
|
||||
before_script:
|
||||
- pip install --user -r requirements.txt
|
||||
before_script: pip install --user -r requirements.txt
|
||||
|
||||
# Perform build and tests
|
||||
script: npm run build
|
||||
script: yarn run build
|
||||
|
||||
@@ -1,3 +1,27 @@
|
||||
mkdocs-material-1.0.4 (2017-02-16)
|
||||
|
||||
* Fixed #142: Documentation build errors if h1 is defined as raw HTML
|
||||
* Fixed #164: PyPI release does not build and install
|
||||
* Fixed offsets of targeted headlines
|
||||
* Increased sidebar font size by 0.12rem
|
||||
|
||||
mkdocs-material-1.0.3 (2017-01-22)
|
||||
|
||||
* Fixed #117: Table of contents items don't blur on fast scrolling
|
||||
* Refactored sidebar positioning logic
|
||||
* Further reduction of repaints
|
||||
|
||||
mkdocs-material-1.0.2 (2017-01-15)
|
||||
|
||||
* Fixed #108: Horizontal scrollbar in content area
|
||||
|
||||
mkdocs-material-1.0.1 (2017-01-14)
|
||||
|
||||
* Fixed massive repaints happening when scrolling
|
||||
* Fixed footer back reference positions in case of overflow
|
||||
* Fixed header logo from showing when the menu icon is rendered
|
||||
* Changed scrollbar behavior to only show when content overflows
|
||||
|
||||
mkdocs-material-1.0.0 (2017-01-13)
|
||||
|
||||
* Introduced Webpack for more sophisticated JavaScript bundling
|
||||
|
||||
@@ -19,9 +19,10 @@
|
||||
# IN THE SOFTWARE.
|
||||
|
||||
FROM jfloff/alpine-python:2.7-slim
|
||||
MAINTAINER Martin Donath <martin.donath@squidfunk.com>
|
||||
|
||||
# Set work directory
|
||||
WORKDIR /usr/src
|
||||
# Set working directory
|
||||
WORKDIR /docs
|
||||
|
||||
# Install packages
|
||||
COPY requirements.txt .
|
||||
|
||||
@@ -35,14 +35,17 @@ const config = {
|
||||
src: "src/assets", /* Source directory for assets */
|
||||
build: "material/assets" /* Target directory for assets */
|
||||
},
|
||||
lib: "lib", /* Libraries */
|
||||
lib: "lib", /* Libraries and tasks */
|
||||
tests: {
|
||||
visual: "tests/visual" /* Base directory for visual tests */
|
||||
},
|
||||
views: {
|
||||
src: "src", /* Source directory for views */
|
||||
build: "material" /* Target directory for views */
|
||||
}
|
||||
}
|
||||
|
||||
const args = yargs
|
||||
let args = yargs
|
||||
.default("clean", false) /* Clean before build */
|
||||
.default("karma", true) /* Karma watchdog */
|
||||
.default("lint", true) /* Lint sources */
|
||||
@@ -52,6 +55,12 @@ const args = yargs
|
||||
.default("sourcemaps", false) /* Create sourcemaps */
|
||||
.argv
|
||||
|
||||
/* Only use the last value seen, so overrides are possible */
|
||||
args = Object.keys(args).reduce((result, arg) => {
|
||||
result[arg] = [].concat(args[arg]).pop()
|
||||
return result
|
||||
}, {})
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
* Overrides and helpers
|
||||
* ------------------------------------------------------------------------- */
|
||||
@@ -92,7 +101,10 @@ gulp.src = (...glob) => {
|
||||
* Helper function to load a task
|
||||
*/
|
||||
const load = task => {
|
||||
return require(`./${config.lib}/tasks/${task}`)(gulp, config, args)
|
||||
return done => {
|
||||
return require(`./${config.lib}/tasks/${task}`)
|
||||
.call(gulp, gulp, config, args)(done)
|
||||
}
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
@@ -228,12 +240,11 @@ gulp.task("assets:clean", [
|
||||
* Minify views
|
||||
*/
|
||||
gulp.task("views:build", (args.revision ? [
|
||||
"assets:images:build",
|
||||
"assets:stylesheets:build",
|
||||
"assets:javascripts:build"
|
||||
"assets:build"
|
||||
] : []).concat(args.clean ? [
|
||||
"views:clean"
|
||||
] : []), load("views/build"))
|
||||
] : []),
|
||||
load("views/build"))
|
||||
|
||||
/*
|
||||
* Clean views
|
||||
@@ -267,14 +278,45 @@ gulp.task("mkdocs:serve",
|
||||
load("mkdocs/serve"))
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
* Tests
|
||||
* Visual tests
|
||||
* ------------------------------------------------------------------------- */
|
||||
|
||||
/*
|
||||
* Start karma test runner
|
||||
* Generate visual tests
|
||||
*/
|
||||
gulp.task("tests:unit:watch",
|
||||
load("tests/unit/watch"))
|
||||
gulp.task("tests:visual:generate", [
|
||||
].concat(args.clean ? [
|
||||
"tests:visual:clean",
|
||||
"assets:build",
|
||||
"views:build"
|
||||
] : []),
|
||||
load("tests/visual/generate"))
|
||||
|
||||
/*
|
||||
* Run visual tests
|
||||
*/
|
||||
gulp.task("tests:visual:run", [
|
||||
"tests:visual:generate"
|
||||
], load("tests/visual/run"))
|
||||
|
||||
/*
|
||||
* Update reference images for visual tests
|
||||
*/
|
||||
gulp.task("tests:visual:update",
|
||||
load("tests/visual/update"))
|
||||
|
||||
/*
|
||||
* Clean files generated by visual tests
|
||||
*/
|
||||
gulp.task("tests:visual:clean",
|
||||
load("tests/visual/clean"))
|
||||
|
||||
/*
|
||||
* Open a SauceConnect session for manual testing
|
||||
*/
|
||||
gulp.task("tests:visual:session", [
|
||||
"tests:visual:generate"
|
||||
], load("tests/visual/session"))
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
* Interface
|
||||
@@ -286,9 +328,9 @@ gulp.task("tests:unit:watch",
|
||||
gulp.task("build", [
|
||||
"assets:build",
|
||||
"views:build"
|
||||
].concat(args.mkdocs
|
||||
? "mkdocs:build"
|
||||
: []))
|
||||
].concat(args.mkdocs ? [
|
||||
"mkdocs:build"
|
||||
] : []))
|
||||
|
||||
/*
|
||||
* Clean assets and documentation
|
||||
|
||||
@@ -3,3 +3,4 @@ recursive-exclude site *
|
||||
recursive-exclude * __pycache__
|
||||
recursive-exclude * *.py[co]
|
||||
include LICENSE
|
||||
include package.json
|
||||
|
||||
@@ -1,17 +1,21 @@
|
||||
[![Travis][travis-image]][travis-link]
|
||||
[![Dependencies][deps-image]][deps-link]
|
||||
[![Codacy][codacy-image]][codacy-link]
|
||||
[![Docker][docker-image]][docker-link]
|
||||
[![PyPI][pypi-image]][pypi-link]
|
||||
|
||||
[travis-image]: https://travis-ci.org/squidfunk/mkdocs-material.svg
|
||||
[travis-image]: https://travis-ci.org/squidfunk/mkdocs-material.svg?branch=master
|
||||
[travis-link]: https://travis-ci.org/squidfunk/mkdocs-material
|
||||
[deps-image]: https://david-dm.org/squidfunk/mkdocs-material/dev-status.svg
|
||||
[deps-link]: https://david-dm.org/squidfunk/mkdocs-material?type=dev
|
||||
[codacy-image]: https://api.codacy.com/project/badge/Grade/fe07aa1fa91d453cb69711d3885c5d7e
|
||||
[codacy-link]: https://www.codacy.com/app/squidfunk/mkdocs-material?utm_source=github.com&utm_medium=referral&utm_content=squidfunk/mkdocs-material&utm_campaign=Badge_Grade
|
||||
[docker-image]: https://img.shields.io/docker/pulls/squidfunk/mkdocs-material.svg
|
||||
[docker-link]: https://hub.docker.com/r/squidfunk/mkdocs-material/
|
||||
[pypi-image]: https://img.shields.io/pypi/v/mkdocs-material.svg
|
||||
[pypi-link]: https://pypi.python.org/pypi/mkdocs-material
|
||||
|
||||
|
||||
# Material for MkDocs
|
||||
|
||||
A Material Design theme for [MkDocs](http://www.mkdocs.org).
|
||||
|
||||
@@ -196,7 +196,7 @@ The Material theme uses a sophisticated asset pipeline using [Gulp][9] and
|
||||
Webpack which can be started with the following command:
|
||||
|
||||
``` sh
|
||||
npm run start
|
||||
npm start
|
||||
```
|
||||
|
||||
This will also start the MkDocs development server which will monitor changes
|
||||
|
||||
@@ -2,6 +2,12 @@
|
||||
|
||||
## Installation
|
||||
|
||||
!!! tip "Set up Material using Docker"
|
||||
|
||||
The official [Docker image][1] for Material comes with all dependencies
|
||||
pre-installed and ready-to-use with the latest version published on PyPI,
|
||||
packaged in a very small image (27MB compressed).
|
||||
|
||||
### Installing MkDocs
|
||||
|
||||
Before installing [MkDocs][2], you need to make sure you have Python and `pip`
|
||||
@@ -22,7 +28,7 @@ pip install mkdocs && mkdocs --version
|
||||
# mkdocs, version 0.16.0
|
||||
```
|
||||
|
||||
!!! warning "MkDocs for Material requirements"
|
||||
!!! warning "MkDocs version requirements"
|
||||
|
||||
Material requires MkDocs >= 0.16.
|
||||
|
||||
@@ -41,7 +47,7 @@ pip install pymdown-extensions
|
||||
|
||||
### Installing Material
|
||||
|
||||
#### by using pip
|
||||
#### using pip
|
||||
|
||||
Material can be installed with `pip`:
|
||||
|
||||
@@ -63,7 +69,23 @@ pip install mkdocs-material
|
||||
to a self-contained solution by installing Python with Homebrew. This
|
||||
should eliminate a lot of problems you may be having with `pip`.
|
||||
|
||||
#### by cloning from GitHub
|
||||
#### using choco
|
||||
|
||||
If you're on Windows you can use [Chocolatey][5] to install [Material][6]:
|
||||
|
||||
``` dos
|
||||
choco install mkdocs-material
|
||||
```
|
||||
|
||||
This will also install all required dependencies like [Python][7] and
|
||||
[MkDocs][8].
|
||||
|
||||
[5]: https://chocolatey.org
|
||||
[6]: https://chocolatey.org/packages/mkdocs-material
|
||||
[7]: https://chocolatey.org/packages/python
|
||||
[8]: https://chocolatey.org/packages/mkdocs
|
||||
|
||||
#### cloning from GitHub
|
||||
|
||||
Material can also be used without a system-wide installation by cloning the
|
||||
repository into a subfolder of your project's root directory:
|
||||
@@ -98,11 +120,11 @@ The development server can be started with the following command:
|
||||
mkdocs serve
|
||||
```
|
||||
|
||||
Now you can point your browser to [localhost:8000][5] and the Material theme
|
||||
Now you can point your browser to [localhost:8000][9] and the Material theme
|
||||
should be visible. From here on, you can start writing your documentation, or
|
||||
read on and customize the theme through some options.
|
||||
|
||||
[5]: http://localhost:8000
|
||||
[9]: http://localhost:8000
|
||||
|
||||
## Options
|
||||
|
||||
@@ -112,7 +134,7 @@ project's `mkdocs.yml`. See the following section for all available options.
|
||||
### Changing the color palette
|
||||
|
||||
Material defines a default hue for every primary and accent color on Google's
|
||||
Material Design [color palette][6]. This makes it very easy to change the
|
||||
Material Design [color palette][10]. This makes it very easy to change the
|
||||
overall look of the theme. Just set the primary and accent colors using the
|
||||
following variables in your `mkdocs.yml`:
|
||||
|
||||
@@ -132,10 +154,10 @@ The last three colors can only be used as a primary color.
|
||||
If the color is set via this configuration, an additional CSS file that
|
||||
defines the color palette is included. If you want to keep things lean, clone
|
||||
the repository and recompile the theme with your custom colors set. See the
|
||||
guide on [customization][7] for more information.
|
||||
guide on [customization][11] for more information.
|
||||
|
||||
[6]: http://www.materialui.co/colors
|
||||
[7]: customization.md
|
||||
[10]: http://www.materialui.co/colors
|
||||
[11]: customization.md
|
||||
|
||||
#### Primary colors
|
||||
|
||||
@@ -202,10 +224,10 @@ Click on a tile to change the accent color of the theme:
|
||||
|
||||
### Changing the font family
|
||||
|
||||
Material uses the [Roboto font family][8] by default, specifically the regular
|
||||
Material uses the [Roboto font family][12] by default, specifically the regular
|
||||
sans-serif type for text and the `monospaced` type for code. Both fonts are
|
||||
loaded from [Google Fonts][9] and can easily be changed to other fonts, like
|
||||
for example the [Ubuntu font family][10]:
|
||||
loaded from [Google Fonts][13] and can easily be changed to other fonts, like
|
||||
for example the [Ubuntu font family][14]:
|
||||
|
||||
``` yaml
|
||||
extra:
|
||||
@@ -223,9 +245,9 @@ extra:
|
||||
font: 'none'
|
||||
```
|
||||
|
||||
[8]: https://fonts.google.com/specimen/Roboto
|
||||
[9]: https://fonts.google.com/
|
||||
[10]: https://fonts.google.com/specimen/Ubuntu
|
||||
[12]: https://fonts.google.com/specimen/Roboto
|
||||
[13]: https://fonts.google.com/
|
||||
[14]: https://fonts.google.com/specimen/Ubuntu
|
||||
|
||||
### Adding a logo
|
||||
|
||||
@@ -244,7 +266,7 @@ extra:
|
||||
|
||||
If you want to link your social accounts, the Material theme provides an easy
|
||||
way for doing this in the footer of the documentation using the automatically
|
||||
included [FontAwesome][11] webfont. The syntax is simple – the `type` must
|
||||
included [FontAwesome][15] webfont. The syntax is simple – the `type` must
|
||||
denote the name of the social service, e.g. `github`, `twitter` or `linkedin`
|
||||
and the `link` must contain the URL you want to link to:
|
||||
|
||||
@@ -263,7 +285,7 @@ The links are generated in order and the `type` of the links must match the
|
||||
name of the FontAwesome glyph. The `fa` is automatically added, so `github`
|
||||
will result in `fa fa-github`.
|
||||
|
||||
[11]: http://fontawesome.io/icons/
|
||||
[15]: http://fontawesome.io/icons/
|
||||
|
||||
### Google Analytics integration
|
||||
|
||||
@@ -296,7 +318,7 @@ translations inside the macro `t`:
|
||||
```
|
||||
|
||||
Just copy the file from the original theme and make your adjustments. See the
|
||||
section on [overriding partials][12] in the customization guide.
|
||||
section on [overriding partials][16] in the customization guide.
|
||||
|
||||
!!! warning "Migrating from Material 0.2.x"
|
||||
|
||||
@@ -304,18 +326,18 @@ section on [overriding partials][12] in the customization guide.
|
||||
`mkdocs.yml`. With 1.0.0 this is no longer possible as the configuration
|
||||
will be ignored.
|
||||
|
||||
[12]: customization.md#overriding-partials
|
||||
[16]: customization.md#overriding-partials
|
||||
|
||||
### More advanced customization
|
||||
|
||||
If you want to change the general appearance of the Material theme, see
|
||||
[this article][13] for more information on advanced customization.
|
||||
[this article][17] for more information on advanced customization.
|
||||
|
||||
[13]: customization.md
|
||||
[17]: customization.md
|
||||
|
||||
## Extensions
|
||||
|
||||
MkDocs supports several [Markdown extensions][14]. The following extensions
|
||||
MkDocs supports several [Markdown extensions][18]. The following extensions
|
||||
are not enabled by default (see the link for which are enabled by default)
|
||||
but highly recommended, so they should be switched on at all times:
|
||||
|
||||
@@ -329,18 +351,18 @@ markdown_extensions:
|
||||
For more information, see the following list of extensions supported by the
|
||||
Material theme including more information regarding installation and usage:
|
||||
|
||||
* [Admonition][15]
|
||||
* [Codehilite][16]
|
||||
* [Permalinks][17]
|
||||
* [Footnotes][18]
|
||||
* [PyMdown Extensions][19]
|
||||
* [Admonition][19]
|
||||
* [Codehilite][20]
|
||||
* [Permalinks][21]
|
||||
* [Footnotes][22]
|
||||
* [PyMdown Extensions][23]
|
||||
|
||||
[14]: http://www.mkdocs.org/user-guide/writing-your-docs/#markdown-extensions
|
||||
[15]: extensions/admonition.md
|
||||
[16]: extensions/codehilite.md
|
||||
[17]: extensions/permalinks.md
|
||||
[18]: extensions/footnotes.md
|
||||
[19]: extensions/pymdown.md
|
||||
[18]: http://www.mkdocs.org/user-guide/writing-your-docs/#markdown-extensions
|
||||
[19]: extensions/admonition.md
|
||||
[20]: extensions/codehilite.md
|
||||
[21]: extensions/permalinks.md
|
||||
[22]: extensions/footnotes.md
|
||||
[23]: extensions/pymdown.md
|
||||
|
||||
## Full example
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Release Notes
|
||||
# Release notes
|
||||
|
||||
## Upgrading
|
||||
|
||||
@@ -12,12 +12,43 @@ To determine the currently installed version, use the following command:
|
||||
|
||||
``` sh
|
||||
pip show mkdocs-material | grep -E ^Version
|
||||
# Version 1.0.0
|
||||
# Version 1.0.4
|
||||
```
|
||||
|
||||
## Changelog
|
||||
|
||||
### 1.0.0 <small> _ January 13, 2017</small>
|
||||
### 1.0.4 <small> _ February 16, 2017</small>
|
||||
|
||||
* Fixed [#142][142]: Documentation build errors if `h1` is defined as raw HTML
|
||||
* Fixed [#164][164]: PyPI release does not build and install
|
||||
* Fixed offsets of targeted headlines
|
||||
* Increased sidebar font size by `0.12rem`
|
||||
|
||||
[142]: https://github.com/squidfunk/mkdocs-material/issues/142
|
||||
[164]: https://github.com/squidfunk/mkdocs-material/issues/164
|
||||
|
||||
### 1.0.3 <small> _ January 22, 2017</small>
|
||||
|
||||
* Fixed [#117][117]: Table of contents items don't blur on fast scrolling
|
||||
* Refactored sidebar positioning logic
|
||||
* Further reduction of repaints
|
||||
|
||||
[117]: https://github.com/squidfunk/mkdocs-material/issues/117
|
||||
|
||||
### 1.0.2 <small> _ January 15, 2017</small>
|
||||
|
||||
* Fixed [#108][108]: Horizontal scrollbar in content area
|
||||
|
||||
[108]: https://github.com/squidfunk/mkdocs-material/issues/108
|
||||
|
||||
### 1.0.1 <small> _ January 14, 2017</small>
|
||||
|
||||
* Fixed massive repaints happening when scrolling
|
||||
* Fixed footer back reference positions in case of overflow
|
||||
* Fixed header logo from showing when the menu icon is rendered
|
||||
* Changed scrollbar behavior to only show when content overflows
|
||||
|
||||
### 1.0.0 <small> _ January 13, 2017</small>
|
||||
|
||||
* Introduced Webpack for more sophisticated JavaScript bundling
|
||||
* Introduced ESLint and Stylelint for code style checks
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"rules": {
|
||||
"no-invalid-this": 0,
|
||||
"max-params": 0
|
||||
}
|
||||
}
|
||||
@@ -21,7 +21,7 @@
|
||||
*/
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
* Definition
|
||||
* Module
|
||||
* ------------------------------------------------------------------------- */
|
||||
|
||||
export default /* JSX */ {
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2017 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 ecstatic from "ecstatic"
|
||||
import * as http from "http"
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
* Locals
|
||||
* ------------------------------------------------------------------------- */
|
||||
|
||||
/* Static file server */
|
||||
let server = null
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
* Functions
|
||||
* ------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* Start static file server
|
||||
*
|
||||
* @param {string} directory - Directory to serve
|
||||
* @param {number} port - Port to listen on
|
||||
* @param {Function} done - Resolve callback
|
||||
*/
|
||||
export const start = (directory, port, done) => {
|
||||
server = http.createServer(ecstatic({
|
||||
root: directory
|
||||
}))
|
||||
|
||||
/* Listen and register signal handlers */
|
||||
server.listen(port, "127.0.0.1", done)
|
||||
for (const signal of ["SIGTERM", "SIGINT", "exit"])
|
||||
process.on(signal, stop)
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop static file server
|
||||
*
|
||||
* @param {Function} done - Resolve callback
|
||||
*/
|
||||
export const stop = done => {
|
||||
if (server) {
|
||||
server.close(done)
|
||||
server = null
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2017 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 launcher from "sauce-connect-launcher"
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
* Locals
|
||||
* ------------------------------------------------------------------------- */
|
||||
|
||||
/* SauceConnect process */
|
||||
let server = null
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
* Functions
|
||||
* ------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* Open SauceConnect tunnel
|
||||
*
|
||||
* @param {string} id - Unique identifier
|
||||
* @param {string} username - SauceConnect username
|
||||
* @param {string} accesskey - SauceConnect accesskey
|
||||
* @param {Function} done - Resolve callback
|
||||
*/
|
||||
export const start = (id, username, accesskey, done) => {
|
||||
launcher({
|
||||
username,
|
||||
accessKey: accesskey,
|
||||
tunnelIdentifier: id
|
||||
}, (err, proc) => {
|
||||
if (err)
|
||||
throw new Error(err)
|
||||
server = proc
|
||||
done()
|
||||
})
|
||||
|
||||
/* Register signal handlers */
|
||||
for (const signal of ["SIGTERM", "SIGINT", "exit"])
|
||||
process.on(signal, stop)
|
||||
}
|
||||
|
||||
/**
|
||||
* Close SauceConnect tunnel
|
||||
*
|
||||
* @param {Function} done - Resolve callback
|
||||
*/
|
||||
export const stop = done => {
|
||||
if (server) {
|
||||
server.close(done)
|
||||
server = null
|
||||
}
|
||||
}
|
||||
@@ -33,19 +33,33 @@ let server = null
|
||||
* Definition
|
||||
* ------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* Start Selenium
|
||||
*
|
||||
* @param {Function} done - Resolve callback
|
||||
*/
|
||||
export const start = done => {
|
||||
selenium.start({}, (err, proc) => {
|
||||
|
||||
/* Register signal handlers */
|
||||
for (const signal of ["SIGTERM", "SIGINT", "exit"])
|
||||
process.on(signal, stop)
|
||||
if (err) {
|
||||
|
||||
/* Install selenium, if not present */
|
||||
if (/^Missing(.*)chromedriver$/.test(err.message)) {
|
||||
selenium.install(done)
|
||||
|
||||
/* Start selenium again */
|
||||
selenium.start({}, (err_, proc_) => {
|
||||
server = proc_
|
||||
new Promise(resolve => {
|
||||
selenium.install({}, resolve)
|
||||
})
|
||||
|
||||
/* Start selenium again */
|
||||
.then(() => {
|
||||
selenium.start({}, (err_, proc_) => {
|
||||
server = proc_
|
||||
done()
|
||||
})
|
||||
})
|
||||
|
||||
/* Otherwise, throw error */
|
||||
} else {
|
||||
throw err
|
||||
@@ -53,20 +67,21 @@ export const start = done => {
|
||||
}
|
||||
|
||||
/* Remember process handle */
|
||||
server = server || proc
|
||||
server = proc
|
||||
done()
|
||||
})
|
||||
}
|
||||
|
||||
export const stop = () => {
|
||||
if (server)
|
||||
/**
|
||||
* Stop Selenium
|
||||
*
|
||||
* @param {Function} done - Resolve callback
|
||||
*/
|
||||
export const stop = done => {
|
||||
if (server) {
|
||||
if (typeof done === "function")
|
||||
server.on("exit", done)
|
||||
server.kill()
|
||||
server = null
|
||||
}
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
* Signal handler
|
||||
* ------------------------------------------------------------------------- */
|
||||
|
||||
/* Register signal handler for all relevant events */
|
||||
for (const signal of ["SIGTERM", "SIGINT", "exit"])
|
||||
process.on(signal, stop)
|
||||
@@ -1,5 +0,0 @@
|
||||
{
|
||||
"rules": {
|
||||
"no-invalid-this": 0
|
||||
}
|
||||
}
|
||||
@@ -50,12 +50,13 @@ export default (gulp, config, args) => {
|
||||
],
|
||||
output: {
|
||||
filename: "application.js",
|
||||
library: "Application"
|
||||
library: "app",
|
||||
libraryTarget: "window"
|
||||
},
|
||||
module: {
|
||||
|
||||
/* Transpile ES6 to ES5 with Babel */
|
||||
loaders: [
|
||||
rules: [
|
||||
{
|
||||
loader: "babel-loader",
|
||||
test: /\.jsx?$/
|
||||
@@ -65,7 +66,7 @@ export default (gulp, config, args) => {
|
||||
plugins: [
|
||||
|
||||
/* Don't emit assets that include errors */
|
||||
new webpack.NoErrorsPlugin(),
|
||||
new webpack.NoEmitOnErrorsPlugin(),
|
||||
|
||||
/* Provide JSX helper */
|
||||
new webpack.ProvidePlugin({
|
||||
@@ -77,19 +78,30 @@ export default (gulp, config, args) => {
|
||||
args.optimize ? [
|
||||
new webpack.optimize.UglifyJsPlugin({
|
||||
compress: {
|
||||
warnings: false
|
||||
warnings: false,
|
||||
screw_ie8: true, // eslint-disable-line camelcase
|
||||
conditionals: true,
|
||||
unused: true,
|
||||
comparisons: true,
|
||||
sequences: true,
|
||||
dead_code: true, // eslint-disable-line camelcase
|
||||
evaluate: true,
|
||||
if_return: true, // eslint-disable-line camelcase
|
||||
join_vars: true // eslint-disable-line camelcase
|
||||
},
|
||||
output: {
|
||||
comments: false
|
||||
}
|
||||
})
|
||||
] : []),
|
||||
|
||||
/* Module resolver */
|
||||
resolve: {
|
||||
modulesDirectories: [
|
||||
modules: [
|
||||
"src/assets/javascripts",
|
||||
"node_modules"
|
||||
],
|
||||
extensions: [
|
||||
"",
|
||||
".js",
|
||||
".jsx"
|
||||
]
|
||||
@@ -101,8 +113,8 @@ export default (gulp, config, args) => {
|
||||
},
|
||||
|
||||
/* Sourcemap support */
|
||||
devtool: args.sourcemaps ? "source-map" : ""
|
||||
}))
|
||||
devtool: args.sourcemaps ? "inline-source-map" : ""
|
||||
}, webpack))
|
||||
|
||||
/* Revisioning */
|
||||
.pipe(gulpif(args.revision, rev()))
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
import path from "path"
|
||||
import through from "through2"
|
||||
import util from "gulp-util"
|
||||
|
||||
import { CLIEngine } from "eslint"
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
|
||||
@@ -25,6 +25,7 @@ import gulpif from "gulp-if"
|
||||
import mincss from "gulp-cssnano"
|
||||
import mqpacker from "css-mqpacker"
|
||||
import postcss from "gulp-postcss"
|
||||
import pseudoclasses from "postcss-pseudo-classes"
|
||||
import rev from "gulp-rev"
|
||||
import sass from "gulp-sass"
|
||||
import sourcemaps from "gulp-sourcemaps"
|
||||
@@ -54,7 +55,11 @@ export default (gulp, config, args) => {
|
||||
postcss([
|
||||
autoprefixer(),
|
||||
mqpacker
|
||||
]))
|
||||
].concat(!args.optimize ? [
|
||||
pseudoclasses({
|
||||
"restrictTo": ["hover", "focus"]
|
||||
})
|
||||
] : [])))
|
||||
|
||||
/* Minify sources */
|
||||
.pipe(gulpif(args.optimize, mincss()))
|
||||
@@ -63,7 +68,7 @@ export default (gulp, config, args) => {
|
||||
.pipe(gulpif(args.revision, rev()))
|
||||
.pipe(gulpif(args.revision,
|
||||
version({ manifest: gulp.src("manifest.json") })))
|
||||
.pipe(gulpif(args.sourcemaps, sourcemaps.write(".")))
|
||||
.pipe(gulpif(args.sourcemaps, sourcemaps.write()))
|
||||
.pipe(gulp.dest(`${config.assets.build}/stylesheets`))
|
||||
.pipe(gulpif(args.revision,
|
||||
rev.manifest("manifest.json", {
|
||||
|
||||
@@ -39,7 +39,7 @@ export default () => {
|
||||
server.kill()
|
||||
|
||||
/* Spawn MkDocs server */
|
||||
server = child.spawn("mkdocs", ["serve", "-a", "0.0.0.0:8000"], {
|
||||
server = child.spawn("mkdocs", ["serve", "--dev-addr", "0.0.0.0:8000"], {
|
||||
stdio: "inherit"
|
||||
})
|
||||
}
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2017 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 clean from "del"
|
||||
import vinyl from "vinyl-paths"
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
* Task: clean files generated by visual tests
|
||||
* ------------------------------------------------------------------------- */
|
||||
|
||||
export default (gulp, config) => {
|
||||
return () => {
|
||||
return gulp.src([
|
||||
`${config.tests.visual}/data`,
|
||||
"./gemini-report"
|
||||
])
|
||||
.pipe(vinyl(clean))
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2017 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 child from "child_process"
|
||||
import path from "path"
|
||||
import through from "through2"
|
||||
import util from "gulp-util"
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
* Task: generate visual tests
|
||||
* ------------------------------------------------------------------------- */
|
||||
|
||||
export default (gulp, config) => {
|
||||
const theme = path.resolve(process.cwd(), config.views.build)
|
||||
return () => {
|
||||
return gulp.src(`${config.tests.visual}/suites/**/mkdocs.yml`)
|
||||
.pipe(
|
||||
through.obj(function(file, enc, done) {
|
||||
if (file.isNull() || file.isStream())
|
||||
return done()
|
||||
|
||||
/* Resolve test name and destination */
|
||||
const name = path.relative(`${config.tests.visual}/suites`,
|
||||
path.dirname(file.path))
|
||||
const site = path.resolve(process.cwd(),
|
||||
`${config.tests.visual}/data`, name, "_")
|
||||
|
||||
/* Generate test fixtures with freshly built theme */
|
||||
const proc = child.spawnSync("mkdocs", [
|
||||
"build", "--site-dir", site, "--theme-dir", theme
|
||||
], {
|
||||
cwd: path.dirname(file.path)
|
||||
})
|
||||
|
||||
/* Emit error, if any */
|
||||
if (proc.status)
|
||||
this.emit("error", new util.PluginError("mkdocs",
|
||||
`Terminated with errors: ${proc.stderr.toString()}`))
|
||||
|
||||
/* Terminate */
|
||||
done()
|
||||
}))
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,166 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2017 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 moniker from "moniker"
|
||||
import path from "path"
|
||||
import * as ecstatic from "~/lib/servers/ecstatic"
|
||||
import * as sauce from "~/lib/servers/sauce-connect"
|
||||
import * as selenium from "~/lib/servers/selenium"
|
||||
|
||||
import Gemini from "gemini"
|
||||
import SauceLabs from "saucelabs"
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
* Locals
|
||||
* ------------------------------------------------------------------------- */
|
||||
|
||||
/* SauceLabs job name */
|
||||
const id = process.env.TRAVIS
|
||||
? `Travis #${process.env.TRAVIS_BUILD_NUMBER}`
|
||||
: `Local #${moniker.choose()}`
|
||||
|
||||
/* SauceLabs test results */
|
||||
const passed = {}
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
* Task: run visual tests
|
||||
* ------------------------------------------------------------------------- */
|
||||
|
||||
export default (gulp, config, args) => {
|
||||
return done => {
|
||||
|
||||
/* Start static file server */
|
||||
let error = false
|
||||
new Promise(resolve => {
|
||||
ecstatic.start(`${config.tests.visual}/data`, 8000, resolve)
|
||||
|
||||
/* Create and start test runner */
|
||||
}).then(() => {
|
||||
return new Promise((resolve, reject) => {
|
||||
|
||||
/* Start SauceConnect tunnel */
|
||||
if (process.env.CI || process.env.SAUCE) {
|
||||
if (!process.env.SAUCE_USERNAME ||
|
||||
!process.env.SAUCE_ACCESS_KEY)
|
||||
throw new Error(
|
||||
"SauceConnect: please provide SAUCE_USERNAME " +
|
||||
"and SAUCE_ACCESS_KEY")
|
||||
|
||||
/* Start tunnel, if credentials are given */
|
||||
sauce.start(
|
||||
id,
|
||||
process.env.SAUCE_USERNAME,
|
||||
process.env.SAUCE_ACCESS_KEY,
|
||||
err => {
|
||||
return err ? reject(err) : resolve(sauce)
|
||||
})
|
||||
|
||||
/* Start Selenium */
|
||||
} else {
|
||||
selenium.start(() => resolve(selenium))
|
||||
}
|
||||
})
|
||||
|
||||
/* Setup and run Gemini */
|
||||
.then(runner => {
|
||||
const setup = require(
|
||||
path.join(process.cwd(), `${config.tests.visual}/config`,
|
||||
process.env.CI || process.env.SAUCE
|
||||
? "gemini.sauce-connect.json"
|
||||
: "gemini.selenium.json"))
|
||||
|
||||
/* Add dynamic configuration to capabilities */
|
||||
for (const key of Object.keys(setup.browsers)) {
|
||||
const caps = setup.browsers[key].desiredCapabilities
|
||||
caps.tunnelIdentifier = id
|
||||
caps.public = "private"
|
||||
caps.name = id
|
||||
|
||||
/* Adjust configuration for Travis CI */
|
||||
if (process.env.CI && process.env.TRAVIS)
|
||||
caps.public = "public"
|
||||
}
|
||||
|
||||
/* Setup Gemini and test listeners */
|
||||
const gemini = new Gemini(setup)
|
||||
if (process.env.CI || process.env.SAUCE) {
|
||||
|
||||
/* Initialize test run */
|
||||
gemini.on(gemini.events.START_BROWSER, job => {
|
||||
passed[job.sessionId] = true
|
||||
})
|
||||
|
||||
/* Update state of test run */
|
||||
gemini.on(gemini.events.TEST_RESULT, job => {
|
||||
passed[job.sessionId] = passed[job.sessionId] && job.equal
|
||||
})
|
||||
}
|
||||
|
||||
/* Run tests */
|
||||
return gemini.test(`${config.tests.visual}/suites`, {
|
||||
reporters: ["flat", "html"],
|
||||
browsers: args.browsers ? [].concat(args.browsers) : null
|
||||
})
|
||||
|
||||
/* Return runner for graceful stop */
|
||||
.then(status => {
|
||||
error = status.failed + status.errored > 0
|
||||
return runner
|
||||
})
|
||||
})
|
||||
|
||||
/* Stop test runner */
|
||||
.then(runner => {
|
||||
return new Promise(resolve => {
|
||||
runner.stop(resolve)
|
||||
})
|
||||
})
|
||||
|
||||
/* Update SauceLabs jobs with test results */
|
||||
.then(() => {
|
||||
const saucelabs = new SauceLabs({
|
||||
username: process.env.SAUCE_USERNAME,
|
||||
password: process.env.SAUCE_ACCESS_KEY
|
||||
})
|
||||
const updates = Object.keys(passed).map(sessionId => {
|
||||
return new Promise(resolve => {
|
||||
saucelabs.updateJob(sessionId, {
|
||||
passed: passed[sessionId]
|
||||
}, resolve)
|
||||
})
|
||||
})
|
||||
return Promise.all(updates)
|
||||
})
|
||||
|
||||
/* Stop static file server */
|
||||
})
|
||||
.then(() => {
|
||||
ecstatic.stop(() => {
|
||||
return error
|
||||
? done(new Error("Gemini terminated with errors"))
|
||||
: done()
|
||||
})
|
||||
}, err => {
|
||||
return done(new Error(err))
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2017 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 moniker from "moniker"
|
||||
import * as ecstatic from "~/lib/servers/ecstatic"
|
||||
import * as sauce from "~/lib/servers/sauce-connect"
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
* Task: run visual tests
|
||||
* ------------------------------------------------------------------------- */
|
||||
|
||||
export default (gulp, config) => {
|
||||
return done => {
|
||||
|
||||
/* Start static file server */
|
||||
new Promise(resolve => {
|
||||
ecstatic.start(`${config.tests.visual}/data`, 8000, resolve)
|
||||
|
||||
/* Open SauceConnect tunnel */
|
||||
}).then(() => {
|
||||
return new Promise((resolve, reject) => {
|
||||
|
||||
/* Start SauceConnect tunnel */
|
||||
if (process.env.CI || process.env.SAUCE) {
|
||||
if (!process.env.SAUCE_USERNAME ||
|
||||
!process.env.SAUCE_ACCESS_KEY)
|
||||
throw new Error(
|
||||
"SauceConnect: please provide SAUCE_USERNAME " +
|
||||
"and SAUCE_ACCESS_KEY")
|
||||
|
||||
/* Open tunnel */
|
||||
sauce.start(
|
||||
`Local #${moniker.choose()}`,
|
||||
process.env.SAUCE_USERNAME,
|
||||
process.env.SAUCE_ACCESS_KEY,
|
||||
err => {
|
||||
return err ? reject(err) : resolve(sauce)
|
||||
})
|
||||
} else {
|
||||
resolve()
|
||||
}
|
||||
})
|
||||
|
||||
/* Close tunnel on CTRL-C */
|
||||
.then(runner => {
|
||||
return new Promise(resolve => {
|
||||
process.on("SIGINT", () => {
|
||||
return runner
|
||||
? runner.stop(resolve)
|
||||
: resolve()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
/* Stop static file server */
|
||||
})
|
||||
.then(() => {
|
||||
ecstatic.stop(done)
|
||||
}, err => {
|
||||
return done(err)
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2017 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 fs from "fs"
|
||||
import path from "path"
|
||||
import through from "through2"
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
* Task: update reference images for visual tests
|
||||
* ------------------------------------------------------------------------- */
|
||||
|
||||
export default (gulp, config) => {
|
||||
return () => {
|
||||
const base = path.join(
|
||||
process.cwd(), `${config.tests.visual}/config`)
|
||||
|
||||
/* Read Gemini configs and map browsers to screenshot directories */
|
||||
const mapping = fs.readdirSync(base)
|
||||
.reduce((result, filename) => {
|
||||
return Object.assign(result, (gemini => {
|
||||
return Object.keys(gemini.browsers)
|
||||
.reduce((browsers, name) => {
|
||||
browsers[name] = gemini.screenshotsDir
|
||||
return browsers
|
||||
}, {})
|
||||
})(require(path.join(base, filename))))
|
||||
}, {})
|
||||
|
||||
/* Prepare filenames */
|
||||
const dest = path.join(process.cwd(), `${config.tests.visual}/baseline`)
|
||||
return gulp.src("gemini-report/images/**/*~current.png")
|
||||
.pipe(
|
||||
through.obj(function(file, enc, done) {
|
||||
if (file.isNull() || file.isStream())
|
||||
return done()
|
||||
|
||||
/* Remove the state from the filename */
|
||||
file.path = file.path.replace("~current", "")
|
||||
|
||||
/* Retrieve the folder for the environment of the baseline */
|
||||
const folder = path.relative(dest,
|
||||
mapping[path.basename(file.path, ".png")])
|
||||
file.path = file.path.replace("images", `images/${folder}`)
|
||||
|
||||
/* Push file to next stage */
|
||||
this.push(file)
|
||||
done()
|
||||
}))
|
||||
|
||||
/* Update reference images */
|
||||
.pipe(gulp.dest(dest))
|
||||
}
|
||||
}
|
||||
@@ -19,7 +19,7 @@
|
||||
{% else %}
|
||||
<link rel="shortcut icon" href="{{ base_url }}/assets/images/favicon.ico">
|
||||
{% endif %}
|
||||
<meta name="generator" content="mkdocs+mkdocs-material#1.0.0">
|
||||
<meta name="generator" content="mkdocs-{{ mkdocs_version }}, mkdocs-material-1.0.3">
|
||||
{% endblock %}
|
||||
{% block htmltitle %}
|
||||
{% if page.title %}
|
||||
@@ -31,7 +31,13 @@
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
{% block libs %}
|
||||
<script src="{{ base_url }}/assets/javascripts/modernizr-facb31f4a3.js"></script>
|
||||
<script src="{{ base_url }}/assets/javascripts/modernizr-5b0c41c2b5.js"></script>
|
||||
{% endblock %}
|
||||
{% block styles %}
|
||||
<link rel="stylesheet" href="{{ base_url }}/assets/stylesheets/application-166740f5bb.css">
|
||||
{% if config.extra.palette %}
|
||||
<link rel="stylesheet" href="{{ base_url }}/assets/stylesheets/application-02ce7adcc2.palette.css">
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
{% block fonts %}
|
||||
{% if config.extra.font != "none" %}
|
||||
@@ -44,15 +50,9 @@
|
||||
{% endif %}
|
||||
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
|
||||
{% endblock %}
|
||||
{% block styles %}
|
||||
<link rel="stylesheet" href="{{ base_url }}/assets/stylesheets/application-ff220fd69d.css">
|
||||
{% if config.extra.palette %}
|
||||
<link rel="stylesheet" href="{{ base_url }}/assets/stylesheets/application-02ce7adcc2.palette.css">
|
||||
{% endif %}
|
||||
{% for path in extra_css %}
|
||||
<link rel="stylesheet" href="{{ path }}">
|
||||
{% endfor %}
|
||||
{% endblock %}
|
||||
{% for path in extra_css %}
|
||||
<link rel="stylesheet" href="{{ path }}">
|
||||
{% endfor %}
|
||||
{% block extrahead %}{% endblock %}
|
||||
</head>
|
||||
{% set palette = config.extra.get("palette", {}) %}
|
||||
@@ -110,7 +110,7 @@
|
||||
<a href="{{ page.edit_url }}" title="{{ lang.t('edit.link.title') }}" class="md-icon md-content__edit">edit</a>
|
||||
{% endif %}
|
||||
{% block content %}
|
||||
{% if not "\x3ch1 id=" in page.content %}
|
||||
{% if not "\x3ch1" in page.content %}
|
||||
<h1>{{ page.title | default(config.site_name, true)}}</h1>
|
||||
{% endif %}
|
||||
{{ page.content }}
|
||||
@@ -124,8 +124,8 @@
|
||||
{% endblock %}
|
||||
</div>
|
||||
{% block scripts %}
|
||||
<script src="{{ base_url }}/assets/javascripts/application-16f434a21a.js"></script>
|
||||
<script>var config={url:{base:"{{ base_url }}"}},app=new Application(config);app.initialize()</script>
|
||||
<script src="{{ base_url }}/assets/javascripts/application-39a173f6f5.js"></script>
|
||||
<script>app.initialize({url:{base:"{{ base_url }}"}})</script>
|
||||
{% for path in extra_javascript %}
|
||||
<script src="{{ path }}"></script>
|
||||
{% endfor %}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
{% if page.previous_page %}
|
||||
<a href="{{ page.previous_page.url }}" title="{{ page.previous_page.title }}" class="md-flex md-footer-nav__link md-footer-nav__link--prev" rel="prev">
|
||||
<div class="md-flex__cell md-flex__cell--shrink">
|
||||
<i class="md-icon md-icon--arrow-back md-footer-nav__icon"></i>
|
||||
<i class="md-icon md-icon--arrow-back md-footer-nav__button"></i>
|
||||
</div>
|
||||
<div class="md-flex__cell md-flex__cell--stretch md-footer-nav__title">
|
||||
<span class="md-flex__ellipsis">
|
||||
@@ -29,7 +29,7 @@
|
||||
</span>
|
||||
</div>
|
||||
<div class="md-flex__cell md-flex__cell--shrink">
|
||||
<i class="md-icon md-icon--arrow-forward md-footer-nav__icon"></i>
|
||||
<i class="md-icon md-icon--arrow-forward md-footer-nav__button"></i>
|
||||
</div>
|
||||
</a>
|
||||
{% endif %}
|
||||
|
||||
@@ -2,14 +2,14 @@
|
||||
<nav class="md-header-nav md-grid">
|
||||
<div class="md-flex">
|
||||
<div class="md-flex__cell md-flex__cell--shrink">
|
||||
<a href="{{ nav.homepage.url }}" title="{{ config.site_name }}" class="md-icon {% if not config.extra.logo %} md-icon--home {% endif %} md-header-nav__icon">
|
||||
<a href="{{ nav.homepage.url }}" title="{{ config.site_name }}" class="{% if config.extra.logo %} md-logo {% else %} md-icon md-icon--home {% endif %} md-header-nav__button">
|
||||
{% if config.extra.logo %}
|
||||
<img src="{{ base_url }}/{{ config.extra.logo }}" width="24" height="24">
|
||||
{% endif %}
|
||||
</a>
|
||||
</div>
|
||||
<div class="md-flex__cell md-flex__cell--shrink">
|
||||
<label class="md-icon md-icon--menu md-header-nav__icon" for="drawer"></label>
|
||||
<label class="md-icon md-icon--menu md-header-nav__button" for="drawer"></label>
|
||||
</div>
|
||||
<div class="md-flex__cell md-flex__cell--stretch">
|
||||
<span class="md-flex__ellipsis md-header-nav__title">
|
||||
@@ -27,7 +27,7 @@
|
||||
</div>
|
||||
<div class="md-flex__cell md-flex__cell--shrink">
|
||||
{% block search_box %}
|
||||
<label class="md-icon md-icon--search md-header-nav__icon" for="search"></label>
|
||||
<label class="md-icon md-icon--search md-header-nav__button" for="search"></label>
|
||||
{% include "partials/search.html" %}
|
||||
{% endblock %}
|
||||
</div>
|
||||
|
||||
@@ -25,10 +25,10 @@
|
||||
<li class="md-nav__item">
|
||||
{% set toc_ = page.toc %}
|
||||
<input class="md-toggle md-nav__toggle" data-md-toggle="toc" type="checkbox" id="toc">
|
||||
{% if "\x3ch1 id=" in page.content %}
|
||||
{% if toc_ | first is defined %}
|
||||
{% set toc_ = (toc_ | first).children %}
|
||||
{% endif %}
|
||||
{% if toc_ and (toc_ | first) %}
|
||||
{% if toc_ | first is defined %}
|
||||
<label class="md-nav__link md-nav__link--active" for="toc">
|
||||
{{ nav_item.title }}
|
||||
</label>
|
||||
@@ -36,7 +36,7 @@
|
||||
<a href="{{ nav_item.url }}" title="{{ nav_item.title }}" class="md-nav__link md-nav__link--active">
|
||||
{{ nav_item.title }}
|
||||
</a>
|
||||
{% if page.toc %}
|
||||
{% if toc_ | first is defined %}
|
||||
{% include "partials/toc.html" %}
|
||||
{% endif %}
|
||||
</li>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<nav class="md-nav md-nav--primary">
|
||||
<label class="md-nav__title md-nav__title--site" for="drawer">
|
||||
<i class="md-icon {% if not config.extra.logo %} md-icon--home {% endif %} md-nav__icon">
|
||||
<i class="{% if config.extra.logo %} md-logo {% else %} md-icon md-icon--home {% endif %} md-nav__button">
|
||||
{% if config.extra.logo %}
|
||||
<img src="{{ base_url }}/{{ config.extra.logo }}">
|
||||
{% endif %}
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
{% import "partials/language.html" as lang %}
|
||||
<nav class="md-nav md-nav--secondary">
|
||||
{% set toc_ = page.toc %}
|
||||
{% if "\x3ch1 id=" in page.content %}
|
||||
{% if toc_ | first is defined and "\x3ch1 id=" in page.content %}
|
||||
{% set toc_ = (toc_ | first).children %}
|
||||
{% endif %}
|
||||
{% if toc_ and (toc_ | first) %}
|
||||
{% if toc_ | first is defined %}
|
||||
<label class="md-nav__title" for="toc">{{ lang.t('toc.title') }}</label>
|
||||
<ul class="md-nav__list" data-md-scrollfix>
|
||||
{% for toc_item in toc_ %}
|
||||
|
||||
@@ -29,9 +29,9 @@ repo_name: squidfunk/mkdocs-material
|
||||
repo_url: https://github.com/squidfunk/mkdocs-material
|
||||
|
||||
# Copyright
|
||||
copyright: 'Copyright © 2016 Martin Donath'
|
||||
copyright: 'Copyright © 2016 - 2017 Martin Donath'
|
||||
|
||||
# Documentation and theme
|
||||
# Theme directory
|
||||
theme_dir: material
|
||||
|
||||
# Options
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "mkdocs-material",
|
||||
"version": "1.0.0",
|
||||
"version": "1.0.4",
|
||||
"description": "A Material Design theme for MkDocs",
|
||||
"keywords": [
|
||||
"mkdocs",
|
||||
@@ -27,26 +27,28 @@
|
||||
"clean": "scripts/clean",
|
||||
"lint": "scripts/lint",
|
||||
"start": "scripts/start",
|
||||
"test": "scripts/test"
|
||||
"test:visual:run": "scripts/test/visual/run",
|
||||
"test:visual:update": "scripts/test/visual/update",
|
||||
"test:visual:session": "scripts/test/visual/session"
|
||||
},
|
||||
"dependencies": {},
|
||||
"devDependencies": {
|
||||
"autoprefixer": "^6.6.1",
|
||||
"autoprefixer": "^6.7.3",
|
||||
"babel-core": "^6.0.0",
|
||||
"babel-eslint": "^7.1.1",
|
||||
"babel-loader": "^6.2.10",
|
||||
"babel-loader": "^6.3.1",
|
||||
"babel-plugin-add-module-exports": "^0.2.1",
|
||||
"babel-plugin-transform-react-jsx": "^6.8.0",
|
||||
"babel-polyfill": "^6.20.0",
|
||||
"babel-preset-es2015": "^6.18.0",
|
||||
"babel-register": "^6.18.0",
|
||||
"babel-preset-es2015": "^6.22.0",
|
||||
"babel-register": "^6.23.0",
|
||||
"babel-root-import": "^4.1.5",
|
||||
"chai": "^3.5.0",
|
||||
"core-js": "^2.4.1",
|
||||
"css-mqpacker": "^5.0.1",
|
||||
"custom-event-polyfill": "^0.3.0",
|
||||
"del": "^2.2.2",
|
||||
"eslint": "^3.13.1",
|
||||
"eslint-plugin-mocha": "^4.8.0",
|
||||
"ecstatic": "^2.1.0",
|
||||
"eslint": "^3.14.0",
|
||||
"fastclick": "^1.0.6",
|
||||
"git-hooks": "^1.1.7",
|
||||
"gulp": "^3.9.1",
|
||||
@@ -70,6 +72,27 @@
|
||||
"gulp-uglify": "^2.0.0",
|
||||
"gulp-util": "^3.0.8",
|
||||
"js-cookie": "^2.1.3",
|
||||
"lunr": "^0.7.2",
|
||||
"material-design-color": "^2.3.2",
|
||||
"material-shadows": "^3.0.1",
|
||||
"modularscale-sass": "^2.1.1",
|
||||
"node-notifier": "^5.0.0",
|
||||
"postcss-pseudo-classes": "^0.2.0",
|
||||
"stylelint": "^7.8.0",
|
||||
"stylelint-config-standard": "^16.0.0",
|
||||
"stylelint-order": "^0.2.2",
|
||||
"stylelint-scss": "^1.4.1",
|
||||
"through2": "^2.0.3",
|
||||
"vinyl-paths": "^2.1.0",
|
||||
"webpack": "^2.2.1",
|
||||
"webpack-stream": "^3.2.0",
|
||||
"whatwg-fetch": "^2.0.1",
|
||||
"yargs": "^6.6.0"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"chai": "^3.5.0",
|
||||
"eslint-plugin-mocha": "^4.8.0",
|
||||
"gemini": "^4.14.3",
|
||||
"karma": "^1.3.0",
|
||||
"karma-chrome-launcher": "^2.0.0",
|
||||
"karma-coverage": "^1.1.1",
|
||||
@@ -78,26 +101,14 @@
|
||||
"karma-sourcemap-loader": "^0.3.7",
|
||||
"karma-spec-reporter": "0.0.26",
|
||||
"karma-webpack": "^2.0.1",
|
||||
"lunr": "^0.7.2",
|
||||
"material-design-color": "^2.3.2",
|
||||
"material-shadows": "^3.0.1",
|
||||
"mocha": "^3.2.0",
|
||||
"modularscale-sass": "^2.1.1",
|
||||
"node-notifier": "^4.6.1",
|
||||
"selenium-standalone": "^5.9.1",
|
||||
"stylelint": "^7.7.1",
|
||||
"stylelint-config-standard": "^15.0.1",
|
||||
"stylelint-order": "^0.2.2",
|
||||
"stylelint-scss": "^1.4.1",
|
||||
"through2": "^2.0.3",
|
||||
"vinyl-paths": "^2.1.0",
|
||||
"webpack": "^1.14.0",
|
||||
"webpack-stream": "^3.2.0",
|
||||
"whatwg-fetch": "^2.0.1",
|
||||
"yargs": "^6.6.0"
|
||||
"moniker": "^0.1.2",
|
||||
"saucelabs": "^1.4.0",
|
||||
"sauce-connect-launcher": "^1.2.0",
|
||||
"selenium-standalone": "^6.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 4.5.0"
|
||||
"node": ">= 5.0.0"
|
||||
},
|
||||
"private": true
|
||||
}
|
||||
|
||||
@@ -20,4 +20,4 @@
|
||||
|
||||
mkdocs>=0.16
|
||||
pygments
|
||||
pymdown-extensions
|
||||
pymdown-extensions>=1.2
|
||||
|
||||
@@ -28,4 +28,4 @@ if [[ ! -d `npm bin` ]]; then
|
||||
fi
|
||||
|
||||
# Run command
|
||||
`npm bin`/gulp build --clean --optimize --revision
|
||||
`npm bin`/gulp build --clean --optimize --revision "$@"
|
||||
|
||||
@@ -28,4 +28,4 @@ if [[ ! -d `npm bin` ]]; then
|
||||
fi
|
||||
|
||||
# Run command
|
||||
`npm bin`/gulp clean
|
||||
`npm bin`/gulp clean "$@"
|
||||
|
||||
@@ -28,7 +28,7 @@ if [[ ! -d `npm bin` ]]; then
|
||||
fi
|
||||
|
||||
# Run ESLint
|
||||
`npm bin`/eslint .
|
||||
`npm bin`/eslint --max-warnings 0 .
|
||||
ESLINT=$?
|
||||
|
||||
# Run Stylelint
|
||||
|
||||
@@ -28,4 +28,4 @@ if [[ ! -d `npm bin` ]]; then
|
||||
fi
|
||||
|
||||
# Run command
|
||||
`npm bin`/gulp watch --no-lint
|
||||
`npm bin`/gulp watch --no-lint "$@"
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Copyright (c) 2016-2017 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.
|
||||
|
||||
# Check if "npm install" was executed
|
||||
if [[ ! -d `npm bin` ]]; then
|
||||
echo "\"node_modules\" not found:"
|
||||
echo "npm install"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Run command
|
||||
`npm bin`/gulp tests:visual:run --clean --no-optimize "$@"
|
||||
@@ -0,0 +1,31 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Copyright (c) 2016-2017 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.
|
||||
|
||||
# Check if "npm install" was executed
|
||||
if [[ ! -d `npm bin` ]]; then
|
||||
echo "\"node_modules\" not found:"
|
||||
echo "npm install"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Run command
|
||||
`npm bin`/gulp tests:visual:session "$@"
|
||||
@@ -28,4 +28,4 @@ if [[ ! -d `npm bin` ]]; then
|
||||
fi
|
||||
|
||||
# Run command
|
||||
`npm bin`/gulp test
|
||||
`npm bin`/gulp tests:visual:update "$@"
|
||||
@@ -18,18 +18,23 @@
|
||||
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
# IN THE SOFTWARE.
|
||||
|
||||
import json
|
||||
from setuptools import setup, find_packages
|
||||
|
||||
# Load package.json contents
|
||||
with open("package.json") as data:
|
||||
package = json.load(data)
|
||||
|
||||
# Package description
|
||||
setup(
|
||||
name = "mkdocs-material",
|
||||
version = "1.0.0",
|
||||
url = "http://squidfunk.github.io/mkdocs-material/",
|
||||
license = "MIT",
|
||||
description = "A Material Design theme for MkDocs",
|
||||
author = "Martin Donath",
|
||||
author_email = "martin.donath@squidfunk.com",
|
||||
keywords = ["mkdocs", "documentation", "theme"],
|
||||
name = package["name"],
|
||||
version = package["version"],
|
||||
url = package["homepage"],
|
||||
license = package["license"],
|
||||
description = package["description"],
|
||||
author = package["author"]["name"],
|
||||
author_email = package["author"]["email"],
|
||||
keywords = package["keywords"],
|
||||
packages = find_packages(),
|
||||
include_package_data = True,
|
||||
entry_points = {
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"presets": [
|
||||
["es2015", { "modules": false }]
|
||||
],
|
||||
"plugins": [
|
||||
["transform-react-jsx", {
|
||||
"pragma": "JSX.createElement"
|
||||
}]
|
||||
]
|
||||
}
|
||||
@@ -27,215 +27,199 @@ import Material from "./components/Material"
|
||||
* Application
|
||||
* ------------------------------------------------------------------------- */
|
||||
|
||||
export default class Application {
|
||||
export const initialize = config => {
|
||||
|
||||
/**
|
||||
* Create the application
|
||||
*
|
||||
* @constructor
|
||||
* @param {object} config Configuration object
|
||||
*/
|
||||
constructor(config) {
|
||||
this.config_ = config
|
||||
}
|
||||
/* Initialize Modernizr and FastClick */
|
||||
new Material.Event.Listener(document, "DOMContentLoaded", () => {
|
||||
|
||||
/**
|
||||
* Initialize all components and listeners
|
||||
*/
|
||||
initialize() {
|
||||
/* Test for iOS */
|
||||
Modernizr.addTest("ios", () => {
|
||||
return !!navigator.userAgent.match(/(iPad|iPhone|iPod)/g)
|
||||
})
|
||||
|
||||
/* Initialize Modernizr and FastClick */
|
||||
new Material.Event.Listener(document, "DOMContentLoaded", () => {
|
||||
/* Test for web application context */
|
||||
Modernizr.addTest("standalone", () => {
|
||||
return !!navigator.standalone
|
||||
})
|
||||
|
||||
/* Test for iOS */
|
||||
Modernizr.addTest("ios", () => {
|
||||
return !!navigator.userAgent.match(/(iPad|iPhone|iPod)/g)
|
||||
})
|
||||
/* Attach FastClick to mitigate 300ms delay on touch devices */
|
||||
FastClick.attach(document.body)
|
||||
|
||||
/* Test for web application context */
|
||||
Modernizr.addTest("standalone", () => {
|
||||
return !!navigator.standalone
|
||||
})
|
||||
/* Wrap all data tables for better overflow scrolling */
|
||||
const tables = document.querySelectorAll("table:not([class])")
|
||||
Array.prototype.forEach.call(tables, table => {
|
||||
const wrap = document.createElement("div")
|
||||
wrap.classList.add("md-typeset__table")
|
||||
if (table.nextSibling) {
|
||||
table.parentNode.insertBefore(wrap, table.nextSibling)
|
||||
} else {
|
||||
table.parentNode.appendChild(wrap)
|
||||
}
|
||||
wrap.appendChild(table)
|
||||
})
|
||||
|
||||
/* Attack FastClick to mitigate 300ms delay on touch devices */
|
||||
FastClick.attach(document.body)
|
||||
/* Force 1px scroll offset to trigger overflow scrolling */
|
||||
if (Modernizr.ios) {
|
||||
const scrollable = document.querySelectorAll("[data-md-scrollfix]")
|
||||
Array.prototype.forEach.call(scrollable, item => {
|
||||
item.addEventListener("touchstart", () => {
|
||||
const top = item.scrollTop
|
||||
|
||||
/* Wrap all data tables for better overflow scrolling */
|
||||
const tables = document.querySelectorAll("table:not([class])")
|
||||
Array.prototype.forEach.call(tables, table => {
|
||||
const wrap = document.createElement("div")
|
||||
wrap.classList.add("md-typeset__table")
|
||||
if (table.nextSibling) {
|
||||
table.parentNode.insertBefore(wrap, table.nextSibling)
|
||||
} else {
|
||||
table.parentNode.appendChild(wrap)
|
||||
}
|
||||
wrap.appendChild(table)
|
||||
})
|
||||
|
||||
/* Force 1px scroll offset to trigger overflow scrolling */
|
||||
if (Modernizr.ios) {
|
||||
const scrollable = document.querySelectorAll("[data-md-scrollfix]")
|
||||
Array.prototype.forEach.call(scrollable, item => {
|
||||
item.addEventListener("touchstart", () => {
|
||||
const top = item.scrollTop
|
||||
|
||||
/* We're at the top of the container */
|
||||
if (top === 0) {
|
||||
item.scrollTop = 1
|
||||
/* We're at the top of the container */
|
||||
if (top === 0) {
|
||||
item.scrollTop = 1
|
||||
|
||||
/* We're at the bottom of the container */
|
||||
} else if (top + item.offsetHeight === item.scrollHeight) {
|
||||
item.scrollTop = top - 1
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
}).listen()
|
||||
|
||||
/* Component: sidebar container */
|
||||
if (!Modernizr.csscalc)
|
||||
new Material.Event.MatchMedia("(min-width: 960px)",
|
||||
new Material.Event.Listener(window, [
|
||||
"resize", "orientationchange"
|
||||
], new Material.Sidebar.Container("[data-md-component=container]")))
|
||||
|
||||
/* Component: sidebar with navigation */
|
||||
new Material.Event.MatchMedia("(min-width: 1220px)",
|
||||
new Material.Event.Listener(window, [
|
||||
"scroll", "resize", "orientationchange"
|
||||
], new Material.Sidebar.Position("[data-md-component=navigation]")))
|
||||
|
||||
/* Component: sidebar with table of contents */
|
||||
new Material.Event.MatchMedia("(min-width: 960px)",
|
||||
new Material.Event.Listener(window, [
|
||||
"scroll", "resize", "orientationchange"
|
||||
], new Material.Sidebar.Position("[data-md-component=toc]")))
|
||||
|
||||
/* Component: link blurring for table of contents */
|
||||
new Material.Event.MatchMedia("(min-width: 960px)",
|
||||
new Material.Event.Listener(window, "scroll",
|
||||
new Material.Nav.Blur("[data-md-component=toc] .md-nav__link")))
|
||||
|
||||
/* Component: collapsible elements for navigation */
|
||||
const collapsibles =
|
||||
document.querySelectorAll("[data-md-component=collapsible]")
|
||||
Array.prototype.forEach.call(collapsibles, collapse => {
|
||||
new Material.Event.MatchMedia("(min-width: 1220px)",
|
||||
new Material.Event.Listener(collapse.previousElementSibling, "click",
|
||||
new Material.Nav.Collapse(collapse)))
|
||||
})
|
||||
|
||||
/* Component: active pane monitor for iOS scrolling fixes */
|
||||
new Material.Event.MatchMedia("(max-width: 1219px)",
|
||||
new Material.Event.Listener(
|
||||
"[data-md-component=navigation] [data-md-toggle]", "change",
|
||||
new Material.Nav.Scrolling("[data-md-component=navigation] nav")))
|
||||
|
||||
/* 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-component=result]", () => {
|
||||
return fetch(`${this.config_.url.base}/mkdocs/search_index.json`, {
|
||||
credentials: "same-origin"
|
||||
}).then(response => response.json())
|
||||
.then(data => {
|
||||
return data.docs.map(doc => {
|
||||
doc.location = this.config_.url.base + doc.location
|
||||
return doc
|
||||
})
|
||||
})
|
||||
})).listen()
|
||||
|
||||
/* Listener: prevent touches on overlay if navigation is active */
|
||||
new Material.Event.MatchMedia("(max-width: 1219px)",
|
||||
new Material.Event.Listener("[data-md-component=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-component=navigation] [href^='#']",
|
||||
"click", () => {
|
||||
const toggle = document.querySelector("[data-md-toggle=drawer]")
|
||||
if (toggle.checked) {
|
||||
toggle.checked = false
|
||||
toggle.dispatchEvent(new CustomEvent("change"))
|
||||
} else if (top + item.offsetHeight === item.scrollHeight) {
|
||||
item.scrollTop = top - 1
|
||||
}
|
||||
}))
|
||||
|
||||
/* Listener: focus input after opening 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: open 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
|
||||
toggle.dispatchEvent(new CustomEvent("change"))
|
||||
}
|
||||
}))
|
||||
|
||||
/* Listener: close search when clicking outside */
|
||||
new Material.Event.MatchMedia("(min-width: 960px)",
|
||||
new Material.Event.Listener(document.body, "click", () => {
|
||||
const toggle = document.querySelector("[data-md-toggle=search]")
|
||||
if (toggle.checked) {
|
||||
toggle.checked = false
|
||||
toggle.dispatchEvent(new CustomEvent("change"))
|
||||
}
|
||||
}))
|
||||
|
||||
/* Listener: disable search when ESC key is pressed */
|
||||
new Material.Event.Listener(window, "keyup", ev => {
|
||||
const code = ev.keyCode || ev.which
|
||||
if (code === 27) {
|
||||
const toggle = document.querySelector("[data-md-toggle=search]")
|
||||
if (toggle.checked) {
|
||||
toggle.checked = false
|
||||
toggle.dispatchEvent(new CustomEvent("change"))
|
||||
document.forms.search.query.blur()
|
||||
}
|
||||
}
|
||||
}).listen()
|
||||
|
||||
/* Listener: fix unclickable toggle due to blur handler */
|
||||
new Material.Event.MatchMedia("(min-width: 960px)",
|
||||
new Material.Event.Listener("[data-md-toggle=search]", "click",
|
||||
ev => ev.stopPropagation()))
|
||||
|
||||
/* Listener: prevent search from closing when clicking */
|
||||
new Material.Event.MatchMedia("(min-width: 960px)",
|
||||
new Material.Event.Listener("[data-md-component=search]", "click",
|
||||
ev => ev.stopPropagation()))
|
||||
|
||||
/* Retrieve facts for the given repository type */
|
||||
;(() => {
|
||||
const el = document.querySelector("[data-md-source]")
|
||||
if (!el) return Promise.resolve([])
|
||||
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]")
|
||||
Array.prototype.forEach.call(sources, source => {
|
||||
new Material.Source.Repository(source)
|
||||
.initialize(facts)
|
||||
})
|
||||
})
|
||||
}
|
||||
}).listen()
|
||||
|
||||
/* Component: sidebar container */
|
||||
if (!Modernizr.csscalc)
|
||||
new Material.Event.MatchMedia("(min-width: 960px)",
|
||||
new Material.Event.Listener(window, [
|
||||
"resize", "orientationchange"
|
||||
], new Material.Sidebar.Container("[data-md-component=container]")))
|
||||
|
||||
/* Component: sidebar with navigation */
|
||||
new Material.Event.MatchMedia("(min-width: 1220px)",
|
||||
new Material.Event.Listener(window, [
|
||||
"scroll", "resize", "orientationchange"
|
||||
], new Material.Sidebar.Position("[data-md-component=navigation]")))
|
||||
|
||||
/* Component: sidebar with table of contents */
|
||||
new Material.Event.MatchMedia("(min-width: 960px)",
|
||||
new Material.Event.Listener(window, [
|
||||
"scroll", "resize", "orientationchange"
|
||||
], new Material.Sidebar.Position("[data-md-component=toc]")))
|
||||
|
||||
/* Component: link blurring for table of contents */
|
||||
new Material.Event.MatchMedia("(min-width: 960px)",
|
||||
new Material.Event.Listener(window, "scroll",
|
||||
new Material.Nav.Blur("[data-md-component=toc] .md-nav__link")))
|
||||
|
||||
/* Component: collapsible elements for navigation */
|
||||
const collapsibles =
|
||||
document.querySelectorAll("[data-md-component=collapsible]")
|
||||
Array.prototype.forEach.call(collapsibles, collapse => {
|
||||
new Material.Event.MatchMedia("(min-width: 1220px)",
|
||||
new Material.Event.Listener(collapse.previousElementSibling, "click",
|
||||
new Material.Nav.Collapse(collapse)))
|
||||
})
|
||||
|
||||
/* Component: active pane monitor for iOS scrolling fixes */
|
||||
new Material.Event.MatchMedia("(max-width: 1219px)",
|
||||
new Material.Event.Listener(
|
||||
"[data-md-component=navigation] [data-md-toggle]", "change",
|
||||
new Material.Nav.Scrolling("[data-md-component=navigation] nav")))
|
||||
|
||||
/* 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-component=result]", () => {
|
||||
return fetch(`${config.url.base}/mkdocs/search_index.json`, {
|
||||
credentials: "same-origin"
|
||||
}).then(response => response.json())
|
||||
.then(data => {
|
||||
return data.docs.map(doc => {
|
||||
doc.location = config.url.base + doc.location
|
||||
return doc
|
||||
})
|
||||
})
|
||||
})).listen()
|
||||
|
||||
/* Listener: prevent touches on overlay if navigation is active */
|
||||
new Material.Event.MatchMedia("(max-width: 1219px)",
|
||||
new Material.Event.Listener("[data-md-component=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-component=navigation] [href^='#']",
|
||||
"click", () => {
|
||||
const toggle = document.querySelector("[data-md-toggle=drawer]")
|
||||
if (toggle.checked) {
|
||||
toggle.checked = false
|
||||
toggle.dispatchEvent(new CustomEvent("change"))
|
||||
}
|
||||
}))
|
||||
|
||||
/* Listener: focus input after opening 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: open 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
|
||||
toggle.dispatchEvent(new CustomEvent("change"))
|
||||
}
|
||||
}))
|
||||
|
||||
/* Listener: close search when clicking outside */
|
||||
new Material.Event.MatchMedia("(min-width: 960px)",
|
||||
new Material.Event.Listener(document.body, "click", () => {
|
||||
const toggle = document.querySelector("[data-md-toggle=search]")
|
||||
if (toggle.checked) {
|
||||
toggle.checked = false
|
||||
toggle.dispatchEvent(new CustomEvent("change"))
|
||||
}
|
||||
}))
|
||||
|
||||
/* Listener: disable search when ESC key is pressed */
|
||||
new Material.Event.Listener(window, "keyup", ev => {
|
||||
const code = ev.keyCode || ev.which
|
||||
if (code === 27) {
|
||||
const toggle = document.querySelector("[data-md-toggle=search]")
|
||||
if (toggle.checked) {
|
||||
toggle.checked = false
|
||||
toggle.dispatchEvent(new CustomEvent("change"))
|
||||
document.forms.search.query.blur()
|
||||
}
|
||||
}
|
||||
}).listen()
|
||||
|
||||
/* Listener: fix unclickable toggle due to blur handler */
|
||||
new Material.Event.MatchMedia("(min-width: 960px)",
|
||||
new Material.Event.Listener("[data-md-toggle=search]", "click",
|
||||
ev => ev.stopPropagation()))
|
||||
|
||||
/* Listener: prevent search from closing when clicking */
|
||||
new Material.Event.MatchMedia("(min-width: 960px)",
|
||||
new Material.Event.Listener("[data-md-component=search]", "click",
|
||||
ev => ev.stopPropagation()))
|
||||
|
||||
/* Retrieve facts for the given repository type */
|
||||
;(() => {
|
||||
const el = document.querySelector("[data-md-source]")
|
||||
if (!el) return Promise.resolve([])
|
||||
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]")
|
||||
Array.prototype.forEach.call(sources, source => {
|
||||
new Material.Source.Repository(source)
|
||||
.initialize(facts)
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -41,6 +41,9 @@ export default class Blur {
|
||||
this.index_ = 0
|
||||
this.offset_ = window.pageYOffset
|
||||
|
||||
/* Necessary state to correctly reset the index */
|
||||
this.dir_ = false
|
||||
|
||||
/* Index anchor node offsets for fast lookup */
|
||||
this.anchors_ = [].map.call(this.els_, el => {
|
||||
return document.getElementById(el.hash.substring(1))
|
||||
@@ -62,6 +65,14 @@ export default class Blur {
|
||||
*/
|
||||
update() {
|
||||
const offset = window.pageYOffset
|
||||
const dir = this.offset_ - offset < 0
|
||||
|
||||
/* Hack: reset index if direction changed, to catch very fast scrolling,
|
||||
because otherwise we would have to register a timer and that sucks */
|
||||
if (this.dir_ !== dir)
|
||||
this.index_ = dir
|
||||
? this.index_ = 0
|
||||
: this.index_ = this.els_.length - 1
|
||||
|
||||
/* Exit when there are no anchors */
|
||||
if (this.anchors_.length === 0)
|
||||
@@ -92,8 +103,9 @@ export default class Blur {
|
||||
}
|
||||
}
|
||||
|
||||
/* Remember current offset for next iteration */
|
||||
/* Remember current offset and direction for next iteration */
|
||||
this.offset_ = offset
|
||||
this.dir_ = dir
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -34,14 +34,9 @@ body {
|
||||
body,
|
||||
input {
|
||||
color: $md-color-black;
|
||||
// font-family: "Roboto", "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||
font-feature-settings: "kern", "onum", "liga";
|
||||
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||
font-weight: 400;
|
||||
|
||||
// Use system fonts, if browser doesn't support webfonts
|
||||
.no-fontface & {
|
||||
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||
}
|
||||
}
|
||||
|
||||
// Proportionally spaced fonts
|
||||
@@ -49,14 +44,9 @@ pre,
|
||||
code,
|
||||
kbd {
|
||||
color: $md-color-black;
|
||||
// font-family: "Roboto Mono", "Courier New", Courier, monospace;
|
||||
font-feature-settings: "kern", "onum", "liga";
|
||||
font-family: "Courier New", Courier, monospace;
|
||||
font-weight: 400;
|
||||
|
||||
// Use system fonts, if browser doesn't support webfonts
|
||||
.no-fontface & {
|
||||
font-family: "Courier New", Courier, monospace;
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
@@ -83,24 +83,21 @@
|
||||
.footnote-backref {
|
||||
@extend %md-icon;
|
||||
|
||||
position: absolute;
|
||||
display: inline-block;
|
||||
transform: translateX(0.5rem);
|
||||
transition:
|
||||
transform 0.25s 0.125s,
|
||||
color 0.25s,
|
||||
opacity 0.125s 0.125s;
|
||||
color: $md-color-black--lighter;
|
||||
font-size: 1.5625em;
|
||||
opacity: 0;
|
||||
vertical-align: middle;
|
||||
|
||||
// Hack: remove Unicode arrow for icon
|
||||
&::first-letter {
|
||||
font-size: 0;
|
||||
}
|
||||
font-size: 0;
|
||||
opacity: 0;
|
||||
vertical-align: text-bottom;
|
||||
|
||||
// Back reference icon
|
||||
&::after {
|
||||
&::before {
|
||||
font-size: 1.6rem;
|
||||
content: "keyboard_return";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -80,18 +80,23 @@
|
||||
}
|
||||
}
|
||||
|
||||
// Hide anchor for top-level heading, as it makes no sense
|
||||
h1[id] .headerlink {
|
||||
display: none;
|
||||
// Correct headline offset with padding due to margin layering
|
||||
h1[id] {
|
||||
padding-top: 0.8rem;
|
||||
|
||||
// Hide anchor for top-level heading, as it makes no sense
|
||||
&.headerlink {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
// Correct anchor offset for link blurring
|
||||
@each $level, $delta in (
|
||||
h2: 0.2rem,
|
||||
h3: 0.4rem,
|
||||
h4: 0.6rem,
|
||||
h5: 1rem,
|
||||
h6: 1rem
|
||||
h2: 0.4rem,
|
||||
h3: 0.7rem,
|
||||
h4: 0.8rem,
|
||||
h5: 1.1rem,
|
||||
h6: 1.1rem
|
||||
) {
|
||||
|
||||
// Un-targeted anchor
|
||||
|
||||
@@ -35,6 +35,9 @@
|
||||
// [screen +]: Add space for table of contents
|
||||
@include break-from-device(screen) {
|
||||
margin-left: 24.2rem;
|
||||
// Hack: setting overflow to auto induces margin collapse which omits
|
||||
// massive repaints because of the margins of the inner elements
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
// Define spacing
|
||||
@@ -44,6 +47,11 @@
|
||||
// [screen +]: Increase spacing
|
||||
@include break-from-device(screen) {
|
||||
margin: 2.4rem;
|
||||
|
||||
// Hack: remove bottom spacing, due to margin collapse
|
||||
:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -50,8 +50,8 @@
|
||||
padding-bottom: 0.8rem;
|
||||
transition: opacity 0.25s;
|
||||
|
||||
// [mobile landscape +]: Set proportional width
|
||||
@include break-from-device(mobile landscape) {
|
||||
// [tablet +]: Set proportional width
|
||||
@include break-from-device(tablet) {
|
||||
width: 50%;
|
||||
}
|
||||
|
||||
@@ -68,8 +68,8 @@
|
||||
// Title
|
||||
.md-footer-nav__title {
|
||||
|
||||
// [mobile portrait -]: Hide title for previous page
|
||||
@include break-to-device(mobile portrait) {
|
||||
// [mobile -]: Hide title for previous page
|
||||
@include break-to-device(mobile) {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
@@ -83,8 +83,8 @@
|
||||
}
|
||||
}
|
||||
|
||||
// Icons
|
||||
&__icon {
|
||||
// Icon buttons
|
||||
&__button {
|
||||
@extend %md-icon__button;
|
||||
|
||||
transition: background 0.25s;
|
||||
|
||||
@@ -48,8 +48,8 @@
|
||||
.md-header-nav {
|
||||
padding: 0.4rem;
|
||||
|
||||
// Icons
|
||||
&__icon {
|
||||
// Icon buttons
|
||||
&__button {
|
||||
@extend %md-icon__button;
|
||||
|
||||
position: relative;
|
||||
@@ -61,8 +61,13 @@
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
// Set correct display on image
|
||||
&.md-logo img {
|
||||
display: block;
|
||||
}
|
||||
|
||||
// Hide search icon, if JavaScript is not available.
|
||||
.no-js & .md-icon--search {
|
||||
.no-js &.md-icon--search {
|
||||
display: none;
|
||||
}
|
||||
|
||||
@@ -75,11 +80,12 @@
|
||||
}
|
||||
}
|
||||
|
||||
// [tablet -]: Hide the home icon
|
||||
// [tablet -]: Hide the home icon or logo
|
||||
@include break-to-device(tablet) {
|
||||
|
||||
// Home icon
|
||||
&.md-icon--home {
|
||||
// Home icon or logo
|
||||
&.md-icon--home,
|
||||
&.md-logo {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
|
||||
// Navigation container
|
||||
.md-nav {
|
||||
font-size: ms(-1);
|
||||
font-size: 1.4rem;
|
||||
line-height: 1.3;
|
||||
|
||||
// Table of contents
|
||||
@@ -51,8 +51,8 @@
|
||||
content: "arrow_back";
|
||||
}
|
||||
|
||||
// Hide icon by default
|
||||
.md-nav__icon {
|
||||
// Hide button by default
|
||||
.md-nav__button {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
@@ -84,8 +84,8 @@
|
||||
}
|
||||
}
|
||||
|
||||
// Icon
|
||||
&__icon {
|
||||
// Button with logo
|
||||
&__button {
|
||||
@extend %md-icon, %md-icon__button;
|
||||
|
||||
// Stretch image
|
||||
@@ -129,18 +129,19 @@
|
||||
}
|
||||
}
|
||||
|
||||
// Blurred item
|
||||
// Blurred link
|
||||
&[data-md-state="blur"] {
|
||||
color: $md-color-black--light;
|
||||
}
|
||||
|
||||
// Active item
|
||||
// Active link
|
||||
&:active,
|
||||
&--active {
|
||||
color: $md-color-primary;
|
||||
}
|
||||
|
||||
// Hovered item
|
||||
// Focused or hovered link
|
||||
&:focus,
|
||||
&:hover {
|
||||
color: $md-color-accent;
|
||||
}
|
||||
@@ -153,6 +154,7 @@
|
||||
|
||||
// [tablet -]: Layered navigation
|
||||
@include break-to-device(tablet) {
|
||||
background-color: $md-color-white;
|
||||
|
||||
// Stretch primary navigation to drawer
|
||||
&--primary,
|
||||
@@ -169,13 +171,12 @@
|
||||
|
||||
// Adjust styles for primary navigation
|
||||
&--primary {
|
||||
background-color: $md-color-white;
|
||||
|
||||
// Move subsequent navigations off
|
||||
.md-nav__toggle ~ .md-nav {
|
||||
@include z-depth(4);
|
||||
|
||||
background-color: $md-color-white;
|
||||
// List title and item
|
||||
.md-nav__title,
|
||||
.md-nav__item {
|
||||
font-size: 1.6rem;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
// List title - higher specificity is necessary to ensure that the title
|
||||
@@ -240,7 +241,7 @@
|
||||
color: $md-color-white;
|
||||
|
||||
// Site logo
|
||||
.md-nav__icon {
|
||||
.md-nav__button {
|
||||
display: block;
|
||||
position: absolute;
|
||||
top: 0.4rem;
|
||||
@@ -260,7 +261,7 @@
|
||||
// List of items
|
||||
.md-nav__list {
|
||||
flex: 1;
|
||||
overflow-y: scroll;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
// List item
|
||||
@@ -294,7 +295,8 @@
|
||||
font-size: 2.4rem;
|
||||
}
|
||||
|
||||
// Color of icon should inherit link color on hover
|
||||
// Color of icon should inherit link color on focus or hover
|
||||
&:focus::after,
|
||||
&:hover::after {
|
||||
color: inherit;
|
||||
}
|
||||
@@ -354,13 +356,6 @@
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
// List item
|
||||
.md-nav__title,
|
||||
.md-nav__item {
|
||||
font-size: 1.6rem;
|
||||
line-height: 1.5;
|
||||
}
|
||||
}
|
||||
|
||||
// [tablet portrait -]: Show table of contents in drawer
|
||||
|
||||
@@ -265,14 +265,14 @@
|
||||
|
||||
// [tablet landscape +]: Header-embedded search
|
||||
@include break-from-device(tablet landscape) {
|
||||
@include z-depth(6);
|
||||
|
||||
top: 4rem;
|
||||
transition: opacity 0.4s;
|
||||
opacity: 0;
|
||||
|
||||
// Show search output in active state
|
||||
[data-md-toggle="search"]:checked ~ .md-header & {
|
||||
@include z-depth(6);
|
||||
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
.md-sidebar {
|
||||
position: relative;
|
||||
width: 24.2rem;
|
||||
padding: 2.4rem 0;
|
||||
float: left;
|
||||
overflow: visible;
|
||||
|
||||
@@ -40,6 +41,7 @@
|
||||
&[data-md-state="lock"] {
|
||||
position: fixed;
|
||||
top: 5.6rem;
|
||||
backface-visibility: hidden;
|
||||
}
|
||||
|
||||
// [tablet -]: Convert navigation to drawer
|
||||
@@ -107,27 +109,24 @@
|
||||
|
||||
// Wrapper for scrolling on overflow
|
||||
&__scrollwrap {
|
||||
margin: 2.4rem 0.4rem;
|
||||
overflow-y: scroll;
|
||||
max-height: 100%;
|
||||
margin: 0 0.4rem;
|
||||
overflow-y: auto;
|
||||
|
||||
// [tablet -]: Adjust margins
|
||||
@include break-to-device(tablet) {
|
||||
|
||||
// Adjust margins for primary scrollbar
|
||||
// Stretch scrollwrap for primary sidebar
|
||||
.md-sidebar--primary & {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Limit height to window, if JavaScript is available
|
||||
.js & {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
// Override native scrollbar styles
|
||||
&::-webkit-scrollbar {
|
||||
width: 0.4rem;
|
||||
|
||||
@@ -118,7 +118,7 @@
|
||||
font-weight: 700;
|
||||
list-style-type: none;
|
||||
opacity: 0.75;
|
||||
overflow: auto;
|
||||
overflow: hidden;
|
||||
|
||||
// Show after the data was loaded
|
||||
[data-md-state="done"] & {
|
||||
|
||||
@@ -56,7 +56,8 @@
|
||||
{% endif %}
|
||||
|
||||
<!-- Generator banner -->
|
||||
<meta name="generator" content="mkdocs+$theme-name$#$theme-version$" />
|
||||
<meta name="generator"
|
||||
content="mkdocs-{{ mkdocs_version }}, $theme-name$-$theme-version$" />
|
||||
{% endblock %}
|
||||
|
||||
<!-- Block: site title -->
|
||||
@@ -75,6 +76,20 @@
|
||||
<script src="{{ base_url }}/assets/javascripts/modernizr.js"></script>
|
||||
{% endblock %}
|
||||
|
||||
<!-- Block: stylesheets -->
|
||||
{% block styles %}
|
||||
|
||||
<!-- Theme-related stylesheets -->
|
||||
<link rel="stylesheet" type="text/css"
|
||||
href="{{ base_url }}/assets/stylesheets/application.css" />
|
||||
|
||||
<!-- Extra color palette -->
|
||||
{% if config.extra.palette %}
|
||||
<link rel="stylesheet" type="text/css"
|
||||
href="{{ base_url }}/assets/stylesheets/application.palette.css" />
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
||||
<!-- Block: webfonts -->
|
||||
{% block fonts %}
|
||||
{% if config.extra.font != "none" %}
|
||||
@@ -101,24 +116,10 @@
|
||||
href="https://fonts.googleapis.com/icon?family=Material+Icons" />
|
||||
{% endblock %}
|
||||
|
||||
<!-- Block: stylesheets -->
|
||||
{% block styles %}
|
||||
|
||||
<!-- Theme-related stylesheets -->
|
||||
<link rel="stylesheet" type="text/css"
|
||||
href="{{ base_url }}/assets/stylesheets/application.css" />
|
||||
|
||||
<!-- Extra color palette -->
|
||||
{% if config.extra.palette %}
|
||||
<link rel="stylesheet" type="text/css"
|
||||
href="{{ base_url }}/assets/stylesheets/application.palette.css" />
|
||||
{% endif %}
|
||||
|
||||
<!-- Custom stylesheets -->
|
||||
{% for path in extra_css %}
|
||||
<link rel="stylesheet" type="text/css" href="{{ path }}" />
|
||||
{% endfor %}
|
||||
{% endblock %}
|
||||
<!-- Custom stylesheets -->
|
||||
{% for path in extra_css %}
|
||||
<link rel="stylesheet" type="text/css" href="{{ path }}" />
|
||||
{% endfor %}
|
||||
|
||||
<!-- Block: custom front matter -->
|
||||
{% block extrahead %}{% endblock %}
|
||||
@@ -218,11 +219,11 @@
|
||||
{% block content %}
|
||||
|
||||
<!--
|
||||
This is a nasty hack that checks whether the content contains
|
||||
a h1 headline. If it doesn't, the page title (or respectively
|
||||
site name) is used as the main headline.
|
||||
Hack: check whether the content contains a h1 headline. If it
|
||||
doesn't, the page title (or respectively site name) is used
|
||||
as the main headline.
|
||||
-->
|
||||
{% if not "\x3ch1 id=" in page.content %}
|
||||
{% if not "\x3ch1" in page.content %}
|
||||
<h1>{{ page.title | default(config.site_name, true)}}</h1>
|
||||
{% endif %}
|
||||
|
||||
@@ -244,17 +245,7 @@
|
||||
{% block scripts %}
|
||||
<script src="{{ base_url }}/assets/javascripts/application.js"></script>
|
||||
<script>
|
||||
|
||||
/* Configuration for application */
|
||||
var config = {
|
||||
url: {
|
||||
base: "{{ base_url }}",
|
||||
}
|
||||
};
|
||||
|
||||
/* Initialize application */
|
||||
var app = new Application(config);
|
||||
app.initialize();
|
||||
app.initialize({ url: { base: "{{ base_url }}", } });
|
||||
</script>
|
||||
{% for path in extra_javascript %}
|
||||
<script src="{{ path }}"></script>
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
rel="prev">
|
||||
<div class="md-flex__cell md-flex__cell--shrink">
|
||||
<i class="md-icon md-icon--arrow-back
|
||||
md-footer-nav__icon"></i>
|
||||
md-footer-nav__button"></i>
|
||||
</div>
|
||||
<div class="md-flex__cell md-flex__cell--stretch
|
||||
md-footer-nav__title">
|
||||
@@ -68,7 +68,7 @@
|
||||
</div>
|
||||
<div class="md-flex__cell md-flex__cell--shrink">
|
||||
<i class="md-icon md-icon--arrow-forward
|
||||
md-footer-nav__icon"></i>
|
||||
md-footer-nav__button"></i>
|
||||
</div>
|
||||
</a>
|
||||
{% endif %}
|
||||
|
||||
@@ -30,10 +30,12 @@
|
||||
<!-- Link to home -->
|
||||
<div class="md-flex__cell md-flex__cell--shrink">
|
||||
<a href="{{ nav.homepage.url }}" title="{{ config.site_name }}"
|
||||
class="md-icon
|
||||
{% if not config.extra.logo %}
|
||||
md-icon--home
|
||||
{% endif %} md-header-nav__icon">
|
||||
class="
|
||||
{% if config.extra.logo %}
|
||||
md-logo
|
||||
{% else %}
|
||||
md-icon md-icon--home
|
||||
{% endif %} md-header-nav__button">
|
||||
{% if config.extra.logo %}
|
||||
<img src="{{ base_url }}/{{ config.extra.logo }}"
|
||||
width="24" height="24" />
|
||||
@@ -43,7 +45,7 @@
|
||||
|
||||
<!-- Button to toggle drawer -->
|
||||
<div class="md-flex__cell md-flex__cell--shrink">
|
||||
<label class="md-icon md-icon--menu md-header-nav__icon"
|
||||
<label class="md-icon md-icon--menu md-header-nav__button"
|
||||
for="drawer"></label>
|
||||
</div>
|
||||
|
||||
@@ -66,7 +68,7 @@
|
||||
<!-- Button to open search dialogue -->
|
||||
<div class="md-flex__cell md-flex__cell--shrink">
|
||||
{% block search_box %}
|
||||
<label class="md-icon md-icon--search md-header-nav__icon"
|
||||
<label class="md-icon md-icon--search md-header-nav__button"
|
||||
for="search"></label>
|
||||
|
||||
<!-- Search interface -->
|
||||
|
||||
@@ -62,13 +62,13 @@
|
||||
<input class="md-toggle md-nav__toggle" data-md-toggle="toc"
|
||||
type="checkbox" id="toc" />
|
||||
|
||||
<!-- Nasty hack - see partials/toc.html for more information -->
|
||||
{% if "\x3ch1 id=" in page.content %}
|
||||
<!-- Hack: see partials/toc.html for more information -->
|
||||
{% if toc_ | first is defined %}
|
||||
{% set toc_ = (toc_ | first).children %}
|
||||
{% endif %}
|
||||
|
||||
<!-- Render table of contents, if not empty -->
|
||||
{% if toc_ and (toc_ | first) %}
|
||||
{% if toc_ | first is defined %}
|
||||
<label class="md-nav__link md-nav__link--active" for="toc">
|
||||
{{ nav_item.title }}
|
||||
</label>
|
||||
@@ -79,7 +79,7 @@
|
||||
</a>
|
||||
|
||||
<!-- Show table of contents -->
|
||||
{% if page.toc %}
|
||||
{% if toc_ | first is defined %}
|
||||
{% include "partials/toc.html" %}
|
||||
{% endif %}
|
||||
</li>
|
||||
|
||||
@@ -23,11 +23,12 @@
|
||||
<!-- Main navigation -->
|
||||
<nav class="md-nav md-nav--primary">
|
||||
<label class="md-nav__title md-nav__title--site" for="drawer">
|
||||
<i class="md-icon
|
||||
{% if not config.extra.logo %}
|
||||
md-icon--home
|
||||
{% endif %}
|
||||
md-nav__icon">
|
||||
<i class="
|
||||
{% if config.extra.logo %}
|
||||
md-logo
|
||||
{% else %}
|
||||
md-icon md-icon--home
|
||||
{% endif %} md-nav__button">
|
||||
{% if config.extra.logo %}
|
||||
<img src="{{ base_url }}/{{ config.extra.logo }}" />
|
||||
{% endif %}
|
||||
|
||||
@@ -27,17 +27,17 @@
|
||||
{% set toc_ = page.toc %}
|
||||
|
||||
<!--
|
||||
This is a nasty hack that checks whether the content contains a h1
|
||||
headline. If it does, the top-level anchor must be skipped, since it would
|
||||
be redundant to the link to the current page that is located just above the
|
||||
anchor. Therefore we directly continue with the children of the anchor.
|
||||
Hack: check whether the content contains a h1 headline. If it does, the
|
||||
top-level anchor must be skipped, since it would be redundant to the link
|
||||
to the current page that is located just above the anchor. Therefore we
|
||||
directly continue with the children of the anchor.
|
||||
-->
|
||||
{% if "\x3ch1 id=" in page.content %}
|
||||
{% if toc_ | first is defined and "\x3ch1 id=" in page.content %}
|
||||
{% set toc_ = (toc_ | first).children %}
|
||||
{% endif %}
|
||||
|
||||
<!-- Render item list -->
|
||||
{% if toc_ and (toc_ | first) %}
|
||||
{% if toc_ | first is defined %}
|
||||
<label class="md-nav__title" for="toc">{{ lang.t('toc.title') }}</label>
|
||||
<ul class="md-nav__list" data-md-scrollfix>
|
||||
{% for toc_item in toc_ %}
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"globals": {
|
||||
"gemini": true
|
||||
},
|
||||
"rules": {
|
||||
"no-loop-func": 0
|
||||
}
|
||||
}
|
||||
|
After Width: | Height: | Size: 5.7 KiB |
|
After Width: | Height: | Size: 7.3 KiB |
|
After Width: | Height: | Size: 5.0 KiB |
|
After Width: | Height: | Size: 7.1 KiB |
|
After Width: | Height: | Size: 6.3 KiB |
|
After Width: | Height: | Size: 8.2 KiB |
|
After Width: | Height: | Size: 5.5 KiB |
|
After Width: | Height: | Size: 8.0 KiB |
|
After Width: | Height: | Size: 5.6 KiB |
|
After Width: | Height: | Size: 7.3 KiB |
|
After Width: | Height: | Size: 5.0 KiB |
|
After Width: | Height: | Size: 7.2 KiB |
|
After Width: | Height: | Size: 4.8 KiB |
|
After Width: | Height: | Size: 6.7 KiB |
|
After Width: | Height: | Size: 4.4 KiB |
|
After Width: | Height: | Size: 6.5 KiB |
|
After Width: | Height: | Size: 5.3 KiB |
|
After Width: | Height: | Size: 6.9 KiB |
|
After Width: | Height: | Size: 4.8 KiB |
|
After Width: | Height: | Size: 6.8 KiB |
|
After Width: | Height: | Size: 8.8 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 7.7 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 5.4 KiB |