Compare commits

...
15 Commits
Author SHA1 Message Date
qingwei.li db7db5af8b -> v1.6.1 2017-01-10 23:49:06 +08:00
qingwei.li a418096a29 bump 1.6.1 2017-01-10 23:48:49 +08:00
qingwei.li 90b490c9c1 Fixed sidebar bug when the coverpage exist 2017-01-10 23:48:12 +08:00
qingwei.li 7915027418 -> v1.6.0 2017-01-10 23:34:20 +08:00
qingwei.li 87b373b841 bump 1.6.0 2017-01-10 23:33:41 +08:00
qingwei.li 510ae37a04 Add doc 2017-01-10 23:32:25 +08:00
qingwei.li ef53a07f49 Add new markdown grammar & improve sidebar performance. 2017-01-10 23:16:55 +08:00
qingwei.li 9defe1bf7d -> v1.5.2 2017-01-10 14:40:36 +08:00
qingwei.li b87f6ae5e8 bump 1.5.2 2017-01-10 14:40:21 +08:00
qingwei.li b8b9dbc872 Fixed number at the beginning of the slug, fixed #51 2017-01-10 14:39:40 +08:00
qingwei.li f7779b01d9 -> v1.5.1 2017-01-09 17:50:54 +08:00
qingwei.li 1c935b2fd7 bump 1.5.1 2017-01-09 17:50:43 +08:00
cinwell.liandGitHub 114955558e Remove HTML tag when handling slug, fixed #49 (#50)
* Remove HTML tag when handling slug, fixed #49

