mirror of
https://github.com/wahyd4/docsify.git
synced 2026-08-10 05:48:18 +10:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
67ec128315 | ||
|
|
77657e3b64 | ||
|
|
9825db47af | ||
|
|
1a5593889e | ||
|
|
fc9cdf37c5 | ||
|
|
80dba191d3 | ||
|
|
5a0c37fcd3 | ||
|
|
1462efedcd | ||
|
|
4cb20a5f9d | ||
|
|
490c8a19d3 | ||
|
|
4b838247ea | ||
|
|
b091f3f10d | ||
|
|
0e74e6c15e | ||
|
|
be8358fcdc | ||
|
|
1ae0a9a845 | ||
|
|
7e169ad154 | ||
|
|
8595c99c0b | ||
|
|
43fc8b8ab1 | ||
|
|
ccec23df7f | ||
|
|
fc1cd3f11d | ||
|
|
3f38810774 | ||
|
|
3db4841da3 | ||
|
|
b764b6e32c | ||
|
|
46261572e3 | ||
|
|
d53b8dadb3 | ||
|
|
b9b9d87681 | ||
|
|
d4f6072d10 | ||
|
|
891475e132 | ||
|
|
1acfdd335c | ||
|
|
1f4514dcad | ||
|
|
eba1c987a8 | ||
|
|
3444884905 | ||
|
|
6dea685fee | ||
|
|
f095eb888f | ||
|
|
8741c746df | ||
|
|
2c7041c8fb | ||
|
|
2a21c40f17 | ||
|
|
000194c8da | ||
|
|
fce1e47131 | ||
|
|
6d244139dd | ||
|
|
eca3368152 | ||
|
|
bab76e004d | ||
|
|
eb9dc4671a | ||
|
|
bb815cb2d4 | ||
|
|
26db33dc31 | ||
|
|
6cbed4b4d8 | ||
|
|
b948cb06d7 | ||
|
|
b2b474264f | ||
|
|
a8c73ee2b9 | ||
|
|
eda9bb8343 | ||
|
|
50e771e6a8 | ||
|
|
2d73285de5 | ||
|
|
d2be5aecf8 | ||
|
|
ca0d6182b9 | ||
|
|
dacea8a39b | ||
|
|
da75d70dee | ||
|
|
6ed25cebe5 | ||
|
|
ee54141776 | ||
|
|
51832d3506 | ||
|
|
25ccc79e56 | ||
|
|
890d29f982 | ||
|
|
76c041ad48 | ||
|
|
2c277b8f79 | ||
|
|
a5f6ccd1d1 | ||
|
|
11c94b2149 | ||
|
|
2653849a3e | ||
|
|
d7b0d1b949 | ||
|
|
6911fb879b | ||
|
|
137a93c7b2 | ||
|
|
5d5caa1f89 | ||
|
|
1dfd6cdcfe | ||
|
|
91c6db2902 | ||
|
|
94d6603c06 | ||
|
|
920f624b5c | ||
|
|
8fb1350728 | ||
|
|
c1df94662a | ||
|
|
9b7e5f5814 | ||
|
|
432bcfb54b | ||
|
|
4f98497284 | ||
|
|
9220523a40 | ||
|
|
b8100c0755 | ||
|
|
be0230ebe9 | ||
|
|
aa6d2afce8 | ||
|
|
a706203879 | ||
|
|
fbc75bdb95 | ||
|
|
5af174bd20 | ||
|
|
e70327ab2b | ||
|
|
7209b82982 | ||
|
|
594299ffbd | ||
|
|
e9bbfd4c53 | ||
|
|
96bc09211e | ||
|
|
8f11653b41 | ||
|
|
6aae64fd54 | ||
|
|
33b7c512bb | ||
|
|
bf35471a2b | ||
|
|
b022aaf14e | ||
|
|
03d8281868 | ||
|
|
4a0cfa799e | ||
|
|
2c2ac5f461 | ||
|
|
1edcd63cdb | ||
|
|
2d6a51b057 | ||
|
|
bf1ae7802d | ||
|
|
cf9b7c99e4 | ||
|
|
c20f3298d8 | ||
|
|
dd7d9aa4ad | ||
|
|
bba957d3bc | ||
|
|
28b3cb4249 | ||
|
|
97e730d7e3 | ||
|
|
65a6b3c659 | ||
|
|
f6b827f7bc | ||
|
|
24d1b0feb6 | ||
|
|
54da5fb6c8 | ||
|
|
d57b80e224 | ||
|
|
788bbb36b4 | ||
|
|
92070e3099 | ||
|
|
de0ad0f04c | ||
|
|
ceafc37bb3 | ||
|
|
1f19cb2ade | ||
|
|
33393ef0f6 |
@@ -0,0 +1,3 @@
|
||||
.git/
|
||||
packages/docsify-server-renderer/build.js
|
||||
node_modules
|
||||
@@ -1,5 +1,10 @@
|
||||
{
|
||||
"extends": ["vue"],
|
||||
"extends": [
|
||||
"vue"
|
||||
],
|
||||
"parserOptions": {
|
||||
"ecmaVersion": 8
|
||||
},
|
||||
"env": {
|
||||
"browser": true
|
||||
},
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
Please makes sure these boxes are checked before submitting your PR, thank you!
|
||||
|
||||
* [ ] Make sure you are merging your commits to `master` branch.
|
||||
* [ ] Add some descriptions and refer relative issues for you PR.
|
||||
* [ ] DO NOT include files inside lib directory.
|
||||
+2
-2
@@ -1,4 +1,4 @@
|
||||
.DS_Store
|
||||
*.log
|
||||
.DS_Store
|
||||
/themes
|
||||
node_modules
|
||||
/themes
|
||||
@@ -0,0 +1,5 @@
|
||||
.eslintignore
|
||||
.eslintrc
|
||||
.github/
|
||||
.gitignore
|
||||
.travis.yml
|
||||
+4
-1
@@ -1,6 +1,9 @@
|
||||
sudo: false
|
||||
cache:
|
||||
directories:
|
||||
- $HOME/.yarn-cache
|
||||
- $HOME/.yarn-cache
|
||||
language: node_js
|
||||
node_js: stable
|
||||
os:
|
||||
- linux
|
||||
- osx
|
||||
|
||||
+98
-16
@@ -1,79 +1,161 @@
|
||||
# Changelog
|
||||
|
||||
# 3.4.2 / 2017-03-11
|
||||
## 4.1.0 / 2017-05-30 🎂 for me
|
||||
|
||||
|
||||
* feat: Support server client renderer [See detail](//docsify.js.org/#/ssr)
|
||||
* feat: Support HTML5 history API. `$docsify.routerMode = 'history'`
|
||||
* Breaking change: Clean global API
|
||||
|
||||
## 3.7.3 / 2017-05-22
|
||||
|
||||
* fix(render): find => filter, Compatible with old browser
|
||||
* Pretty dir tree
|
||||
|
||||
## 3.7.2 / 2017-05-19
|
||||
|
||||
* tweaks
|
||||
|
||||
## 3.7.1 / 2017-05-19
|
||||
|
||||
* fix: docsify-updated is undefined
|
||||
|
||||
## 3.7.0 / 2017-05-16
|
||||
|
||||
* feat: add externalLinkTarget, close ([#149](https://github.com/QingWei-Li/docsify/issues/149)
|
||||
* feat: add **{docsify-updated<span>}</span>**, close ([#158](https://github.com/QingWei-Li/docsify/issues/158)
|
||||
|
||||
## 3.6.6 / 2017-05-06
|
||||
|
||||
* feat: support query string for the search, likes `https://docsify.js.org/#/?s=navbar`, fixed ([#156](https://github.com/QingWei-Li/docsify/issues/156)
|
||||
|
||||
## 3.6.5 / 2017-04-28
|
||||
|
||||
* fix(util): fix crash, fixed ([#154](https://github.com/QingWei-Li/docsify/issues/154)
|
||||
|
||||
## 3.6.4 / 2017-04-28
|
||||
|
||||
* fix(util): correctly clean up duplicate slashes, fixed ([#153](https://github.com/QingWei-Li/docsify/issues/153)
|
||||
|
||||
## 3.6.3 / 2017-04-25
|
||||
|
||||
* fix(external-script): script attrs
|
||||
|
||||
## 3.6.2/ 2017-04-12
|
||||
|
||||
* feat(external-script): detect more than one script dom, fixed ([#146](https://github.com/QingWei-Li/docsify/issues/146)
|
||||
* GA: Send hash instead of complete href ([#147](https://github.com/QingWei-Li/docsify/issues/147)
|
||||
|
||||
## 3.6.1 / 2017-04-09
|
||||
|
||||
* feat(event): Collapse the sidebar when click outside element in the small screen
|
||||
|
||||
## 3.6.0 / 2017-04-09
|
||||
|
||||
* feat(render): add mergeNavbar option, close ([#125](https://github.com/QingWei-Li/docsify/issues/125)
|
||||
|
||||
## 3.5.2/ 2017-04-05
|
||||
|
||||
* add optional current route param to toURL and use it to properly compose local anchor links
|
||||
* fix code style by removing semicolons
|
||||
* in toURL test for anchor links and if so prepend the currentPath to the generated path. fixes ([#142](https://github.com/QingWei-Li/docsify/issues/142))
|
||||
|
||||
## 3.5.1 / 2017-03-25
|
||||
|
||||
* fix: .md file extension regex
|
||||
|
||||
## 3.5.0 / 2017-03-25
|
||||
|
||||
* feat(route): auto remove .md extension
|
||||
* fix: adjust display on small screens [@jrappen](https://github.com/jrappen)
|
||||
* fix: navbar labels for German [@jrappen](https://github.com/jrappen)
|
||||
|
||||
## 3.4.4 / 2017-03-17
|
||||
|
||||
* fix(search): fix input style
|
||||
* fix search plugin match bug
|
||||
|
||||
## 3.4.3 / 2017-03-16
|
||||
|
||||
* Add ability to ignore headers when generating toc ([#127](https://github.com/QingWei-Li/docsify/issues/127) [@christopherwk210](https://github.com/christopherwk210))
|
||||
* fix external-script not inserting script at right place [@Leopoldthecoder](https://github.com/Leopoldthecoder)
|
||||
* add German docs [@jrappen](https://github.com/jrappen)
|
||||
|
||||
## 3.4.2 / 2017-03-11
|
||||
|
||||
* feat(emojify): add no-emoji option
|
||||
|
||||
# 3.4.1 / 2017-03-10
|
||||
## 3.4.1 / 2017-03-10
|
||||
|
||||
* fix(dom): Disable the dom cache when vue is present, fixed [#119](https://github.com/QingWei-Li/docsify/issues/119)
|
||||
* update english docs, [@jrappen](https://github.com/jrappen)
|
||||
|
||||
# 3.4.0 / 2017-03-09
|
||||
## 3.4.0 / 2017-03-09
|
||||
|
||||
* feat(zoom-image): add plugin
|
||||
|
||||
# 3.3.0 / 2017-03-07
|
||||
## 3.3.0 / 2017-03-07
|
||||
|
||||
* add front-matter plugin
|
||||
* add external-script plugin, [@Leopoldthecoder](https://github.com/Leopoldthecoder)
|
||||
* Fix nav showing while loading ([#112](https://github.com/QingWei-Li/docsify/issues/112))
|
||||
|
||||
# 3.2.0 / 2017-02-28
|
||||
## 3.2.0 / 2017-02-28
|
||||
|
||||
* fix(render): Toc rendering error, fixed [#106](https://github.com/QingWei-Li/docsify/issues/106)
|
||||
* feat(search): Localization for no data tip, close [#103](https://github.com/QingWei-Li/docsify/issues/103)
|
||||
* fix(fetch): load sidebar and navbar for parent path, fixed [#100](https://github.com/QingWei-Li/docsify/issues/100)
|
||||
* feat(render) nameLink for each route, fixed [#99](https://github.com/QingWei-Li/docsify/issues/99)
|
||||
|
||||
# 3.1.2 / 2017-02-27
|
||||
## 3.1.2 / 2017-02-27
|
||||
|
||||
* fix(search): dont search nameLink, fixed [#102](https://github.com/QingWei-Li/docsify/issues/102)
|
||||
|
||||
# 3.1.1 / 2017-02-24
|
||||
## 3.1.1 / 2017-02-24
|
||||
|
||||
* fix(search): dont search nameLink, fixed [#102](https://github.com/QingWei-Li/docsify/issues/102)
|
||||
* fix(render): custom cover background image
|
||||
* fix(tpl): extra character, fixed [#101](https://github.com/QingWei-Li/docsify/issues/101)
|
||||
|
||||
# 3.1.0 / 2017-02-22
|
||||
## 3.1.0 / 2017-02-22
|
||||
|
||||
* fix(search): incorrect anchor link, fixed [#90](https://github.com/QingWei-Li/docsify/issues/90)
|
||||
* feat(emoji): add emoji plugin
|
||||
|
||||
# 3.0.5 / 2017-02-21
|
||||
## 3.0.5 / 2017-02-21
|
||||
|
||||
* feat(pwa): add sw.js
|
||||
* fix(layout.css): loading style
|
||||
* fix(event): highlight sidebar when clicked, fixed [#86](https://github.com/QingWei-Li/docsify/issues/86)
|
||||
* fix(gen-tree): cache toc list, fixed [#88](https://github.com/QingWei-Li/docsify/issues/88)
|
||||
|
||||
# 3.0.4 / 2017-02-20
|
||||
## 3.0.4 / 2017-02-20
|
||||
|
||||
* fix(render): execute script
|
||||
* fix(render): disable rendering sub list when loadSidebar is false
|
||||
|
||||
# 3.0.3 / 2017-02-19
|
||||
## 3.0.3 / 2017-02-19
|
||||
|
||||
* fixed look of links in blockquote
|
||||
* fix(scroll) highlight bug
|
||||
|
||||
# 3.0.2 / 2017-02-19
|
||||
## 3.0.2 / 2017-02-19
|
||||
|
||||
* fix(search): add lazy input
|
||||
* fix(compiler): link
|
||||
|
||||
# 3.0.1 / 2017-02-19
|
||||
## 3.0.1 / 2017-02-19
|
||||
|
||||
* fix(route): empty alias
|
||||
|
||||
# 3.0.0 / 2017-02-19
|
||||
## 3.0.0 / 2017-02-19
|
||||
|
||||
#### Breaking change
|
||||
##### Breaking change
|
||||
|
||||
* Not support IE9
|
||||
* The route becomes: `/#/page?id=slug`. The previous route will be redirected
|
||||
|
||||
#### Features
|
||||
##### Features
|
||||
|
||||
* Faster rendering
|
||||
* Clearer source code
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
<a href="https://travis-ci.org/QingWei-Li/docsify"><img alt="Travis Status" src="https://img.shields.io/travis/rust-lang/rust/master.svg?style=flat-square"></a>
|
||||
<a href="https://travis-ci.org/QingWei-Li/docsify"><img alt="Travis Status" src="https://img.shields.io/travis/QingWei-Li/docsify/master.svg?style=flat-square"></a>
|
||||
<a href="https://www.npmjs.com/package/docsify"><img alt="npm" src="https://img.shields.io/npm/v/docsify.svg?style=flat-square"></a>
|
||||
<a href="https://github.com/QingWei-Li/donate"><img alt="donate" src="https://img.shields.io/badge/%24-donate-ff69b4.svg?style=flat-square"></a>
|
||||
</p>
|
||||
@@ -39,12 +39,12 @@ Create an `index.html`.
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<link rel="stylesheet" href="//unpkg.com/docsify/themes/vue.css">
|
||||
<link rel="stylesheet" href="//unpkg.com/docsify/lib/themes/vue.css">
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
</body>
|
||||
<script src="//unpkg.com/docsify"></script>
|
||||
<script src="//unpkg.com/docsify/lib/docsify.min.js"></script>
|
||||
</html>
|
||||
```
|
||||
|
||||
@@ -64,6 +64,9 @@ These open-source projects are using docsify to generate their sites. Pull reque
|
||||
| [Vudash](http://vudash.github.io/vudash/) | Powerful, Flexible, Open Source dashboards for anything |
|
||||
| [Trilogy](http://trilogy.js.org) | No-hassle SQLite with a Promise-based, document store style API. |
|
||||
| [Mybatis-Plus](http://mp.baomidou.com/) | An enhanced toolkit of Mybatis to simplify development |
|
||||
| [JS MythBusters](https://mythbusters.js.org) | An optimization handbook from a high level point of view. |
|
||||
| [hire-me](https://fvcproductions.github.io/hire-me) | A path to getting an awesome tech gig. |
|
||||
| [vue-amap](https://elemefe.github.io/vue-amap/) | A Map Component Library Base on Vue 2.x and Gaode Map. |
|
||||
|
||||
## Similar projects
|
||||
|
||||
|
||||
@@ -1,12 +1,51 @@
|
||||
var serveStatic = require('serve-static')
|
||||
var http = require('http')
|
||||
var fs = require('fs')
|
||||
var Renderer = require('./packages/docsify-server-renderer/build.js')
|
||||
|
||||
var renderer = new Renderer({
|
||||
template: `
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>docsify</title>
|
||||
<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" title="vue">
|
||||
</head>
|
||||
<body>
|
||||
<!--inject-app-->
|
||||
<!--inject-config-->
|
||||
<script src="/lib/docsify.js"></script>
|
||||
</body>
|
||||
</html>`,
|
||||
config: {
|
||||
name: 'docsify',
|
||||
repo: 'qingwei-li/docsify',
|
||||
basePath: 'https://docsify.js.org/',
|
||||
loadNavbar: true,
|
||||
loadSidebar: true,
|
||||
subMaxLevel: 3,
|
||||
auto2top: true,
|
||||
alias: {
|
||||
'/de-de/changelog': '/changelog',
|
||||
'/zh-cn/changelog': '/changelog',
|
||||
'/changelog': 'https://raw.githubusercontent.com/QingWei-Li/docsify/master/CHANGELOG'
|
||||
}
|
||||
},
|
||||
path: './'
|
||||
})
|
||||
|
||||
http.createServer(function (req, res) {
|
||||
serveStatic('.')(req, res, function () {
|
||||
// TEST SSR
|
||||
// renderer.renderToString(req.url)
|
||||
// .then(html => res.end(html))
|
||||
|
||||
res.writeHead(404, { 'Content-Type': 'text/html' })
|
||||
res.end(fs.readFileSync('dev.html'))
|
||||
})
|
||||
}).listen(3000, '0.0.0.0')
|
||||
|
||||
console.log(`\nListening at http://0.0.0.0:3000\n`)
|
||||
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
var rollup = require('rollup')
|
||||
var buble = require('rollup-plugin-buble')
|
||||
var async = require('rollup-plugin-async')
|
||||
var isProd = process.argv[process.argv.length - 1] !== '--dev'
|
||||
|
||||
rollup
|
||||
.rollup({
|
||||
entry: 'packages/docsify-server-renderer/index.js',
|
||||
plugins: [
|
||||
async(),
|
||||
buble({
|
||||
transforms: {
|
||||
generator: false
|
||||
}
|
||||
})
|
||||
],
|
||||
onwarn: function() {}
|
||||
})
|
||||
.then(function (bundle) {
|
||||
var dest = 'packages/docsify-server-renderer/build.js'
|
||||
|
||||
console.log(dest)
|
||||
bundle.write({
|
||||
format: 'cjs',
|
||||
dest: dest
|
||||
})
|
||||
})
|
||||
.catch(function (err) {
|
||||
console.error(err)
|
||||
})
|
||||
@@ -0,0 +1,43 @@
|
||||
set -e
|
||||
|
||||
if [[ -z $1 ]]; then
|
||||
echo "Enter new version: "
|
||||
read VERSION
|
||||
else
|
||||
VERSION=$1
|
||||
fi
|
||||
|
||||
read -p "Releasing $VERSION $RELEASE_TAG - are you sure? (y/n) " -n 1 -r
|
||||
echo
|
||||
if [[ $REPLY =~ ^[Yy]$ ]]; then
|
||||
echo "Releasing $VERSION ..."
|
||||
|
||||
npm run test
|
||||
|
||||
# build
|
||||
VERSION=$VERSION npm run build
|
||||
|
||||
# update packages
|
||||
cd packages/docsify-server-renderer
|
||||
npm version $VERSION
|
||||
if [[ -z $RELEASE_TAG ]]; then
|
||||
npm publish
|
||||
else
|
||||
npm publish --tag $RELEASE_TAG
|
||||
fi
|
||||
cd -
|
||||
|
||||
# commit
|
||||
git add -A
|
||||
git commit -m "[build] $VERSION $RELEASE_TAG"
|
||||
npm version $VERSION --message "[release] $VERSION $RELEASE_TAG"
|
||||
|
||||
# publish
|
||||
git push origin refs/tags/v$VERSION
|
||||
git push
|
||||
if [[ -z $RELEASE_TAG ]]; then
|
||||
npm publish
|
||||
else
|
||||
npm publish --tag $RELEASE_TAG
|
||||
fi
|
||||
fi
|
||||
@@ -7,28 +7,40 @@
|
||||
<link rel="stylesheet" href="/themes/vue.css" title="vue">
|
||||
<link rel="stylesheet" href="/themes/dark.css" title="dark" disabled>
|
||||
<link rel="stylesheet" href="/themes/buble.css" title="buble" disabled>
|
||||
<style>
|
||||
nav.app-nav li ul {
|
||||
min-width: 100px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<nav data-cloak>
|
||||
<a href="#/">EN</a>
|
||||
<a href="#/zh-cn/">中文</a>
|
||||
</nav>
|
||||
<div id="app"></div>
|
||||
</body>
|
||||
<script>
|
||||
window.$docsify = {
|
||||
alias: {
|
||||
'/de-de/changelog': '/changelog',
|
||||
'/zh-cn/changelog': '/changelog',
|
||||
'/changelog': 'https://raw.githubusercontent.com/QingWei-Li/docsify/master/CHANGELOG'
|
||||
},
|
||||
executeScript: true
|
||||
auto2top: true,
|
||||
basePath: '/docs/',
|
||||
executeScript: true,
|
||||
loadNavbar: true,
|
||||
loadSidebar: true,
|
||||
name: 'docsify',
|
||||
subMaxLevel: 2,
|
||||
mergeNavbar: true,
|
||||
formatUpdated: '{MM}/{DD} {HH}:{mm}',
|
||||
routerMode: 'history',
|
||||
plugins: [
|
||||
function(hook) {
|
||||
hook.beforeEach(function (html) {
|
||||
return html += '\n> Last modified {docsify-updated}'
|
||||
})
|
||||
}
|
||||
]
|
||||
}
|
||||
</script>
|
||||
<script
|
||||
src="/lib/docsify.js"
|
||||
data-name="docsify"
|
||||
data-base-path="/docs/"
|
||||
data-load-sidebar
|
||||
data-sub-max-level="2"
|
||||
data-auto2top></script>
|
||||
<script src="/lib/docsify.js"></script>
|
||||
</html>
|
||||
|
||||
+2
-2
@@ -4,9 +4,9 @@
|
||||
|
||||
## What is it
|
||||
|
||||
docsify generates your documentation website on the fly. Unlike GitBook, it does not generate static html files. Instead, it smartly loads and parses your Markdown files and displays them as website. All you need to do is create an `index.html` to start and [deploy it on GitHub Pages](/deploy).
|
||||
docsify generates your documentation website on the fly. Unlike GitBook, it does not generate static html files. Instead, it smartly loads and parses your Markdown files and displays them as website. All you need to do is create an `index.html` to start and [deploy it on GitHub Pages](deploy.md).
|
||||
|
||||
See the [Quick start](/quickstart) for more details.
|
||||
See the [Quick start](quickstart.md) for more details.
|
||||
|
||||
## Features
|
||||
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||

|
||||
|
||||
# docsify <small>3.4</small>
|
||||
# docsify <small>3.7</small>
|
||||
|
||||
> A magical documentation site generator.
|
||||
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
- Translations
|
||||
- [:cn: 中文](/zh-cn/)
|
||||
- [:de: Deutsch](/de-de/)
|
||||
- [:uk: English](/)
|
||||
+17
-16
@@ -1,22 +1,23 @@
|
||||
- Getting started
|
||||
- [Quick start](/quickstart)
|
||||
- [Writing more pages](/more-pages)
|
||||
- [Custom navbar](/custom-navbar)
|
||||
- [Cover page](/cover)
|
||||
- [Quick start](quickstart.md)
|
||||
- [Writing more pages](more-pages.md)
|
||||
- [Custom navbar](custom-navbar.md)
|
||||
- [Cover page](cover.md)
|
||||
|
||||
- Customization
|
||||
- [Configuration](/configuration)
|
||||
- [Themes](/themes)
|
||||
- [List of Plugins](/plugins)
|
||||
- [Write a Plugin](/write-a-plugin)
|
||||
- [Markdown configuration](/markdown)
|
||||
- [Language highlighting](/language-highlight)
|
||||
- [Configuration](configuration.md)
|
||||
- [Themes](themes.md)
|
||||
- [List of Plugins](plugins.md)
|
||||
- [Write a Plugin](write-a-plugin.md)
|
||||
- [Markdown configuration](markdown.md)
|
||||
- [Language highlighting](language-highlight.md)
|
||||
|
||||
- Guide
|
||||
- [Deploy](/deploy)
|
||||
- [Helpers](/helpers)
|
||||
- [Vue compatibility](/vue)
|
||||
- [CDN](/cdn)
|
||||
- [Offline Mode(PWA)](/pwa)
|
||||
- [Deploy](deploy.md)
|
||||
- [Helpers](helpers.md)
|
||||
- [Vue compatibility](vue.md)
|
||||
- [CDN](cdn.md)
|
||||
- [Offline Mode(PWA)](pwa.md)
|
||||
- [Server-client renderer(SSR)](ssr.md)
|
||||
|
||||
- [Changelog](/changelog)
|
||||
- [Changelog](changelog.md)
|
||||
|
||||
+4
-1
@@ -44,4 +44,7 @@ Alternatively, use [compressed files](#compressed-files).
|
||||
|
||||
## Other CDN
|
||||
|
||||
[jsDelivr](http://www.jsdelivr.com/projects/docsify) is available.
|
||||
- http://www.bootcdn.cn/docsify
|
||||
- http://www.jsdelivr.com/projects/docsify
|
||||
- https://cdnjs.com/libraries/docsify
|
||||
|
||||
|
||||
+45
-3
@@ -166,7 +166,7 @@ window.$docsify = {
|
||||
- Type: `Boolean|String`
|
||||
- Default: `false`
|
||||
|
||||
Activate the [cover feature](/cover). If true, it will load from `_coverpage.md`.
|
||||
Activate the [cover feature](cover.md). If true, it will load from `_coverpage.md`.
|
||||
|
||||
```js
|
||||
window.$docsify = {
|
||||
@@ -212,7 +212,7 @@ window.$docsify = {
|
||||
|
||||
- Type: `Function`
|
||||
|
||||
See [Markdown configuration](/markdown).
|
||||
See [Markdown configuration](markdown.md).
|
||||
|
||||
```js
|
||||
window.$docsify = {
|
||||
@@ -294,7 +294,7 @@ window.$docsify = {
|
||||
</script>
|
||||
```
|
||||
|
||||
Note that if you are running an external script, e.g. an embedded jsfiddle demo, make sure to include the [external-script](plugins?id=external-script) plugin.
|
||||
Note that if you are running an external script, e.g. an embedded jsfiddle demo, make sure to include the [external-script](plugins.md?id=external-script) plugin.
|
||||
|
||||
## no-emoji
|
||||
|
||||
@@ -305,3 +305,45 @@ window.$docsify = {
|
||||
noEmoji: true
|
||||
}
|
||||
```
|
||||
|
||||
## merge-navbar
|
||||
|
||||
Navbar will be merged with the sidebar on smaller screens.
|
||||
|
||||
```js
|
||||
window.$docsify = {
|
||||
mergeNavbar: true
|
||||
}
|
||||
```
|
||||
|
||||
## format-updated
|
||||
We can display the file update date through **{docsify-updated<span>}</span>** variable. And format it by `formatUpdated`.
|
||||
See https://github.com/lukeed/tinydate#patterns
|
||||
```js
|
||||
window.$docsify = {
|
||||
formatUpdated: '{MM}/{DD} {HH}:{mm}',
|
||||
|
||||
formatUpdated: function (time) {
|
||||
// ...
|
||||
|
||||
return time
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## external-link-target
|
||||
|
||||
Currently it defaults to _blank, would be nice if configurable:
|
||||
|
||||
```js
|
||||
window.$docsify = {
|
||||
externalLinkTarget: '_self' // default: '_blank'
|
||||
}
|
||||
```
|
||||
|
||||
## router-mode
|
||||
```js
|
||||
window.$docsify = {
|
||||
routerMode: 'history' // default: 'hash'
|
||||
}
|
||||
```
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
# Cover
|
||||
|
||||
Activate the cover feature by setting `coverpage` to **true**, compare [coverpage configuration](configuration#coverpage).
|
||||
Activate the cover feature by setting `coverpage` to **true**, compare [coverpage configuration](configuration.md#coverpage).
|
||||
|
||||
## Basic usage
|
||||
|
||||
|
||||
+10
-10
@@ -20,7 +20,7 @@ If you need custom navigation, you can create a HTML-based navigation bar.
|
||||
|
||||
## Markdown
|
||||
|
||||
Alternatively, you can create a custom markdown-based navigation file by setting `loadNavbar` to **true** and creating `_navbar.md`, compare [load-navbar configuration](configuration#load-navbar).
|
||||
Alternatively, you can create a custom markdown-based navigation file by setting `loadNavbar` to **true** and creating `_navbar.md`, compare [load-navbar configuration](configuration.md#load-navbar).
|
||||
|
||||
```html
|
||||
<!-- index.html -->
|
||||
@@ -52,17 +52,17 @@ You can create sub-lists by indenting items that are under a certain parent.
|
||||
<!-- _navbar.md -->
|
||||
|
||||
- Getting started
|
||||
- [Quick start](/quickstart)
|
||||
- [Writing more pages](/more-pages)
|
||||
- [Custom navbar](/custom-navbar)
|
||||
- [Cover page](/cover)
|
||||
- [Quick start](quickstart.md)
|
||||
- [Writing more pages](more-pages.md)
|
||||
- [Custom navbar](custom-navbar.md)
|
||||
- [Cover page](cover.md)
|
||||
|
||||
- Configuration
|
||||
- [Configuration](/configuration)
|
||||
- [Themes](/themes)
|
||||
- [Using plugins](/plugins)
|
||||
- [Markdown configuration](/markdown)
|
||||
- [Language highlight](/language-highlight)
|
||||
- [Configuration](configuration.md)
|
||||
- [Themes](themes.md)
|
||||
- [Using plugins](plugins.md)
|
||||
- [Markdown configuration](markdown.md)
|
||||
- [Language highlight](language-highlight.md)
|
||||
```
|
||||
|
||||
renders as
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
## docsify
|
||||
|
||||
> Ein magischer Generator für Dokumentationen.
|
||||
|
||||
## Was ist das
|
||||
|
||||
**docsify** generiert deine Dokumentationswebseite zeitgleich (mit der Darstellung). Im Gegensatz zu GitBook, werden keine statischen HTML Seiten generiert. Stattdessen, werden im Hintergrund Markdown Dateien geladen und umgewandelt, und als Webseite dargestellt. Alles, was du brauchst, ist eine Datei namens `index.html`, um sie über [GitHub Pages zu veröffentlichen](de-de/deploy.md).
|
||||
|
||||
Siehe [Schnellstart](de-de/quickstart.md) für weitere Informationen.
|
||||
|
||||
## Features
|
||||
|
||||
* keine generierten, statischen HTML Dateien
|
||||
* einfach und klein (~16kB gzipped)
|
||||
* smarte Erweiterung mit Volltextsuche
|
||||
* mehrere Themes
|
||||
* praktische API für Erweiterungen
|
||||
* Unterstützung für Emoji
|
||||
* Kompatibel mit IE10+
|
||||
|
||||
## Beispiele
|
||||
|
||||
Vergleiche die Liste namens [Showcase](https://github.com/QingWei-Li/docsify/#showcase) mit Beispielen, wie **docsify** verwendet wird.
|
||||
|
||||
## Spenden
|
||||
|
||||
Bitte ziehe eine Spende in Erwägung, sollte **docsify** dir hilfreich oder meine Arbeit dir wertvoll erscheinen. Ich freue mich, wenn du mir [eine Tasse Kaffee kaufst](https://github.com/QingWei-Li/donate). :heart:
|
||||
@@ -0,0 +1,23 @@
|
||||
- Loslegen
|
||||
- [Schnellstart](de-de/quickstart.md)
|
||||
- [Schreiben weiterer Seiten](de-de/more-pages.md)
|
||||
- [Navigationsleiste anpassen](de-de/custom-navbar.md)
|
||||
- [Titelseite](de-de/cover.md)
|
||||
|
||||
- Anpassen
|
||||
- [Einstellungen](de-de/configuration.md)
|
||||
- [Themen](de-de/themes.md)
|
||||
- [Liste der Erweiterungen](de-de/plugins.md)
|
||||
- [Schreiben eigener Erweiterungen](de-de/write-a-plugin.md)
|
||||
- [Markdown-Einstellungen](de-de/markdown.md)
|
||||
- [Hervorheben von Sprachen](de-de/language-highlight.md)
|
||||
|
||||
- Guide
|
||||
- [Inbetriebnahme](de-de/deploy.md)
|
||||
- [Helfer](de-de/helpers.md)
|
||||
- [Vue Kompatibilität](de-de/vue.md)
|
||||
- [CDN](de-de/cdn.md)
|
||||
- [Offline Modus (PWA)](de-de/pwa.md)
|
||||
- [Server-client renderer (SSR)](de-de/ssr.md)
|
||||
|
||||
- [Changelog](de-de/changelog.md)
|
||||
@@ -0,0 +1,49 @@
|
||||
# CDN
|
||||
|
||||
Empfohlen: [unpkg](//unpkg.com), welches jeweils die aktuelle Version liefert, wie sie über npm veröffentlicht wurde. Du kannst auch den Quellcode des npm Packets über [unpkg.com/docsify/](//unpkg.com/docsify/) anschauen.
|
||||
|
||||
## Aktuelle Version
|
||||
|
||||
```html
|
||||
<!-- lade CSS -->
|
||||
<link rel="stylesheet" href="//unpkg.com/docsify/themes/vue.css">
|
||||
|
||||
<!-- lade Script -->
|
||||
<script src="//unpkg.com/docsify/lib/docsify.js"></script>
|
||||
```
|
||||
|
||||
Alternativ kannst du auch die [komprimierten Dateien](#komprimierte-dateien) verwenden.
|
||||
|
||||
## Spezielle Version
|
||||
|
||||
```html
|
||||
<!-- lade CSS -->
|
||||
<link rel="stylesheet" href="//unpkg.com/docsify@2.0.0/themes/vue.css">
|
||||
|
||||
<!-- lade Script -->
|
||||
<script src="//unpkg.com/docsify@2.0.0/lib/docsify.js"></script>
|
||||
```
|
||||
|
||||
## Komprimierte Dateien
|
||||
|
||||
```html
|
||||
<!-- lade CSS -->
|
||||
<link rel="stylesheet" href="//unpkg.com/docsify/lib/themes/vue.css">
|
||||
|
||||
<!-- lade Script -->
|
||||
<script src="//unpkg.com/docsify/lib/docsify.min.js"></script>
|
||||
```
|
||||
|
||||
```html
|
||||
<!-- lade CSS -->
|
||||
<link rel="stylesheet" href="//unpkg.com/docsify@2.0.0/lib/themes/vue.css">
|
||||
|
||||
<!-- lade Script -->
|
||||
<script src="//unpkg.com/docsify@2.0.0/lib/docsify.min.js"></script>
|
||||
```
|
||||
|
||||
## Andere CDN
|
||||
|
||||
- http://www.bootcdn.cn/docsify
|
||||
- http://www.jsdelivr.com/projects/docsify
|
||||
- https://cdnjs.com/libraries/docsify
|
||||
@@ -0,0 +1,342 @@
|
||||
# Einstellungen
|
||||
|
||||
**docsify** unterstützt zwei verschiedene Arten, um die Einstellungen anzupassen. Du kannst das `window.$docsify` anpassen, oder die Einstellungen über das script tag im `data-*` Attribut vornehmen.
|
||||
|
||||
```html
|
||||
<!-- über $docsify -->
|
||||
<script>
|
||||
window.$docsify = {
|
||||
repo: 'QingWei-Li/docsify',
|
||||
maxLevel: 3,
|
||||
coverpage: true
|
||||
}
|
||||
</script>
|
||||
|
||||
<!-- oder data-* -->
|
||||
<script
|
||||
src="//unpkg.com/docsify"
|
||||
data-repo="QingWei-Li/docsify"
|
||||
data-max-level="3"
|
||||
data-coverpage>
|
||||
</script>
|
||||
```
|
||||
|
||||
Beide Arten sind miteinander kompatibel, wobei die erste jedoch empfohlen wird. Sie ist deutlicher und kann in einer separaten Datei geführt werden.
|
||||
|
||||
!> Innerhalb des `window.$docsfiy` sollten die Optionen mit camelCase geschrieben werden.
|
||||
|
||||
## el
|
||||
|
||||
- Typ: `String`
|
||||
- Standard: `#app`
|
||||
|
||||
Das DOM Element kann bei der Initialisierung gesetzt werden. Es kann ein CSS selector string oder ein richtiges HTMLElement sein.
|
||||
|
||||
```js
|
||||
window.$docsify = {
|
||||
el: '#app'
|
||||
}
|
||||
```
|
||||
|
||||
## repo
|
||||
|
||||
- Typ: `String`
|
||||
- Standard: `null`
|
||||
|
||||
Verwende die repository URL oder eine Zeichenfolge aus `Benutzername/repo`, um das [GitHub Corner](http://tholman.com/github-corners/) widget in die obere rechte Ecke der Seite zu implementieren.
|
||||
|
||||
```js
|
||||
window.$docsify = {
|
||||
repo: 'QingWei-Li/docsify',
|
||||
// oder
|
||||
repo: 'https://github.com/QingWei-Li/docsify/'
|
||||
}
|
||||
```
|
||||
|
||||
## max-level
|
||||
|
||||
- Typ: `Number`
|
||||
- Standard: `6`
|
||||
|
||||
Maximale Anzahl der Inhaltsübersichtebenen.
|
||||
|
||||
```js
|
||||
window.$docsify = {
|
||||
maxLevel: 4
|
||||
}
|
||||
```
|
||||
|
||||
## load-navbar
|
||||
|
||||
- Typ: `Boolean|String`
|
||||
- Standard: `false`
|
||||
|
||||
Lädt die Navigationsleiste von der Markdown Datei `_navbar.md` falls **true**, oder vom gewählten Pfad.
|
||||
|
||||
```js
|
||||
window.$docsify = {
|
||||
// lade von _navbar.md
|
||||
loadNavbar: true,
|
||||
|
||||
// lade von nav.md
|
||||
loadNavbar: 'nav.md'
|
||||
}
|
||||
```
|
||||
|
||||
## load-sidebar
|
||||
|
||||
- Typ: `Boolean|String`
|
||||
- Standard: `false`
|
||||
|
||||
Lädt das seitliche Inhaltsverzeichnis von der Markdown Datei `_sidebar.md` falls **true**, oder vom gewählten Pfad.
|
||||
|
||||
```js
|
||||
window.$docsify = {
|
||||
// lade von _sidebar.md
|
||||
loadSidebar: true,
|
||||
|
||||
// lade von summary.md
|
||||
loadSidebar: 'summary.md'
|
||||
}
|
||||
```
|
||||
|
||||
## sub-max-level
|
||||
|
||||
- Typ: `Number`
|
||||
- Standard: `0`
|
||||
|
||||
Wähle die maximale Anzahl der Unterpunkte pro Datei in der Inhaltsübersicht.
|
||||
|
||||
```js
|
||||
window.$docsify = {
|
||||
subMaxLevel: 2
|
||||
}
|
||||
```
|
||||
|
||||
## auto2top
|
||||
|
||||
- Typ: `Boolean`
|
||||
- Standard: `false`
|
||||
|
||||
Scrolle zum Anfang der Seite, wenn die Route gewechselt wird.
|
||||
|
||||
```js
|
||||
window.$docsify = {
|
||||
auto2top: true
|
||||
}
|
||||
```
|
||||
|
||||
## homepage
|
||||
|
||||
- Typ: `String`
|
||||
- Standard: `README.md`
|
||||
|
||||
`README.md` in deinem Ordner für die Dokumentation wird als Startseite für deine Webseite gesetzt, aber manchmal musst du das vielleicht ändern.
|
||||
|
||||
```js
|
||||
window.$docsify = {
|
||||
// Wähle /home.md
|
||||
homepage: 'home.md',
|
||||
|
||||
// Oder verwende das README in deinem repo
|
||||
homepage: 'https://raw.githubusercontent.com/QingWei-Li/docsify/master/README.md'
|
||||
}
|
||||
```
|
||||
|
||||
## base-path
|
||||
|
||||
- Typ: `String`
|
||||
|
||||
Der Basispfad der Webseite. Du kannst einen anderen Ordner wählen, oder eine andere Domain.
|
||||
|
||||
```js
|
||||
window.$docsify = {
|
||||
basePath: '/path/',
|
||||
|
||||
// Lade die Dateien von einer anderen Domain
|
||||
basePath: 'https://docsify.js.org/',
|
||||
|
||||
// Oder lade Dateien von einem anderen repo
|
||||
basePath: 'https://raw.githubusercontent.com/ryanmcdermott/clean-code-javascript/master/'
|
||||
}
|
||||
```
|
||||
|
||||
## coverpage
|
||||
|
||||
- Typ: `Boolean|String`
|
||||
- Standard: `false`
|
||||
|
||||
Aktiviere das [Titelseitenfeature](de-de/cover.md). Falls `true`, wird sie von `_coverpage.md` geladen.
|
||||
|
||||
```js
|
||||
window.$docsify = {
|
||||
coverpage: true,
|
||||
|
||||
// Anderer Dateiname
|
||||
coverpage: 'cover.md'
|
||||
}
|
||||
```
|
||||
|
||||
## name
|
||||
|
||||
- Typ: `String`
|
||||
|
||||
Webseitenname, wie er in der Inhaltsübersicht in der Seitenleiste angezeigt wird.
|
||||
|
||||
```js
|
||||
window.$docsify = {
|
||||
name: 'docsify'
|
||||
}
|
||||
```
|
||||
|
||||
## name-link
|
||||
|
||||
- Typ: `String`
|
||||
- Standard: `window.location.pathname`
|
||||
|
||||
Der Name der Links.
|
||||
|
||||
```js
|
||||
window.$docsify = {
|
||||
nameLink: '/',
|
||||
|
||||
// Für jede Route
|
||||
nameLink: {
|
||||
'/zh-cn/': '/zh-cn/',
|
||||
'/': '/'
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## markdown
|
||||
|
||||
- Typ: `Function`
|
||||
|
||||
Siehe [Markdown Konfiguration](de-de/markdown.md).
|
||||
|
||||
```js
|
||||
window.$docsify = {
|
||||
// Objekt
|
||||
markdown: {
|
||||
smartypants: true,
|
||||
renderer: {
|
||||
link: function() {
|
||||
// ...
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
// Funktion
|
||||
markdown: function (marked, renderer) {
|
||||
// ...
|
||||
return marked
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## theme-color
|
||||
|
||||
- Typ: `String`
|
||||
|
||||
Passe die Farbe der Themen an. Verwende [CSS3 Variablen](https://developer.mozilla.org/en-US/docs/Web/CSS/Using_CSS_variables) und polyfill in älteren Browsern.
|
||||
|
||||
```js
|
||||
window.$docsify = {
|
||||
themeColor: '#3F51B5'
|
||||
}
|
||||
```
|
||||
|
||||
## alias
|
||||
|
||||
- Typ: `Object`
|
||||
|
||||
Verwende alternative Routen. Du kannst sie ungehindert anpassen.
|
||||
|
||||
```js
|
||||
window.$docsify = {
|
||||
alias: {
|
||||
'/zh-cn/changelog': '/changelog',
|
||||
'/changelog': 'https://raw.githubusercontent.com/QingWei-Li/docsify/master/CHANGELOG'
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## auto-header
|
||||
|
||||
- Typ: `Boolean`
|
||||
|
||||
Sollten `loadSidebar` und `autoHeader` beide aktiviert sein, setze einen Header vor die Seite in jedem Link in `_sidebar.md`, bevor sie in HTML umgewandelt wird. Vergleiche [#78](https://github.com/QingWei-Li/docsify/issues/78).
|
||||
|
||||
```js
|
||||
window.$docsify = {
|
||||
loadSidebar: true,
|
||||
autoHeader: true
|
||||
}
|
||||
```
|
||||
|
||||
## execute-script
|
||||
|
||||
- Typ: `Boolean`
|
||||
|
||||
Führe das Skript auf der Seite aus. Analysiere nur das erste script tag ([demo](de-de/themes.md)). Sollte Vue verwendet sein, wird es in der Standardeinstellung ausgeführt.
|
||||
|
||||
```js
|
||||
window.$docsify = {
|
||||
executeScript: true
|
||||
}
|
||||
```
|
||||
|
||||
```markdown
|
||||
## Dies ist ein Test
|
||||
|
||||
<script>
|
||||
console.log(2333)
|
||||
</script>
|
||||
```
|
||||
|
||||
?> Nehme zur Kenntnis, dass, solltest du ein externes Skript ausführen, z.B. ein eingebettete jsfiddle demo, du sicher gehen solltest, das [external-script](de-de/plugins.md?id=external-script) plugin zu verwenden.
|
||||
|
||||
## no-emoji
|
||||
|
||||
Verhindere die Umwandlung in Emojis:
|
||||
|
||||
```js
|
||||
window.$docsify = {
|
||||
noEmoji: true
|
||||
}
|
||||
```
|
||||
|
||||
## merge-navbar
|
||||
|
||||
Navbar will be merged with the sidebar on smaller screens.
|
||||
|
||||
```js
|
||||
window.$docsify = {
|
||||
mergeNavbar: true
|
||||
}
|
||||
```
|
||||
|
||||
## format-updated
|
||||
We can display the file update date through **{docsify-updated<span>}</span>** variable. And format it by `formatUpdated`.
|
||||
See https://github.com/lukeed/tinydate#patterns
|
||||
```js
|
||||
window.$docsify = {
|
||||
formatUpdated: '{MM}/{DD} {HH}:{mm}',
|
||||
|
||||
formatUpdated: function (time) {
|
||||
// ...
|
||||
|
||||
return time
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## external-link-target
|
||||
|
||||
Currently it defaults to _blank, would be nice if configurable:
|
||||
|
||||
```js
|
||||
window.$docsify = {
|
||||
externalLinkTarget: '_self' // default: '_blank'
|
||||
}
|
||||
```
|
||||
@@ -0,0 +1,56 @@
|
||||
# Titelseite
|
||||
|
||||
Aktiviere die Unterstützung für Titelseiten, indem du `coverpage` auf **true** einstellst, vergleiche [coverpage Einstellungen](configuration.md#coverpage).
|
||||
|
||||
## Einfache Verwendung
|
||||
|
||||
Setze `coverpage` auf **true**, und erstelle `_coverpage.md`:
|
||||
|
||||
```html
|
||||
<!-- index.html -->
|
||||
|
||||
<script>
|
||||
window.$docsify = {
|
||||
coverpage: true
|
||||
}
|
||||
</script>
|
||||
<script src="//unpkg.com/docsify/lib/docsify.min.js"></script>
|
||||
```
|
||||
|
||||
```markdown
|
||||
<!-- _coverpage.md -->
|
||||
|
||||

|
||||
|
||||
# docsify <small>3.5</small>
|
||||
|
||||
> Ein magischer Generator für Dokumentationsseiten.
|
||||
|
||||
- Einfach und wenig Speicherbedarf (~16kB gzipped)
|
||||
- Keine statischen HTML Dateien
|
||||
- Mehrere Themes
|
||||
|
||||
[GitHub](https://github.com/QingWei-Li/docsify/)
|
||||
[Schnellstart](#docsify)
|
||||
```
|
||||
|
||||
!> Die Dokumentationsseiten können nur eine Titelseite haben!
|
||||
|
||||
## Eigener Hintergrund
|
||||
|
||||
Die Hintergrundfarbe wird in der Standardeinstellung zufällig generiert. Du kannst sie anpassen, oder auch ein Hintergrundbild verwenden:
|
||||
|
||||
```markdown
|
||||
<!-- _coverpage.md -->
|
||||
|
||||
# docsify <small>3.5</small>
|
||||
|
||||
[GitHub](https://github.com/QingWei-Li/docsify/)
|
||||
[Schnellstart](#quick-start)
|
||||
|
||||
<!-- Hintegrundbild -->
|
||||

|
||||
|
||||
<!-- Hintegrundfarbe -->
|
||||

|
||||
```
|
||||
@@ -0,0 +1,95 @@
|
||||
# Navigationsleiste anpassen
|
||||
|
||||
## HTML
|
||||
|
||||
Solltest du eine Navigationsleiste benötigen, so kannst du eine HTML-basierte erstellen.
|
||||
|
||||
!> Die Links der Dokumentation fangen alle mit `#/` an.
|
||||
|
||||
```html
|
||||
<!-- index.html -->
|
||||
|
||||
<body>
|
||||
<nav>
|
||||
<a href="#/">EN</a>
|
||||
<a href="#/de-de/">DE</a>
|
||||
</nav>
|
||||
<div id="app"></div>
|
||||
</body>
|
||||
```
|
||||
|
||||
## Markdown
|
||||
|
||||
Oder du kannst deine Navigationsleiste mit einer Datei basierend auf Markdown erstellen, indem du `loadNavbar` auf **true** setzt und eine Datei namens `_navbar.md` erstellst, vergleiche [load-navbar Einstellungen](configuration.md#load-navbar).
|
||||
|
||||
```html
|
||||
<!-- index.html -->
|
||||
|
||||
<script>
|
||||
window.$docsify = {
|
||||
loadNavbar: true
|
||||
}
|
||||
</script>
|
||||
<script src="//unpkg.com/docsify/lib/docsify.min.js"></script>
|
||||
```
|
||||
|
||||
```markdown
|
||||
<!-- _navbar.md -->
|
||||
|
||||
- [En](/)
|
||||
- [Deutsch](/de-de/)
|
||||
```
|
||||
|
||||
!> Solltest du Github Pages verwenden, musst du zusätzlich eine Datei namens `.nojekyll` in `./docs` erstellen, um zu verhindern, dass Github Dateien ignoriert, die mit einem Unterstrich anfangen.
|
||||
|
||||
`_navbar.md` wird in jedem Verzeichnislevel geladen. Sollte das aktuelle Verzeichnis keine Datei namens `_navbar.md` haben, so sucht **docsify** in den übergeordneten Ordnern. Wenn du z.B. im Moment im Verzeichnis `/guide/quick-start` bist, so wird `_navbar.md` von der Datei `/guide/_navbar.md` geladen.
|
||||
|
||||
## Aufbauen von Strukturen
|
||||
|
||||
Du kannst untergeordnete Listen erstellen, indem du untergeordnete Punkte einem übergeordneten Punkt gegenüber einrückst.
|
||||
|
||||
```markdown
|
||||
<!-- _navbar.md -->
|
||||
|
||||
- Getting started
|
||||
- [Quick start](de-de/quickstart.md)
|
||||
- [Writing more pages](de-de/more-pages.md)
|
||||
- [Custom navbar](de-de/custom-navbar.md)
|
||||
- [Cover page](de-de/cover.md)
|
||||
|
||||
- Configuration
|
||||
- [Configuration](de-de/configuration.md)
|
||||
- [Themes](de-de/themes.md)
|
||||
- [Using plugins](de-de/plugins.md)
|
||||
- [Markdown configuration](de-de/markdown.md)
|
||||
- [Language highlight](de-de/language-highlight.md)
|
||||
```
|
||||
|
||||
wird also wie folgt aussehen
|
||||
|
||||

|
||||
|
||||
## Angepasste Navigationsleisten in Verbindung mit dem emoji Erweiterung
|
||||
|
||||
Solltest du die [emoji Erweiterung](plugins.md#emoji) verwenden:
|
||||
|
||||
```html
|
||||
<!-- index.html -->
|
||||
|
||||
<script>
|
||||
window.$docsify = {
|
||||
// ...
|
||||
}
|
||||
</script>
|
||||
<script src="//unpkg.com/docsify/lib/docsify.min.js"></script>
|
||||
<script src="//unpkg.com/docsify/lib/plugins/emoji.min.js"></script>
|
||||
```
|
||||
|
||||
so kannst du z.B. auch die Flaggenemojis in der Markdown Datei für deine angepasste Navigationsleiste verwenden:
|
||||
|
||||
```markdown
|
||||
<!-- _navbar.md -->
|
||||
|
||||
- [:us:, :uk:](/)
|
||||
- [:de:](/de-de/)
|
||||
```
|
||||
@@ -0,0 +1,33 @@
|
||||
# Inbetriebnahme
|
||||
|
||||
Ähnlich wie bei [GitBook](https://www.gitbook.com), kannst du deine Dateien über GitHub Pages oder VPS erstellen.
|
||||
|
||||
## GitHub Pages
|
||||
|
||||
Du kannst folgende drei Orte verwenden, um die Dokumentation für dein Github repository zu verwalten:
|
||||
|
||||
* `docs/` Ordner
|
||||
* master branch
|
||||
* gh-pages branch
|
||||
|
||||
Es wird empfohlen, deine Dateien im `./docs` Unterordner im `master` branch deines repository zu speichern. Wechsle dann zu den Einstellungen deines repository und wähle `master branch /docs folder` als deine Github Pages Quelle.
|
||||
|
||||

|
||||
|
||||
!> Du kannst die Dateien auch im Hauptverzeichnis speichern und dann `master branch` in den Einstellungen auswählen.
|
||||
|
||||
## VPS
|
||||
|
||||
Verwende folgende nginx config.
|
||||
|
||||
```nginx
|
||||
server {
|
||||
listen 80;
|
||||
server_name your.domain.com;
|
||||
|
||||
location / {
|
||||
alias /path/to/dir/of/docs;
|
||||
index index.html;
|
||||
}
|
||||
}
|
||||
```
|
||||
@@ -0,0 +1,27 @@
|
||||
# Dokumentationshelfer
|
||||
|
||||
docsify erweitert die Markdownsyntax, um deine Dokumente besser lesbar zu machen.
|
||||
|
||||
## Wichtiger Inhalt
|
||||
|
||||
Wichtiger Inhalt wie:
|
||||
|
||||
```markdown
|
||||
!> **Zeit** ist Geld, mein Freund!
|
||||
```
|
||||
|
||||
wird wie folgt gerendert:
|
||||
|
||||
!> **Zeit** ist Geld, mein Freund!
|
||||
|
||||
## Generelle Tipps
|
||||
|
||||
Generelle Tipps wie:
|
||||
|
||||
```markdown
|
||||
?> *TODO* unit test
|
||||
```
|
||||
|
||||
wird wie folgt gerendert:
|
||||
|
||||
?> *TODO* unit test
|
||||
@@ -0,0 +1,11 @@
|
||||
# Hervorheben von Sprachen
|
||||
|
||||
**docsify** verwendet [Prism](https://github.com/PrismJS/prism) um Quellcodeabschnitte in deinen Seiten hervorzuheben. Als Standardeinstellung werden nur CSS, JavaScipt und HTML unterstützt. Du kannst **Prism** auch mit weiteren Sprachen verwenden:
|
||||
|
||||
```html
|
||||
<script src="//unpkg.com/docsify/lib/docsify.min.js"></script>
|
||||
<script src="//unpkg.com/prismjs/components/prism-bash.min.js"></script>
|
||||
<script src="//unpkg.com/prismjs/components/prism-php.min.js"></script>
|
||||
```
|
||||
|
||||
?> Vergleiche die [component files](https://github.com/PrismJS/prism/tree/gh-pages/components) Liste für weitere Optionen.
|
||||
@@ -0,0 +1,30 @@
|
||||
# Markdown Einstellungen
|
||||
|
||||
**docsify** verwendet [marked](https://github.com/chjj/marked), um Markdown umzuwandeln. Du kannst einstellen, wie es deine Markdown Seiten in HTML umwandelt, indem du `renderer` konfigurierst:
|
||||
|
||||
```js
|
||||
window.$docsify = {
|
||||
markdown: {
|
||||
smartypants: true,
|
||||
renderer: {
|
||||
link: function() {
|
||||
// ...
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
?> Für mögliche Einstellungen, siehe [marked Dokumentation](https://github.com/chjj/marked#options-1)
|
||||
|
||||
Du kannst die Regeln auch beliebig anpassen.
|
||||
|
||||
```js
|
||||
window.$docsify = {
|
||||
markdown: function(marked, renderer) {
|
||||
// ...
|
||||
|
||||
return marked
|
||||
}
|
||||
}
|
||||
```
|
||||
@@ -0,0 +1,92 @@
|
||||
# Noch mehr Seiten
|
||||
|
||||
Wenn du mehr Seiten für deine Dokumentation brauchst, so kannst du weitere Markdown Dateien in deinem **docsify** Ordner erstellen. Eine Datei namens `guide.md` ist dann über `/#/guide` erreichbar.
|
||||
|
||||
Nehmen wir als Beispiel folgende Verzeichnisstruktur:
|
||||
|
||||
```text
|
||||
.
|
||||
├── docs
|
||||
| └── README.md
|
||||
| └── guide.md
|
||||
| └── de-de
|
||||
| └──README.md
|
||||
| └──guide.md
|
||||
```
|
||||
|
||||
Die passenden Routen sind dann
|
||||
|
||||
```text
|
||||
docs/README.md => http://domain.com
|
||||
docs/guide.md => http://domain.com/guide
|
||||
docs/de-de/README.md => http://domain.com/de-de/
|
||||
docs/de-de/guide.md => http://domain.com/de-de/guide
|
||||
```
|
||||
|
||||
## Seitenleiste mit Inhaltsverzeichnis anpassen
|
||||
|
||||
Als Standardeinstellung wird das Inhaltsverzeichnis in der Seitenleiste automatisch basierend auf vorhandenen Markdown Dateien generiert. Wenn du das seitliche Inhaltsverzeichnis anpassen willst, kannst du eine Datei namens `_sidebar.md` erstellen (vergleiche [das seitliche Inhaltsverzeichnis für diese Dokumentation](https://github.com/QingWei-Li/docsify/blob/master/docs/de-de/_sidebar.md) als Beispiel):
|
||||
|
||||
Als Erstes musst du `loadSidebar` auf **true** setzen, vergleiche [Einstellungen für das seitliche Inhaltsverzeichnis](configuration.md#load-sidebar).
|
||||
|
||||
```html
|
||||
<!-- index.html -->
|
||||
|
||||
<script>
|
||||
window.$docsify = {
|
||||
loadSidebar: true
|
||||
}
|
||||
</script>
|
||||
<script src="//unpkg.com/docsify/lib/docsify.min.js"></script>
|
||||
```
|
||||
|
||||
Als Zweites erstellst du eine Datei namens `_sidebar.md`:
|
||||
|
||||
```markdown
|
||||
<!-- docs/_sidebar.md -->
|
||||
|
||||
- [Home](/)
|
||||
- [Guide](de-de/guide.md)
|
||||
```
|
||||
|
||||
!> Solltest du Github Pages verwenden, musst du zusätzlich eine Datei namens `.nojekyll` in `./docs` erstellen, um zu verhindern, dass Github Dateien ignoriert, die mit einem Unterstrich anfangen.
|
||||
|
||||
`_sidebar.md` wird in jedem Verzeichnislevel geladen. Sollte das aktuelle Verzeichnis keine Datei namens `_sidebar.md` haben, so sucht **docsify** in den übergeordneten Ordnern. Wenn du z.B. im Moment im Verzeichnis `/guide/quick-start` bist, so wird `_sidebar.md` von der Datei `/guide/_sidebar.md` geladen.
|
||||
|
||||
## Inhaltsverzeichnis
|
||||
|
||||
Eine angepasste Seitenleist kann auch automatisch ein Inhaltsverzeichnis generieren, indem ein `subMaxLevel` gesetzt wird, vergleiche [sub-max-level Einstellungen](configuration.md#sub-max-level).
|
||||
|
||||
```html
|
||||
<!-- index.html -->
|
||||
|
||||
<script>
|
||||
window.$docsify = {
|
||||
loadSidebar: true,
|
||||
subMaxLevel: 2
|
||||
}
|
||||
</script>
|
||||
<script src="//unpkg.com/docsify/lib/docsify.min.js"></script>
|
||||
```
|
||||
|
||||
## Ignoring Subheaders
|
||||
|
||||
When `subMaxLevel` is set, each header is automatically added to the table of contents by default. If you want to ignore a specific header, add `{docsify-ignore}` to it.
|
||||
|
||||
```markdown
|
||||
# Getting Started
|
||||
|
||||
## Header {docsify-ignore}
|
||||
This header won't appear in the sidebar table of contents.
|
||||
```
|
||||
|
||||
To ignore all headers on a specific page, you can use `{docsify-ignore-all}` on the first header of the page.
|
||||
|
||||
```markdown
|
||||
# Getting Started {docsify-ignore-all}
|
||||
|
||||
## Header
|
||||
This header won't appear in the sidebar table of contents.
|
||||
```
|
||||
|
||||
Both `{docsify-ignore}` and `{docsify-ignore-all}` will not be rendered on the page when used.
|
||||
@@ -0,0 +1,95 @@
|
||||
# Liste der Erweiterungen
|
||||
|
||||
## Volltextsuche
|
||||
|
||||
Als Standardeinstellung werden Hyperlinks auf der aktuellen Seite erkannt und der Inhalt in `localStorage` gespeichert. Du kannst den Pfad zu den Dateien auch anpassen:
|
||||
|
||||
|
||||
```html
|
||||
<script>
|
||||
window.$docsify = {
|
||||
search: 'auto', // Standard
|
||||
|
||||
search : [
|
||||
'/', // => /README.md
|
||||
'/guide', // => /guide.md
|
||||
'/get-started', // => /get-started.md
|
||||
'/de-de/', // => /de-de/README.md
|
||||
],
|
||||
|
||||
// vollständige Parameter für die Einstellungen
|
||||
search: {
|
||||
maxAge: 86400000, // Verfallszeit, als Standard ein Tag
|
||||
paths: [], // oder 'auto'
|
||||
placeholder: 'Type to search',
|
||||
|
||||
// Lokalisation
|
||||
placeholder: {
|
||||
'/de-de/': 'Suche',
|
||||
'/': 'Search'
|
||||
},
|
||||
|
||||
noData: 'No Results!',
|
||||
|
||||
// Lokalisation
|
||||
noData: {
|
||||
'/de-de/': 'Keine Ergebnisse',
|
||||
'/': 'No Results'
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<script src="//unpkg.com/docsify/lib/docsify.min.js"></script>
|
||||
<script src="//unpkg.com/docsify/lib/plugins/search.min.js"></script>
|
||||
```
|
||||
|
||||
## Google Analytics
|
||||
|
||||
Installiere diese Erweiterung und passe die track id an:
|
||||
|
||||
```html
|
||||
<script>
|
||||
window.$docsify = {
|
||||
ga: 'UA-XXXXX-Y'
|
||||
}
|
||||
</script>
|
||||
<script src="//unpkg.com/docsify/lib/docsify.min.js"></script>
|
||||
<script src="//unpkg.com/docsify/lib/plugins/ga.min.js"></script>
|
||||
```
|
||||
|
||||
Konfiguration über `data-ga`:
|
||||
|
||||
```html
|
||||
<script src="//unpkg.com/docsify/lib/docsify.min.js" data-ga="UA-XXXXX-Y"></script>
|
||||
<script src="//unpkg.com/docsify/lib/plugins/ga.min.js"></script>
|
||||
```
|
||||
|
||||
## front matter
|
||||
|
||||
```html
|
||||
<script src="//unpkg.com/docsify/lib/plugins/front-matter.min.js"></script>
|
||||
```
|
||||
|
||||
## emoji
|
||||
|
||||
Als Standardeinstellung werden emojis umgewandelt. Als Beispiel wird `:100:` umgewandelt in :100:. Aber das ist nicht genau, das es keine passende Nicht-emoji Zeichenfolge gibt. Solltest du emojis richtig umwandeln wollen, musst du diese Erweiterung verwenden.
|
||||
|
||||
```html
|
||||
<script src="//unpkg.com/docsify/lib/plugins/emoji.min.js"></script>
|
||||
```
|
||||
|
||||
## Externes Skript
|
||||
|
||||
Wenn das Skript auf der Seite ein externes ist (eine Javascript Datei über das `src` Attribut importiert), brauchst du diese Erweiterung, damit das funktioniert.
|
||||
|
||||
```html
|
||||
<script src="//unpkg.com/docsify/lib/plugins/external-script.min.js"></script>
|
||||
```
|
||||
|
||||
## Bilder zoomen
|
||||
|
||||
Medium's Bilderzoom. Basierend auf [zoom-image](https://github.com/egoist/zoom-image).
|
||||
|
||||
```html
|
||||
<script src="//unpkg.com/docsify/lib/plugins/zoom-image.min.js"></script>
|
||||
```
|
||||
@@ -1,3 +1,16 @@
|
||||
# Offline Modus
|
||||
|
||||
[Progressive Web Apps](https://developers.google.com/web/progressive-web-apps/) (PWA) sind Erfahrungen die Vorzüge des Internets mit den Vorzügen von Apps verbinden. Wir können unsere Webseite verbessern, indem wir sie mit Hilfe von service workers auch **offline** und in schlechten Netzen interagierbar machen.
|
||||
|
||||
Sie sind sehr einfach zu verwenden.
|
||||
|
||||
## serviceWorker erstellen
|
||||
|
||||
Erstelle eine Datei namens `sw.js` in deinem **docsify** Verzeichnis und kopiere folgenden Code:
|
||||
|
||||
*sw.js*
|
||||
|
||||
```js
|
||||
/* ===========================================================
|
||||
* docsify sw.js
|
||||
* ===========================================================
|
||||
@@ -9,7 +22,6 @@
|
||||
const RUNTIME = 'docsify'
|
||||
const HOSTNAME_WHITELIST = [
|
||||
self.location.hostname,
|
||||
'raw.githubusercontent.com',
|
||||
'fonts.gstatic.com',
|
||||
'fonts.googleapis.com',
|
||||
'unpkg.com'
|
||||
@@ -82,3 +94,22 @@ self.addEventListener('fetch', event => {
|
||||
)
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
## Registrieren
|
||||
|
||||
Jetzt registrieren wir die Funktion in der Datei `index.html`. Nur manche aktuellen Browser unterstützen die Funktion, wir müssen also prüfen:
|
||||
|
||||
*index.html*
|
||||
|
||||
```html
|
||||
<script>
|
||||
if (typeof navigator.serviceWorker !== 'undefined') {
|
||||
navigator.serviceWorker.register('sw.js')
|
||||
}
|
||||
</script>
|
||||
```
|
||||
|
||||
## Geniessen
|
||||
|
||||
Du kannst die Website jetzt veröffentlichen und Benutzer können sie dann vollständig offline verwenden, sobald sie einmal geladen wurde :ghost: Du kannst das jetzt ausprobieren, indem du deine Internetverbindung ausschaltest und diese Seite neu lädst.
|
||||
@@ -0,0 +1,87 @@
|
||||
# Schnellstart
|
||||
|
||||
Es wird empfohlen, `docsify-cli` global zu installieren, welches bei der Inbetriebnahme und der lokalen Vorschau hilft.
|
||||
|
||||
```bash
|
||||
npm i docsify-cli -g
|
||||
```
|
||||
|
||||
## Inbetriebnahme
|
||||
|
||||
Wenn du die Dokumentation in dem Unterordner `./docs` erstellen willst, kannst du den Befehl `init` verwenden.
|
||||
|
||||
```bash
|
||||
docsify init ./docs
|
||||
```
|
||||
|
||||
## Inhalt schreiben
|
||||
|
||||
Nachdem der Befehl `init` vollständig ausgeführt wurde, kannst du folgende Dateien im Unterordner `./docs` finden:
|
||||
|
||||
* `index.html` als zentrale Datei
|
||||
* `README.md` als die Startseite für die Dokumentation
|
||||
* `.nojekyll` verhindert, dass Github Pages Dateien ignoriert, die mit einem Unterstrich beginnen.
|
||||
|
||||
Du kannst die Dokumentation über die Datei `./docs/README.md` nach Belieben ändern, und natürlich [weitere Seiten](de-de/more-pages.md) hinzufügen.
|
||||
|
||||
## Vorschau der eigenen Seiten
|
||||
|
||||
Du kannst einen lokalen Server mit dem Befehl `docsify serve` laufen lassen, und auf eine Vorschau deiner Webseite über `http://localhost:3000` zugreifen.
|
||||
|
||||
```bash
|
||||
docsify serve docs
|
||||
```
|
||||
|
||||
?> Für weitere Informationen hinsichtlich der Verwendung von `docsify-cli`, siehe [docsify-cli Dokumentation](https://github.com/QingWei-Li/docsify-cli).
|
||||
|
||||
## Manuelle Inbetriebnahme
|
||||
|
||||
Wenn du `npm` nicht verwenden möchtest, oder Probleme bei der Installation des Tools hast, kannst du auch manuell die Datei namens `index.html` erstellen:
|
||||
|
||||
```html
|
||||
<!-- index.html -->
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">dict.
|
||||
<link rel="stylesheet" href="//unpkg.com/docsify/themes/vue.css">
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
</body>
|
||||
<script src="//unpkg.com/docsify/lib/docsify.min.js"></script>
|
||||
</html>
|
||||
```
|
||||
|
||||
Solltest du Python installiert haben, kannst du einen statischen Server laufen lassen, um eine Vorschau deiner Webseite anzuschauen:
|
||||
|
||||
```bash
|
||||
cd docs && python -m SimpleHTTPServer 3000
|
||||
```
|
||||
|
||||
## Ladedialog
|
||||
|
||||
Wenn du möchtest, kann **docsify** einen Ladedialog anzeigen, während es deine Dokumentation umwandelt:
|
||||
|
||||
```html
|
||||
<!-- index.html -->
|
||||
|
||||
<div id="app">Please wait...</div>
|
||||
```
|
||||
|
||||
Du solltest das `data-app` Attribut anpassen, wenn du `el` geändert hast:
|
||||
|
||||
```html
|
||||
<!-- index.html -->
|
||||
|
||||
<div data-app id="main">Please wait...</div>
|
||||
|
||||
<script>
|
||||
window.$docsify = {
|
||||
el: '#main'
|
||||
}
|
||||
</script>
|
||||
```
|
||||
|
||||
Vergleiche [el Einstellungen](configuration.md#el).
|
||||
@@ -0,0 +1,124 @@
|
||||
# Server client renderer
|
||||
|
||||
See https://docsify.now.sh
|
||||
|
||||
## Why SSR?
|
||||
- Better SEO
|
||||
- Feeling cool
|
||||
|
||||
## Quick start
|
||||
|
||||
Install `now` and `docsify-cli` in your project.
|
||||
|
||||
```bash
|
||||
npm i now -g
|
||||
npm i docsify-cli -D
|
||||
```
|
||||
|
||||
Edit `package.json`. If the documentation in `./docs` subdirectory.
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "my-project",
|
||||
"scripts": {
|
||||
"start": "docsify start ."
|
||||
},
|
||||
"files": [
|
||||
"docs"
|
||||
],
|
||||
"docsify": {
|
||||
"config": {
|
||||
"basePath": "/docs/",
|
||||
"loadSidebar": true,
|
||||
"loadNavbar": true,
|
||||
"coverpage": true,
|
||||
"name": "docsify"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Remove `index.html`
|
||||
|
||||
|
||||
!> The `basePath` just like webpack `publicPath`. You should config it if your docs is in the subdirectory.
|
||||
|
||||
We can preview in the local to see if it works.
|
||||
|
||||
```bash
|
||||
npm start
|
||||
|
||||
# open http://localhost:4000
|
||||
```
|
||||
|
||||
Publish it!
|
||||
|
||||
```bash
|
||||
now -p
|
||||
```
|
||||
|
||||
Now, You have a support for SSR the docs site.
|
||||
|
||||
## Custom template
|
||||
|
||||
You can provide a templte for entire page's HTML. such as
|
||||
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>docsify</title>
|
||||
<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/themes/vue.css" title="vue">
|
||||
</head>
|
||||
<body>
|
||||
<!--inject-app-->
|
||||
<!--inject-config-->
|
||||
</body>
|
||||
<script src="//unpkg.com/docsify/lib/docsify.js"></script>
|
||||
<script src="//unpkg.com/docsify/lib/plugins/search.js"></script>
|
||||
<script src="//unpkg.com/prismjs/components/prism-bash.min.js"></script>
|
||||
<script src="//unpkg.com/prismjs/components/prism-markdown.min.js"></script>
|
||||
<script src="//unpkg.com/prismjs/components/prism-nginx.min.js"></script>
|
||||
</html>
|
||||
```
|
||||
|
||||
The template should contain these comments for rendered app content.
|
||||
- `<!--inject-app-->`
|
||||
- `<!--inject-config-->`
|
||||
|
||||
## Configuration
|
||||
|
||||
You can configure it in a special config file, or `package.json`.
|
||||
|
||||
```js
|
||||
module.exports = {
|
||||
tempate: './ssr.html',
|
||||
config: {
|
||||
// docsify config
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Deploy for your VPS
|
||||
|
||||
You can run `docsify start` directly on your Node server, or write your own server app with `docsify-server-renderer`.
|
||||
|
||||
```js
|
||||
var Renderer = require('docsify-server-renderer')
|
||||
var readFileSync = require('fs').readFileSync
|
||||
|
||||
// init
|
||||
var renderer = new Renderer({
|
||||
template: readFileSync('./docs/index.template.html', 'utf-8').,
|
||||
config: {
|
||||
name: 'docsify',
|
||||
repo: 'qingwei-li/docsify'
|
||||
}
|
||||
})
|
||||
|
||||
renderer.renderToString(url)
|
||||
.then(html => {})
|
||||
.catch(err => {})
|
||||
```
|
||||
@@ -0,0 +1,56 @@
|
||||
# Themes
|
||||
|
||||
Es gibt im Moment vier Themes zur Auswahl, ähnlich wie die Webseiten von [Vue](//vuejs.org) oder [buble](//buble.surge.sh), sowie eine weitere, dunkle von [@liril-net](https://github.com/liril-net).
|
||||
|
||||
```html
|
||||
<link rel="stylesheet" href="//unpkg.com/docsify/themes/vue.css">
|
||||
<link rel="stylesheet" href="//unpkg.com/docsify/themes/buble.css">
|
||||
<link rel="stylesheet" href="//unpkg.com/docsify/themes/dark.css">
|
||||
<link rel="stylesheet" href="//unpkg.com/docsify/themes/pure.css">
|
||||
```
|
||||
|
||||
!> Komprimierte Dateien sind über `/lib/themes/` verfügbar.
|
||||
|
||||
```html
|
||||
<!-- komprimierte Versionen -->
|
||||
|
||||
<link rel="stylesheet" href="//unpkg.com/docsify/lib/themes/vue.css">
|
||||
<link rel="stylesheet" href="//unpkg.com/docsify/lib/themes/buble.css">
|
||||
<link rel="stylesheet" href="//unpkg.com/docsify/lib/themes/dark.css">
|
||||
<link rel="stylesheet" href="//unpkg.com/docsify/lib/themes/pure.css">
|
||||
```
|
||||
|
||||
Solltest du weitere Themes erstellen, kannst du sie gerne der Allgemeinheit mit einem [pull request](https://github.com/QingWei-Li/docsify/pulls) zur Verfügung stellen.
|
||||
|
||||
#### Klicke hier für eine Vorschau
|
||||
|
||||
<div class="demo-theme-preview">
|
||||
<a data-theme="vue">vue.css</a>
|
||||
<a data-theme="buble">buble.css</a>
|
||||
<a data-theme="dark">dark.css</a>
|
||||
<a data-theme="pure">pure.css</a>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.demo-theme-preview a {
|
||||
padding-right: 10px;
|
||||
}
|
||||
|
||||
.demo-theme-preview a:hover {
|
||||
cursor: pointer;
|
||||
text-decoration: underline;
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
var preview = Docsify.dom.find('.demo-theme-preview');
|
||||
var themes = Docsify.dom.findAll('[rel="stylesheet"]');
|
||||
|
||||
preview.onclick = function (e) {
|
||||
var title = e.target.getAttribute('data-theme')
|
||||
|
||||
themes.forEach(function (theme) {
|
||||
theme.disabled = theme.title !== title
|
||||
});
|
||||
};
|
||||
</script>
|
||||
@@ -0,0 +1,100 @@
|
||||
# Kompatibel mit Vue
|
||||
|
||||
Du kannst Vue Komponenten direkt in den Markdown Dateien verwenden, und sie werden umgewandelt. Du kannst dies zum Beispiel verwenden, um Vue Komponenten gleichzeitig zu demonstrieren und zu dokumentieren.
|
||||
|
||||
## Einfache Verwendung
|
||||
|
||||
Lade Vue in `./index.html`.
|
||||
|
||||
```html
|
||||
<script src="//unpkg.com/vue"></script>
|
||||
<script src="//unpkg.com/docsify"></script>
|
||||
|
||||
<!-- oder verwende die komprimierten Dateien -->
|
||||
<script src="//unpkg.com/vue/dist/vue.min.js"></script>
|
||||
<script src="//unpkg.com/docsify/lib/docsify.min.js"></script>
|
||||
```
|
||||
|
||||
Dann kannst du sofort Vue Code in deinen Markdown Dateien verwenden. `new Vue({ el: '#main' })` wird als Standard ausgeführt, um Instanzen zu erschaffen.
|
||||
|
||||
*README.md*
|
||||
|
||||
```markdown
|
||||
# Vue guide
|
||||
|
||||
`v-for` usage.
|
||||
|
||||
```html
|
||||
<ul>
|
||||
<li v-for="i in 10">{{ i }}</li>
|
||||
</ul>
|
||||
``
|
||||
|
||||
<ul>
|
||||
<li v-for="i in 10">{{ i }}</li>
|
||||
</ul>
|
||||
```
|
||||
|
||||
Du kannst manuell eine Vue Instanz initialisieren.
|
||||
|
||||
*README.md*
|
||||
|
||||
```markdown
|
||||
# Vue demo
|
||||
|
||||
<div>hello {{ msg }}</div>
|
||||
|
||||
<script>
|
||||
new Vue({
|
||||
el: '#main',
|
||||
data: { msg: 'Vue' }
|
||||
})
|
||||
</script>
|
||||
```
|
||||
|
||||
!> In Markdown Dateien wird nur das Skript innerhalb des ersten script tag Blocks ausgeführt.
|
||||
|
||||
## Kombiniere Vuep um Demos zu erschaffen
|
||||
|
||||
[Vuep](https://github.com/QingWei-Li/vuep) ist eine Komponente zur Darstellung von Vue Komponenten mit einem Liveeditor und einer Vorschau.Unterstützt die Vue Komponenten spec und JSX.
|
||||
|
||||
*index.html*
|
||||
|
||||
```html
|
||||
<!-- injizieren von CSS -->
|
||||
<link rel="stylesheet" href="//unpkg.com/vuep/dist/vuep.css">
|
||||
|
||||
<!-- injizieren von JS -->
|
||||
<script src="//unpkg.com/vue"></script>
|
||||
<script src="//unpkg.com/vuep"></script>
|
||||
<script src="//unpkg.com/docsify"></script>
|
||||
|
||||
<!-- oder verwende die komprimierten Dateien -->
|
||||
<script src="//unpkg.com/vue/dist/vue.min.js"></script>
|
||||
<script src="//unpkg.com/vuep/dist/vuep.min.js"></script>
|
||||
<script src="//unpkg.com/docsify/lib/docsify.min.js"></script>
|
||||
```
|
||||
|
||||
*README.md*
|
||||
|
||||
```markdown
|
||||
# Vuep
|
||||
|
||||
<vuep template="#example"></vuep>
|
||||
|
||||
<script v-pre type="text/x-template" id="example">
|
||||
<template>
|
||||
<div>Hello, {{ name }}!</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
module.exports = {
|
||||
data: function () {
|
||||
return { name: 'Vue' }
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</script>
|
||||
```
|
||||
|
||||
?> Zum Beispiel vergleich auch die [vuep Dokumentation](https://qingwei-li.github.io/vuep/).
|
||||
@@ -0,0 +1,70 @@
|
||||
# Schreiben einer Erweiterung
|
||||
|
||||
Eine Erweiterung ist schlicht eine Funktion, welche `hook` als Argument nimmt. hook unterstützt dabei das Verwalten von asynchrononen Tasks.
|
||||
|
||||
## Volle Konfiguration
|
||||
|
||||
```js
|
||||
window.$docsify = {
|
||||
plugins: [
|
||||
function (hook, vm) {
|
||||
hook.init(function() {
|
||||
// Called when the script starts running, only trigger once, no arguments,
|
||||
})
|
||||
|
||||
hook.beforeEach(function(content) {
|
||||
// Invoked each time before parsing the Markdown file.
|
||||
// ...
|
||||
return content
|
||||
})
|
||||
|
||||
hook.afterEach(function(html, next) {
|
||||
// Invoked each time after the Markdown file is parsed.
|
||||
// beforeEach and afterEach support asynchronous。
|
||||
// ...
|
||||
// call `next(html)` when task is done.
|
||||
next(html)
|
||||
})
|
||||
|
||||
hook.doneEach(function() {
|
||||
// Invoked each time after the data is fully loaded, no arguments,
|
||||
// ...
|
||||
})
|
||||
|
||||
hook.mounted(function() {
|
||||
// Called after initial completion. Only trigger once, no arguments.
|
||||
})
|
||||
|
||||
hook.ready(function() {
|
||||
// Called after initial completion, no arguments.
|
||||
})
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
!> Du kannst auf interne Methoden über `window.Docsify` zugreifen. Greife auf die aktuelle Instanz über das zweite Argument zu.
|
||||
|
||||
## Beispiel
|
||||
|
||||
Füge jeder Seite eine footer Komponente hinzu:
|
||||
|
||||
```js
|
||||
window.$docsify = {
|
||||
plugins: [
|
||||
function (hook) {
|
||||
var footer = [
|
||||
'<hr/>',
|
||||
'<footer>',
|
||||
'<span><a href="https://github.com/QingWei-Li">cinwell</a> ©2017.</span>',
|
||||
'<span>Proudly published with <a href="https://github.com/QingWei-Li/docsify" target="_blank">docsify</a>.</span>',
|
||||
'</footer>'
|
||||
].join('')
|
||||
|
||||
hook.afterEach(function (html) {
|
||||
return html + footer
|
||||
})
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
+39
-18
@@ -6,36 +6,57 @@
|
||||
<link rel="icon" href="_media/favicon.ico">
|
||||
<meta name="keywords" content="doc,docs,documentation,gitbook,creator,generator,github,jekyll,github-pages">
|
||||
<meta name="description" content="A magical documentation generator.">
|
||||
<meta name="google-site-verification" content="6t0LoIeFksrjF4c9sqUEsVXiQNxLp2hgoqo0KryT-sE" />
|
||||
<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" title="vue">
|
||||
<link rel="stylesheet" href="//unpkg.com/docsify/lib/themes/dark.css" title="dark" disabled>
|
||||
<link rel="stylesheet" href="//unpkg.com/docsify/lib/themes/buble.css" title="buble" disabled>
|
||||
<link rel="stylesheet" href="//unpkg.com/docsify/lib/themes/pure.css" title="pure" disabled>
|
||||
<style>
|
||||
nav.app-nav li ul {
|
||||
min-width: 100px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<nav data-cloak>
|
||||
<a href="#/">En</a>
|
||||
<a href="#/zh-cn/">中文</a>
|
||||
</nav>
|
||||
<div id="app"></div>
|
||||
<div id="app">Loading ...</div>
|
||||
</body>
|
||||
<script>
|
||||
window.$docsify = {
|
||||
name: 'docsify',
|
||||
maxLevel: 4,
|
||||
subMaxLevel: 2,
|
||||
auto2top: true,
|
||||
coverpage: true,
|
||||
loadSidebar: true,
|
||||
executeScript: true,
|
||||
alias: {
|
||||
'/de-de/changelog': '/changelog',
|
||||
'/zh-cn/changelog': '/changelog',
|
||||
'/changelog': 'https://raw.githubusercontent.com/QingWei-Li/docsify/master/CHANGELOG'
|
||||
}
|
||||
}
|
||||
|
||||
if (typeof navigator.serviceWorker !== 'undefined') {
|
||||
navigator.serviceWorker.register('sw.js')
|
||||
},
|
||||
auto2top: true,
|
||||
coverpage: true,
|
||||
executeScript: true,
|
||||
loadSidebar: true,
|
||||
loadNavbar: true,
|
||||
mergeNavbar: true,
|
||||
maxLevel: 4,
|
||||
subMaxLevel: 2,
|
||||
name: 'docsify',
|
||||
search: {
|
||||
noData: {
|
||||
'/de-de/': 'Keine Ergebnisse!',
|
||||
'/zh-cn/': '没有结果!',
|
||||
'/': 'No results!'
|
||||
},
|
||||
paths: 'auto',
|
||||
placeholder: {
|
||||
'/de-de/': 'Suche',
|
||||
'/zh-cn/': '搜索',
|
||||
'/': 'Search'
|
||||
}
|
||||
},
|
||||
formatUpdated: '{MM}/{DD} {HH}:{mm}',
|
||||
plugins: [
|
||||
function(hook) {
|
||||
hook.beforeEach(function (html) {
|
||||
return html += '\n> Last modified {docsify-updated}'
|
||||
})
|
||||
}
|
||||
]
|
||||
}
|
||||
</script>
|
||||
<script src="//unpkg.com/docsify/lib/docsify.min.js"></script>
|
||||
|
||||
+31
-9
@@ -6,12 +6,12 @@ For example, the directory structure is as follows:
|
||||
|
||||
```text
|
||||
.
|
||||
├── docs
|
||||
| └── README.md
|
||||
| └── guide.md
|
||||
| └── zh-cn
|
||||
| └──README.md
|
||||
| └──guide.md
|
||||
└── docs
|
||||
├── README.md
|
||||
├── guide.md
|
||||
└── zh-cn
|
||||
├── README.md
|
||||
└── guide.md
|
||||
```
|
||||
|
||||
Matching routes
|
||||
@@ -27,7 +27,7 @@ docs/zh-cn/guide.md => http://domain.com/zh-cn/guide
|
||||
|
||||
By default, the table of contents in the sidebar is automatically generated based on your markdown files. If you need a custom sidebar, then you can create your own `_sidebar.md` (see [this documentation's sidebar](https://github.com/QingWei-Li/docsify/blob/master/docs/_sidebar.md) for an example):
|
||||
|
||||
First, you need to set `loadSidebar` to **true**. Details are available in the [configuration paragraph](configuration#load-sidebar).
|
||||
First, you need to set `loadSidebar` to **true**. Details are available in the [configuration paragraph](configuration.md#load-sidebar).
|
||||
|
||||
```html
|
||||
<!-- index.html -->
|
||||
@@ -46,7 +46,7 @@ Create the `_sidebar.md`:
|
||||
<!-- docs/_sidebar.md -->
|
||||
|
||||
- [Home](/)
|
||||
- [Guide](/guide)
|
||||
- [Guide](guide.md)
|
||||
```
|
||||
|
||||
!> You need to create a `.nojekyll` in `./docs` to prevent GitHub Pages from ignoring files that begin with an underscore.
|
||||
@@ -55,7 +55,7 @@ Create the `_sidebar.md`:
|
||||
|
||||
## Table of Contents
|
||||
|
||||
A custom sidebar can also automatically generate a table of contents by setting a `subMaxLevel`, compare [sub-max-level configuration](configuration#sub-max-level).
|
||||
A custom sidebar can also automatically generate a table of contents by setting a `subMaxLevel`, compare [sub-max-level configuration](configuration.md#sub-max-level).
|
||||
|
||||
```html
|
||||
<!-- index.html -->
|
||||
@@ -68,3 +68,25 @@ A custom sidebar can also automatically generate a table of contents by setting
|
||||
</script>
|
||||
<script src="//unpkg.com/docsify/lib/docsify.min.js"></script>
|
||||
```
|
||||
|
||||
## Ignoring Subheaders
|
||||
|
||||
When `subMaxLevel` is set, each header is automatically added to the table of contents by default. If you want to ignore a specific header, add `{docsify-ignore}` to it.
|
||||
|
||||
```markdown
|
||||
# Getting Started
|
||||
|
||||
## Header {docsify-ignore}
|
||||
This header won't appear in the sidebar table of contents.
|
||||
```
|
||||
|
||||
To ignore all headers on a specific page, you can use `{docsify-ignore-all}` on the first header of the page.
|
||||
|
||||
```markdown
|
||||
# Getting Started {docsify-ignore-all}
|
||||
|
||||
## Header
|
||||
This header won't appear in the sidebar table of contents.
|
||||
```
|
||||
|
||||
Both `{docsify-ignore}` and `{docsify-ignore-all}` will not be rendered on the page when used.
|
||||
|
||||
+2
-2
@@ -22,7 +22,7 @@ After the `init` is complete, you can see the file list in the `./docs` subdirec
|
||||
* `README.md` as the home page
|
||||
* `.nojekyll` prevents GitHub Pages from ignoring files that begin with an underscore
|
||||
|
||||
You can easily update the documentation in `./docs/README.md`, of course you can add [more pages](more-pages).
|
||||
You can easily update the documentation in `./docs/README.md`, of course you can add [more pages](more-pages.md).
|
||||
|
||||
## Preview your site
|
||||
|
||||
@@ -84,4 +84,4 @@ You should set the `data-app` attribute if you changed `el`:
|
||||
</script>
|
||||
```
|
||||
|
||||
Compare [el configuration](/configuration#el).
|
||||
Compare [el configuration](configuration.md#el).
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
module.exports = {
|
||||
config: {
|
||||
alias: {
|
||||
'/de-de/changelog': '/changelog',
|
||||
'/zh-cn/changelog': '/changelog',
|
||||
'/changelog': 'https://raw.githubusercontent.com/QingWei-Li/docsify/master/CHANGELOG'
|
||||
},
|
||||
auto2top: true,
|
||||
coverpage: true,
|
||||
executeScript: true,
|
||||
loadSidebar: true,
|
||||
loadNavbar: true,
|
||||
mergeNavbar: true,
|
||||
maxLevel: 4,
|
||||
subMaxLevel: 2,
|
||||
basePath: '/docs/',
|
||||
name: 'docsify',
|
||||
search: {
|
||||
noData: {
|
||||
'/de-de/': 'Keine Ergebnisse!',
|
||||
'/zh-cn/': '没有结果!',
|
||||
'/': 'No results!'
|
||||
},
|
||||
paths: 'auto',
|
||||
placeholder: {
|
||||
'/de-de/': 'Suche',
|
||||
'/zh-cn/': '搜索',
|
||||
'/': 'Search'
|
||||
}
|
||||
}
|
||||
},
|
||||
template: './docs/ssr.html'
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>docsify</title>
|
||||
<link rel="icon" href="_media/favicon.ico">
|
||||
<meta name="keywords" content="doc,docs,documentation,gitbook,creator,generator,github,jekyll,github-pages">
|
||||
<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" title="vue">
|
||||
<link rel="stylesheet" href="//unpkg.com/docsify/lib/themes/dark.css" title="dark" disabled>
|
||||
<link rel="stylesheet" href="//unpkg.com/docsify/lib/themes/buble.css" title="buble" disabled>
|
||||
<link rel="stylesheet" href="//unpkg.com/docsify/lib/themes/pure.css" title="pure" disabled>
|
||||
<style>
|
||||
nav.app-nav li ul {
|
||||
min-width: 100px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<!--inject-app-->
|
||||
<!--inject-config-->
|
||||
</body>
|
||||
<script src="//unpkg.com/docsify/lib/docsify.min.js"></script>
|
||||
<script src="//unpkg.com/docsify/lib/plugins/search.min.js"></script>
|
||||
<script src="//unpkg.com/prismjs/components/prism-bash.min.js"></script>
|
||||
<script src="//unpkg.com/prismjs/components/prism-markdown.min.js"></script>
|
||||
<script src="//unpkg.com/prismjs/components/prism-nginx.min.js"></script>
|
||||
</html>
|
||||
+123
@@ -0,0 +1,123 @@
|
||||
# Server client renderer
|
||||
|
||||
See https://docsify.now.sh
|
||||
|
||||
## Why SSR?
|
||||
- Better SEO
|
||||
- Feeling cool
|
||||
|
||||
## Quick start
|
||||
|
||||
Install `now` and `docsify-cli` in your project.
|
||||
|
||||
```bash
|
||||
npm i now -g
|
||||
npm i docsify-cli -D
|
||||
```
|
||||
|
||||
Edit `package.json`. If the documentation in `./docs` subdirectory.
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "my-project",
|
||||
"scripts": {
|
||||
"start": "docsify start ."
|
||||
},
|
||||
"files": [
|
||||
"docs"
|
||||
],
|
||||
"docsify": {
|
||||
"config": {
|
||||
"basePath": "/docs/",
|
||||
"loadSidebar": true,
|
||||
"loadNavbar": true,
|
||||
"coverpage": true,
|
||||
"name": "docsify"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Remove `index.html`
|
||||
|
||||
!> The `basePath` just like webpack `publicPath`. You should config it if your docs is in the subdirectory.
|
||||
|
||||
We can preview in the local to see if it works.
|
||||
|
||||
```bash
|
||||
npm start
|
||||
|
||||
# open http://localhost:4000
|
||||
```
|
||||
|
||||
Publish it!
|
||||
|
||||
```bash
|
||||
now -p
|
||||
```
|
||||
|
||||
Now, You have a support for SSR the docs site.
|
||||
|
||||
## Custom template
|
||||
|
||||
You can provide a templte for entire page's HTML. such as
|
||||
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>docsify</title>
|
||||
<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/themes/vue.css" title="vue">
|
||||
</head>
|
||||
<body>
|
||||
<!--inject-app-->
|
||||
<!--inject-config-->
|
||||
</body>
|
||||
<script src="//unpkg.com/docsify/lib/docsify.js"></script>
|
||||
<script src="//unpkg.com/docsify/lib/plugins/search.js"></script>
|
||||
<script src="//unpkg.com/prismjs/components/prism-bash.min.js"></script>
|
||||
<script src="//unpkg.com/prismjs/components/prism-markdown.min.js"></script>
|
||||
<script src="//unpkg.com/prismjs/components/prism-nginx.min.js"></script>
|
||||
</html>
|
||||
```
|
||||
|
||||
The template should contain these comments for rendered app content.
|
||||
- `<!--inject-app-->`
|
||||
- `<!--inject-config-->`
|
||||
|
||||
## Configuration
|
||||
|
||||
You can configure it in a special config file, or `package.json`.
|
||||
|
||||
```js
|
||||
module.exports = {
|
||||
tempate: './ssr.html',
|
||||
config: {
|
||||
// docsify config
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Deploy for your VPS
|
||||
|
||||
You can run `docsify start` directly on your Node server, or write your own server app with `docsify-server-renderer`.
|
||||
|
||||
```js
|
||||
var Renderer = require('docsify-server-renderer')
|
||||
var readFileSync = require('fs').readFileSync
|
||||
|
||||
// init
|
||||
var renderer = new Renderer({
|
||||
template: readFileSync('./docs/index.template.html', 'utf-8').,
|
||||
config: {
|
||||
name: 'docsify',
|
||||
repo: 'qingwei-li/docsify'
|
||||
}
|
||||
})
|
||||
|
||||
renderer.renderToString(url)
|
||||
.then(html => {})
|
||||
.catch(err => {})
|
||||
```
|
||||
@@ -6,6 +6,7 @@ There are currently three themes available. Copy [Vue](//vuejs.org) and [buble](
|
||||
<link rel="stylesheet" href="//unpkg.com/docsify/themes/vue.css">
|
||||
<link rel="stylesheet" href="//unpkg.com/docsify/themes/buble.css">
|
||||
<link rel="stylesheet" href="//unpkg.com/docsify/themes/dark.css">
|
||||
<link rel="stylesheet" href="//unpkg.com/docsify/themes/pure.css">
|
||||
```
|
||||
|
||||
!> Compressed files are available in `/lib/themes/`.
|
||||
@@ -16,6 +17,7 @@ There are currently three themes available. Copy [Vue](//vuejs.org) and [buble](
|
||||
<link rel="stylesheet" href="//unpkg.com/docsify/lib/themes/vue.css">
|
||||
<link rel="stylesheet" href="//unpkg.com/docsify/lib/themes/buble.css">
|
||||
<link rel="stylesheet" href="//unpkg.com/docsify/lib/themes/dark.css">
|
||||
<link rel="stylesheet" href="//unpkg.com/docsify/lib/themes/pure.css">
|
||||
```
|
||||
|
||||
If you have any ideas or would like to develop a new theme, you are welcome to submit a [pull request](https://github.com/QingWei-Li/docsify/pulls).
|
||||
@@ -26,6 +28,7 @@ If you have any ideas or would like to develop a new theme, you are welcome to s
|
||||
<a data-theme="vue">vue.css</a>
|
||||
<a data-theme="buble">buble.css</a>
|
||||
<a data-theme="dark">dark.css</a>
|
||||
<a data-theme="pure">pure.css</a>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
|
||||
@@ -6,9 +6,9 @@
|
||||
|
||||
docsify 是一个动态生成文档网站的工具。不同于 GitBook、Hexo 的地方是它不会生成将 `.md` 转成 `.html` 文件,所有转换工作都是在运行时进行。
|
||||
|
||||
这将非常实用,如果只是需要快速的搭建一个小型的文档网站,或者不想因为生成的一堆 `.html` 文件“污染” commit 记录,只需要创建一个 `index.html` 就可以开始写文档而且直接[部署在 GitHub Pages](zh-cn/deploy)。
|
||||
这将非常实用,如果只是需要快速的搭建一个小型的文档网站,或者不想因为生成的一堆 `.html` 文件“污染” commit 记录,只需要创建一个 `index.html` 就可以开始写文档而且直接[部署在 GitHub Pages](zh-cn/deploy.md)。
|
||||
|
||||
查看[快速开始](zh-cn/quickstart)了解详情。
|
||||
查看[快速开始](zh-cn/quickstart.md)了解详情。
|
||||
|
||||
## 特性
|
||||
- 无需构建,写完文档直接发布
|
||||
|
||||
+17
-16
@@ -1,22 +1,23 @@
|
||||
- 入门
|
||||
- [快速开始](zh-cn/quickstart)
|
||||
- [多页文档](zh-cn/more-pages)
|
||||
- [定制导航栏](zh-cn/custom-navbar)
|
||||
- [封面](zh-cn/cover)
|
||||
- [快速开始](zh-cn/quickstart.md)
|
||||
- [多页文档](zh-cn/more-pages.md)
|
||||
- [定制导航栏](zh-cn/custom-navbar.md)
|
||||
- [封面](zh-cn/cover.md)
|
||||
|
||||
- 定制化
|
||||
- [配置项](zh-cn/configuration)
|
||||
- [主题](zh-cn/themes)
|
||||
- [插件列表](zh-cn/plugins)
|
||||
- [开发插件](zh-cn/write-a-plugin)
|
||||
- [Markdown 配置](zh-cn/markdown)
|
||||
- [代码高亮](zh-cn/language-highlight)
|
||||
- [配置项](zh-cn/configuration.md)
|
||||
- [主题](zh-cn/themes.md)
|
||||
- [插件列表](zh-cn/plugins.md)
|
||||
- [开发插件](zh-cn/write-a-plugin.md)
|
||||
- [Markdown 配置](zh-cn/markdown.md)
|
||||
- [代码高亮](zh-cn/language-highlight.md)
|
||||
|
||||
- 指南
|
||||
- [部署](zh-cn/deploy)
|
||||
- [文档助手](zh-cn/helpers)
|
||||
- [兼容 Vue](zh-cn/vue)
|
||||
- [CDN](zh-cn/cdn)
|
||||
- [离线模式(PWA)](zh-cn/pwa)
|
||||
- [部署](zh-cn/deploy.md)
|
||||
- [文档助手](zh-cn/helpers.md)
|
||||
- [兼容 Vue](zh-cn/vue.md)
|
||||
- [CDN](zh-cn/cdn.md)
|
||||
- [离线模式(PWA)](zh-cn/pwa.md)
|
||||
- [服务端渲染 (SSR)](zh-cn/ssr.md)
|
||||
|
||||
- [Changelog](zh-cn/changelog)
|
||||
- [Changelog](zh-cn/changelog.md)
|
||||
|
||||
+3
-2
@@ -44,5 +44,6 @@ JS 的压缩文件是原有文件路径的基础上加 `.min`后缀
|
||||
|
||||
## 其他 CDN
|
||||
|
||||
[jsDelivr](http://www.jsdelivr.com/projects/docsify) 也是可用的,具体用法参考其文档。
|
||||
|
||||
- http://www.bootcdn.cn/docsify
|
||||
- http://www.jsdelivr.com/projects/docsify
|
||||
- https://cdnjs.com/libraries/docsify
|
||||
|
||||
@@ -74,7 +74,7 @@ window.$docsify = {
|
||||
- 类型:`Boolean|String`
|
||||
- 默认值: `false`
|
||||
|
||||
加载自定义导航栏,参考[定制导航栏](zh-cn/custom-navbar) 了解用法。设置为 `true` 后会加载 `_navbar.md` 文件,也可以自定义加载的文件名。
|
||||
加载自定义导航栏,参考[定制导航栏](zh-cn/custom-navbar.md) 了解用法。设置为 `true` 后会加载 `_navbar.md` 文件,也可以自定义加载的文件名。
|
||||
|
||||
```js
|
||||
window.$docsify = {
|
||||
@@ -91,7 +91,7 @@ window.$docsify = {
|
||||
- 类型:`Boolean|String`
|
||||
- 默认值: `false`
|
||||
|
||||
加载自定义侧边栏,参考[多页文档](zh-cn/more-pages)。设置为 `true` 后会加载 `_sidebar.md` 文件,也可以自定义加载的文件名。
|
||||
加载自定义侧边栏,参考[多页文档](zh-cn/more-pages.md)。设置为 `true` 后会加载 `_sidebar.md` 文件,也可以自定义加载的文件名。
|
||||
|
||||
```js
|
||||
window.$docsify = {
|
||||
@@ -173,7 +173,7 @@ window.$docsify = {
|
||||
- 类型:`Boolean|String`
|
||||
- 默认值: `false`
|
||||
|
||||
启用[封面页](/zh-cn/cover)。开启后是加载 `_coverpage.md` 文件,也可以自定义文件名。
|
||||
启用[封面页](zh-cn/cover.md)。开启后是加载 `_coverpage.md` 文件,也可以自定义文件名。
|
||||
|
||||
```js
|
||||
window.$docsify = {
|
||||
@@ -220,7 +220,7 @@ window.$docsify = {
|
||||
|
||||
- 类型: `Object|Function`
|
||||
|
||||
参考 [Markdown 配置](/zh-cn/markdown)。
|
||||
参考 [Markdown 配置](zh-cn/markdown.md)。
|
||||
|
||||
```js
|
||||
window.$docsify = {
|
||||
@@ -287,7 +287,7 @@ window.$docsify = {
|
||||
|
||||
- 类型:`Boolean`
|
||||
|
||||
执行文档里的 script 标签里的脚本,只执行第一个 script ([demo](zh-cn/themes))。 如果 Vue 存在,则自动开启。
|
||||
执行文档里的 script 标签里的脚本,只执行第一个 script ([demo](zh-cn/themes.md))。 如果 Vue 存在,则自动开启。
|
||||
|
||||
```js
|
||||
window.$docsify = {
|
||||
@@ -304,7 +304,7 @@ window.$docsify = {
|
||||
|
||||
```
|
||||
|
||||
注意如果执行的是一个外链脚本,比如 jsfiddle 的内嵌 demo,请确保引入 [external-script](zh-cn/plugins?id=外链脚本-external-script) 插件。
|
||||
注意如果执行的是一个外链脚本,比如 jsfiddle 的内嵌 demo,请确保引入 [external-script](plugins.md?id=外链脚本-external-script) 插件。
|
||||
|
||||
## no-emoji
|
||||
|
||||
@@ -315,3 +315,38 @@ window.$docsify = {
|
||||
noEmoji: true
|
||||
}
|
||||
```
|
||||
|
||||
## merge-navbar
|
||||
|
||||
小屏设备下合并导航栏到侧边栏。
|
||||
|
||||
```js
|
||||
window.$docsify = {
|
||||
mergeNavbar: true
|
||||
}
|
||||
```
|
||||
|
||||
## format-updated
|
||||
我们可以显示文档更新日期通过 **{docsify-updated<span>}</span>** 变量. 并且格式化日期通过 `formatUpdated`.
|
||||
参考 https://github.com/lukeed/tinydate#patterns
|
||||
```js
|
||||
window.$docsify = {
|
||||
formatUpdated: '{MM}/{DD} {HH}:{mm}',
|
||||
|
||||
formatUpdated: function (time) {
|
||||
// ...
|
||||
|
||||
return time
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## external-link-target
|
||||
|
||||
Currently it defaults to _blank, would be nice if configurable:
|
||||
|
||||
```js
|
||||
window.$docsify = {
|
||||
externalLinkTarget: '_self' // default: '_blank'
|
||||
}
|
||||
```
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
# 封面
|
||||
|
||||
通过设置 `coverpage` 参数,可以开启渲染封面的功能。具体用法见[配置项#coverpage](zh-cn/configuration#coverpage)。
|
||||
通过设置 `coverpage` 参数,可以开启渲染封面的功能。具体用法见[配置项#coverpage](configuration.md#coverpage)。
|
||||
|
||||
## 基本用法
|
||||
|
||||
|
||||
+10
-10
@@ -17,7 +17,7 @@
|
||||
|
||||
## 配置文件
|
||||
|
||||
那我们可以通过 Markdown 文件来配置导航。首先配置 `loadNavbar`,默认加载的文件为 `_navbar.md`。具体配置规则见[配置项#load-navbar](zh-cn/configuration#load-navbar)。
|
||||
那我们可以通过 Markdown 文件来配置导航。首先配置 `loadNavbar`,默认加载的文件为 `_navbar.md`。具体配置规则见[配置项#load-navbar](configuration.md#load-navbar)。
|
||||
|
||||
*index.html*
|
||||
|
||||
@@ -49,17 +49,17 @@
|
||||
|
||||
```markdown
|
||||
- 基础
|
||||
- [快速开始](zh-cn/quickstart)
|
||||
- [多页文档](zh-cn/more-pages)
|
||||
- [定制导航栏](zh-cn/custom-navbar)
|
||||
- [封面](zh-cn/cover)
|
||||
- [快速开始](zh-cn/quickstart.md)
|
||||
- [多页文档](zh-cn/more-pages.md)
|
||||
- [定制导航栏](zh-cn/custom-navbar.md)
|
||||
- [封面](zh-cn/cover.md)
|
||||
|
||||
- 配置
|
||||
- [配置项](zh-cn/configuration)
|
||||
- [主题](zh-cn/themes)
|
||||
- [使用插件](zh-cn/plugins)
|
||||
- [Markdown 配置](zh-cn/markdown)
|
||||
- [代码高亮](zh-cn/language-highlight)
|
||||
- [配置项](zh-cn/configuration.md)
|
||||
- [主题](zh-cn/themes.md)
|
||||
- [使用插件](zh-cn/plugins.md)
|
||||
- [Markdown 配置](zh-cn/markdown.md)
|
||||
- [代码高亮](zh-cn/language-highlight.md)
|
||||
```
|
||||
|
||||
效果图
|
||||
|
||||
@@ -26,7 +26,7 @@ docs/zh-cn/guide.md => http://domain.com/zh-cn/guide
|
||||
|
||||
默认情况下,侧边栏会根据当前文档的标题生成目录。也可以设置文档链接,通过 Markdown 文件生成,效果如当前的文档的侧边栏。
|
||||
|
||||
首先配置 `loadSidebar` 选项,具体配置规则见[配置项#load-sidebar](zh-cn/configuration#load-sidebar)。
|
||||
首先配置 `loadSidebar` 选项,具体配置规则见[配置项#load-sidebar](configuration.md#load-sidebar)。
|
||||
|
||||
```html
|
||||
<script>
|
||||
@@ -63,4 +63,25 @@ docs/zh-cn/guide.md => http://domain.com/zh-cn/guide
|
||||
<script src="//unpkg.com/docsify"></script>
|
||||
```
|
||||
|
||||
## Ignoring Subheaders
|
||||
|
||||
When `subMaxLevel` is set, each header is automatically added to the table of contents by default. If you want to ignore a specific header, add `{docsify-ignore}` to it.
|
||||
|
||||
```markdown
|
||||
# Getting Started
|
||||
|
||||
## Header {docsify-ignore}
|
||||
This header won't appear in the sidebar table of contents.
|
||||
```
|
||||
|
||||
To ignore all headers on a specific page, you can use `{docsify-ignore-all}` on the first header of the page.
|
||||
|
||||
```markdown
|
||||
# Getting Started {docsify-ignore-all}
|
||||
|
||||
## Header
|
||||
This header won't appear in the sidebar table of contents.
|
||||
```
|
||||
|
||||
Both `{docsify-ignore}` and `{docsify-ignore-all}` will not be rendered on the page when used.
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ docsify init ./docs
|
||||
- `README.md` 会做为主页内容渲染
|
||||
- `.nojekyll` 用于阻止 GitHub Pages 会忽略掉下划线开头的文件
|
||||
|
||||
直接编辑 `docs/README.md` 就能更新网站内容,当然也可以[写多个页面](zh-cn/more-pages)。
|
||||
直接编辑 `docs/README.md` 就能更新网站内容,当然也可以[写多个页面](zh-cn/more-pages.md)。
|
||||
|
||||
## 本地预览网站
|
||||
|
||||
|
||||
@@ -0,0 +1,124 @@
|
||||
# Server client renderer
|
||||
|
||||
See https://docsify.now.sh
|
||||
|
||||
## Why SSR?
|
||||
- Better SEO
|
||||
- Feeling cool
|
||||
|
||||
## Quick start
|
||||
|
||||
Install `now` and `docsify-cli` in your project.
|
||||
|
||||
```bash
|
||||
npm i now -g
|
||||
npm i docsify-cli -D
|
||||
```
|
||||
|
||||
2. Edit `package.json`. If the documentation in `./docs` subdirectory.
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "my-project",
|
||||
"scripts": {
|
||||
"start": "docsify start ."
|
||||
},
|
||||
"files": [
|
||||
"docs"
|
||||
],
|
||||
"docsify": {
|
||||
"config": {
|
||||
"basePath": "/docs/",
|
||||
"loadSidebar": true,
|
||||
"loadNavbar": true,
|
||||
"coverpage": true,
|
||||
"name": "docsify"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
Remove `index.html`
|
||||
|
||||
!> The `basePath` just like webpack `publicPath`. You should config it if your docs is in the subdirectory.
|
||||
|
||||
We can preview in the local to see if it works.
|
||||
|
||||
```bash
|
||||
npm start
|
||||
|
||||
# open http://localhost:4000
|
||||
```
|
||||
|
||||
Publish it!
|
||||
|
||||
```bash
|
||||
now -p
|
||||
```
|
||||
|
||||
Now, You have a support for SSR the docs site.
|
||||
|
||||
## Custom template
|
||||
|
||||
You can provide a templte for entire page's HTML. such as
|
||||
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>docsify</title>
|
||||
<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/themes/vue.css" title="vue">
|
||||
</head>
|
||||
<body>
|
||||
<!--inject-app-->
|
||||
<!--inject-config-->
|
||||
</body>
|
||||
<script src="//unpkg.com/docsify/lib/docsify.js"></script>
|
||||
<script src="//unpkg.com/docsify/lib/plugins/search.js"></script>
|
||||
<script src="//unpkg.com/prismjs/components/prism-bash.min.js"></script>
|
||||
<script src="//unpkg.com/prismjs/components/prism-markdown.min.js"></script>
|
||||
<script src="//unpkg.com/prismjs/components/prism-nginx.min.js"></script>
|
||||
</html>
|
||||
```
|
||||
|
||||
The template should contain these comments for rendered app content.
|
||||
- `<!--inject-app-->`
|
||||
- `<!--inject-config-->`
|
||||
|
||||
## Configuration
|
||||
|
||||
You can configure it in a special config file, or `package.json`.
|
||||
|
||||
```js
|
||||
module.exports = {
|
||||
tempate: './ssr.html',
|
||||
config: {
|
||||
// docsify config
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Deploy for your VPS
|
||||
|
||||
You can run `docsify start` directly on your Node server, or write your own server app with `docsify-server-renderer`.
|
||||
|
||||
```js
|
||||
var Renderer = require('docsify-server-renderer')
|
||||
var readFileSync = require('fs').readFileSync
|
||||
|
||||
// init
|
||||
var renderer = new Renderer({
|
||||
template: readFileSync('./docs/index.template.html', 'utf-8').,
|
||||
config: {
|
||||
name: 'docsify',
|
||||
repo: 'qingwei-li/docsify'
|
||||
}
|
||||
})
|
||||
|
||||
renderer.renderToString(url)
|
||||
.then(html => {})
|
||||
.catch(err => {})
|
||||
```
|
||||
@@ -6,10 +6,18 @@
|
||||
<link rel="stylesheet" href="//unpkg.com/docsify/themes/vue.css">
|
||||
<link rel="stylesheet" href="//unpkg.com/docsify/themes/buble.css">
|
||||
<link rel="stylesheet" href="//unpkg.com/docsify/themes/dark.css">
|
||||
<link rel="stylesheet" href="//unpkg.com/docsify/themes/pure.css">
|
||||
```
|
||||
|
||||
!> CSS 的压缩文件位于 `/lib/themes/`
|
||||
|
||||
```html
|
||||
<link rel="stylesheet" href="//unpkg.com/docsify/lib/themes/vue.css">
|
||||
<link rel="stylesheet" href="//unpkg.com/docsify/lib/themes/buble.css">
|
||||
<link rel="stylesheet" href="//unpkg.com/docsify/lib/themes/dark.css">
|
||||
<link rel="stylesheet" href="//unpkg.com/docsify/lib/themes/pure.css">
|
||||
```
|
||||
|
||||
如果你有其他想法或者想开发别的主题,欢迎提 [PR](https://github.com/QingWei-Li/docsify/pulls)。
|
||||
|
||||
#### 点击切换主题
|
||||
@@ -19,6 +27,7 @@
|
||||
<a data-theme="vue">vue.css</a>
|
||||
<a data-theme="buble">buble.css</a>
|
||||
<a data-theme="dark">dark.css</a>
|
||||
<a data-theme="pure">pure.css</a>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
+803
-540
File diff suppressed because it is too large
Load Diff
Vendored
+2
-2
File diff suppressed because one or more lines are too long
Vendored
+1
-1
File diff suppressed because one or more lines are too long
@@ -4,15 +4,21 @@ this.D = this.D || {};
|
||||
|
||||
function handleExternalScript () {
|
||||
var container = Docsify.dom.getNode('#main');
|
||||
var script = Docsify.dom.find(container, 'script');
|
||||
var scripts = Docsify.dom.findAll(container, 'script');
|
||||
|
||||
if (script && script.src) {
|
||||
var newScript = document.createElement('script');['src', 'async', 'defer'].forEach(function (attribute) {
|
||||
newScript[attribute] = script[attribute];
|
||||
});
|
||||
for (var i = scripts.length; i--;) {
|
||||
var script = scripts[i];
|
||||
|
||||
script.parentNode.removeChild(script);
|
||||
container.appendChild(newScript);
|
||||
if (script && script.src) {
|
||||
var newScript = document.createElement('script');
|
||||
|
||||
Array.prototype.slice.call(script.attributes).forEach(function (attribute) {
|
||||
newScript[attribute.name] = attribute.value;
|
||||
});
|
||||
|
||||
script.parentNode.insertBefore(newScript, script);
|
||||
script.parentNode.removeChild(script);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Vendored
+1
-1
@@ -1 +1 @@
|
||||
this.D=this.D||{},function(){"use strict";function i(){var i=Docsify.dom.getNode("#main"),n=Docsify.dom.find(i,"script");if(n&&n.src){var c=document.createElement("script");["src","async","defer"].forEach(function(i){c[i]=n[i]}),n.parentNode.removeChild(n),i.appendChild(c)}}var n=function(n){n.doneEach(i)};window.$docsify.plugins=[].concat(n,window.$docsify.plugins)}();
|
||||
this.D=this.D||{},function(){"use strict";function e(){for(var e=Docsify.dom.getNode("#main"),i=Docsify.dom.findAll(e,"script"),o=i.length;o--;){var t=i[o];if(t&&t.src){var n=document.createElement("script");Array.prototype.slice.call(t.attributes).forEach(function(e){n[e.name]=e.value}),t.parentNode.insertBefore(n,t),t.parentNode.removeChild(t)}}}var i=function(i){i.doneEach(e)};window.$docsify.plugins=[].concat(i,window.$docsify.plugins)}();
|
||||
|
||||
Vendored
+1
-1
File diff suppressed because one or more lines are too long
+14
-10
@@ -11,24 +11,28 @@ function appendScript () {
|
||||
}
|
||||
|
||||
function init (id) {
|
||||
if (!window.ga) {
|
||||
var ga = window.ga;
|
||||
|
||||
if (!ga) {
|
||||
appendScript();
|
||||
window.ga = window.ga || function () {
|
||||
(window.ga.q = window.ga.q || []).push(arguments);
|
||||
ga = ga || function () {
|
||||
(ga.q = ga.q || []).push(arguments);
|
||||
};
|
||||
window.ga.l = Number(new Date());
|
||||
window.ga('create', id, 'auto');
|
||||
ga.l = Number(new Date());
|
||||
ga('create', id, 'auto');
|
||||
}
|
||||
return ga
|
||||
}
|
||||
|
||||
function collect () {
|
||||
init(window.$docsify.ga);
|
||||
window.ga('set', 'page', location.href);
|
||||
window.ga('send', 'pageview');
|
||||
var ga = init($docsify.ga);
|
||||
|
||||
ga('set', 'page', location.hash);
|
||||
ga('send', 'pageview');
|
||||
}
|
||||
|
||||
var install = function (hook) {
|
||||
if (!window.$docsify.ga) {
|
||||
if (!$docsify.ga) {
|
||||
console.error('[Docsify] ga is required.');
|
||||
return
|
||||
}
|
||||
@@ -36,6 +40,6 @@ var install = function (hook) {
|
||||
hook.beforeEach(collect);
|
||||
};
|
||||
|
||||
window.$docsify.plugins = [].concat(install, window.$docsify.plugins);
|
||||
$docsify.plugins = [].concat(install, $docsify.plugins);
|
||||
|
||||
}());
|
||||
|
||||
Vendored
+1
-1
@@ -1 +1 @@
|
||||
this.D=this.D||{},function(){"use strict";function n(){var n=document.createElement("script");n.async=!0,n.src="https://www.google-analytics.com/analytics.js",document.body.appendChild(n)}function o(o){window.ga||(n(),window.ga=window.ga||function(){(window.ga.q=window.ga.q||[]).push(arguments)},window.ga.l=Number(new Date),window.ga("create",o,"auto"))}function i(){o(window.$docsify.ga),window.ga("set","page",location.href),window.ga("send","pageview")}var w=function(n){return window.$docsify.ga?void n.beforeEach(i):void console.error("[Docsify] ga is required.")};window.$docsify.plugins=[].concat(w,window.$docsify.plugins)}();
|
||||
this.D=this.D||{},function(){"use strict";function n(){var n=document.createElement("script");n.async=!0,n.src="https://www.google-analytics.com/analytics.js",document.body.appendChild(n)}function c(c){var e=window.ga;return e||(n(),e=e||function(){(e.q=e.q||[]).push(arguments)},e.l=Number(new Date),e("create",c,"auto")),e}function e(){var n=c($docsify.ga);n("set","page",location.hash),n("send","pageview")}var i=function(n){if(!$docsify.ga)return void console.error("[Docsify] ga is required.");n.beforeEach(e)};$docsify.plugins=[].concat(i,$docsify.plugins)}();
|
||||
|
||||
+55
-49
@@ -18,18 +18,18 @@ function escapeHtml (string) {
|
||||
return String(string).replace(/[&<>"'\/]/g, function (s) { return entityMap[s]; })
|
||||
}
|
||||
|
||||
function getAllPaths () {
|
||||
function getAllPaths (router) {
|
||||
var paths = [];
|
||||
|
||||
helper.dom.findAll('a:not([data-nosearch])')
|
||||
.map(function (node) {
|
||||
var href = node.href;
|
||||
var originHref = node.getAttribute('href');
|
||||
var path = helper.route.parse(href).path;
|
||||
var path = router.parse(href).path;
|
||||
|
||||
if (path &&
|
||||
paths.indexOf(path) === -1 &&
|
||||
!helper.route.isAbsolutePath(originHref)) {
|
||||
!Docsify.util.isAbsolutePath(originHref)) {
|
||||
paths.push(path);
|
||||
}
|
||||
});
|
||||
@@ -42,18 +42,17 @@ function saveData (maxAge) {
|
||||
localStorage.setItem('docsify.search.index', JSON.stringify(INDEXS));
|
||||
}
|
||||
|
||||
function genIndex (path, content) {
|
||||
function genIndex (path, content, router) {
|
||||
if ( content === void 0 ) content = '';
|
||||
|
||||
var tokens = window.marked.lexer(content);
|
||||
var slugify = window.Docsify.slugify;
|
||||
var toURL = Docsify.route.toURL;
|
||||
var index = {};
|
||||
var slug;
|
||||
|
||||
tokens.forEach(function (token) {
|
||||
if (token.type === 'heading' && token.depth <= 2) {
|
||||
slug = toURL(path, { id: slugify(token.text) });
|
||||
slug = router.toURL(path, { id: slugify(token.text) });
|
||||
index[slug] = { slug: slug, title: token.text, body: '' };
|
||||
} else {
|
||||
if (!slug) { return }
|
||||
@@ -79,7 +78,7 @@ function search (keywords) {
|
||||
data = data.concat(Object.keys(INDEXS[key]).map(function (page) { return INDEXS[key][page]; }));
|
||||
});
|
||||
|
||||
keywords = keywords.trim().split(/[\s\-\,\\/]+/);
|
||||
keywords = [].concat(keywords, keywords.trim().split(/[\s\-\,\\/]+/));
|
||||
|
||||
var loop = function ( i ) {
|
||||
var post = data[i];
|
||||
@@ -153,7 +152,7 @@ function init$1 (config, vm) {
|
||||
return
|
||||
}
|
||||
|
||||
var paths = isAuto ? getAllPaths() : config.paths;
|
||||
var paths = isAuto ? getAllPaths(vm.router) : config.paths;
|
||||
var len = paths.length;
|
||||
var count = 0;
|
||||
|
||||
@@ -161,73 +160,78 @@ function init$1 (config, vm) {
|
||||
if (INDEXS[path]) { return count++ }
|
||||
|
||||
helper
|
||||
.get(vm.$getFile(path))
|
||||
.get(vm.router.getFile(path))
|
||||
.then(function (result) {
|
||||
INDEXS[path] = genIndex(path, result);
|
||||
INDEXS[path] = genIndex(path, result, vm.router);
|
||||
len === ++count && saveData(config.maxAge);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
var dom;
|
||||
var NO_DATA_TEXT = '';
|
||||
|
||||
function style () {
|
||||
var code = "\n.sidebar {\n padding-top: 0;\n}\n\n.search {\n margin-bottom: 20px;\n padding: 6px;\n border-bottom: 1px solid #eee;\n}\n\n.search .results-panel {\n display: none;\n}\n\n.search .results-panel.show {\n display: block;\n}\n\n.search input {\n outline: none;\n border: none;\n width: 100%;\n padding: 7px;\n line-height: 22px;\n font-size: 14px;\n}\n\n.search h2 {\n font-size: 17px;\n margin: 10px 0;\n}\n\n.search a {\n text-decoration: none;\n color: inherit;\n}\n\n.search .matching-post {\n border-bottom: 1px solid #eee;\n}\n\n.search .matching-post:last-child {\n border-bottom: 0;\n}\n\n.search p {\n font-size: 14px;\n overflow: hidden;\n text-overflow: ellipsis;\n display: -webkit-box;\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n}\n\n.search p.empty {\n text-align: center;\n}";
|
||||
var style = dom.create('style', code);
|
||||
dom.appendTo(dom.head, style);
|
||||
var code = "\n.sidebar {\n padding-top: 0;\n}\n\n.search {\n margin-bottom: 20px;\n padding: 6px;\n border-bottom: 1px solid #eee;\n}\n\n.search .results-panel {\n display: none;\n}\n\n.search .results-panel.show {\n display: block;\n}\n\n.search input {\n outline: none;\n border: none;\n width: 100%;\n padding: 7px;\n line-height: 22px;\n font-size: 14px;\n -webkit-appearance: none;\n -moz-appearance: none;\n appearance: none;\n}\n\n.search h2 {\n font-size: 17px;\n margin: 10px 0;\n}\n\n.search a {\n text-decoration: none;\n color: inherit;\n}\n\n.search .matching-post {\n border-bottom: 1px solid #eee;\n}\n\n.search .matching-post:last-child {\n border-bottom: 0;\n}\n\n.search p {\n font-size: 14px;\n overflow: hidden;\n text-overflow: ellipsis;\n display: -webkit-box;\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n}\n\n.search p.empty {\n text-align: center;\n}";
|
||||
var style = Docsify.dom.create('style', code);
|
||||
Docsify.dom.appendTo(Docsify.dom.head, style);
|
||||
}
|
||||
|
||||
function tpl (opts) {
|
||||
function tpl (opts, defaultValue) {
|
||||
if ( defaultValue === void 0 ) defaultValue = '';
|
||||
|
||||
var html =
|
||||
"<input type=\"search\" />" +
|
||||
"<input type=\"search\" value=\"" + defaultValue + "\" />" +
|
||||
'<div class="results-panel"></div>' +
|
||||
'</div>';
|
||||
var el = dom.create('div', html);
|
||||
var aside = dom.find('aside');
|
||||
var el = Docsify.dom.create('div', html);
|
||||
var aside = Docsify.dom.find('aside');
|
||||
|
||||
dom.toggleClass(el, 'search');
|
||||
dom.before(aside, el);
|
||||
Docsify.dom.toggleClass(el, 'search');
|
||||
Docsify.dom.before(aside, el);
|
||||
}
|
||||
|
||||
function doSearch (value) {
|
||||
var $search = Docsify.dom.find('div.search');
|
||||
var $panel = Docsify.dom.find($search, '.results-panel');
|
||||
|
||||
if (!value) {
|
||||
$panel.classList.remove('show');
|
||||
$panel.innerHTML = '';
|
||||
return
|
||||
}
|
||||
var matchs = search(value);
|
||||
|
||||
var html = '';
|
||||
matchs.forEach(function (post) {
|
||||
html += "<div class=\"matching-post\">\n<h2><a href=\"" + (post.url) + "\">" + (post.title) + "</a></h2>\n<p>" + (post.content) + "</p>\n</div>";
|
||||
});
|
||||
|
||||
$panel.classList.add('show');
|
||||
$panel.innerHTML = html || ("<p class=\"empty\">" + NO_DATA_TEXT + "</p>");
|
||||
}
|
||||
|
||||
function bindEvents () {
|
||||
var $search = dom.find('div.search');
|
||||
var $input = dom.find($search, 'input');
|
||||
var $panel = dom.find($search, '.results-panel');
|
||||
var doSearch = function (value) {
|
||||
if (!value) {
|
||||
$panel.classList.remove('show');
|
||||
$panel.innerHTML = '';
|
||||
return
|
||||
}
|
||||
var matchs = search(value);
|
||||
|
||||
var html = '';
|
||||
matchs.forEach(function (post) {
|
||||
html += "<div class=\"matching-post\">\n <h2><a href=\"" + (post.url) + "\">" + (post.title) + "</a></h2>\n <p>" + (post.content) + "</p>\n</div>";
|
||||
});
|
||||
|
||||
$panel.classList.add('show');
|
||||
$panel.innerHTML = html || ("<p class=\"empty\">" + NO_DATA_TEXT + "</p>");
|
||||
};
|
||||
var $search = Docsify.dom.find('div.search');
|
||||
var $input = Docsify.dom.find($search, 'input');
|
||||
|
||||
var timeId;
|
||||
// Prevent to Fold sidebar
|
||||
dom.on($search, 'click',
|
||||
Docsify.dom.on($search, 'click',
|
||||
function (e) { return e.target.tagName !== 'A' && e.stopPropagation(); });
|
||||
dom.on($input, 'input', function (e) {
|
||||
Docsify.dom.on($input, 'input', function (e) {
|
||||
clearTimeout(timeId);
|
||||
timeId = setTimeout(function (_) { return doSearch(e.target.value.trim()); }, 100);
|
||||
});
|
||||
}
|
||||
|
||||
function updatePlaceholder (text, path) {
|
||||
var $input = dom.getNode('.search input[type="search"]');
|
||||
var $input = Docsify.dom.getNode('.search input[type="search"]');
|
||||
|
||||
if (!$input) { return }
|
||||
if (typeof text === 'string') {
|
||||
$input.placeholder = text;
|
||||
} else {
|
||||
var match = Object.keys(text).find(function (key) { return path.indexOf(key) > -1; });
|
||||
var match = Object.keys(text).filter(function (key) { return path.indexOf(key) > -1; })[0];
|
||||
$input.placeholder = text[match];
|
||||
}
|
||||
}
|
||||
@@ -236,16 +240,18 @@ function updateNoData (text, path) {
|
||||
if (typeof text === 'string') {
|
||||
NO_DATA_TEXT = text;
|
||||
} else {
|
||||
var match = Object.keys(text).find(function (key) { return path.indexOf(key) > -1; });
|
||||
var match = Object.keys(text).filter(function (key) { return path.indexOf(key) > -1; })[0];
|
||||
NO_DATA_TEXT = text[match];
|
||||
}
|
||||
}
|
||||
|
||||
function init$$1 (opts) {
|
||||
dom = Docsify.dom;
|
||||
function init$$1 (opts, vm) {
|
||||
var keywords = vm.router.parse().query.s;
|
||||
|
||||
style();
|
||||
tpl(opts);
|
||||
tpl(opts, keywords);
|
||||
bindEvents();
|
||||
keywords && setTimeout(function (_) { return doSearch(keywords); }, 500);
|
||||
}
|
||||
|
||||
function update (opts, vm) {
|
||||
@@ -276,7 +282,7 @@ var install = function (hook, vm) {
|
||||
var isAuto = CONFIG.paths === 'auto';
|
||||
|
||||
hook.mounted(function (_) {
|
||||
init$$1(CONFIG);
|
||||
init$$1(CONFIG, vm);
|
||||
!isAuto && init$1(CONFIG, vm);
|
||||
});
|
||||
hook.doneEach(function (_) {
|
||||
@@ -285,6 +291,6 @@ var install = function (hook, vm) {
|
||||
});
|
||||
};
|
||||
|
||||
window.$docsify.plugins = [].concat(install, window.$docsify.plugins);
|
||||
$docsify.plugins = [].concat(install, $docsify.plugins);
|
||||
|
||||
}());
|
||||
|
||||
Vendored
+1
-1
@@ -1 +1 @@
|
||||
this.D=this.D||{},function(){"use strict";function e(e){var n={"&":"&","<":"<",">":">",'"':""","'":"'","/":"/"};return String(e).replace(/[&<>"'\/]/g,function(e){return n[e]})}function n(){var e=[];return d.dom.findAll("a:not([data-nosearch])").map(function(n){var t=n.href,o=n.getAttribute("href"),a=d.route.parse(t).path;a&&e.indexOf(a)===-1&&!d.route.isAbsolutePath(o)&&e.push(a)}),e}function t(e){localStorage.setItem("docsify.search.expires",Date.now()+e),localStorage.setItem("docsify.search.index",JSON.stringify(g))}function o(e,n){void 0===n&&(n="");var t,o=window.marked.lexer(n),a=window.Docsify.slugify,i=Docsify.route.toURL,r={};return o.forEach(function(n){if("heading"===n.type&&n.depth<=2)t=i(e,{id:a(n.text)}),r[t]={slug:t,title:n.text,body:""};else{if(!t)return;r[t]?r[t].body?r[t].body+="\n"+(n.text||""):r[t].body=n.text:r[t]={slug:t,title:"",body:""}}}),a.clear(),r}function a(n){var t=[],o=[];Object.keys(g).forEach(function(e){o=o.concat(Object.keys(g[e]).map(function(n){return g[e][n]}))}),n=n.trim().split(/[\s\-\,\\\/]+/);for(var a=function(a){var i=o[a],r=!1,s="",c=i.title&&i.title.trim(),l=i.body&&i.body.trim(),u=i.slug||"";if(c&&l&&(n.forEach(function(n,t){var o=new RegExp(n,"gi"),a=-1,i=-1;if(a=c&&c.search(o),i=l&&l.search(o),a<0&&i<0)r=!1;else{r=!0,i<0&&(i=0);var u=0,f=0;u=i<11?0:i-10,f=0===u?70:i+n.length+60,f>l.length&&(f=l.length);var p="..."+e(l).substring(u,f).replace(o,'<em class="search-keyword">'+n+"</em>")+"...";s+=p}}),r)){var f={title:e(c),content:s,url:u};t.push(f)}},i=0;i<o.length;i++)a(i);return t}function i(e,a){d=Docsify;var i="auto"===e.paths,r=localStorage.getItem("docsify.search.expires")<Date.now();if(g=JSON.parse(localStorage.getItem("docsify.search.index")),r)g={};else if(!i)return;var s=i?n():e.paths,c=s.length,l=0;s.forEach(function(n){return g[n]?l++:void d.get(a.$getFile(n)).then(function(a){g[n]=o(n,a),c===++l&&t(e.maxAge)})})}function r(){var e="\n.sidebar {\n padding-top: 0;\n}\n\n.search {\n margin-bottom: 20px;\n padding: 6px;\n border-bottom: 1px solid #eee;\n}\n\n.search .results-panel {\n display: none;\n}\n\n.search .results-panel.show {\n display: block;\n}\n\n.search input {\n outline: none;\n border: none;\n width: 100%;\n padding: 7px;\n line-height: 22px;\n font-size: 14px;\n}\n\n.search h2 {\n font-size: 17px;\n margin: 10px 0;\n}\n\n.search a {\n text-decoration: none;\n color: inherit;\n}\n\n.search .matching-post {\n border-bottom: 1px solid #eee;\n}\n\n.search .matching-post:last-child {\n border-bottom: 0;\n}\n\n.search p {\n font-size: 14px;\n overflow: hidden;\n text-overflow: ellipsis;\n display: -webkit-box;\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n}\n\n.search p.empty {\n text-align: center;\n}",n=h.create("style",e);h.appendTo(h.head,n)}function s(e){var n='<input type="search" /><div class="results-panel"></div></div>',t=h.create("div",n),o=h.find("aside");h.toggleClass(t,"search"),h.before(o,t)}function c(){var e,n=h.find("div.search"),t=h.find(n,"input"),o=h.find(n,".results-panel"),i=function(e){if(!e)return o.classList.remove("show"),void(o.innerHTML="");var n=a(e),t="";n.forEach(function(e){t+='<div class="matching-post">\n <h2><a href="'+e.url+'">'+e.title+"</a></h2>\n <p>"+e.content+"</p>\n</div>"}),o.classList.add("show"),o.innerHTML=t||'<p class="empty">'+y+"</p>"};h.on(n,"click",function(e){return"A"!==e.target.tagName&&e.stopPropagation()}),h.on(t,"input",function(n){clearTimeout(e),e=setTimeout(function(e){return i(n.target.value.trim())},100)})}function l(e,n){var t=h.getNode('.search input[type="search"]');if("string"==typeof e)t.placeholder=e;else{var o=Object.keys(e).find(function(e){return n.indexOf(e)>-1});t.placeholder=e[o]}}function u(e,n){if("string"==typeof e)y=e;else{var t=Object.keys(e).find(function(e){return n.indexOf(e)>-1});y=e[t]}}function f(e){h=Docsify.dom,r(),s(e),c()}function p(e,n){l(e.placeholder,n.route.path),u(e.noData,n.route.path)}var d,h,g={},y="",m={placeholder:"Type to search",noData:"No Results!",paths:"auto",maxAge:864e5},v=function(e,n){var t=Docsify.util,o=n.config.search||m;Array.isArray(o)?m.paths=o:"object"==typeof o&&(m.paths=Array.isArray(o.paths)?o.paths:"auto",m.maxAge=t.isPrimitive(o.maxAge)?o.maxAge:m.maxAge,m.placeholder=o.placeholder||m.placeholder,m.noData=o.noData||m.noData);var a="auto"===m.paths;e.mounted(function(e){f(m),!a&&i(m,n)}),e.doneEach(function(e){p(m,n),a&&i(m,n)})};window.$docsify.plugins=[].concat(v,window.$docsify.plugins)}();
|
||||
this.D=this.D||{},function(){"use strict";function e(e){var n={"&":"&","<":"<",">":">",'"':""","'":"'","/":"/"};return String(e).replace(/[&<>"'\/]/g,function(e){return n[e]})}function n(e){var n=[];return h.dom.findAll("a:not([data-nosearch])").map(function(t){var o=t.href,i=t.getAttribute("href"),r=e.parse(o).path;r&&-1===n.indexOf(r)&&!Docsify.util.isAbsolutePath(i)&&n.push(r)}),n}function t(e){localStorage.setItem("docsify.search.expires",Date.now()+e),localStorage.setItem("docsify.search.index",JSON.stringify(y))}function o(e,n,t){void 0===n&&(n="");var o,i=window.marked.lexer(n),r=window.Docsify.slugify,a={};return i.forEach(function(n){if("heading"===n.type&&n.depth<=2)o=t.toURL(e,{id:r(n.text)}),a[o]={slug:o,title:n.text,body:""};else{if(!o)return;a[o]?a[o].body?a[o].body+="\n"+(n.text||""):a[o].body=n.text:a[o]={slug:o,title:"",body:""}}}),r.clear(),a}function i(n){var t=[],o=[];Object.keys(y).forEach(function(e){o=o.concat(Object.keys(y[e]).map(function(n){return y[e][n]}))}),n=[].concat(n,n.trim().split(/[\s\-\,\\\/]+/));for(var i=0;i<o.length;i++)!function(i){var r=o[i],a=!1,s="",c=r.title&&r.title.trim(),f=r.body&&r.body.trim(),l=r.slug||"";if(c&&f&&(n.forEach(function(n,t){var o=new RegExp(n,"gi"),i=-1,r=-1;if(i=c&&c.search(o),r=f&&f.search(o),i<0&&r<0)a=!1;else{a=!0,r<0&&(r=0);var l=0,d=0;l=r<11?0:r-10,d=0===l?70:r+n.length+60,d>f.length&&(d=f.length);var u="..."+e(f).substring(l,d).replace(o,'<em class="search-keyword">'+n+"</em>")+"...";s+=u}}),a)){var d={title:e(c),content:s,url:l};t.push(d)}}(i);return t}function r(e,i){h=Docsify;var r="auto"===e.paths,a=localStorage.getItem("docsify.search.expires")<Date.now();if(y=JSON.parse(localStorage.getItem("docsify.search.index")),a)y={};else if(!r)return;var s=r?n(i.router):e.paths,c=s.length,f=0;s.forEach(function(n){if(y[n])return f++;h.get(i.router.getFile(n)).then(function(r){y[n]=o(n,r,i.router),c===++f&&t(e.maxAge)})})}function a(){var e=Docsify.dom.create("style","\n.sidebar {\n padding-top: 0;\n}\n\n.search {\n margin-bottom: 20px;\n padding: 6px;\n border-bottom: 1px solid #eee;\n}\n\n.search .results-panel {\n display: none;\n}\n\n.search .results-panel.show {\n display: block;\n}\n\n.search input {\n outline: none;\n border: none;\n width: 100%;\n padding: 7px;\n line-height: 22px;\n font-size: 14px;\n -webkit-appearance: none;\n -moz-appearance: none;\n appearance: none;\n}\n\n.search h2 {\n font-size: 17px;\n margin: 10px 0;\n}\n\n.search a {\n text-decoration: none;\n color: inherit;\n}\n\n.search .matching-post {\n border-bottom: 1px solid #eee;\n}\n\n.search .matching-post:last-child {\n border-bottom: 0;\n}\n\n.search p {\n font-size: 14px;\n overflow: hidden;\n text-overflow: ellipsis;\n display: -webkit-box;\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n}\n\n.search p.empty {\n text-align: center;\n}");Docsify.dom.appendTo(Docsify.dom.head,e)}function s(e,n){void 0===n&&(n="");var t='<input type="search" value="'+n+'" /><div class="results-panel"></div></div>',o=Docsify.dom.create("div",t),i=Docsify.dom.find("aside");Docsify.dom.toggleClass(o,"search"),Docsify.dom.before(i,o)}function c(e){var n=Docsify.dom.find("div.search"),t=Docsify.dom.find(n,".results-panel");if(!e)return t.classList.remove("show"),void(t.innerHTML="");var o=i(e),r="";o.forEach(function(e){r+='<div class="matching-post">\n<h2><a href="'+e.url+'">'+e.title+"</a></h2>\n<p>"+e.content+"</p>\n</div>"}),t.classList.add("show"),t.innerHTML=r||'<p class="empty">'+m+"</p>"}function f(){var e,n=Docsify.dom.find("div.search"),t=Docsify.dom.find(n,"input");Docsify.dom.on(n,"click",function(e){return"A"!==e.target.tagName&&e.stopPropagation()}),Docsify.dom.on(t,"input",function(n){clearTimeout(e),e=setTimeout(function(e){return c(n.target.value.trim())},100)})}function l(e,n){var t=Docsify.dom.getNode('.search input[type="search"]');if(t)if("string"==typeof e)t.placeholder=e;else{var o=Object.keys(e).filter(function(e){return n.indexOf(e)>-1})[0];t.placeholder=e[o]}}function d(e,n){if("string"==typeof e)m=e;else{var t=Object.keys(e).filter(function(e){return n.indexOf(e)>-1})[0];m=e[t]}}function u(e,n){var t=n.router.parse().query.s;a(),s(e,t),f(),t&&setTimeout(function(e){return c(t)},500)}function p(e,n){l(e.placeholder,n.route.path),d(e.noData,n.route.path)}var h,y={},m="",g={placeholder:"Type to search",noData:"No Results!",paths:"auto",maxAge:864e5},v=function(e,n){var t=Docsify.util,o=n.config.search||g;Array.isArray(o)?g.paths=o:"object"==typeof o&&(g.paths=Array.isArray(o.paths)?o.paths:"auto",g.maxAge=t.isPrimitive(o.maxAge)?o.maxAge:g.maxAge,g.placeholder=o.placeholder||g.placeholder,g.noData=o.noData||g.noData);var i="auto"===g.paths;e.mounted(function(e){u(g,n),!i&&r(g,n)}),e.doneEach(function(e){p(g,n),i&&r(g,n)})};$docsify.plugins=[].concat(v,$docsify.plugins)}();
|
||||
|
||||
Vendored
+1
-1
@@ -1 +1 @@
|
||||
this.D=this.D||{},function(){"use strict";function t(t,e){return e={exports:{}},t(e,e.exports),e.exports}function e(t){var e,n=Docsify.dom;n.appendTo(n.head,n.create("style",i)),t.doneEach(function(t){var i=n.findAll("img:not(.emoji)");Array.isArray(e)&&e.length&&(e.forEach(function(t){return t()}),e=[]),e=i.map(o)})}var n="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{},o=t(function(t,e){!function(e,n){t.exports=n()}(n,function(){function t(){g===-1&&(g=window.pageYOffset);var t=Math.abs(g-window.pageYOffset);t>=40&&a()}function e(t){27===t.keyCode&&a()}function n(t){var e=t.touches[0];null!==e&&(y=e.pageY,t.target.addEventListener("touchmove",o))}function o(t){var e=t.touches[0];null!==e&&Math.abs(e.pageY-y)>10&&(a(),t.target.removeEventListener("touchmove",o))}function i(){a()}function r(){document.addEventListener("scroll",t),document.addEventListener("keyup",e),document.addEventListener("touchstart",n),document.addEventListener("click",i,!0)}function s(){document.removeEventListener("scroll",t),document.removeEventListener("keyup",e),document.removeEventListener("touchstart",n),document.removeEventListener("click",i,!0)}function a(t){null!==h&&(t?h.dispose():h.close(),s(),h=null)}function c(t){if(!document.body.classList.contains("zoom-overlay-open"))return t.metaKey||t.ctrlKey?void window.open(t.target.getAttribute("data-original")||t.target.src,"_blank"):void(t.target.width>=m()-v||(a(!0),h=new p(t.target,v),h.zoom(),r()))}var m=function(){return document.documentElement.clientWidth},u=function(){return document.documentElement.clientHeight},d=function(t){var e=t.getBoundingClientRect(),n=document.documentElement,o=window;return{top:e.top+o.pageYOffset-n.clientTop,left:e.left+o.pageXOffset-n.clientLeft}},l=function(t,e,n){var o=function(t){t.target.removeEventListener(e,o),n()};t.addEventListener(e,o)},f=function(t,e){this.w=t,this.h=e},p=function(t,e){this.img=t,this.preservedTransform=t.style.transform,this.wrap=null,this.overlay=null,this.offset=e};p.prototype.forceRepaint=function(){this.img.offsetWidth},p.prototype.zoom=function(){var t=new f(this.img.naturalWidth,this.img.naturalHeight);this.wrap=document.createElement("div"),this.wrap.classList.add("zoom-img-wrap"),this.img.parentNode.insertBefore(this.wrap,this.img),this.wrap.appendChild(this.img),this.img.classList.add("zoom-img"),this.img.setAttribute("data-action","zoom-out"),this.overlay=document.createElement("div"),this.overlay.classList.add("zoom-overlay"),document.body.appendChild(this.overlay),this.forceRepaint();var e=this.calculateScale(t);this.forceRepaint(),this.animate(e),document.body.classList.add("zoom-overlay-open")},p.prototype.calculateScale=function(t){var e=t.w/this.img.width,n=m()-this.offset,o=u()-this.offset,i=t.w/t.h,r=n/o;return t.w<n&&t.h<o?e:i<r?o/t.h*e:n/t.w*e},p.prototype.animate=function(t){var e=d(this.img),n=window.pageYOffset,o=m()/2,i=n+u()/2,r=e.left+this.img.width/2,s=e.top+this.img.height/2,a=o-r,c=i-s,l=0,f="scale("+t+")",p="translate3d("+a+"px, "+c+"px, "+l+"px)";this.img.style.transform=f,this.wrap.style.transform=p},p.prototype.dispose=function(){null!==this.wrap&&null!==this.wrap.parentNode&&(this.img.classList.remove("zoom-img"),this.img.setAttribute("data-action","zoom"),this.wrap.parentNode.insertBefore(this.img,this.wrap),this.wrap.parentNode.removeChild(this.wrap),document.body.removeChild(this.overlay),document.body.classList.remove("zoom-overlay-transitioning"))},p.prototype.close=function(){var t=this;document.body.classList.add("zoom-overlay-transitioning"),this.img.style.transform=this.preservedTransform,0===this.img.style.length&&this.img.removeAttribute("style"),this.wrap.style.transform="none",l(this.img,"transitionend",function(){t.dispose(),document.body.classList.remove("zoom-overlay-open")})};var h=null,v=80,g=-1,y=-1,w=function(t){return t.setAttribute("data-action","zoom"),t.addEventListener("click",c),function(){return t.removeEventListener("click",c)}};return w})}),i='img[data-action="zoom"] {\n cursor: pointer;\n cursor: -webkit-zoom-in;\n cursor: zoom-in;\n}\n.zoom-img,\n.zoom-img-wrap {\n position: relative;\n z-index: 666;\n transition: -webkit-transform 300ms cubic-bezier(.2,0,.2,1);\n transition: transform 300ms cubic-bezier(.2,0,.2,1);\n transition: transform 300ms cubic-bezier(.2,0,.2,1), -webkit-transform 300ms cubic-bezier(.2,0,.2,1);\n}\n.zoom-overlay {\n z-index: 420;\n background: #fff;\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n pointer-events: none;\n opacity: 0;\n transition: opacity 300ms;\n}\n.zoom-overlay-open .zoom-overlay {\n opacity: 1;\n}\n.zoom-overlay-open {\n cursor: pointer;\n cursor: -webkit-zoom-out;\n cursor: zoom-out;\n}\n.zoom-overlay-transitioning {\n cursor: default;\n}\n.zoom-overlay-open.zoom-overlay-transitioning .zoom-overlay{\n opacity: 0;\n}\n';$docsify.plugins=[].concat(e,$docsify.plugins)}();
|
||||
this.D=this.D||{},function(){"use strict";function t(t){var o,i=Docsify.dom;i.appendTo(i.head,i.create("style",n)),t.doneEach(function(t){var n=i.findAll("img:not(.emoji)");Array.isArray(o)&&o.length&&(o.forEach(function(t){return t()}),o=[]),o=n.map(e)})}var e=("undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self&&self,function(t,e){return e={exports:{}},t(e,e.exports),e.exports}(function(t,e){!function(e,n){t.exports=function(){function t(){-1===g&&(g=window.pageYOffset),Math.abs(g-window.pageYOffset)>=40&&a()}function e(t){27===t.keyCode&&a()}function n(t){var e=t.touches[0];null!==e&&(y=e.pageY,t.target.addEventListener("touchmove",o))}function o(t){var e=t.touches[0];null!==e&&Math.abs(e.pageY-y)>10&&(a(),t.target.removeEventListener("touchmove",o))}function i(){a()}function r(){document.addEventListener("scroll",t),document.addEventListener("keyup",e),document.addEventListener("touchstart",n),document.addEventListener("click",i,!0)}function s(){document.removeEventListener("scroll",t),document.removeEventListener("keyup",e),document.removeEventListener("touchstart",n),document.removeEventListener("click",i,!0)}function a(t){null!==h&&(t?h.dispose():h.close(),s(),h=null)}function c(t){if(!document.body.classList.contains("zoom-overlay-open"))return t.metaKey||t.ctrlKey?void window.open(t.target.getAttribute("data-original")||t.target.src,"_blank"):void(t.target.width>=m()-v||(a(!0),h=new p(t.target,v),h.zoom(),r()))}var m=function(){return document.documentElement.clientWidth},u=function(){return document.documentElement.clientHeight},d=function(t){var e=t.getBoundingClientRect(),n=document.documentElement,o=window;return{top:e.top+o.pageYOffset-n.clientTop,left:e.left+o.pageXOffset-n.clientLeft}},l=function(t,e,n){var o=function(t){t.target.removeEventListener(e,o),n()};t.addEventListener(e,o)},f=function(t,e){this.w=t,this.h=e},p=function(t,e){this.img=t,this.preservedTransform=t.style.transform,this.wrap=null,this.overlay=null,this.offset=e};p.prototype.forceRepaint=function(){this.img.offsetWidth},p.prototype.zoom=function(){var t=new f(this.img.naturalWidth,this.img.naturalHeight);this.wrap=document.createElement("div"),this.wrap.classList.add("zoom-img-wrap"),this.img.parentNode.insertBefore(this.wrap,this.img),this.wrap.appendChild(this.img),this.img.classList.add("zoom-img"),this.img.setAttribute("data-action","zoom-out"),this.overlay=document.createElement("div"),this.overlay.classList.add("zoom-overlay"),document.body.appendChild(this.overlay),this.forceRepaint();var e=this.calculateScale(t);this.forceRepaint(),this.animate(e),document.body.classList.add("zoom-overlay-open")},p.prototype.calculateScale=function(t){var e=t.w/this.img.width,n=m()-this.offset,o=u()-this.offset,i=t.w/t.h,r=n/o;return t.w<n&&t.h<o?e:i<r?o/t.h*e:n/t.w*e},p.prototype.animate=function(t){var e=d(this.img),n=window.pageYOffset,o=m()/2,i=n+u()/2,r=e.left+this.img.width/2,s=e.top+this.img.height/2,a=o-r,c=i-s,l="scale("+t+")",f="translate3d("+a+"px, "+c+"px, 0px)";this.img.style.transform=l,this.wrap.style.transform=f},p.prototype.dispose=function(){null!==this.wrap&&null!==this.wrap.parentNode&&(this.img.classList.remove("zoom-img"),this.img.setAttribute("data-action","zoom"),this.wrap.parentNode.insertBefore(this.img,this.wrap),this.wrap.parentNode.removeChild(this.wrap),document.body.removeChild(this.overlay),document.body.classList.remove("zoom-overlay-transitioning"))},p.prototype.close=function(){var t=this;document.body.classList.add("zoom-overlay-transitioning"),this.img.style.transform=this.preservedTransform,0===this.img.style.length&&this.img.removeAttribute("style"),this.wrap.style.transform="none",l(this.img,"transitionend",function(){t.dispose(),document.body.classList.remove("zoom-overlay-open")})};var h=null,v=80,g=-1,y=-1;return function(t){return t.setAttribute("data-action","zoom"),t.addEventListener("click",c),function(){return t.removeEventListener("click",c)}}}()}()})),n='img[data-action="zoom"] {\n cursor: pointer;\n cursor: -webkit-zoom-in;\n cursor: zoom-in;\n}\n.zoom-img,\n.zoom-img-wrap {\n position: relative;\n z-index: 666;\n transition: -webkit-transform 300ms cubic-bezier(.2,0,.2,1);\n transition: transform 300ms cubic-bezier(.2,0,.2,1);\n transition: transform 300ms cubic-bezier(.2,0,.2,1), -webkit-transform 300ms cubic-bezier(.2,0,.2,1);\n}\n.zoom-overlay {\n z-index: 420;\n background: #fff;\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n pointer-events: none;\n opacity: 0;\n transition: opacity 300ms;\n}\n.zoom-overlay-open .zoom-overlay {\n opacity: 1;\n}\n.zoom-overlay-open {\n cursor: pointer;\n cursor: -webkit-zoom-out;\n cursor: zoom-out;\n}\n.zoom-overlay-transitioning {\n cursor: default;\n}\n.zoom-overlay-open.zoom-overlay-transitioning .zoom-overlay{\n opacity: 0;\n}\n';$docsify.plugins=[].concat(t,$docsify.plugins)}();
|
||||
|
||||
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
+42
-33
@@ -1,7 +1,18 @@
|
||||
{
|
||||
"name": "docsify",
|
||||
"version": "3.4.2",
|
||||
"version": "4.1.3",
|
||||
"description": "A magical documentation generator.",
|
||||
"author": {
|
||||
"name": "qingwei-li",
|
||||
"email": "cinwell.li@gmail.com",
|
||||
"url": "https://github.com/QingWei-Li"
|
||||
},
|
||||
"homepage": "https://docsify.js.org",
|
||||
"license": "MIT",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/QingWei-Li/docsify.git"
|
||||
},
|
||||
"main": "lib/docsify.js",
|
||||
"files": [
|
||||
"lib",
|
||||
@@ -9,14 +20,36 @@
|
||||
"themes"
|
||||
],
|
||||
"scripts": {
|
||||
"build": "rm -rf lib themes && node build/build.js && mkdir lib/themes && mkdir themes && node build/build-css.js",
|
||||
"dev:build": "rm -rf lib themes && mkdir themes && node build/build.js --dev && node build/build-css.js --dev",
|
||||
"dev": "node app.js & nodemon -w src -e js,css --exec 'npm run dev:build'",
|
||||
"test": "eslint src"
|
||||
"build": "rm -rf lib themes && node build/build && mkdir lib/themes && mkdir themes && node build/build-css && npm run build:ssr",
|
||||
"dev:build": "rm -rf lib themes && mkdir themes && node build/build --dev && node build/build-css --dev",
|
||||
"dev": "node app & nodemon -w src -e js,css --exec 'npm run dev:build'",
|
||||
"build:ssr": "node build/build-ssr",
|
||||
"test": "eslint {src,packages} --fix",
|
||||
"pub:next": "RELEASE_TAG=next sh build/release.sh",
|
||||
"pub": "sh build/release.sh"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/QingWei-Li/docsify.git"
|
||||
"dependencies": {
|
||||
"marked": "^0.3.6",
|
||||
"prismjs": "^1.6.0",
|
||||
"tinydate": "^1.0.0",
|
||||
"zoom-image": "^0.1.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"cssnano": "^3.10.0",
|
||||
"eslint": "^3.18.0",
|
||||
"eslint-config-vue": "^2.0.2",
|
||||
"eslint-plugin-vue": "^2.0.1",
|
||||
"nodemon": "^1.11.0",
|
||||
"postcss": "^5.2.16",
|
||||
"postcss-salad": "^1.0.8",
|
||||
"rollup": "^0.41.6",
|
||||
"rollup-plugin-async": "^1.2.0",
|
||||
"rollup-plugin-buble": "^0.15.0",
|
||||
"rollup-plugin-commonjs": "^8.0.2",
|
||||
"rollup-plugin-node-resolve": "^2.0.0",
|
||||
"rollup-plugin-string": "^2.0.2",
|
||||
"rollup-plugin-uglify": "^1.0.1",
|
||||
"serve-static": "^1.12.1"
|
||||
},
|
||||
"keywords": [
|
||||
"doc",
|
||||
@@ -24,29 +57,5 @@
|
||||
"documentation",
|
||||
"creator",
|
||||
"generator"
|
||||
],
|
||||
"author": "qingwei-li <cinwell.li@gmail.com> (https://github.com/QingWei-Li)",
|
||||
"homepage": "https://docsify.js.org",
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"cssnano": "^3.8.1",
|
||||
"eslint": "^3.10.2",
|
||||
"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.41.1",
|
||||
"rollup-plugin-buble": "^0.15.0",
|
||||
"rollup-plugin-commonjs": "^7.0.0",
|
||||
"rollup-plugin-node-resolve": "^2.0.0",
|
||||
"rollup-plugin-string": "^2.0.2",
|
||||
"rollup-plugin-uglify": "^1.0.1",
|
||||
"serve-static": "^1.11.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"marked": "^0.3.6",
|
||||
"prismjs": "^1.5.1",
|
||||
"zoom-image": "^0.1.4"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
build.js
|
||||
node_modules
|
||||
*.log
|
||||
.git
|
||||
@@ -0,0 +1,46 @@
|
||||
# docsify-server-renderer
|
||||
|
||||
## Install
|
||||
|
||||
```bash
|
||||
yarn add docsify-server-render
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
```js
|
||||
var Renderer = require('docsify-server-renderer')
|
||||
var readFileSync = require('fs').readFileSync
|
||||
|
||||
// init
|
||||
var renderer = new Renderer({
|
||||
template: readFileSync('./docs/index.template.html', 'utf-8').,
|
||||
config: {
|
||||
name: 'docsify',
|
||||
repo: 'qingwei-li/docsify'
|
||||
}
|
||||
})
|
||||
|
||||
renderer.renderToString(url)
|
||||
.then(html => {})
|
||||
.catch(err => {})
|
||||
```
|
||||
|
||||
*index.template.html*
|
||||
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>docsify</title>
|
||||
<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/themes/buble.css" title="buble" disabled>
|
||||
</head>
|
||||
<body>
|
||||
<!--inject-app-->
|
||||
<!--inject-config-->
|
||||
<script src="//unpkg.com/docsify/lib/docsify.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
@@ -0,0 +1,137 @@
|
||||
import * as tpl from '../../src/core/render/tpl'
|
||||
import fetch from 'node-fetch'
|
||||
import { AbstractHistory } from '../../src/core/router/history/abstract'
|
||||
import { Compiler } from '../../src/core/render/compiler'
|
||||
import { isAbsolutePath } from '../../src/core/router/util'
|
||||
import { readFileSync } from 'fs'
|
||||
import { resolve, basename } from 'path'
|
||||
|
||||
function cwd (...args) {
|
||||
return resolve(process.cwd(), ...args)
|
||||
}
|
||||
|
||||
function mainTpl (config) {
|
||||
let html = `<nav class="app-nav${config.repo ? '' : ' no-badge'}"><!--navbar--></nav>`
|
||||
|
||||
if (config.repo) {
|
||||
html += tpl.corner(config.repo)
|
||||
}
|
||||
if (config.coverpage) {
|
||||
html += tpl.cover()
|
||||
}
|
||||
|
||||
html += tpl.main(config)
|
||||
|
||||
return html
|
||||
}
|
||||
|
||||
export default class Renderer {
|
||||
constructor ({
|
||||
template,
|
||||
config,
|
||||
cache
|
||||
}) {
|
||||
this.html = template
|
||||
this.config = config = Object.assign({}, config, {
|
||||
routerMode: 'history'
|
||||
})
|
||||
this.cache = cache
|
||||
|
||||
this.router = new AbstractHistory(config)
|
||||
this.compiler = new Compiler(config, this.router)
|
||||
|
||||
this.router.getCurrentPath = () => this.url
|
||||
this._renderHtml('inject-config', `<script>window.$docsify = ${JSON.stringify(config)}</script>`)
|
||||
this._renderHtml('inject-app', mainTpl(config))
|
||||
|
||||
this.template = this.html
|
||||
}
|
||||
|
||||
_getPath (url) {
|
||||
const file = this.router.getFile(url)
|
||||
|
||||
return isAbsolutePath(file)
|
||||
? file
|
||||
: cwd(`./${file}`)
|
||||
}
|
||||
|
||||
async renderToString (url) {
|
||||
this.url = url = this.router.parse(url).path
|
||||
const { loadSidebar, loadNavbar } = this.config
|
||||
|
||||
const mainFile = this._getPath(url)
|
||||
this._renderHtml('main', await this._render(mainFile))
|
||||
|
||||
if (loadSidebar) {
|
||||
const name = loadSidebar === true ? '_sidebar.md' : loadSidebar
|
||||
const sidebarFile = this._getPath(resolve(url, `./${name}`))
|
||||
this._renderHtml('sidebar', await this._render(sidebarFile, 'sidebar'))
|
||||
}
|
||||
|
||||
if (loadNavbar) {
|
||||
const name = loadNavbar === true ? '_navbar.md' : loadNavbar
|
||||
const navbarFile = this._getPath(resolve(url, `./${name}`))
|
||||
this._renderHtml('navbar', await this._render(navbarFile, 'navbar'))
|
||||
}
|
||||
|
||||
const html = this.html
|
||||
this.html = this.template
|
||||
|
||||
return html
|
||||
}
|
||||
|
||||
_renderHtml (match, content) {
|
||||
this.html = this.html.replace(new RegExp(`<!--${match}-->`, 'g'), content)
|
||||
|
||||
return this.html
|
||||
}
|
||||
|
||||
async _render (path, type) {
|
||||
let html = await this._loadFile(path)
|
||||
const { subMaxLevel, maxLevel } = this.config
|
||||
|
||||
switch (type) {
|
||||
case 'sidebar':
|
||||
html = this.compiler.sidebar(html, maxLevel) +
|
||||
`<script>window.__SUB_SIDEBAR__ = ${JSON.stringify(
|
||||
this.compiler.subSidebar(html, subMaxLevel)
|
||||
)}</script>`
|
||||
break
|
||||
case 'cover':
|
||||
html = this.compiler.cover(html)
|
||||
break
|
||||
case 'navbar':
|
||||
case 'article':
|
||||
default:
|
||||
html = this.compiler.compile(html)
|
||||
break
|
||||
}
|
||||
|
||||
return html
|
||||
}
|
||||
|
||||
async _loadFile (filePath) {
|
||||
let content
|
||||
try {
|
||||
if (isAbsolutePath(filePath)) {
|
||||
const res = await fetch(filePath)
|
||||
content = await res.text()
|
||||
this.lock = 0
|
||||
} else {
|
||||
content = await readFileSync(filePath, 'utf8')
|
||||
this.lock = 0
|
||||
}
|
||||
return content
|
||||
} catch (e) {
|
||||
this.lock = this.lock || 0
|
||||
if (++this.lock > 10) {
|
||||
this.lock = 0
|
||||
return
|
||||
}
|
||||
|
||||
const fileName = basename(filePath)
|
||||
|
||||
return await this._loadFile(cwd(filePath, '../..', fileName))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"name": "docsify-server-renderer",
|
||||
"version": "4.1.3",
|
||||
"description": "docsify server renderer",
|
||||
"author": {
|
||||
"name": "qingwei-li",
|
||||
"email": "cinwell.li@gmail.com",
|
||||
"url": "https://github.com/QingWei-Li"
|
||||
},
|
||||
"homepage": "https://docsify.js.org",
|
||||
"license": "MIT",
|
||||
"repository": "QingWei-Li/docsify",
|
||||
"main": "build.js",
|
||||
"scripts": {
|
||||
"test": "echo 'hello'"
|
||||
},
|
||||
"dependencies": {
|
||||
"node-fetch": "^1.7.0"
|
||||
}
|
||||
}
|
||||
+5
-1
@@ -17,7 +17,11 @@ const config = merge({
|
||||
autoHeader: false,
|
||||
executeScript: null,
|
||||
noEmoji: false,
|
||||
ga: ''
|
||||
ga: '',
|
||||
mergeNavbar: false,
|
||||
formatUpdated: '',
|
||||
externalLinkTarget: '_blank',
|
||||
routerModel: 'hash'
|
||||
}, window.$docsify)
|
||||
|
||||
const script = document.currentScript ||
|
||||
|
||||
@@ -6,13 +6,13 @@ import { scrollIntoView } from './scroll'
|
||||
export function eventMixin (proto) {
|
||||
proto.$resetEvents = function () {
|
||||
scrollIntoView(this.route.query.id)
|
||||
sidebar.getAndActive('nav')
|
||||
sidebar.getAndActive(this.router, 'nav')
|
||||
}
|
||||
}
|
||||
|
||||
export function initEvent (vm) {
|
||||
// Bind toggle button
|
||||
sidebar.btn('button.sidebar-toggle')
|
||||
sidebar.btn('button.sidebar-toggle', vm.router)
|
||||
// Bind sticky effect
|
||||
if (vm.config.coverpage) {
|
||||
!isMobile && on('scroll', sidebar.sticky)
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { isMobile } from '../util/env'
|
||||
import * as dom from '../util/dom'
|
||||
import { parse } from '../route/hash'
|
||||
|
||||
const nav = {}
|
||||
let hoverOver = false
|
||||
@@ -53,7 +52,7 @@ function highlight () {
|
||||
}
|
||||
}
|
||||
|
||||
export function scrollActiveSidebar () {
|
||||
export function scrollActiveSidebar (router) {
|
||||
if (isMobile) return
|
||||
|
||||
const sidebar = dom.getNode('.sidebar')
|
||||
@@ -66,7 +65,7 @@ export function scrollActiveSidebar () {
|
||||
let href = a.getAttribute('href')
|
||||
|
||||
if (href !== '/') {
|
||||
href = parse(href).query.id
|
||||
href = router.parse(href).query.id
|
||||
}
|
||||
|
||||
nav[decodeURIComponent(href)] = li
|
||||
|
||||
+15
-10
@@ -1,23 +1,27 @@
|
||||
import { isMobile } from '../util/env'
|
||||
import * as dom from '../util/dom'
|
||||
import { getHash } from '../route/hash'
|
||||
|
||||
const title = dom.$.title
|
||||
/**
|
||||
* Toggle button
|
||||
*/
|
||||
export function btn (el) {
|
||||
const toggle = () => dom.body.classList.toggle('close')
|
||||
export function btn (el, router) {
|
||||
const toggle = _ => dom.body.classList.toggle('close')
|
||||
|
||||
el = dom.getNode(el)
|
||||
dom.on(el, 'click', toggle)
|
||||
dom.on(el, 'click', e => {
|
||||
e.stopPropagation()
|
||||
toggle()
|
||||
})
|
||||
|
||||
const sidebar = dom.getNode('.sidebar')
|
||||
|
||||
dom.on(sidebar, 'click', () => {
|
||||
isMobile && toggle()
|
||||
setTimeout(() => getAndActive(sidebar, true, true), 0)
|
||||
})
|
||||
isMobile && dom.on(dom.body, 'click', _ =>
|
||||
dom.body.classList.contains('close') && toggle()
|
||||
)
|
||||
dom.on(sidebar, 'click', _ =>
|
||||
setTimeout((_ => getAndActive(router, sidebar, true, true), 0))
|
||||
)
|
||||
}
|
||||
|
||||
export function sticky () {
|
||||
@@ -34,16 +38,17 @@ export function sticky () {
|
||||
|
||||
/**
|
||||
* Get and active link
|
||||
* @param {object} router
|
||||
* @param {string|element} el
|
||||
* @param {Boolean} isParent acitve parent
|
||||
* @param {Boolean} autoTitle auto set title
|
||||
* @return {element}
|
||||
*/
|
||||
export function getAndActive (el, isParent, autoTitle) {
|
||||
export function getAndActive (router, el, isParent, autoTitle) {
|
||||
el = dom.getNode(el)
|
||||
|
||||
const links = dom.findAll(el, 'a')
|
||||
const hash = '#' + getHash()
|
||||
const hash = router.toURL(router.getCurrentPath())
|
||||
let target
|
||||
|
||||
links
|
||||
|
||||
+11
-4
@@ -14,9 +14,10 @@ export function get (url, hasBar = false) {
|
||||
const on = function () {
|
||||
xhr.addEventListener.apply(xhr, arguments)
|
||||
}
|
||||
const cached = cache[url]
|
||||
|
||||
if (cache[url]) {
|
||||
return { then: cb => cb(cache[url]), abort: noop }
|
||||
if (cached) {
|
||||
return { then: cb => cb(cached.content, cached.opt), abort: noop }
|
||||
}
|
||||
|
||||
xhr.open('GET', url)
|
||||
@@ -41,8 +42,14 @@ export function get (url, hasBar = false) {
|
||||
if (target.status >= 400) {
|
||||
error(target)
|
||||
} else {
|
||||
cache[url] = target.response
|
||||
success(target.response)
|
||||
const result = cache[url] = {
|
||||
content: target.response,
|
||||
opt: {
|
||||
updatedAt: xhr.getResponseHeader('last-modified')
|
||||
}
|
||||
}
|
||||
|
||||
success(result.content, result.opt)
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
+23
-7
@@ -1,7 +1,8 @@
|
||||
import { get } from './ajax'
|
||||
import { callHook } from '../init/lifecycle'
|
||||
import { getParentPath } from '../route/util'
|
||||
import { getParentPath } from '../router/util'
|
||||
import { noop } from '../util/core'
|
||||
import { getAndActive } from '../event/sidebar'
|
||||
|
||||
function loadNested (path, file, next, vm, first) {
|
||||
path = first ? path : path.replace(/\/$/, '')
|
||||
@@ -9,7 +10,7 @@ function loadNested (path, file, next, vm, first) {
|
||||
|
||||
if (!path) return
|
||||
|
||||
get(vm.$getFile(path + file))
|
||||
get(vm.router.getFile(path + file))
|
||||
.then(next, _ => loadNested(path, file, next, vm))
|
||||
}
|
||||
|
||||
@@ -22,14 +23,14 @@ export function fetchMixin (proto) {
|
||||
// Abort last request
|
||||
last && last.abort && last.abort()
|
||||
|
||||
last = get(this.$getFile(path), true)
|
||||
last = get(this.router.getFile(path), true)
|
||||
|
||||
// Current page is html
|
||||
this.isHTML = /\.html$/g.test(path)
|
||||
|
||||
// Load main content
|
||||
last.then(text => {
|
||||
this._renderMain(text)
|
||||
last.then((text, opt) => {
|
||||
this._renderMain(text, opt)
|
||||
if (!loadSidebar) return cb()
|
||||
|
||||
const fn = result => { this._renderSidebar(result); cb() }
|
||||
@@ -47,7 +48,7 @@ export function fetchMixin (proto) {
|
||||
proto._fetchCover = function () {
|
||||
const { coverpage } = this.config
|
||||
const root = getParentPath(this.route.path)
|
||||
const path = this.$getFile(root + coverpage)
|
||||
const path = this.router.getFile(root + coverpage)
|
||||
|
||||
if (this.route.path !== '/' || !coverpage) {
|
||||
this._renderCover()
|
||||
@@ -70,5 +71,20 @@ export function fetchMixin (proto) {
|
||||
}
|
||||
|
||||
export function initFetch (vm) {
|
||||
vm.$fetch(_ => callHook(vm, 'ready'))
|
||||
const { loadSidebar } = vm.config
|
||||
|
||||
// server-client renderer
|
||||
if (vm.rendered) {
|
||||
const activeEl = getAndActive(vm.router, '.sidebar-nav', true, true)
|
||||
if (loadSidebar && activeEl) {
|
||||
activeEl.parentNode.innerHTML += window.__SUB_SIDEBAR__
|
||||
}
|
||||
vm._bindEventOnRendered(activeEl)
|
||||
vm._fetchCover()
|
||||
vm.$resetEvents()
|
||||
callHook(vm, 'doneEach')
|
||||
callHook(vm, 'ready')
|
||||
} else {
|
||||
vm.$fetch(_ => callHook(vm, 'ready'))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
import * as util from './util'
|
||||
import * as dom from './util/dom'
|
||||
import * as render from './render/compiler'
|
||||
import * as route from './route/hash'
|
||||
import { Compiler } from './render/compiler'
|
||||
import { slugify } from './render/slugify'
|
||||
import { get } from './fetch/ajax'
|
||||
import marked from 'marked'
|
||||
import prism from 'prismjs'
|
||||
|
||||
export default function () {
|
||||
window.Docsify = { util, dom, render, route, get, slugify }
|
||||
window.Docsify = { util, dom, get, slugify }
|
||||
window.DocsifyCompiler = Compiler
|
||||
window.marked = marked
|
||||
window.Prism = prism
|
||||
}
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
import { initMixin } from './init'
|
||||
import { routeMixin } from './route'
|
||||
import { routerMixin } from './router'
|
||||
import { renderMixin } from './render'
|
||||
import { fetchMixin } from './fetch'
|
||||
import { eventMixin } from './event'
|
||||
@@ -12,7 +12,7 @@ function Docsify () {
|
||||
const proto = Docsify.prototype
|
||||
|
||||
initMixin(proto)
|
||||
routeMixin(proto)
|
||||
routerMixin(proto)
|
||||
renderMixin(proto)
|
||||
fetchMixin(proto)
|
||||
eventMixin(proto)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import config from '../config'
|
||||
import { initLifecycle, callHook } from './lifecycle'
|
||||
import { initRender } from '../render'
|
||||
import { initRoute } from '../route'
|
||||
import { initRouter } from '../router'
|
||||
import { initEvent } from '../event'
|
||||
import { initFetch } from '../fetch'
|
||||
import { isFn } from '../util/core'
|
||||
@@ -14,9 +14,9 @@ export function initMixin (proto) {
|
||||
initLifecycle(vm) // Init hooks
|
||||
initPlugin(vm) // Install plugins
|
||||
callHook(vm, 'init')
|
||||
initRouter(vm) // Add router
|
||||
initRender(vm) // Render base DOM
|
||||
initEvent(vm) // Bind events
|
||||
initRoute(vm) // Add hashchange eventListener
|
||||
initFetch(vm) // Fetch data
|
||||
callHook(vm, 'mounted')
|
||||
}
|
||||
|
||||
+139
-111
@@ -4,137 +4,165 @@ import { helper as helperTpl, tree as treeTpl } from './tpl'
|
||||
import { genTree } from './gen-tree'
|
||||
import { slugify } from './slugify'
|
||||
import { emojify } from './emojify'
|
||||
import { toURL, parse } from '../route/hash'
|
||||
import { getBasePath, isAbsolutePath, getPath } from '../route/util'
|
||||
import { isAbsolutePath, getPath } from '../router/util'
|
||||
import { isFn, merge, cached } from '../util/core'
|
||||
|
||||
let markdownCompiler = marked
|
||||
let contentBase = ''
|
||||
let currentPath = ''
|
||||
let renderer = new marked.Renderer()
|
||||
const cacheTree = {}
|
||||
let toc = []
|
||||
export class Compiler {
|
||||
constructor (config, router) {
|
||||
this.config = config
|
||||
this.router = router
|
||||
this.cacheTree = {}
|
||||
this.toc = []
|
||||
this.linkTarget = config.externalLinkTarget || '_blank'
|
||||
this.contentBase = router.getBasePath()
|
||||
|
||||
/**
|
||||
* Compile markdown content
|
||||
*/
|
||||
export const markdown = cached(text => {
|
||||
let html = ''
|
||||
const renderer = this._initRenderer()
|
||||
let compile
|
||||
const mdConf = config.markdown || {}
|
||||
|
||||
if (!text) return text
|
||||
if (isFn(mdConf)) {
|
||||
compile = mdConf(marked, renderer)
|
||||
} else {
|
||||
marked.setOptions(merge(mdConf, {
|
||||
renderer: merge(renderer, mdConf.renderer)
|
||||
}))
|
||||
compile = marked
|
||||
}
|
||||
|
||||
html = markdownCompiler(text)
|
||||
html = emojify(html)
|
||||
slugify.clear()
|
||||
this.compile = cached(text => {
|
||||
let html = ''
|
||||
|
||||
return html
|
||||
})
|
||||
if (!text) return text
|
||||
|
||||
markdown.renderer = renderer
|
||||
html = compile(text)
|
||||
html = config.noEmoji ? html : emojify(html)
|
||||
slugify.clear()
|
||||
|
||||
markdown.init = function (config = {}, base = window.location.pathname) {
|
||||
contentBase = getBasePath(base)
|
||||
|
||||
if (isFn(config)) {
|
||||
markdownCompiler = config(marked, renderer)
|
||||
} else {
|
||||
renderer = merge(renderer, config.renderer)
|
||||
marked.setOptions(merge(config, { renderer }))
|
||||
}
|
||||
}
|
||||
|
||||
markdown.update = function () {
|
||||
currentPath = parse().path
|
||||
}
|
||||
|
||||
/**
|
||||
* render anchor tag
|
||||
* @link https://github.com/chjj/marked#overriding-renderer-methods
|
||||
*/
|
||||
renderer.heading = function (text, level) {
|
||||
const slug = slugify(text)
|
||||
const url = toURL(currentPath, { id: slug })
|
||||
|
||||
toc.push({ level, slug: url, title: text })
|
||||
|
||||
return `<h${level} id="${slug}"><a href="${url}" data-id="${slug}" class="anchor"><span>${text}</span></a></h${level}>`
|
||||
}
|
||||
// highlight code
|
||||
renderer.code = function (code, lang = '') {
|
||||
const hl = Prism.highlight(code, Prism.languages[lang] || Prism.languages.markup)
|
||||
|
||||
return `<pre v-pre data-lang="${lang}"><code class="lang-${lang}">${hl}</code></pre>`
|
||||
}
|
||||
renderer.link = function (href, title, text) {
|
||||
let blank = ''
|
||||
if (!/:|(\/{2})/.test(href)) {
|
||||
href = toURL(href)
|
||||
} else {
|
||||
blank = ' target="_blank"'
|
||||
}
|
||||
if (title) {
|
||||
title = ` title="${title}"`
|
||||
}
|
||||
return `<a href="${href}"${title}${blank}>${text}</a>`
|
||||
}
|
||||
renderer.paragraph = function (text) {
|
||||
if (/^!>/.test(text)) {
|
||||
return helperTpl('tip', text)
|
||||
} else if (/^\?>/.test(text)) {
|
||||
return helperTpl('warn', text)
|
||||
}
|
||||
return `<p>${text}</p>`
|
||||
}
|
||||
renderer.image = function (href, title, text) {
|
||||
let url = href
|
||||
const titleHTML = title ? ` title="${title}"` : ''
|
||||
|
||||
if (!isAbsolutePath(href)) {
|
||||
url = getPath(contentBase, href)
|
||||
return html
|
||||
})
|
||||
}
|
||||
|
||||
return `<img src="${url}" data-origin="${href}" alt="${text}"${titleHTML}>`
|
||||
}
|
||||
_initRenderer () {
|
||||
const renderer = new marked.Renderer()
|
||||
const { linkTarget, router, toc, contentBase } = this
|
||||
/**
|
||||
* render anchor tag
|
||||
* @link https://github.com/chjj/marked#overriding-renderer-methods
|
||||
*/
|
||||
renderer.heading = function (text, level) {
|
||||
const nextToc = { level, title: text }
|
||||
|
||||
/**
|
||||
* Compile sidebar
|
||||
*/
|
||||
export function sidebar (text, level) {
|
||||
let html = ''
|
||||
if (/{docsify-ignore}/g.test(text)) {
|
||||
text = text.replace('{docsify-ignore}', '')
|
||||
nextToc.title = text
|
||||
nextToc.ignoreSubHeading = true
|
||||
}
|
||||
|
||||
if (text) {
|
||||
html = markdown(text)
|
||||
html = html.match(/<ul[^>]*>([\s\S]+)<\/ul>/g)[0]
|
||||
} else {
|
||||
const tree = cacheTree[currentPath] || genTree(toc, level)
|
||||
html = treeTpl(tree, '<ul>')
|
||||
cacheTree[currentPath] = tree
|
||||
if (/{docsify-ignore-all}/g.test(text)) {
|
||||
text = text.replace('{docsify-ignore-all}', '')
|
||||
nextToc.title = text
|
||||
nextToc.ignoreAllSubs = true
|
||||
}
|
||||
|
||||
const slug = slugify(text)
|
||||
const url = router.toURL(router.getCurrentPath(), { id: slug })
|
||||
nextToc.slug = url
|
||||
toc.push(nextToc)
|
||||
|
||||
return `<h${level} id="${slug}"><a href="${url}" data-id="${slug}" class="anchor"><span>${text}</span></a></h${level}>`
|
||||
}
|
||||
// highlight code
|
||||
renderer.code = function (code, lang = '') {
|
||||
const hl = Prism.highlight(code, Prism.languages[lang] || Prism.languages.markup)
|
||||
|
||||
return `<pre v-pre data-lang="${lang}"><code class="lang-${lang}">${hl}</code></pre>`
|
||||
}
|
||||
renderer.link = function (href, title, text) {
|
||||
let blank = ''
|
||||
if (!/:|(\/{2})/.test(href)) {
|
||||
href = router.toURL(href, null, router.getCurrentPath())
|
||||
} else {
|
||||
blank = ` target="${linkTarget}"`
|
||||
}
|
||||
if (title) {
|
||||
title = ` title="${title}"`
|
||||
}
|
||||
return `<a href="${href}"${title || ''}${blank}>${text}</a>`
|
||||
}
|
||||
renderer.paragraph = function (text) {
|
||||
if (/^!>/.test(text)) {
|
||||
return helperTpl('tip', text)
|
||||
} else if (/^\?>/.test(text)) {
|
||||
return helperTpl('warn', text)
|
||||
}
|
||||
return `<p>${text}</p>`
|
||||
}
|
||||
renderer.image = function (href, title, text) {
|
||||
let url = href
|
||||
const titleHTML = title ? ` title="${title}"` : ''
|
||||
|
||||
if (!isAbsolutePath(href)) {
|
||||
url = getPath(contentBase, href)
|
||||
}
|
||||
|
||||
return `<img src="${url}" data-origin="${href}" alt="${text}"${titleHTML}>`
|
||||
}
|
||||
|
||||
return renderer
|
||||
}
|
||||
|
||||
return html
|
||||
}
|
||||
/**
|
||||
* Compile sidebar
|
||||
*/
|
||||
sidebar (text, level) {
|
||||
const currentPath = this.router.getCurrentPath()
|
||||
let html = ''
|
||||
|
||||
/**
|
||||
* Compile sub sidebar
|
||||
*/
|
||||
export function subSidebar (el, level) {
|
||||
if (el) {
|
||||
if (text) {
|
||||
html = this.compile(text)
|
||||
html = html && html.match(/<ul[^>]*>([\s\S]+)<\/ul>/g)[0]
|
||||
} else {
|
||||
const tree = this.cacheTree[currentPath] || genTree(this.toc, level)
|
||||
html = treeTpl(tree, '<ul>')
|
||||
this.cacheTree[currentPath] = tree
|
||||
}
|
||||
|
||||
return html
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile sub sidebar
|
||||
*/
|
||||
subSidebar (level) {
|
||||
const currentPath = this.router.getCurrentPath()
|
||||
const { cacheTree, toc } = this
|
||||
|
||||
toc[0] && toc[0].ignoreAllSubs && (this.toc = [])
|
||||
toc[0] && toc[0].level === 1 && toc.shift()
|
||||
toc.forEach((node, i) => {
|
||||
node.ignoreSubHeading && toc.splice(i, 1)
|
||||
})
|
||||
|
||||
const tree = cacheTree[currentPath] || genTree(toc, level)
|
||||
el.parentNode.innerHTML += treeTpl(tree, '<ul class="app-sub-sidebar">')
|
||||
|
||||
cacheTree[currentPath] = tree
|
||||
this.toc = []
|
||||
return treeTpl(tree, '<ul class="app-sub-sidebar">')
|
||||
}
|
||||
toc = []
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile cover page
|
||||
*/
|
||||
export function cover (text) {
|
||||
const cacheToc = toc.slice()
|
||||
const html = markdown(text)
|
||||
article (text) {
|
||||
return this.compile(text)
|
||||
}
|
||||
|
||||
toc = cacheToc.slice()
|
||||
/**
|
||||
* Compile cover page
|
||||
*/
|
||||
cover (text) {
|
||||
const cacheToc = this.toc.slice()
|
||||
const html = this.compile(text)
|
||||
|
||||
return html
|
||||
this.toc = cacheToc.slice()
|
||||
|
||||
return html
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
import { inBrowser } from '../util/env'
|
||||
|
||||
function replace (m, $1) {
|
||||
return '<img class="emoji" src="https://assets-cdn.github.com/images/icons/emoji/' + $1 + '.png" alt="' + $1 + '" />'
|
||||
}
|
||||
|
||||
export function emojify (text) {
|
||||
return $docsify.noEmoji ? text : text
|
||||
return text
|
||||
.replace(/<(pre|template|code)[^>]*?>[\s\S]+?<\/(pre|template|code)>/g, m => m.replace(/:/g, '__colon__'))
|
||||
.replace(/:(\w+?):/ig, window.emojify || replace)
|
||||
.replace(/:(\w+?):/ig, (inBrowser && window.emojify) || replace)
|
||||
.replace(/__colon__/g, ':')
|
||||
}
|
||||
|
||||
+70
-43
@@ -1,12 +1,14 @@
|
||||
import * as dom from '../util/dom'
|
||||
import { getAndActive, sticky } from '../event/sidebar'
|
||||
import { scrollActiveSidebar, scroll2Top } from '../event/scroll'
|
||||
import cssVars from '../util/polyfill/css-vars'
|
||||
import * as tpl from './tpl'
|
||||
import { markdown, sidebar, subSidebar, cover } from './compiler'
|
||||
import cssVars from '../util/polyfill/css-vars'
|
||||
import tinydate from 'tinydate'
|
||||
import { callHook } from '../init/lifecycle'
|
||||
import { getBasePath, getPath, isAbsolutePath } from '../route/util'
|
||||
import { Compiler } from './compiler'
|
||||
import { getAndActive, sticky } from '../event/sidebar'
|
||||
import { getPath, isAbsolutePath } from '../router/util'
|
||||
import { isMobile } from '../util/env'
|
||||
import { isPrimitive } from '../util/core'
|
||||
import { scrollActiveSidebar, scroll2Top } from '../event/scroll'
|
||||
|
||||
function executeScript () {
|
||||
const script = dom.findAll('.markdown-section>script')
|
||||
@@ -20,6 +22,16 @@ function executeScript () {
|
||||
}, 0)
|
||||
}
|
||||
|
||||
function formatUpdated (html, updated, fn) {
|
||||
updated = typeof fn === 'function'
|
||||
? fn(updated)
|
||||
: typeof fn === 'string'
|
||||
? tinydate(fn)(new Date(updated))
|
||||
: updated
|
||||
|
||||
return html.replace(/{docsify-updated}/g, updated)
|
||||
}
|
||||
|
||||
function renderMain (html) {
|
||||
if (!html) {
|
||||
// TODO: Custom 404 page
|
||||
@@ -42,10 +54,6 @@ function renderMain (html) {
|
||||
} else {
|
||||
this.config.executeScript && executeScript()
|
||||
}
|
||||
|
||||
if (this.config.auto2top) {
|
||||
scroll2Top(this.config.auto2top)
|
||||
}
|
||||
}
|
||||
|
||||
function renderNameLink (vm) {
|
||||
@@ -58,7 +66,7 @@ function renderNameLink (vm) {
|
||||
if (isPrimitive(vm.config.nameLink)) {
|
||||
el.setAttribute('href', nameLink)
|
||||
} else if (typeof nameLink === 'object') {
|
||||
const match = Object.keys(nameLink).find(key => path.indexOf(key) > -1)
|
||||
const match = Object.keys(nameLink).filter(key => path.indexOf(key) > -1)[0]
|
||||
|
||||
el.setAttribute('href', nameLink[match])
|
||||
}
|
||||
@@ -71,34 +79,47 @@ export function renderMixin (proto) {
|
||||
}
|
||||
|
||||
proto._renderSidebar = function (text) {
|
||||
const { maxLevel, subMaxLevel, autoHeader, loadSidebar } = this.config
|
||||
const { maxLevel, subMaxLevel, loadSidebar } = this.config
|
||||
|
||||
this._renderTo('.sidebar-nav', sidebar(text, maxLevel))
|
||||
const active = getAndActive('.sidebar-nav', true, true)
|
||||
subSidebar(loadSidebar ? active : '', subMaxLevel)
|
||||
this._renderTo('.sidebar-nav', this.compiler.sidebar(text, maxLevel))
|
||||
const activeEl = getAndActive(this.router, '.sidebar-nav', true, true)
|
||||
if (loadSidebar && activeEl) {
|
||||
activeEl.parentNode.innerHTML += this.compiler.subSidebar(subMaxLevel)
|
||||
}
|
||||
// bind event
|
||||
this.activeLink = active
|
||||
scrollActiveSidebar()
|
||||
this._bindEventOnRendered()
|
||||
}
|
||||
|
||||
if (autoHeader && active) {
|
||||
proto._bindEventOnRendered = function (activeEl) {
|
||||
const { autoHeader, auto2top } = this.config
|
||||
|
||||
scrollActiveSidebar(this.router)
|
||||
|
||||
if (autoHeader && activeEl) {
|
||||
const main = dom.getNode('#main')
|
||||
const firstNode = main.children[0]
|
||||
if (firstNode && firstNode.tagName !== 'H1') {
|
||||
const h1 = dom.create('h1')
|
||||
h1.innerText = active.innerText
|
||||
h1.innerText = activeEl.innerText
|
||||
dom.before(main, h1)
|
||||
}
|
||||
}
|
||||
|
||||
auto2top && scroll2Top(auto2top)
|
||||
}
|
||||
|
||||
proto._renderNav = function (text) {
|
||||
text && this._renderTo('nav', markdown(text))
|
||||
getAndActive('nav')
|
||||
text && this._renderTo('nav', this.compiler.compile(text))
|
||||
getAndActive(this.router, 'nav')
|
||||
}
|
||||
|
||||
proto._renderMain = function (text) {
|
||||
proto._renderMain = function (text, opt = {}) {
|
||||
callHook(this, 'beforeEach', text, result => {
|
||||
const html = this.isHTML ? result : markdown(result)
|
||||
let html = this.isHTML ? result : this.compiler.compile(result)
|
||||
if (opt.updatedAt) {
|
||||
html = formatUpdated(html, opt.updatedAt, this.config.formatUpdated)
|
||||
}
|
||||
|
||||
callHook(this, 'afterEach', html, text => renderMain.call(this, text))
|
||||
})
|
||||
}
|
||||
@@ -111,7 +132,7 @@ export function renderMixin (proto) {
|
||||
}
|
||||
dom.toggleClass(el, 'add', 'show')
|
||||
|
||||
let html = this.coverIsHTML ? text : cover(text)
|
||||
let html = this.coverIsHTML ? text : this.compiler.cover(text)
|
||||
const m = html.trim().match('<p><img.*?data-origin="(.*?)"[^a]+alt="(.*?)">([^<]*?)</p>$')
|
||||
|
||||
if (m) {
|
||||
@@ -122,7 +143,7 @@ export function renderMixin (proto) {
|
||||
|
||||
dom.toggleClass(el, 'add', 'has-mask')
|
||||
if (!isAbsolutePath(m[1])) {
|
||||
path = getPath(getBasePath(this.config.basePath), m[1])
|
||||
path = getPath(this.router.getBasePath(), m[1])
|
||||
}
|
||||
el.style.backgroundImage = `url(${path})`
|
||||
el.style.backgroundSize = 'cover'
|
||||
@@ -136,7 +157,6 @@ export function renderMixin (proto) {
|
||||
}
|
||||
|
||||
proto._updateRender = function () {
|
||||
markdown.update()
|
||||
// render name link
|
||||
renderNameLink(this)
|
||||
}
|
||||
@@ -146,35 +166,42 @@ export function initRender (vm) {
|
||||
const config = vm.config
|
||||
|
||||
// Init markdown compiler
|
||||
markdown.init(config.markdown, config.basePath)
|
||||
vm.compiler = new Compiler(config, vm.router)
|
||||
|
||||
const id = config.el || '#app'
|
||||
const navEl = dom.find('nav') || dom.create('nav')
|
||||
|
||||
let el = dom.find(id)
|
||||
const el = dom.find(id)
|
||||
let html = ''
|
||||
let navAppendToTarget = dom.body
|
||||
|
||||
navEl.classList.add('app-nav')
|
||||
if (el) {
|
||||
if (config.repo) {
|
||||
html += tpl.corner(config.repo)
|
||||
}
|
||||
if (config.coverpage) {
|
||||
html += tpl.cover()
|
||||
}
|
||||
|
||||
if (!config.repo) {
|
||||
navEl.classList.add('no-badge')
|
||||
html += tpl.main(config)
|
||||
// Render main app
|
||||
vm._renderTo(el, html, true)
|
||||
} else {
|
||||
vm.rendered = true
|
||||
}
|
||||
if (!el) {
|
||||
el = dom.create(id)
|
||||
dom.appendTo(dom.body, el)
|
||||
}
|
||||
if (config.repo) {
|
||||
html += tpl.corner(config.repo)
|
||||
}
|
||||
if (config.coverpage) {
|
||||
html += tpl.cover()
|
||||
|
||||
if (config.mergeNavbar && isMobile) {
|
||||
navAppendToTarget = dom.find('.sidebar')
|
||||
} else {
|
||||
navEl.classList.add('app-nav')
|
||||
|
||||
if (!config.repo) {
|
||||
navEl.classList.add('no-badge')
|
||||
}
|
||||
}
|
||||
|
||||
html += tpl.main(config)
|
||||
// Render main app
|
||||
vm._renderTo(el, html, true)
|
||||
// Add nav
|
||||
dom.before(dom.body, navEl)
|
||||
dom.before(navAppendToTarget, navEl)
|
||||
|
||||
if (config.themeColor) {
|
||||
dom.$.head.innerHTML += tpl.theme(config.themeColor)
|
||||
|
||||
@@ -33,12 +33,12 @@ export function main (config) {
|
||||
(config.name
|
||||
? `<h1><a class="app-name-link" data-nosearch>${config.name}</a></h1>`
|
||||
: '') +
|
||||
'<div class="sidebar-nav"></div>' +
|
||||
'<div class="sidebar-nav"><!--sidebar--></div>' +
|
||||
'</aside>')
|
||||
|
||||
return (isMobile ? `${aside}<main>` : `<main>${aside}`) +
|
||||
'<section class="content">' +
|
||||
'<article class="markdown-section" id="main"></article>' +
|
||||
'<article class="markdown-section" id="main"><!--main--></article>' +
|
||||
'</section>' +
|
||||
'</main>'
|
||||
}
|
||||
|
||||
@@ -1,75 +0,0 @@
|
||||
import { merge, cached } from '../util/core'
|
||||
import { parseQuery, stringifyQuery, cleanPath } from './util'
|
||||
export * from './util'
|
||||
|
||||
function replaceHash (path) {
|
||||
const i = window.location.href.indexOf('#')
|
||||
window.location.replace(
|
||||
window.location.href.slice(0, i >= 0 ? i : 0) + '#' + path
|
||||
)
|
||||
}
|
||||
|
||||
const replaceSlug = cached(path => {
|
||||
return path
|
||||
.replace('#', '?id=')
|
||||
.replace(/\?(\w+)=/g, (_, slug) => slug === 'id' ? '?id=' : `&${slug}=`)
|
||||
})
|
||||
/**
|
||||
* Normalize the current url
|
||||
*
|
||||
* @example
|
||||
* domain.com/docs/ => domain.com/docs/#/
|
||||
* domain.com/docs/#/#slug => domain.com/docs/#/?id=slug
|
||||
*/
|
||||
export function normalize () {
|
||||
let path = getHash()
|
||||
|
||||
path = replaceSlug(path)
|
||||
|
||||
if (path.charAt(0) === '/') return replaceHash(path)
|
||||
replaceHash('/' + path)
|
||||
}
|
||||
|
||||
export function getHash () {
|
||||
// We can't use window.location.hash here because it's not
|
||||
// consistent across browsers - Firefox will pre-decode it!
|
||||
const href = window.location.href
|
||||
const index = href.indexOf('#')
|
||||
return index === -1 ? '' : href.slice(index + 1)
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the url
|
||||
* @param {string} [path=window.location.herf]
|
||||
* @return {object} { path, query }
|
||||
*/
|
||||
export function parse (path = window.location.href) {
|
||||
let query = ''
|
||||
|
||||
const queryIndex = path.indexOf('?')
|
||||
if (queryIndex >= 0) {
|
||||
query = path.slice(queryIndex + 1)
|
||||
path = path.slice(0, queryIndex)
|
||||
}
|
||||
|
||||
const hashIndex = path.indexOf('#')
|
||||
if (hashIndex) {
|
||||
path = path.slice(hashIndex + 1)
|
||||
}
|
||||
|
||||
return { path, query: parseQuery(query) }
|
||||
}
|
||||
|
||||
/**
|
||||
* to URL
|
||||
* @param {string} path
|
||||
* @param {object} qs query params
|
||||
*/
|
||||
export function toURL (path, params) {
|
||||
const route = parse(replaceSlug(path))
|
||||
|
||||
route.query = merge({}, route.query, params)
|
||||
path = route.path + stringifyQuery(route.query)
|
||||
|
||||
return cleanPath('#/' + path)
|
||||
}
|
||||
@@ -1,52 +0,0 @@
|
||||
import { normalize, parse } from './hash'
|
||||
import { getBasePath, getPath, isAbsolutePath } from './util'
|
||||
import { on } from '../util/dom'
|
||||
|
||||
function getAlias (path, alias) {
|
||||
return alias[path] ? getAlias(alias[path], alias) : path
|
||||
}
|
||||
|
||||
function getFileName (path) {
|
||||
return /\.(md|html)$/g.test(path)
|
||||
? path
|
||||
: /\/$/g.test(path)
|
||||
? `${path}README.md`
|
||||
: `${path}.md`
|
||||
}
|
||||
|
||||
export function routeMixin (proto) {
|
||||
proto.route = {}
|
||||
proto.$getFile = function (path) {
|
||||
const { config } = this
|
||||
const base = getBasePath(config.basePath)
|
||||
|
||||
path = config.alias ? getAlias(path, config.alias) : path
|
||||
path = getFileName(path)
|
||||
path = path === '/README.md' ? (config.homepage || path) : path
|
||||
path = isAbsolutePath(path) ? path : getPath(base, path)
|
||||
|
||||
return path
|
||||
}
|
||||
}
|
||||
|
||||
let lastRoute = {}
|
||||
|
||||
export function initRoute (vm) {
|
||||
normalize()
|
||||
lastRoute = vm.route = parse()
|
||||
vm._updateRender()
|
||||
|
||||
on('hashchange', _ => {
|
||||
normalize()
|
||||
vm.route = parse()
|
||||
vm._updateRender()
|
||||
|
||||
if (lastRoute.path === vm.route.path) {
|
||||
vm.$resetEvents()
|
||||
return
|
||||
}
|
||||
|
||||
vm.$fetch()
|
||||
lastRoute = vm.route
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
import { History } from './base'
|
||||
import { parseQuery, stringifyQuery, cleanPath } from '../util'
|
||||
import { merge } from '../../util/core'
|
||||
|
||||
export class AbstractHistory extends History {
|
||||
constructor (config) {
|
||||
super(config)
|
||||
this.mode = 'abstract'
|
||||
}
|
||||
|
||||
parse (path) {
|
||||
let query = ''
|
||||
|
||||
const queryIndex = path.indexOf('?')
|
||||
if (queryIndex >= 0) {
|
||||
query = path.slice(queryIndex + 1)
|
||||
path = path.slice(0, queryIndex)
|
||||
}
|
||||
|
||||
return {
|
||||
path,
|
||||
file: this.getFile(path),
|
||||
query: parseQuery(query)
|
||||
}
|
||||
}
|
||||
|
||||
toURL (path, params, currentRoute) {
|
||||
const local = currentRoute && path[0] === '#'
|
||||
const route = this.parse(path)
|
||||
|
||||
route.query = merge({}, route.query, params)
|
||||
path = route.path + stringifyQuery(route.query)
|
||||
path = path.replace(/\.md(\?)|\.md$/, '$1')
|
||||
|
||||
if (local) path = currentRoute + path
|
||||
|
||||
return cleanPath('/' + path)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
import { getPath, isAbsolutePath } from '../util'
|
||||
import { noop } from '../../util/core'
|
||||
|
||||
function getAlias (path, alias) {
|
||||
return alias[path] ? getAlias(alias[path], alias) : path
|
||||
}
|
||||
|
||||
function getFileName (path) {
|
||||
return /\.(md|html)$/g.test(path)
|
||||
? path
|
||||
: /\/$/g.test(path)
|
||||
? `${path}README.md`
|
||||
: `${path}.md`
|
||||
}
|
||||
|
||||
export class History {
|
||||
constructor (config) {
|
||||
this.config = config
|
||||
}
|
||||
|
||||
getBasePath () {
|
||||
return this.config.basePath
|
||||
}
|
||||
|
||||
getFile (path) {
|
||||
path = path || this.getCurrentPath()
|
||||
|
||||
const { config } = this
|
||||
const base = this.getBasePath()
|
||||
|
||||
path = config.alias ? getAlias(path, config.alias) : path
|
||||
path = getFileName(path)
|
||||
path = path === '/README.md' ? (config.homepage || path) : path
|
||||
path = isAbsolutePath(path) ? path : getPath(base, path)
|
||||
|
||||
return path
|
||||
}
|
||||
|
||||
onchange (cb = noop) {
|
||||
cb()
|
||||
}
|
||||
|
||||
getCurrentPath () {}
|
||||
|
||||
normalize () {}
|
||||
|
||||
parse () {}
|
||||
|
||||
toURL () {}
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
import { History } from './base'
|
||||
import { merge, cached, noop } from '../../util/core'
|
||||
import { on } from '../../util/dom'
|
||||
import { parseQuery, stringifyQuery, cleanPath } from '../util'
|
||||
|
||||
function replaceHash (path) {
|
||||
const i = location.href.indexOf('#')
|
||||
location.replace(
|
||||
location.href.slice(0, i >= 0 ? i : 0) + '#' + path
|
||||
)
|
||||
}
|
||||
|
||||
const replaceSlug = cached(path => {
|
||||
return path.replace('#', '?id=')
|
||||
})
|
||||
|
||||
export class HashHistory extends History {
|
||||
constructor (config) {
|
||||
super(config)
|
||||
this.mode = 'hash'
|
||||
}
|
||||
|
||||
getBasePath () {
|
||||
const path = window.location.pathname || ''
|
||||
const base = this.config.basePath
|
||||
|
||||
return /^(\/|https?:)/g.test(base)
|
||||
? base
|
||||
: cleanPath(path + '/' + base)
|
||||
}
|
||||
|
||||
getCurrentPath () {
|
||||
// We can't use location.hash here because it's not
|
||||
// consistent across browsers - Firefox will pre-decode it!
|
||||
const href = location.href
|
||||
const index = href.indexOf('#')
|
||||
return index === -1 ? '' : href.slice(index + 1)
|
||||
}
|
||||
|
||||
onchange (cb = noop) {
|
||||
on('hashchange', cb)
|
||||
}
|
||||
|
||||
normalize () {
|
||||
let path = this.getCurrentPath()
|
||||
|
||||
path = replaceSlug(path)
|
||||
|
||||
if (path.charAt(0) === '/') return replaceHash(path)
|
||||
replaceHash('/' + path)
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the url
|
||||
* @param {string} [path=location.herf]
|
||||
* @return {object} { path, query }
|
||||
*/
|
||||
parse (path = location.href) {
|
||||
let query = ''
|
||||
|
||||
const queryIndex = path.indexOf('?')
|
||||
if (queryIndex >= 0) {
|
||||
query = path.slice(queryIndex + 1)
|
||||
path = path.slice(0, queryIndex)
|
||||
}
|
||||
|
||||
const hashIndex = path.indexOf('#')
|
||||
if (hashIndex) {
|
||||
path = path.slice(hashIndex + 1)
|
||||
}
|
||||
|
||||
return {
|
||||
path,
|
||||
file: this.getFile(path),
|
||||
query: parseQuery(query)
|
||||
}
|
||||
}
|
||||
|
||||
toURL (path, params, currentRoute) {
|
||||
const local = currentRoute && path[0] === '#'
|
||||
const route = this.parse(replaceSlug(path))
|
||||
|
||||
route.query = merge({}, route.query, params)
|
||||
path = route.path + stringifyQuery(route.query)
|
||||
path = path.replace(/\.md(\?)|\.md$/, '$1')
|
||||
|
||||
if (local) path = currentRoute + path
|
||||
|
||||
return cleanPath('#/' + path)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
import { History } from './base'
|
||||
import { merge, noop } from '../../util/core'
|
||||
import { on } from '../../util/dom'
|
||||
import { parseQuery, stringifyQuery, getPath, cleanPath } from '../util'
|
||||
|
||||
export class HTML5History extends History {
|
||||
constructor (config) {
|
||||
super(config)
|
||||
this.mode = 'history'
|
||||
}
|
||||
|
||||
getCurrentPath () {
|
||||
const base = this.getBasePath()
|
||||
let path = window.location.pathname
|
||||
|
||||
if (base && path.indexOf(base) === 0) {
|
||||
path = path.slice(base.length)
|
||||
}
|
||||
|
||||
return (path || '/') + window.location.search + window.location.hash
|
||||
}
|
||||
|
||||
onchange (cb = noop) {
|
||||
on('click', e => {
|
||||
const el = e.target.tagName === 'A'
|
||||
? e.target
|
||||
: e.target.parentNode
|
||||
|
||||
if (el.tagName === 'A' && !/_blank/.test(el.target)) {
|
||||
e.preventDefault()
|
||||
const url = el.href
|
||||
window.history.pushState({ key: url }, '', url)
|
||||
cb()
|
||||
}
|
||||
})
|
||||
|
||||
on('popstate', cb)
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the url
|
||||
* @param {string} [path=location.href]
|
||||
* @return {object} { path, query }
|
||||
*/
|
||||
parse (path = location.href) {
|
||||
let query = ''
|
||||
|
||||
const queryIndex = path.indexOf('?')
|
||||
if (queryIndex >= 0) {
|
||||
query = path.slice(queryIndex + 1)
|
||||
path = path.slice(0, queryIndex)
|
||||
}
|
||||
|
||||
const base = getPath(location.origin)
|
||||
const baseIndex = path.indexOf(base)
|
||||
|
||||
if (baseIndex > -1) {
|
||||
path = path.slice(baseIndex + base.length)
|
||||
}
|
||||
|
||||
return {
|
||||
path,
|
||||
file: this.getFile(path),
|
||||
query: parseQuery(query)
|
||||
}
|
||||
}
|
||||
|
||||
toURL (path, params, currentRoute) {
|
||||
const local = currentRoute && path[0] === '#'
|
||||
const route = this.parse(path)
|
||||
|
||||
route.query = merge({}, route.query, params)
|
||||
path = route.path + stringifyQuery(route.query)
|
||||
path = path.replace(/\.md(\?)|\.md$/, '$1')
|
||||
|
||||
if (local) path = currentRoute + path
|
||||
|
||||
return cleanPath('/' + path)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
import { HashHistory } from './history/hash'
|
||||
import { HTML5History } from './history/html5'
|
||||
import { supportsPushState } from '../util/env'
|
||||
|
||||
export function routerMixin (proto) {
|
||||
proto.route = {}
|
||||
}
|
||||
|
||||
let lastRoute = {}
|
||||
|
||||
export function initRouter (vm) {
|
||||
const config = vm.config
|
||||
const mode = config.routerMode || 'hash'
|
||||
let router
|
||||
|
||||
if (mode === 'history' && supportsPushState) {
|
||||
router = new HTML5History(config)
|
||||
} else {
|
||||
router = new HashHistory(config)
|
||||
}
|
||||
|
||||
vm.router = router
|
||||
|
||||
router.normalize()
|
||||
lastRoute = vm.route = router.parse()
|
||||
vm._updateRender()
|
||||
|
||||
router.onchange(_ => {
|
||||
router.normalize()
|
||||
vm.route = router.parse()
|
||||
vm._updateRender()
|
||||
|
||||
if (lastRoute.path === vm.route.path) {
|
||||
vm.$resetEvents()
|
||||
return
|
||||
}
|
||||
|
||||
vm.$fetch()
|
||||
lastRoute = vm.route
|
||||
})
|
||||
}
|
||||
@@ -31,12 +31,6 @@ export function stringifyQuery (obj) {
|
||||
return qs.length ? `?${qs.join('&')}` : ''
|
||||
}
|
||||
|
||||
export const getBasePath = cached(base => {
|
||||
return /^(\/|https?:)/g.test(base)
|
||||
? base
|
||||
: cleanPath(window.location.pathname + '/' + base)
|
||||
})
|
||||
|
||||
export function getPath (...args) {
|
||||
return cleanPath(args.join('/'))
|
||||
}
|
||||
@@ -54,5 +48,7 @@ export const getParentPath = cached(path => {
|
||||
})
|
||||
|
||||
export const cleanPath = cached(path => {
|
||||
return path.replace(/\/+/g, '/')
|
||||
return path
|
||||
.replace(/^\/+/, '/')
|
||||
.replace(/([^:])\/{2,}/g, '$1/')
|
||||
})
|
||||
+13
-3
@@ -1,5 +1,15 @@
|
||||
export const UA = window.navigator.userAgent.toLowerCase()
|
||||
export const inBrowser = typeof window !== 'undefined'
|
||||
|
||||
export const isIE = UA && /msie|trident/.test(UA)
|
||||
export const isMobile = inBrowser && document.body.clientWidth <= 600
|
||||
|
||||
export const isMobile = document.body.clientWidth <= 600
|
||||
/**
|
||||
* @see https://github.com/MoOx/pjax/blob/master/lib/is-supported.js
|
||||
*/
|
||||
export const supportsPushState = inBrowser && (function () {
|
||||
// Borrowed wholesale from https://github.com/defunkt/jquery-pjax
|
||||
return window.history &&
|
||||
window.history.pushState &&
|
||||
window.history.replaceState &&
|
||||
// pushState isn’t reliable on iOS until 5.
|
||||
!navigator.userAgent.match(/((iPod|iPhone|iPad).+\bOS\s+[1-4]\D|WebApps\/.+CFNetwork)/)
|
||||
})()
|
||||
|
||||
@@ -1,2 +1,3 @@
|
||||
export * from './core'
|
||||
export * from './env'
|
||||
export * from '../router/util'
|
||||
|
||||
@@ -1,16 +1,20 @@
|
||||
function handleExternalScript () {
|
||||
const container = Docsify.dom.getNode('#main')
|
||||
const script = Docsify.dom.find(container, 'script')
|
||||
const scripts = Docsify.dom.findAll(container, 'script')
|
||||
|
||||
if (script && script.src) {
|
||||
const newScript = document.createElement('script')
|
||||
for (let i = scripts.length; i--;) {
|
||||
const script = scripts[i]
|
||||
|
||||
;['src', 'async', 'defer'].forEach(attribute => {
|
||||
newScript[attribute] = script[attribute]
|
||||
})
|
||||
if (script && script.src) {
|
||||
const newScript = document.createElement('script')
|
||||
|
||||
script.parentNode.removeChild(script)
|
||||
container.appendChild(newScript)
|
||||
Array.prototype.slice.call(script.attributes).forEach(attribute => {
|
||||
newScript[attribute.name] = attribute.value
|
||||
})
|
||||
|
||||
script.parentNode.insertBefore(newScript, script)
|
||||
script.parentNode.removeChild(script)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+14
-10
@@ -7,24 +7,28 @@ function appendScript () {
|
||||
}
|
||||
|
||||
function init (id) {
|
||||
if (!window.ga) {
|
||||
let ga = window.ga
|
||||
|
||||
if (!ga) {
|
||||
appendScript()
|
||||
window.ga = window.ga || function () {
|
||||
(window.ga.q = window.ga.q || []).push(arguments)
|
||||
ga = ga || function () {
|
||||
(ga.q = ga.q || []).push(arguments)
|
||||
}
|
||||
window.ga.l = Number(new Date())
|
||||
window.ga('create', id, 'auto')
|
||||
ga.l = Number(new Date())
|
||||
ga('create', id, 'auto')
|
||||
}
|
||||
return ga
|
||||
}
|
||||
|
||||
function collect () {
|
||||
init(window.$docsify.ga)
|
||||
window.ga('set', 'page', location.href)
|
||||
window.ga('send', 'pageview')
|
||||
const ga = init($docsify.ga)
|
||||
|
||||
ga('set', 'page', location.hash)
|
||||
ga('send', 'pageview')
|
||||
}
|
||||
|
||||
const install = function (hook) {
|
||||
if (!window.$docsify.ga) {
|
||||
if (!$docsify.ga) {
|
||||
console.error('[Docsify] ga is required.')
|
||||
return
|
||||
}
|
||||
@@ -32,4 +36,4 @@ const install = function (hook) {
|
||||
hook.beforeEach(collect)
|
||||
}
|
||||
|
||||
window.$docsify.plugins = [].concat(install, window.$docsify.plugins)
|
||||
$docsify.plugins = [].concat(install, $docsify.plugins)
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user