mirror of
https://github.com/docsifyjs/docsify.git
synced 2025-12-08 19:55:52 +00:00
chore: update miscellaneous parts of the source to reasonably modern language alternatives, remove polyfills, improve some JSDoc comments, remove traces of IE
BREAKING: In a minority of cases syntax updates may break apps running in very old browsers (such as Internet Explorer), or apps that build Docsify in a custom way with old build tools. To upgrade, build Docsify for older browsers in a custom way, or update existing build tools to handle newer syntax. DEPRECATED: `$docsify.themeColor` is deprecated and will be eventually removed, use a `--theme-color` CSS variable in your style sheet.
This commit is contained in:
parent
9cb76027cd
commit
b621e0e4e7
1
.github/PULL_REQUEST_TEMPLATE.md
vendored
1
.github/PULL_REQUEST_TEMPLATE.md
vendored
@ -62,4 +62,3 @@ If yes, please describe the impact and migration path for existing applications:
|
||||
- [ ] Firefox
|
||||
- [ ] Safari
|
||||
- [ ] Edge
|
||||
- [ ] IE
|
||||
|
||||
@ -46,7 +46,6 @@
|
||||
- Smart full-text search plugin
|
||||
- Multiple themes
|
||||
- Useful plugin API
|
||||
- Compatible with IE11
|
||||
- Support embedded files
|
||||
|
||||
## Quick start
|
||||
|
||||
@ -26,14 +26,15 @@ async function build(opts) {
|
||||
await rollup
|
||||
.rollup({
|
||||
input: opts.input,
|
||||
plugins: (opts.plugins || []).concat([
|
||||
plugins: [
|
||||
...(opts.plugins || []),
|
||||
commonjs(),
|
||||
nodeResolve(),
|
||||
replace({
|
||||
__VERSION__: version,
|
||||
})
|
||||
]),
|
||||
onwarn: function (message) {
|
||||
],
|
||||
onwarn(message) {
|
||||
if (message.code === 'UNRESOLVED_IMPORT') {
|
||||
throw new Error(
|
||||
`Could not resolve module ` +
|
||||
@ -44,8 +45,8 @@ async function build(opts) {
|
||||
}
|
||||
}
|
||||
})
|
||||
.then(function (bundle) {
|
||||
var dest = 'lib/' + (opts.output || opts.input)
|
||||
.then(bundle => {
|
||||
const dest = 'lib/' + (opts.output || opts.input)
|
||||
|
||||
console.log(dest)
|
||||
return bundle.write({
|
||||
@ -77,7 +78,7 @@ async function buildCore() {
|
||||
}
|
||||
|
||||
async function buildAllPlugin() {
|
||||
var plugins = [
|
||||
const plugins = [
|
||||
{name: 'search', input: 'search/index.js'},
|
||||
{name: 'ga', input: 'ga.js'},
|
||||
{name: 'gtag', input: 'gtag.js'},
|
||||
|
||||
@ -1,17 +1,17 @@
|
||||
import fs from 'fs';
|
||||
import { relative } from './util.js';
|
||||
var read = fs.readFileSync;
|
||||
var write = fs.writeFileSync;
|
||||
const read = fs.readFileSync;
|
||||
const write = fs.writeFileSync;
|
||||
const pkgPath = relative(import.meta, '..', 'package.json');
|
||||
const pkg = JSON.parse(read(pkgPath).toString());
|
||||
var version = process.env.VERSION || pkg.version;
|
||||
const version = process.env.VERSION || pkg.version;
|
||||
|
||||
var file = relative(import.meta, '..', 'docs', '_coverpage.md');
|
||||
var cover = read(file, 'utf8').toString();
|
||||
const file = relative(import.meta, '..', 'docs', '_coverpage.md');
|
||||
let cover = read(file, 'utf8').toString();
|
||||
|
||||
console.log('Replace version number in cover page...');
|
||||
cover = cover.replace(
|
||||
/<small>(\S+)?<\/small>/g,
|
||||
'<small>' + version + '</small>'
|
||||
/* html */ `<small>${version}</small>`
|
||||
);
|
||||
write(file, cover);
|
||||
|
||||
@ -11,17 +11,16 @@ fs.readdir(relative('../src/themes'), (err, files) => {
|
||||
}
|
||||
files.map(async (file) => {
|
||||
if (/\.styl/g.test(file)) {
|
||||
var stylusCMD;
|
||||
const stylusBin = ['node_modules', 'stylus', 'bin', 'stylus'].join(path.sep)
|
||||
var cmdargs = [
|
||||
let cmdargs = [
|
||||
stylusBin,
|
||||
`src/themes/${file}`,
|
||||
'-u',
|
||||
'autoprefixer-stylus'
|
||||
]
|
||||
cmdargs = cmdargs.concat(args)
|
||||
cmdargs = [...cmdargs, ...args]
|
||||
|
||||
stylusCMD = spawn('node', cmdargs, { shell: true })
|
||||
const stylusCMD = spawn('node', cmdargs, { shell: true })
|
||||
|
||||
stylusCMD.stdout.on('data', (data) => {
|
||||
console.log(`[Stylus Build ] stdout: ${data}`);
|
||||
|
||||
@ -93,17 +93,15 @@ function writeEmojiJS(emojiData) {
|
||||
}
|
||||
}
|
||||
|
||||
(async () => {
|
||||
console.info('Build emoji');
|
||||
console.info('Build emoji');
|
||||
|
||||
try {
|
||||
const emojiData = await getEmojiData();
|
||||
try {
|
||||
const emojiData = await getEmojiData();
|
||||
|
||||
if (emojiData) {
|
||||
writeEmojiPage(emojiData);
|
||||
writeEmojiJS(emojiData);
|
||||
}
|
||||
} catch (err) {
|
||||
console.warn(`- Error: ${err.message}`);
|
||||
if (emojiData) {
|
||||
writeEmojiPage(emojiData);
|
||||
writeEmojiJS(emojiData);
|
||||
}
|
||||
})();
|
||||
} catch (err) {
|
||||
console.warn(`- Error: ${err.message}`);
|
||||
}
|
||||
|
||||
@ -16,7 +16,6 @@ See the [Quick start](quickstart.md) guide for more details.
|
||||
- Multiple themes
|
||||
- Useful plugin API
|
||||
- Emoji support
|
||||
- Compatible with IE11
|
||||
|
||||
## Examples
|
||||
|
||||
|
||||
@ -1,16 +1,16 @@
|
||||
import fetch from 'fetch'
|
||||
import fetch from 'fetch';
|
||||
|
||||
const URL = 'https://example.com'
|
||||
const PORT = 8080
|
||||
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))
|
||||
.then(response => {
|
||||
return response.json();
|
||||
})
|
||||
.then(myJson => {
|
||||
console.log(JSON.stringify(myJson));
|
||||
});
|
||||
/// [demo]
|
||||
|
||||
result.then(console.log).catch(console.error)
|
||||
result.then(console.log).catch(console.error);
|
||||
|
||||
@ -244,7 +244,7 @@ See https://github.com/lukeed/tinydate#patterns
|
||||
window.$docsify = {
|
||||
formatUpdated: '{MM}/{DD} {HH}:{mm}',
|
||||
|
||||
formatUpdated: function (time) {
|
||||
formatUpdated(time) {
|
||||
// ...
|
||||
|
||||
return time;
|
||||
@ -341,14 +341,14 @@ window.$docsify = {
|
||||
markdown: {
|
||||
smartypants: true,
|
||||
renderer: {
|
||||
link: function () {
|
||||
link() {
|
||||
// ...
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
// function
|
||||
markdown: function (marked, renderer) {
|
||||
markdown(marked, renderer) {
|
||||
// ...
|
||||
return marked;
|
||||
},
|
||||
@ -689,18 +689,17 @@ window.$docsify = {
|
||||
'/foo': '# Custom Markdown',
|
||||
|
||||
// RegEx match w/ synchronous function
|
||||
'/bar/(.*)': function (route, matched) {
|
||||
'/bar/(.*)'(route, matched) {
|
||||
return '# Custom Markdown';
|
||||
},
|
||||
|
||||
// RegEx match w/ asynchronous function
|
||||
'/baz/(.*)': function (route, matched, next) {
|
||||
// Requires `fetch` polyfill for legacy browsers (https://github.github.io/fetch/)
|
||||
'/baz/(.*)'(route, matched, next) {
|
||||
fetch('/api/users?id=12345')
|
||||
.then(function (response) {
|
||||
.then(response => {
|
||||
next('# Custom Markdown');
|
||||
})
|
||||
.catch(function (err) {
|
||||
.catch(err => {
|
||||
// Handle error...
|
||||
});
|
||||
},
|
||||
@ -714,7 +713,7 @@ Other than strings, route functions can return a falsy value (`null` \ `undefine
|
||||
window.$docsify = {
|
||||
routes: {
|
||||
// accepts everything other than dogs (synchronous)
|
||||
'/pets/(.+)': function(route, matched) {
|
||||
'/pets/(.+)'(route, matched) {
|
||||
if (matched[0] === 'dogs') {
|
||||
return null;
|
||||
} else {
|
||||
@ -723,7 +722,7 @@ window.$docsify = {
|
||||
}
|
||||
|
||||
// accepts everything other than cats (asynchronous)
|
||||
'/pets/(.*)': function(route, matched, next) {
|
||||
'/pets/(.*)'(route, matched, next) {
|
||||
if (matched[0] === 'cats') {
|
||||
next();
|
||||
} else {
|
||||
@ -741,12 +740,12 @@ Finally, if you have a specific path that has a real markdown file (and therefor
|
||||
window.$docsify = {
|
||||
routes: {
|
||||
// if you look up /pets/cats, docsify will skip all routes and look for "pets/cats.md"
|
||||
'/pets/cats': function(route, matched) {
|
||||
'/pets/cats'(route, matched) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// but any other pet should generate dynamic content right here
|
||||
'/pets/(.+)': function(route, matched) {
|
||||
'/pets/(.+)'(route, matched) {
|
||||
const pet = matched[0];
|
||||
return `your pet is ${pet} (but not a cat)`;
|
||||
}
|
||||
@ -777,11 +776,19 @@ If you have a link to the homepage in the sidebar and want it to be shown as act
|
||||
|
||||
For more details, see [#1131](https://github.com/docsifyjs/docsify/issues/1131).
|
||||
|
||||
## themeColor
|
||||
## themeColor (_deprecated_)
|
||||
|
||||
> **Warning** Deprecated. Use the CSS var `--theme-color` in your `<style>` sheet. Example:
|
||||
>
|
||||
> <style>
|
||||
> :root {
|
||||
> --theme-color: deeppink;
|
||||
> }
|
||||
> </style>
|
||||
|
||||
- Type: `String`
|
||||
|
||||
Customize the theme color. Use [CSS3 variables](https://developer.mozilla.org/en-US/docs/Web/CSS/Using_CSS_variables) feature and polyfill in older browsers.
|
||||
Customize the theme color.
|
||||
|
||||
```js
|
||||
window.$docsify = {
|
||||
|
||||
@ -8,7 +8,6 @@
|
||||
name="google-site-verification"
|
||||
content="6t0LoIeFksrjF4c9sqUEsVXiQNxLp2hgoqo0KryT-sE"
|
||||
/>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
|
||||
<meta
|
||||
name="keywords"
|
||||
content="doc,docs,documentation,gitbook,creator,generator,github,jekyll,github-pages"
|
||||
@ -64,7 +63,7 @@
|
||||
<script src="//cdn.jsdelivr.net/npm/docsify-plugin-carbon@1"></script>
|
||||
<script>
|
||||
// Set html "lang" attribute based on URL
|
||||
var lang = location.hash.match(/#\/(de-de|es|ru-ru|zh-cn)\//);
|
||||
const lang = location.hash.match(/#\/(de-de|es|ru-ru|zh-cn)\//);
|
||||
|
||||
if (lang) {
|
||||
document.documentElement.setAttribute('lang', lang[1]);
|
||||
@ -128,9 +127,8 @@
|
||||
},
|
||||
vueComponents: {
|
||||
'button-counter': {
|
||||
template:
|
||||
'<button @click="count += 1">You clicked me {{ count }} times</button>',
|
||||
data: function () {
|
||||
template: /* html */ `<button @click="count += 1">You clicked me {{ count }} times</button>`,
|
||||
data() {
|
||||
return {
|
||||
count: 0,
|
||||
};
|
||||
@ -138,7 +136,7 @@
|
||||
},
|
||||
},
|
||||
vueGlobalOptions: {
|
||||
data: function () {
|
||||
data() {
|
||||
return {
|
||||
count: 0,
|
||||
message: 'Hello, World!',
|
||||
@ -151,7 +149,7 @@
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
timeOfDay: function () {
|
||||
timeOfDay() {
|
||||
const date = new Date();
|
||||
const hours = date.getHours();
|
||||
|
||||
@ -165,14 +163,14 @@
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
hello: function () {
|
||||
hello() {
|
||||
alert(this.message);
|
||||
},
|
||||
},
|
||||
},
|
||||
vueMounts: {
|
||||
'#counter': {
|
||||
data: function () {
|
||||
data() {
|
||||
return {
|
||||
count: 0,
|
||||
};
|
||||
@ -182,7 +180,7 @@
|
||||
plugins: [
|
||||
DocsifyCarbon.create('CEBI6KQE', 'docsifyjsorg'),
|
||||
function (hook, vm) {
|
||||
hook.beforeEach(function (html) {
|
||||
hook.beforeEach(html => {
|
||||
if (/githubusercontent\.com/.test(vm.route.file)) {
|
||||
url = vm.route.file
|
||||
.replace('raw.githubusercontent.com', 'github.com')
|
||||
@ -196,14 +194,14 @@
|
||||
'https://github.com/docsifyjs/docsify/blob/develop/docs/' +
|
||||
vm.route.file;
|
||||
}
|
||||
var editHtml = '[:memo: Edit Document](' + url + ')\n';
|
||||
const editHtml = '[:memo: Edit Document](' + url + ')\n';
|
||||
return (
|
||||
editHtml +
|
||||
html +
|
||||
'\n\n----\n\n' +
|
||||
'<a href="https://docsify.js.org" target="_blank" style="color: inherit; font-weight: normal; text-decoration: none;">Powered by docsify</a>'
|
||||
);
|
||||
})
|
||||
});
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
@ -58,7 +58,7 @@ function getAdder(int $x): int
|
||||
Code blocks [dynamically created from javascript](https://docsify.js.org/#/configuration?id=executescript) can be highlighted using the method `Prism.highlightElement` like so:
|
||||
|
||||
```javascript
|
||||
var code = document.createElement("code");
|
||||
const code = document.createElement("code");
|
||||
code.innerHTML = "console.log('Hello World!')";
|
||||
code.setAttribute("class", "lang-javascript");
|
||||
Prism.highlightElement(code);
|
||||
|
||||
@ -7,7 +7,7 @@ window.$docsify = {
|
||||
markdown: {
|
||||
smartypants: true,
|
||||
renderer: {
|
||||
link: function() {
|
||||
link() {
|
||||
// ...
|
||||
}
|
||||
}
|
||||
@ -21,7 +21,7 @@ You can completely customize the parsing rules.
|
||||
|
||||
```js
|
||||
window.$docsify = {
|
||||
markdown: function(marked, renderer) {
|
||||
markdown(marked, renderer) {
|
||||
// ...
|
||||
|
||||
return marked
|
||||
@ -36,17 +36,17 @@ window.$docsify = {
|
||||
// <link rel="stylesheet" href="//cdn.jsdelivr.net/npm/mermaid/dist/mermaid.min.css">
|
||||
// <script src="//cdn.jsdelivr.net/npm/mermaid/dist/mermaid.min.js"></script>
|
||||
|
||||
var num = 0;
|
||||
let num = 0;
|
||||
mermaid.initialize({ startOnLoad: false });
|
||||
|
||||
window.$docsify = {
|
||||
markdown: {
|
||||
renderer: {
|
||||
code: function(code, lang) {
|
||||
code(code, lang) {
|
||||
if (lang === "mermaid") {
|
||||
return (
|
||||
'<div class="mermaid">' + mermaid.render('mermaid-svg-' + num++, code) + "</div>"
|
||||
);
|
||||
return /* html */ `
|
||||
<div class="mermaid">${mermaid.render('mermaid-svg-' + num++, code)}</div>
|
||||
`;
|
||||
}
|
||||
return this.origin.code.apply(this, arguments);
|
||||
}
|
||||
|
||||
@ -63,11 +63,7 @@ By default, the hyperlink on the current page is recognized and the content is s
|
||||
<script src="//cdn.jsdelivr.net/npm/docsify/lib/plugins/search.min.js"></script>
|
||||
```
|
||||
|
||||
This plugin ignores diacritical marks when performing a full text search (e.g., "cafe" will also match "café"). Legacy browsers like IE11 require the following [String.normalize()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/normalize) polyfill to ignore diacritical marks:
|
||||
|
||||
```html
|
||||
<script src="//polyfill.io/v3/polyfill.min.js?features=String.prototype.normalize"></script>
|
||||
```
|
||||
This plugin ignores diacritical marks when performing a full text search (e.g., "cafe" will also match "café").
|
||||
|
||||
## Google Analytics
|
||||
|
||||
|
||||
@ -29,8 +29,8 @@ const HOSTNAME_WHITELIST = [
|
||||
|
||||
// The Util Function to hack URLs of intercepted requests
|
||||
const getFixedUrl = (req) => {
|
||||
var now = Date.now()
|
||||
var url = new URL(req.url)
|
||||
const now = Date.now()
|
||||
const url = new URL(req.url)
|
||||
|
||||
// 1. fixed http URL
|
||||
// Just keep syncing with location.protocol
|
||||
|
||||
@ -44,7 +44,6 @@ If you don't like `npm` or have trouble installing the tool, you can manually cr
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1" />
|
||||
<meta charset="UTF-8" />
|
||||
<link
|
||||
|
||||
@ -50,13 +50,13 @@ If you have any ideas or would like to develop a new theme, you are welcome to s
|
||||
</style>
|
||||
|
||||
<script>
|
||||
var preview = Docsify.dom.find('.demo-theme-preview');
|
||||
var themes = Docsify.dom.findAll('[rel="stylesheet"]');
|
||||
const preview = Docsify.dom.find('.demo-theme-preview');
|
||||
const themes = Docsify.dom.findAll('[rel="stylesheet"]');
|
||||
|
||||
preview.onclick = function (e) {
|
||||
var title = e.target.getAttribute('data-theme');
|
||||
const title = e.target.getAttribute('data-theme');
|
||||
|
||||
themes.forEach(function (theme) {
|
||||
themes.forEach(theme => {
|
||||
theme.disabled = theme.title !== title;
|
||||
});
|
||||
};
|
||||
|
||||
@ -24,15 +24,15 @@ Alternatively, a plugin can be stored in a separate file and "installed" using a
|
||||
```js
|
||||
// docsify-plugin-myplugin.js
|
||||
|
||||
(function () {
|
||||
var myPlugin = function (hook, vm) {
|
||||
{
|
||||
function myPlugin(hook, vm) {
|
||||
// ...
|
||||
};
|
||||
}
|
||||
|
||||
// Add plugin to docsify's plugin array
|
||||
$docsify = $docsify || {};
|
||||
$docsify.plugins = [].concat($docsify.plugins || [], myPlugin);
|
||||
})();
|
||||
window.$docsify = window.$docsify || {};
|
||||
$docsify.plugins = [...($docsify.plugins || []), myPlugin];
|
||||
}
|
||||
```
|
||||
|
||||
```html
|
||||
@ -51,47 +51,47 @@ Below is a plugin template with placeholders for all available lifecycle hooks.
|
||||
1. Load your plugin using a standard `<script>` tag
|
||||
|
||||
```js
|
||||
(function () {
|
||||
var myPlugin = function (hook, vm) {
|
||||
{
|
||||
function myPlugin(hook, vm) {
|
||||
// Invoked one time when docsify script is initialized
|
||||
hook.init(function () {
|
||||
hook.init(() => {
|
||||
// ...
|
||||
});
|
||||
|
||||
// Invoked one time when the docsify instance has mounted on the DOM
|
||||
hook.mounted(function () {
|
||||
hook.mounted(() => {
|
||||
// ...
|
||||
});
|
||||
|
||||
// Invoked on each page load before new markdown is transformed to HTML.
|
||||
// Supports asynchronous tasks (see beforeEach documentation for details).
|
||||
hook.beforeEach(function (markdown) {
|
||||
hook.beforeEach(markdown => {
|
||||
// ...
|
||||
return markdown;
|
||||
});
|
||||
|
||||
// Invoked on each page load after new markdown has been transformed to HTML.
|
||||
// Supports asynchronous tasks (see afterEach documentation for details).
|
||||
hook.afterEach(function (html) {
|
||||
hook.afterEach(html => {
|
||||
// ...
|
||||
return html;
|
||||
});
|
||||
|
||||
// Invoked on each page load after new HTML has been appended to the DOM
|
||||
hook.doneEach(function () {
|
||||
hook.doneEach(() => {
|
||||
// ...
|
||||
});
|
||||
|
||||
// Invoked one time after rendering the initial page
|
||||
hook.ready(function () {
|
||||
hook.ready(() => {
|
||||
// ...
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
// Add plugin to docsify's plugin array
|
||||
$docsify = $docsify || {};
|
||||
$docsify.plugins = [].concat(myPlugin, $docsify.plugins || []);
|
||||
})();
|
||||
window.$docsify = window.$docsify || {};
|
||||
$docsify.plugins = [myPlugin, ...($docsify.plugins || [])];
|
||||
}
|
||||
```
|
||||
|
||||
## Lifecycle Hooks
|
||||
@ -103,7 +103,7 @@ Lifecycle hooks are provided via the `hook` argument passed to the plugin functi
|
||||
Invoked one time when docsify script is initialized.
|
||||
|
||||
```js
|
||||
hook.init(function () {
|
||||
hook.init(() => {
|
||||
// ...
|
||||
});
|
||||
```
|
||||
@ -113,7 +113,7 @@ hook.init(function () {
|
||||
Invoked one time when the docsify instance has mounted on the DOM.
|
||||
|
||||
```js
|
||||
hook.mounted(function () {
|
||||
hook.mounted(() => {
|
||||
// ...
|
||||
});
|
||||
```
|
||||
@ -123,7 +123,7 @@ hook.mounted(function () {
|
||||
Invoked on each page load before new markdown is transformed to HTML.
|
||||
|
||||
```js
|
||||
hook.beforeEach(function (markdown) {
|
||||
hook.beforeEach(markdown => {
|
||||
// ...
|
||||
return markdown;
|
||||
});
|
||||
@ -132,7 +132,7 @@ hook.beforeEach(function (markdown) {
|
||||
For asynchronous tasks, the hook function accepts a `next` callback as a second argument. Call this function with the final `markdown` value when ready. To prevent errors from affecting docsify and other plugins, wrap async code in a `try/catch/finally` block.
|
||||
|
||||
```js
|
||||
hook.beforeEach(function (markdown, next) {
|
||||
hook.beforeEach((markdown, next) => {
|
||||
try {
|
||||
// Async task(s)...
|
||||
} catch (err) {
|
||||
@ -148,7 +148,7 @@ hook.beforeEach(function (markdown, next) {
|
||||
Invoked on each page load after new markdown has been transformed to HTML.
|
||||
|
||||
```js
|
||||
hook.afterEach(function (html) {
|
||||
hook.afterEach(html => {
|
||||
// ...
|
||||
return html;
|
||||
});
|
||||
@ -157,7 +157,7 @@ hook.afterEach(function (html) {
|
||||
For asynchronous tasks, the hook function accepts a `next` callback as a second argument. Call this function with the final `html` value when ready. To prevent errors from affecting docsify and other plugins, wrap async code in a `try/catch/finally` block.
|
||||
|
||||
```js
|
||||
hook.afterEach(function (html, next) {
|
||||
hook.afterEach((html, next) => {
|
||||
try {
|
||||
// Async task(s)...
|
||||
} catch (err) {
|
||||
@ -173,7 +173,7 @@ hook.afterEach(function (html, next) {
|
||||
Invoked on each page load after new HTML has been appended to the DOM.
|
||||
|
||||
```js
|
||||
hook.doneEach(function () {
|
||||
hook.doneEach(() => {
|
||||
// ...
|
||||
});
|
||||
```
|
||||
@ -183,7 +183,7 @@ hook.doneEach(function () {
|
||||
Invoked one time after rendering the initial page.
|
||||
|
||||
```js
|
||||
hook.ready(function () {
|
||||
hook.ready(() => {
|
||||
// ...
|
||||
});
|
||||
```
|
||||
@ -203,15 +203,15 @@ hook.ready(function () {
|
||||
window.$docsify = {
|
||||
plugins: [
|
||||
function pageFooter(hook, vm) {
|
||||
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/docsifyjs/docsify" target="_blank">docsify</a>.</span>',
|
||||
'</footer>',
|
||||
].join('');
|
||||
const footer = /* html */ `
|
||||
<hr/>
|
||||
<footer>
|
||||
<span><a href="https://github.com/QingWei-Li">cinwell</a> ©2017.</span>
|
||||
<span>Proudly published with <a href="https://github.com/docsifyjs/docsify" target="_blank">docsify</a>.</span>
|
||||
</footer>
|
||||
`;
|
||||
|
||||
hook.afterEach(function (html) {
|
||||
hook.afterEach(html => {
|
||||
return html + footer;
|
||||
});
|
||||
},
|
||||
@ -228,11 +228,11 @@ window.$docsify = {
|
||||
// The date template pattern
|
||||
$docsify.formatUpdated = '{YYYY}/{MM}/{DD} {HH}:{mm}';
|
||||
|
||||
hook.beforeEach(function (html) {
|
||||
var url =
|
||||
hook.beforeEach(html => {
|
||||
const url =
|
||||
'https://github.com/docsifyjs/docsify/blob/master/docs/' +
|
||||
vm.route.file;
|
||||
var editHtml = '[📝 EDIT DOCUMENT](' + url + ')\n';
|
||||
const editHtml = '[📝 EDIT DOCUMENT](' + url + ')\n';
|
||||
|
||||
return (
|
||||
editHtml +
|
||||
|
||||
@ -3,7 +3,6 @@
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<title>docsify</title>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1" />
|
||||
<link rel="stylesheet" href="/themes/vue.css" title="vue" />
|
||||
<link rel="stylesheet" href="/themes/dark.css" title="dark" disabled />
|
||||
@ -27,7 +26,7 @@
|
||||
<script src="//cdn.jsdelivr.net/npm/docsify-plugin-carbon@1"></script>
|
||||
<script>
|
||||
// Set html "lang" attribute based on URL
|
||||
var lang = location.hash.match(/#\/(de-de|es|ru-ru|zh-cn)\//);
|
||||
const lang = location.hash.match(/#\/(de-de|es|ru-ru|zh-cn)\//);
|
||||
|
||||
if (lang) {
|
||||
document.documentElement.setAttribute('lang', lang[1]);
|
||||
@ -88,7 +87,7 @@
|
||||
plugins: [
|
||||
DocsifyCarbon.create('CEBI6KQE', 'docsifyjsorg'),
|
||||
function (hook, vm) {
|
||||
hook.beforeEach(function (html) {
|
||||
hook.beforeEach(html => {
|
||||
if (/githubusercontent\.com/.test(vm.route.file)) {
|
||||
url = vm.route.file
|
||||
.replace('raw.githubusercontent.com', 'github.com')
|
||||
@ -102,7 +101,7 @@
|
||||
'https://github.com/docsifyjs/docsify/blob/develop/docs/' +
|
||||
vm.route.file;
|
||||
}
|
||||
var editHtml = '[:memo: Edit Document](' + url + ')\n';
|
||||
const editHtml = '[:memo: Edit Document](' + url + ')\n';
|
||||
return (
|
||||
editHtml +
|
||||
html +
|
||||
|
||||
@ -32,7 +32,7 @@ export class Docsify extends Fetch(
|
||||
}
|
||||
|
||||
initPlugin() {
|
||||
[].concat(this.config.plugins).forEach(fn => {
|
||||
this.config.plugins.forEach(fn => {
|
||||
try {
|
||||
isFn(fn) && fn(this._lifecycle, this);
|
||||
} catch (err) {
|
||||
|
||||
@ -1,10 +1,11 @@
|
||||
import { merge, hyphenate, isPrimitive, hasOwn } from './util/core.js';
|
||||
import stripIndent from 'strip-indent';
|
||||
import { hyphenate, isPrimitive } from './util/core.js';
|
||||
|
||||
const currentScript = document.currentScript;
|
||||
|
||||
/** @param {import('./Docsify').Docsify} vm */
|
||||
export default function (vm) {
|
||||
const config = merge(
|
||||
const config = Object.assign(
|
||||
{
|
||||
auto2top: false,
|
||||
autoHeader: false,
|
||||
@ -30,14 +31,36 @@ export default function (vm) {
|
||||
noCompileLinks: [],
|
||||
noEmoji: false,
|
||||
notFoundPage: true,
|
||||
plugins: [],
|
||||
relativePath: false,
|
||||
repo: '',
|
||||
routes: {},
|
||||
routerMode: 'hash',
|
||||
subMaxLevel: 0,
|
||||
themeColor: '',
|
||||
// themeColor: '',
|
||||
topMargin: 0,
|
||||
|
||||
// Deprecations //////////////////
|
||||
|
||||
__themeColor: '',
|
||||
get themeColor() {
|
||||
return this.__themeColor;
|
||||
},
|
||||
set themeColor(value) {
|
||||
this.__themeColor = value;
|
||||
console.warn(
|
||||
stripIndent(/* html */ `
|
||||
$docsify.themeColor is deprecated. Use a --theme-color property in your style sheet. Example:
|
||||
<style>
|
||||
:root {
|
||||
--theme-color: deeppink;
|
||||
}
|
||||
</style>
|
||||
`).trim()
|
||||
);
|
||||
},
|
||||
},
|
||||
|
||||
typeof window.$docsify === 'function'
|
||||
? window.$docsify(vm)
|
||||
: window.$docsify
|
||||
@ -45,18 +68,16 @@ export default function (vm) {
|
||||
|
||||
const script =
|
||||
currentScript ||
|
||||
[].slice
|
||||
.call(document.getElementsByTagName('script'))
|
||||
.filter(n => /docsify\./.test(n.src))[0];
|
||||
Array.from(document.getElementsByTagName('script')).filter(n =>
|
||||
/docsify\./.test(n.src)
|
||||
)[0];
|
||||
|
||||
if (script) {
|
||||
for (const prop in config) {
|
||||
if (hasOwn.call(config, prop)) {
|
||||
const val = script.getAttribute('data-' + hyphenate(prop));
|
||||
for (const prop of Object.keys(config)) {
|
||||
const val = script.getAttribute('data-' + hyphenate(prop));
|
||||
|
||||
if (isPrimitive(val)) {
|
||||
config[prop] = val === '' ? true : val;
|
||||
}
|
||||
if (isPrimitive(val)) {
|
||||
config[prop] = val === '' ? true : val;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -14,11 +14,8 @@ export function Events(Base) {
|
||||
$resetEvents(source) {
|
||||
const { auto2top } = this.config;
|
||||
|
||||
(() => {
|
||||
// Rely on the browser's scroll auto-restoration when going back or forward
|
||||
if (source === 'history') {
|
||||
return;
|
||||
}
|
||||
// If 'history', rely on the browser's scroll auto-restoration when going back or forward
|
||||
if (source !== 'history') {
|
||||
// Scroll to ID if specified
|
||||
if (this.route.query.id) {
|
||||
scrollIntoView(this.route.path, this.route.query.id);
|
||||
@ -27,7 +24,7 @@ export function Events(Base) {
|
||||
if (source === 'navigate') {
|
||||
auto2top && scroll2Top(auto2top);
|
||||
}
|
||||
})();
|
||||
}
|
||||
|
||||
if (this.config.loadNavbar) {
|
||||
sidebar.getAndActive(this.router, 'nav');
|
||||
|
||||
@ -43,9 +43,7 @@ function highlight(path) {
|
||||
const top = ((doc && doc.scrollTop) || document.body.scrollTop) - coverHeight;
|
||||
let last;
|
||||
|
||||
for (let i = 0, len = anchors.length; i < len; i += 1) {
|
||||
const node = anchors[i];
|
||||
|
||||
for (const node of anchors) {
|
||||
if (node.offsetTop > top) {
|
||||
if (!last) {
|
||||
last = node;
|
||||
@ -103,8 +101,7 @@ export function scrollActiveSidebar(router) {
|
||||
lis = dom.findAll(sidebar, 'li');
|
||||
}
|
||||
|
||||
for (let i = 0, len = lis.length; i < len; i += 1) {
|
||||
const li = lis[i];
|
||||
for (const li of lis) {
|
||||
const a = li.querySelector('a');
|
||||
if (!a) {
|
||||
continue;
|
||||
|
||||
@ -1,7 +1,13 @@
|
||||
// @ts-check
|
||||
/* eslint-disable no-unused-vars */
|
||||
import progressbar from '../render/progressbar.js';
|
||||
import { noop, hasOwn } from '../util/core.js';
|
||||
import { noop } from '../util/core.js';
|
||||
|
||||
/** @typedef {{updatedAt: string}} CacheOpt */
|
||||
|
||||
/** @typedef {{content: string, opt: CacheOpt}} CacheItem */
|
||||
|
||||
/** @type {Record<string, CacheItem>} */
|
||||
const cache = {};
|
||||
|
||||
/**
|
||||
@ -9,14 +15,13 @@ const cache = {};
|
||||
* @param {string} url Resource URL
|
||||
* @param {boolean} [hasBar=false] Has progress bar
|
||||
* @param {String[]} headers Array of headers
|
||||
* @return {Promise} Promise response
|
||||
* @return A Promise-like response with error callback (error callback is not Promise-like)
|
||||
*/
|
||||
// TODO update to using fetch() + Streams API instead of XMLHttpRequest. See an
|
||||
// example of download progress calculation using fetch() here:
|
||||
// https://streams.spec.whatwg.org/demos/
|
||||
export function get(url, hasBar = false, headers = {}) {
|
||||
const xhr = new XMLHttpRequest();
|
||||
const on = function () {
|
||||
xhr.addEventListener.apply(xhr, arguments);
|
||||
};
|
||||
|
||||
const cached = cache[url];
|
||||
|
||||
if (cached) {
|
||||
@ -24,16 +29,18 @@ export function get(url, hasBar = false, headers = {}) {
|
||||
}
|
||||
|
||||
xhr.open('GET', url);
|
||||
for (const i in headers) {
|
||||
if (hasOwn.call(headers, i)) {
|
||||
xhr.setRequestHeader(i, headers[i]);
|
||||
}
|
||||
for (const i of Object.keys(headers)) {
|
||||
xhr.setRequestHeader(i, headers[i]);
|
||||
}
|
||||
|
||||
xhr.send();
|
||||
|
||||
return {
|
||||
then: function (success, error = noop) {
|
||||
/**
|
||||
* @param {(text: string, opt: CacheOpt) => void} success
|
||||
* @param {(event: ProgressEvent<XMLHttpRequestEventTarget>) => void} error
|
||||
*/
|
||||
then(success, error = noop) {
|
||||
if (hasBar) {
|
||||
const id = setInterval(
|
||||
_ =>
|
||||
@ -43,22 +50,27 @@ export function get(url, hasBar = false, headers = {}) {
|
||||
500
|
||||
);
|
||||
|
||||
on('progress', progressbar);
|
||||
on('loadend', evt => {
|
||||
xhr.addEventListener('progress', progressbar);
|
||||
xhr.addEventListener('loadend', evt => {
|
||||
progressbar(evt);
|
||||
clearInterval(id);
|
||||
});
|
||||
}
|
||||
|
||||
on('error', error);
|
||||
on('load', ({ target }) => {
|
||||
xhr.addEventListener('error', error);
|
||||
xhr.addEventListener('load', event => {
|
||||
const target = /** @type {XMLHttpRequest} */ (event.target);
|
||||
if (target.status >= 400) {
|
||||
error(target);
|
||||
error(event);
|
||||
} else {
|
||||
if (typeof target.response !== 'string') {
|
||||
throw new TypeError('Unsupported content type.');
|
||||
}
|
||||
|
||||
const result = (cache[url] = {
|
||||
content: target.response,
|
||||
opt: {
|
||||
updatedAt: xhr.getResponseHeader('last-modified'),
|
||||
updatedAt: xhr.getResponseHeader('last-modified') ?? '',
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
@ -16,7 +16,7 @@ function loadNested(path, qs, file, next, vm, first) {
|
||||
vm.router.getFile(path + file) + qs,
|
||||
false,
|
||||
vm.config.requestHeaders
|
||||
).then(next, _ => loadNested(path, qs, file, next, vm));
|
||||
).then(next, _error => loadNested(path, qs, file, next, vm));
|
||||
}
|
||||
|
||||
/** @typedef {import('../Docsify').Constructor} Constructor */
|
||||
@ -29,7 +29,7 @@ export function Fetch(Base) {
|
||||
let last;
|
||||
|
||||
const abort = () => last && last.abort && last.abort();
|
||||
const request = (url, hasbar, requestHeaders) => {
|
||||
const request = (url, requestHeaders) => {
|
||||
abort();
|
||||
last = get(url, true, requestHeaders);
|
||||
return last;
|
||||
@ -111,7 +111,7 @@ export function Fetch(Base) {
|
||||
};
|
||||
|
||||
// and a handler that is called if content failed to fetch
|
||||
const contentFailedToFetch = _ => {
|
||||
const contentFailedToFetch = _error => {
|
||||
this._fetchFallbackPage(path, qs, cb) || this._fetch404(file, qs, cb);
|
||||
};
|
||||
|
||||
@ -121,7 +121,7 @@ export function Fetch(Base) {
|
||||
if (typeof contents === 'string') {
|
||||
contentFetched(contents);
|
||||
} else {
|
||||
request(file + qs, true, requestHeaders).then(
|
||||
request(file + qs, requestHeaders).then(
|
||||
contentFetched,
|
||||
contentFailedToFetch
|
||||
);
|
||||
@ -129,7 +129,7 @@ export function Fetch(Base) {
|
||||
});
|
||||
} else {
|
||||
// if the requested url is not local, just fetch the file
|
||||
request(file + qs, true, requestHeaders).then(
|
||||
request(file + qs, requestHeaders).then(
|
||||
contentFetched,
|
||||
contentFailedToFetch
|
||||
);
|
||||
@ -216,7 +216,7 @@ export function Fetch(Base) {
|
||||
const newPath = this.router.getFile(
|
||||
path.replace(new RegExp(`^/${local}`), '')
|
||||
);
|
||||
const req = request(newPath + qs, true, requestHeaders);
|
||||
const req = request(newPath + qs, requestHeaders);
|
||||
|
||||
req.then(
|
||||
(text, opt) =>
|
||||
@ -225,7 +225,7 @@ export function Fetch(Base) {
|
||||
opt,
|
||||
this._loadSideAndNav(path, qs, loadSidebar, cb)
|
||||
),
|
||||
() => this._fetch404(path, qs, cb)
|
||||
_error => this._fetch404(path, qs, cb)
|
||||
);
|
||||
|
||||
return true;
|
||||
@ -246,9 +246,9 @@ export function Fetch(Base) {
|
||||
if (notFoundPage) {
|
||||
const path404 = get404Path(path, this.config);
|
||||
|
||||
request(this.router.getFile(path404), true, requestHeaders).then(
|
||||
request(this.router.getFile(path404), requestHeaders).then(
|
||||
(text, opt) => this._renderMain(text, opt, fnLoadSideAndNav),
|
||||
() => this._renderMain(null, {}, fnLoadSideAndNav)
|
||||
_error => this._renderMain(null, {}, fnLoadSideAndNav)
|
||||
);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import { marked } from 'marked';
|
||||
import { isAbsolutePath, getPath, getParentPath } from '../router/util.js';
|
||||
import { isFn, merge, cached, isPrimitive } from '../util/core.js';
|
||||
import { isFn, cached, isPrimitive } from '../util/core.js';
|
||||
import { tree as treeTpl } from './tpl.js';
|
||||
import { genTree } from './gen-tree.js';
|
||||
import { slugify } from './slugify.js';
|
||||
@ -83,8 +83,8 @@ export class Compiler {
|
||||
compile = mdConf(marked, renderer);
|
||||
} else {
|
||||
marked.setOptions(
|
||||
merge(mdConf, {
|
||||
renderer: merge(renderer, mdConf.renderer),
|
||||
Object.assign(mdConf, {
|
||||
renderer: Object.assign(renderer, mdConf.renderer),
|
||||
})
|
||||
);
|
||||
compile = marked;
|
||||
@ -93,7 +93,8 @@ export class Compiler {
|
||||
this._marked = compile;
|
||||
this.compile = text => {
|
||||
let isCached = true;
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
|
||||
// FIXME: this is not cached.
|
||||
const result = cached(_ => {
|
||||
isCached = false;
|
||||
let html = '';
|
||||
@ -186,8 +187,7 @@ export class Compiler {
|
||||
_matchNotCompileLink(link) {
|
||||
const links = this.config.noCompileLinks || [];
|
||||
|
||||
for (let i = 0; i < links.length; i++) {
|
||||
const n = links[i];
|
||||
for (const n of links) {
|
||||
const re = cachedLinks[n] || (cachedLinks[n] = new RegExp(`^${n}$`));
|
||||
|
||||
if (re.test(link)) {
|
||||
@ -278,7 +278,7 @@ export class Compiler {
|
||||
}
|
||||
|
||||
const tree = this.cacheTree[currentPath] || genTree(toc, level);
|
||||
html = treeTpl(tree, '<ul>{inner}</ul>');
|
||||
html = treeTpl(tree, /* html */ `<ul>{inner}</ul>`);
|
||||
this.cacheTree[currentPath] = tree;
|
||||
}
|
||||
|
||||
|
||||
@ -11,5 +11,5 @@ export const highlightCodeCompiler = ({ renderer }) =>
|
||||
lang
|
||||
);
|
||||
|
||||
return `<pre v-pre data-lang="${lang}"><code class="lang-${lang}">${text}</code></pre>`;
|
||||
return /* html */ `<pre v-pre data-lang="${lang}"><code class="lang-${lang}">${text}</code></pre>`;
|
||||
});
|
||||
|
||||
@ -23,5 +23,5 @@ export const headingCompiler = ({ renderer, router, _self }) =>
|
||||
nextToc.slug = url;
|
||||
_self.toc.push(nextToc);
|
||||
|
||||
return `<h${level} id="${slug}"><a href="${url}" data-id="${slug}" class="anchor"><span>${str}</span></a></h${level}>`;
|
||||
return /* html */ `<h${level} id="${slug}"><a href="${url}" data-id="${slug}" class="anchor"><span>${str}</span></a></h${level}>`;
|
||||
});
|
||||
|
||||
@ -38,11 +38,7 @@ export const imageCompiler = ({ renderer, contentBase, router }) =>
|
||||
url = getPath(contentBase, getParentPath(router.getCurrentPath()), href);
|
||||
}
|
||||
|
||||
if (attrs.length > 0) {
|
||||
return `<img src="${url}" data-origin="${href}" alt="${text}" ${attrs.join(
|
||||
' '
|
||||
)} />`;
|
||||
}
|
||||
|
||||
return `<img src="${url}" data-origin="${href}" alt="${text}"${attrs}>`;
|
||||
return /* html */ `<img src="${url}" data-origin="${href}" alt="${text}" ${attrs.join(
|
||||
' '
|
||||
)} />`;
|
||||
});
|
||||
|
||||
@ -60,5 +60,5 @@ export const linkCompiler = ({
|
||||
attrs.push(`title="${title}"`);
|
||||
}
|
||||
|
||||
return `<a href="${href}" ${attrs.join(' ')}>${text}</a>`;
|
||||
return /* html */ `<a href="${href}" ${attrs.join(' ')}>${text}</a>`;
|
||||
});
|
||||
|
||||
@ -8,7 +8,7 @@ export const paragraphCompiler = ({ renderer }) =>
|
||||
} else if (/^\?>/.test(text)) {
|
||||
result = helperTpl('warn', text);
|
||||
} else {
|
||||
result = `<p>${text}</p>`;
|
||||
result = /* html */ `<p>${text}</p>`;
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
@ -2,8 +2,8 @@ export const taskListItemCompiler = ({ renderer }) =>
|
||||
(renderer.listitem = text => {
|
||||
const isTaskItem = /^(<input.*type="checkbox"[^>]*>)/.test(text);
|
||||
const html = isTaskItem
|
||||
? `<li class="task-list-item"><label>${text}</label></li>`
|
||||
: `<li>${text}</li>`;
|
||||
? /* html */ `<li class="task-list-item"><label>${text}</label></li>`
|
||||
: /* html */ `<li>${text}</li>`;
|
||||
|
||||
return html;
|
||||
});
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
import stripIndent from 'strip-indent';
|
||||
import { get } from '../fetch/ajax.js';
|
||||
import { merge } from '../util/core.js';
|
||||
|
||||
const cached = {};
|
||||
|
||||
@ -14,70 +13,72 @@ function walkFetchEmbed({ embedTokens, compile, fetch }, cb) {
|
||||
}
|
||||
|
||||
while ((token = embedTokens[step++])) {
|
||||
// eslint-disable-next-line no-shadow
|
||||
const next = (function (token) {
|
||||
return text => {
|
||||
let embedToken;
|
||||
if (text) {
|
||||
if (token.embed.type === 'markdown') {
|
||||
let path = token.embed.url.split('/');
|
||||
path.pop();
|
||||
path = path.join('/');
|
||||
// Resolves relative links to absolute
|
||||
text = text.replace(/\[([^[\]]+)\]\(([^)]+)\)/g, x => {
|
||||
const linkBeginIndex = x.indexOf('(');
|
||||
if (x.slice(linkBeginIndex, linkBeginIndex + 2) === '(.') {
|
||||
return (
|
||||
x.substring(0, linkBeginIndex) +
|
||||
`(${window.location.protocol}//${window.location.host}${path}/` +
|
||||
x.substring(linkBeginIndex + 1, x.length - 1) +
|
||||
')'
|
||||
);
|
||||
}
|
||||
return x;
|
||||
});
|
||||
const currentToken = token;
|
||||
|
||||
// This may contain YAML front matter and will need to be stripped.
|
||||
const frontMatterInstalled =
|
||||
($docsify.frontMatter || {}).installed || false;
|
||||
if (frontMatterInstalled === true) {
|
||||
text = $docsify.frontMatter.parseMarkdown(text);
|
||||
}
|
||||
|
||||
embedToken = compile.lexer(text);
|
||||
} 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}\\]`
|
||||
const next = text => {
|
||||
let embedToken;
|
||||
if (text) {
|
||||
if (currentToken.embed.type === 'markdown') {
|
||||
let path = currentToken.embed.url.split('/');
|
||||
path.pop();
|
||||
path = path.join('/');
|
||||
// Resolves relative links to absolute
|
||||
text = text.replace(/\[([^[\]]+)\]\(([^)]+)\)/g, x => {
|
||||
const linkBeginIndex = x.indexOf('(');
|
||||
if (x.slice(linkBeginIndex, linkBeginIndex + 2) === '(.') {
|
||||
return (
|
||||
x.substring(0, linkBeginIndex) +
|
||||
`(${window.location.protocol}//${window.location.host}${path}/` +
|
||||
x.substring(linkBeginIndex + 1, x.length - 1) +
|
||||
')'
|
||||
);
|
||||
text = stripIndent((text.match(pattern) || [])[1] || '').trim();
|
||||
}
|
||||
return x;
|
||||
});
|
||||
|
||||
embedToken = compile.lexer(
|
||||
'```' +
|
||||
token.embed.lang +
|
||||
'\n' +
|
||||
text.replace(/`/g, '@DOCSIFY_QM@') +
|
||||
'\n```\n'
|
||||
);
|
||||
} else if (token.embed.type === 'mermaid') {
|
||||
embedToken = [
|
||||
{ type: 'html', text: `<div class="mermaid">\n${text}\n</div>` },
|
||||
];
|
||||
embedToken.links = {};
|
||||
} else {
|
||||
embedToken = [{ type: 'html', text }];
|
||||
embedToken.links = {};
|
||||
// This may contain YAML front matter and will need to be stripped.
|
||||
const frontMatterInstalled =
|
||||
($docsify.frontMatter || {}).installed || false;
|
||||
if (frontMatterInstalled === true) {
|
||||
text = $docsify.frontMatter.parseMarkdown(text);
|
||||
}
|
||||
}
|
||||
|
||||
cb({ token, embedToken });
|
||||
if (++count >= embedTokens.length) {
|
||||
cb({});
|
||||
embedToken = compile.lexer(text);
|
||||
} else if (currentToken.embed.type === 'code') {
|
||||
if (currentToken.embed.fragment) {
|
||||
const fragment = currentToken.embed.fragment;
|
||||
const pattern = new RegExp(
|
||||
`(?:###|\\/\\/\\/)\\s*\\[${fragment}\\]([\\s\\S]*)(?:###|\\/\\/\\/)\\s*\\[${fragment}\\]`
|
||||
);
|
||||
text = stripIndent((text.match(pattern) || [])[1] || '').trim();
|
||||
}
|
||||
|
||||
embedToken = compile.lexer(
|
||||
'```' +
|
||||
currentToken.embed.lang +
|
||||
'\n' +
|
||||
text.replace(/`/g, '@DOCSIFY_QM@') +
|
||||
'\n```\n'
|
||||
);
|
||||
} else if (currentToken.embed.type === 'mermaid') {
|
||||
embedToken = [
|
||||
{
|
||||
type: 'html',
|
||||
text: /* html */ `<div class="mermaid">\n${text}\n</div>`,
|
||||
},
|
||||
];
|
||||
embedToken.links = {};
|
||||
} else {
|
||||
embedToken = [{ type: 'html', text }];
|
||||
embedToken.links = {};
|
||||
}
|
||||
};
|
||||
})(token);
|
||||
}
|
||||
|
||||
cb({ token: currentToken, embedToken });
|
||||
if (++count >= embedTokens.length) {
|
||||
cb({});
|
||||
}
|
||||
};
|
||||
|
||||
if (token.embed.url) {
|
||||
get(token.embed.url).then(next);
|
||||
@ -136,7 +137,7 @@ export function prerenderEmbed({ compiler, raw = '', fetch }, done) {
|
||||
}
|
||||
});
|
||||
|
||||
merge(links, embedToken.links);
|
||||
Object.assign(links, embedToken.links);
|
||||
|
||||
tokens = tokens
|
||||
.slice(0, index)
|
||||
|
||||
@ -16,9 +16,9 @@ function replaceEmojiShorthand(m, $1, useNativeEmoji) {
|
||||
// Hat tip: https://about.gitlab.com/blog/2018/05/30/journey-in-native-unicode-emoji/#emoji-made-up-of-multiple-characters
|
||||
.join('‍')
|
||||
.concat('︎');
|
||||
result = `<span class="emoji">${emojiUnicode}</span>`;
|
||||
result = /* html */ `<span class="emoji">${emojiUnicode}</span>`;
|
||||
} else {
|
||||
result = `<img src="${emojiData.baseURL}${emojiMatch}.png" alt="${$1}" class="emoji" loading="lazy">`;
|
||||
result = /* html */ `<img src="${emojiData.baseURL}${emojiMatch}.png" alt="${$1}" class="emoji" loading="lazy">`;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -18,7 +18,7 @@ export function genTree(toc, maxLevel) {
|
||||
}
|
||||
|
||||
if (last[len]) {
|
||||
last[len].children = (last[len].children || []).concat(headline);
|
||||
last[len].children = [...(last[len].children || []), headline];
|
||||
} else {
|
||||
headlines.push(headline);
|
||||
}
|
||||
|
||||
@ -1,11 +1,10 @@
|
||||
/* eslint-disable no-unused-vars */
|
||||
import tinydate from 'tinydate';
|
||||
import * as dom from '../util/dom.js';
|
||||
import cssVars from '../util/polyfill/css-vars.js';
|
||||
import { getAndActive, sticky } from '../event/sidebar.js';
|
||||
import { getPath, isAbsolutePath } from '../router/util.js';
|
||||
import { isMobile, inBrowser } from '../util/env.js';
|
||||
import { isPrimitive, merge } from '../util/core.js';
|
||||
import { isPrimitive } from '../util/core.js';
|
||||
import { scrollActiveSidebar } from '../event/scroll.js';
|
||||
import { Compiler } from './compiler.js';
|
||||
import * as tpl from './tpl.js';
|
||||
@ -56,7 +55,7 @@ function renderMain(html) {
|
||||
};
|
||||
|
||||
if (!html) {
|
||||
html = '<h1>404 - Not found</h1>';
|
||||
html = /* html */ `<h1>404 - Not found</h1>`;
|
||||
}
|
||||
|
||||
if ('Vue' in window) {
|
||||
@ -167,15 +166,14 @@ function renderMain(html) {
|
||||
})
|
||||
.map(elm => {
|
||||
// Clone global configuration
|
||||
const vueConfig = merge({}, docsifyConfig.vueGlobalOptions || {});
|
||||
|
||||
const vueConfig = {
|
||||
...docsifyConfig.vueGlobalOptions,
|
||||
};
|
||||
// Replace vueGlobalOptions data() return value with shared data object.
|
||||
// This provides a global store for all Vue instances that receive
|
||||
// vueGlobalOptions as their configuration.
|
||||
if (vueGlobalData) {
|
||||
vueConfig.data = function () {
|
||||
return vueGlobalData;
|
||||
};
|
||||
vueConfig.data = () => vueGlobalData;
|
||||
}
|
||||
|
||||
return [elm, vueConfig];
|
||||
@ -458,8 +456,6 @@ export function Render(Base) {
|
||||
dom.$.head.appendChild(
|
||||
dom.create('div', tpl.theme(config.themeColor)).firstElementChild
|
||||
);
|
||||
// Polyfll
|
||||
cssVars(config.themeColor);
|
||||
}
|
||||
|
||||
this._updateRender();
|
||||
|
||||
@ -16,13 +16,15 @@ function init() {
|
||||
|
||||
/**
|
||||
* Render progress bar
|
||||
* @param {{step: number, loaded?: undefined, total?: undefined} | {step?: undefined, loaded: number, total: number}} info
|
||||
*/
|
||||
export default function ({ loaded, total, step }) {
|
||||
export default function (info) {
|
||||
const { loaded, total, step } = info;
|
||||
let num;
|
||||
|
||||
!barEl && init();
|
||||
|
||||
if (step) {
|
||||
if (typeof step !== 'undefined') {
|
||||
num = parseInt(barEl.style.width || 0, 10) + step;
|
||||
num = num > 80 ? 80 : num;
|
||||
} else {
|
||||
|
||||
@ -1,5 +1,3 @@
|
||||
import { hasOwn } from '../util/core.js';
|
||||
|
||||
let cache = {};
|
||||
const re = /[\u2000-\u206F\u2E00-\u2E7F\\'!"#$%&()*+,./:;<=>?@[\]^`{|}~]/g;
|
||||
|
||||
@ -22,7 +20,7 @@ export function slugify(str) {
|
||||
.replace(/^(\d)/, '_$1');
|
||||
let count = cache[slug];
|
||||
|
||||
count = hasOwn.call(cache, slug) ? count + 1 : 0;
|
||||
count = Object.keys(cache).includes(slug) ? count + 1 : 0;
|
||||
cache[slug] = count;
|
||||
|
||||
if (count) {
|
||||
|
||||
@ -17,15 +17,15 @@ export function corner(data, cornerExternalLinkTarget) {
|
||||
// Double check
|
||||
cornerExternalLinkTarget = cornerExternalLinkTarget || '_blank';
|
||||
|
||||
return (
|
||||
`<a href="${data}" target="${cornerExternalLinkTarget}" class="github-corner" aria-label="View source on Github">` +
|
||||
'<svg viewBox="0 0 250 250" aria-hidden="true">' +
|
||||
'<path d="M0,0 L115,115 L130,115 L142,142 L250,250 L250,0 Z"></path>' +
|
||||
'<path d="M128.3,109.0 C113.8,99.7 119.0,89.6 119.0,89.6 C122.0,82.7 120.5,78.6 120.5,78.6 C119.2,72.0 123.4,76.3 123.4,76.3 C127.3,80.9 125.5,87.3 125.5,87.3 C122.9,97.6 130.6,101.9 134.4,103.2" fill="currentColor" style="transform-origin: 130px 106px;" class="octo-arm"></path>' +
|
||||
'<path d="M115.0,115.0 C114.9,115.1 118.7,116.5 119.8,115.4 L133.7,101.6 C136.9,99.2 139.9,98.4 142.2,98.6 C133.8,88.0 127.5,74.4 143.8,58.0 C148.5,53.4 154.0,51.2 159.7,51.0 C160.3,49.4 163.2,43.6 171.4,40.1 C171.4,40.1 176.1,42.5 178.8,56.2 C183.1,58.6 187.2,61.8 190.9,65.4 C194.5,69.0 197.7,73.2 200.1,77.6 C213.8,80.2 216.3,84.9 216.3,84.9 C212.7,93.1 206.9,96.0 205.4,96.6 C205.1,102.4 203.0,107.8 198.3,112.5 C181.9,128.9 168.3,122.5 157.7,114.1 C157.9,116.9 156.7,120.9 152.7,124.9 L141.0,136.5 C139.8,137.7 141.6,141.9 141.8,141.8 Z" fill="currentColor" class="octo-body"></path>' +
|
||||
'</svg>' +
|
||||
'</a>'
|
||||
);
|
||||
return /* html */ `
|
||||
<a href="${data}" target="${cornerExternalLinkTarget}" class="github-corner" aria-label="View source on Github">
|
||||
<svg viewBox="0 0 250 250" aria-hidden="true">
|
||||
<path d="M0,0 L115,115 L130,115 L142,142 L250,250 L250,0 Z"></path>
|
||||
<path d="M128.3,109.0 C113.8,99.7 119.0,89.6 119.0,89.6 C122.0,82.7 120.5,78.6 120.5,78.6 C119.2,72.0 123.4,76.3 123.4,76.3 C127.3,80.9 125.5,87.3 125.5,87.3 C122.9,97.6 130.6,101.9 134.4,103.2" fill="currentColor" style="transform-origin: 130px 106px;" class="octo-arm"></path>
|
||||
<path d="M115.0,115.0 C114.9,115.1 118.7,116.5 119.8,115.4 L133.7,101.6 C136.9,99.2 139.9,98.4 142.2,98.6 C133.8,88.0 127.5,74.4 143.8,58.0 C148.5,53.4 154.0,51.2 159.7,51.0 C160.3,49.4 163.2,43.6 171.4,40.1 C171.4,40.1 176.1,42.5 178.8,56.2 C183.1,58.6 187.2,61.8 190.9,65.4 C194.5,69.0 197.7,73.2 200.1,77.6 C213.8,80.2 216.3,84.9 216.3,84.9 C212.7,93.1 206.9,96.0 205.4,96.6 C205.1,102.4 203.0,107.8 198.3,112.5 C181.9,128.9 168.3,122.5 157.7,114.1 C157.9,116.9 156.7,120.9 152.7,124.9 L141.0,136.5 C139.8,137.7 141.6,141.9 141.8,141.8 Z" fill="currentColor" class="octo-body"></path>
|
||||
</svg>
|
||||
</a>
|
||||
`;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -36,27 +36,33 @@ export function corner(data, cornerExternalLinkTarget) {
|
||||
export function main(config) {
|
||||
const name = config.name ? config.name : '';
|
||||
|
||||
const aside =
|
||||
'<button class="sidebar-toggle" aria-label="Menu">' +
|
||||
'<div class="sidebar-toggle-button">' +
|
||||
'<span></span><span></span><span></span>' +
|
||||
'</div>' +
|
||||
'</button>' +
|
||||
'<aside class="sidebar">' +
|
||||
(config.name
|
||||
? `<h1 class="app-name"><a class="app-name-link" data-nosearch>${
|
||||
config.logo ? `<img alt="${name}" src=${config.logo}>` : name
|
||||
}</a></h1>`
|
||||
: '') +
|
||||
'<div class="sidebar-nav"><!--sidebar--></div>' +
|
||||
'</aside>';
|
||||
return (
|
||||
`<main>${aside}` +
|
||||
'<section class="content">' +
|
||||
'<article class="markdown-section" id="main"><!--main--></article>' +
|
||||
'</section>' +
|
||||
'</main>'
|
||||
);
|
||||
const aside = /* html */ `
|
||||
<button class="sidebar-toggle" aria-label="Menu">
|
||||
<div class="sidebar-toggle-button">
|
||||
<span></span><span></span><span></span>
|
||||
</div>
|
||||
</button>
|
||||
<aside class="sidebar">
|
||||
${
|
||||
config.name
|
||||
? /* html */ `
|
||||
<h1 class="app-name"><a class="app-name-link" data-nosearch>${
|
||||
config.logo ? `<img alt="${name}" src=${config.logo} />` : name
|
||||
}</a></h1>
|
||||
`
|
||||
: ''
|
||||
}
|
||||
<div class="sidebar-nav"><!--sidebar--></div>
|
||||
</aside>
|
||||
`;
|
||||
|
||||
return /* html */ `
|
||||
<main>${aside}
|
||||
<section class="content">
|
||||
<article class="markdown-section" id="main"><!--main--></article>
|
||||
</section>
|
||||
</main>
|
||||
`;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -65,17 +71,20 @@ export function main(config) {
|
||||
*/
|
||||
export function cover() {
|
||||
const SL = ', 100%, 85%';
|
||||
const bgc =
|
||||
'linear-gradient(to left bottom, ' +
|
||||
`hsl(${Math.floor(Math.random() * 255) + SL}) 0%,` +
|
||||
`hsl(${Math.floor(Math.random() * 255) + SL}) 100%)`;
|
||||
const bgc = `
|
||||
linear-gradient(
|
||||
to left bottom,
|
||||
hsl(${Math.floor(Math.random() * 255) + SL}) 0%,
|
||||
hsl(${Math.floor(Math.random() * 255) + SL}) 100%
|
||||
)
|
||||
`;
|
||||
|
||||
return (
|
||||
`<section class="cover show" style="background: ${bgc}">` +
|
||||
'<div class="mask"></div>' +
|
||||
'<div class="cover-main"><!--cover--></div>' +
|
||||
'</section>'
|
||||
);
|
||||
return /* html */ `
|
||||
<section class="cover show" style="background: ${bgc}">
|
||||
<div class="mask"></div>
|
||||
<div class="cover-main"><!--cover--></div>
|
||||
</section>
|
||||
`;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -84,7 +93,10 @@ export function cover() {
|
||||
* @param {String} tpl TPL list
|
||||
* @return {String} Rendered tree
|
||||
*/
|
||||
export function tree(toc, tpl = '<ul class="app-sub-sidebar">{inner}</ul>') {
|
||||
export function tree(
|
||||
toc,
|
||||
tpl = /* html */ `<ul class="app-sub-sidebar">{inner}</ul>`
|
||||
) {
|
||||
if (!toc || !toc.length) {
|
||||
return '';
|
||||
}
|
||||
@ -92,7 +104,7 @@ export function tree(toc, tpl = '<ul class="app-sub-sidebar">{inner}</ul>') {
|
||||
let innerHTML = '';
|
||||
toc.forEach(node => {
|
||||
const title = node.title.replace(/(<([^>]+)>)/g, '');
|
||||
innerHTML += `<li><a class="section-link" href="${node.slug}" title="${title}">${node.title}</a></li>`;
|
||||
innerHTML += /* html */ `<li><a class="section-link" href="${node.slug}" title="${title}">${node.title}</a></li>`;
|
||||
if (node.children) {
|
||||
innerHTML += tree(node.children, tpl);
|
||||
}
|
||||
@ -101,9 +113,12 @@ export function tree(toc, tpl = '<ul class="app-sub-sidebar">{inner}</ul>') {
|
||||
}
|
||||
|
||||
export function helper(className, content) {
|
||||
return `<p class="${className}">${content.slice(5).trim()}</p>`;
|
||||
return /* html */ `<p class="${className}">${content.slice(5).trim()}</p>`;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
export function theme(color) {
|
||||
return `<style>:root{--theme-color: ${color};}</style>`;
|
||||
return /* html */ `<style>:root{--theme-color: ${color};}</style>`;
|
||||
}
|
||||
|
||||
@ -6,7 +6,7 @@ import {
|
||||
replaceSlug,
|
||||
resolvePath,
|
||||
} from '../util.js';
|
||||
import { noop, merge } from '../../util/core.js';
|
||||
import { noop } from '../../util/core.js';
|
||||
|
||||
const cached = {};
|
||||
|
||||
@ -69,7 +69,7 @@ export class History {
|
||||
const local = currentRoute && path[0] === '#';
|
||||
const route = this.parse(replaceSlug(path));
|
||||
|
||||
route.query = merge({}, route.query, params);
|
||||
route.query = { ...route.query, ...params };
|
||||
path = route.path + stringifyQuery(route.query);
|
||||
path = path.replace(/\.md(\?)|\.md$/, '$1');
|
||||
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
import { isExternal, noop } from '../../util/core.js';
|
||||
import { on } from '../../util/dom.js';
|
||||
import { endsWith } from '../../util/str.js';
|
||||
import { parseQuery, cleanPath, replaceSlug } from '../util.js';
|
||||
import { History } from './base.js';
|
||||
|
||||
@ -23,7 +22,7 @@ export class HashHistory extends History {
|
||||
// prevents the `/index.html` part of the URI from being
|
||||
// remove during routing.
|
||||
// See here: https://github.com/docsifyjs/docsify/pull/1372
|
||||
const basePath = endsWith(path, '.html')
|
||||
const basePath = path.endsWith('.html')
|
||||
? path + '#/' + base
|
||||
: path + '/' + base;
|
||||
return /^(\/|https?:)/g.test(base) ? base : cleanPath(basePath);
|
||||
|
||||
@ -1,4 +1,3 @@
|
||||
import { supportsPushState } from '../util/env.js';
|
||||
import * as dom from '../util/dom.js';
|
||||
import { noop } from '../util/core.js';
|
||||
import { HashHistory } from './history/hash.js';
|
||||
@ -39,7 +38,7 @@ export function Router(Base) {
|
||||
const mode = config.routerMode || 'hash';
|
||||
let router;
|
||||
|
||||
if (mode === 'history' && supportsPushState) {
|
||||
if (mode === 'history') {
|
||||
router = new HTML5History(config);
|
||||
} else {
|
||||
router = new HashHistory(config);
|
||||
|
||||
@ -13,7 +13,7 @@ export function parseQuery(query) {
|
||||
}
|
||||
|
||||
// Simple parse
|
||||
query.split('&').forEach(function (param) {
|
||||
query.split('&').forEach(param => {
|
||||
const parts = param.replace(/\+/g, ' ').split('=');
|
||||
|
||||
res[parts[0]] = parts[1] && decode(parts[1]);
|
||||
@ -64,8 +64,7 @@ export const cleanPath = cached(path => {
|
||||
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];
|
||||
for (const segment of segments) {
|
||||
if (segment === '..') {
|
||||
resolved.pop();
|
||||
} else if (segment !== '.') {
|
||||
|
||||
@ -1,9 +1,11 @@
|
||||
/**
|
||||
* Create a cached version of a pure function.
|
||||
* Create a cached version of fn that given an input string returns a
|
||||
* cached return value mapped from the string, regardless if fn is a new function every time.
|
||||
* created.
|
||||
* @param {*} fn The function call to be cached
|
||||
* @void
|
||||
*/
|
||||
|
||||
// TODO Replace this with a proper memo(fn) based on args per function.
|
||||
export function cached(fn) {
|
||||
const cache = Object.create(null);
|
||||
return function (str) {
|
||||
@ -20,33 +22,10 @@ export const hyphenate = cached(str => {
|
||||
return str.replace(/([A-Z])/g, m => '-' + m.toLowerCase());
|
||||
});
|
||||
|
||||
export const hasOwn = Object.prototype.hasOwnProperty;
|
||||
|
||||
/**
|
||||
* Simple Object.assign polyfill
|
||||
* @param {Object} to The object to be merged with
|
||||
* @returns {Object} The merged object
|
||||
*/
|
||||
export const merge =
|
||||
Object.assign ||
|
||||
function (to) {
|
||||
for (let i = 1; i < arguments.length; i++) {
|
||||
const from = Object(arguments[i]);
|
||||
|
||||
for (const key in from) {
|
||||
if (hasOwn.call(from, key)) {
|
||||
to[key] = from[key];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return to;
|
||||
};
|
||||
|
||||
/**
|
||||
* Check if value is primitive
|
||||
* @param {*} value Checks if a value is primitive
|
||||
* @returns {Boolean} Result of the check
|
||||
* @returns {value is string | number} Result of the check
|
||||
*/
|
||||
export function isPrimitive(value) {
|
||||
return typeof value === 'string' || typeof value === 'number';
|
||||
@ -61,7 +40,7 @@ export function noop() {}
|
||||
/**
|
||||
* Check if value is function
|
||||
* @param {*} obj Any javascript object
|
||||
* @returns {Boolean} True if the passed-in value is a function
|
||||
* @returns {obj is Function} True if the passed-in value is a function
|
||||
*/
|
||||
export function isFn(obj) {
|
||||
return typeof obj === 'function';
|
||||
|
||||
@ -7,7 +7,7 @@ const cacheNode = {};
|
||||
* Get Node
|
||||
* @param {String|Element} el A DOM element
|
||||
* @param {Boolean} noCache Flag to use or not use the cache
|
||||
* @return {Element} The found node element
|
||||
* @return {HTMLElement | SVGElement} The found node element
|
||||
*/
|
||||
export function getNode(el, noCache = false) {
|
||||
if (typeof el === 'string') {
|
||||
@ -46,13 +46,11 @@ export function find(el, node) {
|
||||
* @param {Element} node The query
|
||||
* @returns {Array<Element>} An array of DOM elements
|
||||
* @example
|
||||
* findAll('a') => [].slice.call(document.querySelectorAll('a'))
|
||||
* findAll(nav, 'a') => [].slice.call(nav.querySelectorAll('a'))
|
||||
* findAll('a') => Array.from(document.querySelectorAll('a'))
|
||||
* findAll(nav, 'a') => Array.from(nav.querySelectorAll('a'))
|
||||
*/
|
||||
export function findAll(el, node) {
|
||||
return [].slice.call(
|
||||
node ? el.querySelectorAll(node) : $.querySelectorAll(el)
|
||||
);
|
||||
return Array.from(node ? el.querySelectorAll(node) : $.querySelectorAll(el));
|
||||
}
|
||||
|
||||
export function create(node, tpl) {
|
||||
@ -86,8 +84,8 @@ export function off(el, type, handler) {
|
||||
|
||||
/**
|
||||
* Toggle class
|
||||
* @param {String|Element} el The element that needs the class to be toggled
|
||||
* @param {Element} type The type of action to be performed on the classList (toggle by default)
|
||||
* @param {Element|null} el The element that needs the class to be toggled
|
||||
* @param {string} type The type of action to be performed on the classList (toggle by default)
|
||||
* @param {String} val Name of the class to be toggled
|
||||
* @void
|
||||
* @example
|
||||
|
||||
@ -1,21 +1,3 @@
|
||||
export const inBrowser = true; // True for now, may change when we add SSR.
|
||||
|
||||
export const isMobile = inBrowser && document.body.clientWidth <= 600;
|
||||
|
||||
/**
|
||||
* @see https://github.com/MoOx/pjax/blob/master/lib/is-supported.js
|
||||
*/
|
||||
export const supportsPushState =
|
||||
inBrowser &&
|
||||
(function () {
|
||||
// Borrowed wholesale from https://github.com/defunkt/jquery-pjax
|
||||
return (
|
||||
window.history &&
|
||||
window.history.pushState &&
|
||||
window.history.replaceState &&
|
||||
// PushState isn’t reliable on iOS until 5.
|
||||
!navigator.userAgent.match(
|
||||
/((iPod|iPhone|iPad).+\bOS\s+[1-4]\D|WebApps\/.+CFNetwork)/
|
||||
)
|
||||
);
|
||||
})();
|
||||
|
||||
@ -1,36 +0,0 @@
|
||||
import * as dom from '../dom.js';
|
||||
import { get } from '../../fetch/ajax.js';
|
||||
|
||||
function replaceVar(block, color) {
|
||||
block.innerHTML = block.innerHTML.replace(
|
||||
/var\(\s*--theme-color.*?\)/g,
|
||||
color
|
||||
);
|
||||
}
|
||||
|
||||
export default function (color) {
|
||||
// Variable support
|
||||
if (window.CSS && window.CSS.supports && window.CSS.supports('(--v:red)')) {
|
||||
return;
|
||||
}
|
||||
|
||||
const styleBlocks = dom.findAll('style:not(.inserted),link');
|
||||
[].forEach.call(styleBlocks, block => {
|
||||
if (block.nodeName === 'STYLE') {
|
||||
replaceVar(block, color);
|
||||
} else if (block.nodeName === 'LINK') {
|
||||
const href = block.getAttribute('href');
|
||||
|
||||
if (!/\.css$/.test(href)) {
|
||||
return;
|
||||
}
|
||||
|
||||
get(href).then(res => {
|
||||
const style = dom.create('style', res);
|
||||
|
||||
dom.head.appendChild(style);
|
||||
replaceVar(style, color);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -1,11 +1,3 @@
|
||||
export function startsWith(str, prefix) {
|
||||
return str.indexOf(prefix) === 0;
|
||||
}
|
||||
|
||||
export function endsWith(str, suffix) {
|
||||
return str.indexOf(suffix, str.length - suffix.length) !== -1;
|
||||
}
|
||||
|
||||
export function removeDocsifyIgnoreTag(str) {
|
||||
return str
|
||||
.replace(/<!-- {docsify-ignore} -->/, '')
|
||||
|
||||
@ -1,21 +1,17 @@
|
||||
import { startsWith, endsWith } from '../util/str.js';
|
||||
|
||||
/**
|
||||
* Adds beginning of input (^) and end of input ($) assertions if needed into a regex string
|
||||
* @param {string} matcher the string to match
|
||||
* @returns {string}
|
||||
*/
|
||||
export function makeExactMatcher(matcher) {
|
||||
const matcherWithBeginningOfInput = startsWith(matcher, '^')
|
||||
const matcherWithBeginningOfInput = matcher.startsWith('^')
|
||||
? matcher
|
||||
: `^${matcher}`;
|
||||
|
||||
const matcherWithBeginningAndEndOfInput = endsWith(
|
||||
matcherWithBeginningOfInput,
|
||||
'$'
|
||||
)
|
||||
? matcherWithBeginningOfInput
|
||||
: `${matcherWithBeginningOfInput}$`;
|
||||
const matcherWithBeginningAndEndOfInput =
|
||||
matcherWithBeginningOfInput.endsWith('$')
|
||||
? matcherWithBeginningOfInput
|
||||
: `${matcherWithBeginningOfInput}$`;
|
||||
|
||||
return matcherWithBeginningAndEndOfInput;
|
||||
}
|
||||
|
||||
@ -83,7 +83,7 @@ export function VirtualRoutes(Base) {
|
||||
}
|
||||
|
||||
return {
|
||||
then: function (cb) {
|
||||
then(cb) {
|
||||
done = cb;
|
||||
asyncMatchNextRoute();
|
||||
},
|
||||
|
||||
@ -1,4 +1,3 @@
|
||||
/* eslint-disable no-unused-vars */
|
||||
const fixedPath = location.href.replace('/-/', '/#/');
|
||||
if (fixedPath !== location.href) {
|
||||
location.href = fixedPath;
|
||||
@ -28,7 +27,7 @@ function install(hook, vm) {
|
||||
dom.appendTo(dom.find('.content'), div);
|
||||
|
||||
// eslint-disable-next-line
|
||||
window.disqus_config = function() {
|
||||
window.disqus_config = function () {
|
||||
this.page.url = location.origin + '/-' + vm.route.path;
|
||||
this.page.identifier = vm.route.path;
|
||||
this.page.title = document.title;
|
||||
@ -39,7 +38,7 @@ function install(hook, vm) {
|
||||
if (typeof window.DISQUS !== 'undefined') {
|
||||
window.DISQUS.reset({
|
||||
reload: true,
|
||||
config: function () {
|
||||
config() {
|
||||
this.page.url = location.origin + '/-' + vm.route.path;
|
||||
this.page.identifier = vm.route.path;
|
||||
this.page.title = document.title;
|
||||
@ -49,4 +48,5 @@ function install(hook, vm) {
|
||||
});
|
||||
}
|
||||
|
||||
$docsify.plugins = [].concat(install, $docsify.plugins);
|
||||
window.$docsify = window.$docsify || {};
|
||||
$docsify.plugins = [install, ...($docsify.plugins || [])];
|
||||
|
||||
@ -7,7 +7,7 @@ if (window && window.console) {
|
||||
|
||||
// Emoji from GitHub API
|
||||
window.emojify = function (match, $1) {
|
||||
return Object.prototype.hasOwnProperty.call(emojiData.data, $1) === false
|
||||
? match
|
||||
: `<img src="${emojiData.baseURL}${emojiData.data[$1]}" alt="${$1}" class="emoji" />`;
|
||||
return $1 in emojiData.data
|
||||
? /* html */ `<img src="${emojiData.baseURL}${emojiData.data[$1]}" alt="${$1}" class="emoji" />`
|
||||
: match;
|
||||
};
|
||||
|
||||
@ -2,13 +2,11 @@ function handleExternalScript() {
|
||||
const container = Docsify.dom.getNode('#main');
|
||||
const scripts = Docsify.dom.findAll(container, 'script');
|
||||
|
||||
for (let i = scripts.length; i--; ) {
|
||||
const script = scripts[i];
|
||||
|
||||
if (script && script.src) {
|
||||
for (const script of scripts) {
|
||||
if (script.src) {
|
||||
const newScript = document.createElement('script');
|
||||
|
||||
Array.prototype.slice.call(script.attributes).forEach(attribute => {
|
||||
Array.from(script.attributes).forEach(attribute => {
|
||||
newScript[attribute.name] = attribute.value;
|
||||
});
|
||||
|
||||
@ -22,4 +20,5 @@ const install = function (hook) {
|
||||
hook.doneEach(handleExternalScript);
|
||||
};
|
||||
|
||||
window.$docsify.plugins = [].concat(install, window.$docsify.plugins);
|
||||
window.$docsify = window.$docsify || {};
|
||||
$docsify.plugins = [install, ...($docsify.plugins || [])];
|
||||
|
||||
@ -18,4 +18,5 @@ const install = function (hook, vm) {
|
||||
});
|
||||
};
|
||||
|
||||
$docsify.plugins = [].concat(install, $docsify.plugins);
|
||||
window.$docsify = window.$docsify || {};
|
||||
$docsify.plugins = [install, ...($docsify.plugins || [])];
|
||||
|
||||
@ -4,8 +4,8 @@
|
||||
/* eslint-disable */
|
||||
import parser from './yaml.js'
|
||||
|
||||
var optionalByteOrderMark = '\\ufeff?'
|
||||
var pattern =
|
||||
const optionalByteOrderMark = '\\ufeff?'
|
||||
const pattern =
|
||||
'^(' +
|
||||
optionalByteOrderMark +
|
||||
'(= yaml =|---)' +
|
||||
@ -16,12 +16,12 @@ var pattern =
|
||||
'(?:\\n)?)'
|
||||
// NOTE: If this pattern uses the 'g' flag the `regex` variable definition will
|
||||
// need to be moved down into the functions that use it.
|
||||
var regex = new RegExp(pattern, 'm')
|
||||
const regex = new RegExp(pattern, 'm')
|
||||
|
||||
function extractor(string) {
|
||||
string = string || ''
|
||||
|
||||
var lines = string.split(/(\r?\n)/)
|
||||
const lines = string.split(/(\r?\n)/)
|
||||
if (lines[0] && /= yaml =|---/.test(lines[0])) {
|
||||
return parse(string)
|
||||
} else {
|
||||
@ -30,7 +30,7 @@ function extractor(string) {
|
||||
}
|
||||
|
||||
function parse(string) {
|
||||
var match = regex.exec(string)
|
||||
const match = regex.exec(string)
|
||||
|
||||
if (!match) {
|
||||
return {
|
||||
@ -39,17 +39,11 @@ function parse(string) {
|
||||
}
|
||||
}
|
||||
|
||||
var yaml = match[match.length - 1].replace(/^\s+|\s+$/g, '')
|
||||
var attributes = parser(yaml) || {}
|
||||
var body = string.replace(match[0], '')
|
||||
const yaml = match[match.length - 1].replace(/^\s+|\s+$/g, '')
|
||||
const attributes = parser(yaml) || {}
|
||||
const body = string.replace(match[0], '')
|
||||
|
||||
return { attributes: attributes, body: body, frontmatter: yaml }
|
||||
}
|
||||
|
||||
function test(string) {
|
||||
string = string || ''
|
||||
|
||||
return regex.test(string)
|
||||
}
|
||||
|
||||
export default extractor
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Fork https://github.com/egoist/docute/blob/master/src/utils/yaml.js
|
||||
* Forked from https://github.com/egoist/docute/blob/master/src/utils/yaml.js
|
||||
*/
|
||||
/* eslint-disable */
|
||||
/*
|
||||
@ -75,37 +75,6 @@ function Block(lvl) {
|
||||
}
|
||||
}
|
||||
|
||||
// function to create an XMLHttpClient in a cross-browser manner
|
||||
function createXMLHTTPRequest() {
|
||||
var xmlhttp
|
||||
|
||||
try {
|
||||
// Mozilla / Safari / IE7
|
||||
xmlhttp = new XMLHttpRequest()
|
||||
} catch (e) {
|
||||
// IE
|
||||
var XMLHTTP_IDS = new Array(
|
||||
'MSXML2.XMLHTTP.5.0',
|
||||
'MSXML2.XMLHTTP.4.0',
|
||||
'MSXML2.XMLHTTP.3.0',
|
||||
'MSXML2.XMLHTTP',
|
||||
'Microsoft.XMLHTTP'
|
||||
)
|
||||
var success = false
|
||||
for (var i = 0; i < XMLHTTP_IDS.length && !success; i++) {
|
||||
try {
|
||||
xmlhttp = new ActiveXObject(XMLHTTP_IDS[i])
|
||||
success = true
|
||||
} catch (e) {}
|
||||
}
|
||||
if (!success) {
|
||||
throw new Error('Unable to create XMLHttpRequest.')
|
||||
}
|
||||
}
|
||||
|
||||
return xmlhttp
|
||||
}
|
||||
|
||||
function parser(str) {
|
||||
var regLevel = regex['regLevel']
|
||||
var invalidLine = regex['invalidLine']
|
||||
|
||||
@ -1,4 +1,3 @@
|
||||
/* eslint-disable no-console */
|
||||
// From https://github.com/egoist/vue-ga/blob/master/src/index.js
|
||||
function appendScript() {
|
||||
const script = document.createElement('script');
|
||||
@ -37,4 +36,5 @@ const install = function (hook) {
|
||||
hook.beforeEach(collect);
|
||||
};
|
||||
|
||||
$docsify.plugins = [].concat(install, $docsify.plugins);
|
||||
window.$docsify = window.$docsify || {};
|
||||
$docsify.plugins = [install, ...($docsify.plugins || [])];
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
/* eslint-disable no-unused-vars */
|
||||
/* global gitalk */
|
||||
function install(hook) {
|
||||
const dom = Docsify.dom;
|
||||
|
||||
@ -16,9 +16,9 @@ function install(hook) {
|
||||
el.removeChild(el.firstChild);
|
||||
}
|
||||
|
||||
// eslint-disable-next-line
|
||||
gitalk.render('gitalk-container');
|
||||
});
|
||||
}
|
||||
|
||||
$docsify.plugins = [].concat(install, $docsify.plugins);
|
||||
window.$docsify = window.$docsify || {};
|
||||
$docsify.plugins = [install, ...($docsify.plugins || [])];
|
||||
|
||||
@ -1,4 +1,3 @@
|
||||
/* eslint-disable no-console */
|
||||
// From ./ga.js
|
||||
|
||||
function appendScript(id) {
|
||||
@ -69,4 +68,5 @@ const install = function (hook) {
|
||||
hook.beforeEach(collect);
|
||||
};
|
||||
|
||||
$docsify.plugins = [].concat(install, $docsify.plugins);
|
||||
window.$docsify = window.$docsify || {};
|
||||
$docsify.plugins = [install, ...($docsify.plugins || [])];
|
||||
|
||||
@ -9,7 +9,7 @@ function init(options) {
|
||||
window._paq = window._paq || [];
|
||||
window._paq.push(['trackPageView']);
|
||||
window._paq.push(['enableLinkTracking']);
|
||||
setTimeout(function () {
|
||||
setTimeout(() => {
|
||||
appendScript(options);
|
||||
window._paq.push(['setTrackerUrl', options.host + '/matomo.php']);
|
||||
window._paq.push(['setSiteId', String(options.id)]);
|
||||
@ -36,4 +36,5 @@ const install = function (hook) {
|
||||
hook.beforeEach(collect);
|
||||
};
|
||||
|
||||
$docsify.plugins = [].concat(install, $docsify.plugins);
|
||||
window.$docsify = window.$docsify || {};
|
||||
$docsify.plugins = [install, ...($docsify.plugins || [])];
|
||||
|
||||
@ -111,7 +111,8 @@ function style() {
|
||||
}
|
||||
|
||||
function tpl(defaultValue = '') {
|
||||
const html = `<div class="input-wrap">
|
||||
const html = /* html */ `
|
||||
<div class="input-wrap">
|
||||
<input type="search" value="${defaultValue}" aria-label="Search text" />
|
||||
<div class="clear-button">
|
||||
<svg width="26" height="24">
|
||||
@ -122,7 +123,7 @@ function tpl(defaultValue = '') {
|
||||
</div>
|
||||
</div>
|
||||
<div class="results-panel"></div>
|
||||
</div>`;
|
||||
`;
|
||||
const el = Docsify.dom.create('div', html);
|
||||
const aside = Docsify.dom.find('aside');
|
||||
|
||||
@ -154,17 +155,19 @@ function doSearch(value) {
|
||||
|
||||
let html = '';
|
||||
matchs.forEach(post => {
|
||||
html += `<div class="matching-post">
|
||||
<a href="${post.url}">
|
||||
<h2>${post.title}</h2>
|
||||
<p>${post.content}</p>
|
||||
</a>
|
||||
</div>`;
|
||||
html += /* html */ `
|
||||
<div class="matching-post">
|
||||
<a href="${post.url}">
|
||||
<h2>${post.title}</h2>
|
||||
<p>${post.content}</p>
|
||||
</a>
|
||||
</div>
|
||||
`;
|
||||
});
|
||||
|
||||
$panel.classList.add('show');
|
||||
$clearBtn.classList.add('show');
|
||||
$panel.innerHTML = html || `<p class="empty">${NO_DATA_TEXT}</p>`;
|
||||
$panel.innerHTML = html || /* html */ `<p class="empty">${NO_DATA_TEXT}</p>`;
|
||||
if (options.hideOtherSidebarContent) {
|
||||
$sidebarNav && $sidebarNav.classList.add('hide');
|
||||
$appName && $appName.classList.add('hide');
|
||||
|
||||
@ -46,4 +46,5 @@ const install = function (hook, vm) {
|
||||
});
|
||||
};
|
||||
|
||||
$docsify.plugins = [].concat(install, $docsify.plugins);
|
||||
window.$docsify = window.$docsify || {};
|
||||
$docsify.plugins = [install, ...($docsify.plugins || [])];
|
||||
|
||||
@ -84,7 +84,7 @@ export function genIndex(path, content = '', router, depth) {
|
||||
let slug;
|
||||
let title = '';
|
||||
|
||||
tokens.forEach(function (token, tokenIndex) {
|
||||
tokens.forEach((token, tokenIndex) => {
|
||||
if (token.type === 'heading' && token.depth <= depth) {
|
||||
const { str, config } = getAndRemoveConfig(token.text);
|
||||
|
||||
@ -149,17 +149,19 @@ export function search(query) {
|
||||
const matchingResults = [];
|
||||
let data = [];
|
||||
Object.keys(INDEXS).forEach(key => {
|
||||
data = data.concat(Object.keys(INDEXS[key]).map(page => INDEXS[key][page]));
|
||||
data = [
|
||||
...data,
|
||||
...Object.keys(INDEXS[key]).map(page => INDEXS[key][page]),
|
||||
];
|
||||
});
|
||||
|
||||
query = query.trim();
|
||||
let keywords = query.split(/[\s\-,\\/]+/);
|
||||
if (keywords.length !== 1) {
|
||||
keywords = [].concat(query, keywords);
|
||||
keywords = [query, ...keywords];
|
||||
}
|
||||
|
||||
for (let i = 0; i < data.length; i++) {
|
||||
const post = data[i];
|
||||
for (const post of data) {
|
||||
let matchesScore = 0;
|
||||
let resultStr = '';
|
||||
let handlePostTitle = '';
|
||||
@ -213,7 +215,7 @@ export function search(query) {
|
||||
.substring(start, end)
|
||||
.replace(
|
||||
regEx,
|
||||
word => `<em class="search-keyword">${word}</em>`
|
||||
word => /* html */ `<em class="search-keyword">${word}</em>`
|
||||
) +
|
||||
'...';
|
||||
|
||||
|
||||
@ -1,23 +1,16 @@
|
||||
/* eslint-disable no-unused-vars */
|
||||
import mediumZoom from 'medium-zoom';
|
||||
|
||||
const matchesSelector =
|
||||
Element.prototype.matches ||
|
||||
Element.prototype.webkitMatchesSelector ||
|
||||
Element.prototype.msMatchesSelector;
|
||||
|
||||
function install(hook) {
|
||||
let zoom;
|
||||
|
||||
hook.doneEach(_ => {
|
||||
let elms = Array.apply(
|
||||
null,
|
||||
let elms = Array.from(
|
||||
document.querySelectorAll(
|
||||
'.markdown-section img:not(.emoji):not([data-no-zoom])'
|
||||
)
|
||||
);
|
||||
|
||||
elms = elms.filter(elm => matchesSelector.call(elm, 'a img') === false);
|
||||
elms = elms.filter(elm => !elm.matches('a img'));
|
||||
|
||||
if (zoom) {
|
||||
zoom.detach();
|
||||
@ -27,4 +20,5 @@ function install(hook) {
|
||||
});
|
||||
}
|
||||
|
||||
$docsify.plugins = [].concat(install, $docsify.plugins);
|
||||
window.$docsify = window.$docsify || {};
|
||||
$docsify.plugins = [install, ...($docsify.plugins || [])];
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
import { create } from 'browser-sync';
|
||||
import path from 'path';
|
||||
import url from 'url';
|
||||
import { noop } from '../../src/core/util/core.js';
|
||||
|
||||
const browserSync = create();
|
||||
|
||||
@ -15,13 +16,13 @@ const __dirname = path.dirname(__filename);
|
||||
|
||||
export const TEST_HOST = `http://${serverConfig.hostname}:${serverConfig.port}`;
|
||||
|
||||
function startServer(options = {}, cb = Function.prototype) {
|
||||
function startServer(options = {}, cb = noop) {
|
||||
const defaults = {
|
||||
...serverConfig,
|
||||
middleware: [
|
||||
{
|
||||
route: '/_blank.html',
|
||||
handle: function (req, res, next) {
|
||||
handle(req, res, next) {
|
||||
res.setHeader('Content-Type', 'text/html');
|
||||
res.end('');
|
||||
next();
|
||||
@ -50,23 +51,20 @@ function startServer(options = {}, cb = Function.prototype) {
|
||||
snippetOptions: {
|
||||
rule: {
|
||||
match: /<\/body>/i,
|
||||
fn: function (snippet, match) {
|
||||
fn(snippet, match) {
|
||||
// Override changelog alias to load local changelog (see routes)
|
||||
const newSnippet = `
|
||||
const newSnippet = /* html */ `
|
||||
${snippet.replace(/<script[^>]*/, '$& type="text/plain"')}
|
||||
<script>
|
||||
(function() {
|
||||
var aliasConfig = (window && window.$docsify && window.$docsify.alias) || {};
|
||||
var isIE = /*@cc_on!@*/false || !!document.documentMode;
|
||||
{
|
||||
const aliasConfig = (window && window.$docsify && window.$docsify.alias) || {};
|
||||
|
||||
// Fix /docs site configuration during tests
|
||||
aliasConfig['.*?/changelog'] = '/changelog.md';
|
||||
|
||||
// Enable BrowserSync snippet for non-IE browsers
|
||||
if (!isIE) {
|
||||
document.querySelector('#__bs_script__').removeAttribute('type');
|
||||
}
|
||||
})();
|
||||
// Enable BrowserSync snippet
|
||||
document.querySelector('#__bs_script__').removeAttribute('type');
|
||||
}
|
||||
</script>
|
||||
${match}
|
||||
`;
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
/* global fail */
|
||||
import docsifyInit from '../helpers/docsify-init.js';
|
||||
import { test, expect } from './fixtures/docsify-init-fixture.js';
|
||||
|
||||
@ -14,10 +15,9 @@ test.describe('Configuration options', () => {
|
||||
plugins: [
|
||||
function (hook, vm) {
|
||||
hook.init(function () {
|
||||
// eslint-disable-next-line no-undef
|
||||
fail();
|
||||
});
|
||||
hook.beforeEach(function (markdown) {
|
||||
hook.beforeEach(markdown => {
|
||||
return `${markdown}\n\nbeforeEach`;
|
||||
});
|
||||
},
|
||||
@ -49,7 +49,6 @@ test.describe('Configuration options', () => {
|
||||
plugins: [
|
||||
function (hook, vm) {
|
||||
hook.ready(function () {
|
||||
// eslint-disable-next-line no-undef
|
||||
fail();
|
||||
});
|
||||
},
|
||||
|
||||
@ -21,43 +21,43 @@ test.describe('Plugins', () => {
|
||||
config: {
|
||||
plugins: [
|
||||
function (hook, vm) {
|
||||
hook.init(function () {
|
||||
hook.init(() => {
|
||||
console.log('init');
|
||||
});
|
||||
|
||||
hook.mounted(function () {
|
||||
hook.mounted(() => {
|
||||
console.log('mounted');
|
||||
});
|
||||
|
||||
hook.beforeEach(function (markdown, next) {
|
||||
setTimeout(function () {
|
||||
hook.beforeEach((markdown, next) => {
|
||||
setTimeout(() => {
|
||||
console.log('beforeEach-async');
|
||||
next(markdown);
|
||||
}, 100);
|
||||
});
|
||||
|
||||
hook.beforeEach(function (markdown) {
|
||||
hook.beforeEach(markdown => {
|
||||
console.log('beforeEach');
|
||||
return markdown;
|
||||
});
|
||||
|
||||
hook.afterEach(function (html, next) {
|
||||
setTimeout(function () {
|
||||
hook.afterEach((html, next) => {
|
||||
setTimeout(() => {
|
||||
console.log('afterEach-async');
|
||||
next(html);
|
||||
}, 100);
|
||||
});
|
||||
|
||||
hook.afterEach(function (html) {
|
||||
hook.afterEach(html => {
|
||||
console.log('afterEach');
|
||||
return html;
|
||||
});
|
||||
|
||||
hook.doneEach(function () {
|
||||
hook.doneEach(() => {
|
||||
console.log('doneEach');
|
||||
});
|
||||
|
||||
hook.ready(function () {
|
||||
hook.ready(() => {
|
||||
console.log('ready');
|
||||
});
|
||||
},
|
||||
@ -77,7 +77,7 @@ test.describe('Plugins', () => {
|
||||
config: {
|
||||
plugins: [
|
||||
function (hook, vm) {
|
||||
hook.beforeEach(function (markdown) {
|
||||
hook.beforeEach(markdown => {
|
||||
return 'beforeEach';
|
||||
});
|
||||
},
|
||||
@ -94,8 +94,8 @@ test.describe('Plugins', () => {
|
||||
config: {
|
||||
plugins: [
|
||||
function (hook, vm) {
|
||||
hook.beforeEach(function (markdown, next) {
|
||||
setTimeout(function () {
|
||||
hook.beforeEach((markdown, next) => {
|
||||
setTimeout(() => {
|
||||
next('beforeEach');
|
||||
}, 100);
|
||||
});
|
||||
@ -116,7 +116,7 @@ test.describe('Plugins', () => {
|
||||
config: {
|
||||
plugins: [
|
||||
function (hook, vm) {
|
||||
hook.afterEach(function (html) {
|
||||
hook.afterEach(html => {
|
||||
return '<p>afterEach</p>';
|
||||
});
|
||||
},
|
||||
@ -136,8 +136,8 @@ test.describe('Plugins', () => {
|
||||
config: {
|
||||
plugins: [
|
||||
function (hook, vm) {
|
||||
hook.afterEach(function (html, next) {
|
||||
setTimeout(function () {
|
||||
hook.afterEach((html, next) => {
|
||||
setTimeout(() => {
|
||||
next('<p>afterEach</p>');
|
||||
}, 100);
|
||||
});
|
||||
|
||||
@ -101,9 +101,7 @@ test.describe('Virtual Routes - Generate Dynamic Content via Config', () => {
|
||||
page,
|
||||
}) => {
|
||||
const routes = {
|
||||
'/pets/(.*)': function (route) {
|
||||
return `# Route: /pets/dog`;
|
||||
},
|
||||
'/pets/(.*)': route => `# Route: /pets/dog`,
|
||||
};
|
||||
|
||||
await docsifyInit({
|
||||
@ -122,7 +120,7 @@ test.describe('Virtual Routes - Generate Dynamic Content via Config', () => {
|
||||
page,
|
||||
}) => {
|
||||
const routes = {
|
||||
'/pets/(.*)': function (_, matched) {
|
||||
'/pets/(.*)'(_, matched) {
|
||||
return `# Pets Page (${matched[1]})`;
|
||||
},
|
||||
};
|
||||
|
||||
@ -24,16 +24,14 @@ test.describe('Vue.js Compatibility', () => {
|
||||
},
|
||||
},
|
||||
vueGlobalOptions: {
|
||||
data: function () {
|
||||
return {
|
||||
counter: 0,
|
||||
msg: 'vueglobaloptions',
|
||||
};
|
||||
},
|
||||
data: () => ({
|
||||
counter: 0,
|
||||
msg: 'vueglobaloptions',
|
||||
}),
|
||||
},
|
||||
vueMounts: {
|
||||
'#vuemounts': {
|
||||
data: function () {
|
||||
data() {
|
||||
return {
|
||||
counter: 0,
|
||||
msg: 'vuemounts',
|
||||
|
||||
@ -225,11 +225,29 @@ async function docsifyInit(options = {}) {
|
||||
|
||||
await page.evaluate(config => {
|
||||
// Restore config functions from strings
|
||||
const configObj = JSON.parse(config, (key, val) =>
|
||||
/^__FN__/.test(val)
|
||||
? new Function(`return ${val.split('__FN__')[1]}`)()
|
||||
: val
|
||||
);
|
||||
const configObj = JSON.parse(config, (key, val) => {
|
||||
if (/^__FN__/.test(val)) {
|
||||
let source = val.split('__FN__')[1];
|
||||
|
||||
// f.e. `foo() {}` or `'bar!?'() {}` without the `function ` prefix
|
||||
const isConcise =
|
||||
!source.includes('function') && !source.includes('=>');
|
||||
|
||||
if (isConcise) {
|
||||
source = `{ ${source} }`;
|
||||
} else {
|
||||
source = `{ _: ${source} }`;
|
||||
}
|
||||
|
||||
return new Function(/* js */ `
|
||||
const o = ${source}
|
||||
const keys = Object.keys(o)
|
||||
return o[keys[0]]
|
||||
`)();
|
||||
} else {
|
||||
return val;
|
||||
}
|
||||
});
|
||||
|
||||
window.$docsify = configObj;
|
||||
}, configString);
|
||||
|
||||
@ -1,12 +1,26 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`Docs Site coverpage renders and is unchanged 1`] = `
|
||||
"<section class=\\"cover show\\" style=\\"background: linear-gradient(to left bottom, hsl(127, 100%, 85%) 0%,hsl(127, 100%, 85%) 100%)\\"><div class=\\"mask\\"></div><div class=\\"cover-main\\"><p><img src=\\"http://127.0.0.1:3001/_media/icon.svg\\" data-origin=\\"_media/icon.svg\\" alt=\\"logo\\"></p><h1 id=\\"docsify-4130\\"><a href=\\"#/?id=docsify-4130\\" data-id=\\"docsify-4130\\" class=\\"anchor\\"><span>docsify <small>4.13.0</small></span></a></h1><blockquote>
|
||||
"<section class=\\"cover show\\" style=\\"background:
|
||||
linear-gradient(
|
||||
to left bottom,
|
||||
hsl(127, 100%, 85%) 0%,
|
||||
hsl(127, 100%, 85%) 100%
|
||||
)
|
||||
\\">
|
||||
<div class=\\"mask\\"></div>
|
||||
<div class=\\"cover-main\\"><p><img src=\\"http://127.0.0.1:3001/_media/icon.svg\\" data-origin=\\"_media/icon.svg\\" alt=\\"logo\\"></p><h1 id=\\"docsify-4130\\"><a href=\\"#/?id=docsify-4130\\" data-id=\\"docsify-4130\\" class=\\"anchor\\"><span>docsify <small>4.13.0</small></span></a></h1><blockquote>
|
||||
<p>A magical documentation site generator.</p></blockquote>
|
||||
<ul><li>Simple and lightweight</li><li>No statically built html files</li><li>Multiple themes</li></ul><p><a href=\\"https://github.com/docsifyjs/docsify/\\" target=\\"_blank\\" rel=\\"noopener\\">GitHub</a>
|
||||
<a href=\\"#/?id=docsify\\">Getting Started</a></p></div></section>"
|
||||
<a href=\\"#/?id=docsify\\">Getting Started</a></p></div>
|
||||
</section>"
|
||||
`;
|
||||
|
||||
exports[`Docs Site navbar renders and is unchanged 1`] = `"<nav class=\\"app-nav no-badge\\"><ul><li>Translations<ul><li><a href=\\"#/\\" title=\\"undefined\\" class=\\"active\\"><img src=\\"https://github.githubassets.com/images/icons/emoji/unicode/1f1ec-1f1e7.png?v8.png\\" alt=\\"uk\\" class=\\"emoji\\" loading=\\"lazy\\"> English</a></li><li><a href=\\"#/zh-cn/\\" title=\\"undefined\\"><img src=\\"https://github.githubassets.com/images/icons/emoji/unicode/1f1e8-1f1f3.png?v8.png\\" alt=\\"cn\\" class=\\"emoji\\" loading=\\"lazy\\"> 简体中文</a></li><li><a href=\\"#/de-de/\\" title=\\"undefined\\"><img src=\\"https://github.githubassets.com/images/icons/emoji/unicode/1f1e9-1f1ea.png?v8.png\\" alt=\\"de\\" class=\\"emoji\\" loading=\\"lazy\\"> Deutsch</a></li><li><a href=\\"#/es/\\" title=\\"undefined\\"><img src=\\"https://github.githubassets.com/images/icons/emoji/unicode/1f1ea-1f1f8.png?v8.png\\" alt=\\"es\\" class=\\"emoji\\" loading=\\"lazy\\"> Español</a></li><li><a href=\\"#/ru-ru/\\" title=\\"undefined\\"><img src=\\"https://github.githubassets.com/images/icons/emoji/unicode/1f1f7-1f1fa.png?v8.png\\" alt=\\"ru\\" class=\\"emoji\\" loading=\\"lazy\\"> Русский</a></li></ul></li></ul></nav>"`;
|
||||
|
||||
exports[`Docs Site sidebar renders and is unchanged 1`] = `"<aside class=\\"sidebar\\"><div class=\\"sidebar-nav\\"><ul><li><p>Getting started</p><ul><li><a href=\\"#/quickstart\\" title=\\"undefined\\">Quick start</a></li><li><a href=\\"#/more-pages\\" title=\\"undefined\\">Writing more pages</a></li><li><a href=\\"#/custom-navbar\\" title=\\"undefined\\">Custom navbar</a></li><li><a href=\\"#/cover\\" title=\\"undefined\\">Cover page</a></li></ul></li><li><p>Customization</p><ul><li><a href=\\"#/configuration\\" title=\\"undefined\\">Configuration</a></li><li><a href=\\"#/themes\\" title=\\"undefined\\">Themes</a></li><li><a href=\\"#/plugins\\" title=\\"undefined\\">List of Plugins</a></li><li><a href=\\"#/write-a-plugin\\" title=\\"undefined\\">Write a Plugin</a></li><li><a href=\\"#/markdown\\" title=\\"undefined\\">Markdown configuration</a></li><li><a href=\\"#/language-highlight\\" title=\\"undefined\\">Language highlighting</a></li><li><a href=\\"#/emoji\\" title=\\"undefined\\">Emoji</a></li></ul></li><li><p>Guide</p><ul><li><a href=\\"#/deploy\\" title=\\"undefined\\">Deploy</a></li><li><a href=\\"#/helpers\\" title=\\"undefined\\">Helpers</a></li><li><a href=\\"#/vue\\" title=\\"undefined\\">Vue compatibility</a></li><li><a href=\\"#/cdn\\" title=\\"undefined\\">CDN</a></li><li><a href=\\"#/pwa\\" title=\\"undefined\\">Offline Mode (PWA)</a></li><li><a href=\\"#/embed-files\\" title=\\"undefined\\">Embed Files</a></li></ul></li><li><p><a href=\\"#/awesome\\" title=\\"undefined\\">Awesome docsify</a></p></li><li><p><a href=\\"#/changelog\\" title=\\"undefined\\">Changelog</a></p></li></ul></div></aside>"`;
|
||||
exports[`Docs Site sidebar renders and is unchanged 1`] = `
|
||||
"<aside class=\\"sidebar\\">
|
||||
|
||||
<div class=\\"sidebar-nav\\"><ul><li><p>Getting started</p><ul><li><a href=\\"#/quickstart\\" title=\\"undefined\\">Quick start</a></li><li><a href=\\"#/more-pages\\" title=\\"undefined\\">Writing more pages</a></li><li><a href=\\"#/custom-navbar\\" title=\\"undefined\\">Custom navbar</a></li><li><a href=\\"#/cover\\" title=\\"undefined\\">Cover page</a></li></ul></li><li><p>Customization</p><ul><li><a href=\\"#/configuration\\" title=\\"undefined\\">Configuration</a></li><li><a href=\\"#/themes\\" title=\\"undefined\\">Themes</a></li><li><a href=\\"#/plugins\\" title=\\"undefined\\">List of Plugins</a></li><li><a href=\\"#/write-a-plugin\\" title=\\"undefined\\">Write a Plugin</a></li><li><a href=\\"#/markdown\\" title=\\"undefined\\">Markdown configuration</a></li><li><a href=\\"#/language-highlight\\" title=\\"undefined\\">Language highlighting</a></li><li><a href=\\"#/emoji\\" title=\\"undefined\\">Emoji</a></li></ul></li><li><p>Guide</p><ul><li><a href=\\"#/deploy\\" title=\\"undefined\\">Deploy</a></li><li><a href=\\"#/helpers\\" title=\\"undefined\\">Helpers</a></li><li><a href=\\"#/vue\\" title=\\"undefined\\">Vue compatibility</a></li><li><a href=\\"#/cdn\\" title=\\"undefined\\">CDN</a></li><li><a href=\\"#/pwa\\" title=\\"undefined\\">Offline Mode (PWA)</a></li><li><a href=\\"#/embed-files\\" title=\\"undefined\\">Embed Files</a></li></ul></li><li><p><a href=\\"#/awesome\\" title=\\"undefined\\">Awesome docsify</a></p></li><li><p><a href=\\"#/changelog\\" title=\\"undefined\\">Changelog</a></p></li></ul></div>
|
||||
</aside>"
|
||||
`;
|
||||
|
||||
@ -137,7 +137,7 @@ describe('Emoji', function () {
|
||||
test('Ignores emoji shorthand codes in html attributes', async () => {
|
||||
await docsifyInit({
|
||||
markdown: {
|
||||
homepage: `<a href="http://domain.com/:smile:/"> <img src='http://domain.com/:smile:/file.png'> <script src=http://domain.com/:smile:/file.js></script>`,
|
||||
homepage: /* html */ `<a href="http://domain.com/:smile:/"> <img src='http://domain.com/:smile:/file.png'> <script src=http://domain.com/:smile:/file.js></script>`,
|
||||
},
|
||||
// _logHTML: true,
|
||||
});
|
||||
@ -150,7 +150,7 @@ describe('Emoji', function () {
|
||||
test('Ignores emoji shorthand codes in style url() values', async () => {
|
||||
await docsifyInit({
|
||||
markdown: {
|
||||
homepage: `<style>@import url(http://domain.com/:smile/file.css);</style>`,
|
||||
homepage: /* html */ `<style>@import url(http://domain.com/:smile/file.css);</style>`,
|
||||
},
|
||||
// _logHTML: true,
|
||||
});
|
||||
@ -163,7 +163,7 @@ describe('Emoji', function () {
|
||||
test('Ignores emoji shorthand codes in code, pre, script, and template tags', async () => {
|
||||
await docsifyInit({
|
||||
markdown: {
|
||||
homepage: `
|
||||
homepage: /* html */ `
|
||||
<pre>:100:</pre>
|
||||
|
||||
<code>:100:</code>
|
||||
|
||||
@ -104,7 +104,7 @@ describe('render', function () {
|
||||
const output = window.marked('');
|
||||
|
||||
expect(output).toMatchInlineSnapshot(
|
||||
`"<p><img src=\\"http://imageUrl\\" data-origin=\\"http://imageUrl\\" alt=\\"alt text\\"></p>"`
|
||||
`"<p><img src=\\"http://imageUrl\\" data-origin=\\"http://imageUrl\\" alt=\\"alt text\\" /></p>"`
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
@ -122,7 +122,7 @@ describe('core/render/tpl', () => {
|
||||
]);
|
||||
|
||||
expect(result).toBe(
|
||||
`<ul class="app-sub-sidebar"><li><a class="section-link" href="#/cover?id=basic-usage" title="Basic usage"><span style="color:red">Basic usage</span></a></li><li><a class="section-link" href="#/cover?id=custom-background" title="Custom background">Custom background</a></li><li><a class="section-link" href="#/cover?id=test" title="Test"><img src="/docs/_media/favicon.ico" data-origin="/_media/favicon.ico" alt="ico">Test</a></li></ul>`
|
||||
/* html */ `<ul class="app-sub-sidebar"><li><a class="section-link" href="#/cover?id=basic-usage" title="Basic usage"><span style="color:red">Basic usage</span></a></li><li><a class="section-link" href="#/cover?id=custom-background" title="Custom background">Custom background</a></li><li><a class="section-link" href="#/cover?id=test" title="Test"><img src="/docs/_media/favicon.ico" data-origin="/_media/favicon.ico" alt="ico">Test</a></li></ul>`
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user