--- /dev/null
+.toc-menu {
+ color: var(--toc-font-color);
+}
+
+.toc.sidebar .toc-menu {
+ margin-right: 0.75rem;
+ position: sticky;
+ top: var(--toc-top);
+}
+
+.toc .toc-menu h3 {
+ color: var(--toc-heading-font-color);
+ font-size: calc(16 / var(--rem-base) * 1rem);
+ font-weight: var(--body-font-weight-bold);
+ line-height: 1.3;
+ margin: 0 -0.5px;
+ padding-bottom: 0.25rem;
+}
+
+.toc.sidebar .toc-menu h3 {
+ display: flex;
+ flex-direction: column;
+ height: 2.5rem;
+ justify-content: flex-end;
+}
+
+.toc .toc-menu ul {
+ font-size: calc(15 / var(--rem-base) * 1rem);
+ line-height: var(--toc-line-height);
+ list-style: none;
+ margin: 0;
+ padding: 0;
+}
+
+.toc.sidebar .toc-menu ul {
+ max-height: var(--toc-height);
+ overflow-y: auto;
+ scrollbar-width: none;
+}
+
+.toc .toc-menu ul::-webkit-scrollbar {
+ width: 0;
+}
+
+@media screen and (min-width: 1024px) {
+ .toc .toc-menu h3 {
+ font-size: calc(15 / var(--rem-base) * 1rem);
+ }
+
+ .toc .toc-menu ul {
+ font-size: calc(13.5 / var(--rem-base) * 1rem);
+ }
+}
+
+.toc .toc-menu li {
+ margin: 0;
+}
+
+.toc .toc-menu li[data-level="2"] a {
+ padding-left: 1.25rem;
+}
+
+.toc .toc-menu li[data-level="3"] a {
+ padding-left: 2rem;
+}
+
+.toc .toc-menu a {
+ color: inherit;
+ border-left: 2px solid var(--toc-border-color);
+ display: inline-block;
+ padding: 0.25rem 0 0.25rem 0.5rem;
+ text-decoration: none;
+}
+
+.sidebar.toc .toc-menu a {
+ display: block;
+ outline: none;
+}
+
+.toc .toc-menu a:hover {
+ color: var(--link-font-color);
+}
+
+.toc .toc-menu a.is-active {
+ border-left-color: var(--link-font-color);
+ color: var(--doc-font-color);
+}
+
+.sidebar.toc .toc-menu a:focus {
+ background: var(--panel-background);
+}
+
+.toc .toc-menu .is-hidden-toc {
+ display: none !important;
+}
--toolbar-muted-color: var(--color-gray-30);
--page-version-menu-background: var(--color-smoke-70);
--page-version-missing-font-color: var(--color-gray-30);
+ /* toc */
+ --toc-font-color: var(--nav-muted-color);
+ --toc-heading-font-color: var(--doc-font-color);
+ --toc-border-color: var(--panel-border-color);
+ --toc-line-height: 1.2;
/* admonitions */
--caution-color: #a0439c;
--caution-on-color: var(--color-white);
--footer-background: var(--color-smoke-90);
--footer-font-color: var(--color-gray-70);
--footer-link-font-color: var(--color-jet-80);
- /* dimensions */
+ /* dimensions and positioning */
--navbar-height: calc(63 / var(--rem-base) * 1rem);
--toolbar-height: calc(45 / var(--rem-base) * 1rem);
--drawer-height: var(--toolbar-height);
--nav-panel-height: calc(var(--nav-height) - var(--drawer-height));
--nav-panel-height--desktop: calc(var(--nav-height--desktop) - var(--drawer-height));
--nav-width: calc(270 / var(--rem-base) * 1rem);
+ --toc-top: calc(var(--body-top) + var(--toolbar-height));
+ --toc-height: calc(100vh - var(--toc-top) - 2.5rem);
+ --toc-width: calc(162 / var(--rem-base) * 1rem);
+ --toc-width--widescreen: calc(216 / var(--rem-base) * 1rem);
--doc-max-width: calc(720 / var(--rem-base) * 1rem);
--doc-max-width--desktop: calc(828 / var(--rem-base) * 1rem);
/* stacking */
-/* Copyright (c) 2018 OpenDevise Inc. and individual contributors.
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/.
- */
;(function () {
'use strict'
var sidebar = document.querySelector('aside.toc.sidebar')
if (!sidebar) return
- var doc
+ if (document.querySelector('body.-toc')) return sidebar.parentNode.removeChild(sidebar) && undefined
+ var levels = parseInt(sidebar.dataset.levels || 2)
+ if (levels < 0) return
+ var article = document.querySelector('article.doc')
var headings
- if (
- document.querySelector('.body.-toc') ||
- !(headings = find('h1[id].sect0, .sect1 > h2[id]', (doc = document.querySelector('article.doc')))).length
- ) {
- sidebar.parentNode.removeChild(sidebar)
- return
+ var headingSelector = []
+ for (var l = 0; l <= levels; l++) headingSelector.push(l ? '.sect' + l + ' > h' + (l + 1) + '[id]' : 'h1[id].sect0')
+ if (!(headings = find(headingSelector.join(', '), article)).length) {
+ return sidebar.parentNode.removeChild(sidebar) && undefined
}
+
var lastActiveFragment
var links = {}
- var menu
-
var list = headings.reduce(function (accum, heading) {
var link = toArray(heading.childNodes).reduce(function (target, child) {
if (child.nodeName !== 'A') target.appendChild(child.cloneNode(true))
}, document.createElement('a'))
links[(link.href = '#' + heading.id)] = link
var listItem = document.createElement('li')
+ listItem.dataset.level = parseInt(heading.nodeName.slice(1)) - 1
listItem.appendChild(link)
accum.appendChild(listItem)
return accum
}, document.createElement('ul'))
- if (!(menu = sidebar && sidebar.querySelector('.toc-menu'))) {
+ var menu = sidebar.querySelector('.toc-menu')
+ if (!menu) {
menu = document.createElement('div')
menu.className = 'toc-menu'
}
var title = document.createElement('h3')
- title.textContent = 'On This Page'
+ title.textContent = sidebar.dataset.title || 'Contents'
menu.appendChild(title)
menu.appendChild(list)
- if (sidebar) {
- window.addEventListener('load', function () {
- onScroll()
- window.addEventListener('scroll', onScroll)
- })
- }
-
- var startOfContent = doc.querySelector('h1.page ~ :not(.labels)')
+ var startOfContent = !document.getElementById('toc') && article.querySelector('h1.page ~ :not(.is-before-toc)')
if (startOfContent) {
var embeddedToc = document.createElement('aside')
embeddedToc.className = 'toc embedded'
embeddedToc.appendChild(menu.cloneNode(true))
- doc.insertBefore(embeddedToc, startOfContent)
+ startOfContent.parentNode.insertBefore(embeddedToc, startOfContent)
}
+ window.addEventListener('load', function () {
+ onScroll()
+ window.addEventListener('scroll', onScroll)
+ })
+
function onScroll () {
- // NOTE doc.parentNode.offsetTop ~= doc.parentNode.getBoundingClientRect().top + window.pageYOffset
- //var targetPosition = doc.parentNode.offsetTop
- // NOTE no need to compensate wheen using spacer above [id] elements
- var targetPosition = 0
var activeFragment
- headings.some(function (heading) {
- if (Math.floor(heading.getBoundingClientRect().top) <= targetPosition) {
+ var scrolledBy = window.pageYOffset
+ var buffer = getStyleValueAsInt(document.documentElement, 'fontSize')
+ if (scrolledBy && window.innerHeight + scrolledBy + 2 >= document.documentElement.scrollHeight) {
+ activeFragment = '#' + headings[headings.length - 1].id
+ } else {
+ var targetPosition = article.offsetTop
+ headings.some(function (heading) {
+ var headingTop = heading.getBoundingClientRect().top + getStyleValueAsInt(heading, 'paddingTop')
+ if (targetPosition < headingTop - buffer) return true
activeFragment = '#' + heading.id
- } else {
- return true
- }
- })
+ })
+ }
if (activeFragment) {
if (activeFragment !== lastActiveFragment) {
if (lastActiveFragment) {
}
var activeLink = links[activeFragment]
activeLink.classList.add('is-active')
- if (menu.scrollHeight > menu.offsetHeight) {
- menu.scrollTop = Math.max(0, activeLink.offsetTop + activeLink.offsetHeight - menu.offsetHeight)
+ if (list.scrollHeight > list.offsetHeight) {
+ list.scrollTop = Math.max(0, activeLink.offsetTop + activeLink.offsetHeight - list.offsetHeight)
}
lastActiveFragment = activeFragment
}
function toArray (collection) {
return [].slice.call(collection)
}
+
+ function getStyleValueAsInt (el, prop) {
+ return parseInt(window.getComputedStyle(el)[prop])
+ }
})()