mirror of
https://github.com/wahyd4/docsify.git
synced 2026-08-10 05:48:18 +10:00
Compare commits
30
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
09616dec06 | ||
|
|
f74b53f53e | ||
|
|
bba44fb536 | ||
|
|
270fa6cb41 | ||
|
|
24e61f5e2f | ||
|
|
ca8ae50717 | ||
|
|
31654f12ec | ||
|
|
d80aa2189b | ||
|
|
21cde83949 | ||
|
|
c1d4961a64 | ||
|
|
2039e0dd1c | ||
|
|
d5910bd1f9 | ||
|
|
a35531967a | ||
|
|
dac0bfec6c | ||
|
|
01ea44106b | ||
|
|
11ea1f8d12 | ||
|
|
bc4d06bb16 | ||
|
|
29d9cda3de | ||
|
|
140bf10377 | ||
|
|
dfd31b5de7 | ||
|
|
d1c72686bb | ||
|
|
8cd786c9d5 | ||
|
|
b53571810b | ||
|
|
cb53106fa7 | ||
|
|
fd86c727af | ||
|
|
69ef489210 | ||
|
|
c3345ba20c | ||
|
|
1447c8a40a | ||
|
|
3b952ac7c3 | ||
|
|
99dbaa3050 |
@@ -1,2 +0,0 @@
|
|||||||
<!-- Love docsify? Please consider supporting our collective:
|
|
||||||
👉 https://opencollective.com/docsify/donate -->
|
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
---
|
||||||
|
name: Bug report
|
||||||
|
about: Create a report to help us improve
|
||||||
|
|
||||||
|
---
|
||||||
|
<!-- Please don't delete this template or we'll close your issue -->
|
||||||
|
<!-- Please use English language -->
|
||||||
|
<!-- Before creating an issue please make sure you are using the latest version of Docsify. -->
|
||||||
|
<!-- Please ask questions on StackOverflow: https://stackoverflow.com/questions/ask?tags=docsify -->
|
||||||
|
|
||||||
|
## Bug Report
|
||||||
|
|
||||||
|
#### Steps to reproduce
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#### What is current behaviour
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#### What is the expected behaviour
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
- [ ] Bug does still occur when all/other plugins are disabled?
|
||||||
|
|
||||||
|
<!-- Please type in your environment -->
|
||||||
|
Environment:
|
||||||
|
|
||||||
|
```
|
||||||
|
docsify version:
|
||||||
|
docsify plugins:
|
||||||
|
browser:
|
||||||
|
```
|
||||||
|
|
||||||
|
<!-- Love docsify? Please consider supporting our collective:
|
||||||
|
👉 https://opencollective.com/docsify/donate -->
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
---
|
||||||
|
name: Feature request
|
||||||
|
about: Suggest an idea for this project
|
||||||
|
|
||||||
|
---
|
||||||
|
<!-- Please don't delete this template or we'll close your issue -->
|
||||||
|
<!-- Please use English language -->
|
||||||
|
<!-- Before creating an issue please make sure you are using the latest version of Docsify. -->
|
||||||
|
<!-- Please ask questions on StackOverflow 👉 https://stackoverflow.com/questions/ask?tags=docsify -->
|
||||||
|
|
||||||
|
## Feature request
|
||||||
|
|
||||||
|
#### What problem does this feature solve?
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#### What does the proposed API look like?
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#### How should this be implemented in your opinion?
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#### Are you willing to work on this yourself?
|
||||||
@@ -1,5 +1,54 @@
|
|||||||
Please makes sure these boxes are checked before submitting your PR, thank you!
|
<!-- Please use English language -->
|
||||||
|
<!-- Please don't delete this template -->
|
||||||
|
|
||||||
|
<!-- PULL REQUEST TEMPLATE -->
|
||||||
|
<!-- (Update "[ ]" to "[x]" to check a box) -->
|
||||||
|
|
||||||
|
**Summary**
|
||||||
|
|
||||||
|
**What kind of change does this PR introduce?** (check at least one)
|
||||||
|
|
||||||
|
- [ ] Bugfix
|
||||||
|
- [ ] Feature
|
||||||
|
- [ ] Code style update
|
||||||
|
- [ ] Refactor
|
||||||
|
- [ ] Docs
|
||||||
|
- [ ] Build-related changes
|
||||||
|
- [ ] Other, please describe:
|
||||||
|
|
||||||
|
If changing the UI of default theme, please provide the **before/after** screenshot:
|
||||||
|
|
||||||
|
**Does this PR introduce a breaking change?** (check one)
|
||||||
|
|
||||||
|
- [ ] Yes
|
||||||
|
- [ ] No
|
||||||
|
|
||||||
|
If yes, please describe the impact and migration path for existing applications:
|
||||||
|
|
||||||
|
**The PR fulfills these requirements:**
|
||||||
|
|
||||||
|
- [ ] When resolving a specific issue, it's referenced in the PR's title (e.g. `fix #xxx[,#xxx]`, where "xxx" is the issue number)
|
||||||
|
|
||||||
|
You have tested in the following browsers: (Providing a detailed version will be better.)
|
||||||
|
|
||||||
|
- [ ] Chrome
|
||||||
|
- [ ] Firefox
|
||||||
|
- [ ] Safari
|
||||||
|
- [ ] Edge
|
||||||
|
- [ ] IE
|
||||||
|
|
||||||
|
If adding a **new feature**, the PR's description includes:
|
||||||
|
|
||||||
|
- [ ] A convincing reason for adding this feature
|
||||||
|
- [ ] Related documents have been updated
|
||||||
|
- [ ] Related tests have been updated
|
||||||
|
|
||||||
|
To avoid wasting your time, it's best to open a **feature request issue** first and wait for approval before working on it.
|
||||||
|
|
||||||
|
|
||||||
|
**Other information:**
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
* [ ] Make sure you are merging your commits to `master` branch.
|
|
||||||
* [ ] Add some descriptions and refer relative issues for you PR.
|
|
||||||
* [ ] DO NOT include files inside `lib` directory.
|
* [ ] DO NOT include files inside `lib` directory.
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,31 @@
|
|||||||
|
<a name="4.9.1"></a>
|
||||||
|
## [4.9.1](https://github.com/docsifyjs/docsify/compare/v4.9.0...v4.9.1) (2019-02-21)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* github assets url ([#774](https://github.com/docsifyjs/docsify/issues/774)) ([140bf10](https://github.com/docsifyjs/docsify/commit/140bf10))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<a name="4.9.0"></a>
|
||||||
|
# [4.9.0](https://github.com/docsifyjs/docsify/compare/v4.8.6...v4.9.0) (2019-02-19)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* task list rendering (Fix [#749](https://github.com/docsifyjs/docsify/issues/749)) ([#757](https://github.com/docsifyjs/docsify/issues/757)) ([69ef489](https://github.com/docsifyjs/docsify/commit/69ef489))
|
||||||
|
* upgrade npm-run-all ([049726e](https://github.com/docsifyjs/docsify/commit/049726e))
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* **search-plugin:** add namespace option ([#706](https://github.com/docsifyjs/docsify/issues/706)) ([28beff8](https://github.com/docsifyjs/docsify/commit/28beff8))
|
||||||
|
* Add new theme "dolphin" ([#735](https://github.com/docsifyjs/docsify/issues/735)) ([c3345ba](https://github.com/docsifyjs/docsify/commit/c3345ba))
|
||||||
|
* Provide code fragments feature ([#748](https://github.com/docsifyjs/docsify/issues/748)) ([1447c8a](https://github.com/docsifyjs/docsify/commit/1447c8a))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<a name="4.8.6"></a>
|
<a name="4.8.6"></a>
|
||||||
## [4.8.6](https://github.com/docsifyjs/docsify/compare/v4.8.5...v4.8.6) (2018-11-12)
|
## [4.8.6](https://github.com/docsifyjs/docsify/compare/v4.8.5...v4.8.6) (2018-11-12)
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||

|

|
||||||
|
|
||||||
# docsify <small>4.8.6</small>
|
# docsify <small>4.9.1</small>
|
||||||
|
|
||||||
> A magical documentation site generator.
|
> A magical documentation site generator.
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,16 @@
|
|||||||
|
import fetch from 'fetch'
|
||||||
|
|
||||||
|
const URL = 'https://example.com'
|
||||||
|
const PORT = 8080
|
||||||
|
|
||||||
|
/// [demo]
|
||||||
|
const result = fetch(`${URL}:${PORT}`)
|
||||||
|
.then(function(response) {
|
||||||
|
return response.json();
|
||||||
|
})
|
||||||
|
.then(function(myJson) {
|
||||||
|
console.log(JSON.stringify(myJson));
|
||||||
|
});
|
||||||
|
/// [demo]
|
||||||
|
|
||||||
|
result.then(console.log).catch(console.error)
|
||||||
@@ -150,6 +150,46 @@ window.$docsify = {
|
|||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## relativePath
|
||||||
|
|
||||||
|
- Type: `Boolean`
|
||||||
|
- Default: `false`
|
||||||
|
|
||||||
|
If **true** links are relative to the current context.
|
||||||
|
|
||||||
|
For example, the directory structure is as follows:
|
||||||
|
|
||||||
|
```text
|
||||||
|
.
|
||||||
|
└── docs
|
||||||
|
├── README.md
|
||||||
|
├── guide.md
|
||||||
|
└── zh-cn
|
||||||
|
├── README.md
|
||||||
|
├── guide.md
|
||||||
|
└── config
|
||||||
|
└── example.md
|
||||||
|
```
|
||||||
|
|
||||||
|
With relative path **enabled** and current URL `http://domain.com/zh-cn/README`, given links will resolve to:
|
||||||
|
|
||||||
|
```text
|
||||||
|
guide.md => http://domain.com/zh-cn/guide
|
||||||
|
config/example.md => http://domain.com/zh-cn/config/example
|
||||||
|
../README.md => http://domain.com/README
|
||||||
|
/README.md => http://domain.com/README
|
||||||
|
```
|
||||||
|
|
||||||
|
```js
|
||||||
|
window.$docsify = {
|
||||||
|
// Relative path enabled
|
||||||
|
relativePath: true,
|
||||||
|
|
||||||
|
// Relative path disabled (default value)
|
||||||
|
relativePath: false
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
## coverpage
|
## coverpage
|
||||||
|
|
||||||
- Type: `Boolean|String|String[]|Object`
|
- Type: `Boolean|String|String[]|Object`
|
||||||
|
|||||||
@@ -87,3 +87,45 @@ When using the HTML5 router, you need to set up redirect rules that redirect all
|
|||||||
```sh
|
```sh
|
||||||
/* /index.html 200
|
/* /index.html 200
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## AWS Amplify
|
||||||
|
|
||||||
|
1. Set the routerMode in the Docsify project `index.html` to *history* mode.
|
||||||
|
|
||||||
|
```html
|
||||||
|
<script>
|
||||||
|
window.$docsify = {
|
||||||
|
loadSidebar: true,
|
||||||
|
routerMode: 'history'
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
```
|
||||||
|
|
||||||
|
2. Login to your [AWS Console](https://aws.amazon.com).
|
||||||
|
3. Go to the [AWS Amplify Dashboard](https://aws.amazon.com/amplify).
|
||||||
|
4. Choose the **Deploy** route to setup your project.
|
||||||
|
5. When prompted, keep the build settings empty if you're serving your docs within the root directory. If you're serving your docs from a different directory, customise your amplify.yml
|
||||||
|
|
||||||
|
```yml
|
||||||
|
version: 0.1
|
||||||
|
frontend:
|
||||||
|
phases:
|
||||||
|
build:
|
||||||
|
commands:
|
||||||
|
- echo "Nothing to build"
|
||||||
|
artifacts:
|
||||||
|
baseDirectory: /docs
|
||||||
|
files:
|
||||||
|
- '**/*'
|
||||||
|
cache:
|
||||||
|
paths: []
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
6. Add the following Redirect rules in their displayed order.
|
||||||
|
|
||||||
|
| Source address | Target address | Type |
|
||||||
|
|----------------|----------------|---------------|
|
||||||
|
| /<*>.md | /<*>.md | 200 (Rewrite) |
|
||||||
|
| /<*> | /index.html | 200 (Rewrite) |
|
||||||
|
|
||||||
|
|||||||
@@ -39,6 +39,21 @@ You will get it
|
|||||||
|
|
||||||
[filename](_media/example.md ':include :type=code')
|
[filename](_media/example.md ':include :type=code')
|
||||||
|
|
||||||
|
## Embedded code fragments
|
||||||
|
Sometimes you don't want to embed a whole file. Maybe because you need just a few lines but you want to compile and test the file in CI.
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
[filename](_media/example.js ':include :type=code :fragment=demo')
|
||||||
|
```
|
||||||
|
|
||||||
|
In your code file you need to surround the fragment between `/// [demo]` lines (before and after the fragment).
|
||||||
|
Alternatively you can use `### [demo]`.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
[filename](_media/example.js ':include :type=code :fragment=demo')
|
||||||
|
|
||||||
|
|
||||||
## Tag attribute
|
## Tag attribute
|
||||||
|
|
||||||
If you embed the file as `iframe`, `audio` and `video`, then you may need to set the attributes of these tags.
|
If you embed the file as `iframe`, `audio` and `video`, then you may need to set the attributes of these tags.
|
||||||
|
|||||||
@@ -72,6 +72,16 @@ You can specify `alias` to avoid unnecessary fallback.
|
|||||||
|
|
||||||
!> You can create a `README.md` file in a subdirectory to use it as the landing page for the route.
|
!> You can create a `README.md` file in a subdirectory to use it as the landing page for the route.
|
||||||
|
|
||||||
|
## Set Page Titles from Sidebar Selection
|
||||||
|
|
||||||
|
A page's `title` tag is generated from the _selected_ sidebar item name. For better SEO, you can customize the title by specifying a string after the filename.
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
<!-- docs/_sidebar.md -->
|
||||||
|
* [Home](/)
|
||||||
|
* [Guide](guide.md "The greatest guide in the world")
|
||||||
|
```
|
||||||
|
|
||||||
## Table of Contents
|
## Table of Contents
|
||||||
|
|
||||||
Once you've created `_sidebar.md`, the sidebar content is automatically generated based on the headers in the markdown files.
|
Once you've created `_sidebar.md`, the sidebar content is automatically generated based on the headers in the markdown files.
|
||||||
|
|||||||
+1
-1
@@ -111,7 +111,7 @@ var readFileSync = require('fs').readFileSync
|
|||||||
|
|
||||||
// init
|
// init
|
||||||
var renderer = new Renderer({
|
var renderer = new Renderer({
|
||||||
template: readFileSync('./docs/index.template.html', 'utf-8').,
|
template: readFileSync('./docs/index.template.html', 'utf-8'),
|
||||||
config: {
|
config: {
|
||||||
name: 'docsify',
|
name: 'docsify',
|
||||||
repo: 'docsifyjs/docsify'
|
repo: 'docsifyjs/docsify'
|
||||||
|
|||||||
@@ -79,7 +79,7 @@ window.$docsify = {
|
|||||||
function(hook, vm) {
|
function(hook, vm) {
|
||||||
hook.beforeEach(function(html) {
|
hook.beforeEach(function(html) {
|
||||||
var url =
|
var url =
|
||||||
'https://github.com/docsifyjs/docsify/blob/master/docs' +
|
'https://github.com/docsifyjs/docsify/blob/master/docs/' +
|
||||||
vm.route.file;
|
vm.route.file;
|
||||||
var editHtml = '[📝 EDIT DOCUMENT](' + url + ')\n';
|
var editHtml = '[📝 EDIT DOCUMENT](' + url + ')\n';
|
||||||
|
|
||||||
|
|||||||
+40
-7
@@ -3157,7 +3157,7 @@ slugify.clear = function () {
|
|||||||
};
|
};
|
||||||
|
|
||||||
function replace(m, $1) {
|
function replace(m, $1) {
|
||||||
return '<img class="emoji" src="https://assets-cdn.github.com/images/icons/emoji/' + $1 + '.png" alt="' + $1 + '" />'
|
return '<img class="emoji" src="https://github.githubassets.com/images/icons/emoji/' + $1 + '.png" alt="' + $1 + '" />'
|
||||||
}
|
}
|
||||||
|
|
||||||
function emojify(text) {
|
function emojify(text) {
|
||||||
@@ -3335,7 +3335,7 @@ function getAndRemoveConfig(str) {
|
|||||||
str = str
|
str = str
|
||||||
.replace(/^'/, '')
|
.replace(/^'/, '')
|
||||||
.replace(/'$/, '')
|
.replace(/'$/, '')
|
||||||
.replace(/:([\w-]+)=?([\w-]+)?/g, function (m, key, value) {
|
.replace(/(?:^|\s):([\w-]+)=?([\w-]+)?/g, function (m, key, value) {
|
||||||
config[key] = (value && value.replace(/"/g, '')) || true;
|
config[key] = (value && value.replace(/"/g, '')) || true;
|
||||||
return ''
|
return ''
|
||||||
})
|
})
|
||||||
@@ -3483,6 +3483,7 @@ Compiler.prototype.compileEmbed = function compileEmbed (href, title) {
|
|||||||
embed = compileMedia[type].call(this, href, title);
|
embed = compileMedia[type].call(this, href, title);
|
||||||
embed.type = type;
|
embed.type = type;
|
||||||
}
|
}
|
||||||
|
embed.fragment = config.fragment;
|
||||||
|
|
||||||
return embed
|
return embed
|
||||||
}
|
}
|
||||||
@@ -3633,6 +3634,23 @@ Compiler.prototype._initRenderer = function _initRenderer () {
|
|||||||
|
|
||||||
return ("<img src=\"" + url + "\"data-origin=\"" + href + "\" alt=\"" + text + "\"" + attrs + ">")
|
return ("<img src=\"" + url + "\"data-origin=\"" + href + "\" alt=\"" + text + "\"" + attrs + ">")
|
||||||
};
|
};
|
||||||
|
origin.list = renderer.list = function (body, ordered, start) {
|
||||||
|
var isTaskList = /<li class="task-list-item">/.test(body.split('class="task-list"')[0]);
|
||||||
|
var isStartReq = start && start > 1;
|
||||||
|
var tag = ordered ? 'ol' : 'ul';
|
||||||
|
var tagAttrs = [
|
||||||
|
(isTaskList ? 'class="task-list"' : ''),
|
||||||
|
(isStartReq ? ("start=\"" + start + "\"") : '')
|
||||||
|
].join(' ').trim();
|
||||||
|
|
||||||
|
return ("<" + tag + " " + tagAttrs + ">" + body + "</" + tag + ">")
|
||||||
|
};
|
||||||
|
origin.listitem = renderer.listitem = function (text) {
|
||||||
|
var isTaskItem = /^(<input.*type="checkbox"[^>]*>)/.test(text);
|
||||||
|
var html = isTaskItem ? ("<li class=\"task-list-item\"><label>" + text + "</label></li>") : ("<li>" + text + "</li>");
|
||||||
|
|
||||||
|
return html
|
||||||
|
};
|
||||||
|
|
||||||
renderer.origin = origin;
|
renderer.origin = origin;
|
||||||
|
|
||||||
@@ -3708,6 +3726,9 @@ function btn(el) {
|
|||||||
var toggle = function (_) { return body.classList.toggle('close'); };
|
var toggle = function (_) { return body.classList.toggle('close'); };
|
||||||
|
|
||||||
el = getNode(el);
|
el = getNode(el);
|
||||||
|
if (el == null) {
|
||||||
|
return
|
||||||
|
}
|
||||||
on(el, 'click', function (e) {
|
on(el, 'click', function (e) {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
toggle();
|
toggle();
|
||||||
@@ -3723,7 +3744,9 @@ function btn(el) {
|
|||||||
|
|
||||||
function collapse(el) {
|
function collapse(el) {
|
||||||
el = getNode(el);
|
el = getNode(el);
|
||||||
|
if (el == null) {
|
||||||
|
return
|
||||||
|
}
|
||||||
on(el, 'click', function (ref) {
|
on(el, 'click', function (ref) {
|
||||||
var target = ref.target;
|
var target = ref.target;
|
||||||
|
|
||||||
@@ -3761,8 +3784,10 @@ function sticky() {
|
|||||||
*/
|
*/
|
||||||
function getAndActive(router, el, isParent, autoTitle) {
|
function getAndActive(router, el, isParent, autoTitle) {
|
||||||
el = getNode(el);
|
el = getNode(el);
|
||||||
|
var links = [];
|
||||||
var links = findAll(el, 'a');
|
if (el != null) {
|
||||||
|
links = findAll(el, 'a');
|
||||||
|
}
|
||||||
var hash = decodeURI(router.toURL(router.getCurrentPath()));
|
var hash = decodeURI(router.toURL(router.getCurrentPath()));
|
||||||
var target;
|
var target;
|
||||||
|
|
||||||
@@ -3965,7 +3990,10 @@ function scrollActiveSidebar(router) {
|
|||||||
coverHeight = cover ? cover.offsetHeight : 0;
|
coverHeight = cover ? cover.offsetHeight : 0;
|
||||||
|
|
||||||
var sidebar = getNode('.sidebar');
|
var sidebar = getNode('.sidebar');
|
||||||
var lis = findAll(sidebar, 'li');
|
var lis = [];
|
||||||
|
if (sidebar != null) {
|
||||||
|
lis = findAll(sidebar, 'li');
|
||||||
|
}
|
||||||
|
|
||||||
for (var i = 0, len = lis.length; i < len; i += 1) {
|
for (var i = 0, len = lis.length; i < len; i += 1) {
|
||||||
var li = lis[i];
|
var li = lis[i];
|
||||||
@@ -4049,6 +4077,11 @@ function walkFetchEmbed(ref, cb) {
|
|||||||
if (token.embed.type === 'markdown') {
|
if (token.embed.type === 'markdown') {
|
||||||
embedToken = compile.lexer(text);
|
embedToken = compile.lexer(text);
|
||||||
} else if (token.embed.type === 'code') {
|
} else if (token.embed.type === 'code') {
|
||||||
|
if (token.embed.fragment) {
|
||||||
|
var fragment = token.embed.fragment;
|
||||||
|
var pattern = new RegExp(("(?:###|\\/\\/\\/)\\s*\\[" + fragment + "\\]([\\s\\S]*)(?:###|\\/\\/\\/)\\s*\\[" + fragment + "\\]"));
|
||||||
|
text = ((text.match(pattern) || [])[1] || '').trim();
|
||||||
|
}
|
||||||
embedToken = compile.lexer(
|
embedToken = compile.lexer(
|
||||||
'```' +
|
'```' +
|
||||||
token.embed.lang +
|
token.embed.lang +
|
||||||
@@ -5013,7 +5046,7 @@ function initGlobalAPI () {
|
|||||||
dom: dom,
|
dom: dom,
|
||||||
get: get,
|
get: get,
|
||||||
slugify: slugify,
|
slugify: slugify,
|
||||||
version: '4.8.6'
|
version: '4.9.1'
|
||||||
};
|
};
|
||||||
window.DocsifyCompiler = Compiler;
|
window.DocsifyCompiler = Compiler;
|
||||||
window.marked = marked;
|
window.marked = marked;
|
||||||
|
|||||||
Vendored
+1
-1
File diff suppressed because one or more lines are too long
@@ -893,7 +893,7 @@ var AllGithubEmoji = [
|
|||||||
window.emojify = function (match, $1) {
|
window.emojify = function (match, $1) {
|
||||||
return AllGithubEmoji.indexOf($1) === -1 ?
|
return AllGithubEmoji.indexOf($1) === -1 ?
|
||||||
match :
|
match :
|
||||||
'<img class="emoji" src="https://assets-cdn.github.com/images/icons/emoji/' +
|
'<img class="emoji" src="https://github.githubassets.com/images/icons/emoji/' +
|
||||||
$1 +
|
$1 +
|
||||||
'.png" alt="' +
|
'.png" alt="' +
|
||||||
$1 +
|
$1 +
|
||||||
|
|||||||
Vendored
+1
-1
File diff suppressed because one or more lines are too long
+25
-7
@@ -1,6 +1,18 @@
|
|||||||
(function () {
|
(function () {
|
||||||
var INDEXS = {};
|
var INDEXS = {};
|
||||||
|
|
||||||
|
var LOCAL_STORAGE = {
|
||||||
|
EXPIRE_KEY: 'docsify.search.expires',
|
||||||
|
INDEX_KEY: 'docsify.search.index'
|
||||||
|
};
|
||||||
|
|
||||||
|
function resolveExpireKey(namespace) {
|
||||||
|
return namespace ? ((LOCAL_STORAGE.EXPIRE_KEY) + "/" + namespace) : LOCAL_STORAGE.EXPIRE_KEY
|
||||||
|
}
|
||||||
|
function resolveIndexKey(namespace) {
|
||||||
|
return namespace ? ((LOCAL_STORAGE.INDEX_KEY) + "/" + namespace) : LOCAL_STORAGE.INDEX_KEY
|
||||||
|
}
|
||||||
|
|
||||||
function escapeHtml(string) {
|
function escapeHtml(string) {
|
||||||
var entityMap = {
|
var entityMap = {
|
||||||
'&': '&',
|
'&': '&',
|
||||||
@@ -34,9 +46,9 @@ function getAllPaths(router) {
|
|||||||
return paths
|
return paths
|
||||||
}
|
}
|
||||||
|
|
||||||
function saveData(maxAge) {
|
function saveData(maxAge, expireKey, indexKey) {
|
||||||
localStorage.setItem('docsify.search.expires', Date.now() + maxAge);
|
localStorage.setItem(expireKey, Date.now() + maxAge);
|
||||||
localStorage.setItem('docsify.search.index', JSON.stringify(INDEXS));
|
localStorage.setItem(indexKey, JSON.stringify(INDEXS));
|
||||||
}
|
}
|
||||||
|
|
||||||
function genIndex(path, content, router, depth) {
|
function genIndex(path, content, router, depth) {
|
||||||
@@ -154,9 +166,13 @@ function search(query) {
|
|||||||
|
|
||||||
function init$1(config, vm) {
|
function init$1(config, vm) {
|
||||||
var isAuto = config.paths === 'auto';
|
var isAuto = config.paths === 'auto';
|
||||||
var isExpired = localStorage.getItem('docsify.search.expires') < Date.now();
|
|
||||||
|
|
||||||
INDEXS = JSON.parse(localStorage.getItem('docsify.search.index'));
|
var expireKey = resolveExpireKey(config.namespace);
|
||||||
|
var indexKey = resolveIndexKey(config.namespace);
|
||||||
|
|
||||||
|
var isExpired = localStorage.getItem(expireKey) < Date.now();
|
||||||
|
|
||||||
|
INDEXS = JSON.parse(localStorage.getItem(indexKey));
|
||||||
|
|
||||||
if (isExpired) {
|
if (isExpired) {
|
||||||
INDEXS = {};
|
INDEXS = {};
|
||||||
@@ -177,7 +193,7 @@ function init$1(config, vm) {
|
|||||||
.get(vm.router.getFile(path), false, vm.config.requestHeaders)
|
.get(vm.router.getFile(path), false, vm.config.requestHeaders)
|
||||||
.then(function (result) {
|
.then(function (result) {
|
||||||
INDEXS[path] = genIndex(path, result, vm.router, config.depth);
|
INDEXS[path] = genIndex(path, result, vm.router, config.depth);
|
||||||
len === ++count && saveData(config.maxAge);
|
len === ++count && saveData(config.maxAge, expireKey, indexKey);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -311,7 +327,8 @@ var CONFIG = {
|
|||||||
paths: 'auto',
|
paths: 'auto',
|
||||||
depth: 2,
|
depth: 2,
|
||||||
maxAge: 86400000, // 1 day
|
maxAge: 86400000, // 1 day
|
||||||
hideOtherSidebarContent: false
|
hideOtherSidebarContent: false,
|
||||||
|
namespace: undefined
|
||||||
};
|
};
|
||||||
|
|
||||||
var install = function (hook, vm) {
|
var install = function (hook, vm) {
|
||||||
@@ -327,6 +344,7 @@ var install = function (hook, vm) {
|
|||||||
CONFIG.noData = opts.noData || CONFIG.noData;
|
CONFIG.noData = opts.noData || CONFIG.noData;
|
||||||
CONFIG.depth = opts.depth || CONFIG.depth;
|
CONFIG.depth = opts.depth || CONFIG.depth;
|
||||||
CONFIG.hideOtherSidebarContent = opts.hideOtherSidebarContent || CONFIG.hideOtherSidebarContent;
|
CONFIG.hideOtherSidebarContent = opts.hideOtherSidebarContent || CONFIG.hideOtherSidebarContent;
|
||||||
|
CONFIG.namespace = opts.namespace || CONFIG.namespace;
|
||||||
}
|
}
|
||||||
|
|
||||||
var isAuto = CONFIG.paths === 'auto';
|
var isAuto = CONFIG.paths === 'auto';
|
||||||
|
|||||||
Vendored
+1
-1
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
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
Generated
+811
-1
File diff suppressed because it is too large
Load Diff
+6
-2
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "docsify",
|
"name": "docsify",
|
||||||
"version": "4.8.6",
|
"version": "4.9.1",
|
||||||
"description": "A magical documentation generator.",
|
"description": "A magical documentation generator.",
|
||||||
"author": {
|
"author": {
|
||||||
"name": "qingwei-li",
|
"name": "qingwei-li",
|
||||||
@@ -27,7 +27,7 @@
|
|||||||
"dev": "run-p serve watch:*",
|
"dev": "run-p serve watch:*",
|
||||||
"dev:ssr": "run-p serve:ssr watch:*",
|
"dev:ssr": "run-p serve:ssr watch:*",
|
||||||
"lint": "eslint {src,packages} --fix",
|
"lint": "eslint {src,packages} --fix",
|
||||||
"test": "run-p lint",
|
"test": "mocha test/*/**",
|
||||||
"css": "stylus src/themes/*.styl -u autoprefixer-stylus",
|
"css": "stylus src/themes/*.styl -u autoprefixer-stylus",
|
||||||
"watch:css": "run-p 'css -- -o themes -w'",
|
"watch:css": "run-p 'css -- -o themes -w'",
|
||||||
"watch:js": "node build/build.js",
|
"watch:js": "node build/build.js",
|
||||||
@@ -51,14 +51,18 @@
|
|||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"autoprefixer-stylus": "^0.14.0",
|
"autoprefixer-stylus": "^0.14.0",
|
||||||
|
"chai": "^4.2.0",
|
||||||
"chokidar": "^2.0.2",
|
"chokidar": "^2.0.2",
|
||||||
"conventional-changelog-cli": "^1.3.5",
|
"conventional-changelog-cli": "^1.3.5",
|
||||||
"cross-env": "^5.1.3",
|
"cross-env": "^5.1.3",
|
||||||
"cssnano": "^3.10.0",
|
"cssnano": "^3.10.0",
|
||||||
"eslint": "^4.14.0",
|
"eslint": "^4.14.0",
|
||||||
"eslint-config-xo-space": "^0.18.0",
|
"eslint-config-xo-space": "^0.18.0",
|
||||||
|
"esm": "^3.1.4",
|
||||||
|
"jsdom": "^13.2.0",
|
||||||
"lerna": "^2.5.1",
|
"lerna": "^2.5.1",
|
||||||
"live-server": "^1.2.1",
|
"live-server": "^1.2.1",
|
||||||
|
"mocha": "^5.2.0",
|
||||||
"npm-run-all": "^4.1.5",
|
"npm-run-all": "^4.1.5",
|
||||||
"rimraf": "^2.6.2",
|
"rimraf": "^2.6.2",
|
||||||
"rollup": "^0.53.3",
|
"rollup": "^0.53.3",
|
||||||
|
|||||||
+1
-1
@@ -37,5 +37,5 @@
|
|||||||
"integrity": "sha1-6DWIAbhrg7F1YNTjw4LXrvIQCUQ="
|
"integrity": "sha1-6DWIAbhrg7F1YNTjw4LXrvIQCUQ="
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"version": "4.8.6"
|
"version": "4.9.1"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "docsify-server-renderer",
|
"name": "docsify-server-renderer",
|
||||||
"version": "4.8.6",
|
"version": "4.9.1",
|
||||||
"description": "docsify server renderer",
|
"description": "docsify server renderer",
|
||||||
"author": {
|
"author": {
|
||||||
"name": "qingwei-li",
|
"name": "qingwei-li",
|
||||||
|
|||||||
+2
-1
@@ -25,7 +25,8 @@ export default function () {
|
|||||||
formatUpdated: '',
|
formatUpdated: '',
|
||||||
externalLinkTarget: '_blank',
|
externalLinkTarget: '_blank',
|
||||||
routerMode: 'hash',
|
routerMode: 'hash',
|
||||||
noCompileLinks: []
|
noCompileLinks: [],
|
||||||
|
relativePath: false
|
||||||
},
|
},
|
||||||
window.$docsify
|
window.$docsify
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import {isMobile} from '../util/env'
|
import {isMobile} from '../util/env'
|
||||||
import * as dom from '../util/dom'
|
import * as dom from '../util/dom'
|
||||||
import image from '../util/image'
|
|
||||||
import Tweezer from 'tweezer.js'
|
import Tweezer from 'tweezer.js'
|
||||||
|
|
||||||
const nav = {}
|
const nav = {}
|
||||||
@@ -88,7 +87,10 @@ export function scrollActiveSidebar(router) {
|
|||||||
coverHeight = cover ? cover.offsetHeight : 0
|
coverHeight = cover ? cover.offsetHeight : 0
|
||||||
|
|
||||||
const sidebar = dom.getNode('.sidebar')
|
const sidebar = dom.getNode('.sidebar')
|
||||||
const lis = dom.findAll(sidebar, 'li')
|
let lis = []
|
||||||
|
if (sidebar != null) {
|
||||||
|
lis = dom.findAll(sidebar, 'li')
|
||||||
|
}
|
||||||
|
|
||||||
for (let i = 0, len = lis.length; i < len; i += 1) {
|
for (let i = 0, len = lis.length; i < len; i += 1) {
|
||||||
const li = lis[i]
|
const li = lis[i]
|
||||||
@@ -124,34 +126,11 @@ export function scrollActiveSidebar(router) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
export let pausedScrollToView
|
|
||||||
|
|
||||||
export function proceedScrollToView() {
|
|
||||||
if (pausedScrollToView) {
|
|
||||||
const copy = pausedScrollToView.slice()
|
|
||||||
pausedScrollToView = undefined
|
|
||||||
scrollIntoView(...copy)
|
|
||||||
}
|
|
||||||
|
|
||||||
image.unsubscribe(proceedScrollToView)
|
|
||||||
}
|
|
||||||
|
|
||||||
export function scrollIntoView(path, id) {
|
export function scrollIntoView(path, id) {
|
||||||
if (!id) {
|
if (!id) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pausedScrollToView) {
|
|
||||||
pausedScrollToView = [path, id]
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!image.isAllImagesComplete()) {
|
|
||||||
pausedScrollToView = [path, id]
|
|
||||||
image.subscribe(proceedScrollToView)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
const section = dom.find('#' + id)
|
const section = dom.find('#' + id)
|
||||||
section && scrollTo(section)
|
section && scrollTo(section)
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,9 @@ export function btn(el) {
|
|||||||
const toggle = _ => dom.body.classList.toggle('close')
|
const toggle = _ => dom.body.classList.toggle('close')
|
||||||
|
|
||||||
el = dom.getNode(el)
|
el = dom.getNode(el)
|
||||||
|
if (el == null) {
|
||||||
|
return
|
||||||
|
}
|
||||||
dom.on(el, 'click', e => {
|
dom.on(el, 'click', e => {
|
||||||
e.stopPropagation()
|
e.stopPropagation()
|
||||||
toggle()
|
toggle()
|
||||||
@@ -24,7 +27,9 @@ export function btn(el) {
|
|||||||
|
|
||||||
export function collapse(el) {
|
export function collapse(el) {
|
||||||
el = dom.getNode(el)
|
el = dom.getNode(el)
|
||||||
|
if (el == null) {
|
||||||
|
return
|
||||||
|
}
|
||||||
dom.on(el, 'click', ({target}) => {
|
dom.on(el, 'click', ({target}) => {
|
||||||
if (
|
if (
|
||||||
target.nodeName === 'A' &&
|
target.nodeName === 'A' &&
|
||||||
@@ -60,8 +65,10 @@ export function sticky() {
|
|||||||
*/
|
*/
|
||||||
export function getAndActive(router, el, isParent, autoTitle) {
|
export function getAndActive(router, el, isParent, autoTitle) {
|
||||||
el = dom.getNode(el)
|
el = dom.getNode(el)
|
||||||
|
let links = []
|
||||||
const links = dom.findAll(el, 'a')
|
if (el != null) {
|
||||||
|
links = dom.findAll(el, 'a')
|
||||||
|
}
|
||||||
const hash = decodeURI(router.toURL(router.getCurrentPath()))
|
const hash = decodeURI(router.toURL(router.getCurrentPath()))
|
||||||
let target
|
let target
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ import {slugify} from './slugify'
|
|||||||
import {emojify} from './emojify'
|
import {emojify} from './emojify'
|
||||||
import {isAbsolutePath, getPath, getParentPath} from '../router/util'
|
import {isAbsolutePath, getPath, getParentPath} from '../router/util'
|
||||||
import {isFn, merge, cached, isPrimitive} from '../util/core'
|
import {isFn, merge, cached, isPrimitive} from '../util/core'
|
||||||
import image from '../util/image'
|
|
||||||
|
|
||||||
// See https://github.com/PrismJS/prism/pull/1367
|
// See https://github.com/PrismJS/prism/pull/1367
|
||||||
import 'prismjs/components/prism-markup-templating'
|
import 'prismjs/components/prism-markup-templating'
|
||||||
@@ -165,6 +164,7 @@ export class Compiler {
|
|||||||
embed = compileMedia[type].call(this, href, title)
|
embed = compileMedia[type].call(this, href, title)
|
||||||
embed.type = type
|
embed.type = type
|
||||||
}
|
}
|
||||||
|
embed.fragment = config.fragment
|
||||||
|
|
||||||
return embed
|
return embed
|
||||||
}
|
}
|
||||||
@@ -300,9 +300,24 @@ export class Compiler {
|
|||||||
url = getPath(contentBase, getParentPath(router.getCurrentPath()), href)
|
url = getPath(contentBase, getParentPath(router.getCurrentPath()), href)
|
||||||
}
|
}
|
||||||
|
|
||||||
image.increaseLoadingImageCount()
|
return `<img src="${url}"data-origin="${href}" alt="${text}"${attrs}>`
|
||||||
|
}
|
||||||
|
origin.list = renderer.list = function (body, ordered, start) {
|
||||||
|
const isTaskList = /<li class="task-list-item">/.test(body.split('class="task-list"')[0])
|
||||||
|
const isStartReq = start && start > 1
|
||||||
|
const tag = ordered ? 'ol' : 'ul'
|
||||||
|
const tagAttrs = [
|
||||||
|
(isTaskList ? 'class="task-list"' : ''),
|
||||||
|
(isStartReq ? `start="${start}"` : '')
|
||||||
|
].join(' ').trim()
|
||||||
|
|
||||||
return `<img src="${url}" data-origin="${href}" alt="${text}" onload="javascript:Docsify.util.image.onLoad(this)" onerror="javascript:Docsify.util.image.onError(this)"${attrs}>`
|
return `<${tag} ${tagAttrs}>${body}</${tag}>`
|
||||||
|
}
|
||||||
|
origin.listitem = renderer.listitem = function (text) {
|
||||||
|
const isTaskItem = /^(<input.*type="checkbox"[^>]*>)/.test(text)
|
||||||
|
const html = isTaskItem ? `<li class="task-list-item"><label>${text}</label></li>` : `<li>${text}</li>`
|
||||||
|
|
||||||
|
return html
|
||||||
}
|
}
|
||||||
|
|
||||||
renderer.origin = origin
|
renderer.origin = origin
|
||||||
|
|||||||
@@ -20,6 +20,11 @@ function walkFetchEmbed({embedTokens, compile, fetch}, cb) {
|
|||||||
if (token.embed.type === 'markdown') {
|
if (token.embed.type === 'markdown') {
|
||||||
embedToken = compile.lexer(text)
|
embedToken = compile.lexer(text)
|
||||||
} else if (token.embed.type === 'code') {
|
} else if (token.embed.type === 'code') {
|
||||||
|
if (token.embed.fragment) {
|
||||||
|
const fragment = token.embed.fragment
|
||||||
|
const pattern = new RegExp(`(?:###|\\/\\/\\/)\\s*\\[${fragment}\\]([\\s\\S]*)(?:###|\\/\\/\\/)\\s*\\[${fragment}\\]`)
|
||||||
|
text = ((text.match(pattern) || [])[1] || '').trim()
|
||||||
|
}
|
||||||
embedToken = compile.lexer(
|
embedToken = compile.lexer(
|
||||||
'```' +
|
'```' +
|
||||||
token.embed.lang +
|
token.embed.lang +
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import {inBrowser} from '../util/env'
|
import {inBrowser} from '../util/env'
|
||||||
|
|
||||||
function replace(m, $1) {
|
function replace(m, $1) {
|
||||||
return '<img class="emoji" src="https://assets-cdn.github.com/images/icons/emoji/' + $1 + '.png" alt="' + $1 + '" />'
|
return '<img class="emoji" src="https://github.githubassets.com/images/icons/emoji/' + $1 + '.png" alt="' + $1 + '" />'
|
||||||
}
|
}
|
||||||
|
|
||||||
export function emojify(text) {
|
export function emojify(text) {
|
||||||
|
|||||||
@@ -3,7 +3,8 @@ import {
|
|||||||
isAbsolutePath,
|
isAbsolutePath,
|
||||||
stringifyQuery,
|
stringifyQuery,
|
||||||
cleanPath,
|
cleanPath,
|
||||||
replaceSlug
|
replaceSlug,
|
||||||
|
resolvePath
|
||||||
} from '../util'
|
} from '../util'
|
||||||
import {noop, merge} from '../../util/core'
|
import {noop, merge} from '../../util/core'
|
||||||
|
|
||||||
@@ -73,9 +74,13 @@ export class History {
|
|||||||
if (local) {
|
if (local) {
|
||||||
const idIndex = currentRoute.indexOf('?')
|
const idIndex = currentRoute.indexOf('?')
|
||||||
path =
|
path =
|
||||||
(idIndex > 0 ? currentRoute.substr(0, idIndex) : currentRoute) + path
|
(idIndex > 0 ? currentRoute.substring(0, idIndex) : currentRoute) + path
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this.config.relativePath && path.indexOf('/') !== 0) {
|
||||||
|
const currentDir = currentRoute.substring(0, currentRoute.lastIndexOf('/') + 1)
|
||||||
|
return cleanPath(resolvePath(currentDir + path))
|
||||||
|
}
|
||||||
return cleanPath('/' + path)
|
return cleanPath('/' + path)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -53,6 +53,20 @@ export const cleanPath = cached(path => {
|
|||||||
return path.replace(/^\/+/, '/').replace(/([^:])\/{2,}/g, '$1/')
|
return path.replace(/^\/+/, '/').replace(/([^:])\/{2,}/g, '$1/')
|
||||||
})
|
})
|
||||||
|
|
||||||
|
export const resolvePath = cached(path => {
|
||||||
|
const segments = path.replace(/^\//, '').split('/')
|
||||||
|
let resolved = []
|
||||||
|
for (let i = 0, len = segments.length; i < len; i++) {
|
||||||
|
const segment = segments[i]
|
||||||
|
if (segment === '..') {
|
||||||
|
resolved.pop()
|
||||||
|
} else if (segment !== '.') {
|
||||||
|
resolved.push(segment)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return '/' + resolved.join('/')
|
||||||
|
})
|
||||||
|
|
||||||
export function getPath(...args) {
|
export function getPath(...args) {
|
||||||
return cleanPath(args.join('/'))
|
return cleanPath(args.join('/'))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,62 +0,0 @@
|
|||||||
export default (function () {
|
|
||||||
let loadingImageCount = 0
|
|
||||||
const subscribers = []
|
|
||||||
|
|
||||||
function subscribe(cb) {
|
|
||||||
subscribers.push(cb)
|
|
||||||
}
|
|
||||||
|
|
||||||
function unsubscribe(cb) {
|
|
||||||
const index = subscribers.indexOf(cb)
|
|
||||||
|
|
||||||
if (index !== -1) {
|
|
||||||
subscribers.splice(index, 1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function notifyAllImagesComplete() {
|
|
||||||
for (let i = 0; i < subscribers.length; i++) {
|
|
||||||
subscribers[i]()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function increaseLoadingImageCount() {
|
|
||||||
loadingImageCount += 1
|
|
||||||
}
|
|
||||||
|
|
||||||
function decreaseLoadingImageCount() {
|
|
||||||
loadingImageCount -= 1
|
|
||||||
|
|
||||||
if (loadingImageCount === 0) {
|
|
||||||
notifyAllImagesComplete()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function cleanElement(ele) {
|
|
||||||
ele.removeAttribute('onload')
|
|
||||||
ele.removeAttribute('onerror')
|
|
||||||
}
|
|
||||||
|
|
||||||
function onLoad(ele) {
|
|
||||||
cleanElement(ele)
|
|
||||||
decreaseLoadingImageCount()
|
|
||||||
}
|
|
||||||
|
|
||||||
function onError(ele) {
|
|
||||||
cleanElement(ele)
|
|
||||||
decreaseLoadingImageCount()
|
|
||||||
}
|
|
||||||
|
|
||||||
function isAllImagesComplete() {
|
|
||||||
return loadingImageCount === 0
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
subscribe,
|
|
||||||
unsubscribe,
|
|
||||||
increaseLoadingImageCount,
|
|
||||||
onLoad,
|
|
||||||
onError,
|
|
||||||
isAllImagesComplete
|
|
||||||
}
|
|
||||||
})()
|
|
||||||
@@ -1,4 +1,3 @@
|
|||||||
export * from './core'
|
export * from './core'
|
||||||
export * from './env'
|
export * from './env'
|
||||||
export * from '../router/util'
|
export * from '../router/util'
|
||||||
export {default as image} from './image'
|
|
||||||
|
|||||||
@@ -892,7 +892,7 @@ const AllGithubEmoji = [
|
|||||||
window.emojify = function (match, $1) {
|
window.emojify = function (match, $1) {
|
||||||
return AllGithubEmoji.indexOf($1) === -1 ?
|
return AllGithubEmoji.indexOf($1) === -1 ?
|
||||||
match :
|
match :
|
||||||
'<img class="emoji" src="https://assets-cdn.github.com/images/icons/emoji/' +
|
'<img class="emoji" src="https://github.githubassets.com/images/icons/emoji/' +
|
||||||
$1 +
|
$1 +
|
||||||
'.png" alt="' +
|
'.png" alt="' +
|
||||||
$1 +
|
$1 +
|
||||||
|
|||||||
+10
-4
@@ -7,10 +7,16 @@ function install(hook) {
|
|||||||
const main = dom.getNode('#main')
|
const main = dom.getNode('#main')
|
||||||
div.style = `width: ${main.clientWidth}px; margin: 0 auto 20px;`
|
div.style = `width: ${main.clientWidth}px; margin: 0 auto 20px;`
|
||||||
dom.appendTo(dom.find('.content'), div)
|
dom.appendTo(dom.find('.content'), div)
|
||||||
const script = dom.create('script')
|
})
|
||||||
const content = `gitalk.render('gitalk-container')`
|
|
||||||
script.textContent = content
|
hook.doneEach(_ => {
|
||||||
dom.appendTo(dom.body, script)
|
const el = document.getElementById('gitalk-container')
|
||||||
|
while (el.hasChildNodes()) {
|
||||||
|
el.removeChild(el.firstChild)
|
||||||
|
}
|
||||||
|
|
||||||
|
// eslint-disable-next-line
|
||||||
|
gitalk.render('gitalk-container')
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -323,6 +323,9 @@ body.sticky
|
|||||||
|
|
||||||
.markdown-section iframe
|
.markdown-section iframe
|
||||||
border 1px solid #eee
|
border 1px solid #eee
|
||||||
|
/* fix horizontal overflow on iOS Safari */
|
||||||
|
width 1px
|
||||||
|
min-width 100%
|
||||||
|
|
||||||
.markdown-section table
|
.markdown-section table
|
||||||
border-collapse collapse
|
border-collapse collapse
|
||||||
@@ -383,6 +386,9 @@ body.sticky
|
|||||||
border-radius 2px
|
border-radius 2px
|
||||||
padding 1rem
|
padding 1rem
|
||||||
|
|
||||||
|
.markdown-section ul.task-list > li
|
||||||
|
list-style-type none
|
||||||
|
|
||||||
body.close
|
body.close
|
||||||
.sidebar
|
.sidebar
|
||||||
transform translateX(- $sidebar-width)
|
transform translateX(- $sidebar-width)
|
||||||
|
|||||||
@@ -0,0 +1,228 @@
|
|||||||
|
@import url('https://fonts.googleapis.com/css?family=Thasadith:400,400i,700')
|
||||||
|
|
||||||
|
$color-primary = #00ffff
|
||||||
|
$color-bg = #f0ffff
|
||||||
|
$color-text = #34495e
|
||||||
|
$sidebar-width = 300px
|
||||||
|
|
||||||
|
@import 'basic/_layout'
|
||||||
|
@import 'basic/_coverpage'
|
||||||
|
|
||||||
|
body
|
||||||
|
background-color $color-bg
|
||||||
|
|
||||||
|
/* sidebar */
|
||||||
|
.sidebar
|
||||||
|
background-color $color-bg
|
||||||
|
color #364149
|
||||||
|
|
||||||
|
li
|
||||||
|
margin 6px 0 6px 0
|
||||||
|
|
||||||
|
ul li a
|
||||||
|
color #505d6b
|
||||||
|
font-size 14px
|
||||||
|
font-weight normal
|
||||||
|
overflow hidden
|
||||||
|
text-decoration none
|
||||||
|
text-overflow ellipsis
|
||||||
|
white-space nowrap
|
||||||
|
|
||||||
|
&:hover
|
||||||
|
text-decoration underline
|
||||||
|
|
||||||
|
ul li ul
|
||||||
|
padding 0
|
||||||
|
|
||||||
|
ul li.active > a
|
||||||
|
border-right 2px solid
|
||||||
|
color var(--theme-color, $color-primary)
|
||||||
|
font-weight 600
|
||||||
|
|
||||||
|
.app-sub-sidebar
|
||||||
|
li
|
||||||
|
&::before
|
||||||
|
content '-'
|
||||||
|
padding-right 4px
|
||||||
|
float left
|
||||||
|
|
||||||
|
/* markdown content found on pages */
|
||||||
|
.markdown-section h1, .markdown-section h2, .markdown-section h3, .markdown-section h4, .markdown-section strong
|
||||||
|
color #2c3e50
|
||||||
|
font-weight 600
|
||||||
|
|
||||||
|
.markdown-section a
|
||||||
|
color var(--theme-color, $color-primary)
|
||||||
|
font-weight 600
|
||||||
|
|
||||||
|
&:hover
|
||||||
|
text-decoration underline
|
||||||
|
|
||||||
|
.markdown-section h1
|
||||||
|
font-size 2rem
|
||||||
|
margin 0 0 1rem
|
||||||
|
|
||||||
|
.markdown-section h2
|
||||||
|
font-size 1.75rem
|
||||||
|
margin 45px 0 0.8rem
|
||||||
|
|
||||||
|
.markdown-section h3
|
||||||
|
font-size 1.5rem
|
||||||
|
margin 40px 0 0.6rem
|
||||||
|
|
||||||
|
.markdown-section h4
|
||||||
|
font-size 1.25rem
|
||||||
|
|
||||||
|
.markdown-section h5
|
||||||
|
font-size 1rem
|
||||||
|
|
||||||
|
.markdown-section h6
|
||||||
|
color #777
|
||||||
|
font-size 1rem
|
||||||
|
|
||||||
|
.markdown-section figure, .markdown-section p
|
||||||
|
margin 1.2em 0
|
||||||
|
|
||||||
|
.markdown-section p, .markdown-section ul, .markdown-section ol
|
||||||
|
line-height 1.6rem
|
||||||
|
word-spacing 0.05rem
|
||||||
|
|
||||||
|
.markdown-section ul, .markdown-section ol
|
||||||
|
padding-left 1.5rem
|
||||||
|
|
||||||
|
.markdown-section blockquote
|
||||||
|
border-left 4px solid var(--theme-color, $color-primary)
|
||||||
|
color #858585
|
||||||
|
margin 2em 0
|
||||||
|
padding-left 20px
|
||||||
|
|
||||||
|
.markdown-section blockquote p
|
||||||
|
font-weight 600
|
||||||
|
margin-left 0
|
||||||
|
|
||||||
|
.markdown-section iframe
|
||||||
|
margin 1em 0
|
||||||
|
|
||||||
|
.markdown-section em
|
||||||
|
color #7f8c8d
|
||||||
|
|
||||||
|
.markdown-section code
|
||||||
|
background-color #f8f8f8
|
||||||
|
border-radius 2px
|
||||||
|
color #e96900
|
||||||
|
font-family 'Roboto Mono', Monaco, courier, monospace
|
||||||
|
font-size 0.8rem
|
||||||
|
margin 0 2px
|
||||||
|
padding 3px 5px
|
||||||
|
white-space pre-wrap
|
||||||
|
|
||||||
|
.markdown-section pre
|
||||||
|
-moz-osx-font-smoothing initial
|
||||||
|
-webkit-font-smoothing initial
|
||||||
|
background-color #f8f8f8
|
||||||
|
font-family 'Roboto Mono', Monaco, courier, monospace
|
||||||
|
line-height 1.5rem
|
||||||
|
margin 1.2em 0
|
||||||
|
overflow auto
|
||||||
|
padding 0 1.4rem
|
||||||
|
position relative
|
||||||
|
word-wrap normal
|
||||||
|
|
||||||
|
/* code highlight */
|
||||||
|
.token.comment, .token.prolog, .token.doctype, .token.cdata
|
||||||
|
color #8e908c
|
||||||
|
|
||||||
|
.token.namespace
|
||||||
|
opacity 0.7
|
||||||
|
|
||||||
|
.token.boolean, .token.number
|
||||||
|
color #c76b29
|
||||||
|
|
||||||
|
.token.punctuation
|
||||||
|
color #525252
|
||||||
|
|
||||||
|
.token.property
|
||||||
|
color #c08b30
|
||||||
|
|
||||||
|
.token.tag
|
||||||
|
color #2973b7
|
||||||
|
|
||||||
|
.token.string
|
||||||
|
color var(--theme-color, $color-primary)
|
||||||
|
|
||||||
|
.token.selector
|
||||||
|
color #6679cc
|
||||||
|
|
||||||
|
.token.attr-name
|
||||||
|
color #2973b7
|
||||||
|
|
||||||
|
.token.entity, .token.url, .language-css .token.string, .style .token.string
|
||||||
|
color #22a2c9
|
||||||
|
|
||||||
|
.token.attr-value, .token.control, .token.directive, .token.unit
|
||||||
|
color var(--theme-color, $color-primary)
|
||||||
|
|
||||||
|
.token.keyword, .token.function
|
||||||
|
color #e96900
|
||||||
|
|
||||||
|
.token.statement, .token.regex, .token.atrule
|
||||||
|
color #22a2c9
|
||||||
|
|
||||||
|
.token.placeholder, .token.variable
|
||||||
|
color #3d8fd1
|
||||||
|
|
||||||
|
.token.deleted
|
||||||
|
text-decoration line-through
|
||||||
|
|
||||||
|
.token.inserted
|
||||||
|
border-bottom 1px dotted #202746
|
||||||
|
text-decoration none
|
||||||
|
|
||||||
|
.token.italic
|
||||||
|
font-style italic
|
||||||
|
|
||||||
|
.token.important, .token.bold
|
||||||
|
font-weight bold
|
||||||
|
|
||||||
|
.token.important
|
||||||
|
color #c94922
|
||||||
|
|
||||||
|
.token.entity
|
||||||
|
cursor help
|
||||||
|
|
||||||
|
.markdown-section pre > code
|
||||||
|
-moz-osx-font-smoothing initial
|
||||||
|
-webkit-font-smoothing initial
|
||||||
|
background-color #f8f8f8
|
||||||
|
border-radius 2px
|
||||||
|
color #525252
|
||||||
|
display block
|
||||||
|
font-family 'Roboto Mono', Monaco, courier, monospace
|
||||||
|
font-size 0.8rem
|
||||||
|
line-height inherit
|
||||||
|
margin 0 2px
|
||||||
|
max-width inherit
|
||||||
|
overflow inherit
|
||||||
|
padding 2.2em 5px
|
||||||
|
white-space inherit
|
||||||
|
|
||||||
|
.markdown-section code::after, .markdown-section code::before
|
||||||
|
letter-spacing 0.05rem
|
||||||
|
|
||||||
|
code .token
|
||||||
|
-moz-osx-font-smoothing initial
|
||||||
|
-webkit-font-smoothing initial
|
||||||
|
min-height 1.5rem
|
||||||
|
|
||||||
|
pre::after
|
||||||
|
color #ccc
|
||||||
|
content attr(data-lang)
|
||||||
|
font-size 0.6rem
|
||||||
|
font-weight 600
|
||||||
|
height 15px
|
||||||
|
line-height 15px
|
||||||
|
padding 5px 10px 0
|
||||||
|
position absolute
|
||||||
|
right 0
|
||||||
|
text-align right
|
||||||
|
top 0
|
||||||
@@ -0,0 +1,87 @@
|
|||||||
|
// load ES6 modules in Node.js on the fly
|
||||||
|
require = require('esm')(module/*, options*/)
|
||||||
|
|
||||||
|
const path = require('path')
|
||||||
|
const {expect} = require('chai')
|
||||||
|
|
||||||
|
const {JSDOM} = require('jsdom')
|
||||||
|
|
||||||
|
function ready(callback) {
|
||||||
|
const state = document.readyState
|
||||||
|
|
||||||
|
if (state === 'complete' || state === 'interactive') {
|
||||||
|
return setTimeout(callback, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
document.addEventListener('DOMContentLoaded', callback)
|
||||||
|
}
|
||||||
|
module.exports.init = function(fixture = 'default', config = {}, markup) {
|
||||||
|
if (markup == null) {
|
||||||
|
markup = `<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head></head>
|
||||||
|
<body>
|
||||||
|
<div id="app"></div>
|
||||||
|
<script>
|
||||||
|
window.$docsify = ${JSON.stringify(config, null, 2)}
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>`
|
||||||
|
}
|
||||||
|
const rootPath = path.join(__dirname, 'fixtures', fixture)
|
||||||
|
|
||||||
|
const dom = new JSDOM(markup)
|
||||||
|
dom.reconfigure({ url: 'file:///' + rootPath })
|
||||||
|
|
||||||
|
global.window = dom.window
|
||||||
|
global.document = dom.window.document
|
||||||
|
global.navigator = dom.window.navigator
|
||||||
|
global.location = dom.window.location
|
||||||
|
global.XMLHttpRequest = dom.window.XMLHttpRequest
|
||||||
|
|
||||||
|
// mimic src/core/index.js but for Node.js
|
||||||
|
function Docsify() {
|
||||||
|
this._init()
|
||||||
|
}
|
||||||
|
|
||||||
|
const proto = Docsify.prototype
|
||||||
|
|
||||||
|
const {initMixin} = require('../src/core/init')
|
||||||
|
const {routerMixin} = require('../src/core//router')
|
||||||
|
const {renderMixin} = require('../src/core//render')
|
||||||
|
const {fetchMixin} = require('../src/core/fetch')
|
||||||
|
const {eventMixin} = require('../src/core//event')
|
||||||
|
|
||||||
|
initMixin(proto)
|
||||||
|
routerMixin(proto)
|
||||||
|
renderMixin(proto)
|
||||||
|
fetchMixin(proto)
|
||||||
|
eventMixin(proto)
|
||||||
|
|
||||||
|
const NOT_INIT_PATTERN = '<!--main-->'
|
||||||
|
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
ready(() => {
|
||||||
|
const docsify = new Docsify()
|
||||||
|
// NOTE: I was not able to get it working with a callback, but polling works usually at the first time
|
||||||
|
const id = setInterval(() => {
|
||||||
|
if (dom.window.document.body.innerHTML.indexOf(NOT_INIT_PATTERN) == -1) {
|
||||||
|
clearInterval(id)
|
||||||
|
return resolve({
|
||||||
|
docsify: docsify,
|
||||||
|
dom: dom
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}, 10)
|
||||||
|
})
|
||||||
|
|
||||||
|
})
|
||||||
|
}
|
||||||
|
module.exports.expectSameDom = function(actual, expected) {
|
||||||
|
const WHITESPACES_BETWEEN_TAGS = />(\s\s+)</g
|
||||||
|
function replacer(match, group1) {
|
||||||
|
return match.replace(group1, '')
|
||||||
|
}
|
||||||
|
expect(actual.replace(WHITESPACES_BETWEEN_TAGS, replacer).trim())
|
||||||
|
.equal(expected.replace(WHITESPACES_BETWEEN_TAGS, replacer).trim())
|
||||||
|
}
|
||||||
Vendored
+6
@@ -0,0 +1,6 @@
|
|||||||
|
<!--
|
||||||
|
|
||||||
|
create your own fixture directory
|
||||||
|
if you need a custom README.md or sidebar
|
||||||
|
|
||||||
|
-->
|
||||||
Vendored
+18
@@ -0,0 +1,18 @@
|
|||||||
|
# Heading
|
||||||
|
|
||||||
|
[another page](other.md)
|
||||||
|
|
||||||
|
## II 1
|
||||||
|
|
||||||
|
### III 1
|
||||||
|
|
||||||
|
#### IV 1
|
||||||
|
|
||||||
|
##### V 1
|
||||||
|
|
||||||
|
|
||||||
|
## II 2
|
||||||
|
|
||||||
|
### III 2
|
||||||
|
|
||||||
|
#### IV 2
|
||||||
Vendored
+16
@@ -0,0 +1,16 @@
|
|||||||
|
# Other
|
||||||
|
|
||||||
|
## two 1
|
||||||
|
|
||||||
|
### three 1
|
||||||
|
|
||||||
|
#### four 1
|
||||||
|
|
||||||
|
##### five 1
|
||||||
|
|
||||||
|
|
||||||
|
## two 2
|
||||||
|
|
||||||
|
### three 2
|
||||||
|
|
||||||
|
#### four 2
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
const path = require('path')
|
||||||
|
|
||||||
|
const {expect} = require('chai')
|
||||||
|
|
||||||
|
const {init, expectSameDom} = require('../_helper')
|
||||||
|
|
||||||
|
describe('full docsify initialization', function() {
|
||||||
|
it('TODO: check generated markup', async function() {
|
||||||
|
const {docsify, dom} = await init('simple', {loadSidebar: true})
|
||||||
|
console.log(dom.window.document.body.innerHTML)
|
||||||
|
// TODO: add some expectations
|
||||||
|
})
|
||||||
|
|
||||||
|
})
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
const path = require('path')
|
||||||
|
|
||||||
|
const {expect} = require('chai')
|
||||||
|
|
||||||
|
const {init, expectSameDom} = require('../_helper')
|
||||||
|
|
||||||
|
describe('router', function() {
|
||||||
|
it('TODO: trigger to load another page', async function() {
|
||||||
|
const {docsify} = await init()
|
||||||
|
window.location = '/?foo=bar'
|
||||||
|
// TODO: add some expectations
|
||||||
|
})
|
||||||
|
|
||||||
|
})
|
||||||
@@ -0,0 +1,62 @@
|
|||||||
|
/* eslint-env node, chai, mocha */
|
||||||
|
require = require('esm')(module/*, options*/)
|
||||||
|
const {expect} = require('chai')
|
||||||
|
const {History} = require('../../src/core/router/history/base')
|
||||||
|
|
||||||
|
class MockHistory extends History {
|
||||||
|
parse(path) {
|
||||||
|
return {path}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
describe('router/history/base', function () {
|
||||||
|
describe('relativePath true', function () {
|
||||||
|
var history
|
||||||
|
|
||||||
|
beforeEach(function () {
|
||||||
|
history = new MockHistory({relativePath: true})
|
||||||
|
})
|
||||||
|
|
||||||
|
it('toURL', function () {
|
||||||
|
// WHEN
|
||||||
|
const url = history.toURL('guide.md', {}, '/zh-ch/')
|
||||||
|
|
||||||
|
// THEN
|
||||||
|
expect(url).equal('/zh-ch/guide')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('toURL with double dot', function () {
|
||||||
|
// WHEN
|
||||||
|
const url = history.toURL('../README.md', {}, '/zh-ch/')
|
||||||
|
|
||||||
|
// THEN
|
||||||
|
expect(url).equal('/README')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('toURL child path', function () {
|
||||||
|
// WHEN
|
||||||
|
const url = history.toURL('config/example.md', {}, '/zh-ch/')
|
||||||
|
|
||||||
|
// THEN
|
||||||
|
expect(url).equal('/zh-ch/config/example')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('toURL absolute path', function () {
|
||||||
|
// WHEN
|
||||||
|
const url = history.toURL('/README', {}, '/zh-ch/')
|
||||||
|
|
||||||
|
// THEN
|
||||||
|
expect(url).equal('/README')
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it('toURL without relative path', function () {
|
||||||
|
const history = new MockHistory({relativePath: false})
|
||||||
|
|
||||||
|
// WHEN
|
||||||
|
const url = history.toURL('README', {}, '/zh-ch/')
|
||||||
|
|
||||||
|
// THEN
|
||||||
|
expect(url).equal('/README')
|
||||||
|
})
|
||||||
|
})
|
||||||
@@ -0,0 +1,89 @@
|
|||||||
|
const path = require('path')
|
||||||
|
|
||||||
|
const {expect} = require('chai')
|
||||||
|
|
||||||
|
const {init, expectSameDom} = require('../_helper')
|
||||||
|
|
||||||
|
describe('render', function() {
|
||||||
|
it('important content (tips)', async function() {
|
||||||
|
const {docsify, dom} = await init()
|
||||||
|
const output = docsify.compiler.compile('!> **Time** is money, my friend!')
|
||||||
|
expect(output).equal('<p class="tip"><strong>Time</strong> is money, my friend!</p>')
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('lists', function() {
|
||||||
|
it('as unordered task list', async function() {
|
||||||
|
const {docsify, dom} = await init()
|
||||||
|
const output = docsify.compiler.compile(`
|
||||||
|
- [x] Task 1
|
||||||
|
- [ ] Task 2
|
||||||
|
- [ ] Task 3`)
|
||||||
|
expect(output, `<ul class="task-list">
|
||||||
|
<li class="task-list-item"><label><input checked="" disabled="" type="checkbox"> Task 1</label></li>
|
||||||
|
<li class="task-list-item"><label><input disabled="" type="checkbox"> Task 2</label></li>
|
||||||
|
<li class="task-list-item"><label><input disabled="" type="checkbox"> Task 3</label></li>
|
||||||
|
</ul>`)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('as ordered task list', async function() {
|
||||||
|
const {docsify, dom} = await init()
|
||||||
|
const output = docsify.compiler.compile(`
|
||||||
|
1. [ ] Task 1
|
||||||
|
2. [x] Task 2`)
|
||||||
|
expectSameDom(output, `<ol class="task-list">
|
||||||
|
<li class="task-list-item"><label><input disabled="" type="checkbox"> Task 1</label></li>
|
||||||
|
<li class="task-list-item"><label><input checked="" disabled="" type="checkbox"> Task 2</label></li>
|
||||||
|
</ol>`)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('normal unordered', async function() {
|
||||||
|
const {docsify, dom} = await init()
|
||||||
|
const output = docsify.compiler.compile(`
|
||||||
|
- [linktext](link)
|
||||||
|
- just text`)
|
||||||
|
expectSameDom(output, `<ul >
|
||||||
|
<li><a href="#/link">linktext</a></li>
|
||||||
|
<li>just text</li>
|
||||||
|
</ul>`)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('unordered with custom start', async function() {
|
||||||
|
const {docsify, dom} = await init()
|
||||||
|
const output = docsify.compiler.compile(`
|
||||||
|
1. first
|
||||||
|
2. second
|
||||||
|
|
||||||
|
text
|
||||||
|
|
||||||
|
3. third`)
|
||||||
|
expectSameDom(output, `<ol >
|
||||||
|
<li>first</li>
|
||||||
|
<li>second</li>
|
||||||
|
</ol>
|
||||||
|
<p>text</p>
|
||||||
|
<ol start="3">
|
||||||
|
<li>third</li>
|
||||||
|
</ol>`)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('nested', async function() {
|
||||||
|
const {docsify, dom} = await init()
|
||||||
|
const output = docsify.compiler.compile(`
|
||||||
|
- 1
|
||||||
|
- 2
|
||||||
|
- 2 a
|
||||||
|
- 2 b
|
||||||
|
- 3`)
|
||||||
|
expectSameDom(output, `<ul >
|
||||||
|
<li>1</li>
|
||||||
|
<li>2<ul >
|
||||||
|
<li>2 a</li>
|
||||||
|
<li>2 b</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
<li>3</li>
|
||||||
|
</ul>`)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
})
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
/* eslint-env node, chai, mocha */
|
||||||
|
require = require('esm')(module/*, options*/)
|
||||||
|
const {expect} = require('chai')
|
||||||
|
const {resolvePath} = require('../../src/core/router/util')
|
||||||
|
|
||||||
|
describe('router/util', function () {
|
||||||
|
it('resolvePath', async function () {
|
||||||
|
// WHEN
|
||||||
|
const result = resolvePath('hello.md')
|
||||||
|
|
||||||
|
// THEN
|
||||||
|
expect(result).equal('/hello.md')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('resolvePath with dot', async function () {
|
||||||
|
// WHEN
|
||||||
|
const result = resolvePath('./hello.md')
|
||||||
|
|
||||||
|
// THEN
|
||||||
|
expect(result).equal('/hello.md')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('resolvePath with two dots', async function () {
|
||||||
|
// WHEN
|
||||||
|
const result = resolvePath('test/../hello.md')
|
||||||
|
|
||||||
|
// THEN
|
||||||
|
expect(result).equal('/hello.md')
|
||||||
|
})
|
||||||
|
})
|
||||||
Reference in New Issue
Block a user