From c95b2729afeaf42679a9905fea7369fd9a1ff19a Mon Sep 17 00:00:00 2001
From: Koy Zhuang <369491420@qq.com>
Date: Wed, 26 Oct 2022 22:36:01 +0800
Subject: [PATCH] Revert "feat: Plugin error handling (#1742)"
This reverts commit 7a0c50a5f4c609d40d11db772a28818fa49f310a.
---
docs/configuration.md | 63 ++++----
docs/write-a-plugin.md | 256 ++++++++-------------------------
src/core/Docsify.js | 15 +-
src/core/config.js | 1 -
src/core/init/lifecycle.js | 36 +----
test/e2e/configuration.test.js | 67 ---------
test/e2e/plugins.test.js | 156 --------------------
7 files changed, 99 insertions(+), 495 deletions(-)
delete mode 100644 test/e2e/configuration.test.js
delete mode 100644 test/e2e/plugins.test.js
diff --git a/docs/configuration.md b/docs/configuration.md
index 6f0c4e475b..9762b21438 100644
--- a/docs/configuration.md
+++ b/docs/configuration.md
@@ -365,7 +365,7 @@ window.$docsify = {
## autoHeader
-- Type: `Boolean`
+- type: `Boolean`
If `loadSidebar` and `autoHeader` are both enabled, for each link in `_sidebar.md`, prepend a header to the page before converting it to HTML. See [#78](https://github.com/docsifyjs/docsify/issues/78).
@@ -378,7 +378,7 @@ window.$docsify = {
## executeScript
-- Type: `Boolean`
+- type: `Boolean`
Execute the script on the page. Only parse the first script tag ([demo](themes)). If Vue is present, it is turned on by default.
@@ -400,8 +400,8 @@ Note that if you are running an external script, e.g. an embedded jsfiddle demo,
## nativeEmoji
-- Type: `Boolean`
-- Default: `false`
+- type: `Boolean`
+- default: `false`
Render emoji shorthand codes using GitHub-style emoji images or platform-native emoji characters.
@@ -453,8 +453,8 @@ To render shorthand codes as text, replace `:` characters with the `:` HTM
## noEmoji
-- Type: `Boolean`
-- Default: `false`
+- type: `Boolean`
+- default: `false`
Disabled emoji parsing and render all emoji shorthand as text.
@@ -492,7 +492,7 @@ To disable emoji parsing of individual shorthand codes, replace `:` characters w
## mergeNavbar
-- Type: `Boolean`
+- type: `Boolean`
Navbar will be merged with the sidebar on smaller screens.
@@ -504,7 +504,7 @@ window.$docsify = {
## formatUpdated
-- Type: `String|Function`
+- type: `String|Function`
We can display the file update date through **{docsify-updated}** variable. And format it by `formatUpdated`.
See https://github.com/lukeed/tinydate#patterns
@@ -523,8 +523,8 @@ window.$docsify = {
## externalLinkTarget
-- Type: `String`
-- Default: `_blank`
+- type: `String`
+- default: `_blank`
Target to open external links inside the markdown. Default `'_blank'` (new window/tab)
@@ -536,8 +536,8 @@ window.$docsify = {
## cornerExternalLinkTarget
-- Type:`String`
-- Default:`_blank`
+- type:`String`
+- default:`_blank`
Target to open external link at the top right corner. Default `'_blank'` (new window/tab)
@@ -549,8 +549,8 @@ window.$docsify = {
## externalLinkRel
-- Type: `String`
-- Default: `noopener`
+- type: `String`
+- default: `noopener`
Default `'noopener'` (no opener) prevents the newly opened external page (when [externalLinkTarget](#externallinktarget) is `'_blank'`) from having the ability to control our page. No `rel` is set when it's not `'_blank'`. See [this post](https://mathiasbynens.github.io/rel-noopener/) for more information about why you may want to use this option.
@@ -562,8 +562,8 @@ window.$docsify = {
## routerMode
-- Type: `String`
-- Default: `hash`
+- type: `String`
+- default: `hash`
```js
window.$docsify = {
@@ -573,7 +573,7 @@ window.$docsify = {
## crossOriginLinks
-- Type: `Array`
+- type: `Array`
When `routerMode: 'history'`, you may face cross-origin issues. See [#1379](https://github.com/docsifyjs/docsify/issues/1379).
In Markdown content, there is a simple way to solve it: see extends Markdown syntax `Cross-Origin link` in [helpers](helpers.md).
@@ -586,7 +586,7 @@ window.$docsify = {
## noCompileLinks
-- Type: `Array`
+- type: `Array`
Sometimes we do not want docsify to handle our links. See [#203](https://github.com/docsifyjs/docsify/issues/203). We can skip compiling of certain links by specifying an array of strings. Each string is converted into to a regular expression (`RegExp`) and the _whole_ href of a link is matched against it.
@@ -598,7 +598,7 @@ window.$docsify = {
## onlyCover
-- Type: `Boolean`
+- type: `Boolean`
Only coverpage is loaded when visiting the home page.
@@ -610,7 +610,7 @@ window.$docsify = {
## requestHeaders
-- Type: `Object`
+- type: `Object`
Set the request resource headers.
@@ -634,7 +634,7 @@ window.$docsify = {
## ext
-- Type: `String`
+- type: `String`
Request file extension.
@@ -646,7 +646,7 @@ window.$docsify = {
## fallbackLanguages
-- Type: `Array`
+- type: `Array`
List of languages that will fallback to the default language when a page is requested and it doesn't exist for the given locale.
@@ -664,7 +664,7 @@ window.$docsify = {
## notFoundPage
-- Type: `Boolean` | `String` | `Object`
+- type: `Boolean` | `String` | `Object`
Load the `_404.md` file:
@@ -697,8 +697,8 @@ window.$docsify = {
## topMargin
-- Type: `Number`
-- Default: `0`
+- type: `Number`
+- default: `0`
Adds a space on top when scrolling the content page to reach the selected section. This is useful in case you have a _sticky-header_ layout and you want to align anchors to the end of your header.
@@ -710,7 +710,7 @@ window.$docsify = {
## vueComponents
-- Type: `Object`
+- type: `Object`
Creates and registers global [Vue components](https://vuejs.org/v2/guide/components.html). Components are specified using the component name as the key with an object containing Vue options as the value. Component `data` is unique for each instance and will not persist as users navigate the site.
@@ -743,7 +743,7 @@ window.$docsify = {
## vueGlobalOptions
-- Type: `Object`
+- type: `Object`
Specifies [Vue options](https://vuejs.org/v2/api/#Options-Data) for use with Vue content not explicitly mounted with [vueMounts](#mounting-dom-elements), [vueComponents](#components), or a [markdown script](#markdown-script). Changes to global `data` will persist and be reflected anywhere global references are used.
@@ -777,7 +777,7 @@ window.$docsify = {
## vueMounts
-- Type: `Object`
+- type: `Object`
Specifies DOM elements to mount as [Vue instances](https://vuejs.org/v2/guide/instance.html) and their associated options. Mount elements are specified using a [CSS selector](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Selectors) as the key with an object containing Vue options as their value. Docsify will mount the first matching element in the main content area each time a new page is loaded. Mount element `data` is unique for each instance and will not persist as users navigate the site.
@@ -808,10 +808,3 @@ window.$docsify = {
{{ count }}
-
-## catchPluginErrors
-
-- Type: `Boolean`
-- Default: `true`
-
-Determines if Docsify should handle uncaught _synchronous_ plugin errors automatically. This can prevent plugin errors from affecting docsify's ability to properly render live site content.
diff --git a/docs/write-a-plugin.md b/docs/write-a-plugin.md
index ad9b4bf70e..5495a87712 100644
--- a/docs/write-a-plugin.md
+++ b/docs/write-a-plugin.md
@@ -1,232 +1,85 @@
# Write a plugin
-A docsify plugin is a function with the ability to execute custom JavaScript code at various stages of Docsify's lifecycle.
+A plugin is simply a function that takes `hook` as an argument. The hook supports handling of asynchronous tasks.
-## Setup
-
-Docsify plugins can be added directly to the `plugins` array.
+## Full configuration
```js
window.$docsify = {
plugins: [
- function myPlugin1(hook, vm) {
- // ...
- },
- function myPlugin2(hook, vm) {
- // ...
- },
- ],
-};
-```
-
-Alternatively, a plugin can be stored in a separate file and "installed" using a standard `
-```
-
-## Template
-
-Below is a plugin template with placeholders for all available lifecycle hooks.
-
-1. Copy the template
-1. Modify the `myPlugin` name as appropriate
-1. Add your plugin logic
-1. Remove unused lifecycle hooks
-1. Save the file as `docsify-plugin-[name].js`
-1. Load your plugin using a standard `
diff --git a/src/core/Docsify.js b/src/core/Docsify.js
index ad339311c4..ba6c54b88f 100644
--- a/src/core/Docsify.js
+++ b/src/core/Docsify.js
@@ -28,18 +28,9 @@ export class Docsify extends Fetch(Events(Render(Router(Lifecycle(Object))))) {
}
initPlugin() {
- [].concat(this.config.plugins).forEach(fn => {
- try {
- isFn(fn) && fn(this._lifecycle, this);
- } catch (err) {
- if (this.config.catchPluginErrors) {
- const errTitle = 'Docsify plugin error';
- console.error(errTitle, err);
- } else {
- throw err;
- }
- }
- });
+ []
+ .concat(this.config.plugins)
+ .forEach(fn => isFn(fn) && fn(this._lifecycle, this));
}
}
diff --git a/src/core/config.js b/src/core/config.js
index 5830656a93..d766291593 100644
--- a/src/core/config.js
+++ b/src/core/config.js
@@ -37,7 +37,6 @@ export default function (vm) {
crossOriginLinks: [],
relativePath: false,
topMargin: 0,
- catchPluginErrors: true,
},
typeof window.$docsify === 'function'
? window.$docsify(vm)
diff --git a/src/core/init/lifecycle.js b/src/core/init/lifecycle.js
index 94a3981fe7..c04fc1a72c 100644
--- a/src/core/init/lifecycle.js
+++ b/src/core/init/lifecycle.js
@@ -29,7 +29,6 @@ export function Lifecycle(Base) {
callHook(hookName, data, next = noop) {
const queue = this._hooks[hookName];
- const catchPluginErrors = this.config.catchPluginErrors;
const step = function (index) {
const hookFn = queue[index];
@@ -37,38 +36,15 @@ export function Lifecycle(Base) {
if (index >= queue.length) {
next(data);
} else if (typeof hookFn === 'function') {
- const errTitle = 'Docsify plugin error';
-
if (hookFn.length === 2) {
- try {
- hookFn(data, result => {
- data = result;
- step(index + 1);
- });
- } catch (err) {
- if (catchPluginErrors) {
- console.error(errTitle, err);
- } else {
- throw err;
- }
-
+ hookFn(data, result => {
+ data = result;
step(index + 1);
- }
+ });
} else {
- try {
- const result = hookFn(data);
-
- data = result === undefined ? data : result;
- step(index + 1);
- } catch (err) {
- if (catchPluginErrors) {
- console.error(errTitle, err);
- } else {
- throw err;
- }
-
- step(index + 1);
- }
+ const result = hookFn(data);
+ data = result === undefined ? data : result;
+ step(index + 1);
}
} else {
step(index + 1);
diff --git a/test/e2e/configuration.test.js b/test/e2e/configuration.test.js
deleted file mode 100644
index 8aa3c5f083..0000000000
--- a/test/e2e/configuration.test.js
+++ /dev/null
@@ -1,67 +0,0 @@
-const docsifyInit = require('../helpers/docsify-init');
-const { test, expect } = require('./fixtures/docsify-init-fixture');
-
-test.describe('Configuration options', () => {
- test('catchPluginErrors:true (handles uncaught errors)', async ({ page }) => {
- let consoleMsg, errorMsg;
-
- page.on('console', msg => (consoleMsg = msg.text()));
- page.on('pageerror', err => (errorMsg = err.message));
-
- await docsifyInit({
- config: {
- catchPluginErrors: true,
- plugins: [
- function (hook, vm) {
- hook.init(function () {
- // eslint-disable-next-line no-undef
- fail();
- });
- hook.beforeEach(function (markdown) {
- return `${markdown}\n\nbeforeEach`;
- });
- },
- ],
- },
- markdown: {
- homepage: '# Hello World',
- },
- // _logHTML: true,
- });
-
- const mainElm = page.locator('#main');
-
- expect(errorMsg).toBeUndefined();
- expect(consoleMsg).toContain('Docsify plugin error');
- await expect(mainElm).toContainText('Hello World');
- await expect(mainElm).toContainText('beforeEach');
- });
-
- test('catchPluginErrors:false (throws uncaught errors)', async ({ page }) => {
- let consoleMsg, errorMsg;
-
- page.on('console', msg => (consoleMsg = msg.text()));
- page.on('pageerror', err => (errorMsg = err.message));
-
- await docsifyInit({
- config: {
- catchPluginErrors: false,
- plugins: [
- function (hook, vm) {
- hook.ready(function () {
- // eslint-disable-next-line no-undef
- fail();
- });
- },
- ],
- },
- markdown: {
- homepage: '# Hello World',
- },
- // _logHTML: true,
- });
-
- expect(consoleMsg).toBeUndefined();
- expect(errorMsg).toContain('fail');
- });
-});
diff --git a/test/e2e/plugins.test.js b/test/e2e/plugins.test.js
deleted file mode 100644
index 92f00ca568..0000000000
--- a/test/e2e/plugins.test.js
+++ /dev/null
@@ -1,156 +0,0 @@
-const docsifyInit = require('../helpers/docsify-init');
-const { test, expect } = require('./fixtures/docsify-init-fixture');
-
-test.describe('Plugins', () => {
- test('Hook order', async ({ page }) => {
- const consoleMsgs = [];
- const expectedMsgs = [
- 'init',
- 'mounted',
- 'beforeEach-async',
- 'beforeEach',
- // 'afterEach-async',
- 'afterEach',
- 'doneEach',
- 'ready',
- ];
-
- page.on('console', msg => consoleMsgs.push(msg.text()));
-
- await docsifyInit({
- config: {
- plugins: [
- function (hook, vm) {
- hook.init(function () {
- console.log('init');
- });
-
- hook.mounted(function () {
- console.log('mounted');
- });
-
- hook.beforeEach(function (markdown, next) {
- setTimeout(function () {
- console.log('beforeEach-async');
- next(markdown);
- }, 100);
- });
-
- hook.beforeEach(function (markdown) {
- console.log('beforeEach');
- return markdown;
- });
-
- // FIXME: https://github.com/docsifyjs/docsify/issues/449
- // hook.afterEach(function (html, next) {
- // setTimeout(function () {
- // console.log('afterEach-async');
- // next(html);
- // }, 100);
- // });
-
- hook.afterEach(function (html) {
- console.log('afterEach');
- return html;
- });
-
- hook.doneEach(function () {
- console.log('doneEach');
- });
-
- hook.ready(function () {
- console.log('ready');
- });
- },
- ],
- },
- markdown: {
- homepage: '# Hello World',
- },
- // _logHTML: true,
- });
-
- expect(consoleMsgs).toEqual(expectedMsgs);
- });
-
- test('beforeEach() return value', async ({ page }) => {
- await docsifyInit({
- config: {
- plugins: [
- function (hook, vm) {
- hook.beforeEach(function (markdown) {
- return 'beforeEach';
- });
- },
- ],
- },
- // _logHTML: true,
- });
-
- await expect(page.locator('#main')).toContainText('beforeEach');
- });
-
- test('beforeEach() async return value', async ({ page }) => {
- await docsifyInit({
- config: {
- plugins: [
- function (hook, vm) {
- hook.beforeEach(function (markdown, next) {
- setTimeout(function () {
- next('beforeEach');
- }, 100);
- });
- },
- ],
- },
- markdown: {
- homepage: '# Hello World',
- },
- // _logHTML: true,
- });
-
- await expect(page.locator('#main')).toContainText('beforeEach');
- });
-
- test('afterEach() return value', async ({ page }) => {
- await docsifyInit({
- config: {
- plugins: [
- function (hook, vm) {
- hook.afterEach(function (html) {
- return 'afterEach
';
- });
- },
- ],
- },
- markdown: {
- homepage: '# Hello World',
- },
- // _logHTML: true,
- });
-
- await expect(page.locator('#main')).toContainText('afterEach');
- });
-
- test('afterEach() async return value', async ({ page }) => {
- await docsifyInit({
- config: {
- plugins: [
- function (hook, vm) {
- hook.afterEach(function (html, next) {
- setTimeout(function () {
- next('afterEach
');
- }, 100);
- });
- },
- ],
- },
- markdown: {
- homepage: '# Hello World',
- },
- // _logHTML: true,
- });
-
- await expect(page.locator('#main')).toContainText('afterEach');
- });
-});