Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions src/core/render/embed.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -122,7 +122,7 @@ function walkFetchEmbed({ embedTokens, compile, fetch }, cb) {
};

if (currentToken.embed.url) {
get(currentToken.embed.url).then(next);
get(currentToken.embed.url).then(next, () => next());
} else {
next(currentToken.embed.html);
}
Expand DownExpand Up@@ -205,7 +205,7 @@ export function prerenderEmbed({ compiler, raw = '', fetch }, done) {
walkFetchEmbed(
{ compile, embedTokens, fetch },
({ embedToken, token, rowIndex, cellIndex, tokenRef }) => {
if (token) {
if (token && embedToken) {
Object.assign(links, embedToken.links);

if (typeof rowIndex === 'number' && typeof cellIndex === 'number') {
Expand DownExpand Up@@ -269,7 +269,7 @@ export function prerenderEmbed({ compiler, raw = '', fetch }, done) {
});
}
}
} else {
} else if (!token) {
cached[raw] = tokens.concat();
tokens.links = cached[raw].links = links;
done(tokens);
Expand Down
7 changes: 5 additions & 2 deletions src/core/util/core.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -10,8 +10,11 @@ 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));
if (key in cache) {
return cache[key];
}

return (cache[key] = fn(str));
};
}

Expand Down
29 changes: 29 additions & 0 deletions test/integration/embed.test.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -262,6 +262,35 @@ Command | Description | Parameters
expect(mainText).not.toContain("_media/second.md ':include'");
});

test('failed embed URL does not block page render', async () => {
await docsifyInit({
markdown: {
homepage: `
# Embed Test

[missing](_media/missing.md ':include')

Text after missing embed

[ok](_media/ok.md ':include')
`,
},
routes: {
'_media/missing.md': {
status: 404,
body: 'Not Found',
contentType: 'text/markdown',
},
'_media/ok.md': 'reachable include content',
},
});

expect(await waitForText('#main', 'Text after missing embed')).toBeTruthy();
expect(
await waitForText('#main', 'reachable include content'),
).toBeTruthy();
});

test('embed file table cell', async () => {
await docsifyInit({
markdown: {
Expand Down
30 changes: 28 additions & 2 deletions test/unit/core-util.test.js
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,38 @@
import { isExternal } from '../../src/core/util/index.js';
import { cached, isExternal } from '../../src/core/util/index.js';

// Core util
// -----------------------------------------------------------------------------
describe('core/util', () => {
describe('cached()', () => {
test('memoizes falsy return values', () => {
let calls = 0;
const fn = cached(() => {
calls += 1;
return '';
});

expect(fn('same-key')).toBe('');
expect(fn('same-key')).toBe('');
expect(calls).toBe(1);
});

test('memoizes undefined return values', () => {
let calls = 0;
const fn = cached(() => {
calls += 1;
return undefined;
});

expect(fn('same-key')).toBeUndefined();
expect(fn('same-key')).toBeUndefined();
expect(calls).toBe(1);
});
});

// isExternal()
// ---------------------------------------------------------------------------
describe('isExternal()', () => {
// cases nonexternal
// cases non-external
test('non external local url with one /', () => {
const result = isExternal(`/${location.host}/docsify/demo.md`);

Expand Down
Loading