Skip to content

Commit 2d2fae1

Browse files
Merge pull request #42 from underthecocotree/master
Load css from link tag in the html
2 parents c24d71f + ab1272c commit 2d2fae1

File tree

7 files changed

+174
-11
lines changed

7 files changed

+174
-11
lines changed

README.md

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ The goal of this package is to automate the process of inlining that CSS before
1515
## How?
1616
Using a wonderful [CSS inliner package](https://github.com/tijsverkoyen/CssToInlineStyles) wraped in a SwiftMailer plugin and served as a Service Provider it justs works without any configuration.
1717

18-
Turns:
18+
Turns style tag:
1919
```html
2020
<html>
2121
<head>
@@ -31,6 +31,17 @@ Turns:
3131
</body>
3232
</html>
3333
```
34+
Or the link tag:
35+
```html
36+
<html>
37+
<head>
38+
<link rel="stylesheet" type="text/css" href="./tests/css/test.css">
39+
</head>
40+
<body>
41+
<h1>Hey you</h1>
42+
</body>
43+
</html>
44+
```
3445

3546
Into this:
3647
```html
@@ -74,6 +85,8 @@ and changing the settings on the generated `config/css-inliner.php` file.
7485
```bash
7586
$ composer install
7687
$ ./vendor/bin/phpunit
88+
$ ./vendor/bin/phpcs --standard=phpcs.xml ./src/
89+
$ ./vendor/bin/phpcs --standard=phpcs.xml ./tests/;
7790
```
7891
In addition to a full test suite, there is Travis integration.
7992

src/CssInlinerPlugin.php

Lines changed: 55 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,7 @@ class CssInlinerPlugin implements \Swift_Events_SendListener
2222
public function __construct(array $options)
2323
{
2424
$this->converter = new CssToInlineStyles();
25-
if (isset($options['css-files']) && count($options['css-files']) > 0) {
26-
$this->css = '';
27-
foreach ($options['css-files'] as $file) {
28-
$this->css .= file_get_contents($file);
29-
}
30-
}
25+
$this->loadOptions($options);
3126
}
3227

3328
/**
@@ -41,12 +36,14 @@ public function beforeSendPerformed(\Swift_Events_SendEvent $evt)
4136
|| ($message->getContentType() === 'multipart/alternative' && $message->getBody())
4237
|| ($message->getContentType() === 'multipart/mixed' && $message->getBody())
4338
) {
44-
$message->setBody($this->converter->convert($message->getBody(), $this->css));
39+
$body = $this->loadCssFilesFromLinks($message->getBody());
40+
$message->setBody($this->converter->convert($body, $this->css));
4541
}
4642

4743
foreach ($message->getChildren() as $part) {
4844
if (strpos($part->getContentType(), 'text/html') === 0) {
49-
$part->setBody($this->converter->convert($part->getBody(), $this->css));
45+
$body = $this->loadCssFilesFromLinks($part->getBody());
46+
$part->setBody($this->converter->convert($body, $this->css));
5047
}
5148
}
5249
}
@@ -60,4 +57,54 @@ public function sendPerformed(\Swift_Events_SendEvent $evt)
6057
{
6158
// Do Nothing
6259
}
60+
61+
/**
62+
* Load the options
63+
* @param array $options Options array
64+
*/
65+
public function loadOptions($options)
66+
{
67+
if (isset($options['css-files']) && count($options['css-files']) > 0) {
68+
$this->css = '';
69+
foreach ($options['css-files'] as $file) {
70+
$this->css .= file_get_contents($file);
71+
}
72+
}
73+
}
74+
75+
/**
76+
* Find CSS stylesheet links and load them
77+
*
78+
* Loads the body of the message and passes
79+
* any link stylesheets to $this->css
80+
* Removes any link elements
81+
*
82+
* @return string $message The message
83+
*/
84+
public function loadCssFilesFromLinks($message)
85+
{
86+
$dom = new \DOMDocument();
87+
$dom->loadHTML($message);
88+
$link_tags = $dom->getElementsByTagName('link');
89+
90+
if ($link_tags->length > 0) {
91+
do {
92+
if ($link_tags->item(0)->getAttribute('rel') == "stylesheet") {
93+
$options['css-files'][] = $link_tags->item(0)->getAttribute('href');
94+
95+
// remove the link node
96+
$link_tags->item(0)->parentNode->removeChild($link_tags->item(0));
97+
}
98+
} while ($link_tags->length > 0);
99+
100+
if (isset($options)) {
101+
// reload the options
102+
$this->loadOptions($options);
103+
}
104+
105+
return $dom->saveHTML();
106+
}
107+
108+
return $message;
109+
}
63110
}

tests/CssInlinerPluginTest.php

Lines changed: 43 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,9 @@ class CssInlinerPluginTest extends PHPUnit_Framework_TestCase
99
protected $options;
1010

1111
protected static $stubDefinitions = array(
12-
'plain-text', 'original-html', 'original-html-with-css','converted-html',
13-
'converted-html-with-css'
12+
'plain-text', 'original-html', 'original-html-with-css',
13+
'original-html-with-link-css', 'original-html-with-links-css',
14+
'converted-html', 'converted-html-with-css', 'converted-html-with-links-css'
1415
);
1516

1617
public function setUp()
@@ -125,4 +126,44 @@ public function itShouldConvertHtmlBodyAsAPart()
125126

126127
$this->assertEquals($this->stubs['converted-html'], $children[0]->getBody());
127128
}
129+
130+
/** @test **/
131+
public function itShouldConvertHtmlBodyWithLinkCss()
132+
{
133+
$mailer = Swift_Mailer::newInstance(Swift_NullTransport::newInstance());
134+
135+
$mailer->registerPlugin(new CssInlinerPlugin($this->options));
136+
137+
$message = Swift_Message::newInstance();
138+
139+
$message->setFrom('[email protected]');
140+
$message->setTo('[email protected]');
141+
$message->setSubject('Test');
142+
143+
$message->setBody($this->stubs['original-html-with-link-css'], 'text/html');
144+
145+
$mailer->send($message);
146+
147+
$this->assertEquals($this->stubs['converted-html-with-css'], $message->getBody());
148+
}
149+
150+
/** @test **/
151+
public function itShouldConvertHtmlBodyWithLinksCss()
152+
{
153+
$mailer = Swift_Mailer::newInstance(Swift_NullTransport::newInstance());
154+
155+
$mailer->registerPlugin(new CssInlinerPlugin($this->options));
156+
157+
$message = Swift_Message::newInstance();
158+
159+
$message->setFrom('[email protected]');
160+
$message->setTo('[email protected]');
161+
$message->setSubject('Test');
162+
163+
$message->setBody($this->stubs['original-html-with-links-css'], 'text/html');
164+
165+
$mailer->send($message);
166+
167+
$this->assertEquals($this->stubs['converted-html-with-links-css'], $message->getBody());
168+
}
128169
}

tests/css/test2.css

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
body {
2+
background-color: red;
3+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
2+
<html>
3+
<head></head>
4+
<body style="background-color: red;">
5+
<div class="pixels-10" style="width: 10px;">
6+
text
7+
8+
<ul>
9+
<li>
10+
Big list
11+
</li>
12+
<li>
13+
Small list
14+
</li>
15+
</ul>
16+
</div>
17+
</body>
18+
</html>
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<html>
2+
<head>
3+
<link rel="stylesheet" type="text/css" href="./tests/css/test.css">
4+
</head>
5+
<body>
6+
<div class="pixels-10">
7+
text
8+
9+
<ul>
10+
<li>
11+
Big list
12+
</li>
13+
<li>
14+
Small list
15+
</li>
16+
</ul>
17+
</div>
18+
</body>
19+
</html>
20+
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<html>
2+
<head>
3+
<link rel="stylesheet" type="text/css" href="./tests/css/test.css">
4+
<link rel="stylesheet" type="text/css" href="./tests/css/test2.css">
5+
</head>
6+
<body>
7+
<div class="pixels-10">
8+
text
9+
10+
<ul>
11+
<li>
12+
Big list
13+
</li>
14+
<li>
15+
Small list
16+
</li>
17+
</ul>
18+
</div>
19+
</body>
20+
</html>
21+

0 commit comments

Comments
 (0)