apim-tools
Version:
APIM Tools
108 lines (91 loc) • 3.31 kB
JavaScript
/**
* @file 页面注入内容处理器
* @author sparklewhy@gmail.com
*/
;
const fs = require('fs');
const pathUtil = require('path');
const util = require('../util');
const rewriter = require('./content-rewriter');
const LAST_CLOSE_BODY_REGEXP = util.getCloseElementRegexp('body');
const CLOSE_BODY_TAG = '</body>';
let ENTRY_SCRIPT_SNIPPET = '';
let ENTRY_STYLE_SNIPPET = '';
function loadEntryScriptSnippet() {
if (ENTRY_SCRIPT_SNIPPET) {
return ENTRY_SCRIPT_SNIPPET;
}
ENTRY_SCRIPT_SNIPPET = fs.readFileSync(
pathUtil.join(__dirname, '..', 'client/entry/script.js')
).toString();
return ENTRY_SCRIPT_SNIPPET;
}
function loadEntryStyleSnippet() {
if (ENTRY_STYLE_SNIPPET) {
return ENTRY_STYLE_SNIPPET;
}
ENTRY_STYLE_SNIPPET = fs.readFileSync(
pathUtil.join(__dirname, '..', 'client/entry/style.css')
).toString();
return ENTRY_STYLE_SNIPPET;
}
function isHTMLContent(value) {
return value.toLowerCase().indexOf('text/html') !== -1;
}
function injectMockManageScript(content, options, context) {
let entryScript = loadEntryScriptSnippet();
entryScript = util.formatString(entryScript, {
manageUrl: util.normalizeUrl(
`http://${context.host}/${context.clientRequestPrefix}`
)
});
let entryStyle = loadEntryStyleSnippet();
entryStyle = entryStyle.replace('/*${customStyle}*/', '${customStyle}');
entryStyle = util.formatString(entryStyle, {
customStyle: options.style || ''
});
let snippet = `<style type="text/css">${entryStyle}</style><script>${entryScript}</script>`;
return content.replace(LAST_CLOSE_BODY_REGEXP, snippet + CLOSE_BODY_TAG);
}
/**
* html 页面注入 mock 入口代码处理器
*
* @param {Object} options 注入选项
* @param {function(string, Object):boolean=} options.whenContentType
* 自定义是否执行注入操作,默认只针对内容类型为 text/html 进行注入操作
* @param {Array<Object>=} options.tasks 注入操作的任务,默认只有注入入口脚本的任务
* 任务结构:
* {
* process: function (content, options, context) {
* return content;
* },
* options: Object, // 处理选项
* when: function (context) {return true;} // 是否执行该任务
* }
* @param {Object|boolean=} options.entry 入口选项,是否注入 mock 入口按钮,默认注入
* @param {string=} options.entry.style 入口自定义的样式
* @param {function(Object):boolean} options.entry.when 判断是否注入入口按钮
* @return {Function}
*/
module.exports = function (options) {
options || (options = {});
let entryOpts = options.entry;
if (entryOpts === true || entryOpts == null) {
entryOpts = {};
}
const tasks = [];
if (entryOpts) {
tasks.push({
process: injectMockManageScript,
options: entryOpts,
when: entryOpts.when || function (context) {
return !context.isMockClientRequest();
}
});
}
tasks.push.apply(tasks, options.tasks || []);
return rewriter({
whenContentType: options.whenContentType || isHTMLContent,
tasks
});
};