mirror of
https://github.com/wahyd4/docsify.git
synced 2026-08-09 13:26:34 +10:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
84871ca09e | ||
|
|
200dcf61ce | ||
|
|
816b6e2035 | ||
|
|
e4a35d9dcf | ||
|
|
02a0adb872 | ||
|
|
e48518b42a | ||
|
|
4d56be2f10 | ||
|
|
19bf043cf8 | ||
|
|
a74cf6ceaf | ||
|
|
0f966e2eb1 | ||
|
|
d07ddaa85d | ||
|
|
dd361b34b9 | ||
|
|
1a7c6c094c | ||
|
|
35d3bd1647 | ||
|
|
e09b6f218f | ||
|
|
4d7772035f | ||
|
|
6540e7370d | ||
|
|
f3853d8e7f | ||
|
|
93ddf08615 | ||
|
|
7c05d729b4 | ||
|
|
5953ef7739 | ||
|
|
d556282471 | ||
|
|
ec58149aad | ||
|
|
e15c53a6b8 | ||
|
|
f450b118ee | ||
|
|
6ac7d4f66f |
@@ -1,3 +1,4 @@
|
||||
*.log
|
||||
node_modules
|
||||
yarn.lock
|
||||
/themes
|
||||
+2
-6
@@ -3,14 +3,10 @@
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
|
||||
<link rel="stylesheet" href="/themes/vue.css">
|
||||
<link rel="stylesheet" href="/themes/buble.css">
|
||||
</head>
|
||||
<body>
|
||||
<nav>
|
||||
<a href="/">En</a>
|
||||
<a href="/zh-cn">中文</a>
|
||||
</nav>
|
||||
<div id="app"></div>
|
||||
</body>
|
||||
<script src="/lib/docsify.js" data-repo="qingwei-li/docsify"></script>
|
||||
<script src="/lib/docsify.js" data-repo="qingwei-li/docsify" data-sidebar-toggle data-load-navbar></script>
|
||||
</html>
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
## 0.7.0
|
||||
### Breaking change
|
||||
- `themes/` was removed, only exists in the npm package.
|
||||
|
||||
### Bug fixes
|
||||
- Fix style.
|
||||
- Fix sidebar animation again.
|
||||
|
||||
## 0.6.1
|
||||
### Bug fixes
|
||||
- In the mobile, it should collapse the sidebar when toggle is clicked.
|
||||
- Fix the dropdown list style.
|
||||
- Fix sidebar animation.
|
||||
|
||||
## 0.6.0
|
||||
### Features
|
||||
- Navbar support dropdown list, #6
|
||||
- Sidebar with toggle
|
||||
|
||||
### Bug fixes
|
||||
- Fix ineffective option, fixed #10
|
||||
|
||||
## 0.5.0
|
||||
### Features
|
||||
- Custom sidebars and navbars by markdown file
|
||||
|
||||
## 0.4.2
|
||||
### Bug fixes
|
||||
- Correct catch ajax error
|
||||
|
||||
## 0.4.1
|
||||
### Bug fixes
|
||||
- catch ajax error
|
||||
|
||||
## 0.4.0
|
||||
### Features
|
||||
- Custom sidebar
|
||||
|
||||
### Bug fixes
|
||||
- Fix undefined language
|
||||
|
||||
## 0.3.1
|
||||
### Bug fixes
|
||||
- Strip HTML tag when rendering the headings
|
||||
|
||||
## 0.3.0
|
||||
### Features
|
||||
- Add minified css files
|
||||
- Add max level option
|
||||
- Add pure.css
|
||||
|
||||
## 0.2.1
|
||||
### Bug fixes
|
||||
- Fix vue.css
|
||||
|
||||
## 0.2.0
|
||||
### Bug fixes
|
||||
- Fix route
|
||||
- Remove dynamic title
|
||||
|
||||
## 0.1.0
|
||||
### Features
|
||||
- Add buble.css
|
||||
@@ -5,7 +5,7 @@
|
||||
>🃏 A magical documentation site generator.
|
||||
|
||||
## Links
|
||||
- [Documentation](https://qingwei-li.github.io/docsify)
|
||||
- [Documentation](https://docsify.js.org)
|
||||
- [CLI](https://github.com/QingWei-Li/docsify-cli)
|
||||
|
||||
## Features
|
||||
@@ -14,7 +14,7 @@
|
||||
- No build
|
||||
|
||||
## Quick start
|
||||
Create `404.html` and `README.md` into `/docs`.
|
||||
Create a `404.html` and `README.md` into `/docs`.
|
||||
|
||||
404.html
|
||||
|
||||
@@ -30,6 +30,12 @@ Create `404.html` and `README.md` into `/docs`.
|
||||
</html>
|
||||
```
|
||||
|
||||
## Showcase
|
||||
These open-source projects are using docsify to generate their sites.
|
||||
|
||||
- [docsify](https://docsify.js.org) - A magical documentation site generator.
|
||||
|
||||
|
||||
## How to contribute
|
||||
|
||||
- Fork it and clone!
|
||||
|
||||
+22
-4
@@ -1,20 +1,38 @@
|
||||
var fs = require('fs')
|
||||
var cssnano = require('cssnano').process
|
||||
var resolve = require('path').resolve
|
||||
var postcss = require('postcss')
|
||||
|
||||
var save = function (file, content) {
|
||||
var processor = postcss([require('postcss-salad')])
|
||||
|
||||
var saveMin = function (file, content) {
|
||||
fs.writeFileSync(resolve(__dirname, '../lib/themes/', file), content)
|
||||
}
|
||||
var save = function (file, content) {
|
||||
fs.writeFileSync(resolve(__dirname, '../themes/', file), content)
|
||||
}
|
||||
var load = function (file) {
|
||||
return fs.readFileSync(resolve(__dirname, '../src/themes/', file)).toString()
|
||||
}
|
||||
var loadLib = function (file) {
|
||||
return fs.readFileSync(resolve(__dirname, '../themes/', file)).toString()
|
||||
}
|
||||
|
||||
var list = fs.readdirSync(resolve(__dirname, '../themes'))
|
||||
var list = fs.readdirSync(resolve(__dirname, '../src/themes'))
|
||||
|
||||
list.forEach(function (file) {
|
||||
cssnano(load(file))
|
||||
if (!/\.css$/.test(file)) return
|
||||
processor.process(load(file), { from: resolve(__dirname, '../src/themes/', file) })
|
||||
.then(function (result) {
|
||||
save(file, result.css)
|
||||
console.log('cssnao - ' + file)
|
||||
console.log('salad - ' + file)
|
||||
cssnano(loadLib(file))
|
||||
.then(function (result) {
|
||||
saveMin(file, result.css)
|
||||
console.log('cssnao - ' + file)
|
||||
})
|
||||
}).catch(function (err) {
|
||||
console.log(err)
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
+4
-1
@@ -15,11 +15,14 @@ var build = function (opts) {
|
||||
|
||||
console.log(dest)
|
||||
bundle.write({
|
||||
format: 'umd',
|
||||
format: 'iife',
|
||||
moduleName: opts.moduleName || 'Docsify',
|
||||
dest: dest
|
||||
})
|
||||
})
|
||||
.catch(function (err) {
|
||||
console.error(err)
|
||||
})
|
||||
}
|
||||
|
||||
build({
|
||||
|
||||
+8
-4
@@ -2,17 +2,21 @@
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Docsify</title>
|
||||
<title>docsify - A magical documentation site generator.</title>
|
||||
<meta name="description" content="A magical documentation generator.">
|
||||
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
|
||||
<link rel="stylesheet" href="//unpkg.com/docsify/lib/themes/vue.css">
|
||||
</head>
|
||||
<body>
|
||||
<nav>
|
||||
<a href="/docsify/">En</a>
|
||||
<a href="/docsify/zh-cn">中文</a>
|
||||
<a href="/">En</a>
|
||||
<a href="/zh-cn">中文</a>
|
||||
</nav>
|
||||
<div id="app"></div>
|
||||
</body>
|
||||
<script src="//unpkg.com/docsify/lib/docsify.min.js" data-repo="qingwei-li/docsify" data-max-level="3"></script>
|
||||
<script
|
||||
src="//unpkg.com/docsify/lib/docsify.min.js"
|
||||
data-repo="qingwei-li/docsify"
|
||||
data-max-level="3"
|
||||
data-sidebar-toggle></script>
|
||||
</html>
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
docsify.js.org
|
||||
@@ -121,6 +121,14 @@ Root element.
|
||||
<script src="//unpkg.com/docsify" data-el="#app"></script>
|
||||
```
|
||||
|
||||
#### sidebar-toggle
|
||||
|
||||
Sidebar with toggle
|
||||
|
||||
```html
|
||||
<script src="//unpkg.com/docsify" data-sidebar-toggle></script>
|
||||
```
|
||||
|
||||
#### sidebar
|
||||
|
||||
Custom sidebar. if it'set, the TOC will be disabeld. Bind global variables on the `data-sidebar`.
|
||||
@@ -144,3 +152,69 @@ Custom sidebar. if it'set, the TOC will be disabeld. Bind global variables on th
|
||||
<script src="/lib/docsify.js" data-sidebar="sidebar"></script>
|
||||
```
|
||||
|
||||
|
||||
#### 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 TOC.
|
||||
|
||||
```html
|
||||
<script src="/lib/docsify.js" data-load-sidebar></script>
|
||||
```
|
||||
|
||||
You can specify a file:
|
||||
|
||||
```html
|
||||
<script src="/lib/docsify.js" data-load-sidebar="_sidebar.md"></script>
|
||||
```
|
||||
|
||||
The contents of the file can be:
|
||||
|
||||
```markdown
|
||||
- [Home](/)
|
||||
- [Installation](/installation)
|
||||
- Essentials
|
||||
- [Getting Started](/getting-started)
|
||||
- [Dynamic Route Matching](/dynamic-matching)
|
||||
- [Nested Routes](/nested-routes)
|
||||
- [Programmatic Navigation](/navigation)
|
||||
- [Named Routes](/named-routes)
|
||||
- [Named Views](/named-views)
|
||||
- [Redirect and Alias](/redirect-and-alias)
|
||||
- [HTML5 History Mode](/history-mode)
|
||||
```
|
||||
|
||||
#### load-navbar
|
||||
|
||||
Load navbar markdown file. If it is configured, load the current directory `_navbar.md` by default.
|
||||
|
||||
```html
|
||||
<script src="/lib/docsify.js" data-load-navbar></script>
|
||||
```
|
||||
|
||||
You can specify a file:
|
||||
|
||||
```html
|
||||
<script src="/lib/docsify.js" data-load-navbar="_navbar.md"></script>
|
||||
```
|
||||
|
||||
The contents of the file can be:
|
||||
|
||||
```markdown
|
||||
- [en](/)
|
||||
- [chinese](/zh-cn)
|
||||
```
|
||||
|
||||
If you write a sub level list, it will generate a dropdown list.
|
||||
|
||||
```markdown
|
||||
- [download](/download)
|
||||
- language
|
||||
- [en](/)
|
||||
- [chinese](/zh-cn)
|
||||
```
|
||||
|
||||
## FAQ
|
||||
|
||||
### Why use `404.html` instead of `index.html`
|
||||
|
||||
[issues/7](https://github.com/QingWei-Li/docsify/issues/7)
|
||||
|
||||
@@ -119,6 +119,14 @@ docsify serve docs
|
||||
<script src="//unpkg.com/docsify" data-el="#app"></script>
|
||||
```
|
||||
|
||||
#### sidebar-toggle
|
||||
|
||||
Sidebar 开关按钮
|
||||
|
||||
```html
|
||||
<script src="//unpkg.com/docsify" data-sidebar-toggle></script>
|
||||
```
|
||||
|
||||
#### sidebar
|
||||
|
||||
设置后 TOC 功能将不可用,适合导航较多的文档,`data-sidebar` 传入全局变量名。
|
||||
@@ -142,3 +150,72 @@ docsify serve docs
|
||||
<script src="/lib/docsify.js" data-sidebar="sidebar"></script>
|
||||
```
|
||||
|
||||
#### load-sidebar
|
||||
|
||||
读取侧边栏配置文件,如果配置,默认加载当前目录下的 `_sidebar.md`。如果文件不存在,会显示 TOC 作为侧边栏内容。如果你有二级目录,也应该放置一份配置文件。
|
||||
|
||||
```html
|
||||
<script src="/lib/docsify.js" data-load-sidebar></script>
|
||||
```
|
||||
|
||||
你可以指定侧边栏文件名
|
||||
|
||||
```html
|
||||
<script src="/lib/docsify.js" data-load-sidebar="_sidebar.md"></script>
|
||||
```
|
||||
|
||||
`_sidebar.md` 的内容可以是这样的
|
||||
|
||||
```markdown
|
||||
- [Home](/)
|
||||
- [Installation](/installation)
|
||||
- Essentials
|
||||
- [Getting Started](/getting-started)
|
||||
- [Dynamic Route Matching](/dynamic-matching)
|
||||
- [Nested Routes](/nested-routes)
|
||||
- [Programmatic Navigation](/navigation)
|
||||
- [Named Routes](/named-routes)
|
||||
- [Named Views](/named-views)
|
||||
- [Redirect and Alias](/redirect-and-alias)
|
||||
- [HTML5 History Mode](/history-mode)
|
||||
```
|
||||
|
||||
#### load-navbar
|
||||
|
||||
读取导航配置文件,如果配置,默认加载当前目录下的 `_navbar.md`。如果文件不存在,会显示 html 里定义的导航栏。
|
||||
|
||||
```html
|
||||
<script src="/lib/docsify.js" data-load-navbar></script>
|
||||
```
|
||||
|
||||
你可以指定导航栏文件名
|
||||
|
||||
```html
|
||||
<script src="/lib/docsify.js" data-load-navbar="_navbar.md"></script>
|
||||
```
|
||||
|
||||
`_navbar.md` 的内容可以是这样
|
||||
|
||||
```markdown
|
||||
- [en](/)
|
||||
- [中文](/zh-cn)
|
||||
```
|
||||
|
||||
当然也支持二级列表,将生成一个下拉列表
|
||||
```markdown
|
||||
- [download](/download)
|
||||
- language
|
||||
- [en](/)
|
||||
- [中文](/zh-cn)
|
||||
```
|
||||
|
||||
|
||||
## FAQ
|
||||
|
||||
### 为什么是 `404.html` 而不用 `index.html`
|
||||
|
||||
docsify 想要实现的是用最简单的方式 **动态渲染内容**。
|
||||
|
||||
例如我有两个文档分别为 `README.md` 和 `guide.md`,如果我用 `index.html` 作为文件名,`README.md` 可以被正确的渲染因为我们已经规定它为首页文件,但是如果我们访问 `my-domain.com/guide` 想要得到的结果是 `guide.md` 的内容,它将无法工作,因为目录下并不存在一个 `guide.html` 的文件。
|
||||
|
||||
但是 GitHub Pages 服务器找不到资源, 就会回退并渲染 `404.html` 文件。😄
|
||||
|
||||
+269
-151
@@ -1,21 +1,80 @@
|
||||
(function (global, factory) {
|
||||
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
|
||||
typeof define === 'function' && define.amd ? define(factory) :
|
||||
(global.Docsify = factory());
|
||||
}(this, (function () { 'use strict';
|
||||
var Docsify = (function () {
|
||||
'use strict';
|
||||
|
||||
var ajax = function (url, options) {
|
||||
if ( options === void 0 ) options = {};
|
||||
/**
|
||||
* Simple ajax
|
||||
* @param {String} url
|
||||
* @param {String} [method=get]
|
||||
* @return {Promise}
|
||||
*/
|
||||
function load (url, method) {
|
||||
if ( method === void 0 ) method = 'get';
|
||||
|
||||
var xhr = new XMLHttpRequest();
|
||||
|
||||
xhr.open(options.method || 'get', url);
|
||||
xhr.open(method, url);
|
||||
xhr.send();
|
||||
|
||||
return {
|
||||
then: function (cb) { return xhr.addEventListener('load', cb); }
|
||||
then: function (success, error) {
|
||||
if ( error === void 0 ) error = function () {};
|
||||
|
||||
xhr.addEventListener('error', error);
|
||||
xhr.addEventListener('load', function (ref) {
|
||||
var target = ref.target;
|
||||
|
||||
target.status >= 400 ? error(target) : success(target.response);
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* gen toc tree
|
||||
* @link https://github.com/killercup/grock/blob/5280ae63e16c5739e9233d9009bc235ed7d79a50/styles/solarized/assets/js/behavior.coffee#L54-L81
|
||||
* @param {Array} toc
|
||||
* @param {Number} maxLevel
|
||||
* @return {Array}
|
||||
*/
|
||||
function genTree (toc, maxLevel) {
|
||||
var headlines = [];
|
||||
var last = {};
|
||||
|
||||
toc.forEach(function (headline) {
|
||||
var level = headline.level || 1;
|
||||
var len = level - 1;
|
||||
|
||||
if (level > maxLevel) { return }
|
||||
if (last[len]) {
|
||||
last[len].children = last[len].children || [];
|
||||
last[len].children.push(headline);
|
||||
} else {
|
||||
headlines.push(headline);
|
||||
}
|
||||
last[level] = headline;
|
||||
});
|
||||
|
||||
return headlines
|
||||
}
|
||||
|
||||
/**
|
||||
* camel to kebab
|
||||
* @link https://github.com/bokuweb/kebab2camel/blob/master/index.js
|
||||
* @param {String} str
|
||||
* @return {String}
|
||||
*/
|
||||
function camel2kebab (str) {
|
||||
return str.replace(/([A-Z])/g, function (m) { return '-' + m.toLowerCase(); })
|
||||
}
|
||||
|
||||
/**
|
||||
* is nil
|
||||
* @param {Object} object
|
||||
* @return {Boolean}
|
||||
*/
|
||||
function isNil (o) {
|
||||
return o === null || o === undefined
|
||||
}
|
||||
|
||||
var commonjsGlobal = typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
|
||||
|
||||
@@ -2112,96 +2171,58 @@ Prism.languages.js = Prism.languages.javascript;
|
||||
});
|
||||
|
||||
/**
|
||||
* @link from https://github.com/killercup/grock/blob/5280ae63e16c5739e9233d9009bc235ed7d79a50/styles/solarized/assets/js/behavior.coffee#L54-L81
|
||||
* Render github corner
|
||||
* @param {Object} data
|
||||
* @return {String}
|
||||
*/
|
||||
var tocToTree = function (toc, maxLevel) {
|
||||
var headlines = [];
|
||||
var last = {};
|
||||
function corner (data) {
|
||||
if (!data) { return '' }
|
||||
if (!/\/\//.test(data)) { data = 'https://github.com/' + data; }
|
||||
data = data.replace(/^git\+/, '');
|
||||
|
||||
toc.forEach(function (headline) {
|
||||
var level = headline.level || 1;
|
||||
var len = level - 1;
|
||||
return ("\n <a href=\"" + data + "\" class=\"github-corner\" aria-label=\"View source on Github\">\n <svg viewBox=\"0 0 250 250\" aria-hidden=\"true\">\n <path d=\"M0,0 L115,115 L130,115 L142,142 L250,250 L250,0 Z\"></path>\n <path d=\"M128.3,109.0 C113.8,99.7 119.0,89.6 119.0,89.6 C122.0,82.7 120.5,78.6 120.5,78.6 C119.2,72.0 123.4,76.3 123.4,76.3 C127.3,80.9 125.5,87.3 125.5,87.3 C122.9,97.6 130.6,101.9 134.4,103.2\" fill=\"currentColor\" style=\"transform-origin: 130px 106px;\" class=\"octo-arm\"></path>\n <path d=\"M115.0,115.0 C114.9,115.1 118.7,116.5 119.8,115.4 L133.7,101.6 C136.9,99.2 139.9,98.4 142.2,98.6 C133.8,88.0 127.5,74.4 143.8,58.0 C148.5,53.4 154.0,51.2 159.7,51.0 C160.3,49.4 163.2,43.6 171.4,40.1 C171.4,40.1 176.1,42.5 178.8,56.2 C183.1,58.6 187.2,61.8 190.9,65.4 C194.5,69.0 197.7,73.2 200.1,77.6 C213.8,80.2 216.3,84.9 216.3,84.9 C212.7,93.1 206.9,96.0 205.4,96.6 C205.1,102.4 203.0,107.8 198.3,112.5 C181.9,128.9 168.3,122.5 157.7,114.1 C157.9,116.9 156.7,120.9 152.7,124.9 L141.0,136.5 C139.8,137.7 141.6,141.9 141.8,141.8 Z\" fill=\"currentColor\" class=\"octo-body\"></path>\n </svg>\n </a>")
|
||||
}
|
||||
|
||||
if (level > maxLevel) { return }
|
||||
if (last[len]) {
|
||||
last[len].children = last[len].children || [];
|
||||
last[len].children.push(headline);
|
||||
} else {
|
||||
headlines.push(headline);
|
||||
}
|
||||
last[level] = headline;
|
||||
});
|
||||
/**
|
||||
* Render main content
|
||||
* @return {[type]} [description]
|
||||
*/
|
||||
function main () {
|
||||
return "<main>\n <aside class=\"sidebar\"></aside>\n <section class=\"content\">\n <article class=\"markdown-section\"></article>\n </section>\n </main>"
|
||||
}
|
||||
|
||||
return headlines
|
||||
};
|
||||
function toggle (bool) {
|
||||
if (!bool) { return '' }
|
||||
return "<button class=\"sidebar-toggle\">\n <span></span><span></span><span></span>\n </button>"
|
||||
}
|
||||
|
||||
var buildHeadlinesTree = function (tree, tpl) {
|
||||
/**
|
||||
* Render tree
|
||||
* @param {Array} tree
|
||||
* @param {String} tpl
|
||||
* @return {String}
|
||||
*/
|
||||
function tree (toc, tpl) {
|
||||
if ( tpl === void 0 ) tpl = '';
|
||||
|
||||
if (!tree || !tree.length) { return '' }
|
||||
if (!toc || !toc.length) { return '' }
|
||||
|
||||
tree.forEach(function (node) {
|
||||
toc.forEach(function (node) {
|
||||
tpl += "<li><a class=\"section-link\" href=\"" + (node.slug) + "\">" + (node.title) + "</a></li>";
|
||||
if (node.children) {
|
||||
tpl += "<li><ul class=\"children\">" + (buildHeadlinesTree(node.children)) + "</li></ul>";
|
||||
tpl += "<li><ul class=\"children\">" + (tree(node.children)) + "</li></ul>";
|
||||
}
|
||||
});
|
||||
|
||||
return tpl
|
||||
};
|
||||
|
||||
var genToc = function (toc, opts) {
|
||||
var tree = Array.isArray(opts.sidebar)
|
||||
? opts.sidebar
|
||||
: tocToTree(toc, opts['max-level']);
|
||||
|
||||
return buildHeadlinesTree(tree, '<ul>')
|
||||
};
|
||||
|
||||
var cornerTpl = "\n <a href=\"{{repo}}\" class=\"github-corner\" aria-label=\"View source on Github\">\n <svg viewBox=\"0 0 250 250\" aria-hidden=\"true\">\n <path d=\"M0,0 L115,115 L130,115 L142,142 L250,250 L250,0 Z\"></path>\n <path d=\"M128.3,109.0 C113.8,99.7 119.0,89.6 119.0,89.6 C122.0,82.7 120.5,78.6 120.5,78.6 C119.2,72.0 123.4,76.3 123.4,76.3 C127.3,80.9 125.5,87.3 125.5,87.3 C122.9,97.6 130.6,101.9 134.4,103.2\" fill=\"currentColor\" style=\"transform-origin: 130px 106px;\" class=\"octo-arm\"></path>\n <path d=\"M115.0,115.0 C114.9,115.1 118.7,116.5 119.8,115.4 L133.7,101.6 C136.9,99.2 139.9,98.4 142.2,98.6 C133.8,88.0 127.5,74.4 143.8,58.0 C148.5,53.4 154.0,51.2 159.7,51.0 C160.3,49.4 163.2,43.6 171.4,40.1 C171.4,40.1 176.1,42.5 178.8,56.2 C183.1,58.6 187.2,61.8 190.9,65.4 C194.5,69.0 197.7,73.2 200.1,77.6 C213.8,80.2 216.3,84.9 216.3,84.9 C212.7,93.1 206.9,96.0 205.4,96.6 C205.1,102.4 203.0,107.8 198.3,112.5 C181.9,128.9 168.3,122.5 157.7,114.1 C157.9,116.9 156.7,120.9 152.7,124.9 L141.0,136.5 C139.8,137.7 141.6,141.9 141.8,141.8 Z\" fill=\"currentColor\" class=\"octo-body\"></path>\n </svg>\n </a>\n";
|
||||
var toc = [];
|
||||
var renderer = new marked.Renderer();
|
||||
}
|
||||
|
||||
/**
|
||||
* render anchor tag
|
||||
* @link https://github.com/chjj/marked#overriding-renderer-methods
|
||||
* Active sidebar when scroll
|
||||
* @link https://buble.surge.sh/
|
||||
*/
|
||||
renderer.heading = function (text, level) {
|
||||
var slug = text.replace(/<(?:.|\n)*?>/gm, '').toLowerCase().replace(/[\s\n\t]+/g, '-');
|
||||
|
||||
toc.push({ level: level, slug: '#' + slug, title: text });
|
||||
|
||||
return ("<h" + level + " id=\"" + slug + "\"><a href=\"#" + slug + "\" class=\"anchor\"></a>" + text + "</h" + level + ">")
|
||||
};
|
||||
|
||||
// highlight code
|
||||
renderer.code = function (code, lang) {
|
||||
if ( lang === void 0 ) lang = '';
|
||||
|
||||
var hl = prism.highlight(code, prism.languages[lang] || prism.languages.markup);
|
||||
|
||||
return ("<pre data-lang=\"" + lang + "\"><code class=\"lang-" + lang + "\">" + hl + "</code></pre>")
|
||||
};
|
||||
marked.setOptions({ renderer: renderer });
|
||||
|
||||
var render = function (content, opts) {
|
||||
if ( opts === void 0 ) opts = {};
|
||||
|
||||
var corner = '';
|
||||
|
||||
if (opts.repo) {
|
||||
var repo = /\/\//.test(opts.repo) ? opts.repo : ('https://github.com/' + opts.repo);
|
||||
corner = cornerTpl.replace(/{{repo}}/g, repo);
|
||||
}
|
||||
|
||||
var section = "<section class=\"content\">\n <article class=\"markdown-section\">" + (marked(content)) + "</article>\n </section>";
|
||||
var sidebar = "<aside class=\"sidebar\">" + (genToc(toc, opts)) + "</aside>";
|
||||
|
||||
return (corner + "<main>" + sidebar + section + "</main>")
|
||||
};
|
||||
|
||||
function scrollActiveSidebar (isCustom) {
|
||||
if (/mobile/i.test(navigator.userAgent) || isCustom) { return }
|
||||
function scrollActiveSidebar () {
|
||||
if (/mobile/i.test(navigator.userAgent)) { return }
|
||||
|
||||
var anchors = document.querySelectorAll('.anchor');
|
||||
var nav = {};
|
||||
@@ -2250,82 +2271,179 @@ function scrollActiveSidebar (isCustom) {
|
||||
scrollIntoView();
|
||||
}
|
||||
|
||||
var bindEvent = function (isCustom) {
|
||||
scrollActiveSidebar(isCustom);
|
||||
};
|
||||
/**
|
||||
* Acitve link
|
||||
*/
|
||||
function activeLink (dom, activeParent) {
|
||||
var host = document.location.origin + document.location.pathname;
|
||||
|
||||
var DEFAULT_OPTS = {
|
||||
el: '#app',
|
||||
repo: '',
|
||||
'max-level': 6,
|
||||
sidebar: ''
|
||||
};
|
||||
dom = typeof dom === 'object' ? dom : document.querySelector(dom);
|
||||
if (!dom) { return
|
||||
|
||||
var script = document.currentScript || [].slice.call(document.getElementsByTagName('script')).pop();
|
||||
|
||||
if (script) {
|
||||
for (var prop in DEFAULT_OPTS) {
|
||||
DEFAULT_OPTS[prop] = script.getAttribute('data-' + prop) || DEFAULT_OPTS[prop];
|
||||
}
|
||||
}
|
||||
|
||||
var Docsify = function Docsify (opts) {
|
||||
Docsify.installed = true;
|
||||
|
||||
this.opts = Object.assign({}, opts, DEFAULT_OPTS);
|
||||
this.replace = true;
|
||||
this.dom = document.querySelector(this.opts.el);
|
||||
if (!this.dom) {
|
||||
this.dom = document.body;
|
||||
this.replace = false;
|
||||
}
|
||||
if (this.opts.sidebar) { this.opts.sidebar = window[this.opts.sidebar]; }
|
||||
|
||||
this.loc = document.location.pathname;
|
||||
if (/\/$/.test(this.loc)) { this.loc += 'README'; }
|
||||
|
||||
this.load();
|
||||
|
||||
var nav = document.querySelector('nav');
|
||||
if (nav) { this.activeNav(nav); }
|
||||
};
|
||||
|
||||
Docsify.prototype.load = function load () {
|
||||
var this$1 = this;
|
||||
|
||||
ajax(((this.loc) + ".md")).then(function (res) {
|
||||
var target = res.target;
|
||||
if (target.status >= 400) {
|
||||
this$1.render('not found');
|
||||
} else {
|
||||
this$1.render(res.target.response);
|
||||
bindEvent(!!this$1.opts.sidebar);
|
||||
if (this$1.opts.sidebar) {
|
||||
this$1.activeNav(document.querySelector('aside.sidebar'), true);
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
Docsify.prototype.render = function render$1 (content) {
|
||||
this.dom[this.replace ? 'outerHTML' : 'innerHTML'] = render(content, this.opts);
|
||||
};
|
||||
|
||||
Docsify.prototype.activeNav = function activeNav (elm, activeParentNode) {
|
||||
var host = document.location.origin + document.location.pathname;[].slice.call(elm.querySelectorAll('a')).forEach(function (node) {
|
||||
; }[].slice.call(dom.querySelectorAll('a')).forEach(function (node) {
|
||||
if (node.href === host) {
|
||||
activeParentNode
|
||||
activeParent
|
||||
? node.parentNode.setAttribute('class', 'active')
|
||||
: node.setAttribute('class', 'active');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* sidebar toggle
|
||||
*/
|
||||
function bindToggle (dom) {
|
||||
dom = typeof dom === 'object' ? dom : document.querySelector(dom);
|
||||
if (!dom) { return }
|
||||
var body = document.body;
|
||||
|
||||
dom.addEventListener('click', function () { return body.classList.toggle('close'); });
|
||||
|
||||
if (!/mobile/i.test(navigator.userAgent)) { return }
|
||||
document.querySelector('aside').addEventListener('click', function (event) {
|
||||
body.classList.toggle('close');
|
||||
});
|
||||
}
|
||||
|
||||
var renderTo = function (dom, content) {
|
||||
dom = typeof dom === 'object' ? dom : document.querySelector(dom);
|
||||
dom.innerHTML = content;
|
||||
|
||||
return dom
|
||||
};
|
||||
var toc = [];
|
||||
var renderer = new marked.Renderer();
|
||||
|
||||
/**
|
||||
* render anchor tag
|
||||
* @link https://github.com/chjj/marked#overriding-renderer-methods
|
||||
*/
|
||||
renderer.heading = function (text, level) {
|
||||
var slug = text.toLowerCase().replace(/<(?:.|\n)*?>/gm, '').replace(/[\s\n\t]+/g, '-');
|
||||
|
||||
toc.push({ level: level, slug: '#' + slug, title: text });
|
||||
|
||||
return ("<h" + level + " id=\"" + slug + "\"><a href=\"#" + slug + "\" class=\"anchor\"></a>" + text + "</h" + level + ">")
|
||||
};
|
||||
// highlight code
|
||||
renderer.code = function (code, lang) {
|
||||
if ( lang === void 0 ) lang = '';
|
||||
|
||||
var hl = prism.highlight(code, prism.languages[lang] || prism.languages.markup);
|
||||
|
||||
return ("<pre data-lang=\"" + lang + "\"><code class=\"lang-" + lang + "\">" + hl + "</code></pre>")
|
||||
};
|
||||
marked.setOptions({ renderer: renderer });
|
||||
|
||||
/**
|
||||
* App
|
||||
*/
|
||||
function renderApp (dom, replace, opts) {
|
||||
var nav = document.querySelector('nav') || document.createElement('nav');
|
||||
|
||||
dom[replace ? 'outerHTML' : 'innerHTML'] = toggle(opts.sidebarToggle) + corner(opts.repo) + main();
|
||||
document.body.insertBefore(nav, document.body.children[0]);
|
||||
|
||||
// bind toggle
|
||||
bindToggle('button.sidebar-toggle');
|
||||
}
|
||||
|
||||
/**
|
||||
* article
|
||||
*/
|
||||
function renderArticle (content, OPTIONS) {
|
||||
renderTo('article', content ? marked(content) : 'not found');
|
||||
if (!renderSidebar.rendered) { renderSidebar(null, OPTIONS); }
|
||||
if (!renderNavbar.rendered) { renderNavbar(null, OPTIONS); }
|
||||
}
|
||||
|
||||
/**
|
||||
* navbar
|
||||
*/
|
||||
function renderNavbar (content, OPTIONS) {
|
||||
if ( OPTIONS === void 0 ) OPTIONS = {};
|
||||
|
||||
renderNavbar.rendered = true;
|
||||
|
||||
if (content) { renderTo('nav', marked(content)); }
|
||||
activeLink('nav');
|
||||
}
|
||||
|
||||
/**
|
||||
* sidebar
|
||||
*/
|
||||
function renderSidebar (content, OPTIONS) {
|
||||
if ( OPTIONS === void 0 ) OPTIONS = {};
|
||||
|
||||
renderSidebar.rendered = true;
|
||||
|
||||
var isToc = false;
|
||||
|
||||
if (content) {
|
||||
content = marked(content);
|
||||
} else if (OPTIONS.sidebar) {
|
||||
content = tree(OPTIONS.sidebar, '<ul>');
|
||||
} else {
|
||||
content = tree(genTree(toc, OPTIONS.maxLevel), '<ul>');
|
||||
isToc = true;
|
||||
}
|
||||
|
||||
renderTo('aside.sidebar', content);
|
||||
isToc ? scrollActiveSidebar() : activeLink('aside.sidebar', true);
|
||||
}
|
||||
|
||||
var OPTIONS = {
|
||||
el: '#app',
|
||||
repo: '',
|
||||
maxLevel: 6,
|
||||
sidebar: '',
|
||||
sidebarToggle: false,
|
||||
loadSidebar: null,
|
||||
loadNavbar: null
|
||||
};
|
||||
var script = document.currentScript || [].slice.call(document.getElementsByTagName('script')).pop();
|
||||
|
||||
// load configuration for script attribute
|
||||
if (script) {
|
||||
for (var prop in OPTIONS) {
|
||||
var val = script.getAttribute('data-' + camel2kebab(prop));
|
||||
OPTIONS[prop] = isNil(val) ? OPTIONS[prop] : (val || true);
|
||||
}
|
||||
if (OPTIONS.loadSidebar === true) { OPTIONS.loadSidebar = '_sidebar.md'; }
|
||||
if (OPTIONS.loadNavbar === true) { OPTIONS.loadNavbar = '_navbar.md'; }
|
||||
if (OPTIONS.sidebar) { OPTIONS.sidebar = window[OPTIONS.sidebar]; }
|
||||
}
|
||||
|
||||
var Docsify = function () {
|
||||
var dom = document.querySelector(OPTIONS.el) || document.body;
|
||||
var replace = dom !== document.body;
|
||||
var loc = document.location.pathname;
|
||||
|
||||
if (/\/$/.test(loc)) { loc += 'README'; }
|
||||
|
||||
// Render app
|
||||
renderApp(dom, replace, OPTIONS);
|
||||
|
||||
// Render markdown file
|
||||
load((loc + ".md"))
|
||||
.then(function (content) { return renderArticle(content, OPTIONS); },
|
||||
function (_) { return renderArticle(null, OPTIONS); });
|
||||
|
||||
// Render sidebar
|
||||
if (OPTIONS.loadSidebar) {
|
||||
load(OPTIONS.loadSidebar)
|
||||
.then(function (content) { return renderSidebar(content, OPTIONS); });
|
||||
}
|
||||
|
||||
// Render navbar
|
||||
if (OPTIONS.loadNavbar) {
|
||||
load(OPTIONS.loadNavbar)
|
||||
.then(function (content) { return renderNavbar(content, OPTIONS); });
|
||||
}
|
||||
};
|
||||
|
||||
window.addEventListener('load', function () {
|
||||
if (Docsify.installed) { return }
|
||||
new Docsify();
|
||||
});
|
||||
var index = Docsify();
|
||||
|
||||
return Docsify;
|
||||
return index;
|
||||
|
||||
})));
|
||||
}());
|
||||
|
||||
Vendored
+1
-1
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+1
-1
@@ -1 +1 @@
|
||||
*{box-sizing:border-box;-webkit-overflow-scrolling:touch;-webkit-tap-highlight-color:rgba(0,0,0,0);-webkit-text-size-adjust:none;-webkit-touch-callout:none;-webkit-font-smoothing:antialiased}nav{position:absolute;right:0;left:0;z-index:2;margin:25px 60px 0 0;text-align:right}nav a{margin:0 1em;padding:5px 0;font-size:16px;text-decoration:none;color:inherit;transition:color .3s}.github-corner{position:absolute;top:0;right:0;z-index:2}.github-corner svg{color:#fff;height:80px;width:80px}.github-corner:hover .octo-arm{animation:a .56s ease-in-out}@keyframes a{0%,to{transform:rotate(0)}20%,60%{transform:rotate(-25deg)}40%,80%{transform:rotate(10deg)}}@media (max-width:500px){.github-corner:hover .octo-arm{animation:none}.github-corner .octo-arm{animation:a .56s ease-in-out}}body,html{height:100%}body{-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;font-family:Source Sans Pro,Helvetica Neue,Arial,sans-serif;font-size:15px;letter-spacing:0;margin:0}main{height:100%;position:relative;width:100%}.sidebar{border-right:1px solid rgba(0,0,0,.07);bottom:0;overflow-y:auto;position:absolute;top:0;width:300px;z-index:1;padding-top:40px}.sidebar ul{margin:0;padding:0}.sidebar ul,.sidebar ul li{list-style:none}.sidebar ul li a{display:block;border-bottom:none}.sidebar ul li ul{padding-left:20px}.content{bottom:0;left:300px;overflow-y:auto;position:absolute;right:0;top:0;overflow-x:hidden;padding-top:20px}@media screen and (max-width:600px){.sidebar{left:-300px}.content{left:0}}.markdown-section{position:relative;margin:0 auto;max-width:800px;padding:20px 15px 40px}.markdown-section *{box-sizing:border-box;-webkit-box-sizing:border-box;font-size:inherit}.markdown-section>:first-child{margin-top:0!important}
|
||||
*{box-sizing:border-box;-webkit-overflow-scrolling:touch;-webkit-tap-highlight-color:rgba(0,0,0,0);-webkit-text-size-adjust:none;-webkit-touch-callout:none;-webkit-font-smoothing:antialiased}body,html{height:100%}body{background-color:#fff;-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;font-family:Source Sans Pro,Helvetica Neue,Arial,sans-serif;font-size:15px;letter-spacing:0;margin:0;overflow-x:hidden}nav{position:absolute;right:0;left:0;z-index:2;margin:25px 60px 0 0;text-align:right}nav p{margin:0}nav li,nav ul{list-style:none;display:inline-block;margin:0}nav a{margin:0 1em;padding:5px 0;font-size:16px;text-decoration:none;color:inherit;-webkit-transition:color .3s;transition:color .3s}nav a:hover{color:#000}nav a.active{color:#000;border-bottom:2px solid #000}nav li{position:relative;display:inline-block}nav li ul{background-color:hsla(0,0%,100%,.6);border:1px solid #000;opacity:0;overflow:hidden;padding:0;position:absolute;right:1em;top:26px;-webkit-transform-origin:100% 0;transform-origin:100% 0;-webkit-transform:scaleY(0);transform:scaleY(0);-webkit-transition:opacity .4s ease-out,-webkit-transform .2s ease;transition:opacity .4s ease-out,-webkit-transform .2s ease;transition:opacity .4s ease-out,transform .2s ease;transition:opacity .4s ease-out,transform .2s ease,-webkit-transform .2s ease;-webkit-transition-delay:.3s;transition-delay:.3s}nav li ul li{display:block;font-size:14px;margin:0;padding:4px 10px;white-space:nowrap}nav li ul a{display:block;margin:0;padding:0}nav li ul a.active{border-bottom:0}nav li:hover ul{opacity:1;-webkit-transform:scale(1);transform:scale(1);-webkit-transition:opacity .4s ease,-webkit-transform .2s ease-out;transition:opacity .4s ease,-webkit-transform .2s ease-out;transition:opacity .4s ease,transform .2s ease-out;transition:opacity .4s ease,transform .2s ease-out,-webkit-transform .2s ease-out;-webkit-transition-delay:0;transition-delay:0}.github-corner{position:absolute;top:0;right:0;z-index:1}.github-corner svg{color:#fff;height:80px;width:80px;fill:#000}.github-corner:hover .octo-arm{-webkit-animation:a .56s ease-in-out;animation:a .56s ease-in-out}main{width:100%;height:100%;position:relative}.sidebar{background-color:#fff;border-right:1px solid rgba(0,0,0,.07);overflow-y:auto;padding-top:40px;top:0;bottom:0;left:0;position:absolute;-webkit-transition:-webkit-transform .25s ease-out;transition:-webkit-transform .25s ease-out;transition:transform .25s ease-out;transition:transform .25s ease-out,-webkit-transform .25s ease-out;width:300px;z-index:3}.sidebar ul{margin:0;padding:0}.sidebar ul,.sidebar ul li{list-style:none}.sidebar ul li a{display:block;border-bottom:none}.sidebar ul li ul{padding-left:20px}.sidebar-toggle{background-color:transparent;border:0;bottom:10px;left:10px;position:absolute;text-align:center;-webkit-transition:opacity .3s;transition:opacity .3s;width:30px;z-index:4;outline:none}.sidebar-toggle span{background-color:#000;display:block;width:16px;height:2px;margin-bottom:4px}.sidebar-toggle:hover{opacity:.4}.content{overflow-y:auto;top:0;right:0;bottom:0;left:300px;position:absolute;overflow-x:hidden;padding-top:20px;-webkit-transition:left .25s ease;transition:left .25s ease}.markdown-section{position:relative;margin:0 auto;max-width:800px;padding:20px 15px 40px}.markdown-section>*{box-sizing:border-box;font-size:inherit}.markdown-section>:first-child{margin-top:0!important}body.close .sidebar{-webkit-transform:translateX(-300px);transform:translateX(-300px)}body.close .content{left:0}@media (max-width:600px){nav{margin-top:16px}nav li ul{top:30px}.sidebar{left:-300px;-webkit-transition:-webkit-transform .25s ease-out;transition:-webkit-transform .25s ease-out;transition:transform .25s ease-out;transition:transform .25s ease-out,-webkit-transform .25s ease-out}.content{left:0;min-width:100vw;-webkit-transition:-webkit-transform .25s ease;transition:-webkit-transform .25s ease;transition:transform .25s ease;transition:transform .25s ease,-webkit-transform .25s ease}.github-corner,nav{-webkit-transition:-webkit-transform .25s ease-out;transition:-webkit-transform .25s ease-out;transition:transform .25s ease-out;transition:transform .25s ease-out,-webkit-transform .25s ease-out}body.close .content,body.close .github-corner,body.close .sidebar,body.close nav{-webkit-transform:translateX(300px);transform:translateX(300px)}.github-corner .octo-arm{-webkit-animation:a .56s ease-in-out;animation:a .56s ease-in-out}.github-corner:hover .octo-arm{-webkit-animation:none;animation:none}}@-webkit-keyframes a{0%,to{-webkit-transform:rotate(0);transform:rotate(0)}20%,60%{-webkit-transform:rotate(-25deg);transform:rotate(-25deg)}40%,80%{-webkit-transform:rotate(10deg);transform:rotate(10deg)}}@keyframes a{0%,to{-webkit-transform:rotate(0);transform:rotate(0)}20%,60%{-webkit-transform:rotate(-25deg);transform:rotate(-25deg)}40%,80%{-webkit-transform:rotate(10deg);transform:rotate(10deg)}}
|
||||
+1
-1
File diff suppressed because one or more lines are too long
+5
-3
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "docsify",
|
||||
"version": "0.4.0",
|
||||
"version": "0.7.0",
|
||||
"description": "A magical documentation generator.",
|
||||
"main": "lib/docsify.js",
|
||||
"files": [
|
||||
@@ -9,8 +9,8 @@
|
||||
"themes"
|
||||
],
|
||||
"scripts": {
|
||||
"build": "rm -rf lib && node build/build.js && mkdir lib/themes && node build/build-css.js",
|
||||
"dev": "node app.js & nodemon --watch src themes --exec 'npm run build'",
|
||||
"build": "rm -rf lib themes && node build/build.js && mkdir lib/themes && mkdir themes && node build/build-css.js",
|
||||
"dev": "node app.js & nodemon -w src --exec 'npm run build'",
|
||||
"test": "eslint src test"
|
||||
},
|
||||
"repository": {
|
||||
@@ -33,6 +33,8 @@
|
||||
"eslint-config-vue": "^2.0.1",
|
||||
"eslint-plugin-vue": "^1.0.0",
|
||||
"nodemon": "^1.11.0",
|
||||
"postcss": "^5.2.6",
|
||||
"postcss-salad": "^1.0.5",
|
||||
"rollup": "^0.36.3",
|
||||
"rollup-plugin-buble": "^0.14.0",
|
||||
"rollup-plugin-commonjs": "^5.0.5",
|
||||
|
||||
-10
@@ -1,10 +0,0 @@
|
||||
export default function (url, options = {}) {
|
||||
const xhr = new XMLHttpRequest()
|
||||
|
||||
xhr.open(options.method || 'get', url)
|
||||
xhr.send()
|
||||
|
||||
return {
|
||||
then: cb => xhr.addEventListener('load', cb)
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,10 @@
|
||||
function scrollActiveSidebar (isCustom) {
|
||||
if (/mobile/i.test(navigator.userAgent) || isCustom) return
|
||||
|
||||
/**
|
||||
* Active sidebar when scroll
|
||||
* @link https://buble.surge.sh/
|
||||
*/
|
||||
export function scrollActiveSidebar () {
|
||||
if (/mobile/i.test(navigator.userAgent)) return
|
||||
|
||||
const anchors = document.querySelectorAll('.anchor')
|
||||
const nav = {}
|
||||
@@ -48,6 +53,36 @@ function scrollActiveSidebar (isCustom) {
|
||||
scrollIntoView()
|
||||
}
|
||||
|
||||
export default function (isCustom) {
|
||||
scrollActiveSidebar(isCustom)
|
||||
/**
|
||||
* Acitve link
|
||||
*/
|
||||
export function activeLink (dom, activeParent) {
|
||||
const host = document.location.origin + document.location.pathname
|
||||
|
||||
dom = typeof dom === 'object' ? dom : document.querySelector(dom)
|
||||
if (!dom) return
|
||||
|
||||
;[].slice.call(dom.querySelectorAll('a')).forEach(node => {
|
||||
if (node.href === host) {
|
||||
activeParent
|
||||
? node.parentNode.setAttribute('class', 'active')
|
||||
: node.setAttribute('class', 'active')
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* sidebar toggle
|
||||
*/
|
||||
export function bindToggle (dom) {
|
||||
dom = typeof dom === 'object' ? dom : document.querySelector(dom)
|
||||
if (!dom) return
|
||||
const body = document.body
|
||||
|
||||
dom.addEventListener('click', () => body.classList.toggle('close'))
|
||||
|
||||
if (!/mobile/i.test(navigator.userAgent)) return
|
||||
document.querySelector('aside').addEventListener('click', event => {
|
||||
body.classList.toggle('close')
|
||||
})
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
/**
|
||||
* @link from https://github.com/killercup/grock/blob/5280ae63e16c5739e9233d9009bc235ed7d79a50/styles/solarized/assets/js/behavior.coffee#L54-L81
|
||||
*/
|
||||
const tocToTree = function (toc, maxLevel) {
|
||||
const headlines = []
|
||||
const last = {}
|
||||
|
||||
toc.forEach(headline => {
|
||||
const level = headline.level || 1
|
||||
const len = level - 1
|
||||
|
||||
if (level > maxLevel) return
|
||||
if (last[len]) {
|
||||
last[len].children = last[len].children || []
|
||||
last[len].children.push(headline)
|
||||
} else {
|
||||
headlines.push(headline)
|
||||
}
|
||||
last[level] = headline
|
||||
})
|
||||
|
||||
return headlines
|
||||
}
|
||||
|
||||
const buildHeadlinesTree = function (tree, tpl = '') {
|
||||
if (!tree || !tree.length) return ''
|
||||
|
||||
tree.forEach(node => {
|
||||
tpl += `<li><a class="section-link" href="${node.slug}">${node.title}</a></li>`
|
||||
if (node.children) {
|
||||
tpl += `<li><ul class="children">${buildHeadlinesTree(node.children)}</li></ul>`
|
||||
}
|
||||
})
|
||||
|
||||
return tpl
|
||||
}
|
||||
|
||||
export default function (toc, opts) {
|
||||
var tree = Array.isArray(opts.sidebar)
|
||||
? opts.sidebar
|
||||
: tocToTree(toc, opts['max-level'])
|
||||
|
||||
return buildHeadlinesTree(tree, '<ul>')
|
||||
}
|
||||
+44
-69
@@ -1,79 +1,54 @@
|
||||
import ajax from './ajax'
|
||||
import render from './render'
|
||||
import bindEvent from './bind-event'
|
||||
import { load, camel2kebab, isNil } from './util'
|
||||
import * as render from './render'
|
||||
|
||||
const DEFAULT_OPTS = {
|
||||
const OPTIONS = {
|
||||
el: '#app',
|
||||
repo: '',
|
||||
'max-level': 6,
|
||||
sidebar: ''
|
||||
maxLevel: 6,
|
||||
sidebar: '',
|
||||
sidebarToggle: false,
|
||||
loadSidebar: null,
|
||||
loadNavbar: null
|
||||
}
|
||||
|
||||
const script = document.currentScript || [].slice.call(document.getElementsByTagName('script')).pop()
|
||||
|
||||
// load configuration for script attribute
|
||||
if (script) {
|
||||
for (const prop in DEFAULT_OPTS) {
|
||||
DEFAULT_OPTS[prop] = script.getAttribute('data-' + prop) || DEFAULT_OPTS[prop]
|
||||
for (const prop in OPTIONS) {
|
||||
const val = script.getAttribute('data-' + camel2kebab(prop))
|
||||
OPTIONS[prop] = isNil(val) ? OPTIONS[prop] : (val || true)
|
||||
}
|
||||
if (OPTIONS.loadSidebar === true) OPTIONS.loadSidebar = '_sidebar.md'
|
||||
if (OPTIONS.loadNavbar === true) OPTIONS.loadNavbar = '_navbar.md'
|
||||
if (OPTIONS.sidebar) OPTIONS.sidebar = window[OPTIONS.sidebar]
|
||||
}
|
||||
|
||||
const Docsify = function () {
|
||||
const dom = document.querySelector(OPTIONS.el) || document.body
|
||||
const replace = dom !== document.body
|
||||
let loc = document.location.pathname
|
||||
|
||||
if (/\/$/.test(loc)) loc += 'README'
|
||||
|
||||
// Render app
|
||||
render.renderApp(dom, replace, OPTIONS)
|
||||
|
||||
// Render markdown file
|
||||
load(`${loc}.md`)
|
||||
.then(content => render.renderArticle(content, OPTIONS),
|
||||
_ => render.renderArticle(null, OPTIONS))
|
||||
|
||||
// Render sidebar
|
||||
if (OPTIONS.loadSidebar) {
|
||||
load(OPTIONS.loadSidebar)
|
||||
.then(content => render.renderSidebar(content, OPTIONS))
|
||||
}
|
||||
|
||||
// Render navbar
|
||||
if (OPTIONS.loadNavbar) {
|
||||
load(OPTIONS.loadNavbar)
|
||||
.then(content => render.renderNavbar(content, OPTIONS))
|
||||
}
|
||||
}
|
||||
|
||||
class Docsify {
|
||||
constructor (opts) {
|
||||
Docsify.installed = true
|
||||
|
||||
this.opts = Object.assign({}, opts, DEFAULT_OPTS)
|
||||
this.replace = true
|
||||
this.dom = document.querySelector(this.opts.el)
|
||||
if (!this.dom) {
|
||||
this.dom = document.body
|
||||
this.replace = false
|
||||
}
|
||||
if (this.opts.sidebar) this.opts.sidebar = window[this.opts.sidebar]
|
||||
|
||||
this.loc = document.location.pathname
|
||||
if (/\/$/.test(this.loc)) this.loc += 'README'
|
||||
|
||||
this.load()
|
||||
|
||||
const nav = document.querySelector('nav')
|
||||
if (nav) this.activeNav(nav)
|
||||
}
|
||||
|
||||
load () {
|
||||
ajax(`${this.loc}.md`).then(res => {
|
||||
const target = res.target
|
||||
if (target.status >= 400) {
|
||||
this.render('not found')
|
||||
} else {
|
||||
this.render(res.target.response)
|
||||
bindEvent(!!this.opts.sidebar)
|
||||
if (this.opts.sidebar) {
|
||||
this.activeNav(document.querySelector('aside.sidebar'), true)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
render (content) {
|
||||
this.dom[this.replace ? 'outerHTML' : 'innerHTML'] = render(content, this.opts)
|
||||
}
|
||||
|
||||
activeNav (elm, activeParentNode) {
|
||||
const host = document.location.origin + document.location.pathname
|
||||
|
||||
;[].slice.call(elm.querySelectorAll('a')).forEach(node => {
|
||||
if (node.href === host) {
|
||||
activeParentNode
|
||||
? node.parentNode.setAttribute('class', 'active')
|
||||
: node.setAttribute('class', 'active')
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
window.addEventListener('load', () => {
|
||||
if (Docsify.installed) return
|
||||
new Docsify()
|
||||
})
|
||||
|
||||
export default Docsify
|
||||
export default Docsify()
|
||||
|
||||
+58
-23
@@ -1,16 +1,15 @@
|
||||
import marked from 'marked'
|
||||
import Prism from 'prismjs'
|
||||
import genToc from './gen-toc'
|
||||
import * as tpl from './tpl'
|
||||
import { activeLink, scrollActiveSidebar, bindToggle } from './event'
|
||||
import { genTree } from './util'
|
||||
|
||||
const cornerTpl = `
|
||||
<a href="{{repo}}" class="github-corner" aria-label="View source on Github">
|
||||
<svg viewBox="0 0 250 250" aria-hidden="true">
|
||||
<path d="M0,0 L115,115 L130,115 L142,142 L250,250 L250,0 Z"></path>
|
||||
<path d="M128.3,109.0 C113.8,99.7 119.0,89.6 119.0,89.6 C122.0,82.7 120.5,78.6 120.5,78.6 C119.2,72.0 123.4,76.3 123.4,76.3 C127.3,80.9 125.5,87.3 125.5,87.3 C122.9,97.6 130.6,101.9 134.4,103.2" fill="currentColor" style="transform-origin: 130px 106px;" class="octo-arm"></path>
|
||||
<path d="M115.0,115.0 C114.9,115.1 118.7,116.5 119.8,115.4 L133.7,101.6 C136.9,99.2 139.9,98.4 142.2,98.6 C133.8,88.0 127.5,74.4 143.8,58.0 C148.5,53.4 154.0,51.2 159.7,51.0 C160.3,49.4 163.2,43.6 171.4,40.1 C171.4,40.1 176.1,42.5 178.8,56.2 C183.1,58.6 187.2,61.8 190.9,65.4 C194.5,69.0 197.7,73.2 200.1,77.6 C213.8,80.2 216.3,84.9 216.3,84.9 C212.7,93.1 206.9,96.0 205.4,96.6 C205.1,102.4 203.0,107.8 198.3,112.5 C181.9,128.9 168.3,122.5 157.7,114.1 C157.9,116.9 156.7,120.9 152.7,124.9 L141.0,136.5 C139.8,137.7 141.6,141.9 141.8,141.8 Z" fill="currentColor" class="octo-body"></path>
|
||||
</svg>
|
||||
</a>
|
||||
`
|
||||
const renderTo = function (dom, content) {
|
||||
dom = typeof dom === 'object' ? dom : document.querySelector(dom)
|
||||
dom.innerHTML = content
|
||||
|
||||
return dom
|
||||
}
|
||||
const toc = []
|
||||
const renderer = new marked.Renderer()
|
||||
|
||||
@@ -19,13 +18,12 @@ const renderer = new marked.Renderer()
|
||||
* @link https://github.com/chjj/marked#overriding-renderer-methods
|
||||
*/
|
||||
renderer.heading = function (text, level) {
|
||||
const slug = text.replace(/<(?:.|\n)*?>/gm, '').toLowerCase().replace(/[\s\n\t]+/g, '-')
|
||||
const slug = text.toLowerCase().replace(/<(?:.|\n)*?>/gm, '').replace(/[\s\n\t]+/g, '-')
|
||||
|
||||
toc.push({ level, slug: '#' + slug, title: text })
|
||||
|
||||
return `<h${level} id="${slug}"><a href="#${slug}" class="anchor"></a>${text}</h${level}>`
|
||||
}
|
||||
|
||||
// highlight code
|
||||
renderer.code = function (code, lang = '') {
|
||||
const hl = Prism.highlight(code, Prism.languages[lang] || Prism.languages.markup)
|
||||
@@ -34,18 +32,55 @@ renderer.code = function (code, lang = '') {
|
||||
}
|
||||
marked.setOptions({ renderer })
|
||||
|
||||
export default function (content, opts = {}) {
|
||||
let corner = ''
|
||||
/**
|
||||
* App
|
||||
*/
|
||||
export function renderApp (dom, replace, opts) {
|
||||
const nav = document.querySelector('nav') || document.createElement('nav')
|
||||
|
||||
if (opts.repo) {
|
||||
const repo = /\/\//.test(opts.repo) ? opts.repo : ('https://github.com/' + opts.repo)
|
||||
corner = cornerTpl.replace(/{{repo}}/g, repo)
|
||||
dom[replace ? 'outerHTML' : 'innerHTML'] = tpl.toggle(opts.sidebarToggle) + tpl.corner(opts.repo) + tpl.main()
|
||||
document.body.insertBefore(nav, document.body.children[0])
|
||||
|
||||
// bind toggle
|
||||
bindToggle('button.sidebar-toggle')
|
||||
}
|
||||
|
||||
/**
|
||||
* article
|
||||
*/
|
||||
export function renderArticle (content, OPTIONS) {
|
||||
renderTo('article', content ? marked(content) : 'not found')
|
||||
if (!renderSidebar.rendered) renderSidebar(null, OPTIONS)
|
||||
if (!renderNavbar.rendered) renderNavbar(null, OPTIONS)
|
||||
}
|
||||
|
||||
/**
|
||||
* navbar
|
||||
*/
|
||||
export function renderNavbar (content, OPTIONS = {}) {
|
||||
renderNavbar.rendered = true
|
||||
|
||||
if (content) renderTo('nav', marked(content))
|
||||
activeLink('nav')
|
||||
}
|
||||
|
||||
/**
|
||||
* sidebar
|
||||
*/
|
||||
export function renderSidebar (content, OPTIONS = {}) {
|
||||
renderSidebar.rendered = true
|
||||
|
||||
let isToc = false
|
||||
|
||||
if (content) {
|
||||
content = marked(content)
|
||||
} else if (OPTIONS.sidebar) {
|
||||
content = tpl.tree(OPTIONS.sidebar, '<ul>')
|
||||
} else {
|
||||
content = tpl.tree(genTree(toc, OPTIONS.maxLevel), '<ul>')
|
||||
isToc = true
|
||||
}
|
||||
|
||||
const section = `<section class="content">
|
||||
<article class="markdown-section">${marked(content)}</article>
|
||||
</section>`
|
||||
const sidebar = `<aside class="sidebar">${genToc(toc, opts)}</aside>`
|
||||
|
||||
return `${corner}<main>${sidebar}${section}</main>`
|
||||
renderTo('aside.sidebar', content)
|
||||
isToc ? scrollActiveSidebar() : activeLink('aside.sidebar', true)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,279 @@
|
||||
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
|
||||
-webkit-text-size-adjust: none;
|
||||
-webkit-touch-callout: none;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
}
|
||||
|
||||
html, body {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: #fff;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
font-family: 'Source Sans Pro', 'Helvetica Neue', Arial, sans-serif;
|
||||
font-size: 15px;
|
||||
letter-spacing: 0;
|
||||
margin: 0;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
/* navbar */
|
||||
nav {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
left: 0;
|
||||
z-index: 10;
|
||||
margin: 25px 60px 0 0;
|
||||
text-align: right;
|
||||
|
||||
p {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
ul, li {
|
||||
list-style: none;
|
||||
display: inline-block;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
a {
|
||||
margin: 0 1em;
|
||||
padding: 5px 0;
|
||||
font-size: 16px;
|
||||
text-decoration: none;
|
||||
color: inherit;
|
||||
transition: color .3s;
|
||||
|
||||
&:hover {
|
||||
color: $color-primary;
|
||||
}
|
||||
|
||||
&.active {
|
||||
color: $color-primary;
|
||||
border-bottom: 2px solid $color-primary;
|
||||
}
|
||||
}
|
||||
|
||||
/* navbar dropdown */
|
||||
li {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
|
||||
ul {
|
||||
background-color: rgba(#fff, .6);
|
||||
border: 1px solid $color-primary;
|
||||
opacity: 0;
|
||||
overflow: hidden;
|
||||
padding: 0;
|
||||
position: absolute;
|
||||
right: 1em;
|
||||
top: 26px;
|
||||
transform-origin: 100% 0%;
|
||||
transform: scale(1, 0);
|
||||
transition: opacity .4s ease-out, transform .2s ease;
|
||||
transition-delay: .3s;
|
||||
|
||||
li {
|
||||
display: block;
|
||||
font-size: 14px;
|
||||
margin: 0;
|
||||
padding: 4px 10px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
a {
|
||||
display: block;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
|
||||
&.active {
|
||||
border-bottom: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&:hover ul {
|
||||
opacity: 1;
|
||||
transform: scale(1, 1);
|
||||
transition: opacity .4s ease, transform .2s ease-out;
|
||||
transition-delay: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* github corner */
|
||||
.github-corner {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
z-index: 1;
|
||||
|
||||
&:hover .octo-arm {
|
||||
animation:octocat-wave 560ms ease-in-out;
|
||||
}
|
||||
|
||||
svg {
|
||||
color: #fff;
|
||||
height: 80px;
|
||||
width: 80px;
|
||||
fill: $color-primary;
|
||||
}
|
||||
}
|
||||
|
||||
/* main */
|
||||
main {
|
||||
size: 100% 100%;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
/* sidebar */
|
||||
.sidebar {
|
||||
background-color: #fff;
|
||||
border-right: 1px solid rgba(0, 0, 0, .07);
|
||||
overflow-y: auto;
|
||||
padding-top: 40px;
|
||||
position: absolute 0 * 0 0;
|
||||
transition: transform 250ms ease-out;
|
||||
width: $sidebar-width;
|
||||
z-index: 20;
|
||||
|
||||
ul {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
ul, ul li {
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
ul li a {
|
||||
display: block;
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
ul li ul {
|
||||
padding-left: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
/* sidebar toggle */
|
||||
.sidebar-toggle {
|
||||
background-color: transparent;
|
||||
border: 0;
|
||||
bottom: 10px;
|
||||
left: 10px;
|
||||
outline: none;
|
||||
position: absolute;
|
||||
text-align: center;
|
||||
transition: opacity .3s;
|
||||
width: 30px;
|
||||
z-index: 30;
|
||||
outline: none;
|
||||
|
||||
&:hover {
|
||||
opacity: .4;
|
||||
}
|
||||
|
||||
span {
|
||||
background-color: $color-primary;
|
||||
display: block;
|
||||
size: 16px 2px;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
}
|
||||
|
||||
/* main content */
|
||||
.content {
|
||||
overflow-y: auto;
|
||||
position: absolute 0 0 0 $sidebar-width;
|
||||
overflow-x: hidden;
|
||||
padding-top: 20px;
|
||||
transition: left 250ms ease;
|
||||
}
|
||||
|
||||
/* markdown content found on pages */
|
||||
.markdown-section {
|
||||
position: relative;
|
||||
margin: 0 auto;
|
||||
max-width: 800px;
|
||||
padding: 20px 15px 40px 15px;
|
||||
|
||||
> * {
|
||||
box-sizing: border-box;
|
||||
font-size: inherit;
|
||||
}
|
||||
|
||||
>:first-child {
|
||||
margin-top: 0!important;
|
||||
}
|
||||
}
|
||||
|
||||
body.close {
|
||||
.sidebar {
|
||||
transform: translateX(-$sidebar-width);
|
||||
}
|
||||
|
||||
.content {
|
||||
left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 600px) {
|
||||
nav {
|
||||
margin-top: 16px;
|
||||
}
|
||||
|
||||
nav li ul {
|
||||
top: 30px;
|
||||
}
|
||||
|
||||
.sidebar {
|
||||
left: -$sidebar-width;
|
||||
transition: transform 250ms ease-out;
|
||||
}
|
||||
|
||||
.content {
|
||||
left: 0;
|
||||
min-width: 100vw;
|
||||
transition: transform 250ms ease;
|
||||
}
|
||||
|
||||
nav, .github-corner {
|
||||
transition: transform 250ms ease-out;
|
||||
}
|
||||
|
||||
body.close {
|
||||
.sidebar {
|
||||
transform: translateX($sidebar-width);
|
||||
}
|
||||
|
||||
.content {
|
||||
transform: translateX($sidebar-width);
|
||||
}
|
||||
|
||||
nav, .github-corner {
|
||||
transform: translateX($sidebar-width);
|
||||
}
|
||||
}
|
||||
|
||||
.github-corner {
|
||||
&:hover .octo-arm {
|
||||
animation: none;
|
||||
}
|
||||
.octo-arm {
|
||||
animation: octocat-wave 560ms ease-in-out;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes octocat-wave {
|
||||
0%,100% { transform: rotate(0); }
|
||||
20%,60% { transform: rotate(-25deg); }
|
||||
40%,80% { transform: rotate(10deg); }
|
||||
}
|
||||
@@ -1,181 +1,39 @@
|
||||
@import url('https://fonts.googleapis.com/css?family=Inconsolata|Inconsolata-Bold');
|
||||
|
||||
* {
|
||||
-webkit-box-sizing: border-box;
|
||||
-moz-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
|
||||
-webkit-text-size-adjust: none;
|
||||
-webkit-touch-callout: none;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
}
|
||||
$color-primary: #0074D9;
|
||||
$sidebar-width: 16em;
|
||||
|
||||
/* navbar */
|
||||
nav {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
left: 0;
|
||||
z-index: 10;
|
||||
margin: 25px 60px 0 0;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
nav a {
|
||||
margin: 0 1em;
|
||||
padding: 5px 0;
|
||||
font-size: 16px;
|
||||
text-decoration: none;
|
||||
color: inherit;
|
||||
transition: color .3s;
|
||||
}
|
||||
|
||||
nav a:hover {
|
||||
color: #0074D9;
|
||||
}
|
||||
|
||||
nav a.active {
|
||||
color: #0074D9;
|
||||
border-bottom: 2px solid #0074D9;
|
||||
}
|
||||
|
||||
/* github corner */
|
||||
.github-corner {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
.github-corner svg {
|
||||
color: #fff;
|
||||
fill: #0074D9;
|
||||
height: 80px;
|
||||
width: 80px;
|
||||
}
|
||||
|
||||
.github-corner:hover .octo-arm {
|
||||
animation:octocat-wave 560ms ease-in-out;
|
||||
}
|
||||
|
||||
@keyframes octocat-wave {
|
||||
0%,100%{ transform: rotate(0); }
|
||||
20%,60%{ transform: rotate(-25deg); }
|
||||
40%,80%{ transform: rotate(10deg); }
|
||||
}
|
||||
|
||||
@media (max-width: 500px) {
|
||||
.github-corner:hover .octo-arm {
|
||||
animation: none;
|
||||
}
|
||||
.github-corner .octo-arm {
|
||||
animation: octocat-wave 560ms ease-in-out;
|
||||
}
|
||||
}
|
||||
|
||||
html, body {
|
||||
height: 100%;
|
||||
}
|
||||
@import "basic/layout";
|
||||
|
||||
body {
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
background-color: #fff;
|
||||
color: #34495e;
|
||||
font-family: 'Source Sans Pro', arial, sans-serif;
|
||||
font-weight: 400px;
|
||||
font-size: 15px;
|
||||
letter-spacing: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
/* main */
|
||||
main {
|
||||
height: 100%;
|
||||
position: relative;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
/* sidebar */
|
||||
.sidebar {
|
||||
background-color: #fff;
|
||||
border-right: 1px solid rgba(0,0,0,.07);
|
||||
bottom: 0;
|
||||
color: #364149;
|
||||
overflow-y: auto;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
width: 14em;
|
||||
z-index: 1;
|
||||
padding-top: 40px;
|
||||
}
|
||||
|
||||
.sidebar ul {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.sidebar ul, .sidebar ul li {
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
.sidebar a {
|
||||
color: #666;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.sidebar li {
|
||||
list-style: none;
|
||||
padding: 0.2em 0.2em 0.2em 1em;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.sidebar .active {
|
||||
background-color: #eee;
|
||||
}
|
||||
|
||||
.sidebar .active a {
|
||||
color: #333;
|
||||
}
|
||||
|
||||
/* main content */
|
||||
.content {
|
||||
bottom: 0;
|
||||
left: 14em;
|
||||
overflow-y: auto;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
overflow-x: hidden;
|
||||
padding-top: 20px;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 600px) {
|
||||
.sidebar {
|
||||
left: -14em;
|
||||
a {
|
||||
color: #666;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.content {
|
||||
left: 0;
|
||||
li {
|
||||
list-style: none;
|
||||
padding: 0.2em 0 0.2em 1em;
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* markdown content found on pages */
|
||||
.markdown-section {
|
||||
position: relative;
|
||||
margin: 0 auto;
|
||||
max-width: 64em;
|
||||
padding: 20px 15px 40px 15px;
|
||||
}
|
||||
ul li ul {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.markdown-section * {
|
||||
box-sizing: border-box;
|
||||
-webkit-box-sizing: border-box;
|
||||
font-size: inherit;
|
||||
}
|
||||
.active {
|
||||
background-color: #eee;
|
||||
|
||||
.markdown-section>:first-child {
|
||||
margin-top: 0!important;
|
||||
a {
|
||||
color: #333;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.markdown-section h1,
|
||||
@@ -188,7 +46,7 @@ main {
|
||||
}
|
||||
|
||||
.markdown-section a {
|
||||
color: #0074D9;
|
||||
color: $color-primary;
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
@@ -256,7 +114,7 @@ main {
|
||||
|
||||
.markdown-section blockquote {
|
||||
color: #858585;
|
||||
border-left: 4px solid #0074D9;
|
||||
border-left: 4px solid $color-primary;
|
||||
margin: 2em 0;
|
||||
padding-left: 20px;
|
||||
}
|
||||
@@ -290,6 +148,8 @@ main {
|
||||
font-family: Inconsolata;
|
||||
padding: 12px 10px 12px 12px;
|
||||
font-size: 16px;
|
||||
overflow: auto;
|
||||
word-wrap: normal;
|
||||
}
|
||||
|
||||
/* code highlight */
|
||||
@@ -364,8 +224,13 @@ main {
|
||||
.markdown-section pre>code {
|
||||
display: block;
|
||||
font-family: Inconsolata;
|
||||
line-height: 1.2em;
|
||||
padding: 0;
|
||||
overflow: inherit;
|
||||
max-width: inherit;
|
||||
position: relative;
|
||||
background-color: #f8f8f8;
|
||||
padding: 0.8em 0.8em 0.4em;
|
||||
line-height: 1.1em;
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
.markdown-section code::after, .markdown-section code::before {
|
||||
@@ -378,16 +243,6 @@ code .token {
|
||||
-moz-osx-font-smoothing: initial;
|
||||
}
|
||||
|
||||
pre code {
|
||||
overflow-x: auto;
|
||||
position: relative;
|
||||
padding: 0;
|
||||
background-color: #f8f8f8;
|
||||
padding: 0.8em 0.8em 0.4em;
|
||||
line-height: 1.1em;
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
.content img {
|
||||
max-width: 100%;
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
$color-primary: #000;
|
||||
$sidebar-width: 300px;
|
||||
@import "basic/layout";
|
||||
@@ -1,187 +1,46 @@
|
||||
@import url('https://fonts.googleapis.com/css?family=Roboto+Mono|Source+Sans+Pro:300,400,600');
|
||||
|
||||
* {
|
||||
-webkit-box-sizing: border-box;
|
||||
-moz-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
|
||||
-webkit-text-size-adjust: none;
|
||||
-webkit-touch-callout: none;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
}
|
||||
$color-primary: #42b983;
|
||||
$sidebar-width: 300px;
|
||||
|
||||
/* navbar */
|
||||
nav {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
left: 0;
|
||||
z-index: 10;
|
||||
margin: 25px 60px 0 0;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
nav a {
|
||||
margin: 0 1em;
|
||||
padding: 5px 0;
|
||||
font-size: 16px;
|
||||
text-decoration: none;
|
||||
color: inherit;
|
||||
transition: color .3s;
|
||||
}
|
||||
|
||||
nav a:hover {
|
||||
color: #42b983;
|
||||
}
|
||||
|
||||
nav a.active {
|
||||
color: #42b983;
|
||||
border-bottom: 2px solid #42b983;
|
||||
}
|
||||
|
||||
/* github corner */
|
||||
.github-corner {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
.github-corner svg {
|
||||
color: #fff;
|
||||
fill: #42b983;
|
||||
height: 80px;
|
||||
width: 80px;
|
||||
}
|
||||
|
||||
.github-corner:hover .octo-arm {
|
||||
animation:octocat-wave 560ms ease-in-out;
|
||||
}
|
||||
|
||||
@keyframes octocat-wave {
|
||||
0%,100%{ transform: rotate(0); }
|
||||
20%,60%{ transform: rotate(-25deg); }
|
||||
40%,80%{ transform: rotate(10deg); }
|
||||
}
|
||||
|
||||
@media (max-width: 500px) {
|
||||
.github-corner:hover .octo-arm {
|
||||
animation: none;
|
||||
}
|
||||
.github-corner .octo-arm {
|
||||
animation: octocat-wave 560ms ease-in-out;
|
||||
}
|
||||
}
|
||||
|
||||
html, body {
|
||||
height: 100%;
|
||||
}
|
||||
@import "basic/layout";
|
||||
|
||||
body {
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
background-color: #fff;
|
||||
color: #34495e;
|
||||
font-family: 'Source Sans Pro', 'Helvetica Neue', Arial, sans-serif;
|
||||
font-size: 15px;
|
||||
letter-spacing: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
/* main */
|
||||
main {
|
||||
height: 100%;
|
||||
position: relative;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
/* sidebar */
|
||||
.sidebar {
|
||||
background-color: #fff;
|
||||
border-right: 1px solid rgba(0,0,0,.07);
|
||||
bottom: 0;
|
||||
color: #364149;
|
||||
overflow-y: auto;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
width: 300px;
|
||||
z-index: 1;
|
||||
padding-top: 40px;
|
||||
}
|
||||
|
||||
.sidebar ul {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.sidebar ul, .sidebar ul li {
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
.sidebar ul li a {
|
||||
color: #7f8c8d;
|
||||
display: block;
|
||||
padding: 6px 15px;
|
||||
border-bottom: none;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.sidebar ul li a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.sidebar ul li.active>a {
|
||||
color: #42b983;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.sidebar ul li ul {
|
||||
padding-left: 20px;
|
||||
}
|
||||
|
||||
/* main content */
|
||||
.content {
|
||||
bottom: 0;
|
||||
left: 300px;
|
||||
overflow-y: auto;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
overflow-x: hidden;
|
||||
padding-top: 20px;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 600px) {
|
||||
.sidebar {
|
||||
left: -300px;
|
||||
li {
|
||||
margin: 6px 15px;
|
||||
}
|
||||
|
||||
.content {
|
||||
left: 0;
|
||||
ul li a {
|
||||
color: #7f8c8d;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-decoration: none;
|
||||
|
||||
&:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
|
||||
ul li ul {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
ul li.active>a {
|
||||
color: $color-primary;
|
||||
font-weight: 500;
|
||||
}
|
||||
}
|
||||
|
||||
/* markdown content found on pages */
|
||||
.markdown-section {
|
||||
position: relative;
|
||||
margin: 0 auto;
|
||||
max-width: 800px;
|
||||
padding: 20px 15px 40px 15px;
|
||||
}
|
||||
|
||||
.markdown-section * {
|
||||
box-sizing: border-box;
|
||||
-webkit-box-sizing: border-box;
|
||||
font-size: inherit;
|
||||
}
|
||||
|
||||
.markdown-section>:first-child {
|
||||
margin-top: 0!important;
|
||||
}
|
||||
|
||||
.markdown-section h1,
|
||||
.markdown-section h2,
|
||||
.markdown-section h3,
|
||||
@@ -192,7 +51,7 @@ main {
|
||||
}
|
||||
|
||||
.markdown-section a {
|
||||
color: #42b983;
|
||||
color: $color-primary;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
@@ -213,11 +72,10 @@ main {
|
||||
}
|
||||
|
||||
.markdown-section h3 {
|
||||
margin: 52px 0 1.2em;
|
||||
margin: 40px 0 .6em;
|
||||
font-size: 1.5em;
|
||||
}
|
||||
|
||||
|
||||
.markdown-section h4 {
|
||||
font-size: 1.25em;
|
||||
}
|
||||
@@ -251,7 +109,7 @@ main {
|
||||
|
||||
.markdown-section blockquote {
|
||||
color: #858585;
|
||||
border-left: 4px solid #42b983;
|
||||
border-left: 4px solid $color-primary;
|
||||
margin: 2em 0;
|
||||
padding-left: 20px;
|
||||
}
|
||||
@@ -289,6 +147,8 @@ main {
|
||||
margin: 1.2em 0;
|
||||
padding: 1.2em 1.4em;
|
||||
position: relative;
|
||||
overflow: auto;
|
||||
word-wrap: normal;
|
||||
}
|
||||
|
||||
/* code highlight */
|
||||
@@ -321,7 +181,7 @@ main {
|
||||
}
|
||||
|
||||
.token.string {
|
||||
color: #42b983;
|
||||
color: $color-primary;
|
||||
}
|
||||
|
||||
.token.selector {
|
||||
@@ -343,7 +203,7 @@ main {
|
||||
.token.control,
|
||||
.token.directive,
|
||||
.token.unit {
|
||||
color: #42b983;
|
||||
color: $color-primary;
|
||||
}
|
||||
|
||||
.token.keyword {
|
||||
@@ -398,8 +258,10 @@ main {
|
||||
font-size: 0.8em;
|
||||
line-height: inherit;
|
||||
margin: 0 2px;
|
||||
overflow: inherit;
|
||||
padding: 3px 5px;
|
||||
white-space: inherit;
|
||||
max-width: inherit;
|
||||
}
|
||||
|
||||
.markdown-section code::after, .markdown-section code::before {
|
||||
@@ -412,15 +274,6 @@ code .token {
|
||||
-moz-osx-font-smoothing: initial;
|
||||
}
|
||||
|
||||
pre code {
|
||||
overflow-x: auto;
|
||||
padding: 0;
|
||||
background-color: #f8f8f8;
|
||||
padding: 0.8em 0.8em 0.4em;
|
||||
line-height: 1.1em;
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
pre::after {
|
||||
color: #ccc;
|
||||
content: attr(data-lang);
|
||||
+59
@@ -0,0 +1,59 @@
|
||||
|
||||
/**
|
||||
* Render github corner
|
||||
* @param {Object} data
|
||||
* @return {String}
|
||||
*/
|
||||
export function corner (data) {
|
||||
if (!data) return ''
|
||||
if (!/\/\//.test(data)) data = 'https://github.com/' + data
|
||||
data = data.replace(/^git\+/, '')
|
||||
|
||||
return `
|
||||
<a href="${data}" class="github-corner" aria-label="View source on Github">
|
||||
<svg viewBox="0 0 250 250" aria-hidden="true">
|
||||
<path d="M0,0 L115,115 L130,115 L142,142 L250,250 L250,0 Z"></path>
|
||||
<path d="M128.3,109.0 C113.8,99.7 119.0,89.6 119.0,89.6 C122.0,82.7 120.5,78.6 120.5,78.6 C119.2,72.0 123.4,76.3 123.4,76.3 C127.3,80.9 125.5,87.3 125.5,87.3 C122.9,97.6 130.6,101.9 134.4,103.2" fill="currentColor" style="transform-origin: 130px 106px;" class="octo-arm"></path>
|
||||
<path d="M115.0,115.0 C114.9,115.1 118.7,116.5 119.8,115.4 L133.7,101.6 C136.9,99.2 139.9,98.4 142.2,98.6 C133.8,88.0 127.5,74.4 143.8,58.0 C148.5,53.4 154.0,51.2 159.7,51.0 C160.3,49.4 163.2,43.6 171.4,40.1 C171.4,40.1 176.1,42.5 178.8,56.2 C183.1,58.6 187.2,61.8 190.9,65.4 C194.5,69.0 197.7,73.2 200.1,77.6 C213.8,80.2 216.3,84.9 216.3,84.9 C212.7,93.1 206.9,96.0 205.4,96.6 C205.1,102.4 203.0,107.8 198.3,112.5 C181.9,128.9 168.3,122.5 157.7,114.1 C157.9,116.9 156.7,120.9 152.7,124.9 L141.0,136.5 C139.8,137.7 141.6,141.9 141.8,141.8 Z" fill="currentColor" class="octo-body"></path>
|
||||
</svg>
|
||||
</a>`
|
||||
}
|
||||
|
||||
/**
|
||||
* Render main content
|
||||
* @return {[type]} [description]
|
||||
*/
|
||||
export function main () {
|
||||
return `<main>
|
||||
<aside class="sidebar"></aside>
|
||||
<section class="content">
|
||||
<article class="markdown-section"></article>
|
||||
</section>
|
||||
</main>`
|
||||
}
|
||||
|
||||
export function toggle (bool) {
|
||||
if (!bool) return ''
|
||||
return `<button class="sidebar-toggle">
|
||||
<span></span><span></span><span></span>
|
||||
</button>`
|
||||
}
|
||||
|
||||
/**
|
||||
* Render tree
|
||||
* @param {Array} tree
|
||||
* @param {String} tpl
|
||||
* @return {String}
|
||||
*/
|
||||
export function tree (toc, tpl = '') {
|
||||
if (!toc || !toc.length) return ''
|
||||
|
||||
toc.forEach(node => {
|
||||
tpl += `<li><a class="section-link" href="${node.slug}">${node.title}</a></li>`
|
||||
if (node.children) {
|
||||
tpl += `<li><ul class="children">${tree(node.children)}</li></ul>`
|
||||
}
|
||||
})
|
||||
|
||||
return tpl
|
||||
}
|
||||
+68
@@ -0,0 +1,68 @@
|
||||
/**
|
||||
* Simple ajax
|
||||
* @param {String} url
|
||||
* @param {String} [method=get]
|
||||
* @return {Promise}
|
||||
*/
|
||||
export function load (url, method = 'get') {
|
||||
const xhr = new XMLHttpRequest()
|
||||
|
||||
xhr.open(method, url)
|
||||
xhr.send()
|
||||
|
||||
return {
|
||||
then: function (success, error = function () {}) {
|
||||
xhr.addEventListener('error', error)
|
||||
xhr.addEventListener('load', ({ target }) => {
|
||||
target.status >= 400 ? error(target) : success(target.response)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* gen toc tree
|
||||
* @link https://github.com/killercup/grock/blob/5280ae63e16c5739e9233d9009bc235ed7d79a50/styles/solarized/assets/js/behavior.coffee#L54-L81
|
||||
* @param {Array} toc
|
||||
* @param {Number} maxLevel
|
||||
* @return {Array}
|
||||
*/
|
||||
export function genTree (toc, maxLevel) {
|
||||
const headlines = []
|
||||
const last = {}
|
||||
|
||||
toc.forEach(headline => {
|
||||
const level = headline.level || 1
|
||||
const len = level - 1
|
||||
|
||||
if (level > maxLevel) return
|
||||
if (last[len]) {
|
||||
last[len].children = last[len].children || []
|
||||
last[len].children.push(headline)
|
||||
} else {
|
||||
headlines.push(headline)
|
||||
}
|
||||
last[level] = headline
|
||||
})
|
||||
|
||||
return headlines
|
||||
}
|
||||
|
||||
/**
|
||||
* camel to kebab
|
||||
* @link https://github.com/bokuweb/kebab2camel/blob/master/index.js
|
||||
* @param {String} str
|
||||
* @return {String}
|
||||
*/
|
||||
export function camel2kebab (str) {
|
||||
return str.replace(/([A-Z])/g, m => '-' + m.toLowerCase())
|
||||
}
|
||||
|
||||
/**
|
||||
* is nil
|
||||
* @param {Object} object
|
||||
* @return {Boolean}
|
||||
*/
|
||||
export function isNil (o) {
|
||||
return o === null || o === undefined
|
||||
}
|
||||
-152
@@ -1,152 +0,0 @@
|
||||
* {
|
||||
-webkit-box-sizing: border-box;
|
||||
-moz-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
|
||||
-webkit-text-size-adjust: none;
|
||||
-webkit-touch-callout: none;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
}
|
||||
|
||||
/* navbar */
|
||||
nav {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
left: 0;
|
||||
z-index: 10;
|
||||
margin: 25px 60px 0 0;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
nav a {
|
||||
margin: 0 1em;
|
||||
padding: 5px 0;
|
||||
font-size: 16px;
|
||||
text-decoration: none;
|
||||
color: inherit;
|
||||
transition: color .3s;
|
||||
}
|
||||
|
||||
/* github corner */
|
||||
.github-corner {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
.github-corner svg {
|
||||
color: #fff;
|
||||
height: 80px;
|
||||
width: 80px;
|
||||
}
|
||||
|
||||
.github-corner:hover .octo-arm {
|
||||
animation:octocat-wave 560ms ease-in-out;
|
||||
}
|
||||
|
||||
@keyframes octocat-wave {
|
||||
0%,100%{ transform: rotate(0); }
|
||||
20%,60%{ transform: rotate(-25deg); }
|
||||
40%,80%{ transform: rotate(10deg); }
|
||||
}
|
||||
|
||||
@media (max-width: 500px) {
|
||||
.github-corner:hover .octo-arm {
|
||||
animation: none;
|
||||
}
|
||||
.github-corner .octo-arm {
|
||||
animation: octocat-wave 560ms ease-in-out;
|
||||
}
|
||||
}
|
||||
|
||||
html, body {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
body {
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
font-family: 'Source Sans Pro', 'Helvetica Neue', Arial, sans-serif;
|
||||
font-size: 15px;
|
||||
letter-spacing: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
/* main */
|
||||
main {
|
||||
height: 100%;
|
||||
position: relative;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
/* sidebar */
|
||||
.sidebar {
|
||||
border-right: 1px solid rgba(0,0,0,.07);
|
||||
bottom: 0;
|
||||
overflow-y: auto;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
width: 300px;
|
||||
z-index: 1;
|
||||
padding-top: 40px;
|
||||
}
|
||||
|
||||
.sidebar ul {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.sidebar ul, .sidebar ul li {
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
.sidebar ul li a {
|
||||
display: block;
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.sidebar ul li ul {
|
||||
padding-left: 20px;
|
||||
}
|
||||
|
||||
/* main content */
|
||||
.content {
|
||||
bottom: 0;
|
||||
left: 300px;
|
||||
overflow-y: auto;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
overflow-x: hidden;
|
||||
padding-top: 20px;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 600px) {
|
||||
.sidebar {
|
||||
left: -300px;
|
||||
}
|
||||
|
||||
.content {
|
||||
left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* markdown content found on pages */
|
||||
.markdown-section {
|
||||
position: relative;
|
||||
margin: 0 auto;
|
||||
max-width: 800px;
|
||||
padding: 20px 15px 40px 15px;
|
||||
}
|
||||
|
||||
.markdown-section * {
|
||||
box-sizing: border-box;
|
||||
-webkit-box-sizing: border-box;
|
||||
font-size: inherit;
|
||||
}
|
||||
|
||||
.markdown-section>:first-child {
|
||||
margin-top: 0!important;
|
||||
}
|
||||
Reference in New Issue
Block a user