Skip to content

Commit 47433cb

Browse files
authored
Merge pull request #3690 from curbengh/sri-css
feat(css_helper): add support for custom attributes
2 parents 7126202 + 814b4d8 commit 47433cb

File tree

2 files changed

+75
-16
lines changed

2 files changed

+75
-16
lines changed

lib/plugins/helper/css.js

Lines changed: 38 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,46 @@
11
'use strict';
22

3+
const { htmlTag } = require('hexo-util');
4+
const url_for = require('./url_for');
5+
6+
const flatten = function(arr, result = []) {
7+
for (const i in arr) {
8+
const value = arr[i];
9+
if (Array.isArray(value)) {
10+
flatten(value, result);
11+
} else {
12+
result.push(value);
13+
}
14+
}
15+
return result;
16+
};
17+
318
function cssHelper(...args) {
4-
return args.reduce((result, path, i) => {
5-
if (i) result += '\n';
19+
let result = '\n';
20+
let items = args;
21+
22+
if (!Array.isArray(args)) {
23+
items = [args];
24+
}
25+
26+
items = flatten(items);
627

7-
if (Array.isArray(path)) {
8-
return result + Reflect.apply(cssHelper, this, path);
28+
items.forEach(item => {
29+
// Old syntax
30+
if (typeof item === 'string' || item instanceof String) {
31+
let path = item;
32+
if (!path.endsWith('.css')) {
33+
path += '.css';
34+
}
35+
result += `<link rel="stylesheet" href="${this.url_for(path)}">\n`;
36+
} else {
37+
// New syntax
38+
item.href = url_for.call(this, item.href);
39+
if (!item.href.endsWith('.css')) item.href += '.css';
40+
result += htmlTag('link', { rel: 'stylesheet', ...item }) + '\n';
941
}
10-
if (!path.includes('?') && !path.endsWith('.css')) path += '.css';
11-
return `${result}<link rel="stylesheet" href="${this.url_for(path)}">`;
12-
}, '');
42+
});
43+
return result;
1344
}
1445

1546
module.exports = cssHelper;

test/scripts/helpers/css.js

Lines changed: 37 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
'use strict';
22

3+
const cheerio = require('cheerio');
4+
35
describe('css', () => {
46
const Hexo = require('../../../lib/hexo');
57
const hexo = new Hexo(__dirname);
@@ -12,14 +14,22 @@ describe('css', () => {
1214

1315
const css = require('../../../lib/plugins/helper/css').bind(ctx);
1416

15-
function assertResult(result) {
16-
let expected = '';
17+
function assertResult(result, expected) {
18+
const $ = cheerio.load(result);
1719

18-
for (let i = 1, len = arguments.length; i < len; i++) {
19-
expected += '<link rel="stylesheet" href="' + arguments[i] + '">\n';
20+
if (!Array.isArray(expected)) {
21+
expected = [expected];
2022
}
2123

22-
result.should.eql(expected.trim());
24+
expected.forEach((item, index) => {
25+
if (typeof item === 'string' || item instanceof String) {
26+
$('link').eq(index).attr('href').should.eql(item);
27+
} else {
28+
for (const attribute in item) {
29+
$('link').eq(index).attr(attribute).should.eql(item[attribute]);
30+
}
31+
}
32+
});
2333
}
2434

2535
it('a string', () => {
@@ -30,18 +40,36 @@ describe('css', () => {
3040
});
3141

3242
it('an array', () => {
33-
assertResult(css(['foo', 'bar', 'baz']), '/foo.css', '/bar.css', '/baz.css');
43+
assertResult(css(['foo', 'bar', 'baz']), ['/foo.css', '/bar.css', '/baz.css']);
3444
});
3545

3646
it('multiple strings', () => {
37-
assertResult(css('foo', 'bar', 'baz'), '/foo.css', '/bar.css', '/baz.css');
47+
assertResult(css('foo', 'bar', 'baz'), ['/foo.css', '/bar.css', '/baz.css']);
3848
});
3949

4050
it('multiple arrays', () => {
41-
assertResult(css(['foo', 'bar'], ['baz']), '/foo.css', '/bar.css', '/baz.css');
51+
assertResult(css(['foo', 'bar'], ['baz']), ['/foo.css', '/bar.css', '/baz.css']);
4252
});
4353

4454
it('mixed', () => {
45-
assertResult(css(['foo', 'bar'], 'baz'), '/foo.css', '/bar.css', '/baz.css');
55+
assertResult(css(['foo', 'bar'], 'baz'), ['/foo.css', '/bar.css', '/baz.css']);
56+
});
57+
58+
it('an object', () => {
59+
assertResult(css({href: 'script.css'}), {href: '/script.css'});
60+
assertResult(css({href: '/script.css'}), {href: '/script.css'});
61+
assertResult(css({href: '/script.css', foo: 'bar'}), {href: '/script.css', foo: 'bar'});
62+
});
63+
64+
it('mulitple objects', () => {
65+
assertResult(css({href: '/foo.css'}, {href: '/bar.css'}), [{href: '/foo.css'}, {href: '/bar.css'}]);
66+
assertResult(css({href: '/aaa.css', bbb: 'ccc'}, {href: '/ddd.css', eee: 'fff'}),
67+
[{href: '/aaa.css', bbb: 'ccc'}, {href: '/ddd.css', eee: 'fff'}]);
68+
});
69+
70+
it('an array of objects', () => {
71+
assertResult(css([{href: '/foo.css'}, {href: '/bar.css'}]), [{href: '/foo.css'}, {href: '/bar.css'}]);
72+
assertResult(css([{href: '/aaa.css', bbb: 'ccc'}, {href: '/ddd.css', eee: 'fff'}]),
73+
[{href: '/aaa.css', bbb: 'ccc'}, {href: '/ddd.css', eee: 'fff'}]);
4674
});
4775
});

0 commit comments

Comments
 (0)