Skip to content

Commit

Permalink
refactor(injector): add exec() method
Browse files Browse the repository at this point in the history
- Remove injectorFilter from plugin dir
- Move cache into Injector Class
- Remove decache
  • Loading branch information
SukkaW committed Feb 6, 2020
1 parent 18421ce commit 8cdaf0b
Show file tree
Hide file tree
Showing 7 changed files with 202 additions and 205 deletions.
43 changes: 43 additions & 0 deletions lib/extend/injector.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
'use strict';

const { Cache } = require('hexo-util');

class Injector {
constructor() {
this.store = {
Expand All @@ -8,6 +10,8 @@ class Injector {
body_begin: {},
body_end: {}
};

this.cache = new Cache();
}

list() {
Expand All @@ -33,6 +37,45 @@ class Injector {
valueSet.add(value);
entryMap[to] = valueSet;
}

exec(data, locals = { page: {} }) {
let currentType = 'default';
const { page } = locals;

if (page.__index) currentType = 'home';
if (page.__post) currentType = 'post';
if (page.__page) currentType = 'page';
if (page.archive) currentType = 'archive';
if (page.category) currentType = 'category';
if (page.tag) currentType = 'tag';
if (page.layout) currentType = page.layout;

const injector = (data, pattern, flag, isBegin = true) => {
if (data.includes(`hexo injector ${flag}`)) return data;

const code = this.cache.apply(`${flag}-${currentType}-code`, () => {
const content = currentType === 'default' ? this.getText(flag, 'default') : this.getText(flag, currentType) + this.getText(flag, 'default');

if (!content.length) return '';
return '<!-- hexo injector ' + flag + ' start -->' + content + '<!-- hexo injector ' + flag + ' end -->';
});

// avoid unnesscary replace() for better performance
if (!code.length) return data;
return data.replace(pattern, str => { return isBegin ? str + code : code + str; });
};

// Inject head_begin
data = injector(data, /<head.*?>/, 'head_begin', true);
// Inject head_end
data = injector(data, '</head>', 'head_end', false);
// Inject body_begin
data = injector(data, /<body.*?>/, 'body_begin', true);
// Inject body_end
data = injector(data, '</body>', 'body_end', false);

return data;
}
}

module.exports = Injector;
4 changes: 2 additions & 2 deletions lib/hexo/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ const defaultConfig = require('./default_config');
const loadDatabase = require('./load_database');
const multiConfigPath = require('./multi_config_path');
const { sync } = require('resolve');
const injectorFilter = require('../plugins/injector');
const { inherits } = require('util');
const { deepMerge, full_url_for } = require('hexo-util');

Expand Down Expand Up @@ -57,7 +56,7 @@ const createLoadThemeRoute = function(generatorResult, locals, ctx) {
if (view) {
log.debug(`Rendering HTML ${name}: ${magenta(path)}`);
return view.render(locals)
.then(result => injectorFilter.call(ctx, result, locals))
.then(result => ctx.extend.injector.exec(result, locals))
.then(result => ctx.execFilter('after_route_render', result, {
context: ctx,
args: [locals]
Expand Down Expand Up @@ -225,6 +224,7 @@ class Hexo {
require('../plugins/filter')(this);
require('../plugins/generator')(this);
require('../plugins/helper')(this);
require('../plugins/injector')(this);
require('../plugins/processor')(this);
require('../plugins/renderer')(this);
require('../plugins/tag')(this);
Expand Down
54 changes: 4 additions & 50 deletions lib/plugins/injector/index.js
Original file line number Diff line number Diff line change
@@ -1,52 +1,6 @@
'use strict';

const { Cache } = require('hexo-util');
const cache = new Cache();

function injectFilter(data, locals = { page: {} }) {
const Injector = this.extend.injector;

const current = () => {
const { page } = locals;

if (page.__index) return 'home';
if (page.__post) return 'post';
if (page.__page) return 'page';
if (page.archive) return 'archive';
if (page.category) return 'category';
if (page.tag) return 'tag';
if (page.layout) return page.layout;
return 'default';
};

function injector(data, pattern, flag, isBegin = true) {
if (data.includes(`hexo injector ${flag}`)) return data;

const currentType = current();
const code = cache.apply(`${flag}-${currentType}-code`, () => {
const content = currentType === 'default' ? Injector.getText(flag, 'default') : Injector.getText(flag, currentType) + Injector.getText(flag, 'default');

if (!content.length) return '';

return '<!-- hexo injector ' + flag + ' start -->' + content + '<!-- hexo injector ' + flag + ' end -->';
});

// avoid unnesscary replace() for better performance
if (!code.length) return data;

return data.replace(pattern, str => { return isBegin ? str + code : code + str; });
}

// Inject head_begin
data = injector(data, /<head.*?>/, 'head_begin', true);
// Inject head_end
data = injector(data, '</head>', 'head_end', false);
// Inject body_begin
data = injector(data, /<body.*?>/, 'body_begin', true);
// Inject body_end
data = injector(data, '</body>', 'body_end', false);

return data;
}

module.exports = injectFilter;
module.exports = ctx => {
// eslint-disable-next-line no-unused-vars
const { injector } = ctx.extend;
};
1 change: 0 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,6 @@
"chai": "^4.1.2",
"chai-as-promised": "^7.1.1",
"cheerio": "0.22.0",
"decache": "^4.5.1",
"eslint": "^6.0.1",
"eslint-config-hexo": "^4.1.0",
"hexo-renderer-marked": "^2.0.0",
Expand Down
1 change: 0 additions & 1 deletion test/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ describe('Hexo', () => {
require('./scripts/generators');
require('./scripts/helpers');
require('./scripts/hexo');
require('./scripts/injector');
require('./scripts/models');
require('./scripts/processors');
require('./scripts/renderers');
Expand Down
153 changes: 153 additions & 0 deletions test/scripts/extend/injector.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,18 @@
'use strict';

describe('Injector', () => {
const content = [
'<!DOCTYPE html>',
'<html lang="en">',
'<head id="head"><title>Test</title>',
'</head>',
'<body id="body">',
'<div></div>',
'<p></p>',
'</body>',
'</html>'
].join('');

const Injector = require('../../../lib/extend/injector');

it('register() - entry is required', () => {
Expand Down Expand Up @@ -81,4 +93,145 @@ describe('Injector', () => {
i.getText('body_end', 'home').should.eql(str);
i.getText('body_end').should.eql('');
});

it('exec() - default', () => {
const i = new Injector();
const result = i.exec(content);
result.should.contain('<head id="head"><title>Test</title></head>');
result.should.contain('<body id="body"><div></div><p></p></body>');
});

it('exec() - default', () => {
const i = new Injector();
const result = i.exec(content);
result.should.contain('<head id="head"><title>Test</title></head>');
result.should.contain('<body id="body"><div></div><p></p></body>');
});

it('exec() - insert code', () => {
const i = new Injector();

i.register('head_begin', '<!-- Powered by Hexo -->');
i.register('head_end', '<link href="prism.css" rel="stylesheet">');
i.register('head_end', '<link href="prism-linenumber.css" rel="stylesheet">');
i.register('body_begin', '<script>window.Prism = window.Prism || {}; window.Prism.manual = true;</script>');
i.register('body_end', '<script src="prism.js"></script>');

const result = i.exec(content);

result.should.contain('<head id="head"><!-- hexo injector head_begin start --><!-- Powered by Hexo --><!-- hexo injector head_begin end -->');
result.should.contain('<!-- hexo injector head_end start --><link href="prism.css" rel="stylesheet"><link href="prism-linenumber.css" rel="stylesheet"><!-- hexo injector head_end end --></head>');
result.should.contain('<body id="body"><!-- hexo injector body_begin start --><script>window.Prism = window.Prism || {}; window.Prism.manual = true;</script><!-- hexo injector body_begin end -->');
result.should.contain('<!-- hexo injector body_end start --><script src="prism.js"></script><!-- hexo injector body_end end --></body>');
});

it('exec() - no duplicate insert', () => {
const content = [
'<!DOCTYPE html>',
'<html lang="en">',
'<head id="head"><!-- hexo injector head_begin start --><!-- hexo injector head_begin end -->',
'<title>Test</title>',
'<!-- hexo injector head_end start --><link href="prism.css" rel="stylesheet"></head>',
'<body id="body"><!-- hexo injector body_begin start --><!-- hexo injector body_begin end -->',
'<div></div>',
'<p></p>',
'<!-- hexo injector body_end start --><script src="prism.js"></script><!-- hexo injector body_end end --></body>',
'</html>'
].join('');

const i = new Injector();

i.register('head_begin', '<!-- Powered by Hexo -->');
i.register('head_end', '<link href="prism.css" rel="stylesheet">');
i.register('head_end', '<link href="prism-linenumber.css" rel="stylesheet">');
i.register('body_begin', '<script>window.Prism = window.Prism || {}; window.Prism.manual = true;</script>');
i.register('body_end', '<script src="prism.js"></script>');

const result = i.exec(content);

result.should.contain('<head id="head"><!-- hexo injector head_begin start --><!-- hexo injector head_begin end -->');
result.should.contain('<!-- hexo injector head_end start --><link href="prism.css" rel="stylesheet"></head>');
result.should.contain('<body id="body"><!-- hexo injector body_begin start --><!-- hexo injector body_begin end -->');
result.should.contain('<!-- hexo injector body_end start --><script src="prism.js"></script><!-- hexo injector body_end end --></body>');
});

it('exec() - multi-line head & body', () => {
const content = [
'<!DOCTYPE html>',
'<html lang="en">',
'<head id="head"><title>Test</title>',
'</head>',
'<body id="body">',
'<div></div>',
'<p></p>',
'</body>',
'</html>'
].join('\n');

const i = new Injector();

i.register('head_begin', '<!-- Powered by Hexo -->');
i.register('head_end', '<link href="prism.css" rel="stylesheet">');
i.register('head_end', '<link href="prism-linenumber.css" rel="stylesheet">');
i.register('body_begin', '<script>window.Prism = window.Prism || {}; window.Prism.manual = true;</script>');
i.register('body_end', '<script src="prism.js"></script>');

const result = i.exec(content);

result.should.contain('<head id="head"><!-- hexo injector head_begin start --><!-- Powered by Hexo --><!-- hexo injector head_begin end -->');
result.should.contain('<!-- hexo injector head_end start --><link href="prism.css" rel="stylesheet"><link href="prism-linenumber.css" rel="stylesheet"><!-- hexo injector head_end end --></head>');
result.should.contain('<body id="body"><!-- hexo injector body_begin start --><script>window.Prism = window.Prism || {}; window.Prism.manual = true;</script><!-- hexo injector body_begin end -->');
result.should.contain('<!-- hexo injector body_end start --><script src="prism.js"></script><!-- hexo injector body_end end --></body>');
});

it('exec() - inject on specific page', () => {
const content = [
'<!DOCTYPE html>',
'<html lang="en">',
'<head id="head"><title>Test</title>',
'</head>',
'<body id="body">',
'<div></div>',
'<p></p>',
'</body>',
'</html>'
].join('\n');

const i = new Injector();

i.register('head_begin', '<!-- head_begin_default -->');
i.register('head_begin', '<!-- head_begin_home -->', 'home');
i.register('head_begin', '<!-- head_begin_post -->', 'post');
i.register('head_begin', '<!-- head_begin_page -->', 'page');
i.register('head_begin', '<!-- head_begin_archive -->', 'archive');
i.register('head_begin', '<!-- head_begin_category -->', 'category');
i.register('head_begin', '<!-- head_begin_tag -->', 'tag');

const result1 = i.exec(content, { page: {} });
const result2 = i.exec(content, { page: { __index: true } });
const result3 = i.exec(content, { page: { __post: true } });
const result4 = i.exec(content, { page: { __page: true } });
const result5 = i.exec(content, { page: { archive: true } });
const result6 = i.exec(content, { page: { category: true } });
const result7 = i.exec(content, { page: { tag: true } });

// home
result1.should.not.contain('<!-- head_begin_home -->');
result2.should.contain('<!-- head_begin_home --><!-- head_begin_default -->');
// post
result1.should.not.contain('<!-- head_begin_post -->');
result3.should.contain('<!-- head_begin_post --><!-- head_begin_default -->');
// page
result1.should.not.contain('<!-- head_begin_page -->');
result4.should.contain('<!-- head_begin_page --><!-- head_begin_default -->');
// archive
result1.should.not.contain('<!-- head_begin_archive -->');
result5.should.contain('<!-- head_begin_archive --><!-- head_begin_default -->');
// category
result1.should.not.contain('<!-- head_begin_category -->');
result6.should.contain('<!-- head_begin_category --><!-- head_begin_default -->');
// tag
result1.should.not.contain('<!-- head_begin_tag -->');
result7.should.contain('<!-- head_begin_tag --><!-- head_begin_default -->');
});
});
Loading

0 comments on commit 8cdaf0b

Please sign in to comment.