script.js 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240
  1. /*global minify:false, JS_Parse_Error:false */
  2. /*jshint globalstrict:true */
  3. 'use strict';
  4. var default_options = {};
  5. function $(id) {
  6. return document.getElementById(id);
  7. }
  8. // Handle the UI
  9. var uglify_options;
  10. var $options = $('options');
  11. var $out = $('out');
  12. var $in = $('in');
  13. var $error = $('error');
  14. var $stats = $('stats');
  15. var $body = document.body;
  16. var $btn_options = $('btn-options');
  17. var $btn_options_save = $('btn-options-save');
  18. var $cb_as_i_type = $('cb-as-i-type');
  19. $('header-link').onclick = go_to_start;
  20. $('btn-go').onclick = go;
  21. $btn_options.onclick = show_options;
  22. $btn_options_save.onclick = set_options;
  23. $('btn-options-reset').onclick = reset_options;
  24. $in.oninput = $in.onkeyup = $in.onblur = $in.onfocus = go_ait;
  25. $cb_as_i_type.onclick = set_options_ait;
  26. $out.onfocus = select_text;
  27. var default_options_text;
  28. set_options_initial();
  29. function hide(class_name) {
  30. var names = class_name.split(' ');
  31. var cur = ' ' + $body.className + ' ';
  32. for (var i = 0; i < names.length; i++) {
  33. while (cur.indexOf(' ' + names[i] + ' ') >= 0) {
  34. cur = cur.replace(' ' + names[i] + ' ', ' ');
  35. }
  36. }
  37. $body.className = cur.replace(/^\s+|\s+$/g, '');
  38. }
  39. function show(class_name) {
  40. $body.className += ' ' + class_name;
  41. }
  42. function show_options() {
  43. show('s-options');
  44. hide('s-input');
  45. }
  46. function get_options(value) {
  47. /*jshint evil:true */
  48. return new Function('return (' + (value || $options.value) + ');')();
  49. }
  50. function set_options() {
  51. var old_options = uglify_options;
  52. try {
  53. uglify_options = get_options();
  54. // The options could be parsed. Try to update localStorage.
  55. try {
  56. if (default_options_text === $options.value)
  57. localStorage.removeItem('uglify-options');
  58. else
  59. localStorage.setItem('uglify-options', $options.value);
  60. } catch (e) {}
  61. // Run Uglify with the new options.
  62. go(true);
  63. show('s-input');
  64. hide('s-options');
  65. return true;
  66. } catch (e) {
  67. if (e instanceof JS_Parse_Error) {
  68. // the options are actually okay, just the code that's bad
  69. show_error(e, $in.value);
  70. return true;
  71. } else {
  72. uglify_options = old_options;
  73. show_error(e);
  74. return false;
  75. }
  76. }
  77. }
  78. function reset_options() {
  79. $options.value = default_options_text;
  80. set_options();
  81. }
  82. function set_options_ait() {
  83. try {
  84. if ($cb_as_i_type.checked)
  85. localStorage.removeItem('uglify-options-disable-ait');
  86. else
  87. localStorage.setItem('uglify-options-disable-ait', 1);
  88. } catch (e) {}
  89. }
  90. function set_options_initial() {
  91. default_options_text = $options.textContent || $options.innerText;
  92. default_options = get_options(default_options_text);
  93. // If there are options saved with localStorage, load them now.
  94. try {
  95. var options_text = localStorage.getItem('uglify-options');
  96. if (options_text) {
  97. $options.value = options_text;
  98. }
  99. $cb_as_i_type.checked = !localStorage.getItem('uglify-options-disable-ait');
  100. } catch (e) {}
  101. try {
  102. uglify_options = get_options();
  103. } catch (e) {
  104. // if it didn't work, reset the textarea
  105. $options.value = default_options_text;
  106. uglify_options = default_options;
  107. }
  108. }
  109. function encodeHTML(str) {
  110. return (str + '')
  111. .replace(/&/g, '&amp;')
  112. .replace(/</g, '&lt;')
  113. .replace(/"/g, '&quot;');
  114. }
  115. var last_input;
  116. function go(throw_on_error) {
  117. var input = $in.value;
  118. last_input = input;
  119. if (throw_on_error === true) {
  120. main();
  121. } else {
  122. try {
  123. main();
  124. } catch (e) {
  125. show_error(e, input);
  126. }
  127. }
  128. function main() {
  129. if (!input || input === $in.textContent) {
  130. go_to_start();
  131. return;
  132. }
  133. var res = minify(input, uglify_options);
  134. if (res.error) {
  135. throw res.error;
  136. }
  137. hide('s-info s-error');
  138. show('s-output');
  139. $out.value = res.code || '/* no output! */';
  140. $stats.innerHTML = res.code.length + ' bytes, saved ' + ((1 - res.code.length / input.length) * 100 || 0).toFixed(2) + '%';
  141. }
  142. }
  143. // As I type (AIT) functionality. Spend at least half of the time idle.
  144. var ait_timeout;
  145. var ait_last_duration = 50;
  146. function go_ait() {
  147. if (!$cb_as_i_type.checked)
  148. return;
  149. var input = $in.value;
  150. if (input === last_input)
  151. return;
  152. last_input = input;
  153. clearTimeout(ait_timeout);
  154. ait_timeout = setTimeout(function () {
  155. var start = new Date();
  156. go();
  157. ait_last_duration = new Date() - start;
  158. }, ait_last_duration);
  159. }
  160. function show_error(e, param) {
  161. console.error('Error', e);
  162. hide('s-info s-output');
  163. show('s-error');
  164. if (e instanceof JS_Parse_Error) {
  165. var input = param;
  166. var lines = input.split('\n');
  167. var line = lines[e.line - 1];
  168. e = 'Parse error: <strong>' + encodeHTML(e.message) + '</strong>\n' +
  169. '<small>Line ' + e.line + ', column ' + (e.col + 1) + '</small>\n\n' +
  170. (lines[e.line-2] ? (e.line - 1) + ': ' + encodeHTML(lines[e.line-2]) + '\n' : '') +
  171. e.line + ': ' +
  172. encodeHTML(line.substr(0, e.col)) +
  173. '<mark>' + encodeHTML(line.substr(e.col, 1) || ' ') + '</mark>' +
  174. encodeHTML(line.substr(e.col + 1)) + '\n' +
  175. (lines[e.line] ? (e.line + 1) + ': ' + encodeHTML(lines[e.line]) : '');
  176. } else if (e instanceof Error) {
  177. e = e.name + ': <strong>' + encodeHTML(e.message) + '</strong>';
  178. } else {
  179. e = '<strong>' + encodeHTML(e) + '</strong>';
  180. }
  181. $error.innerHTML = e;
  182. }
  183. function go_to_start() {
  184. clearTimeout(ait_timeout);
  185. hide('s-options s-error s-output');
  186. show('s-input s-info');
  187. return false;
  188. }
  189. function select_text() {
  190. /*jshint validthis:true */
  191. var self = this;
  192. self.select();
  193. self.onmouseup = self.onkeyup = function() {
  194. // Prevent further mouseup intervention
  195. self.onmouseup = self.onkeyup = null;
  196. self.scrollTop = 0;
  197. return false;
  198. };
  199. return false;
  200. }