Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(helpers, tag plugins): encode url by default #3710

Merged
merged 14 commits into from
Oct 7, 2019
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
30 changes: 4 additions & 26 deletions lib/plugins/helper/relative_url.js
Original file line number Diff line number Diff line change
@@ -1,29 +1,7 @@
'use strict';

function relativeUrlHelper(from = '', to = '') {
const fromParts = from.split('/');
const toParts = to.split('/');
const length = Math.min(fromParts.length, toParts.length);
let i = 0;
const { relative_url } = require('hexo-util');

for (; i < length; i++) {
if (fromParts[i] !== toParts[i]) break;
}

let out = toParts.slice(i);

for (let j = fromParts.length - i - 1; j > 0; j--) {
out.unshift('..');
}

const outLength = out.length;

// If the last 2 elements of `out` is empty strings, replace them with `index.html`.
if (outLength > 1 && !out[outLength - 1] && !out[outLength - 2]) {
out = out.slice(0, outLength - 2).concat('index.html');
}

return out.join('/').replace(/\/{2,}/g, '/');
}

module.exports = relativeUrlHelper;
module.exports = function(from, to) {
return relative_url(from, to);
};
curbengh marked this conversation as resolved.
Show resolved Hide resolved
36 changes: 4 additions & 32 deletions lib/plugins/helper/url_for.js
Original file line number Diff line number Diff line change
@@ -1,35 +1,7 @@
'use strict';

const url = require('url');
const relative_url = require('./relative_url');
const { url_for } = require('hexo-util');

function urlForHelper(path = '/', options) {
if (path[0] === '#' || path.startsWith('//')) {
return path;
}

const { config } = this;
const { root } = config;
const data = url.parse(path);

options = Object.assign({
relative: config.relative_link
}, options);

// Exit if this is an external path
if (data.protocol) {
return path;
}

// Resolve relative url
if (options.relative) {
return relative_url(this.path, path);
}

// Prepend root path
path = root + path;

return path.replace(/\/{2,}/g, '/');
}

module.exports = urlForHelper;
module.exports = function(path, options) {
return url_for.call(this, path, options);
};
curbengh marked this conversation as resolved.
Show resolved Hide resolved
5 changes: 3 additions & 2 deletions lib/plugins/tag/asset_img.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
'use strict';

const url = require('url');
const { resolve } = require('url');
const img = require('./img');
const { encodeURL } = require('hexo-util');

