mirror of
https://github.com/docsifyjs/docsify.git
synced 2025-12-08 19:55:52 +00:00
Merge branch 'develop' into update-routerMode-docs
This commit is contained in:
commit
dab6e1c1be
@ -1,5 +0,0 @@
|
||||
{
|
||||
"sandboxes": ["2d17z"],
|
||||
"packages": [".", "packages/docsify-server-renderer"],
|
||||
"node": "16"
|
||||
}
|
||||
@ -4,6 +4,5 @@ build
|
||||
docs
|
||||
lib
|
||||
node_modules
|
||||
packages/docsify-server-renderer/build.js
|
||||
server.js
|
||||
themes
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
const prettierConfig = require('./.prettierrc');
|
||||
const prettierConfig = require('./.prettierrc.json');
|
||||
|
||||
module.exports = {
|
||||
root: true,
|
||||
@ -63,7 +63,6 @@ module.exports = {
|
||||
yoda: ['error', 'never'],
|
||||
|
||||
// Import rules
|
||||
// Search way how integrate with `lerna`
|
||||
'import/imports-first': ['error'],
|
||||
'import/newline-after-import': ['error'],
|
||||
'import/no-duplicates': ['error'],
|
||||
17
.github/dependabot.yml
vendored
Normal file
17
.github/dependabot.yml
vendored
Normal file
@ -0,0 +1,17 @@
|
||||
# To get started with Dependabot version updates, you'll need to specify which
|
||||
# package ecosystems to update and where the package manifests are located.
|
||||
# Please see the documentation for all configuration options:
|
||||
# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
|
||||
|
||||
version: 2
|
||||
updates:
|
||||
- package-ecosystem: npm # See documentation for possible values
|
||||
directory: "/" # Location of package manifests
|
||||
open-pull-requests-limit: 10
|
||||
schedule:
|
||||
interval: "weekly"
|
||||
- package-ecosystem: "github-actions"
|
||||
directory: "/"
|
||||
open-pull-requests-limit: 10
|
||||
schedule:
|
||||
interval: monthly
|
||||
24
.github/workflows/test.yml
vendored
24
.github/workflows/test.yml
vendored
@ -1,10 +1,6 @@
|
||||
name: Build & Test
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [master, develop]
|
||||
pull_request:
|
||||
branches: [master, develop]
|
||||
on: [push]
|
||||
|
||||
jobs:
|
||||
lint:
|
||||
@ -13,9 +9,9 @@ jobs:
|
||||
matrix:
|
||||
node-version: ['lts/*']
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v3
|
||||
- name: Setup Node.js ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@v2
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
cache: 'npm'
|
||||
@ -26,10 +22,6 @@ jobs:
|
||||
- name: Lint
|
||||
run: npm run lint
|
||||
|
||||
- name: Verify dependencies [server-renderer]
|
||||
working-directory: ./packages/docsify-server-renderer
|
||||
run: npm ci --ignore-scripts
|
||||
|
||||
test-jest:
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
@ -38,9 +30,9 @@ jobs:
|
||||
node-version: ['lts/*']
|
||||
os: ['macos-latest', 'ubuntu-latest', 'windows-latest']
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v3
|
||||
- name: Setup Node.js ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@v2
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
cache: 'npm'
|
||||
@ -59,9 +51,9 @@ jobs:
|
||||
matrix:
|
||||
node-version: ['lts/*']
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v3
|
||||
- name: Setup Node.js ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@v2
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
cache: 'npm'
|
||||
@ -74,7 +66,7 @@ jobs:
|
||||
- name: E2E Tests (Playwright)
|
||||
run: npm run test:e2e
|
||||
- name: Store artifacts
|
||||
uses: actions/upload-artifact@v2
|
||||
uses: actions/upload-artifact@v3
|
||||
if: failure()
|
||||
with:
|
||||
name: ${{ matrix.os }}-${{ matrix.node-version }}-artifacts
|
||||
|
||||
@ -1,5 +1,4 @@
|
||||
.eslintignore
|
||||
.eslintrc
|
||||
.eslintrc.cjs
|
||||
.github
|
||||
.gitignore
|
||||
.travis.yml
|
||||
|
||||
@ -1,4 +0,0 @@
|
||||
module.exports = {
|
||||
arrowParens: 'avoid',
|
||||
singleQuote: true,
|
||||
};
|
||||
4
.prettierrc.json
Normal file
4
.prettierrc.json
Normal file
@ -0,0 +1,4 @@
|
||||
{
|
||||
"arrowParens": "avoid",
|
||||
"singleQuote": true
|
||||
}
|
||||
19
.vscode/launch.json
vendored
19
.vscode/launch.json
vendored
@ -7,18 +7,18 @@
|
||||
{
|
||||
"type": "node",
|
||||
"request": "launch",
|
||||
"name": "Run tests",
|
||||
"name": "Run unit tests",
|
||||
"runtimeExecutable": "npm",
|
||||
"runtimeArgs": ["run-script", "test"],
|
||||
"runtimeArgs": ["test"],
|
||||
"console": "integratedTerminal"
|
||||
},
|
||||
{
|
||||
"type": "node",
|
||||
"request": "launch",
|
||||
"name": "Run current test file",
|
||||
"runtimeExecutable": "npm",
|
||||
"runtimeArgs": ["run-script", "test"],
|
||||
"args": ["--", "-i", "${relativeFile}", "--testPathIgnorePatterns"],
|
||||
"runtimeExecutable": "npx",
|
||||
"runtimeArgs": ["jest"],
|
||||
"args": ["-i", "${relativeFile}", "--testPathIgnorePatterns"],
|
||||
"console": "integratedTerminal"
|
||||
},
|
||||
{
|
||||
@ -41,10 +41,9 @@
|
||||
"type": "node",
|
||||
"request": "launch",
|
||||
"name": "Update current test file snapshot(s)",
|
||||
"runtimeExecutable": "npm",
|
||||
"runtimeArgs": ["run-script", "test"],
|
||||
"runtimeExecutable": "npx",
|
||||
"runtimeArgs": ["jest"],
|
||||
"args": [
|
||||
"--",
|
||||
"-i",
|
||||
"${relativeFile}",
|
||||
"--updateSnapshot",
|
||||
@ -56,8 +55,8 @@
|
||||
"type": "node",
|
||||
"request": "launch",
|
||||
"name": "Update selected test name snapshot(s)",
|
||||
"runtimeExecutable": "npm",
|
||||
"runtimeArgs": ["run-script", "test"],
|
||||
"runtimeExecutable": "npx",
|
||||
"runtimeArgs": ["jest"],
|
||||
"args": [
|
||||
"--",
|
||||
"-i",
|
||||
|
||||
@ -4,7 +4,8 @@
|
||||
|
||||
First, thank you for considering contributing to docsify! It's people like you that make the open source community such a great community! 😊
|
||||
|
||||
We welcome any type of contribution, not only code. You can help with
|
||||
We welcome any type of contribution, not only code. You can help with
|
||||
|
||||
- **QA**: file bug reports, the more details you can give the better (e.g. screenshots with the console open)
|
||||
- **Marketing**: writing blog posts, howto's, printing stickers, ...
|
||||
- **Community**: presenting the project at meetups, organizing a dedicated meetup for the local community, ...
|
||||
@ -13,12 +14,50 @@ We welcome any type of contribution, not only code. You can help with
|
||||
|
||||
## Your First Contribution
|
||||
|
||||
Working on your first Pull Request? You can learn how from this *free* series, [How to Contribute to an Open Source Project on GitHub](https://app.egghead.io/playlists/how-to-contribute-to-an-open-source-project-on-github).
|
||||
Working on your first Pull Request ever? You can learn how from this _free_ series, [How to Contribute to an Open Source Project on GitHub](https://app.egghead.io/playlists/how-to-contribute-to-an-open-source-project-on-github).
|
||||
|
||||
## Online one-click setup for Contributing
|
||||
|
||||
You can use Gitpod (a free online VS Code-like IDE) for contributing. With a single click it'll launch a workspace and automatically:
|
||||
|
||||
- clone the docsify repo.
|
||||
- install the dependencies.
|
||||
- start `npm run dev`.
|
||||
|
||||
```bash
|
||||
npm install && npm run dev
|
||||
```
|
||||
|
||||
So that you can start straight away.
|
||||
|
||||
[](https://gitpod.io/#https://github.com/docsifyjs/docsify)
|
||||
|
||||
- Fork it!
|
||||
- Create your feature branch: `git checkout -b my-new-feature`
|
||||
- Commit your changes: `git add . && git commit -m 'Add some feature'`
|
||||
- Push to the branch: `git push origin my-new-feature`
|
||||
- Submit a pull request
|
||||
|
||||
## Submitting code
|
||||
|
||||
Any code change should be submitted as a pull request. The description should explain what the code does and give steps to execute it. The pull request should also contain tests.
|
||||
|
||||
## Testing
|
||||
|
||||
Ensure that things work by running:
|
||||
|
||||
```sh
|
||||
npm test
|
||||
```
|
||||
|
||||
## Test Snapshots
|
||||
|
||||
If a snapshot fails, or to add new snapshots, run:
|
||||
|
||||
```sh
|
||||
npx jest --updateSnapshot
|
||||
```
|
||||
|
||||
## Code review process
|
||||
|
||||
The bigger the pull request, the longer it will take to review and merge. Try to break down large pull requests in smaller chunks that are easier to review and merge.
|
||||
@ -41,14 +80,12 @@ You can also reach us at hello@docsify.opencollective.com.
|
||||
Thank you to all the people who have already contributed to docsify!
|
||||
<a href="graphs/contributors"><img src="https://opencollective.com/docsify/contributors.svg?width=890" /></a>
|
||||
|
||||
|
||||
### Backers
|
||||
|
||||
Thank you to all our backers! [[Become a backer](https://opencollective.com/docsify#backer)]
|
||||
|
||||
<a href="https://opencollective.com/docsify#backers" target="_blank"><img src="https://opencollective.com/docsify/backers.svg?width=890"></a>
|
||||
|
||||
|
||||
### Sponsors
|
||||
|
||||
Thank you to all our sponsors! (please ask your company to also support this open source project by [becoming a sponsor](https://opencollective.com/docsify#sponsor))
|
||||
|
||||
36
README.md
36
README.md
@ -32,7 +32,10 @@
|
||||
- [`develop` branch preview](https://docsify-preview.vercel.app/)
|
||||
- [Documentation](https://docsify.js.org)
|
||||
- [CLI](https://github.com/docsifyjs/docsify-cli)
|
||||
- CDN: [UNPKG](https://unpkg.com/docsify/) | [jsDelivr](https://cdn.jsdelivr.net/npm/docsify/) | [cdnjs](https://cdnjs.com/libraries/docsify)
|
||||
- CDN:
|
||||
- [UNPKG](https://unpkg.com/docsify/)
|
||||
- [jsDelivr](https://cdn.jsdelivr.net/npm/docsify/)
|
||||
- [cdnjs](https://cdnjs.com/libraries/docsify)
|
||||
- [Awesome docsify](https://github.com/docsifyjs/awesome-docsify)
|
||||
- [Community chat](https://discord.gg/3NwKFyR)
|
||||
|
||||
@ -44,7 +47,6 @@
|
||||
- Multiple themes
|
||||
- Useful plugin API
|
||||
- Compatible with IE11
|
||||
- Experimental SSR support ([example](https://github.com/docsifyjs/docsify-ssr-demo))
|
||||
- Support embedded files
|
||||
|
||||
## Quick start
|
||||
@ -63,34 +65,14 @@ Move to [awesome-docsify](https://github.com/docsifyjs/awesome-docsify#showcase)
|
||||
|
||||
| Project | Description |
|
||||
| ------------------------------------------------ | ---------------------------------------- |
|
||||
| [docute](https://github.com/egoist/docute) | 📜 Effortlessly documentation done right |
|
||||
| [docpress](https://github.com/docpress/docpress) | Documentation website generator |
|
||||
| [Docusaurus](https://docusaurus.io) | Docusaurus makes it easy to maintain Open Source documentation websites |
|
||||
| [GitBook](https://www.gitbook.com) | Where technical teams document |
|
||||
| [MkDocs](https://www.mkdocs.org) | Project documentation with Markdown |
|
||||
| [VuePress](https://vuepress.vuejs.org) | Vue-powered Static Site Generator |
|
||||
|
||||
## Contributing
|
||||
|
||||
### Online one-click setup for Contributing
|
||||
|
||||
You can use Gitpod (a free online VS Code-like IDE) for contributing. With a single click it'll launch a workspace and automatically:
|
||||
|
||||
- clone the docsify repo.
|
||||
- install the dependencies.
|
||||
- start `npm run dev`.
|
||||
|
||||
So that you can start straight away.
|
||||
|
||||
[](https://gitpod.io/#https://github.com/docsifyjs/docsify)
|
||||
|
||||
- Fork it!
|
||||
- Create your feature branch: `git checkout -b my-new-feature`
|
||||
- Commit your changes: `git add . && git commit -m 'Add some feature'`
|
||||
- Push to the branch: `git push origin my-new-feature`
|
||||
- Submit a pull request
|
||||
|
||||
## Development
|
||||
|
||||
```bash
|
||||
npm run bootstrap && npm run dev
|
||||
```
|
||||
See [CONTRIBUTING.md](./CONTRIBUTING.md).
|
||||
|
||||
## Backers
|
||||
|
||||
|
||||
@ -1,12 +0,0 @@
|
||||
module.exports = {
|
||||
presets: [
|
||||
[
|
||||
'@babel/preset-env',
|
||||
{
|
||||
targets: {
|
||||
node: 'current',
|
||||
},
|
||||
},
|
||||
],
|
||||
],
|
||||
};
|
||||
12
babel.config.json
Normal file
12
babel.config.json
Normal file
@ -0,0 +1,12 @@
|
||||
{
|
||||
"presets": [
|
||||
[
|
||||
"@babel/preset-env",
|
||||
{
|
||||
"targets": {
|
||||
"node": "current"
|
||||
}
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
||||
@ -1,13 +1,18 @@
|
||||
const rollup = require('rollup')
|
||||
const buble = require('rollup-plugin-buble')
|
||||
const commonjs = require('rollup-plugin-commonjs')
|
||||
const nodeResolve = require('rollup-plugin-node-resolve')
|
||||
const { uglify } = require('rollup-plugin-uglify')
|
||||
const replace = require('rollup-plugin-replace')
|
||||
const isProd = process.env.NODE_ENV === 'production'
|
||||
const version = process.env.VERSION || require('../package.json').version
|
||||
const chokidar = require('chokidar')
|
||||
const path = require('path')
|
||||
import * as rollup from 'rollup';
|
||||
import commonjs from '@rollup/plugin-commonjs';
|
||||
import nodeResolve from '@rollup/plugin-node-resolve';
|
||||
import uglify from '@rollup/plugin-terser';
|
||||
import replace from '@rollup/plugin-replace';
|
||||
import chokidar from 'chokidar';
|
||||
import path from 'path';
|
||||
import { relative } from './util.js';
|
||||
import { promises as fs } from 'fs';
|
||||
|
||||
const pkgPath = relative(import.meta, '..', 'package.json');
|
||||
const pkgString = (await fs.readFile(pkgPath)).toString();
|
||||
const pkg = JSON.parse(pkgString);
|
||||
const isProd = process.env.NODE_ENV === 'production';
|
||||
const version = process.env.VERSION || pkg.version;
|
||||
|
||||
/**
|
||||
* @param {{
|
||||
@ -22,15 +27,10 @@ async function build(opts) {
|
||||
.rollup({
|
||||
input: opts.input,
|
||||
plugins: (opts.plugins || []).concat([
|
||||
buble({
|
||||
transforms: {
|
||||
dangerousForOf: true
|
||||
}}),
|
||||
commonjs(),
|
||||
nodeResolve(),
|
||||
replace({
|
||||
__VERSION__: version,
|
||||
'process.env.SSR': false
|
||||
})
|
||||
]),
|
||||
onwarn: function (message) {
|
||||
@ -80,6 +80,7 @@ async function buildAllPlugin() {
|
||||
var plugins = [
|
||||
{name: 'search', input: 'search/index.js'},
|
||||
{name: 'ga', input: 'ga.js'},
|
||||
{name: 'gtag', input: 'gtag.js'},
|
||||
{name: 'matomo', input: 'matomo.js'},
|
||||
{name: 'emoji', input: 'emoji.js'},
|
||||
{name: 'external-script', input: 'external-script.js'},
|
||||
|
||||
@ -1,14 +1,17 @@
|
||||
var fs = require('fs')
|
||||
var read = fs.readFileSync
|
||||
var write = fs.writeFileSync
|
||||
var version = process.env.VERSION || require('../package.json').version
|
||||
import fs from 'fs';
|
||||
import { relative } from './util.js';
|
||||
var read = fs.readFileSync;
|
||||
var write = fs.writeFileSync;
|
||||
const pkgPath = relative(import.meta, '..', 'package.json');
|
||||
const pkg = JSON.parse(read(pkgPath).toString());
|
||||
var version = process.env.VERSION || pkg.version;
|
||||
|
||||
var file = __dirname + '/../docs/_coverpage.md'
|
||||
var cover = read(file, 'utf8').toString()
|
||||
var file = relative(import.meta, '..', 'docs', '_coverpage.md');
|
||||
var cover = read(file, 'utf8').toString();
|
||||
|
||||
console.log('Replace version number in cover page...')
|
||||
console.log('Replace version number in cover page...');
|
||||
cover = cover.replace(
|
||||
/<small>(\S+)?<\/small>/g,
|
||||
'<small>' + version + '</small>'
|
||||
)
|
||||
write(file, cover)
|
||||
);
|
||||
write(file, cover);
|
||||
|
||||
@ -1,9 +1,10 @@
|
||||
const fs = require('fs')
|
||||
const path = require('path')
|
||||
const {spawn} = require('child_process')
|
||||
import fs from 'fs'
|
||||
import path from 'path'
|
||||
import {spawn} from 'child_process'
|
||||
|
||||
const relative = path => new URL(path, import.meta.url);
|
||||
const args = process.argv.slice(2)
|
||||
fs.readdir(path.join(__dirname, '../src/themes'), (err, files) => {
|
||||
fs.readdir(relative('../src/themes'), (err, files) => {
|
||||
if (err) {
|
||||
console.error('err', err)
|
||||
process.exit(1)
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
const axios = require('axios');
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
import axios from 'axios';
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
|
||||
const filePaths = {
|
||||
emojiMarkdown: path.resolve(process.cwd(), 'docs', 'emoji.md'),
|
||||
|
||||
@ -1,12 +1,12 @@
|
||||
const cssnano = require('cssnano').process
|
||||
const path = require('path')
|
||||
const fs = require('fs')
|
||||
import cssnano from 'cssnano';
|
||||
import path from 'path'
|
||||
import fs from 'fs'
|
||||
|
||||
files = fs.readdirSync(path.resolve('lib/themes'))
|
||||
const files = fs.readdirSync(path.resolve('lib/themes'))
|
||||
|
||||
files.forEach(file => {
|
||||
file = path.resolve('lib/themes', file)
|
||||
cssnano(fs.readFileSync(file)).then(result => {
|
||||
cssnano.process(fs.readFileSync(file)).then(result => {
|
||||
fs.writeFileSync(file, result.css)
|
||||
}).catch(e => {
|
||||
console.error(e)
|
||||
|
||||
@ -12,22 +12,11 @@ echo
|
||||
if [[ $REPLY =~ ^[Yy]$ ]]; then
|
||||
echo "Releasing $VERSION ..."
|
||||
|
||||
# Removing test script as non - availibity of tests. Will Add it once tests are completed
|
||||
|
||||
# npm run test
|
||||
|
||||
# build
|
||||
VERSION=$VERSION npm run build
|
||||
|
||||
# update packages
|
||||
cd packages/docsify-server-renderer
|
||||
npm version $VERSION
|
||||
if [[ -z $RELEASE_TAG ]]; then
|
||||
npm publish
|
||||
else
|
||||
npm publish --tag $RELEASE_TAG
|
||||
fi
|
||||
cd -
|
||||
# TODO
|
||||
# npm test
|
||||
|
||||
# commit
|
||||
git add -A
|
||||
|
||||
35
build/ssr.js
35
build/ssr.js
@ -1,35 +0,0 @@
|
||||
var rollup = require('rollup')
|
||||
var buble = require('rollup-plugin-buble')
|
||||
var async = require('rollup-plugin-async')
|
||||
var replace = require('rollup-plugin-replace')
|
||||
|
||||
rollup
|
||||
.rollup({
|
||||
input: 'packages/docsify-server-renderer/index.js',
|
||||
plugins: [
|
||||
async(),
|
||||
replace({
|
||||
__VERSION__: process.env.VERSION || require('../package.json').version,
|
||||
'process.env.SSR': true
|
||||
}),
|
||||
buble({
|
||||
transforms: {
|
||||
generator: false
|
||||
}
|
||||
})
|
||||
],
|
||||
onwarn: function () {}
|
||||
})
|
||||
.then(function (bundle) {
|
||||
var dest = 'packages/docsify-server-renderer/build.js'
|
||||
|
||||
console.log(dest)
|
||||
return bundle.write({
|
||||
format: 'cjs',
|
||||
file: dest
|
||||
})
|
||||
})
|
||||
.catch(function (err) {
|
||||
console.error(err)
|
||||
process.exit(1)
|
||||
})
|
||||
6
build/util.js
Normal file
6
build/util.js
Normal file
@ -0,0 +1,6 @@
|
||||
import url from 'url';
|
||||
import path from 'path';
|
||||
|
||||
/** Get a new path relative to the current module (pass import.meta). */
|
||||
export const relative = (meta, ...to) =>
|
||||
path.resolve(path.dirname(url.fileURLToPath(meta.url)), ...to);
|
||||
@ -17,7 +17,6 @@ See the [Quick start](quickstart.md) guide for more details.
|
||||
- Useful plugin API
|
||||
- Emoji support
|
||||
- Compatible with IE11
|
||||
- Support server-side rendering ([example](https://github.com/docsifyjs/docsify-ssr-demo))
|
||||
|
||||
## Examples
|
||||
|
||||
|
||||
@ -22,7 +22,6 @@
|
||||
- [Vue compatibility](vue.md)
|
||||
- [CDN](cdn.md)
|
||||
- [Offline Mode (PWA)](pwa.md)
|
||||
- [Server-Side Rendering (SSR)](ssr.md)
|
||||
- [Embed Files](embed-files.md)
|
||||
|
||||
- [Awesome docsify](awesome.md)
|
||||
|
||||
@ -34,6 +34,8 @@ Below is a complete list of emoji shorthand codes. Docsify can be configured to
|
||||
|
||||
:accept: `:accept:`
|
||||
|
||||
:accessibility: `:accessibility:`
|
||||
|
||||
:accordion: `:accordion:`
|
||||
|
||||
:adhesive_bandage: `:adhesive_bandage:`
|
||||
@ -920,6 +922,8 @@ Below is a complete list of emoji shorthand codes. Docsify can be configured to
|
||||
|
||||
:department_store: `:department_store:`
|
||||
|
||||
:dependabot: `:dependabot:`
|
||||
|
||||
:derelict_house: `:derelict_house:`
|
||||
|
||||
:desert: `:desert:`
|
||||
@ -1238,6 +1242,8 @@ Below is a complete list of emoji shorthand codes. Docsify can be configured to
|
||||
|
||||
:fishing_pole_and_fish: `:fishing_pole_and_fish:`
|
||||
|
||||
:fishsticks: `:fishsticks:`
|
||||
|
||||
:fist: `:fist:`
|
||||
|
||||
:fist_left: `:fist_left:`
|
||||
|
||||
@ -71,6 +71,8 @@ This plugin ignores diacritical marks when performing a full text search (e.g.,
|
||||
|
||||
## Google Analytics
|
||||
|
||||
> Google's Universal Analytics service will no longer process new data in standard properties beginning July 1, 2023. Prepare now by setting up and switching over to a Google Analytics 4 property and docsify's gtag.js plugin.
|
||||
|
||||
Install the plugin and configure the track id.
|
||||
|
||||
```html
|
||||
@ -91,6 +93,31 @@ Configure by `data-ga`.
|
||||
<script src="//cdn.jsdelivr.net/npm/docsify/lib/plugins/ga.min.js"></script>
|
||||
```
|
||||
|
||||
## Google Analytics 4 (GA4)
|
||||
|
||||
Install the plugin and configure the track id.
|
||||
|
||||
```html
|
||||
<script>
|
||||
// Single ID
|
||||
window.$docsify = {
|
||||
gtag: 'UA-XXXXX-Y',
|
||||
};
|
||||
|
||||
// Multiple IDs
|
||||
window.$docsify = {
|
||||
gtag: [
|
||||
'G-XXXXXXXX', // Google Analytics 4 (GA4)
|
||||
'UA-XXXXXXXX', // Google Universal Analytics (GA3)
|
||||
'AW-XXXXXXXX', // Google Ads
|
||||
'DC-XXXXXXXX', // Floodlight
|
||||
],
|
||||
};
|
||||
</script>
|
||||
<script src="//cdn.jsdelivr.net/npm/docsify/lib/docsify.min.js"></script>
|
||||
<script src="//cdn.jsdelivr.net/npm/docsify/lib/plugins/gtag.min.js"></script>
|
||||
```
|
||||
|
||||
## Emoji
|
||||
|
||||
Renders a larger collection of emoji shorthand codes. Without this plugin, Docsify is able to render only a limited number of emoji shorthand codes.
|
||||
|
||||
131
docs/ssr.md
131
docs/ssr.md
@ -1,131 +0,0 @@
|
||||
# Server-Side Rendering
|
||||
|
||||
!> :construction: SSR support is experimental and incomplete. We are working on it. Plugins and
|
||||
some features of Docsify will not work in SSR mode yet. :construction:
|
||||
|
||||
<!--
|
||||
This link is dead.
|
||||
See https://docsify.now.sh
|
||||
-->
|
||||
|
||||
Sample repo at https://github.com/docsifyjs/docsify-ssr-demo
|
||||
|
||||
## Why SSR?
|
||||
|
||||
- Better SEO
|
||||
- Feeling cool
|
||||
|
||||
## Quick start
|
||||
|
||||
Install `now` and `docsify-cli` in your project.
|
||||
|
||||
```bash
|
||||
npm i now docsify-cli -D
|
||||
```
|
||||
|
||||
Edit `package.json`. The below assumes the documentation is in the `./docs` subdirectory.
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "my-project",
|
||||
"scripts": {
|
||||
"start": "docsify start . -c ssr.config.js",
|
||||
"deploy": "now -p"
|
||||
},
|
||||
"files": [
|
||||
"docs"
|
||||
],
|
||||
"docsify": {
|
||||
"config": {
|
||||
"basePath": "https://docsify.js.org/",
|
||||
"loadSidebar": true,
|
||||
"loadNavbar": true,
|
||||
"coverpage": true,
|
||||
"name": "docsify"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
!> The `basePath` just like webpack `publicPath`. We can use local or remote files.
|
||||
|
||||
We can preview the local site to see if it works.
|
||||
|
||||
```bash
|
||||
npm start
|
||||
|
||||
# open http://localhost:4000
|
||||
```
|
||||
|
||||
Publish it!
|
||||
|
||||
```bash
|
||||
now -p
|
||||
```
|
||||
|
||||
Now, you have support for SSR.
|
||||
|
||||
## Custom template
|
||||
|
||||
You can provide a template for an entire page's HTML, such as
|
||||
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>docsify</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0">
|
||||
<link rel="stylesheet" href="//cdn.jsdelivr.net/npm/docsify/themes/vue.css" title="vue">
|
||||
</head>
|
||||
<body>
|
||||
<!--inject-app-->
|
||||
<!--inject-config-->
|
||||
<script src="//cdn.jsdelivr.net/npm/docsify/lib/docsify.js"></script>
|
||||
<script src="//cdn.jsdelivr.net/npm/docsify/lib/plugins/search.js"></script>
|
||||
<script src="//cdn.jsdelivr.net/npm/prismjs/components/prism-bash.min.js"></script>
|
||||
<script src="//cdn.jsdelivr.net/npm/prismjs/components/prism-markdown.min.js"></script>
|
||||
<script src="//cdn.jsdelivr.net/npm/prismjs/components/prism-nginx.min.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
The template should contain these comments for rendered app content.
|
||||
- `<!--inject-app-->`
|
||||
- `<!--inject-config-->`
|
||||
|
||||
## Configuration
|
||||
|
||||
You can configure it in a special config file, or `package.json`.
|
||||
|
||||
```js
|
||||
module.exports = {
|
||||
template: './ssr.html',
|
||||
maxAge: 60 * 60 * 1000, // lru-cache config
|
||||
config: {
|
||||
// docsify config
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Deploy for your VPS
|
||||
|
||||
You can run `docsify start` directly on your Node server, or write your own server app with `docsify-server-renderer`.
|
||||
|
||||
```js
|
||||
var Renderer = require('docsify-server-renderer')
|
||||
var readFileSync = require('fs').readFileSync
|
||||
|
||||
// init
|
||||
var renderer = new Renderer({
|
||||
template: readFileSync('./docs/index.template.html', 'utf-8'),
|
||||
config: {
|
||||
name: 'docsify',
|
||||
repo: 'docsifyjs/docsify'
|
||||
}
|
||||
})
|
||||
|
||||
renderer.renderToString(url)
|
||||
.then(html => {})
|
||||
.catch(err => {})
|
||||
```
|
||||
@ -1,4 +1,4 @@
|
||||
const { TEST_HOST } = require('./test/config/server.js');
|
||||
import { TEST_HOST } from './test/config/server.js';
|
||||
|
||||
const sharedConfig = {
|
||||
errorOnDeprecated: true,
|
||||
@ -11,7 +11,8 @@ const sharedConfig = {
|
||||
testURL: `${TEST_HOST}/_blank.html`,
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
export default {
|
||||
transform: {},
|
||||
projects: [
|
||||
// Unit Tests
|
||||
{
|
||||
|
||||
@ -1,7 +0,0 @@
|
||||
{
|
||||
"lerna": "2.0.0-rc.5",
|
||||
"packages": [
|
||||
"packages/*"
|
||||
],
|
||||
"version": "0.0.0"
|
||||
}
|
||||
19980
package-lock.json
generated
19980
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
81
package.json
81
package.json
@ -2,35 +2,35 @@
|
||||
"name": "docsify",
|
||||
"version": "4.13.0",
|
||||
"description": "A magical documentation generator.",
|
||||
"author": {
|
||||
"name": "qingwei-li",
|
||||
"email": "cinwell.li@gmail.com",
|
||||
"url": "https://github.com/QingWei-Li"
|
||||
},
|
||||
"homepage": "https://docsify.js.org",
|
||||
"repository": "github:docsifyjs/docsify",
|
||||
"authors": "https://github.com/docsifyjs/docsify/graphs/contributors",
|
||||
"license": "MIT",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/docsifyjs/docsify.git"
|
||||
"collective": {
|
||||
"url": "https://opencollective.com/docsify"
|
||||
},
|
||||
"type": "module",
|
||||
"// The 'main' and 'unpkg' fields will remain as legacy for backwards compatbility for now. We will add deprectaion warnings to these outputs to give people time to see the warnings in their apps in a non-breaking way, and eventually we can remove the legacy stuff.": "",
|
||||
"main": "lib/docsify.js",
|
||||
"unpkg": "lib/docsify.min.js",
|
||||
"// We're using the 'exports' field as an override of the 'main' field to provide the new ESM setup. Once we remove legacy 'main', we will remove the 'exports' field and have a simple ESM setup with only a 'main' field.": "",
|
||||
"exports": {
|
||||
".": "./src/Docsify.js",
|
||||
"./*": "./*"
|
||||
},
|
||||
"files": [
|
||||
"lib",
|
||||
"themes"
|
||||
],
|
||||
"scripts": {
|
||||
"bootstrap": "npm i && lerna bootstrap && npm run build:ssr",
|
||||
"build:cover": "node build/cover.js",
|
||||
"build:css:min": "mkdirp lib/themes && npm run css -- -o lib/themes && node build/mincss.js",
|
||||
"build:css": "mkdirp themes && npm run css -- -o themes",
|
||||
"build:emoji": "node ./build/emoji.js",
|
||||
"build:js": "cross-env NODE_ENV=production node build/build.js",
|
||||
"build:ssr": "node build/ssr.js",
|
||||
"build:test": "npm run build && npm test",
|
||||
"build": "rimraf lib themes && run-s build:js build:css build:css:min build:ssr build:cover build:emoji",
|
||||
"build": "rimraf lib themes && run-s build:js build:css build:css:min build:cover build:emoji",
|
||||
"css": "node build/css",
|
||||
"dev:ssr": "run-p serve:ssr watch:*",
|
||||
"dev": "run-p serve watch:*",
|
||||
"docker:build:test": "npm run docker:cli -- build:test",
|
||||
"docker:build": "docker build -f Dockerfile -t docsify-test:local .",
|
||||
@ -47,12 +47,12 @@
|
||||
"prepare": "npm run build",
|
||||
"pub:next": "cross-env RELEASE_TAG=next sh build/release.sh",
|
||||
"pub": "sh build/release.sh",
|
||||
"serve:ssr": "cross-env SSR=1 node server",
|
||||
"serve": "node server",
|
||||
"test:e2e": "playwright test",
|
||||
"test:integration": "jest --selectProjects integration",
|
||||
"test:unit": "jest --selectProjects unit",
|
||||
"test": "jest && run-s test:e2e",
|
||||
"test:integration": "npm run jest -- --selectProjects integration",
|
||||
"test:unit": "npm run jest -- --selectProjects unit",
|
||||
"test": "npm run jest && run-s test:e2e",
|
||||
"jest": "cross-env NODE_OPTIONS=--experimental-vm-modules jest",
|
||||
"watch:css": "npm run css -- -o themes -w",
|
||||
"watch:js": "node build/build.js"
|
||||
},
|
||||
@ -65,7 +65,7 @@
|
||||
"*.js": "eslint --fix"
|
||||
},
|
||||
"dependencies": {
|
||||
"marked": "^1.2.9",
|
||||
"marked": "^4.2.12",
|
||||
"medium-zoom": "^1.0.8",
|
||||
"opencollective-postinstall": "^2.0.2",
|
||||
"prismjs": "^1.29.0",
|
||||
@ -77,41 +77,41 @@
|
||||
"@babel/core": "^7.11.6",
|
||||
"@babel/eslint-parser": "^7.16.5",
|
||||
"@babel/preset-env": "^7.11.5",
|
||||
"@eslint/js": "^8.43.0",
|
||||
"@playwright/test": "^1.18.1",
|
||||
"@rollup/plugin-commonjs": "^25.0.2",
|
||||
"@rollup/plugin-node-resolve": "^15.1.0",
|
||||
"@rollup/plugin-replace": "^5.0.2",
|
||||
"@rollup/plugin-terser": "^0.4.3",
|
||||
"@types/eslint": "^8.40.2",
|
||||
"autoprefixer-stylus": "^1.0.0",
|
||||
"axios": "^0.21.1",
|
||||
"babel-jest": "^27.4.6",
|
||||
"browser-sync": "^2.26.12",
|
||||
"chokidar": "^3.4.2",
|
||||
"common-tags": "^1.8.0",
|
||||
"conventional-changelog-cli": "^2.1.0",
|
||||
"conventional-changelog-cli": "^3.0.0",
|
||||
"copy-dir": "^1.2.0",
|
||||
"cross-env": "^6.0.3",
|
||||
"cross-env": "^7.0.3",
|
||||
"cssnano": "^4.1.10",
|
||||
"eslint": "^8.7.0",
|
||||
"eslint-config-prettier": "^8.3.0",
|
||||
"eslint-plugin-import": "^2.20.1",
|
||||
"eslint-plugin-jest": "^26.0.0",
|
||||
"eslint-plugin-playwright": "^0.8.0",
|
||||
"eslint-plugin-prettier": "^4.0.0",
|
||||
"husky": "^3.1.0",
|
||||
"eslint": "^8.43.0",
|
||||
"eslint-config-prettier": "^8.8.0",
|
||||
"eslint-plugin-import": "^2.27.5",
|
||||
"eslint-plugin-jest": "^27.2.2",
|
||||
"eslint-plugin-playwright": "^0.15.1",
|
||||
"eslint-plugin-prettier": "^4.2.1",
|
||||
"globals": "^13.20.0",
|
||||
"husky": "^8.0.3",
|
||||
"jest": "^27.4.7",
|
||||
"lerna": "^5.5.1",
|
||||
"lint-staged": "^10.4.0",
|
||||
"lint-staged": "^13.2.2",
|
||||
"live-server": "^1.2.1",
|
||||
"mkdirp": "^0.5.1",
|
||||
"mkdirp": "^3.0.0",
|
||||
"npm-run-all": "^4.1.5",
|
||||
"prettier": "^2.5.1",
|
||||
"prettier": "^2.8.8",
|
||||
"rimraf": "^3.0.0",
|
||||
"rollup": "^1.23.1",
|
||||
"rollup-plugin-async": "^1.2.0",
|
||||
"rollup-plugin-buble": "^0.19.8",
|
||||
"rollup-plugin-commonjs": "^10.1.0",
|
||||
"rollup-plugin-node-resolve": "^5.2.0",
|
||||
"rollup-plugin-replace": "^2.2.0",
|
||||
"rollup-plugin-uglify": "^6.0.4",
|
||||
"rollup": "^3.25.3",
|
||||
"serve-handler": "^6.1.2",
|
||||
"stylus": "^0.54.5",
|
||||
"stylus": "^0.59.0",
|
||||
"vue2": "npm:vue@^2.6.12",
|
||||
"vue3": "npm:vue@^3.0.0",
|
||||
"xhr-mock": "^2.5.1"
|
||||
@ -122,8 +122,5 @@
|
||||
"documentation",
|
||||
"creator",
|
||||
"generator"
|
||||
],
|
||||
"collective": {
|
||||
"url": "https://opencollective.com/docsify"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
4
packages/docsify-server-renderer/.gitignore
vendored
4
packages/docsify-server-renderer/.gitignore
vendored
@ -1,4 +0,0 @@
|
||||
build.js
|
||||
node_modules
|
||||
*.log
|
||||
.git
|
||||
@ -1,46 +0,0 @@
|
||||
# docsify-server-renderer
|
||||
|
||||
## Install
|
||||
|
||||
```bash
|
||||
yarn add docsify-server-renderer
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
```js
|
||||
var Renderer = require('docsify-server-renderer')
|
||||
var readFileSync = require('fs').readFileSync
|
||||
|
||||
// init
|
||||
var renderer = new Renderer({
|
||||
template: readFileSync('./docs/index.template.html', 'utf-8'),
|
||||
config: {
|
||||
name: 'docsify',
|
||||
repo: 'docsifyjs/docsify'
|
||||
}
|
||||
})
|
||||
|
||||
renderer.renderToString(url)
|
||||
.then(html => {})
|
||||
.catch(err => {})
|
||||
```
|
||||
|
||||
*index.template.html*
|
||||
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>docsify</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0">
|
||||
<link rel="stylesheet" href="//cdn.jsdelivr.net/npm/docsify/themes/vue.css" title="vue">
|
||||
</head>
|
||||
<body>
|
||||
<!--inject-app-->
|
||||
<!--inject-config-->
|
||||
<script src="//cdn.jsdelivr.net/npm/docsify/lib/docsify.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
@ -1,212 +0,0 @@
|
||||
import { readFileSync } from 'fs';
|
||||
import { resolve, basename } from 'path';
|
||||
import resolvePathname from 'resolve-pathname';
|
||||
import fetch from 'node-fetch';
|
||||
import debug from 'debug';
|
||||
import { AbstractHistory } from '../../src/core/router/history/abstract';
|
||||
import { Compiler } from '../../src/core/render/compiler';
|
||||
import { isAbsolutePath } from '../../src/core/router/util';
|
||||
import * as tpl from '../../src/core/render/tpl';
|
||||
import { prerenderEmbed } from '../../src/core/render/embed';
|
||||
|
||||
function cwd(...args) {
|
||||
return resolve(process.cwd(), ...args);
|
||||
}
|
||||
|
||||
function isExternal(url) {
|
||||
let match = url.match(
|
||||
/^([^:/?#]+:)?(?:\/\/([^/?#]*))?([^?#]+)?(\?[^#]*)?(#.*)?/
|
||||
);
|
||||
if (
|
||||
typeof match[1] === 'string' &&
|
||||
match[1].length > 0 &&
|
||||
match[1].toLowerCase() !== location.protocol
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
if (
|
||||
typeof match[2] === 'string' &&
|
||||
match[2].length > 0 &&
|
||||
match[2].replace(
|
||||
new RegExp(
|
||||
':(' + { 'http:': 80, 'https:': 443 }[location.protocol] + ')?$'
|
||||
),
|
||||
''
|
||||
) !== location.host
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function mainTpl(config) {
|
||||
let html = `<nav class="app-nav${
|
||||
config.repo ? '' : ' no-badge'
|
||||
}"><!--navbar--></nav>`;
|
||||
|
||||
if (config.repo) {
|
||||
html += tpl.corner(config.repo);
|
||||
}
|
||||
|
||||
if (config.coverpage) {
|
||||
html += tpl.cover();
|
||||
}
|
||||
|
||||
html += tpl.main(config);
|
||||
|
||||
return html;
|
||||
}
|
||||
|
||||
export default class Renderer {
|
||||
constructor({ template, config, cache }) {
|
||||
this.html = template;
|
||||
this.config = config = Object.assign({}, config, {
|
||||
routerMode: 'history',
|
||||
});
|
||||
this.cache = cache;
|
||||
|
||||
this.router = new AbstractHistory(config);
|
||||
this.compiler = new Compiler(config, this.router);
|
||||
|
||||
this.router.getCurrentPath = () => this.url;
|
||||
this._renderHtml(
|
||||
'inject-config',
|
||||
`<script>window.$docsify = ${JSON.stringify(config)}</script>`
|
||||
);
|
||||
this._renderHtml('inject-app', mainTpl(config));
|
||||
|
||||
this.template = this.html;
|
||||
}
|
||||
|
||||
_getPath(url) {
|
||||
const file = this.router.getFile(url);
|
||||
|
||||
return isAbsolutePath(file) ? file : cwd(`./${file}`);
|
||||
}
|
||||
|
||||
async renderToString(url) {
|
||||
this.url = url = this.router.parse(url).path;
|
||||
this.isRemoteUrl = isExternal(this.url);
|
||||
const { loadSidebar, loadNavbar, coverpage } = this.config;
|
||||
|
||||
const mainFile = this._getPath(url);
|
||||
this._renderHtml('main', await this._render(mainFile, 'main'));
|
||||
|
||||
if (loadSidebar) {
|
||||
const name = loadSidebar === true ? '_sidebar.md' : loadSidebar;
|
||||
const sidebarFile = this._getPath(resolve(url, `./${name}`));
|
||||
this._renderHtml('sidebar', await this._render(sidebarFile, 'sidebar'));
|
||||
}
|
||||
|
||||
if (loadNavbar) {
|
||||
const name = loadNavbar === true ? '_navbar.md' : loadNavbar;
|
||||
const navbarFile = this._getPath(resolve(url, `./${name}`));
|
||||
this._renderHtml('navbar', await this._render(navbarFile, 'navbar'));
|
||||
}
|
||||
|
||||
if (coverpage) {
|
||||
let path = null;
|
||||
if (typeof coverpage === 'string') {
|
||||
if (url === '/') {
|
||||
path = coverpage;
|
||||
}
|
||||
} else if (Array.isArray(coverpage)) {
|
||||
path = coverpage.indexOf(url) > -1 && '_coverpage.md';
|
||||
} else {
|
||||
const cover = coverpage[url];
|
||||
path = cover === true ? '_coverpage.md' : cover;
|
||||
}
|
||||
|
||||
const coverFile = this._getPath(resolve(url, `./${path}`));
|
||||
|
||||
this._renderHtml('cover', await this._render(coverFile), 'cover');
|
||||
}
|
||||
|
||||
const html = this.html;
|
||||
|
||||
this.html = this.template;
|
||||
|
||||
return html;
|
||||
}
|
||||
|
||||
_renderHtml(match, content) {
|
||||
this.html = this.html.replace(new RegExp(`<!--${match}-->`, 'g'), content);
|
||||
|
||||
return this.html;
|
||||
}
|
||||
|
||||
async _render(path, type) {
|
||||
let html = await this._loadFile(path);
|
||||
const { subMaxLevel, maxLevel } = this.config;
|
||||
let tokens;
|
||||
|
||||
switch (type) {
|
||||
case 'sidebar':
|
||||
html =
|
||||
this.compiler.sidebar(html, maxLevel) +
|
||||
`<script>window.__SUB_SIDEBAR__ = ${JSON.stringify(
|
||||
this.compiler.subSidebar(subMaxLevel)
|
||||
)}</script>`;
|
||||
break;
|
||||
case 'cover':
|
||||
html = this.compiler.cover(html);
|
||||
break;
|
||||
case 'main':
|
||||
tokens = await new Promise(r => {
|
||||
prerenderEmbed(
|
||||
{
|
||||
fetch: url => this._loadFile(this._getPath(url)),
|
||||
compiler: this.compiler,
|
||||
raw: html,
|
||||
},
|
||||
r
|
||||
);
|
||||
});
|
||||
html = this.compiler.compile(tokens);
|
||||
break;
|
||||
case 'navbar':
|
||||
case 'article':
|
||||
default:
|
||||
html = this.compiler.compile(html);
|
||||
break;
|
||||
}
|
||||
|
||||
return html;
|
||||
}
|
||||
|
||||
async _loadFile(filePath) {
|
||||
debug('docsify')(`load > ${filePath}`);
|
||||
let content;
|
||||
try {
|
||||
if (isAbsolutePath(filePath)) {
|
||||
const res = await fetch(filePath);
|
||||
if (!res.ok) {
|
||||
throw Error();
|
||||
}
|
||||
|
||||
content = await res.text();
|
||||
this.lock = 0;
|
||||
} else {
|
||||
content = await readFileSync(filePath, 'utf8');
|
||||
this.lock = 0;
|
||||
}
|
||||
|
||||
return content;
|
||||
} catch (e) {
|
||||
this.lock = this.lock || 0;
|
||||
if (++this.lock > 10) {
|
||||
this.lock = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
const fileName = basename(filePath);
|
||||
const result = await this._loadFile(
|
||||
resolvePathname(`../${fileName}`, filePath)
|
||||
);
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Renderer.version = '__VERSION__';
|
||||
266
packages/docsify-server-renderer/package-lock.json
generated
266
packages/docsify-server-renderer/package-lock.json
generated
@ -1,266 +0,0 @@
|
||||
{
|
||||
"name": "docsify-server-renderer",
|
||||
"version": "4.13.0",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "docsify-server-renderer",
|
||||
"version": "4.13.0",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"debug": "^4.3.4",
|
||||
"docsify": "^4.13.0",
|
||||
"node-fetch": "^2.6.9",
|
||||
"resolve-pathname": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/debug": {
|
||||
"version": "4.3.4",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
|
||||
"integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
|
||||
"dependencies": {
|
||||
"ms": "2.1.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"supports-color": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/docsify": {
|
||||
"version": "4.13.0",
|
||||
"resolved": "https://registry.npmjs.org/docsify/-/docsify-4.13.0.tgz",
|
||||
"integrity": "sha512-dM2D0LZKrhK9e5cPwzOTO8FJ2l9IxgiSmTgLBIMjkBlTs1rAUT5camzekbk2AhH0Tw+5lzkNrSb7dmKFuTiLCA==",
|
||||
"hasInstallScript": true,
|
||||
"dependencies": {
|
||||
"marked": "^1.2.9",
|
||||
"medium-zoom": "^1.0.6",
|
||||
"opencollective-postinstall": "^2.0.2",
|
||||
"prismjs": "^1.27.0",
|
||||
"strip-indent": "^3.0.0",
|
||||
"tinydate": "^1.3.0",
|
||||
"tweezer.js": "^1.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/marked": {
|
||||
"version": "1.2.9",
|
||||
"resolved": "https://registry.npmjs.org/marked/-/marked-1.2.9.tgz",
|
||||
"integrity": "sha512-H8lIX2SvyitGX+TRdtS06m1jHMijKN/XjfH6Ooii9fvxMlh8QdqBfBDkGUpMWH2kQNrtixjzYUa3SH8ROTgRRw==",
|
||||
"bin": {
|
||||
"marked": "bin/marked"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 8.16.2"
|
||||
}
|
||||
},
|
||||
"node_modules/medium-zoom": {
|
||||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/medium-zoom/-/medium-zoom-1.0.6.tgz",
|
||||
"integrity": "sha512-UdiUWfvz9fZMg1pzf4dcuqA0W079o0mpqbTnOz5ip4VGYX96QjmbM+OgOU/0uOzAytxC0Ny4z+VcYQnhdifimg=="
|
||||
},
|
||||
"node_modules/min-indent": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz",
|
||||
"integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==",
|
||||
"engines": {
|
||||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/ms": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
||||
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
|
||||
},
|
||||
"node_modules/node-fetch": {
|
||||
"version": "2.6.9",
|
||||
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.9.tgz",
|
||||
"integrity": "sha512-DJm/CJkZkRjKKj4Zi4BsKVZh3ValV5IR5s7LVZnW+6YMh0W1BfNA8XSs6DLMGYlId5F3KnA70uu2qepcR08Qqg==",
|
||||
"dependencies": {
|
||||
"whatwg-url": "^5.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "4.x || >=6.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"encoding": "^0.1.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"encoding": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/opencollective-postinstall": {
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/opencollective-postinstall/-/opencollective-postinstall-2.0.3.tgz",
|
||||
"integrity": "sha512-8AV/sCtuzUeTo8gQK5qDZzARrulB3egtLzFgteqB2tcT4Mw7B8Kt7JcDHmltjz6FOAHsvTevk70gZEbhM4ZS9Q==",
|
||||
"bin": {
|
||||
"opencollective-postinstall": "index.js"
|
||||
}
|
||||
},
|
||||
"node_modules/prismjs": {
|
||||
"version": "1.27.0",
|
||||
"resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.27.0.tgz",
|
||||
"integrity": "sha512-t13BGPUlFDR7wRB5kQDG4jjl7XeuH6jbJGt11JHPL96qwsEHNX2+68tFXqc1/k+/jALsbSWJKUOT/hcYAZ5LkA==",
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/resolve-pathname": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/resolve-pathname/-/resolve-pathname-3.0.0.tgz",
|
||||
"integrity": "sha512-C7rARubxI8bXFNB/hqcp/4iUeIXJhJZvFPFPiSPRnhU5UPxzMFIl+2E6yY6c4k9giDJAhtV+enfA+G89N6Csng=="
|
||||
},
|
||||
"node_modules/strip-indent": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz",
|
||||
"integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==",
|
||||
"dependencies": {
|
||||
"min-indent": "^1.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/tinydate": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/tinydate/-/tinydate-1.3.0.tgz",
|
||||
"integrity": "sha512-7cR8rLy2QhYHpsBDBVYnnWXm8uRTr38RoZakFSW7Bs7PzfMPNZthuMLkwqZv7MTu8lhQ91cOFYS5a7iFj2oR3w==",
|
||||
"engines": {
|
||||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/tr46": {
|
||||
"version": "0.0.3",
|
||||
"resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
|
||||
"integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o="
|
||||
},
|
||||
"node_modules/tweezer.js": {
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/tweezer.js/-/tweezer.js-1.5.0.tgz",
|
||||
"integrity": "sha512-aSiJz7rGWNAQq7hjMK9ZYDuEawXupcCWgl3woQQSoDP2Oh8O4srWb/uO1PzzHIsrPEOqrjJ2sUb9FERfzuBabQ=="
|
||||
},
|
||||
"node_modules/webidl-conversions": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
|
||||
"integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE="
|
||||
},
|
||||
"node_modules/whatwg-url": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
|
||||
"integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=",
|
||||
"dependencies": {
|
||||
"tr46": "~0.0.3",
|
||||
"webidl-conversions": "^3.0.0"
|
||||
}
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"debug": {
|
||||
"version": "4.3.4",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
|
||||
"integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
|
||||
"requires": {
|
||||
"ms": "2.1.2"
|
||||
}
|
||||
},
|
||||
"docsify": {
|
||||
"version": "4.13.0",
|
||||
"resolved": "https://registry.npmjs.org/docsify/-/docsify-4.13.0.tgz",
|
||||
"integrity": "sha512-dM2D0LZKrhK9e5cPwzOTO8FJ2l9IxgiSmTgLBIMjkBlTs1rAUT5camzekbk2AhH0Tw+5lzkNrSb7dmKFuTiLCA==",
|
||||
"requires": {
|
||||
"marked": "^1.2.9",
|
||||
"medium-zoom": "^1.0.6",
|
||||
"opencollective-postinstall": "^2.0.2",
|
||||
"prismjs": "^1.27.0",
|
||||
"strip-indent": "^3.0.0",
|
||||
"tinydate": "^1.3.0",
|
||||
"tweezer.js": "^1.4.0"
|
||||
}
|
||||
},
|
||||
"marked": {
|
||||
"version": "1.2.9",
|
||||
"resolved": "https://registry.npmjs.org/marked/-/marked-1.2.9.tgz",
|
||||
"integrity": "sha512-H8lIX2SvyitGX+TRdtS06m1jHMijKN/XjfH6Ooii9fvxMlh8QdqBfBDkGUpMWH2kQNrtixjzYUa3SH8ROTgRRw=="
|
||||
},
|
||||
"medium-zoom": {
|
||||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/medium-zoom/-/medium-zoom-1.0.6.tgz",
|
||||
"integrity": "sha512-UdiUWfvz9fZMg1pzf4dcuqA0W079o0mpqbTnOz5ip4VGYX96QjmbM+OgOU/0uOzAytxC0Ny4z+VcYQnhdifimg=="
|
||||
},
|
||||
"min-indent": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz",
|
||||
"integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg=="
|
||||
},
|
||||
"ms": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
||||
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
|
||||
},
|
||||
"node-fetch": {
|
||||
"version": "2.6.9",
|
||||
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.9.tgz",
|
||||
"integrity": "sha512-DJm/CJkZkRjKKj4Zi4BsKVZh3ValV5IR5s7LVZnW+6YMh0W1BfNA8XSs6DLMGYlId5F3KnA70uu2qepcR08Qqg==",
|
||||
"requires": {
|
||||
"whatwg-url": "^5.0.0"
|
||||
}
|
||||
},
|
||||
"opencollective-postinstall": {
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/opencollective-postinstall/-/opencollective-postinstall-2.0.3.tgz",
|
||||
"integrity": "sha512-8AV/sCtuzUeTo8gQK5qDZzARrulB3egtLzFgteqB2tcT4Mw7B8Kt7JcDHmltjz6FOAHsvTevk70gZEbhM4ZS9Q=="
|
||||
},
|
||||
"prismjs": {
|
||||
"version": "1.27.0",
|
||||
"resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.27.0.tgz",
|
||||
"integrity": "sha512-t13BGPUlFDR7wRB5kQDG4jjl7XeuH6jbJGt11JHPL96qwsEHNX2+68tFXqc1/k+/jALsbSWJKUOT/hcYAZ5LkA=="
|
||||
},
|
||||
"resolve-pathname": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/resolve-pathname/-/resolve-pathname-3.0.0.tgz",
|
||||
"integrity": "sha512-C7rARubxI8bXFNB/hqcp/4iUeIXJhJZvFPFPiSPRnhU5UPxzMFIl+2E6yY6c4k9giDJAhtV+enfA+G89N6Csng=="
|
||||
},
|
||||
"strip-indent": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz",
|
||||
"integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==",
|
||||
"requires": {
|
||||
"min-indent": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"tinydate": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/tinydate/-/tinydate-1.3.0.tgz",
|
||||
"integrity": "sha512-7cR8rLy2QhYHpsBDBVYnnWXm8uRTr38RoZakFSW7Bs7PzfMPNZthuMLkwqZv7MTu8lhQ91cOFYS5a7iFj2oR3w=="
|
||||
},
|
||||
"tr46": {
|
||||
"version": "0.0.3",
|
||||
"resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
|
||||
"integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o="
|
||||
},
|
||||
"tweezer.js": {
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/tweezer.js/-/tweezer.js-1.5.0.tgz",
|
||||
"integrity": "sha512-aSiJz7rGWNAQq7hjMK9ZYDuEawXupcCWgl3woQQSoDP2Oh8O4srWb/uO1PzzHIsrPEOqrjJ2sUb9FERfzuBabQ=="
|
||||
},
|
||||
"webidl-conversions": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
|
||||
"integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE="
|
||||
},
|
||||
"whatwg-url": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
|
||||
"integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=",
|
||||
"requires": {
|
||||
"tr46": "~0.0.3",
|
||||
"webidl-conversions": "^3.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,23 +0,0 @@
|
||||
{
|
||||
"name": "docsify-server-renderer",
|
||||
"version": "4.13.0",
|
||||
"description": "docsify server renderer",
|
||||
"author": {
|
||||
"name": "qingwei-li",
|
||||
"email": "cinwell.li@gmail.com",
|
||||
"url": "https://github.com/QingWei-Li"
|
||||
},
|
||||
"homepage": "https://docsify.js.org",
|
||||
"license": "MIT",
|
||||
"repository": "docsifyjs/docsify",
|
||||
"main": "build.js",
|
||||
"scripts": {
|
||||
"test": "echo 'hello'"
|
||||
},
|
||||
"dependencies": {
|
||||
"debug": "^4.3.4",
|
||||
"docsify": "^4.13.0",
|
||||
"node-fetch": "^2.6.9",
|
||||
"resolve-pathname": "^3.0.0"
|
||||
}
|
||||
}
|
||||
@ -1,4 +1,4 @@
|
||||
const { devices } = require('@playwright/test');
|
||||
import { devices } from '@playwright/test';
|
||||
|
||||
/**
|
||||
* @see https://playwright.dev/docs/test-configuration
|
||||
@ -61,4 +61,4 @@ const config = {
|
||||
],
|
||||
};
|
||||
|
||||
module.exports = config;
|
||||
export default config;
|
||||
|
||||
@ -1,4 +0,0 @@
|
||||
{
|
||||
"template": "node",
|
||||
"node": "16"
|
||||
}
|
||||
55
server.js
55
server.js
@ -1,55 +1,10 @@
|
||||
const liveServer = require('live-server')
|
||||
const isSSR = !!process.env.SSR
|
||||
const middleware = []
|
||||
|
||||
if (isSSR) {
|
||||
const Renderer = require('./packages/docsify-server-renderer/build.js')
|
||||
const renderer = new Renderer({
|
||||
template: `
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>docsify</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0">
|
||||
<link rel="stylesheet" href="/themes/vue.css" title="vue">
|
||||
</head>
|
||||
<body>
|
||||
<!--inject-app-->
|
||||
<!--inject-config-->
|
||||
<script src="/lib/docsify.js"></script>
|
||||
</body>
|
||||
</html>`,
|
||||
config: {
|
||||
name: 'docsify',
|
||||
repo: 'docsifyjs/docsify',
|
||||
basePath: 'https://docsify.js.org/',
|
||||
loadNavbar: true,
|
||||
loadSidebar: true,
|
||||
subMaxLevel: 3,
|
||||
auto2top: true,
|
||||
alias: {
|
||||
'/de-de/changelog': '/changelog',
|
||||
'/zh-cn/changelog': '/changelog',
|
||||
'/changelog':
|
||||
'https://raw.githubusercontent.com/docsifyjs/docsify/master/CHANGELOG'
|
||||
}
|
||||
},
|
||||
path: './'
|
||||
})
|
||||
|
||||
middleware.push(function(req, res, next) {
|
||||
if (/\.(css|js)$/.test(req.url)) {
|
||||
return next()
|
||||
}
|
||||
renderer.renderToString(req.url).then(html => res.end(html))
|
||||
})
|
||||
}
|
||||
import liveServer from 'live-server';
|
||||
const middleware = [];
|
||||
|
||||
const params = {
|
||||
port: 3000,
|
||||
watch: ['lib', 'docs', 'themes'],
|
||||
middleware
|
||||
}
|
||||
middleware,
|
||||
};
|
||||
|
||||
liveServer.start(params)
|
||||
liveServer.start(params);
|
||||
|
||||
@ -6,8 +6,8 @@ import { VirtualRoutes } from './virtual-routes/index.js';
|
||||
import initGlobalAPI from './global-api.js';
|
||||
|
||||
import config from './config.js';
|
||||
import { isFn } from './util/core';
|
||||
import { Lifecycle } from './init/lifecycle';
|
||||
import { isFn } from './util/core.js';
|
||||
import { Lifecycle } from './init/lifecycle.js';
|
||||
|
||||
/** @typedef {new (...args: any[]) => any} Constructor */
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { merge, hyphenate, isPrimitive, hasOwn } from './util/core';
|
||||
import { merge, hyphenate, isPrimitive, hasOwn } from './util/core.js';
|
||||
|
||||
const currentScript = document.currentScript;
|
||||
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import { isMobile } from '../util/env';
|
||||
import { body, on } from '../util/dom';
|
||||
import * as sidebar from './sidebar';
|
||||
import { scrollIntoView, scroll2Top } from './scroll';
|
||||
import { isMobile } from '../util/env.js';
|
||||
import { body, on } from '../util/dom.js';
|
||||
import * as sidebar from './sidebar.js';
|
||||
import { scrollIntoView, scroll2Top } from './scroll.js';
|
||||
|
||||
/** @typedef {import('../Docsify').Constructor} Constructor */
|
||||
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
import Tweezer from 'tweezer.js';
|
||||
import { isMobile } from '../util/env';
|
||||
import * as dom from '../util/dom';
|
||||
import { removeParams } from '../router/util';
|
||||
import config from '../config';
|
||||
import { isMobile } from '../util/env.js';
|
||||
import * as dom from '../util/dom.js';
|
||||
import { removeParams } from '../router/util.js';
|
||||
import config from '../config.js';
|
||||
|
||||
const nav = {};
|
||||
let hoverOver = false;
|
||||
@ -147,7 +147,9 @@ export function scrollIntoView(path, id) {
|
||||
return;
|
||||
}
|
||||
const topMargin = config().topMargin;
|
||||
const section = dom.find('#' + id);
|
||||
// Use [id='1234'] instead of #id to handle special cases such as reserved characters and pure number id
|
||||
// https://stackoverflow.com/questions/37270787/uncaught-syntaxerror-failed-to-execute-queryselector-on-document
|
||||
const section = dom.find("[id='" + id + "']");
|
||||
section && scrollTo(section, topMargin);
|
||||
|
||||
const li = nav[getNavKey(path, id)];
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
/* eslint-disable no-unused-vars */
|
||||
import { isMobile } from '../util/env';
|
||||
import * as dom from '../util/dom';
|
||||
import { isMobile } from '../util/env.js';
|
||||
import * as dom from '../util/dom.js';
|
||||
|
||||
const title = dom.$.title;
|
||||
/**
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
/* eslint-disable no-unused-vars */
|
||||
import progressbar from '../render/progressbar';
|
||||
import { noop, hasOwn } from '../util/core';
|
||||
import progressbar from '../render/progressbar.js';
|
||||
import { noop, hasOwn } from '../util/core.js';
|
||||
|
||||
const cache = {};
|
||||
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
/* eslint-disable no-unused-vars */
|
||||
import { getParentPath, stringifyQuery } from '../router/util';
|
||||
import { noop, isExternal } from '../util/core';
|
||||
import { getAndActive } from '../event/sidebar';
|
||||
import { get } from './ajax';
|
||||
import { getParentPath, stringifyQuery } from '../router/util.js';
|
||||
import { noop, isExternal } from '../util/core.js';
|
||||
import { getAndActive } from '../event/sidebar.js';
|
||||
import { get } from './ajax.js';
|
||||
|
||||
function loadNested(path, qs, file, next, vm, first) {
|
||||
path = first ? path : path.replace(/\/$/, '');
|
||||
|
||||
@ -1,10 +1,10 @@
|
||||
import prism from 'prismjs';
|
||||
import marked from 'marked';
|
||||
import * as util from './util';
|
||||
import * as dom from './util/dom';
|
||||
import { Compiler } from './render/compiler';
|
||||
import { slugify } from './render/slugify';
|
||||
import { get } from './fetch/ajax';
|
||||
import { marked } from 'marked';
|
||||
import * as util from './util/index.js';
|
||||
import * as dom from './util/dom.js';
|
||||
import { Compiler } from './render/compiler.js';
|
||||
import { slugify } from './render/slugify.js';
|
||||
import { get } from './fetch/ajax.js';
|
||||
|
||||
// TODO This is deprecated, kept for backwards compatibility. Remove in next
|
||||
// major release. We'll tell people to get everything from the DOCSIFY global
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { documentReady } from './util/dom';
|
||||
import { Docsify } from './Docsify';
|
||||
import { documentReady } from './util/dom.js';
|
||||
import { Docsify } from './Docsify.js';
|
||||
|
||||
/**
|
||||
* Run Docsify
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { noop } from '../util/core';
|
||||
import { noop } from '../util/core.js';
|
||||
|
||||
/** @typedef {import('../Docsify').Constructor} Constructor */
|
||||
|
||||
|
||||
@ -1,21 +1,21 @@
|
||||
import marked from 'marked';
|
||||
import { isAbsolutePath, getPath, getParentPath } from '../router/util';
|
||||
import { isFn, merge, cached, isPrimitive } from '../util/core';
|
||||
import { tree as treeTpl } from './tpl';
|
||||
import { genTree } from './gen-tree';
|
||||
import { slugify } from './slugify';
|
||||
import { emojify } from './emojify';
|
||||
import { marked } from 'marked';
|
||||
import { isAbsolutePath, getPath, getParentPath } from '../router/util.js';
|
||||
import { isFn, merge, cached, isPrimitive } from '../util/core.js';
|
||||
import { tree as treeTpl } from './tpl.js';
|
||||
import { genTree } from './gen-tree.js';
|
||||
import { slugify } from './slugify.js';
|
||||
import { emojify } from './emojify.js';
|
||||
import {
|
||||
getAndRemoveConfig,
|
||||
removeAtag,
|
||||
getAndRemoveDocisfyIgnorConfig,
|
||||
} from './utils';
|
||||
import { imageCompiler } from './compiler/image';
|
||||
import { highlightCodeCompiler } from './compiler/code';
|
||||
import { paragraphCompiler } from './compiler/paragraph';
|
||||
import { taskListCompiler } from './compiler/taskList';
|
||||
import { taskListItemCompiler } from './compiler/taskListItem';
|
||||
import { linkCompiler } from './compiler/link';
|
||||
} from './utils.js';
|
||||
import { imageCompiler } from './compiler/image.js';
|
||||
import { highlightCodeCompiler } from './compiler/code.js';
|
||||
import { paragraphCompiler } from './compiler/paragraph.js';
|
||||
import { taskListCompiler } from './compiler/taskList.js';
|
||||
import { taskListItemCompiler } from './compiler/taskListItem.js';
|
||||
import { linkCompiler } from './compiler/link.js';
|
||||
|
||||
const cachedLinks = {};
|
||||
|
||||
@ -149,7 +149,7 @@ export class Compiler {
|
||||
if (config.include) {
|
||||
if (!isAbsolutePath(href)) {
|
||||
href = getPath(
|
||||
process.env.SSR ? '' : this.contentBase,
|
||||
this.contentBase,
|
||||
getParentPath(this.router.getCurrentPath()),
|
||||
href
|
||||
);
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import Prism from 'prismjs';
|
||||
// See https://github.com/PrismJS/prism/pull/1367
|
||||
import 'prismjs/components/prism-markup-templating';
|
||||
import 'prismjs/components/prism-markup-templating.js';
|
||||
|
||||
export const highlightCodeCompiler = ({ renderer }) =>
|
||||
(renderer.code = function (code, lang = 'markup') {
|
||||
|
||||
@ -2,8 +2,8 @@ import {
|
||||
getAndRemoveConfig,
|
||||
removeAtag,
|
||||
getAndRemoveDocisfyIgnorConfig,
|
||||
} from '../utils';
|
||||
import { slugify } from './slugify';
|
||||
} from '../utils.js';
|
||||
import { slugify } from './slugify.js';
|
||||
|
||||
export const headingCompiler = ({ renderer, router, _self }) =>
|
||||
(renderer.code = (text, level) => {
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { getAndRemoveConfig } from '../utils';
|
||||
import { isAbsolutePath, getPath, getParentPath } from '../../router/util';
|
||||
import { getAndRemoveConfig } from '../utils.js';
|
||||
import { isAbsolutePath, getPath, getParentPath } from '../../router/util.js';
|
||||
|
||||
export const imageCompiler = ({ renderer, contentBase, router }) =>
|
||||
(renderer.image = (href, title, text) => {
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { getAndRemoveConfig } from '../utils';
|
||||
import { isAbsolutePath } from '../../router/util';
|
||||
import { getAndRemoveConfig } from '../utils.js';
|
||||
import { isAbsolutePath } from '../../router/util.js';
|
||||
|
||||
export const linkCompiler = ({
|
||||
renderer,
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { helper as helperTpl } from '../tpl';
|
||||
import { helper as helperTpl } from '../tpl.js';
|
||||
|
||||
export const paragraphCompiler = ({ renderer }) =>
|
||||
(renderer.paragraph = text => {
|
||||
|
||||
@ -1,13 +1,13 @@
|
||||
import stripIndent from 'strip-indent';
|
||||
import { get } from '../fetch/ajax';
|
||||
import { merge } from '../util/core';
|
||||
import { get } from '../fetch/ajax.js';
|
||||
import { merge } from '../util/core.js';
|
||||
|
||||
const cached = {};
|
||||
|
||||
function walkFetchEmbed({ embedTokens, compile, fetch }, cb) {
|
||||
let token;
|
||||
let step = 0;
|
||||
let count = 1;
|
||||
let count = 0;
|
||||
|
||||
if (!embedTokens.length) {
|
||||
return cb({});
|
||||
@ -73,18 +73,14 @@ function walkFetchEmbed({ embedTokens, compile, fetch }, cb) {
|
||||
}
|
||||
|
||||
cb({ token, embedToken });
|
||||
if (++count >= step) {
|
||||
if (++count >= embedTokens.length) {
|
||||
cb({});
|
||||
}
|
||||
};
|
||||
})(token);
|
||||
|
||||
if (token.embed.url) {
|
||||
if (process.env.SSR) {
|
||||
fetch(token.embed.url).then(next);
|
||||
} else {
|
||||
get(token.embed.url).then(next);
|
||||
}
|
||||
get(token.embed.url).then(next);
|
||||
} else {
|
||||
next(token.embed.html);
|
||||
}
|
||||
|
||||
@ -21,6 +21,7 @@ export default {
|
||||
"abc": "unicode/1f524.png?v8",
|
||||
"abcd": "unicode/1f521.png?v8",
|
||||
"accept": "unicode/1f251.png?v8",
|
||||
"accessibility": "accessibility.png?v8",
|
||||
"accordion": "unicode/1fa97.png?v8",
|
||||
"adhesive_bandage": "unicode/1fa79.png?v8",
|
||||
"adult": "unicode/1f9d1.png?v8",
|
||||
@ -464,6 +465,7 @@ export default {
|
||||
"deer": "unicode/1f98c.png?v8",
|
||||
"denmark": "unicode/1f1e9-1f1f0.png?v8",
|
||||
"department_store": "unicode/1f3ec.png?v8",
|
||||
"dependabot": "dependabot.png?v8",
|
||||
"derelict_house": "unicode/1f3da.png?v8",
|
||||
"desert": "unicode/1f3dc.png?v8",
|
||||
"desert_island": "unicode/1f3dd.png?v8",
|
||||
@ -623,6 +625,7 @@ export default {
|
||||
"fish": "unicode/1f41f.png?v8",
|
||||
"fish_cake": "unicode/1f365.png?v8",
|
||||
"fishing_pole_and_fish": "unicode/1f3a3.png?v8",
|
||||
"fishsticks": "fishsticks.png?v8",
|
||||
"fist": "unicode/270a.png?v8",
|
||||
"fist_left": "unicode/1f91b.png?v8",
|
||||
"fist_oncoming": "unicode/1f44a.png?v8",
|
||||
|
||||
@ -1,15 +1,15 @@
|
||||
/* eslint-disable no-unused-vars */
|
||||
import tinydate from 'tinydate';
|
||||
import * as dom from '../util/dom';
|
||||
import cssVars from '../util/polyfill/css-vars';
|
||||
import { getAndActive, sticky } from '../event/sidebar';
|
||||
import { getPath, isAbsolutePath } from '../router/util';
|
||||
import { isMobile, inBrowser } from '../util/env';
|
||||
import { isPrimitive, merge } from '../util/core';
|
||||
import { scrollActiveSidebar } from '../event/scroll';
|
||||
import { Compiler } from './compiler';
|
||||
import * as tpl from './tpl';
|
||||
import { prerenderEmbed } from './embed';
|
||||
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 { scrollActiveSidebar } from '../event/scroll.js';
|
||||
import { Compiler } from './compiler.js';
|
||||
import * as tpl from './tpl.js';
|
||||
import { prerenderEmbed } from './embed.js';
|
||||
|
||||
let vueGlobalData;
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import * as dom from '../util/dom';
|
||||
import * as dom from '../util/dom.js';
|
||||
|
||||
let barEl;
|
||||
let timeId;
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { hasOwn } from '../util/core';
|
||||
import { hasOwn } from '../util/core.js';
|
||||
|
||||
let cache = {};
|
||||
const re = /[\u2000-\u206F\u2E00-\u2E7F\\'!"#$%&()*+,./:;<=>?@[\]^`{|}~]/g;
|
||||
|
||||
@ -1,25 +0,0 @@
|
||||
import { parseQuery } from '../util';
|
||||
import { History } from './base';
|
||||
|
||||
export class AbstractHistory extends History {
|
||||
constructor(config) {
|
||||
super(config);
|
||||
this.mode = 'abstract';
|
||||
}
|
||||
|
||||
parse(path) {
|
||||
let query = '';
|
||||
|
||||
const queryIndex = path.indexOf('?');
|
||||
if (queryIndex >= 0) {
|
||||
query = path.slice(queryIndex + 1);
|
||||
path = path.slice(0, queryIndex);
|
||||
}
|
||||
|
||||
return {
|
||||
path,
|
||||
file: this.getFile(path),
|
||||
query: parseQuery(query),
|
||||
};
|
||||
}
|
||||
}
|
||||
@ -5,8 +5,8 @@ import {
|
||||
cleanPath,
|
||||
replaceSlug,
|
||||
resolvePath,
|
||||
} from '../util';
|
||||
import { noop, merge } from '../../util/core';
|
||||
} from '../util.js';
|
||||
import { noop, merge } from '../../util/core.js';
|
||||
|
||||
const cached = {};
|
||||
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
import { isExternal, noop } from '../../util/core';
|
||||
import { on } from '../../util/dom';
|
||||
import { endsWith } from '../../util/str';
|
||||
import { parseQuery, cleanPath, replaceSlug } from '../util';
|
||||
import { History } from './base';
|
||||
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';
|
||||
|
||||
function replaceHash(path) {
|
||||
const i = location.href.indexOf('#');
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import { isExternal, noop } from '../../util/core';
|
||||
import { on } from '../../util/dom';
|
||||
import { parseQuery, getPath } from '../util';
|
||||
import { History } from './base';
|
||||
import { isExternal, noop } from '../../util/core.js';
|
||||
import { on } from '../../util/dom.js';
|
||||
import { parseQuery, getPath } from '../util.js';
|
||||
import { History } from './base.js';
|
||||
|
||||
export class HTML5History extends History {
|
||||
constructor(config) {
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
import { supportsPushState } from '../util/env';
|
||||
import * as dom from '../util/dom';
|
||||
import { noop } from '../util/core';
|
||||
import { HashHistory } from './history/hash';
|
||||
import { HTML5History } from './history/html5';
|
||||
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';
|
||||
import { HTML5History } from './history/html5.js';
|
||||
|
||||
/**
|
||||
* @typedef {{
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { cached } from '../util/core';
|
||||
import { cached } from '../util/core.js';
|
||||
|
||||
const decode = decodeURIComponent;
|
||||
const encode = encodeURIComponent;
|
||||
|
||||
@ -96,5 +96,8 @@ export function isExternal(url) {
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
if (/^\/\\/.test(url)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { isFn } from '../util/core';
|
||||
import { inBrowser } from './env';
|
||||
import { isFn } from '../util/core.js';
|
||||
import { inBrowser } from './env.js';
|
||||
|
||||
const cacheNode = {};
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
export const inBrowser = !process.env.SSR;
|
||||
export const inBrowser = true; // True for now, may change when we add SSR.
|
||||
|
||||
export const isMobile = inBrowser && document.body.clientWidth <= 600;
|
||||
|
||||
|
||||
@ -1,3 +1,3 @@
|
||||
export * from './core';
|
||||
export * from './env';
|
||||
export * from '../router/util';
|
||||
export * from './core.js';
|
||||
export * from './env.js';
|
||||
export * from '../router/util.js';
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import * as dom from '../dom';
|
||||
import { get } from '../../fetch/ajax';
|
||||
import * as dom from '../dom.js';
|
||||
import { get } from '../../fetch/ajax.js';
|
||||
|
||||
function replaceVar(block, color) {
|
||||
block.innerHTML = block.innerHTML.replace(
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { startsWith, endsWith } from '../util/str';
|
||||
import { startsWith, endsWith } from '../util/str.js';
|
||||
|
||||
/**
|
||||
* Adds beginning of input (^) and end of input ($) assertions if needed into a regex string
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { makeExactMatcher } from './exact-match';
|
||||
import { createNextFunction } from './next';
|
||||
import { makeExactMatcher } from './exact-match.js';
|
||||
import { createNextFunction } from './next.js';
|
||||
|
||||
/** @typedef {import('../Docsify').Constructor} Constructor */
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import parser from './parser';
|
||||
import parser from './parser.js';
|
||||
|
||||
const install = function (hook, vm) {
|
||||
// Used to remove front matter from embedded pages if installed.
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
* Fork https://github.com/egoist/docute/blob/master/src/utils/front-matter.js
|
||||
*/
|
||||
/* eslint-disable */
|
||||
import parser from './yaml'
|
||||
import parser from './yaml.js'
|
||||
|
||||
var optionalByteOrderMark = '\\ufeff?'
|
||||
var pattern =
|
||||
|
||||
72
src/plugins/gtag.js
Normal file
72
src/plugins/gtag.js
Normal file
@ -0,0 +1,72 @@
|
||||
/* eslint-disable no-console */
|
||||
// From ./ga.js
|
||||
|
||||
function appendScript(id) {
|
||||
const script = document.createElement('script');
|
||||
script.async = true;
|
||||
script.src = 'https://www.googletagmanager.com/gtag/js?id=' + id;
|
||||
document.body.appendChild(script);
|
||||
}
|
||||
|
||||
// global site tag instance initialized
|
||||
function initGlobalSiteTag(id) {
|
||||
appendScript(id);
|
||||
|
||||
window.dataLayer = window.dataLayer || [];
|
||||
window.gtag =
|
||||
window.gtag ||
|
||||
function () {
|
||||
window.dataLayer.push(arguments);
|
||||
};
|
||||
|
||||
window.gtag('js', new Date());
|
||||
window.gtag('config', id);
|
||||
}
|
||||
|
||||
// add additional products to your tag
|
||||
// https://developers.google.com/tag-platform/gtagjs/install
|
||||
function initAdditionalTag(id) {
|
||||
window.gtag('config', id);
|
||||
}
|
||||
|
||||
function init(ids) {
|
||||
if (Array.isArray(ids)) {
|
||||
// set the first id to be a global site tag
|
||||
initGlobalSiteTag(ids[0]);
|
||||
|
||||
// the rest ids
|
||||
ids.forEach((id, index) => {
|
||||
if (index > 0) {
|
||||
initAdditionalTag(id);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
initGlobalSiteTag(ids);
|
||||
}
|
||||
}
|
||||
|
||||
function collect() {
|
||||
if (!window.gtag) {
|
||||
init($docsify.gtag);
|
||||
}
|
||||
|
||||
// usage: https://developers.google.com/analytics/devguides/collection/gtagjs/pages
|
||||
window.gtag('event', 'page_view', {
|
||||
/* eslint-disable camelcase */
|
||||
page_title: document.title,
|
||||
page_location: location.href,
|
||||
page_path: location.pathname,
|
||||
/* eslint-disable camelcase */
|
||||
});
|
||||
}
|
||||
|
||||
const install = function (hook) {
|
||||
if (!$docsify.gtag) {
|
||||
console.error('[Docsify] gtag is required.');
|
||||
return;
|
||||
}
|
||||
|
||||
hook.beforeEach(collect);
|
||||
};
|
||||
|
||||
$docsify.plugins = [].concat(install, $docsify.plugins);
|
||||
@ -1,5 +1,5 @@
|
||||
/* eslint-disable no-unused-vars */
|
||||
import { search } from './search';
|
||||
import { search } from './search.js';
|
||||
|
||||
let NO_DATA_TEXT = '';
|
||||
let options;
|
||||
|
||||
@ -1,6 +1,9 @@
|
||||
/* eslint-disable no-unused-vars */
|
||||
import { init as initComponent, update as updateComponent } from './component';
|
||||
import { init as initSearch } from './search';
|
||||
import {
|
||||
init as initComponent,
|
||||
update as updateComponent,
|
||||
} from './component.js';
|
||||
import { init as initSearch } from './search.js';
|
||||
|
||||
const CONFIG = {
|
||||
placeholder: 'Type to search',
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
/* eslint-disable no-unused-vars */
|
||||
import { getAndRemoveConfig } from '../../core/render/utils';
|
||||
import { removeDocsifyIgnoreTag } from '../../core/util/str';
|
||||
import { getAndRemoveConfig } from '../../core/render/utils.js';
|
||||
import { removeDocsifyIgnoreTag } from '../../core/util/str.js';
|
||||
|
||||
let INDEXS = {};
|
||||
|
||||
@ -57,11 +57,9 @@ function getAllPaths(router) {
|
||||
|
||||
function getTableData(token) {
|
||||
if (!token.text && token.type === 'table') {
|
||||
token.cells.unshift(token.header);
|
||||
token.text = token.cells
|
||||
.map(function (rows) {
|
||||
return rows.join(' | ');
|
||||
})
|
||||
token.rows.unshift(token.header);
|
||||
token.text = token.rows
|
||||
.map(columns => columns.map(r => r.text).join(' | '))
|
||||
.join(' |\n ');
|
||||
}
|
||||
return token.text;
|
||||
|
||||
@ -1,6 +1,8 @@
|
||||
/* global afterEach, beforeAll, beforeEach */
|
||||
|
||||
import mock from 'xhr-mock';
|
||||
import _mock from 'xhr-mock';
|
||||
|
||||
const mock = _mock.default;
|
||||
|
||||
const sideEffects = {
|
||||
document: {
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
const server = require('./server.js');
|
||||
import server from './server.js';
|
||||
|
||||
module.exports = async () => {
|
||||
export default async () => {
|
||||
await server.startAsync();
|
||||
};
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
const server = require('./server.js');
|
||||
import server from './server.js';
|
||||
|
||||
module.exports = async () => {
|
||||
export default async () => {
|
||||
server.stop();
|
||||
};
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
const server = require('./server.js');
|
||||
import server from './server.js';
|
||||
|
||||
module.exports = async config => {
|
||||
export default async config => {
|
||||
await server.startAsync();
|
||||
};
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
const server = require('./server.js');
|
||||
import server from './server.js';
|
||||
|
||||
module.exports = async config => {
|
||||
export default async config => {
|
||||
server.stop();
|
||||
};
|
||||
|
||||
@ -1,5 +1,8 @@
|
||||
const browserSync = require('browser-sync').create();
|
||||
const path = require('path');
|
||||
import { create } from 'browser-sync';
|
||||
import path from 'path';
|
||||
import url from 'url';
|
||||
|
||||
const browserSync = create();
|
||||
|
||||
const hasStartArg = process.argv.includes('--start');
|
||||
const serverConfig = {
|
||||
@ -7,6 +10,11 @@ const serverConfig = {
|
||||
port: hasStartArg ? 3002 : 3001,
|
||||
};
|
||||
|
||||
const __filename = url.fileURLToPath(import.meta.url);
|
||||
const __dirname = path.dirname(__filename);
|
||||
|
||||
export const TEST_HOST = `http://${serverConfig.hostname}:${serverConfig.port}`;
|
||||
|
||||
function startServer(options = {}, cb = Function.prototype) {
|
||||
const defaults = {
|
||||
...serverConfig,
|
||||
@ -73,7 +81,7 @@ function startServer(options = {}, cb = Function.prototype) {
|
||||
console.log('\n');
|
||||
|
||||
// Set TEST_HOST environment variable
|
||||
process.env.TEST_HOST = `http://${serverConfig.hostname}:${serverConfig.port}`;
|
||||
process.env.TEST_HOST = TEST_HOST;
|
||||
|
||||
// Start server
|
||||
browserSync.init(
|
||||
@ -111,13 +119,20 @@ if (hasStartArg) {
|
||||
});
|
||||
}
|
||||
// Display friendly message about manually starting a server instance
|
||||
else if (require.main === module) {
|
||||
else if (isMain(import.meta)) {
|
||||
console.info('Use --start argument to manually start server instance');
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
// Replacement for CommonJS `require.main === module`. https://2ality.com/2022/07/nodejs-esm-main.html
|
||||
function isMain(meta) {
|
||||
if (meta.url.startsWith('file:')) {
|
||||
if (process.argv[1] === __filename) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
export default {
|
||||
start: startServer,
|
||||
startAsync: startServerAsync,
|
||||
stop: stopServer,
|
||||
TEST_HOST: `http://${serverConfig.hostname}:${serverConfig.port}`,
|
||||
};
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
const docsifyInit = require('../helpers/docsify-init');
|
||||
const { test, expect } = require('./fixtures/docsify-init-fixture');
|
||||
import docsifyInit from '../helpers/docsify-init.js';
|
||||
import { test, expect } from './fixtures/docsify-init-fixture.js';
|
||||
|
||||
test.describe('Configuration options', () => {
|
||||
test('catchPluginErrors:true (handles uncaught errors)', async ({ page }) => {
|
||||
|
||||
@ -1,81 +1,7 @@
|
||||
// Modules, constants, and variables
|
||||
// -----------------------------------------------------------------------------
|
||||
const docsifyInit = require('../helpers/docsify-init');
|
||||
const { test, expect } = require('./fixtures/docsify-init-fixture');
|
||||
|
||||
// Suite
|
||||
// -----------------------------------------------------------------------------
|
||||
test.describe('Example Tests', () => {
|
||||
// Tests
|
||||
// ---------------------------------------------------------------------------
|
||||
test('dom manipulation', async ({ page }) => {
|
||||
const testText = 'This is a test';
|
||||
const testHTML = `<h1>Test</h1><p>${testText}</p>`;
|
||||
|
||||
// Inject HTML
|
||||
await page.setContent(testHTML);
|
||||
|
||||
// Get reference to page element
|
||||
const bodyElm = page.locator('body');
|
||||
const pElm = page.locator('body > p');
|
||||
|
||||
// Add class to element and test
|
||||
await bodyElm.evaluate(elm => elm.classList.add('foo'));
|
||||
|
||||
// Tests
|
||||
await expect(bodyElm).toHaveClass('foo');
|
||||
await expect(bodyElm).toContainText('Test');
|
||||
await expect(pElm).toHaveCount(1);
|
||||
await expect(pElm).toHaveText(testText);
|
||||
await expect(pElm).not.toHaveText('NOPE');
|
||||
});
|
||||
|
||||
test('javascript in browser context', async ({ page }) => {
|
||||
// Get native DOM values
|
||||
const clientDimensions = await page.evaluate(() => {
|
||||
return {
|
||||
width: document.documentElement.clientWidth,
|
||||
height: document.documentElement.clientHeight,
|
||||
};
|
||||
});
|
||||
|
||||
expect(clientDimensions).toHaveProperty('width');
|
||||
expect(typeof clientDimensions.width).toBe('number');
|
||||
expect(clientDimensions).toHaveProperty('height');
|
||||
expect(typeof clientDimensions.height).toBe('number');
|
||||
|
||||
// Get result of script executed in browser context
|
||||
const scriptResult = await page.evaluate(
|
||||
numbers => {
|
||||
const result = numbers.reduce(
|
||||
(accumulator, currentValue) => accumulator + currentValue
|
||||
);
|
||||
|
||||
return Promise.resolve(result);
|
||||
},
|
||||
[1, 2, 3]
|
||||
);
|
||||
|
||||
expect(scriptResult).toBe(6);
|
||||
|
||||
// Get result of local function executed in browser context
|
||||
function add(...addends) {
|
||||
return addends.reduce(
|
||||
(accumulator, currentValue) => accumulator + currentValue
|
||||
);
|
||||
}
|
||||
|
||||
const functionResult = await page.evaluate(`
|
||||
const add = ${add.toString()};
|
||||
|
||||
const result = add(1, 2, 3);
|
||||
|
||||
Promise.resolve(result);
|
||||
`);
|
||||
|
||||
expect(functionResult).toBe(6);
|
||||
});
|
||||
import docsifyInit from '../helpers/docsify-init.js';
|
||||
import { test, expect } from './fixtures/docsify-init-fixture.js';
|
||||
|
||||
test.describe('Creating a Docsify site (e2e tests in Playwright)', () => {
|
||||
test('manual docsify site using playwright methods', async ({ page }) => {
|
||||
// Add docsify target element
|
||||
await page.setContent('<div id="app"></div>');
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
const base = require('@playwright/test');
|
||||
import { test as _test, expect as _expect } from '@playwright/test';
|
||||
|
||||
exports.test = base.test.extend({
|
||||
export const test = _test.extend({
|
||||
page: async ({ page }, use) => {
|
||||
global.page = page;
|
||||
|
||||
@ -13,4 +13,5 @@ exports.test = base.test.extend({
|
||||
await use(page);
|
||||
},
|
||||
});
|
||||
exports.expect = base.expect;
|
||||
|
||||
export const expect = _expect;
|
||||
|
||||
90
test/e2e/gtag.test.js
Normal file
90
test/e2e/gtag.test.js
Normal file
@ -0,0 +1,90 @@
|
||||
import docsifyInit from '../helpers/docsify-init.js';
|
||||
import { test, expect } from './fixtures/docsify-init-fixture.js';
|
||||
|
||||
const gtagList = [
|
||||
'AW-YYYYYY', // Google Ads
|
||||
'DC-ZZZZZZ', // Floodlight
|
||||
'G-XXXXXX', // Google Analytics 4 (GA4)
|
||||
'UA-XXXXXX', // Google Universal Analytics (GA3)
|
||||
];
|
||||
|
||||
test.describe('Gtag Plugin Tests', () => {
|
||||
// page request listened, print collect url
|
||||
function pageRequestListened(page) {
|
||||
page.on('request', request => {
|
||||
if (request.url().indexOf('www.google-analytics.com') !== -1) {
|
||||
// console.log(request.url());
|
||||
}
|
||||
});
|
||||
|
||||
page.on('response', response => {
|
||||
const request = response.request();
|
||||
// googleads.g.doubleclick.net
|
||||
// www.google-analytics.com
|
||||
// www.googletagmanager.com
|
||||
const reg =
|
||||
/googleads\.g\.doubleclick\.net|www\.google-analytics\.com|www\.googletagmanager\.com/g;
|
||||
if (request.url().match(reg)) {
|
||||
// console.log(request.url(), response.status());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
test('single gtag', async ({ page }) => {
|
||||
pageRequestListened(page);
|
||||
|
||||
const docsifyInitConfig = {
|
||||
config: {
|
||||
gtag: gtagList[0],
|
||||
},
|
||||
scriptURLs: ['/lib/plugins/gtag.min.js'],
|
||||
styleURLs: ['/lib/themes/vue.css'],
|
||||
};
|
||||
|
||||
await docsifyInit({
|
||||
...docsifyInitConfig,
|
||||
});
|
||||
|
||||
const $docsify = await page.evaluate(() => window.$docsify);
|
||||
|
||||
// Verify config options
|
||||
expect(typeof $docsify).toEqual('object');
|
||||
|
||||
// console.log($docsify.gtag, $docsify.gtag === '');
|
||||
|
||||
// Tests
|
||||
expect($docsify.gtag).not.toEqual('');
|
||||
});
|
||||
|
||||
test('multi gtag', async ({ page }) => {
|
||||
pageRequestListened(page);
|
||||
|
||||
const docsifyInitConfig = {
|
||||
config: {
|
||||
gtag: gtagList,
|
||||
},
|
||||
scriptURLs: ['/lib/plugins/gtag.min.js'],
|
||||
styleURLs: ['/lib/themes/vue.css'],
|
||||
};
|
||||
|
||||
await docsifyInit({
|
||||
...docsifyInitConfig,
|
||||
});
|
||||
|
||||
const $docsify = await page.evaluate(() => window.$docsify);
|
||||
|
||||
// Verify config options
|
||||
expect(typeof $docsify).toEqual('object');
|
||||
|
||||
// console.log($docsify.gtag, $docsify.gtag === '');
|
||||
|
||||
// Tests
|
||||
expect($docsify.gtag).not.toEqual('');
|
||||
});
|
||||
|
||||
test('data-ga attribute', async ({ page }) => {
|
||||
pageRequestListened(page);
|
||||
|
||||
// TODO
|
||||
});
|
||||
});
|
||||
@ -1,5 +1,5 @@
|
||||
const docsifyInit = require('../helpers/docsify-init');
|
||||
const { test, expect } = require('./fixtures/docsify-init-fixture');
|
||||
import docsifyInit from '../helpers/docsify-init.js';
|
||||
import { test, expect } from './fixtures/docsify-init-fixture.js';
|
||||
|
||||
test.describe('Index file hosting', () => {
|
||||
const sharedOptions = {
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
const docsifyInit = require('../helpers/docsify-init');
|
||||
const { test, expect } = require('./fixtures/docsify-init-fixture');
|
||||
import docsifyInit from '../helpers/docsify-init.js';
|
||||
import { test, expect } from './fixtures/docsify-init-fixture.js';
|
||||
|
||||
test.describe('Plugins', () => {
|
||||
test('Hook order', async ({ page }) => {
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
const docsifyInit = require('../helpers/docsify-init');
|
||||
const { test, expect } = require('./fixtures/docsify-init-fixture');
|
||||
import docsifyInit from '../helpers/docsify-init.js';
|
||||
import { test, expect } from './fixtures/docsify-init-fixture.js';
|
||||
|
||||
test.describe('Search Plugin Tests', () => {
|
||||
test('search readme', async ({ page }) => {
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
const docsifyInit = require('../helpers/docsify-init');
|
||||
const { test, expect } = require('./fixtures/docsify-init-fixture');
|
||||
import docsifyInit from '../helpers/docsify-init.js';
|
||||
import { test, expect } from './fixtures/docsify-init-fixture.js';
|
||||
|
||||
test.describe('Security - Cross Site Scripting (XSS)', () => {
|
||||
const sharedOptions = {
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
const docsifyInit = require('../helpers/docsify-init');
|
||||
const { test, expect } = require('./fixtures/docsify-init-fixture');
|
||||
import docsifyInit from '../helpers/docsify-init.js';
|
||||
import { test, expect } from './fixtures/docsify-init-fixture.js';
|
||||
|
||||
// Suite
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
const docsifyInit = require('../helpers/docsify-init');
|
||||
const { test, expect } = require('./fixtures/docsify-init-fixture');
|
||||
import docsifyInit from '../helpers/docsify-init.js';
|
||||
import { test, expect } from './fixtures/docsify-init-fixture.js';
|
||||
|
||||
/**
|
||||
* Navigate to a specific route in the site
|
||||
@ -8,6 +8,8 @@ const { test, expect } = require('./fixtures/docsify-init-fixture');
|
||||
*/
|
||||
async function navigateToRoute(page, route) {
|
||||
await page.evaluate(r => (window.location.hash = r), route);
|
||||
// TODO: playwright eslint now recommends not using networkidle
|
||||
// eslint-disable-next-line
|
||||
await page.waitForLoadState('networkidle');
|
||||
}
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
const stripIndent = require('common-tags/lib/stripIndent');
|
||||
const docsifyInit = require('../helpers/docsify-init');
|
||||
const { test, expect } = require('./fixtures/docsify-init-fixture');
|
||||
import stripIndent from 'common-tags/lib/stripIndent/index.js';
|
||||
import docsifyInit from '../helpers/docsify-init.js';
|
||||
import { test, expect } from './fixtures/docsify-init-fixture.js';
|
||||
|
||||
const vueURLs = [
|
||||
'/node_modules/vue2/dist/vue.js',
|
||||
@ -179,6 +179,7 @@ test.describe('Vue.js Compatibility', () => {
|
||||
await expect(page.locator('#vuefor')).toHaveText('12345');
|
||||
await expect(page.locator('#vuecomponent')).toHaveText('0');
|
||||
await expect(page.locator('#vuecomponent')).toHaveText('0');
|
||||
// eslint-disable-next-line playwright/prefer-web-first-assertions
|
||||
expect(await page.locator('#vueglobaloptions p').innerText()).toBe('');
|
||||
await expect(page.locator('#vuemounts p')).toHaveText('vuemounts');
|
||||
await expect(page.locator('#vuescript p')).toHaveText('vuescript');
|
||||
|
||||
@ -1,12 +1,13 @@
|
||||
/* globals page */
|
||||
import _mock, { proxy } from 'xhr-mock';
|
||||
|
||||
const axios = require('axios');
|
||||
const mock = require('xhr-mock').default;
|
||||
const prettier = require('prettier');
|
||||
const stripIndent = require('common-tags/lib/stripIndent');
|
||||
const { proxy } = require('xhr-mock');
|
||||
const { waitForSelector } = require('./wait-for');
|
||||
import axios from 'axios';
|
||||
import prettier from 'prettier';
|
||||
import stripIndent from 'common-tags/lib/stripIndent/index.js';
|
||||
// import { TEST_HOST } from '../config/server.js';
|
||||
import { waitForSelector } from './wait-for.js';
|
||||
|
||||
const mock = _mock.default;
|
||||
const docsifyPATH = '../../lib/docsify.js'; // JSDOM
|
||||
const docsifyURL = '/lib/docsify.js'; // Playwright
|
||||
|
||||
@ -262,7 +263,7 @@ async function docsifyInit(options = {}) {
|
||||
const isDocsifyLoaded = 'Docsify' in window;
|
||||
|
||||
if (!isDocsifyLoaded) {
|
||||
require(docsifyPATH);
|
||||
await import(docsifyPATH);
|
||||
}
|
||||
} else if (isPlaywright) {
|
||||
for (const url of settings.scriptURLs) {
|
||||
@ -358,4 +359,4 @@ async function docsifyInit(options = {}) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
module.exports = docsifyInit;
|
||||
export default docsifyInit;
|
||||
|
||||
@ -125,8 +125,4 @@ function waitForText(cssSelector, text, options = {}) {
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
waitForFunction,
|
||||
waitForSelector,
|
||||
waitForText,
|
||||
};
|
||||
export { waitForFunction, waitForSelector, waitForText };
|
||||
|
||||
1
test/integration/.eslintrc.cjs
Normal file
1
test/integration/.eslintrc.cjs
Normal file
@ -0,0 +1 @@
|
||||
module.exports = require('../unit/.eslintrc.cjs');
|
||||
@ -1 +0,0 @@
|
||||
module.exports = require('../unit/.eslintrc');
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user