Adds a remove_unset_properties setting. Squashed commits.

This commit is contained in:
David Barbarisi 2015-09-09 16:37:38 -04:00
parent 9c94ebe20e
commit 9d984ba7e4
3 changed files with 80 additions and 8 deletions

View File

@ -19,7 +19,12 @@ def csstext_to_pairs(csstext):
csstext_to_pairs._lock = threading.RLock()
def merge_styles(inline_style, new_styles, classes):
def merge_styles(
inline_style,
new_styles,
classes,
remove_unset_properties=False
):
"""
This will merge all new styles where the order is important
The last one will override the first
@ -29,9 +34,12 @@ def merge_styles(inline_style, new_styles, classes):
Args:
inline_style(str): the old inline style of the element if there
is one new_styles: a list of new styles, each element should be
a list of tuple classes: a list of classes which maps
new_styles, important!
is one
new_styles: a list of new styles, each element should be
a list of tuple
classes: a list of classes which maps new_styles, important!
remove_unset_properties(bool): Allow us to remove certain CSS
properties with rules that set their value to 'unset'
Returns:
str: the final style
@ -55,6 +63,13 @@ def merge_styles(inline_style, new_styles, classes):
normal_styles = []
pseudo_styles = []
for pseudoclass, kv in styles.items():
if remove_unset_properties:
# Remove rules that we were going to have value 'unset' because
# they effectively are the same as not saying anything about the
# property when inlined
kv = dict(
(k, v) for (k, v) in kv.items() if not v.lower() == 'unset'
)
if not kv:
continue
if pseudoclass:

View File

@ -115,7 +115,8 @@ class Premailer(object):
cssutils_logging_handler=None,
cssutils_logging_level=None,
disable_leftover_css=False,
align_floating_images=True):
align_floating_images=True,
remove_unset_properties=True):
self.html = html
self.base_url = base_url
self.preserve_internal_links = preserve_internal_links
@ -143,6 +144,7 @@ class Premailer(object):
self.cache_css_parsing = cache_css_parsing
self.disable_leftover_css = disable_leftover_css
self.align_floating_images = align_floating_images
self.remove_unset_properties = remove_unset_properties
if cssutils_logging_handler:
cssutils.log.addHandler(cssutils_logging_handler)
@ -396,9 +398,16 @@ class Premailer(object):
# crucial when you have a lot of pseudo/classes
# and a long list of elements
for _, element in elements.items():
final_style = merge_styles(element['item'].attrib.get('style', ''),
element['style'], element['classes'])
element['item'].attrib['style'] = final_style
final_style = merge_styles(
element['item'].attrib.get('style', ''),
element['style'],
element['classes'],
remove_unset_properties=self.remove_unset_properties,
)
if final_style:
# final style could be empty string because of
# remove_unset_properties
element['item'].attrib['style'] = final_style
self._style_to_basic_html_attributes(
element['item'],
final_style,

View File

@ -143,6 +143,21 @@ class Tests(unittest.TestCase):
for each in expect:
ok_(each in result)
def test_merge_styles_with_unset(self):
inline_style = 'color: red'
new = 'font-size: 10px; font-size: unset; font-weight: bold'
expect = 'color:red;', 'font-weight:bold'
css_new = csstext_to_pairs(new)
result = merge_styles(
inline_style,
[css_new],
[''],
remove_unset_properties=True,
)
for each in expect:
ok_(each in result)
ok_('font-size' not in result)
def test_basic_html(self):
"""test the simplest case"""
@ -2453,3 +2468,36 @@ sheet" type="text/css">
p = Premailer(html, align_floating_images=True)
result_html = p.transform()
compare_html(expect_html, result_html)
def test_remove_unset_properties(self):
html = """<html>
<head>
<style>
div {
color: green;
}
span {
color: blue;
}
span.nocolor {
color: unset;
}
</style>
</head>
<body>
<div class="color"><span class="nocolor"></span></div>
</body>
</html>"""
expect_html = """<html>
<head>
</head>
<body>
<div style="color:green"><span></span></div>
</body>
</html>"""
p = Premailer(html, remove_unset_properties=True)
self.assertTrue(p.remove_unset_properties)
result_html = p.transform()
compare_html(expect_html, result_html)