From 8cdaf0b756662ca425fd2bce64ad364ca9e9f55e Mon Sep 17 00:00:00 2001 From: SukkaW Date: Fri, 31 Jan 2020 22:41:07 +0800 Subject: [PATCH] refactor(injector): add exec() method - Remove injectorFilter from plugin dir - Move cache into Injector Class - Remove decache --- lib/extend/injector.js | 43 +++++++++ lib/hexo/index.js | 4 +- lib/plugins/injector/index.js | 54 +---------- package.json | 1 - test/index.js | 1 - test/scripts/extend/injector.js | 153 ++++++++++++++++++++++++++++++++ test/scripts/injector/index.js | 151 ------------------------------- 7 files changed, 202 insertions(+), 205 deletions(-) delete mode 100644 test/scripts/injector/index.js diff --git a/lib/extend/injector.js b/lib/extend/injector.js index 116e39cbff..ed25e1041c 100644 --- a/lib/extend/injector.js +++ b/lib/extend/injector.js @@ -1,5 +1,7 @@ 'use strict'; +const { Cache } = require('hexo-util'); + class Injector { constructor() { this.store = { @@ -8,6 +10,8 @@ class Injector { body_begin: {}, body_end: {} }; + + this.cache = new Cache(); } list() { @@ -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 '' + content + ''; + }); + + // 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_begin', true); + // Inject head_end + data = injector(data, '', 'head_end', false); + // Inject body_begin + data = injector(data, //, 'body_begin', true); + // Inject body_end + data = injector(data, '', 'body_end', false); + + return data; + } } module.exports = Injector; diff --git a/lib/hexo/index.js b/lib/hexo/index.js index 7e442f4ad9..05a2098619 100644 --- a/lib/hexo/index.js +++ b/lib/hexo/index.js @@ -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'); @@ -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] @@ -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); diff --git a/lib/plugins/injector/index.js b/lib/plugins/injector/index.js index 7dc8583a92..be1a9aaca9 100644 --- a/lib/plugins/injector/index.js +++ b/lib/plugins/injector/index.js @@ -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 '' + content + ''; - }); - - // 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_begin', true); - // Inject head_end - data = injector(data, '', 'head_end', false); - // Inject body_begin - data = injector(data, //, 'body_begin', true); - // Inject body_end - data = injector(data, '', 'body_end', false); - - return data; -} - -module.exports = injectFilter; +module.exports = ctx => { + // eslint-disable-next-line no-unused-vars + const { injector } = ctx.extend; +}; diff --git a/package.json b/package.json index 6efe4fd042..6ea886e2a8 100644 --- a/package.json +++ b/package.json @@ -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", diff --git a/test/index.js b/test/index.js index 6210636470..68b8655b91 100644 --- a/test/index.js +++ b/test/index.js @@ -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'); diff --git a/test/scripts/extend/injector.js b/test/scripts/extend/injector.js index 3b471b986f..900c331f8f 100644 --- a/test/scripts/extend/injector.js +++ b/test/scripts/extend/injector.js @@ -1,6 +1,18 @@ 'use strict'; describe('Injector', () => { + const content = [ + '', + '', + 'Test', + '', + '', + '
', + '

', + '', + '' + ].join(''); + const Injector = require('../../../lib/extend/injector'); it('register() - entry is required', () => { @@ -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('Test'); + result.should.contain('

'); + }); + + it('exec() - default', () => { + const i = new Injector(); + const result = i.exec(content); + result.should.contain('Test'); + result.should.contain('

'); + }); + + it('exec() - insert code', () => { + const i = new Injector(); + + i.register('head_begin', ''); + i.register('head_end', ''); + i.register('head_end', ''); + i.register('body_begin', ''); + i.register('body_end', ''); + + const result = i.exec(content); + + result.should.contain(''); + result.should.contain(''); + result.should.contain(''); + result.should.contain(''); + }); + + it('exec() - no duplicate insert', () => { + const content = [ + '', + '', + '', + 'Test', + '', + '', + '
', + '

', + '', + '' + ].join(''); + + const i = new Injector(); + + i.register('head_begin', ''); + i.register('head_end', ''); + i.register('head_end', ''); + i.register('body_begin', ''); + i.register('body_end', ''); + + const result = i.exec(content); + + result.should.contain(''); + result.should.contain(''); + result.should.contain(''); + result.should.contain(''); + }); + + it('exec() - multi-line head & body', () => { + const content = [ + '', + '', + 'Test', + '', + '', + '
', + '

', + '', + '' + ].join('\n'); + + const i = new Injector(); + + i.register('head_begin', ''); + i.register('head_end', ''); + i.register('head_end', ''); + i.register('body_begin', ''); + i.register('body_end', ''); + + const result = i.exec(content); + + result.should.contain(''); + result.should.contain(''); + result.should.contain(''); + result.should.contain(''); + }); + + it('exec() - inject on specific page', () => { + const content = [ + '', + '', + 'Test', + '', + '', + '
', + '

', + '', + '' + ].join('\n'); + + const i = new Injector(); + + i.register('head_begin', ''); + i.register('head_begin', '', 'home'); + i.register('head_begin', '', 'post'); + i.register('head_begin', '', 'page'); + i.register('head_begin', '', 'archive'); + i.register('head_begin', '', 'category'); + i.register('head_begin', '', '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(''); + result2.should.contain(''); + // post + result1.should.not.contain(''); + result3.should.contain(''); + // page + result1.should.not.contain(''); + result4.should.contain(''); + // archive + result1.should.not.contain(''); + result5.should.contain(''); + // category + result1.should.not.contain(''); + result6.should.contain(''); + // tag + result1.should.not.contain(''); + result7.should.contain(''); + }); }); diff --git a/test/scripts/injector/index.js b/test/scripts/injector/index.js deleted file mode 100644 index d5e62a4286..0000000000 --- a/test/scripts/injector/index.js +++ /dev/null @@ -1,151 +0,0 @@ -'use strict'; - -const decache = require('decache'); - -describe('Injector', () => { - const Hexo = require('../../../lib/hexo'); - let hexo, injectorFilter; - - beforeEach(async () => { - await decache('../../../lib/plugins/injector'); - hexo = new Hexo(); - injectorFilter = require('../../../lib/plugins/injector').bind(hexo); - }); - - const content = [ - '', - '', - 'Test', - '', - '', - '
', - '

', - '', - '' - ].join(''); - - it('default', () => { - const result = injectorFilter(content); - result.should.contain('Test'); - result.should.contain('

'); - }); - - it('insert code', () => { - hexo.extend.injector.register('head_begin', ''); - hexo.extend.injector.register('head_end', ''); - hexo.extend.injector.register('head_end', ''); - hexo.extend.injector.register('body_begin', ''); - hexo.extend.injector.register('body_end', ''); - - const result = injectorFilter(content); - - result.should.contain(''); - result.should.contain(''); - result.should.contain(''); - result.should.contain(''); - }); - - it('no duplicate insert', () => { - const content = [ - '', - '', - '', - 'Test', - '', - '', - '
', - '

', - '', - '' - ].join(''); - - hexo.extend.injector.register('head_begin', ''); - hexo.extend.injector.register('head_end', ''); - hexo.extend.injector.register('head_end', ''); - hexo.extend.injector.register('body_begin', ''); - hexo.extend.injector.register('body_end', ''); - - const result = injectorFilter(content); - - result.should.contain(''); - result.should.contain(''); - result.should.contain(''); - result.should.contain(''); - }); - - it('multi-line head & body', () => { - const content = [ - '', - '', - 'Test', - '', - '', - '
', - '

', - '', - '' - ].join('\n'); - - hexo.extend.injector.register('head_begin', ''); - hexo.extend.injector.register('head_end', ''); - hexo.extend.injector.register('head_end', ''); - hexo.extend.injector.register('body_begin', ''); - hexo.extend.injector.register('body_end', ''); - - const result = injectorFilter(content); - - result.should.contain(''); - result.should.contain(''); - result.should.contain(''); - result.should.contain(''); - }); - - it('inject on specific page', () => { - const content = [ - '', - '', - 'Test', - '', - '', - '
', - '

', - '', - '' - ].join('\n'); - - hexo.extend.injector.register('head_begin', ''); - hexo.extend.injector.register('head_begin', '', 'home'); - hexo.extend.injector.register('head_begin', '', 'post'); - hexo.extend.injector.register('head_begin', '', 'page'); - hexo.extend.injector.register('head_begin', '', 'archive'); - hexo.extend.injector.register('head_begin', '', 'category'); - hexo.extend.injector.register('head_begin', '', 'tag'); - - const result1 = injectorFilter(content, { page: {} }); - const result2 = injectorFilter(content, { page: { __index: true } }); - const result3 = injectorFilter(content, { page: { __post: true } }); - const result4 = injectorFilter(content, { page: { __page: true } }); - const result5 = injectorFilter(content, { page: { archive: true } }); - const result6 = injectorFilter(content, { page: { category: true } }); - const result7 = injectorFilter(content, { page: { tag: true } }); - - // home - result1.should.not.contain(''); - result2.should.contain(''); - // post - result1.should.not.contain(''); - result3.should.contain(''); - // page - result1.should.not.contain(''); - result4.should.contain(''); - // archive - result1.should.not.contain(''); - result5.should.contain(''); - // category - result1.should.not.contain(''); - result6.should.contain(''); - // tag - result1.should.not.contain(''); - result7.should.contain(''); - }); -});