diff --git a/src/core/fetch/index.js b/src/core/fetch/index.js index 3dcc0caf9d..fbd5b3d1b6 100644 --- a/src/core/fetch/index.js +++ b/src/core/fetch/index.js @@ -23,6 +23,7 @@ export function Fetch(Base) { path = getParentPath(path); if (!path) { + next(''); return; } diff --git a/src/core/render/compiler.js b/src/core/render/compiler.js index e81aaa81f8..d77a153645 100644 --- a/src/core/render/compiler.js +++ b/src/core/render/compiler.js @@ -206,7 +206,7 @@ export class Compiler { let html = ''; // compile sidebar from _sidebar.md - if (text) { + if (typeof text === 'string') { return this.compile(text); } // compile sidebar from content's headings toc diff --git a/test/e2e/plugins.test.js b/test/e2e/plugins.test.js index b1e53d729a..53e2b96e0a 100644 --- a/test/e2e/plugins.test.js +++ b/test/e2e/plugins.test.js @@ -79,6 +79,89 @@ test.describe('Plugins', () => { expect(consoleMsgs).toEqual(expectedMsgs); }); + test('ready runs once when the initial sidebar is missing', async ({ + page, + }) => { + await page.route('_sidebar.md', route => route.fulfill({ status: 404 })); + + await docsifyInit({ + config: { + loadSidebar: true, + name: 'Docsify', + nameLink: '#/', + plugins: [ + function (hook) { + window.hookCalls = []; + + hook.doneEach(() => { + window.hookCalls.push('doneEach'); + }); + + hook.ready(() => { + window.hookCalls.push('ready'); + document + .querySelector('.sidebar-nav') + .addEventListener('click', event => { + const groupTitle = event.target.closest( + '.sidebar-nav > ul > li > p', + ); + + groupTitle?.parentElement.classList.toggle('plugin-collapse'); + }); + }); + }, + ], + }, + markdown: { + homepage: ` + # Home + + [Section](/section/) + `, + }, + routes: { + '/section/README.md': '# Section', + '/section/_sidebar.md': ` + - Group + - [Page](page) + `, + }, + }); + + await expect + .poll(() => page.evaluate(() => window.hookCalls)) + .toEqual(['doneEach', 'ready']); + await expect(page.locator('.sidebar-nav')).toBeEmpty(); + + await page.locator('a[href="#/section/"]').click(); + + const group = page.locator('.sidebar-nav > ul > li').first(); + await expect(group.locator(':scope > p')).toHaveText('Group'); + + await group.locator(':scope > p').click(); + await expect(group).toHaveClass(/plugin-collapse/); + await expect + .poll(() => page.evaluate(() => window.hookCalls)) + .toEqual(['doneEach', 'ready', 'doneEach']); + + await page.locator('.app-name-link').click(); + + await expect(page.locator('#main h1')).toHaveText('Home'); + await expect(page.locator('.sidebar-nav')).toBeEmpty(); + await expect + .poll(() => page.evaluate(() => window.hookCalls)) + .toEqual(['doneEach', 'ready', 'doneEach', 'doneEach']); + + await page.locator('a[href="#/section/"]').click(); + + await expect(group.locator(':scope > p')).toHaveText('Group'); + await group.locator(':scope > p').click(); + await expect(group).toHaveClass(/plugin-collapse/); + await expect + .poll(() => page.evaluate(() => window.hookCalls)) + .toEqual(['doneEach', 'ready', 'doneEach', 'doneEach', 'doneEach']); + }); + test.describe('beforeEach()', () => { test('return value', async ({ page }) => { await docsifyInit({