Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(17)

Side by Side Diff: Source/build/scripts/rjsmin.py

Issue 252633006: Compact JS resource better by using rjsmin. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 #!/usr/bin/env python 1 #!/usr/bin/env python
2 # -*- coding: ascii -*-
3 # 2 #
4 # Copyright 2011 - 2013 3 # Copyright 2011 - 2013
5 # Andr\xe9 Malo or his licensors, as applicable 4 # Andr\xe9 Malo or his licensors, as applicable
6 # 5 #
7 # Licensed under the Apache License, Version 2.0 (the "License"); 6 # Licensed under the Apache License, Version 2.0 (the "License");
8 # you may not use this file except in compliance with the License. 7 # you may not use this file except in compliance with the License.
9 # You may obtain a copy of the License at 8 # You may obtain a copy of the License at
10 # 9 #
11 # http://www.apache.org/licenses/LICENSE-2.0 10 # http://www.apache.org/licenses/LICENSE-2.0
12 # 11 #
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
84 if not python_only: 83 if not python_only:
85 try: 84 try:
86 import _rjsmin 85 import _rjsmin
87 except ImportError: 86 except ImportError:
88 pass 87 pass
89 else: 88 else:
90 return _rjsmin.jsmin 89 return _rjsmin.jsmin
91 try: 90 try:
92 xrange 91 xrange
93 except NameError: 92 except NameError:
94 xrange = range # pylint: disable = W0622 93 xrange = range # pylint: disable = W0622
Daniel Bratell 2014/04/25 09:49:39 The changes I've done in this file is just to get
95 94
96 space_chars = r'[\000-\011\013\014\016-\040]' 95 space_chars = r'[\000-\011\013\014\016-\040]'
97 96
98 line_comment = r'(?://[^\r\n]*)' 97 line_comment = r'(?://[^\r\n]*)'
99 space_comment = r'(?:/\*[^*]*\*+(?:[^/*][^*]*\*+)*/)' 98 space_comment = r'(?:/\*[^*]*\*+(?:[^/*][^*]*\*+)*/)'
100 string1 = \ 99 string1 = \
101 r'(?:\047[^\047\\\r\n]*(?:\\(?:[^\r\n]|\r?\n|\r)[^\047\\\r\n]*)*\047)' 100 r'(?:\047[^\047\\\r\n]*(?:\\(?:[^\r\n]|\r?\n|\r)[^\047\\\r\n]*)*\047)'
102 string2 = r'(?:"[^"\\\r\n]*(?:\\(?:[^\r\n]|\r?\n|\r)[^"\\\r\n]*)*")' 101 string2 = r'(?:"[^"\\\r\n]*(?:\\(?:[^\r\n]|\r?\n|\r)[^"\\\r\n]*)*")'
103 strings = r'(?:%s|%s)' % (string1, string2) 102 strings = r'(?:%s|%s)' % (string1, string2)
104 103
105 charclass = r'(?:\[[^\\\]\r\n]*(?:\\[^\r\n][^\\\]\r\n]*)*\])' 104 charclass = r'(?:\[[^\\\]\r\n]*(?:\\[^\r\n][^\\\]\r\n]*)*\])'
106 nospecial = r'[^/\\\[\r\n]' 105 nospecial = r'[^/\\\[\r\n]'
107 regex = r'(?:/(?![\r\n/*])%s*(?:(?:\\[^\r\n]|%s)%s*)*/)' % ( 106 regex = r'(?:/(?![\r\n/*])%s*(?:(?:\\[^\r\n]|%s)%s*)*/)' % (
108 nospecial, charclass, nospecial 107 nospecial, charclass, nospecial)
109 )
110 space = r'(?:%s|%s)' % (space_chars, space_comment) 108 space = r'(?:%s|%s)' % (space_chars, space_comment)
111 newline = r'(?:%s?[\r\n])' % line_comment 109 newline = r'(?:%s?[\r\n])' % line_comment
112 110
113 def fix_charclass(result): 111 def fix_charclass(result):
114 """ Fixup string of chars to fit into a regex char class """ 112 """ Fixup string of chars to fit into a regex char class """
115 pos = result.find('-') 113 pos = result.find('-')
116 if pos >= 0: 114 if pos >= 0:
117 result = r'%s%s-' % (result[:pos], result[pos + 1:]) 115 result = r'%s%s-' % (result[:pos], result[pos + 1:])
118 116
119 def sequentize(string): 117 def sequentize(string):
120 """ 118 """
121 Notate consecutive characters as sequence 119 Notate consecutive characters as sequence
122 120
123 (1-4 instead of 1234) 121 (1-4 instead of 1234)
124 """ 122 """
125 first, last, result = None, None, [] 123 first, last, result = None, None, []
126 for char in map(ord, string): 124 for char in map(ord, string):
127 if last is None: 125 if last is None:
128 first = last = char 126 first = last = char
129 elif last + 1 == char: 127 elif last + 1 == char:
130 last = char 128 last = char
131 else: 129 else:
132 result.append((first, last)) 130 result.append((first, last))
133 first = last = char 131 first = last = char
134 if last is not None: 132 if last is not None:
135 result.append((first, last)) 133 result.append((first, last))
136 return ''.join(['%s%s%s' % ( 134 return ''.join(['%s%s%s' % (
137 chr(first), 135 chr(first),
138 last > first + 1 and '-' or '', 136 last > first + 1 and '-' or '',
139 last != first and chr(last) or '' 137 last != first and chr(last) or '') for first, last in result])
140 ) for first, last in result])
141 138
142 return _re.sub(r'([\000-\040\047])', # for better portability 139 return _re.sub(r'([\000-\040\047])', # for better portability
143 lambda m: '\\%03o' % ord(m.group(1)), (sequentize(result) 140 lambda m: '\\%03o' % ord(m.group(1)), (sequentize(result)
144 .replace('\\', '\\\\') 141 .replace('\\', '\\\\')
145 .replace('[', '\\[') 142 .replace('[', '\\[')
146 .replace(']', '\\]') 143 .replace(']', '\\]')))
147 )
148 )
149 144
150 def id_literal_(what): 145 def id_literal_(what):
151 """ Make id_literal like char class """ 146 """ Make id_literal like char class """
152 match = _re.compile(what).match 147 match = _re.compile(what).match
153 result = ''.join([ 148 result = ''.join([chr(c) for c in xrange(127) if not match(chr(c))])
154 chr(c) for c in xrange(127) if not match(chr(c))
155 ])
156 return '[^%s]' % fix_charclass(result) 149 return '[^%s]' % fix_charclass(result)
157 150
158 def not_id_literal_(keep): 151 def not_id_literal_(keep):
159 """ Make negated id_literal like char class """ 152 """ Make negated id_literal like char class """
160 match = _re.compile(id_literal_(keep)).match 153 match = _re.compile(id_literal_(keep)).match
161 result = ''.join([ 154 result = ''.join([chr(c) for c in xrange(127) if not match(chr(c))])
162 chr(c) for c in xrange(127) if not match(chr(c))
163 ])
164 return r'[%s]' % fix_charclass(result) 155 return r'[%s]' % fix_charclass(result)
165 156
166 not_id_literal = not_id_literal_(r'[a-zA-Z0-9_$]') 157 not_id_literal = not_id_literal_(r'[a-zA-Z0-9_$]')
167 preregex1 = r'[(,=:\[!&|?{};\r\n]' 158 preregex1 = r'[(,=:\[!&|?{};\r\n]'
168 preregex2 = r'%(not_id_literal)sreturn' % locals() 159 preregex2 = r'%(not_id_literal)sreturn' % locals()
169 160
170 id_literal = id_literal_(r'[a-zA-Z0-9_$]') 161 id_literal = id_literal_(r'[a-zA-Z0-9_$]')
171 id_literal_open = id_literal_(r'[a-zA-Z0-9_${\[(!+-]') 162 id_literal_open = id_literal_(r'[a-zA-Z0-9_${\[(!+-]')
172 id_literal_close = id_literal_(r'[a-zA-Z0-9_$}\])"\047+-]') 163 id_literal_close = id_literal_(r'[a-zA-Z0-9_$}\])"\047+-]')
173 164
174 dull = r'[^\047"/\000-\040]' 165 dull = r'[^\047"/\000-\040]'
175 166
176 space_sub = _re.compile(( 167 space_sub = _re.compile((
177 r'(%(dull)s+)' 168 r'(%(dull)s+)'
178 r'|(%(strings)s%(dull)s*)' 169 r'|(%(strings)s%(dull)s*)'
179 r'|(?<=%(preregex1)s)' 170 r'|(?<=%(preregex1)s)'
180 r'%(space)s*(?:%(newline)s%(space)s*)*' 171 r'%(space)s*(?:%(newline)s%(space)s*)*'
181 r'(%(regex)s%(dull)s*)' 172 r'(%(regex)s%(dull)s*)'
182 r'|(?<=%(preregex2)s)' 173 r'|(?<=%(preregex2)s)'
183 r'%(space)s*(?:%(newline)s%(space)s)*' 174 r'%(space)s*(?:%(newline)s%(space)s)*'
184 r'(%(regex)s%(dull)s*)' 175 r'(%(regex)s%(dull)s*)'
185 r'|(?<=%(id_literal_close)s)' 176 r'|(?<=%(id_literal_close)s)'
186 r'%(space)s*(?:(%(newline)s)%(space)s*)+' 177 r'%(space)s*(?:(%(newline)s)%(space)s*)+'
187 r'(?=%(id_literal_open)s)' 178 r'(?=%(id_literal_open)s)'
188 r'|(?<=%(id_literal)s)(%(space)s)+(?=%(id_literal)s)' 179 r'|(?<=%(id_literal)s)(%(space)s)+(?=%(id_literal)s)'
189 r'|(?<=\+)(%(space)s)+(?=\+)' 180 r'|(?<=\+)(%(space)s)+(?=\+)'
190 r'|(?<=-)(%(space)s)+(?=-)' 181 r'|(?<=-)(%(space)s)+(?=-)'
191 r'|%(space)s+' 182 r'|%(space)s+'
192 r'|(?:%(newline)s%(space)s*)+' 183 r'|(?:%(newline)s%(space)s*)+') % locals()).sub
193 ) % locals()).sub
194 #print space_sub.__self__.pattern 184 #print space_sub.__self__.pattern
195 185
196 def space_subber(match): 186 def space_subber(match):
197 """ Substitution callback """ 187 """ Substitution callback """
198 # pylint: disable = C0321, R0911 188 # pylint: disable = C0321, R0911
199 groups = match.groups() 189 groups = match.groups()
200 if groups[0]: return groups[0] 190 if groups[0]:
201 elif groups[1]: return groups[1] 191 return groups[0]
202 elif groups[2]: return groups[2] 192 elif groups[1]:
203 elif groups[3]: return groups[3] 193 return groups[1]
204 elif groups[4]: return '\n' 194 elif groups[2]:
205 elif groups[5] or groups[6] or groups[7]: return ' ' 195 return groups[2]
206 else: return '' 196 elif groups[3]:
197 return groups[3]
198 elif groups[4]:
199 return '\n'
200 elif groups[5] or groups[6] or groups[7]:
201 return ' '
202 else:
203 return ''
207 204
208 def jsmin(script): # pylint: disable = W0621 205 def jsmin(script): # pylint: disable = W0621
209 r""" 206 r"""
210 Minify javascript based on `jsmin.c by Douglas Crockford`_\. 207 Minify javascript based on `jsmin.c by Douglas Crockford`_\.
211 208
212 Instead of parsing the stream char by char, it uses a regular 209 Instead of parsing the stream char by char, it uses a regular
213 expression approach which minifies the whole script with one big 210 expression approach which minifies the whole script with one big
214 substitution regex. 211 substitution regex.
215 212
216 .. _jsmin.c by Douglas Crockford: 213 .. _jsmin.c by Douglas Crockford:
217 http://www.crockford.com/javascript/jsmin.c 214 http://www.crockford.com/javascript/jsmin.c
218 215
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
257 groups = match.groups() 254 groups = match.groups()
258 return ( 255 return (
259 groups[0] or 256 groups[0] or
260 groups[1] or 257 groups[1] or
261 groups[2] or 258 groups[2] or
262 groups[3] or 259 groups[3] or
263 (groups[4] and '\n') or 260 (groups[4] and '\n') or
264 (groups[5] and ' ') or 261 (groups[5] and ' ') or
265 (groups[6] and ' ') or 262 (groups[6] and ' ') or
266 (groups[7] and ' ') or 263 (groups[7] and ' ') or
267 '' 264 '')
268 )
269 265
270 return _re.sub( 266 return _re.sub(
271 r'([^\047"/\000-\040]+)|((?:(?:\047[^\047\\\r\n]*(?:\\(?:[^\r\n]|\r?' 267 r'([^\047"/\000-\040]+)|((?:(?:\047[^\047\\\r\n]*(?:\\(?:[^\r\n]|\r?'
272 r'\n|\r)[^\047\\\r\n]*)*\047)|(?:"[^"\\\r\n]*(?:\\(?:[^\r\n]|\r?\n|' 268 r'\n|\r)[^\047\\\r\n]*)*\047)|(?:"[^"\\\r\n]*(?:\\(?:[^\r\n]|\r?\n|'
273 r'\r)[^"\\\r\n]*)*"))[^\047"/\000-\040]*)|(?<=[(,=:\[!&|?{};\r\n])(?' 269 r'\r)[^"\\\r\n]*)*"))[^\047"/\000-\040]*)|(?<=[(,=:\[!&|?{};\r\n])(?'
274 r':[\000-\011\013\014\016-\040]|(?:/\*[^*]*\*+(?:[^/*][^*]*\*+)*/))*' 270 r':[\000-\011\013\014\016-\040]|(?:/\*[^*]*\*+(?:[^/*][^*]*\*+)*/))*'
275 r'(?:(?:(?://[^\r\n]*)?[\r\n])(?:[\000-\011\013\014\016-\040]|(?:/\*' 271 r'(?:(?:(?://[^\r\n]*)?[\r\n])(?:[\000-\011\013\014\016-\040]|(?:/\*'
276 r'[^*]*\*+(?:[^/*][^*]*\*+)*/))*)*((?:/(?![\r\n/*])[^/\\\[\r\n]*(?:(' 272 r'[^*]*\*+(?:[^/*][^*]*\*+)*/))*)*((?:/(?![\r\n/*])[^/\\\[\r\n]*(?:('
277 r'?:\\[^\r\n]|(?:\[[^\\\]\r\n]*(?:\\[^\r\n][^\\\]\r\n]*)*\]))[^/\\\[' 273 r'?:\\[^\r\n]|(?:\[[^\\\]\r\n]*(?:\\[^\r\n][^\\\]\r\n]*)*\]))[^/\\\['
278 r'\r\n]*)*/)[^\047"/\000-\040]*)|(?<=[\000-#%-,./:-@\[-^`{-~-]return' 274 r'\r\n]*)*/)[^\047"/\000-\040]*)|(?<=[\000-#%-,./:-@\[-^`{-~-]return'
279 r')(?:[\000-\011\013\014\016-\040]|(?:/\*[^*]*\*+(?:[^/*][^*]*\*+)*/' 275 r')(?:[\000-\011\013\014\016-\040]|(?:/\*[^*]*\*+(?:[^/*][^*]*\*+)*/'
280 r'))*(?:(?:(?://[^\r\n]*)?[\r\n])(?:[\000-\011\013\014\016-\040]|(?:' 276 r'))*(?:(?:(?://[^\r\n]*)?[\r\n])(?:[\000-\011\013\014\016-\040]|(?:'
281 r'/\*[^*]*\*+(?:[^/*][^*]*\*+)*/)))*((?:/(?![\r\n/*])[^/\\\[\r\n]*(?' 277 r'/\*[^*]*\*+(?:[^/*][^*]*\*+)*/)))*((?:/(?![\r\n/*])[^/\\\[\r\n]*(?'
282 r':(?:\\[^\r\n]|(?:\[[^\\\]\r\n]*(?:\\[^\r\n][^\\\]\r\n]*)*\]))[^/' 278 r':(?:\\[^\r\n]|(?:\[[^\\\]\r\n]*(?:\\[^\r\n][^\\\]\r\n]*)*\]))[^/'
283 r'\\\[\r\n]*)*/)[^\047"/\000-\040]*)|(?<=[^\000-!#%&(*,./:-@\[\\^`{|' 279 r'\\\[\r\n]*)*/)[^\047"/\000-\040]*)|(?<=[^\000-!#%&(*,./:-@\[\\^`{|'
284 r'~])(?:[\000-\011\013\014\016-\040]|(?:/\*[^*]*\*+(?:[^/*][^*]*\*+)' 280 r'~])(?:[\000-\011\013\014\016-\040]|(?:/\*[^*]*\*+(?:[^/*][^*]*\*+)'
285 r'*/))*(?:((?:(?://[^\r\n]*)?[\r\n]))(?:[\000-\011\013\014\016-\040]' 281 r'*/))*(?:((?:(?://[^\r\n]*)?[\r\n]))(?:[\000-\011\013\014\016-\040]'
286 r'|(?:/\*[^*]*\*+(?:[^/*][^*]*\*+)*/))*)+(?=[^\000-\040"#%-\047)*,./' 282 r'|(?:/\*[^*]*\*+(?:[^/*][^*]*\*+)*/))*)+(?=[^\000-\040"#%-\047)*,./'
287 r':-@\\-^`|-~])|(?<=[^\000-#%-,./:-@\[-^`{-~-])((?:[\000-\011\013\01' 283 r':-@\\-^`|-~])|(?<=[^\000-#%-,./:-@\[-^`{-~-])((?:[\000-\011\013\01'
288 r'4\016-\040]|(?:/\*[^*]*\*+(?:[^/*][^*]*\*+)*/)))+(?=[^\000-#%-,./:' 284 r'4\016-\040]|(?:/\*[^*]*\*+(?:[^/*][^*]*\*+)*/)))+(?=[^\000-#%-,./:'
289 r'-@\[-^`{-~-])|(?<=\+)((?:[\000-\011\013\014\016-\040]|(?:/\*[^*]*' 285 r'-@\[-^`{-~-])|(?<=\+)((?:[\000-\011\013\014\016-\040]|(?:/\*[^*]*'
290 r'\*+(?:[^/*][^*]*\*+)*/)))+(?=\+)|(?<=-)((?:[\000-\011\013\014\016-' 286 r'\*+(?:[^/*][^*]*\*+)*/)))+(?=\+)|(?<=-)((?:[\000-\011\013\014\016-'
291 r'\040]|(?:/\*[^*]*\*+(?:[^/*][^*]*\*+)*/)))+(?=-)|(?:[\000-\011\013' 287 r'\040]|(?:/\*[^*]*\*+(?:[^/*][^*]*\*+)*/)))+(?=-)|(?:[\000-\011\013'
292 r'\014\016-\040]|(?:/\*[^*]*\*+(?:[^/*][^*]*\*+)*/))+|(?:(?:(?://[^' 288 r'\014\016-\040]|(?:/\*[^*]*\*+(?:[^/*][^*]*\*+)*/))+|(?:(?:(?://[^'
293 r'\r\n]*)?[\r\n])(?:[\000-\011\013\014\016-\040]|(?:/\*[^*]*\*+(?:[^' 289 r'\r\n]*)?[\r\n])(?:[\000-\011\013\014\016-\040]|(?:/\*[^*]*\*+(?:[^'
294 r'/*][^*]*\*+)*/))*)+', subber, '\n%s\n' % script 290 r'/*][^*]*\*+)*/))*)+', subber, '\n%s\n' % script).strip()
295 ).strip()
296 291
297 292
298 if __name__ == '__main__': 293 if __name__ == '__main__':
299 import sys as _sys 294 import sys as _sys
300 _sys.stdout.write(jsmin(_sys.stdin.read())) 295 _sys.stdout.write(jsmin(_sys.stdin.read()))
OLDNEW
« no previous file with comments | « no previous file | Source/devtools/scripts/concatenate_js_files.py » ('j') | Source/web/scripts/make-file-arrays.py » ('J')

Powered by Google App Engine
This is Rietveld 408576698