Compare commits

...
44 Commits
Author SHA1 Message Date
qingwei.li 86923d03d3 -> v3.4.0 2017-03-09 20:30:44 +08:00
qingwei.li 8b696cd99d bump: 3.4.0 2017-03-09 20:30:38 +08:00
qingwei.li 3b30d42e9a add changelog 2017-03-09 20:29:01 +08:00
qingwei.li 50fa6fcb89 feat(zoom-image): add plugin 2017-03-09 20:26:33 +08:00
qingwei.li 8463f4d5c5 -> v3.3.0 2017-03-07 12:00:47 +08:00
qingwei.li 9e7d365872 bump: 3.3.0 2017-03-07 12:00:23 +08:00
cinwell.liandGitHub 9e9ad57540 Merge pull request #115 from Leopoldthecoder/master
add external-script plugin
2017-03-07 11:57:13 +08:00
Leopoldthecoder 9c54bafae4 switch to doneEach and cache #main dom 2017-03-07 11:30:09 +08:00
Leopoldthecoder 1aa6636ba8 add external-script plugin 2017-03-06 23:57:28 +08:00
qingwei.li 723a6040f2 docs: fix typo, fixed #114 2017-03-05 10:26:59 +08:00
gpreslandandcinwell.li d6b5403982 Update dictory structure in more-pages.md (#113)
Cleaner unicode structure.
2017-03-04 14:53:22 +08:00
杨奕andcinwell.li 9f0fc83b54 Fix nav showing while loading (#112) 2017-03-03 10:43:36 +08:00
Prayag Vermaandcinwell.li b02e1f1409 Fix a typo (#111)
ture → true
2017-03-02 14:05:03 +08:00
qingwei.li bca7b00c94 Update changelog 2017-02-28 22:06:17 +08:00
qingwei.li 0ae14e8ddc -> v3.2.0 2017-02-28 22:03:53 +08:00
qingwei.li 61e0aacb43 bump: 3.2 2017-02-28 22:03:47 +08:00
qingwei.li b927a30cc6 docs(changelog): 3.2 2017-02-28 22:03:09 +08:00
qingwei.li 0d59ee939f fix(render): Toc rendering error, fixed #106 2017-02-28 22:03:09 +08:00
qingwei.li 0aead898eb docs: updates 2017-02-28 22:03:09 +08:00
qingwei.li d3c9fbd124 feat(search): Localization for no data tip, close #103 2017-02-28 22:03:09 +08:00
qingwei.li f3fc596951 fix(fetch): load sidebar and navbar for parent path, fixed #100 2017-02-28 22:03:09 +08:00
qingwei.li 07a2a91296 docs(configuration): nameLink 2017-02-28 22:03:09 +08:00
qingwei.li 8ad835ca26 feat(render) nameLink for each route, fixed #99 2017-02-28 22:03:09 +08:00
qingwei.li 0994663c5a -> v3.1.2 2017-02-27 11:47:26 +08:00
qingwei.li 5067769a65 bump: 3.1.2 2017-02-27 11:47:22 +08:00
woshiguabiandcinwell.li 92d6e8a1ee Update search.js 2017-02-27 11:45:14 +08:00
qingwei.li 0dd9feffe5 -> v3.1.1 2017-02-24 20:19:40 +08:00
qingwei.li 82173627e5 bump: 3.1.1 2017-02-24 20:19:34 +08:00
qingwei.li 507d9e834c fix(search): dont search nameLink, fixed #102 2017-02-24 20:18:17 +08:00
qingwei.li 83ae93cae0 docs: update package size 2017-02-24 20:18:17 +08:00
qingwei.li 8f9bf29ee5 fix(render): custom cover background image 2017-02-24 20:18:17 +08:00
qingwei.li d67d25fed4 fix(tpl): extra character, fixed #101 2017-02-24 20:18:17 +08:00
qingwei.li 95a324c7e0 docs: update changelog 2017-02-22 22:32:51 +08:00
qingwei.li 5712c1f59d -> v3.1.0 2017-02-22 22:31:25 +08:00
qingwei.li 490a2cd64e bump: 3.1 2017-02-22 22:31:16 +08:00
qingwei.li b8a3d8f380 fix(search): incorrect anchor link, fixed #90 2017-02-22 22:30:07 +08:00
qingwei.li 855c450a97 feat(emoji): add emoji plugin 2017-02-22 22:30:07 +08:00
qingwei.li 2521c58c73 docs: tweaks 2017-02-22 22:11:05 +08:00
sokamalandcinwell.li 8df746e9d1 add emojis (#93)
* 更新 emoji 支持,增加 github emoji 列表,防止 “2017-02-22 15:13:22” 中的 :13: 被转义。

* 修正代码格式。
2017-02-22 16:40:48 +08:00
Le Liuandcinwell.li 2945e94e3c fix the extra character when github corner is enabled (#91) 2017-02-22 14:02:16 +08:00
qingwei.li 083cc4af56 docs(sw): cache unpkg.com 2017-02-22 09:39:17 +08:00
qingwei.li 5cab56cc92 docs(pwa): fix typo 2017-02-21 23:00:22 +08:00
qingwei.li d8ad679e2c docs(pwa): add pwa 2017-02-21 22:16:10 +08:00
qingwei.li f2975a5e5e fix(sw): update white list 2017-02-21 21:30:35 +08:00
57 changed files with 1893 additions and 253 deletions
+42 -2
View File
@@ -1,11 +1,51 @@
3.4.0 / 2017-03-09
==================
* feat(zoom-image): add plugin
3.3.0 / 2017-03-07
==================
* add front-matter plugin
* add external-script plugin
* Fix nav showing while loading (#112)
* Fix a typo (#111)
* Update changelog
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
==================
* fix(search): dont search nameLink, fixed [#102](https://github.com/QingWei-Li/docsify/issues/102)
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
==================
* 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
==================
* feat(pwa): add sw.js
* fix(layout.css): loading style
* fix(event): highlight sidebar when clicked, fixed #86
* fix(gen-tree): cache toc list, fixed #88
* 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
==================
+1 -1
View File
@@ -21,7 +21,7 @@
## Features
- No statically built html files
- Simple and lightweight (~14kB gzipped)
- Simple and lightweight (~16kB gzipped)
- Smart full-text search plugin
- Multiple themes
- Useful plugin API
+12 -3
View File
@@ -2,6 +2,7 @@ var rollup = require('rollup')
var buble = require('rollup-plugin-buble')
var commonjs = require('rollup-plugin-commonjs')
var nodeResolve = require('rollup-plugin-node-resolve')
var string = require('rollup-plugin-string')
var uglify = require('rollup-plugin-uglify')
var isProd = process.argv[process.argv.length - 1] !== '--dev'
@@ -9,7 +10,12 @@ var build = function (opts) {
rollup
.rollup({
entry: 'src/' + opts.entry,
plugins: [buble(), commonjs(), nodeResolve()].concat(opts.plugins || [])
plugins: (opts.plugins || []).concat([
string({ include: '**/*.css' }),
buble(),
commonjs(),
nodeResolve()
])
})
.then(function (bundle) {
var dest = 'lib/' + (opts.output || opts.entry)
@@ -33,8 +39,11 @@ build({
var plugins = [
{ name: 'search', entry: 'search/index.js', moduleName: 'Search' },
{ name: 'ga', entry: 'ga.js', moduleName: 'GA' }
// { name: 'front-matter', entry: 'front-matter/index.js', moduleName: 'FrontMatter' }
{ name: 'ga', entry: 'ga.js', moduleName: 'GA' },
{ name: 'emoji', entry: 'emoji.js', moduleName: 'Emoji' },
{ name: 'external-script', entry: 'external-script.js', moduleName: 'ExternalScript' },
{ name: 'front-matter', entry: 'front-matter/index.js', moduleName: 'FrontMatter' },
{ name: 'zoom-image', entry: 'zoom-image.js', moduleName: 'ZoomImage' }
]
plugins.forEach(item => {
+2 -2
View File
@@ -11,10 +11,11 @@ See the [Quick start](/quickstart) for more details.
## Features
- No statically built html files
- Simple and lightweight (~14kB gzipped)
- Simple and lightweight (~16kB gzipped)
- Smart full-text search plugin
- Multiple themes
- Useful plugin API
- Emoji support
- Compatible with IE10+
## Examples
@@ -24,4 +25,3 @@ Check out the [Showcase](https://github.com/QingWei-Li/docsify/#showcase) to doc
## Donate
Please consider donating if you think docsify is helpful to you or that my work is valuable. I am happy if you can help me [buy a cup of coffee](https://github.com/QingWei-Li/donate). :heart:
+2 -2
View File
@@ -1,10 +1,10 @@
![logo](_media/icon.svg)
# docsify <small>3.0</small>
# docsify <small>3.4</small>
> A magical documentation site generator.
- Simple and lightweight (~14kB gzipped)
- Simple and lightweight (~16kB gzipped)
- No statically built html files
- Multiple themes
+4 -2
View File
@@ -7,14 +7,16 @@
- Customization
- [Configuration](/configuration)
- [Themes](/themes)
- [Using plugins](/plugins)
- [List of Plugins](/plugins)
- [Write a Plugin](/write-a-plugin)
- [Markdown configuration](/markdown)
- [Lanuage highlighting](/language-highlight)
- [Language highlighting](/language-highlight)
- Guide
- [Deploy](/deploy)
- [Helpers](/helpers)
- [Vue compatibility](/vue)
- [CDN](/cdn)
- [Offline Mode(PWA)](/pwa)
- [Changelog](/changelog)
+9 -2
View File
@@ -173,7 +173,7 @@ window.$docsify = {
- Type: `Boolean|String`
- Default: `false`
Activate the [cover feature](/cover). If ture, it will load from `_coverpage.md`.
Activate the [cover feature](/cover). If true, it will load from `_coverpage.md`.
```js
window.$docsify = {
@@ -206,7 +206,13 @@ The name of the link.
```js
window.$docsify = {
nameLink: '/'
nameLink: '/',
// For each route
nameLink: {
'/zh-cn/': '/zh-cn/',
'/': '/'
}
}
```
@@ -300,3 +306,4 @@ window.$docsify = {
```
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.
+1 -1
View File
@@ -27,7 +27,7 @@ Set `coverpage` to **true**, and create a `_coverpage.md`:
> A magical documentation site generator.
- Simple and lightweight (~14kB gzipped)
- Simple and lightweight (~16kB gzipped)
- No statically built html files
- Multiple themes
+1 -1
View File
@@ -61,7 +61,7 @@ You can create sub-lists by indenting items that are under a certain parent.
- [Themes](/themes)
- [Using plugins](/plugins)
- [Markdown configuration](/markdown)
- [Lanuage highlight](/language-highlight)
- [Language highlight](/language-highlight)
```
renders as
+1
View File
@@ -6,6 +6,7 @@
<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>
+8 -7
View File
@@ -5,12 +5,13 @@ If you need more pages, you can simply create more markdown files in your docsif
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
@@ -67,4 +68,4 @@ A custom sidebar can also automatically generate a table of contents by setting
}
</script>
<script src="//unpkg.com/docsify"></script>
```
```
+25 -67
View File
@@ -1,8 +1,6 @@
# Using plugins
# List of Plugins
## List of Plugins
### Full text search
## Full text search
By default, the hyperlink on the current page is recognized and the content is saved in `localStorage`. You can also specify the path to the files.
@@ -29,6 +27,14 @@ By default, the hyperlink on the current page is recognized and the content is s
placeholder: {
'/zh-cn/': '搜索',
'/': 'Type to search'
},
noData: 'No Results!',
// Localization
noData: {
'/zh-cn/': '找不到结果',
'/': 'No Results'
}
}
}
@@ -38,7 +44,7 @@ By default, the hyperlink on the current page is recognized and the content is s
```
### Google Analytics
## Google Analytics
Install the plugin and configure the track id.
@@ -60,75 +66,27 @@ Configure by `data-ga`.
<script src="//unpkg.com/docsify/lib/plugins/ga.js"></script>
```
## emoji
## Write a plugin
The default is to support parsing emoji. For example `:100:` will be parsed to :100:. But it is not precise because there is no matching non-emoji string. If you need to correctly parse the emoji string, you need install this plugin.
A plugin is simply a function that takes `hook` as arguments.
The hook supports handling asynchronous tasks.
#### Full configuration
```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.
})
}
]
}
```html
<script src="//unpkg.com/docsify/lib/plugins/emoji.js"></script>
```
!> You can get internal methods through `window.Docsify`. Get the current instance through the second argument.
## External Script
#### Example
If the script on the page is an external one (imports a js file via `src` attribute), you'll need this plugin to make it work.
Add footer component in each pages.
```html
<script src="//unpkg.com/docsify/lib/plugins/external-script.js"></script>
```
```js
window.$docsify = {
plugins: [
function (hook) {
var footer = [
'<hr/>',
'<footer>',
'<span><a href="https://github.com/QingWei-Li">cinwell</a> &copy;2017.</span>',
'<span>Proudly published with <a href="https://github.com/QingWei-Li/docsify" target="_blank">docsify</a>.</span>',
'</footer>'
].join('')
## Zoom image
hook.afterEach(function (html) {
return html + footer
})
}
]
}
Medium's Image Zoom. Based on [zoom-image](https://github.com/egoist/zoom-image).
```html
<script src="//unpkg.com/docsify/lib/plugins/zoom-image.js"></script>
```
+113
View File
@@ -0,0 +1,113 @@
# Offline Mode
[Progressive Web Apps](https://developers.google.com/web/progressive-web-apps/)(PWA) are experiences that combine the best of the web and the best of apps. we can enhance our website with service workers to work **offline** or on low-quality networks.
It is also very easy to use it.
## Create serviceWorker
Create a sw.js file in your documents root directory and copy this code.
*sw.js*
```js
/* ===========================================================
* docsify sw.js
* ===========================================================
* Copyright 2016 @huxpro
* Licensed under Apache 2.0
* Register service worker.
* ========================================================== */
const RUNTIME = 'docsify'
const HOSTNAME_WHITELIST = [
self.location.hostname,
'fonts.gstatic.com',
'fonts.googleapis.com',
'unpkg.com'
]
// The Util Function to hack URLs of intercepted requests
const getFixedUrl = (req) => {
var now = Date.now()
var url = new URL(req.url)
// 1. fixed http URL
// Just keep syncing with location.protocol
// fetch(httpURL) belongs to active mixed content.
// And fetch(httpRequest) is not supported yet.
url.protocol = self.location.protocol
// 2. add query for caching-busting.
// Github Pages served with Cache-Control: max-age=600
// max-age on mutable content is error-prone, with SW life of bugs can even extend.
// Until cache mode of Fetch API landed, we have to workaround cache-busting with query string.
// Cache-Control-Bug: https://bugs.chromium.org/p/chromium/issues/detail?id=453190
if (url.hostname === self.location.hostname) {
url.search += (url.search ? '&' : '?') + 'cache-bust=' + now
}
return url.href
}
/**
* @Lifecycle Activate
* New one activated when old isnt being used.
*
* waitUntil(): activating ====> activated
*/
self.addEventListener('activate', event => {
event.waitUntil(self.clients.claim())
})
/**
* @Functional Fetch
* All network requests are being intercepted here.
*
* void respondWith(Promise<Response> r)
*/
self.addEventListener('fetch', event => {
// Skip some of cross-origin requests, like those for Google Analytics.
if (HOSTNAME_WHITELIST.indexOf(new URL(event.request.url).hostname) > -1) {
// Stale-while-revalidate
// similar to HTTP's stale-while-revalidate: https://www.mnot.net/blog/2007/12/12/stale
// Upgrade from Jake's to Surma's: https://gist.github.com/surma/eb441223daaedf880801ad80006389f1
const cached = caches.match(event.request)
const fixedUrl = getFixedUrl(event.request)
const fetched = fetch(fixedUrl, { cache: 'no-store' })
const fetchedCopy = fetched.then(resp => resp.clone())
// Call respondWith() with whatever we get first.
// If the fetch fails (e.g disconnected), wait for the cache.
// If theres nothing in cache, wait for the fetch.
// If neither yields a response, return offline pages.
event.respondWith(
Promise.race([fetched.catch(_ => cached), cached])
.then(resp => resp || fetched)
.catch(_ => { /* eat any errors */ })
)
// Update the cache with the version we fetched (only for ok status)
event.waitUntil(
Promise.all([fetchedCopy, caches.open(RUNTIME)])
.then(([response, cache]) => response.ok && cache.put(event.request, response))
.catch(_ => { /* eat any errors */ })
)
}
})
```
## Register
Now, register it in your `index.html`. It only works on some modern browsers, so we need to judge.
*index.html*
```html
<script>
if (typeof navigator.serviceWorker !== 'undefined') {
navigator.serviceWorker.register('sw.js')
}
</script>
```
## Enjoy it
Release your website and start experiencing magical offline feature. :ghost: You can turn off Wi-Fi and refresh the current site to experience it.
+1 -1
View File
@@ -76,7 +76,7 @@ You should set the `data-app` attribute if you changed `el`:
```html
<!-- index.html -->
<div data-app id="main">Please wait...</div>
<script>
+21 -20
View File
@@ -6,18 +6,18 @@
* Register service worker.
* ========================================================== */
const RUNTIME = 'docsify';
const RUNTIME = 'docsify'
const HOSTNAME_WHITELIST = [
self.location.hostname,
'unpkg.com',
'fonts.gstatic.com',
'fonts.googleapis.com'
'fonts.googleapis.com',
'unpkg.com'
]
// The Util Function to hack URLs of intercepted requests
const getFixedUrl = (req) => {
var now = Date.now();
url = new URL(req.url)
var now = Date.now()
var url = new URL(req.url)
// 1. fixed http URL
// Just keep syncing with location.protocol
@@ -30,7 +30,9 @@ const getFixedUrl = (req) => {
// max-age on mutable content is error-prone, with SW life of bugs can even extend.
// Until cache mode of Fetch API landed, we have to workaround cache-busting with query string.
// Cache-Control-Bug: https://bugs.chromium.org/p/chromium/issues/detail?id=453190
url.search += (url.search ? '&' : '?') + 'cache-bust=' + now;
if (url.hostname === self.location.hostname) {
url.search += (url.search ? '&' : '?') + 'cache-bust=' + now
}
return url.href
}
@@ -40,16 +42,15 @@ const getFixedUrl = (req) => {
*
* waitUntil(): activating ====> activated
*/
self.addEventListener('activate', event => {
event.waitUntil(self.clients.claim());
});
self.addEventListener('activate', event => {
event.waitUntil(self.clients.claim())
})
/**
* @Functional Fetch
* All network requests are being intercepted here.
*
* void respondWith(Promise<Response> r);
* void respondWith(Promise<Response> r)
*/
self.addEventListener('fetch', event => {
// Skip some of cross-origin requests, like those for Google Analytics.
@@ -57,10 +58,10 @@ self.addEventListener('fetch', event => {
// Stale-while-revalidate
// similar to HTTP's stale-while-revalidate: https://www.mnot.net/blog/2007/12/12/stale
// Upgrade from Jake's to Surma's: https://gist.github.com/surma/eb441223daaedf880801ad80006389f1
const cached = caches.match(event.request);
const fixedUrl = getFixedUrl(event.request);
const fetched = fetch(fixedUrl, {cache: 'no-store'});
const fetchedCopy = fetched.then(resp => resp.clone());
const cached = caches.match(event.request)
const fixedUrl = getFixedUrl(event.request)
const fetched = fetch(fixedUrl, { cache: 'no-store' })
const fetchedCopy = fetched.then(resp => resp.clone())
// Call respondWith() with whatever we get first.
// If the fetch fails (e.g disconnected), wait for the cache.
@@ -69,14 +70,14 @@ self.addEventListener('fetch', event => {
event.respondWith(
Promise.race([fetched.catch(_ => cached), cached])
.then(resp => resp || fetched)
.catch(_ => {/* eat any errors */})
);
.catch(_ => { /* eat any errors */ })
)
// Update the cache with the version we fetched (only for ok status)
event.waitUntil(
Promise.all([fetchedCopy, caches.open(RUNTIME)])
.then(([response, cache]) => response.ok && cache.put(event.request, response))
.catch(_ => {/* eat any errors */})
);
.catch(_ => { /* eat any errors */ })
)
}
});
})
+71
View File
@@ -0,0 +1,71 @@
# Write a plugin
A plugin is simply a function that takes `hook` as arguments.
The hook supports handling asynchronous tasks.
## Full configuration
```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.
})
}
]
}
```
!> You can get internal methods through `window.Docsify`. Get the current instance through the second argument.
## Example
Add footer component in each pages.
```js
window.$docsify = {
plugins: [
function (hook) {
var footer = [
'<hr/>',
'<footer>',
'<span><a href="https://github.com/QingWei-Li">cinwell</a> &copy;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
})
}
]
}
```
+2 -1
View File
@@ -12,10 +12,11 @@ docsify 是一个动态生成文档网站的工具。不同于 GitBook、Hexo
## 特性
- 无需构建,写完文档直接发布
- 容易使用并且轻量 (~14kB gzipped)
- 容易使用并且轻量 (~16kB gzipped)
- 智能的全文搜索
- 提供多套主题
- 丰富的 API
- 支持 Emoji
- 兼容 IE10+
## 例子
+3 -1
View File
@@ -7,7 +7,8 @@
- 定制化
- [配置项](zh-cn/configuration)
- [主题](zh-cn/themes)
- [使用插件](zh-cn/plugins)
- [插件列表](zh-cn/plugins)
- [开发插件](zh-cn/write-a-plugin)
- [Markdown 配置](zh-cn/markdown)
- [代码高亮](zh-cn/language-highlight)
@@ -16,5 +17,6 @@
- [文档助手](zh-cn/helpers)
- [兼容 Vue](zh-cn/vue)
- [CDN](zh-cn/cdn)
- [离线模式(PWA)](zh-cn/pwa)
- [Changelog](zh-cn/changelog)
+8 -1
View File
@@ -206,7 +206,13 @@ window.$docsify = {
```js
window.$docsify = {
nameLink: '/'
nameLink: '/',
// 按照路由切换
nameLink: {
'/zh-cn/': '/zh-cn/',
'/': '/'
}
}
```
@@ -298,3 +304,4 @@ window.$docsify = {
```
注意如果执行的是一个外链脚本,比如 jsfiddle 的内嵌 demo,请确保引入 [external-script](zh-cn/plugins?id=外链脚本-external-script) 插件。
+25 -65
View File
@@ -1,8 +1,6 @@
# 使用插件
# 插件列表
## 内置插件
### 全文搜索 - Search
## 全文搜索 - Search
全文搜索插件会根据当前页面上的超链接获取文档内容,在 `localStorage` 内建立文档索引。默认过期时间为一天,当然我们可以自己指定需要缓存的文件列表或者配置过期时间。
@@ -29,6 +27,14 @@
placeholder: {
'/zh-cn/': '搜索',
'/': 'Type to search'
},
noData: 'No Results!',
// 支持本地化
noData: {
'/zh-cn/': '找不到结果',
'/': 'No Results'
}
}
}
@@ -37,7 +43,7 @@
<script src="//unpkg.com/docsify/lib/plugins/search.js"></script>
```
### 谷歌统计 - Google Analytics
## 谷歌统计 - Google Analytics
需要配置 track id 才能使用。
@@ -58,72 +64,26 @@
<script src="//unpkg.com/docsify/lib/plugins/ga.js"></script>
```
## 自定义插件
## emoji
docsify 提供了一套插件机制,其中提供的钩子(hook)支持处理异步逻辑,可以很方便的扩展功能
默认是提供 emoji 解析的,能将类似 `:100:` 解析成 :100:。但是它不是精准的,因为没有处理非 emoji 的字符串。如果你需要正确解析 emoji 字符串,你可以引入这个插件
#### 完整功能
```js
window.$docsify = {
plugins: [
function (hook, vm) {
hook.init(function() {
// 初始化时调用,只调用一次,没有参数。
})
hook.beforeEach(function(content) {
// 每次开始解析 Markdown 内容时调用
// ...
return content
})
hook.afterEach(function(html, next) {
// 解析成 html 后调用。beforeEach 和 afterEach 支持处理异步逻辑
// ...
// 异步处理完成后调用 next(html) 返回结果
next(html)
})
hook.doneEach(function() {
// 每次路由切换时数据全部加载完成后调用,没有参数。
// ...
})
hook.mounted(function() {
// 初始化完成后调用 ,只调用一次,没有参数。
})
hook.ready(function() {
// 初始化并第一次加完成数据后调用,没有参数。
})
}
]
}
```html
<script src="//unpkg.com/docsify/lib/plugins/emoji.js"></script>
```
!> 如果需要用 docsify 的内部方法,可以通过 `window.Docsify` 获取,通过 `vm` 获取当前实例。
## 外链脚本 - External Script
#### 例子
如果文档里的 script 是内联脚本,可以直接执行;而如果是外链脚本(即 js 文件内容由 `src` 属性引入),则需要使用此插件。
给每个页面的末尾加上 `footer`
```html
<script src="//unpkg.com/docsify/lib/plugins/external-script.js"></script>
```
```js
window.$docsify = {
plugins: [
function (hook) {
var footer = [
'<hr/>',
'<footer>',
'<span><a href="https://github.com/QingWei-Li">cinwell</a> &copy;2017.</span>',
'<span>Proudly published with <a href="https://github.com/QingWei-Li/docsify" target="_blank">docsify</a>.</span>',
'</footer>'
].join('')
## 图片缩放 - Zoom image
hook.afterEach(function (html) {
return html + footer
})
}
]
}
Medium's 风格的图片缩放插件. 基于 [zoom-image](https://github.com/egoist/zoom-image)。
```html
<script src="//unpkg.com/docsify/lib/plugins/zoom-image.js"></script>
```
+113
View File
@@ -0,0 +1,113 @@
# 离线模式
[Progressive Web Apps](https://developers.google.com/web/progressive-web-apps/)(PWA) 是一项融合 Web 和 Native 应用各项优点的解决方案。我们可以利用其支持离线功能的特点,让我们的网站可以在信号差或者离线状态下正常运行。
要使用它也非常容易。
## 创建 serviceWorker
这里已经整理好了一份代码,你只需要在网站根目录下创建一个 `sw.js` 文件,并粘贴下面的代码。
*sw.js*
```js
/* ===========================================================
* docsify sw.js
* ===========================================================
* Copyright 2016 @huxpro
* Licensed under Apache 2.0
* Register service worker.
* ========================================================== */
const RUNTIME = 'docsify'
const HOSTNAME_WHITELIST = [
self.location.hostname,
'fonts.gstatic.com',
'fonts.googleapis.com',
'unpkg.com'
]
// The Util Function to hack URLs of intercepted requests
const getFixedUrl = (req) => {
var now = Date.now()
var url = new URL(req.url)
// 1. fixed http URL
// Just keep syncing with location.protocol
// fetch(httpURL) belongs to active mixed content.
// And fetch(httpRequest) is not supported yet.
url.protocol = self.location.protocol
// 2. add query for caching-busting.
// Github Pages served with Cache-Control: max-age=600
// max-age on mutable content is error-prone, with SW life of bugs can even extend.
// Until cache mode of Fetch API landed, we have to workaround cache-busting with query string.
// Cache-Control-Bug: https://bugs.chromium.org/p/chromium/issues/detail?id=453190
if (url.hostname === self.location.hostname) {
url.search += (url.search ? '&' : '?') + 'cache-bust=' + now
}
return url.href
}
/**
* @Lifecycle Activate
* New one activated when old isnt being used.
*
* waitUntil(): activating ====> activated
*/
self.addEventListener('activate', event => {
event.waitUntil(self.clients.claim())
})
/**
* @Functional Fetch
* All network requests are being intercepted here.
*
* void respondWith(Promise<Response> r)
*/
self.addEventListener('fetch', event => {
// Skip some of cross-origin requests, like those for Google Analytics.
if (HOSTNAME_WHITELIST.indexOf(new URL(event.request.url).hostname) > -1) {
// Stale-while-revalidate
// similar to HTTP's stale-while-revalidate: https://www.mnot.net/blog/2007/12/12/stale
// Upgrade from Jake's to Surma's: https://gist.github.com/surma/eb441223daaedf880801ad80006389f1
const cached = caches.match(event.request)
const fixedUrl = getFixedUrl(event.request)
const fetched = fetch(fixedUrl, { cache: 'no-store' })
const fetchedCopy = fetched.then(resp => resp.clone())
// Call respondWith() with whatever we get first.
// If the fetch fails (e.g disconnected), wait for the cache.
// If theres nothing in cache, wait for the fetch.
// If neither yields a response, return offline pages.
event.respondWith(
Promise.race([fetched.catch(_ => cached), cached])
.then(resp => resp || fetched)
.catch(_ => { /* eat any errors */ })
)
// Update the cache with the version we fetched (only for ok status)
event.waitUntil(
Promise.all([fetchedCopy, caches.open(RUNTIME)])
.then(([response, cache]) => response.ok && cache.put(event.request, response))
.catch(_ => { /* eat any errors */ })
)
}
})
```
## 注册
现在,到 `index.html` 里注册它。这个功能只能工作在一些现代浏览器上,所以我们需要加个判断。
*index.html*
```html
<script>
if (typeof navigator.serviceWorker !== 'undefined') {
navigator.serviceWorker.register('sw.js')
}
</script>
```
## 体验一下
发布你的网站,并开始享受离线模式的魔力吧!:ghost: 当然你现在看到的 docsify 的文档网站已经支持离线模式了,你可以关掉 Wi-Fi 体验一下。
-1
View File
@@ -81,4 +81,3 @@ cd docs && python -m SimpleHTTPServer 3000
}
</script>
```
+69
View File
@@ -0,0 +1,69 @@
# 自定义插件
docsify 提供了一套插件机制,其中提供的钩子(hook)支持处理异步逻辑,可以很方便的扩展功能。
## 完整功能
```js
window.$docsify = {
plugins: [
function (hook, vm) {
hook.init(function() {
// 初始化时调用,只调用一次,没有参数。
})
hook.beforeEach(function(content) {
// 每次开始解析 Markdown 内容时调用
// ...
return content
})
hook.afterEach(function(html, next) {
// 解析成 html 后调用。beforeEach 和 afterEach 支持处理异步逻辑
// ...
// 异步处理完成后调用 next(html) 返回结果
next(html)
})
hook.doneEach(function() {
// 每次路由切换时数据全部加载完成后调用,没有参数。
// ...
})
hook.mounted(function() {
// 初始化完成后调用 ,只调用一次,没有参数。
})
hook.ready(function() {
// 初始化并第一次加完成数据后调用,没有参数。
})
}
]
}
```
!> 如果需要用 docsify 的内部方法,可以通过 `window.Docsify` 获取,通过 `vm` 获取当前实例。
## 例子
给每个页面的末尾加上 `footer`
```js
window.$docsify = {
plugins: [
function (hook) {
var footer = [
'<hr/>',
'<footer>',
'<span><a href="https://github.com/QingWei-Li">cinwell</a> &copy;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
})
}
]
}
```
+57 -26
View File
@@ -161,7 +161,7 @@ function getNode (el, noCache) {
if ( noCache === void 0 ) noCache = false;
if (typeof el === 'string') {
el = noCache ? find(el) : (cacheNode[el] || find(el));
el = noCache ? find(el) : (cacheNode[el] || (cacheNode[el] = find(el)));
}
return el
@@ -300,8 +300,12 @@ var isAbsolutePath = cached(function (path) {
return /(:|(\/{2}))/.test(path)
});
var getRoot = cached(function (path) {
return /\/$/g.test(path) ? path : path.match(/(\S*\/)[^\/]+$/)[1]
var getParentPath = cached(function (path) {
return /\/$/g.test(path)
? path
: (path = path.match(/(\S*\/)[^\/]+$/))
? path[1]
: ''
});
var cleanPath = cached(function (path) {
@@ -393,7 +397,7 @@ var route = Object.freeze({
getBasePath: getBasePath,
getPath: getPath,
isAbsolutePath: isAbsolutePath,
getRoot: getRoot,
getParentPath: getParentPath,
cleanPath: cleanPath
});
@@ -696,7 +700,7 @@ function corner (data) {
'<path d="M128.3,109.0 C113.8,99.7 119.0,89.6 119.0,89.6 C122.0,82.7 120.5,78.6 120.5,78.6 C119.2,72.0 123.4,76.3 123.4,76.3 C127.3,80.9 125.5,87.3 125.5,87.3 C122.9,97.6 130.6,101.9 134.4,103.2" fill="currentColor" style="transform-origin: 130px 106px;" class="octo-arm"></path>' +
'<path d="M115.0,115.0 C114.9,115.1 118.7,116.5 119.8,115.4 L133.7,101.6 C136.9,99.2 139.9,98.4 142.2,98.6 C133.8,88.0 127.5,74.4 143.8,58.0 C148.5,53.4 154.0,51.2 159.7,51.0 C160.3,49.4 163.2,43.6 171.4,40.1 C171.4,40.1 176.1,42.5 178.8,56.2 C183.1,58.6 187.2,61.8 190.9,65.4 C194.5,69.0 197.7,73.2 200.1,77.6 C213.8,80.2 216.3,84.9 216.3,84.9 C212.7,93.1 206.9,96.0 205.4,96.6 C205.1,102.4 203.0,107.8 198.3,112.5 C181.9,128.9 168.3,122.5 157.7,114.1 C157.9,116.9 156.7,120.9 152.7,124.9 L141.0,136.5 C139.8,137.7 141.6,141.9 141.8,141.8 Z" fill="currentColor" class="octo-body"></path>' +
'</svg>' +
'</a>`')
'</a>')
}
/**
@@ -711,7 +715,7 @@ function main (config) {
'</button>' +
'<aside class="sidebar">' +
(config.name
? ("<h1><a href=\"" + (config.nameLink) + "\">" + (config.name) + "</a></h1>")
? ("<h1><a class=\"app-name-link\" data-nosearch>" + (config.name) + "</a></h1>")
: '') +
'<div class="sidebar-nav"></div>' +
'</aside>');
@@ -2922,14 +2926,18 @@ function slugify (str) {
return slug
}
function clearSlugCache () {
slugify.clear = function () {
cache$1 = {};
};
function replace (m, $1) {
return '<img class="emoji" src="https://assets-cdn.github.com/images/icons/emoji/' + $1 + '.png" alt="' + $1 + '" />'
}
function emojify (text) {
return text
.replace(/<(pre|template)[^>]*?>([\s\S]+)<\/(pre|template)>/g, function (m) { return m.replace(/:/g, '__colon__'); })
.replace(/:(\w+?):/ig, '<img class="emoji" src="https://assets-cdn.github.com/images/icons/emoji/$1.png" alt="$1" />')
.replace(/<(pre|template|code)[^>]*?>[\s\S]+?<\/(pre|template|code)>/g, function (m) { return m.replace(/:/g, '__colon__'); })
.replace(/:(\w+?):/ig, window.emojify || replace)
.replace(/__colon__/g, ':')
}
@@ -2950,7 +2958,7 @@ var markdown = cached(function (text) {
html = markdownCompiler(text);
html = emojify(html);
clearSlugCache();
slugify.clear();
return html
});
@@ -2962,7 +2970,6 @@ markdown.init = function (config, base) {
if ( base === void 0 ) base = window.location.pathname;
contentBase = getBasePath(base);
currentPath = parse().path;
if (isFn(config)) {
markdownCompiler = config(marked, renderer);
@@ -3037,8 +3044,9 @@ function sidebar (text, level) {
html = markdown(text);
html = html.match(/<ul[^>]*>([\s\S]+)<\/ul>/g)[0];
} else {
var tree$$1 = genTree(toc, level);
var tree$$1 = cacheTree[currentPath] || genTree(toc, level);
html = tree(tree$$1, '<ul>');
cacheTree[currentPath] = tree$$1;
}
return html
@@ -3117,6 +3125,22 @@ function renderMain (html) {
}
}
function renderNameLink (vm) {
var el = getNode('.app-name-link');
var nameLink = vm.config.nameLink;
var path = vm.route.path;
if (!el) { return }
if (isPrimitive(vm.config.nameLink)) {
el.setAttribute('href', nameLink);
} else if (typeof nameLink === 'object') {
var match = Object.keys(nameLink).find(function (key) { return path.indexOf(key) > -1; });
el.setAttribute('href', nameLink[match]);
}
}
function renderMixin (proto) {
proto._renderTo = function (el, content, replace) {
var node = getNode(el);
@@ -3132,7 +3156,7 @@ function renderMixin (proto) {
this._renderTo('.sidebar-nav', sidebar(text, maxLevel));
var active = getAndActive('.sidebar-nav', true, true);
loadSidebar && subSidebar(active, subMaxLevel);
subSidebar(loadSidebar ? active : '', subMaxLevel);
// bind event
this.activeLink = active;
scrollActiveSidebar();
@@ -3180,10 +3204,12 @@ function renderMixin (proto) {
var path = m[1];
toggleClass(el, 'add', 'has-mask');
if (isAbsolutePath(m[1])) {
if (!isAbsolutePath(m[1])) {
path = getPath(getBasePath(this.config.basePath), m[1]);
}
el.style.backgroundImage = "url(" + path + ")";
el.style.backgroundSize = 'cover';
el.style.backgroundPosition = 'center center';
}
html = html.replace(m[0], '');
}
@@ -3194,6 +3220,8 @@ function renderMixin (proto) {
proto._updateRender = function () {
markdown.update();
// render name link
renderNameLink(this);
};
}
@@ -3272,6 +3300,7 @@ var lastRoute = {};
function initRoute (vm) {
normalize();
lastRoute = vm.route = parse();
vm._updateRender();
on('hashchange', function (_) {
normalize();
@@ -3306,6 +3335,16 @@ function initEvent (vm) {
}
}
function loadNested (path, file, next, vm, first) {
path = first ? path : path.replace(/\/$/, '');
path = getParentPath(path);
if (!path) { return }
get(vm.$getFile(path + file))
.then(next, function (_) { return loadNested(path, file, next, vm); });
}
function fetchMixin (proto) {
var last;
proto._fetch = function (cb) {
@@ -3317,7 +3356,6 @@ function fetchMixin (proto) {
var ref$1 = this.config;
var loadNavbar = ref$1.loadNavbar;
var loadSidebar = ref$1.loadSidebar;
var root = getRoot(path);
// Abort last request
last && last.abort && last.abort();
@@ -3335,20 +3373,13 @@ function fetchMixin (proto) {
var fn = function (result) { this$1._renderSidebar(result); cb(); };
// Load sidebar
get(this$1.$getFile(root + loadSidebar))
// fallback root navbar when fail
.then(fn, function (_) { return get(loadSidebar).then(fn); });
loadNested(path, loadSidebar, fn, this$1, true);
},
function (_) { return this$1._renderMain(null); });
// Load nav
loadNavbar &&
get(this.$getFile(root + loadNavbar))
.then(
function (text) { return this$1._renderNav(text); },
// fallback root navbar when fail
function (_) { return get(loadNavbar).then(function (text) { return this$1._renderNav(text); }); }
);
loadNested(path, loadNavbar, function (text) { return this$1._renderNav(text); }, this, true);
};
proto._fetchCover = function () {
@@ -3356,7 +3387,7 @@ function fetchMixin (proto) {
var ref = this.config;
var coverpage = ref.coverpage;
var root = getRoot(this.route.path);
var root = getParentPath(this.route.path);
var path = this.$getFile(root + coverpage);
if (this.route.path !== '/' || !coverpage) {
@@ -3421,7 +3452,7 @@ var util = Object.freeze({
});
var initGlobalAPI = function () {
window.Docsify = { util: util, dom: dom, render: render, route: route, get: get };
window.Docsify = { util: util, dom: dom, render: render, route: route, get: get, slugify: slugify };
window.marked = marked;
window.Prism = prism;
};
+2 -2
View File
File diff suppressed because one or more lines are too long
+159
View File
@@ -0,0 +1,159 @@
this.D = this.D || {};
(function () {
'use strict';
var AllGithubEmoji = ['+1', '100', '1234', '8ball', 'a', 'ab', 'abc', 'abcd',
'accept', 'aerial_tramway', 'airplane', 'alarm_clock', 'alien', 'ambulance',
'anchor', 'angel', 'anger', 'angry', 'anguished', 'ant', 'apple', 'aquarius',
'aries', 'arrow_backward', 'arrow_double_down', 'arrow_double_up', 'arrow_down',
'arrow_down_small', 'arrow_forward', 'arrow_heading_down', 'arrow_heading_up',
'arrow_left', 'arrow_lower_left', 'arrow_lower_right', 'arrow_right',
'arrow_right_hook', 'arrow_up', 'arrow_up_down', 'arrow_up_small', 'arrow_upper_left',
'arrow_upper_right', 'arrows_clockwise', 'arrows_counterclockwise', 'art',
'articulated_lorry', 'astonished', 'athletic_shoe', 'atm', 'b', 'baby', 'baby_bottle',
'baby_chick', 'baby_symbol', 'back', 'baggage_claim', 'balloon', 'ballot_box_with_check',
'bamboo', 'banana', 'bangbang', 'bank', 'bar_chart', 'barber', 'baseball', 'basketball',
'bath', 'bathtub', 'battery', 'bear', 'bee', 'beer', 'beers', 'beetle', 'beginner',
'bell', 'bento', 'bicyclist', 'bike', 'bikini', 'bird', 'birthday', 'black_circle',
'black_joker', 'black_large_square', 'black_medium_small_square', 'black_medium_square',
'black_nib', 'black_small_square', 'black_square_button', 'blossom', 'blowfish',
'blue_book', 'blue_car', 'blue_heart', 'blush', 'boar', 'boat', 'bomb', 'book',
'bookmark', 'bookmark_tabs', 'books', 'boom', 'boot', 'bouquet', 'bow', 'bowling',
'bowtie', 'boy', 'bread', 'bride_with_veil', 'bridge_at_night', 'briefcase',
'broken_heart', 'bug', 'bulb', 'bullettrain_front', 'bullettrain_side', 'bus',
'busstop', 'bust_in_silhouette', 'busts_in_silhouette', 'cactus', 'cake', 'calendar',
'calling', 'camel', 'camera', 'cancer', 'candy', 'capital_abcd', 'capricorn', 'car',
'card_index', 'carousel_horse', 'cat', 'cat2', 'cd', 'chart', 'chart_with_downwards_trend',
'chart_with_upwards_trend', 'checkered_flag', 'cherries', 'cherry_blossom', 'chestnut',
'chicken', 'children_crossing', 'chocolate_bar', 'christmas_tree', 'church', 'cinema',
'circus_tent', 'city_sunrise', 'city_sunset', 'cl', 'clap', 'clapper', 'clipboard',
'clock1', 'clock10', 'clock1030', 'clock11', 'clock1130', 'clock12', 'clock1230',
'clock130', 'clock2', 'clock230', 'clock3', 'clock330', 'clock4', 'clock430',
'clock5', 'clock530', 'clock6', 'clock630', 'clock7', 'clock730', 'clock8', 'clock830',
'clock9', 'clock930', 'closed_book', 'closed_lock_with_key', 'closed_umbrella',
'cloud', 'clubs', 'cn', 'cocktail', 'coffee', 'cold_sweat', 'collision', 'computer',
'confetti_ball', 'confounded', 'confused', 'congratulations', 'construction',
'construction_worker', 'convenience_store', 'cookie', 'cool', 'cop', 'copyright',
'corn', 'couple', 'couple_with_heart', 'couplekiss', 'cow', 'cow2', 'credit_card',
'crescent_moon', 'crocodile', 'crossed_flags', 'crown', 'cry', 'crying_cat_face',
'crystal_ball', 'cupid', 'curly_loop', 'currency_exchange', 'curry', 'custard',
'customs', 'cyclone', 'dancer', 'dancers', 'dango', 'dart', 'dash', 'date', 'de',
'deciduous_tree', 'department_store', 'diamond_shape_with_a_dot_inside', 'diamonds',
'disappointed', 'disappointed_relieved', 'dizzy', 'dizzy_face', 'do_not_litter',
'dog', 'dog2', 'dollar', 'dolls', 'dolphin', 'door', 'doughnut', 'dragon',
'dragon_face', 'dress', 'dromedary_camel', 'droplet', 'dvd', 'e-mail', 'ear',
'ear_of_rice', 'earth_africa', 'earth_americas', 'earth_asia', 'egg', 'eggplant',
'eight', 'eight_pointed_black_star', 'eight_spoked_asterisk', 'electric_plug',
'elephant', 'email', 'end', 'envelope', 'envelope_with_arrow', 'es', 'euro',
'european_castle', 'european_post_office', 'evergreen_tree', 'exclamation',
'expressionless', 'eyeglasses', 'eyes', 'facepunch', 'factory', 'fallen_leaf',
'family', 'fast_forward', 'fax', 'fearful', 'feelsgood', 'feet', 'ferris_wheel',
'file_folder', 'finnadie', 'fire', 'fire_engine', 'fireworks', 'first_quarter_moon',
'first_quarter_moon_with_face', 'fish', 'fish_cake', 'fishing_pole_and_fish',
'fist', 'five', 'flags', 'flashlight', 'flipper', 'floppy_disk', 'flower_playing_cards',
'flushed', 'foggy', 'football', 'footprints', 'fork_and_knife', 'fountain',
'four', 'four_leaf_clover', 'fr', 'free', 'fried_shrimp', 'fries', 'frog',
'frowning', 'fu', 'fuelpump', 'full_moon', 'full_moon_with_face', 'game_die',
'gb', 'gem', 'gemini', 'ghost', 'gift', 'gift_heart', 'girl', 'globe_with_meridians',
'goat', 'goberserk', 'godmode', 'golf', 'grapes', 'green_apple', 'green_book',
'green_heart', 'grey_exclamation', 'grey_question', 'grimacing', 'grin',
'grinning', 'guardsman', 'guitar', 'gun', 'haircut', 'hamburger', 'hammer',
'hamster', 'hand', 'handbag', 'hankey', 'hash', 'hatched_chick', 'hatching_chick',
'headphones', 'hear_no_evil', 'heart', 'heart_decoration', 'heart_eyes',
'heart_eyes_cat', 'heartbeat', 'heartpulse', 'hearts', 'heavy_check_mark',
'heavy_division_sign', 'heavy_dollar_sign', 'heavy_exclamation_mark', 'heavy_minus_sign',
'heavy_multiplication_x', 'heavy_plus_sign', 'helicopter', 'herb', 'hibiscus',
'high_brightness', 'high_heel', 'hocho', 'honey_pot', 'honeybee', 'horse',
'horse_racing', 'hospital', 'hotel', 'hotsprings', 'hourglass', 'hourglass_flowing_sand',
'house', 'house_with_garden', 'hurtrealbad', 'hushed', 'ice_cream', 'icecream',
'id', 'ideograph_advantage', 'imp', 'inbox_tray', 'incoming_envelope',
'information_desk_person', 'information_source', 'innocent', 'interrobang',
'iphone', 'it', 'izakaya_lantern', 'jack_o_lantern', 'japan', 'japanese_castle',
'japanese_goblin', 'japanese_ogre', 'jeans', 'joy', 'joy_cat', 'jp', 'key',
'keycap_ten', 'kimono', 'kiss', 'kissing', 'kissing_cat', 'kissing_closed_eyes',
'kissing_heart', 'kissing_smiling_eyes', 'koala', 'koko', 'kr', 'lantern',
'large_blue_circle', 'large_blue_diamond', 'large_orange_diamond', 'last_quarter_moon',
'last_quarter_moon_with_face', 'laughing', 'leaves', 'ledger', 'left_luggage',
'left_right_arrow', 'leftwards_arrow_with_hook', 'lemon', 'leo', 'leopard',
'libra', 'light_rail', 'link', 'lips', 'lipstick', 'lock', 'lock_with_ink_pen',
'lollipop', 'loop', 'loud_sound', 'loudspeaker', 'love_hotel', 'love_letter',
'low_brightness', 'm', 'mag', 'mag_right', 'mahjong', 'mailbox', 'mailbox_closed',
'mailbox_with_mail', 'mailbox_with_no_mail', 'man', 'man_with_gua_pi_mao',
'man_with_turban', 'mans_shoe', 'maple_leaf', 'mask', 'massage', 'meat_on_bone',
'mega', 'melon', 'memo', 'mens', 'metal', 'metro', 'microphone', 'microscope',
'milky_way', 'minibus', 'minidisc', 'mobile_phone_off', 'money_with_wings',
'moneybag', 'monkey', 'monkey_face', 'monorail', 'moon', 'mortar_board', 'mount_fuji',
'mountain_bicyclist', 'mountain_cableway', 'mountain_railway', 'mouse', 'mouse2',
'movie_camera', 'moyai', 'muscle', 'mushroom', 'musical_keyboard', 'musical_note',
'musical_score', 'mute', 'nail_care', 'name_badge', 'neckbeard', 'necktie',
'negative_squared_cross_mark', 'neutral_face', 'new', 'new_moon', 'new_moon_with_face',
'newspaper', 'ng', 'night_with_stars', 'nine', 'no_bell', 'no_bicycles', 'no_entry',
'no_entry_sign', 'no_good', 'no_mobile_phones', 'no_mouth', 'no_pedestrians',
'no_smoking', 'non-potable_water', 'nose', 'notebook', 'notebook_with_decorative_cover',
'notes', 'nut_and_bolt', 'o', 'o2', 'ocean', 'octocat', 'octopus', 'oden', 'office',
'ok', 'ok_hand', 'ok_woman', 'older_man', 'older_woman', 'on', 'oncoming_automobile',
'oncoming_bus', 'oncoming_police_car', 'oncoming_taxi', 'one', 'open_book',
'open_file_folder', 'open_hands', 'open_mouth', 'ophiuchus', 'orange_book',
'outbox_tray', 'ox', 'package', 'page_facing_up', 'page_with_curl', 'pager',
'palm_tree', 'panda_face', 'paperclip', 'parking', 'part_alternation_mark',
'partly_sunny', 'passport_control', 'paw_prints', 'peach', 'pear', 'pencil',
'pencil2', 'penguin', 'pensive', 'performing_arts', 'persevere', 'person_frowning',
'person_with_blond_hair', 'person_with_pouting_face', 'phone', 'pig', 'pig2',
'pig_nose', 'pill', 'pineapple', 'pisces', 'pizza', 'point_down', 'point_left',
'point_right', 'point_up', 'point_up_2', 'police_car', 'poodle', 'poop',
'post_office', 'postal_horn', 'postbox', 'potable_water', 'pouch', 'poultry_leg',
'pound', 'pouting_cat', 'pray', 'princess', 'punch', 'purple_heart', 'purse',
'pushpin', 'put_litter_in_its_place', 'question', 'rabbit', 'rabbit2', 'racehorse',
'radio', 'radio_button', 'rage', 'rage1', 'rage2', 'rage3', 'rage4', 'railway_car',
'rainbow', 'raised_hand', 'raised_hands', 'raising_hand', 'ram', 'ramen', 'rat',
'recycle', 'red_car', 'red_circle', 'registered', 'relaxed', 'relieved', 'repeat',
'repeat_one', 'restroom', 'revolving_hearts', 'rewind', 'ribbon', 'rice',
'rice_ball', 'rice_cracker', 'rice_scene', 'ring', 'rocket', 'roller_coaster',
'rooster', 'rose', 'rotating_light', 'round_pushpin', 'rowboat', 'ru', 'rugby_football',
'runner', 'running', 'running_shirt_with_sash', 'sa', 'sagittarius', 'sailboat',
'sake', 'sandal', 'santa', 'satellite', 'satisfied', 'saxophone', 'school',
'school_satchel', 'scissors', 'scorpius', 'scream', 'scream_cat', 'scroll',
'seat', 'secret', 'see_no_evil', 'seedling', 'seven', 'shaved_ice', 'sheep',
'shell', 'ship', 'shipit', 'shirt', 'shit', 'shoe', 'shower', 'signal_strength',
'six', 'six_pointed_star', 'ski', 'skull', 'sleeping', 'sleepy', 'slot_machine',
'small_blue_diamond', 'small_orange_diamond', 'small_red_triangle',
'small_red_triangle_down', 'smile', 'smile_cat', 'smiley', 'smiley_cat',
'smiling_imp', 'smirk', 'smirk_cat', 'smoking', 'snail', 'snake', 'snowboarder',
'snowflake', 'snowman', 'sob', 'soccer', 'soon', 'sos', 'sound', 'space_invader',
'spades', 'spaghetti', 'sparkle', 'sparkler', 'sparkles', 'sparkling_heart',
'speak_no_evil', 'speaker', 'speech_balloon', 'speedboat', 'squirrel', 'star',
'star2', 'stars', 'station', 'statue_of_liberty', 'steam_locomotive', 'stew',
'straight_ruler', 'strawberry', 'stuck_out_tongue', 'stuck_out_tongue_closed_eyes',
'stuck_out_tongue_winking_eye', 'sun_with_face', 'sunflower', 'sunglasses',
'sunny', 'sunrise', 'sunrise_over_mountains', 'surfer', 'sushi', 'suspect',
'suspension_railway', 'sweat', 'sweat_drops', 'sweat_smile', 'sweet_potato',
'swimmer', 'symbols', 'syringe', 'tada', 'tanabata_tree', 'tangerine', 'taurus',
'taxi', 'tea', 'telephone', 'telephone_receiver', 'telescope', 'tennis', 'tent',
'thought_balloon', 'three', 'thumbsdown', 'thumbsup', 'ticket', 'tiger', 'tiger2',
'tired_face', 'tm', 'toilet', 'tokyo_tower', 'tomato', 'tongue', 'top', 'tophat',
'tractor', 'traffic_light', 'train', 'train2', 'tram', 'triangular_flag_on_post',
'triangular_ruler', 'trident', 'triumph', 'trolleybus', 'trollface', 'trophy',
'tropical_drink', 'tropical_fish', 'truck', 'trumpet', 'tshirt', 'tulip',
'turtle', 'tv', 'twisted_rightwards_arrows', 'two', 'two_hearts', 'two_men_holding_hands',
'two_women_holding_hands', 'u5272', 'u5408', 'u55b6', 'u6307', 'u6708', 'u6709',
'u6e80', 'u7121', 'u7533', 'u7981', 'u7a7a', 'uk', 'umbrella', 'unamused',
'underage', 'unlock', 'up', 'us', 'v', 'vertical_traffic_light', 'vhs',
'vibration_mode', 'video_camera', 'video_game', 'violin', 'virgo', 'volcano',
'vs', 'walking', 'waning_crescent_moon', 'waning_gibbous_moon', 'warning',
'watch', 'water_buffalo', 'watermelon', 'wave', 'wavy_dash', 'waxing_crescent_moon',
'waxing_gibbous_moon', 'wc', 'weary', 'wedding', 'whale', 'whale2', 'wheelchair',
'white_check_mark', 'white_circle', 'white_flower', 'white_large_square',
'white_medium_small_square', 'white_medium_square', 'white_small_square',
'white_square_button', 'wind_chime', 'wine_glass', 'wink', 'wolf', 'woman',
'womans_clothes', 'womans_hat', 'womens', 'worried', 'wrench', 'x', 'yellow_heart',
'yen', 'yum', 'zap', 'zero', 'zzz'];
// emoji from All-Github-Emoji-Icons
// https://github.com/scotch-io/All-Github-Emoji-Icons
window.emojify = function (match, $1) {
return AllGithubEmoji.indexOf($1) === -1
? match
: '<img class="emoji" src="https://assets-cdn.github.com/images/icons/emoji/' + $1 + '.png" alt="' + $1 + '" />'
};
}());
+1
View File
File diff suppressed because one or more lines are too long
+25
View File
@@ -0,0 +1,25 @@
this.D = this.D || {};
(function () {
'use strict';
function handleExternalScript () {
var container = Docsify.dom.getNode('#main');
var script = Docsify.dom.find(container, 'script');
if (script && script.src) {
var newScript = document.createElement('script');['src', 'async', 'defer'].forEach(function (attribute) {
newScript[attribute] = script[attribute];
});
script.parentNode.removeChild(script);
container.appendChild(newScript);
}
}
var install = function (hook) {
hook.doneEach(handleExternalScript);
};
window.$docsify.plugins = [].concat(install, window.$docsify.plugins);
}());
+1
View File
@@ -0,0 +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)}();
+503
View File
@@ -0,0 +1,503 @@
this.D = this.D || {};
(function () {
'use strict';
/**
* Fork https://github.com/egoist/docute/blob/master/src/utils/yaml.js
*/
/* eslint-disable */
/*
YAML parser for Javascript
Author: Diogo Costa
This program is released under the MIT License as follows:
Copyright (c) 2011 Diogo Costa (costa.h4evr@gmail.com)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
/**
* @name YAML
* @namespace
*/
var errors = [];
var reference_blocks = [];
var processing_time = 0;
var regex$1 =
{
"regLevel" : new RegExp("^([\\s\\-]+)"),
"invalidLine" : new RegExp("^\\-\\-\\-|^\\.\\.\\.|^\\s*#.*|^\\s*$"),
"dashesString" : new RegExp("^\\s*\\\"([^\\\"]*)\\\"\\s*$"),
"quotesString" : new RegExp("^\\s*\\\'([^\\\']*)\\\'\\s*$"),
"float" : new RegExp("^[+-]?[0-9]+\\.[0-9]+(e[+-]?[0-9]+(\\.[0-9]+)?)?$"),
"integer" : new RegExp("^[+-]?[0-9]+$"),
"array" : new RegExp("\\[\\s*(.*)\\s*\\]"),
"map" : new RegExp("\\{\\s*(.*)\\s*\\}"),
"key_value" : new RegExp("([a-z0-9_-][ a-z0-9_-]*):( .+)", "i"),
"single_key_value" : new RegExp("^([a-z0-9_-][ a-z0-9_-]*):( .+?)$", "i"),
"key" : new RegExp("([a-z0-9_-][ a-z0-9_-]+):( .+)?", "i"),
"item" : new RegExp("^-\\s+"),
"trim" : new RegExp("^\\s+|\\s+$"),
"comment" : new RegExp("([^\\\'\\\"#]+([\\\'\\\"][^\\\'\\\"]*[\\\'\\\"])*)*(#.*)?")
};
/**
* @class A block of lines of a given level.
* @param {int} lvl The block's level.
* @private
*/
function Block(lvl) {
return {
/* The block's parent */
parent: null,
/* Number of children */
length: 0,
/* Block's level */
level: lvl,
/* Lines of code to process */
lines: [],
/* Blocks with greater level */
children : [],
/* Add a block to the children collection */
addChild : function(obj) {
this.children.push(obj);
obj.parent = this;
++this.length;
}
};
}
function parser$1(str) {
var regLevel = regex$1["regLevel"];
var invalidLine = regex$1["invalidLine"];
var lines = str.split("\n");
var m;
var level = 0, curLevel = 0;
var blocks = [];
var result = new Block(-1);
var currentBlock = new Block(0);
result.addChild(currentBlock);
var levels = [];
var line = "";
blocks.push(currentBlock);
levels.push(level);
for(var i = 0, len = lines.length; i < len; ++i) {
line = lines[i];
if(line.match(invalidLine)) {
continue;
}
if(m = regLevel.exec(line)) {
level = m[1].length;
} else
{ level = 0; }
if(level > curLevel) {
var oldBlock = currentBlock;
currentBlock = new Block(level);
oldBlock.addChild(currentBlock);
blocks.push(currentBlock);
levels.push(level);
} else if(level < curLevel) {
var added = false;
var k = levels.length - 1;
for(; k >= 0; --k) {
if(levels[k] == level) {
currentBlock = new Block(level);
blocks.push(currentBlock);
levels.push(level);
if(blocks[k].parent!= null)
{ blocks[k].parent.addChild(currentBlock); }
added = true;
break;
}
}
if(!added) {
errors.push("Error: Invalid indentation at line " + i + ": " + line);
return;
}
}
currentBlock.lines.push(line.replace(regex$1["trim"], ""));
curLevel = level;
}
return result;
}
function processValue(val) {
val = val.replace(regex$1["trim"], "");
var m = null;
if(val == 'true') {
return true;
} else if(val == 'false') {
return false;
} else if(val == '.NaN') {
return Number.NaN;
} else if(val == 'null') {
return null;
} else if(val == '.inf') {
return Number.POSITIVE_INFINITY;
} else if(val == '-.inf') {
return Number.NEGATIVE_INFINITY;
} else if(m = val.match(regex$1["dashesString"])) {
return m[1];
} else if(m = val.match(regex$1["quotesString"])) {
return m[1];
} else if(m = val.match(regex$1["float"])) {
return parseFloat(m[0]);
} else if(m = val.match(regex$1["integer"])) {
return parseInt(m[0]);
} else if( !isNaN(m = Date.parse(val))) {
return new Date(m);
} else if(m = val.match(regex$1["single_key_value"])) {
var res = {};
res[m[1]] = processValue(m[2]);
return res;
} else if(m = val.match(regex$1["array"])){
var count = 0, c = ' ';
var res = [];
var content = "";
var str = false;
for(var j = 0, lenJ = m[1].length; j < lenJ; ++j) {
c = m[1][j];
if(c == '\'' || c == '"') {
if(str === false) {
str = c;
content += c;
continue;
} else if((c == '\'' && str == '\'') || (c == '"' && str == '"')) {
str = false;
content += c;
continue;
}
} else if(str === false && (c == '[' || c == '{')) {
++count;
} else if(str === false && (c == ']' || c == '}')) {
--count;
} else if(str === false && count == 0 && c == ',') {
res.push(processValue(content));
content = "";
continue;
}
content += c;
}
if(content.length > 0)
{ res.push(processValue(content)); }
return res;
} else if(m = val.match(regex$1["map"])){
var count = 0, c = ' ';
var res = [];
var content = "";
var str = false;
for(var j = 0, lenJ = m[1].length; j < lenJ; ++j) {
c = m[1][j];
if(c == '\'' || c == '"') {
if(str === false) {
str = c;
content += c;
continue;
} else if((c == '\'' && str == '\'') || (c == '"' && str == '"')) {
str = false;
content += c;
continue;
}
} else if(str === false && (c == '[' || c == '{')) {
++count;
} else if(str === false && (c == ']' || c == '}')) {
--count;
} else if(str === false && count == 0 && c == ',') {
res.push(content);
content = "";
continue;
}
content += c;
}
if(content.length > 0)
{ res.push(content); }
var newRes = {};
for(var j = 0, lenJ = res.length; j < lenJ; ++j) {
if(m = res[j].match(regex$1["key_value"])) {
newRes[m[1]] = processValue(m[2]);
}
}
return newRes;
} else
{ return val; }
}
function processFoldedBlock(block) {
var lines = block.lines;
var children = block.children;
var str = lines.join(" ");
var chunks = [str];
for(var i = 0, len = children.length; i < len; ++i) {
chunks.push(processFoldedBlock(children[i]));
}
return chunks.join("\n");
}
function processLiteralBlock(block) {
var lines = block.lines;
var children = block.children;
var str = lines.join("\n");
for(var i = 0, len = children.length; i < len; ++i) {
str += processLiteralBlock(children[i]);
}
return str;
}
function processBlock(blocks) {
var m = null;
var res = {};
var lines = null;
var children = null;
var currentObj = null;
var level = -1;
var processedBlocks = [];
var isMap = true;
for(var j = 0, lenJ = blocks.length; j < lenJ; ++j) {
if(level != -1 && level != blocks[j].level)
{ continue; }
processedBlocks.push(j);
level = blocks[j].level;
lines = blocks[j].lines;
children = blocks[j].children;
currentObj = null;
for(var i = 0, len = lines.length; i < len; ++i) {
var line = lines[i];
if(m = line.match(regex$1["key"])) {
var key = m[1];
if(key[0] == '-') {
key = key.replace(regex$1["item"], "");
if (isMap) {
isMap = false;
if (typeof(res.length) === "undefined") {
res = [];
}
}
if(currentObj != null) { res.push(currentObj); }
currentObj = {};
isMap = true;
}
if(typeof m[2] != "undefined") {
var value = m[2].replace(regex$1["trim"], "");
if(value[0] == '&') {
var nb = processBlock(children);
if(currentObj != null) { currentObj[key] = nb; }
else { res[key] = nb; }
reference_blocks[value.substr(1)] = nb;
} else if(value[0] == '|') {
if(currentObj != null) { currentObj[key] = processLiteralBlock(children.shift()); }
else { res[key] = processLiteralBlock(children.shift()); }
} else if(value[0] == '*') {
var v = value.substr(1);
var no = {};
if(typeof reference_blocks[v] == "undefined") {
errors.push("Reference '" + v + "' not found!");
} else {
for(var k in reference_blocks[v]) {
no[k] = reference_blocks[v][k];
}
if(currentObj != null) { currentObj[key] = no; }
else { res[key] = no; }
}
} else if(value[0] == '>') {
if(currentObj != null) { currentObj[key] = processFoldedBlock(children.shift()); }
else { res[key] = processFoldedBlock(children.shift()); }
} else {
if(currentObj != null) { currentObj[key] = processValue(value); }
else { res[key] = processValue(value); }
}
} else {
if(currentObj != null) { currentObj[key] = processBlock(children); }
else { res[key] = processBlock(children); }
}
} else if(line.match(/^-\s*$/)) {
if (isMap) {
isMap = false;
if (typeof(res.length) === "undefined") {
res = [];
}
}
if(currentObj != null) { res.push(currentObj); }
currentObj = {};
isMap = true;
continue;
} else if(m = line.match(/^-\s*(.*)/)) {
if(currentObj != null)
{ currentObj.push(processValue(m[1])); }
else {
if (isMap) {
isMap = false;
if (typeof(res.length) === "undefined") {
res = [];
}
}
res.push(processValue(m[1]));
}
continue;
}
}
if(currentObj != null) {
if (isMap) {
isMap = false;
if (typeof(res.length) === "undefined") {
res = [];
}
}
res.push(currentObj);
}
}
for(var j = processedBlocks.length - 1; j >= 0; --j) {
blocks.splice.call(blocks, processedBlocks[j], 1);
}
return res;
}
function semanticAnalysis(blocks) {
var res = processBlock(blocks.children);
return res;
}
function preProcess(src) {
var m;
var lines = src.split("\n");
var r = regex$1["comment"];
for(var i in lines) {
if(m = lines[i].match(r)) {
/* var cmt = "";
if(typeof m[3] != "undefined")
lines[i] = m[1];
else if(typeof m[3] != "undefined")
lines[i] = m[3];
else
lines[i] = "";
*/
if(typeof m[3] !== "undefined") {
lines[i] = m[0].substr(0, m[0].length - m[3].length);
}
}
}
return lines.join("\n");
}
function load(str) {
errors = [];
reference_blocks = [];
processing_time = (new Date()).getTime();
var pre = preProcess(str);
var doc = parser$1(pre);
var res = semanticAnalysis(doc);
processing_time = (new Date()).getTime() - processing_time;
return res;
}
/**
* Fork https://github.com/egoist/docute/blob/master/src/utils/front-matter.js
*/
/* eslint-disable */
var optionalByteOrderMark = '\\ufeff?';
var pattern = '^(' +
optionalByteOrderMark +
'(= yaml =|---)' +
'$([\\s\\S]*?)' +
'(?:\\2|\\.\\.\\.)' +
'$' +
'' +
'(?:\\n)?)';
// NOTE: If this pattern uses the 'g' flag the `regex` variable definition will
// need to be moved down into the functions that use it.
var regex = new RegExp(pattern, 'm');
function extractor (string) {
string = string || '';
var lines = string.split(/(\r?\n)/);
if (lines[0] && /= yaml =|---/.test(lines[0])) {
return parse(string)
} else {
return { attributes: {}, body: string }
}
}
function parse (string) {
var match = regex.exec(string);
if (!match) {
return {
attributes: {},
body: string
}
}
var yaml = match[match.length - 1].replace(/^\s+|\s+$/g, '');
var attributes = load(yaml) || {};
var body = string.replace(match[0], '');
return { attributes: attributes, body: body, frontmatter: yaml }
}
var install = function (hook, vm) {
hook.beforeEach(function (content) {
var ref = extractor(content);
var attributes = ref.attributes;
var body = ref.body;
Docsify.util.merge(vm.config, attributes.config);
return body
});
};
window.$docsify.plugins = [].concat(install, window.$docsify.plugins);
}());
File diff suppressed because one or more lines are too long
+19 -5
View File
@@ -21,7 +21,7 @@ function escapeHtml (string) {
function getAllPaths () {
var paths = [];
helper.dom.findAll('a')
helper.dom.findAll('a:not([data-nosearch])')
.map(function (node) {
var href = node.href;
var originHref = node.getAttribute('href');
@@ -46,13 +46,14 @@ function genIndex (path, content) {
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: token.text });
slug = toURL(path, { id: slugify(token.text) });
index[slug] = { slug: slug, title: token.text, body: '' };
} else {
if (!slug) { return }
@@ -67,7 +68,7 @@ function genIndex (path, content) {
}
}
});
slugify.clear();
return index
}
@@ -169,6 +170,7 @@ function init$1 (config, vm) {
}
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}";
@@ -206,7 +208,7 @@ function bindEvents () {
});
$panel.classList.add('show');
$panel.innerHTML = html || '<p class="empty">No Results!</p>';
$panel.innerHTML = html || ("<p class=\"empty\">" + NO_DATA_TEXT + "</p>");
};
var timeId;
@@ -215,7 +217,7 @@ function bindEvents () {
function (e) { return e.target.tagName !== 'A' && e.stopPropagation(); });
dom.on($input, 'input', function (e) {
clearTimeout(timeId);
timeId = setTimeout(function (_) { return doSearch(e.target.value.trim()); }, 200);
timeId = setTimeout(function (_) { return doSearch(e.target.value.trim()); }, 100);
});
}
@@ -230,6 +232,15 @@ function updatePlaceholder (text, path) {
}
}
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; });
NO_DATA_TEXT = text[match];
}
}
function init$$1 (opts) {
dom = Docsify.dom;
style();
@@ -239,10 +250,12 @@ function init$$1 (opts) {
function update (opts, vm) {
updatePlaceholder(opts.placeholder, vm.route.path);
updateNoData(opts.noData, vm.route.path);
}
var CONFIG = {
placeholder: 'Type to search',
noData: 'No Results!',
paths: 'auto',
maxAge: 86400000 // 1 day
};
@@ -257,6 +270,7 @@ var install = function (hook, vm) {
CONFIG.paths = Array.isArray(opts.paths) ? opts.paths : 'auto';
CONFIG.maxAge = util.isPrimitive(opts.maxAge) ? opts.maxAge : CONFIG.maxAge;
CONFIG.placeholder = opts.placeholder || CONFIG.placeholder;
CONFIG.noData = opts.noData || CONFIG.noData;
}
var isAuto = CONFIG.paths === 'auto';
+1 -1
View File
@@ -1 +1 @@
this.D=this.D||{},function(){"use strict";function e(e){var n={"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#39;","/":"&#x2F;"};return String(e).replace(/[&<>"'\/]/g,function(e){return n[e]})}function n(){var e=[];return d.dom.findAll("a").map(function(n){var t=n.href,r=n.getAttribute("href"),i=d.route.parse(t).path;i&&e.indexOf(i)===-1&&!d.route.isAbsolutePath(r)&&e.push(i)}),e}function t(e){localStorage.setItem("docsify.search.expires",Date.now()+e),localStorage.setItem("docsify.search.index",JSON.stringify(f))}function r(e,n){void 0===n&&(n="");var t,r=window.marked.lexer(n),i=Docsify.route.toURL,o={};return r.forEach(function(n){if("heading"===n.type&&n.depth<=2)t=i(e,{id:n.text}),o[t]={slug:t,title:n.text,body:""};else{if(!t)return;o[t]?o[t].body?o[t].body+="\n"+(n.text||""):o[t].body=n.text:o[t]={slug:t,title:"",body:""}}}),o}function i(n){var t=[],r=[];Object.keys(f).forEach(function(e){r=r.concat(Object.keys(f[e]).map(function(n){return f[e][n]}))}),n=n.trim().split(/[\s\-\\\/]+/);for(var i=function(i){var o=r[i],a=!1,s="",c=o.title&&o.title.trim(),l=o.body&&o.body.trim(),p=o.slug||"";if(c&&l&&(n.forEach(function(n,t){var r=new RegExp(n,"gi"),i=-1,o=-1;if(i=c&&c.search(r),o=l&&l.search(r),i<0&&o<0)a=!1;else{a=!0,o<0&&(o=0);var p=0,u=0;p=o<11?0:o-10,u=0===p?70:o+n.length+60,u>l.length&&(u=l.length);var d="..."+e(l).substring(p,u).replace(r,'<em class="search-keyword">'+n+"</em>")+"...";s+=d}}),a)){var u={title:e(c),content:s,url:p};t.push(u)}},o=0;o<r.length;o++)i(o);return t}function o(e,i){d=Docsify;var o="auto"===e.paths,a=localStorage.getItem("docsify.search.expires")<Date.now();if(f=JSON.parse(localStorage.getItem("docsify.search.index")),a)f={};else if(!o)return;var s=o?n():e.paths,c=s.length,l=0;s.forEach(function(n){return f[n]?l++:void d.get(i.$getFile(n)).then(function(i){f[n]=r(n,i),c===++l&&t(e.maxAge)})})}function a(){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),r=h.find("aside");h.toggleClass(t,"search"),h.before(r,t)}function c(){var e,n=h.find("div.search"),t=h.find(n,"input"),r=h.find(n,".results-panel"),o=function(e){if(!e)return r.classList.remove("show"),void(r.innerHTML="");var n=i(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>"}),r.classList.add("show"),r.innerHTML=t||'<p class="empty">No Results!</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 o(n.target.value.trim())},200)})}function l(e,n){var t=h.getNode('.search input[type="search"]');if("string"==typeof e)t.placeholder=e;else{var r=Object.keys(e).find(function(e){return n.indexOf(e)>-1});t.placeholder=e[r]}}function p(e){h=Docsify.dom,a(),s(e),c()}function u(e,n){l(e.placeholder,n.route.path)}var d,h,f={},g={placeholder:"Type to search",paths:"auto",maxAge:864e5},m=function(e,n){var t=Docsify.util,r=n.config.search||g;Array.isArray(r)?g.paths=r:"object"==typeof r&&(g.paths=Array.isArray(r.paths)?r.paths:"auto",g.maxAge=t.isPrimitive(r.maxAge)?r.maxAge:g.maxAge,g.placeholder=r.placeholder||g.placeholder);var i="auto"===g.paths;e.mounted(function(e){p(g),!i&&o(g,n)}),e.doneEach(function(e){u(g,n),i&&o(g,n)})};window.$docsify.plugins=[].concat(m,window.$docsify.plugins)}();
this.D=this.D||{},function(){"use strict";function e(e){var n={"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#39;","/":"&#x2F;"};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)}();
+304
View File
@@ -0,0 +1,304 @@
this.D = this.D || {};
(function () {
'use strict';
var commonjsGlobal = typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
function createCommonjsModule(fn, module) {
return module = { exports: {} }, fn(module, module.exports), module.exports;
}
var zoomImage = createCommonjsModule(function (module, exports) {
(function (global, factory) {
module.exports = factory();
}(commonjsGlobal, (function () { 'use strict';
var windowWidth = function () { return document.documentElement.clientWidth; };
var windowHeight = function () { return document.documentElement.clientHeight; };
var elemOffset = function (elem) {
var rect = elem.getBoundingClientRect();
var docElem = document.documentElement;
var win = window;
return {
top: rect.top + win.pageYOffset - docElem.clientTop,
left: rect.left + win.pageXOffset - docElem.clientLeft
}
};
var once = function (elem, type, handler) {
var fn = function (e) {
e.target.removeEventListener(type, fn);
handler();
};
elem.addEventListener(type, fn);
};
var Size = function Size(w, h) {
this.w = w;
this.h = h;
};
var ZoomImage = function ZoomImage(img, offset) {
this.img = img;
this.preservedTransform = img.style.transform;
this.wrap = null;
this.overlay = null;
this.offset = offset;
};
ZoomImage.prototype.forceRepaint = function forceRepaint () {
var _ = this.img.offsetWidth;
return
};
ZoomImage.prototype.zoom = function zoom () {
var size = new Size(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 scale = this.calculateScale(size);
this.forceRepaint();
this.animate(scale);
document.body.classList.add('zoom-overlay-open');
};
ZoomImage.prototype.calculateScale = function calculateScale (size) {
var maxScaleFactor = size.w / this.img.width;
var viewportWidth = (windowWidth() - this.offset);
var viewportHeight = (windowHeight() - this.offset);
var imageAspectRatio = size.w / size.h;
var viewportAspectRatio = viewportWidth / viewportHeight;
if (size.w < viewportWidth && size.h < viewportHeight) {
return maxScaleFactor
} else if (imageAspectRatio < viewportAspectRatio) {
return (viewportHeight / size.h) * maxScaleFactor
}
return (viewportWidth / size.w) * maxScaleFactor
};
ZoomImage.prototype.animate = function animate (scale) {
var imageOffset = elemOffset(this.img);
var scrollTop = window.pageYOffset;
var viewportX = (windowWidth() / 2);
var viewportY = scrollTop + (windowHeight() / 2);
var imageCenterX = imageOffset.left + (this.img.width / 2);
var imageCenterY = imageOffset.top + (this.img.height / 2);
var tx = viewportX - imageCenterX;
var ty = viewportY - imageCenterY;
var tz = 0;
var imgTr = "scale(" + scale + ")";
var wrapTr = "translate3d(" + tx + "px, " + ty + "px, " + tz + "px)";
this.img.style.transform = imgTr;
this.wrap.style.transform = wrapTr;
};
ZoomImage.prototype.dispose = function dispose () {
if (this.wrap === null || this.wrap.parentNode === null) {
return
}
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');
};
ZoomImage.prototype.close = function close () {
var this$1 = this;
document.body.classList.add('zoom-overlay-transitioning');
this.img.style.transform = this.preservedTransform;
if (this.img.style.length === 0) {
this.img.removeAttribute('style');
}
this.wrap.style.transform = 'none';
once(this.img, 'transitionend', function () {
this$1.dispose();
// remove class should happen after dispose. Otherwise,
// a new click event could fire and create a duplicate ZoomImage for
// the same <img> element.
document.body.classList.remove('zoom-overlay-open');
});
};
/**
* Pure JavaScript implementation of zoom.js.
*
* Original preamble:
* zoom.js - It's the best way to zoom an image
* @version v0.0.2
* @link https://github.com/fat/zoom.js
* @license MIT
*
* Needs a related CSS file to work. See the README at
* https://github.com/nishanths/zoom.js for more info.
*
* This is a fork of the original zoom.js implementation by @fat.
* Copyrights for the original project are held by @fat. All other copyright
* for changes in the fork are held by Nishanth Shanmugham.
*
* Copyright (c) 2013 @fat
* The MIT License. Copyright © 2016 Nishanth Shanmugham.
*/
var current = null;
var offset = 80;
var initialScrollPos = -1;
var initialTouchPos = -1;
function handleScroll() {
if (initialScrollPos === -1) {
initialScrollPos = window.pageYOffset;
}
var deltaY = Math.abs(initialScrollPos - window.pageYOffset);
if (deltaY >= 40) {
closeCurrent();
}
}
function handleKeyup(e) {
if (e.keyCode === 27) {
closeCurrent();
}
}
function handleTouchStart(e) {
var t = e.touches[0];
if (t === null) {
return
}
initialTouchPos = t.pageY;
e.target.addEventListener('touchmove', handleTouchMove);
}
function handleTouchMove(e) {
var t = e.touches[0];
if (t === null) {
return
}
if (Math.abs(t.pageY - initialTouchPos) > 10) {
closeCurrent();
e.target.removeEventListener('touchmove', handleTouchMove);
}
}
function handleClick() {
closeCurrent();
}
function addCloseListeners() {
document.addEventListener('scroll', handleScroll);
document.addEventListener('keyup', handleKeyup);
document.addEventListener('touchstart', handleTouchStart);
document.addEventListener('click', handleClick, true);
}
function removeCloseListeners() {
document.removeEventListener('scroll', handleScroll);
document.removeEventListener('keyup', handleKeyup);
document.removeEventListener('touchstart', handleTouchStart);
document.removeEventListener('click', handleClick, true);
}
function closeCurrent(force) {
if (current === null) {
return
}
if (force) {
current.dispose();
} else {
current.close();
}
removeCloseListeners();
current = null;
}
function prepareZoom(e) {
if (document.body.classList.contains('zoom-overlay-open')) {
return
}
if (e.metaKey || e.ctrlKey) {
window.open((e.target.getAttribute('data-original') || e.target.src), '_blank');
return
}
if (e.target.width >= windowWidth() - offset) {
return
}
closeCurrent(true);
current = new ZoomImage(e.target, offset);
current.zoom();
addCloseListeners();
}
var zoom = function (el) {
el.setAttribute('data-action', 'zoom');
el.addEventListener('click', prepareZoom);
return function () { return el.removeEventListener('click', prepareZoom); }
};
return zoom;
})));
});
var style = "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";
function install (hook) {
var dom = Docsify.dom;
var destroys;
// add style
dom.appendTo(dom.head, dom.create('style', style));
hook.doneEach(function (_) {
var images = dom.findAll('img:not(.emoji)');
if (Array.isArray(destroys) && destroys.length) {
destroys.forEach(function (o) { return o(); });
destroys = [];
}
destroys = images.map(zoomImage);
});
}
$docsify.plugins = [].concat(install, $docsify.plugins);
}());
+1
View File
@@ -0,0 +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)}();
+1 -1
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
File diff suppressed because one or more lines are too long
+4 -2
View File
@@ -1,6 +1,6 @@
{
"name": "docsify",
"version": "3.0.5",
"version": "3.4.0",
"description": "A magical documentation generator.",
"main": "lib/docsify.js",
"files": [
@@ -40,11 +40,13 @@
"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"
"prismjs": "^1.5.1",
"zoom-image": "^0.1.4"
}
}
+14 -12
View File
@@ -1,14 +1,23 @@
import { get } from './ajax'
import { callHook } from '../init/lifecycle'
import { getRoot } from '../route/util'
import { getParentPath } from '../route/util'
import { noop } from '../util/core'
function loadNested (path, file, next, vm, first) {
path = first ? path : path.replace(/\/$/, '')
path = getParentPath(path)
if (!path) return
get(vm.$getFile(path + file))
.then(next, _ => loadNested(path, file, next, vm))
}
export function fetchMixin (proto) {
let last
proto._fetch = function (cb = noop) {
const { path } = this.route
const { loadNavbar, loadSidebar } = this.config
const root = getRoot(path)
// Abort last request
last && last.abort && last.abort()
@@ -26,25 +35,18 @@ export function fetchMixin (proto) {
const fn = result => { this._renderSidebar(result); cb() }
// Load sidebar
get(this.$getFile(root + loadSidebar))
// fallback root navbar when fail
.then(fn, _ => get(loadSidebar).then(fn))
loadNested(path, loadSidebar, fn, this, true)
},
_ => this._renderMain(null))
// Load nav
loadNavbar &&
get(this.$getFile(root + loadNavbar))
.then(
text => this._renderNav(text),
// fallback root navbar when fail
_ => get(loadNavbar).then(text => this._renderNav(text))
)
loadNested(path, loadNavbar, text => this._renderNav(text), this, true)
}
proto._fetchCover = function () {
const { coverpage } = this.config
const root = getRoot(this.route.path)
const root = getParentPath(this.route.path)
const path = this.$getFile(root + coverpage)
if (this.route.path !== '/' || !coverpage) {
+2 -1
View File
@@ -2,12 +2,13 @@ import * as util from './util'
import * as dom from './util/dom'
import * as render from './render/compiler'
import * as route from './route/hash'
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 }
window.Docsify = { util, dom, render, route, get, slugify }
window.marked = marked
window.Prism = prism
}
+4 -4
View File
@@ -2,7 +2,7 @@ import marked from 'marked'
import Prism from 'prismjs'
import { helper as helperTpl, tree as treeTpl } from './tpl'
import { genTree } from './gen-tree'
import { slugify, clearSlugCache } from './slugify'
import { slugify } from './slugify'
import { emojify } from './emojify'
import { toURL, parse } from '../route/hash'
import { getBasePath, isAbsolutePath, getPath } from '../route/util'
@@ -25,7 +25,7 @@ export const markdown = cached(text => {
html = markdownCompiler(text)
html = emojify(html)
clearSlugCache()
slugify.clear()
return html
})
@@ -34,7 +34,6 @@ markdown.renderer = renderer
markdown.init = function (config = {}, base = window.location.pathname) {
contentBase = getBasePath(base)
currentPath = parse().path
if (isFn(config)) {
markdownCompiler = config(marked, renderer)
@@ -107,8 +106,9 @@ export function sidebar (text, level) {
html = markdown(text)
html = html.match(/<ul[^>]*>([\s\S]+)<\/ul>/g)[0]
} else {
const tree = genTree(toc, level)
const tree = cacheTree[currentPath] || genTree(toc, level)
html = treeTpl(tree, '<ul>')
cacheTree[currentPath] = tree
}
return html
+6 -2
View File
@@ -1,6 +1,10 @@
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 text
.replace(/<(pre|template)[^>]*?>([\s\S]+)<\/(pre|template)>/g, m => m.replace(/:/g, '__colon__'))
.replace(/:(\w+?):/ig, '<img class="emoji" src="https://assets-cdn.github.com/images/icons/emoji/$1.png" alt="$1" />')
.replace(/<(pre|template|code)[^>]*?>[\s\S]+?<\/(pre|template|code)>/g, m => m.replace(/:/g, '__colon__'))
.replace(/:(\w+?):/ig, window.emojify || replace)
.replace(/__colon__/g, ':')
}
+23 -2
View File
@@ -6,6 +6,7 @@ import * as tpl from './tpl'
import { markdown, sidebar, subSidebar, cover } from './compiler'
import { callHook } from '../init/lifecycle'
import { getBasePath, getPath, isAbsolutePath } from '../route/util'
import { isPrimitive } from '../util/core'
function executeScript () {
const script = dom.findAll('.markdown-section>script')
@@ -47,6 +48,22 @@ function renderMain (html) {
}
}
function renderNameLink (vm) {
const el = dom.getNode('.app-name-link')
const nameLink = vm.config.nameLink
const path = vm.route.path
if (!el) return
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)
el.setAttribute('href', nameLink[match])
}
}
export function renderMixin (proto) {
proto._renderTo = function (el, content, replace) {
const node = dom.getNode(el)
@@ -58,7 +75,7 @@ export function renderMixin (proto) {
this._renderTo('.sidebar-nav', sidebar(text, maxLevel))
const active = getAndActive('.sidebar-nav', true, true)
loadSidebar && subSidebar(active, subMaxLevel)
subSidebar(loadSidebar ? active : '', subMaxLevel)
// bind event
this.activeLink = active
scrollActiveSidebar()
@@ -104,10 +121,12 @@ export function renderMixin (proto) {
let path = m[1]
dom.toggleClass(el, 'add', 'has-mask')
if (isAbsolutePath(m[1])) {
if (!isAbsolutePath(m[1])) {
path = getPath(getBasePath(this.config.basePath), m[1])
}
el.style.backgroundImage = `url(${path})`
el.style.backgroundSize = 'cover'
el.style.backgroundPosition = 'center center'
}
html = html.replace(m[0], '')
}
@@ -118,6 +137,8 @@ export function renderMixin (proto) {
proto._updateRender = function () {
markdown.update()
// render name link
renderNameLink(this)
}
}
+1 -1
View File
@@ -22,6 +22,6 @@ export function slugify (str) {
return slug
}
export function clearSlugCache () {
slugify.clear = function () {
cache = {}
}
+2 -2
View File
@@ -16,7 +16,7 @@ export function corner (data) {
'<path d="M128.3,109.0 C113.8,99.7 119.0,89.6 119.0,89.6 C122.0,82.7 120.5,78.6 120.5,78.6 C119.2,72.0 123.4,76.3 123.4,76.3 C127.3,80.9 125.5,87.3 125.5,87.3 C122.9,97.6 130.6,101.9 134.4,103.2" fill="currentColor" style="transform-origin: 130px 106px;" class="octo-arm"></path>' +
'<path d="M115.0,115.0 C114.9,115.1 118.7,116.5 119.8,115.4 L133.7,101.6 C136.9,99.2 139.9,98.4 142.2,98.6 C133.8,88.0 127.5,74.4 143.8,58.0 C148.5,53.4 154.0,51.2 159.7,51.0 C160.3,49.4 163.2,43.6 171.4,40.1 C171.4,40.1 176.1,42.5 178.8,56.2 C183.1,58.6 187.2,61.8 190.9,65.4 C194.5,69.0 197.7,73.2 200.1,77.6 C213.8,80.2 216.3,84.9 216.3,84.9 C212.7,93.1 206.9,96.0 205.4,96.6 C205.1,102.4 203.0,107.8 198.3,112.5 C181.9,128.9 168.3,122.5 157.7,114.1 C157.9,116.9 156.7,120.9 152.7,124.9 L141.0,136.5 C139.8,137.7 141.6,141.9 141.8,141.8 Z" fill="currentColor" class="octo-body"></path>' +
'</svg>' +
'</a>`')
'</a>')
}
/**
@@ -31,7 +31,7 @@ export function main (config) {
'</button>' +
'<aside class="sidebar">' +
(config.name
? `<h1><a href="${config.nameLink}">${config.name}</a></h1>`
? `<h1><a class="app-name-link" data-nosearch>${config.name}</a></h1>`
: '') +
'<div class="sidebar-nav"></div>' +
'</aside>')
+1
View File
@@ -34,6 +34,7 @@ let lastRoute = {}
export function initRoute (vm) {
normalize()
lastRoute = vm.route = parse()
vm._updateRender()
on('hashchange', _ => {
normalize()
+6 -2
View File
@@ -45,8 +45,12 @@ export const isAbsolutePath = cached(path => {
return /(:|(\/{2}))/.test(path)
})
export const getRoot = cached(path => {
return /\/$/g.test(path) ? path : path.match(/(\S*\/)[^\/]+$/)[1]
export const getParentPath = cached(path => {
return /\/$/g.test(path)
? path
: (path = path.match(/(\S*\/)[^\/]+$/))
? path[1]
: ''
})
export const cleanPath = cached(path => {
+1 -1
View File
@@ -10,7 +10,7 @@ const cacheNode = {}
*/
export function getNode (el, noCache = false) {
if (typeof el === 'string') {
el = noCache ? find(el) : (cacheNode[el] || find(el))
el = noCache ? find(el) : (cacheNode[el] || (cacheNode[el] = find(el)))
}
return el
+153
View File
@@ -0,0 +1,153 @@
const AllGithubEmoji = ['+1', '100', '1234', '8ball', 'a', 'ab', 'abc', 'abcd',
'accept', 'aerial_tramway', 'airplane', 'alarm_clock', 'alien', 'ambulance',
'anchor', 'angel', 'anger', 'angry', 'anguished', 'ant', 'apple', 'aquarius',
'aries', 'arrow_backward', 'arrow_double_down', 'arrow_double_up', 'arrow_down',
'arrow_down_small', 'arrow_forward', 'arrow_heading_down', 'arrow_heading_up',
'arrow_left', 'arrow_lower_left', 'arrow_lower_right', 'arrow_right',
'arrow_right_hook', 'arrow_up', 'arrow_up_down', 'arrow_up_small', 'arrow_upper_left',
'arrow_upper_right', 'arrows_clockwise', 'arrows_counterclockwise', 'art',
'articulated_lorry', 'astonished', 'athletic_shoe', 'atm', 'b', 'baby', 'baby_bottle',
'baby_chick', 'baby_symbol', 'back', 'baggage_claim', 'balloon', 'ballot_box_with_check',
'bamboo', 'banana', 'bangbang', 'bank', 'bar_chart', 'barber', 'baseball', 'basketball',
'bath', 'bathtub', 'battery', 'bear', 'bee', 'beer', 'beers', 'beetle', 'beginner',
'bell', 'bento', 'bicyclist', 'bike', 'bikini', 'bird', 'birthday', 'black_circle',
'black_joker', 'black_large_square', 'black_medium_small_square', 'black_medium_square',
'black_nib', 'black_small_square', 'black_square_button', 'blossom', 'blowfish',
'blue_book', 'blue_car', 'blue_heart', 'blush', 'boar', 'boat', 'bomb', 'book',
'bookmark', 'bookmark_tabs', 'books', 'boom', 'boot', 'bouquet', 'bow', 'bowling',
'bowtie', 'boy', 'bread', 'bride_with_veil', 'bridge_at_night', 'briefcase',
'broken_heart', 'bug', 'bulb', 'bullettrain_front', 'bullettrain_side', 'bus',
'busstop', 'bust_in_silhouette', 'busts_in_silhouette', 'cactus', 'cake', 'calendar',
'calling', 'camel', 'camera', 'cancer', 'candy', 'capital_abcd', 'capricorn', 'car',
'card_index', 'carousel_horse', 'cat', 'cat2', 'cd', 'chart', 'chart_with_downwards_trend',
'chart_with_upwards_trend', 'checkered_flag', 'cherries', 'cherry_blossom', 'chestnut',
'chicken', 'children_crossing', 'chocolate_bar', 'christmas_tree', 'church', 'cinema',
'circus_tent', 'city_sunrise', 'city_sunset', 'cl', 'clap', 'clapper', 'clipboard',
'clock1', 'clock10', 'clock1030', 'clock11', 'clock1130', 'clock12', 'clock1230',
'clock130', 'clock2', 'clock230', 'clock3', 'clock330', 'clock4', 'clock430',
'clock5', 'clock530', 'clock6', 'clock630', 'clock7', 'clock730', 'clock8', 'clock830',
'clock9', 'clock930', 'closed_book', 'closed_lock_with_key', 'closed_umbrella',
'cloud', 'clubs', 'cn', 'cocktail', 'coffee', 'cold_sweat', 'collision', 'computer',
'confetti_ball', 'confounded', 'confused', 'congratulations', 'construction',
'construction_worker', 'convenience_store', 'cookie', 'cool', 'cop', 'copyright',
'corn', 'couple', 'couple_with_heart', 'couplekiss', 'cow', 'cow2', 'credit_card',
'crescent_moon', 'crocodile', 'crossed_flags', 'crown', 'cry', 'crying_cat_face',
'crystal_ball', 'cupid', 'curly_loop', 'currency_exchange', 'curry', 'custard',
'customs', 'cyclone', 'dancer', 'dancers', 'dango', 'dart', 'dash', 'date', 'de',
'deciduous_tree', 'department_store', 'diamond_shape_with_a_dot_inside', 'diamonds',
'disappointed', 'disappointed_relieved', 'dizzy', 'dizzy_face', 'do_not_litter',
'dog', 'dog2', 'dollar', 'dolls', 'dolphin', 'door', 'doughnut', 'dragon',
'dragon_face', 'dress', 'dromedary_camel', 'droplet', 'dvd', 'e-mail', 'ear',
'ear_of_rice', 'earth_africa', 'earth_americas', 'earth_asia', 'egg', 'eggplant',
'eight', 'eight_pointed_black_star', 'eight_spoked_asterisk', 'electric_plug',
'elephant', 'email', 'end', 'envelope', 'envelope_with_arrow', 'es', 'euro',
'european_castle', 'european_post_office', 'evergreen_tree', 'exclamation',
'expressionless', 'eyeglasses', 'eyes', 'facepunch', 'factory', 'fallen_leaf',
'family', 'fast_forward', 'fax', 'fearful', 'feelsgood', 'feet', 'ferris_wheel',
'file_folder', 'finnadie', 'fire', 'fire_engine', 'fireworks', 'first_quarter_moon',
'first_quarter_moon_with_face', 'fish', 'fish_cake', 'fishing_pole_and_fish',
'fist', 'five', 'flags', 'flashlight', 'flipper', 'floppy_disk', 'flower_playing_cards',
'flushed', 'foggy', 'football', 'footprints', 'fork_and_knife', 'fountain',
'four', 'four_leaf_clover', 'fr', 'free', 'fried_shrimp', 'fries', 'frog',
'frowning', 'fu', 'fuelpump', 'full_moon', 'full_moon_with_face', 'game_die',
'gb', 'gem', 'gemini', 'ghost', 'gift', 'gift_heart', 'girl', 'globe_with_meridians',
'goat', 'goberserk', 'godmode', 'golf', 'grapes', 'green_apple', 'green_book',
'green_heart', 'grey_exclamation', 'grey_question', 'grimacing', 'grin',
'grinning', 'guardsman', 'guitar', 'gun', 'haircut', 'hamburger', 'hammer',
'hamster', 'hand', 'handbag', 'hankey', 'hash', 'hatched_chick', 'hatching_chick',
'headphones', 'hear_no_evil', 'heart', 'heart_decoration', 'heart_eyes',
'heart_eyes_cat', 'heartbeat', 'heartpulse', 'hearts', 'heavy_check_mark',
'heavy_division_sign', 'heavy_dollar_sign', 'heavy_exclamation_mark', 'heavy_minus_sign',
'heavy_multiplication_x', 'heavy_plus_sign', 'helicopter', 'herb', 'hibiscus',
'high_brightness', 'high_heel', 'hocho', 'honey_pot', 'honeybee', 'horse',
'horse_racing', 'hospital', 'hotel', 'hotsprings', 'hourglass', 'hourglass_flowing_sand',
'house', 'house_with_garden', 'hurtrealbad', 'hushed', 'ice_cream', 'icecream',
'id', 'ideograph_advantage', 'imp', 'inbox_tray', 'incoming_envelope',
'information_desk_person', 'information_source', 'innocent', 'interrobang',
'iphone', 'it', 'izakaya_lantern', 'jack_o_lantern', 'japan', 'japanese_castle',
'japanese_goblin', 'japanese_ogre', 'jeans', 'joy', 'joy_cat', 'jp', 'key',
'keycap_ten', 'kimono', 'kiss', 'kissing', 'kissing_cat', 'kissing_closed_eyes',
'kissing_heart', 'kissing_smiling_eyes', 'koala', 'koko', 'kr', 'lantern',
'large_blue_circle', 'large_blue_diamond', 'large_orange_diamond', 'last_quarter_moon',
'last_quarter_moon_with_face', 'laughing', 'leaves', 'ledger', 'left_luggage',
'left_right_arrow', 'leftwards_arrow_with_hook', 'lemon', 'leo', 'leopard',
'libra', 'light_rail', 'link', 'lips', 'lipstick', 'lock', 'lock_with_ink_pen',
'lollipop', 'loop', 'loud_sound', 'loudspeaker', 'love_hotel', 'love_letter',
'low_brightness', 'm', 'mag', 'mag_right', 'mahjong', 'mailbox', 'mailbox_closed',
'mailbox_with_mail', 'mailbox_with_no_mail', 'man', 'man_with_gua_pi_mao',
'man_with_turban', 'mans_shoe', 'maple_leaf', 'mask', 'massage', 'meat_on_bone',
'mega', 'melon', 'memo', 'mens', 'metal', 'metro', 'microphone', 'microscope',
'milky_way', 'minibus', 'minidisc', 'mobile_phone_off', 'money_with_wings',
'moneybag', 'monkey', 'monkey_face', 'monorail', 'moon', 'mortar_board', 'mount_fuji',
'mountain_bicyclist', 'mountain_cableway', 'mountain_railway', 'mouse', 'mouse2',
'movie_camera', 'moyai', 'muscle', 'mushroom', 'musical_keyboard', 'musical_note',
'musical_score', 'mute', 'nail_care', 'name_badge', 'neckbeard', 'necktie',
'negative_squared_cross_mark', 'neutral_face', 'new', 'new_moon', 'new_moon_with_face',
'newspaper', 'ng', 'night_with_stars', 'nine', 'no_bell', 'no_bicycles', 'no_entry',
'no_entry_sign', 'no_good', 'no_mobile_phones', 'no_mouth', 'no_pedestrians',
'no_smoking', 'non-potable_water', 'nose', 'notebook', 'notebook_with_decorative_cover',
'notes', 'nut_and_bolt', 'o', 'o2', 'ocean', 'octocat', 'octopus', 'oden', 'office',
'ok', 'ok_hand', 'ok_woman', 'older_man', 'older_woman', 'on', 'oncoming_automobile',
'oncoming_bus', 'oncoming_police_car', 'oncoming_taxi', 'one', 'open_book',
'open_file_folder', 'open_hands', 'open_mouth', 'ophiuchus', 'orange_book',
'outbox_tray', 'ox', 'package', 'page_facing_up', 'page_with_curl', 'pager',
'palm_tree', 'panda_face', 'paperclip', 'parking', 'part_alternation_mark',
'partly_sunny', 'passport_control', 'paw_prints', 'peach', 'pear', 'pencil',
'pencil2', 'penguin', 'pensive', 'performing_arts', 'persevere', 'person_frowning',
'person_with_blond_hair', 'person_with_pouting_face', 'phone', 'pig', 'pig2',
'pig_nose', 'pill', 'pineapple', 'pisces', 'pizza', 'point_down', 'point_left',
'point_right', 'point_up', 'point_up_2', 'police_car', 'poodle', 'poop',
'post_office', 'postal_horn', 'postbox', 'potable_water', 'pouch', 'poultry_leg',
'pound', 'pouting_cat', 'pray', 'princess', 'punch', 'purple_heart', 'purse',
'pushpin', 'put_litter_in_its_place', 'question', 'rabbit', 'rabbit2', 'racehorse',
'radio', 'radio_button', 'rage', 'rage1', 'rage2', 'rage3', 'rage4', 'railway_car',
'rainbow', 'raised_hand', 'raised_hands', 'raising_hand', 'ram', 'ramen', 'rat',
'recycle', 'red_car', 'red_circle', 'registered', 'relaxed', 'relieved', 'repeat',
'repeat_one', 'restroom', 'revolving_hearts', 'rewind', 'ribbon', 'rice',
'rice_ball', 'rice_cracker', 'rice_scene', 'ring', 'rocket', 'roller_coaster',
'rooster', 'rose', 'rotating_light', 'round_pushpin', 'rowboat', 'ru', 'rugby_football',
'runner', 'running', 'running_shirt_with_sash', 'sa', 'sagittarius', 'sailboat',
'sake', 'sandal', 'santa', 'satellite', 'satisfied', 'saxophone', 'school',
'school_satchel', 'scissors', 'scorpius', 'scream', 'scream_cat', 'scroll',
'seat', 'secret', 'see_no_evil', 'seedling', 'seven', 'shaved_ice', 'sheep',
'shell', 'ship', 'shipit', 'shirt', 'shit', 'shoe', 'shower', 'signal_strength',
'six', 'six_pointed_star', 'ski', 'skull', 'sleeping', 'sleepy', 'slot_machine',
'small_blue_diamond', 'small_orange_diamond', 'small_red_triangle',
'small_red_triangle_down', 'smile', 'smile_cat', 'smiley', 'smiley_cat',
'smiling_imp', 'smirk', 'smirk_cat', 'smoking', 'snail', 'snake', 'snowboarder',
'snowflake', 'snowman', 'sob', 'soccer', 'soon', 'sos', 'sound', 'space_invader',
'spades', 'spaghetti', 'sparkle', 'sparkler', 'sparkles', 'sparkling_heart',
'speak_no_evil', 'speaker', 'speech_balloon', 'speedboat', 'squirrel', 'star',
'star2', 'stars', 'station', 'statue_of_liberty', 'steam_locomotive', 'stew',
'straight_ruler', 'strawberry', 'stuck_out_tongue', 'stuck_out_tongue_closed_eyes',
'stuck_out_tongue_winking_eye', 'sun_with_face', 'sunflower', 'sunglasses',
'sunny', 'sunrise', 'sunrise_over_mountains', 'surfer', 'sushi', 'suspect',
'suspension_railway', 'sweat', 'sweat_drops', 'sweat_smile', 'sweet_potato',
'swimmer', 'symbols', 'syringe', 'tada', 'tanabata_tree', 'tangerine', 'taurus',
'taxi', 'tea', 'telephone', 'telephone_receiver', 'telescope', 'tennis', 'tent',
'thought_balloon', 'three', 'thumbsdown', 'thumbsup', 'ticket', 'tiger', 'tiger2',
'tired_face', 'tm', 'toilet', 'tokyo_tower', 'tomato', 'tongue', 'top', 'tophat',
'tractor', 'traffic_light', 'train', 'train2', 'tram', 'triangular_flag_on_post',
'triangular_ruler', 'trident', 'triumph', 'trolleybus', 'trollface', 'trophy',
'tropical_drink', 'tropical_fish', 'truck', 'trumpet', 'tshirt', 'tulip',
'turtle', 'tv', 'twisted_rightwards_arrows', 'two', 'two_hearts', 'two_men_holding_hands',
'two_women_holding_hands', 'u5272', 'u5408', 'u55b6', 'u6307', 'u6708', 'u6709',
'u6e80', 'u7121', 'u7533', 'u7981', 'u7a7a', 'uk', 'umbrella', 'unamused',
'underage', 'unlock', 'up', 'us', 'v', 'vertical_traffic_light', 'vhs',
'vibration_mode', 'video_camera', 'video_game', 'violin', 'virgo', 'volcano',
'vs', 'walking', 'waning_crescent_moon', 'waning_gibbous_moon', 'warning',
'watch', 'water_buffalo', 'watermelon', 'wave', 'wavy_dash', 'waxing_crescent_moon',
'waxing_gibbous_moon', 'wc', 'weary', 'wedding', 'whale', 'whale2', 'wheelchair',
'white_check_mark', 'white_circle', 'white_flower', 'white_large_square',
'white_medium_small_square', 'white_medium_square', 'white_small_square',
'white_square_button', 'wind_chime', 'wine_glass', 'wink', 'wolf', 'woman',
'womans_clothes', 'womans_hat', 'womens', 'worried', 'wrench', 'x', 'yellow_heart',
'yen', 'yum', 'zap', 'zero', 'zzz']
// emoji from All-Github-Emoji-Icons
// https://github.com/scotch-io/All-Github-Emoji-Icons
window.emojify = function (match, $1) {
return AllGithubEmoji.indexOf($1) === -1
? match
: '<img class="emoji" src="https://assets-cdn.github.com/images/icons/emoji/' + $1 + '.png" alt="' + $1 + '" />'
}
+21
View File
@@ -0,0 +1,21 @@
function handleExternalScript () {
const container = Docsify.dom.getNode('#main')
const script = Docsify.dom.find(container, 'script')
if (script && script.src) {
const newScript = document.createElement('script')
;['src', 'async', 'defer'].forEach(attribute => {
newScript[attribute] = script[attribute]
})
script.parentNode.removeChild(script)
container.appendChild(newScript)
}
}
const install = function (hook) {
hook.doneEach(handleExternalScript)
}
window.$docsify.plugins = [].concat(install, window.$docsify.plugins)
+13 -2
View File
@@ -1,6 +1,7 @@
import { search } from './search'
let dom
let NO_DATA_TEXT = ''
function style () {
const code = `
@@ -98,7 +99,7 @@ function bindEvents () {
})
$panel.classList.add('show')
$panel.innerHTML = html || '<p class="empty">No Results!</p>'
$panel.innerHTML = html || `<p class="empty">${NO_DATA_TEXT}</p>`
}
let timeId
@@ -107,7 +108,7 @@ function bindEvents () {
e => e.target.tagName !== 'A' && e.stopPropagation())
dom.on($input, 'input', e => {
clearTimeout(timeId)
timeId = setTimeout(_ => doSearch(e.target.value.trim()), 200)
timeId = setTimeout(_ => doSearch(e.target.value.trim()), 100)
})
}
@@ -122,6 +123,15 @@ function updatePlaceholder (text, path) {
}
}
function updateNoData (text, path) {
if (typeof text === 'string') {
NO_DATA_TEXT = text
} else {
const match = Object.keys(text).find(key => path.indexOf(key) > -1)
NO_DATA_TEXT = text[match]
}
}
export function init (opts) {
dom = Docsify.dom
style()
@@ -131,5 +141,6 @@ export function init (opts) {
export function update (opts, vm) {
updatePlaceholder(opts.placeholder, vm.route.path)
updateNoData(opts.noData, vm.route.path)
}
+2
View File
@@ -3,6 +3,7 @@ import { init as initSearch } from './search'
const CONFIG = {
placeholder: 'Type to search',
noData: 'No Results!',
paths: 'auto',
maxAge: 86400000 // 1 day
}
@@ -17,6 +18,7 @@ const install = function (hook, vm) {
CONFIG.paths = Array.isArray(opts.paths) ? opts.paths : 'auto'
CONFIG.maxAge = util.isPrimitive(opts.maxAge) ? opts.maxAge : CONFIG.maxAge
CONFIG.placeholder = opts.placeholder || CONFIG.placeholder
CONFIG.noData = opts.noData || CONFIG.noData
}
const isAuto = CONFIG.paths === 'auto'
+4 -3
View File
@@ -17,7 +17,7 @@ function escapeHtml (string) {
function getAllPaths () {
const paths = []
helper.dom.findAll('a')
helper.dom.findAll('a:not([data-nosearch])')
.map(node => {
const href = node.href
const originHref = node.getAttribute('href')
@@ -40,13 +40,14 @@ function saveData (maxAge) {
export function genIndex (path, content = '') {
const tokens = window.marked.lexer(content)
const slugify = window.Docsify.slugify
const toURL = Docsify.route.toURL
const index = {}
let slug
tokens.forEach(token => {
if (token.type === 'heading' && token.depth <= 2) {
slug = toURL(path, { id: token.text })
slug = toURL(path, { id: slugify(token.text) })
index[slug] = { slug, title: token.text, body: '' }
} else {
if (!slug) return
@@ -61,7 +62,7 @@ export function genIndex (path, content = '') {
}
}
})
slugify.clear()
return index
}
+23
View File
@@ -0,0 +1,23 @@
import zoom from 'zoom-image'
import style from 'zoom-image/css/zoom-image.css'
function install (hook) {
const dom = Docsify.dom
let destroys
// add style
dom.appendTo(dom.head, dom.create('style', style))
hook.doneEach(_ => {
const images = dom.findAll('img:not(.emoji)')
if (Array.isArray(destroys) && destroys.length) {
destroys.forEach(o => o())
destroys = []
}
destroys = images.map(zoom)
})
}
$docsify.plugins = [].concat(install, $docsify.plugins)
+1 -1
View File
@@ -10,7 +10,7 @@
body:not(.ready) {
overflow: hidden;
[data-cloak] {
[data-cloak], nav {
display: none;
}
}