* Fix slugify
2017-01-09 17:47:38 +08:00
qingwei.li 847cf3b656 Update readme 2017-01-05 10:33:48 +08:00
Sina Nedadahandehandcinwell.li 356b937d44 Clean up readme (#48)
* Readme/homepage cleanup

* Readme cleanup
2017-01-05 10:31:41 +08:00
16 changed files with 216 additions and 98 deletions
+17
View File
@@ -1,3 +1,20 @@
## 1.6.1
### Bug fixes
- Fixed sidebar bug when the coverpage exist
## 1.6.0
### Features
- Improve sidebar performance. The active item is automatically scrolled in the visible view.
- New doc helper: `! `. e.g. `! content` will be rendered as `<p class="tip">content</p>`
## 1.5.2
### Bug fixes
- Fixed number at the beginning of the slug
## 1.5.1
### Bug fixes
- Remove HTML tag when handling slug
## 1.5.0
### Bug fixes
+31 -8
View File
@@ -33,7 +33,7 @@ Create `README.md` as the main page
```
### Deploy!
Push and open the **GitHub Pages** feature
Push code and activate **GitHub Pages** via your repo's settings
![image](https://cloud.githubusercontent.com/assets/7565692/20639058/e65e6d22-b3f3-11e6-9b8b-6309c89826f2.png)
## CLI
@@ -98,7 +98,7 @@ Code in `index.html`
### Cover Page
Generate a cover page through with markdown. Create a `_coverpage.md` and set `data-coverpage` in script tag.
Generate a cover page with markdown. Create a `_coverpage.md` and set `data-coverpage` in the script tag.
```markdown
![logo](_media/icon.svg)
@@ -117,7 +117,7 @@ Generate a cover page through with markdown. Create a `_coverpage.md` and set `d
```
#### Custom background
Currently the background of cover page is generated randomly. We can customize the background, just using the syntax to add image.
Currently the background of the cover page is generated randomly. We can customize the background color, or add a background image.
```markdown
# docsify <small>1.2.0</small>
@@ -135,7 +135,7 @@ Currently the background of cover page is generated randomly. We can customize t
### Markdown parser
Docsify uses [marked](https://github.com/chjj/marked) to parse markdown, we can configure it
Docsify uses [marked](https://github.com/chjj/marked) to parse markdown. We can configure it
```js
window.$docsify = {
@@ -145,7 +145,7 @@ window.$docsify = {
}
```
And can even be completely customized
And it can even be customized
```js
window.$docsify = {
@@ -157,9 +157,29 @@ window.$docsify = {
}
```
### Doc Helpers
#### p.tip
'! ' add your content will rendered as `<p class="tip">content</p>`
```markdown
! Important **information**
```
It will be rendered
```html
<p class="tip">Important <strong>information</strong></p>
```
e.g.
! Important **information**
## Options
You can add configuration by script tag attributes or `window.$docsify`.
You can add configurations in the script tag attributes or with `window.$docsify`.
### repo
Display the [GitHub Corner](http://tholman.com/github-corners/) widget.
@@ -247,7 +267,7 @@ window.$docsify = {
### load-sidebar
Load sidebar markdown file. If it is configured, load the current directory `_sidebar.md` by default. If the file isn't exist, sidebar will appear as a TOC.
Load sidebar markdown file. If it is configured, load the current directory `_sidebar.md` by default. If the file doesn't exist, the sidebar will appear as a TOC.
** you should add `.nojekyll` into docs folder to prevent GitHub Pages from ignoring the `_sidebar.md`**
```html
@@ -351,11 +371,14 @@ Scroll to the top on changing hash.
```html
<script src="/lib/docsify.js" data-auto2top></script>
<!-- Set offset top -->
<script src="/lib/docsify.js" data-auto2top="50"></script>
```
```js
window.$docsify = {
auto2top: true
auto2top: true,
// auto2top: 50
}
```
+1 -1
View File
@@ -1,6 +1,6 @@
![logo](_media/icon.svg)
# docsify <small>1.5.0</small>
# docsify <small>1.6.0</small>
> A magical documentation site generator.
+18
View File
@@ -163,6 +163,24 @@ window.$docsify = {
}
```
### 文档助手
#### 内置「提示」语法
感叹号加空格,后面接内容,会渲染成带 tip 类名的段落。
```markdown
! 提示信息,**支持其他 markdown 语法**
```
将被渲染成
```html
<p class="tip">提示信息<strong>支持其他 markdown 语法</strong></p>
```
效果
! 适合显示醒目的内容
## 配置参数
+52 -26
View File
@@ -125,8 +125,11 @@ function slugify (string) {
if (!maintainCase) { string = string.toLowerCase(); }
var slug = string.trim()
.replace(/<[^>\d]+>/g, '')
.replace(re, '')
.replace(/\s/g, replacement);
.replace(/\s/g, replacement)
.replace(/-+/g, replacement)
.replace(/^(\d)/, '_$1');
var occurrences = slugify.occurrences[slug];
if (slugify.occurrences.hasOwnProperty(slug)) {
@@ -172,10 +175,12 @@ var merge = Object.assign || function (to) {
function scrollActiveSidebar () {
if (isMobile()) { return }
var hoveredOverSidebar = false;
var anchors = document.querySelectorAll('.anchor');
var sidebar = document.querySelector('aside.sidebar');
var nav = {};
var lis = document.querySelectorAll('.sidebar li');
var active = null;
var lis = sidebar.querySelectorAll('li');
var active = sidebar.querySelector('li.active');
for (var i = 0, len = lis.length; i < len; i += 1) {
var li = lis[i];
@@ -190,27 +195,34 @@ function scrollActiveSidebar () {
}
function highlight () {
var top = document.body.scrollTop;
var last;
for (var i = 0, len = anchors.length; i < len; i += 1) {
var node = anchors[i];
var bcr = node.getBoundingClientRect();
if (bcr.top < 10 && bcr.bottom > 10) {
var li = nav[node.getAttribute('data-id')];
if (!li || li === active) { return }
if (active) { active.setAttribute('class', ''); }
li.setAttribute('class', 'active');
active = li;
return
if (node.offsetTop > top) {
if (!last) { last = node; }
break
} else {
last = node;
}
}
if (!last) { return }
var li = nav[last.getAttribute('data-id')];
if (!li || li === active) { return }
if (active) { active.classList.remove('active'); }
li.classList.add('active');
active = li;
!hoveredOverSidebar && sticky.isSticky && active.scrollIntoView();
}
window.removeEventListener('scroll', highlight);
window.addEventListener('scroll', highlight);
highlight();
sidebar.addEventListener('mouseover', function () { hoveredOverSidebar = true; });
sidebar.addEventListener('mouseleave', function () { hoveredOverSidebar = false; });
}
function scrollIntoView () {
@@ -218,7 +230,9 @@ function scrollIntoView () {
if (!id || !id.length) { return }
var section = document.querySelector(decodeURIComponent(id[0]));
if (section) { section.scrollIntoView(); }
if (section) { setTimeout(function () { return section.scrollIntoView(); }, 0); }
return section
}
/**
@@ -234,13 +248,13 @@ function activeLink (dom, activeParent) {
.forEach(function (node) {
if (host.indexOf(node.href) === 0 && !target) {
activeParent
? node.parentNode.setAttribute('class', 'active')
: node.setAttribute('class', 'active');
? node.parentNode.classList.add('active')
: node.classList.add('active');
target = node;
} else {
activeParent
? node.parentNode.removeAttribute('class')
: node.removeAttribute('class');
? node.parentNode.classList.remove('active')
: node.classList.remove('active');
}
});
@@ -258,13 +272,18 @@ function bindToggle (dom) {
dom.addEventListener('click', function () { return body.classList.toggle('close'); });
if (isMobile()) {
document.querySelector('aside')
.addEventListener('click', function (_) { return body.classList.toggle('close'); });
var sidebar = document.querySelector('aside.sidebar');
document.body.addEventListener('click', function (e) {
if (e.target !== dom && !dom.contains(e.target)) { body.classList.toggle('close'); }
if (sidebar.contains(e.target)) { setTimeout(function () { return activeLink(sidebar, true); }, 0); }
});
}
}
function scroll2Top () {
document.body.scrollTop = 0;
function scroll2Top (offset) {
if ( offset === void 0 ) offset = 0;
document.body.scrollTop = offset === true ? 0 : Number(offset);
}
function sticky () {
@@ -274,8 +293,10 @@ function sticky () {
return (function () {
if (window.pageYOffset >= coverHeight || dom.classList.contains('hidden')) {
document.body.classList.add('sticky');
sticky.isSticky = true;
} else {
document.body.classList.remove('sticky');
sticky.isSticky = false;
}
})()
}
@@ -2436,6 +2457,7 @@ var OPTIONS$1 = {};
var markdown = marked;
var toc = [];
var CACHE = {};
var TIP_RE = /^!\s/;
var renderTo = function (dom, content) {
dom = typeof dom === 'object' ? dom : document.querySelector(dom);
@@ -2485,6 +2507,10 @@ function init (options) {
return ("<a href=\"" + href + "\" title=\"" + (title || '') + "\">" + text + "</a>")
};
renderer.paragraph = function (text) {
var isTip = TIP_RE.test(text);
return isTip ? ("<p class=\"tip\">" + (text.replace(TIP_RE, '')) + "</p>") : ("<p>" + text + "</p>")
};
if (typeof OPTIONS$1.markdown === 'function') {
markdown.setOptions({ renderer: renderer });
@@ -2528,7 +2554,7 @@ function renderArticle (content) {
var vm = new Vue({ el: 'main' }); // eslint-disable-line
vm.$nextTick(function (_) { return scrollActiveSidebar(); });
}
if (OPTIONS$1.auto2top) { scroll2Top(); }
if (OPTIONS$1.auto2top) { setTimeout(function () { return scroll2Top(OPTIONS$1.auto2top); }, 0); }
}
/**
@@ -2558,7 +2584,7 @@ function renderSidebar (content) {
renderTo('aside.sidebar', html);
var target = activeLink('aside.sidebar', true);
if (content) { renderSubSidebar(target); }
if (target) { renderSubSidebar(target); }
toc = [];
scrollActiveSidebar();
+2 -2
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "docsify",
"version": "1.5.0",
"version": "1.6.1",
"description": "A magical documentation generator.",
"main": "lib/docsify.js",
"files": [
+39 -23
View File
@@ -7,10 +7,12 @@ import { isMobile } from './util'
export function scrollActiveSidebar () {
if (isMobile()) return
let hoveredOverSidebar = false
const anchors = document.querySelectorAll('.anchor')
const sidebar = document.querySelector('aside.sidebar')
const nav = {}
const lis = document.querySelectorAll('.sidebar li')
let active = null
const lis = sidebar.querySelectorAll('li')
let active = sidebar.querySelector('li.active')
for (let i = 0, len = lis.length; i < len; i += 1) {
const li = lis[i]
@@ -25,27 +27,34 @@ export function scrollActiveSidebar () {
}
function highlight () {
const top = document.body.scrollTop
let last
for (let i = 0, len = anchors.length; i < len; i += 1) {
const node = anchors[i]
const bcr = node.getBoundingClientRect()
if (bcr.top < 10 && bcr.bottom > 10) {
const li = nav[node.getAttribute('data-id')]
if (!li || li === active) return
if (active) active.setAttribute('class', '')
li.setAttribute('class', 'active')
active = li
return
if (node.offsetTop > top) {
if (!last) last = node
break
} else {
last = node
}
}
if (!last) return
const li = nav[last.getAttribute('data-id')]
if (!li || li === active) return
if (active) active.classList.remove('active')
li.classList.add('active')
active = li
!hoveredOverSidebar && sticky.isSticky && active.scrollIntoView()
}
window.removeEventListener('scroll', highlight)
window.addEventListener('scroll', highlight)
highlight()
sidebar.addEventListener('mouseover', () => { hoveredOverSidebar = true })
sidebar.addEventListener('mouseleave', () => { hoveredOverSidebar = false })
}
export function scrollIntoView () {
@@ -53,7 +62,9 @@ export function scrollIntoView () {
if (!id || !id.length) return
const section = document.querySelector(decodeURIComponent(id[0]))
if (section) section.scrollIntoView()
if (section) setTimeout(() => section.scrollIntoView(), 0)
return section
}
/**
@@ -71,13 +82,13 @@ export function activeLink (dom, activeParent) {
.forEach(node => {
if (host.indexOf(node.href) === 0 && !target) {
activeParent
? node.parentNode.setAttribute('class', 'active')
: node.setAttribute('class', 'active')
? node.parentNode.classList.add('active')
: node.classList.add('active')
target = node
} else {
activeParent
? node.parentNode.removeAttribute('class')
: node.removeAttribute('class')
? node.parentNode.classList.remove('active')
: node.classList.remove('active')
}
})
@@ -95,13 +106,16 @@ export function bindToggle (dom) {
dom.addEventListener('click', () => body.classList.toggle('close'))
if (isMobile()) {
document.querySelector('aside')
.addEventListener('click', _ => body.classList.toggle('close'))
const sidebar = document.querySelector('aside.sidebar')
document.body.addEventListener('click', e => {
if (e.target !== dom && !dom.contains(e.target)) body.classList.toggle('close')
if (sidebar.contains(e.target)) setTimeout(() => activeLink(sidebar, true), 0)
})
}
}
export function scroll2Top () {
document.body.scrollTop = 0
export function scroll2Top (offset = 0) {
document.body.scrollTop = offset === true ? 0 : Number(offset)
}
export function sticky () {
@@ -111,8 +125,10 @@ export function sticky () {
return (function () {
if (window.pageYOffset >= coverHeight || dom.classList.contains('hidden')) {
document.body.classList.add('sticky')
sticky.isSticky = true
} else {
document.body.classList.remove('sticky')
sticky.isSticky = false
}
})()
}
+15 -10
View File
@@ -1,13 +1,14 @@
import marked from 'marked'
import Prism from 'prismjs'
import * as tpl from './tpl'
import { activeLink, scrollActiveSidebar, bindToggle, scroll2Top, sticky } from './event'
import * as event from './event'
import { genTree, getRoute, isMobile, slugify, merge } from './util'
let OPTIONS = {}
let markdown = marked
let toc = []
const CACHE = {}
const TIP_RE = /^!\s/
const renderTo = function (dom, content) {
dom = typeof dom === 'object' ? dom : document.querySelector(dom)
@@ -55,6 +56,10 @@ export function init (options) {
return `<a href="${href}" title="${title || ''}">${text}</a>`
}
renderer.paragraph = function (text) {
const isTip = TIP_RE.test(text)
return isTip ? `<p class="tip">${text.replace(TIP_RE, '')}</p>` : `<p>${text}</p>`
}
if (typeof OPTIONS.markdown === 'function') {
markdown.setOptions({ renderer })
@@ -78,10 +83,10 @@ export function renderApp (dom, replace) {
document.body.insertBefore(nav, document.body.children[0])
// bind toggle
bindToggle('button.sidebar-toggle')
event.bindToggle('button.sidebar-toggle')
// bind sticky effect
if (OPTIONS.coverpage) {
!isMobile() && window.addEventListener('scroll', sticky)
!isMobile() && window.addEventListener('scroll', event.sticky)
} else {
document.body.classList.add('sticky')
}
@@ -96,9 +101,9 @@ export function renderArticle (content) {
if (content && typeof Vue !== 'undefined' && typeof Vuep !== 'undefined') {
const vm = new Vue({ el: 'main' }) // eslint-disable-line
vm.$nextTick(_ => scrollActiveSidebar())
vm.$nextTick(_ => event.scrollActiveSidebar())
}
if (OPTIONS.auto2top) scroll2Top()
if (OPTIONS.auto2top) setTimeout(() => event.scroll2Top(OPTIONS.auto2top), 0)
}
/**
@@ -109,7 +114,7 @@ export function renderNavbar (content) {
CACHE.navbar = content
if (content) renderTo('nav', markdown(content))
activeLink('nav')
event.activeLink('nav')
}
/**
@@ -127,11 +132,11 @@ export function renderSidebar (content) {
}
renderTo('aside.sidebar', html)
const target = activeLink('aside.sidebar', true)
if (content) renderSubSidebar(target)
const target = event.activeLink('aside.sidebar', true)
if (target) renderSubSidebar(target)
toc = []
scrollActiveSidebar()
event.scrollActiveSidebar()
}
export function renderSubSidebar (target) {
@@ -171,7 +176,7 @@ export function renderCover (content) {
renderTo('.cover-main', html)
renderCover.rendered = true
sticky()
event.sticky()
}
/**
+34
View File
@@ -291,6 +291,40 @@ body.sticky {
}
}
.markdown-section p.tip {
padding: 12px 24px 12px 30px;
margin: 2em 0;
border-left: 4px solid #f66;
background-color: #f8f8f8;
position: relative;
border-bottom-right-radius: 2px;
border-top-right-radius: 2px;
&:before {
position: absolute;
top: 14px;
left: -12px;
background-color: #f66;
color: $color-bg;
content: "!";
size: 20px;
border-radius: 100%;
text-align: center;
line-height: 20px;
font-weight: bold;
font-family: 'Dosis', 'Source Sans Pro', 'Helvetica Neue', Arial, sans-serif;
font-size: 14px;
}
code {
background-color: #efefef;
}
em {
color: $color-text;
}
}
body.close {
.sidebar {
transform: translateX(-$sidebar-width);
-12
View File
@@ -238,15 +238,3 @@ code .token {
-webkit-font-smoothing: initial;
-moz-osx-font-smoothing: initial;
}
.content span.light {
color: #7f8c8d;
}
.content span.info {
display: inline-block;
font-size: 0.85em;
margin-left: 20px;
vertical-align: middle;
width: 280px;
}
-12
View File
@@ -285,15 +285,3 @@ pre::after {
text-align: right;
top: 0;
}
.content span.light {
color: #7f8c8d;
}
.content span.info {
display: inline-block;
font-size: 0.85em;
margin-left: 20px;
vertical-align: middle;
width: 280px;
}
+3
View File
@@ -117,8 +117,11 @@ export function slugify (string) {
if (!maintainCase) string = string.toLowerCase()
let slug = string.trim()
.replace(/<[^>\d]+>/g, '')
.replace(re, '')
.replace(/\s/g, replacement)
.replace(/-+/g, replacement)
.replace(/^(\d)/, '_$1')
let occurrences = slugify.occurrences[slug]
if (slugify.occurrences.hasOwnProperty(slug)) {