Repository: peterbe/premailer

Issue:
Crashing when using on Semantic with exclude_pseudoclasses=False
Tried running this script:
```
# Just a test script for premailer

import premailer

html = """
    <html>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/semantic-ui/2.2.9/semantic.min.css"/>
    <style>
        h1{ border: 1px solid blue}
        h1:hover {border: 1px solid green}
        
    </style>
    <h1>Hey</h1>
    </html>
"""

p = premailer.Premailer(html, exclude_pseudoclasses=False)
print(p.transform())
```

but it crashes and returns:
```
...
WARNING	Property: Unknown Property name.
WARNING	Property: Unknown Property name.
WARNING	Property: Unknown Property name.
WARNING	Property: Unknown Property name.
WARNING	Property: Unknown Property name.
WARNING	Property: Unknown Property name.
WARNING	Property: Unknown Property name.
WARNING	Property: Unknown Property name.
Traceback (most recent call last):
  File "prem.py", line 18, in <module>
    print(p.transform())
  File "/home/jddantes/.conda/envs/pulse/lib/python3.6/site-packages/premailer/premailer.py", line 404, in transform
    sel = CSSSelector(selector)
  File "/home/jddantes/.conda/envs/pulse/lib/python3.6/site-packages/lxml/cssselect.py", line 94, in __init__
    path = translator.css_to_xpath(css)
  File "/home/jddantes/.conda/envs/pulse/lib/python3.6/site-packages/cssselect/xpath.py", line 192, in css_to_xpath
    for selector in parse(css))
  File "/home/jddantes/.conda/envs/pulse/lib/python3.6/site-packages/cssselect/parser.py", line 355, in parse
    return list(parse_selector_group(stream))
  File "/home/jddantes/.conda/envs/pulse/lib/python3.6/site-packages/cssselect/parser.py", line 370, in parse_selector_group
    yield Selector(*parse_selector(stream))
  File "/home/jddantes/.conda/envs/pulse/lib/python3.6/site-packages/cssselect/parser.py", line 378, in parse_selector
    result, pseudo_element = parse_simple_selector(stream)
  File "/home/jddantes/.conda/envs/pulse/lib/python3.6/site-packages/cssselect/parser.py", line 480, in parse_simple_selector
    "Expected selector, got %s" % (stream.peek(),))
cssselect.parser.SelectorSyntaxError: Expected selector, got <EOF at 0>

```

premailer==3.0.0
lxml==3.8.0

Discussion:
coveralls: 
[![Coverage Status](https://coveralls.io/builds/12542863/badge)](https://coveralls.io/builds/12542863)

Coverage remained the same at 100.0% when pulling **b4509c51881fb2ace20f6af569f2e44aa0c900da on no-exclude_pseudoclasses-without-selector-value** into **597b57740c661df8b3f4f5bdec7c495afe955275 on master**.


Patch:
diff --git a/premailer/premailer.py b/premailer/premailer.py
index 7cfb186..0a8c40d 100644
--- a/premailer/premailer.py
+++ b/premailer/premailer.py
@@ -250,6 +250,9 @@ class Premailer(object):
                     continue
                 elif '*' in selector and not self.include_star_selectors:
                     continue
+                elif selector.startswith(':'):
+                    continue
+
                 # Crudely calculate specificity
                 id_count = selector.count('#')
                 class_count = selector.count('.')
@@ -274,6 +277,7 @@ class Premailer(object):
                         len(rules)  # this is the rule's index number
                     )
                     rules.append((specificity, selector, bulk))
+
         return rules, leftover
 
     def transform(self, pretty_print=True, **kwargs):
@@ -401,6 +405,7 @@ class Premailer(object):
             else:
                 selector = new_selector
 
+            assert selector
             sel = CSSSelector(selector)
             items = sel(page)
             if len(items):


Test patch:
diff --git a/premailer/tests/test_premailer.py b/premailer/tests/test_premailer.py
index dc7f2c1..fa5c2eb 100644
--- a/premailer/tests/test_premailer.py
+++ b/premailer/tests/test_premailer.py
@@ -2622,3 +2622,53 @@ sheet" type="text/css">
         )
         result_html = p.transform()
         compare_html(expect_html, result_html)
+
+    def test_pseudo_selectors_without_selector(self):
+        """Happens when you have pseudo selectors without an actual selector.
+        Which means it's not possible to find it in the DOM.
+
+        For example:
+
+           <style>
+           :before{box-sizing:inherit}
+           </style>
+
+        Semantic-UI uses this in its normalizer.
+
+        Original issue: https://github.com/peterbe/premailer/issues/184
+        """
+
+        html = """
+            <html>
+            <style>
+                 *,:after,:before{box-sizing:inherit}
+                h1{ border: 1px solid blue}
+                h1:hover {border: 1px solid green}
+
+            </style>
+            <h1>Hey</h1>
+            </html>
+        """
+
+        expect_html = """
+<html>
+    <head>
+    <style>
+         *,:after,:before{box-sizing:inherit}
+        h1{ border: 1px solid blue}
+        h1:hover {border: 1px solid green}
+
+    </style>
+    </head>
+    <body>
+    <h1 style="{border:1px solid blue} :hover{border:1px solid green}">Hey</h1>
+    </body>
+</html>
+        """
+        p = Premailer(
+            html,
+            exclude_pseudoclasses=False,
+            keep_style_tags=True,
+        )
+        result_html = p.transform()
+        compare_html(expect_html, result_html)