Skip to content
Open
Show file tree
Hide file tree
Changes from 6 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
5 changes: 5 additions & 0 deletions src/core/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ export default function(vm) {
crossOriginLinks: [],
relativePath: false,
topMargin: 0,
rootRelativeImageURL: false,
},
typeof window.$docsify === 'function'
? window.$docsify(vm)
Expand Down Expand Up @@ -79,6 +80,10 @@ export default function(vm) {
config.name = '';
}

if (config.rootRelativeImageURL === true) {
config.rootRelativeImageURL = '';
}

window.$docsify = config;

return config;
Expand Down
16 changes: 14 additions & 2 deletions src/core/render/compiler.js
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ export class Compiler {
this.linkRel =
this.linkTarget === '_blank' ? config.externalLinkRel || 'noopener' : '';
this.contentBase = router.getBasePath();
this.rootRelativeImageURL = config.rootRelativeImageURL;

const renderer = this._initRenderer();
this.heading = renderer.heading;
Expand Down Expand Up @@ -193,7 +194,13 @@ export class Compiler {

_initRenderer() {
const renderer = new marked.Renderer();
const { linkTarget, linkRel, router, contentBase } = this;
const {
linkTarget,
linkRel,
router,
contentBase,
rootRelativeImageURL,
} = this;
const _self = this;
const origin = {};

Expand Down Expand Up @@ -249,7 +256,12 @@ export class Compiler {
compilerClass: _self,
});
origin.paragraph = paragraphCompiler({ renderer });
origin.image = imageCompiler({ renderer, contentBase, router });
origin.image = imageCompiler({
renderer,
contentBase,
router,
rootRelativeImageURL,
});
origin.list = taskListCompiler({ renderer });
origin.listitem = taskListItemCompiler({ renderer });

Expand Down
21 changes: 17 additions & 4 deletions src/core/render/compiler/image.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,17 @@
import { getAndRemoveConfig } from '../utils';
import { isAbsolutePath, getPath, getParentPath } from '../../router/util';

export const imageCompiler = ({ renderer, contentBase, router }) =>
import {
isAbsolutePath,
isPathRootRelative,
getPath,
getParentPath,
} from '../../router/util';

export const imageCompiler = ({
renderer,
contentBase,
router,
rootRelativeImageURL,
}) =>
(renderer.image = (href, title, text) => {
let url = href;
let attrs = [];
Expand Down Expand Up @@ -35,7 +45,10 @@ export const imageCompiler = ({ renderer, contentBase, router }) =>
}

if (!isAbsolutePath(href)) {
url = getPath(contentBase, getParentPath(router.getCurrentPath()), href);
url =
isPathRootRelative(href) && rootRelativeImageURL !== false
? getPath('/' + String(rootRelativeImageURL), href)
: getPath(contentBase, getParentPath(router.getCurrentPath()), href);
}

if (attrs.length > 0) {
Expand Down
4 changes: 4 additions & 0 deletions src/core/router/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,10 @@ export const isAbsolutePath = cached(path => {
return /(:|(\/{2}))/g.test(path);
});

export const isPathRootRelative = cached(path => {
return path[0] === '/';
});

export const removeParams = cached(path => {
return path.split(/[?#]/)[0];
});
Expand Down
4 changes: 3 additions & 1 deletion test/_helper.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,9 @@ module.exports.init = function(

const rootPath = path.join(__dirname, 'fixtures', fixture);

const dom = initJSDOM(markup);
const runScriptInJSDom =
Object.values(config).length !== 0 ? 'dangerously' : undefined;
const dom = initJSDOM(markup, { runScripts: runScriptInJSDom });
dom.reconfigure({ url: 'file:///' + rootPath });

// Mimic src/core/index.js but for Node.js
Expand Down
65 changes: 65 additions & 0 deletions test/unit/render.test.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
const path = require('path');
const { expect } = require('chai');
const { init, expectSameDom } = require('../_helper');

Expand Down Expand Up @@ -104,6 +105,23 @@ describe('render', function() {
);
});

it('relative image url', async function() {
const { docsify } = await init();
const output = docsify.compiler.compile(
'![alt text](some-path/image.png)'
);
const expectedCompiledPath = path.posix.join(
// must use posix here because if run on windows, paths are joined using backslash (\)
__dirname,
'../fixtures/default',
'some-path/image.png'
);
expectSameDom(
output,
`<p><img src="${expectedCompiledPath}" data-origin="some-path/image.png" alt="alt text"></p>`
);
});

it('class', async function() {
const { docsify } = await init();
const output = docsify.compiler.compile(
Expand Down Expand Up @@ -165,6 +183,53 @@ describe('render', function() {
);
});
});

describe('compiling root-relative image src path', async function() {
it('behaves normally if config.rootRelativeImageURL is set to false', async function() {
const { docsify } = await init('default', {
rootRelativeImageURL: false,
});
const rootRelativePathOutput = docsify.compiler.compile(
'![alt text](/some-path/image.png)'
);
const expectedCompiledPath = path.posix.join(
// must use posix here because if run on windows, file paths use backslash (\)
__dirname,
'../fixtures/default',
'some-path/image.png'
);
expectSameDom(
rootRelativePathOutput,
`<p><img src="${expectedCompiledPath}" data-origin="/some-path/image.png" alt="alt text"></p>`
);
});

it('only uses the image href if config.rootRelativeImageURL is set to true', async function() {
const { docsify } = await init('default', {
rootRelativeImageURL: true,
});
const rootRelativePathOutput = docsify.compiler.compile(
'![alt text](/some-path/image.png)'
);
expectSameDom(
rootRelativePathOutput,
`<p><img src="/some-path/image.png" data-origin="/some-path/image.png" alt="alt text"></p>`
);
});

it('uses config.rootRelativeImageURL as a prefix for the compiled image path, if passed as a string', async function() {
const { docsify } = await init('default', {
rootRelativeImageURL: 'docs',
});
const rootRelativePathOutput = docsify.compiler.compile(
'![alt text](/some-path/image.png)'
);
expectSameDom(
rootRelativePathOutput,
`<p><img src="/docs/some-path/image.png" data-origin="/some-path/image.png" alt="alt text"></p>`
);
});
});
});

describe('heading', function() {
Expand Down