]>
git.saurik.com Git - apple/javascriptcore.git/blob - inspector/scripts/jsmin.py
   1 # This code is original from jsmin by Douglas Crockford, it was translated to 
   2 # Python by Baruch Even. It was rewritten by Dave St.Germain for speed. 
   4 # The MIT License (MIT) 
   6 # Copyright (c) 2013 Dave St.Germain 
   8 # Permission is hereby granted, free of charge, to any person obtaining a copy 
   9 # of this software and associated documentation files (the "Software"), to deal 
  10 # in the Software without restriction, including without limitation the rights 
  11 # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 
  12 # copies of the Software, and to permit persons to whom the Software is 
  13 # furnished to do so, subject to the following conditions: 
  15 # The above copyright notice and this permission notice shall be included in 
  16 # all copies or substantial portions of the Software. 
  18 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
  19 # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
  20 # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 
  21 # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
  22 # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 
  23 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 
  28 is_3 
= sys
.version_info 
>= (3, 0) 
  39 __all__ 
= ['jsmin', 'JavascriptMinify'] 
  45     returns a minified version of the javascript string 
  48         if cStringIO 
and not isinstance(js
, unicode): 
  49             # strings can use cStringIO for a 3x performance 
  50             # improvement, but unicode (in python2) cannot 
  51             klass 
= cStringIO
.StringIO
 
  53             klass 
= StringIO
.StringIO
 
  58     JavascriptMinify(ins
, outs
).minify() 
  59     return outs
.getvalue() 
  62 class JavascriptMinify(object): 
  64     Minify an input stream of javascript, writing 
  68     def __init__(self
, instream
=None, outstream
=None): 
  72     def minify(self
, instream
=None, outstream
=None): 
  73         if instream 
and outstream
: 
  74             self
.ins
, self
.outs 
= instream
, outstream
 
  76         self
.is_return 
= False 
  80             # all of this is to support literal regular expressions. 
  83                 self
.return_buf 
+= char
 
  84                 self
.is_return 
= self
.return_buf 
== 'return' 
  91         space_strings 
= "abcdefghijklmnopqrstuvwxyz"\
 
  92         "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_$\\" 
  93         starters
, enders 
= '{[(+-', '}])+-"\'' 
  94         newlinestart_strings 
= starters 
+ space_strings
 
  95         newlineend_strings 
= enders 
+ space_strings
 
  98         escape_slash_count 
= 0 
  99         doing_single_comment 
= False 
 100         previous_before_comment 
= '' 
 101         doing_multi_comment 
= False 
 108             escape_slash_count 
+= 1 
 112                 doing_single_comment 
= True 
 114                 doing_multi_comment 
= True 
 121         elif previous 
>= '!': 
 122             if previous 
in "'\"": 
 125             previous_non_space 
= previous
 
 127             previous_non_space 
= ' ' 
 135                 if not (doing_single_comment 
or doing_multi_comment
)\
 
 136                     and last 
not in ('', '/'): 
 138                         write(''.join(quote_buf
)) 
 141             if doing_multi_comment
: 
 142                 if next1 
== '*' and next2 
== '/': 
 143                     doing_multi_comment 
= False 
 145             elif doing_single_comment
: 
 147                     doing_single_comment 
= False 
 148                     while next2 
in '\r\n': 
 152                     if previous_before_comment 
in ')}]': 
 154                     elif previous_before_comment 
in space_strings
: 
 157                 quote_buf
.append(next1
) 
 159                 if next1 
== in_quote
: 
 161                     for c 
in reversed(quote_buf
[:-1]): 
 166                     if numslashes 
% 2 == 0: 
 168                         write(''.join(quote_buf
)) 
 169             elif next1 
in '\r\n': 
 170                 if previous_non_space 
in newlineend_strings \
 
 171                     or previous_non_space 
> '~': 
 178                             if next2 
in newlinestart_strings \
 
 179                                 or next2 
> '~' or next2 
== '/': 
 182             elif next1 
< '!' and not in_re
: 
 183                 if (previous_non_space 
in space_strings \
 
 184                     or previous_non_space 
> '~') \
 
 185                     and (next2 
in space_strings 
or next2 
> '~'): 
 187                 elif previous_non_space 
in '-+' and next2 
== previous_non_space
: 
 188                     # protect against + ++ or - -- sequences 
 190                 elif self
.is_return 
and next2 
== '/': 
 191                     # returning a regex... 
 197                     if previous 
!= '\\' or (not escape_slash_count 
% 2) or next2 
in 'gimy': 
 201                     doing_single_comment 
= True 
 202                     previous_before_comment 
= previous_non_space
 
 204                     doing_multi_comment 
= True 
 209                     in_re 
= previous_non_space 
in '(,=:[?!&|' or self
.is_return  
# literal regular expression 
 220                 if not in_re 
and next1 
in "'\"": 
 228                 previous_non_space 
= previous
 
 231                 escape_slash_count 
+= 1 
 233                 escape_slash_count 
= 0 
 235 if __name__ 
== '__main__': 
 236     minifier 
= JavascriptMinify(sys
.stdin
, sys
.stdout
) 
 238     sys
.stdout
.write('\n')