235 lines
8.4 KiB
JavaScript
235 lines
8.4 KiB
JavaScript
"use strict";
|
|
|
|
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
exports["default"] = processTpl;
|
|
exports.inlineScriptReplaceSymbol = exports.genScriptReplaceSymbol = exports.genModuleScriptReplaceSymbol = exports.genLinkReplaceSymbol = exports.genIgnoreAssetReplaceSymbol = void 0;
|
|
|
|
var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
|
|
|
|
var _utils = require("./utils");
|
|
|
|
/**
|
|
* @author Kuitos
|
|
* @homepage https://github.com/kuitos/
|
|
* @since 2018-09-03 15:04
|
|
*/
|
|
var ALL_SCRIPT_REGEX = /(<script[\s\S]*?>)[\s\S]*?<\/script>/gi;
|
|
var SCRIPT_TAG_REGEX = /<(script)\s+((?!type=('|")text\/ng\x2Dtemplate\3)[\s\S])*?>[\s\S]*?<\/\1>/i;
|
|
var SCRIPT_SRC_REGEX = /.*\ssrc=('|")?([^>'"\s]+)/;
|
|
var SCRIPT_TYPE_REGEX = /.*\stype=('|")?([^>'"\s]+)/;
|
|
var SCRIPT_ENTRY_REGEX = /.*\sentry\s*.*/;
|
|
var SCRIPT_ASYNC_REGEX = /.*\sasync\s*.*/;
|
|
var SCRIPT_NO_MODULE_REGEX = /.*\snomodule\s*.*/;
|
|
var SCRIPT_MODULE_REGEX = /.*\stype=('|")?module('|")?\s*.*/;
|
|
var LINK_TAG_REGEX = /<(link)\s+[\s\S]*?>/ig;
|
|
var LINK_PRELOAD_OR_PREFETCH_REGEX = /\srel=('|")?(preload|prefetch)\1/;
|
|
var LINK_HREF_REGEX = /.*\shref=('|")?([^>'"\s]+)/;
|
|
var LINK_AS_FONT = /.*\sas=('|")?font\1.*/;
|
|
var STYLE_TAG_REGEX = /<style[^>]*>[\s\S]*?<\/style>/gi;
|
|
var STYLE_TYPE_REGEX = /\s+rel=('|")?stylesheet\1.*/;
|
|
var STYLE_HREF_REGEX = /.*\shref=('|")?([^>'"\s]+)/;
|
|
var HTML_COMMENT_REGEX = /<!--([\s\S]*?)-->/g;
|
|
var LINK_IGNORE_REGEX = /<link(\s+|\s+[\s\S]+\s+)ignore(\s*|\s+[\s\S]*|=[\s\S]*)>/i;
|
|
var STYLE_IGNORE_REGEX = /<style(\s+|\s+[\s\S]+\s+)ignore(\s*|\s+[\s\S]*|=[\s\S]*)>/i;
|
|
var SCRIPT_IGNORE_REGEX = /<script(\s+|\s+[\s\S]+\s+)ignore(\s*|\s+[\s\S]*|=[\s\S]*)>/i;
|
|
|
|
function hasProtocol(url) {
|
|
return url.startsWith('//') || url.startsWith('http://') || url.startsWith('https://');
|
|
}
|
|
|
|
function getEntirePath(path, baseURI) {
|
|
return new URL(path, baseURI).toString();
|
|
}
|
|
|
|
function isValidJavaScriptType(type) {
|
|
var handleTypes = ['text/javascript', 'module', 'application/javascript', 'text/ecmascript', 'application/ecmascript'];
|
|
return !type || handleTypes.indexOf(type) !== -1;
|
|
}
|
|
|
|
var genLinkReplaceSymbol = function genLinkReplaceSymbol(linkHref) {
|
|
var preloadOrPrefetch = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
|
|
return "<!-- ".concat(preloadOrPrefetch ? 'prefetch/preload' : '', " link ").concat(linkHref, " replaced by import-html-entry -->");
|
|
};
|
|
|
|
exports.genLinkReplaceSymbol = genLinkReplaceSymbol;
|
|
|
|
var genScriptReplaceSymbol = function genScriptReplaceSymbol(scriptSrc) {
|
|
var async = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
|
|
return "<!-- ".concat(async ? 'async' : '', " script ").concat(scriptSrc, " replaced by import-html-entry -->");
|
|
};
|
|
|
|
exports.genScriptReplaceSymbol = genScriptReplaceSymbol;
|
|
var inlineScriptReplaceSymbol = "<!-- inline scripts replaced by import-html-entry -->";
|
|
exports.inlineScriptReplaceSymbol = inlineScriptReplaceSymbol;
|
|
|
|
var genIgnoreAssetReplaceSymbol = function genIgnoreAssetReplaceSymbol(url) {
|
|
return "<!-- ignore asset ".concat(url || 'file', " replaced by import-html-entry -->");
|
|
};
|
|
|
|
exports.genIgnoreAssetReplaceSymbol = genIgnoreAssetReplaceSymbol;
|
|
|
|
var genModuleScriptReplaceSymbol = function genModuleScriptReplaceSymbol(scriptSrc, moduleSupport) {
|
|
return "<!-- ".concat(moduleSupport ? 'nomodule' : 'module', " script ").concat(scriptSrc, " ignored by import-html-entry -->");
|
|
};
|
|
/**
|
|
* parse the script link from the template
|
|
* 1. collect stylesheets
|
|
* 2. use global eval to evaluate the inline scripts
|
|
* see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function#Difference_between_Function_constructor_and_function_declaration
|
|
* see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval#Do_not_ever_use_eval!
|
|
* @param tpl
|
|
* @param baseURI
|
|
* @stripStyles whether to strip the css links
|
|
* @returns {{template: void | string | *, scripts: *[], entry: *}}
|
|
*/
|
|
|
|
|
|
exports.genModuleScriptReplaceSymbol = genModuleScriptReplaceSymbol;
|
|
|
|
function processTpl(tpl, baseURI, postProcessTemplate) {
|
|
var scripts = [];
|
|
var styles = [];
|
|
var entry = null;
|
|
var moduleSupport = (0, _utils.isModuleScriptSupported)();
|
|
var template = tpl
|
|
/*
|
|
remove html comment first
|
|
*/
|
|
.replace(HTML_COMMENT_REGEX, '').replace(LINK_TAG_REGEX, function (match) {
|
|
/*
|
|
change the css link
|
|
*/
|
|
var styleType = !!match.match(STYLE_TYPE_REGEX);
|
|
|
|
if (styleType) {
|
|
var styleHref = match.match(STYLE_HREF_REGEX);
|
|
var styleIgnore = match.match(LINK_IGNORE_REGEX);
|
|
|
|
if (styleHref) {
|
|
var href = styleHref && styleHref[2];
|
|
var newHref = href;
|
|
|
|
if (href && !hasProtocol(href)) {
|
|
newHref = getEntirePath(href, baseURI);
|
|
}
|
|
|
|
if (styleIgnore) {
|
|
return genIgnoreAssetReplaceSymbol(newHref);
|
|
}
|
|
|
|
styles.push(newHref);
|
|
return genLinkReplaceSymbol(newHref);
|
|
}
|
|
}
|
|
|
|
var preloadOrPrefetchType = match.match(LINK_PRELOAD_OR_PREFETCH_REGEX) && match.match(LINK_HREF_REGEX) && !match.match(LINK_AS_FONT);
|
|
|
|
if (preloadOrPrefetchType) {
|
|
var _match$match = match.match(LINK_HREF_REGEX),
|
|
_match$match2 = (0, _slicedToArray2["default"])(_match$match, 3),
|
|
linkHref = _match$match2[2];
|
|
|
|
return genLinkReplaceSymbol(linkHref, true);
|
|
}
|
|
|
|
return match;
|
|
}).replace(STYLE_TAG_REGEX, function (match) {
|
|
if (STYLE_IGNORE_REGEX.test(match)) {
|
|
return genIgnoreAssetReplaceSymbol('style file');
|
|
}
|
|
|
|
return match;
|
|
}).replace(ALL_SCRIPT_REGEX, function (match, scriptTag) {
|
|
var scriptIgnore = scriptTag.match(SCRIPT_IGNORE_REGEX);
|
|
var moduleScriptIgnore = moduleSupport && !!scriptTag.match(SCRIPT_NO_MODULE_REGEX) || !moduleSupport && !!scriptTag.match(SCRIPT_MODULE_REGEX); // in order to keep the exec order of all javascripts
|
|
|
|
var matchedScriptTypeMatch = scriptTag.match(SCRIPT_TYPE_REGEX);
|
|
var matchedScriptType = matchedScriptTypeMatch && matchedScriptTypeMatch[2];
|
|
|
|
if (!isValidJavaScriptType(matchedScriptType)) {
|
|
return match;
|
|
} // if it is a external script
|
|
|
|
|
|
if (SCRIPT_TAG_REGEX.test(match) && scriptTag.match(SCRIPT_SRC_REGEX)) {
|
|
/*
|
|
collect scripts and replace the ref
|
|
*/
|
|
var matchedScriptEntry = scriptTag.match(SCRIPT_ENTRY_REGEX);
|
|
var matchedScriptSrcMatch = scriptTag.match(SCRIPT_SRC_REGEX);
|
|
var matchedScriptSrc = matchedScriptSrcMatch && matchedScriptSrcMatch[2];
|
|
|
|
if (entry && matchedScriptEntry) {
|
|
throw new SyntaxError('You should not set multiply entry script!');
|
|
} else {
|
|
// append the domain while the script not have an protocol prefix
|
|
if (matchedScriptSrc && !hasProtocol(matchedScriptSrc)) {
|
|
matchedScriptSrc = getEntirePath(matchedScriptSrc, baseURI);
|
|
}
|
|
|
|
entry = entry || matchedScriptEntry && matchedScriptSrc;
|
|
}
|
|
|
|
if (scriptIgnore) {
|
|
return genIgnoreAssetReplaceSymbol(matchedScriptSrc || 'js file');
|
|
}
|
|
|
|
if (moduleScriptIgnore) {
|
|
return genModuleScriptReplaceSymbol(matchedScriptSrc || 'js file', moduleSupport);
|
|
}
|
|
|
|
if (matchedScriptSrc) {
|
|
var asyncScript = !!scriptTag.match(SCRIPT_ASYNC_REGEX);
|
|
scripts.push(asyncScript ? {
|
|
async: true,
|
|
src: matchedScriptSrc
|
|
} : matchedScriptSrc);
|
|
return genScriptReplaceSymbol(matchedScriptSrc, asyncScript);
|
|
}
|
|
|
|
return match;
|
|
} else {
|
|
if (scriptIgnore) {
|
|
return genIgnoreAssetReplaceSymbol('js file');
|
|
}
|
|
|
|
if (moduleScriptIgnore) {
|
|
return genModuleScriptReplaceSymbol('js file', moduleSupport);
|
|
} // if it is an inline script
|
|
|
|
|
|
var code = (0, _utils.getInlineCode)(match); // remove script blocks when all of these lines are comments.
|
|
|
|
var isPureCommentBlock = code.split(/[\r\n]+/).every(function (line) {
|
|
return !line.trim() || line.trim().startsWith('//');
|
|
});
|
|
|
|
if (!isPureCommentBlock) {
|
|
scripts.push(match);
|
|
}
|
|
|
|
return inlineScriptReplaceSymbol;
|
|
}
|
|
});
|
|
scripts = scripts.filter(function (script) {
|
|
// filter empty script
|
|
return !!script;
|
|
});
|
|
var tplResult = {
|
|
template: template,
|
|
scripts: scripts,
|
|
styles: styles,
|
|
// set the last script as entry if have not set
|
|
entry: entry || scripts[scripts.length - 1]
|
|
};
|
|
|
|
if (typeof postProcessTemplate === 'function') {
|
|
tplResult = postProcessTemplate(tplResult);
|
|
}
|
|
|
|
return tplResult;
|
|
} |