Skip to content

Commit

Permalink
Split cache in Post.prototype.render() into classes (#3117)
Browse files Browse the repository at this point in the history
* Divide internal cache of Post.prototype.render into classes

* move RegExp object into local scope

* Combine unnecessarily divided callbacks in Post.prototype.render().

* refactor: Post.prototype.render()
  • Loading branch information
segayuu authored and NoahDragon committed Apr 13, 2018
1 parent 106980e commit 373b9c7
Showing 1 changed file with 55 additions and 55 deletions.
110 changes: 55 additions & 55 deletions lib/hexo/post.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,40 @@ const { slugize, escapeRegExp } = require('hexo-util');
const fs = require('hexo-fs');
const yfm = require('hexo-front-matter');

const rEscapeContent = /<escape(?:[^>]*)>([\s\S]*?)<\/escape>/g;
const rSwigVar = /\{\{[\s\S]*?\}\}/g;
const rSwigComment = /\{#[\s\S]*?#\}/g;
const rSwigBlock = /\{%[\s\S]*?%\}/g;
const rSwigFullBlock = /\{% *(.+?)(?: *| +.*)%\}[\s\S]+?\{% *end\1 *%\}/g;
const placeholder = '\uFFFC';
const rPlaceholder = /(?:<|&lt;)!--\uFFFC(\d+)--(?:>|&gt;)/g;

const preservedKeys = ['title', 'slug', 'path', 'layout', 'date', 'content'];

function PostRenderCache() {
this.cache = [];
}

const _escapeContent = (cache, str) => {
const placeholder = '\uFFFC';
return `<!--${placeholder}${cache.push(str) - 1}-->`;
};

PostRenderCache.prototype.escapeContent = function(str) {
const rEscapeContent = /<escape(?:[^>]*)>([\s\S]*?)<\/escape>/g;
return str.replace(rEscapeContent, (_, content) => _escapeContent(this.cache, content));
};

PostRenderCache.prototype.loadContent = function(str) {
const rPlaceholder = /(?:<|&lt;)!--\uFFFC(\d+)--(?:>|&gt;)/g;
return str.replace(rPlaceholder, (_, index) => this.cache[index]);
};

PostRenderCache.prototype.escapeAllSwigTags = function(str) {
const rSwigVar = /\{\{[\s\S]*?\}\}/g;
const rSwigComment = /\{#[\s\S]*?#\}/g;
const rSwigBlock = /\{%[\s\S]*?%\}/g;
const rSwigFullBlock = /\{% *(.+?)(?: *| +.*)%\}[\s\S]+?\{% *end\1 *%\}/g;

const escape = _str => _escapeContent(this.cache, _str);
return str.replace(rSwigFullBlock, escape)
.replace(rSwigBlock, escape)
.replace(rSwigComment, '')
.replace(rSwigVar, escape);
};

function Post(context) {
this.context = context;
}
Expand Down Expand Up @@ -200,36 +224,9 @@ Post.prototype.publish = function(data, replace, callback) {
Post.prototype.render = function(source, data = {}, callback) {
const ctx = this.context;
const { config } = ctx;
const cache = [];
const { tag } = ctx.extend;
const ext = data.engine || (source ? pathFn.extname(source) : '');

const isSwig = ext === 'swig';

let disableNunjucks = false;

if (ext && ctx.render.renderer.get(ext)) {

// disable Nunjucks when the renderer spcify that.

disableNunjucks = disableNunjucks || !!ctx.render.renderer.get(ext).disableNunjucks;

}

function escapeContent(str) {
return `<!--${placeholder}${cache.push(str) - 1}-->`;
}

function tagFilter(content) {
if (disableNunjucks) return content;
// Replace cache data with real contents
content = content.replace(rPlaceholder, (...args) => cache[args[1]]);

// Render with Nunjucks
data.content = content;
return tag.render(data.content, data);
}

let promise;

if (data.content != null) {
Expand All @@ -241,24 +238,29 @@ Post.prototype.render = function(source, data = {}, callback) {
return Promise.reject(new Error('No input file or string!')).asCallback(callback);
}

const isSwig = ext === 'swig';

// disable Nunjucks when the renderer spcify that.
const disableNunjucks = ext && ctx.render.renderer.get(ext) && !!ctx.render.renderer.get(ext).disableNunjucks;

const cacheObj = new PostRenderCache();

return promise.then(content => {
data.content = content;

// Run "before_post_render" filters
return ctx.execFilter('before_post_render', data, {context: ctx}).then(() => {
data.content = data.content.replace(rEscapeContent, (match, content) => escapeContent(content));
});
return ctx.execFilter('before_post_render', data, {context: ctx});
}).then(() => {
// Skip rendering if this is a swig file
if (isSwig) return data.content;
data.content = cacheObj.escapeContent(data.content);

if (isSwig) {
// Render with Nunjucks if this is a swig file
return tag.render(data.content, data);
}

// Escape all Swig tags
if (!disableNunjucks) {
data.content = data.content
.replace(rSwigFullBlock, escapeContent)
.replace(rSwigBlock, escapeContent)
.replace(rSwigComment, '')
.replace(rSwigVar, escapeContent);
data.content = cacheObj.escapeAllSwigTags(data.content);
}

const options = data.markdown || {};
Expand All @@ -270,17 +272,15 @@ Post.prototype.render = function(source, data = {}, callback) {
path: source,
engine: data.engine,
toString: true,
onRenderEnd: tagFilter
}, options);
}).then(content => {
data.content = content;
onRenderEnd(content) {
if (disableNunjucks) return content;
// Replace cache data with real contents
data.content = cacheObj.loadContent(content);

if (!isSwig) {
return data.content;
}

// Render with Nunjucks
return tag.render(data.content, data);
// Render with Nunjucks
return tag.render(data.content, data);
}
}, options);
}).then(content => {
data.content = content;

Expand Down

0 comments on commit 373b9c7

Please sign in to comment.