From 8c72bdf7f022ac4164c6d33929bf66091f3feccf Mon Sep 17 00:00:00 2001 From: Peter Bengtsson Date: Mon, 10 Jul 2017 14:13:47 -0400 Subject: [PATCH 01/14] deal with duplicate media queries, fixes #46 --- mincss/processor.py | 2 +- tests/duplicate-media-queries.html | 12 ++++++++++++ tests/test_mincss.py | 13 +++++++++++++ 3 files changed, 26 insertions(+), 1 deletion(-) create mode 100644 tests/duplicate-media-queries.html diff --git a/mincss/processor.py b/mincss/processor.py index de4d924..d856496 100644 --- a/mincss/processor.py +++ b/mincss/processor.py @@ -389,7 +389,7 @@ def commentmatcher(match): for temp_key, old, __ in inner_improvements: assert old in content, old - content = content.replace(old, temp_key) + content = content.replace(old, temp_key, 1) _regex = re.compile('((.*?){(.*?)})', re.DOTALL | re.M) diff --git a/tests/duplicate-media-queries.html b/tests/duplicate-media-queries.html new file mode 100644 index 0000000..611662b --- /dev/null +++ b/tests/duplicate-media-queries.html @@ -0,0 +1,12 @@ + + + + + + +

Hello world

