Skip to content

Commit b7768b1

Browse files
committed
feat(render): add auto header
1 parent fd9c3bd commit b7768b1

File tree

6 files changed

+50
-26
lines changed

6 files changed

+50
-26
lines changed

src/core/config.js

+1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ const config = merge({
1414
name: '',
1515
themeColor: '',
1616
nameLink: window.location.pathname,
17+
autoHeader: false,
1718
ga: ''
1819
}, window.$docsify)
1920

src/core/event/sidebar.js

+28-16
Original file line numberDiff line numberDiff line change
@@ -1,43 +1,51 @@
11
import { isMobile } from '../util/env'
2-
import { getNode, on, body, findAll, toggleClass } from '../util/dom'
2+
import * as dom from '../util/dom'
33
import { getHash } from '../route/hash'
44

5+
const title = dom.$.title
56
/**
67
* Toggle button
78
*/
89
export function btn (el) {
9-
const toggle = () => body.classList.toggle('close')
10+
const toggle = () => dom.body.classList.toggle('close')
1011

11-
el = getNode(el)
12-
on(el, 'click', toggle)
12+
el = dom.getNode(el)
13+
dom.on(el, 'click', toggle)
1314

1415
if (isMobile) {
15-
const sidebar = getNode('.sidebar')
16+
const sidebar = dom.getNode('.sidebar')
1617

17-
on(sidebar, 'click', () => {
18+
dom.on(sidebar, 'click', () => {
1819
toggle()
19-
setTimeout(() => getAndActive(true), 0)
20+
setTimeout(() => getAndActive(sidebar, true, true), 0)
2021
})
2122
}
2223
}
2324

2425
export function sticky () {
25-
const cover = getNode('section.cover')
26+
const cover = dom.getNode('section.cover')
2627
if (!cover) return
2728
const coverHeight = cover.getBoundingClientRect().height
2829

2930
if (window.pageYOffset >= coverHeight || cover.classList.contains('hidden')) {
30-
toggleClass(body, 'add', 'sticky')
31+
dom.toggleClass(dom.body, 'add', 'sticky')
3132
} else {
32-
toggleClass(body, 'remove', 'sticky')
33+
dom.toggleClass(dom.body, 'remove', 'sticky')
3334
}
3435
}
3536

36-
export function getAndActive (el, isParent) {
37-
const dom = getNode(el)
38-
const links = findAll(dom, 'a')
39-
const hash = '#' + getHash()
37+
/**
38+
* Get and active link
39+
* @param {string|element} el
40+
* @param {Boolean} isParent acitve parent
41+
* @param {Boolean} autoTitle auto set title
42+
* @return {element}
43+
*/
44+
export function getAndActive (el, isParent, autoTitle) {
45+
el = dom.getNode(el)
4046

47+
const links = dom.findAll(el, 'a')
48+
const hash = '#' + getHash()
4149
let target
4250

4351
links
@@ -48,11 +56,15 @@ export function getAndActive (el, isParent) {
4856

4957
if (hash.indexOf(href) === 0 && !target) {
5058
target = a
51-
toggleClass(node, 'add', 'active')
59+
dom.toggleClass(node, 'add', 'active')
5260
} else {
53-
toggleClass(node, 'remove', 'active')
61+
dom.toggleClass(node, 'remove', 'active')
5462
}
5563
})
5664

65+
if (autoTitle) {
66+
dom.$.title = target ? `${target.innerText} - ${title}` : title
67+
}
68+
5769
return target
5870
}

src/core/render/compiler.js

+1-4
Original file line numberDiff line numberDiff line change
@@ -67,10 +67,7 @@ renderer.code = function (code, lang = '') {
6767
return `<pre v-pre data-lang="${lang}"><code class="lang-${lang}">${hl}</code></pre>`
6868
}
6969
renderer.link = function (href, title, text) {
70-
if (!/:|(\/{2})/.test(href)) {
71-
href = toURL(href)
72-
}
73-
return `<a href="${href}" title="${title || ''}">${text}</a>`
70+
return `<a href="${toURL(href)}" title="${title || text}">${text}</a>`
7471
}
7572
renderer.paragraph = function (text) {
7673
if (/^!&gt;/.test(text)) {

src/core/render/index.js

+13-3
Original file line numberDiff line numberDiff line change
@@ -46,12 +46,22 @@ export function renderMixin (proto) {
4646
}
4747

4848
proto._renderSidebar = function (text) {
49-
const { maxLevel, subMaxLevel } = this.config
49+
const { maxLevel, subMaxLevel, autoHeader } = this.config
5050

5151
this._renderTo('.sidebar-nav', sidebar(text, maxLevel))
52-
subSidebar(getAndActive('.sidebar-nav', true), subMaxLevel)
52+
const active = getAndActive('.sidebar-nav', true, true)
53+
subSidebar(active, subMaxLevel)
5354
// bind event
5455
scrollActiveSidebar()
56+
57+
if (autoHeader && active) {
58+
const main = dom.getNode('#main')
59+
if (main.children[0].tagName !== 'H1') {
60+
const h1 = dom.create('h1')
61+
h1.innerText = active.innerText
62+
dom.before(main, h1)
63+
}
64+
}
5565
}
5666

5767
proto._renderNav = function (text) {
@@ -128,7 +138,7 @@ export function initRender (vm) {
128138
// Render main app
129139
vm._renderTo(el, html, true)
130140
// Add nav
131-
dom.body.insertBefore(navEl, dom.body.children[0])
141+
dom.before(dom.body, navEl)
132142

133143
if (config.themeColor) {
134144
dom.$.head += tpl.theme(config.themeColor)

src/core/route/hash.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { merge, cached } from '../util/core'
2-
import { parseQuery, stringifyQuery } from './util'
2+
import { parseQuery, stringifyQuery, cleanPath } from './util'
33

44
function replaceHash (path) {
55
const i = window.location.href.indexOf('#')
@@ -70,5 +70,5 @@ export function toURL (path, params) {
7070
route.query = merge({}, route.query, params)
7171
path = route.path + stringifyQuery(route.query)
7272

73-
return '#' + path
73+
return cleanPath('#/' + path)
7474
}

src/core/util/dom.js

+5-1
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,10 @@ export function appendTo (target, el) {
5252
return target.appendChild(el)
5353
}
5454

55+
export function before (target, el) {
56+
return target.insertBefore(el, target.children[0])
57+
}
58+
5559
export function on (el, type, handler) {
5660
isFn(type)
5761
? window.addEventListener(el, type)
@@ -72,5 +76,5 @@ export const off = function on (el, type, handler) {
7276
* toggleClass(el, 'add', 'active') => el.classList.add('active')
7377
*/
7478
export function toggleClass (el, type, val) {
75-
el.classList[val ? type : 'toggle'](val || type)
79+
el && el.classList[val ? type : 'toggle'](val || type)
7680
}

0 commit comments

Comments
 (0)