Chromium Code Reviews| Index: third_party/WebKit/Source/build/scripts/minimize_css.py |
| diff --git a/third_party/WebKit/Source/build/scripts/minimize_css.py b/third_party/WebKit/Source/build/scripts/minimize_css.py |
| new file mode 100755 |
| index 0000000000000000000000000000000000000000..d62629e20f2a0524a33511c348d6dda5b59eb732 |
| --- /dev/null |
| +++ b/third_party/WebKit/Source/build/scripts/minimize_css.py |
| @@ -0,0 +1,113 @@ |
| +#!/usr/bin/env python |
| +# Copyright 2016 The Chromium Authors. All rights reserved. |
| +# Use of this source code is governed by a BSD-style license that can be |
| +# found in the LICENSE file. |
| + |
| +import os.path |
| +import re |
| +import sys |
| + |
| +import in_generator |
| + |
| + |
| +class CSSMinimizer(object): |
| + |
| + INITIAL = 0 |
| + MAYBE_COMMENT_START = 1 |
| + INSIDE_COMMENT = 2 |
| + MAYBE_COMMENT_END = 3 |
| + INSIDE_SINGLE_QUOTE = 4 |
| + INSIDE_DOUBLE_QUOTE = 5 |
| + |
| + WHITESPACE_PATTERN = re.compile(r"\s+", re.MULTILINE) |
| + WHITESPACE_PATTERN = re.compile(r"\s+", re.MULTILINE) |
|
esprehn
2016/06/27 05:17:31
You have this twice
kouhei (in TOK)
2016/06/27 05:39:22
Done.
|
| + OP_PADDING_PATTERN = re.compile(r";?\s*(?P<op>[\{\};])\s*", re.MULTILINE) |
| + |
| + def __init__(self): |
| + self._output = '' |
| + self._codeblock = '' |
| + |
| + def flush_codeblock(self): |
| + stripped = re.sub(self.WHITESPACE_PATTERN, ' ', self._codeblock) |
| + stripped = re.sub(self.OP_PADDING_PATTERN, r'\g<op>', stripped) |
| + self._output += stripped |
| + self._codeblock = '' |
| + |
| + def parse(self, content): |
| + state = self.INITIAL |
| + for c in content: |
| + if state == self.INITIAL: |
| + if c == '/': |
| + state = self.MAYBE_COMMENT_START |
| + elif c == '\'': |
| + self.flush_codeblock() |
| + self._output += c |
| + state = self.INSIDE_SINGLE_QUOTE |
| + elif c == '\"': |
| + self.flush_codeblock() |
| + self._output += c |
| + state = self.INSIDE_DOUBLE_QUOTE |
| + else: |
| + self._codeblock += c |
| + elif state == self.MAYBE_COMMENT_START: |
| + if c == '*': |
| + self.flush_codeblock() |
| + state = self.INSIDE_COMMENT |
| + else: |
| + self._codeblock += '/' + c |
| + state = self.INITIAL |
| + elif state == self.INSIDE_COMMENT: |
| + if c == '*': |
| + state = self.MAYBE_COMMENT_END |
| + else: |
| + pass |
| + elif state == self.MAYBE_COMMENT_END: |
| + if c == '/': |
| + state = self.INITIAL |
| + else: |
| + state = self.INSIDE_COMMENT |
| + elif state == self.INSIDE_SINGLE_QUOTE: |
| + if c == '\'': |
| + self._output += c |
| + state = self.INITIAL |
| + else: |
|
esprehn
2016/06/27 05:17:31
This is a lot of code to not have any tests...
kouhei (in TOK)
2016/06/27 05:39:22
Ack. I'll add test before commit.
kouhei (in TOK)
2016/07/05 05:11:09
Done.
|
| + self._output += c |
| + elif state == self.INSIDE_DOUBLE_QUOTE: |
| + if c == '"': |
| + self._output += c |
| + state = self.INITIAL |
| + else: |
| + self._output += c |
| + |
| + return self._output |
| + |
| + @property |
| + def output(self): |
| + return self._output |
| + |
| + @classmethod |
| + def minimize_css(cls, content): |
| + minimizer = CSSMinimizer() |
| + minimizer.parse(content) |
| + return minimizer.output |
| + |
| + |
| +class CSSMinimizerWriter(in_generator.GenericWriter): |
| + |
| + def __init__(self, in_file_paths): |
| + super(CSSMinimizerWriter, self).__init__(in_file_paths) |
| + |
| + self._outputs = {} |
| + for in_file_path in in_file_paths: |
| + out_path = os.path.basename(in_file_path) |
| + self._outputs[out_path] = lambda fp=in_file_path: self.generate_implementation(fp) |
| + |
| + def generate_implementation(self, in_file_path): |
| + content = '' |
| + with open(os.path.abspath(in_file_path)) as in_file: |
| + content = in_file.read() |
| + return CSSMinimizer.minimize_css(content) |
| + |
| + |
| +if __name__ == '__main__': |
| + in_generator.Maker(CSSMinimizerWriter).main(sys.argv) |