| Index: Source/web/scripts/make-file-arrays.py
|
| diff --git a/Source/web/scripts/make-file-arrays.py b/Source/web/scripts/make-file-arrays.py
|
| index 21ee6fbd26ef2e05e97136c710aae8b1e0e10bdf..1cf0b535fe5d9cd712e132b3095942b5b6165c8e 100755
|
| --- a/Source/web/scripts/make-file-arrays.py
|
| +++ b/Source/web/scripts/make-file-arrays.py
|
| @@ -34,6 +34,8 @@ import re
|
| import sys
|
| from optparse import OptionParser
|
|
|
| +# Should be spam in the build log?
|
| +DEBUG_OUTPUT = False
|
|
|
| def make_variable_name_and_read(file_name):
|
| result = re.match(r'([\w\d_]+)\.([\w\d_]+)', os.path.basename(file_name))
|
| @@ -46,6 +48,76 @@ def make_variable_name_and_read(file_name):
|
| return variable_name, content
|
|
|
|
|
| +def is_identifier_char(c):
|
| + assert len(c) == 1
|
| + return c.isalnum() or c in "$_"
|
| +
|
| +
|
| +def strip_js_whitespace_not_in_strings(content):
|
| + """Removes whitespace we don't need in this javascript
|
| + program. Whitespace is relevant inside strings and regexps (not
|
| + supported) and sometimes new-lines are needed to trigger the
|
| + automatic semi-colon insertion.
|
| +
|
| + This is _slightly_ worse than Closure at stripping whitespace
|
| + but so close that there is no urgent reason to improve it."""
|
| +
|
| + out = ""
|
| +
|
| + quoted_char = False # When True the next char is to be output as is.
|
| + string_delimiter = None # When set we're inside a string.
|
| + lazy_space = False
|
| + lazy_new_line = False
|
| + for c in content:
|
| + if quoted_char:
|
| + quoted_char = False
|
| + out += c
|
| + elif string_delimiter:
|
| + out += c
|
| + if c == "\\":
|
| + quoted_char = True
|
| + elif c == string_delimiter:
|
| + string_delimiter = None
|
| + else:
|
| + if c == "\\":
|
| + quoted_char = True
|
| + elif c == '"' or c == "'":
|
| + string_delimiter = c
|
| +
|
| + if c in " \t\n\r\f":
|
| + lazy_space = True
|
| + if c == "\n":
|
| + lazy_new_line = True
|
| + else:
|
| + if lazy_space and out:
|
| + output_space = False
|
| + if is_identifier_char(out[-1]) and is_identifier_char(c):
|
| + # Will prevent "var i" -> "vari" or
|
| + # "function $" -> "function$"
|
| + output_space = True
|
| + elif out[-1] == c and c not in "{}()[]":
|
| + # Will prevent "a - -b" -> "a--b" or "a--\n-b" -> "a---b"
|
| + output_space = True
|
| + if output_space:
|
| + if lazy_new_line:
|
| + out += "\n"
|
| + else:
|
| + out += " "
|
| + lazy_space = False
|
| + lazy_new_line = False
|
| + out += c
|
| + return out
|
| +
|
| +# Quick self testing. If this fails, we better not proceed with the build.
|
| +assert strip_js_whitespace_not_in_strings(' var a = \' \\" \\" \' ;') == 'var a=\' \\" \\" \';'
|
| +
|
| +assert strip_js_whitespace_not_in_strings("a-- - \t--b") == "a-- - --b"
|
| +
|
| +assert strip_js_whitespace_not_in_strings("if (a == $) {\n}") == "if(a==$){}"
|
| +assert strip_js_whitespace_not_in_strings("var \n a") == "var\na"
|
| +assert strip_js_whitespace_not_in_strings("{ { a( (1+ 2) / 3);}\n} ") == "{{a((1+2)/3);}}"
|
| +assert strip_js_whitespace_not_in_strings(r" ' \' ' ") == r"' \' '"
|
| +
|
| def strip_whitespace_and_comments(file_name, content):
|
| result = re.match(r'.*\.([^.]+)', file_name)
|
| if not result:
|
| @@ -60,20 +132,28 @@ def strip_whitespace_and_comments(file_name, content):
|
| leading_space = re.compile(r'^[ \t]+', re.MULTILINE)
|
| trailing_space = re.compile(r'[ \t]+$', re.MULTILINE)
|
| empty_line = re.compile(r'\n+')
|
| + orig_content = content
|
| if extension == 'js':
|
| + content = orig_content
|
| content = multi_line_comment.sub('', content)
|
| content = single_line_comment.sub('', content)
|
| content = trailing_comment.sub(r'\1', content)
|
| - content = repeating_space.sub(' ', content)
|
| - content = leading_space.sub('', content)
|
| - content = trailing_space.sub('', content)
|
| - content = empty_line.sub('\n', content)
|
| + content = strip_js_whitespace_not_in_strings(content)
|
| + optimized_content_content = content
|
| + content = orig_content
|
| + if len(optimized_content_content) < len(content):
|
| + content = optimized_content_content
|
| elif extension == 'css':
|
| content = multi_line_comment.sub('', content)
|
| content = repeating_space.sub(' ', content)
|
| content = leading_space.sub('', content)
|
| content = trailing_space.sub('', content)
|
| content = empty_line.sub('\n', content)
|
| + if DEBUG_OUTPUT:
|
| + in_size = len(orig_content)
|
| + out_size = len(content)
|
| + if out_size < in_size:
|
| + print("%s: Compaction saved %.1f%% for a total of %d bytes." % (file_name, float(100 * (in_size - out_size)) / in_size, in_size - out_size))
|
| return content
|
|
|
|
|
| @@ -81,6 +161,10 @@ def process_file(file_name):
|
| variable_name, content = make_variable_name_and_read(file_name)
|
| content = strip_whitespace_and_comments(file_name, content)
|
| size = len(content)
|
| + if DEBUG_OUTPUT:
|
| + out_debug_name = file_name + ".generated"
|
| + with open(out_debug_name, "w") as out_debug_file:
|
| + out_debug_file.write(content)
|
| return variable_name, content
|
|
|
|
|
|
|