1.3 (#38)
* Add cover page * Update doc * Add kbd style, resolve #37 * headling can cliked, resolve #36 * Update change log, close #35 * Update docs
This commit is contained in:
parent
b14fcf7d1c
commit
50addfdac6
14 changed files with 312 additions and 48 deletions
22
src/event.js
22
src/event.js
|
|
@ -23,11 +23,11 @@ export function scrollActiveSidebar () {
|
|||
|
||||
function highlight () {
|
||||
for (let i = 0, len = anchors.length; i < len; i += 1) {
|
||||
const node = anchors[i].parentNode
|
||||
const node = anchors[i]
|
||||
const bcr = node.getBoundingClientRect()
|
||||
|
||||
if (bcr.top < 10 && bcr.bottom > 10) {
|
||||
const li = nav[node.id]
|
||||
const li = nav[node.getAttribute('data-id')]
|
||||
|
||||
if (!li || li === active) return
|
||||
if (active) active.setAttribute('class', '')
|
||||
|
|
@ -40,9 +40,8 @@ export function scrollActiveSidebar () {
|
|||
}
|
||||
}
|
||||
|
||||
const dom = document.querySelector('main .content')
|
||||
dom.removeEventListener('scroll', highlight)
|
||||
dom.addEventListener('scroll', highlight)
|
||||
window.removeEventListener('scroll', highlight)
|
||||
window.addEventListener('scroll', highlight)
|
||||
highlight()
|
||||
}
|
||||
|
||||
|
|
@ -100,3 +99,16 @@ export function scroll2Top () {
|
|||
}
|
||||
cacheContentDOM.scrollTop = 0
|
||||
}
|
||||
|
||||
export function sticky () {
|
||||
const dom = document.querySelector('section.cover')
|
||||
const coverHeight = dom.getBoundingClientRect().height
|
||||
|
||||
return (function () {
|
||||
if (window.pageYOffset >= coverHeight || dom.classList.contains('hidden')) {
|
||||
document.body.classList.add('sticky')
|
||||
} else {
|
||||
document.body.classList.remove('sticky')
|
||||
}
|
||||
})()
|
||||
}
|
||||
|
|
|
|||
14
src/index.js
14
src/index.js
|
|
@ -1,5 +1,5 @@
|
|||
import { load, camel2kebab, isNil, getRoute } from './util'
|
||||
import { activeLink, scrollIntoView } from './event'
|
||||
import { activeLink, scrollIntoView, sticky } from './event'
|
||||
import * as render from './render'
|
||||
|
||||
const OPTIONS = {
|
||||
|
|
@ -12,6 +12,7 @@ const OPTIONS = {
|
|||
loadNavbar: null,
|
||||
router: false,
|
||||
homepage: 'README.md',
|
||||
coverpage: '',
|
||||
basePath: '',
|
||||
auto2top: false
|
||||
}
|
||||
|
|
@ -25,6 +26,7 @@ if (script) {
|
|||
}
|
||||
if (OPTIONS.loadSidebar === true) OPTIONS.loadSidebar = '_sidebar.md'
|
||||
if (OPTIONS.loadNavbar === true) OPTIONS.loadNavbar = '_navbar.md'
|
||||
if (OPTIONS.coverpage === true) OPTIONS.coverpage = '_coverpage.md'
|
||||
if (OPTIONS.sidebar) OPTIONS.sidebar = window[OPTIONS.sidebar]
|
||||
}
|
||||
|
||||
|
|
@ -56,6 +58,15 @@ const mainRender = function (cb) {
|
|||
page = `${route}.md`
|
||||
}
|
||||
|
||||
// Render Cover page
|
||||
if (OPTIONS.coverpage) {
|
||||
if (page === OPTIONS.homepage) {
|
||||
load(OPTIONS.coverpage).then(render.renderCover)
|
||||
} else {
|
||||
render.renderCover()
|
||||
}
|
||||
}
|
||||
|
||||
cacheXhr && cacheXhr.abort && cacheXhr.abort()
|
||||
// Render markdown file
|
||||
cacheXhr = load(page, 'GET', render.renderLoading)
|
||||
|
|
@ -91,6 +102,7 @@ const Docsify = function () {
|
|||
mainRender(_ => {
|
||||
activeLink('aside.sidebar', true)
|
||||
scrollIntoView()
|
||||
OPTIONS.coverpage && sticky()
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
import marked from 'marked'
|
||||
import Prism from 'prismjs'
|
||||
import * as tpl from './tpl'
|
||||
import { activeLink, scrollActiveSidebar, bindToggle, scroll2Top } from './event'
|
||||
import { genTree, getRoute } from './util'
|
||||
import { activeLink, scrollActiveSidebar, bindToggle, scroll2Top, sticky } from './event'
|
||||
import { genTree, getRoute, isMobile } from './util'
|
||||
|
||||
let OPTIONS = {}
|
||||
const CACHE = {}
|
||||
|
|
@ -32,7 +32,7 @@ renderer.heading = function (text, level) {
|
|||
|
||||
toc.push({ level, slug: `${route}#${encodeURIComponent(slug)}`, title: text })
|
||||
|
||||
return `<h${level} id="${slug}"><a href="${route}#${slug}" class="anchor"></a>${text}</h${level}>`
|
||||
return `<a href="${route}#${slug}" data-id="${slug}" class="anchor"><h${level} id="${slug}">${text}</h${level}></a>`
|
||||
}
|
||||
// highlight code
|
||||
renderer.code = function (code, lang = '') {
|
||||
|
|
@ -55,11 +55,21 @@ marked.setOptions({ renderer })
|
|||
export function renderApp (dom, replace) {
|
||||
const nav = document.querySelector('nav') || document.createElement('nav')
|
||||
|
||||
dom[replace ? 'outerHTML' : 'innerHTML'] = tpl.toggle(OPTIONS.sidebarToggle) + tpl.corner(OPTIONS.repo) + tpl.main()
|
||||
if (!OPTIONS.repo) nav.classList.add('no-badge')
|
||||
|
||||
dom[replace ? 'outerHTML' : 'innerHTML'] = tpl.corner(OPTIONS.repo) +
|
||||
(OPTIONS.coverpage ? tpl.cover() : '') +
|
||||
tpl.main(OPTIONS.sidebarToggle ? tpl.toggle() : '')
|
||||
document.body.insertBefore(nav, document.body.children[0])
|
||||
|
||||
// bind toggle
|
||||
bindToggle('button.sidebar-toggle')
|
||||
// bind sticky effect
|
||||
if (OPTIONS.coverpage) {
|
||||
!isMobile() && window.addEventListener('scroll', sticky)
|
||||
} else {
|
||||
document.body.classList.add('sticky')
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -110,6 +120,20 @@ export function renderSidebar (content) {
|
|||
toc = []
|
||||
}
|
||||
|
||||
/**
|
||||
* Cover Page
|
||||
*/
|
||||
export function renderCover (content) {
|
||||
renderCover.dom = renderCover.dom || document.querySelector('section.cover')
|
||||
if (!content) {
|
||||
renderCover.dom.classList.add('hidden')
|
||||
} else {
|
||||
renderCover.dom.classList.remove('hidden')
|
||||
!renderCover.rendered && renderTo('.cover-main', marked(content))
|
||||
renderCover.rendered = true
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* render loading bar
|
||||
* @return {[type]} [description]
|
||||
|
|
|
|||
82
src/themes/basic/_coverpage.css
Normal file
82
src/themes/basic/_coverpage.css
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
section.cover {
|
||||
&.hidden {
|
||||
display: none;
|
||||
}
|
||||
|
||||
height: 100vh;
|
||||
position: relative;
|
||||
|
||||
.cover-main {
|
||||
position: absolute 0 0 0 0;
|
||||
padding: 20vh 0;
|
||||
text-align: center;
|
||||
margin: 0 16px;
|
||||
}
|
||||
|
||||
a {
|
||||
color: inherit;
|
||||
text-decoration: none;
|
||||
|
||||
&:hover {
|
||||
text-decoration: none;
|
||||
}
|
||||
}
|
||||
|
||||
h1 {
|
||||
text-align: center;
|
||||
font-size: 2.5rem;
|
||||
position: relative;
|
||||
margin: .625rem 0 2.5rem;
|
||||
font-weight: 300;
|
||||
color: inherit;
|
||||
|
||||
small {
|
||||
position: absolute;
|
||||
bottom: -.4375rem;
|
||||
font-size: 1rem;
|
||||
}
|
||||
}
|
||||
|
||||
blockquote {
|
||||
text-align: center;
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
|
||||
ul {
|
||||
max-width: 500px;
|
||||
list-style-type: none;
|
||||
margin: 1em auto;
|
||||
padding: 0;
|
||||
line-height: 1.8;
|
||||
}
|
||||
|
||||
p a {
|
||||
margin-top: 1em;
|
||||
border-radius: 2em;
|
||||
border: 1px solid $color-primary;
|
||||
box-sizing: border-box;
|
||||
color: $color-primary;
|
||||
font-size: 1.05em;
|
||||
letter-spacing: 0.1em;
|
||||
padding: 0.75em 2em;
|
||||
text-decoration: none;
|
||||
transition: all 0.15s ease;
|
||||
margin-right: 1em;
|
||||
display: inline-block;
|
||||
|
||||
&:last-child {
|
||||
margin-right: 0;
|
||||
background-color: $color-primary;
|
||||
color: #fff;
|
||||
|
||||
&:hover {
|
||||
opacity: .8;
|
||||
color: inherit;
|
||||
}
|
||||
}
|
||||
|
||||
&:hover {
|
||||
color: inherit;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
|
|
@ -38,6 +37,17 @@ img {
|
|||
max-width: 100%;
|
||||
}
|
||||
|
||||
kbd {
|
||||
display: inline-block;
|
||||
padding: 3px 5px;
|
||||
margin-bottom : 3px;
|
||||
font-size: 12px !important;
|
||||
line-height: 12px;
|
||||
vertical-align: middle;
|
||||
border: solid 1px #ccc;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
/* navbar */
|
||||
nav {
|
||||
position: absolute;
|
||||
|
|
@ -47,6 +57,10 @@ nav {
|
|||
margin: 25px 60px 0 0;
|
||||
text-align: right;
|
||||
|
||||
&.no-badge {
|
||||
margin-right: 25px;
|
||||
}
|
||||
|
||||
p {
|
||||
margin: 0;
|
||||
}
|
||||
|
|
@ -124,18 +138,13 @@ nav {
|
|||
|
||||
/* github corner */
|
||||
.github-corner {
|
||||
position: absolute;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
right: 0;
|
||||
z-index: 1;
|
||||
text-decoration: none;
|
||||
border-bottom: 0;
|
||||
|
||||
&:hover {
|
||||
background-color: inherit;
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
&:hover .octo-arm {
|
||||
animation:octocat-wave 560ms ease-in-out;
|
||||
}
|
||||
|
|
@ -154,6 +163,16 @@ main {
|
|||
position: relative;
|
||||
}
|
||||
|
||||
.anchor {
|
||||
text-decoration: none;
|
||||
transition: all .3s;
|
||||
display: block;
|
||||
|
||||
&:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
|
||||
/* sidebar */
|
||||
.sidebar {
|
||||
border-right: 1px solid rgba(0, 0, 0, .07);
|
||||
|
|
@ -209,11 +228,15 @@ main {
|
|||
}
|
||||
}
|
||||
|
||||
body.sticky {
|
||||
.sidebar, .sidebar-toggle {
|
||||
position: fixed;
|
||||
}
|
||||
}
|
||||
|
||||
/* main content */
|
||||
.content {
|
||||
overflow-y: auto;
|
||||
position: absolute 0 0 0 $sidebar-width;
|
||||
overflow-x: hidden;
|
||||
padding-top: 20px;
|
||||
transition: left 250ms ease;
|
||||
}
|
||||
|
|
@ -278,7 +301,6 @@ body.close {
|
|||
}
|
||||
|
||||
nav {
|
||||
position: static;
|
||||
margin-top: 16px;
|
||||
}
|
||||
|
||||
|
|
@ -295,8 +317,6 @@ body.close {
|
|||
left: 0;
|
||||
min-width: 100vw;
|
||||
transition: transform 250ms ease;
|
||||
position: static;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
nav, .github-corner {
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ $color-primary: #0074D9;
|
|||
$sidebar-width: 16em;
|
||||
|
||||
@import "basic/layout";
|
||||
@import "basic/coverpage";
|
||||
|
||||
body {
|
||||
color: #34495e;
|
||||
|
|
@ -11,6 +12,7 @@ body {
|
|||
/* sidebar */
|
||||
.sidebar {
|
||||
color: #364149;
|
||||
background-color: #fff;
|
||||
|
||||
a {
|
||||
color: #666;
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ $color-primary: #42b983;
|
|||
$sidebar-width: 300px;
|
||||
|
||||
@import "basic/layout";
|
||||
@import "basic/coverpage";
|
||||
|
||||
body {
|
||||
background-color: #fff;
|
||||
|
|
@ -13,6 +14,7 @@ body {
|
|||
/* sidebar */
|
||||
.sidebar {
|
||||
color: #364149;
|
||||
background-color: #fff;
|
||||
|
||||
li {
|
||||
margin: 6px 15px;
|
||||
|
|
|
|||
19
src/tpl.js
19
src/tpl.js
|
|
@ -21,10 +21,10 @@ export function corner (data) {
|
|||
|
||||
/**
|
||||
* Render main content
|
||||
* @return {[type]} [description]
|
||||
*/
|
||||
export function main () {
|
||||
export function main (tpl) {
|
||||
return `<main>
|
||||
${tpl}
|
||||
<aside class="sidebar"></aside>
|
||||
<section class="content">
|
||||
<article class="markdown-section"></article>
|
||||
|
|
@ -32,8 +32,19 @@ export function main () {
|
|||
</main>`
|
||||
}
|
||||
|
||||
export function toggle (bool) {
|
||||
if (!bool) return ''
|
||||
/**
|
||||
* Cover Page
|
||||
*/
|
||||
export function cover () {
|
||||
const SL = ', 100%, 85%'
|
||||
const bgc = `linear-gradient(to left bottom, hsl(${Math.floor(Math.random() * 255) + SL}) 0%, hsl(${Math.floor(Math.random() * 255) + SL}) 100%)`
|
||||
|
||||
return `<section class="cover" style="background: ${bgc}">
|
||||
<div class="cover-main"></div>
|
||||
</section>`
|
||||
}
|
||||
|
||||
export function toggle () {
|
||||
return `<button class="sidebar-toggle">
|
||||
<span></span><span></span><span></span>
|
||||
</button>`
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue