Skip to content

Commit da34b93

Browse files
authored
Merge pull request #11 from Vindexus/keep-important
Added a KeepBangImportant option to preserve '!important' in final style attribute.
2 parents be27abe + 0ba3c6c commit da34b93

File tree

4 files changed

+61
-1
lines changed

4 files changed

+61
-1
lines changed

premailer/element.go

+9
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ type elementRules struct {
1414
element *goquery.Selection
1515
rules []*styleRule
1616
cssToAttributes bool
17+
keepBangImportant bool
1718
}
1819

1920
func (er *elementRules) inline() {
@@ -30,6 +31,9 @@ func (er *elementRules) inline() {
3031
for _, s := range rule.styles {
3132
prop := s.Property
3233
styles[prop] = s.Value
34+
if er.keepBangImportant && s.Important == 1 {
35+
styles[prop] += " !important"
36+
}
3337
orders = append(orders, prop)
3438
}
3539
}
@@ -78,6 +82,11 @@ func (er *elementRules) styleToBasicHtmlAttribute(prop, value string) {
7882
case "width":
7983
fallthrough
8084
case "height":
85+
// If we are keeping "!important" in our styles, we need to strip it out
86+
// here so that the proper px value can be parsed
87+
if er.keepBangImportant {
88+
value = strings.Replace(value, " !important", "", 1)
89+
}
8190
if strings.HasSuffix(value, "px") {
8291
value = value[:len(value)-2]
8392
er.element.SetAttr(prop, value)

premailer/options.go

+9
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,20 @@ type Options struct {
88
// Copy related CSS properties into HTML attributes (e.g. background-color to bgcolor)
99
// Default true
1010
CssToAttributes bool
11+
12+
// If true, then style declarations that have "!important" will keep the "!important" in the final
13+
// style attribute
14+
// Example:
15+
// <style>p { width: 100% !important }</style><p>Text</p>
16+
// gives
17+
// <p style="width: 100% !important">Text</p>
18+
KeepBangImportant bool
1119
}
1220

1321
// NewOptions return an Options instance with default value
1422
func NewOptions() *Options {
1523
options := &Options{}
1624
options.CssToAttributes = true
25+
options.KeepBangImportant = false
1726
return options
1827
}

premailer/premailer.go

+6-1
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,12 @@ func (pr *premailer) collectElements() {
133133
s.SetAttr(pr.elIdAttr, id)
134134
rules := make([]*styleRule, 0)
135135
rules = append(rules, rule)
136-
pr.elements[id] = &elementRules{element: s, rules: rules, cssToAttributes: pr.options.CssToAttributes}
136+
pr.elements[id] = &elementRules{
137+
element: s,
138+
rules: rules,
139+
cssToAttributes: pr.options.CssToAttributes,
140+
keepBangImportant: pr.options.KeepBangImportant,
141+
}
137142
pr.elementId += 1
138143
}
139144
})

premailer/premailer_test.go

+37
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,43 @@ func TestWithImportant(t *testing.T) {
260260
assert.Contains(t, resultHTML, "<p class=\"wide\" style=\"color:blue;width:100px\" width=\"100\"><strong>Yes!</strong></p>")
261261
}
262262

263+
264+
func TestWithKeepImportant(t *testing.T) {
265+
html := `<html>
266+
<head>
267+
<title>Title</title>
268+
<style type="text/css">
269+
h1, h2 {
270+
color:red;
271+
}
272+
p {
273+
width: 100px !important;
274+
color: blue
275+
}
276+
.wide {
277+
width: 1000px;
278+
}
279+
</style>
280+
</head>
281+
<body>
282+
<h1>Hi!</h1>
283+
<p class="wide"><strong>Yes!</strong></p>
284+
</body>
285+
</html>`
286+
287+
options := NewOptions()
288+
options.KeepBangImportant = true
289+
p, err := NewPremailerFromString(html, options)
290+
assert.Nil(t, err)
291+
resultHTML, err := p.Transform()
292+
assert.Nil(t, err)
293+
294+
assert.Contains(t, resultHTML, "<h1 style=\"color:red\">Hi!</h1>")
295+
assert.Contains(t, resultHTML, "<p class=\"wide\" style=\"color:blue;width:100px !important\" width=\"100\"><strong>Yes!</strong></p>")
296+
297+
}
298+
299+
263300
func TestWithMediaRule(t *testing.T) {
264301
html := `<html>
265302
<head>

0 commit comments

Comments
 (0)