From 4fdcb8de92d5d24e9944934863d13a7bf576e4d3 Mon Sep 17 00:00:00 2001 From: squidfunk Date: Thu, 28 Jan 2016 23:27:15 +0100 Subject: [PATCH] Initial commit --- .gitignore | 22 + Gulpfile.js | 329 +++++++++++ bower.json | 30 + package.json | 47 ++ src/assets/fonts/icon.eot | Bin 0 -> 2328 bytes src/assets/fonts/icon.json | 319 +++++++++++ src/assets/fonts/icon.svg | 21 + src/assets/fonts/icon.ttf | Bin 0 -> 2176 bytes src/assets/fonts/icon.woff | Bin 0 -> 2252 bytes src/assets/images/favicon-16x16.png | Bin 0 -> 317 bytes src/assets/images/favicon-32x32.png | Bin 0 -> 501 bytes src/assets/javascripts/application.js | 518 ++++++++++++++++++ src/assets/javascripts/standalone.js | 49 ++ src/assets/stylesheets/_highlight.scss | 75 +++ src/assets/stylesheets/_palette.scss | 47 ++ src/assets/stylesheets/_print.scss | 66 +++ src/assets/stylesheets/_reset.scss | 143 +++++ src/assets/stylesheets/_shame.scss | 38 ++ src/assets/stylesheets/application.scss | 50 ++ src/assets/stylesheets/fonts/_icon.scss | 137 +++++ src/assets/stylesheets/mixins/_break.scss | 206 +++++++ src/assets/stylesheets/modules/_article.scss | 26 + src/assets/stylesheets/modules/_base.scss | 26 + src/assets/stylesheets/modules/_drawer.scss | 26 + src/assets/stylesheets/modules/_search.scss | 26 + .../modules/article/_animation.scss | 45 ++ .../modules/article/_appearance.scss | 152 +++++ .../stylesheets/modules/article/_layout.scss | 455 +++++++++++++++ .../modules/article/_typography.scss | 38 ++ .../stylesheets/modules/base/_animation.scss | 73 +++ .../stylesheets/modules/base/_appearance.scss | 137 +++++ .../stylesheets/modules/base/_layout.scss | 347 ++++++++++++ .../stylesheets/modules/base/_typography.scss | 58 ++ .../modules/drawer/_animation.scss | 74 +++ .../modules/drawer/_appearance.scss | 149 +++++ .../stylesheets/modules/drawer/_layout.scss | 281 ++++++++++ .../modules/drawer/_typography.scss | 69 +++ .../modules/search/_animation.scss | 134 +++++ .../modules/search/_appearance.scss | 139 +++++ .../stylesheets/modules/search/_layout.scss | 219 ++++++++ .../modules/search/_typography.scss | 29 + src/views/base.html | 176 ++++++ src/views/drawer.html | 81 +++ src/views/footer.html | 44 ++ src/views/header.html | 86 +++ src/views/toc.html | 37 ++ 46 files changed, 5024 insertions(+) create mode 100644 .gitignore create mode 100755 Gulpfile.js create mode 100644 bower.json create mode 100644 package.json create mode 100755 src/assets/fonts/icon.eot create mode 100644 src/assets/fonts/icon.json create mode 100755 src/assets/fonts/icon.svg create mode 100755 src/assets/fonts/icon.ttf create mode 100755 src/assets/fonts/icon.woff create mode 100755 src/assets/images/favicon-16x16.png create mode 100755 src/assets/images/favicon-32x32.png create mode 100644 src/assets/javascripts/application.js create mode 100644 src/assets/javascripts/standalone.js create mode 100644 src/assets/stylesheets/_highlight.scss create mode 100644 src/assets/stylesheets/_palette.scss create mode 100644 src/assets/stylesheets/_print.scss create mode 100644 src/assets/stylesheets/_reset.scss create mode 100644 src/assets/stylesheets/_shame.scss create mode 100644 src/assets/stylesheets/application.scss create mode 100644 src/assets/stylesheets/fonts/_icon.scss create mode 100644 src/assets/stylesheets/mixins/_break.scss create mode 100644 src/assets/stylesheets/modules/_article.scss create mode 100644 src/assets/stylesheets/modules/_base.scss create mode 100644 src/assets/stylesheets/modules/_drawer.scss create mode 100644 src/assets/stylesheets/modules/_search.scss create mode 100644 src/assets/stylesheets/modules/article/_animation.scss create mode 100644 src/assets/stylesheets/modules/article/_appearance.scss create mode 100644 src/assets/stylesheets/modules/article/_layout.scss create mode 100644 src/assets/stylesheets/modules/article/_typography.scss create mode 100644 src/assets/stylesheets/modules/base/_animation.scss create mode 100644 src/assets/stylesheets/modules/base/_appearance.scss create mode 100644 src/assets/stylesheets/modules/base/_layout.scss create mode 100644 src/assets/stylesheets/modules/base/_typography.scss create mode 100644 src/assets/stylesheets/modules/drawer/_animation.scss create mode 100644 src/assets/stylesheets/modules/drawer/_appearance.scss create mode 100644 src/assets/stylesheets/modules/drawer/_layout.scss create mode 100644 src/assets/stylesheets/modules/drawer/_typography.scss create mode 100644 src/assets/stylesheets/modules/search/_animation.scss create mode 100644 src/assets/stylesheets/modules/search/_appearance.scss create mode 100644 src/assets/stylesheets/modules/search/_layout.scss create mode 100644 src/assets/stylesheets/modules/search/_typography.scss create mode 100644 src/views/base.html create mode 100644 src/views/drawer.html create mode 100644 src/views/footer.html create mode 100644 src/views/header.html create mode 100644 src/views/toc.html diff --git a/.gitignore b/.gitignore new file mode 100644 index 000000000..7147a9e5d --- /dev/null +++ b/.gitignore @@ -0,0 +1,22 @@ +# Copyright (c) 2016 Martin Donath + +# 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. + +# Mac OS X internals +.DS_Store \ No newline at end of file diff --git a/Gulpfile.js b/Gulpfile.js new file mode 100755 index 000000000..718a98079 --- /dev/null +++ b/Gulpfile.js @@ -0,0 +1,329 @@ +/* + * Copyright (c) 2013-2016 Martin Donath + * + * 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. + */ + +/* ---------------------------------------------------------------------------- + * Imports + * ------------------------------------------------------------------------- */ + +var gulp = require('gulp'); +var addsrc = require('gulp-add-src'); +var args = require('yargs').argv; +var autoprefix = require('autoprefixer-core'); +var child = require('child_process'); +var clean = require('del'); +var collect = require('gulp-rev-collector'); +var compact = require('gulp-remove-empty-lines'); +var concat = require('gulp-concat'); +var ignore = require('gulp-ignore'); +var gulpif = require('gulp-if'); +var mincss = require('gulp-minify-css'); +var minhtml = require('gulp-htmlmin'); +var minimage = require('gulp-image-optimization'); +var modernizr = require('gulp-modernizr'); +var mqpacker = require('css-mqpacker'); +var notifier = require('node-notifier'); +var plumber = require('gulp-plumber'); +var postcss = require('gulp-postcss'); +var rev = require('gulp-rev'); +var sass = require('gulp-sass'); +var sourcemaps = require('gulp-sourcemaps'); +var uglify = require('gulp-uglify'); +var util = require('gulp-util'); +var vinyl = require('vinyl-paths'); + +/* ---------------------------------------------------------------------------- + * Locals + * ------------------------------------------------------------------------- */ + +/* Application server */ +var server = null; + +/* ---------------------------------------------------------------------------- + * Overrides + * ------------------------------------------------------------------------- */ + +/* + * Override gulp.src() for nicer error handling. + */ +var src = gulp.src; +gulp.src = function() { + return src.apply(gulp, arguments) + .pipe( + plumber(function(error) { + util.log(util.colors.red( + 'Error (' + error.plugin + '): ' + error.message + )); + notifier.notify({ + title: 'Error (' + error.plugin + ')', + message: error.message.split('\n')[0] + }); + this.emit('end'); + })); +}; + +/* ---------------------------------------------------------------------------- + * Asset pipeline + * ------------------------------------------------------------------------- */ + +/* + * Build stylesheets from SASS source. + */ +gulp.task('assets:stylesheets', function() { + return gulp.src('src/assets/stylesheets/*.scss') + .pipe(gulpif(args.sourcemaps, sourcemaps.init())) + .pipe( + sass({ + includePaths: [ + 'bower_components/bourbon/app/assets/stylesheets/', + 'bower_components/quantum-colors/', + 'bower_components/quantum-shadows/' + ] + })) + .pipe( + postcss([ + autoprefix(), + mqpacker + ])) + .pipe(gulpif(args.sourcemaps, sourcemaps.write())) + .pipe(gulpif(args.production, mincss())) + .pipe(gulp.dest('dist/assets/stylesheets/')); +}); + +/* + * Build javascripts from Bower components and source. + */ +gulp.task('assets:javascripts', function() { + return gulp.src([ + + /* Bower components */ + 'bower_components/classlist/classList.js', + 'bower_components/fastclick/lib/fastclick.js', + 'bower_components/pegasus/dist/pegasus.js', + 'bower_components/lunr.js/lunr.js', + + /* Application javascripts */ + 'src/assets/javascripts/application.js', + 'src/assets/javascripts/standalone.js' + ]).pipe(gulpif(args.sourcemaps, sourcemaps.init())) + .pipe(concat('application.js')) + .pipe(gulpif(args.sourcemaps, sourcemaps.write())) + .pipe(gulpif(args.production, uglify())) + .pipe(gulp.dest('dist/assets/javascripts/')); +}); + +/* + * Create a customized modernizr build. + */ +gulp.task('assets:modernizr', [ + 'assets:stylesheets', + 'assets:javascripts' +], function() { + return gulp.src([ + 'dist/assets/stylesheets/application.css', + 'dist/assets/javascripts/application.js' + ]).pipe( + modernizr({ + options: [ + 'addTest', /* Add custom tests */ + 'fnBind', /* Use function.bind */ + 'html5printshiv', /* HTML5 support for IE */ + 'setClasses', /* Add CSS classes to root tag */ + 'testProp' /* Test for properties */ + ] + })) + .pipe(addsrc.append('bower_components/respond/dest/respond.src.js')) + .pipe(concat('modernizr.js')) + .pipe(gulpif(args.production, uglify())) + .pipe(gulp.dest('dist/assets/javascripts')); +}); + +/* + * Copy static assets like images and webfonts. + */ +gulp.task('assets:static', function() { + return gulp.src('src/assets/{fonts,images}/*.{jpg,png,gif}') + .pipe(gulpif(args.production, + minimage({ + optimizationLevel: 5, + progressive: true, + interlaced: true + }))) + .pipe(addsrc.append('src/assets/{fonts,images}/*.{eot,svg,ttf,woff}')) + .pipe(gulp.dest('dist/assets/')); +}); + +/* + * Minify views. + */ +gulp.task('assets:views', args.production ? [ + 'assets:revisions:clean', + 'assets:revisions' +] : [], function() { + return gulp.src([ + 'src/views/*.html' + ]).pipe( + minhtml({ + collapseBooleanAttributes: true, + removeComments: true, + removeScriptTypeAttributes: true, + removeStyleLinkTypeAttributes: true + })) + .pipe(compact()) + .pipe(gulpif(args.production, + addsrc.append([ + 'dist/manifest.json', + 'dist/**/*.css' + ]))) + .pipe(gulpif(args.production, collect())) + .pipe(ignore.exclude(/manifest\.json$/)) + .pipe(gulp.dest('dist')); +}); + +/* + * Clean outdated revisions. + */ +gulp.task('assets:revisions:clean', function() { + return gulp.src(['dist/**/*.{css,js,png,jpg,gif}']) + .pipe(ignore.include(/-[a-f0-9]{8}\.(css|js|png|jpg|gif)$/)) + .pipe(vinyl(clean)); +}); + +/* + * Revision assets after build. + */ +gulp.task('assets:revisions', [ + 'assets:revisions:clean', + 'assets:stylesheets', + 'assets:javascripts', + 'assets:static' +], function() { + return gulp.src(['dist/**/*.{css,js,png,jpg,gif}']) + .pipe(ignore.exclude(/-[a-f0-9]{8}\.(css|js|png|jpg|gif)$/)) + .pipe(rev()) + .pipe(gulp.dest('dist')) + .pipe(rev.manifest('manifest.json')) + .pipe(gulp.dest('dist')); +}); + +/* + * Build assets. + */ +gulp.task('assets:build', [ + 'assets:stylesheets', + 'assets:javascripts', + 'assets:modernizr', + 'assets:static', + 'assets:views' +]); + +/* + * Watch assets for changes and rebuild on the fly. + */ +gulp.task('assets:watch', function() { + + /* Rebuild stylesheets */ + gulp.watch([ + 'src/assets/stylesheets/**/*.scss' + ], ['assets:stylesheets']); + + /* Rebuild javascripts */ + gulp.watch([ + 'src/assets/javascripts/**/*.js', + 'bower.json' + ], ['assets:javascripts']); + + /* Copy static assets */ + gulp.watch([ + 'assets/assets/{fonts,images}/*' + ], ['assets:static']); + + /* Minify views */ + gulp.watch([ + 'src/views/*.html' + ], ['assets:views']); +}); + +/* ---------------------------------------------------------------------------- + * Application server + * ------------------------------------------------------------------------- */ + +/* + * Build application server. + */ +gulp.task('server:build', [ + 'assets:build' +], function() { + return child.spawnSync('mkdocs', ['build']); +}); + +/* + * Restart application server. + */ +gulp.task('server:spawn', function() { + if (server) + server.kill(); + + /* Spawn application server */ + server = child.spawn('mkdocs', ['serve', '-a', '0.0.0.0:8000']); + + /* Pretty print server log output */ + server.stdout.on('data', function(data) { + var lines = data.toString().split('\n') + for (var l in lines) + if (lines[l].length) + util.log(lines[l]); + }); + + /* Print errors to stdout */ + server.stderr.on('data', function(data) { + process.stdout.write(data.toString()); + }); +}); + +/* ---------------------------------------------------------------------------- + * Interface + * ------------------------------------------------------------------------- */ + +/* + * Build assets and application server. + */ +gulp.task('build', [ + 'assets:build', + 'server:build' +]); + +/* + * Start asset and server watchdogs. + */ +gulp.task('watch', [ + 'assets:build', +], function() { + return gulp.start([ + 'assets:watch', + 'server:spawn' + ]); +}); + +/* + * Build assets by default. + */ +gulp.task('default', ['build']); \ No newline at end of file diff --git a/bower.json b/bower.json new file mode 100644 index 000000000..2fc4ccaec --- /dev/null +++ b/bower.json @@ -0,0 +1,30 @@ +{ + "name": "materializr", + "version": "0.1.0", + "description": "A material design template for mkdocs", + "homepage": "https://github.com/squidfunk/materializr", + "authors": [ + "squidfunk " + ], + "license": "MIT", + "moduleType": [ + "globals" + ], + "ignore": [ + "**/.*", + "bower_components", + "node_modules" + ], + "dependencies": { + "classlist": "~2014.12.13", + "fastclick": "~1.0.6", + "lunr.js": "~0.5.10", + "pegasus": "~0.3.1", + "respond": "~1.4.2" + }, + "devDependencies": { + "bourbon": "~4.2.2", + "quantum-colors": "~1.0.1", + "quantum-shadows": "~1.0.0" + } +} diff --git a/package.json b/package.json new file mode 100644 index 000000000..f22d22303 --- /dev/null +++ b/package.json @@ -0,0 +1,47 @@ +{ + "name": "materializr", + "version": "0.1.0", + "description": "A material design template for mkdocs", + "homepage": "https://github.com/squidfunk/materializr", + "authors": [ + "squidfunk " + ], + "license": "MIT", + "main": "Gulpfile.js", + "scripts": { + "start": "gulp watch" + }, + "repository": { + "type": "git", + "url": "https://github.com/squidfunk/materializr.git" + }, + "devDependencies": { + "autoprefixer-core": "^5.1.11", + "css-mqpacker": "^3.1.0", + "del": "^1.1.1", + "gulp": "^3.8.11", + "gulp-add-src": "^0.2.0", + "gulp-concat": "^2.5.2", + "gulp-debug": "^2.0.1", + "gulp-htmlmin": "^1.1.1", + "gulp-if": "^1.2.5", + "gulp-ignore": "^1.2.1", + "gulp-image-optimization": "^0.1.3", + "gulp-match": "^0.2.1", + "gulp-minify-css": "^1.1.0", + "gulp-modernizr": "^1.0.0-alpha", + "gulp-plumber": "^1.0.0", + "gulp-postcss": "^5.1.3", + "gulp-remove-empty-lines": "0.0.2", + "gulp-rev": "^3.0.1", + "gulp-rev-collector": "^1.0.0", + "gulp-sass": "^2.0.3", + "gulp-sourcemaps": "^1.5.2", + "gulp-sync": "^0.1.4", + "gulp-uglify": "^1.2.0", + "gulp-util": "^3.0.4", + "node-notifier": "^4.2.1", + "vinyl-paths": "^1.0.0", + "yargs": "^3.8.0" + } +} diff --git a/src/assets/fonts/icon.eot b/src/assets/fonts/icon.eot new file mode 100755 index 0000000000000000000000000000000000000000..431eeca1c277d040190d69502b371a92bdec5bf8 GIT binary patch literal 2328 zcmaJ@Urbw782`>WrMEy!X=!^4>u5{=T-LI-l$JZN-Ee=Ha}1EtYLqD*bbvz302dZt z>VwIQ56%Y@_vAD_t&6WqjERf#GUMW6EKepr7>SEX8KfPxNy0EPWT;5y-wvB~{%ZmUw|<`L(=bpSe8f;q@T4pnV11zA{tw_zDF zu!a&Fq*1a4>uAMoT+k08h@hs?4_O|h6$-#0GI2f}HJTZ&6u!nbJGYWq-5J~2LL&$A zGYgsZRUF%q-^5Y3uzd9rIluH7@&y3R7mL}ayNm z{~hfO%bjB#-_zrKO%MAFT2 zJuvnoxeiSL^alL_B_FCI`4a{Re~U&Uxa|Ej055TWIi*r1ahk1H-CXG4ne0J*AP7s-C#a*I$Gb zOW~&AP7}8*H4}^zXQ|!C-j-<;S(K}Cg z9g~Oq#)jOCKL1W`Rx%g|0$mYn=7qKc#uiJn<*ieL@4aZ~)O*HWO80&A>nG#H8Mo3u z^d^lZ;Wc*&POp3DT+m=|Wj#aVVKIJCo^cR^o)9v&Ze$utk4=$4gc6&lQ@?z>v?#O* zHW`l*4M6P?yTj}tLKsqT4Zvp+w1U>tBl#sv6M0a^Oc8COt?7T{VodUTdQ=ZSS}oj~ zKhKdUcjr%BR=oMldvo*o>oIs79)m~X@h~w3o0a4Qoylakn@xgFCz#B3yUC;z$cmt1 zvw&n)^}tA`eII|Ajpa=#cR*k z#AIJ9X%ZO)q8oi!y}!9xz5j6Z`%g*Vy)JT~`g_;C>dzQ&8%iud-vuog&`ah41-ClT z^mKv1bTyF1Azix7!`)VUrEYoc0yvM{th`}N{LSlu(@zhYJD-lVM_47i%=w9^68b3T zD^EHk?0Gdcl2O&DBJPHK0b3D|)Ethbr##MeN6~Xx3fs2g)q;PFZkT~9n8}~RSMY!w zAx~%*jnOG3ni1aTlOpY{N@40<8+=(`6H%uVXFB zhw8Wmy5JI?HAK^l5*=z(Oz|f@R>utG{dKHC{CXWX;cr{4V=c;)b=(3mC@jt8b9=x1 zbarihDW7xoha&&|pKmm7#8cUYx0f?(`>zX)2BZ1hhHD|4%dTZMvh%KsS6yf3^5^pT vTnI*$i^K-F@S>5$D+Rw^WMBiwd6Zp*tJt4Wt|aHsl3zMPxXb*n`3(98(OP+C literal 0 HcmV?d00001 diff --git a/src/assets/fonts/icon.json b/src/assets/fonts/icon.json new file mode 100644 index 000000000..70727adea --- /dev/null +++ b/src/assets/fonts/icon.json @@ -0,0 +1,319 @@ +{ + "IcoMoonType": "selection", + "icons": [ + { + "icon": { + "paths": [ + "M661.333 597.333h-33.92l-11.733-11.733c41.813-48.427 66.987-111.36 66.987-180.267 0-153.173-124.16-277.333-277.333-277.333s-277.333 124.16-277.333 277.333 124.16 277.333 277.333 277.333c68.907 0 131.84-25.173 180.267-66.773l11.733 11.733v33.707l213.333 212.907 63.573-63.573-212.907-213.333zM405.333 597.333c-106.027 0-192-85.973-192-192s85.973-192 192-192 192 85.973 192 192-85.973 192-192 192z" + ], + "attrs": [], + "isMulticolor": false, + "tags": [ + "search" + ], + "grid": 24 + }, + "attrs": [], + "properties": { + "id": 1, + "order": 7, + "prevSize": 24, + "code": 58880, + "name": "search" + }, + "setIdx": 0, + "setId": 3, + "iconIdx": 1 + }, + { + "icon": { + "paths": [ + "M853.333 469.333h-519.253l238.293-238.293-60.373-60.373-341.333 341.333 341.333 341.333 60.373-60.373-238.293-238.293h519.253v-85.333z" + ], + "attrs": [], + "isMulticolor": false, + "tags": [ + "arrow-back" + ], + "grid": 24 + }, + "attrs": [], + "properties": { + "id": 2, + "order": 4, + "prevSize": 24, + "code": 58881, + "name": "arrow-back" + }, + "setIdx": 0, + "setId": 3, + "iconIdx": 2 + }, + { + "icon": { + "paths": [ + "M426.667 256l-60.373 60.373 195.627 195.627-195.627 195.627 60.373 60.373 256-256z" + ], + "attrs": [], + "isMulticolor": false, + "tags": [ + "chevron-right" + ], + "grid": 24 + }, + "attrs": [], + "properties": { + "id": 3, + "order": 9, + "prevSize": 24, + "code": 58882, + "name": "chevron-right" + }, + "setIdx": 0, + "setId": 3, + "iconIdx": 3 + }, + { + "icon": { + "paths": [ + "M810.667 273.707l-60.373-60.373-238.293 238.293-238.293-238.293-60.373 60.373 238.293 238.293-238.293 238.293 60.373 60.373 238.293-238.293 238.293 238.293 60.373-60.373-238.293-238.293z" + ], + "attrs": [], + "isMulticolor": false, + "tags": [ + "close" + ], + "grid": 24 + }, + "attrs": [], + "properties": { + "id": 4, + "order": 8, + "prevSize": 24, + "code": 58883, + "name": "close" + }, + "setIdx": 0, + "setId": 3, + "iconIdx": 4 + }, + { + "icon": { + "paths": [ + "M128 768h768v-85.333h-768v85.333zM128 554.667h768v-85.333h-768v85.333zM128 256v85.333h768v-85.333h-768z" + ], + "attrs": [], + "isMulticolor": false, + "tags": [ + "menu" + ], + "grid": 24 + }, + "attrs": [], + "properties": { + "id": 5, + "order": 10, + "prevSize": 24, + "code": 58884, + "name": "menu" + }, + "setIdx": 0, + "setId": 3, + "iconIdx": 5 + }, + { + "icon": { + "paths": [ + "M512 170.667l-60.373 60.373 238.293 238.293h-519.253v85.333h519.253l-238.293 238.293 60.373 60.373 341.333-341.333z" + ], + "attrs": [], + "isMulticolor": false, + "tags": [ + "arrow-forward" + ], + "grid": 24 + }, + "attrs": [], + "properties": { + "id": 6, + "order": 15, + "prevSize": 24, + "code": 58885, + "name": "arrow-forward" + }, + "setIdx": 0, + "setId": 3, + "iconIdx": 6 + }, + { + "icon": { + "paths": [ + "M1024 194.418c-37.676 16.708-78.164 28.002-120.66 33.080 43.372-26 76.686-67.17 92.372-116.23-40.596 24.078-85.556 41.56-133.41 50.98-38.32-40.83-92.922-66.34-153.346-66.34-116.022 0-210.088 94.058-210.088 210.078 0 16.466 1.858 32.5 5.44 47.878-174.6-8.764-329.402-92.4-433.018-219.506-18.084 31.028-28.446 67.116-28.446 105.618 0 72.888 37.088 137.192 93.46 174.866-34.438-1.092-66.832-10.542-95.154-26.278-0.020 0.876-0.020 1.756-0.020 2.642 0 101.788 72.418 186.696 168.522 206-17.626 4.8-36.188 7.372-55.348 7.372-13.538 0-26.698-1.32-39.528-3.772 26.736 83.46 104.32 144.206 196.252 145.896-71.9 56.35-162.486 89.934-260.916 89.934-16.958 0-33.68-0.994-50.116-2.94 92.972 59.61 203.402 94.394 322.042 94.394 386.422 0 597.736-320.124 597.736-597.744 0-9.108-0.206-18.168-0.61-27.18 41.056-29.62 76.672-66.62 104.836-108.748z" + ], + "attrs": [], + "isMulticolor": false, + "tags": [ + "twitter", + "brand", + "tweet", + "social" + ], + "defaultCode": 58525, + "grid": 24 + }, + "attrs": [], + "properties": { + "id": 7, + "order": 9, + "prevSize": 24, + "code": 58886, + "ligatures": "twitter, brand11", + "name": "twitter" + }, + "setIdx": 0, + "setId": 3, + "iconIdx": 7 + }, + { + "icon": { + "paths": [ + "M810.667 384h-170.667v-256h-256v256h-170.667l298.667 298.667 298.667-298.667zM213.333 768v85.333h597.333v-85.333h-597.333z" + ], + "attrs": [], + "isMulticolor": false, + "tags": [ + "file-download" + ], + "grid": 24 + }, + "attrs": [], + "properties": { + "id": 8, + "order": 10, + "prevSize": 24, + "code": 58888, + "name": "download" + }, + "setIdx": 0, + "setId": 3, + "iconIdx": 8 + }, + { + "icon": { + "paths": [ + "M512 736.853l263.68 159.147-69.973-299.947 232.96-201.813-306.773-26.027-119.893-282.88-119.893 282.88-306.773 26.027 232.96 201.813-69.973 299.947z" + ], + "attrs": [], + "isMulticolor": false, + "tags": [ + "star" + ], + "grid": 24 + }, + "attrs": [], + "properties": { + "id": 9, + "order": 9, + "prevSize": 24, + "code": 58889, + "name": "star" + }, + "setIdx": 0, + "setId": 3, + "iconIdx": 9 + }, + { + "icon": { + "paths": [ + "M598 726l84-172h-128v-256h256v256l-84 172h-128zM256 726l86-172h-128v-256h256v256l-86 172h-128z" + ], + "attrs": [], + "isMulticolor": false, + "tags": [ + "format_quote" + ], + "defaultCode": 57924, + "grid": 24 + }, + "attrs": [], + "properties": { + "order": 10, + "ligatures": "format_quote", + "prevSize": 24, + "name": "quote", + "id": 247, + "code": 58896 + }, + "setIdx": 1, + "setId": 2, + "iconIdx": 247 + }, + { + "icon": { + "paths": [ + "M365.714 694.857q0 22.857-7.143 46.857t-24.571 43.429-41.429 19.429-41.429-19.429-24.571-43.429-7.143-46.857 7.143-46.857 24.571-43.429 41.429-19.429 41.429 19.429 24.571 43.429 7.143 46.857zM731.429 694.857q0 22.857-7.143 46.857t-24.571 43.429-41.429 19.429-41.429-19.429-24.571-43.429-7.143-46.857 7.143-46.857 24.571-43.429 41.429-19.429 41.429 19.429 24.571 43.429 7.143 46.857zM822.857 694.857q0-68.571-39.429-116.571t-106.857-48q-23.429 0-111.429 12-40.571 6.286-89.714 6.286t-89.714-6.286q-86.857-12-111.429-12-67.429 0-106.857 48t-39.429 116.571q0 50.286 18.286 87.714t46.286 58.857 69.714 34.286 80 16.857 85.143 4h96q46.857 0 85.143-4t80-16.857 69.714-34.286 46.286-58.857 18.286-87.714zM950.857 594.286q0 118.286-34.857 189.143-21.714 44-60.286 76t-80.571 49.143-97.143 27.143-98 12.571-95.429 2.571q-44.571 0-81.143-1.714t-84.286-7.143-87.143-17.143-78.286-29.429-69.143-46.286-49.143-65.714q-35.429-70.286-35.429-189.143 0-135.429 77.714-226.286-15.429-46.857-15.429-97.143 0-66.286 29.143-124.571 61.714 0 108.571 22.571t108 70.571q84-20 176.571-20 84.571 0 160 18.286 60-46.857 106.857-69.143t108-22.286q29.143 58.286 29.143 124.571 0 49.714-15.429 96 77.714 91.429 77.714 227.429z" + ], + "attrs": [], + "isMulticolor": false, + "width": 951, + "tags": [ + "github-alt" + ], + "grid": 0 + }, + "attrs": [], + "properties": { + "order": 13, + "id": 1, + "prevSize": 24, + "code": 58887, + "name": "github" + }, + "setIdx": 2, + "setId": 1, + "iconIdx": 1 + } + ], + "height": 1024, + "metadata": { + "name": "icon" + }, + "preferences": { + "showGlyphs": true, + "showQuickUse": true, + "showQuickUse2": true, + "showSVGs": true, + "fontPref": { + "prefix": "icon-", + "metadata": { + "fontFamily": "icon", + "majorVersion": 1, + "minorVersion": 0 + }, + "metrics": { + "emSize": 1024, + "baseline": 6.25, + "whitespace": 50 + }, + "ie7": true, + "showSelector": true, + "selector": "class", + "classSelector": ".icon", + "showMetrics": true, + "showMetadata": true, + "cssVars": true, + "embed": false, + "noie8": false + }, + "imagePref": { + "prefix": "icon-", + "png": true, + "useClassSelector": true, + "color": 4473924, + "bgColor": 16777215 + }, + "historySize": 100, + "showCodes": true, + "gridSize": 16 + } +} \ No newline at end of file diff --git a/src/assets/fonts/icon.svg b/src/assets/fonts/icon.svg new file mode 100755 index 000000000..31f4dbe97 --- /dev/null +++ b/src/assets/fonts/icon.svg @@ -0,0 +1,21 @@ + + + +Generated by IcoMoon + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/assets/fonts/icon.ttf b/src/assets/fonts/icon.ttf new file mode 100755 index 0000000000000000000000000000000000000000..446da0f602bd21872704b175abe8da770c29ae8f GIT binary patch literal 2176 zcmaJ?O>7%Q6n-<~c%8&Qv15Ck)Q#=L7Ucx_Mv4|2;Z^$D9@qnTVC7R9=NUDK^graxmsArYR7~O z$~>QYExWxAR(K!fU%8ymuH~kae+91bt@m9V98t}Ro6n{1EsvE|^VAhye+kkojhliyO+2#HN-$4?r4Jre zlC=^^Co5DS_r?Cu06Pa~(AP+WQ6l3UCh8{J#W0hM z#AZc6B&Pz5XbVU^L~H;y7#pRDcp!nH8gQoEo~Yh+(&wB$+CMSuVf6X8^YfCyG#KoT z+OjVg51HDmt=6|r554=Mp-bBEB-Y)&>t@5&96zsAK+Z3Swklkhu5Fr9-xB=j| z3R*$y?Ue!&9us*;#*-r2MSIKt=*74c@b;<^oZGD2n?KKy7!T)9LRO;r%1_qj>o;=n zJUj=_#Pi|76zn#V7j$N`!(lNCI-Ov)I2>lPP9ST7iY)??MYRiaebPzCD}AwnzL&dB z_DPmbr}IcKAcf~6QXqK5>Fl%=z4m|<49apS6hG?sMWYf@kE_!=*>QL@5=qTooSjI9 zBdMN_$%mrD(P_1IIvnD&(Wz)uuhr_K(NnR2-)=J)G)M-6&F&Ax7O$P@ce~Bzwl+p7 z(YEOIX3Jrx|ID=;uSH@fM(kqLYKhqGBPU|vxf^(El(Bz8*t-Jg@nm_;9<#TV5InIS z7An=DL_#EVaFb?mgb383RwkiZ5sxpP$uxvmiKTh(`CFLmZznAxqd;`y4{GA%}e4%PnXzFYeR^X);I1?fAW1p`LOJfYxG8O_WV3Cz}l8DyFAEuQX{IxBt4 zdl$fU?6c|{rsO}oA2|JdzqRWruRp{t;cd=uM3pc`xnKFAL&BMNQ!|-Vi>l&bC>L>* z@Jh`iFF%!Wt=o#7>(V&(l&CiRWAwlrT*H(61$+(n$uaVncGEbWQL>rfJ-#T?ld2S< zF&W{jMomQVQtPAmO-?uT4E0AFScCZ025!N7M&H0%)DJgs8+5~EylaT26*W4vsF;Eg zCK{NbexQLhh+l8u7O-Pis{UHkry95o;!s>!DCA)U7N7w6Om1UyrI2?Igrksw9BjZQ zn$Q4lTsRETX6I%+lUusFn%#gI3|fM#unJk&Xm%Jc7%Q6n-<~c542Ov6RFLE_onSO31w~E{%j%T^6t=PqF9X zQCcMmA{Wka?825?xj>_M7;vX3VgjCB{cd|>uhCHaJiEBIG9ry%yEL8krk^sYGz19R znw8a5mIBB_N(xW%csfU+gt@=Q!kEt?Oy4JskYpl4eLW^>w{_Ej_@FG>MOpIp1e1xu zfw;qN)B5N~J#B7(-`V`|Q2uNm_Ctx;K-8>wnFRju*1 zhI?CrGArS_3y2vIlLAx4;FB6b@BBDoY`!nvT-O~fW(1Mv}>OaznY zssUHpE%F?;T`>43S_rnkL*a`2t!jGYGG`19Gm z4}bZ1g1D1*`n$oRv8DXhF2U{h4xI}doo%dVXd)^m56ZJHVl)s!#@EeEL+R0J5{gmc z@O2uNwcueF$8BdDn5FIW5!;1+i z=<88EcyG6HYyLb#;@q7-Nm=pcD?eVFuiuQpU3HxI)SVRDz*wJR&`#O?Ujx@U+j(d_rB11yjQYzxLk)qK`C-EDg{G_T&@ml$>#`4 zp^z+x!->NIe=H`Ubh|rz6YU2_qS5rsg_-eGB%1DSpLi%bogFq?htnxO9i5293|g%r z7CR9S1{`*yQG;SM+8u#leE#aGK99#@X>Dbc5^amYV6h%_1x{VP{&F;aY}g^jY}Tm5 zF?=i@nZ1s;Mg{99jI}F(0Z*3C;RgFy0PSSctw2 zS}>xQ%mWHuwWHaY5`md|D2rXTvcw(LU_w}7m`o=@7 z5?3z*IuvYqHSHI(I-^qD4aX(aGG3_#>?=>kxYjLYo^u)09mT5^{}|o) zAG?Yt`E&Rh?vo?rZ`wr@bXtjKhIjd*D37yJ2F=CvcsjrE#&T{ArqO8u z-hgGu!P-UTIW4mPl#NA40_ V!}g4l-#N78$wY9M`Cs!X@(*P3Z@~Zn literal 0 HcmV?d00001 diff --git a/src/assets/images/favicon-16x16.png b/src/assets/images/favicon-16x16.png new file mode 100755 index 0000000000000000000000000000000000000000..2719887cb452042037e88ee4842811077c08c649 GIT binary patch literal 317 zcmV-D0mA-?P)1pw7>423!iW$IhEh5g4+ddFCU2d30-qu0=-Pv1$WS_!j2&wqK^Ss@8p}}PfI}jj zbO-_Cq!8#-`hf=VNI#zhe?AVtZnqOfQQQq|ABJHKh~;v5J2a(KEv4K8P?qHl@C9sp z%V@1Vt@S;y9@uADmL7oHn>qqyZ!ZVtUNUj@V}Ho62b^l{ftq905#aUCoXovo$8=pM zj4@+l%s7goSKtuG@td_)SZjqbW?WU3r<7U%ha^c}Hk-|P`}utS0CbMyZ1X%1`!<`+ z9)W|Da-C&aaCW(ETX!;H74Iu&tqa;c8}0bN`>xC(Baic@haog`xsaTU5)i)67E zg_H;#O2N_;N@DECqUD-OqC@G>`@k7)!gJ2a;p74g2IG%$(1*!n;%hdWaR5#mZf!M3hAcg3#*s`{uu9iC(W4 rh{xmCw3kdKFJ)QYZ1ETj#=qhVs^!43){E$I00000NkvXXu0mjf2*l#b literal 0 HcmV?d00001 diff --git a/src/assets/javascripts/application.js b/src/assets/javascripts/application.js new file mode 100644 index 000000000..e249885f1 --- /dev/null +++ b/src/assets/javascripts/application.js @@ -0,0 +1,518 @@ +/* + * Copyright (c) 2016 Martin Donath + * + * 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. + */ + +/* Hey, there's your missing semicolon, lunr.js! */ +; + +/* Truncate a string after the given number of characters */ +String.prototype.truncate = function(n) { + if (this.length > n) { + while (this[n] != ' ' && --n > 0); + return this.substring(0, n) + '…'; + } + return this; +} + +/* Wrap an HTMLElement around each element in an HTMLElement array */ +HTMLElement.prototype.wrap = function (elms) { + if (!elms.length) elms = [elms]; + for (var i = elms.length - 1; i >= 0; i--) { + var child = (i > 0) ? this.cloneNode(true) : this; + var el = elms[i]; + + /* Cache current parent and sibling */ + var parent = el.parentNode, + sibling = el.nextSibling; + + /* Wrap the element and remove it from its current parent */ + child.appendChild(el); + if (sibling) { + parent.insertBefore(child, sibling); + } else { + parent.appendChild(child); + } + } +} + +/* ---------------------------------------------------------------------------- + * Application logic + * ------------------------------------------------------------------------- */ + +/* Initialize application upon DOM ready */ +document.addEventListener('DOMContentLoaded', function() { + 'use strict'; + + /* Test for iOS */ + Modernizr.addTest('ios', function() { + return !!navigator.userAgent.match(/(iPad|iPhone|iPod)/g); + }); + + /* Test for web application context */ + Modernizr.addTest('standalone', function() { + return !!navigator.standalone; + }); + + /* Attack FastClick to mitigate 300ms delay on touch devices */ + FastClick.attach(document.body); + + /* Grab relevant elements from the DOM */ + var toggle = document.getElementById('toggle-search'), + reset = document.getElementById('reset-search'), + drawer = document.querySelector('.drawer'), + anchors = document.querySelectorAll('.anchor'), + search = document.querySelector('.search .field'), + query = document.querySelector('.query'), + meta = document.querySelector('.results .meta'); + +/* ---------------------------------------------------------------------------- + * Initialize drawer + * ------------------------------------------------------------------------- */ + + /* Automatically close drawer when anchors are clicked */ + Array.prototype.forEach.call(anchors, function(item) { + item.querySelector('a').addEventListener('click', function() { + document.getElementById('toggle-drawer').checked = false; + document.body.classList.remove('toggle-drawer'); + }); + }); + + /* Align drawer to window offset */ + var pageYOffsetLast = window.pageYOffset; + var align = function() { + var boundary = window.pageYOffset + window.innerHeight; + var clipping = Math.max(0, window.innerHeight - drawer.offsetHeight); + + /* Ensure alignment with footer if at end of document */ + if (boundary > document.body.clientHeight - (96 - clipping)) { + if (drawer.style.position != 'absolute') { + drawer.style.position = 'absolute'; + drawer.style.top = null; + drawer.style.bottom = 0; + } + + /* Pin drawer to top, if window is higher than drawer */ + } else if (drawer.offsetHeight < window.innerHeight) { + if (drawer.style.position != 'fixed') { + drawer.style.position = 'fixed'; + drawer.style.top = 0; + drawer.style.bottom = null; + } + + /* If the drawer is not pinned, check if we need to pin it */ + } else if (drawer.style.position != 'fixed') { + + /* Pin drawer to bottom of window */ + if (boundary > drawer.offsetTop + drawer.offsetHeight) { + drawer.style.position = 'fixed'; + drawer.style.top = null; + drawer.style.bottom = -96 + 'px'; + + /* Pin drawer to top of window */ + } else if (window.pageYOffset < drawer.offsetTop) { + drawer.style.position = 'fixed'; + drawer.style.top = 0; + drawer.style.bottom = null; + } + + /* If the drawer is pinned, check if we have to unpin it */ + } else { + if (window.pageYOffset > pageYOffsetLast) { + if (drawer.style.top) { + drawer.style.position = 'absolute'; + drawer.style.top = Math.max(0, pageYOffsetLast) + 'px'; + drawer.style.bottom = null; + } + } else if (drawer.style.bottom) { + drawer.style.position = 'absolute'; + drawer.style.top = (boundary - drawer.offsetHeight) + 'px'; + drawer.style.bottom = null; + } + } + + /* Update last offset (mitigiate negative offsets in Safari) */ + pageYOffsetLast = Math.max(0, window.pageYOffset); + } + + /* Check for media query events */ + var check = function() { + var main = document.querySelector('.main'); + window.removeEventListener('scroll', align); + + /* Reset drawer position when entering collapsed mode */ + if (matchMedia("only screen and (max-width: 959px)").matches) { + drawer.style.position = null; + drawer.style.top = null; + drawer.style.bottom = null; + + /* Check if the scroll handler needs to be registered */ + } else if (drawer.offsetHeight + 96 < main.offsetHeight) { + window.addEventListener('scroll', align); + align(); + } + } + + /* Register resize handler and fire once */ + window.addEventListener('resize', check); + check(); + +/* ---------------------------------------------------------------------------- + * Initialize search index + * ------------------------------------------------------------------------- */ + + /* Initialize index */ + var initialize = function() { + pegasus(base_url + '/mkdocs/search_index.json').then( + + /* Request successful, we got the index */ + function(data, xhr) { + + /* Create index */ + var index = lunr(function() { + this.field('title', { boost: 10 }); + this.field('text'); + this.ref('location'); + }); + + /* Index articles */ + var articles = {}; + data.docs.map(function(article) { + articles.location = base_url + article.location; + articles[article.location] = article; + index.add(article); + }); + + /* Register keyhandler to execute search on key up */ + query.addEventListener('keyup', function() { + var container = document.querySelector('.results .list'); + while (container.firstChild) + container.removeChild(container.firstChild); + + /* Abort, if the query is empty */ + var bar = document.querySelector('.bar.search'); + if (!query.value.length) { + while (meta.firstChild) + meta.removeChild(meta.firstChild); + + /* Restore state */ + bar.classList.remove('non-empty'); + return; + } + + /* Show reset button */ + bar.classList.add('non-empty'); + + /* Execute search */ + var results = index.search(query.value); + results.map(function(result) { + var article = articles[result.ref]; + + /* Create article container */ + var teaser = document.createElement('article'); + teaser.classList.add('result'); + + /* Create title element */ + var title = document.createElement('h1'); + title.innerHTML = article.title; + teaser.appendChild(title); + + /* Create url element */ + var url = document.createElement('span'); + url.innerHTML = window.location.host + + article.location.split('#')[0]; + teaser.appendChild(url); + + // /* Create text element */ + // var text = document.createElement('p'); + // text.innerHTML = article.text.truncate(140); + // teaser.appendChild(text); + + /* Create a link referring to the article */ + var link = document.createElement('a'); + link.href = article.location; + link.appendChild(teaser); + + /* Close search and jump to anchor when on same page */ + var parts = article.location.split('#'); + if (parts[0] == window.location.pathname) { + link.addEventListener('click', function(e) { + document.body.classList.remove('toggle-search'); + document.body.classList.remove('locked'); + toggle.checked = false; + + /* Prevent default to intercept scroll-to behaviour and + stop propagation, as this interferes with the link-lock in + the web application context, which opens all internal links + inside the same context */ + e.preventDefault(); + e.stopPropagation(); + + /* Scroll to chapter, if given */ + if (parts.length != 1) { + var chapter = document.getElementById(parts[1]); + if (chapter) { + + /* Scroll to chapter, but wait for 100ms to prevent flashes + on iOS. A short timeout seems to do the trick */ + setTimeout(function() { + chapter.scrollIntoView && chapter.scrollIntoView() || + window.scrollTo(0, chapter.offsetTop); + }, 100); + } + } + }); + } + + /* Add article to search results */ + container.appendChild(link); + }); + + /* Show number of search results */ + var number = document.createElement('strong'); + number.innerHTML = results.length + ' search result' + + (results.length != 1 ? 's' : ''); + + /* Update number */ + while (meta.firstChild) + meta.removeChild(meta.firstChild); + meta.appendChild(number); + }); + }, + + /* Handle error */ + function(data, xhr) { + console.error(data, xhr.status); + } + ); + + /* Remove listener, as we only have to initialize once */ + toggle.removeEventListener('click', initialize); + }; + + /* Initialize on first click */ + toggle.addEventListener('click', initialize); + +/* ---------------------------------------------------------------------------- + * Initialize search modal + * ------------------------------------------------------------------------- */ + + /* Intercept click on search mode toggle */ + var offset = 0; + toggle.addEventListener('click', function(e) { + var list = document.body.classList; + var lock = !matchMedia('only screen and (min-width: 960px)').matches; + + /* Exiting search mode */ + if (list.contains('locked')) { + list.remove('locked'); + + /* Scroll to former position, but wait for 100ms to prevent flashes + on iOS. A short timeout seems to do the trick */ + if (lock) + setTimeout(function() { + window.scrollTo(0, offset); + }, 100); + + /* Entering search mode */ + } else { + offset = window.scrollY; + + /* First timeout: scroll to top after transition, to omit flickering */ + if (lock) + setTimeout(function(){ + window.scrollTo(0, 0); + }, 400); + + /* Second timeout: Lock body after finishing transition and scrolling to + top and focus input field. Sadly, the focus event is not dispatched + on iOS Safari and there's nothing we can do about it. */ + setTimeout(function() { + + /* This additional check is necessary to handle fast subsequent clicks + on the toggle and the timeout to lock the body must be canceled */ + if (this.checked) { + if (lock) + list.add('locked'); + setTimeout(function() { + query.focus(); + }, 200); + } + }.bind(this), 450); + } + }); + + /* Dispatch input focus on touch of search section */ + search.addEventListener('touchstart', function() { + query.focus(); + }); + + /* Exit search mode when pressing ESC */ + window.addEventListener('keyup', function(e) { + var code = e.keyCode || e.which; + if (code == 27) { + document.body.classList.remove('toggle-search'); + document.body.classList.remove('locked'); + toggle.checked = false; + } + }); + + /* Delete search results upon click on "x" */ + var empty = document.getElementById('reset-search'); + empty.addEventListener('click', function() { + var container = document.querySelector('.results .list'); + while (container.firstChild) + container.removeChild(container.firstChild); + + /* Hide search button */ + var bar = document.querySelector('.bar.search'); + bar.classList.remove('non-empty'); + + /* Reset number of search results */ + meta.innerHTML = ''; + + /* Empty search input */ + query.value = ''; + query.focus(); + }); + +/* ---------------------------------------------------------------------------- + * Initialize scroll spy + * ------------------------------------------------------------------------- */ + + /* Retrieve vertical offset of article chapters */ + var chapters = document.querySelectorAll('h2'); + chapters = Array.prototype.map.call(chapters, function(item) { + return item.offsetTop; + }); + + /* Update currently active chapter, if the new chapter is two thirds + into the viewport - account for iOS web application context */ + var visible = null; + document.addEventListener('scroll', function() { + var offset = window.scrollY + (window.innerHeight / 3), + active = chapters.length - 1; + for (var c = 0; c < active; c++) + if (offset < chapters[c + 1]) + active = c; + + /* Update anchors, if a new chapter became visible */ + if (active != visible) { + visible = active; + Array.prototype.forEach.call(anchors, function(item, index) { + var link = item.querySelector('a'); + if (index != visible || link.classList.add('current')) + link.classList.remove('current'); + }); + } + }); + +/* ---------------------------------------------------------------------------- + * Fix syntax highlighting + * ------------------------------------------------------------------------- */ + + /* Fix highlighting for function calls */ + var functions = document.querySelectorAll('.n + .p'); + Array.prototype.forEach.call(functions, function(item) { + var text = item.innerText || item.textContent; + if (text && text[0] == '(') + item.previousSibling.classList.add('f'); + }); + +/* ---------------------------------------------------------------------------- + * Progressive structure enhancement + * ------------------------------------------------------------------------- */ + + /* Wrap all data tables */ + var tables = document.querySelectorAll('table'); + Array.prototype.forEach.call(tables, function(item) { + var wrapper = document.createElement('div'); + wrapper.classList.add('data'); + wrapper.wrap(item); + }); + +/* ---------------------------------------------------------------------------- + * Fix overflow scrolling on iOS + * ------------------------------------------------------------------------- */ + + /* Force 1px scroll offset to trigger overflow scrolling */ + if (Modernizr.ios) { + var scrollable = document.querySelectorAll( + '.scrollable, .standalone .article'); + Array.prototype.forEach.call(scrollable, function(item) { + item.addEventListener('touchstart', function() { + var top = this.scrollTop; + + /* We're at the top of the container */ + if (top == 0) { + this.scrollTop = 1; + + /* We're at the bottom of the container */ + } else if (top + this.offsetHeight == this.scrollHeight) { + this.scrollTop = top - 1; + } + }); + }); + } + + /* Prevent scrolling on project, overlay and header */ + var prevented = document.querySelectorAll('.project, .overlay, .header'); + Array.prototype.forEach.call(prevented, function(item) { + item.addEventListener('touchmove', function(e) { + e.preventDefault(); + }); + }); + +/* ---------------------------------------------------------------------------- + * Fallback for browsers that don't support :checked + * ------------------------------------------------------------------------- */ + + /* Set representative class on body for active toggle */ + var toggles = document.querySelectorAll('.toggle'); + Array.prototype.forEach.call(toggles, function(item) { + item.addEventListener('click', function() { + document.body.classList.toggle(this.id); + }); + }); + +/* ---------------------------------------------------------------------------- + * Initialize GitHub star button + * ------------------------------------------------------------------------- */ + + /* Get Stars for current repository */ + pegasus('https://api.github.com/repos/' + repo_id + '/stargazers').then( + + /* Request successful, we got the stars */ + function(data, xhr) { + var count = data.length; + if (count > 1000) + count = (count / 1000).toFixed(1) + "k"; + + /* Set number of stars */ + var stars = document.querySelector('.repo-stars .count'); + stars.innerHTML = count; + }, + + /* Handle error */ + function(data, xhr) { + console.error(data, xhr.status); + } + ); +}); \ No newline at end of file diff --git a/src/assets/javascripts/standalone.js b/src/assets/javascripts/standalone.js new file mode 100644 index 000000000..0ed044874 --- /dev/null +++ b/src/assets/javascripts/standalone.js @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2016 Martin Donath + * + * 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. + */ + +/* ---------------------------------------------------------------------------- + * Taken and adapted from https://gist.github.com/kylebarrow/1042026 + * ------------------------------------------------------------------------- */ + +/* Detect standalone mode */ +if (('standalone' in window.navigator) && window.navigator.standalone) { + + /* If you want to prevent remote links in standalone web apps opening + Mobile Safari, change 'remotes' to true */ + var node, remotes = false; + + /* Bind to document */ + document.addEventListener('click', function(event) { + node = event.target; + + /* Bubble up until we hit link or top HTML element. Warning: BODY element + is not compulsory so better to stop on HTML */ + while (node.nodeName !== 'A' && node.nodeName !== 'HTML') { + node = node.parentNode; + } + if ('href' in node && node.href.indexOf('http') !== -1 && ( + node.href.indexOf(document.location.host) !== -1 || remotes)) { + event.preventDefault(); + document.location.href = node.href; + } + }, false); +} \ No newline at end of file diff --git a/src/assets/stylesheets/_highlight.scss b/src/assets/stylesheets/_highlight.scss new file mode 100644 index 000000000..257ef7398 --- /dev/null +++ b/src/assets/stylesheets/_highlight.scss @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2016 Martin Donath + * + * 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. + */ + +/* ---------------------------------------------------------------------------- + * Code highlighter + * ------------------------------------------------------------------------- */ + +/* + * Comments + */ +.c, +.cm { + color: #666; +} + +/* + * Keywords + */ +.k { + color: $pink-500; +} + +/* + * Types + */ +.kt, .kd { + color: $light-blue-300; +} + +/* + * Strings + */ +.s { + color: $lime-300; +} + +/* + * Operators and names + */ +.o, .na { + color: $white-light; +} + +/* + * Numbers + */ +.mi { + color: $deep-purple-300; +} + +/* + * Functions + */ +.n.f { + color: saturate(mix($green-300, $teal-300, 50%), 50%); +} \ No newline at end of file diff --git a/src/assets/stylesheets/_palette.scss b/src/assets/stylesheets/_palette.scss new file mode 100644 index 000000000..9f47ff50f --- /dev/null +++ b/src/assets/stylesheets/_palette.scss @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2016 Martin Donath + * + * 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. + */ + +/* ---------------------------------------------------------------------------- + * Palette + * ------------------------------------------------------------------------- */ + +/* + * Primary and accent color + */ +$primary: $indigo-500; +$accent: $teal-500; + +/* + * Black opacities + */ +$black: rgba(black, 0.87); +$black-light: rgba(black, 0.54); +$black-lighter: rgba(black, 0.26); +$black-lightest: rgba(black, 0.12); + +/* + * White opacities + */ +$white: rgba(white, 1.00); +$white-light: rgba(white, 0.70); +$white-lighter: rgba(white, 0.30); +$white-lightest: rgba(white, 0.12); \ No newline at end of file diff --git a/src/assets/stylesheets/_print.scss b/src/assets/stylesheets/_print.scss new file mode 100644 index 000000000..f30286eef --- /dev/null +++ b/src/assets/stylesheets/_print.scss @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2016 Martin Donath + * + * 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. + */ + +/* ---------------------------------------------------------------------------- + * Print overrides + * ------------------------------------------------------------------------- */ + +/* + * Print styles + */ +@media print { + + /* + * Hide non-relevant elements + */ + .header, .project, .footer { + display: none; + } + + /* + * Article + */ + .article { + + /* + * Remove color in all code blocks + */ + pre, pre * { + color: $black !important; + } + + /* + * Border-radius makes this table entirely black on paper + */ + table { + border-radius: none; + box-shadow: none; + + /* + * Color header + */ + th { + color: $primary; + } + } + } +} \ No newline at end of file diff --git a/src/assets/stylesheets/_reset.scss b/src/assets/stylesheets/_reset.scss new file mode 100644 index 000000000..b2f395101 --- /dev/null +++ b/src/assets/stylesheets/_reset.scss @@ -0,0 +1,143 @@ +/* + * Copyright (c) 2016 Martin Donath + * + * 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. + */ + +/* ---------------------------------------------------------------------------- + * Resets + * ------------------------------------------------------------------------- */ + +/* + * Enfore correct box model - the prefixed versions are necessary for older + * browsers, i.e. Chrome < 10, Firefox < 29, Safari < 6 and Android < 4 + */ +html { + box-sizing: border-box; + -moz-box-sizing: border-box; + -webkit-box-sizing: border-box; +} + +/* + * All elements shall inherit the document default + */ +*, *:before, *:after { + box-sizing: inherit; + -moz-box-sizing: inherit; + -webkit-box-sizing: inherit; +} + +/* + * 16px --> 10px, browser default + */ +html { + font-size: 62.5%; + text-size-adjust: none; +} + +/* + * Reset spacing and borders for all tags + */ +html, body, div, span, applet, object, iframe, +h1, h2, h3, h4, h5, h6, p, blockquote, pre, +a, abbr, acronym, address, big, cite, code, +del, dfn, em, img, ins, kbd, q, s, samp, +small, strike, strong, sub, sup, tt, var, +b, u, i, center, +dl, dt, dd, ol, ul, li, +fieldset, form, label, legend, +table, caption, tbody, tfoot, thead, tr, th, td, +article, aside, canvas, details, embed, +figure, figcaption, footer, header, hgroup, main, +menu, nav, output, ruby, section, summary, +time, mark, audio, video { + margin: 0; + padding: 0; + border: 0; +} + +/* + * Reset list styles + */ +ul { + list-style: none; +} + +/* + * Reset table styles + */ +table { + border-collapse: collapse; + border-spacing: 0; +} + +/* + * Reset table cell styles + */ +td { + text-align: left; + font-weight: normal; + vertical-align: middle; +} + +/* + * Reset (native) button styles + */ +button { + outline: 0; + padding: 0; + + background: transparent; + border: none; + + font-size: inherit; +} + +/* + * Reset (native) input styles + */ +input { + @include appearance(none); + + outline: none; + border: none; +} + +/* + * Reset link styles + */ +a { + text-decoration: none; + color: inherit; +} + +/* + * Reset tap outlines on iOS and Android + */ +a, button, label, input { + -webkit-tap-highlight-color: rgba(white, 0); + -webkit-tap-highlight-color: transparent; +} + +/* + * Reset headlines + */ +h1, h2, h3, h4, h5, h6 { + font-weight: inherit; +} \ No newline at end of file diff --git a/src/assets/stylesheets/_shame.scss b/src/assets/stylesheets/_shame.scss new file mode 100644 index 000000000..14a99e659 --- /dev/null +++ b/src/assets/stylesheets/_shame.scss @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2016 Martin Donath + * + * 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. + */ + +/* ---------------------------------------------------------------------------- + * Here should be nothing + * ------------------------------------------------------------------------- */ + +/* [tablet portait+]: Slightly larger project name */ +@include break-from-device(tablet landscape) { + .project .name { + color: $black; + } +} + +@include break-from-device(tablet landscape) { + .button-menu { + display: none; + } +} \ No newline at end of file diff --git a/src/assets/stylesheets/application.scss b/src/assets/stylesheets/application.scss new file mode 100644 index 000000000..83098fbc4 --- /dev/null +++ b/src/assets/stylesheets/application.scss @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2016 Martin Donath + * + * 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. + */ + +/* ---------------------------------------------------------------------------- + * Dependencies + * ------------------------------------------------------------------------- */ + +@import "bourbon"; +@import "quantum-colors"; +@import "quantum-shadows"; + +/* ---------------------------------------------------------------------------- + * Application + * ------------------------------------------------------------------------- */ + +@import "reset"; +@import "palette"; +@import "highlight"; + +@import "fonts/icon"; + +@import "mixins/break"; + +@import "modules/base"; +@import "modules/drawer"; +@import "modules/article"; +@import "modules/search"; + +@import "print"; + +@import "shame"; \ No newline at end of file diff --git a/src/assets/stylesheets/fonts/_icon.scss b/src/assets/stylesheets/fonts/_icon.scss new file mode 100644 index 000000000..b4b74b50c --- /dev/null +++ b/src/assets/stylesheets/fonts/_icon.scss @@ -0,0 +1,137 @@ +/* + * Copyright (c) 2016 Martin Donath + * + * 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. + */ + +/* ---------------------------------------------------------------------------- + * Font faces + * ------------------------------------------------------------------------- */ + +/* + * Icon font + */ +@font-face { + font-family: 'Icon'; + src: url('/assets/fonts/icon.eot?52m981'); + src: url('/assets/fonts/icon.eot?#iefix52m981') format('embedded-opentype'), + url('/assets/fonts/icon.woff?52m981') format('woff'), + url('/assets/fonts/icon.ttf?52m981') format('truetype'), + url('/assets/fonts/icon.svg?52m981#icon') format('svg'); + font-weight: normal; + font-style: normal; +} + +/* ---------------------------------------------------------------------------- + * Representational classes + * ------------------------------------------------------------------------- */ + +/* + * Base icon class + */ +.icon { + font-family: 'Icon'; + speak: none; + font-style: normal; + font-weight: normal; + font-variant: normal; + text-transform: none; + line-height: 1; + + /* Better Font Rendering */ + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +/* + * Magnifying glass + */ +.icon-search:before { + content: "\e600"; +} + +/* + * Back arrow + */ +.icon-back:before { + content: "\e601"; +} + +/* + * Link indicator + */ +.icon-link:before { + content: "\e602"; +} + +/* + * Close button + */ +.icon-close:before { + content: "\e603"; +} + +/* + * Hamburger icon + */ +.icon-menu:before { + content: "\e604"; +} + +/* + * Forward arrow + */ +.icon-forward:before { + content: "\e605"; +} + +/* + * Twitter icon + */ +.icon-twitter:before { + content: "\e606"; +} + +/* + * GitHub icon + */ +.icon-github:before { + content: "\e607"; +} + +/* + * Download icon + */ +.icon-download:before { + content: "\e608"; +} + +/* + * Star icon + */ +.icon-star:before { + content: "\e609"; +} + +/* + * Quote icon + */ +.icon-quote:before { + content: "\e610"; +} \ No newline at end of file diff --git a/src/assets/stylesheets/mixins/_break.scss b/src/assets/stylesheets/mixins/_break.scss new file mode 100644 index 000000000..468fa2ec7 --- /dev/null +++ b/src/assets/stylesheets/mixins/_break.scss @@ -0,0 +1,206 @@ +/* + * Copyright (c) 2016 Martin Donath + * + * 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. + */ + +/* ---------------------------------------------------------------------------- + * Defaults + * ------------------------------------------------------------------------- */ + +$break: ( + devices: ( + mobile: ( + portrait: 220px 479px, + landscape: 480px 719px + ), + tablet: ( + portrait: 720px 959px, + landscape: 960px 1199px + ), + screen: 1200px + ) +) !default; + +/* ---------------------------------------------------------------------------- + * Helper functions + * ------------------------------------------------------------------------- */ + +/* + * Choose minimum and maximum device widths. + */ +@function break-select-min-max($devices) { + $min: 1000000; $max: 0; + @each $key, $value in $devices { + @while type-of($value) == map { + $value: break-select-min-max($value); + } + @if type-of($value) == list { + @each $number in $value { + @if type-of($number) == number { + $min: min($number, $min); + @if $max != null { + $max: max($number, $max); + } + } @else { + @warn "Invalid number: #{$number}"; + } + } + } @elseif type-of($value) == number { + $min: min($value, $min); + $max: null; + } @else { + @warn "Invalid tuple: #{$value}"; + } + } + @return $min, $max; +} + +/* + * Select minimum and maximum widths for a device breakpoint. + */ +@function break-select-device($device) { + $devices: map-get($break, devices); + @for $n from 1 through length($device) { + @if type-of($devices) == map { + $devices: map-get($devices, nth($device, $n)); + } @else { + @warn "Invalid device map: #{$devices}"; + } + } + @if type-of($devices) == list or + type-of($devices) == number { + $devices: (default: $devices); + } + @return break-select-min-max($devices); +} + +/* ---------------------------------------------------------------------------- + * Mixins for numeric breakpoints + * ------------------------------------------------------------------------- */ + +/* + * A minimum-maximum media query breakpoint. + */ +@mixin break-at($breakpoint) { + @if type-of($breakpoint) == number { + @media only screen and (min-width: $breakpoint) { + @content; + } + } @elseif type-of($breakpoint) == list { + $min: nth($breakpoint, 1); $max: nth($breakpoint, 2); + @if type-of($min) == number and type-of($max) == number { + @media only screen and (min-width: $min) and (max-width: $max) { + @content; + } + } @else { + @warn "Invalid breakpoint: #{$breakpoint}"; + } + } @else { + @warn "Invalid breakpoint: #{$breakpoint}"; + } +} + +/* + * An orientation media query breakpoint. + */ +@mixin break-at-orientation($breakpoint) { + @if type-of($breakpoint) == string { + @media only screen and (orientation: $breakpoint) { + @content; + } + } @else { + @warn "Invalid breakpoint: #{$breakpoint}"; + } +} + +/* + * A maximum-aspect-ratio media query breakpoint. + */ +@mixin break-at-ratio($breakpoint) { + @if type-of($breakpoint) == number { + @media only screen and (max-aspect-ratio: $breakpoint) { + @content; + } + } @else { + @warn "Invalid breakpoint: #{$breakpoint}"; + } +} + +/* ---------------------------------------------------------------------------- + * Mixins for device breakpoints + * ------------------------------------------------------------------------- */ + +/* + * A minimum-maximum media query device breakpoint. + */ +@mixin break-at-device($device) { + @if type-of($device) == string { + $device: $device,; + } + @if type-of($device) == list { + $breakpoint: break-select-device($device); + @if nth($breakpoint, 2) != null { + $min: nth($breakpoint, 1); $max: nth($breakpoint, 2); + @media only screen and (min-width: $min) and (max-width: $max) { + @content; + } + } @else { + @warn "Invalid device: #{$device}"; + } + } @else { + @warn "Invalid device: #{$device}"; + } +} + +/* + * A minimum media query device breakpoint. + */ +@mixin break-from-device($device) { + @if type-of($device) == string { + $device: $device,; + } + @if type-of($device) == list { + $breakpoint: break-select-device($device); + $min: nth($breakpoint, 1); + @media only screen and (min-width: $min) { + @content; + } + } @else { + @warn "Invalid device: #{$device}"; + } +} + +/* + * A maximum media query device breakpoint. + */ +@mixin break-to-device($device) { + @if type-of($device) == string { + $device: $device,; + } + @if type-of($device) == list { + $breakpoint: break-select-device($device); + $max: nth($breakpoint, 1) - 1; + @media only screen and (max-width: $max) { + @content; + } + } @else { + @warn "Invalid device: #{$device}"; + } +} \ No newline at end of file diff --git a/src/assets/stylesheets/modules/_article.scss b/src/assets/stylesheets/modules/_article.scss new file mode 100644 index 000000000..0529e777a --- /dev/null +++ b/src/assets/stylesheets/modules/_article.scss @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2016 Martin Donath + * + * 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 "article/animation"; +@import "article/appearance"; +@import "article/layout"; +@import "article/typography"; \ No newline at end of file diff --git a/src/assets/stylesheets/modules/_base.scss b/src/assets/stylesheets/modules/_base.scss new file mode 100644 index 000000000..140d308fb --- /dev/null +++ b/src/assets/stylesheets/modules/_base.scss @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2016 Martin Donath + * + * 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 "base/animation"; +@import "base/appearance"; +@import "base/layout"; +@import "base/typography"; \ No newline at end of file diff --git a/src/assets/stylesheets/modules/_drawer.scss b/src/assets/stylesheets/modules/_drawer.scss new file mode 100644 index 000000000..afefecffd --- /dev/null +++ b/src/assets/stylesheets/modules/_drawer.scss @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2016 Martin Donath + * + * 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 "drawer/animation"; +@import "drawer/appearance"; +@import "drawer/layout"; +@import "drawer/typography"; \ No newline at end of file diff --git a/src/assets/stylesheets/modules/_search.scss b/src/assets/stylesheets/modules/_search.scss new file mode 100644 index 000000000..77914e3b1 --- /dev/null +++ b/src/assets/stylesheets/modules/_search.scss @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2016 Martin Donath + * + * 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 "search/animation"; +@import "search/appearance"; +@import "search/layout"; +@import "search/typography"; \ No newline at end of file diff --git a/src/assets/stylesheets/modules/article/_animation.scss b/src/assets/stylesheets/modules/article/_animation.scss new file mode 100644 index 000000000..4a3cfb106 --- /dev/null +++ b/src/assets/stylesheets/modules/article/_animation.scss @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2016 Martin Donath + * + * 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. + */ + +/* ---------------------------------------------------------------------------- + * Article animation + * ------------------------------------------------------------------------- */ + +/* + * Fade color after highlighting + */ +pre span { + transition: color .25s; +} + +/* + * Copyright and theme information + */ +.copyright { + + /* + * Animate color on hover + */ + a { + transition: color .25s; + } +} \ No newline at end of file diff --git a/src/assets/stylesheets/modules/article/_appearance.scss b/src/assets/stylesheets/modules/article/_appearance.scss new file mode 100644 index 000000000..33b093528 --- /dev/null +++ b/src/assets/stylesheets/modules/article/_appearance.scss @@ -0,0 +1,152 @@ +/* + * Copyright (c) 2016 Martin Donath + * + * 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. + */ + +/* ---------------------------------------------------------------------------- + * Article appearance + * ------------------------------------------------------------------------- */ + +/* + * Article + */ +.article { + color: $black; + + + /* + * Differing top and bottom rubberband backgrounds in iOS web application + */ + .ios.standalone & { + background: linear-gradient( + to bottom, $white 50%, $primary 50%); + + /* Hack [iOS]: Mitigate black bounding box with linear gradient */ + .wrapper { + background: linear-gradient( + to bottom, $white 50%, $white 50%); + } + } + + /* + * Headlines and chapters in primary color + */ + h1, h2, p > code, td > code { + color: $primary; + } + + /* + * Code listing in negative colors + */ + pre { + background: $black; + color: $white; + } + + /* + * Color links + */ + a { + color: $primary; + + /* + * Hovered link + */ + &:hover, + &:focus { + color: $accent; + } + } + + /* + * Data tables + */ + table { + @include drop-shadow(1); + + border-radius: 3px; + + /* + * Table heading + */ + th { + background: mix($primary, $white, 75%); + color: $white; + + /* + * Round upper left border + */ + &:first-child { + border-top-left-radius: 3px; + } + + /* + * Round upper right border + */ + &:last-child { + border-top-right-radius: 3px; + } + } + + /* + * Table cell + */ + td { + border-top: 1px solid rgba($black, 0.05); + } + } +} + +/* + * Article footer + */ +.footer { + background: $primary; + color: $white; +} + +/* + * Copyright and theme information + */ +.copyright { + color: $black-light; +} + +/* + * Pagination + */ +.pagination { + + /* + * Inherit color for links + */ + a, + a:hover, + a:focus { + color: inherit; + } + + /* + * Smaller font size for direction + */ + .direction { + color: $white-light; + } +} \ No newline at end of file diff --git a/src/assets/stylesheets/modules/article/_layout.scss b/src/assets/stylesheets/modules/article/_layout.scss new file mode 100644 index 000000000..a048e073a --- /dev/null +++ b/src/assets/stylesheets/modules/article/_layout.scss @@ -0,0 +1,455 @@ +/* + * Copyright (c) 2016 Martin Donath + * + * 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. + */ + +/* ---------------------------------------------------------------------------- + * Article layout + * ------------------------------------------------------------------------- */ + +/* + * Article + */ +.article { + font-size: 14px; + line-height: 24px; + + /* [tablet landscape+]: Indent to account for drawer */ + @include break-from-device(tablet landscape) { + margin-left: 262px; + } + + /* + * Clearfix + */ + &:after { + display: block; + content: " "; + clear: both; + } + + /* + * Article wrapper + */ + .wrapper { + padding: 116px 16px 92px; + + /* [tablet portait+]: Increase top spacing */ + @include break-from-device(tablet portrait) { + padding: 128px 24px 96px; + } + } + + /* + * Enable overflow scrolling in iOS web application + */ + .ios.standalone & { + @include position(absolute, 56px 0 0 0); + + overflow: auto; + -webkit-overflow-scrolling: touch; + + /* [orientation: portrait]: Account for status bar in portrait mode */ + @include break-at-orientation(portrait) { + @include position(absolute, (56px + 20px) 0 0 0); + } + + /* + * Article wrapper + */ + .wrapper { + position: relative; + min-height: 100%; + padding-top: 60px; + margin-bottom: 2px; + } + } + + /* + * Article headlines + */ + h1 { + font-size: 24px; + line-height: 32px; + padding-top: 20px; + margin-bottom: 42px; + } + + /* + * Article chapters - account for fixed header offset + */ + h2 { + font-size: 20px; + line-height: 28px; + padding-top: (36px + 56px); + margin-top: (0px - 56px); + + /* + * No offset correction in iOS web application + */ + .ios.standalone & { + padding-top: 36px; + margin: 0; + } + } + + /* + * Paragraphs and section titles + */ + p, h3, li { + font-size: 14px; + margin-top: 20px; + } + + /* + * List elements + */ + li { + margin-left: 18px; + + /* + * Inline paragraphs in list elements + */ + p { + display: inline; + } + } + + /* + * Add icon for elements of an unordered list + */ + ul li:before { + display: inline-block; + content: '\e602'; + font-family: 'Icon'; + font-size: 16px; + width: 1.2em; + margin-left: -1.2em; + vertical-align: -0.1em; + } + + /* + * Inline code snippets must not wrap + */ + p > code { + white-space: nowrap; + } + + /* + * Code listing container + */ + pre { + padding: 16px; + margin: 20px -16px 0; + overflow: auto; + -webkit-overflow-scrolling: touch; + + /* + * Code listing + */ + code { + line-height: 21px; + } + } + + /* + * Data tables + */ + table { + margin: 40px 0 20px; + font-size: 13px; + + /* + * The semi-cool solution, in case javascript is not available + */ + .no-js & { + display: inline-block; + max-width: 100%; + overflow: auto; + -webkit-overflow-scrolling: touch; + } + + /* + * Table heading + */ + th { + min-width: 100px; + padding: 12px 16px; + font-size: 12px; + text-align: left; + white-space: nowrap; + } + + /* + * Table cell + */ + td { + padding: 12px 16px; + white-space: nowrap; + } + } + + /* + * Data table wrapper, in case javascript is available + */ + .data { + margin: 20px -16px; + padding: 20px 0; + overflow: auto; + -webkit-overflow-scrolling: touch; + text-align: center; + + /* + * Data table + */ + table { + display: inline-block; + margin: 0 16px; + text-align: left; + } + + /* [tablet portait+]: Increase spacing */ + @include break-from-device(tablet portrait) { + margin: 20px -24px; + + /* + * Data table + */ + table { + margin: 0 24px; + } + } + } + + /* [tablet portait+]: Increase spacing */ + @include break-from-device(tablet portrait) { + + /* + * Account for larged header bar and anchors + */ + h2 { + padding-top: (28px + 72px); + margin-top: (8px - 72px); + + /* + * No offset correction in iOS web application + */ + .ios.standalone & { + padding-top: 28px; + margin-top: 8px; + } + } + + /* + * Increase spacing for code blocks + */ + pre { + padding: 20px 24px; + margin: 20px -24px 0; + } + } +} + +/* + * Article footer + */ +.footer { + position: absolute; + bottom: 0; + left: 0; + right: 0; + padding: 0 4px; + + /* [tablet portait+]: Larger spacing */ + @include break-from-device(tablet portrait) { + padding: 0 8px; + } + + /* [tablet landscape+]: Stretch footer to viewport */ + @include break-from-device(tablet landscape) { + z-index: 5; + } +} + +/* + * Copyright and theme information + */ +.copyright { + margin: 20px 0; + + /* [tablet landscape+]: Add bottom spacing */ + @include break-from-device(tablet landscape) { + margin-bottom: 64px; + } +} + +/* + * Pagination + */ +.pagination { + max-width: 1184px; + height: 92px; + padding: 4px 0; + margin-left: auto; + margin-right: auto; + overflow: hidden; + + /* [tablet portait+]: Larger pagination and spacing */ + @include break-from-device(tablet portrait) { + height: 96px; + padding: 8px 0; + } + + /* + * Links should span icons entirely + */ + a { + display: block; + height: 100%; + } + + /* + * Previous and next page + */ + .previous, + .next { + position: relative; + float: left; + height: 100%; + } + + /* + * Previous page + */ + .previous { + width: 25%; + + /* + * Hide direction + */ + .direction { + display: none; + } + + /* + * Hide title + */ + .stretch { + display: none; + } + } + + /* + * Next page + */ + .next { + width: 75%; + text-align: right; + } + + /* + * Link to page + */ + .page { + display: table; + position: absolute; + bottom: 4px; + } + + /* + * Put direction over page title + */ + .direction { + display: block; + position: absolute; + bottom: 40px; + width: 100%; + font-size: 15px; + line-height: 20px; + padding: 0 52px; + } + + /* + * Decrease indent for stretching content + */ + .stretch { + padding: 0 4px; + + /* + * Correct vertical spacing + */ + .title { + font-size: 18px; + padding: 11px 0 13px; + } + } + + /* [mobile landscape+]: Proportional width for pagination */ + @include break-from-device(mobile landscape) { + + /* + * Previous and next page + */ + .previous, + .next { + width: 50%; + } + + /* + * Previous page + */ + .previous { + width: 50%; + + /* + * Show direction + */ + .direction { + display: block; + } + + /* + * Show title + */ + .stretch { + display: table; + } + } + } + + /* [tablet portrait+]: Increase vertical spacing */ + @include break-from-device(tablet portrait) { + + /* + * Increase vertical spacing + */ + .direction { + padding: 0 56px; + bottom: 40px; + } + + /* + * Increase vertical spacing + */ + .stretch { + padding: 0 8px; + } + } +} \ No newline at end of file diff --git a/src/assets/stylesheets/modules/article/_typography.scss b/src/assets/stylesheets/modules/article/_typography.scss new file mode 100644 index 000000000..06e2a34c2 --- /dev/null +++ b/src/assets/stylesheets/modules/article/_typography.scss @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2016 Martin Donath + * + * 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. + */ + +/* ---------------------------------------------------------------------------- + * Article typography + * ------------------------------------------------------------------------- */ + +/* + * Article + */ +.article { + + /* + * Section titles should be bold + */ + h3 { + font-weight: 700; + } +} \ No newline at end of file diff --git a/src/assets/stylesheets/modules/base/_animation.scss b/src/assets/stylesheets/modules/base/_animation.scss new file mode 100644 index 000000000..720621f68 --- /dev/null +++ b/src/assets/stylesheets/modules/base/_animation.scss @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2016 Martin Donath + * + * 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. + */ + +/* ---------------------------------------------------------------------------- + * Base animation + * ------------------------------------------------------------------------- */ + +/* + * Animate color on hover + */ +a { + transition: color .25s; +} + +/* + * Overlay + */ +.overlay { + transition: opacity .25s, + width .0s .25s, + height .0s .25s; + + /* + * Expanded drawer + */ + #toggle-drawer:checked ~ &, + .toggle-drawer & { + transition: opacity .25s, + width .0s, + height .0s; + } +} + +/* + * Application header - check for javascript to omit flashing + */ +.js .header { + transition: background .6s, + color .6s; + + /* + * Status bar + */ + &:before { + transition: background .6s; + } +} + +/* + * Extended visible touch area on icon + */ +.button .icon { + transition: background .25s; +} \ No newline at end of file diff --git a/src/assets/stylesheets/modules/base/_appearance.scss b/src/assets/stylesheets/modules/base/_appearance.scss new file mode 100644 index 000000000..33cca1a63 --- /dev/null +++ b/src/assets/stylesheets/modules/base/_appearance.scss @@ -0,0 +1,137 @@ +/* + * Copyright (c) 2016 Martin Donath + * + * 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. + */ + +/* ---------------------------------------------------------------------------- + * Base appearance + * ------------------------------------------------------------------------- */ + +/* + * Device specific background hacks related to rubberband + */ +body { + + /* Hack [Chrome, Opera]: Set background color in Chrome and Opera */ + @supports (-webkit-appearance: none) { + background: $primary; + } + + /* + * Don't tint menu bar on iOS + */ + .ios & { + background: $white; + } +} + +/* + * Horizontal separators + */ +hr { + border: 0; + border-top: 1px solid $black-lightest; +} + +/* + * Toggle button + */ +.toggle-button { + cursor: pointer; + color: inherit; +} + +/* + * Backdrop + */ +.backdrop { + background: $white; + + /* [tablet landscape+]: Introduce paper with shadow */ + @include break-from-device(tablet landscape) { + background: darken($white, 5%); + } +} + +/* + * Backdrop paper with shadow + */ +.backdrop-paper:after { + background: $white; + + /* [tablet landscape+]: Add drop shadow */ + @include break-from-device(tablet landscape) { + @include drop-shadow(1); + } +} + +/* + * Overlay + */ +.overlay { + background: $black-light; + opacity: 0; + + /* + * Expanded drawer + */ + #toggle-drawer:checked ~ &, + .toggle-drawer & { + opacity: 1; + } +} + +/* + * Application header + */ +.header { + @include drop-shadow(1); + + background: $primary; + color: $white; + + /* + * Add status bar overlay for iOS web application + */ + .ios.standalone &:before { + background: $black-lightest; + } +} + +/* + * Navigation path within header bar + */ +.bar .path { + color: $white-light; +} + +/* + * Draw round area around icon on touch + */ +.button .icon { + border-radius: 100%; +} + +/* + * Pushed/clicked icon + */ +.button .icon:active { + background: $white-lightest; +} \ No newline at end of file diff --git a/src/assets/stylesheets/modules/base/_layout.scss b/src/assets/stylesheets/modules/base/_layout.scss new file mode 100644 index 000000000..b59e168c1 --- /dev/null +++ b/src/assets/stylesheets/modules/base/_layout.scss @@ -0,0 +1,347 @@ +/* + * Copyright (c) 2016 Martin Donath + * + * 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. + */ + +/* ---------------------------------------------------------------------------- + * Base layout + * ------------------------------------------------------------------------- */ + +/* + * Stretch container to viewport + */ +html { + height: 100%; +} + +/* + * Stretch body to container and leave room for sticky footer. + */ +body { + position: relative; + min-height: 100%; +} + +/* + * Horizontal separators + */ +hr { + display: block; + height: 1px; + padding: 0; + margin: 0; +} + +/* + * Lock body (e.g. in search mode) + */ +.locked { + height: 100%; + overflow: hidden; +} + +/* + * Scrollable container + */ +.scrollable { + @include position(absolute, 0 0 0 0); + + overflow: auto; + -webkit-overflow-scrolling: touch; + + /* + * Content wrapper + */ + .wrapper { + height: 100%; + + /* Hack [iOS]: Force overflow scrolling */ + .ios & { + margin-bottom: 2px; + } + } +} + +/* + * Toggle states and button + */ +.toggle { + display: none; + + /* + * Toggle button + */ + &-button { + display: block; + } +} + +/* + * Backdrop + */ +.backdrop { + @include position(absolute, 0 0 0 0); + + z-index: -1; +} + +/* + * Backdrop paper container + */ +.backdrop-paper { + max-width: 1200px; + height: 100%; + margin-left: auto; + margin-right: auto; + + /* + * Actual paper + */ + &:after { + display: block; + content: " "; + height: 100%; + margin-left: 262px; + } +} + +/* + * Overlay + */ +.overlay { + position: fixed; + top: 0; + width: 0; + height: 0; + z-index: 4; + + /* [tablet landscape-]: Trigger overlay */ + @include break-to-device(tablet landscape) { + + /* + * Expanded drawer + */ + #toggle-drawer:checked ~ &, + .toggle-drawer & { + width: 100%; + height: 100%; + } + } +} + +/* + * Application header stays always on top + */ +.header { + @include user-select(none); + + position: fixed; + top: 0; + left: 0; + z-index: 3; + height: 56px; + padding: 4px; + overflow: hidden; + + /* [tablet portait+]: Larger header bar */ + @include break-from-device(tablet portrait) { + height: 64px; + padding: 8px; + } + + /* [screen+]: Stretch to screen */ + @include break-from-device(screen) { + width: 100%; + } + + /* + * Absolute positioning in iOS web application + */ + .ios.standalone & { + position: absolute; + + /* [orientation: portrait]: Account for status bar in portrait mode */ + @include break-at-orientation(portrait) { + height: (56px + 20px); + padding-top: (4px + 20px); + + /* [tablet portait+]: Larger header bar */ + @include break-from-device(tablet portrait) { + height: (64px + 20px); + padding-top: (8px + 20px); + } + + /* + * Add status bar overlay + */ + &:before { + content: " "; + position: absolute; + top: 0; + left: 0; + z-index: 4; + width: 100%; + height: 20px; + } + } + } +} + +/* + * Header bar + */ +.bar { + display: table; + max-width: 1184px; + margin-left: auto; + margin-right: auto; + + /* + * Links should span icons entirely + */ + a { + display: block; + } + + /* + * Hide search button, in case javascript is not available. + */ + .no-js & .button-search { + display: none; + } + + /* + * Navigation path + */ + .path { + + /* + * Correct icon alignment + */ + .icon:before { + vertical-align: -1.5px; + } + + /* [tablet portait-]: Hide path */ + @include break-to-device(tablet portrait) { + display: none; + } + } +} + +/* + * Buttons + */ +.button { + display: table-cell; + vertical-align: top; + width: 1%; + + /* + * Remove native spacing on button + */ + button { + margin: 0; + padding: 0; + + /* Hack [IE]: Remove button offset in active state */ + &:active:before { + position: relative; + top: 0; + left: 0; + } + } + + /* + * Button icons + */ + .icon { + display: inline-block; + font-size: 24px; + padding: 8px; + margin: 4px; + } +} + +/* + * Hide source and twitter button + */ +.button-github, +.button-twitter { + + /* [mobile landscape-]: Hide button */ + @include break-to-device(mobile landscape) { + display: none; + } +} + +/* + * Stretch content to remaining space + */ +.stretch { + display: table; + table-layout: fixed; + width: 100%; + + /* + * Set vertical spacing for header + */ + .header & { + padding: 0 20px; + + /* [tablet portait+]: Increase vertical spacing */ + @include break-from-device(tablet portrait) { + padding: 0 24px; + } + } + + /* + * Title with ellipsis on overflow + */ + .title { + display: table-cell; + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; + + /* + * Increase header font size + */ + .header & { + font-size: 18px; + padding: 13px 0; + + /* [tablet portait+]: Slightly larger typography in header */ + @include break-from-device(tablet portrait) { + font-size: 20px; + padding: 12px 0; + } + } + } +} + +/* + * Main content + */ +.main { + max-width: 1200px; + margin-left: auto; + margin-right: auto; +} \ No newline at end of file diff --git a/src/assets/stylesheets/modules/base/_typography.scss b/src/assets/stylesheets/modules/base/_typography.scss new file mode 100644 index 000000000..b6f6d5f68 --- /dev/null +++ b/src/assets/stylesheets/modules/base/_typography.scss @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2016 Martin Donath + * + * 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. + */ + +/* ---------------------------------------------------------------------------- + * Base typography + * ------------------------------------------------------------------------- */ + +/* + * Default font styles + */ +body, input { + font-family: 'Ubuntu', 'Helvetica Neue', Helvetica, Arial, sans-serif; + font-weight: 400; + + /* Enable font-smoothing in Webkit and FF */ + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + + /* + * Use system fonts, if browser doesn't support webfonts + */ + .no-fontface & { + font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; + } +} + +/* + * Proportional fonts + */ +pre, code { + font-family: 'Ubuntu Mono', 'Courier New', 'Courier', monospace; + + /* + * Use system fonts, if browser doesn't support webfonts + */ + .no-fontface & { + font-family: 'Courier New', 'Courier', monospace; + } +} \ No newline at end of file diff --git a/src/assets/stylesheets/modules/drawer/_animation.scss b/src/assets/stylesheets/modules/drawer/_animation.scss new file mode 100644 index 000000000..b357b957a --- /dev/null +++ b/src/assets/stylesheets/modules/drawer/_animation.scss @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2016 Martin Donath + * + * 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. + */ + +/* ---------------------------------------------------------------------------- + * Drawer animation + * ------------------------------------------------------------------------- */ + +/* + * Drawer container + */ +.drawer { + + /* [tablet landscape-]: Hide menu */ + @include break-to-device(tablet landscape) { + transform: translate3d(-262px, 0, 0); + transition: transform .25s cubic-bezier(.4, 0, .2, 1); + + /* + * Just hide drawer, if browser doesn't support 3D transforms + */ + .no-csstransforms3d & { + display: none; + } + } + + /* + * Expanded drawer + */ + #toggle-drawer:checked ~ .main &, + .toggle-drawer & { + transform: translate3d(0, 0, 0); + + /* + * Just show drawer, if browser doesn't support 3D transforms + */ + .no-csstransforms3d & { + display: block; + } + } +} + +/* + * Project logo image + */ +.project .logo img { + transition: box-shadow .4s; +} + +/* + * Repository buttons + */ +.repo a { + transition: box-shadow .4s, + opacity .4s; +} \ No newline at end of file diff --git a/src/assets/stylesheets/modules/drawer/_appearance.scss b/src/assets/stylesheets/modules/drawer/_appearance.scss new file mode 100644 index 000000000..e3f4a8257 --- /dev/null +++ b/src/assets/stylesheets/modules/drawer/_appearance.scss @@ -0,0 +1,149 @@ +/* + * Copyright (c) 2016 Martin Donath + * + * 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. + */ + +/* ---------------------------------------------------------------------------- + * Drawer appearance + * ------------------------------------------------------------------------- */ + +/* + * Drawer container + */ +.drawer { + + /* [tablet landscape-]: Light gray background */ + @include break-to-device(tablet landscape) { + background: darken($white, 5%); + } + + /* + * Color links + */ + .toc a { + + /* + * Current active element + */ + &.current { + color: $primary; + } + + /* + * Hovered link + */ + &:hover, &:focus { + color: $accent; + } + } + + /* + * Main sections + */ + .section { + color: $black-light; + } + + /* + * Content wrapper + */ + .wrapper { + + /* [tablet landscape-]: Light gray background */ + @include break-to-device(tablet landscape) { + background: darken($white, 5%); + } + } +} + +/* + * Project information + */ +.project { + color: $white; + + /* [tablet landscape-]: Add drop shadow */ + @include break-to-device(tablet landscape) { + @include drop-shadow(1); + + background: $primary; + } + + /* + * Add status bar overlay for iOS web application + */ + .ios.standalone &:before { + background: $black-lightest; + } + + /* + * Project logo + */ + .logo img { + background: $white; + border-radius: 100%; + } + + /* + * Scale logo on hover + */ + &:hover .logo img, + &:focus .logo img { + @include drop-shadow(3); + } +} + +/* + * Repository buttons + */ +.repo a { + @include drop-shadow(1); + + background: $accent; + color: $white; + border-radius: 3px; + + /* + * Hovered button + */ + &:hover, &:focus { + @include drop-shadow(3); + + opacity: 0.8; + } + + /* + * Stars + */ + .count { + background: $black-lighter; + color: $white; + border-radius: 0px 3px 3px 0px; + + /* + * Star bubble + */ + &:before { + border-width: 15px 5px 15px 0; + border-color: transparent $black-lighter; + border-style: solid; + } + } +} \ No newline at end of file diff --git a/src/assets/stylesheets/modules/drawer/_layout.scss b/src/assets/stylesheets/modules/drawer/_layout.scss new file mode 100644 index 000000000..74c80a813 --- /dev/null +++ b/src/assets/stylesheets/modules/drawer/_layout.scss @@ -0,0 +1,281 @@ +/* + * Copyright (c) 2016 Martin Donath + * + * 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. + */ + +/* ---------------------------------------------------------------------------- + * Drawer layout + * ------------------------------------------------------------------------- */ + +/* + * Drawer container + */ +.drawer { + width: 262px; + font-size: 13px; + line-height: 1.0em; + + /* [tablet landscape-]: Fixed positioning */ + @include break-to-device(tablet landscape) { + position: fixed; + z-index: 5; + height: 100%; + } + + /* [tablet landscape+]: Inline with content */ + @include break-from-device(tablet landscape) { + position: static; + float: left; + height: auto; + margin-bottom: 96px; + padding-top: 80px; + } + + /* Hack [iOS]: Mitigate scrolling of parent container on boundaries */ + .ios & { + overflow: scroll; + -webkit-overflow-scrolling: touch; + } + + /* + * Links to articles + */ + .toc li a { + display: block; + padding: 14.5px 24px; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + } + + /* + * Links to chapters inside the current article + */ + .toc li.anchor a { + padding: 10px 24px 10px 48px; + } + + /* + * Main sections + */ + .section { + display: block; + font-size: 11px; + padding: 14.5px 24px; + } + + /* + * Scrollable container + */ + .scrollable { + top: 104px; + z-index: -1; + + /* [tablet landscape+]: Revert fixed positioning */ + @include break-from-device(tablet landscape) { + position: initial; + } + + /* + * Leave room for status bar in iOS web application + */ + .ios.standalone & { + + /* [orientation: portrait]: Account for status bar in portrait mode */ + @include break-at-orientation(portrait) { + top: (104px + 20px); + } + } + + /* + * Content wrapper + */ + .wrapper { + height: auto; + min-height: 100%; + + /* + * Add spacing at top and bottom of separator + */ + hr { + margin: 12px 0; + + /* [screen+]: Shorten separator */ + @include break-from-device(screen) { + width: 48px; + } + } + + /* + * Add spacing at top and bottom of top level navigation + */ + .toc { + margin: 12px 0; + } + } + } +} + +/* + * Project information + */ +.project { + display: block; + + /* + * Leave room for status bar in iOS web application + */ + .ios.standalone & { + + /* [orientation: portrait]: Account for status bar in portrait mode */ + @include break-at-orientation(portrait) { + padding-top: 20px; + + /* + * Add status bar overlay + */ + &:before { + content: " "; + position: absolute; + top: 0; + left: 0; + z-index: 4; + width: 100%; + height: 20px; + } + } + } + + /* + * Project banner + */ + .banner { + display: table; + width: 100%; + padding: 20px; + } + + /* + * Project logo + */ + .logo { + display: table-cell; + width: 64px; + height: 64px; + + /* + * Project logo image + */ + img { + display: block; + width: 100%; + height: auto; + } + } + + /* + * Project name + */ + .name { + display: table-cell; + font-size: 16px; + line-height: 1.25em; + padding-left: 16px; + vertical-align: middle; + + /* [tablet portait+]: Slightly larger project name */ + @include break-from-device(tablet portrait) { + margin: 26px 0 0 5px; + } + } +} + +/* + * Repository + */ +.repo { + padding: 0 16px; + margin: 24px 0; + text-align: center; + + /* + * Inline buttons + */ + li { + display: inline-block; + padding-right: 12px; + white-space: nowrap; + + /* + * No padding on last button + */ + &:last-child { + padding-right: 0; + } + } + + /* + * Buttons + */ + a { + display: inline-block; + padding: 0px 10px 0px 6px; + font-size: 12px; + line-height: 30px; + height: 30px; + + /* + * Slightly larger icons + */ + .icon { + font-size: 18px; + vertical-align: -3px; + } + + /* + * Stars + */ + .count { + display: inline-block; + position: relative; + padding: 0px 8px 0 4px; + margin: 0 -10px 0 8px; + font-size: 12px; + + /* + * Star bubble + */ + &:before { + content: " "; + display: block; + position: absolute; + top: 0px; + left: -5px; + } + + /* + * Hide count, in case javascript is not available. + */ + .no-js & { + display: none; + } + } + } +} \ No newline at end of file diff --git a/src/assets/stylesheets/modules/drawer/_typography.scss b/src/assets/stylesheets/modules/drawer/_typography.scss new file mode 100644 index 000000000..58c79d69c --- /dev/null +++ b/src/assets/stylesheets/modules/drawer/_typography.scss @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2016 Martin Donath + * + * 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. + */ + +/* ---------------------------------------------------------------------------- + * Drawer typography + * ------------------------------------------------------------------------- */ + +/* + * Drawer container + */ +.drawer { + + /* + * Links to articles + */ + .toc li a { + font-weight: 700; + } + + /* + * Links to chapters inside the current article + */ + .toc li.anchor a { + font-weight: 400; + } + + /* + * Main sections + */ + .section { + text-transform: uppercase; + font-weight: 700; + } +} + +/* + * Repository buttons + */ +.repo a { + text-transform: uppercase; + font-weight: 700; + + /* + * Stars + */ + .count { + text-transform: none; + font-weight: 700; + } +} \ No newline at end of file diff --git a/src/assets/stylesheets/modules/search/_animation.scss b/src/assets/stylesheets/modules/search/_animation.scss new file mode 100644 index 000000000..37df48f32 --- /dev/null +++ b/src/assets/stylesheets/modules/search/_animation.scss @@ -0,0 +1,134 @@ +/* + * Copyright (c) 2016 Martin Donath + * + * 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. + */ + +/* ---------------------------------------------------------------------------- + * Search animation + * ------------------------------------------------------------------------- */ + +/* + * Animate header bar in offset and opacity + */ +.bar { + transform: translate3d(0, 0, 0); + transition: opacity .2s cubic-bezier(.75, 0, .25, 1), + transform .4s cubic-bezier(.75, 0, .25, 1); + + /* + * Active search mode + */ + #toggle-search:checked ~ .header &, + .toggle-search & { + transform: translate3d(0, -56px, 0); + } + + /* + * Search animations + */ + &.search { + + /* + * Hide reset button by default + */ + .button-reset { + transform: scale(0.5, 0.5); + transition: opacity .4s cubic-bezier(.1, .7, .1, 1), + transform .4s cubic-bezier(.1, .7, .1, 1); + opacity: 0; + } + + /* + * Show reset button if search is not empty + */ + &.non-empty .button-reset { + transform: scale(1.0, 1.0); + opacity: 1; + } + } +} + +/* + * Search results + */ +.results { + transition: opacity .3s .1s, + width .0s .4s, + height .0s .4s; + + /* + * Active search mode + */ + #toggle-search:checked ~ .main &, + .toggle-search & { + transition: opacity .4s, + width .0s, + height .0s; + } + + /* + * Search result item link + */ + .list a { + transition: background .25s; + } +} + +/* + * Just hide and show bars, if browser doesn't support 3D transforms + */ +.no-csstransforms3d { + + /* + * Show default bar + */ + .bar.default { + display: table; + } + + /* + * Hide search bar + */ + .bar.search { + display: none; + margin-top: 0; + } + + /* + * Active search mode + */ + #toggle-search:checked ~ .header, + .toggle-search { + + /* + * Hide default bar + */ + .bar.default { + display: none; + } + + /* + * Show search bar + */ + .bar.search { + display: table; + } + } +} \ No newline at end of file diff --git a/src/assets/stylesheets/modules/search/_appearance.scss b/src/assets/stylesheets/modules/search/_appearance.scss new file mode 100644 index 000000000..045cd7613 --- /dev/null +++ b/src/assets/stylesheets/modules/search/_appearance.scss @@ -0,0 +1,139 @@ +/* + * Copyright (c) 2016 Martin Donath + * + * 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. + */ + +/* ---------------------------------------------------------------------------- + * Search appearance + * ------------------------------------------------------------------------- */ + +/* + * Search bar + */ +.bar.search { + opacity: 0; + + /* + * Search input + */ + .query { + background: transparent; + color: $black; + + /* + * Search input placeholder + */ + @include placeholder { + color: $black-lighter; + } + } + + /* + * Pushed/clicked icon + */ + .button .icon:active { + background: $black-lightest; + } +} + +/* + * Search results + */ +.results { + @include drop-shadow(2); + + background: $white; + color: $black; + opacity: 0; + + /* + * Active search mode + */ + #toggle-search:checked ~ .main &, + .toggle-search & { + opacity: 1; + } + + /* + * Search meta data + */ + .meta { + background: $primary; + color: $white; + } + + /* + * Search result item link + */ + .list a { + border-bottom: 1px solid $black-lightest; + + /* + * Remove border on last element + */ + &:last-child { + border-bottom: none; + } + + /* + * Active item link + */ + &:active { + background: $black-lightest; + } + } +} + +/* + * Article link + */ +.result span { + color: $black-light; +} + +/* + * Active search bar + */ +#toggle-search:checked ~ .header, +.toggle-search .header { + background: $white; + color: $black-light; + + /* + * Add darker status bar overlay in search mode + */ + &:before { + background: $black-light; + } + + /* + * Fade out default header bar + */ + .bar.default { + opacity: 0; + } + + /* + * Fade in search header bar + */ + .bar.search { + opacity: 1; + } +} \ No newline at end of file diff --git a/src/assets/stylesheets/modules/search/_layout.scss b/src/assets/stylesheets/modules/search/_layout.scss new file mode 100644 index 000000000..f5b85eb3a --- /dev/null +++ b/src/assets/stylesheets/modules/search/_layout.scss @@ -0,0 +1,219 @@ +/* + * Copyright (c) 2016 Martin Donath + * + * 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. + */ + +/* ---------------------------------------------------------------------------- + * Search layout + * ------------------------------------------------------------------------- */ + +/* + * Search bar + */ +.bar.search { + margin-top: 8px; + + /* + * Search input + */ + .query { + font-size: 18px; + padding: 13px 0; + margin: 0; + width: 100%; + height: 48px; + + /* [tablet portait+]: Slightly larger typo */ + @include break-from-device(tablet portrait) { + font-size: 20px; + padding: 12px 0; + } + } +} + +/* + * Search results + */ +.results { + position: fixed; + top: 0; + left: 0; + width: 0; + z-index: 2; + overflow: scroll; + -webkit-overflow-scrolling: touch; + + /* [tablet landscape+]: Limit results to five entries */ + @include break-from-device(tablet landscape) { + top: 64px; + } + + /* + * Scrollable container + */ + .scrollable { + top: 56px; + + /* [tablet portait+]: Increase vertical spacing */ + @include break-from-device(tablet portrait) { + top: 64px; + } + + /* [tablet landscape+]: Limit results to five entries */ + @include break-from-device(tablet landscape) { + position: initial; + bottom: auto; + max-height: 413px; + } + + /* + * Leave room for status bar in iOS web application + */ + .ios.standalone & { + + /* [orientation: portrait]: Account for status bar in portrait mode */ + @include break-at-orientation(portrait) { + top: (56px + 20px); + + /* [tablet portait+]: Increase vertical spacing */ + @include break-from-device(tablet portrait) { + top: (64px + 20px); + } + } + } + } + + /* + * Active search mode + */ + #toggle-search:checked ~ .main &, + .toggle-search & { + width: 100%; + + /* Hack [Firefox]: div doesn't collapse, unless this is applied */ + overflow-y: visible; + + /* [tablet portait+]: Stretch to viewport */ + @include break-to-device(tablet landscape) { + height: 100%; + } + } + + /* + * Search meta data + */ + .meta { + font-weight: 700; + + /* + * Number of results + */ + strong { + display: block; + font-size: 11px; + max-width: 1200px; + margin-left: auto; + margin-right: auto; + padding: 16px; + + /* [tablet portait+]: Increase vertical spacing */ + @include break-from-device(tablet portrait) { + padding: 16px 24px; + } + } + } + + /* + * Search result item link + */ + .list a { + display: block; + } +} + +/* + * Search result item + */ +.result { + max-width: 1200px; + margin-left: auto; + margin-right: auto; + padding: 12px 16px 16px; + + /* [tablet portait+]: Increase vertical spacing */ + @include break-from-device(tablet portrait) { + padding: 16px 24px 20px; + } + + /* + * Article title + */ + h1 { + line-height: 24px; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; + } + + /* + * Article link + */ + span { + font-size: 12px; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; + } +} + +/* + * Prevent flickering on scroll in IE9 + */ +.ie9 { + + /* + * Hide search results + */ + .results { + display: none; + } + + /* + * Active search mode + */ + #toggle-search:checked ~ .main, + .toggle-search { + + /* + * Show search results + */ + .results { + display: block; + overflow: auto; + } + + /* + * Article and footer may shine through, so make them invisible + */ + .article, .footer { + visibility: hidden; + } + } +} \ No newline at end of file diff --git a/src/assets/stylesheets/modules/search/_typography.scss b/src/assets/stylesheets/modules/search/_typography.scss new file mode 100644 index 000000000..465f20ede --- /dev/null +++ b/src/assets/stylesheets/modules/search/_typography.scss @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2016 Martin Donath + * + * 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. + */ + +/* + * Search meta data + */ +.meta { + text-transform: uppercase; + font-weight: 700; +} \ No newline at end of file diff --git a/src/views/base.html b/src/views/base.html new file mode 100644 index 000000000..d012d7672 --- /dev/null +++ b/src/views/base.html @@ -0,0 +1,176 @@ + + + + + + + + + + + + + + {% block htmltitle %} + + + {% if page_title %} + {{ page_title }} - {{ site_name }} + {% else %} + {{ site_name }} + {% endif %} + + + {% if page_description %} + + {% endif %} + + + {% if canonical_url %} + + {% endif %} + + + {% if site_author %} + + {% endif %} + {% endblock %} + + + + + + + + + + + + + + + + + {% for path in extra_css %} + + {% endfor %} + + + {% block extrahead %}{% endblock %} + + + + +
+
+
+ + + + + + + + + +
+ {% include "header.html" %} +
+ + +
+ + +
+ {% include "drawer.html" %} +
+ + +
+
+ + + {% if page_title %} +

