|
1 /*jslint onevar: false, plusplus: false */ |
|
2 /*jshint curly:true, eqeqeq:true, laxbreak:true, noempty:false */ |
|
3 /* |
|
4 |
|
5 JS Beautifier |
|
6 --------------- |
|
7 |
|
8 |
|
9 Written by Einar Lielmanis, <einar@jsbeautifier.org> |
|
10 http://jsbeautifier.org/ |
|
11 |
|
12 Originally converted to javascript by Vital, <vital76@gmail.com> |
|
13 "End braces on own line" added by Chris J. Shull, <chrisjshull@gmail.com> |
|
14 |
|
15 You are free to use this in any way you want, in case you find this useful or working for you. |
|
16 |
|
17 Usage: |
|
18 js_beautify(js_source_text); |
|
19 js_beautify(js_source_text, options); |
|
20 |
|
21 The options are: |
|
22 indent_size (default 4) - indentation size, |
|
23 indent_char (default space) - character to indent with, |
|
24 preserve_newlines (default true) - whether existing line breaks should be preserved, |
|
25 max_preserve_newlines (default unlimited) - maximum number of line breaks to be preserved in one chunk, |
|
26 |
|
27 jslint_happy (default false) - if true, then jslint-stricter mode is enforced. |
|
28 |
|
29 jslint_happy !jslint_happy |
|
30 --------------------------------- |
|
31 function () function() |
|
32 |
|
33 brace_style (default "collapse") - "collapse" | "expand" | "end-expand" | "expand-strict" |
|
34 put braces on the same line as control statements (default), or put braces on own line (Allman / ANSI style), or just put end braces on own line. |
|
35 |
|
36 expand-strict: put brace on own line even in such cases: |
|
37 |
|
38 var a = |
|
39 { |
|
40 a: 5, |
|
41 b: 6 |
|
42 } |
|
43 This mode may break your scripts - e.g "return { a: 1 }" will be broken into two lines, so beware. |
|
44 |
|
45 space_before_conditional (default true) - should the space before conditional statement be added, "if(true)" vs "if (true)", |
|
46 |
|
47 unescape_strings (default false) - should printable characters in strings encoded in \xNN notation be unescaped, "example" vs "\x65\x78\x61\x6d\x70\x6c\x65" |
|
48 |
|
49 e.g |
|
50 |
|
51 js_beautify(js_source_text, { |
|
52 'indent_size': 1, |
|
53 'indent_char': '\t' |
|
54 }); |
|
55 |
|
56 |
|
57 */ |
|
58 |
|
59 this.EXPORTED_SYMBOLS = ["js_beautify"]; |
|
60 |
|
61 this.js_beautify = function js_beautify(js_source_text, options) { |
|
62 |
|
63 var input, output, token_text, last_type, last_text, last_last_text, last_word, flags, flag_store, indent_string; |
|
64 var whitespace, wordchar, punct, parser_pos, line_starters, digits; |
|
65 var prefix, token_type, do_block_just_closed; |
|
66 var wanted_newline, just_added_newline, n_newlines; |
|
67 var preindent_string = ''; |
|
68 |
|
69 |
|
70 // Some interpreters have unexpected results with foo = baz || bar; |
|
71 options = options ? options : {}; |
|
72 |
|
73 var opt_brace_style; |
|
74 |
|
75 // compatibility |
|
76 if (options.space_after_anon_function !== undefined && options.jslint_happy === undefined) { |
|
77 options.jslint_happy = options.space_after_anon_function; |
|
78 } |
|
79 if (options.braces_on_own_line !== undefined) { //graceful handling of deprecated option |
|
80 opt_brace_style = options.braces_on_own_line ? "expand" : "collapse"; |
|
81 } |
|
82 opt_brace_style = options.brace_style ? options.brace_style : (opt_brace_style ? opt_brace_style : "collapse"); |
|
83 |
|
84 |
|
85 var opt_indent_size = options.indent_size ? options.indent_size : 4; |
|
86 var opt_indent_char = options.indent_char ? options.indent_char : ' '; |
|
87 var opt_preserve_newlines = typeof options.preserve_newlines === 'undefined' ? true : options.preserve_newlines; |
|
88 var opt_max_preserve_newlines = typeof options.max_preserve_newlines === 'undefined' ? false : options.max_preserve_newlines; |
|
89 var opt_jslint_happy = options.jslint_happy === 'undefined' ? false : options.jslint_happy; |
|
90 var opt_keep_array_indentation = typeof options.keep_array_indentation === 'undefined' ? false : options.keep_array_indentation; |
|
91 var opt_space_before_conditional = typeof options.space_before_conditional === 'undefined' ? true : options.space_before_conditional; |
|
92 var opt_indent_case = typeof options.indent_case === 'undefined' ? false : options.indent_case; |
|
93 var opt_unescape_strings = typeof options.unescape_strings === 'undefined' ? false : options.unescape_strings; |
|
94 |
|
95 just_added_newline = false; |
|
96 |
|
97 // cache the source's length. |
|
98 var input_length = js_source_text.length; |
|
99 |
|
100 function trim_output(eat_newlines) { |
|
101 eat_newlines = typeof eat_newlines === 'undefined' ? false : eat_newlines; |
|
102 while (output.length && (output[output.length - 1] === ' ' |
|
103 || output[output.length - 1] === indent_string |
|
104 || output[output.length - 1] === preindent_string |
|
105 || (eat_newlines && (output[output.length - 1] === '\n' || output[output.length - 1] === '\r')))) { |
|
106 output.pop(); |
|
107 } |
|
108 } |
|
109 |
|
110 function trim(s) { |
|
111 return s.replace(/^\s\s*|\s\s*$/, ''); |
|
112 } |
|
113 |
|
114 // we could use just string.split, but |
|
115 // IE doesn't like returning empty strings |
|
116 function split_newlines(s) { |
|
117 return s.split(/\x0d\x0a|\x0a/); |
|
118 } |
|
119 |
|
120 function force_newline() { |
|
121 var old_keep_array_indentation = opt_keep_array_indentation; |
|
122 opt_keep_array_indentation = false; |
|
123 print_newline(); |
|
124 opt_keep_array_indentation = old_keep_array_indentation; |
|
125 } |
|
126 |
|
127 function print_newline(ignore_repeated) { |
|
128 |
|
129 flags.eat_next_space = false; |
|
130 if (opt_keep_array_indentation && is_array(flags.mode)) { |
|
131 return; |
|
132 } |
|
133 |
|
134 ignore_repeated = typeof ignore_repeated === 'undefined' ? true : ignore_repeated; |
|
135 |
|
136 flags.if_line = false; |
|
137 trim_output(); |
|
138 |
|
139 if (!output.length) { |
|
140 return; // no newline on start of file |
|
141 } |
|
142 |
|
143 if (output[output.length - 1] !== "\n" || !ignore_repeated) { |
|
144 just_added_newline = true; |
|
145 output.push("\n"); |
|
146 } |
|
147 if (preindent_string) { |
|
148 output.push(preindent_string); |
|
149 } |
|
150 for (var i = 0; i < flags.indentation_level; i += 1) { |
|
151 output.push(indent_string); |
|
152 } |
|
153 if (flags.var_line && flags.var_line_reindented) { |
|
154 output.push(indent_string); // skip space-stuffing, if indenting with a tab |
|
155 } |
|
156 if (flags.case_body) { |
|
157 output.push(indent_string); |
|
158 } |
|
159 } |
|
160 |
|
161 |
|
162 |
|
163 function print_single_space() { |
|
164 |
|
165 if (last_type === 'TK_COMMENT') { |
|
166 return print_newline(); |
|
167 } |
|
168 if (flags.eat_next_space) { |
|
169 flags.eat_next_space = false; |
|
170 return; |
|
171 } |
|
172 var last_output = ' '; |
|
173 if (output.length) { |
|
174 last_output = output[output.length - 1]; |
|
175 } |
|
176 if (last_output !== ' ' && last_output !== '\n' && last_output !== indent_string) { // prevent occassional duplicate space |
|
177 output.push(' '); |
|
178 } |
|
179 } |
|
180 |
|
181 |
|
182 function print_token() { |
|
183 just_added_newline = false; |
|
184 flags.eat_next_space = false; |
|
185 output.push(token_text); |
|
186 } |
|
187 |
|
188 function indent() { |
|
189 flags.indentation_level += 1; |
|
190 } |
|
191 |
|
192 |
|
193 function remove_indent() { |
|
194 if (output.length && output[output.length - 1] === indent_string) { |
|
195 output.pop(); |
|
196 } |
|
197 } |
|
198 |
|
199 function set_mode(mode) { |
|
200 if (flags) { |
|
201 flag_store.push(flags); |
|
202 } |
|
203 flags = { |
|
204 previous_mode: flags ? flags.mode : 'BLOCK', |
|
205 mode: mode, |
|
206 var_line: false, |
|
207 var_line_tainted: false, |
|
208 var_line_reindented: false, |
|
209 in_html_comment: false, |
|
210 if_line: false, |
|
211 in_case_statement: false, // switch(..){ INSIDE HERE } |
|
212 in_case: false, // we're on the exact line with "case 0:" |
|
213 case_body: false, // the indented case-action block |
|
214 eat_next_space: false, |
|
215 indentation_baseline: -1, |
|
216 indentation_level: (flags ? flags.indentation_level + (flags.case_body ? 1 : 0) + ((flags.var_line && flags.var_line_reindented) ? 1 : 0) : 0), |
|
217 ternary_depth: 0 |
|
218 }; |
|
219 } |
|
220 |
|
221 function is_array(mode) { |
|
222 return mode === '[EXPRESSION]' || mode === '[INDENTED-EXPRESSION]'; |
|
223 } |
|
224 |
|
225 function is_expression(mode) { |
|
226 return in_array(mode, ['[EXPRESSION]', '(EXPRESSION)', '(FOR-EXPRESSION)', '(COND-EXPRESSION)']); |
|
227 } |
|
228 |
|
229 function restore_mode() { |
|
230 do_block_just_closed = flags.mode === 'DO_BLOCK'; |
|
231 if (flag_store.length > 0) { |
|
232 var mode = flags.mode; |
|
233 flags = flag_store.pop(); |
|
234 flags.previous_mode = mode; |
|
235 } |
|
236 } |
|
237 |
|
238 function all_lines_start_with(lines, c) { |
|
239 for (var i = 0; i < lines.length; i++) { |
|
240 var line = trim(lines[i]); |
|
241 if (line.charAt(0) !== c) { |
|
242 return false; |
|
243 } |
|
244 } |
|
245 return true; |
|
246 } |
|
247 |
|
248 function is_special_word(word) { |
|
249 return in_array(word, ['case', 'return', 'do', 'if', 'throw', 'else']); |
|
250 } |
|
251 |
|
252 function in_array(what, arr) { |
|
253 for (var i = 0; i < arr.length; i += 1) { |
|
254 if (arr[i] === what) { |
|
255 return true; |
|
256 } |
|
257 } |
|
258 return false; |
|
259 } |
|
260 |
|
261 function look_up(exclude) { |
|
262 var local_pos = parser_pos; |
|
263 var c = input.charAt(local_pos); |
|
264 while (in_array(c, whitespace) && c !== exclude) { |
|
265 local_pos++; |
|
266 if (local_pos >= input_length) { |
|
267 return 0; |
|
268 } |
|
269 c = input.charAt(local_pos); |
|
270 } |
|
271 return c; |
|
272 } |
|
273 |
|
274 function get_next_token() { |
|
275 var i; |
|
276 var resulting_string; |
|
277 |
|
278 n_newlines = 0; |
|
279 |
|
280 if (parser_pos >= input_length) { |
|
281 return ['', 'TK_EOF']; |
|
282 } |
|
283 |
|
284 wanted_newline = false; |
|
285 |
|
286 var c = input.charAt(parser_pos); |
|
287 parser_pos += 1; |
|
288 |
|
289 |
|
290 var keep_whitespace = opt_keep_array_indentation && is_array(flags.mode); |
|
291 |
|
292 if (keep_whitespace) { |
|
293 |
|
294 // |
|
295 // slight mess to allow nice preservation of array indentation and reindent that correctly |
|
296 // first time when we get to the arrays: |
|
297 // var a = [ |
|
298 // ....'something' |
|
299 // we make note of whitespace_count = 4 into flags.indentation_baseline |
|
300 // so we know that 4 whitespaces in original source match indent_level of reindented source |
|
301 // |
|
302 // and afterwards, when we get to |
|
303 // 'something, |
|
304 // .......'something else' |
|
305 // we know that this should be indented to indent_level + (7 - indentation_baseline) spaces |
|
306 // |
|
307 var whitespace_count = 0; |
|
308 |
|
309 while (in_array(c, whitespace)) { |
|
310 |
|
311 if (c === "\n") { |
|
312 trim_output(); |
|
313 output.push("\n"); |
|
314 just_added_newline = true; |
|
315 whitespace_count = 0; |
|
316 } else { |
|
317 if (c === '\t') { |
|
318 whitespace_count += 4; |
|
319 } else if (c === '\r') { |
|
320 // nothing |
|
321 } else { |
|
322 whitespace_count += 1; |
|
323 } |
|
324 } |
|
325 |
|
326 if (parser_pos >= input_length) { |
|
327 return ['', 'TK_EOF']; |
|
328 } |
|
329 |
|
330 c = input.charAt(parser_pos); |
|
331 parser_pos += 1; |
|
332 |
|
333 } |
|
334 if (flags.indentation_baseline === -1) { |
|
335 flags.indentation_baseline = whitespace_count; |
|
336 } |
|
337 |
|
338 if (just_added_newline) { |
|
339 for (i = 0; i < flags.indentation_level + 1; i += 1) { |
|
340 output.push(indent_string); |
|
341 } |
|
342 if (flags.indentation_baseline !== -1) { |
|
343 for (i = 0; i < whitespace_count - flags.indentation_baseline; i++) { |
|
344 output.push(' '); |
|
345 } |
|
346 } |
|
347 } |
|
348 |
|
349 } else { |
|
350 while (in_array(c, whitespace)) { |
|
351 |
|
352 if (c === "\n") { |
|
353 n_newlines += ((opt_max_preserve_newlines) ? (n_newlines <= opt_max_preserve_newlines) ? 1 : 0 : 1); |
|
354 } |
|
355 |
|
356 |
|
357 if (parser_pos >= input_length) { |
|
358 return ['', 'TK_EOF']; |
|
359 } |
|
360 |
|
361 c = input.charAt(parser_pos); |
|
362 parser_pos += 1; |
|
363 |
|
364 } |
|
365 |
|
366 if (opt_preserve_newlines) { |
|
367 if (n_newlines > 1) { |
|
368 for (i = 0; i < n_newlines; i += 1) { |
|
369 print_newline(i === 0); |
|
370 just_added_newline = true; |
|
371 } |
|
372 } |
|
373 } |
|
374 wanted_newline = n_newlines > 0; |
|
375 } |
|
376 |
|
377 |
|
378 if (in_array(c, wordchar)) { |
|
379 if (parser_pos < input_length) { |
|
380 while (in_array(input.charAt(parser_pos), wordchar)) { |
|
381 c += input.charAt(parser_pos); |
|
382 parser_pos += 1; |
|
383 if (parser_pos === input_length) { |
|
384 break; |
|
385 } |
|
386 } |
|
387 } |
|
388 |
|
389 // small and surprisingly unugly hack for 1E-10 representation |
|
390 if (parser_pos !== input_length && c.match(/^[0-9]+[Ee]$/) && (input.charAt(parser_pos) === '-' || input.charAt(parser_pos) === '+')) { |
|
391 |
|
392 var sign = input.charAt(parser_pos); |
|
393 parser_pos += 1; |
|
394 |
|
395 var t = get_next_token(); |
|
396 c += sign + t[0]; |
|
397 return [c, 'TK_WORD']; |
|
398 } |
|
399 |
|
400 if (c === 'in') { // hack for 'in' operator |
|
401 return [c, 'TK_OPERATOR']; |
|
402 } |
|
403 if (wanted_newline && last_type !== 'TK_OPERATOR' |
|
404 && last_type !== 'TK_EQUALS' |
|
405 && !flags.if_line && (opt_preserve_newlines || last_text !== 'var')) { |
|
406 print_newline(); |
|
407 } |
|
408 return [c, 'TK_WORD']; |
|
409 } |
|
410 |
|
411 if (c === '(' || c === '[') { |
|
412 return [c, 'TK_START_EXPR']; |
|
413 } |
|
414 |
|
415 if (c === ')' || c === ']') { |
|
416 return [c, 'TK_END_EXPR']; |
|
417 } |
|
418 |
|
419 if (c === '{') { |
|
420 return [c, 'TK_START_BLOCK']; |
|
421 } |
|
422 |
|
423 if (c === '}') { |
|
424 return [c, 'TK_END_BLOCK']; |
|
425 } |
|
426 |
|
427 if (c === ';') { |
|
428 return [c, 'TK_SEMICOLON']; |
|
429 } |
|
430 |
|
431 if (c === '/') { |
|
432 var comment = ''; |
|
433 // peek for comment /* ... */ |
|
434 var inline_comment = true; |
|
435 if (input.charAt(parser_pos) === '*') { |
|
436 parser_pos += 1; |
|
437 if (parser_pos < input_length) { |
|
438 while (parser_pos < input_length && |
|
439 ! (input.charAt(parser_pos) === '*' && input.charAt(parser_pos + 1) && input.charAt(parser_pos + 1) === '/')) { |
|
440 c = input.charAt(parser_pos); |
|
441 comment += c; |
|
442 if (c === "\n" || c === "\r") { |
|
443 inline_comment = false; |
|
444 } |
|
445 parser_pos += 1; |
|
446 if (parser_pos >= input_length) { |
|
447 break; |
|
448 } |
|
449 } |
|
450 } |
|
451 parser_pos += 2; |
|
452 if (inline_comment && n_newlines === 0) { |
|
453 return ['/*' + comment + '*/', 'TK_INLINE_COMMENT']; |
|
454 } else { |
|
455 return ['/*' + comment + '*/', 'TK_BLOCK_COMMENT']; |
|
456 } |
|
457 } |
|
458 // peek for comment // ... |
|
459 if (input.charAt(parser_pos) === '/') { |
|
460 comment = c; |
|
461 while (input.charAt(parser_pos) !== '\r' && input.charAt(parser_pos) !== '\n') { |
|
462 comment += input.charAt(parser_pos); |
|
463 parser_pos += 1; |
|
464 if (parser_pos >= input_length) { |
|
465 break; |
|
466 } |
|
467 } |
|
468 if (wanted_newline) { |
|
469 print_newline(); |
|
470 } |
|
471 return [comment, 'TK_COMMENT']; |
|
472 } |
|
473 |
|
474 } |
|
475 |
|
476 if (c === "'" || // string |
|
477 c === '"' || // string |
|
478 (c === '/' && |
|
479 ((last_type === 'TK_WORD' && is_special_word(last_text)) || |
|
480 (last_text === ')' && in_array(flags.previous_mode, ['(COND-EXPRESSION)', '(FOR-EXPRESSION)'])) || |
|
481 (last_type === 'TK_COMMA' || last_type === 'TK_COMMENT' || last_type === 'TK_START_EXPR' || last_type === 'TK_START_BLOCK' || last_type === 'TK_END_BLOCK' || last_type === 'TK_OPERATOR' || last_type === 'TK_EQUALS' || last_type === 'TK_EOF' || last_type === 'TK_SEMICOLON')))) { // regexp |
|
482 var sep = c; |
|
483 var esc = false; |
|
484 var esc1 = 0; |
|
485 var esc2 = 0; |
|
486 resulting_string = c; |
|
487 |
|
488 if (parser_pos < input_length) { |
|
489 if (sep === '/') { |
|
490 // |
|
491 // handle regexp separately... |
|
492 // |
|
493 var in_char_class = false; |
|
494 while (esc || in_char_class || input.charAt(parser_pos) !== sep) { |
|
495 resulting_string += input.charAt(parser_pos); |
|
496 if (!esc) { |
|
497 esc = input.charAt(parser_pos) === '\\'; |
|
498 if (input.charAt(parser_pos) === '[') { |
|
499 in_char_class = true; |
|
500 } else if (input.charAt(parser_pos) === ']') { |
|
501 in_char_class = false; |
|
502 } |
|
503 } else { |
|
504 esc = false; |
|
505 } |
|
506 parser_pos += 1; |
|
507 if (parser_pos >= input_length) { |
|
508 // incomplete string/rexp when end-of-file reached. |
|
509 // bail out with what had been received so far. |
|
510 return [resulting_string, 'TK_STRING']; |
|
511 } |
|
512 } |
|
513 |
|
514 } else { |
|
515 // |
|
516 // and handle string also separately |
|
517 // |
|
518 while (esc || input.charAt(parser_pos) !== sep) { |
|
519 resulting_string += input.charAt(parser_pos); |
|
520 if (esc1 && esc1 >= esc2) { |
|
521 esc1 = parseInt(resulting_string.substr(-esc2), 16); |
|
522 if (esc1 && esc1 >= 0x20 && esc1 <= 0x7e) { |
|
523 esc1 = String.fromCharCode(esc1); |
|
524 resulting_string = resulting_string.substr(0, resulting_string.length - esc2 - 2) + (((esc1 === sep) || (esc1 === '\\')) ? '\\' : '') + esc1; |
|
525 } |
|
526 esc1 = 0; |
|
527 } |
|
528 if (esc1) { |
|
529 esc1++; |
|
530 } else if (!esc) { |
|
531 esc = input.charAt(parser_pos) === '\\'; |
|
532 } else { |
|
533 esc = false; |
|
534 if (opt_unescape_strings) { |
|
535 if (input.charAt(parser_pos) === 'x') { |
|
536 esc1++; |
|
537 esc2 = 2; |
|
538 } else if (input.charAt(parser_pos) === 'u') { |
|
539 esc1++; |
|
540 esc2 = 4; |
|
541 } |
|
542 } |
|
543 } |
|
544 parser_pos += 1; |
|
545 if (parser_pos >= input_length) { |
|
546 // incomplete string/rexp when end-of-file reached. |
|
547 // bail out with what had been received so far. |
|
548 return [resulting_string, 'TK_STRING']; |
|
549 } |
|
550 } |
|
551 } |
|
552 |
|
553 |
|
554 |
|
555 } |
|
556 |
|
557 parser_pos += 1; |
|
558 |
|
559 resulting_string += sep; |
|
560 |
|
561 if (sep === '/') { |
|
562 // regexps may have modifiers /regexp/MOD , so fetch those, too |
|
563 while (parser_pos < input_length && in_array(input.charAt(parser_pos), wordchar)) { |
|
564 resulting_string += input.charAt(parser_pos); |
|
565 parser_pos += 1; |
|
566 } |
|
567 } |
|
568 return [resulting_string, 'TK_STRING']; |
|
569 } |
|
570 |
|
571 if (c === '#') { |
|
572 |
|
573 |
|
574 if (output.length === 0 && input.charAt(parser_pos) === '!') { |
|
575 // shebang |
|
576 resulting_string = c; |
|
577 while (parser_pos < input_length && c !== '\n') { |
|
578 c = input.charAt(parser_pos); |
|
579 resulting_string += c; |
|
580 parser_pos += 1; |
|
581 } |
|
582 output.push(trim(resulting_string) + '\n'); |
|
583 print_newline(); |
|
584 return get_next_token(); |
|
585 } |
|
586 |
|
587 |
|
588 |
|
589 // Spidermonkey-specific sharp variables for circular references |
|
590 // https://developer.mozilla.org/En/Sharp_variables_in_JavaScript |
|
591 // http://mxr.mozilla.org/mozilla-central/source/js/src/jsscan.cpp around line 1935 |
|
592 var sharp = '#'; |
|
593 if (parser_pos < input_length && in_array(input.charAt(parser_pos), digits)) { |
|
594 do { |
|
595 c = input.charAt(parser_pos); |
|
596 sharp += c; |
|
597 parser_pos += 1; |
|
598 } while (parser_pos < input_length && c !== '#' && c !== '='); |
|
599 if (c === '#') { |
|
600 // |
|
601 } else if (input.charAt(parser_pos) === '[' && input.charAt(parser_pos + 1) === ']') { |
|
602 sharp += '[]'; |
|
603 parser_pos += 2; |
|
604 } else if (input.charAt(parser_pos) === '{' && input.charAt(parser_pos + 1) === '}') { |
|
605 sharp += '{}'; |
|
606 parser_pos += 2; |
|
607 } |
|
608 return [sharp, 'TK_WORD']; |
|
609 } |
|
610 } |
|
611 |
|
612 if (c === '<' && input.substring(parser_pos - 1, parser_pos + 3) === '<!--') { |
|
613 parser_pos += 3; |
|
614 c = '<!--'; |
|
615 while (input.charAt(parser_pos) !== '\n' && parser_pos < input_length) { |
|
616 c += input.charAt(parser_pos); |
|
617 parser_pos++; |
|
618 } |
|
619 flags.in_html_comment = true; |
|
620 return [c, 'TK_COMMENT']; |
|
621 } |
|
622 |
|
623 if (c === '-' && flags.in_html_comment && input.substring(parser_pos - 1, parser_pos + 2) === '-->') { |
|
624 flags.in_html_comment = false; |
|
625 parser_pos += 2; |
|
626 if (wanted_newline) { |
|
627 print_newline(); |
|
628 } |
|
629 return ['-->', 'TK_COMMENT']; |
|
630 } |
|
631 |
|
632 if (in_array(c, punct)) { |
|
633 while (parser_pos < input_length && in_array(c + input.charAt(parser_pos), punct)) { |
|
634 c += input.charAt(parser_pos); |
|
635 parser_pos += 1; |
|
636 if (parser_pos >= input_length) { |
|
637 break; |
|
638 } |
|
639 } |
|
640 |
|
641 if (c === ',') { |
|
642 return [c, 'TK_COMMA']; |
|
643 } else if (c === '=') { |
|
644 return [c, 'TK_EQUALS']; |
|
645 } else { |
|
646 return [c, 'TK_OPERATOR']; |
|
647 } |
|
648 } |
|
649 |
|
650 return [c, 'TK_UNKNOWN']; |
|
651 } |
|
652 |
|
653 //---------------------------------- |
|
654 indent_string = ''; |
|
655 while (opt_indent_size > 0) { |
|
656 indent_string += opt_indent_char; |
|
657 opt_indent_size -= 1; |
|
658 } |
|
659 |
|
660 while (js_source_text && (js_source_text.charAt(0) === ' ' || js_source_text.charAt(0) === '\t')) { |
|
661 preindent_string += js_source_text.charAt(0); |
|
662 js_source_text = js_source_text.substring(1); |
|
663 } |
|
664 input = js_source_text; |
|
665 |
|
666 last_word = ''; // last 'TK_WORD' passed |
|
667 last_type = 'TK_START_EXPR'; // last token type |
|
668 last_text = ''; // last token text |
|
669 last_last_text = ''; // pre-last token text |
|
670 output = []; |
|
671 |
|
672 do_block_just_closed = false; |
|
673 |
|
674 whitespace = "\n\r\t ".split(''); |
|
675 wordchar = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_$'.split(''); |
|
676 digits = '0123456789'.split(''); |
|
677 |
|
678 punct = '+ - * / % & ++ -- = += -= *= /= %= == === != !== > < >= <= >> << >>> >>>= >>= <<= && &= | || ! !! , : ? ^ ^= |= ::'; |
|
679 punct += ' <%= <% %> <?= <? ?>'; // try to be a good boy and try not to break the markup language identifiers |
|
680 punct = punct.split(' '); |
|
681 |
|
682 // words which should always start on new line. |
|
683 line_starters = 'continue,try,throw,return,var,if,switch,case,default,for,while,break,function'.split(','); |
|
684 |
|
685 // states showing if we are currently in expression (i.e. "if" case) - 'EXPRESSION', or in usual block (like, procedure), 'BLOCK'. |
|
686 // some formatting depends on that. |
|
687 flag_store = []; |
|
688 set_mode('BLOCK'); |
|
689 |
|
690 parser_pos = 0; |
|
691 while (true) { |
|
692 var t = get_next_token(); |
|
693 token_text = t[0]; |
|
694 token_type = t[1]; |
|
695 if (token_type === 'TK_EOF') { |
|
696 break; |
|
697 } |
|
698 |
|
699 switch (token_type) { |
|
700 |
|
701 case 'TK_START_EXPR': |
|
702 |
|
703 if (token_text === '[') { |
|
704 |
|
705 if (last_type === 'TK_WORD' || last_text === ')') { |
|
706 // this is array index specifier, break immediately |
|
707 // a[x], fn()[x] |
|
708 if (in_array(last_text, line_starters)) { |
|
709 print_single_space(); |
|
710 } |
|
711 set_mode('(EXPRESSION)'); |
|
712 print_token(); |
|
713 break; |
|
714 } |
|
715 |
|
716 if (flags.mode === '[EXPRESSION]' || flags.mode === '[INDENTED-EXPRESSION]') { |
|
717 if (last_last_text === ']' && last_text === ',') { |
|
718 // ], [ goes to new line |
|
719 if (flags.mode === '[EXPRESSION]') { |
|
720 flags.mode = '[INDENTED-EXPRESSION]'; |
|
721 if (!opt_keep_array_indentation) { |
|
722 indent(); |
|
723 } |
|
724 } |
|
725 set_mode('[EXPRESSION]'); |
|
726 if (!opt_keep_array_indentation) { |
|
727 print_newline(); |
|
728 } |
|
729 } else if (last_text === '[') { |
|
730 if (flags.mode === '[EXPRESSION]') { |
|
731 flags.mode = '[INDENTED-EXPRESSION]'; |
|
732 if (!opt_keep_array_indentation) { |
|
733 indent(); |
|
734 } |
|
735 } |
|
736 set_mode('[EXPRESSION]'); |
|
737 |
|
738 if (!opt_keep_array_indentation) { |
|
739 print_newline(); |
|
740 } |
|
741 } else { |
|
742 set_mode('[EXPRESSION]'); |
|
743 } |
|
744 } else { |
|
745 set_mode('[EXPRESSION]'); |
|
746 } |
|
747 |
|
748 |
|
749 |
|
750 } else { |
|
751 if (last_word === 'for') { |
|
752 set_mode('(FOR-EXPRESSION)'); |
|
753 } else if (in_array(last_word, ['if', 'while'])) { |
|
754 set_mode('(COND-EXPRESSION)'); |
|
755 } else { |
|
756 set_mode('(EXPRESSION)'); |
|
757 } |
|
758 } |
|
759 |
|
760 if (last_text === ';' || last_type === 'TK_START_BLOCK') { |
|
761 print_newline(); |
|
762 } else if (last_type === 'TK_END_EXPR' || last_type === 'TK_START_EXPR' || last_type === 'TK_END_BLOCK' || last_text === '.') { |
|
763 if (wanted_newline) { |
|
764 print_newline(); |
|
765 } |
|
766 // do nothing on (( and )( and ][ and ]( and .( |
|
767 } else if (last_type !== 'TK_WORD' && last_type !== 'TK_OPERATOR') { |
|
768 print_single_space(); |
|
769 } else if (last_word === 'function' || last_word === 'typeof') { |
|
770 // function() vs function () |
|
771 if (opt_jslint_happy) { |
|
772 print_single_space(); |
|
773 } |
|
774 } else if (in_array(last_text, line_starters) || last_text === 'catch') { |
|
775 if (opt_space_before_conditional) { |
|
776 print_single_space(); |
|
777 } |
|
778 } |
|
779 print_token(); |
|
780 |
|
781 break; |
|
782 |
|
783 case 'TK_END_EXPR': |
|
784 if (token_text === ']') { |
|
785 if (opt_keep_array_indentation) { |
|
786 if (last_text === '}') { |
|
787 // trim_output(); |
|
788 // print_newline(true); |
|
789 remove_indent(); |
|
790 print_token(); |
|
791 restore_mode(); |
|
792 break; |
|
793 } |
|
794 } else { |
|
795 if (flags.mode === '[INDENTED-EXPRESSION]') { |
|
796 if (last_text === ']') { |
|
797 restore_mode(); |
|
798 print_newline(); |
|
799 print_token(); |
|
800 break; |
|
801 } |
|
802 } |
|
803 } |
|
804 } |
|
805 restore_mode(); |
|
806 print_token(); |
|
807 break; |
|
808 |
|
809 case 'TK_START_BLOCK': |
|
810 |
|
811 if (last_word === 'do') { |
|
812 set_mode('DO_BLOCK'); |
|
813 } else { |
|
814 set_mode('BLOCK'); |
|
815 } |
|
816 if (opt_brace_style === "expand" || opt_brace_style === "expand-strict") { |
|
817 var empty_braces = false; |
|
818 if (opt_brace_style === "expand-strict") { |
|
819 empty_braces = (look_up() === '}'); |
|
820 if (!empty_braces) { |
|
821 print_newline(true); |
|
822 } |
|
823 } else { |
|
824 if (last_type !== 'TK_OPERATOR') { |
|
825 if (last_text === '=' || (is_special_word(last_text) && last_text !== 'else')) { |
|
826 print_single_space(); |
|
827 } else { |
|
828 print_newline(true); |
|
829 } |
|
830 } |
|
831 } |
|
832 print_token(); |
|
833 if (!empty_braces) { |
|
834 indent(); |
|
835 } |
|
836 } else { |
|
837 if (last_type !== 'TK_OPERATOR' && last_type !== 'TK_START_EXPR') { |
|
838 if (last_type === 'TK_START_BLOCK') { |
|
839 print_newline(); |
|
840 } else { |
|
841 print_single_space(); |
|
842 } |
|
843 } else { |
|
844 // if TK_OPERATOR or TK_START_EXPR |
|
845 if (is_array(flags.previous_mode) && last_text === ',') { |
|
846 if (last_last_text === '}') { |
|
847 // }, { in array context |
|
848 print_single_space(); |
|
849 } else { |
|
850 print_newline(); // [a, b, c, { |
|
851 } |
|
852 } |
|
853 } |
|
854 indent(); |
|
855 print_token(); |
|
856 } |
|
857 |
|
858 break; |
|
859 |
|
860 case 'TK_END_BLOCK': |
|
861 restore_mode(); |
|
862 if (opt_brace_style === "expand" || opt_brace_style === "expand-strict") { |
|
863 if (last_text !== '{') { |
|
864 print_newline(); |
|
865 } |
|
866 print_token(); |
|
867 } else { |
|
868 if (last_type === 'TK_START_BLOCK') { |
|
869 // nothing |
|
870 if (just_added_newline) { |
|
871 remove_indent(); |
|
872 } else { |
|
873 // {} |
|
874 trim_output(); |
|
875 } |
|
876 } else { |
|
877 if (is_array(flags.mode) && opt_keep_array_indentation) { |
|
878 // we REALLY need a newline here, but newliner would skip that |
|
879 opt_keep_array_indentation = false; |
|
880 print_newline(); |
|
881 opt_keep_array_indentation = true; |
|
882 |
|
883 } else { |
|
884 print_newline(); |
|
885 } |
|
886 } |
|
887 print_token(); |
|
888 } |
|
889 break; |
|
890 |
|
891 case 'TK_WORD': |
|
892 |
|
893 // no, it's not you. even I have problems understanding how this works |
|
894 // and what does what. |
|
895 if (do_block_just_closed) { |
|
896 // do {} ## while () |
|
897 print_single_space(); |
|
898 print_token(); |
|
899 print_single_space(); |
|
900 do_block_just_closed = false; |
|
901 break; |
|
902 } |
|
903 |
|
904 prefix = 'NONE'; |
|
905 |
|
906 if (token_text === 'function') { |
|
907 if (flags.var_line && last_type !== 'TK_EQUALS' ) { |
|
908 flags.var_line_reindented = true; |
|
909 } |
|
910 if ((just_added_newline || last_text === ';') && last_text !== '{' |
|
911 && last_type !== 'TK_BLOCK_COMMENT' && last_type !== 'TK_COMMENT') { |
|
912 // make sure there is a nice clean space of at least one blank line |
|
913 // before a new function definition |
|
914 n_newlines = just_added_newline ? n_newlines : 0; |
|
915 if (!opt_preserve_newlines) { |
|
916 n_newlines = 1; |
|
917 } |
|
918 |
|
919 for (var i = 0; i < 2 - n_newlines; i++) { |
|
920 print_newline(false); |
|
921 } |
|
922 } |
|
923 if (last_type === 'TK_WORD') { |
|
924 if (last_text === 'get' || last_text === 'set' || last_text === 'new' || last_text === 'return') { |
|
925 print_single_space(); |
|
926 } else { |
|
927 print_newline(); |
|
928 } |
|
929 } else if (last_type === 'TK_OPERATOR' || last_text === '=') { |
|
930 // foo = function |
|
931 print_single_space(); |
|
932 } else if (is_expression(flags.mode)) { |
|
933 //ää print nothing |
|
934 } else { |
|
935 print_newline(); |
|
936 } |
|
937 |
|
938 print_token(); |
|
939 last_word = token_text; |
|
940 break; |
|
941 } |
|
942 |
|
943 if (token_text === 'case' || (token_text === 'default' && flags.in_case_statement)) { |
|
944 if (last_text === ':' || flags.case_body) { |
|
945 // switch cases following one another |
|
946 remove_indent(); |
|
947 } else { |
|
948 // case statement starts in the same line where switch |
|
949 if (!opt_indent_case) { |
|
950 flags.indentation_level--; |
|
951 } |
|
952 print_newline(); |
|
953 if (!opt_indent_case) { |
|
954 flags.indentation_level++; |
|
955 } |
|
956 } |
|
957 print_token(); |
|
958 flags.in_case = true; |
|
959 flags.in_case_statement = true; |
|
960 flags.case_body = false; |
|
961 break; |
|
962 } |
|
963 |
|
964 if (last_type === 'TK_END_BLOCK') { |
|
965 |
|
966 if (!in_array(token_text.toLowerCase(), ['else', 'catch', 'finally'])) { |
|
967 prefix = 'NEWLINE'; |
|
968 } else { |
|
969 if (opt_brace_style === "expand" || opt_brace_style === "end-expand" || opt_brace_style === "expand-strict") { |
|
970 prefix = 'NEWLINE'; |
|
971 } else { |
|
972 prefix = 'SPACE'; |
|
973 print_single_space(); |
|
974 } |
|
975 } |
|
976 } else if (last_type === 'TK_SEMICOLON' && (flags.mode === 'BLOCK' || flags.mode === 'DO_BLOCK')) { |
|
977 prefix = 'NEWLINE'; |
|
978 } else if (last_type === 'TK_SEMICOLON' && is_expression(flags.mode)) { |
|
979 prefix = 'SPACE'; |
|
980 } else if (last_type === 'TK_STRING') { |
|
981 prefix = 'NEWLINE'; |
|
982 } else if (last_type === 'TK_WORD') { |
|
983 if (last_text === 'else') { |
|
984 // eat newlines between ...else *** some_op... |
|
985 // won't preserve extra newlines in this place (if any), but don't care that much |
|
986 trim_output(true); |
|
987 } |
|
988 prefix = 'SPACE'; |
|
989 } else if (last_type === 'TK_START_BLOCK') { |
|
990 prefix = 'NEWLINE'; |
|
991 } else if (last_type === 'TK_END_EXPR') { |
|
992 print_single_space(); |
|
993 prefix = 'NEWLINE'; |
|
994 } |
|
995 |
|
996 if (in_array(token_text, line_starters) && last_text !== ')') { |
|
997 if (last_text === 'else') { |
|
998 prefix = 'SPACE'; |
|
999 } else { |
|
1000 prefix = 'NEWLINE'; |
|
1001 } |
|
1002 |
|
1003 } |
|
1004 |
|
1005 if (flags.if_line && last_type === 'TK_END_EXPR') { |
|
1006 flags.if_line = false; |
|
1007 } |
|
1008 if (in_array(token_text.toLowerCase(), ['else', 'catch', 'finally'])) { |
|
1009 if (last_type !== 'TK_END_BLOCK' || opt_brace_style === "expand" || opt_brace_style === "end-expand" || opt_brace_style === "expand-strict") { |
|
1010 print_newline(); |
|
1011 } else { |
|
1012 trim_output(true); |
|
1013 print_single_space(); |
|
1014 } |
|
1015 } else if (prefix === 'NEWLINE') { |
|
1016 if (is_special_word(last_text)) { |
|
1017 // no newline between 'return nnn' |
|
1018 print_single_space(); |
|
1019 } else if (last_type !== 'TK_END_EXPR') { |
|
1020 if ((last_type !== 'TK_START_EXPR' || token_text !== 'var') && last_text !== ':') { |
|
1021 // no need to force newline on 'var': for (var x = 0...) |
|
1022 if (token_text === 'if' && last_word === 'else' && last_text !== '{') { |
|
1023 // no newline for } else if { |
|
1024 print_single_space(); |
|
1025 } else { |
|
1026 flags.var_line = false; |
|
1027 flags.var_line_reindented = false; |
|
1028 print_newline(); |
|
1029 } |
|
1030 } |
|
1031 } else if (in_array(token_text, line_starters) && last_text !== ')') { |
|
1032 flags.var_line = false; |
|
1033 flags.var_line_reindented = false; |
|
1034 print_newline(); |
|
1035 } |
|
1036 } else if (is_array(flags.mode) && last_text === ',' && last_last_text === '}') { |
|
1037 print_newline(); // }, in lists get a newline treatment |
|
1038 } else if (prefix === 'SPACE') { |
|
1039 print_single_space(); |
|
1040 } |
|
1041 print_token(); |
|
1042 last_word = token_text; |
|
1043 |
|
1044 if (token_text === 'var') { |
|
1045 flags.var_line = true; |
|
1046 flags.var_line_reindented = false; |
|
1047 flags.var_line_tainted = false; |
|
1048 } |
|
1049 |
|
1050 if (token_text === 'if') { |
|
1051 flags.if_line = true; |
|
1052 } |
|
1053 if (token_text === 'else') { |
|
1054 flags.if_line = false; |
|
1055 } |
|
1056 |
|
1057 break; |
|
1058 |
|
1059 case 'TK_SEMICOLON': |
|
1060 |
|
1061 print_token(); |
|
1062 flags.var_line = false; |
|
1063 flags.var_line_reindented = false; |
|
1064 if (flags.mode === 'OBJECT') { |
|
1065 // OBJECT mode is weird and doesn't get reset too well. |
|
1066 flags.mode = 'BLOCK'; |
|
1067 } |
|
1068 break; |
|
1069 |
|
1070 case 'TK_STRING': |
|
1071 |
|
1072 if (last_type === 'TK_END_EXPR' && in_array(flags.previous_mode, ['(COND-EXPRESSION)', '(FOR-EXPRESSION)'])) { |
|
1073 print_single_space(); |
|
1074 } else if (last_type === 'TK_COMMENT' || last_type === 'TK_STRING' || last_type === 'TK_START_BLOCK' || last_type === 'TK_END_BLOCK' || last_type === 'TK_SEMICOLON') { |
|
1075 print_newline(); |
|
1076 } else if (last_type === 'TK_WORD') { |
|
1077 print_single_space(); |
|
1078 } |
|
1079 print_token(); |
|
1080 break; |
|
1081 |
|
1082 case 'TK_EQUALS': |
|
1083 if (flags.var_line) { |
|
1084 // just got an '=' in a var-line, different formatting/line-breaking, etc will now be done |
|
1085 flags.var_line_tainted = true; |
|
1086 } |
|
1087 print_single_space(); |
|
1088 print_token(); |
|
1089 print_single_space(); |
|
1090 break; |
|
1091 |
|
1092 case 'TK_COMMA': |
|
1093 if (flags.var_line) { |
|
1094 if (is_expression(flags.mode) || last_type === 'TK_END_BLOCK' ) { |
|
1095 // do not break on comma, for(var a = 1, b = 2) |
|
1096 flags.var_line_tainted = false; |
|
1097 } |
|
1098 if (flags.var_line_tainted) { |
|
1099 print_token(); |
|
1100 flags.var_line_reindented = true; |
|
1101 flags.var_line_tainted = false; |
|
1102 print_newline(); |
|
1103 break; |
|
1104 } else { |
|
1105 flags.var_line_tainted = false; |
|
1106 } |
|
1107 |
|
1108 print_token(); |
|
1109 print_single_space(); |
|
1110 break; |
|
1111 } |
|
1112 |
|
1113 if (last_type === 'TK_COMMENT') { |
|
1114 print_newline(); |
|
1115 } |
|
1116 |
|
1117 if (last_type === 'TK_END_BLOCK' && flags.mode !== "(EXPRESSION)") { |
|
1118 print_token(); |
|
1119 if (flags.mode === 'OBJECT' && last_text === '}') { |
|
1120 print_newline(); |
|
1121 } else { |
|
1122 print_single_space(); |
|
1123 } |
|
1124 } else { |
|
1125 if (flags.mode === 'OBJECT') { |
|
1126 print_token(); |
|
1127 print_newline(); |
|
1128 } else { |
|
1129 // EXPR or DO_BLOCK |
|
1130 print_token(); |
|
1131 print_single_space(); |
|
1132 } |
|
1133 } |
|
1134 break; |
|
1135 |
|
1136 |
|
1137 case 'TK_OPERATOR': |
|
1138 |
|
1139 var space_before = true; |
|
1140 var space_after = true; |
|
1141 |
|
1142 if (is_special_word(last_text)) { |
|
1143 // "return" had a special handling in TK_WORD. Now we need to return the favor |
|
1144 print_single_space(); |
|
1145 print_token(); |
|
1146 break; |
|
1147 } |
|
1148 |
|
1149 // hack for actionscript's import .*; |
|
1150 if (token_text === '*' && last_type === 'TK_UNKNOWN' && !last_last_text.match(/^\d+$/)) { |
|
1151 print_token(); |
|
1152 break; |
|
1153 } |
|
1154 |
|
1155 if (token_text === ':' && flags.in_case) { |
|
1156 if (opt_indent_case) { |
|
1157 flags.case_body = true; |
|
1158 } |
|
1159 print_token(); // colon really asks for separate treatment |
|
1160 print_newline(); |
|
1161 flags.in_case = false; |
|
1162 break; |
|
1163 } |
|
1164 |
|
1165 if (token_text === '::') { |
|
1166 // no spaces around exotic namespacing syntax operator |
|
1167 print_token(); |
|
1168 break; |
|
1169 } |
|
1170 |
|
1171 if (in_array(token_text, ['--', '++', '!']) || (in_array(token_text, ['-', '+']) && (in_array(last_type, ['TK_START_BLOCK', 'TK_START_EXPR', 'TK_EQUALS', 'TK_OPERATOR']) || in_array(last_text, line_starters)))) { |
|
1172 // unary operators (and binary +/- pretending to be unary) special cases |
|
1173 |
|
1174 space_before = false; |
|
1175 space_after = false; |
|
1176 |
|
1177 if (last_text === ';' && is_expression(flags.mode)) { |
|
1178 // for (;; ++i) |
|
1179 // ^^^ |
|
1180 space_before = true; |
|
1181 } |
|
1182 if (last_type === 'TK_WORD' && in_array(last_text, line_starters)) { |
|
1183 space_before = true; |
|
1184 } |
|
1185 |
|
1186 if (flags.mode === 'BLOCK' && (last_text === '{' || last_text === ';')) { |
|
1187 // { foo; --i } |
|
1188 // foo(); --bar; |
|
1189 print_newline(); |
|
1190 } |
|
1191 } else if (token_text === '.') { |
|
1192 // decimal digits or object.property |
|
1193 space_before = false; |
|
1194 |
|
1195 } else if (token_text === ':') { |
|
1196 if (flags.ternary_depth === 0) { |
|
1197 if (flags.mode === 'BLOCK') { |
|
1198 flags.mode = 'OBJECT'; |
|
1199 } |
|
1200 space_before = false; |
|
1201 } else { |
|
1202 flags.ternary_depth -= 1; |
|
1203 } |
|
1204 } else if (token_text === '?') { |
|
1205 flags.ternary_depth += 1; |
|
1206 } |
|
1207 if (space_before) { |
|
1208 print_single_space(); |
|
1209 } |
|
1210 |
|
1211 print_token(); |
|
1212 |
|
1213 if (space_after) { |
|
1214 print_single_space(); |
|
1215 } |
|
1216 |
|
1217 break; |
|
1218 |
|
1219 case 'TK_BLOCK_COMMENT': |
|
1220 |
|
1221 var lines = split_newlines(token_text); |
|
1222 var j; // iterator for this case |
|
1223 |
|
1224 if (all_lines_start_with(lines.slice(1), '*')) { |
|
1225 // javadoc: reformat and reindent |
|
1226 print_newline(); |
|
1227 output.push(lines[0]); |
|
1228 for (j = 1; j < lines.length; j++) { |
|
1229 print_newline(); |
|
1230 output.push(' '); |
|
1231 output.push(trim(lines[j])); |
|
1232 } |
|
1233 |
|
1234 } else { |
|
1235 |
|
1236 // simple block comment: leave intact |
|
1237 if (lines.length > 1) { |
|
1238 // multiline comment block starts with a new line |
|
1239 print_newline(); |
|
1240 } else { |
|
1241 // single-line /* comment */ stays where it is |
|
1242 if (last_type === 'TK_END_BLOCK') { |
|
1243 print_newline(); |
|
1244 } else { |
|
1245 print_single_space(); |
|
1246 } |
|
1247 |
|
1248 } |
|
1249 |
|
1250 for (j = 0; j < lines.length; j++) { |
|
1251 output.push(lines[j]); |
|
1252 output.push("\n"); |
|
1253 } |
|
1254 |
|
1255 } |
|
1256 if (look_up('\n') !== '\n') { |
|
1257 print_newline(); |
|
1258 } |
|
1259 break; |
|
1260 |
|
1261 case 'TK_INLINE_COMMENT': |
|
1262 print_single_space(); |
|
1263 print_token(); |
|
1264 if (is_expression(flags.mode)) { |
|
1265 print_single_space(); |
|
1266 } else { |
|
1267 force_newline(); |
|
1268 } |
|
1269 break; |
|
1270 |
|
1271 case 'TK_COMMENT': |
|
1272 |
|
1273 if (last_text === ',' && !wanted_newline) { |
|
1274 trim_output(true); |
|
1275 } |
|
1276 if (last_type !== 'TK_COMMENT') { |
|
1277 if (wanted_newline) { |
|
1278 print_newline(); |
|
1279 } else { |
|
1280 print_single_space(); |
|
1281 } |
|
1282 } |
|
1283 print_token(); |
|
1284 print_newline(); |
|
1285 break; |
|
1286 |
|
1287 case 'TK_UNKNOWN': |
|
1288 if (is_special_word(last_text)) { |
|
1289 print_single_space(); |
|
1290 } |
|
1291 print_token(); |
|
1292 break; |
|
1293 } |
|
1294 |
|
1295 last_last_text = last_text; |
|
1296 last_type = token_type; |
|
1297 last_text = token_text; |
|
1298 } |
|
1299 |
|
1300 var sweet_code = preindent_string + output.join('').replace(/[\r\n ]+$/, ''); |
|
1301 return sweet_code; |
|
1302 |
|
1303 } |