Skip to content

Commit 7cc7cdf

Browse files
committed
feat: cover page supports embedding external files
1 parent ec48f93 commit 7cc7cdf

File tree

4 files changed

+121
-26
lines changed

4 files changed

+121
-26
lines changed

src/core/fetch/index.js

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -170,18 +170,23 @@ export function Fetch(Base) {
170170
}
171171

172172
const coverOnly = Boolean(path) && this.config.onlyCover;
173+
const next = () => cb(coverOnly);
173174
if (path) {
174175
path = this.router.getFile(root + path);
175176
this.coverIsHTML = /\.html$/g.test(path);
176177
get(path + stringifyQuery(query, ['id']), false, requestHeaders).then(
177-
text => {
178-
this._renderCover(text, coverOnly);
179-
cb(coverOnly);
178+
text => this._renderCover(text, coverOnly, next),
179+
(event, response) => {
180+
this.coverIsHTML = false;
181+
this._renderCover(
182+
`# ${response.status} - ${response.statusText}`,
183+
coverOnly,
184+
next,
185+
);
180186
},
181187
);
182188
} else {
183-
this._renderCover(null, coverOnly);
184-
cb(coverOnly);
189+
this._renderCover(null, coverOnly, next);
185190
}
186191
} else {
187192
cb(false);

src/core/render/index.js

Lines changed: 38 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -382,7 +382,7 @@ export function Render(Base) {
382382
});
383383
}
384384

385-
_renderCover(text, coverOnly) {
385+
_renderCover(text, coverOnly, next) {
386386
const el = dom.getNode('.cover');
387387

388388
dom.toggleClass(
@@ -392,37 +392,56 @@ export function Render(Base) {
392392
);
393393
if (!text) {
394394
dom.toggleClass(el, 'remove', 'show');
395+
next();
395396
return;
396397
}
397398

398399
dom.toggleClass(el, 'add', 'show');
399400

400-
let html = this.coverIsHTML ? text : this.compiler.cover(text);
401+
const callback = html => {
402+
const m = html
403+
.trim()
404+
.match('<p><img.*?data-origin="(.*?)"[^a]+alt="(.*?)">([^<]*?)</p>$');
401405

402-
const m = html
403-
.trim()
404-
.match('<p><img.*?data-origin="(.*?)"[^a]+alt="(.*?)">([^<]*?)</p>$');
406+
if (m) {
407+
if (m[2] === 'color') {
408+
el.style.background = m[1] + (m[3] || '');
409+
} else {
410+
let path = m[1];
405411

406-
if (m) {
407-
if (m[2] === 'color') {
408-
el.style.background = m[1] + (m[3] || '');
409-
} else {
410-
let path = m[1];
412+
dom.toggleClass(el, 'add', 'has-mask');
413+
if (!isAbsolutePath(m[1])) {
414+
path = getPath(this.router.getBasePath(), m[1]);
415+
}
411416

412-
dom.toggleClass(el, 'add', 'has-mask');
413-
if (!isAbsolutePath(m[1])) {
414-
path = getPath(this.router.getBasePath(), m[1]);
417+
el.style.backgroundImage = `url(${path})`;
418+
el.style.backgroundSize = 'cover';
419+
el.style.backgroundPosition = 'center center';
415420
}
416421

417-
el.style.backgroundImage = `url(${path})`;
418-
el.style.backgroundSize = 'cover';
419-
el.style.backgroundPosition = 'center center';
422+
html = html.replace(m[0], '');
420423
}
421424

422-
html = html.replace(m[0], '');
423-
}
425+
this._renderTo('.cover-main', html);
426+
next();
427+
};
424428

425-
this._renderTo('.cover-main', html);
429+
// TODO: Call the 'beforeEach' and 'afterEach' hooks.
430+
// However, when the cover and the home page are on the same page,
431+
// the 'beforeEach' and 'afterEach' hooks are called multiple times.
432+
// It is difficult to determine the target of the hook within the
433+
// hook functions. We might need to make some changes.
434+
if (this.coverIsHTML) {
435+
callback(text);
436+
} else {
437+
prerenderEmbed(
438+
{
439+
compiler: this.compiler,
440+
raw: text,
441+
},
442+
tokens => callback(this.compiler.cover(tokens)),
443+
);
444+
}
426445
}
427446

428447
_updateRender() {

test/e2e/embed-files.test.js

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import docsifyInit from '../helpers/docsify-init.js';
2+
import { test, expect } from './fixtures/docsify-init-fixture.js';
3+
4+
test.describe('Embed files', () => {
5+
const routes = {
6+
'fragment.md': '## Fragment',
7+
};
8+
9+
test('embed into homepage', async ({ page }) => {
10+
await docsifyInit({
11+
routes,
12+
markdown: {
13+
homepage: "# Hello World\n\n[fragment](fragment.md ':include')",
14+
},
15+
_logHTML: {},
16+
});
17+
18+
await expect(page.locator('#main')).toContainText('Fragment');
19+
});
20+
21+
test('embed into cover', async ({ page }) => {
22+
await docsifyInit({
23+
routes,
24+
markdown: {
25+
homepage: '# Hello World',
26+
coverpage: "# Cover\n\n[fragment](fragment.md ':include')",
27+
},
28+
_logHTML: {},
29+
});
30+
31+
await expect(page.locator('.cover-main')).toContainText('Fragment');
32+
});
33+
});

test/e2e/plugins.test.js

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -179,13 +179,51 @@ test.describe('Plugins', () => {
179179
},
180180
markdown: {
181181
homepage: '# Hello World :id=homepage-title',
182-
coverpage: '# Cover Page :id=cover-title',
182+
coverpage: () => {
183+
return new Promise(resolve => {
184+
setTimeout(() => resolve('# Cover Page :id=cover-title'), 500);
185+
});
186+
},
183187
},
184-
// _logHTML: true,
188+
// _logHTML: {},
185189
});
186190

187191
await expect(consoleMessages).toEqual(['Hello World', 'Cover Page']);
188192
});
193+
194+
test('only cover', async ({ page }) => {
195+
const consoleMessages = [];
196+
197+
page.on('console', msg => consoleMessages.push(msg.text()));
198+
199+
await docsifyInit({
200+
config: {
201+
onlyCover: true,
202+
plugins: [
203+
function (hook) {
204+
hook.doneEach(() => {
205+
const homepageTitle = document.querySelector('#homepage-title');
206+
const coverTitle = document.querySelector('#cover-title');
207+
console.log(homepageTitle?.textContent);
208+
console.log(coverTitle?.textContent);
209+
});
210+
},
211+
],
212+
},
213+
markdown: {
214+
homepage: '# Hello World :id=homepage-title',
215+
coverpage: () => {
216+
return new Promise(resolve => {
217+
setTimeout(() => resolve('# Cover Page :id=cover-title'), 500);
218+
});
219+
},
220+
},
221+
waitForSelector: '.cover-main > *:first-child',
222+
// _logHTML: {},
223+
});
224+
225+
await expect(consoleMessages).toEqual(['undefined', 'Cover Page']);
226+
});
189227
});
190228

191229
test.describe('route data accessible to plugins', () => {

0 commit comments

Comments
 (0)