{{ page_title }}

+ {% else %} +

{{ site_name }}

+ {% endif %} +
+ + + {{ content }} + + + + + + {% block footer %} +
+ {% include "footer.html" %} +
+ {% endblock %} +
+ + + +
+
+
+
+
+
+
+
+
+ + + + + + {% set repo_id = repo_url | replace('https://github.com/', '') %} + + + {% for path in extra_javascript %} + + {% endfor %} + + + {% if google_analytics %} + + {% endif %} + + \ No newline at end of file diff --git a/src/views/drawer.html b/src/views/drawer.html new file mode 100644 index 000000000..9fbc86a7d --- /dev/null +++ b/src/views/drawer.html @@ -0,0 +1,81 @@ + + \ No newline at end of file diff --git a/src/views/footer.html b/src/views/footer.html new file mode 100644 index 000000000..2964ab901 --- /dev/null +++ b/src/views/footer.html @@ -0,0 +1,44 @@ + +{% if include_next_prev %} + +{% endif %} \ No newline at end of file diff --git a/src/views/header.html b/src/views/header.html new file mode 100644 index 000000000..2d4a34d88 --- /dev/null +++ b/src/views/header.html @@ -0,0 +1,86 @@ + + \ No newline at end of file diff --git a/src/views/toc.html b/src/views/toc.html new file mode 100644 index 000000000..f0167b82b --- /dev/null +++ b/src/views/toc.html @@ -0,0 +1,37 @@ + +{% if nav_item.children %} +
  • +
    + {{ nav_item.title }} +
      + + + {% for nav_item in nav_item.children %} + {% include 'toc.html' %} + {% endfor %} +
    +
  • + + +{% else %} +
  • + + {{ nav_item.title }} + + + + {% if nav_item == current_page %} + + {% endif %} +
  • +{% endif %} \ No newline at end of file