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

Unified Diff: Source/web/scripts/make-file-arrays.py

Issue 214003005: Compact JS resource better. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Created 6 years, 9 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698