From 222617a820026c5644e6cd0d90ebc3b06d2edef4 Mon Sep 17 00:00:00 2001 From: anikethsaha Date: Thu, 20 Feb 2020 13:28:15 +0530 Subject: [PATCH 1/3] chore: added new linter config --- .eslintignore | 6 +- .eslintrc | 34 -- .eslintrc.js | 63 +++ .prettierrc.js | 4 + package-lock.json | 578 +++++++++++++++++++++- package.json | 5 +- packages/docsify-server-renderer/index.js | 164 +++--- src/core/config.js | 30 +- src/core/event/index.js | 24 +- src/core/event/scroll.js | 146 +++--- src/core/event/sidebar.js | 77 +-- src/core/fetch/ajax.js | 57 +-- src/core/fetch/index.js | 213 ++++---- src/core/global-api.js | 26 +- src/core/index.js | 37 +- src/core/init/index.js | 40 +- src/core/init/lifecycle.js | 42 +- src/core/render/compiler.js | 320 ++++++------ src/core/render/compiler/code.js | 18 +- src/core/render/compiler/headline.js | 44 +- src/core/render/compiler/image.js | 74 +-- src/core/render/compiler/link.js | 75 +-- src/core/render/compiler/paragraph.js | 26 +- src/core/render/compiler/taskList.js | 27 +- src/core/render/compiler/taskListItem.js | 13 +- src/core/render/embed.js | 112 +++-- src/core/render/emojify.js | 18 +- src/core/render/gen-tree.js | 20 +- src/core/render/index.js | 263 +++++----- src/core/render/progressbar.js | 39 +- src/core/render/slugify.js | 28 +- src/core/render/tpl.js | 50 +- src/core/router/history/abstract.js | 20 +- src/core/router/history/base.js | 76 +-- src/core/router/history/hash.js | 56 +-- src/core/router/history/html5.js | 52 +- src/core/router/index.js | 49 +- src/core/router/util.js | 72 +-- src/core/util/core.js | 35 +- src/core/util/dom.js | 48 +- src/core/util/env.js | 10 +- src/core/util/index.js | 6 +- src/core/util/polyfill/css-vars.js | 26 +- src/plugins/disqus.js | 59 +-- src/plugins/emoji.js | 16 +- src/plugins/external-script.js | 26 +- src/plugins/front-matter/index.js | 16 +- src/plugins/ga.js | 39 +- src/plugins/gitalk.js | 25 +- src/plugins/matomo.js | 45 +- src/plugins/search/component.js | 122 ++--- src/plugins/search/index.js | 50 +- src/plugins/search/search.js | 197 ++++---- src/plugins/zoom-image.js | 27 +- test/_helper.js | 100 ++-- test/integration/render.js | 14 +- test/integration/router.js | 14 +- test/unit/base.test.js | 69 +-- test/unit/render.test.js | 427 +++++++++------- test/unit/util.test.js | 37 +- 60 files changed, 2599 insertions(+), 1807 deletions(-) delete mode 100644 .eslintrc create mode 100644 .eslintrc.js create mode 100644 .prettierrc.js diff --git a/.eslintignore b/.eslintignore index 7c59bb6bd..b9a9017c5 100644 --- a/.eslintignore +++ b/.eslintignore @@ -4,4 +4,8 @@ node_modules build server.js cypress -lib \ No newline at end of file +lib +themes +build +docs/ +**/*.md \ No newline at end of file diff --git a/.eslintrc b/.eslintrc deleted file mode 100644 index 3d14bbc2f..000000000 --- a/.eslintrc +++ /dev/null @@ -1,34 +0,0 @@ -{ - "extends": "xo-space/browser", - "rules": { - "semi": [ - 2, - "never" - ], - "no-return-assign": "off", - "no-unused-expressions": "off", - "no-new-func": "off", - "no-multi-assign": "off", - "no-mixed-operators": "off", - "max-params": "off", - "no-script-url": "off", - "camelcase": "off", - "object-curly-spacing": "off", - "no-warning-comments": "off", - "no-negated-condition": "off", - "eqeqeq": "warn", - "no-eq-null": "warn", - "max-statements-per-line": "warn" - }, - "globals": { - "Docsify": true, - "$docsify": true, - "process": true - }, - "env": { - "browser": true, - "amd": true, - "node": true, - "jest": true - } -} \ No newline at end of file diff --git a/.eslintrc.js b/.eslintrc.js new file mode 100644 index 000000000..3ffb3deb9 --- /dev/null +++ b/.eslintrc.js @@ -0,0 +1,63 @@ +module.exports = { + root: true, + parser: 'babel-eslint', + parserOptions: { + sourceType: 'module', + ecmaVersion: 2019, + }, + env: { + jest: true, + browser: true, + node: true, + es6: true, + }, + plugins: ['prettier', 'import'], + extends: ['eslint:recommended', 'plugin:import/recommended'], + settings: { + 'import/ignore': ['node_modules', '.json$'], + }, + rules: { + 'prettier/prettier': ['error'], + camelcase: ['warn'], + curly: ['error', 'all'], + 'dot-notation': ['error'], + eqeqeq: ['error'], + 'handle-callback-err': ['error'], + 'new-cap': ['error'], + 'no-alert': ['error'], + 'no-caller': ['error'], + 'no-eval': ['error'], + 'no-labels': ['error'], + 'no-lonely-if': ['error'], + 'no-new': ['error'], + 'no-proto': ['error'], + 'no-return-assign': ['error'], + 'no-self-compare': ['error'], + 'no-shadow': ['warn'], + 'no-shadow-restricted-names': ['error'], + 'no-useless-call': ['error'], + 'no-var': ['error'], + 'no-void': ['error'], + 'no-with': ['error'], + radix: ['error'], + 'spaced-comment': ['error', 'always'], + strict: ['error', 'global'], + yoda: ['error', 'never'], + + // Import rules + // Search way how integrate with `lerna` + 'import/no-unresolved': 'off', + 'import/imports-first': ['error'], + 'import/newline-after-import': ['error'], + 'import/no-duplicates': ['error'], + 'import/no-mutable-exports': ['error'], + 'import/no-named-as-default': ['error'], + 'import/no-named-as-default-member': ['error'], + 'import/order': ['error'], + }, + globals: { + Docsify: 'writable', + $docsify: 'writable', + dom: 'writable', + }, +}; diff --git a/.prettierrc.js b/.prettierrc.js new file mode 100644 index 000000000..a425d3f76 --- /dev/null +++ b/.prettierrc.js @@ -0,0 +1,4 @@ +module.exports = { + singleQuote: true, + trailingComma: 'es5', +}; diff --git a/package-lock.json b/package-lock.json index 5d959ac2c..08fe99a9e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,6 +13,61 @@ "@babel/highlight": "^7.0.0" } }, + "@babel/generator": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.8.4.tgz", + "integrity": "sha512-PwhclGdRpNAf3IxZb0YVuITPZmmrXz9zf6fH8lT4XbrmfQKr6ryBzhv593P5C6poJRciFCL/eHGW2NuGrgEyxA==", + "dev": true, + "requires": { + "@babel/types": "^7.8.3", + "jsesc": "^2.5.1", + "lodash": "^4.17.13", + "source-map": "^0.5.0" + }, + "dependencies": { + "jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + } + } + }, + "@babel/helper-function-name": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.8.3.tgz", + "integrity": "sha512-BCxgX1BC2hD/oBlIFUgOCQDOPV8nSINxCwM3o93xP4P9Fq6aV5sgv2cOOITDMtCfQ+3PvHp3l689XZvAM9QyOA==", + "dev": true, + "requires": { + "@babel/helper-get-function-arity": "^7.8.3", + "@babel/template": "^7.8.3", + "@babel/types": "^7.8.3" + } + }, + "@babel/helper-get-function-arity": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.8.3.tgz", + "integrity": "sha512-FVDR+Gd9iLjUMY1fzE2SR0IuaJToR4RkCDARVfsBBPSP53GEqSFjD8gNyxg246VUyc/ALRxFaAK8rVG7UT7xRA==", + "dev": true, + "requires": { + "@babel/types": "^7.8.3" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.8.3.tgz", + "integrity": "sha512-3x3yOeyBhW851hroze7ElzdkeRXQYQbFIb7gLK1WQYsw2GWDay5gAJNw1sWJ0VFP6z5J1whqeXH/WCdCjZv6dA==", + "dev": true, + "requires": { + "@babel/types": "^7.8.3" + } + }, "@babel/highlight": { "version": "7.5.0", "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.5.0.tgz", @@ -24,6 +79,95 @@ "js-tokens": "^4.0.0" } }, + "@babel/parser": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.8.4.tgz", + "integrity": "sha512-0fKu/QqildpXmPVaRBoXOlyBb3MC+J0A66x97qEfLOMkn3u6nfY5esWogQwi/K0BjASYy4DbnsEWnpNL6qT5Mw==", + "dev": true + }, + "@babel/template": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.8.3.tgz", + "integrity": "sha512-04m87AcQgAFdvuoyiQ2kgELr2tV8B4fP/xJAVUL3Yb3bkNdMedD3d0rlSQr3PegP0cms3eHjl1F7PWlvWbU8FQ==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.8.3", + "@babel/parser": "^7.8.3", + "@babel/types": "^7.8.3" + }, + "dependencies": { + "@babel/code-frame": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.8.3.tgz", + "integrity": "sha512-a9gxpmdXtZEInkCSHUJDLHZVBgb1QS0jhss4cPP93EW7s+uC5bikET2twEF3KV+7rDblJcmNvTR7VJejqd2C2g==", + "dev": true, + "requires": { + "@babel/highlight": "^7.8.3" + } + }, + "@babel/highlight": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.8.3.tgz", + "integrity": "sha512-PX4y5xQUvy0fnEVHrYOarRPXVWafSjTW9T0Hab8gVIawpl2Sj0ORyrygANq+KjcNlSSTw0YCLSNA8OyZ1I4yEg==", + "dev": true, + "requires": { + "chalk": "^2.0.0", + "esutils": "^2.0.2", + "js-tokens": "^4.0.0" + } + } + } + }, + "@babel/traverse": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.8.4.tgz", + "integrity": "sha512-NGLJPZwnVEyBPLI+bl9y9aSnxMhsKz42so7ApAv9D+b4vAFPpY013FTS9LdKxcABoIYFU52HcYga1pPlx454mg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.8.3", + "@babel/generator": "^7.8.4", + "@babel/helper-function-name": "^7.8.3", + "@babel/helper-split-export-declaration": "^7.8.3", + "@babel/parser": "^7.8.4", + "@babel/types": "^7.8.3", + "debug": "^4.1.0", + "globals": "^11.1.0", + "lodash": "^4.17.13" + }, + "dependencies": { + "@babel/code-frame": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.8.3.tgz", + "integrity": "sha512-a9gxpmdXtZEInkCSHUJDLHZVBgb1QS0jhss4cPP93EW7s+uC5bikET2twEF3KV+7rDblJcmNvTR7VJejqd2C2g==", + "dev": true, + "requires": { + "@babel/highlight": "^7.8.3" + } + }, + "@babel/highlight": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.8.3.tgz", + "integrity": "sha512-PX4y5xQUvy0fnEVHrYOarRPXVWafSjTW9T0Hab8gVIawpl2Sj0ORyrygANq+KjcNlSSTw0YCLSNA8OyZ1I4yEg==", + "dev": true, + "requires": { + "chalk": "^2.0.0", + "esutils": "^2.0.2", + "js-tokens": "^4.0.0" + } + } + } + }, + "@babel/types": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.8.3.tgz", + "integrity": "sha512-jBD+G8+LWpMBBWvVcdr4QysjUE4mU/syrhN17o1u3gx0/WzJB1kwiVZAXRtWbsIPOwW8pF/YJV5+nmetPzepXg==", + "dev": true, + "requires": { + "esutils": "^2.0.2", + "lodash": "^4.17.13", + "to-fast-properties": "^2.0.0" + } + }, "@cypress/listr-verbose-renderer": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/@cypress/listr-verbose-renderer/-/listr-verbose-renderer-0.4.1.tgz", @@ -1888,6 +2032,96 @@ "integrity": "sha1-nlKHYrSpBmrRY6aWKjZEGOlibs4=", "dev": true }, + "array-includes": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.1.tgz", + "integrity": "sha512-c2VXaCHl7zPsvpkFsw4nxvFie4fh1ur9bpcgsVkIjqn0H/Xwdg+7fv3n2r/isyS8EBj5b06M9kHyZuIr4El6WQ==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0", + "is-string": "^1.0.5" + }, + "dependencies": { + "es-abstract": { + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.4.tgz", + "integrity": "sha512-Ae3um/gb8F0mui/jPL+QiqmglkUsaQf7FwBEHYIFkztkneosu9imhqHpBzQ3h1vit8t5iQ74t6PEVvphBZiuiQ==", + "dev": true, + "requires": { + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1", + "is-callable": "^1.1.5", + "is-regex": "^1.0.5", + "object-inspect": "^1.7.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.0", + "string.prototype.trimleft": "^2.1.1", + "string.prototype.trimright": "^2.1.1" + } + }, + "es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dev": true, + "requires": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + } + }, + "has-symbols": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", + "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", + "dev": true + }, + "is-callable": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.5.tgz", + "integrity": "sha512-ESKv5sMCJB2jnHTWZ3O5itG+O128Hsus4K4Qh1h2/cgn2vbgnLSVqfV46AeJA9D5EeeLa9w81KUXMtn34zhX+Q==", + "dev": true + }, + "is-regex": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.5.tgz", + "integrity": "sha512-vlKW17SNq44owv5AQR3Cq0bQPEb8+kF3UKZ2fiZNOWtztYE5i0CzCZxFDwO58qAOWtxdBRVO/V5Qin1wjCqFYQ==", + "dev": true, + "requires": { + "has": "^1.0.3" + } + }, + "object-inspect": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.7.0.tgz", + "integrity": "sha512-a7pEHdh1xKIAgTySUGgLMx/xwDZskN1Ud6egYYN3EdRW4ZMPNEDUTF+hwy2LUC+Bl+SyLXANnwz/jyh/qutKUw==", + "dev": true + }, + "string.prototype.trimleft": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string.prototype.trimleft/-/string.prototype.trimleft-2.1.1.tgz", + "integrity": "sha512-iu2AGd3PuP5Rp7x2kEZCrB2Nf41ehzh+goo8TV7z8/XDBbsvc6HQIlUl9RjkZ4oyrW1XM5UwlGl1oVEaDjg6Ag==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "function-bind": "^1.1.1" + } + }, + "string.prototype.trimright": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string.prototype.trimright/-/string.prototype.trimright-2.1.1.tgz", + "integrity": "sha512-qFvWL3/+QIgZXVmJBfpHmxLB7xsUXz6HsUmP8+5dRaC3Q7oKUv9Vo6aMCRZC1smrtyECFsIT30PqBJ1gTjAs+g==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "function-bind": "^1.1.1" + } + } + } + }, "array-union": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", @@ -1909,6 +2143,95 @@ "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", "dev": true }, + "array.prototype.flat": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.2.3.tgz", + "integrity": "sha512-gBlRZV0VSmfPIeWfuuy56XZMvbVfbEUnOXUvt3F/eUUUSyzlgLxhEX4YAEpxNAogRGehPSnfXyPtYyKAhkzQhQ==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0-next.1" + }, + "dependencies": { + "es-abstract": { + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.4.tgz", + "integrity": "sha512-Ae3um/gb8F0mui/jPL+QiqmglkUsaQf7FwBEHYIFkztkneosu9imhqHpBzQ3h1vit8t5iQ74t6PEVvphBZiuiQ==", + "dev": true, + "requires": { + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1", + "is-callable": "^1.1.5", + "is-regex": "^1.0.5", + "object-inspect": "^1.7.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.0", + "string.prototype.trimleft": "^2.1.1", + "string.prototype.trimright": "^2.1.1" + } + }, + "es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dev": true, + "requires": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + } + }, + "has-symbols": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", + "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", + "dev": true + }, + "is-callable": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.5.tgz", + "integrity": "sha512-ESKv5sMCJB2jnHTWZ3O5itG+O128Hsus4K4Qh1h2/cgn2vbgnLSVqfV46AeJA9D5EeeLa9w81KUXMtn34zhX+Q==", + "dev": true + }, + "is-regex": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.5.tgz", + "integrity": "sha512-vlKW17SNq44owv5AQR3Cq0bQPEb8+kF3UKZ2fiZNOWtztYE5i0CzCZxFDwO58qAOWtxdBRVO/V5Qin1wjCqFYQ==", + "dev": true, + "requires": { + "has": "^1.0.3" + } + }, + "object-inspect": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.7.0.tgz", + "integrity": "sha512-a7pEHdh1xKIAgTySUGgLMx/xwDZskN1Ud6egYYN3EdRW4ZMPNEDUTF+hwy2LUC+Bl+SyLXANnwz/jyh/qutKUw==", + "dev": true + }, + "string.prototype.trimleft": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string.prototype.trimleft/-/string.prototype.trimleft-2.1.1.tgz", + "integrity": "sha512-iu2AGd3PuP5Rp7x2kEZCrB2Nf41ehzh+goo8TV7z8/XDBbsvc6HQIlUl9RjkZ4oyrW1XM5UwlGl1oVEaDjg6Ag==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "function-bind": "^1.1.1" + } + }, + "string.prototype.trimright": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string.prototype.trimright/-/string.prototype.trimright-2.1.1.tgz", + "integrity": "sha512-qFvWL3/+QIgZXVmJBfpHmxLB7xsUXz6HsUmP8+5dRaC3Q7oKUv9Vo6aMCRZC1smrtyECFsIT30PqBJ1gTjAs+g==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "function-bind": "^1.1.1" + } + } + } + }, "arrify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", @@ -2042,6 +2365,20 @@ "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==", "dev": true }, + "babel-eslint": { + "version": "10.0.3", + "resolved": "https://registry.npmjs.org/babel-eslint/-/babel-eslint-10.0.3.tgz", + "integrity": "sha512-z3U7eMY6r/3f3/JB9mTsLjyxrv0Yb1zb8PCWCLpguxfCzBIZUwy23R1t/XKewP+8mEN2Ck8Dtr4q20z6ce6SoA==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "@babel/parser": "^7.0.0", + "@babel/traverse": "^7.0.0", + "@babel/types": "^7.0.0", + "eslint-visitor-keys": "^1.0.0", + "resolve": "^1.12.0" + } + }, "babylon": { "version": "6.18.0", "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz", @@ -2860,6 +3197,12 @@ "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=", "dev": true }, + "contains-path": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/contains-path/-/contains-path-0.1.0.tgz", + "integrity": "sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo=", + "dev": true + }, "conventional-changelog": { "version": "3.1.12", "resolved": "https://registry.npmjs.org/conventional-changelog/-/conventional-changelog-3.1.12.tgz", @@ -4597,19 +4940,189 @@ } } }, - "eslint-config-xo": { - "version": "0.26.0", - "resolved": "https://registry.npmjs.org/eslint-config-xo/-/eslint-config-xo-0.26.0.tgz", - "integrity": "sha512-l+93kmBSNr5rMrsqwC6xVWsi8LI4He3z6jSk38e9bAkMNsVsQ8XYO+qzXfJFgFX4i/+hiTswyHtl+nDut9rPaA==", - "dev": true + "eslint-import-resolver-node": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.3.tgz", + "integrity": "sha512-b8crLDo0M5RSe5YG8Pu2DYBj71tSB6OvXkfzwbJU2w7y8P4/yo0MyF8jU26IEuEuHF2K5/gcAJE3LhQGqBBbVg==", + "dev": true, + "requires": { + "debug": "^2.6.9", + "resolve": "^1.13.1" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "resolve": { + "version": "1.15.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.15.1.tgz", + "integrity": "sha512-84oo6ZTtoTUpjgNEr5SJyzQhzL72gaRodsSfyxC/AXRvwu0Yse9H8eF9IpGo7b8YetZhlI6v7ZQ6bKBFV/6S7w==", + "dev": true, + "requires": { + "path-parse": "^1.0.6" + } + } + } + }, + "eslint-module-utils": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.5.2.tgz", + "integrity": "sha512-LGScZ/JSlqGKiT8OC+cYRxseMjyqt6QO54nl281CK93unD89ijSeRV6An8Ci/2nvWVKe8K/Tqdm75RQoIOCr+Q==", + "dev": true, + "requires": { + "debug": "^2.6.9", + "pkg-dir": "^2.0.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "pkg-dir": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz", + "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=", + "dev": true, + "requires": { + "find-up": "^2.1.0" + } + } + } + }, + "eslint-plugin-import": { + "version": "2.20.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.20.1.tgz", + "integrity": "sha512-qQHgFOTjguR+LnYRoToeZWT62XM55MBVXObHM6SKFd1VzDcX/vqT1kAz8ssqigh5eMj8qXcRoXXGZpPP6RfdCw==", + "dev": true, + "requires": { + "array-includes": "^3.0.3", + "array.prototype.flat": "^1.2.1", + "contains-path": "^0.1.0", + "debug": "^2.6.9", + "doctrine": "1.5.0", + "eslint-import-resolver-node": "^0.3.2", + "eslint-module-utils": "^2.4.1", + "has": "^1.0.3", + "minimatch": "^3.0.4", + "object.values": "^1.1.0", + "read-pkg-up": "^2.0.0", + "resolve": "^1.12.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "doctrine": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz", + "integrity": "sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=", + "dev": true, + "requires": { + "esutils": "^2.0.2", + "isarray": "^1.0.0" + } + }, + "load-json-file": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", + "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "parse-json": "^2.2.0", + "pify": "^2.0.0", + "strip-bom": "^3.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "parse-json": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", + "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", + "dev": true, + "requires": { + "error-ex": "^1.2.0" + } + }, + "path-type": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", + "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=", + "dev": true, + "requires": { + "pify": "^2.0.0" + } + }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + }, + "read-pkg": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", + "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=", + "dev": true, + "requires": { + "load-json-file": "^2.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^2.0.0" + } + }, + "read-pkg-up": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz", + "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=", + "dev": true, + "requires": { + "find-up": "^2.0.0", + "read-pkg": "^2.0.0" + } + } + } }, - "eslint-config-xo-space": { - "version": "0.21.0", - "resolved": "https://registry.npmjs.org/eslint-config-xo-space/-/eslint-config-xo-space-0.21.0.tgz", - "integrity": "sha512-4/Ko662Ghi1hgAF5H9Z37isg7WAeW1eGaY85pf/KLdLaif5qSPqpRZzaFzKjfCgkz3tU1GgpUIYYcMpLetNdyQ==", + "eslint-plugin-prettier": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-3.1.2.tgz", + "integrity": "sha512-GlolCC9y3XZfv3RQfwGew7NnuFDKsfI4lbvRK+PIIo23SFH+LemGs4cKwzAaRa+Mdb+lQO/STaIayno8T5sJJA==", "dev": true, "requires": { - "eslint-config-xo": "^0.26.0" + "prettier-linter-helpers": "^1.0.0" } }, "eslint-scope": { @@ -5026,6 +5539,12 @@ "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=", "dev": true }, + "fast-diff": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz", + "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==", + "dev": true + }, "fast-glob": { "version": "2.2.7", "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-2.2.7.tgz", @@ -6826,6 +7345,12 @@ "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", "dev": true }, + "is-string": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.5.tgz", + "integrity": "sha512-buY6VNRjhQMiF1qWDouloZlQbRhDPCebwxSjxMjxgemYT46YMd2NR0/H+fBhEfWX4A/w9TBJ+ol+okqJKFE6vQ==", + "dev": true + }, "is-svg": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-svg/-/is-svg-3.0.0.tgz", @@ -9389,6 +9914,18 @@ "isobject": "^3.0.0" } }, + "object.assign": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", + "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", + "dev": true, + "requires": { + "define-properties": "^1.1.2", + "function-bind": "^1.1.1", + "has-symbols": "^1.0.0", + "object-keys": "^1.0.11" + } + }, "object.getownpropertydescriptors": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.0.3.tgz", @@ -10655,6 +11192,21 @@ "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", "dev": true }, + "prettier": { + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.19.1.tgz", + "integrity": "sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew==", + "dev": true + }, + "prettier-linter-helpers": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", + "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", + "dev": true, + "requires": { + "fast-diff": "^1.1.2" + } + }, "prismjs": { "version": "1.17.1", "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.17.1.tgz", @@ -12626,6 +13178,12 @@ "os-tmpdir": "~1.0.2" } }, + "to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", + "dev": true + }, "to-object-path": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", diff --git a/package.json b/package.json index 1837c1728..a3c0550b5 100644 --- a/package.json +++ b/package.json @@ -70,6 +70,7 @@ }, "devDependencies": { "autoprefixer-stylus": "^1.0.0", + "babel-eslint": "^10.0.3", "chai": "^4.2.0", "chokidar": "^3.2.1", "conventional-changelog-cli": "^2.0.25", @@ -80,7 +81,8 @@ "cypress": "^3.8.1", "cypress-image-snapshot": "^3.1.1", "eslint": "^5.16.0", - "eslint-config-xo-space": "^0.21.0", + "eslint-plugin-import": "^2.20.1", + "eslint-plugin-prettier": "^3.1.2", "esm": "^3.1.4", "husky": "^3.1.0", "jsdom": "^15.1.1", @@ -90,6 +92,7 @@ "mkdirp": "^0.5.1", "mocha": "^5.2.0", "npm-run-all": "^4.1.5", + "prettier": "^1.19.1", "rimraf": "^3.0.0", "rollup": "^1.23.1", "rollup-plugin-async": "^1.2.0", diff --git a/packages/docsify-server-renderer/index.js b/packages/docsify-server-renderer/index.js index 5b62effee..3d9f03730 100644 --- a/packages/docsify-server-renderer/index.js +++ b/packages/docsify-server-renderer/index.js @@ -1,116 +1,116 @@ -import * as tpl from '../../src/core/render/tpl' -import fetch from 'node-fetch' -import {AbstractHistory} from '../../src/core/router/history/abstract' -import {Compiler} from '../../src/core/render/compiler' -import {isAbsolutePath} from '../../src/core/router/util' -import {readFileSync} from 'fs' -import {resolve, basename} from 'path' -import resolvePathname from 'resolve-pathname' -import debug from 'debug' -import {prerenderEmbed} from '../../src/core/render/embed' +import { readFileSync } from 'fs'; +import { resolve, basename } from 'path'; +import resolvePathname from 'resolve-pathname'; +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'; +import debug from 'debug'; +import fetch from 'node-fetch'; function cwd(...args) { - return resolve(process.cwd(), ...args) + return resolve(process.cwd(), ...args); } function mainTpl(config) { let html = `` + }">`; if (config.repo) { - html += tpl.corner(config.repo) + html += tpl.corner(config.repo); } if (config.coverpage) { - html += tpl.cover() + html += tpl.cover(); } - html += tpl.main(config) + html += tpl.main(config); - return html + return html; } export default class Renderer { - constructor({template, config, cache}) { - this.html = template + constructor({ template, config, cache }) { + this.html = template; this.config = config = Object.assign({}, config, { - routerMode: 'history' - }) - this.cache = cache + routerMode: 'history', + }); + this.cache = cache; - this.router = new AbstractHistory(config) - this.compiler = new Compiler(config, this.router) + this.router = new AbstractHistory(config); + this.compiler = new Compiler(config, this.router); - this.router.getCurrentPath = () => this.url + this.router.getCurrentPath = () => this.url; this._renderHtml( 'inject-config', `` - ) - this._renderHtml('inject-app', mainTpl(config)) + ); + this._renderHtml('inject-app', mainTpl(config)); - this.template = this.html + this.template = this.html; } _getPath(url) { - const file = this.router.getFile(url) + const file = this.router.getFile(url); - return isAbsolutePath(file) ? file : cwd(`./${file}`) + return isAbsolutePath(file) ? file : cwd(`./${file}`); } async renderToString(url) { - this.url = url = this.router.parse(url).path - const {loadSidebar, loadNavbar, coverpage} = this.config + this.url = url = this.router.parse(url).path; + const { loadSidebar, loadNavbar, coverpage } = this.config; - const mainFile = this._getPath(url) - this._renderHtml('main', await this._render(mainFile, 'main')) + 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')) + 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')) + 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 + let path = null; if (typeof coverpage === 'string') { if (url === '/') { - path = coverpage + path = coverpage; } } else if (Array.isArray(coverpage)) { - path = coverpage.indexOf(url) > -1 && '_coverpage.md' + path = coverpage.indexOf(url) > -1 && '_coverpage.md'; } else { - const cover = coverpage[url] - path = cover === true ? '_coverpage.md' : cover + const cover = coverpage[url]; + path = cover === true ? '_coverpage.md' : cover; } - const coverFile = this._getPath(resolve(url, `./${path}`)) + const coverFile = this._getPath(resolve(url, `./${path}`)); - this._renderHtml('cover', await this._render(coverFile), 'cover') + this._renderHtml('cover', await this._render(coverFile), 'cover'); } - const html = this.html - this.html = this.template + const html = this.html; + this.html = this.template; - return html + return html; } _renderHtml(match, content) { - this.html = this.html.replace(new RegExp(``, 'g'), content) + this.html = this.html.replace(new RegExp(``, 'g'), content); - return this.html + return this.html; } async _render(path, type) { - let html = await this._loadFile(path) - const {subMaxLevel, maxLevel} = this.config - let tokens + let html = await this._loadFile(path); + const { subMaxLevel, maxLevel } = this.config; + let tokens; switch (type) { case 'sidebar': @@ -118,67 +118,67 @@ export default class Renderer { this.compiler.sidebar(html, maxLevel) + `` - break + )}`; + break; case 'cover': - html = this.compiler.cover(html) - break + 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 + raw: html, }, r - ) - }) - html = this.compiler.compile(tokens) - break + ); + }); + html = this.compiler.compile(tokens); + break; case 'navbar': case 'article': default: - html = this.compiler.compile(html) - break + html = this.compiler.compile(html); + break; } - return html + return html; } async _loadFile(filePath) { - debug('docsify')(`load > ${filePath}`) - let content + debug('docsify')(`load > ${filePath}`); + let content; try { if (isAbsolutePath(filePath)) { - const res = await fetch(filePath) + const res = await fetch(filePath); if (!res.ok) { - throw Error() + throw Error(); } - content = await res.text() - this.lock = 0 + content = await res.text(); + this.lock = 0; } else { - content = await readFileSync(filePath, 'utf8') - this.lock = 0 + content = await readFileSync(filePath, 'utf8'); + this.lock = 0; } - return content + return content; } catch (e) { - this.lock = this.lock || 0 + this.lock = this.lock || 0; if (++this.lock > 10) { - this.lock = 0 - return + this.lock = 0; + return; } - const fileName = basename(filePath) + const fileName = basename(filePath); const result = await this._loadFile( resolvePathname(`../${fileName}`, filePath) - ) + ); - return result + return result; } } } -Renderer.version = '__VERSION__' +Renderer.version = '__VERSION__'; diff --git a/src/core/config.js b/src/core/config.js index 7ffdb0fd2..ed64e6718 100644 --- a/src/core/config.js +++ b/src/core/config.js @@ -1,8 +1,8 @@ -import {merge, hyphenate, isPrimitive, hasOwn} from './util/core' +import { merge, hyphenate, isPrimitive, hasOwn } from './util/core'; -const currentScript = document.currentScript +const currentScript = document.currentScript; -export default function () { +export default function() { const config = merge( { el: '#app', @@ -32,50 +32,50 @@ export default function () { externalLinkRel: 'noopener', routerMode: 'hash', noCompileLinks: [], - relativePath: false + relativePath: false, }, window.$docsify - ) + ); const script = currentScript || [].slice .call(document.getElementsByTagName('script')) - .filter(n => /docsify\./.test(n.src))[0] + .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)) + const val = script.getAttribute('data-' + hyphenate(prop)); if (isPrimitive(val)) { - config[prop] = val === '' ? true : val + config[prop] = val === '' ? true : val; } } } } if (config.loadSidebar === true) { - config.loadSidebar = '_sidebar' + config.ext + config.loadSidebar = '_sidebar' + config.ext; } if (config.loadNavbar === true) { - config.loadNavbar = '_navbar' + config.ext + config.loadNavbar = '_navbar' + config.ext; } if (config.coverpage === true) { - config.coverpage = '_coverpage' + config.ext + config.coverpage = '_coverpage' + config.ext; } if (config.repo === true) { - config.repo = '' + config.repo = ''; } if (config.name === true) { - config.name = '' + config.name = ''; } - window.$docsify = config + window.$docsify = config; - return config + return config; } diff --git a/src/core/event/index.js b/src/core/event/index.js index 8b8c275b1..596d3debb 100644 --- a/src/core/event/index.js +++ b/src/core/event/index.js @@ -1,26 +1,26 @@ -import {isMobile} from '../util/env' -import {body, on} from '../util/dom' -import * as sidebar from './sidebar' -import {scrollIntoView} from './scroll' +import { isMobile } from '../util/env'; +import { body, on } from '../util/dom'; +import * as sidebar from './sidebar'; +import { scrollIntoView } from './scroll'; export function eventMixin(proto) { - proto.$resetEvents = function () { - scrollIntoView(this.route.path, this.route.query.id) + proto.$resetEvents = function() { + scrollIntoView(this.route.path, this.route.query.id); if (this.config.loadNavbar) { - sidebar.getAndActive(this.router, 'nav') + sidebar.getAndActive(this.router, 'nav'); } - } + }; } export function initEvent(vm) { // Bind toggle button - sidebar.btn('button.sidebar-toggle', vm.router) - sidebar.collapse('.sidebar', vm.router) + sidebar.btn('button.sidebar-toggle', vm.router); + sidebar.collapse('.sidebar', vm.router); // Bind sticky effect if (vm.config.coverpage) { - !isMobile && on('scroll', sidebar.sticky) + !isMobile && on('scroll', sidebar.sticky); } else { - body.classList.add('sticky') + body.classList.add('sticky'); } } diff --git a/src/core/event/scroll.js b/src/core/event/scroll.js index 6c6578f2a..2a3b16cae 100644 --- a/src/core/event/scroll.js +++ b/src/core/event/scroll.js @@ -1,156 +1,160 @@ -import { isMobile } from '../util/env' -import * as dom from '../util/dom' -import Tweezer from 'tweezer.js' -import cssEscape from 'css.escape' +import { isMobile } from '../util/env'; +import * as dom from '../util/dom'; +import Tweezer from 'tweezer.js'; +import cssEscape from 'css.escape'; -const nav = {} -let hoverOver = false -let scroller = null -let enableScrollEvent = true -let coverHeight = 0 +const nav = {}; +let hoverOver = false; +let scroller = null; +let enableScrollEvent = true; +let coverHeight = 0; function scrollTo(el) { if (scroller) { - scroller.stop() + scroller.stop(); } - enableScrollEvent = false + enableScrollEvent = false; scroller = new Tweezer({ start: window.pageYOffset, end: el.getBoundingClientRect().top + window.pageYOffset, - duration: 500 + duration: 500, }) .on('tick', v => window.scrollTo(0, v)) .on('done', () => { - enableScrollEvent = true - scroller = null + enableScrollEvent = true; + scroller = null; }) - .begin() + .begin(); } function highlight(path) { if (!enableScrollEvent) { - return + return; } - const sidebar = dom.getNode('.sidebar') - const anchors = dom.findAll('.anchor') - const wrap = dom.find(sidebar, '.sidebar-nav') - let active = dom.find(sidebar, 'li.active') - const doc = document.documentElement - const top = ((doc && doc.scrollTop) || document.body.scrollTop) - coverHeight - let last + const sidebar = dom.getNode('.sidebar'); + const anchors = dom.findAll('.anchor'); + const wrap = dom.find(sidebar, '.sidebar-nav'); + let active = dom.find(sidebar, 'li.active'); + const doc = document.documentElement; + 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] + const node = anchors[i]; if (node.offsetTop > top) { if (!last) { - last = node + last = node; } - break + break; } else { - last = node + last = node; } } if (!last) { - return + return; } - const li = nav[getNavKey(decodeURIComponent(path), last.getAttribute('data-id'))] + const li = + nav[getNavKey(decodeURIComponent(path), last.getAttribute('data-id'))]; if (!li || li === active) { - return + return; } - active && active.classList.remove('active') - li.classList.add('active') - active = li + active && active.classList.remove('active'); + li.classList.add('active'); + active = li; // Scroll into view // https://github.com/vuejs/vuejs.org/blob/master/themes/vue/source/js/common.js#L282-L297 if (!hoverOver && dom.body.classList.contains('sticky')) { - const height = sidebar.clientHeight - const curOffset = 0 - const cur = active.offsetTop + active.clientHeight + 40 + const height = sidebar.clientHeight; + const curOffset = 0; + const cur = active.offsetTop + active.clientHeight + 40; const isInView = - active.offsetTop >= wrap.scrollTop && cur <= wrap.scrollTop + height - const notThan = cur - curOffset < height - const top = isInView ? wrap.scrollTop : notThan ? curOffset : cur - height + active.offsetTop >= wrap.scrollTop && cur <= wrap.scrollTop + height; + const notThan = cur - curOffset < height; + const top = isInView ? wrap.scrollTop : notThan ? curOffset : cur - height; - sidebar.scrollTop = top + sidebar.scrollTop = top; } } function getNavKey(path, id) { - return `${path}?id=${id}` + return `${path}?id=${id}`; } export function scrollActiveSidebar(router) { - const cover = dom.find('.cover.show') - coverHeight = cover ? cover.offsetHeight : 0 + const cover = dom.find('.cover.show'); + coverHeight = cover ? cover.offsetHeight : 0; - const sidebar = dom.getNode('.sidebar') - let lis = [] + const sidebar = dom.getNode('.sidebar'); + let lis = []; if (sidebar !== null && sidebar !== undefined) { - lis = dom.findAll(sidebar, 'li') + lis = dom.findAll(sidebar, 'li'); } for (let i = 0, len = lis.length; i < len; i += 1) { - const li = lis[i] - const a = li.querySelector('a') + const li = lis[i]; + const a = li.querySelector('a'); if (!a) { - continue + continue; } - let href = a.getAttribute('href') + let href = a.getAttribute('href'); if (href !== '/') { - const { query: { id }, path } = router.parse(href) + const { + query: { id }, + path, + } = router.parse(href); if (id) { - href = getNavKey(path, id) + href = getNavKey(path, id); } } if (href) { - nav[decodeURIComponent(href)] = li + nav[decodeURIComponent(href)] = li; } } if (isMobile) { - return + return; } - const path = router.getCurrentPath() - dom.off('scroll', () => highlight(path)) - dom.on('scroll', () => highlight(path)) + const path = router.getCurrentPath(); + dom.off('scroll', () => highlight(path)); + dom.on('scroll', () => highlight(path)); dom.on(sidebar, 'mouseover', () => { - hoverOver = true - }) + hoverOver = true; + }); dom.on(sidebar, 'mouseleave', () => { - hoverOver = false - }) + hoverOver = false; + }); } export function scrollIntoView(path, id) { if (!id) { - return + return; } - const section = dom.find('#' + cssEscape(id)) - section && scrollTo(section) + const section = dom.find('#' + cssEscape(id)); + section && scrollTo(section); - const li = nav[getNavKey(path, id)] - const sidebar = dom.getNode('.sidebar') - const active = dom.find(sidebar, 'li.active') - active && active.classList.remove('active') - li && li.classList.add('active') + const li = nav[getNavKey(path, id)]; + const sidebar = dom.getNode('.sidebar'); + const active = dom.find(sidebar, 'li.active'); + active && active.classList.remove('active'); + li && li.classList.add('active'); } -const scrollEl = dom.$.scrollingElement || dom.$.documentElement +const scrollEl = dom.$.scrollingElement || dom.$.documentElement; export function scroll2Top(offset = 0) { - scrollEl.scrollTop = offset === true ? 0 : Number(offset) + scrollEl.scrollTop = offset === true ? 0 : Number(offset); } diff --git a/src/core/event/sidebar.js b/src/core/event/sidebar.js index 8aa2bb8b8..f252f2b48 100644 --- a/src/core/event/sidebar.js +++ b/src/core/event/sidebar.js @@ -1,37 +1,38 @@ -import { isMobile } from '../util/env' -import * as dom from '../util/dom' +/* eslint-disable no-unused-vars */ +import { isMobile } from '../util/env'; +import * as dom from '../util/dom'; -const title = dom.$.title +const title = dom.$.title; /** * Toggle button * @param {Element} el Button to be toggled * @void */ export function btn(el) { - const toggle = _ => dom.body.classList.toggle('close') + const toggle = _ => dom.body.classList.toggle('close'); - el = dom.getNode(el) + el = dom.getNode(el); if (el === null || el === undefined) { - return + return; } dom.on(el, 'click', e => { - e.stopPropagation() - toggle() - }) + e.stopPropagation(); + toggle(); + }); isMobile && dom.on( dom.body, 'click', _ => dom.body.classList.contains('close') && toggle() - ) + ); } export function collapse(el) { - el = dom.getNode(el) + el = dom.getNode(el); if (el === null || el === undefined) { - return + return; } dom.on(el, 'click', ({ target }) => { @@ -40,23 +41,23 @@ export function collapse(el) { target.nextSibling && target.nextSibling.classList.contains('app-sub-sidebar') ) { - dom.toggleClass(target.parentNode, 'collapse') + dom.toggleClass(target.parentNode, 'collapse'); } - }) + }); } export function sticky() { - const cover = dom.getNode('section.cover') + const cover = dom.getNode('section.cover'); if (!cover) { - return + return; } - const coverHeight = cover.getBoundingClientRect().height + const coverHeight = cover.getBoundingClientRect().height; if (window.pageYOffset >= coverHeight || cover.classList.contains('hidden')) { - dom.toggleClass(dom.body, 'add', 'sticky') + dom.toggleClass(dom.body, 'add', 'sticky'); } else { - dom.toggleClass(dom.body, 'remove', 'sticky') + dom.toggleClass(dom.body, 'remove', 'sticky'); } } @@ -69,30 +70,34 @@ export function sticky() { * @return {Element} Active element */ export function getAndActive(router, el, isParent, autoTitle) { - el = dom.getNode(el) - let links = [] + el = dom.getNode(el); + let links = []; if (el !== null && el !== undefined) { - links = dom.findAll(el, 'a') + links = dom.findAll(el, 'a'); } - const hash = decodeURI(router.toURL(router.getCurrentPath())) - let target + const hash = decodeURI(router.toURL(router.getCurrentPath())); + let target; - links.sort((a, b) => b.href.length - a.href.length).forEach(a => { - const href = a.getAttribute('href') - const node = isParent ? a.parentNode : a + links + .sort((a, b) => b.href.length - a.href.length) + .forEach(a => { + const href = a.getAttribute('href'); + const node = isParent ? a.parentNode : a; - if (hash.indexOf(href) === 0 && !target) { - target = a - dom.toggleClass(node, 'add', 'active') - } else { - dom.toggleClass(node, 'remove', 'active') - } - }) + if (hash.indexOf(href) === 0 && !target) { + target = a; + dom.toggleClass(node, 'add', 'active'); + } else { + dom.toggleClass(node, 'remove', 'active'); + } + }); if (autoTitle) { - dom.$.title = target ? (target.title || `${target.innerText} - ${title}`) : title + dom.$.title = target + ? target.title || `${target.innerText} - ${title}` + : title; } - return target + return target; } diff --git a/src/core/fetch/ajax.js b/src/core/fetch/ajax.js index c70944a2e..319ab1a81 100644 --- a/src/core/fetch/ajax.js +++ b/src/core/fetch/ajax.js @@ -1,7 +1,8 @@ -import progressbar from '../render/progressbar' -import { noop, hasOwn } from '../util/core' +/* eslint-disable no-unused-vars */ +import progressbar from '../render/progressbar'; +import { noop, hasOwn } from '../util/core'; -const cache = {} +const cache = {}; /** * Ajax GET implmentation @@ -11,60 +12,60 @@ const cache = {} * @return {Promise} Promise response */ export function get(url, hasBar = false, headers = {}) { - const xhr = new XMLHttpRequest() - const on = function () { - xhr.addEventListener.apply(xhr, arguments) - } + const xhr = new XMLHttpRequest(); + const on = function() { + xhr.addEventListener.apply(xhr, arguments); + }; - const cached = cache[url] + const cached = cache[url]; if (cached) { - return { then: cb => cb(cached.content, cached.opt), abort: noop } + return { then: cb => cb(cached.content, cached.opt), abort: noop }; } - xhr.open('GET', url) + xhr.open('GET', url); for (const i in headers) { if (hasOwn.call(headers, i)) { - xhr.setRequestHeader(i, headers[i]) + xhr.setRequestHeader(i, headers[i]); } } - xhr.send() + xhr.send(); return { - then: function (success, error = noop) { + then: function(success, error = noop) { if (hasBar) { const id = setInterval( _ => progressbar({ - step: Math.floor(Math.random() * 5 + 1) + step: Math.floor(Math.random() * 5 + 1), }), 500 - ) + ); - on('progress', progressbar) + on('progress', progressbar); on('loadend', evt => { - progressbar(evt) - clearInterval(id) - }) + progressbar(evt); + clearInterval(id); + }); } - on('error', error) + on('error', error); on('load', ({ target }) => { if (target.status >= 400) { - error(target) + error(target); } else { const result = (cache[url] = { content: target.response, opt: { - updatedAt: xhr.getResponseHeader('last-modified') - } - }) + updatedAt: xhr.getResponseHeader('last-modified'), + }, + }); - success(result.content, result.opt) + success(result.content, result.opt); } - }) + }); }, - abort: _ => xhr.readyState !== 4 && xhr.abort() - } + abort: _ => xhr.readyState !== 4 && xhr.abort(), + }; } diff --git a/src/core/fetch/index.js b/src/core/fetch/index.js index fb4f0d20a..14c7fc888 100644 --- a/src/core/fetch/index.js +++ b/src/core/fetch/index.js @@ -1,90 +1,91 @@ -import { get } from './ajax' -import { callHook } from '../init/lifecycle' -import { getParentPath, stringifyQuery } from '../router/util' -import { noop } from '../util/core' -import { getAndActive } from '../event/sidebar' +/* eslint-disable no-unused-vars */ +import { callHook } from '../init/lifecycle'; +import { getParentPath, stringifyQuery } from '../router/util'; +import { noop } from '../util/core'; +import { getAndActive } from '../event/sidebar'; +import { get } from './ajax'; function loadNested(path, qs, file, next, vm, first) { - path = first ? path : path.replace(/\/$/, '') - path = getParentPath(path) + path = first ? path : path.replace(/\/$/, ''); + path = getParentPath(path); if (!path) { - return + return; } get( vm.router.getFile(path + file) + qs, false, vm.config.requestHeaders - ).then(next, _ => loadNested(path, qs, file, next, vm)) + ).then(next, _ => loadNested(path, qs, file, next, vm)); } export function fetchMixin(proto) { - let last + let last; - const abort = () => last && last.abort && last.abort() + const abort = () => last && last.abort && last.abort(); const request = (url, hasbar, requestHeaders) => { - abort() - last = get(url, true, requestHeaders) - return last - } + abort(); + last = get(url, true, requestHeaders); + return last; + }; const get404Path = (path, config) => { - const { notFoundPage, ext } = config - const defaultPath = '_404' + (ext || '.md') - let key - let path404 + const { notFoundPage, ext } = config; + const defaultPath = '_404' + (ext || '.md'); + let key; + let path404; switch (typeof notFoundPage) { case 'boolean': - path404 = defaultPath - break + path404 = defaultPath; + break; case 'string': - path404 = notFoundPage - break + path404 = notFoundPage; + break; case 'object': key = Object.keys(notFoundPage) .sort((a, b) => b.length - a.length) - .find(key => path.match(new RegExp('^' + key))) + .find(key => path.match(new RegExp('^' + key))); - path404 = (key && notFoundPage[key]) || defaultPath - break + path404 = (key && notFoundPage[key]) || defaultPath; + break; default: - break + break; } - return path404 - } + return path404; + }; - proto._loadSideAndNav = function (path, qs, loadSidebar, cb) { + proto._loadSideAndNav = function(path, qs, loadSidebar, cb) { return () => { if (!loadSidebar) { - return cb() + return cb(); } const fn = result => { - this._renderSidebar(result) - cb() - } + this._renderSidebar(result); + cb(); + }; // Load sidebar - loadNested(path, qs, loadSidebar, fn, this, true) - } - } - - proto._fetch = function (cb = noop) { - const { path, query } = this.route - const qs = stringifyQuery(query, ['id']) - const { loadNavbar, requestHeaders, loadSidebar } = this.config + loadNested(path, qs, loadSidebar, fn, this, true); + }; + }; + + proto._fetch = function(cb = noop) { + const { path, query } = this.route; + const qs = stringifyQuery(query, ['id']); + const { loadNavbar, requestHeaders, loadSidebar } = this.config; // Abort last request - const file = this.router.getFile(path) - const req = request(file + qs, true, requestHeaders) + const file = this.router.getFile(path); + const req = request(file + qs, true, requestHeaders); // Current page is html - this.isHTML = /\.html$/g.test(file) + this.isHTML = /\.html$/g.test(file); // Load main content req.then( @@ -95,9 +96,9 @@ export function fetchMixin(proto) { this._loadSideAndNav(path, qs, loadSidebar, cb) ), _ => { - this._fetchFallbackPage(file, qs, cb) || this._fetch404(file, qs, cb) + this._fetchFallbackPage(file, qs, cb) || this._fetch404(file, qs, cb); } - ) + ); // Load nav loadNavbar && @@ -108,76 +109,78 @@ export function fetchMixin(proto) { text => this._renderNav(text), this, true - ) - } + ); + }; - proto._fetchCover = function () { - const { coverpage, requestHeaders } = this.config - const query = this.route.query - const root = getParentPath(this.route.path) + proto._fetchCover = function() { + const { coverpage, requestHeaders } = this.config; + const query = this.route.query; + const root = getParentPath(this.route.path); if (coverpage) { - let path = null - const routePath = this.route.path + let path = null; + const routePath = this.route.path; if (typeof coverpage === 'string') { if (routePath === '/') { - path = coverpage + path = coverpage; } } else if (Array.isArray(coverpage)) { - path = coverpage.indexOf(routePath) > -1 && '_coverpage' + path = coverpage.indexOf(routePath) > -1 && '_coverpage'; } else { - const cover = coverpage[routePath] - path = cover === true ? '_coverpage' : cover + const cover = coverpage[routePath]; + path = cover === true ? '_coverpage' : cover; } - const coverOnly = Boolean(path) && this.config.onlyCover + const coverOnly = Boolean(path) && this.config.onlyCover; if (path) { - path = this.router.getFile(root + path) - this.coverIsHTML = /\.html$/g.test(path) - get(path + stringifyQuery(query, ['id']), false, requestHeaders).then( - text => this._renderCover(text, coverOnly) - ) + path = this.router.getFile(root + path); + this.coverIsHTML = /\.html$/g.test(path); + get( + path + stringifyQuery(query, ['id']), + false, + requestHeaders + ).then(text => this._renderCover(text, coverOnly)); } else { - this._renderCover(null, coverOnly) + this._renderCover(null, coverOnly); } - return coverOnly + return coverOnly; } - } + }; - proto.$fetch = function (cb = noop) { + proto.$fetch = function(cb = noop) { const done = () => { - callHook(this, 'doneEach') - cb() - } + callHook(this, 'doneEach'); + cb(); + }; - const onlyCover = this._fetchCover() + const onlyCover = this._fetchCover(); if (onlyCover) { - done() + done(); } else { this._fetch(() => { - this.$resetEvents() - done() - }) + this.$resetEvents(); + done(); + }); } - } + }; - proto._fetchFallbackPage = function (path, qs, cb = noop) { - const { requestHeaders, fallbackLanguages, loadSidebar } = this.config + proto._fetchFallbackPage = function(path, qs, cb = noop) { + const { requestHeaders, fallbackLanguages, loadSidebar } = this.config; if (!fallbackLanguages) { - return false + return false; } - const local = path.split('/')[1] + const local = path.split('/')[1]; if (fallbackLanguages.indexOf(local) === -1) { - return false + return false; } - const newPath = path.replace(new RegExp(`^/${local}`), '') - const req = request(newPath + qs, true, requestHeaders) + const newPath = path.replace(new RegExp(`^/${local}`), ''); + const req = request(newPath + qs, true, requestHeaders); req.then( (text, opt) => @@ -187,10 +190,10 @@ export function fetchMixin(proto) { this._loadSideAndNav(path, qs, loadSidebar, cb) ), () => this._fetch404(path, qs, cb) - ) + ); - return true - } + return true; + }; /** * Load the 404 page @@ -200,40 +203,40 @@ export function fetchMixin(proto) { * @returns {Boolean} True if the requested page is not found * @private */ - proto._fetch404 = function (path, qs, cb = noop) { - const { loadSidebar, requestHeaders, notFoundPage } = this.config + proto._fetch404 = function(path, qs, cb = noop) { + const { loadSidebar, requestHeaders, notFoundPage } = this.config; - const fnLoadSideAndNav = this._loadSideAndNav(path, qs, loadSidebar, cb) + const fnLoadSideAndNav = this._loadSideAndNav(path, qs, loadSidebar, cb); if (notFoundPage) { - const path404 = get404Path(path, this.config) + const path404 = get404Path(path, this.config); request(this.router.getFile(path404), true, requestHeaders).then( (text, opt) => this._renderMain(text, opt, fnLoadSideAndNav), () => this._renderMain(null, {}, fnLoadSideAndNav) - ) - return true + ); + return true; } - this._renderMain(null, {}, fnLoadSideAndNav) - return false - } + this._renderMain(null, {}, fnLoadSideAndNav); + return false; + }; } export function initFetch(vm) { - const { loadSidebar } = vm.config + const { loadSidebar } = vm.config; // Server-Side Rendering if (vm.rendered) { - const activeEl = getAndActive(vm.router, '.sidebar-nav', true, true) + const activeEl = getAndActive(vm.router, '.sidebar-nav', true, true); if (loadSidebar && activeEl) { - activeEl.parentNode.innerHTML += window.__SUB_SIDEBAR__ + activeEl.parentNode.innerHTML += window.__SUB_SIDEBAR__; } - vm._bindEventOnRendered(activeEl) - vm.$resetEvents() - callHook(vm, 'doneEach') - callHook(vm, 'ready') + vm._bindEventOnRendered(activeEl); + vm.$resetEvents(); + callHook(vm, 'doneEach'); + callHook(vm, 'ready'); } else { - vm.$fetch(_ => callHook(vm, 'ready')) + vm.$fetch(_ => callHook(vm, 'ready')); } } diff --git a/src/core/global-api.js b/src/core/global-api.js index 7bdf74c65..102ded28e 100644 --- a/src/core/global-api.js +++ b/src/core/global-api.js @@ -1,20 +1,20 @@ -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 prism from 'prismjs' +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 prism from 'prismjs'; -export default function () { +export default function() { window.Docsify = { util, dom, get, slugify, - version: '__VERSION__' - } - window.DocsifyCompiler = Compiler - window.marked = marked - window.Prism = prism + version: '__VERSION__', + }; + window.DocsifyCompiler = Compiler; + window.marked = marked; + window.Prism = prism; } diff --git a/src/core/index.js b/src/core/index.js index cc00cc1f2..14f5d9422 100644 --- a/src/core/index.js +++ b/src/core/index.js @@ -1,9 +1,9 @@ -import { initMixin } from './init' -import { routerMixin } from './router' -import { renderMixin } from './render' -import { fetchMixin } from './fetch' -import { eventMixin } from './event' -import initGlobalAPI from './global-api' +import { initMixin } from './init'; +import { routerMixin } from './router'; +import { renderMixin } from './render'; +import { fetchMixin } from './fetch'; +import { eventMixin } from './event'; +import initGlobalAPI from './global-api'; /** * Fork https://github.com/bendrucker/document-ready/blob/master/index.js @@ -12,33 +12,34 @@ import initGlobalAPI from './global-api' * otherwise it only attaches the callback to the DOMContentLoaded event */ function ready(callback) { - const state = document.readyState + const state = document.readyState; if (state === 'complete' || state === 'interactive') { - return setTimeout(callback, 0) + return setTimeout(callback, 0); } - document.addEventListener('DOMContentLoaded', callback) + document.addEventListener('DOMContentLoaded', callback); } function Docsify() { - this._init() + this._init(); } -const proto = Docsify.prototype +const proto = Docsify.prototype; -initMixin(proto) -routerMixin(proto) -renderMixin(proto) -fetchMixin(proto) -eventMixin(proto) +initMixin(proto); +routerMixin(proto); +renderMixin(proto); +fetchMixin(proto); +eventMixin(proto); /** * Global API */ -initGlobalAPI() +initGlobalAPI(); /** * Run Docsify */ -ready(_ => new Docsify()) +// eslint-disable-next-line no-unused-vars +ready(_ => new Docsify()); diff --git a/src/core/init/index.js b/src/core/init/index.js index fe88c31d4..9231acc1d 100644 --- a/src/core/init/index.js +++ b/src/core/init/index.js @@ -1,27 +1,27 @@ -import config from '../config' -import {initLifecycle, callHook} from './lifecycle' -import {initRender} from '../render' -import {initRouter} from '../router' -import {initEvent} from '../event' -import {initFetch} from '../fetch' -import {isFn} from '../util/core' +import config from '../config'; +import { initRender } from '../render'; +import { initRouter } from '../router'; +import { initEvent } from '../event'; +import { initFetch } from '../fetch'; +import { isFn } from '../util/core'; +import { initLifecycle, callHook } from './lifecycle'; export function initMixin(proto) { - proto._init = function () { - const vm = this - vm.config = config() + proto._init = function() { + const vm = this; + vm.config = config(); - initLifecycle(vm) // Init hooks - initPlugin(vm) // Install plugins - callHook(vm, 'init') - initRouter(vm) // Add router - initRender(vm) // Render base DOM - initEvent(vm) // Bind events - initFetch(vm) // Fetch data - callHook(vm, 'mounted') - } + initLifecycle(vm); // Init hooks + initPlugin(vm); // Install plugins + callHook(vm, 'init'); + initRouter(vm); // Add router + initRender(vm); // Render base DOM + initEvent(vm); // Bind events + initFetch(vm); // Fetch data + callHook(vm, 'mounted'); + }; } function initPlugin(vm) { - [].concat(vm.config.plugins).forEach(fn => isFn(fn) && fn(vm._lifecycle, vm)) + [].concat(vm.config.plugins).forEach(fn => isFn(fn) && fn(vm._lifecycle, vm)); } diff --git a/src/core/init/lifecycle.js b/src/core/init/lifecycle.js index fd9b7aea9..d8106adc9 100644 --- a/src/core/init/lifecycle.js +++ b/src/core/init/lifecycle.js @@ -1,4 +1,4 @@ -import {noop} from '../util/core' +import { noop } from '../util/core'; export function initLifecycle(vm) { const hooks = [ @@ -7,39 +7,39 @@ export function initLifecycle(vm) { 'beforeEach', 'afterEach', 'doneEach', - 'ready' - ] + 'ready', + ]; - vm._hooks = {} - vm._lifecycle = {} + vm._hooks = {}; + vm._lifecycle = {}; hooks.forEach(hook => { - const arr = (vm._hooks[hook] = []) - vm._lifecycle[hook] = fn => arr.push(fn) - }) + const arr = (vm._hooks[hook] = []); + vm._lifecycle[hook] = fn => arr.push(fn); + }); } export function callHook(vm, hook, data, next = noop) { - const queue = vm._hooks[hook] + const queue = vm._hooks[hook]; - const step = function (index) { - const hook = queue[index] + const step = function(index) { + const hook = queue[index]; if (index >= queue.length) { - next(data) + next(data); } else if (typeof hook === 'function') { if (hook.length === 2) { hook(data, result => { - data = result - step(index + 1) - }) + data = result; + step(index + 1); + }); } else { - const result = hook(data) - data = result === undefined ? data : result - step(index + 1) + const result = hook(data); + data = result === undefined ? data : result; + step(index + 1); } } else { - step(index + 1) + step(index + 1); } - } + }; - step(0) + step(0); } diff --git a/src/core/render/compiler.js b/src/core/render/compiler.js index 132f51413..d00b3e209 100644 --- a/src/core/render/compiler.js +++ b/src/core/render/compiler.js @@ -1,21 +1,21 @@ -import { tree as treeTpl } from './tpl' -import { genTree } from './gen-tree' -import { slugify } from './slugify' -import { emojify } from './emojify' -import { isAbsolutePath, getPath, getParentPath } from '../router/util' -import { isFn, merge, cached, isPrimitive } from '../util/core' -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' -import marked from 'marked' - -const cachedLinks = {} +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 { 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'; +import marked from 'marked'; + +const cachedLinks = {}; export function getAndRemoveConfig(str = '') { - const config = {} + const config = {}; if (str) { str = str @@ -23,125 +23,128 @@ export function getAndRemoveConfig(str = '') { .replace(/'$/, '') .replace(/(?:^|\s):([\w-]+:?)=?([\w-]+)?/g, (m, key, value) => { if (key.indexOf(':') === -1) { - config[key] = (value && value.replace(/"/g, '')) || true - return '' + config[key] = (value && value.replace(/"/g, '')) || true; + return ''; } - return m + return m; }) - .trim() + .trim(); } - return { str, config } + return { str, config }; } const compileMedia = { markdown(url) { return { - url - } + url, + }; }, mermaid(url) { return { - url - } + url, + }; }, iframe(url, title) { return { - html: `` - } + html: ``, + }; }, video(url, title) { return { - html: `` - } + html: ``, + }; }, audio(url, title) { return { - html: `` - } + html: ``, + }; }, code(url, title) { - let lang = url.match(/\.(\w+)$/) + let lang = url.match(/\.(\w+)$/); - lang = title || (lang && lang[1]) + lang = title || (lang && lang[1]); if (lang === 'md') { - lang = 'markdown' + lang = 'markdown'; } return { url, - lang - } - } -} + lang, + }; + }, +}; export class Compiler { constructor(config, router) { - this.config = config - this.router = router - this.cacheTree = {} - this.toc = [] - this.cacheTOC = {} - this.linkTarget = config.externalLinkTarget || '_blank' - this.linkRel = this.linkTarget === '_blank' ? (config.externalLinkRel || 'noopener') : '' - this.contentBase = router.getBasePath() - - const renderer = this._initRenderer() - this.heading = renderer.heading - let compile - const mdConf = config.markdown || {} + this.config = config; + this.router = router; + this.cacheTree = {}; + this.toc = []; + this.cacheTOC = {}; + this.linkTarget = config.externalLinkTarget || '_blank'; + this.linkRel = + this.linkTarget === '_blank' ? config.externalLinkRel || 'noopener' : ''; + this.contentBase = router.getBasePath(); + + const renderer = this._initRenderer(); + this.heading = renderer.heading; + let compile; + const mdConf = config.markdown || {}; if (isFn(mdConf)) { - compile = mdConf(marked, renderer) + compile = mdConf(marked, renderer); } else { marked.setOptions( merge(mdConf, { - renderer: merge(renderer, mdConf.renderer) + renderer: merge(renderer, mdConf.renderer), }) - ) - compile = marked + ); + compile = marked; } - this._marked = compile + this._marked = compile; this.compile = text => { - let isCached = true + let isCached = true; + // eslint-disable-next-line no-unused-vars const result = cached(_ => { - isCached = false - let html = '' + isCached = false; + let html = ''; if (!text) { - return text + return text; } if (isPrimitive(text)) { - html = compile(text) + html = compile(text); } else { - html = compile.parser(text) + html = compile.parser(text); } - html = config.noEmoji ? html : emojify(html) - slugify.clear() + html = config.noEmoji ? html : emojify(html); + slugify.clear(); - return html - })(text) + return html; + })(text); - const curFileName = this.router.parse().file + const curFileName = this.router.parse().file; if (isCached) { - this.toc = this.cacheTOC[curFileName] + this.toc = this.cacheTOC[curFileName]; } else { - this.cacheTOC[curFileName] = [...this.toc] + this.cacheTOC[curFileName] = [...this.toc]; } - return result - } + return result; + }; } compileEmbed(href, title) { - const { str, config } = getAndRemoveConfig(title) - let embed - title = str + const { str, config } = getAndRemoveConfig(title); + let embed; + title = str; if (config.include) { if (!isAbsolutePath(href)) { @@ -149,55 +152,55 @@ export class Compiler { process.env.SSR ? '' : this.contentBase, getParentPath(this.router.getCurrentPath()), href - ) + ); } - let media + let media; if (config.type && (media = compileMedia[config.type])) { - embed = media.call(this, href, title) - embed.type = config.type + embed = media.call(this, href, title); + embed.type = config.type; } else { - let type = 'code' + let type = 'code'; if (/\.(md|markdown)/.test(href)) { - type = 'markdown' + type = 'markdown'; } else if (/\.mmd/.test(href)) { - type = 'mermaid' + type = 'mermaid'; } else if (/\.html?/.test(href)) { - type = 'iframe' + type = 'iframe'; } else if (/\.(mp4|ogg)/.test(href)) { - type = 'video' + type = 'video'; } else if (/\.mp3/.test(href)) { - type = 'audio' + type = 'audio'; } - embed = compileMedia[type].call(this, href, title) - embed.type = type + embed = compileMedia[type].call(this, href, title); + embed.type = type; } - embed.fragment = config.fragment + embed.fragment = config.fragment; - return embed + return embed; } } _matchNotCompileLink(link) { - const links = this.config.noCompileLinks || [] + const links = this.config.noCompileLinks || []; - for (var i = 0; i < links.length; i++) { - const n = links[i] - const re = cachedLinks[n] || (cachedLinks[n] = new RegExp(`^${n}$`)) + for (let i = 0; i < links.length; i++) { + const n = links[i]; + const re = cachedLinks[n] || (cachedLinks[n] = new RegExp(`^${n}$`)); if (re.test(link)) { - return link + return link; } } } _initRenderer() { - const renderer = new marked.Renderer() - const { linkTarget, router, contentBase } = this - const _self = this - const origin = {} + const renderer = new marked.Renderer(); + const { linkTarget, router, contentBase } = this; + const _self = this; + const origin = {}; /** * Render anchor tag @@ -206,40 +209,45 @@ export class Compiler { * @param {Number} level Type of heading (h tag) * @returns {String} Heading element */ - origin.heading = renderer.heading = function (text, level) { - let { str, config } = getAndRemoveConfig(text) - const nextToc = { level, title: str } + origin.heading = renderer.heading = function(text, level) { + let { str, config } = getAndRemoveConfig(text); + const nextToc = { level, title: str }; if (/{docsify-ignore}/g.test(str)) { - str = str.replace('{docsify-ignore}', '') - nextToc.title = str - nextToc.ignoreSubHeading = true + str = str.replace('{docsify-ignore}', ''); + nextToc.title = str; + nextToc.ignoreSubHeading = true; } if (/{docsify-ignore-all}/g.test(str)) { - str = str.replace('{docsify-ignore-all}', '') - nextToc.title = str - nextToc.ignoreAllSubs = true + str = str.replace('{docsify-ignore-all}', ''); + nextToc.title = str; + nextToc.ignoreAllSubs = true; } - const slug = slugify(config.id || str) - const url = router.toURL(router.getCurrentPath(), { id: slug }) - nextToc.slug = url - _self.toc.push(nextToc) - - return `${str}` - } - - origin.code = highlightCodeCompiler({ renderer }) - origin.link = linkCompiler({ renderer, router, linkTarget, compilerClass: _self }) - origin.paragraph = paragraphCompiler({ renderer }) - origin.image = imageCompiler({ renderer, contentBase, router }) - origin.list = taskListCompiler({ renderer }) - origin.listitem = taskListItemCompiler({ renderer }) - - renderer.origin = origin - - return renderer + const slug = slugify(config.id || str); + const url = router.toURL(router.getCurrentPath(), { id: slug }); + nextToc.slug = url; + _self.toc.push(nextToc); + + return `${str}`; + }; + + origin.code = highlightCodeCompiler({ renderer }); + origin.link = linkCompiler({ + renderer, + router, + linkTarget, + compilerClass: _self, + }); + origin.paragraph = paragraphCompiler({ renderer }); + origin.image = imageCompiler({ renderer, contentBase, router }); + origin.list = taskListCompiler({ renderer }); + origin.listitem = taskListItemCompiler({ renderer }); + + renderer.origin = origin; + + return renderer; } /** @@ -249,32 +257,36 @@ export class Compiler { * @returns {String} Sidebar element */ sidebar(text, level) { - const { toc } = this - const currentPath = this.router.getCurrentPath() - let html = '' + const { toc } = this; + const currentPath = this.router.getCurrentPath(); + let html = ''; if (text) { - html = this.compile(text) + html = this.compile(text); } else { for (let i = 0; i < toc.length; i++) { if (toc[i].ignoreSubHeading) { - const deletedHeaderLevel = toc[i].level - toc.splice(i, 1) + const deletedHeaderLevel = toc[i].level; + toc.splice(i, 1); // Remove headers who are under current header - for (let j = i; deletedHeaderLevel < toc[j].level && j < toc.length; j++) { - toc.splice(j, 1) && j-- && i++ + for ( + let j = i; + deletedHeaderLevel < toc[j].level && j < toc.length; + j++ + ) { + toc.splice(j, 1) && j-- && i++; } - i-- + i--; } } - const tree = this.cacheTree[currentPath] || genTree(toc, level) - html = treeTpl(tree, '') - this.cacheTree[currentPath] = tree + const tree = this.cacheTree[currentPath] || genTree(toc, level); + html = treeTpl(tree, ''); + this.cacheTree[currentPath] = tree; } - return html + return html; } /** @@ -284,33 +296,33 @@ export class Compiler { */ subSidebar(level) { if (!level) { - this.toc = [] - return + this.toc = []; + return; } - const currentPath = this.router.getCurrentPath() - const { cacheTree, toc } = this + const currentPath = this.router.getCurrentPath(); + const { cacheTree, toc } = this; - toc[0] && toc[0].ignoreAllSubs && toc.splice(0) - toc[0] && toc[0].level === 1 && toc.shift() + toc[0] && toc[0].ignoreAllSubs && toc.splice(0); + toc[0] && toc[0].level === 1 && toc.shift(); for (let i = 0; i < toc.length; i++) { - toc[i].ignoreSubHeading && toc.splice(i, 1) && i-- + toc[i].ignoreSubHeading && toc.splice(i, 1) && i--; } - const tree = cacheTree[currentPath] || genTree(toc, level) + const tree = cacheTree[currentPath] || genTree(toc, level); - cacheTree[currentPath] = tree - this.toc = [] - return treeTpl(tree) + cacheTree[currentPath] = tree; + this.toc = []; + return treeTpl(tree); } header(text, level) { - return this.heading(text, level) + return this.heading(text, level); } article(text) { - return this.compile(text) + return this.compile(text); } /** @@ -319,11 +331,11 @@ export class Compiler { * @returns {String} Cover page */ cover(text) { - const cacheToc = this.toc.slice() - const html = this.compile(text) + const cacheToc = this.toc.slice(); + const html = this.compile(text); - this.toc = cacheToc.slice() + this.toc = cacheToc.slice(); - return html + return html; } } diff --git a/src/core/render/compiler/code.js b/src/core/render/compiler/code.js index fb9d88021..da470d78f 100644 --- a/src/core/render/compiler/code.js +++ b/src/core/render/compiler/code.js @@ -1,10 +1,14 @@ -import Prism from 'prismjs' +import Prism from 'prismjs'; // See https://github.com/PrismJS/prism/pull/1367 -import 'prismjs/components/prism-markup-templating' +import 'prismjs/components/prism-markup-templating'; -export const highlightCodeCompiler = ({ renderer }) => renderer.code = function (code, lang = '') { - const langOrMarkup = Prism.languages[lang] || Prism.languages.markup - const text = Prism.highlight(code.replace(/@DOCSIFY_QM@/g, '`'), langOrMarkup) +export const highlightCodeCompiler = ({ renderer }) => + (renderer.code = function(code, lang = '') { + const langOrMarkup = Prism.languages[lang] || Prism.languages.markup; + const text = Prism.highlight( + code.replace(/@DOCSIFY_QM@/g, '`'), + langOrMarkup + ); - return `
${text}
` -} + return `
${text}
`; + }); diff --git a/src/core/render/compiler/headline.js b/src/core/render/compiler/headline.js index 2a5cbb795..10cb4ac84 100644 --- a/src/core/render/compiler/headline.js +++ b/src/core/render/compiler/headline.js @@ -1,27 +1,27 @@ +import { getAndRemoveConfig } from '../compiler'; +import { slugify } from './slugify'; -import { getAndRemoveConfig } from '../compiler' -import { slugify } from './slugify' +export const headingCompiler = ({ renderer, router, _self }) => + (renderer.code = (text, level) => { + let { str, config } = getAndRemoveConfig(text); + const nextToc = { level, title: str }; -export const headingCompiler = ({ renderer, router, _self }) => renderer.code = (text, level) => { - let { str, config } = getAndRemoveConfig(text) - const nextToc = { level, title: str } + if (/{docsify-ignore}/g.test(str)) { + str = str.replace('{docsify-ignore}', ''); + nextToc.title = str; + nextToc.ignoreSubHeading = true; + } - if (/{docsify-ignore}/g.test(str)) { - str = str.replace('{docsify-ignore}', '') - nextToc.title = str - nextToc.ignoreSubHeading = true - } + if (/{docsify-ignore-all}/g.test(str)) { + str = str.replace('{docsify-ignore-all}', ''); + nextToc.title = str; + nextToc.ignoreAllSubs = true; + } - if (/{docsify-ignore-all}/g.test(str)) { - str = str.replace('{docsify-ignore-all}', '') - nextToc.title = str - nextToc.ignoreAllSubs = true - } + const slug = slugify(config.id || str); + const url = router.toURL(router.getCurrentPath(), { id: slug }); + nextToc.slug = url; + _self.toc.push(nextToc); - const slug = slugify(config.id || str) - const url = router.toURL(router.getCurrentPath(), { id: slug }) - nextToc.slug = url - _self.toc.push(nextToc) - - return `${str}` -} + return `${str}`; + }); diff --git a/src/core/render/compiler/image.js b/src/core/render/compiler/image.js index e07602dd8..76e05ed26 100644 --- a/src/core/render/compiler/image.js +++ b/src/core/render/compiler/image.js @@ -1,42 +1,44 @@ -import { getAndRemoveConfig } from '../compiler' -import { isAbsolutePath, getPath, getParentPath } from '../../router/util' - -export const imageCompiler = ({ renderer, contentBase, router }) => renderer.image = (href, title, text) => { - let url = href - let attrs = [] - - const { str, config } = getAndRemoveConfig(title) - title = str - - if (config['no-zoom']) { - attrs.push('data-no-zoom') - } - - if (title) { - attrs.push(`title="${title}"`) - } - - if (config.size) { - const [width, height] = config.size.split('x') - if (height) { - attrs.push(`width="${width}" height="${height}"`) - } else { - attrs.push(`width="${width}" height="${width}"`) +import { getAndRemoveConfig } from '../compiler'; +import { isAbsolutePath, getPath, getParentPath } from '../../router/util'; + +export const imageCompiler = ({ renderer, contentBase, router }) => + (renderer.image = (href, title, text) => { + let url = href; + let attrs = []; + + const { str, config } = getAndRemoveConfig(title); + title = str; + + if (config['no-zoom']) { + attrs.push('data-no-zoom'); } - } - if (config.class) { - attrs.push(`class="${config.class}"`) - } + if (title) { + attrs.push(`title="${title}"`); + } - if (config.id) { - attrs.push(`id="${config.id}"`) - } + if (config.size) { + const [width, height] = config.size.split('x'); + if (height) { + attrs.push(`width="${width}" height="${height}"`); + } else { + attrs.push(`width="${width}" height="${width}"`); + } + } - if (!isAbsolutePath(href)) { - url = getPath(contentBase, getParentPath(router.getCurrentPath()), href) - } + if (config.class) { + attrs.push(`class="${config.class}"`); + } + + if (config.id) { + attrs.push(`id="${config.id}"`); + } - return `${text}` -} + if (!isAbsolutePath(href)) { + url = getPath(contentBase, getParentPath(router.getCurrentPath()), href); + } + return `${text}`; + }); diff --git a/src/core/render/compiler/link.js b/src/core/render/compiler/link.js index 53e6250cc..91b292715 100644 --- a/src/core/render/compiler/link.js +++ b/src/core/render/compiler/link.js @@ -1,42 +1,47 @@ -import { getAndRemoveConfig } from '../compiler' -import { isAbsolutePath } from '../../router/util' - -export const linkCompiler = ({ renderer, router, linkTarget, compilerClass }) => renderer.link = (href, title = '', text) => { - let attrs = [] - const { str, config } = getAndRemoveConfig(title) - - title = str - - if (!isAbsolutePath(href) && !compilerClass._matchNotCompileLink(href) && !config.ignore) { - if (href === compilerClass.config.homepage) { - href = 'README' +import { getAndRemoveConfig } from '../compiler'; +import { isAbsolutePath } from '../../router/util'; + +export const linkCompiler = ({ renderer, router, linkTarget, compilerClass }) => + (renderer.link = (href, title = '', text) => { + let attrs = []; + const { str, config } = getAndRemoveConfig(title); + + title = str; + + if ( + !isAbsolutePath(href) && + !compilerClass._matchNotCompileLink(href) && + !config.ignore + ) { + if (href === compilerClass.config.homepage) { + href = 'README'; + } + + href = router.toURL(href, null, router.getCurrentPath()); + } else { + attrs.push(href.indexOf('mailto:') === 0 ? '' : `target="${linkTarget}"`); } - href = router.toURL(href, null, router.getCurrentPath()) - } else { - attrs.push(href.indexOf('mailto:') === 0 ? '' : `target="${linkTarget}"`) - } - - if (config.target) { - attrs.push(`target="${config.target}"`) - } + if (config.target) { + attrs.push(`target="${config.target}"`); + } - if (config.disabled) { - attrs.push('disabled') - href = 'javascript:void(0)' - } + if (config.disabled) { + attrs.push('disabled'); + href = 'javascript:void(0)'; + } - if (config.class) { - attrs.push(`class="${config.class}"`) - } + if (config.class) { + attrs.push(`class="${config.class}"`); + } - if (config.id) { - attrs.push(`id="${config.id}"`) - } + if (config.id) { + attrs.push(`id="${config.id}"`); + } - if (title) { - attrs.push(`title="${title}"`) - } + if (title) { + attrs.push(`title="${title}"`); + } - return `${text}` -} + return `${text}`; + }); diff --git a/src/core/render/compiler/paragraph.js b/src/core/render/compiler/paragraph.js index 63ff1c111..e166bf91e 100644 --- a/src/core/render/compiler/paragraph.js +++ b/src/core/render/compiler/paragraph.js @@ -1,15 +1,15 @@ -import { helper as helperTpl } from '../tpl' +import { helper as helperTpl } from '../tpl'; -export const paragraphCompiler = ({ renderer }) => renderer.paragraph = text => { - let result - if (/^!>/.test(text)) { - result = helperTpl('tip', text) - } else if (/^\?>/.test(text)) { - result = helperTpl('warn', text) - } else { - result = `

${text}

` - } - - return result -} +export const paragraphCompiler = ({ renderer }) => + (renderer.paragraph = text => { + let result; + if (/^!>/.test(text)) { + result = helperTpl('tip', text); + } else if (/^\?>/.test(text)) { + result = helperTpl('warn', text); + } else { + result = `

${text}

`; + } + return result; + }); diff --git a/src/core/render/compiler/taskList.js b/src/core/render/compiler/taskList.js index fbf76aa9f..17897974b 100644 --- a/src/core/render/compiler/taskList.js +++ b/src/core/render/compiler/taskList.js @@ -1,13 +1,16 @@ -export const taskListCompiler = ({renderer}) => renderer.list = (body, ordered, start) => { - const isTaskList = /
  • /.test(body.split('class="task-list"')[0]) - const isStartReq = start && start > 1 - const tag = ordered ? 'ol' : 'ul' - const tagAttrs = [ - (isTaskList ? 'class="task-list"' : ''), - (isStartReq ? `start="${start}"` : '') - ] - .join(' ') - .trim() +export const taskListCompiler = ({ renderer }) => + (renderer.list = (body, ordered, start) => { + const isTaskList = /
  • /.test( + body.split('class="task-list"')[0] + ); + const isStartReq = start && start > 1; + const tag = ordered ? 'ol' : 'ul'; + const tagAttrs = [ + isTaskList ? 'class="task-list"' : '', + isStartReq ? `start="${start}"` : '', + ] + .join(' ') + .trim(); - return `<${tag} ${tagAttrs}>${body}` -} + return `<${tag} ${tagAttrs}>${body}`; + }); diff --git a/src/core/render/compiler/taskListItem.js b/src/core/render/compiler/taskListItem.js index df705ce58..afc6b1052 100644 --- a/src/core/render/compiler/taskListItem.js +++ b/src/core/render/compiler/taskListItem.js @@ -1,6 +1,9 @@ -export const taskListItemCompiler = ({ renderer }) => renderer.listitem = text => { - const isTaskItem = /^(]*>)/.test(text) - const html = isTaskItem ? `
  • ` : `
  • ${text}
  • ` +export const taskListItemCompiler = ({ renderer }) => + (renderer.listitem = text => { + const isTaskItem = /^(]*>)/.test(text); + const html = isTaskItem + ? `
  • ` + : `
  • ${text}
  • `; - return html -} + return html; + }); diff --git a/src/core/render/embed.js b/src/core/render/embed.js index 51f5e4f27..2b5826f15 100644 --- a/src/core/render/embed.js +++ b/src/core/render/embed.js @@ -1,118 +1,120 @@ -import { get } from '../fetch/ajax' -import { merge } from '../util/core' -import stripIndent from 'strip-indent' +import { get } from '../fetch/ajax'; +import { merge } from '../util/core'; +import stripIndent from 'strip-indent'; -const cached = {} +const cached = {}; function walkFetchEmbed({ embedTokens, compile, fetch }, cb) { - let token - let step = 0 - let count = 1 + let token; + let step = 0; + let count = 1; if (!embedTokens.length) { - return cb({}) + return cb({}); } while ((token = embedTokens[step++])) { - const next = (function (token) { + const next = (function(token) { return text => { - let embedToken + let embedToken; if (text) { if (token.embed.type === 'markdown') { - embedToken = compile.lexer(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}\\]`) - text = stripIndent((text.match(pattern) || [])[1] || '').trim() + const fragment = token.embed.fragment; + const pattern = new RegExp( + `(?:###|\\/\\/\\/)\\s*\\[${fragment}\\]([\\s\\S]*)(?:###|\\/\\/\\/)\\s*\\[${fragment}\\]` + ); + text = stripIndent((text.match(pattern) || [])[1] || '').trim(); } embedToken = compile.lexer( '```' + - token.embed.lang + - '\n' + - text.replace(/`/g, '@DOCSIFY_QM@') + - '\n```\n' - ) + token.embed.lang + + '\n' + + text.replace(/`/g, '@DOCSIFY_QM@') + + '\n```\n' + ); } else if (token.embed.type === 'mermaid') { embedToken = [ - { type: 'html', text: `
    \n${text}\n
    ` } - ] - embedToken.links = {} + { type: 'html', text: `
    \n${text}\n
    ` }, + ]; + embedToken.links = {}; } else { - embedToken = [{ type: 'html', text }] - embedToken.links = {} + embedToken = [{ type: 'html', text }]; + embedToken.links = {}; } } - cb({ token, embedToken }) + cb({ token, embedToken }); if (++count >= step) { - cb({}) + cb({}); } - } - })(token) + }; + })(token); if (token.embed.url) { if (process.env.SSR) { - fetch(token.embed.url).then(next) + fetch(token.embed.url).then(next); } else { - get(token.embed.url).then(next) + get(token.embed.url).then(next); } } else { - next(token.embed.html) + next(token.embed.html); } } } export function prerenderEmbed({ compiler, raw = '', fetch }, done) { - let hit = cached[raw] + let hit = cached[raw]; if (hit) { - const copy = hit.slice() - copy.links = hit.links - return done(copy) + const copy = hit.slice(); + copy.links = hit.links; + return done(copy); } - const compile = compiler._marked - let tokens = compile.lexer(raw) - const embedTokens = [] - const linkRE = compile.InlineLexer.rules.link - const links = tokens.links + const compile = compiler._marked; + let tokens = compile.lexer(raw); + const embedTokens = []; + const linkRE = compile.InlineLexer.rules.link; + const links = tokens.links; tokens.forEach((token, index) => { if (token.type === 'paragraph') { token.text = token.text.replace( new RegExp(linkRE.source, 'g'), (src, filename, href, title) => { - const embed = compiler.compileEmbed(href, title) + const embed = compiler.compileEmbed(href, title); if (embed) { embedTokens.push({ index, - embed - }) + embed, + }); } - return src + return src; } - ) + ); } - }) + }); - let moveIndex = 0 + let moveIndex = 0; walkFetchEmbed({ compile, embedTokens, fetch }, ({ embedToken, token }) => { if (token) { - const index = token.index + moveIndex + const index = token.index + moveIndex; - merge(links, embedToken.links) + merge(links, embedToken.links); tokens = tokens .slice(0, index) - .concat(embedToken, tokens.slice(index + 1)) - moveIndex += embedToken.length - 1 + .concat(embedToken, tokens.slice(index + 1)); + moveIndex += embedToken.length - 1; } else { - cached[raw] = tokens.concat() - tokens.links = cached[raw].links = links - done(tokens) + cached[raw] = tokens.concat(); + tokens.links = cached[raw].links = links; + done(tokens); } - }) + }); } diff --git a/src/core/render/emojify.js b/src/core/render/emojify.js index 95b946a16..7e8d079bb 100644 --- a/src/core/render/emojify.js +++ b/src/core/render/emojify.js @@ -1,12 +1,20 @@ -import {inBrowser} from '../util/env' +import { inBrowser } from '../util/env'; function replace(m, $1) { - return '' + $1 + '' + return ( + '' +
+    $1 +
+    '' + ); } export function emojify(text) { return text - .replace(/<(pre|template|code)[^>]*?>[\s\S]+?<\/(pre|template|code)>/g, m => m.replace(/:/g, '__colon__')) - .replace(/:(\w+?):/ig, (inBrowser && window.emojify) || replace) - .replace(/__colon__/g, ':') + .replace(/<(pre|template|code)[^>]*?>[\s\S]+?<\/(pre|template|code)>/g, m => + m.replace(/:/g, '__colon__') + ) + .replace(/:(\w+?):/gi, (inBrowser && window.emojify) || replace) + .replace(/__colon__/g, ':'); } diff --git a/src/core/render/gen-tree.js b/src/core/render/gen-tree.js index 24dffe70c..cfe49282c 100644 --- a/src/core/render/gen-tree.js +++ b/src/core/render/gen-tree.js @@ -6,25 +6,25 @@ * @return {Array} Headlines */ export function genTree(toc, maxLevel) { - const headlines = [] - const last = {} + const headlines = []; + const last = {}; toc.forEach(headline => { - const level = headline.level || 1 - const len = level - 1 + const level = headline.level || 1; + const len = level - 1; if (level > maxLevel) { - return + return; } if (last[len]) { - last[len].children = (last[len].children || []).concat(headline) + last[len].children = (last[len].children || []).concat(headline); } else { - headlines.push(headline) + headlines.push(headline); } - last[level] = headline - }) + last[level] = headline; + }); - return headlines + return headlines; } diff --git a/src/core/render/index.js b/src/core/render/index.js index cead7ba0b..033837e20 100644 --- a/src/core/render/index.js +++ b/src/core/render/index.js @@ -1,53 +1,54 @@ -import * as dom from '../util/dom' -import * as tpl from './tpl' -import cssVars from '../util/polyfill/css-vars' -import tinydate from 'tinydate' -import {callHook} from '../init/lifecycle' -import {Compiler} from './compiler' -import {getAndActive, sticky} from '../event/sidebar' -import {getPath, isAbsolutePath} from '../router/util' -import {isMobile, inBrowser} from '../util/env' -import {isPrimitive} from '../util/core' -import {scrollActiveSidebar, scroll2Top} from '../event/scroll' -import {prerenderEmbed} from './embed' +/* eslint-disable no-unused-vars */ +import * as dom from '../util/dom'; +import cssVars from '../util/polyfill/css-vars'; +import { callHook } from '../init/lifecycle'; +import { getAndActive, sticky } from '../event/sidebar'; +import { getPath, isAbsolutePath } from '../router/util'; +import { isMobile, inBrowser } from '../util/env'; +import { isPrimitive } from '../util/core'; +import { scrollActiveSidebar, scroll2Top } from '../event/scroll'; +import { Compiler } from './compiler'; +import * as tpl from './tpl'; +import { prerenderEmbed } from './embed'; +import tinydate from 'tinydate'; function executeScript() { const script = dom .findAll('.markdown-section>script') - .filter(s => !/template/.test(s.type))[0] + .filter(s => !/template/.test(s.type))[0]; if (!script) { - return false + return false; } - const code = script.innerText.trim() + const code = script.innerText.trim(); if (!code) { - return false + return false; } setTimeout(_ => { - window.__EXECUTE_RESULT__ = new Function(code)() - }, 0) + window.__EXECUTE_RESULT__ = new Function(code)(); + }, 0); } function formatUpdated(html, updated, fn) { updated = - typeof fn === 'function' ? - fn(updated) : - typeof fn === 'string' ? - tinydate(fn)(new Date(updated)) : - updated + typeof fn === 'function' + ? fn(updated) + : typeof fn === 'string' + ? tinydate(fn)(new Date(updated)) + : updated; - return html.replace(/{docsify-updated}/g, updated) + return html.replace(/{docsify-updated}/g, updated); } function renderMain(html) { if (!html) { - html = '

    404 - Not found

    ' + html = '

    404 - Not found

    '; } - this._renderTo('.markdown-section', html) + this._renderTo('.markdown-section', html); // Render sidebar with the TOC - !this.config.loadSidebar && this._renderSidebar() + !this.config.loadSidebar && this._renderSidebar(); // Execute script if ( @@ -56,229 +57,235 @@ function renderMain(html) { !executeScript() ) { setTimeout(_ => { - const vueVM = window.__EXECUTE_RESULT__ - vueVM && vueVM.$destroy && vueVM.$destroy() - window.__EXECUTE_RESULT__ = new window.Vue().$mount('#main') - }, 0) + const vueVM = window.__EXECUTE_RESULT__; + vueVM && vueVM.$destroy && vueVM.$destroy(); + window.__EXECUTE_RESULT__ = new window.Vue().$mount('#main'); + }, 0); } else { - this.config.executeScript && executeScript() + this.config.executeScript && executeScript(); } } function renderNameLink(vm) { - const el = dom.getNode('.app-name-link') - const nameLink = vm.config.nameLink - const path = vm.route.path + const el = dom.getNode('.app-name-link'); + const nameLink = vm.config.nameLink; + const path = vm.route.path; if (!el) { - return + return; } if (isPrimitive(vm.config.nameLink)) { - el.setAttribute('href', nameLink) + el.setAttribute('href', nameLink); } else if (typeof nameLink === 'object') { - const match = Object.keys(nameLink).filter(key => path.indexOf(key) > -1)[0] + const match = Object.keys(nameLink).filter( + key => path.indexOf(key) > -1 + )[0]; - el.setAttribute('href', nameLink[match]) + el.setAttribute('href', nameLink[match]); } } export function renderMixin(proto) { - proto._renderTo = function (el, content, replace) { - const node = dom.getNode(el) + proto._renderTo = function(el, content, replace) { + const node = dom.getNode(el); if (node) { - node[replace ? 'outerHTML' : 'innerHTML'] = content + node[replace ? 'outerHTML' : 'innerHTML'] = content; } - } + }; - proto._renderSidebar = function (text) { - const {maxLevel, subMaxLevel, loadSidebar} = this.config + proto._renderSidebar = function(text) { + const { maxLevel, subMaxLevel, loadSidebar } = this.config; - this._renderTo('.sidebar-nav', this.compiler.sidebar(text, maxLevel)) - const activeEl = getAndActive(this.router, '.sidebar-nav', true, true) + this._renderTo('.sidebar-nav', this.compiler.sidebar(text, maxLevel)); + const activeEl = getAndActive(this.router, '.sidebar-nav', true, true); if (loadSidebar && activeEl) { activeEl.parentNode.innerHTML += - this.compiler.subSidebar(subMaxLevel) || '' + this.compiler.subSidebar(subMaxLevel) || ''; } else { // Reset toc - this.compiler.subSidebar() + this.compiler.subSidebar(); } // Bind event - this._bindEventOnRendered(activeEl) - } + this._bindEventOnRendered(activeEl); + }; - proto._bindEventOnRendered = function (activeEl) { - const {autoHeader, auto2top} = this.config + proto._bindEventOnRendered = function(activeEl) { + const { autoHeader, auto2top } = this.config; - scrollActiveSidebar(this.router) + scrollActiveSidebar(this.router); if (autoHeader && activeEl) { - const main = dom.getNode('#main') - const firstNode = main.children[0] + const main = dom.getNode('#main'); + const firstNode = main.children[0]; if (firstNode && firstNode.tagName !== 'H1') { - const h1 = this.compiler.header(activeEl.innerText, 1) - const wrapper = dom.create('div', h1) - dom.before(main, wrapper.children[0]) + const h1 = this.compiler.header(activeEl.innerText, 1); + const wrapper = dom.create('div', h1); + dom.before(main, wrapper.children[0]); } } - auto2top && scroll2Top(auto2top) - } + auto2top && scroll2Top(auto2top); + }; - proto._renderNav = function (text) { - text && this._renderTo('nav', this.compiler.compile(text)) + proto._renderNav = function(text) { + text && this._renderTo('nav', this.compiler.compile(text)); if (this.config.loadNavbar) { - getAndActive(this.router, 'nav') + getAndActive(this.router, 'nav'); } - } + }; - proto._renderMain = function (text, opt = {}, next) { + proto._renderMain = function(text, opt = {}, next) { if (!text) { - return renderMain.call(this, text) + return renderMain.call(this, text); } callHook(this, 'beforeEach', text, result => { - let html + let html; const callback = () => { if (opt.updatedAt) { - html = formatUpdated(html, opt.updatedAt, this.config.formatUpdated) + html = formatUpdated(html, opt.updatedAt, this.config.formatUpdated); } - callHook(this, 'afterEach', html, text => renderMain.call(this, text)) - } + callHook(this, 'afterEach', html, text => renderMain.call(this, text)); + }; if (this.isHTML) { - html = this.result = text - callback() - next() + html = this.result = text; + callback(); + next(); } else { prerenderEmbed( { compiler: this.compiler, - raw: result + raw: result, }, tokens => { - html = this.compiler.compile(tokens) - callback() - next() + html = this.compiler.compile(tokens); + callback(); + next(); } - ) + ); } - }) - } + }); + }; - proto._renderCover = function (text, coverOnly) { - const el = dom.getNode('.cover') + proto._renderCover = function(text, coverOnly) { + const el = dom.getNode('.cover'); - dom.toggleClass(dom.getNode('main'), coverOnly ? 'add' : 'remove', 'hidden') + dom.toggleClass( + dom.getNode('main'), + coverOnly ? 'add' : 'remove', + 'hidden' + ); if (!text) { - dom.toggleClass(el, 'remove', 'show') - return + dom.toggleClass(el, 'remove', 'show'); + return; } - dom.toggleClass(el, 'add', 'show') + dom.toggleClass(el, 'add', 'show'); - let html = this.coverIsHTML ? text : this.compiler.cover(text) + let html = this.coverIsHTML ? text : this.compiler.cover(text); const m = html .trim() - .match('

    ([^<]*?)

    $') + .match('

    ([^<]*?)

    $'); if (m) { if (m[2] === 'color') { - el.style.background = m[1] + (m[3] || '') + el.style.background = m[1] + (m[3] || ''); } else { - let path = m[1] + let path = m[1]; - dom.toggleClass(el, 'add', 'has-mask') + dom.toggleClass(el, 'add', 'has-mask'); if (!isAbsolutePath(m[1])) { - path = getPath(this.router.getBasePath(), m[1]) + path = getPath(this.router.getBasePath(), m[1]); } - el.style.backgroundImage = `url(${path})` - el.style.backgroundSize = 'cover' - el.style.backgroundPosition = 'center center' + el.style.backgroundImage = `url(${path})`; + el.style.backgroundSize = 'cover'; + el.style.backgroundPosition = 'center center'; } - html = html.replace(m[0], '') + html = html.replace(m[0], ''); } - this._renderTo('.cover-main', html) - sticky() - } + this._renderTo('.cover-main', html); + sticky(); + }; - proto._updateRender = function () { + proto._updateRender = function() { // Render name link - renderNameLink(this) - } + renderNameLink(this); + }; } export function initRender(vm) { - const config = vm.config + const config = vm.config; // Init markdown compiler - vm.compiler = new Compiler(config, vm.router) + vm.compiler = new Compiler(config, vm.router); if (inBrowser) { - window.__current_docsify_compiler__ = vm.compiler + window.__current_docsify_compiler__ = vm.compiler; } - const id = config.el || '#app' - const navEl = dom.find('nav') || dom.create('nav') + const id = config.el || '#app'; + const navEl = dom.find('nav') || dom.create('nav'); - const el = dom.find(id) - let html = '' - let navAppendToTarget = dom.body + const el = dom.find(id); + let html = ''; + let navAppendToTarget = dom.body; if (el) { if (config.repo) { - html += tpl.corner(config.repo, config.cornerExternalLinkTarge) + html += tpl.corner(config.repo, config.cornerExternalLinkTarge); } if (config.coverpage) { - html += tpl.cover() + html += tpl.cover(); } if (config.logo) { - const isBase64 = /^data:image/.test(config.logo) - const isExternal = /(?:http[s]?:)?\/\//.test(config.logo) - const isRelative = /^\./.test(config.logo) + const isBase64 = /^data:image/.test(config.logo); + const isExternal = /(?:http[s]?:)?\/\//.test(config.logo); + const isRelative = /^\./.test(config.logo); if (!isBase64 && !isExternal && !isRelative) { - config.logo = getPath(vm.router.getBasePath(), config.logo) + config.logo = getPath(vm.router.getBasePath(), config.logo); } } - html += tpl.main(config) + html += tpl.main(config); // Render main app - vm._renderTo(el, html, true) + vm._renderTo(el, html, true); } else { - vm.rendered = true + vm.rendered = true; } if (config.mergeNavbar && isMobile) { - navAppendToTarget = dom.find('.sidebar') + navAppendToTarget = dom.find('.sidebar'); } else { - navEl.classList.add('app-nav') + navEl.classList.add('app-nav'); if (!config.repo) { - navEl.classList.add('no-badge') + navEl.classList.add('no-badge'); } } // Add nav if (config.loadNavbar) { - dom.before(navAppendToTarget, navEl) + dom.before(navAppendToTarget, navEl); } if (config.themeColor) { dom.$.head.appendChild( dom.create('div', tpl.theme(config.themeColor)).firstElementChild - ) + ); // Polyfll - cssVars(config.themeColor) + cssVars(config.themeColor); } - vm._updateRender() - dom.toggleClass(dom.body, 'ready') + vm._updateRender(); + dom.toggleClass(dom.body, 'ready'); } diff --git a/src/core/render/progressbar.js b/src/core/render/progressbar.js index 61a2aae22..762ec6289 100644 --- a/src/core/render/progressbar.js +++ b/src/core/render/progressbar.js @@ -1,42 +1,43 @@ -import * as dom from '../util/dom' +import * as dom from '../util/dom'; -let barEl -let timeId +let barEl; +let timeId; /** * Init progress component */ function init() { - const div = dom.create('div') + const div = dom.create('div'); - div.classList.add('progress') - dom.appendTo(dom.body, div) - barEl = div + div.classList.add('progress'); + dom.appendTo(dom.body, div); + barEl = div; } /** * Render progress bar */ -export default function ({loaded, total, step}) { - let num +export default function({ loaded, total, step }) { + let num; - !barEl && init() + !barEl && init(); if (step) { - num = parseInt(barEl.style.width || 0, 10) + step - num = num > 80 ? 80 : num + num = parseInt(barEl.style.width || 0, 10) + step; + num = num > 80 ? 80 : num; } else { - num = Math.floor(loaded / total * 100) + num = Math.floor((loaded / total) * 100); } - barEl.style.opacity = 1 - barEl.style.width = num >= 95 ? '100%' : num + '%' + barEl.style.opacity = 1; + barEl.style.width = num >= 95 ? '100%' : num + '%'; if (num >= 95) { - clearTimeout(timeId) + clearTimeout(timeId); + // eslint-disable-next-line no-unused-vars timeId = setTimeout(_ => { - barEl.style.opacity = 0 - barEl.style.width = '0%' - }, 200) + barEl.style.opacity = 0; + barEl.style.width = '0%'; + }, 200); } } diff --git a/src/core/render/slugify.js b/src/core/render/slugify.js index 948c81a8f..c6bda03dc 100644 --- a/src/core/render/slugify.js +++ b/src/core/render/slugify.js @@ -1,15 +1,15 @@ -import {hasOwn} from '../util/core' +import { hasOwn } from '../util/core'; -let cache = {} -const re = /[\u2000-\u206F\u2E00-\u2E7F\\'!"#$%&()*+,./:;<=>?@[\]^`{|}~]/g +let cache = {}; +const re = /[\u2000-\u206F\u2E00-\u2E7F\\'!"#$%&()*+,./:;<=>?@[\]^`{|}~]/g; function lower(string) { - return string.toLowerCase() + return string.toLowerCase(); } export function slugify(str) { if (typeof str !== 'string') { - return '' + return ''; } let slug = str @@ -18,19 +18,19 @@ export function slugify(str) { .replace(/<[^>\d]+>/g, '') .replace(re, '') .replace(/\s/g, '-') - .replace(/-+/g, '-') - let count = cache[slug] + .replace(/-+/g, '-'); + let count = cache[slug]; - count = hasOwn.call(cache, slug) ? count + 1 : 0 - cache[slug] = count + count = hasOwn.call(cache, slug) ? count + 1 : 0; + cache[slug] = count; if (count) { - slug = slug + '-' + count + slug = slug + '-' + count; } - return slug + return slug; } -slugify.clear = function () { - cache = {} -} +slugify.clear = function() { + cache = {}; +}; diff --git a/src/core/render/tpl.js b/src/core/render/tpl.js index 41f63a75b..85efa436c 100644 --- a/src/core/render/tpl.js +++ b/src/core/render/tpl.js @@ -1,4 +1,4 @@ -import { isMobile } from '../util/env' +import { isMobile } from '../util/env'; /** * Render github corner * @param {Object} data URL for the View Source on Github link @@ -7,16 +7,16 @@ import { isMobile } from '../util/env' */ export function corner(data, cornerExternalLinkTarge) { if (!data) { - return '' + return ''; } if (!/\/\//.test(data)) { - data = 'https://github.com/' + data + data = 'https://github.com/' + data; } - data = data.replace(/^git\+/, '') + data = data.replace(/^git\+/, ''); // Double check - cornerExternalLinkTarge = cornerExternalLinkTarge || '_blank' + cornerExternalLinkTarge = cornerExternalLinkTarge || '_blank'; return ( `` + @@ -26,7 +26,7 @@ export function corner(data, cornerExternalLinkTarge) { '' + '' + '' - ) + ); } /** @@ -35,7 +35,7 @@ export function corner(data, cornerExternalLinkTarge) { * @returns {String} HTML of the main content */ export function main(config) { - const name = config.name ? config.name : '' + const name = config.name ? config.name : ''; const aside = '' + '' + ''; return ( (isMobile ? `${aside}
    ` : `
    ${aside}`) + @@ -58,7 +58,7 @@ export function main(config) { '
    ' + '' + '
    ' - ) + ); } /** @@ -66,18 +66,18 @@ export function main(config) { * @returns {String} Cover page */ export function cover() { - const SL = ', 100%, 85%' + 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%)` + `hsl(${Math.floor(Math.random() * 255) + SL}) 100%)`; return ( `
    ` + '
    ' + '
    ' + '
    ' - ) + ); } /** @@ -88,23 +88,23 @@ export function cover() { */ export function tree(toc, tpl = '
      {inner}
    ') { if (!toc || !toc.length) { - return '' + return ''; } - let innerHTML = '' + let innerHTML = ''; toc.forEach(node => { - innerHTML += `
  • ${node.title}
  • ` + innerHTML += `
  • ${node.title}
  • `; if (node.children) { - innerHTML += tree(node.children, tpl) + innerHTML += tree(node.children, tpl); } - }) - return tpl.replace('{inner}', innerHTML) + }); + return tpl.replace('{inner}', innerHTML); } export function helper(className, content) { - return `

    ${content.slice(5).trim()}

    ` + return `

    ${content.slice(5).trim()}

    `; } export function theme(color) { - return `` + return ``; } diff --git a/src/core/router/history/abstract.js b/src/core/router/history/abstract.js index 2c0bd951d..02881f165 100644 --- a/src/core/router/history/abstract.js +++ b/src/core/router/history/abstract.js @@ -1,25 +1,25 @@ -import {History} from './base' -import {parseQuery} from '../util' +import { parseQuery } from '../util'; +import { History } from './base'; export class AbstractHistory extends History { constructor(config) { - super(config) - this.mode = 'abstract' + super(config); + this.mode = 'abstract'; } parse(path) { - let query = '' + let query = ''; - const queryIndex = path.indexOf('?') + const queryIndex = path.indexOf('?'); if (queryIndex >= 0) { - query = path.slice(queryIndex + 1) - path = path.slice(0, queryIndex) + query = path.slice(queryIndex + 1); + path = path.slice(0, queryIndex); } return { path, file: this.getFile(path), - query: parseQuery(query) - } + query: parseQuery(query), + }; } } diff --git a/src/core/router/history/base.js b/src/core/router/history/base.js index 4c570df1c..68c98b7f5 100644 --- a/src/core/router/history/base.js +++ b/src/core/router/history/base.js @@ -4,57 +4,59 @@ import { stringifyQuery, cleanPath, replaceSlug, - resolvePath -} from '../util' -import {noop, merge} from '../../util/core' + resolvePath, +} from '../util'; +import { noop, merge } from '../../util/core'; -const cached = {} +const cached = {}; function getAlias(path, alias, last) { const match = Object.keys(alias).filter(key => { - const re = cached[key] || (cached[key] = new RegExp(`^${key}$`)) - return re.test(path) && path !== last - })[0] + const re = cached[key] || (cached[key] = new RegExp(`^${key}$`)); + return re.test(path) && path !== last; + })[0]; - return match ? - getAlias(path.replace(cached[match], alias[match]), alias, path) : - path + return match + ? getAlias(path.replace(cached[match], alias[match]), alias, path) + : path; } function getFileName(path, ext) { - return new RegExp(`\\.(${ext.replace(/^\./, '')}|html)$`, 'g').test(path) ? - path : - /\/$/g.test(path) ? `${path}README${ext}` : `${path}${ext}` + return new RegExp(`\\.(${ext.replace(/^\./, '')}|html)$`, 'g').test(path) + ? path + : /\/$/g.test(path) + ? `${path}README${ext}` + : `${path}${ext}`; } export class History { constructor(config) { - this.config = config + this.config = config; } getBasePath() { - return this.config.basePath + return this.config.basePath; } getFile(path = this.getCurrentPath(), isRelative) { - const {config} = this - const base = this.getBasePath() - const ext = typeof config.ext === 'string' ? config.ext : '.md' + const { config } = this; + const base = this.getBasePath(); + const ext = typeof config.ext === 'string' ? config.ext : '.md'; - path = config.alias ? getAlias(path, config.alias) : path - path = getFileName(path, ext) - path = path === `/README${ext}` ? config.homepage || path : path - path = isAbsolutePath(path) ? path : getPath(base, path) + path = config.alias ? getAlias(path, config.alias) : path; + path = getFileName(path, ext); + path = path === `/README${ext}` ? config.homepage || path : path; + path = isAbsolutePath(path) ? path : getPath(base, path); if (isRelative) { - path = path.replace(new RegExp(`^${base}`), '') + path = path.replace(new RegExp(`^${base}`), ''); } - return path + return path; } onchange(cb = noop) { - cb() + cb(); } getCurrentPath() {} @@ -64,24 +66,28 @@ export class History { parse() {} toURL(path, params, currentRoute) { - const local = currentRoute && path[0] === '#' - const route = this.parse(replaceSlug(path)) + const local = currentRoute && path[0] === '#'; + const route = this.parse(replaceSlug(path)); - route.query = merge({}, route.query, params) - path = route.path + stringifyQuery(route.query) - path = path.replace(/\.md(\?)|\.md$/, '$1') + route.query = merge({}, route.query, params); + path = route.path + stringifyQuery(route.query); + path = path.replace(/\.md(\?)|\.md$/, '$1'); if (local) { - const idIndex = currentRoute.indexOf('?') + const idIndex = currentRoute.indexOf('?'); path = - (idIndex > 0 ? currentRoute.substring(0, idIndex) : currentRoute) + path + (idIndex > 0 ? currentRoute.substring(0, idIndex) : currentRoute) + + path; } if (this.config.relativePath && path.indexOf('/') !== 0) { - const currentDir = currentRoute.substring(0, currentRoute.lastIndexOf('/') + 1) - return cleanPath(resolvePath(currentDir + path)) + const currentDir = currentRoute.substring( + 0, + currentRoute.lastIndexOf('/') + 1 + ); + return cleanPath(resolvePath(currentDir + path)); } - return cleanPath('/' + path) + return cleanPath('/' + path); } } diff --git a/src/core/router/history/hash.js b/src/core/router/history/hash.js index 4e1b1a361..1e099eacf 100644 --- a/src/core/router/history/hash.js +++ b/src/core/router/history/hash.js @@ -1,48 +1,48 @@ -import { History } from './base' -import { noop } from '../../util/core' -import { on } from '../../util/dom' -import { parseQuery, cleanPath, replaceSlug } from '../util' +import { noop } from '../../util/core'; +import { on } from '../../util/dom'; +import { parseQuery, cleanPath, replaceSlug } from '../util'; +import { History } from './base'; function replaceHash(path) { - const i = location.href.indexOf('#') - location.replace(location.href.slice(0, i >= 0 ? i : 0) + '#' + path) + const i = location.href.indexOf('#'); + location.replace(location.href.slice(0, i >= 0 ? i : 0) + '#' + path); } export class HashHistory extends History { constructor(config) { - super(config) - this.mode = 'hash' + super(config); + this.mode = 'hash'; } getBasePath() { - const path = window.location.pathname || '' - const base = this.config.basePath + const path = window.location.pathname || ''; + const base = this.config.basePath; - return /^(\/|https?:)/g.test(base) ? base : cleanPath(path + '/' + base) + return /^(\/|https?:)/g.test(base) ? base : cleanPath(path + '/' + base); } getCurrentPath() { // We can't use location.hash here because it's not // consistent across browsers - Firefox will pre-decode it! - const href = location.href - const index = href.indexOf('#') - return index === -1 ? '' : href.slice(index + 1) + const href = location.href; + const index = href.indexOf('#'); + return index === -1 ? '' : href.slice(index + 1); } onchange(cb = noop) { - on('hashchange', cb) + on('hashchange', cb); } normalize() { - let path = this.getCurrentPath() + let path = this.getCurrentPath(); - path = replaceSlug(path) + path = replaceSlug(path); if (path.charAt(0) === '/') { - return replaceHash(path) + return replaceHash(path); } - replaceHash('/' + path) + replaceHash('/' + path); } /** @@ -51,27 +51,27 @@ export class HashHistory extends History { * @return {object} { path, query } */ parse(path = location.href) { - let query = '' + let query = ''; - const hashIndex = path.indexOf('#') + const hashIndex = path.indexOf('#'); if (hashIndex >= 0) { - path = path.slice(hashIndex + 1) + path = path.slice(hashIndex + 1); } - const queryIndex = path.indexOf('?') + const queryIndex = path.indexOf('?'); if (queryIndex >= 0) { - query = path.slice(queryIndex + 1) - path = path.slice(0, queryIndex) + query = path.slice(queryIndex + 1); + path = path.slice(0, queryIndex); } return { path, file: this.getFile(path, true), - query: parseQuery(query) - } + query: parseQuery(query), + }; } toURL(path, params, currentRoute) { - return '#' + super.toURL(path, params, currentRoute) + return '#' + super.toURL(path, params, currentRoute); } } diff --git a/src/core/router/history/html5.js b/src/core/router/history/html5.js index a3bda1391..4ae3b8d83 100644 --- a/src/core/router/history/html5.js +++ b/src/core/router/history/html5.js @@ -1,38 +1,38 @@ -import { History } from './base' -import { noop } from '../../util/core' -import { on } from '../../util/dom' -import { parseQuery, getPath } from '../util' +import { noop } from '../../util/core'; +import { on } from '../../util/dom'; +import { parseQuery, getPath } from '../util'; +import { History } from './base'; export class HTML5History extends History { constructor(config) { - super(config) - this.mode = 'history' + super(config); + this.mode = 'history'; } getCurrentPath() { - const base = this.getBasePath() - let path = window.location.pathname + const base = this.getBasePath(); + let path = window.location.pathname; if (base && path.indexOf(base) === 0) { - path = path.slice(base.length) + path = path.slice(base.length); } - return (path || '/') + window.location.search + window.location.hash + return (path || '/') + window.location.search + window.location.hash; } onchange(cb = noop) { on('click', e => { - const el = e.target.tagName === 'A' ? e.target : e.target.parentNode + const el = e.target.tagName === 'A' ? e.target : e.target.parentNode; if (el.tagName === 'A' && !/_blank/.test(el.target)) { - e.preventDefault() - const url = el.href - window.history.pushState({ key: url }, '', url) - cb() + e.preventDefault(); + const url = el.href; + window.history.pushState({ key: url }, '', url); + cb(); } - }) + }); - on('popstate', cb) + on('popstate', cb); } /** @@ -41,25 +41,25 @@ export class HTML5History extends History { * @return {object} { path, query } */ parse(path = location.href) { - let query = '' + let query = ''; - const queryIndex = path.indexOf('?') + const queryIndex = path.indexOf('?'); if (queryIndex >= 0) { - query = path.slice(queryIndex + 1) - path = path.slice(0, queryIndex) + query = path.slice(queryIndex + 1); + path = path.slice(0, queryIndex); } - const base = getPath(location.origin) - const baseIndex = path.indexOf(base) + const base = getPath(location.origin); + const baseIndex = path.indexOf(base); if (baseIndex > -1) { - path = path.slice(baseIndex + base.length) + path = path.slice(baseIndex + base.length); } return { path, file: this.getFile(path), - query: parseQuery(query) - } + query: parseQuery(query), + }; } } diff --git a/src/core/router/index.js b/src/core/router/index.js index 943fe6c3e..6967b20b8 100644 --- a/src/core/router/index.js +++ b/src/core/router/index.js @@ -1,45 +1,46 @@ -import {HashHistory} from './history/hash' -import {HTML5History} from './history/html5' -import {supportsPushState} from '../util/env' -import * as dom from '../util/dom' +import { supportsPushState } from '../util/env'; +import * as dom from '../util/dom'; +import { HashHistory } from './history/hash'; +import { HTML5History } from './history/html5'; export function routerMixin(proto) { - proto.route = {} + proto.route = {}; } -let lastRoute = {} +let lastRoute = {}; function updateRender(vm) { - vm.router.normalize() - vm.route = vm.router.parse() - dom.body.setAttribute('data-page', vm.route.file) + vm.router.normalize(); + vm.route = vm.router.parse(); + dom.body.setAttribute('data-page', vm.route.file); } export function initRouter(vm) { - const config = vm.config - const mode = config.routerMode || 'hash' - let router + const config = vm.config; + const mode = config.routerMode || 'hash'; + let router; if (mode === 'history' && supportsPushState) { - router = new HTML5History(config) + router = new HTML5History(config); } else { - router = new HashHistory(config) + router = new HashHistory(config); } - vm.router = router - updateRender(vm) - lastRoute = vm.route + vm.router = router; + updateRender(vm); + lastRoute = vm.route; + // eslint-disable-next-line no-unused-vars router.onchange(_ => { - updateRender(vm) - vm._updateRender() + updateRender(vm); + vm._updateRender(); if (lastRoute.path === vm.route.path) { - vm.$resetEvents() - return + vm.$resetEvents(); + return; } - vm.$fetch() - lastRoute = vm.route - }) + vm.$fetch(); + lastRoute = vm.route; + }); } diff --git a/src/core/router/util.js b/src/core/router/util.js index 8b3ce7b4a..ba2eed8a1 100644 --- a/src/core/router/util.js +++ b/src/core/router/util.js @@ -1,81 +1,81 @@ -import { cached } from '../util/core' +import { cached } from '../util/core'; -const decode = decodeURIComponent -const encode = encodeURIComponent +const decode = decodeURIComponent; +const encode = encodeURIComponent; export function parseQuery(query) { - const res = {} + const res = {}; - query = query.trim().replace(/^(\?|#|&)/, '') + query = query.trim().replace(/^(\?|#|&)/, ''); if (!query) { - return res + return res; } // Simple parse - query.split('&').forEach(function (param) { - const parts = param.replace(/\+/g, ' ').split('=') + query.split('&').forEach(function(param) { + const parts = param.replace(/\+/g, ' ').split('='); - res[parts[0]] = parts[1] && decode(parts[1]) - }) + res[parts[0]] = parts[1] && decode(parts[1]); + }); - return res + return res; } export function stringifyQuery(obj, ignores = []) { - const qs = [] + const qs = []; for (const key in obj) { if (ignores.indexOf(key) > -1) { - continue + continue; } qs.push( - obj[key] ? - `${encode(key)}=${encode(obj[key])}`.toLowerCase() : - encode(key) - ) + obj[key] + ? `${encode(key)}=${encode(obj[key])}`.toLowerCase() + : encode(key) + ); } - return qs.length ? `?${qs.join('&')}` : '' + return qs.length ? `?${qs.join('&')}` : ''; } export const isAbsolutePath = cached(path => { - return /(:|(\/{2}))/g.test(path) -}) + return /(:|(\/{2}))/g.test(path); +}); export const getParentPath = cached(path => { if (/\/$/g.test(path)) { - return path + return path; } - const matchingParts = path.match(/(\S*\/)[^/]+$/) - return matchingParts ? matchingParts[1] : '' -}) + const matchingParts = path.match(/(\S*\/)[^/]+$/); + return matchingParts ? matchingParts[1] : ''; +}); export const cleanPath = cached(path => { - return path.replace(/^\/+/, '/').replace(/([^:])\/{2,}/g, '$1/') -}) + return path.replace(/^\/+/, '/').replace(/([^:])\/{2,}/g, '$1/'); +}); export const resolvePath = cached(path => { - const segments = path.replace(/^\//, '').split('/') - let resolved = [] + const segments = path.replace(/^\//, '').split('/'); + let resolved = []; for (let i = 0, len = segments.length; i < len; i++) { - const segment = segments[i] + const segment = segments[i]; if (segment === '..') { - resolved.pop() + resolved.pop(); } else if (segment !== '.') { - resolved.push(segment) + resolved.push(segment); } } - return '/' + resolved.join('/') -}) + return '/' + resolved.join('/'); +}); export function getPath(...args) { - return cleanPath(args.join('/')) + return cleanPath(args.join('/')); } export const replaceSlug = cached(path => { - return path.replace('#', '?id=') -}) + return path.replace('#', '?id='); +}); diff --git a/src/core/util/core.js b/src/core/util/core.js index 2d4f20c9b..9d2638412 100644 --- a/src/core/util/core.js +++ b/src/core/util/core.js @@ -5,22 +5,22 @@ */ export function cached(fn) { - const cache = Object.create(null) - return function (str) { - const key = isPrimitive(str) ? str : JSON.stringify(str) - const hit = cache[key] - return hit || (cache[key] = fn(str)) - } + const cache = Object.create(null); + return function(str) { + const key = isPrimitive(str) ? str : JSON.stringify(str); + const hit = cache[key]; + return hit || (cache[key] = fn(str)); + }; } /** * Hyphenate a camelCase string. */ export const hyphenate = cached(str => { - return str.replace(/([A-Z])/g, m => '-' + m.toLowerCase()) -}) + return str.replace(/([A-Z])/g, m => '-' + m.toLowerCase()); +}); -export const hasOwn = Object.prototype.hasOwnProperty +export const hasOwn = Object.prototype.hasOwnProperty; /** * Simple Object.assign polyfill @@ -29,19 +29,19 @@ export const hasOwn = Object.prototype.hasOwnProperty */ export const merge = Object.assign || - function (to) { + function(to) { for (let i = 1; i < arguments.length; i++) { - const from = Object(arguments[i]) + const from = Object(arguments[i]); for (const key in from) { if (hasOwn.call(from, key)) { - to[key] = from[key] + to[key] = from[key]; } } } - return to - } + return to; + }; /** * Check if value is primitive @@ -49,14 +49,14 @@ export const merge = * @returns {Boolean} Result of the check */ export function isPrimitive(value) { - return typeof value === 'string' || typeof value === 'number' + return typeof value === 'string' || typeof value === 'number'; } /** * Performs no operation. * @void */ -export function noop() { } +export function noop() {} /** * Check if value is function @@ -64,6 +64,5 @@ export function noop() { } * @returns {Boolean} True if the passed-in value is a function */ export function isFn(obj) { - return typeof obj === 'function' + return typeof obj === 'function'; } - diff --git a/src/core/util/dom.js b/src/core/util/dom.js index 3d529bba5..b17628636 100644 --- a/src/core/util/dom.js +++ b/src/core/util/dom.js @@ -1,7 +1,7 @@ -import { isFn } from '../util/core' -import { inBrowser } from './env' +import { isFn } from '../util/core'; +import { inBrowser } from './env'; -const cacheNode = {} +const cacheNode = {}; /** * Get Node @@ -12,20 +12,20 @@ const cacheNode = {} export function getNode(el, noCache = false) { if (typeof el === 'string') { if (typeof window.Vue !== 'undefined') { - return find(el) + return find(el); } - el = noCache ? find(el) : cacheNode[el] || (cacheNode[el] = find(el)) + el = noCache ? find(el) : cacheNode[el] || (cacheNode[el] = find(el)); } - return el + return el; } -export const $ = inBrowser && document +export const $ = inBrowser && document; -export const body = inBrowser && $.body +export const body = inBrowser && $.body; -export const head = inBrowser && $.head +export const head = inBrowser && $.head; /** * Find elements @@ -37,7 +37,7 @@ export const head = inBrowser && $.head * find(nav, 'a') => nav.querySelector('a') */ export function find(el, node) { - return node ? el.querySelector(node) : $.querySelector(el) + return node ? el.querySelector(node) : $.querySelector(el); } /** @@ -52,36 +52,36 @@ export function find(el, node) { export function findAll(el, node) { return [].slice.call( node ? el.querySelectorAll(node) : $.querySelectorAll(el) - ) + ); } export function create(node, tpl) { - node = $.createElement(node) + node = $.createElement(node); if (tpl) { - node.innerHTML = tpl + node.innerHTML = tpl; } - return node + return node; } export function appendTo(target, el) { - return target.appendChild(el) + return target.appendChild(el); } export function before(target, el) { - return target.insertBefore(el, target.children[0]) + return target.insertBefore(el, target.children[0]); } export function on(el, type, handler) { - isFn(type) ? - window.addEventListener(el, type) : - el.addEventListener(type, handler) + isFn(type) + ? window.addEventListener(el, type) + : el.addEventListener(type, handler); } export function off(el, type, handler) { - isFn(type) ? - window.removeEventListener(el, type) : - el.removeEventListener(type, handler) + isFn(type) + ? window.removeEventListener(el, type) + : el.removeEventListener(type, handler); } /** @@ -95,9 +95,9 @@ export function off(el, type, handler) { * toggleClass(el, 'add', 'active') => el.classList.add('active') */ export function toggleClass(el, type, val) { - el && el.classList[val ? type : 'toggle'](val || type) + el && el.classList[val ? type : 'toggle'](val || type); } export function style(content) { - appendTo(head, create('style', content)) + appendTo(head, create('style', content)); } diff --git a/src/core/util/env.js b/src/core/util/env.js index cd5163558..015179c58 100644 --- a/src/core/util/env.js +++ b/src/core/util/env.js @@ -1,13 +1,13 @@ -export const inBrowser = !process.env.SSR +export const inBrowser = !process.env.SSR; -export const isMobile = inBrowser && document.body.clientWidth <= 600 +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 () { + (function() { // Borrowed wholesale from https://github.com/defunkt/jquery-pjax return ( window.history && @@ -17,5 +17,5 @@ export const supportsPushState = !navigator.userAgent.match( /((iPod|iPhone|iPad).+\bOS\s+[1-4]\D|WebApps\/.+CFNetwork)/ ) - ) - })() + ); + })(); diff --git a/src/core/util/index.js b/src/core/util/index.js index eba6598f5..444ea9d47 100644 --- a/src/core/util/index.js +++ b/src/core/util/index.js @@ -1,3 +1,3 @@ -export * from './core' -export * from './env' -export * from '../router/util' +export * from './core'; +export * from './env'; +export * from '../router/util'; diff --git a/src/core/util/polyfill/css-vars.js b/src/core/util/polyfill/css-vars.js index fb3a80a2b..34e201f28 100644 --- a/src/core/util/polyfill/css-vars.js +++ b/src/core/util/polyfill/css-vars.js @@ -1,36 +1,36 @@ -import * as dom from '../dom' -import {get} from '../../fetch/ajax' +import * as dom from '../dom'; +import { get } from '../../fetch/ajax'; function replaceVar(block, color) { block.innerHTML = block.innerHTML.replace( /var\(\s*--theme-color.*?\)/g, color - ) + ); } -export default function (color) { +export default function(color) { // Variable support if (window.CSS && window.CSS.supports && window.CSS.supports('(--v:red)')) { - return + return; } const styleBlocks = dom.findAll('style:not(.inserted),link'); [].forEach.call(styleBlocks, block => { if (block.nodeName === 'STYLE') { - replaceVar(block, color) + replaceVar(block, color); } else if (block.nodeName === 'LINK') { - const href = block.getAttribute('href') + const href = block.getAttribute('href'); if (!/\.css$/.test(href)) { - return + return; } get(href).then(res => { - const style = dom.create('style', res) + const style = dom.create('style', res); - dom.head.appendChild(style) - replaceVar(style, color) - }) + dom.head.appendChild(style); + replaceVar(style, color); + }); } - }) + }); } diff --git a/src/plugins/disqus.js b/src/plugins/disqus.js index dba7aef82..4355692ec 100644 --- a/src/plugins/disqus.js +++ b/src/plugins/disqus.js @@ -1,51 +1,52 @@ -const fixedPath = location.href.replace('/-/', '/#/') +/* eslint-disable no-unused-vars */ +const fixedPath = location.href.replace('/-/', '/#/'); if (fixedPath !== location.href) { - location.href = fixedPath + location.href = fixedPath; } function install(hook, vm) { - const dom = Docsify.dom - const disqus = vm.config.disqus + const dom = Docsify.dom; + const disqus = vm.config.disqus; if (!disqus) { - throw Error('$docsify.disqus is required') + throw Error('$docsify.disqus is required'); } hook.init(_ => { - const script = dom.create('script') + const script = dom.create('script'); - script.async = true - script.src = `https://${disqus}.disqus.com/embed.js` - script.setAttribute('data-timestamp', Number(new Date())) - dom.appendTo(dom.body, script) - }) + script.async = true; + script.src = `https://${disqus}.disqus.com/embed.js`; + script.setAttribute('data-timestamp', Number(new Date())); + dom.appendTo(dom.body, script); + }); hook.mounted(_ => { - const div = dom.create('div') - div.id = 'disqus_thread' - const main = dom.getNode('#main') - div.style = `width: ${main.clientWidth}px; margin: 0 auto 20px;` - dom.appendTo(dom.find('.content'), div) + const div = dom.create('div'); + div.id = 'disqus_thread'; + const main = dom.getNode('#main'); + div.style = `width: ${main.clientWidth}px; margin: 0 auto 20px;`; + dom.appendTo(dom.find('.content'), div); // eslint-disable-next-line window.disqus_config = function() { - this.page.url = location.origin + '/-' + vm.route.path - this.page.identifier = vm.route.path - this.page.title = document.title - } - }) + this.page.url = location.origin + '/-' + vm.route.path; + this.page.identifier = vm.route.path; + this.page.title = document.title; + }; + }); hook.doneEach(_ => { if (typeof window.DISQUS !== 'undefined') { window.DISQUS.reset({ reload: true, - config: function () { - this.page.url = location.origin + '/-' + vm.route.path - this.page.identifier = vm.route.path - this.page.title = document.title - } - }) + config: function() { + this.page.url = location.origin + '/-' + vm.route.path; + this.page.identifier = vm.route.path; + this.page.title = document.title; + }, + }); } - }) + }); } -$docsify.plugins = [].concat(install, $docsify.plugins) +$docsify.plugins = [].concat(install, $docsify.plugins); diff --git a/src/plugins/emoji.js b/src/plugins/emoji.js index e65e42c4b..2898c3d04 100644 --- a/src/plugins/emoji.js +++ b/src/plugins/emoji.js @@ -1508,17 +1508,17 @@ const AllGithubEmoji = [ 'zero', 'zimbabwe', 'zipper_mouth_face', - 'zzz' -] + 'zzz', +]; // Emoji from All-Github-Emoji-Icons // https://github.com/scotch-io/All-Github-Emoji-Icons -window.emojify = function (match, $1) { - return AllGithubEmoji.indexOf($1) === -1 ? - match : - '' +
         $1 +
-        '' -} + '" />'; +}; diff --git a/src/plugins/external-script.js b/src/plugins/external-script.js index 2954030a1..f8bf9175f 100644 --- a/src/plugins/external-script.js +++ b/src/plugins/external-script.js @@ -1,25 +1,25 @@ function handleExternalScript() { - const container = Docsify.dom.getNode('#main') - const scripts = Docsify.dom.findAll(container, 'script') + const container = Docsify.dom.getNode('#main'); + const scripts = Docsify.dom.findAll(container, 'script'); - for (let i = scripts.length; i--;) { - const script = scripts[i] + for (let i = scripts.length; i--; ) { + const script = scripts[i]; if (script && script.src) { - const newScript = document.createElement('script') + const newScript = document.createElement('script'); Array.prototype.slice.call(script.attributes).forEach(attribute => { - newScript[attribute.name] = attribute.value - }) + newScript[attribute.name] = attribute.value; + }); - script.parentNode.insertBefore(newScript, script) - script.parentNode.removeChild(script) + script.parentNode.insertBefore(newScript, script); + script.parentNode.removeChild(script); } } } -const install = function (hook) { - hook.doneEach(handleExternalScript) -} +const install = function(hook) { + hook.doneEach(handleExternalScript); +}; -window.$docsify.plugins = [].concat(install, window.$docsify.plugins) +window.$docsify.plugins = [].concat(install, window.$docsify.plugins); diff --git a/src/plugins/front-matter/index.js b/src/plugins/front-matter/index.js index cb90ed91f..e91c4efc3 100644 --- a/src/plugins/front-matter/index.js +++ b/src/plugins/front-matter/index.js @@ -1,13 +1,13 @@ -import parser from './parser' +import parser from './parser'; -const install = function (hook, vm) { +const install = function(hook, vm) { hook.beforeEach(content => { - const {attributes, body} = parser(content) + const { attributes, body } = parser(content); - vm.frontmatter = attributes + vm.frontmatter = attributes; - return body - }) -} + return body; + }); +}; -$docsify.plugins = [].concat(install, $docsify.plugins) +$docsify.plugins = [].concat(install, $docsify.plugins); diff --git a/src/plugins/ga.js b/src/plugins/ga.js index b327d9b5d..2a6474ac0 100644 --- a/src/plugins/ga.js +++ b/src/plugins/ga.js @@ -1,39 +1,40 @@ +/* eslint-disable no-console */ // From https://github.com/egoist/vue-ga/blob/master/src/index.js function appendScript() { - const script = document.createElement('script') - script.async = true - script.src = 'https://www.google-analytics.com/analytics.js' - document.body.appendChild(script) + const script = document.createElement('script'); + script.async = true; + script.src = 'https://www.google-analytics.com/analytics.js'; + document.body.appendChild(script); } function init(id) { - appendScript() + appendScript(); window.ga = window.ga || - function () { - (window.ga.q = window.ga.q || []).push(arguments) - } + function() { + (window.ga.q = window.ga.q || []).push(arguments); + }; - window.ga.l = Number(new Date()) - window.ga('create', id, 'auto') + window.ga.l = Number(new Date()); + window.ga('create', id, 'auto'); } function collect() { if (!window.ga) { - init($docsify.ga) + init($docsify.ga); } - window.ga('set', 'page', location.hash) - window.ga('send', 'pageview') + window.ga('set', 'page', location.hash); + window.ga('send', 'pageview'); } -const install = function (hook) { +const install = function(hook) { if (!$docsify.ga) { - console.error('[Docsify] ga is required.') - return + console.error('[Docsify] ga is required.'); + return; } - hook.beforeEach(collect) -} + hook.beforeEach(collect); +}; -$docsify.plugins = [].concat(install, $docsify.plugins) +$docsify.plugins = [].concat(install, $docsify.plugins); diff --git a/src/plugins/gitalk.js b/src/plugins/gitalk.js index 8ba9acec6..b8d5f46e4 100644 --- a/src/plugins/gitalk.js +++ b/src/plugins/gitalk.js @@ -1,23 +1,24 @@ +/* eslint-disable no-unused-vars */ function install(hook) { - const dom = Docsify.dom + const dom = Docsify.dom; hook.mounted(_ => { - const div = dom.create('div') - div.id = 'gitalk-container' - const main = dom.getNode('#main') - div.style = `width: ${main.clientWidth}px; margin: 0 auto 20px;` - dom.appendTo(dom.find('.content'), div) - }) + const div = dom.create('div'); + div.id = 'gitalk-container'; + const main = dom.getNode('#main'); + div.style = `width: ${main.clientWidth}px; margin: 0 auto 20px;`; + dom.appendTo(dom.find('.content'), div); + }); hook.doneEach(_ => { - const el = document.getElementById('gitalk-container') + const el = document.getElementById('gitalk-container'); while (el.hasChildNodes()) { - el.removeChild(el.firstChild) + el.removeChild(el.firstChild); } // eslint-disable-next-line - gitalk.render('gitalk-container') - }) + gitalk.render('gitalk-container'); + }); } -$docsify.plugins = [].concat(install, $docsify.plugins) +$docsify.plugins = [].concat(install, $docsify.plugins); diff --git a/src/plugins/matomo.js b/src/plugins/matomo.js index a27de2a06..2074be767 100644 --- a/src/plugins/matomo.js +++ b/src/plugins/matomo.js @@ -1,38 +1,39 @@ function appendScript(options) { - const script = document.createElement('script') - script.async = true - script.src = options.host + '/matomo.js' - document.body.appendChild(script) + const script = document.createElement('script'); + script.async = true; + script.src = options.host + '/matomo.js'; + document.body.appendChild(script); } function init(options) { - window._paq = window._paq || [] - window._paq.push(['trackPageView']) - window._paq.push(['enableLinkTracking']) - setTimeout(function () { - appendScript(options) - window._paq.push(['setTrackerUrl', options.host + '/matomo.php']) - window._paq.push(['setSiteId', String(options.id)]) - }, 0) + window._paq = window._paq || []; + window._paq.push(['trackPageView']); + window._paq.push(['enableLinkTracking']); + setTimeout(function() { + appendScript(options); + window._paq.push(['setTrackerUrl', options.host + '/matomo.php']); + window._paq.push(['setSiteId', String(options.id)]); + }, 0); } function collect() { if (!window._paq) { - init($docsify.matomo) + init($docsify.matomo); } - window._paq.push(['setCustomUrl', window.location.hash.substr(1)]) - window._paq.push(['setDocumentTitle', document.title]) - window._paq.push(['trackPageView']) + window._paq.push(['setCustomUrl', window.location.hash.substr(1)]); + window._paq.push(['setDocumentTitle', document.title]); + window._paq.push(['trackPageView']); } -const install = function (hook) { +const install = function(hook) { if (!$docsify.matomo) { - console.error('[Docsify] matomo is required.') - return + // eslint-disable-next-line no-console + console.error('[Docsify] matomo is required.'); + return; } - hook.beforeEach(collect) -} + hook.beforeEach(collect); +}; -$docsify.plugins = [].concat(install, $docsify.plugins) +$docsify.plugins = [].concat(install, $docsify.plugins); diff --git a/src/plugins/search/component.js b/src/plugins/search/component.js index 37f964e9c..21add7ef2 100644 --- a/src/plugins/search/component.js +++ b/src/plugins/search/component.js @@ -1,7 +1,8 @@ -import {search} from './search' +/* eslint-disable no-unused-vars */ +import { search } from './search'; -let NO_DATA_TEXT = '' -let options +let NO_DATA_TEXT = ''; +let options; function style() { const code = ` @@ -97,14 +98,13 @@ function style() { .app-name.hide, .sidebar-nav.hide { display: none; -}` +}`; - Docsify.dom.style(code) + Docsify.dom.style(code); } function tpl(defaultValue = '') { - const html = - `
    + const html = `
    @@ -115,120 +115,120 @@ function tpl(defaultValue = '') {
    -
    ` - const el = Docsify.dom.create('div', html) - const aside = Docsify.dom.find('aside') + `; + const el = Docsify.dom.create('div', html); + const aside = Docsify.dom.find('aside'); - Docsify.dom.toggleClass(el, 'search') - Docsify.dom.before(aside, el) + Docsify.dom.toggleClass(el, 'search'); + Docsify.dom.before(aside, el); } function doSearch(value) { - const $search = Docsify.dom.find('div.search') - const $panel = Docsify.dom.find($search, '.results-panel') - const $clearBtn = Docsify.dom.find($search, '.clear-button') - const $sidebarNav = Docsify.dom.find('.sidebar-nav') - const $appName = Docsify.dom.find('.app-name') + const $search = Docsify.dom.find('div.search'); + const $panel = Docsify.dom.find($search, '.results-panel'); + const $clearBtn = Docsify.dom.find($search, '.clear-button'); + const $sidebarNav = Docsify.dom.find('.sidebar-nav'); + const $appName = Docsify.dom.find('.app-name'); if (!value) { - $panel.classList.remove('show') - $clearBtn.classList.remove('show') - $panel.innerHTML = '' + $panel.classList.remove('show'); + $clearBtn.classList.remove('show'); + $panel.innerHTML = ''; if (options.hideOtherSidebarContent) { - $sidebarNav.classList.remove('hide') - $appName.classList.remove('hide') + $sidebarNav.classList.remove('hide'); + $appName.classList.remove('hide'); } - return + return; } - const matchs = search(value) + const matchs = search(value); - let html = '' + let html = ''; matchs.forEach(post => { html += `

    ${post.title}

    ${post.content}

    -
    ` - }) +`; + }); - $panel.classList.add('show') - $clearBtn.classList.add('show') - $panel.innerHTML = html || `

    ${NO_DATA_TEXT}

    ` + $panel.classList.add('show'); + $clearBtn.classList.add('show'); + $panel.innerHTML = html || `

    ${NO_DATA_TEXT}

    `; if (options.hideOtherSidebarContent) { - $sidebarNav.classList.add('hide') - $appName.classList.add('hide') + $sidebarNav.classList.add('hide'); + $appName.classList.add('hide'); } } function bindEvents() { - const $search = Docsify.dom.find('div.search') - const $input = Docsify.dom.find($search, 'input') - const $inputWrap = Docsify.dom.find($search, '.input-wrap') + const $search = Docsify.dom.find('div.search'); + const $input = Docsify.dom.find($search, 'input'); + const $inputWrap = Docsify.dom.find($search, '.input-wrap'); - let timeId + let timeId; // Prevent to Fold sidebar Docsify.dom.on( $search, 'click', e => e.target.tagName !== 'A' && e.stopPropagation() - ) + ); Docsify.dom.on($input, 'input', e => { - clearTimeout(timeId) - timeId = setTimeout(_ => doSearch(e.target.value.trim()), 100) - }) + clearTimeout(timeId); + timeId = setTimeout(_ => doSearch(e.target.value.trim()), 100); + }); Docsify.dom.on($inputWrap, 'click', e => { // Click input outside if (e.target.tagName !== 'INPUT') { - $input.value = '' - doSearch() + $input.value = ''; + doSearch(); } - }) + }); } function updatePlaceholder(text, path) { - const $input = Docsify.dom.getNode('.search input[type="search"]') + const $input = Docsify.dom.getNode('.search input[type="search"]'); if (!$input) { - return + return; } if (typeof text === 'string') { - $input.placeholder = text + $input.placeholder = text; } else { - const match = Object.keys(text).filter(key => path.indexOf(key) > -1)[0] - $input.placeholder = text[match] + const match = Object.keys(text).filter(key => path.indexOf(key) > -1)[0]; + $input.placeholder = text[match]; } } function updateNoData(text, path) { if (typeof text === 'string') { - NO_DATA_TEXT = text + NO_DATA_TEXT = text; } else { - const match = Object.keys(text).filter(key => path.indexOf(key) > -1)[0] - NO_DATA_TEXT = text[match] + const match = Object.keys(text).filter(key => path.indexOf(key) > -1)[0]; + NO_DATA_TEXT = text[match]; } } function updateOptions(opts) { - options = opts + options = opts; } export function init(opts, vm) { - const keywords = vm.router.parse().query.s + const keywords = vm.router.parse().query.s; - updateOptions(opts) - style() - tpl(keywords) - bindEvents() - keywords && setTimeout(_ => doSearch(keywords), 500) + updateOptions(opts); + style(); + tpl(keywords); + bindEvents(); + keywords && setTimeout(_ => doSearch(keywords), 500); } export function update(opts, vm) { - updateOptions(opts) - updatePlaceholder(opts.placeholder, vm.route.path) - updateNoData(opts.noData, vm.route.path) + updateOptions(opts); + updatePlaceholder(opts.placeholder, vm.route.path); + updateNoData(opts.noData, vm.route.path); } diff --git a/src/plugins/search/index.js b/src/plugins/search/index.js index bbd3af6f0..3bfd3b6b5 100644 --- a/src/plugins/search/index.js +++ b/src/plugins/search/index.js @@ -1,5 +1,6 @@ -import {init as initComponet, update as updateComponent} from './component' -import {init as initSearch} from './search' +/* eslint-disable no-unused-vars */ +import { init as initComponet, update as updateComponent } from './component'; +import { init as initSearch } from './search'; const CONFIG = { placeholder: 'Type to search', @@ -8,35 +9,36 @@ const CONFIG = { depth: 2, maxAge: 86400000, // 1 day hideOtherSidebarContent: false, - namespace: undefined -} + namespace: undefined, +}; -const install = function (hook, vm) { - const {util} = Docsify - const opts = vm.config.search || CONFIG +const install = function(hook, vm) { + const { util } = Docsify; + const opts = vm.config.search || CONFIG; if (Array.isArray(opts)) { - CONFIG.paths = opts + CONFIG.paths = opts; } else if (typeof opts === 'object') { - CONFIG.paths = Array.isArray(opts.paths) ? opts.paths : 'auto' - CONFIG.maxAge = util.isPrimitive(opts.maxAge) ? opts.maxAge : CONFIG.maxAge - CONFIG.placeholder = opts.placeholder || CONFIG.placeholder - CONFIG.noData = opts.noData || CONFIG.noData - CONFIG.depth = opts.depth || CONFIG.depth - CONFIG.hideOtherSidebarContent = opts.hideOtherSidebarContent || CONFIG.hideOtherSidebarContent - CONFIG.namespace = opts.namespace || CONFIG.namespace + CONFIG.paths = Array.isArray(opts.paths) ? opts.paths : 'auto'; + CONFIG.maxAge = util.isPrimitive(opts.maxAge) ? opts.maxAge : CONFIG.maxAge; + CONFIG.placeholder = opts.placeholder || CONFIG.placeholder; + CONFIG.noData = opts.noData || CONFIG.noData; + CONFIG.depth = opts.depth || CONFIG.depth; + CONFIG.hideOtherSidebarContent = + opts.hideOtherSidebarContent || CONFIG.hideOtherSidebarContent; + CONFIG.namespace = opts.namespace || CONFIG.namespace; } - const isAuto = CONFIG.paths === 'auto' + const isAuto = CONFIG.paths === 'auto'; hook.mounted(_ => { - initComponet(CONFIG, vm) - !isAuto && initSearch(CONFIG, vm) - }) + initComponet(CONFIG, vm); + !isAuto && initSearch(CONFIG, vm); + }); hook.doneEach(_ => { - updateComponent(CONFIG, vm) - isAuto && initSearch(CONFIG, vm) - }) -} + updateComponent(CONFIG, vm); + isAuto && initSearch(CONFIG, vm); + }); +}; -$docsify.plugins = [].concat(install, $docsify.plugins) +$docsify.plugins = [].concat(install, $docsify.plugins); diff --git a/src/plugins/search/search.js b/src/plugins/search/search.js index fe124d7d0..29d74b79e 100644 --- a/src/plugins/search/search.js +++ b/src/plugins/search/search.js @@ -1,16 +1,21 @@ -let INDEXS = {} +/* eslint-disable no-unused-vars */ +let INDEXS = {}; const LOCAL_STORAGE = { EXPIRE_KEY: 'docsify.search.expires', - INDEX_KEY: 'docsify.search.index' -} + INDEX_KEY: 'docsify.search.index', +}; function resolveExpireKey(namespace) { - return namespace ? `${LOCAL_STORAGE.EXPIRE_KEY}/${namespace}` : LOCAL_STORAGE.EXPIRE_KEY + return namespace + ? `${LOCAL_STORAGE.EXPIRE_KEY}/${namespace}` + : LOCAL_STORAGE.EXPIRE_KEY; } function resolveIndexKey(namespace) { - return namespace ? `${LOCAL_STORAGE.INDEX_KEY}/${namespace}` : LOCAL_STORAGE.INDEX_KEY + return namespace + ? `${LOCAL_STORAGE.INDEX_KEY}/${namespace}` + : LOCAL_STORAGE.INDEX_KEY; } function escapeHtml(string) { @@ -19,72 +24,78 @@ function escapeHtml(string) { '<': '<', '>': '>', '"': '"', - '\'': ''', - '/': '/' - } + "'": ''', + '/': '/', + }; - return String(string).replace(/[&<>"'/]/g, s => entityMap[s]) + return String(string).replace(/[&<>"'/]/g, s => entityMap[s]); } function getAllPaths(router) { - const paths = [] - - Docsify.dom.findAll('.sidebar-nav a:not(.section-link):not([data-nosearch])').forEach(node => { - const href = node.href - const originHref = node.getAttribute('href') - const path = router.parse(href).path - - if ( - path && - paths.indexOf(path) === -1 && - !Docsify.util.isAbsolutePath(originHref) - ) { - paths.push(path) - } - }) + const paths = []; + + Docsify.dom + .findAll('.sidebar-nav a:not(.section-link):not([data-nosearch])') + .forEach(node => { + const href = node.href; + const originHref = node.getAttribute('href'); + const path = router.parse(href).path; + + if ( + path && + paths.indexOf(path) === -1 && + !Docsify.util.isAbsolutePath(originHref) + ) { + paths.push(path); + } + }); - return paths + return paths; } function saveData(maxAge, expireKey, indexKey) { - localStorage.setItem(expireKey, Date.now() + maxAge) - localStorage.setItem(indexKey, JSON.stringify(INDEXS)) + localStorage.setItem(expireKey, Date.now() + maxAge); + localStorage.setItem(indexKey, JSON.stringify(INDEXS)); } export function genIndex(path, content = '', router, depth) { - const tokens = window.marked.lexer(content) - const slugify = window.Docsify.slugify - const index = {} - let slug + const tokens = window.marked.lexer(content); + const slugify = window.Docsify.slugify; + const index = {}; + let slug; tokens.forEach(token => { if (token.type === 'heading' && token.depth <= depth) { - slug = router.toURL(path, { id: slugify(token.text) }) - index[slug] = { slug, title: token.text, body: '' } + slug = router.toURL(path, { id: slugify(token.text) }); + index[slug] = { slug, title: token.text, body: '' }; } else { if (!slug) { - return + return; } if (!index[slug]) { - index[slug] = { slug, title: '', body: '' } + index[slug] = { slug, title: '', body: '' }; } else if (index[slug].body) { - index[slug].body += '\n' + (token.text || '') + index[slug].body += '\n' + (token.text || ''); } else { if (!token.text) { if (token.type === 'table') { - token.text = token.cells.map(function (rows) { - return rows.join(' | ') - }).join(' |\n ') + token.text = token.cells + .map(function(rows) { + return rows.join(' | '); + }) + .join(' |\n '); } } - index[slug].body = (index[slug].body ? index[slug].body + token.text : token.text) + index[slug].body = index[slug].body + ? index[slug].body + token.text + : token.text; } } - }) - slugify.clear() - return index + }); + slugify.clear(); + return index; } /** @@ -92,25 +103,25 @@ export function genIndex(path, content = '', router, depth) { * @returns {Array} Array of results */ export function search(query) { - const matchingResults = [] - let data = [] + const matchingResults = []; + let data = []; Object.keys(INDEXS).forEach(key => { - data = data.concat(Object.keys(INDEXS[key]).map(page => INDEXS[key][page])) - }) + data = data.concat(Object.keys(INDEXS[key]).map(page => INDEXS[key][page])); + }); - query = query.trim() - let keywords = query.split(/[\s\-,\\/]+/) + query = query.trim(); + let keywords = query.split(/[\s\-,\\/]+/); if (keywords.length !== 1) { - keywords = [].concat(query, keywords) + keywords = [].concat(query, keywords); } for (let i = 0; i < data.length; i++) { - const post = data[i] - let matchesScore = 0 - let resultStr = '' - const postTitle = post.title && post.title.trim() - const postContent = post.body && post.body.trim() - const postUrl = post.slug || '' + const post = data[i]; + let matchesScore = 0; + let resultStr = ''; + const postTitle = post.title && post.title.trim(); + const postContent = post.body && post.body.trim(); + const postUrl = post.slug || ''; if (postTitle) { keywords.forEach(keyword => { @@ -118,27 +129,27 @@ export function search(query) { const regEx = new RegExp( keyword.replace(/[|\\{}()[\]^$+*?.]/g, '\\$&'), 'gi' - ) - let indexTitle = -1 - let indexContent = -1 + ); + let indexTitle = -1; + let indexContent = -1; - indexTitle = postTitle ? postTitle.search(regEx) : -1 - indexContent = postContent ? postContent.search(regEx) : -1 + indexTitle = postTitle ? postTitle.search(regEx) : -1; + indexContent = postContent ? postContent.search(regEx) : -1; if (indexTitle >= 0 || indexContent >= 0) { - matchesScore += indexTitle >= 0 ? 3 : indexContent >= 0 ? 2 : 0 + matchesScore += indexTitle >= 0 ? 3 : indexContent >= 0 ? 2 : 0; if (indexContent < 0) { - indexContent = 0 + indexContent = 0; } - let start = 0 - let end = 0 + let start = 0; + let end = 0; - start = indexContent < 11 ? 0 : indexContent - 10 - end = start === 0 ? 70 : indexContent + keyword.length + 60 + start = indexContent < 11 ? 0 : indexContent - 10; + end = start === 0 ? 70 : indexContent + keyword.length + 60; if (postContent && end > postContent.length) { - end = postContent.length + end = postContent.length; } const matchContent = @@ -146,58 +157,58 @@ export function search(query) { escapeHtml(postContent) .substring(start, end) .replace(regEx, `${keyword}`) + - '...' + '...'; - resultStr += matchContent + resultStr += matchContent; } - }) + }); if (matchesScore > 0) { const matchingPost = { title: escapeHtml(postTitle), content: postContent ? resultStr : '', url: postUrl, - score: matchesScore - } + score: matchesScore, + }; - matchingResults.push(matchingPost) + matchingResults.push(matchingPost); } } } - return matchingResults.sort((r1, r2) => r2.score - r1.score) + return matchingResults.sort((r1, r2) => r2.score - r1.score); } export function init(config, vm) { - const isAuto = config.paths === 'auto' + const isAuto = config.paths === 'auto'; - const expireKey = resolveExpireKey(config.namespace) - const indexKey = resolveIndexKey(config.namespace) + const expireKey = resolveExpireKey(config.namespace); + const indexKey = resolveIndexKey(config.namespace); - const isExpired = localStorage.getItem(expireKey) < Date.now() + const isExpired = localStorage.getItem(expireKey) < Date.now(); - INDEXS = JSON.parse(localStorage.getItem(indexKey)) + INDEXS = JSON.parse(localStorage.getItem(indexKey)); if (isExpired) { - INDEXS = {} + INDEXS = {}; } else if (!isAuto) { - return + return; } - const paths = isAuto ? getAllPaths(vm.router) : config.paths - const len = paths.length - let count = 0 + const paths = isAuto ? getAllPaths(vm.router) : config.paths; + const len = paths.length; + let count = 0; paths.forEach(path => { if (INDEXS[path]) { - return count++ + return count++; } - Docsify - .get(vm.router.getFile(path), false, vm.config.requestHeaders) - .then(result => { - INDEXS[path] = genIndex(path, result, vm.router, config.depth) - len === ++count && saveData(config.maxAge, expireKey, indexKey) - }) - }) + Docsify.get(vm.router.getFile(path), false, vm.config.requestHeaders).then( + result => { + INDEXS[path] = genIndex(path, result, vm.router, config.depth); + len === ++count && saveData(config.maxAge, expireKey, indexKey); + } + ); + }); } diff --git a/src/plugins/zoom-image.js b/src/plugins/zoom-image.js index faf92e1dd..f227e9fee 100644 --- a/src/plugins/zoom-image.js +++ b/src/plugins/zoom-image.js @@ -1,21 +1,30 @@ -import mediumZoom from 'medium-zoom' +/* eslint-disable no-unused-vars */ +import mediumZoom from 'medium-zoom'; -const matchesSelector = Element.prototype.matches || Element.prototype.webkitMatchesSelector || Element.prototype.msMatchesSelector +const matchesSelector = + Element.prototype.matches || + Element.prototype.webkitMatchesSelector || + Element.prototype.msMatchesSelector; function install(hook) { - let zoom + let zoom; hook.doneEach(_ => { - let elms = Array.apply(null, document.querySelectorAll('.markdown-section img:not(.emoji):not([data-no-zoom])')) + let elms = Array.apply( + null, + 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 => matchesSelector.call(elm, 'a img') === false); if (zoom) { - zoom.detach() + zoom.detach(); } - zoom = mediumZoom(elms) - }) + zoom = mediumZoom(elms); + }); } -$docsify.plugins = [].concat(install, $docsify.plugins) +$docsify.plugins = [].concat(install, $docsify.plugins); diff --git a/test/_helper.js b/test/_helper.js index b638cd819..afd0c07fd 100644 --- a/test/_helper.js +++ b/test/_helper.js @@ -1,22 +1,29 @@ +/* eslint-disable no-global-assign */ // Load ES6 modules in Node.js on the fly -require = require('esm')(module/* , options */) /* eslint-disable-line no-global-assign */ +require = require('esm')( + module /* , options */ +); /* eslint-disable-line no-global-assign */ -const path = require('path') -const { expect } = require('chai') +const path = require('path'); +const { expect } = require('chai'); -const { JSDOM } = require('jsdom') +const { JSDOM } = require('jsdom'); function ready(callback) { - const state = document.readyState + const state = document.readyState; if (state === 'complete' || state === 'interactive') { - return setTimeout(callback, 0) + return setTimeout(callback, 0); } - document.addEventListener('DOMContentLoaded', callback) + document.addEventListener('DOMContentLoaded', callback); } -module.exports.init = function (fixture = 'default', config = {}, markup = null) { +module.exports.init = function( + fixture = 'default', + config = {}, + markup = null +) { if (markup === null || markup === undefined) { markup = ` @@ -27,64 +34,67 @@ module.exports.init = function (fixture = 'default', config = {}, markup = null) window.$docsify = ${JSON.stringify(config, null, 2)} - ` + `; } - const rootPath = path.join(__dirname, 'fixtures', fixture) + const rootPath = path.join(__dirname, 'fixtures', fixture); - const dom = new JSDOM(markup) - dom.reconfigure({ url: 'file:///' + rootPath }) + const dom = new JSDOM(markup); + dom.reconfigure({ url: 'file:///' + rootPath }); - global.window = dom.window - global.document = dom.window.document - global.navigator = dom.window.navigator - global.location = dom.window.location - global.XMLHttpRequest = dom.window.XMLHttpRequest + global.window = dom.window; + global.document = dom.window.document; + global.navigator = dom.window.navigator; + global.location = dom.window.location; + global.XMLHttpRequest = dom.window.XMLHttpRequest; // Mimic src/core/index.js but for Node.js function Docsify() { - this._init() + this._init(); } - const proto = Docsify.prototype + const proto = Docsify.prototype; - const { initMixin } = require('../src/core/init') - const { routerMixin } = require('../src/core//router') - const { renderMixin } = require('../src/core//render') - const { fetchMixin } = require('../src/core/fetch') - const { eventMixin } = require('../src/core//event') + const { initMixin } = require('../src/core/init'); + const { routerMixin } = require('../src/core//router'); + const { renderMixin } = require('../src/core//render'); + const { fetchMixin } = require('../src/core/fetch'); + const { eventMixin } = require('../src/core//event'); - initMixin(proto) - routerMixin(proto) - renderMixin(proto) - fetchMixin(proto) - eventMixin(proto) + initMixin(proto); + routerMixin(proto); + renderMixin(proto); + fetchMixin(proto); + eventMixin(proto); - const NOT_INIT_PATTERN = '' + const NOT_INIT_PATTERN = ''; return new Promise(resolve => { ready(() => { - const docsify = new Docsify() + const docsify = new Docsify(); // NOTE: I was not able to get it working with a callback, but polling works usually at the first time const id = setInterval(() => { - if (dom.window.document.body.innerHTML.indexOf(NOT_INIT_PATTERN) === -1) { - clearInterval(id) + if ( + dom.window.document.body.innerHTML.indexOf(NOT_INIT_PATTERN) === -1 + ) { + clearInterval(id); return resolve({ docsify: docsify, - dom: dom - }) + dom: dom, + }); } - }, 10) - }) - }) -} + }, 10); + }); + }); +}; -module.exports.expectSameDom = function (actual, expected) { - const WHITESPACES_BETWEEN_TAGS = />(\s\s+)(\s\s+) **Time** is money, my friend!') - expect(output).equal('

    Time is money, my friend!

    ') - }) - - describe('lists', function () { - it('as unordered task list', async function () { - const { docsify } = await init() +const { init, expectSameDom } = require('../_helper'); +const { expect } = require('chai'); + +describe('render', function() { + it('important content (tips)', async function() { + const { docsify } = await init(); + const output = docsify.compiler.compile('!> **Time** is money, my friend!'); + expect(output).equal( + '

    Time is money, my friend!

    ' + ); + }); + + describe('lists', function() { + it('as unordered task list', async function() { + const { docsify } = await init(); const output = docsify.compiler.compile(` - [x] Task 1 - [ ] Task 2 -- [ ] Task 3`) - expect(output, `
      +- [ ] Task 3`); + expect( + output, + `
      • -
      `) - }) +
    ` + ); + }); - it('as ordered task list', async function () { - const { docsify } = await init() + it('as ordered task list', async function() { + const { docsify } = await init(); const output = docsify.compiler.compile(` 1. [ ] Task 1 -2. [x] Task 2`) - expectSameDom(output, `
      +2. [x] Task 2`); + expectSameDom( + output, + `
      1. -
      `) - }) +
    ` + ); + }); - it('normal unordered', async function () { - const { docsify } = await init() + it('normal unordered', async function() { + const { docsify } = await init(); const output = docsify.compiler.compile(` - [linktext](link) -- just text`) - expectSameDom(output, `
      +- just text`); + expectSameDom( + output, + ``) - }) +
    ` + ); + }); - it('unordered with custom start', async function () { - const { docsify } = await init() + it('unordered with custom start', async function() { + const { docsify } = await init(); const output = docsify.compiler.compile(` 1. first 2. second text -3. third`) - expectSameDom(output, `
      +3. third`); + expectSameDom( + output, + `
      1. first
      2. second

      text

      1. third
      2. -
      `) - }) +
    ` + ); + }); - it('nested', async function () { - const { docsify } = await init() + it('nested', async function() { + const { docsify } = await init(); const output = docsify.compiler.compile(` - 1 - 2 - 2 a - 2 b -- 3`) - expectSameDom(output, `
      +- 3`); + expectSameDom( + output, + `
      • 1
      • 2
        • 2 a
        • @@ -80,158 +95,228 @@ text
      • 3
      • -
      `) - }) - }) - - describe('image', function () { - it('regular', async function () { - const { docsify } = await init() - const output = docsify.compiler.compile('![alt text](http://imageUrl)') - - expectSameDom(output, '

      alt text

      ') - }) - - it('class', async function () { - const { docsify } = await init() - const output = docsify.compiler.compile('![alt text](http://imageUrl \':class=someCssClass\')') - - expectSameDom(output, '

      alt text

      ') - }) - - it('id', async function () { - const { docsify } = await init() - const output = docsify.compiler.compile('![alt text](http://imageUrl \':id=someCssID\')') - - expectSameDom(output, '

      alt text

      ') - }) - - it('no-zoom', async function () { - const { docsify } = await init() - const output = docsify.compiler.compile('![alt text](http://imageUrl \':no-zoom\')') - - expectSameDom(output, '

      alt text

      ') - }) - - describe('size', function () { - it('width and height', async function () { - const { docsify } = await init() - const output = docsify.compiler.compile('![alt text](http://imageUrl \':size=WIDTHxHEIGHT\')') - - expectSameDom(output, '

      alt text

      ') - }) - - it('width', async function () { - const { docsify } = await init() - const output = docsify.compiler.compile('![alt text](http://imageUrl \':size=50\')') - - expectSameDom(output, '

      alt text

      ') - }) - }) - }) - - describe('heading', function () { - it('h1', async function () { - const { docsify } = await init() - const output = docsify.compiler.compile('# h1 tag') - expectSameDom(output, ` +
    ` + ); + }); + }); + + describe('image', function() { + it('regular', async function() { + const { docsify } = await init(); + const output = docsify.compiler.compile('![alt text](http://imageUrl)'); + + expectSameDom( + output, + '

    alt text

    ' + ); + }); + + it('class', async function() { + const { docsify } = await init(); + const output = docsify.compiler.compile( + "![alt text](http://imageUrl ':class=someCssClass')" + ); + + expectSameDom( + output, + '

    alt text

    ' + ); + }); + + it('id', async function() { + const { docsify } = await init(); + const output = docsify.compiler.compile( + "![alt text](http://imageUrl ':id=someCssID')" + ); + + expectSameDom( + output, + '

    alt text

    ' + ); + }); + + it('no-zoom', async function() { + const { docsify } = await init(); + const output = docsify.compiler.compile( + "![alt text](http://imageUrl ':no-zoom')" + ); + + expectSameDom( + output, + '

    alt text

    ' + ); + }); + + describe('size', function() { + it('width and height', async function() { + const { docsify } = await init(); + const output = docsify.compiler.compile( + "![alt text](http://imageUrl ':size=WIDTHxHEIGHT')" + ); + + expectSameDom( + output, + '

    alt text

    ' + ); + }); + + it('width', async function() { + const { docsify } = await init(); + const output = docsify.compiler.compile( + "![alt text](http://imageUrl ':size=50')" + ); + + expectSameDom( + output, + '

    alt text

    ' + ); + }); + }); + }); + + describe('heading', function() { + it('h1', async function() { + const { docsify } = await init(); + const output = docsify.compiler.compile('# h1 tag'); + expectSameDom( + output, + `

    h1 tag -

    `) - }) - - it('h2', async function () { - const { docsify } = await init() - const output = docsify.compiler.compile('## h2 tag') - expectSameDom(output, ` + ` + ); + }); + + it('h2', async function() { + const { docsify } = await init(); + const output = docsify.compiler.compile('## h2 tag'); + expectSameDom( + output, + `

    h2 tag -

    `) - }) - - it('h3', async function () { - const { docsify } = await init() - const output = docsify.compiler.compile('### h3 tag') - expectSameDom(output, ` + ` + ); + }); + + it('h3', async function() { + const { docsify } = await init(); + const output = docsify.compiler.compile('### h3 tag'); + expectSameDom( + output, + `

    h3 tag -

    `) - }) - - it('h4', async function () { - const { docsify } = await init() - const output = docsify.compiler.compile('#### h4 tag') - expectSameDom(output, ` + ` + ); + }); + + it('h4', async function() { + const { docsify } = await init(); + const output = docsify.compiler.compile('#### h4 tag'); + expectSameDom( + output, + `

    h4 tag -

    `) - }) - - it('h5', async function () { - const { docsify } = await init() - const output = docsify.compiler.compile('##### h5 tag') - expectSameDom(output, ` + ` + ); + }); + + it('h5', async function() { + const { docsify } = await init(); + const output = docsify.compiler.compile('##### h5 tag'); + expectSameDom( + output, + `
    h5 tag -
    `) - }) - - it('h6', async function () { - const { docsify } = await init() - const output = docsify.compiler.compile('###### h6 tag') - expectSameDom(output, ` + ` + ); + }); + + it('h6', async function() { + const { docsify } = await init(); + const output = docsify.compiler.compile('###### h6 tag'); + expectSameDom( + output, + `
    h6 tag -
    `) - }) - }) - - describe('link', function () { - it('regular', async function () { - const { docsify } = await init() - const output = docsify.compiler.compile('[alt text](http://url)') - - expectSameDom(output, '

    alt text

    ') - }) - - it('disabled', async function () { - const { docsify } = await init() - const output = docsify.compiler.compile('[alt text](http://url \':disabled\')') - - expectSameDom(output, '

    alt text

    ') - }) - - it('target', async function () { - const { docsify } = await init() - const output = docsify.compiler.compile('[alt text](http://url \':target=_self\')') - - expectSameDom(output, '

    alt text

    ') - }) - - it('class', async function () { - const { docsify } = await init() - const output = docsify.compiler.compile('[alt text](http://url \':class=someCssClass\')') - - expectSameDom(output, '

    alt text

    ') - }) - - it('id', async function () { - const { docsify } = await init() - const output = docsify.compiler.compile('[alt text](http://url \':id=someCssID\')') - - expectSameDom(output, '

    alt text

    ') - }) - }) -}) + ` + ); + }); + }); + + describe('link', function() { + it('regular', async function() { + const { docsify } = await init(); + const output = docsify.compiler.compile('[alt text](http://url)'); + + expectSameDom( + output, + '

    alt text

    ' + ); + }); + + it('disabled', async function() { + const { docsify } = await init(); + const output = docsify.compiler.compile( + "[alt text](http://url ':disabled')" + ); + + expectSameDom( + output, + '

    alt text

    ' + ); + }); + + it('target', async function() { + const { docsify } = await init(); + const output = docsify.compiler.compile( + "[alt text](http://url ':target=_self')" + ); + + expectSameDom( + output, + '

    alt text

    ' + ); + }); + + it('class', async function() { + const { docsify } = await init(); + const output = docsify.compiler.compile( + "[alt text](http://url ':class=someCssClass')" + ); + + expectSameDom( + output, + '

    alt text

    ' + ); + }); + + it('id', async function() { + const { docsify } = await init(); + const output = docsify.compiler.compile( + "[alt text](http://url ':id=someCssID')" + ); + + expectSameDom( + output, + '

    alt text

    ' + ); + }); + }); +}); diff --git a/test/unit/util.test.js b/test/unit/util.test.js index f4d70e8d7..e4e8a0e3b 100644 --- a/test/unit/util.test.js +++ b/test/unit/util.test.js @@ -1,29 +1,32 @@ -require = require('esm')(module/* , options */) /* eslint-disable-line no-global-assign */ -const { expect } = require('chai') -const { resolvePath } = require('../../src/core/router/util') +/* eslint-disable no-global-assign */ +require = require('esm')( + module /* , options */ +); /* eslint-disable-line no-global-assign */ +const { resolvePath } = require('../../src/core/router/util'); +const { expect } = require('chai'); -describe('router/util', function () { - it('resolvePath', async function () { +describe('router/util', function() { + it('resolvePath', async function() { // WHEN - const result = resolvePath('hello.md') + const result = resolvePath('hello.md'); // THEN - expect(result).equal('/hello.md') - }) + expect(result).equal('/hello.md'); + }); - it('resolvePath with dot', async function () { + it('resolvePath with dot', async function() { // WHEN - const result = resolvePath('./hello.md') + const result = resolvePath('./hello.md'); // THEN - expect(result).equal('/hello.md') - }) + expect(result).equal('/hello.md'); + }); - it('resolvePath with two dots', async function () { + it('resolvePath with two dots', async function() { // WHEN - const result = resolvePath('test/../hello.md') + const result = resolvePath('test/../hello.md'); // THEN - expect(result).equal('/hello.md') - }) -}) + expect(result).equal('/hello.md'); + }); +}); From 92cd7aaa989e3bb46c79955089b4371696fbd502 Mon Sep 17 00:00:00 2001 From: anikethsaha Date: Thu, 20 Feb 2020 13:44:10 +0530 Subject: [PATCH 2/3] chore: linting fixes --- packages/docsify-server-renderer/index.js | 2 +- packages/docsify-server-renderer/package-lock.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/docsify-server-renderer/index.js b/packages/docsify-server-renderer/index.js index 3d9f03730..dfd06c9cb 100644 --- a/packages/docsify-server-renderer/index.js +++ b/packages/docsify-server-renderer/index.js @@ -1,11 +1,11 @@ import { readFileSync } from 'fs'; import { resolve, basename } from 'path'; -import resolvePathname from 'resolve-pathname'; 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'; +import resolvePathname from 'resolve-pathname'; import debug from 'debug'; import fetch from 'node-fetch'; diff --git a/packages/docsify-server-renderer/package-lock.json b/packages/docsify-server-renderer/package-lock.json index eae88000a..d26e84572 100644 --- a/packages/docsify-server-renderer/package-lock.json +++ b/packages/docsify-server-renderer/package-lock.json @@ -436,4 +436,4 @@ "integrity": "sha512-aSiJz7rGWNAQq7hjMK9ZYDuEawXupcCWgl3woQQSoDP2Oh8O4srWb/uO1PzzHIsrPEOqrjJ2sUb9FERfzuBabQ==" } } -} \ No newline at end of file +} From 4011976f2b4852d5cc02b82bfeec7d0527e9cda5 Mon Sep 17 00:00:00 2001 From: anikethsaha Date: Thu, 20 Feb 2020 13:53:19 +0530 Subject: [PATCH 3/3] chore: refactore in linting config and minor linting fixes --- .eslintrc.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.eslintrc.js b/.eslintrc.js index 3ffb3deb9..087ae9e76 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -53,7 +53,7 @@ module.exports = { 'import/no-mutable-exports': ['error'], 'import/no-named-as-default': ['error'], 'import/no-named-as-default-member': ['error'], - 'import/order': ['error'], + 'import/order': ['warn'], }, globals: { Docsify: 'writable',