aboutsummaryrefslogtreecommitdiffstats
path: root/mitmproxy/contentviews
diff options
context:
space:
mode:
authorMaximilian Hils <git@maximilianhils.com>2017-08-24 18:59:56 +0200
committerMaximilian Hils <git@maximilianhils.com>2017-08-24 20:39:21 +0200
commit8eb65585707204ff43c63603fe3b5093a6facdfc (patch)
treeee96aad467f4b5ab67726faba8edf7975baa9bcc /mitmproxy/contentviews
parent72ac89f666d0093f523998eaa2a5ff9a41a26ff7 (diff)
downloadmitmproxy-8eb65585707204ff43c63603fe3b5093a6facdfc.tar.gz
mitmproxy-8eb65585707204ff43c63603fe3b5093a6facdfc.tar.bz2
mitmproxy-8eb65585707204ff43c63603fe3b5093a6facdfc.zip
add new, faster css prettifier :tada:
Diffstat (limited to 'mitmproxy/contentviews')
-rw-r--r--mitmproxy/contentviews/css.py67
1 files changed, 56 insertions, 11 deletions
diff --git a/mitmproxy/contentviews/css.py b/mitmproxy/contentviews/css.py
index 353a3257..8fa09ed3 100644
--- a/mitmproxy/contentviews/css.py
+++ b/mitmproxy/contentviews/css.py
@@ -1,8 +1,51 @@
-import logging
+import re
+import time
-import cssutils
+from mitmproxy.contentviews import base
+from mitmproxy.utils import strutils
-from . import base
+"""
+A custom CSS prettifier. Compared to other prettifiers, its main features are:
+
+- Implemented in pure Python.
+- Modifies whitespace only.
+- Works with any input.
+- Considerably faster than e.g. cssutils.
+"""
+
+CSS_SPECIAL_AREAS = (
+ ("'", strutils.NO_ESCAPE + "'"),
+ ('"', strutils.NO_ESCAPE + '"'),
+ (r"/\*", r"\*/"),
+ ("//", "$")
+)
+CSS_SPECIAL_CHARS = "{};:"
+
+
+def beautify(data: str, indent: str = " "):
+ """Beautify a string containing CSS code"""
+ data = strutils.escape_special_areas(
+ data.strip(),
+ CSS_SPECIAL_AREAS,
+ CSS_SPECIAL_CHARS,
+ )
+
+ # Add newlines
+ data = re.sub(r"\s*;\s*", ";\n", data)
+ data = re.sub(r"\s*{\s*", " {\n", data)
+ data = re.sub(r"\s*}\s*", "\n}\n\n", data)
+
+ # Fix incorrect ":" placement
+ data = re.sub(r"\s*:\s*(?=[^{]+})", ": ", data)
+ # Fix no space after ","
+ data = re.sub(r"\s*,\s*", ", ", data)
+
+ # indent
+ data = re.sub("\n[ \t]+", "\n", data)
+ data = re.sub("\n(?![}\n])(?=[^{]*})", "\n" + indent, data)
+
+ data = strutils.unescape_special_areas(data)
+ return data.rstrip("\n") + "\n"
class ViewCSS(base.View):
@@ -13,13 +56,15 @@ class ViewCSS(base.View):
]
def __call__(self, data, **metadata):
- cssutils.log.setLevel(logging.CRITICAL)
- cssutils.ser.prefs.keepComments = True
- cssutils.ser.prefs.omitLastSemicolon = False
- cssutils.ser.prefs.indentClosingBrace = False
- cssutils.ser.prefs.validOnly = False
+ data = data.decode("utf8", "surrogateescape")
+ beautified = beautify(data)
+ return "CSS", base.format_text(beautified)
- sheet = cssutils.parseString(data)
- beautified = sheet.cssText
- return "CSS", base.format_text(beautified)
+if __name__ == "__main__": # pragma: no cover
+ with open("../tools/web/static/vendor.css") as f:
+ data = f.read()
+
+ t = time.time()
+ x = beautify(data)
+ print("Beautifying vendor.css took {:.2}s".format(time.time() - t))