"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 = /()[\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 = /]*>[\s\S]*?<\/style>/gi; var STYLE_TYPE_REGEX = /\s+rel=('|")?stylesheet\1.*/; var STYLE_HREF_REGEX = /.*\shref=('|")?([^>'"\s]+)/; var HTML_COMMENT_REGEX = //g; var LINK_IGNORE_REGEX = //i; var STYLE_IGNORE_REGEX = //i; var SCRIPT_IGNORE_REGEX = //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 ""); }; exports.genLinkReplaceSymbol = genLinkReplaceSymbol; var genScriptReplaceSymbol = function genScriptReplaceSymbol(scriptSrc) { var async = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; return ""); }; exports.genScriptReplaceSymbol = genScriptReplaceSymbol; var inlineScriptReplaceSymbol = ""; exports.inlineScriptReplaceSymbol = inlineScriptReplaceSymbol; var genIgnoreAssetReplaceSymbol = function genIgnoreAssetReplaceSymbol(url) { return ""); }; exports.genIgnoreAssetReplaceSymbol = genIgnoreAssetReplaceSymbol; var genModuleScriptReplaceSymbol = function genModuleScriptReplaceSymbol(scriptSrc, moduleSupport) { return ""); }; /** * 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; }