diff --git a/src/core/event/sidebar.js b/src/core/event/sidebar.js index 498354f5..aa4475b4 100644 --- a/src/core/event/sidebar.js +++ b/src/core/event/sidebar.js @@ -1,6 +1,7 @@ import { isMobile } from '../util/env' import { getNode, on, body, findAll, toggleClass } from '../util/dom' import { getHash } from '../route/hash' + /** * Toggle button */ @@ -21,7 +22,15 @@ export function btn (el) { } export function sticky () { + const cover = getNode('section.cover') + if (!cover) return + const coverHeight = cover.getBoundingClientRect().height + if (window.pageYOffset >= coverHeight || cover.classList.contains('hidden')) { + toggleClass(body, 'add', 'sticky') + } else { + toggleClass(body, 'remove', 'sticky') + } } export function getAndActive (el, isParent) { @@ -45,6 +54,5 @@ export function getAndActive (el, isParent) { } }) - // TODO FIXED return target } diff --git a/src/core/fetch/index.js b/src/core/fetch/index.js index 3602baf4..d5316aeb 100644 --- a/src/core/fetch/index.js +++ b/src/core/fetch/index.js @@ -15,6 +15,8 @@ export function fetchMixin (Docsify) { last && last.abort && last.abort() last = get(this.$getFile(path), true) + + // Load main content last.then(text => { this._renderMain(text) if (!loadSidebar) return cb() @@ -23,6 +25,7 @@ export function fetchMixin (Docsify) { // Load sidebar get(this.$getFile(root + loadSidebar)) + // fallback root navbar when fail .then(fn, _ => get(loadSidebar).then(fn)) }, _ => this._renderMain(null)) @@ -31,13 +34,28 @@ export function fetchMixin (Docsify) { loadNavbar && get(this.$getFile(root + loadNavbar)) .then( - this._renderNav, - _ => get(loadNavbar).then(this._renderNav) + text => this._renderNav(text), + // fallback root navbar when fail + _ => get(loadNavbar).then(text => this._renderNav(text)) ) } + + Docsify.prototype._fetchCover = function () { + const { coverpage } = this.config + const root = getRoot(this.route.path) + + if (this.route.path !== '/' || !coverpage) { + this._renderCover() + return + } + + get(this.$getFile(root + coverpage)) + .then(text => this._renderCover(text)) + } } export function initFetch (vm) { + vm._fetchCover(vm) vm._fetch(result => { vm.$resetEvents() callHook(vm, 'doneEach') diff --git a/src/core/render/compiler.js b/src/core/render/compiler.js index 129be25b..06c046c4 100644 --- a/src/core/render/compiler.js +++ b/src/core/render/compiler.js @@ -5,7 +5,7 @@ import { genTree } from './gen-tree' import { slugify, clearSlugCache } from './slugify' import { emojify } from './emojify' import { toURL } from '../route/hash' -import { isFn, merge, cached } from '../util/core' +import { isFn, merge, cached, noop } from '../util/core' let markdownCompiler = marked let contentBase = '' @@ -115,4 +115,10 @@ export function subSidebar (el, level) { * Compile cover page */ export function cover (text) { + const cacheToc = toc.slice() + const html = markdown(text) + + toc = cacheToc.slice() + + return html } diff --git a/src/core/render/index.js b/src/core/render/index.js index 2f4d1b88..53cc62da 100644 --- a/src/core/render/index.js +++ b/src/core/render/index.js @@ -1,9 +1,9 @@ import * as dom from '../util/dom' -import { getAndActive } from '../event/sidebar' +import { getAndActive, sticky } from '../event/sidebar' import { scrollActiveSidebar } from '../event/scroll' import cssVars from '../util/polyfill/css-vars' import * as tpl from './tpl' -import { markdown, sidebar, subSidebar } from './compiler' +import { markdown, sidebar, subSidebar, cover } from './compiler' import { callHook } from '../init/lifecycle' function renderMain (html) { @@ -34,7 +34,8 @@ export function renderMixin (Docsify) { } proto._renderNav = function (text) { - this._renderTo('nav', markdown(text)) + text && this._renderTo('nav', markdown(text)) + getAndActive('nav') } proto._renderMain = function (text) { @@ -43,6 +44,31 @@ export function renderMixin (Docsify) { callHook(this, 'afterEach', html, text => renderMain.call(this, text)) }) } + + proto._renderCover = function (text) { + const el = dom.getNode('.cover') + if (!text) { + dom.toggleClass(el, 'remove', 'show') + return + } + dom.toggleClass(el, 'add', 'show') + + let html = cover(text) + const m = html.trim().match('

([^<]*?)

$') + + if (m) { + if (m[2] === 'color') { + el.style.background = m[1] + (m[3] || '') + } else { + dom.toggleClass(el, 'add', 'has-mask') + el.style.backgroundImage = `url(${m[1]})` + } + html = html.replace(m[0], '') + } + + this._renderTo('.cover-main', html) + sticky() + } } export function initRender (vm) { diff --git a/src/core/route/hash.js b/src/core/route/hash.js index b114f3db..7f0129df 100644 --- a/src/core/route/hash.js +++ b/src/core/route/hash.js @@ -1,5 +1,5 @@ import { merge } from '../util/core' -import { parseQuery, stringifyQuery, cleanPath } from './util' +import { parseQuery, stringifyQuery } from './util' function replaceHash (path) { const i = window.location.href.indexOf('#') diff --git a/src/core/route/index.js b/src/core/route/index.js index dc8eca2a..ad29c574 100644 --- a/src/core/route/index.js +++ b/src/core/route/index.js @@ -39,10 +39,13 @@ export function initRoute (vm) { on('hashchange', _ => { normalize() vm.route = parse() + if (lastRoute.path === vm.route.path) { // TODO: goto xxx return } + + vm._fetchCover() vm._fetch() lastRoute = vm.route })