| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237 |
- /**
- * FeHelper Code Compress
- */
- let editor = {};
- new Vue({
- el: '#pageContainer',
- data: {
- codeType: 'html',
- sourceContent: '',
- resultContent: '',
- hasError: false,
- compressInfo: ''
- },
- mounted: function () {
- editor = CodeMirror.fromTextArea(this.$refs.codeSource, {
- mode: "htmlmixed",
- lineNumbers: true,
- matchBrackets: true,
- styleActiveLine: true,
- lineWrapping: true
- });
- //输入框聚焦
- editor.focus();
- this.loadPatchHotfix();
- },
- methods: {
- loadPatchHotfix() {
- // 页面加载时自动获取并注入页面的补丁
- chrome.runtime.sendMessage({
- type: 'fh-dynamic-any-thing',
- thing: 'fh-get-tool-patch',
- toolName: 'code-compress'
- }, patch => {
- if (patch) {
- if (patch.css) {
- const style = document.createElement('style');
- style.textContent = patch.css;
- document.head.appendChild(style);
- }
- if (patch.js) {
- try {
- if (window.evalCore && window.evalCore.getEvalInstance) {
- window.evalCore.getEvalInstance(window)(patch.js);
- }
- } catch (e) {
- console.error('code-compress补丁JS执行失败', e);
- }
- }
- }
- });
- },
- compress: function () {
- this.hasError = false;
- this.compressInfo = '';
- this.sourceContent = editor.getValue().trim();
- if (!this.sourceContent) {
- alert('请先粘贴您需要压缩的代码');
- } else {
- if (this.codeType === 'js') {
- this.jsCompress(this.sourceContent);
- } else if (this.codeType === 'css') {
- this.cssCompress(this.sourceContent);
- } else {
- this.htmlCompress(this.sourceContent);
- }
- }
- },
- changeCodeType(ctype) {
- let editorMode = {
- css: 'text/css',
- js: {name: 'javascript', json: true},
- html: 'htmlmixed'
- };
- editor.setOption('mode', editorMode[ctype]);
- if (editor.getValue().trim()) {
- this.$nextTick(this.compress);
- }
- },
- buildCompressInfo(original, minified) {
- let commify = str => String(str).split('').reverse().join('').replace(/(...)(?!$)/g, '$1,').split('').reverse().join('');
- let diff = original.length - minified.length;
- let savings = original.length ? (100 * diff / minified.length).toFixed(2) : 0;
- this.compressInfo = '压缩前: <strong>' + commify(original.length) + '</strong>' +
- ',压缩后: <strong>' + commify(minified.length) + '</strong>' +
- ',压缩率: <strong>' + commify(diff) + ' (' + savings + '%)</strong>';
- },
- jsCompress(js) {
- // 判断是否为合法JSON,如果是则加t=前缀后用UglifyJS压缩,压缩后去掉t=前缀
- let isJSON = false;
- let jsonStr = js.trim();
- let result;
- try {
- if ((jsonStr.startsWith('{') || jsonStr.startsWith('[')) && (jsonStr.endsWith('}') || jsonStr.endsWith(']'))) {
- JSON.parse(jsonStr);
- isJSON = true;
- }
- } catch (e) {
- isJSON = false;
- }
- if (isJSON) {
- // 加t=前缀
- let jsWithPrefix = 't=' + jsonStr;
- result = UglifyJs3.compress(jsWithPrefix);
- this.hasError = !!result.error;
- if (!this.hasError && result.out.startsWith('t=')) {
- this.resultContent = result.out.substring(2); // 去掉t=
- } else {
- this.resultContent = result.out || result.error;
- }
- !this.hasError && this.buildCompressInfo(this.sourceContent, this.resultContent);
- return;
- }
- // 原有JS压缩逻辑
- result = UglifyJs3.compress(js);
- this.hasError = !!result.error;
- this.resultContent = result.out || result.error;
- !this.hasError && this.buildCompressInfo(this.sourceContent, this.resultContent);
- },
- cssCompress(css) {
- let res = css.replace(/\/\*(.|\n)*?\*\//g, "")
- .replace(/\s*([\{\}\:\;\,])\s*/g, "$1")
- .replace(/\,[\s\.\#\d]*\{/g, "{")
- .replace(/;\s*;/g, ";")
- .match(/^\s*(\S+(\s+\S+)*)\s*$/);
- this.resultContent = (res === null) ? css : res[1];
- this.buildCompressInfo(this.sourceContent, this.resultContent);
- },
- htmlCompress(html) {
- let options = {
- "caseSensitive": false,
- "collapseBooleanAttributes": true,
- "collapseInlineTagWhitespace": false,
- "collapseWhitespace": true,
- "conservativeCollapse": false,
- "decodeEntities": true,
- "html5": true,
- "includeAutoGeneratedTags": false,
- "keepClosingSlash": false,
- "minifyCSS": true,
- "minifyJS": true,
- "preserveLineBreaks": false,
- "preventAttributesEscaping": false,
- "processConditionalComments": true,
- "processScripts": ["text/html"],
- "removeAttributeQuotes": true,
- "removeComments": true,
- "removeEmptyAttributes": true,
- "removeEmptyElements": false,
- "removeOptionalTags": true,
- "removeRedundantAttributes": true,
- "removeScriptTypeAttributes": true,
- "removeStyleLinkTypeAttributes": true,
- "removeTagWhitespace": true,
- "sortAttributes": true,
- "sortClassName": true,
- "trimCustomFragments": true,
- "useShortDoctype": true
- };
- options.log = console.log;
- try {
- this.resultContent = require('html-minifier').minify(html, options);
- this.buildCompressInfo(this.sourceContent, this.resultContent);
- } catch (err) {
- this.hasError = true;
- this.resultContent = err;
- }
- },
- toast(content) {
- window.clearTimeout(window.feHelperAlertMsgTid);
- let elAlertMsg = document.querySelector("#fehelper_alertmsg");
- if (!elAlertMsg) {
- let elWrapper = document.createElement('div');
- elWrapper.innerHTML = '<div id="fehelper_alertmsg">' + content + '</div>';
- elAlertMsg = elWrapper.childNodes[0];
- document.body.appendChild(elAlertMsg);
- } else {
- elAlertMsg.innerHTML = content;
- elAlertMsg.style.display = 'block';
- }
- window.feHelperAlertMsgTid = window.setTimeout(function () {
- elAlertMsg.style.display = 'none';
- }, 3000);
- },
- copyToClipboard(text) {
- if (this.hasError) return false;
- let input = document.createElement('textarea');
- input.style.position = 'fixed';
- input.style.opacity = 0;
- input.value = text;
- document.body.appendChild(input);
- input.select();
- document.execCommand('Copy');
- document.body.removeChild(input);
- this.toast('压缩结果已复制成功,随处粘贴可用!');
- },
- loadExample(type,event) {
- if(event){
- event.preventDefault();
- }
- this.codeType = type;
- editor.setValue(EXAMPLES[type]);
- this.changeCodeType(type);
- },
- openOptionsPage: function(event) {
- event.preventDefault();
- event.stopPropagation();
- chrome.runtime.openOptionsPage();
- },
- openDonateModal: function(event ){
- event.preventDefault();
- event.stopPropagation();
- chrome.runtime.sendMessage({
- type: 'fh-dynamic-any-thing',
- thing: 'open-donate-modal',
- params: { toolName: 'code-compress' }
- });
- }
- }
- });
|