diff --git a/src/core/event/scroll.js b/src/core/event/scroll.js
index b79589b8..503c6b46 100644
--- a/src/core/event/scroll.js
+++ b/src/core/event/scroll.js
@@ -1,4 +1,4 @@
-export function activeSidebar () {
+export function scrollActiveSidebar () {
}
diff --git a/src/core/event/sidebar.js b/src/core/event/sidebar.js
index a02ef7be..498354f5 100644
--- a/src/core/event/sidebar.js
+++ b/src/core/event/sidebar.js
@@ -1,5 +1,6 @@
import { isMobile } from '../util/env'
-import { getNode, on, body } from '../util/dom'
+import { getNode, on, body, findAll, toggleClass } from '../util/dom'
+import { getHash } from '../route/hash'
/**
* Toggle button
*/
@@ -14,7 +15,7 @@ export function btn (el) {
on(sidebar, 'click', () => {
toggle()
- setTimeout(() => activeLink(sidebar, true), 0)
+ setTimeout(() => getAndActive(true), 0)
})
}
}
@@ -23,6 +24,27 @@ export function sticky () {
}
-export function activeLink () {
+export function getAndActive (el, isParent) {
+ const dom = getNode(el)
+ const links = findAll(dom, 'a')
+ const hash = '#' + getHash()
+ let target
+
+ links
+ .sort((a, b) => b.href.length - a.href.length)
+ .forEach(a => {
+ const href = a.getAttribute('href')
+ const node = isParent ? a.parentNode : a
+
+ if (hash.indexOf(href) === 0 && !target) {
+ target = a
+ toggleClass(node, 'add', 'active')
+ } else {
+ toggleClass(node, 'remove', 'active')
+ }
+ })
+
+ // TODO FIXED
+ return target
}
diff --git a/src/core/render/compiler.js b/src/core/render/compiler.js
index 2d202407..129be25b 100644
--- a/src/core/render/compiler.js
+++ b/src/core/render/compiler.js
@@ -1,6 +1,7 @@
import marked from 'marked'
import Prism from 'prismjs'
-import { helper as helperTpl } from './tpl'
+import { helper as helperTpl, tree as treeTpl } from './tpl'
+import { genTree } from './gen-tree'
import { slugify, clearSlugCache } from './slugify'
import { emojify } from './emojify'
import { toURL } from '../route/hash'
@@ -9,8 +10,7 @@ import { isFn, merge, cached } from '../util/core'
let markdownCompiler = marked
let contentBase = ''
let renderer = new marked.Renderer()
-
-const toc = []
+let toc = []
/**
* Compile markdown content
@@ -29,8 +29,8 @@ export const markdown = cached(text => {
markdown.renderer = renderer
-markdown.init = function (config = {}, context = window.location.pathname) {
- contentBase = context
+markdown.init = function (config = {}, base = window.location.pathname) {
+ contentBase = base
if (isFn(config)) {
markdownCompiler = config(marked, renderer)
@@ -85,6 +85,34 @@ renderer.image = function (href, title, text) {
/**
* Compile sidebar
*/
-export function sidebar (text) {
+export function sidebar (text, level) {
+ let html = ''
+ if (text) {
+ html = markdown(text)
+ html = html.match(/
]*>([\s\S]+)<\/ul>/g)[0]
+ } else {
+ const tree = genTree(toc, level)
+ html = treeTpl(tree, '')
+ }
+
+ return html
+}
+
+/**
+ * Compile sub sidebar
+ */
+export function subSidebar (el, level) {
+ if (el) {
+ toc[0] && toc[0].level === 1 && toc.shift()
+ const tree = genTree(toc, level)
+ el.parentNode.innerHTML += treeTpl(tree, '')
+ }
+ toc = []
+}
+
+/**
+ * Compile cover page
+ */
+export function cover (text) {
}
diff --git a/src/core/render/index.js b/src/core/render/index.js
index ff25518e..2f4d1b88 100644
--- a/src/core/render/index.js
+++ b/src/core/render/index.js
@@ -1,14 +1,19 @@
import * as dom from '../util/dom'
+import { getAndActive } from '../event/sidebar'
+import { scrollActiveSidebar } from '../event/scroll'
import cssVars from '../util/polyfill/css-vars'
import * as tpl from './tpl'
-import { markdown, sidebar } from './compiler'
+import { markdown, sidebar, subSidebar } from './compiler'
import { callHook } from '../init/lifecycle'
function renderMain (html) {
if (!html) {
// TODO: Custom 404 page
}
+
this._renderTo('.markdown-section', html)
+ // Render sidebar with the TOC
+ !this.config.loadSidebar && this._renderSidebar()
}
export function renderMixin (Docsify) {
@@ -20,8 +25,12 @@ export function renderMixin (Docsify) {
}
proto._renderSidebar = function (text) {
- this._renderTo('.sidebar-nav', sidebar(text))
+ const { maxLevel, subMaxLevel } = this.config
+
+ this._renderTo('.sidebar-nav', sidebar(text, maxLevel))
+ subSidebar(getAndActive('.sidebar-nav', true), subMaxLevel)
// bind event
+ scrollActiveSidebar()
}
proto._renderNav = function (text) {
diff --git a/src/core/route/index.js b/src/core/route/index.js
index 3fa1020f..dc8eca2a 100644
--- a/src/core/route/index.js
+++ b/src/core/route/index.js
@@ -38,11 +38,12 @@ export function initRoute (vm) {
on('hashchange', _ => {
normalize()
- lastRoute = vm.route = parse()
+ vm.route = parse()
if (lastRoute.path === vm.route.path) {
// TODO: goto xxx
return
}
vm._fetch()
+ lastRoute = vm.route
})
}
diff --git a/src/core/util/dom.js b/src/core/util/dom.js
index a2bd22cc..06016a57 100644
--- a/src/core/util/dom.js
+++ b/src/core/util/dom.js
@@ -22,12 +22,24 @@ export const body = $.body
export const head = $.head
-export function find (node) {
- return $.querySelector(node)
+/**
+ * Find element
+ * @example
+ * find('nav') => document.querySelector('nav')
+ * find(nav, 'a') => nav.querySelector('a')
+ */
+export function find (el, node) {
+ return node ? el.querySelector(node) : $.querySelector(el)
}
-export function findAll (node) {
- return [].clice.call($.querySelectorAll(node))
+/**
+ * Find all elements
+ * @example
+ * findAll('a') => [].slice.call(document.querySelectorAll('a'))
+ * findAll(nav, 'a') => [].slice.call(nav.querySelectorAll('a'))
+ */
+export function findAll (el, node) {
+ return [].slice.call(node ? el.querySelectorAll(node) : $.querySelectorAll(el))
}
export function create (node, tpl) {
@@ -51,3 +63,14 @@ export const off = function on (el, type, handler) {
? window.removeEventListener(el, type)
: el.removeEventListener(type, handler)
}
+
+/**
+ * Toggle class
+ *
+ * @example
+ * toggleClass(el, 'active') => el.classList.toggle('active')
+ * toggleClass(el, 'add', 'active') => el.classList.add('active')
+ */
+export function toggleClass (el, type, val) {
+ el.classList[val ? type : 'toggle'](val || type)
+}