ecology9-src4js-tools
Version:
src4js-tools
108 lines (100 loc) • 11.9 kB
JavaScript
class HtmlWebpackHandleCssInjectPlugin {
constructor(options = {}) {
this.options = options;
}
apply(compiler) {
let themeCss = [];
let mainJs = [];
// const reg = /\/theme-.+\.(\w|\d){8}\.css$/;
const reg = /\/theme-[^\.]+\.css\?v=(\w|\d){8}$/;
const handleHtmlWebpackPluginBeforeHtmlGeneration = (data,cb) => {
// 过滤主题 css
mainJs = [].concat(data.assets.js);
const newCss = [];
const css = data.assets.css;
css.forEach((c) => {
if(reg.test(c)) {
themeCss.push(c);
} else {
newCss.push(c);
}
});
data.assets.css = newCss;
data.assets.js = [];
// 过滤主题 css in json
const newAssetJson = [];
const assetJson = JSON.parse(data.plugin.assetJson);
assetJson.forEach(a => {
if (!reg.test(a)) {
newAssetJson.push(a);
}
});
data.plugin.assetJson = JSON.stringify(newAssetJson);
cb(null,data);
};
const camelCase = name => name.replace(/-(\w)/g, (m, n) => n.toUpperCase());
const handleHtmlWebpackPluginAfterHtmlProcessing = (data,cb) => {
let themes = [];
let themesObj = {};
let themeStr = '';
const { themelessVarsToJs, isDev } = this.options;
themeCss.forEach((t, i) => {
let strs = t.match(reg);
// const name = strs[0].replace(/(\/)|(\.(\w|\d){8}\.css$)/g, '');
const name = strs[0].replace(/(\/)|(\.css\?v=(\w|\d){8}$)/g, '');
let obj = {
name: name,
url: t,
};
themesObj[name] = t;
themes.push(obj);
});
let appendMainJs = '';
let devMainJs = '';
mainJs.forEach((m, i) => {
devMainJs += `<script type="text/javascript" src="${m}"></script>`;
appendMainJs += `var script${i}=document.createElement('script');script${i}.src='${m}';script${i}.type="text/javascript";script${i}.onload=function(){window.wm_test_main_js_loaded=new Date().getTime()};document.body.appendChild(script${i});`;
});
const resetColor = 'function resetColor(){window.changeStyle.request(themeUrl).then(function(){if(!isDefaultThemeColor){window.changeStyle.replace([{reg:defaultThemeColorReg,to:themeColor},{reg:/(#|%23)3998(e|E)2/g,to:themeColor}])}});}';
themeStr += `${resetColor}var themeUrls=${JSON.stringify(themesObj)};var themeUrl=themeUrls[target]||themeUrls["theme-default"];if(themeUrl){window.loadjs("css!"+themeUrl,{success:function(){resetColor()}});window.onload=function(){window.loadjs("css!"+themeUrl,{success:function(){resetColor()}})}}`;
const changeColor = `var themeColor=window.localStorage['theme-color'];var isDefaultThemeColor=true;var defaultThemeColorReg=/(#|%23)55(b|B)1(f|F)9/g;if(themeColor&&colorReg.test(themeColor)&&!defaultThemeColorReg.test(themeColor)){isDefaultThemeColor=false}`;
const changeStyle = `(function(){'use strict';var _createClass=function(){function defineProperties(target,props){for(var i=0;i<props.length;i++){var descriptor=props[i];descriptor.enumerable=descriptor.enumerable||false;descriptor.configurable=true;if("value"in descriptor)descriptor.writable=true;Object.defineProperty(target,descriptor.key,descriptor)}}return function(Constructor,protoProps,staticProps){if(protoProps)defineProperties(Constructor.prototype,protoProps);if(staticProps)defineProperties(Constructor,staticProps);return Constructor}}();function _classCallCheck(instance,Constructor){if(!(instance instanceof Constructor)){throw new TypeError("Cannot call a class as a function");}}var ChangeStyle=function(){function ChangeStyle(options){var _this=this;_classCallCheck(this,ChangeStyle);this.checkRequested=function(checkUrl){var url=checkUrl||_this.cssUrl;return url&&_this.cssUrls.some(function(u){return u===url})};this.request=function(url){return new Promise(function(resolve,reject){if(_this.checkRequested(url)){_this.cssUrl=url;resolve()}else{var xhr=new XMLHttpRequest();xhr.open("GET",url);xhr.onload=function(){if(xhr.status<200||xhr.status>=300){reject()}else{var text=xhr.responseText;_this.cssUrl=url;_this.cssList.push({url:url,text:text});resolve()}};xhr.send()}})};this.replace=function(){var setting=arguments.length>0&&arguments[0]!==undefined?arguments[0]:[];if(_this.cssText&&setting.length>0){var style=document.getElementById('__WM_CHANGE_STYLE__');if(style){document.head.removeChild(style)}style=document.createElement('style');style.id='__WM_CHANGE_STYLE__';document.head.appendChild(style);var result=_this.cssText;setting.forEach(function(s){if(s.reg&&s.to){result=result.replace(s.reg,s.to)}});style.innerHTML=result}};this.cssList=[];this.cssUrl=''}_createClass(ChangeStyle,[{key:'cssUrls',get:function get(){return this.cssList.map(function(css){return css.url})}},{key:'cssText',get:function get(){var _this2=this;var css=this.cssList.filter(function(c){return c.url===_this2.cssUrl});if(css.length>0)return css[0].text;return''}}]);window.ChangeStyle=ChangeStyle;return ChangeStyle}();})();window.changeStyle=new ChangeStyle();`;
const devThemejs = isDev ? `name='theme-default';` : '';
const testCode = `<script>(function(){var accesspageUrl=window.location.pathname;window.wm_test_accesspage=function(){if(window.wm_test_accesspage_did)return;var end=new Date().getTime();var endType='setTimeout5000';if(window.wm_test_main_js_loaded){end=window.wm_test_main_js_loaded;endType='mainJsLoaded'}if(window.wm_test_getlocal_end){end=window.wm_test_getlocal_end;endType='getlocal'};var params={endType:endType,head:window.wm_test_body_js_start-window.wm_test_head_start,js:window.wm_test_ssoinit_start-window.wm_test_body_js_start,ssoInit:window.wm_test_ssoinit_end?window.wm_test_ssoinit_end-window.wm_test_ssoinit_start:0,sso_api:window.wm_test_sso_api_end?window.wm_test_sso_api_end-window.wm_test_ssoinit_start:0,sso_config:window.wm_test_sso_config_loaded_end?window.wm_test_sso_config_loaded_end-window.wm_test_sso_api_end:0,sso_em:window.wm_test_sso_em_loaded_end?window.wm_test_sso_em_loaded_end-window.wm_test_sso_config_loaded_end:0,getClientInfo:window.wm_test_em_getClientInfo_end?window.wm_test_em_getClientInfo_end-window.wm_test_ssoinit_end:0,mainJsLoaded:window.wm_test_main_js_loaded?window.wm_test_main_js_loaded-(window.wm_test_changeLang_end||window.wm_test_ssoinit_end):0,getLabel:window.wm_test_getlocal_end?window.wm_test_getlocal_end-window.wm_test_getlocal_start:0,};window.wm_test_time_params=params;window.sso_callApi({url:'/api/ec/dev/util/accesspage',method:'POST',params:{ua:(window.em?'__emobile__':'')+window.navigator.userAgent,url:accesspageUrl,accesstime:end-window.wm_test_head_start,params:JSON.stringify(params),wm_test_accesskey:window.wm_test_accesskey}});window.wm_test_accesspage_did=true}})();</script>`;
const themejs = themelessVarsToJs ? `window.theme=${JSON.stringify(themelessVarsToJs)};function getThemeVars(themeName){if(!window.theme)return;var name=themeName||window.localStorage['theme']||'theme-default';${devThemejs}return window.theme[name]}window.getThemeVars=getThemeVars;` : '';
const em_ssoInit = `window.wm_test_ssoinit_start=new Date().getTime();window.em_ssoInit().then(function(){window.wm_test_ssoinit_end=new Date().getTime();if(window.em&&window.em.checkJsApi('getClientInfo')){window.em.getClientInfo({success:function(res){window.wm_test_em_getClientInfo_end=new Date().getTime();if(colorReg.test(res.clientTheme)){localStorage['theme-color']=/^(#|%23)((f|F){3}){1,2}$/.test(res.clientTheme)?"#55b1f9":res.clientTheme}if(res.clientFont){localStorage['theme']=res.clientFont==='3'?'theme-large':res.clientFont==='2'?'theme-big':'theme-default'}appendMainJs();changeTheme()},fail:function(err){alert('getClientInfo 接口错误:'+JSON.stringify(err));appendMainJs();changeTheme()}})}else{appendMainJs();changeTheme()}}).catch(function(res){alert(res.msg)});`;
const themeHtml = isDev ? `<script>${themejs}</script>${devMainJs}` :
`${testCode}<script>${changeStyle}</script><script>${themejs}</script><script>(function(){var colorReg=/^(#|%23)([a-fA-F0-9]{6}|[a-fA-F0-9]{3})$/;function changeTheme(target,noSave){target=target||window.localStorage['theme'];target=(!target||target==='undefined')?'theme-default':target;if(!noSave)window.localStorage['theme']=target;${changeColor}${themeStr}}function appendMainJs(){${appendMainJs}}${em_ssoInit}function changeThemeLoad(p1,p2){changeTheme(p1,p2);window.location.reload()}window.changeTheme=changeTheme;window.changeThemeLoad=changeThemeLoad;})()</script>`;
data.html = data.html.replace('</body>', themeHtml +'</body>');
if (isDev) {
data.html = data.html.replace('<script type="text/javascript" src="/cloudstore/resource/mobile/loadjs/loadjs.min.js"></script>','');
data.html = data.html.replace('<script type="text/javascript" src="/spa/coms/ssoSDK/WebViewJavascriptBridge.js"></script>','');
data.html = data.html.replace('<script type="text/javascript" src="/spa/coms/ssoConfig/config.js"></script>','');
data.html = data.html.replace('<script type="text/javascript" src="/spa/coms/ssoSDK/ssoInit.js"></script>','');
} else {
let initLoadingStyle = `<style>body{background:#f3f7fe;margin:0}.init-loading,.init-loading:after,.init-loading:before{border-radius:50%;width:2.5em;height:2.5em;-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation:initloading 1.2s infinite ease-in-out;animation:initloading 1.2s infinite ease-in-out}.init-loading{color:#ccc;font-size:9pt;margin:75pt auto;text-indent:-9999em;-webkit-transform:translateZ(0);transform:translateZ(0);-webkit-animation-delay:-.16s;animation-delay:-.16s}.init-loading:after,.init-loading:before{content:'';position:absolute;top:0}.init-loading:before{left:-3.5em;-webkit-animation-delay:-.32s;animation-delay:-.32s}.init-loading:after{left:3.5em}@-webkit-keyframes initloading{0%,80%,to{box-shadow:0 2.5em 0 -1.3em}40%{box-shadow:0 2.5em 0 0}}@keyframes initloading{0%,80%,to{box-shadow:0 2.5em 0 -1.3em}40%{box-shadow:0 2.5em 0 0}}</style>`;
initLoadingStyle = `<style>body{background:#f3f7fe;margin:0}@keyframes placeHolderShimmer{0%{background-position:-10px 0}to{background-position:400px 0}}.init-loading{position:relative;margin:200px auto 0;background:#d8d8d8;background-image:linear-gradient(to right,#d8d8d8 8%,#bbb 18%,#d8d8d8 28%);background-size:400px 104px;animation:placeHolderShimmer 1s forwards infinite linear;-webkit-animation:placeHolderShimmer 1s forwards infinite linear;-webkit-text-fill-color:transparent;background-clip:text;-webkit-background-clip:text;font-weight:700;font-size:36px;line-height:1.5;text-align:center;color:#bbb;font-family:lato,Helvetica Neue,Helvetica,PingFang SC,Hiragino Sans GB,Microsoft YaHei,Arial,sans-serif;font-style:italic}</style>`;
const initLoading = '<div class="init-loading">loading</div>';
data.html = data.html.replace('</head>', initLoadingStyle + '</head>');
data.html = data.html.replace('<div id=\"root\">', '<div id=\"root\">' + initLoading);
}
cb(null,data);
};
if (compiler.hooks) {
compiler.hooks.compilation.tap('htmlWebpackPluginBeforeHtmlGeneration', (compilation) => {
compilation.hooks.htmlWebpackPluginAfterHtmlProcessing.tapAsync(
'htmlWebpackPluginBeforeHtmlGeneration',
handleHtmlWebpackPluginBeforeHtmlGeneration
);
});
}
else {
compiler.plugin('compilation', (compilation) => {
// compilation.plugin('html-webpack-plugin-after-html-processing', handleHtmlWebpackPluginAfterHtmlProcessing);
compilation.plugin('html-webpack-plugin-before-html-generation', handleHtmlWebpackPluginBeforeHtmlGeneration);
compilation.plugin('html-webpack-plugin-after-html-processing', handleHtmlWebpackPluginAfterHtmlProcessing);
});
}
}
}
module.exports = HtmlWebpackHandleCssInjectPlugin;