mirror of
https://github.com/wahyd4/docsify.git
synced 2026-08-09 21:36:10 +10:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0ae14e8ddc | ||
|
|
61e0aacb43 | ||
|
|
b927a30cc6 | ||
|
|
0d59ee939f | ||
|
|
0aead898eb | ||
|
|
d3c9fbd124 | ||
|
|
f3fc596951 | ||
|
|
07a2a91296 | ||
|
|
8ad835ca26 | ||
|
|
0994663c5a | ||
|
|
5067769a65 | ||
|
|
92d6e8a1ee | ||
|
|
0dd9feffe5 | ||
|
|
82173627e5 | ||
|
|
507d9e834c | ||
|
|
83ae93cae0 | ||
|
|
8f9bf29ee5 | ||
|
|
d67d25fed4 | ||
|
|
95a324c7e0 | ||
|
|
5712c1f59d | ||
|
|
490a2cd64e | ||
|
|
b8a3d8f380 | ||
|
|
855c450a97 | ||
|
|
2521c58c73 | ||
|
|
8df746e9d1 | ||
|
|
2945e94e3c | ||
|
|
083cc4af56 | ||
|
|
5cab56cc92 | ||
|
|
d8ad679e2c | ||
|
|
f2975a5e5e | ||
|
|
58789bfec7 | ||
|
|
e7e519bad2 | ||
|
|
f7111b5903 | ||
|
|
42b2dba589 | ||
|
|
2a1157a706 | ||
|
|
3394ebb9a5 | ||
|
|
b4fc6a9d72 | ||
|
|
feb4b89461 |
@@ -1,4 +1,38 @@
|
||||
|
||||
3.2.0 / 2017-02-28
|
||||
==================
|
||||
|
||||
* fix(render): Toc rendering error, fixed #106
|
||||
* feat(search): Localization for no data tip, close #103
|
||||
* fix(fetch): load sidebar and navbar for parent path, fixed #100
|
||||
* feat(render) nameLink for each route, fixed #99
|
||||
|
||||
3.1.2 / 2017-02-27
|
||||
==================
|
||||
|
||||
* fix(search): dont search nameLink, fixed #102
|
||||
|
||||
3.1.1 / 2017-02-24
|
||||
==================
|
||||
|
||||
* fix(search): dont search nameLink, fixed #102
|
||||
* fix(render): custom cover background image
|
||||
* fix(tpl): extra character, fixed #101
|
||||
|
||||
3.1.0 / 2017-02-22
|
||||
==================
|
||||
|
||||
* fix(search): incorrect anchor link, fixed #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
|
||||
|
||||
3.0.4 / 2017-02-20
|
||||
==================
|
||||
|
||||
|
||||
@@ -19,8 +19,9 @@
|
||||
- [CLI](https://github.com/QingWei-Li/docsify-cli)
|
||||
|
||||
## Features
|
||||
- Not build static html files
|
||||
- Simple and lightweight (~14kB gzipped)
|
||||
|
||||
- No statically built html files
|
||||
- Simple and lightweight (~16kB gzipped)
|
||||
- Smart full-text search plugin
|
||||
- Multiple themes
|
||||
- Useful plugin API
|
||||
@@ -29,9 +30,9 @@
|
||||
## Quick start
|
||||
Create a `index.html`.
|
||||
|
||||
index.html
|
||||
|
||||
```html
|
||||
<!-- index.html -->
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
@@ -47,10 +48,10 @@ index.html
|
||||
|
||||
## Browser Support
|
||||
|
||||
Modern browsers and Internet Explorer 9+.
|
||||
Modern browsers and Internet Explorer 10+.
|
||||
|
||||
## Showcase
|
||||
These open-source projects are using docsify to generate their sites. Pull requests welcome : )
|
||||
These open-source projects are using docsify to generate their sites. Pull requests welcome :blush:
|
||||
|
||||
- [Snipaste](https://docs.snipaste.com/) - Snip & Paste
|
||||
- [puck](https://puck.zz173.com/) - A small & magical php framework.
|
||||
@@ -69,7 +70,7 @@ These open-source projects are using docsify to generate their sites. Pull reque
|
||||
- Create your feature branch: `git checkout -b my-new-feature`
|
||||
- Commit your changes: `git commit -am 'Add some feature'`
|
||||
- Push to the branch: `git push origin my-new-feature`
|
||||
- Submit a pull request :D
|
||||
- Submit a pull request
|
||||
|
||||
|
||||
## Development
|
||||
|
||||
+2
-1
@@ -33,7 +33,8 @@ build({
|
||||
|
||||
var plugins = [
|
||||
{ name: 'search', entry: 'search/index.js', moduleName: 'Search' },
|
||||
{ name: 'ga', entry: 'ga.js', moduleName: 'GA' }
|
||||
{ name: 'ga', entry: 'ga.js', moduleName: 'GA' },
|
||||
{ name: 'emoji', entry: 'emoji.js', moduleName: 'Emoji' }
|
||||
// { name: 'front-matter', entry: 'front-matter/index.js', moduleName: 'FrontMatter' }
|
||||
]
|
||||
|
||||
|
||||
+6
-6
@@ -4,24 +4,24 @@
|
||||
|
||||
## What is it
|
||||
|
||||
docsify generates your documentation website on the fly. Unlike GitBook, it does not generate static html files. It smartly loads and parses your Markdown files and displays them in website. All you need to do is create an `index.html` to start and [deploy it on GitHub Pages](/deploy).
|
||||
docsify generates your documentation website on the fly. Unlike GitBook, it does not generate static html files. Instead, it smartly loads and parses your Markdown files and displays them as website. All you need to do is create an `index.html` to start and [deploy it on GitHub Pages](/deploy).
|
||||
|
||||
See the [Quick start](/quickstart) for more details.
|
||||
|
||||
## Features
|
||||
|
||||
- Not build static html files
|
||||
- Simple and lightweight (~14kB gzipped)
|
||||
- No statically built html files
|
||||
- Simple and lightweight (~16kB gzipped)
|
||||
- Smart full-text search plugin
|
||||
- Multiple themes
|
||||
- Useful plugin API
|
||||
- Emoji support
|
||||
- Compatible with IE10+
|
||||
|
||||
## Examples
|
||||
|
||||
Check out the [Showcase](https://github.com/QingWei-Li/docsify/#showcase) to see use the docsify generated website.
|
||||
Check out the [Showcase](https://github.com/QingWei-Li/docsify/#showcase) to docsify in use.
|
||||
|
||||
## Donate
|
||||
|
||||
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:
|
||||
|
||||
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:
|
||||
|
||||
+3
-3
@@ -1,11 +1,11 @@
|
||||

|
||||
|
||||
# docsify <small>3.0</small>
|
||||
# docsify <small>3.2</small>
|
||||
|
||||
> A magical documentation site generator.
|
||||
|
||||
- Simple and lightweight (~14kB gzipped)
|
||||
- Not build static html files
|
||||
- Simple and lightweight (~16kB gzipped)
|
||||
- No statically built html files
|
||||
- Multiple themes
|
||||
|
||||
|
||||
|
||||
+6
-4
@@ -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 highlight](/language-highlight)
|
||||
- [Lanuage highlighting](/language-highlight)
|
||||
|
||||
- Guide
|
||||
- [Deploy](/deploy)
|
||||
- [Doc helper](/helpers)
|
||||
- [Compatible Vue](/vue)
|
||||
- [Helpers](/helpers)
|
||||
- [Vue compatibility](/vue)
|
||||
- [CDN](/cdn)
|
||||
- [Offline Mode(PWA)](/pwa)
|
||||
|
||||
- [Changelog](/changelog)
|
||||
@@ -206,7 +206,13 @@ The name of the link.
|
||||
|
||||
```js
|
||||
window.$docsify = {
|
||||
nameLink: '/'
|
||||
nameLink: '/',
|
||||
|
||||
// For each route
|
||||
nameLink: {
|
||||
'/zh-cn/': '/zh-cn/',
|
||||
'/': '/'
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
+13
-13
@@ -1,15 +1,14 @@
|
||||
# Cover
|
||||
|
||||
Activate the cover feature by setting `coverpage`. The detail in [Configuration#coverpage](configuration#coverpage).
|
||||
Activate the cover feature by setting `coverpage` to **true**. Details are available in the [coverpage configuration paragraph](configuration#coverpage).
|
||||
|
||||
## Basic usage
|
||||
|
||||
Set `coverpage` to **true**, and create a `_coverpage.md`. You can see the effect in current website.
|
||||
|
||||
|
||||
*index.html*
|
||||
Set `coverpage` to **true**, and create a `_coverpage.md`:
|
||||
|
||||
```html
|
||||
<!-- index.html -->
|
||||
|
||||
<script>
|
||||
window.$docsify = {
|
||||
coverpage: true
|
||||
@@ -18,33 +17,34 @@ Set `coverpage` to **true**, and create a `_coverpage.md`. You can see the effec
|
||||
<script src="//unpkg.com/docsify"></script>
|
||||
```
|
||||
|
||||
*_coverpage.md*
|
||||
|
||||
```markdown
|
||||
<!-- _coverpage.md -->
|
||||
|
||||

|
||||
|
||||
# docsify
|
||||
# docsify <small>3.0</small>
|
||||
|
||||
> A magical documentation site generator.
|
||||
|
||||
- Simple and lightweight (~12kb gzipped)
|
||||
- Simple and lightweight (~16kB gzipped)
|
||||
- No statically built html files
|
||||
- Multiple themes
|
||||
- Not build static html files
|
||||
|
||||
|
||||
[GitHub](https://github.com/QingWei-Li/docsify/)
|
||||
[Get Started](#quick-start)
|
||||
[Get Started](#docsify)
|
||||
```
|
||||
|
||||
!> A document site can have only one cover page.
|
||||
|
||||
## Custom background
|
||||
|
||||
The background color is generated randomly by default. You can customize the background color or image.
|
||||
|
||||
*_coverpage.md*
|
||||
The background color is generated randomly by default. You can customize the background color or image:
|
||||
|
||||
```markdown
|
||||
<!-- _coverpage.md -->
|
||||
|
||||
# docsify
|
||||
|
||||
[GitHub](https://github.com/QingWei-Li/docsify/)
|
||||
|
||||
+16
-11
@@ -1,10 +1,12 @@
|
||||
# Custom navbar
|
||||
|
||||
You can create navbar in HTML file. But note that the link begins with `#/`.
|
||||
## HTML
|
||||
|
||||
*index.html*
|
||||
If you need custom navigation, you can create a HTML-based navigation bar (but note that documentation links begin with `#/`).
|
||||
|
||||
```html
|
||||
<!-- index.html -->
|
||||
|
||||
<body>
|
||||
<nav>
|
||||
<a href="#/">EN</a>
|
||||
@@ -14,14 +16,13 @@ You can create navbar in HTML file. But note that the link begins with `#/`.
|
||||
</body>
|
||||
```
|
||||
|
||||
## Writing by Markdown
|
||||
|
||||
You can custom navbar by Markdown file. Set the `loadNavbar` to **true** and create a `_navbar.md`. The detail in [Configuration#load-navbar](configuration#load-navbar).
|
||||
|
||||
*index.html*
|
||||
## Markdown
|
||||
|
||||
Alternatively, you can create a custom markdown-based navigation file by setting `loadNavbar` to **true** and creating `_navbar.md`. Details are available in the [load-navbar configuration paragraph](configuration#load-navbar).
|
||||
|
||||
```html
|
||||
<!-- index.html -->
|
||||
|
||||
<script>
|
||||
window.$docsify = {
|
||||
loadNavbar: true
|
||||
@@ -30,21 +31,25 @@ You can custom navbar by Markdown file. Set the `loadNavbar` to **true** and cre
|
||||
<script src="//unpkg.com/docsify"></script>
|
||||
```
|
||||
|
||||
*_navbar.md*
|
||||
|
||||
|
||||
```markdown
|
||||
<!-- _navbar.md -->
|
||||
|
||||
- [En](/)
|
||||
- [chinese](/zh-cn/)
|
||||
```
|
||||
|
||||
`_navbar.md` is loaded from each level directory. If this directory doesn't have `_navbar.md`, it will fallback to parent directory. For example, the current path is `/guide/quick-start`, the `_navbar.md` will be loaded from `/guide/_navbar.md`.
|
||||
!> You need to create a `.nojekyll` in `./docs` to prevent GitHub Pages from ignoring files that begin with an underscore.
|
||||
|
||||
`_navbar.md` is loaded from each level directory. If the current directory doesn't have `_navbar.md`, it will fall back to the parent directory. If, for example, the current path is `/guide/quick-start`, the `_navbar.md` will be loaded from `/guide/_navbar.md`.
|
||||
|
||||
## Nesting
|
||||
|
||||
You can create sub-lists by indenting items that are under a certain parent.
|
||||
|
||||
```markdown
|
||||
<!-- _navbar.md -->
|
||||
|
||||
- Getting started
|
||||
- [Quick start](/quickstart)
|
||||
- [Writing more pages](/more-pages)
|
||||
@@ -59,7 +64,7 @@ You can create sub-lists by indenting items that are under a certain parent.
|
||||
- [Lanuage highlight](/language-highlight)
|
||||
```
|
||||
|
||||
Example.
|
||||
renders as
|
||||
|
||||

|
||||
|
||||
|
||||
@@ -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>
|
||||
@@ -32,6 +33,10 @@
|
||||
'/changelog': 'https://raw.githubusercontent.com/QingWei-Li/docsify/master/CHANGELOG'
|
||||
}
|
||||
}
|
||||
|
||||
if (typeof navigator.serviceWorker !== 'undefined') {
|
||||
navigator.serviceWorker.register('sw.js')
|
||||
}
|
||||
</script>
|
||||
<script src="//unpkg.com/docsify/lib/docsify.min.js"></script>
|
||||
<script src="//unpkg.com/docsify/lib/plugins/search.min.js"></script>
|
||||
|
||||
+14
-10
@@ -1,10 +1,9 @@
|
||||
# More pages
|
||||
|
||||
If you need more pages multi-level routing site. It is easy to achieve in docsify. A simple example: If you create a `guide.md`, then get the route is `/#/guide`.
|
||||
If you need more pages, you can simply create more markdown files in your docsify directory. If you create a file named `guide.md`, then it is accessible via `/#/guide`.
|
||||
|
||||
For example, the directory structure is as follows:
|
||||
|
||||
|
||||
```text
|
||||
-| docs/
|
||||
-| README.md
|
||||
@@ -26,11 +25,13 @@ docs/zh-cn/guide.md => http://domain.com/zh-cn/guide
|
||||
|
||||
## Custom sidebar
|
||||
|
||||
By default, the TOC in sidebar is automatically generated based on Markdown file. You can create a Table of Contents page to list down pages in your site.
|
||||
By default, the table of contents in the sidebar is automatically generated based on your markdown files. If you need a custom sidebar, then you can create your own `_sidebar.md` (see [this documentation's sidebar](https://github.com/QingWei-Li/docsify/blob/master/docs/_sidebar.md) for an example):
|
||||
|
||||
First, you need to set `loadSidebar` to **true**. The detail in [Configuration#load-sidebar](configuration#load-sidebar).
|
||||
First, you need to set `loadSidebar` to **true**. Details are available in the [configuration paragraph](configuration#load-sidebar).
|
||||
|
||||
```html
|
||||
<!-- index.html -->
|
||||
|
||||
<script>
|
||||
window.$docsify = {
|
||||
loadSidebar: true
|
||||
@@ -39,22 +40,26 @@ First, you need to set `loadSidebar` to **true**. The detail in [Configuration#l
|
||||
<script src="//unpkg.com/docsify"></script>
|
||||
```
|
||||
|
||||
Create the `_sidebar.md`
|
||||
Create the `_sidebar.md`:
|
||||
|
||||
```markdown
|
||||
<!-- docs/_sidebar.md -->
|
||||
|
||||
- [Home](/)
|
||||
- [Guide](/guide)
|
||||
```
|
||||
|
||||
!> Need create a `.nojekyll` in `./docs` to prevent GitHub Pages from ignoring files that begin with an underscore.
|
||||
!> You need to create a `.nojekyll` in `./docs` to prevent GitHub Pages from ignoring files that begin with an underscore.
|
||||
|
||||
`_sidebar.md` is loaded from each level directory. If this directory doesn't have `_sidebar.md`, it will fallback to parent directory. For example, the current path is `/guide/quick-start`, the `_sidebar.md` will be loaded from `/guide/_sidebar.md`.
|
||||
`_sidebar.md` is loaded from each level directory. If the current directory doesn't have `_sidebar.md`, it will fall back to the parent directory. If, for example, the current path is `/guide/quick-start`, the `_sidebar.md` will be loaded from `/guide/_sidebar.md`.
|
||||
|
||||
## Table of Contents
|
||||
|
||||
Custom sidebar can also be automatically generate TOC by setting `subMaxLevel`. The detail in [Configuration#sub-max-level](configuration#sub-max-level).
|
||||
A custom sidebar can also automatically generate a table of contents by setting a `subMaxLevel`. Details are available in the [max-level configuration paragraph](configuration#sub-max-level).
|
||||
|
||||
```html
|
||||
<!-- index.html -->
|
||||
|
||||
<script>
|
||||
window.$docsify = {
|
||||
loadSidebar: true,
|
||||
@@ -62,5 +67,4 @@ Custom sidebar can also be automatically generate TOC by setting `subMaxLevel`.
|
||||
}
|
||||
</script>
|
||||
<script src="//unpkg.com/docsify"></script>
|
||||
```
|
||||
|
||||
```
|
||||
+15
-72
@@ -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,12 @@ 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.
|
||||
|
||||
#### 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> ©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
|
||||
})
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
+113
@@ -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 there’s 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.
|
||||
+18
-16
@@ -1,14 +1,14 @@
|
||||
# Quick start
|
||||
|
||||
Recommended install `docsify-cli` globally, which can help us to initialize and preview the website locally.
|
||||
It is recommended to install `docsify-cli` globally, which helps initializing and previewing the website locally.
|
||||
|
||||
```bash
|
||||
npm i docsify-cli -g
|
||||
```
|
||||
|
||||
## initialize
|
||||
## Initialize
|
||||
|
||||
If you want to write the documentation in `./docs` directory, you can use the `init` command.
|
||||
If you want to write the documentation in the `./docs` directory, you can use the `init` command.
|
||||
|
||||
```bash
|
||||
docsify init ./docs
|
||||
@@ -21,28 +21,28 @@ After the init is complete, you can see the file list in the docs directory.
|
||||
|
||||
- `index.html` as the entry file
|
||||
- `README.md` as the home page
|
||||
- `.nojekyll` can prevent GitHub Pages from ignoring files that begin with an underscore
|
||||
- `.nojekyll` prevents GitHub Pages from ignoring files that begin with an underscore
|
||||
|
||||
You can easily update the documentation in `docs/README.md`, of course you can add [more pages](more-pages).
|
||||
|
||||
## Preview your site
|
||||
|
||||
Run the local server via `docsify serve`. You can preview your site in browser via http://localhost:3000.
|
||||
Run the local server with `docsify serve`. You can preview your site in your browser on `http://localhost:3000`.
|
||||
|
||||
|
||||
```bash
|
||||
docsify serve docs
|
||||
```
|
||||
|
||||
?> More usages of reference [docsify-cli documentation](https://github.com/QingWei-Li/docsify-cli).
|
||||
?> For more use cases of `docsify-cli`, head over to the [docsify-cli documentation](https://github.com/QingWei-Li/docsify-cli).
|
||||
|
||||
## Manually
|
||||
## Manual initialization
|
||||
|
||||
If you don't like npm or feel the trouble to install the tool. What we need is an `index.html`.
|
||||
|
||||
*index.html*
|
||||
If you don't like npm or have trouble installing the tool, you can manually create `index.html`:
|
||||
|
||||
```html
|
||||
<!-- index.html -->
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
@@ -56,25 +56,27 @@ If you don't like npm or feel the trouble to install the tool. What we need is a
|
||||
</html>
|
||||
```
|
||||
|
||||
If your system has Python, you can easily to run a static server to preview your site.
|
||||
If you installed python on your system, you can easily use it to run a static server to preview your site.
|
||||
|
||||
```bash
|
||||
cd docs && python -m SimpleHTTPServer 3000
|
||||
```
|
||||
|
||||
## Loading tip
|
||||
## Loading dialog
|
||||
|
||||
Show `Loading...` Before starting rendering. You can customize the content.
|
||||
If you want, you can show a loading dialog before docsify starts to render your documentation:
|
||||
|
||||
*index.html*
|
||||
```html
|
||||
<!-- index.html -->
|
||||
|
||||
<div id="app">Please wait...</div>
|
||||
```
|
||||
|
||||
You should set the `data-app` attribute if you changed `el`.
|
||||
You should set the `data-app` attribute if you changed `el`:
|
||||
|
||||
*index.html*
|
||||
```html
|
||||
<!-- index.html -->
|
||||
|
||||
<div data-app id="main">Please wait...</div>
|
||||
|
||||
<script>
|
||||
|
||||
+83
@@ -0,0 +1,83 @@
|
||||
/* ===========================================================
|
||||
* 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 there’s 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 */ })
|
||||
)
|
||||
}
|
||||
})
|
||||
+1
-1
@@ -76,7 +76,7 @@ You can manually initialize a Vue instance.
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
module.exports = {
|
||||
data: function () {
|
||||
return { name: 'Vue' }
|
||||
}
|
||||
|
||||
@@ -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> ©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
|
||||
})
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
@@ -12,10 +12,11 @@ docsify 是一个动态生成文档网站的工具。不同于 GitBook、Hexo
|
||||
|
||||
## 特性
|
||||
- 无需构建,写完文档直接发布
|
||||
- 容易使用并且轻量 (~14kB gzipped)
|
||||
- 容易使用并且轻量 (~16kB gzipped)
|
||||
- 智能的全文搜索
|
||||
- 提供多套主题
|
||||
- 丰富的 API
|
||||
- 支持 Emoji
|
||||
- 兼容 IE10+
|
||||
|
||||
## 例子
|
||||
|
||||
@@ -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)
|
||||
@@ -206,7 +206,13 @@ window.$docsify = {
|
||||
|
||||
```js
|
||||
window.$docsify = {
|
||||
nameLink: '/'
|
||||
nameLink: '/',
|
||||
|
||||
// 按照路由切换
|
||||
nameLink: {
|
||||
'/zh-cn/': '/zh-cn/',
|
||||
'/': '/'
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
+15
-71
@@ -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,10 @@
|
||||
<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() {
|
||||
// 初始化并第一次加完成数据后调用,没有参数。
|
||||
})
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
!> 如果需要用 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> ©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
|
||||
})
|
||||
}
|
||||
]
|
||||
}
|
||||
```html
|
||||
<script src="//unpkg.com/docsify/lib/plugins/emoji.js"></script>
|
||||
```
|
||||
|
||||
@@ -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 there’s 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 体验一下。
|
||||
@@ -81,4 +81,3 @@ cd docs && python -m SimpleHTTPServer 3000
|
||||
}
|
||||
</script>
|
||||
```
|
||||
|
||||
|
||||
+1
-1
@@ -75,7 +75,7 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
module.exports = {
|
||||
data: function () {
|
||||
return { name: 'Vue' }
|
||||
}
|
||||
|
||||
@@ -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> ©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
|
||||
})
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
+65
-42
@@ -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
|
||||
});
|
||||
|
||||
@@ -407,14 +411,12 @@ function btn (el) {
|
||||
el = getNode(el);
|
||||
on(el, 'click', toggle);
|
||||
|
||||
if (isMobile) {
|
||||
var sidebar = getNode('.sidebar');
|
||||
var sidebar = getNode('.sidebar');
|
||||
|
||||
on(sidebar, 'click', function () {
|
||||
toggle();
|
||||
setTimeout(function () { return getAndActive(sidebar, true, true); }, 0);
|
||||
});
|
||||
}
|
||||
on(sidebar, 'click', function () {
|
||||
isMobile && toggle();
|
||||
setTimeout(function () { return getAndActive(sidebar, true, true); }, 0);
|
||||
});
|
||||
}
|
||||
|
||||
function sticky () {
|
||||
@@ -598,7 +600,6 @@ var progressbar = function (ref) {
|
||||
};
|
||||
|
||||
var cache = {};
|
||||
var RUN_VERSION = Date.now();
|
||||
|
||||
/**
|
||||
* Simple ajax get
|
||||
@@ -614,8 +615,6 @@ function get (url, hasBar) {
|
||||
xhr.addEventListener.apply(xhr, arguments);
|
||||
};
|
||||
|
||||
url += (/\?(\w+)=/g.test(url) ? '&' : '?') + "v=" + RUN_VERSION;
|
||||
|
||||
if (cache[url]) {
|
||||
return { then: function (cb) { return cb(cache[url]); }, abort: noop }
|
||||
}
|
||||
@@ -701,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>')
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -716,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>');
|
||||
@@ -2893,8 +2892,7 @@ function genTree (toc, maxLevel) {
|
||||
|
||||
if (level > maxLevel) { return }
|
||||
if (last[len]) {
|
||||
last[len].children = last[len].children || [];
|
||||
last[len].children.push(headline);
|
||||
last[len].children = (last[len].children || []).concat(headline);
|
||||
} else {
|
||||
headlines.push(headline);
|
||||
}
|
||||
@@ -2928,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, ':')
|
||||
}
|
||||
|
||||
@@ -2943,7 +2945,7 @@ var markdownCompiler = marked;
|
||||
var contentBase = '';
|
||||
var currentPath = '';
|
||||
var renderer = new marked.Renderer();
|
||||
var TOC = {};
|
||||
var cacheTree = {};
|
||||
var toc = [];
|
||||
|
||||
/**
|
||||
@@ -2956,7 +2958,7 @@ var markdown = cached(function (text) {
|
||||
|
||||
html = markdownCompiler(text);
|
||||
html = emojify(html);
|
||||
clearSlugCache();
|
||||
slugify.clear();
|
||||
|
||||
return html
|
||||
});
|
||||
@@ -2968,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);
|
||||
@@ -3043,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
|
||||
@@ -3056,11 +3058,9 @@ function sidebar (text, level) {
|
||||
function subSidebar (el, level) {
|
||||
if (el) {
|
||||
toc[0] && toc[0].level === 1 && toc.shift();
|
||||
var tree$$1 = genTree(TOC[currentPath] || toc, level);
|
||||
var tree$$1 = cacheTree[currentPath] || genTree(toc, level);
|
||||
el.parentNode.innerHTML += tree(tree$$1, '<ul class="app-sub-sidebar">');
|
||||
}
|
||||
if (toc.length) {
|
||||
TOC[currentPath] = toc.slice();
|
||||
cacheTree[currentPath] = tree$$1;
|
||||
}
|
||||
toc = [];
|
||||
}
|
||||
@@ -3125,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);
|
||||
@@ -3140,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();
|
||||
@@ -3188,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], '');
|
||||
}
|
||||
@@ -3202,6 +3220,8 @@ function renderMixin (proto) {
|
||||
|
||||
proto._updateRender = function () {
|
||||
markdown.update();
|
||||
// render name link
|
||||
renderNameLink(this);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -3280,6 +3300,7 @@ var lastRoute = {};
|
||||
function initRoute (vm) {
|
||||
normalize();
|
||||
lastRoute = vm.route = parse();
|
||||
vm._updateRender();
|
||||
|
||||
on('hashchange', function (_) {
|
||||
normalize();
|
||||
@@ -3314,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) {
|
||||
@@ -3325,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();
|
||||
@@ -3343,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 () {
|
||||
@@ -3364,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) {
|
||||
@@ -3429,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;
|
||||
};
|
||||
|
||||
Vendored
+2
-2
File diff suppressed because one or more lines are too long
@@ -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 + '" />'
|
||||
};
|
||||
|
||||
}());
|
||||
Vendored
+1
File diff suppressed because one or more lines are too long
+19
-5
@@ -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';
|
||||
|
||||
Vendored
+1
-1
@@ -1 +1 @@
|
||||
this.D=this.D||{},function(){"use strict";function e(e){var n={"&":"&","<":"<",">":">",'"':""","'":"'","/":"/"};return String(e).replace(/[&<>"'\/]/g,function(e){return n[e]})}function n(){var e=[];return d.dom.findAll("a").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={"&":"&","<":"<",">":">",'"':""","'":"'","/":"/"};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)}();
|
||||
|
||||
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "docsify",
|
||||
"version": "3.0.4",
|
||||
"version": "3.2.0",
|
||||
"description": "A magical documentation generator.",
|
||||
"main": "lib/docsify.js",
|
||||
"files": [
|
||||
|
||||
@@ -12,14 +12,12 @@ export function btn (el) {
|
||||
el = dom.getNode(el)
|
||||
dom.on(el, 'click', toggle)
|
||||
|
||||
if (isMobile) {
|
||||
const sidebar = dom.getNode('.sidebar')
|
||||
const sidebar = dom.getNode('.sidebar')
|
||||
|
||||
dom.on(sidebar, 'click', () => {
|
||||
toggle()
|
||||
setTimeout(() => getAndActive(sidebar, true, true), 0)
|
||||
})
|
||||
}
|
||||
dom.on(sidebar, 'click', () => {
|
||||
isMobile && toggle()
|
||||
setTimeout(() => getAndActive(sidebar, true, true), 0)
|
||||
})
|
||||
}
|
||||
|
||||
export function sticky () {
|
||||
|
||||
@@ -2,7 +2,6 @@ import progressbar from '../render/progressbar'
|
||||
import { noop } from '../util/core'
|
||||
|
||||
const cache = {}
|
||||
const RUN_VERSION = Date.now()
|
||||
|
||||
/**
|
||||
* Simple ajax get
|
||||
@@ -16,8 +15,6 @@ export function get (url, hasBar = false) {
|
||||
xhr.addEventListener.apply(xhr, arguments)
|
||||
}
|
||||
|
||||
url += (/\?(\w+)=/g.test(url) ? '&' : '?') + `v=${RUN_VERSION}`
|
||||
|
||||
if (cache[url]) {
|
||||
return { then: cb => cb(cache[url]), abort: noop }
|
||||
}
|
||||
|
||||
+14
-12
@@ -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,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
|
||||
}
|
||||
|
||||
@@ -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'
|
||||
@@ -12,7 +12,7 @@ let markdownCompiler = marked
|
||||
let contentBase = ''
|
||||
let currentPath = ''
|
||||
let renderer = new marked.Renderer()
|
||||
const TOC = {}
|
||||
const cacheTree = {}
|
||||
let toc = []
|
||||
|
||||
/**
|
||||
@@ -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
|
||||
@@ -120,11 +120,9 @@ export function sidebar (text, level) {
|
||||
export function subSidebar (el, level) {
|
||||
if (el) {
|
||||
toc[0] && toc[0].level === 1 && toc.shift()
|
||||
const tree = genTree(TOC[currentPath] || toc, level)
|
||||
const tree = cacheTree[currentPath] || genTree(toc, level)
|
||||
el.parentNode.innerHTML += treeTpl(tree, '<ul class="app-sub-sidebar">')
|
||||
}
|
||||
if (toc.length) {
|
||||
TOC[currentPath] = toc.slice()
|
||||
cacheTree[currentPath] = tree
|
||||
}
|
||||
toc = []
|
||||
}
|
||||
|
||||
@@ -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, ':')
|
||||
}
|
||||
|
||||
@@ -15,8 +15,7 @@ export function genTree (toc, maxLevel) {
|
||||
|
||||
if (level > maxLevel) return
|
||||
if (last[len]) {
|
||||
last[len].children = last[len].children || []
|
||||
last[len].children.push(headline)
|
||||
last[len].children = (last[len].children || []).concat(headline)
|
||||
} else {
|
||||
headlines.push(headline)
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -22,6 +22,6 @@ export function slugify (str) {
|
||||
return slug
|
||||
}
|
||||
|
||||
export function clearSlugCache () {
|
||||
slugify.clear = function () {
|
||||
cache = {}
|
||||
}
|
||||
|
||||
@@ -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>')
|
||||
|
||||
@@ -34,6 +34,7 @@ let lastRoute = {}
|
||||
export function initRoute (vm) {
|
||||
normalize()
|
||||
lastRoute = vm.route = parse()
|
||||
vm._updateRender()
|
||||
|
||||
on('hashchange', _ => {
|
||||
normalize()
|
||||
|
||||
@@ -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 => {
|
||||
|
||||
@@ -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 + '" />'
|
||||
}
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
|
||||
@@ -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'
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -8,6 +8,8 @@
|
||||
}
|
||||
|
||||
body:not(.ready) {
|
||||
overflow: hidden;
|
||||
|
||||
[data-cloak] {
|
||||
display: none;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user