/**
* Asset image tag
Expand All @@ -19,7 +20,7 @@ module.exports = ctx => {
for (let i = 0; i < len; i++) {
const asset = PostAsset.findOne({post: this._id, slug: args[i]});
if (asset) {
args[i] = url.resolve('/', asset.path);
args[i] = encodeURL(resolve('/', asset.path));
return img(ctx)(args);
}
}
Expand Down
8 changes: 5 additions & 3 deletions lib/plugins/tag/asset_link.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
'use strict';

const url = require('url');
const { escapeHTML } = require('hexo-util');
const { encodeURL, escapeHTML } = require('hexo-util');
const { resolve } = require('url');

/**
* Asset link tag
Expand Down Expand Up @@ -30,6 +30,8 @@ module.exports = ctx => {
const attrTitle = escapeHTML(title);
if (escape === 'true') title = attrTitle;

return `<a href="${url.resolve(ctx.config.root, asset.path)}" title="${attrTitle}">${title}</a>`;
const link = encodeURL(resolve(ctx.config.root, asset.path));

return `<a href="${link}" title="${attrTitle}">${title}</a>`;
};
};
7 changes: 5 additions & 2 deletions lib/plugins/tag/asset_path.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
'use strict';

const url = require('url');
const { resolve } = require('url');
const { encodeURL } = require('hexo-util');

/**
* Asset path tag
Expand All @@ -18,6 +19,8 @@ module.exports = ctx => {
const asset = PostAsset.findOne({post: this._id, slug});
if (!asset) return;

return url.resolve(ctx.config.root, asset.path);
const path = encodeURL(resolve(ctx.config.root, asset.path));

return path;
};
};
7 changes: 5 additions & 2 deletions lib/plugins/tag/post_link.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
'use strict';

const { escapeHTML } = require('hexo-util');
const { encodeURL, escapeHTML } = require('hexo-util');
const { resolve } = require('url');

/**
* Post link tag
Expand Down Expand Up @@ -29,6 +30,8 @@ module.exports = ctx => {
const attrTitle = escapeHTML(title);
if (escape === 'true') title = attrTitle;

return `<a href="${ctx.config.root}${post.path}" title="${attrTitle}">${title}</a>`;
const link = encodeURL(resolve(ctx.config.root, post.path));

return `<a href="${link}" title="${attrTitle}">${title}</a>`;
};
};
7 changes: 6 additions & 1 deletion lib/plugins/tag/post_path.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
'use strict';

const { resolve } = require('url');
const { encodeURL } = require('hexo-util');

/**
* Post path tag
*
Expand All @@ -16,6 +19,8 @@ module.exports = ctx => {
const post = Post.findOne({slug});
if (!post) return;

return ctx.config.root + post.path;
const link = encodeURL(resolve(ctx.config.root, post.path));

return link;
};
};
4 changes: 4 additions & 0 deletions test/scripts/helpers/relative_url.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,8 @@ describe('relative_url', () => {
relativeURL('foo/', '/').should.eql('../index.html');
relativeURL('foo/index.html', '/').should.eql('../index.html');
});

it('should encode path', () => {
relativeURL('foo/', 'css/fôo.css').should.eql('../css/f%C3%B4o.css');
});
});
8 changes: 8 additions & 0 deletions test/scripts/helpers/url_for.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,14 @@ describe('url_for', () => {

const urlFor = require('../../../lib/plugins/helper/url_for').bind(ctx);

it('should encode path', () => {
ctx.config.root = '/';
urlFor('fôo.html').should.eql('/f%C3%B4o.html');

ctx.config.root = '/fôo/';
urlFor('bár.html').should.eql('/f%C3%B4o/b%C3%A1r.html');
});

it('internal url (relative off)', () => {
ctx.config.root = '/';
urlFor('index.html').should.eql('/index.html');
Expand Down
9 changes: 9 additions & 0 deletions test/scripts/tags/asset_img.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,11 @@ describe('asset_img', () => {
slug: 'bar',
post: post._id
}),
PostAsset.insert({
_id: 'bár',
slug: 'bár',
post: post._id
}),
PostAsset.insert({
_id: 'spaced asset',
slug: 'spaced asset',
Expand All @@ -40,6 +45,10 @@ describe('asset_img', () => {
assetImg('bar').should.eql('<img src="/foo/bar" class="">');
});

it('should encode path', () => {
assetImg('bár').should.eql('<img src="/foo/b%C3%A1r" class="">');
});

it('default', () => {
assetImg('bar title').should.eql('<img src="/foo/bar" class="" title="title">');
});
Expand Down
9 changes: 9 additions & 0 deletions test/scripts/tags/asset_link.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,11 @@ describe('asset_link', () => {
slug: 'bar',
post: post._id
}),
PostAsset.insert({
_id: 'bár',
slug: 'bár',
post: post._id
}),
PostAsset.insert({
_id: 'spaced asset',
slug: 'spaced asset',
Expand All @@ -40,6 +45,10 @@ describe('asset_link', () => {
assetLink('bar').should.eql('<a href="/foo/bar" title="bar">bar</a>');
});

it('should encode path', () => {
assetLink('bár').should.eql('<a href="/foo/b%C3%A1r" title="bár">bár</a>');
});

it('title', () => {
assetLink('bar Hello world').should.eql('<a href="/foo/bar" title="Hello world">Hello world</a>');
});
Expand Down
9 changes: 9 additions & 0 deletions test/scripts/tags/asset_path.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,11 @@ describe('asset_path', () => {
slug: 'bar',
post: post._id
}),
PostAsset.insert({
_id: 'bár',
slug: 'bár',
post: post._id
}),
PostAsset.insert({
_id: 'spaced asset',
slug: 'spaced asset',
Expand All @@ -40,6 +45,10 @@ describe('asset_path', () => {
assetPath('bar').should.eql('/foo/bar');
});

it('should encode path', () => {
assetPath('bár').should.eql('/foo/b%C3%A1r');
});

it('with space', () => {
// {% asset_path "spaced asset" %}
assetPathTag.call(post, ['spaced asset'])
Expand Down
9 changes: 9 additions & 0 deletions test/scripts/tags/post_link.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,21 @@ describe('post_link', () => {
source: 'title-with-tag',
slug: 'title-with-tag',
title: '"Hello" <new world>!'
},
{
source: 'fôo',
slug: 'fôo',
title: 'Hello world'
}])));

it('default', () => {
postLink(['foo']).should.eql('<a href="/foo/" title="Hello world">Hello world</a>');
});

it('should encode path', () => {
postLink(['fôo']).should.eql('<a href="/f%C3%B4o/" title="Hello world">Hello world</a>');
});

it('title', () => {
postLink(['foo', 'test']).should.eql('<a href="/foo/" title="test">test</a>');
});
Expand Down
11 changes: 9 additions & 2 deletions test/scripts/tags/post_path.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,22 @@ describe('post_path', () => {

hexo.config.permalink = ':title/';

before(() => hexo.init().then(() => Post.insert({
before(() => hexo.init().then(() => Post.insert([{
source: 'foo',
slug: 'foo'
})));
}, {
source: 'fôo',
slug: 'fôo'
}])));

it('default', () => {
postPath(['foo']).should.eql('/foo/');
});

it('should encode path', () => {
postPath(['fôo']).should.eql('/f%C3%B4o/');
});

it('no slug', () => {
should.not.exist(postPath([]));
});
Expand Down