var path = require('path');
var fs = require('fs');
require("./hooks-core-blocks-render.js")
class Echo {
get isEmpty() {
return !this.html.length;
}
constructor(message) {
this.html = "";
if (message) {
this.html = message;
}
this.attach = this.appendString.bind(this)
return this;
}
appendString(sth) {
if (typeof(sth) == 'string') {
this.html += sth;
}
else if (sth.toString && typeof(sth.toString) == 'function') {
this.html += sth.toString();
}
else {
var tryStr = JSON.Stringify( sth );
this.html += tryStr ? tryStr : '__UNDEFINED__';
}
return this;
}
}
var nv_render_static_url_registered = false;
var nv_render_rendering_mode_setted = false;
global.nv_render_assistant = ({rendering_mode, root_folder, template, routes})=>{
if (root_folder) {
if (!nv_render_static_url_registered) {
register_static_url('/', root_folder )
nv_render_static_url_registered = true;
} else {
console.log('错误:nv_render_assistant 多次设置 root_folder')
}
}
if (rendering_mode) {
if (!nv_render_rendering_mode_setted) {
set_frontstage_rendering_mode(rendering_mode, root_folder);
nv_render_rendering_mode_setted = true;
} else {
console.log('错误:nv_render_assistant 多次设置 rendering_mode')
}
}
if (routes) {
// 处理静态地址
routes.forEach(original_route=>{
add_action('register_server_side_render_router', express=>{
express.get(original_route.path, (req, res, next)=>{
// 需要解绑重新赋一下,不然的话会一个status改变后会污染原始的数据
var route = {...original_route}
async function fn() {
var type = route.type || 'text/html';
var use_template = route.use_template !== false;
var echo_instance = new Echo();
if (type == 'text/html' && use_template) {
// head
if (template && template.head) {
var head_func = template.head;
} else {
var head_func = (req,route) => `<!DOCTYPE html><html lang="zh-cn"><head>${ nv_head(req,route) }</head><body>`;
}
echo_instance.attach( head_func(req,route) );
// body
await do_async_action(`async:nv_render:${route.name}`, {
echo: echo_instance.attach,
req, res, route,
});
// footer
if (template && template.foot) {
var foot_func = template.foot;
} else {
var foot_func = (req,route) => `</body></html>`;
}
echo_instance.attach( foot_func(req,route) );
} else {
await do_async_action(`async:nv_render:${route.name}`, {
echo: echo_instance.attach,
req, res,
});
}
res.type(type);
res.status(route.status || 200).send( echo_instance.html );
}
fn();
})
}, original_route.priority || 10)
})
}
}
// 比较版本号大小。返回:1~前一个大,-1~后一个大, 0~一样大
global.nv_compare_version = (version1, version2) => {
const arr1 = version1.split('.')
const arr2 = version2.split('.')
const length1 = arr1.length
const length2 = arr2.length
const minlength = Math.min(length1, length2)
let i = 0
for (i ; i < minlength; i++) {
let a = parseInt(arr1[i])
let b = parseInt(arr2[i])
if (a > b) {
return 1
} else if (a < b) {
return -1
}
}
if (length1 > length2) {
for(let j = i; j < length1; j++) {
if (parseInt(arr1[j]) != 0) {
return 1
}
}
return 0
} else if (length1 < length2) {
for(let j = i; j < length2; j++) {
if (parseInt(arr2[j]) != 0) {
return -1
}
}
return 0
}
return 0
}
var head_tags = [
// {tag, attributes, content, name, version}
];
global.nv_enqueue_script = (url, name, version)=>{
nv_enqueue_head({
tag: 'script',
attributes: {
src: url,
},
name,
version,
content: "",
})
}
global.nv_enqueue_style = (url, name, version)=>{
nv_enqueue_head({
tag: 'link',
attributes: {
href: url,
rel: "stylesheet",
},
name,
version,
})
}
global.nv_enqueue_head = (args)=>{
// 允许 args 是字符串,把内容作为字符串放进去即可
if (typeof(args) == 'string') {
head_tags.push({
tag: undefined,
attributes: undefined,
name: undefined,
version: undefined,
content: args,
})
return;
}
var {tag, attributes, content, name, version} = args;
// 没有tag,不允许
if (!tag) { return; }
var last = name ? head_tags.filter(item=>item.tag==tag && item.name == name)[0] : null;
if (last) {
// 对比version,现在的大、或相同,那就覆盖之前的
if (nv_compare_version(version+'', last.version+'') >= 0) {
last.attributes = attributes;
last.content = content;
last.version = version;
}
} else {
head_tags.push({tag, attributes, content, name, version})
}
}
global.nv_head = (req,route) => {
req = req ? req : {};
route = route ? route : {};
var head_string = "";
// reset tags
head_tags = [];
do_action('nv_head', req, route);
head_tags.forEach(({tag, attributes, content, name, version})=>{
if (content && !tag && !attributes) {
head_string += content;
} else {
head_string += `<${tag} `;
if (typeof(attributes) == 'object') {
Object.keys(attributes).forEach(attr=>{
head_string += `${esc_html(attr)}="${esc_html(attributes[attr])}" `;
})
}
if (typeof(content) == 'string') {
head_string += `>${content}</${tag}>`
} else {
if (['script'].includes(tag)) {
head_string += `></${tag}>`
} else {
head_string += `/>`
}
}
}
})
return head_string;
}
// =========================== admin head ==============================
var admin_head_tags = [
// {tag, attributes, content, name, version}
];
global.nv_enqueue_admin_script = (url, name, version)=>{
nv_enqueue_admin_head({
tag: 'script',
attributes: {
src: url,
},
name,
version,
content: "",
})
}
global.nv_enqueue_admin_style = (url, name, version)=>{
nv_enqueue_admin_head({
tag: 'link',
attributes: {
href: url,
rel: "stylesheet",
},
name,
version,
})
}
global.nv_enqueue_admin_head = (args)=>{
// 允许 args 是字符串,把内容作为字符串放进去即可
if (typeof(args) == 'string') {
admin_head_tags.push({
tag: undefined,
attributes: undefined,
name: undefined,
version: undefined,
content: args,
})
return;
}
var {tag, attributes, content, name, version} = args;
// 没有tag,不允许
if (!tag) { return; }
var last = name ? admin_head_tags.filter(item=>item.tag==tag && item.name == name)[0] : null;
if (last) {
// 对比version,现在的大、或相同,那就覆盖之前的
if (nv_compare_version(version+'', last.version+'') >= 0) {
last.attributes = attributes;
last.content = content;
last.version = version;
}
} else {
admin_head_tags.push({tag, attributes, content, name, version})
}
}
global.nv_admin_head = (mode, option) => {
// reset tags
admin_head_tags = [];
do_action('nv_admin_head', mode, option);
var head_string = "";
admin_head_tags.forEach(({tag, attributes, content, name, version})=>{
if (content && !tag && !attributes) {
head_string += content;
} else {
head_string += `<${tag} `;
if (typeof(attributes) == 'object') {
Object.keys(attributes).forEach(attr=>{
head_string += `${esc_html(attr)}="${esc_html(attributes[attr])}" `;
})
}
if (typeof(content) == 'string') {
head_string += `>${content}</${tag}>`
} else {
if (['script'].includes(tag)) {
head_string += `></${tag}>`
} else {
head_string += `/>`
}
}
}
})
return head_string;
}