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

refactor(render): Class syntax #3935

Merged
merged 3 commits into from
Dec 15, 2019
Merged
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
184 changes: 93 additions & 91 deletions lib/hexo/render.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,127 +2,129 @@

const { extname } = require('path');
const Promise = require('bluebird');
const fs = require('hexo-fs');
const { readFile, readFileSync } = require('hexo-fs');

function getExtname(str) {
const getExtname = str => {
if (typeof str !== 'string') return '';

const ext = extname(str);
return ext[0] === '.' ? ext.slice(1) : ext;
}

function Render(ctx) {
this.context = ctx;
this.renderer = ctx.extend.renderer;
}

Render.prototype.isRenderable = function(path) {
return this.renderer.isRenderable(path);
};

Render.prototype.isRenderableSync = function(path) {
return this.renderer.isRenderableSync(path);
};

Render.prototype.getOutput = function(path) {
return this.renderer.getOutput(path);
};
const toString = (result, options) => {
if (!Object.prototype.hasOwnProperty.call(options, 'toString') || typeof result === 'string') return result;

Render.prototype.getRenderer = function(ext, sync) {
return this.renderer.get(ext, sync);
};
if (typeof options.toString === 'function') {
return options.toString(result);
} else if (typeof result === 'object') {
return JSON.stringify(result);
} else if (result.toString) {
return result.toString();
}

Render.prototype.getRendererSync = function(ext) {
return this.getRenderer(ext, true);
return result;
};

Render.prototype.render = function(data, options, callback) {
if (!callback && typeof options === 'function') {
callback = options;
options = {};
class Render {
constructor(ctx) {
this.context = ctx;
this.renderer = ctx.extend.renderer;
}

const ctx = this.context;
let ext = '';
isRenderable(path) {
return this.renderer.isRenderable(path);
}

return new Promise((resolve, reject) => {
if (!data) return reject(new TypeError('No input file or string!'));
if (data.text != null) return resolve(data.text);
if (!data.path) return reject(new TypeError('No input file or string!'));
isRenderableSync(path) {
return this.renderer.isRenderableSync(path);
}

fs.readFile(data.path).then(resolve, reject);
}).then(text => {
data.text = text;
ext = data.engine || getExtname(data.path);
if (!ext || !this.isRenderable(ext)) return text;
getOutput(path) {
return this.renderer.getOutput(path);
}

const renderer = this.getRenderer(ext);
return Reflect.apply(renderer, ctx, [data, options]);
}).then(result => {
result = toString(result, data);
if (data.onRenderEnd) {
return data.onRenderEnd(result);
}
getRenderer(ext, sync) {
return this.renderer.get(ext, sync);
}

return result;
}).then(result => {
const output = this.getOutput(ext) || ext;
return ctx.execFilter(`after_render:${output}`, result, {
context: ctx,
args: [data]
});
}).asCallback(callback);
};
getRendererSync(ext) {
return this.getRenderer(ext, true);
}

Render.prototype.renderSync = function(data, options) {
if (!data) throw new TypeError('No input file or string!');
render(data, options, callback) {
if (!callback && typeof options === 'function') {
callback = options;
options = {};
}

options = options || {};
const ctx = this.context;
let ext = '';

return new Promise((resolve, reject) => {
if (!data) return reject(new TypeError('No input file or string!'));
if (data.text != null) return resolve(data.text);
if (!data.path) return reject(new TypeError('No input file or string!'));

readFile(data.path).then(resolve, reject);
}).then(text => {
data.text = text;
ext = data.engine || getExtname(data.path);
if (!ext || !this.isRenderable(ext)) return text;

const renderer = this.getRenderer(ext);
return Reflect.apply(renderer, ctx, [data, options]);
}).then(result => {
result = toString(result, data);
if (data.onRenderEnd) {
return data.onRenderEnd(result);
}

return result;
}).then(result => {
const output = this.getOutput(ext) || ext;
return ctx.execFilter(`after_render:${output}`, result, {
context: ctx,
args: [data]
});
}).asCallback(callback);
}

const ctx = this.context;
renderSync(data, options) {
if (!data) throw new TypeError('No input file or string!');

if (data.text == null) {
if (!data.path) throw new TypeError('No input file or string!');
data.text = fs.readFileSync(data.path);
}
options = options || {};

if (data.text == null) throw new TypeError('No input file or string!');
const ctx = this.context;

const ext = data.engine || getExtname(data.path);
let result;
if (data.text == null) {
if (!data.path) throw new TypeError('No input file or string!');
data.text = readFileSync(data.path);
}

if (ext && this.isRenderableSync(ext)) {
const renderer = this.getRendererSync(ext);
result = Reflect.apply(renderer, ctx, [data, options]);
} else {
result = data.text;
}
if (data.text == null) throw new TypeError('No input file or string!');

const output = this.getOutput(ext) || ext;
result = toString(result, data);
const ext = data.engine || getExtname(data.path);
let result;

if (data.onRenderEnd) {
result = data.onRenderEnd(result);
}
if (ext && this.isRenderableSync(ext)) {
const renderer = this.getRendererSync(ext);
result = Reflect.apply(renderer, ctx, [data, options]);
} else {
result = data.text;
}

return ctx.execFilterSync(`after_render:${output}`, result, {
context: ctx,
args: [data]
});
};
const output = this.getOutput(ext) || ext;
result = toString(result, data);

function toString(result, options) {
if (!Object.prototype.hasOwnProperty.call(options, 'toString') || typeof result === 'string') return result;
if (data.onRenderEnd) {
result = data.onRenderEnd(result);
}

if (typeof options.toString === 'function') {
return options.toString(result);
} else if (typeof result === 'object') {
return JSON.stringify(result);
} else if (result.toString) {
return result.toString();
return ctx.execFilterSync(`after_render:${output}`, result, {
context: ctx,
args: [data]
});
}

return result;
}

module.exports = Render;