1
0
mirror of https://github.com/til-schneider/slim-wiki.git synced 2025-08-06 16:46:31 +02:00

Added TOC

This commit is contained in:
til-schneider
2016-05-25 17:01:52 +02:00
parent dd1a4579c5
commit cb13fb33a7
6 changed files with 99 additions and 6 deletions

View File

@@ -78,6 +78,7 @@ Build a release zip:
- [Parsedown](https://github.com/erusev/parsedown/) - PHP markdown parser.
- [prism](http://prismjs.com/) - JavaScript syntax highlighter.
- [CodeMirror](https://codemirror.net/) - JavaScript in-browser code editor.
- [Tocbot](http://tscanlin.github.io/tocbot/) - JavaScript table of contents generator.
- [Vanilla JS](http://vanilla-js.com/) - No jQuery. Instead standard DOM API in order to make things fast and slim.

View File

@@ -1,4 +1,4 @@
(function(document, slimwiki, Prism) {
(function(document, slimwiki, Prism, tocbot) {
slimwiki.View = {
updateSyntaxHighlighting: updateSyntaxHighlighting
@@ -15,10 +15,40 @@
Prism.plugins.autoloader.languages_path = 'client/libs/prism/components/';
if (mode == 'view' || mode == 'edit') {
initToc();
updateSyntaxHighlighting();
}
}
function initToc() {
var headingSelector = 'h1, h2, h3',
nextId = 1,
headingsOffset = 80,
headings;
// tocbot needs ID attributes at the headings in order to function
headings = document.getElementById('content').querySelectorAll(headingSelector);
Array.prototype.forEach.call(headings, function (headingElem) {
headingElem.id = 'heading-' + (nextId++);
});
tocbot.init({
// Where to render the table of contents.
tocSelector: '.toc-wrapper',
// Where to grab the headings to build the table of contents.
contentSelector: '#content',
// Which headings to grab inside of the contentSelector element.
headingSelector: headingSelector,
// Headings offset between the headings and the top of the document.
headingsOffset: headingsOffset,
// smooth-scroll options object, see docs at:
// https://github.com/cferdinandi/smooth-scroll
smoothScrollOptions: {
offset: headingsOffset
}
});
}
function updateSyntaxHighlighting(parentElem) {
if (! parentElem) {
parentElem = document.getElementById('content');
@@ -30,4 +60,4 @@
});
}
})(document, slimwiki, Prism);
})(document, slimwiki, Prism, tocbot);

View File

@@ -32,6 +32,7 @@ include($themeDir . '/init-theme.php');
<!-- build:css client/view.css -->
<link href="client/libs/prism/themes/prism-default-patched.css" rel="stylesheet" />
<link href="client/libs/tocbot/tocbot.css" rel="stylesheet" />
<link href=".tmp/app-view.css" rel="stylesheet" />
<!-- endbuild -->
@@ -179,6 +180,7 @@ if ($mode == 'edit') {
<!-- build:js client/view.js -->
<script src="client/libs/prism/prism-patched.js"></script>
<script src="client/libs/prism/plugins/autoloader/prism-autoloader.js"></script>
<script src="client/libs/tocbot/tocbot.js"></script>
<script src="client/js/app-view.js"></script>
<!-- endbuild -->

View File

@@ -1,10 +1,20 @@
@contentMaxWidth: 800px;
@contentMinMarginX: 30px;
@tocMinWidth: 200px;
@tocMarginLeft: @contentMinMarginX;
// We need a variable using brackets here, otherwise less won't calculate the width
// See: https://github.com/less/less.js/issues/1903
@small-screen-breakpoint: (@contentMaxWidth + 2 * @contentMinMarginX);
// Screen sizes:
// - small: Content takes full width, TOC is hidden
// - medium: Content is left, TOC is right or hidden (if width < @screen-size-toc-hidden-max)
// - large: Content is centered, TOC is right
//
// NOTE: We need a variable using brackets here, otherwise less won't calculate the width
// See: https://github.com/less/less.js/issues/1903
@screen-size-small-max: (@contentMaxWidth + 2 * @contentMinMarginX);
@screen-size-toc-hidden-max: (@screen-size-small-max + @tocMinWidth);
@screen-size-medium-min: (@screen-size-small-max + 1px);
@screen-size-medium-max: (@contentMaxWidth + 2 * @tocMinWidth);
.main-column {
width: @contentMaxWidth;
@@ -15,7 +25,11 @@
margin: 0 @contentMinMarginX;
}
@media (max-width: @small-screen-breakpoint) {
@media (min-width: @screen-size-medium-min) and (max-width: @screen-size-medium-max) {
width: @contentMaxWidth;
margin: 0 @contentMinMarginX;
}
@media (max-width: @screen-size-small-max) {
width: auto;
margin: 0 @contentMinMarginX;
}
@@ -32,6 +46,26 @@
}
}
.toc-wrapper {
position: fixed;
left: 50%;
right: 10px;
top: 70px;
margin-left: @contentMaxWidth / 2 + @tocMarginLeft;
.mode-edit & {
display: none;
}
@media (min-width: @screen-size-medium-min) and (max-width: @screen-size-medium-max) {
left: @contentMinMarginX + @contentMaxWidth + @tocMarginLeft;
margin-left: 0;
}
@media (max-width: @screen-size-toc-hidden-max) {
display: none;
}
}
#content {
padding: 30px 0 150px;
}

View File

@@ -26,6 +26,31 @@ body {
}
}
.toc-wrapper {
ul {
list-style: none;
}
.toc-link {
display: block;
padding: 5px 0;
line-height: 1;
text-decoration: none;
cursor: pointer;
&::before {
margin-top: -5px;
}
}
.is-active-link {
font-weight: normal;
color: @brand-primary;
&::before {
background-color: @brand-primary;
}
}
}
footer {
height: 80px;
padding-top: 30px;

View File

@@ -19,3 +19,4 @@ foreach ($data['breadcrumbs'] as $item) {
$isFirst = false;
}
?></div></nav>
<nav class="toc-wrapper"></nav>