+ + diff --git a/tests/test_mincss.py b/tests/test_mincss.py index 99b8d77..ee462d3 100644 --- a/tests/test_mincss.py +++ b/tests/test_mincss.py @@ -355,3 +355,16 @@ def test_before_after(self): after = p.inlines[0].after ok_('ul li:after { content: "x"; }' not in after) ok_('ol li:before { content: "x"; }' in after) + + def test_duplicate_media_queries(self): + """if two media queries look exactly the same, it shouldn't fail. + + This is kinda hackish but it desperately tries to solve + https://github.com/peterbe/mincss/issues/46 + """ + html = os.path.join(HERE, 'duplicate-media-queries.html') + url = 'file://' + html + p = Processor() + p.process(url) + snippet = '@media screen and (min-width: 600px) {' + eq_(p.inlines[0].after.count(snippet), 2) From 72e0e5e936833315ed1013b92dd47fd486038e5d Mon Sep 17 00:00:00 2001 From: Peter Bengtsson Date: Mon, 10 Jul 2017 14:15:19 -0400 Subject: [PATCH 02/14] bump to version 0.11.3 --- mincss/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mincss/__init__.py b/mincss/__init__.py index 2b3823f..4ad2f68 100644 --- a/mincss/__init__.py +++ b/mincss/__init__.py @@ -1 +1 @@ -__version__ = '0.11.2' +__version__ = '0.11.3' From 2502bc4ff270cdf531a3351442fd091251cadbf2 Mon Sep 17 00:00:00 2001 From: Peter Bengtsson Date: Mon, 10 Jul 2017 14:25:14 -0400 Subject: [PATCH 03/14] Still a bit maintained --- README.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.rst b/README.rst index 7f33bf0..33918ff 100644 --- a/README.rst +++ b/README.rst @@ -8,7 +8,7 @@ mincss Clears the junk out of your CSS by finding out which selectors are actually not used in your HTML. -By Peter Bengtsson, 2012-2015 +By Peter Bengtsson, 2012-2017 Tested in Python 2.7, 3.3 and 3.4 From 9490c16bcfa2e01e763e61031c583ec4318cbc68 Mon Sep 17 00:00:00 2001 From: Peter Bengtsson Date: Mon, 10 Jul 2017 14:26:55 -0400 Subject: [PATCH 04/14] travis test in Python 3.5 too --- .travis.yml | 1 + README.rst | 2 +- setup.py | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 73f9e10..884c645 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,6 +6,7 @@ cache: pip python: - '2.7' +- '3.3' - '3.4' - '3.5' diff --git a/README.rst b/README.rst index 33918ff..447e19e 100644 --- a/README.rst +++ b/README.rst @@ -10,7 +10,7 @@ actually not used in your HTML. By Peter Bengtsson, 2012-2017 -Tested in Python 2.7, 3.3 and 3.4 +Tested in Python 2.7, 3.3, 3.4 and 3.5 Example ------- diff --git a/setup.py b/setup.py index bd61d7d..f09a8a6 100755 --- a/setup.py +++ b/setup.py @@ -62,6 +62,7 @@ def find_install_requires(): 'Programming Language :: Python :: 2.7', 'Programming Language :: Python :: 3.3', 'Programming Language :: Python :: 3.4', + 'Programming Language :: Python :: 3.5', ], install_requires=find_install_requires(), entry_points={'console_scripts': ['mincss=mincss.main:main']}, From 811af80ac0245796ffe396c171e4381dedf37e22 Mon Sep 17 00:00:00 2001 From: Berni Moses Date: Wed, 12 Jul 2017 15:34:25 +0200 Subject: [PATCH 05/14] Fixed syntax and unicode encode errors. (#20) * Fixed SyntaxErrors. * Fixed UnicodeEncodeError. * Use codecs.open instead of open. --- run.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/run.py b/run.py index 94c4083..93e3682 100755 --- a/run.py +++ b/run.py @@ -3,6 +3,7 @@ import os import sys import time +import codecs # make sure it's running the mincss here and not anything installed @@ -40,11 +41,11 @@ def run(args): #print("AFTER ".ljust(79, '-')) #print(link.after) orig_name = link.href.split('/')[-1] - with open(os.path.join(output_dir, orig_name), 'w') as f: + with codecs.open(os.path.join(output_dir, orig_name), 'w') as f: f.write(link.after) before_name = 'before_' + link.href.split('/')[-1] - with open(os.path.join(output_dir, before_name), 'w') as f: - f.write(link.before.encode('utf-8')) + with codecs.open(os.path.join(output_dir, before_name), 'w') as f: + f.write(link.before) print("Files written to", output_dir) print() print( From a554067c6713dfa7f63ade526686e00c78c3cd4a Mon Sep 17 00:00:00 2001 From: Peter Bengtsson Date: Tue, 21 Nov 2017 08:31:08 -0500 Subject: [PATCH 06/14] use utf-8 to codec write outputs (#50) --- run.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/run.py b/run.py index 93e3682..bb4d10b 100755 --- a/run.py +++ b/run.py @@ -41,10 +41,12 @@ def run(args): #print("AFTER ".ljust(79, '-')) #print(link.after) orig_name = link.href.split('/')[-1] - with codecs.open(os.path.join(output_dir, orig_name), 'w') as f: + fn = os.path.join(output_dir, orig_name) + with codecs.open(fn, 'w', 'utf-8') as f: f.write(link.after) before_name = 'before_' + link.href.split('/')[-1] - with codecs.open(os.path.join(output_dir, before_name), 'w') as f: + fn = os.path.join(output_dir, before_name) + with codecs.open(fn, 'w', 'utf-8') as f: f.write(link.before) print("Files written to", output_dir) print() From b1b195c7cf808e5e427264200e70285d70ccc915 Mon Sep 17 00:00:00 2001 From: Peter Bengtsson Date: Wed, 3 Jan 2018 10:59:58 -0500 Subject: [PATCH 07/14] split on : better, fixes #51 (#52) --- mincss/processor.py | 10 +++++++--- tests/complex-selector.html | 9 +++++++++ tests/test_mincss.py | 2 ++ 3 files changed, 18 insertions(+), 3 deletions(-) diff --git a/mincss/processor.py b/mincss/processor.py index bd8c3e9..05119f3 100644 --- a/mincss/processor.py +++ b/mincss/processor.py @@ -43,6 +43,12 @@ VENDOR_PREFIXED_PSEUDO_CLASSES = re.compile( ':-(webkit|moz)-' ) +# For matching things like "foo:bar" and '"foo:ing":bar' because it's +# not enough to just do a split on ':' since the ':' might be inside +# quotation marks. E.g. 'a[href^="javascript:"]' +PSEUDO_SELECTOR = re.compile( + r':(?=([^"\'\\]*(\\.|["\']([^"\'\\]*\\.)*[^"\'\\]*[\'"]))*[^"\']*$)' +) EXCEPTIONAL_SELECTORS = ( 'html', @@ -504,8 +510,6 @@ def _found(self, bodies, selector): # If the last part of the selector is a tag like # ".foo blockquote" or "sometag" then we can look for it # in plain HTML as a form of optimization - last_part = selector.split()[-1] - # if self._all_tags and '"' not in selector: if not re.findall('[^\w \.]', selector): # It's a trivial selector. Like "tag.myclass", # or ".one.two". Let's look for some cheap wins @@ -525,7 +529,7 @@ def _found(self, bodies, selector): def _simplified_selector(selector): # If the select has something like :active or :hover, # then evaluate it as if it's without that pseudo class - return selector.split(':')[0].strip() + return PSEUDO_SELECTOR.split(selector)[0].strip() def _selector_query_found(self, bodies, selector): if '}' in selector: diff --git a/tests/complex-selector.html b/tests/complex-selector.html index 14f057f..40916d3 100644 --- a/tests/complex-selector.html +++ b/tests/complex-selector.html @@ -6,11 +6,20 @@

h1

actually +
+ Stuff +
diff --git a/tests/test_mincss.py b/tests/test_mincss.py index ee462d3..cd661d6 100644 --- a/tests/test_mincss.py +++ b/tests/test_mincss.py @@ -346,6 +346,8 @@ def test_complex_colons_in_selector_expression(self): after = p.inlines[0].after ok_('a[href^="javascript:"] { color: pink; }' in after) ok_('a[href^="javascript:"]:after { content: "x"; }' in after) + ok_('.ui[class*="4:3"].embed' in after) + ok_('.ui[class*="6:9"].embed' not in after) def test_before_after(self): html = os.path.join(HERE, 'before-after.html') From 386d7e4397880a6a76a7ef4a25a7524c27c3e84a Mon Sep 17 00:00:00 2001 From: Peter Bengtsson Date: Wed, 3 Jan 2018 11:01:42 -0500 Subject: [PATCH 08/14] version 0.11.4 --- README.rst | 2 +- mincss/__init__.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.rst b/README.rst index 447e19e..656e6fc 100644 --- a/README.rst +++ b/README.rst @@ -8,7 +8,7 @@ mincss Clears the junk out of your CSS by finding out which selectors are actually not used in your HTML. -By Peter Bengtsson, 2012-2017 +By Peter Bengtsson, 2012-2018 Tested in Python 2.7, 3.3, 3.4 and 3.5 diff --git a/mincss/__init__.py b/mincss/__init__.py index 4ad2f68..8e747cc 100644 --- a/mincss/__init__.py +++ b/mincss/__init__.py @@ -1 +1 @@ -__version__ = '0.11.3' +__version__ = '0.11.4' From 2095baf02cb0d4d87070352d1d24a1b432c03f30 Mon Sep 17 00:00:00 2001 From: Peter Bengtsson Date: Tue, 30 Jan 2018 08:05:52 -0500 Subject: [PATCH 09/14] speedup when mincss=no (#54) --- mincss/processor.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/mincss/processor.py b/mincss/processor.py index 05119f3..f8ef569 100644 --- a/mincss/processor.py +++ b/mincss/processor.py @@ -159,12 +159,14 @@ def process(self, *urls): for identifier in sorted(self.blocks.keys()): content = self.blocks[identifier] - processed = self._process_content(content, self._bodies) + no_mincss = identifier[-1] + if no_mincss: + processed = content + else: + processed = self._process_content(content, self._bodies) if identifier[1] == INLINE: - line, _, url, no_mincss = identifier - if no_mincss: - processed = content + line, _, url, _ = identifier self.inlines.append( InlineResult( line, @@ -174,9 +176,7 @@ def process(self, *urls): ) ) else: - _, _, url, href, no_mincss = identifier - if no_mincss: - processed = content + _, _, url, href, _ = identifier self.links.append( LinkResult( href, From 9c4e6e0c560db97397e810e5bb6e54d28b12e802 Mon Sep 17 00:00:00 2001 From: Peter Bengtsson Date: Tue, 30 Jan 2018 08:06:45 -0500 Subject: [PATCH 10/14] version 0.11.5 --- mincss/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mincss/__init__.py b/mincss/__init__.py index 8e747cc..eebcbfe 100644 --- a/mincss/__init__.py +++ b/mincss/__init__.py @@ -1 +1 @@ -__version__ = '0.11.4' +__version__ = '0.11.5' From 371aac74238d810f7328bac1e393883d64b8a636 Mon Sep 17 00:00:00 2001 From: Peter Bengtsson Date: Tue, 30 Jan 2018 08:13:15 -0500 Subject: [PATCH 11/14] ignore more --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index 57ac9b1..22875f1 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,5 @@ mincss.egg-info/ simple.js *.pyc __pycache__/ +.cache/ +.eggs/ From 715a48fbdaaa180fe8cb795716345c2b71e65426 Mon Sep 17 00:00:00 2001 From: Peter Bengtsson Date: Thu, 8 Feb 2018 08:48:34 -0500 Subject: [PATCH 12/14] cli supports --version --- mincss/__init__.py | 2 +- mincss/main.py | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/mincss/__init__.py b/mincss/__init__.py index eebcbfe..94f8ab8 100644 --- a/mincss/__init__.py +++ b/mincss/__init__.py @@ -1 +1 @@ -__version__ = '0.11.5' +__version__ = '0.11.6' diff --git a/mincss/main.py b/mincss/main.py index 5f2f6f0..0f79534 100644 --- a/mincss/main.py +++ b/mincss/main.py @@ -4,10 +4,14 @@ import os import time +from mincss import __version__ from .processor import Processor def run(args): + if args.version: + print(__version__) + return options = {'debug': args.verbose} if args.phantomjs_path: options['phantomjs'] = args.phantomjs_path @@ -64,6 +68,9 @@ def main(): add('--phantomjs-path', action='store', default='', help='Where is the phantomjs executable') + add('--version', action='store_true', + default=False, + help='Prints out the version of mincss') args = parser.parse_args() return run(args) or 0 From f313d9458d8931b800d9121428edf2591811d5ca Mon Sep 17 00:00:00 2001 From: sureshvv Date: Thu, 7 Jun 2018 00:02:07 +0530 Subject: [PATCH 13/14] Discovered empirically. (#56) --- docs/api.rst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/api.rst b/docs/api.rst index 01d5a0c..b303e1b 100644 --- a/docs/api.rst +++ b/docs/api.rst @@ -51,6 +51,10 @@ API If you for some reason already have the HTML you can jump straight to this method. Note, you still need to provide the URL where you got the HTML from so it can use that to download any external CSS. + + * When calling ``process_url()`` or ``process_html()``, you have to call ``process()`` + at the end without arguments, in order to post process the pages that were + processed individually. The ``Processor`` instance will make two attributes available From b964a38de27e06033a5bd3627217a7a5de8fa536 Mon Sep 17 00:00:00 2001 From: Peter Bengtsson Date: Mon, 15 Apr 2019 20:34:36 -0400 Subject: [PATCH 14/14] Link to minimalcss --- README.rst | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.rst b/README.rst index 656e6fc..24eaf8f 100644 --- a/README.rst +++ b/README.rst @@ -1,3 +1,9 @@ +**UPDATE April 2019** + +INSTEAD OF USING THIS, A MUCH BETTER ALTERNATIVE IS https://github.com/peterbe/minimalcss/ WHICH SUPPORTS JAVASCRIPT AND THE CSS PARSING AND TRANSFORMATIONS ARE DONE WITH A PARSED AST. + + + mincss ======