summaryrefslogtreecommitdiffstats
path: root/chromium/third_party/WebKit/Source/build/scripts/rjsmin.py
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/third_party/WebKit/Source/build/scripts/rjsmin.py')
-rwxr-xr-xchromium/third_party/WebKit/Source/build/scripts/rjsmin.py295
1 files changed, 295 insertions, 0 deletions
diff --git a/chromium/third_party/WebKit/Source/build/scripts/rjsmin.py b/chromium/third_party/WebKit/Source/build/scripts/rjsmin.py
new file mode 100755
index 00000000000..8357a6dcc10
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/build/scripts/rjsmin.py
@@ -0,0 +1,295 @@
+#!/usr/bin/env python
+#
+# Copyright 2011 - 2013
+# Andr\xe9 Malo or his licensors, as applicable
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+r"""
+=====================
+ Javascript Minifier
+=====================
+
+rJSmin is a javascript minifier written in python.
+
+The minifier is based on the semantics of `jsmin.c by Douglas Crockford`_\.
+
+The module is a re-implementation aiming for speed, so it can be used at
+runtime (rather than during a preprocessing step). Usually it produces the
+same results as the original ``jsmin.c``. It differs in the following ways:
+
+- there is no error detection: unterminated string, regex and comment
+ literals are treated as regular javascript code and minified as such.
+- Control characters inside string and regex literals are left untouched; they
+ are not converted to spaces (nor to \n)
+- Newline characters are not allowed inside string and regex literals, except
+ for line continuations in string literals (ECMA-5).
+- "return /regex/" is recognized correctly.
+- "+ +" and "- -" sequences are not collapsed to '++' or '--'
+- Newlines before ! operators are removed more sensibly
+- rJSmin does not handle streams, but only complete strings. (However, the
+ module provides a "streamy" interface).
+
+Since most parts of the logic are handled by the regex engine it's way
+faster than the original python port of ``jsmin.c`` by Baruch Even. The speed
+factor varies between about 6 and 55 depending on input and python version
+(it gets faster the more compressed the input already is). Compared to the
+speed-refactored python port by Dave St.Germain the performance gain is less
+dramatic but still between 1.2 and 7. See the docs/BENCHMARKS file for
+details.
+
+rjsmin.c is a reimplementation of rjsmin.py in C and speeds it up even more.
+
+Both python 2 and python 3 are supported.
+
+.. _jsmin.c by Douglas Crockford:
+ http://www.crockford.com/javascript/jsmin.c
+"""
+__author__ = "Andr\xe9 Malo"
+__author__ = getattr(__author__, 'decode', lambda x: __author__)('latin-1')
+__docformat__ = "restructuredtext en"
+__license__ = "Apache License, Version 2.0"
+__version__ = '1.0.7'
+__all__ = ['jsmin']
+
+import re as _re
+
+
+def _make_jsmin(python_only=False):
+ """
+ Generate JS minifier based on `jsmin.c by Douglas Crockford`_
+
+ .. _jsmin.c by Douglas Crockford:
+ http://www.crockford.com/javascript/jsmin.c
+
+ :Parameters:
+ `python_only` : ``bool``
+ Use only the python variant. If true, the c extension is not even
+ tried to be loaded.
+
+ :Return: Minifier
+ :Rtype: ``callable``
+ """
+ # pylint: disable = R0912, R0914, W0612
+ if not python_only:
+ try:
+ import _rjsmin
+ except ImportError:
+ pass
+ else:
+ return _rjsmin.jsmin
+ try:
+ xrange
+ except NameError:
+ xrange = range # pylint: disable = W0622
+
+ space_chars = r'[\000-\011\013\014\016-\040]'
+
+ line_comment = r'(?://[^\r\n]*)'
+ space_comment = r'(?:/\*[^*]*\*+(?:[^/*][^*]*\*+)*/)'
+ string1 = \
+ r'(?:\047[^\047\\\r\n]*(?:\\(?:[^\r\n]|\r?\n|\r)[^\047\\\r\n]*)*\047)'
+ string2 = r'(?:"[^"\\\r\n]*(?:\\(?:[^\r\n]|\r?\n|\r)[^"\\\r\n]*)*")'
+ strings = r'(?:%s|%s)' % (string1, string2)
+
+ charclass = r'(?:\[[^\\\]\r\n]*(?:\\[^\r\n][^\\\]\r\n]*)*\])'
+ nospecial = r'[^/\\\[\r\n]'
+ regex = r'(?:/(?![\r\n/*])%s*(?:(?:\\[^\r\n]|%s)%s*)*/)' % (
+ nospecial, charclass, nospecial)
+ space = r'(?:%s|%s)' % (space_chars, space_comment)
+ newline = r'(?:%s?[\r\n])' % line_comment
+
+ def fix_charclass(result):
+ """ Fixup string of chars to fit into a regex char class """
+ pos = result.find('-')
+ if pos >= 0:
+ result = r'%s%s-' % (result[:pos], result[pos + 1:])
+
+ def sequentize(string):
+ """
+ Notate consecutive characters as sequence
+
+ (1-4 instead of 1234)
+ """
+ first, last, result = None, None, []
+ for char in map(ord, string):
+ if last is None:
+ first = last = char
+ elif last + 1 == char:
+ last = char
+ else:
+ result.append((first, last))
+ first = last = char
+ if last is not None:
+ result.append((first, last))
+ return ''.join(['%s%s%s' % (
+ chr(first),
+ last > first + 1 and '-' or '',
+ last != first and chr(last) or '') for first, last in result])
+
+ return _re.sub(r'([\000-\040\047])', # for better portability
+ lambda m: '\\%03o' % ord(m.group(1)), (sequentize(result)
+ .replace('\\', '\\\\')
+ .replace('[', '\\[')
+ .replace(']', '\\]')))
+
+ def id_literal_(what):
+ """ Make id_literal like char class """
+ match = _re.compile(what).match
+ result = ''.join([chr(c) for c in xrange(127) if not match(chr(c))])
+ return '[^%s]' % fix_charclass(result)
+
+ def not_id_literal_(keep):
+ """ Make negated id_literal like char class """
+ match = _re.compile(id_literal_(keep)).match
+ result = ''.join([chr(c) for c in xrange(127) if not match(chr(c))])
+ return r'[%s]' % fix_charclass(result)
+
+ not_id_literal = not_id_literal_(r'[a-zA-Z0-9_$]')
+ preregex1 = r'[(,=:\[!&|?{};\r\n]'
+ preregex2 = r'%(not_id_literal)sreturn' % locals()
+
+ id_literal = id_literal_(r'[a-zA-Z0-9_$]')
+ id_literal_open = id_literal_(r'[a-zA-Z0-9_${\[(!+-]')
+ id_literal_close = id_literal_(r'[a-zA-Z0-9_$}\])"\047+-]')
+
+ dull = r'[^\047"/\000-\040]'
+
+ space_sub = _re.compile((
+ r'(%(dull)s+)'
+ r'|(%(strings)s%(dull)s*)'
+ r'|(?<=%(preregex1)s)'
+ r'%(space)s*(?:%(newline)s%(space)s*)*'
+ r'(%(regex)s%(dull)s*)'
+ r'|(?<=%(preregex2)s)'
+ r'%(space)s*(?:%(newline)s%(space)s)*'
+ r'(%(regex)s%(dull)s*)'
+ r'|(?<=%(id_literal_close)s)'
+ r'%(space)s*(?:(%(newline)s)%(space)s*)+'
+ r'(?=%(id_literal_open)s)'
+ r'|(?<=%(id_literal)s)(%(space)s)+(?=%(id_literal)s)'
+ r'|(?<=\+)(%(space)s)+(?=\+)'
+ r'|(?<=-)(%(space)s)+(?=-)'
+ r'|%(space)s+'
+ r'|(?:%(newline)s%(space)s*)+') % locals()).sub
+ #print space_sub.__self__.pattern
+
+ def space_subber(match):
+ """ Substitution callback """
+ # pylint: disable = C0321, R0911
+ groups = match.groups()
+ if groups[0]:
+ return groups[0]
+ elif groups[1]:
+ return groups[1]
+ elif groups[2]:
+ return groups[2]
+ elif groups[3]:
+ return groups[3]
+ elif groups[4]:
+ return '\n'
+ elif groups[5] or groups[6] or groups[7]:
+ return ' '
+ else:
+ return ''
+
+ def jsmin(script): # pylint: disable = W0621
+ r"""
+ Minify javascript based on `jsmin.c by Douglas Crockford`_\.
+
+ Instead of parsing the stream char by char, it uses a regular
+ expression approach which minifies the whole script with one big
+ substitution regex.
+
+ .. _jsmin.c by Douglas Crockford:
+ http://www.crockford.com/javascript/jsmin.c
+
+ :Parameters:
+ `script` : ``str``
+ Script to minify
+
+ :Return: Minified script
+ :Rtype: ``str``
+ """
+ return space_sub(space_subber, '\n%s\n' % script).strip()
+
+ return jsmin
+
+jsmin = _make_jsmin()
+
+
+def jsmin_for_posers(script):
+ r"""
+ Minify javascript based on `jsmin.c by Douglas Crockford`_\.
+
+ Instead of parsing the stream char by char, it uses a regular
+ expression approach which minifies the whole script with one big
+ substitution regex.
+
+ .. _jsmin.c by Douglas Crockford:
+ http://www.crockford.com/javascript/jsmin.c
+
+ :Warning: This function is the digest of a _make_jsmin() call. It just
+ utilizes the resulting regex. It's just for fun here and may
+ vanish any time. Use the `jsmin` function instead.
+
+ :Parameters:
+ `script` : ``str``
+ Script to minify
+
+ :Return: Minified script
+ :Rtype: ``str``
+ """
+ def subber(match):
+ """ Substitution callback """
+ groups = match.groups()
+ return (
+ groups[0] or
+ groups[1] or
+ groups[2] or
+ groups[3] or
+ (groups[4] and '\n') or
+ (groups[5] and ' ') or
+ (groups[6] and ' ') or
+ (groups[7] and ' ') or
+ '')
+
+ return _re.sub(
+ r'([^\047"/\000-\040]+)|((?:(?:\047[^\047\\\r\n]*(?:\\(?:[^\r\n]|\r?'
+ r'\n|\r)[^\047\\\r\n]*)*\047)|(?:"[^"\\\r\n]*(?:\\(?:[^\r\n]|\r?\n|'
+ r'\r)[^"\\\r\n]*)*"))[^\047"/\000-\040]*)|(?<=[(,=:\[!&|?{};\r\n])(?'
+ r':[\000-\011\013\014\016-\040]|(?:/\*[^*]*\*+(?:[^/*][^*]*\*+)*/))*'
+ r'(?:(?:(?://[^\r\n]*)?[\r\n])(?:[\000-\011\013\014\016-\040]|(?:/\*'
+ r'[^*]*\*+(?:[^/*][^*]*\*+)*/))*)*((?:/(?![\r\n/*])[^/\\\[\r\n]*(?:('
+ r'?:\\[^\r\n]|(?:\[[^\\\]\r\n]*(?:\\[^\r\n][^\\\]\r\n]*)*\]))[^/\\\['
+ r'\r\n]*)*/)[^\047"/\000-\040]*)|(?<=[\000-#%-,./:-@\[-^`{-~-]return'
+ r')(?:[\000-\011\013\014\016-\040]|(?:/\*[^*]*\*+(?:[^/*][^*]*\*+)*/'
+ r'))*(?:(?:(?://[^\r\n]*)?[\r\n])(?:[\000-\011\013\014\016-\040]|(?:'
+ r'/\*[^*]*\*+(?:[^/*][^*]*\*+)*/)))*((?:/(?![\r\n/*])[^/\\\[\r\n]*(?'
+ r':(?:\\[^\r\n]|(?:\[[^\\\]\r\n]*(?:\\[^\r\n][^\\\]\r\n]*)*\]))[^/'
+ r'\\\[\r\n]*)*/)[^\047"/\000-\040]*)|(?<=[^\000-!#%&(*,./:-@\[\\^`{|'
+ r'~])(?:[\000-\011\013\014\016-\040]|(?:/\*[^*]*\*+(?:[^/*][^*]*\*+)'
+ r'*/))*(?:((?:(?://[^\r\n]*)?[\r\n]))(?:[\000-\011\013\014\016-\040]'
+ r'|(?:/\*[^*]*\*+(?:[^/*][^*]*\*+)*/))*)+(?=[^\000-\040"#%-\047)*,./'
+ r':-@\\-^`|-~])|(?<=[^\000-#%-,./:-@\[-^`{-~-])((?:[\000-\011\013\01'
+ r'4\016-\040]|(?:/\*[^*]*\*+(?:[^/*][^*]*\*+)*/)))+(?=[^\000-#%-,./:'
+ r'-@\[-^`{-~-])|(?<=\+)((?:[\000-\011\013\014\016-\040]|(?:/\*[^*]*'
+ r'\*+(?:[^/*][^*]*\*+)*/)))+(?=\+)|(?<=-)((?:[\000-\011\013\014\016-'
+ r'\040]|(?:/\*[^*]*\*+(?:[^/*][^*]*\*+)*/)))+(?=-)|(?:[\000-\011\013'
+ r'\014\016-\040]|(?:/\*[^*]*\*+(?:[^/*][^*]*\*+)*/))+|(?:(?:(?://[^'
+ r'\r\n]*)?[\r\n])(?:[\000-\011\013\014\016-\040]|(?:/\*[^*]*\*+(?:[^'
+ r'/*][^*]*\*+)*/))*)+', subber, '\n%s\n' % script).strip()
+
+
+if __name__ == '__main__':
+ import sys as _sys
+ _sys.stdout.write(jsmin(_sys.stdin.read()))