rennat / pynliner

Python CSS-to-inline-styles conversion tool for HTML using BeautifulSoup and cssutils
http://pythonhosted.org/pynliner/
180 stars 93 forks source link

media queries are removed #13

Closed GotenXiao closed 8 years ago

GotenXiao commented 12 years ago

Given the following sample code:

<!DOCTYPE html>
<html>
    <head>
        <title>Example</title>
        <style type="text/css">
            @media screen and (min-device-width: 480)
            {
                #content
                {
                        width: 480px;
                }
            }
            #content
            {
                border: 1px solid black;
            }
        </style>
    </head>
    <body>
        <div id="content">
            <h1>Hello world</h1>
        </div>
    </body>
</html>

I would expect the default border rule to be applied, and the media query hunk to be left alone (since it will only be parsed and used on compatible devices).

As a potential quick fix, pynliner could exclude processing of style or link blocks that have media query-like syntax, or are present and not screen.

GotenXiao commented 12 years ago

Quick fix patch:

index 7d6fa52..13c2f27 100644
--- a/pynliner/__init__.py
+++ b/pynliner/__init__.py
@@ -29,6 +29,10 @@ class Pynliner(object):
     style_string = False
     stylesheet = False
     output = False
+    exclude_if_media = True
+    inline_media_types = [
+            'screen',
+            ]

     def __init__(self, log=None):
         self.log = log
@@ -151,6 +155,15 @@ class Pynliner(object):

         style_tags = self.soup.findAll('style')
         for tag in style_tags:
+            if self.exclude_if_media:
+                skip_tag = False
+                for attr_name, attr_value in tag.attrs:
+                    if attr_name == 'media' \
+                    and attr_value not in self.inline_media_types:
+                        skip_tag = True
+                        break
+                if skip_tag:
+                    continue
             self.style_string += u'\n'.join(tag.contents) + u'\n'
             tag.extract()

Obviously this doesn't try to parse the CSS itself, but this is probably an acceptable workaround for now.

rennat commented 12 years ago

I like the approach you have taken here but I think we should look at applying this more generically so that any css that cannot be inlined will be left alone in a style element.

rennat commented 12 years ago

What would be helpful here is building up tests for each of these cases where the css cannot be inlined.

I can write the tests but I am not aware of everything that can and can't be applied inline. I plan to research the specification further when I have time but as I'm not sure when that will be feel free to submit test cases or even a list of css declarations to test for.

mrmch commented 10 years ago

@rennat any updates on this? Happy to contribute if needed. Better support for media queries in pynliner would be grand.

rennat commented 10 years ago

Nope. I've started, very slowly, on a complete refactor to address some of the reported issues so far (mainly the speed and limited support for templating languages without breaking the current API/tests) but I have not done anything with the current codebase related to this issue. I'll happily check out pull requests for it tho!

oppianmatt commented 8 years ago

+1 to merge the PR #38

Is this project abandoned? No commits since 2014, happy to help maintain if you need someone.

rennat commented 8 years ago

not abandoned yet :) just maintained by busy people :(

rennat commented 8 years ago

38 does look good