mikedamage-premailer-plus 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/LICENSE +20 -0
- data/README.textile +41 -0
- data/Rakefile +56 -0
- data/VERSION.yml +4 -0
- data/bin/premailer_plus +108 -0
- data/lib/html_to_plain_text.rb +61 -0
- data/lib/premailer.rb +396 -0
- data/test/fixtures/client_support.html +10 -0
- data/test/fixtures/test-import.css +4 -0
- data/test/fixtures/test-with-folding.html +77 -0
- data/test/fixtures/test.css +90 -0
- data/test/fixtures/test.html +66 -0
- data/test/fixtures/test2.css +81 -0
- data/test/fixtures/test2.html +75 -0
- data/test/fixtures/test3-import.css +4 -0
- data/test/fixtures/test3-noimport.css +1 -0
- data/test/fixtures/test3-out.html +82 -0
- data/test/fixtures/test3.css +83 -0
- data/test/fixtures/test3.html +85 -0
- data/test/images/content_bg.jpg +0 -0
- data/test/images/inset.jpg +0 -0
- data/test/speed.rb +34 -0
- data/test/test_convert_to_plain_text.rb +30 -0
- data/test/test_helper.rb +6 -0
- data/test/test_link_resolver.rb +32 -0
- data/test/test_premailer.rb +22 -0
- data/test/test_premailer_download.rb +77 -0
- metadata +86 -0
@@ -0,0 +1,83 @@
|
|
1
|
+
/*
|
2
|
+
Premailer (http://code.dunae.ca/premailer.web/) test stylesheet
|
3
|
+
*/
|
4
|
+
|
5
|
+
@import "test3-import.css" screen;
|
6
|
+
@import "test3-noimport.css" print;
|
7
|
+
|
8
|
+
#container {
|
9
|
+
margin: 0;
|
10
|
+
width: 100%;
|
11
|
+
font: 300 normal 13px "Georgia", Times, serif;
|
12
|
+
font-size: 12px;
|
13
|
+
}
|
14
|
+
|
15
|
+
#frame {
|
16
|
+
margin: 0 auto;
|
17
|
+
width: 740px;
|
18
|
+
}
|
19
|
+
|
20
|
+
td {
|
21
|
+
font-family: Georgia, Times, serif;
|
22
|
+
line-height: 18px;
|
23
|
+
}
|
24
|
+
|
25
|
+
#head td {
|
26
|
+
text-align: center;
|
27
|
+
font-size: 11px;
|
28
|
+
}
|
29
|
+
|
30
|
+
|
31
|
+
#head td, #head a,
|
32
|
+
#legal td, #legal a{
|
33
|
+
color: #fff;
|
34
|
+
background: #1c2815 none;
|
35
|
+
}
|
36
|
+
|
37
|
+
#head a, #legal a { text-decoration: underline; }
|
38
|
+
|
39
|
+
#content h1 {
|
40
|
+
font-style: italic;
|
41
|
+
font-size: 24px;
|
42
|
+
}
|
43
|
+
|
44
|
+
#content td {
|
45
|
+
padding: 18px 0;
|
46
|
+
color: #666;
|
47
|
+
background: #deddc9 url("images/content_bg.jpg") repeat-y center top;
|
48
|
+
border-color: #fff;
|
49
|
+
border-style: solid;
|
50
|
+
border-width: 10px;
|
51
|
+
}
|
52
|
+
|
53
|
+
.feature {
|
54
|
+
border: 3px solid #fff;
|
55
|
+
}
|
56
|
+
|
57
|
+
img.right {
|
58
|
+
margin: 0 36px 27px;
|
59
|
+
float: right;
|
60
|
+
}
|
61
|
+
|
62
|
+
|
63
|
+
#content a {
|
64
|
+
color: #900;
|
65
|
+
background-color: transparent;
|
66
|
+
font-weight: bold;
|
67
|
+
}
|
68
|
+
|
69
|
+
#content h1,
|
70
|
+
#content td h2,
|
71
|
+
#content td p {
|
72
|
+
padding: 0 36px 9px;
|
73
|
+
}
|
74
|
+
|
75
|
+
ul.spacious li {
|
76
|
+
margin: 18px;
|
77
|
+
}
|
78
|
+
|
79
|
+
.intro {
|
80
|
+
font-size: 18px;
|
81
|
+
}
|
82
|
+
|
83
|
+
|
@@ -0,0 +1,85 @@
|
|
1
|
+
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
2
|
+
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-ca" lang="en-ca">
|
3
|
+
<head>
|
4
|
+
<title>Premailer Test Page</title>
|
5
|
+
<link rel="schema.dc" href="http://www.purl.org/dc/elements/1.1/" />
|
6
|
+
<meta name="dc.creator" content="Alex Dunae - dunae.ca" />
|
7
|
+
<meta name="description" content="Premailer (http://code.dunae.ca/premailer.web/) test page" />
|
8
|
+
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
|
9
|
+
<link rel="stylesheet" type="text/css" href="test3.css" />
|
10
|
+
<style type="text/css">
|
11
|
+
@import "test3-noimport.css" print;
|
12
|
+
|
13
|
+
#legal td { padding-top: 27px; }
|
14
|
+
|
15
|
+
#legal p { margin: 0 36px; font-size: 11px; }
|
16
|
+
|
17
|
+
#legal a { text-decoration: underline; }
|
18
|
+
|
19
|
+
#legal .right { text-align: right; }
|
20
|
+
|
21
|
+
a:hover { color: #fff !important; }
|
22
|
+
</style>
|
23
|
+
</head>
|
24
|
+
<body>
|
25
|
+
<div id="container">
|
26
|
+
<table id="frame" width="740" cellpadding="10" cellspacing="0"><tr><td>
|
27
|
+
<table id="head" cellspacing="0" cellpadding="0" width="720">
|
28
|
+
<tr>
|
29
|
+
<td>
|
30
|
+
<p>Having trouble reading this email? You can <a href="#" style="color: #f00;">read it on our web site</a>.</p>
|
31
|
+
</td>
|
32
|
+
</tr>
|
33
|
+
</table>
|
34
|
+
|
35
|
+
<table id="content" cellspacing="0" width="720">
|
36
|
+
<tr valign="top">
|
37
|
+
<td>
|
38
|
+
<!-- MAIN CONTENT BEGINS -->
|
39
|
+
|
40
|
+
<h1>Premailer Test Page</h1>
|
41
|
+
|
42
|
+
<img src="images/inset.jpg" alt="Inset image" class="feature right" />
|
43
|
+
|
44
|
+
<p class="intro">Lorem ipsum dolor sit amet, consectetuer adipiscing elit.</p>
|
45
|
+
|
46
|
+
<p>Sed quis justo ut velit mattis adipiscing. Sed in mauris et libero dapibus varius. Quisque quis neque sed neque tincidunt scelerisque. Praesent vitae velit sit amet libero pharetra rhoncus. Phasellus laoreet. Sed nibh. Integer venenatis odio vitae neque. Quisque et mi ac libero blandit interdum. Suspendisse vitae massa. Suspendisse purus ligula, egestas in, ultrices non, fermentum at, lorem.</p>
|
47
|
+
|
48
|
+
<h2>Links</h2>
|
49
|
+
|
50
|
+
<ul class="spacious">
|
51
|
+
<li><a href="/">Relative path to root</a></li>
|
52
|
+
<li><a href="http://code.dunae.ca/">Absolute path to root</a></li>
|
53
|
+
<li><a href="http://example.com/">Different domain</a></li>
|
54
|
+
<li><a href="images/">Relative path to sub-directory</a></li>
|
55
|
+
<li><a href="#relative">Link is not converted</a></li>
|
56
|
+
<li><a href="http://example.com/test.html?cn=tf&c=20&ord=%%RANDOM%%">Funky ASP URL</a></li>
|
57
|
+
<li><a href="?query=string">Appends tracking query string</a></li>
|
58
|
+
<li><a href="{DONOTCONVERT}">Link is not converted</a></li>
|
59
|
+
<li><a href="[DONOTCONVERT]">Link is not converted</a></li>
|
60
|
+
<li><a href="<DONOTCONVERT>">Link is not converted</a></li>
|
61
|
+
</ul>
|
62
|
+
|
63
|
+
<p>Vestibulum <strong>tristique adipiscing</strong> nisi. Suspendisse bibendum pretium justo. Vestibulum nec ante. Nulla mollis molestie nibh. Curabitur facilisis neque a risus. Curabitur aliquam gravida nisl. Sed consectetuer. Nullam interdum faucibus quam. Suspendisse pulvinar orci nec metus. Vivamus nonummy. Nam dignissim arcu a metus. Mauris leo. Nulla facilisi. Ut varius. Duis ultricies tristique magna. Vestibulum in lorem vitae diam pharetra vehicula. Suspendisse condimentum. Curabitur dictum magna eget tellus.</p>
|
64
|
+
<!-- MAIN CONTENT ENDS -->
|
65
|
+
</td>
|
66
|
+
</tr>
|
67
|
+
</table>
|
68
|
+
|
69
|
+
<table id="legal" cellspacing="0" cellpadding="0" width="720">
|
70
|
+
<tr>
|
71
|
+
<td class="left" width="50%" height="120" valign="top">
|
72
|
+
<p>This e-mail was sent to <b>test@example.com</b><br />
|
73
|
+
<a href="#">Click here</a> to <i>instantly</i> unsubscribe.</p>
|
74
|
+
</td>
|
75
|
+
<td class="right" width="50%" height="120" valign="top">
|
76
|
+
<p>Sent by <a href="http://example.com/" title="Test Co. web site">Test Co.</a><br />
|
77
|
+
Vancouver Island, BC, Canada</p>
|
78
|
+
</td>
|
79
|
+
</tr>
|
80
|
+
</table>
|
81
|
+
|
82
|
+
</td></tr></table><!-- / #frame -->
|
83
|
+
</div><!-- / #container -->
|
84
|
+
</body>
|
85
|
+
</html>
|
Binary file
|
Binary file
|
data/test/speed.rb
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
$LOAD_PATH.unshift(File.expand_path(File.dirname(__FILE__), '../css_parser/'))
|
2
|
+
$LOAD_PATH.unshift(File.expand_path(File.dirname(__FILE__), '../'))
|
3
|
+
|
4
|
+
|
5
|
+
|
6
|
+
|
7
|
+
require "benchmark"
|
8
|
+
require 'css_parser'
|
9
|
+
|
10
|
+
include Benchmark
|
11
|
+
|
12
|
+
|
13
|
+
|
14
|
+
css_block = {:declarations=>"color: #fff; background: #1c2815 none;", :selector=>"body", :specificity=>1},
|
15
|
+
{:declarations=>"color: #fff; background: #1c2815 none;", :selector=>"#container", :specificity=>100}
|
16
|
+
|
17
|
+
n = 10000
|
18
|
+
|
19
|
+
|
20
|
+
bm(12) do |test|
|
21
|
+
test.report("creating ruleset:") do
|
22
|
+
@cp = CssParser.new
|
23
|
+
n.times do |x|
|
24
|
+
@cp.fold_declarations(css_block)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
test.report("parsing in block:") do
|
28
|
+
@cp = CssParser.new
|
29
|
+
n.times do |x|
|
30
|
+
@cp.fold_declarations_old(css_block)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/test_helper'
|
2
|
+
require 'lib/html_to_plain_text'
|
3
|
+
|
4
|
+
class PlainTextTests < Test::Unit::TestCase
|
5
|
+
include HtmlToPlainText
|
6
|
+
|
7
|
+
def test_unordered_lists
|
8
|
+
html = %q{
|
9
|
+
<link rel="test" />
|
10
|
+
<ul>
|
11
|
+
<li class="123" id="456">Test 1</li>
|
12
|
+
<li>Test 2
|
13
|
+
<ul>
|
14
|
+
<li>Test 2a</li>
|
15
|
+
</ul>
|
16
|
+
</li>
|
17
|
+
<li>Test 3</li>
|
18
|
+
</ul>
|
19
|
+
}
|
20
|
+
text = %q{ * Test 1
|
21
|
+
* Test 2
|
22
|
+
* Test 2a
|
23
|
+
* Test 3}
|
24
|
+
|
25
|
+
assert_equal text, convert_to_text(html, 80)
|
26
|
+
end
|
27
|
+
|
28
|
+
|
29
|
+
|
30
|
+
end
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/test_helper'
|
2
|
+
|
3
|
+
|
4
|
+
class PremailerLinkResolverTests < Test::Unit::TestCase
|
5
|
+
def test_resolving_urls_from_string
|
6
|
+
['test.html', '/test.html', './test.html',
|
7
|
+
'test/../test.html', 'test/../test/../test.html'].each do |q|
|
8
|
+
assert_equal 'http://example.com/test.html', Premailer.resolve_link(q, 'http://example.com/'), q
|
9
|
+
end
|
10
|
+
|
11
|
+
assert_equal 'https://example.net:80/~basedir/test.html?var=1#anchor', Premailer.resolve_link('test/../test/../test.html?var=1#anchor', 'https://example.net:80/~basedir/')
|
12
|
+
end
|
13
|
+
|
14
|
+
def test_resolving_urls_from_uri
|
15
|
+
base_uri = URI.parse('http://example.com/')
|
16
|
+
['test.html', '/test.html', './test.html',
|
17
|
+
'test/../test.html', 'test/../test/../test.html'].each do |q|
|
18
|
+
assert_equal 'http://example.com/test.html', Premailer.resolve_link(q, base_uri), q
|
19
|
+
end
|
20
|
+
|
21
|
+
base_uri = URI.parse('https://example.net:80/~basedir/')
|
22
|
+
assert_equal 'https://example.net:80/~basedir/test.html?var=1#anchor', Premailer.resolve_link('test/../test/../test.html?var=1#anchor', base_uri)
|
23
|
+
end
|
24
|
+
|
25
|
+
def test_resolving_local_paths
|
26
|
+
base_dir = 'c:/root/'
|
27
|
+
['test.html', 'test/../test.html', './test.html',
|
28
|
+
'test/../test.html', 'test/../test/../test.html'].each do |q|
|
29
|
+
assert_equal 'c:/root/test.html', Premailer.resolve_link(q, base_dir), q
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/test_helper'
|
2
|
+
|
3
|
+
|
4
|
+
class PremailerTests < Test::Unit::TestCase
|
5
|
+
|
6
|
+
def setup
|
7
|
+
#@premailer = Premailer.new
|
8
|
+
end
|
9
|
+
|
10
|
+
def test_escaping_strings
|
11
|
+
str = %q{url("/images/test.png");}
|
12
|
+
assert "url(\'/images/test.png\');", Premailer.escape_string(str)
|
13
|
+
|
14
|
+
str = %q{url("/images/\"test.png");}
|
15
|
+
assert "url(\'/images/\'test.png\');", Premailer.escape_string(str)
|
16
|
+
|
17
|
+
str = %q{url('/images/\"test.png');}
|
18
|
+
assert "url(\'/images/\'test.png\');", Premailer.escape_string(str)
|
19
|
+
end
|
20
|
+
|
21
|
+
|
22
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/test_helper'
|
2
|
+
|
3
|
+
# Test cases for the CssParser's downloading functions.
|
4
|
+
class PremailerDownloadTest < Test::Unit::TestCase
|
5
|
+
include WEBrick
|
6
|
+
|
7
|
+
def setup
|
8
|
+
@uri_base = 'http://localhost:12000'
|
9
|
+
|
10
|
+
www_root = File.dirname(__FILE__) + '/fixtures/'
|
11
|
+
|
12
|
+
@server_thread = Thread.new do
|
13
|
+
s = WEBrick::HTTPServer.new(:Port => 12000, :DocumentRoot => www_root, :Logger => Log.new(nil, BasicLog::ERROR), :AccessLog => [])
|
14
|
+
@port = s.config[:Port]
|
15
|
+
begin
|
16
|
+
s.start
|
17
|
+
ensure
|
18
|
+
s.shutdown
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
sleep 1 # ensure the server has time to load
|
23
|
+
end
|
24
|
+
|
25
|
+
def teardown
|
26
|
+
@server_thread.kill
|
27
|
+
@server_thread.join(5)
|
28
|
+
@server_thread = nil
|
29
|
+
end
|
30
|
+
|
31
|
+
def test_loading_a_remote_file
|
32
|
+
@cp.load_uri!("#{@uri_base}/simple.css")
|
33
|
+
assert_equal 'margin: 0px;', @cp.find_by_selector('p').join(' ')
|
34
|
+
end
|
35
|
+
|
36
|
+
def test_following_at_import_rules
|
37
|
+
@cp.load_uri!("#{@uri_base}/import1.css")
|
38
|
+
|
39
|
+
# from '/import1.css'
|
40
|
+
assert_equal 'color: lime;', @cp.find_by_selector('div').join(' ')
|
41
|
+
|
42
|
+
# from '/subdir/import2.css'
|
43
|
+
assert_equal 'text-decoration: none;', @cp.find_by_selector('a').join(' ')
|
44
|
+
|
45
|
+
# from '/subdir/../simple.css'
|
46
|
+
assert_equal 'margin: 0px;', @cp.find_by_selector('p').join(' ')
|
47
|
+
end
|
48
|
+
|
49
|
+
def test_importing_with_media_types
|
50
|
+
@cp.load_uri!("#{@uri_base}/import-with-media-types.css")
|
51
|
+
|
52
|
+
# from simple.css with :screen media type
|
53
|
+
assert_equal 'margin: 0px;', @cp.find_by_selector('p', :screen).join(' ')
|
54
|
+
assert_equal '', @cp.find_by_selector('p', :tty).join(' ')
|
55
|
+
end
|
56
|
+
|
57
|
+
def test_throwing_circular_reference_exception
|
58
|
+
assert_raise CircularReferenceError do
|
59
|
+
@cp.load_uri!("#{@uri_base}/import-circular-reference.css")
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def test_toggling_not_found_exceptions
|
64
|
+
cp_with_exceptions = Parser.new(:io_exceptions => true)
|
65
|
+
|
66
|
+
assert_raise RemoteFileError do
|
67
|
+
cp_with_exceptions.load_uri!("#{@uri_base}/no-exist.xyz")
|
68
|
+
end
|
69
|
+
|
70
|
+
cp_without_exceptions = Parser.new(:io_exceptions => false)
|
71
|
+
|
72
|
+
assert_nothing_raised RemoteFileError do
|
73
|
+
cp_without_exceptions.load_uri!("#{@uri_base}/no-exist.xyz")
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
metadata
ADDED
@@ -0,0 +1,86 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: mikedamage-premailer-plus
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Mike Green
|
8
|
+
- Alex Dunae
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
|
13
|
+
date: 2009-05-24 00:00:00 -07:00
|
14
|
+
default_executable: premailer_plus
|
15
|
+
dependencies: []
|
16
|
+
|
17
|
+
description: Premailer Plus is a re-packaged, bugfixed and improved version of Alex Dunae's Premailer gem
|
18
|
+
email: mike.is.green@gmail.com
|
19
|
+
executables:
|
20
|
+
- premailer_plus
|
21
|
+
extensions: []
|
22
|
+
|
23
|
+
extra_rdoc_files:
|
24
|
+
- LICENSE
|
25
|
+
- README.textile
|
26
|
+
files:
|
27
|
+
- LICENSE
|
28
|
+
- README.textile
|
29
|
+
- Rakefile
|
30
|
+
- VERSION.yml
|
31
|
+
- bin/premailer_plus
|
32
|
+
- lib/html_to_plain_text.rb
|
33
|
+
- lib/premailer.rb
|
34
|
+
- test/fixtures/client_support.html
|
35
|
+
- test/fixtures/test-import.css
|
36
|
+
- test/fixtures/test-with-folding.html
|
37
|
+
- test/fixtures/test.css
|
38
|
+
- test/fixtures/test.html
|
39
|
+
- test/fixtures/test2.css
|
40
|
+
- test/fixtures/test2.html
|
41
|
+
- test/fixtures/test3-import.css
|
42
|
+
- test/fixtures/test3-noimport.css
|
43
|
+
- test/fixtures/test3-out.html
|
44
|
+
- test/fixtures/test3.css
|
45
|
+
- test/fixtures/test3.html
|
46
|
+
- test/images/content_bg.jpg
|
47
|
+
- test/images/inset.jpg
|
48
|
+
- test/speed.rb
|
49
|
+
- test/test_convert_to_plain_text.rb
|
50
|
+
- test/test_helper.rb
|
51
|
+
- test/test_link_resolver.rb
|
52
|
+
- test/test_premailer.rb
|
53
|
+
- test/test_premailer_download.rb
|
54
|
+
has_rdoc: true
|
55
|
+
homepage: http://github.com/mikedamage/premailer-plus
|
56
|
+
post_install_message:
|
57
|
+
rdoc_options:
|
58
|
+
- --charset=UTF-8
|
59
|
+
require_paths:
|
60
|
+
- lib
|
61
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
62
|
+
requirements:
|
63
|
+
- - ">="
|
64
|
+
- !ruby/object:Gem::Version
|
65
|
+
version: "0"
|
66
|
+
version:
|
67
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
68
|
+
requirements:
|
69
|
+
- - ">="
|
70
|
+
- !ruby/object:Gem::Version
|
71
|
+
version: "0"
|
72
|
+
version:
|
73
|
+
requirements: []
|
74
|
+
|
75
|
+
rubyforge_project:
|
76
|
+
rubygems_version: 1.2.0
|
77
|
+
signing_key:
|
78
|
+
specification_version: 3
|
79
|
+
summary: Miscellaneous improvements and fixes to Alex Dunae's Premailer gem
|
80
|
+
test_files:
|
81
|
+
- test/speed.rb
|
82
|
+
- test/test_convert_to_plain_text.rb
|
83
|
+
- test/test_helper.rb
|
84
|
+
- test/test_link_resolver.rb
|
85
|
+
- test/test_premailer.rb
|
86
|
+
- test/test_premailer_download.rb
|