beautify-worker.js 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. // beautify-worker.js
  2. // 独立Web Worker脚本,用于CSS代码美化
  3. self.onmessage = function (evt) {
  4. function Beautifier(source_text, options) {
  5. options = options || {};
  6. var indentSize = options.indent_size || 4;
  7. var indentCharacter = options.indent_char || ' ';
  8. // compatibility
  9. if (typeof indentSize === "string") {
  10. indentSize = parseInt(indentSize, 10);
  11. }
  12. // tokenizer
  13. var whiteRe = /^\s+$/;
  14. var wordRe = /[\w$\-_]/;
  15. var pos = -1, ch;
  16. function next() {
  17. ch = source_text.charAt(++pos);
  18. return ch;
  19. }
  20. function peek() {
  21. return source_text.charAt(pos + 1);
  22. }
  23. function eatString(comma) {
  24. var start = pos;
  25. while (next()) {
  26. if (ch === "\\") {
  27. next();
  28. next();
  29. } else if (ch === comma) {
  30. break;
  31. } else if (ch === "\n") {
  32. break;
  33. }
  34. }
  35. return source_text.substring(start, pos + 1);
  36. }
  37. function eatWhitespace() {
  38. var start = pos;
  39. while (whiteRe.test(peek())) {
  40. pos++;
  41. }
  42. return pos !== start;
  43. }
  44. function skipWhitespace() {
  45. var start = pos;
  46. do {
  47. } while (whiteRe.test(next()));
  48. return pos !== start + 1;
  49. }
  50. function eatComment() {
  51. var start = pos;
  52. next();
  53. while (next()) {
  54. if (ch === "*" && peek() === "/") {
  55. pos++;
  56. break;
  57. }
  58. }
  59. return source_text.substring(start, pos + 1);
  60. }
  61. function lookBack(str) {
  62. return source_text.substring(pos - str.length, pos).toLowerCase() === str;
  63. }
  64. // printer
  65. var indentString = source_text.match(/^[\r\n]*[\t ]*/)[0];
  66. var singleIndent = Array(indentSize + 1).join(indentCharacter);
  67. var indentLevel = 0;
  68. function indent() {
  69. indentLevel++;
  70. indentString += singleIndent;
  71. }
  72. function outdent() {
  73. indentLevel--;
  74. indentString = indentString.slice(0, -indentSize);
  75. }
  76. var print = {};
  77. print["{"] = function (ch) {
  78. print.singleSpace();
  79. output.push(ch);
  80. print.newLine();
  81. };
  82. print["}"] = function (ch) {
  83. print.newLine();
  84. output.push(ch);
  85. print.newLine();
  86. };
  87. print.newLine = function (keepWhitespace) {
  88. if (!keepWhitespace) {
  89. while (whiteRe.test(output[output.length - 1])) {
  90. output.pop();
  91. }
  92. }
  93. if (output.length) {
  94. output.push('\n');
  95. }
  96. if (indentString) {
  97. output.push(indentString);
  98. }
  99. };
  100. print.singleSpace = function () {
  101. if (output.length && !whiteRe.test(output[output.length - 1])) {
  102. output.push(' ');
  103. }
  104. };
  105. var output = [];
  106. if (indentString) {
  107. output.push(indentString);
  108. }
  109. /*_____________________--------------------_____________________*/
  110. while (true) {
  111. var isAfterSpace = skipWhitespace();
  112. if (!ch) {
  113. break;
  114. }
  115. if (ch === '{') {
  116. indent();
  117. print["{"](ch);
  118. } else if (ch === '}') {
  119. outdent();
  120. print["}"](ch);
  121. } else if (ch === '"' || ch === '\'') {
  122. output.push(eatString(ch));
  123. } else if (ch === ';') {
  124. output.push(ch, '\n', indentString);
  125. } else if (ch === '/' && peek() === '*') { // comment
  126. print.newLine();
  127. output.push(eatComment(), "\n", indentString);
  128. } else if (ch === '(') { // may be a url
  129. if (lookBack("url")) {
  130. output.push(ch);
  131. eatWhitespace();
  132. if (next()) {
  133. if (ch !== ')' && ch !== '"' && ch !== '\'') {
  134. output.push(eatString(')'));
  135. } else {
  136. pos--;
  137. }
  138. }
  139. } else {
  140. if (isAfterSpace) {
  141. print.singleSpace();
  142. }
  143. output.push(ch);
  144. eatWhitespace();
  145. }
  146. } else if (ch === ')') {
  147. output.push(ch);
  148. } else if (ch === ',') {
  149. eatWhitespace();
  150. output.push(ch);
  151. print.singleSpace();
  152. } else if (ch === ']') {
  153. output.push(ch);
  154. } else if (ch === '[' || ch === '=') { // no whitespace before or after
  155. eatWhitespace();
  156. output.push(ch);
  157. } else {
  158. if (isAfterSpace) {
  159. print.singleSpace();
  160. }
  161. output.push(ch);
  162. }
  163. }
  164. var sweetCode = output.join('').replace(/[\n ]+$/, '');
  165. return sweetCode;
  166. }
  167. var result = Beautifier(evt.data.source_text, evt.data.options);
  168. self.postMessage(result);
  169. };