index.js 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. /**
  2. * FeHelper Code Compress
  3. */
  4. let editor = {};
  5. new Vue({
  6. el: '#pageContainer',
  7. data: {
  8. codeType: 'html',
  9. sourceContent: '',
  10. resultContent: '',
  11. hasError: false,
  12. compressInfo: ''
  13. },
  14. mounted: function () {
  15. editor = CodeMirror.fromTextArea(this.$refs.codeSource, {
  16. mode: "htmlmixed",
  17. lineNumbers: true,
  18. matchBrackets: true,
  19. styleActiveLine: true,
  20. lineWrapping: true
  21. });
  22. //输入框聚焦
  23. editor.focus();
  24. },
  25. methods: {
  26. compress: function () {
  27. this.hasError = false;
  28. this.compressInfo = '';
  29. this.sourceContent = editor.getValue().trim();
  30. if (!this.sourceContent) {
  31. alert('请先粘贴您需要压缩的代码');
  32. } else {
  33. if (this.codeType === 'js') {
  34. this.jsCompress(this.sourceContent);
  35. } else if (this.codeType === 'css') {
  36. this.cssCompress(this.sourceContent);
  37. } else {
  38. this.htmlCompress(this.sourceContent);
  39. }
  40. }
  41. },
  42. changeCodeType(ctype) {
  43. let editorMode = {
  44. css: 'text/css',
  45. js: {name: 'javascript', json: true},
  46. html: 'htmlmixed'
  47. };
  48. editor.setOption('mode', editorMode[ctype]);
  49. if (editor.getValue().trim()) {
  50. this.$nextTick(this.compress);
  51. }
  52. },
  53. buildCompressInfo(original, minified) {
  54. let commify = str => String(str).split('').reverse().join('').replace(/(...)(?!$)/g, '$1,').split('').reverse().join('');
  55. let diff = original.length - minified.length;
  56. let savings = original.length ? (100 * diff / minified.length).toFixed(2) : 0;
  57. this.compressInfo = '压缩前: <strong>' + commify(original.length) + '</strong>' +
  58. ',压缩后: <strong>' + commify(minified.length) + '</strong>' +
  59. ',压缩率: <strong>' + commify(diff) + ' (' + savings + '%)</strong>';
  60. },
  61. jsCompress(js) {
  62. let result = UglifyJs3.compress(js);
  63. this.hasError = !!result.error;
  64. this.resultContent = result.out || result.error;
  65. !this.hasError && this.buildCompressInfo(this.sourceContent, this.resultContent);
  66. },
  67. cssCompress(css) {
  68. let res = css.replace(/\/\*(.|\n)*?\*\//g, "")
  69. .replace(/\s*([\{\}\:\;\,])\s*/g, "$1")
  70. .replace(/\,[\s\.\#\d]*\{/g, "{")
  71. .replace(/;\s*;/g, ";")
  72. .match(/^\s*(\S+(\s+\S+)*)\s*$/);
  73. this.resultContent = (res === null) ? css : res[1];
  74. this.buildCompressInfo(this.sourceContent, this.resultContent);
  75. },
  76. htmlCompress(html) {
  77. let options = {
  78. "caseSensitive": false,
  79. "collapseBooleanAttributes": true,
  80. "collapseInlineTagWhitespace": false,
  81. "collapseWhitespace": true,
  82. "conservativeCollapse": false,
  83. "decodeEntities": true,
  84. "html5": true,
  85. "includeAutoGeneratedTags": false,
  86. "keepClosingSlash": false,
  87. "minifyCSS": true,
  88. "minifyJS": true,
  89. "preserveLineBreaks": false,
  90. "preventAttributesEscaping": false,
  91. "processConditionalComments": true,
  92. "processScripts": ["text/html"],
  93. "removeAttributeQuotes": true,
  94. "removeComments": true,
  95. "removeEmptyAttributes": true,
  96. "removeEmptyElements": false,
  97. "removeOptionalTags": true,
  98. "removeRedundantAttributes": true,
  99. "removeScriptTypeAttributes": true,
  100. "removeStyleLinkTypeAttributes": true,
  101. "removeTagWhitespace": true,
  102. "sortAttributes": true,
  103. "sortClassName": true,
  104. "trimCustomFragments": true,
  105. "useShortDoctype": true
  106. };
  107. options.log = console.log;
  108. try {
  109. this.resultContent = require('html-minifier').minify(html, options);
  110. this.buildCompressInfo(this.sourceContent, this.resultContent);
  111. } catch (err) {
  112. this.hasError = true;
  113. this.resultContent = err;
  114. }
  115. },
  116. toast(content) {
  117. window.clearTimeout(window.feHelperAlertMsgTid);
  118. let elAlertMsg = document.querySelector("#fehelper_alertmsg");
  119. if (!elAlertMsg) {
  120. let elWrapper = document.createElement('div');
  121. elWrapper.innerHTML = '<div id="fehelper_alertmsg">' + content + '</div>';
  122. elAlertMsg = elWrapper.childNodes[0];
  123. document.body.appendChild(elAlertMsg);
  124. } else {
  125. elAlertMsg.innerHTML = content;
  126. elAlertMsg.style.display = 'block';
  127. }
  128. window.feHelperAlertMsgTid = window.setTimeout(function () {
  129. elAlertMsg.style.display = 'none';
  130. }, 3000);
  131. },
  132. copyToClipboard(text) {
  133. if (this.hasError) return false;
  134. let input = document.createElement('textarea');
  135. input.style.position = 'fixed';
  136. input.style.opacity = 0;
  137. input.value = text;
  138. document.body.appendChild(input);
  139. input.select();
  140. document.execCommand('Copy');
  141. document.body.removeChild(input);
  142. this.toast('压缩结果已复制成功,随处粘贴可用!');
  143. }
  144. }
  145. });