premailer-1.8.6/0000755000175000017500000000000012703352566015005 5ustar balasankarcbalasankarcpremailer-1.8.6/init.rb0000644000175000017500000000002412703352566016271 0ustar balasankarcbalasankarcrequire 'premailer' premailer-1.8.6/.jrubyrc0000644000175000017500000000002212703352566016460 0ustar balasankarcbalasankarccext.enabled=true premailer-1.8.6/bin/0000755000175000017500000000000012703352566015555 5ustar balasankarcbalasankarcpremailer-1.8.6/bin/premailer0000755000175000017500000000022012703352566017455 0ustar balasankarcbalasankarc#!/usr/bin/env ruby # This binary used in rubygems environment only as part of installed gem require 'rubygems' require 'premailer/executor' premailer-1.8.6/local-premailer0000755000175000017500000000030112703352566017775 0ustar balasankarcbalasankarc#!/usr/bin/env ruby # This binary used only in development environment require 'rubygems' $LOAD_PATH.unshift(File.expand_path('./lib', File.dirname(__FILE__))) require 'premailer/executor' premailer-1.8.6/Gemfile0000644000175000017500000000067312703352566016306 0ustar balasankarcbalasankarcsource "https://rubygems.org" gem 'css_parser', :git => 'git://github.com/premailer/css_parser.git' gem 'webmock', :group => [:development, :test] platforms :jruby do gem 'jruby-openssl' end gemspec gem "ripper", :group => :development, :platforms => :mri_18 gem "coveralls", :require => false, :platforms => [:mri_19, :mri_20], :group => :development gem 'test-unit', :group => [:development, :test], :platforms => [:mri_20, :mri_22] premailer-1.8.6/gemfiles/0000755000175000017500000000000012703352566016600 5ustar balasankarcbalasankarcpremailer-1.8.6/gemfiles/.ruby187.gemfile0000644000175000017500000000114612703352566021433 0ustar balasankarcbalasankarcsource "https://rubygems.org" gem 'css_parser', '>= 1.3.5', :git => 'git://github.com/premailer/css_parser.git' gem 'webmock', :group => [:development, :test] gemspec :path => '..' gem "ripper", :group => :development, :platforms => :mri_18 gem "coveralls", :require => false, :platforms => [:mri_19, :mri_20], :group => :development # Gemspec dependencies gem 'htmlentities', [ '>= 4.0.0', '<= 4.3.1' ] gem 'bundler', '~> 1.3' gem 'rake', ['~> 0.8', '!= 0.9.0'] gem 'hpricot', '>= 0.8.3' gem 'nokogiri', '~> 1.5.10' gem 'yard', '~> 0.8.7' gem 'redcarpet', '~> 2.3.0' gem 'yard-redcarpet-ext', '~> 0.0.3'premailer-1.8.6/premailer.gemspec0000644000175000017500000000241212703352566020331 0ustar balasankarcbalasankarcGEM_ROOT = File.dirname(__FILE__).freeze unless defined?(GEM_ROOT) lib_path = File.expand_path('lib', GEM_ROOT) $LOAD_PATH.unshift(lib_path) unless $LOAD_PATH.include? lib_path require 'premailer/version' Gem::Specification.new do |s| s.name = "premailer" s.version = Premailer::VERSION.dup s.date = Time.now.strftime('%Y-%m-%d') s.summary = "Preflight for HTML e-mail." s.email = "code@dunae.ca" s.homepage = "http://premailer.dialect.ca/" s.description = "Improve the rendering of HTML emails by making CSS inline, converting links and warning about unsupported code." s.has_rdoc = true s.author = "Alex Dunae" s.files = `git ls-files`.split("\n") s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n") s.executables = `git ls-files -- bin/*`.split("\n").map { |f| File.basename(f) } s.add_dependency('css_parser', '>= 1.3.6') s.add_dependency('htmlentities', ['>= 4.0.0']) s.add_development_dependency "bundler", "~> 1.3" s.add_development_dependency('rake', ['~> 0.8', '!= 0.9.0']) s.add_development_dependency('hpricot', '>= 0.8.3') s.add_development_dependency('nokogiri', '>= 1.4.4') s.add_development_dependency('yard', '~> 0.8.7.6') s.add_development_dependency('redcarpet', '~> 3.0') end premailer-1.8.6/LICENSE.md0000644000175000017500000000274112703352566016415 0ustar balasankarcbalasankarc# Premailer License Copyright (c) 2007-2012, Alex Dunae. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Premailer, Alex Dunae nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. premailer-1.8.6/test/0000755000175000017500000000000012703352566015764 5ustar balasankarcbalasankarcpremailer-1.8.6/test/test_adapter.rb0000644000175000017500000000151212703352566020767 0ustar balasankarcbalasankarcrequire File.expand_path(File.dirname(__FILE__)) + '/helper' class TestAdapter < Premailer::TestCase def test_default_to_best_available require 'hpricot' assert_equal 'Premailer::Adapter::Hpricot', Premailer::Adapter.use.name end def test_settable_via_symbol Premailer::Adapter.use = :hpricot assert_equal 'Premailer::Adapter::Hpricot', Premailer::Adapter.use.name end def test_adapters_are_findable_by_symbol assert_equal 'Premailer::Adapter::Hpricot', Premailer::Adapter.find(:hpricot).name end def test_adapters_are_findable_by_class assert_equal 'Premailer::Adapter::Hpricot', Premailer::Adapter.find(Premailer::Adapter::Hpricot).name end def test_raises_argument_error assert_raises(ArgumentError, "Invalid adapter: unknown") { Premailer::Adapter.find(:unknown) } end end premailer-1.8.6/test/helper.rb0000644000175000017500000000232512703352566017572 0ustar balasankarcbalasankarc# encoding: utf-8 $:.unshift(File.expand_path(File.dirname(__FILE__) + '/../lib')) $:.unshift(File.expand_path(File.dirname(__FILE__) + '/../')) require 'rubygems' require 'test/unit' require 'webmock/test_unit' require 'premailer' class Premailer::TestCase < Test::Unit::TestCase BASE_URI = 'http://premailer.dev/' BASE_PATH = File.expand_path(File.dirname(__FILE__)) + '/files' def setup stub_request(:any, /premailer\.dev\/*/).to_return do |request| file_path = BASE_PATH + URI.parse(request.uri).path if File.exists?(file_path) { :status => 200, :body => File.open(file_path) } else { :status => 404, :body => "#{file_path} not found" } end end stub_request(:get, /my\.example\.com\:8080\/*/).to_return(:status => 200, :body => "", :headers => {}) end def default_test; end protected def local_setup(f = 'base.html', opts = {}) base_file = BASE_PATH + '/' + f premailer = Premailer.new(base_file, opts) premailer.to_inline_css @doc = premailer.processed_doc end def remote_setup(f = 'base.html', opts = {}) @premailer = Premailer.new(BASE_URI + "#{f}", opts) @premailer.to_inline_css @doc = @premailer.processed_doc end end premailer-1.8.6/test/test_links.rb0000644000175000017500000001662712703352566020504 0ustar balasankarcbalasankarc# encoding: UTF-8 require File.expand_path(File.dirname(__FILE__)) + '/helper' class TestLinks < Premailer::TestCase def test_empty_query_string assert_nothing_raised do premailer = Premailer.new('

Test

', :with_html_string => true, :link_query_string => ' ') premailer.to_inline_css end end def test_appending_link_query_string qs = 'utm_source=1234&tracking=good&doublescape' opts = {:base_url => 'http://example.com/', :link_query_string => qs, :with_html_string => true, :adapter => :hpricot} appendable = [ '/', opts[:base_url], 'https://example.com/tester', 'images/', "#{opts[:base_url]}test.html?cn=tf&c=20&ord=random", '?query=string' ] not_appendable = [ '%DONOTCONVERT%', '{DONOTCONVERT}', '[DONOTCONVERT]', '', '{@msg-txturl}', '[[!unsubscribe]]', '#relative', 'tel:5555551212', 'http://example.net/', 'mailto:premailer@example.com', 'ftp://example.com', 'gopher://gopher.floodgap.com/1/fun/twitpher' ] html = appendable.collect {|url| "Link" } premailer = Premailer.new(html.to_s, opts) premailer.to_inline_css premailer.processed_doc.search('a').each do |el| href = el.attributes['href'].to_s next if href.nil? or href.empty? uri = URI.parse(href) assert_match qs, uri.query, "missing query string for #{el.to_s}" end html = not_appendable.collect {|url| "Link" } premailer = Premailer.new(html.to_s, opts) premailer.to_inline_css premailer.processed_doc.search('a').each do |el| href = el['href'] next if href.nil? or href.empty? assert not_appendable.include?(href), "link #{href} should not be converted: see #{not_appendable.to_s}" end end def test_stripping_extra_question_marks_from_query_string qs = '??utm_source=1234' premailer = Premailer.new("Link Link", :link_query_string => qs, :with_html_string => true) premailer.to_inline_css premailer.processed_doc.search('a').each do |a| assert_equal '/test/?utm_source=1234', a['href'].to_s end premailer = Premailer.new("Link", :link_query_string => qs, :with_html_string => true) premailer.to_inline_css assert_equal '/test/?123&456&utm_source=1234', premailer.processed_doc.at('a')['href'] end def test_unescape_ampersand qs = 'utm_source=1234' premailer = Premailer.new("Link", :link_query_string => qs, :with_html_string => true, :unescaped_ampersand => true) premailer.to_inline_css premailer.processed_doc.search('a').each do |a| assert_equal '/test/?q=query&utm_source=1234', a['href'].to_s end end def test_preserving_links html = "Link" premailer = Premailer.new(html.to_s, :link_query_string => '', :with_html_string => true) premailer.to_inline_css assert_equal 'http://example.com/index.php?pram1=one&pram2=two', premailer.processed_doc.at('a')['href'] html = "Link" premailer = Premailer.new(html.to_s, :link_query_string => 'qs', :with_html_string => true) premailer.to_inline_css assert_equal 'http://example.com/index.php?pram1=one&pram2=two&qs', premailer.processed_doc.at('a')['href'] end def test_resolving_urls_from_string ['test.html', '/test.html', './test.html', 'test/../test.html', 'test/../test/../test.html'].each do |q| assert_equal 'http://example.com/test.html', Premailer.resolve_link(q, 'http://example.com/'), q end 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/') end def test_resolving_urls_from_uri base_uri = URI.parse('http://example.com/') ['test.html', '/test.html', './test.html', 'test/../test.html', 'test/../test/../test.html'].each do |q| assert_equal 'http://example.com/test.html', Premailer.resolve_link(q, base_uri), q end base_uri = URI.parse('https://example.net:80/~basedir/') assert_equal 'https://example.net:80/~basedir/test.html?var=1#anchor', Premailer.resolve_link('test/../test/../test.html?var=1#anchor', base_uri) # base URI with a query string base_uri = URI.parse('http://example.com/dir/index.cfm?newsletterID=16') assert_equal 'http://example.com/dir/index.cfm?link=15', Premailer.resolve_link('?link=15', base_uri) # URI preceded by a space base_uri = URI.parse('http://example.com/') assert_equal 'http://example.com/path', Premailer.resolve_link(' path', base_uri) end def test_resolving_urls_from_html_string # The inner URI is on its own line to ensure that the impl doesn't match # URIs based on start of line. base_uri = "\nhttp://example.com/\n" ['test.html', '/test.html', './test.html', 'test/../test.html', 'test/../test/../test.html'].each do |q| assert_nothing_raised do Premailer.resolve_link(q, base_uri) end end end def test_resolving_urls_in_doc # force Nokogiri since this consistenly segfaults with Hpricot base_file = File.dirname(__FILE__) + '/files/base.html' base_url = 'https://my.example.com:8080/test-path.html' premailer = Premailer.new(base_file, :base_url => base_url, :adapter => :nokogiri) premailer.to_inline_css pdoc = premailer.processed_doc doc = premailer.doc # unchanged links ['#l02', '#l03', '#l05', '#l06', '#l07', '#l08', '#l09', '#l10', '#l11', '#l12', '#l13'].each do |link_id| assert_equal doc.at(link_id).attributes['href'], pdoc.at(link_id).attributes['href'], link_id end assert_equal 'https://my.example.com:8080/', pdoc.at('#l01').attributes['href'].to_s assert_equal 'https://my.example.com:8080/images/', pdoc.at('#l04').attributes['href'].to_s end def test_convertable_inline_links convertable = [ 'my/path/to', 'other/path', '/' ] html = convertable.collect {|url| "Link" } premailer = Premailer.new(html.to_s, :base_url => "http://example.com", :with_html_string => true) premailer.processed_doc.search('a').each do |el| href = el.attributes['href'].to_s assert(href =~ /http:\/\/example.com/, "link #{href} is not absolute") end end def test_non_convertable_inline_links not_convertable = [ '%DONOTCONVERT%', '{DONOTCONVERT}', '[DONOTCONVERT]', '', '{@msg-txturl}', '[[!unsubscribe]]', '#relative', 'tel:5555551212', 'mailto:premailer@example.com', 'ftp://example.com', 'gopher://gopher.floodgap.com/1/fun/twitpher', 'cid:13443452066.10392logo.jpeg@inline_attachment' ] html = not_convertable.collect {|url| "Link" } premailer = Premailer.new(html.to_s, :base_url => "example.com", :with_html_string => true) premailer.to_inline_css premailer.processed_doc.search('a').each do |el| href = el.attributes['href'].to_s assert not_convertable.include?(href), "link #{href} should not be converted: see #{not_convertable.inspect}" end end end premailer-1.8.6/test/test_misc.rb0000644000175000017500000002565512703352566020320 0ustar balasankarcbalasankarc# encoding: UTF-8 require File.expand_path(File.dirname(__FILE__)) + '/helper' # Random tests for specific issues. # # The test suite will be cleaned up at some point soon. class TestMisc < Premailer::TestCase # in response to http://github.com/alexdunae/premailer/issues#issue/4 # # NB: 2010-11-16 -- after reverting to Hpricot this test can no longer pass. # It's too much of an edge case to get any dev time. def test_parsing_extra_quotes io = StringIO.new('

Writes and Resources

') premailer = Premailer.new(io, :adapter => :nokogiri) assert_match /

[\s]*[\s]*<\/a>[\s]*Writes and Resources[\s]*<\/h3>/i, premailer.to_inline_css end def test_styles_in_the_body html = <

Test

END_HTML premailer = Premailer.new(html, :with_html_string => true) premailer.to_inline_css assert_match /color\: red/i, premailer.processed_doc.at('p')['style'] end def test_commented_out_styles_in_the_body html = <

Test

END_HTML premailer = Premailer.new(html, :with_html_string => true) premailer.to_inline_css assert_match /color\: red/i, premailer.processed_doc.at('p')['style'] end def test_not_applying_styles_to_the_head html = < Title

Test

END_HTML [:nokogiri, :hpricot].each do |adapter| premailer = Premailer.new(html, :with_html_string => true, :adapter => adapter) premailer.to_inline_css h = premailer.processed_doc.at('head') assert_nil h['style'] t = premailer.processed_doc.at('title') assert_nil t['style'] end end def test_multiple_identical_ids html = <<-END_HTML

Test

Test

END_HTML premailer = Premailer.new(html, :with_html_string => true) premailer.to_inline_css premailer.processed_doc.search('p').each do |el| assert_match /red/i, el['style'] end end def test_preserving_styles html = <

Test

END_HTML [:nokogiri, :hpricot].each do |adapter| premailer = Premailer.new(html, :with_html_string => true, :preserve_styles => true, :adapter => adapter) premailer.to_inline_css assert_equal 1, premailer.processed_doc.search('head link').length assert_equal 1, premailer.processed_doc.search('head style').length premailer = Premailer.new(html, :with_html_string => true, :preserve_styles => false, :adapter => adapter) premailer.to_inline_css assert_nil premailer.processed_doc.at('body link') # should be preserved as unmergeable assert_match /color: red/i, premailer.processed_doc.at('body style').inner_html assert_match /a:hover/i, premailer.processed_doc.at('style').inner_html end end def test_unmergable_rules html = <

Test

END_HTML premailer = Premailer.new(html, :with_html_string => true, :verbose => true) premailer.to_inline_css # blue should be inlined assert_no_match /a\:hover[\s]*\{[\s]*color\:[\s]*blue[\s]*;[\s]*\}/i, premailer.processed_doc.at('body style').inner_html # red should remain in

Test

END_HTML [:nokogiri, :hpricot].each do |adapter| puts "------- Testing adapter #{adapter}" premailer = Premailer.new(html, :with_html_string => true, :adapter => adapter) puts premailer.to_inline_css style_tag = premailer.processed_doc.at('body style') assert style_tag, "#{adapter} failed to add a body style tag" style_tag_contents = style_tag.inner_html assert_equal "color: blue", premailer.processed_doc.at('a').attributes['style'].to_s, "#{adapter}: Failed to inline the default style" assert_match /@media \(min-width:500px\) \{.*?a \{.*?color: red;.*?\}.*?\}/m, style_tag_contents, "#{adapter}: Failed to add media query with no type to style" assert_match /@media screen and \(orientation: portrait\) \{.*?a \{.*?color: green;.*?\}.*?\}/m, style_tag_contents, "#{adapter}: Failed to add media query with type to style" end end def test_unmergable_rules_with_no_body html = <

Test

END_HTML premailer = Premailer.new(html, :with_html_string => true) assert_nothing_raised do premailer.to_inline_css end assert_match /a\:hover[\s]*\{[\s]*color\:[\s]*red;[\s]*\}/i, premailer.processed_doc.at('style').inner_html end # in response to https://github.com/alexdunae/premailer/issues#issue/7 def test_ignoring_link_pseudo_selectors html = < Test END_HTML premailer = Premailer.new(html, :with_html_string => true) assert_nothing_raised do premailer.to_inline_css end assert_match /color: red/, premailer.processed_doc.at('a').attributes['style'].to_s end # in response to https://github.com/alexdunae/premailer/issues#issue/7 # # fails sometimes in JRuby, see https://github.com/alexdunae/premailer/issues/79 def test_parsing_bad_markup_around_tables html = < PROMOCION CURSOS PRESENCIALES END_HTML premailer = Premailer.new(html, :with_html_string => true) premailer.to_inline_css assert_match /font-size: xx-large/, premailer.processed_doc.search('.style3').first.attributes['style'].to_s assert_match /background: #000080/, premailer.processed_doc.search('.style5').first.attributes['style'].to_s end # in response to https://github.com/alexdunae/premailer/issues/56 def test_inline_important html = <

test

END_HTML premailer = Premailer.new(html, :with_html_string => true, :adapter => :nokogiri) premailer.to_inline_css assert_equal 'color: green !important', premailer.processed_doc.search('p').first.attributes['style'].to_s end # in response to https://github.com/alexdunae/premailer/issues/28 def test_handling_shorthand_auto_properties html = <

test

END_HTML premailer = Premailer.new(html, :with_html_string => true) premailer.to_inline_css assert_match /margin: 0 auto/, premailer.processed_doc.search('#page').first.attributes['style'].to_s assert_match /border-style: solid none solid solid;/, premailer.processed_doc.search('p').first.attributes['style'].to_s end def test_sorting_style_attributes html = <
test
END_HTML premailer = Premailer.new(html, :with_html_string => true) premailer.to_inline_css assert_equal "left: 5px; right: 10px", premailer.processed_doc.search('#page').first.attributes['style'].to_s end def test_removing_scripts html = < content END_HTML [:nokogiri, :hpricot].each do |adapter| premailer = Premailer.new(html, :with_html_string => true, :remove_scripts => true, :adapter => adapter) premailer.to_inline_css assert_equal 0, premailer.processed_doc.search('script').length end [:nokogiri, :hpricot].each do |adapter| premailer = Premailer.new(html, :with_html_string => true, :remove_scripts => false, :adapter => adapter) premailer.to_inline_css assert_equal 1, premailer.processed_doc.search('script').length end end def test_strip_important_from_attributes html = <
red
END_HTML [:nokogiri, :hpricot].each do |adapter| premailer = Premailer.new(html, :with_html_string => true, :adapter => adapter) assert_match 'bgcolor="#FF0000"', premailer.to_inline_css end end def test_scripts_with_nokogiri html = < END_HTML premailer = Premailer.new(html, :with_html_string => true, :remove_scripts => false, :adapter => :nokogiri) premailer.to_inline_css assert !premailer.processed_doc.css('script[type="application/ld+json"]').first.children.first.cdata? end end premailer-1.8.6/test/test_html_to_plain_text.rb0000644000175000017500000001531412703352566023251 0ustar balasankarcbalasankarc# encoding: utf-8 require File.expand_path(File.dirname(__FILE__)) + '/helper' class TestHtmlToPlainText < Premailer::TestCase include HtmlToPlainText def test_to_plain_text_with_fragment premailer = Premailer.new('

Test

', :with_html_string => true) assert_match /Test/, premailer.to_plain_text end def test_to_plain_text_with_body html = < Ignore me

Test

END_HTML premailer = Premailer.new(html, :with_html_string => true) assert_match /Test/, premailer.to_plain_text end def test_to_plain_text_with_malformed_body html = < Ignore me

Test END_HTML premailer = Premailer.new(html, :with_html_string => true) assert_match /Test/, premailer.to_plain_text end def test_specialchars assert_plaintext 'cédille garçon & à ñ', 'cédille garçon & à ñ' end def test_stripping_whitespace assert_plaintext "text\ntext", " \ttext\ntext\n" assert_plaintext "a\na", " \na \n a \t" assert_plaintext "a\n\na", " \na \n\t \n \n a \t" assert_plaintext "test text", "test text " assert_plaintext "test text", "test text" end def test_wrapping_spans html = <

Test line 2

END_HTML premailer = Premailer.new(html, :with_html_string => true) assert_match /Test line 2/, premailer.to_plain_text end def test_line_breaks assert_plaintext "Test text\nTest text", "Test text\r\nTest text" assert_plaintext "Test text\nTest text", "Test text\rTest text" end def test_lists assert_plaintext "* item 1\n* item 2", "
  • item 1
  • item 2
  • \n" assert_plaintext "* item 1\n* item 2\n* item 3", "
  • item 1
  • \t\n
  • item 2
  • item 3
  • \n" end def test_stripping_html assert_plaintext 'test text', "

    test text\n" end def test_stripping_ignored_blocks html = <test

    logo

    text

    END_HTML premailer = Premailer.new(html, :with_html_string => true) assert_match /test\n\ntext/, premailer.to_plain_text end def test_paragraphs_and_breaks assert_plaintext "Test text\n\nTest text", "

    Test text

    Test text

    " assert_plaintext "Test text\n\nTest text", "\n

    Test text

    \n\n\n\t

    Test text

    \n" assert_plaintext "Test text\nTest text", "\n

    Test text
    Test text

    \n" assert_plaintext "Test text\nTest text", "\n

    Test text
    \tTest text

    \n" assert_plaintext "Test text\n\nTest text", "Test text

    Test text" end def test_headings assert_plaintext "****\nTest\n****", "

    Test

    " assert_plaintext "****\nTest\n****", "\t

    \nTest

    " assert_plaintext "***********\nTest line 1\nTest 2\n***********", "\t

    \nTest line 1
    Test 2

    " assert_plaintext "****\nTest\n****\n\n****\nTest\n****", "

    Test

    Test

    " assert_plaintext "----\nTest\n----", "

    Test

    " assert_plaintext "Test\n----", "

    Test

    " end def test_wrapping_lines raw = '' 100.times { raw += 'test ' } txt = convert_to_text(raw, 20) lens = [] txt.each_line { |l| lens << l.length } assert lens.max <= 20 end def test_img_alt_tags # ensure html imag tags that aren't self-closed are parsed, # along with accepting both '' and "" as attribute quotes # assert_plaintext 'Example ( http://example.com/ )', 'Example' # assert_plaintext 'Example ( http://example.com/ )', 'Example' # assert_plaintext 'Example ( http://example.com/ )', "Example" # assert_plaintext 'Example ( http://example.com/ )', "Example" end def test_links # basic assert_plaintext 'Link ( http://example.com/ )', 'Link' # nested html assert_plaintext 'Link ( http://example.com/ )', 'Link' # nested html with new line assert_plaintext 'Link ( http://example.com/ )', "\n\tLink\n\t" # mailto assert_plaintext 'Contact Us ( contact@example.org )', "Contact Us" # complex link assert_plaintext 'Link ( http://example.com:80/~user?aaa=bb&c=d,e,f#foo )', 'Link' # attributes assert_plaintext 'Link ( http://example.com/ )', 'Link' # spacing assert_plaintext 'Link ( http://example.com/ )', ' Link ' # multiple assert_plaintext 'Link A ( http://example.com/a/ ) Link B ( http://example.com/b/ )', 'Link A Link B' # merge links assert_plaintext 'Link ( %%LINK%% )', 'Link' assert_plaintext 'Link ( [LINK] )', 'Link' assert_plaintext 'Link ( {LINK} )', 'Link' # unsubscribe assert_plaintext 'Link ( [[!unsubscribe]] )', 'Link' # empty link gets dropped, and shouldn't run forever assert_plaintext(("This is some more text\n\n" * 14 + "This is some more text"), "#{"\n

    This is some more text

    " * 15}") end # see https://github.com/alexdunae/premailer/issues/72 def test_multiple_links_per_line assert_plaintext 'This is link1 ( http://www.google.com ) and link2 ( http://www.google.com ) is next.', '

    This is link1 and link2 is next.

    ', nil, 10000 end # see https://github.com/alexdunae/premailer/issues/72 def test_links_within_headings assert_plaintext "****************************\nTest ( http://example.com/ )\n****************************", "

    Test

    " end def assert_plaintext(out, raw, msg = nil, line_length = 65) assert_equal out, convert_to_text(raw, line_length), msg end end premailer-1.8.6/test/test_premailer.rb0000644000175000017500000003177012703352566021340 0ustar balasankarcbalasankarc# -*- encoding: UTF-8 -*- require File.expand_path(File.dirname(__FILE__)) + '/helper' class TestPremailer < Premailer::TestCase def test_special_characters_nokogiri html = '

    cédille cé & garçon garçon à à   & ©

    ' premailer = Premailer.new(html, :with_html_string => true, :adapter => :nokogiri) premailer.to_inline_css assert_equal 'cédille cé & garçon garçon à à   & ©', premailer.processed_doc.at('p').inner_html end def test_special_characters_nokogiri_remote remote_setup('chars.html', :adapter => :nokogiri) @premailer.to_inline_css assert_equal 'cédille cé & garçon garçon à à   & ©', @premailer.processed_doc.at('p').inner_html end #def test_cyrillic_nokogiri_remote # if RUBY_VERSION =~ /1.9/ # remote_setup('iso-8859-5.html', :adapter => :nokogiri) #, :encoding => 'iso-8859-5') # @premailer.to_inline_css # assert_equal Encoding.find('ISO-8859-5'), @premailer.processed_doc.at('p').inner_html.encoding # end #end # TODO: this passes when run from rake but not when run from: # ruby -Itest test/test_premailer.rb -n test_special_characters_hpricot def test_special_characters_hpricot html = '

    cédille cé & garçon garçon à à   &

    ' premailer = Premailer.new(html, :with_html_string => true, :adapter => :hpricot) premailer.to_inline_css assert_equal 'cédille cé & garçon garçon à à   &', premailer.processed_doc.at('p').inner_html end def test_detecting_html [:nokogiri, :hpricot].each do |adapter| remote_setup('base.html', :adapter => adapter) assert !@premailer.is_xhtml? end end def test_detecting_xhtml [:nokogiri, :hpricot].each do |adapter| remote_setup('xhtml.html', :adapter => adapter) assert @premailer.is_xhtml? end end def test_self_closing_xhtml_tags [:nokogiri, :hpricot].each do |adapter| remote_setup('xhtml.html', :adapter => adapter) assert_match //, @premailer.to_s assert_match //, @premailer.to_inline_css end end def test_non_self_closing_html_tags [:nokogiri, :hpricot].each do |adapter| remote_setup('html4.html', :adapter => adapter) assert_match /
    /, @premailer.to_s assert_match /
    /, @premailer.to_inline_css end end def test_mailtos_with_query_strings html = < Test END_HTML qs = 'testing=123' [:nokogiri, :hpricot].each do |adapter| premailer = Premailer.new(html, :with_html_string => true, :link_query_string => qs, :adapter => adapter) premailer.to_inline_css assert_no_match /testing=123/, premailer.processed_doc.search('a').first.attributes['href'].to_s end end def test_escaping_strings local_setup str = %q{url("/images/test.png");} assert_equal("url(\'/images/test.png\');", Premailer.escape_string(str)) end def test_preserving_ignored_style_elements [:nokogiri, :hpricot].each do |adapter| local_setup('ignore.html', :adapter => adapter) assert_nil @doc.at('h1')['style'] end end def test_preserving_ignored_link_elements [:nokogiri, :hpricot].each do |adapter| local_setup('ignore.html', :adapter => adapter) assert_nil @doc.at('body')['style'] end end def test_importing_local_css # , :hpricot [:nokogiri].each do |adapter| local_setup('base.html', :adapter => adapter) # noimport.css (print stylesheet) sets body { background } to red assert_no_match /red/, @doc.at('body').attributes['style'].to_s # import.css sets .hide to { display: none } assert_match /display: none/, @doc.at('#hide01').attributes['style'].to_s end end def test_importing_remote_css [:nokogiri, :hpricot].each do |adapter| remote_setup('base.html', :adapter => adapter) # noimport.css (print stylesheet) sets body { background } to red assert_no_match /red/, @doc.at('body')['style'] # import.css sets .hide to { display: none } assert_match /display: none/, @doc.at('#hide01')['style'] end end def test_importing_css_as_string files_base = File.expand_path(File.dirname(__FILE__)) + '/files/' css_string = IO.read(File.join(files_base, 'import.css')) [:nokogiri, :hpricot].each do |adapter| premailer = Premailer.new(File.join(files_base, 'no_css.html'), {:css_string => css_string, :adapter => adapter}) premailer.to_inline_css @doc = premailer.processed_doc # import.css sets .hide to { display: none } assert_match /display: none/, @doc.at('#hide01')['style'] end end def test_local_remote_check assert Premailer.local_data?( StringIO.new('a') ) assert Premailer.local_data?( '/path/' ) assert !Premailer.local_data?( 'http://example.com/path/' ) # the old way is deprecated but should still work premailer = Premailer.new( StringIO.new('a') ) assert premailer.local_uri?( '/path/' ) end def test_initialize_can_accept_io_object [:nokogiri, :hpricot].each do |adapter| io = StringIO.new('hi mom') premailer = Premailer.new(io, :adapter => adapter) assert_match /hi mom/, premailer.to_inline_css end end def test_initialize_can_accept_html_string [:nokogiri, :hpricot].each do |adapter| premailer = Premailer.new('

    test

    ', :with_html_string => true, :adapter => adapter) assert_match /test/, premailer.to_inline_css end end def test_initialize_no_escape_attributes_option html = < Google Link END_HTML [:nokogiri, :hpricot].each do |adapter| pm = Premailer.new(html, :with_html_string => true, :adapter => adapter, :escape_url_attributes => false) pm.to_inline_css doc = pm.processed_doc assert_equal doc.at('#google')['href'], 'http://google.com' assert_equal doc.at('#noescape')['href'], '{{link_url}}' end end def test_remove_ids html = <

    Test

    Test

    END_HTML [:nokogiri, :hpricot].each do |adapter| pm = Premailer.new(html, :with_html_string => true, :remove_ids => true, :adapter => adapter) pm.to_inline_css doc = pm.processed_doc assert_nil doc.at('#remove') assert_nil doc.at('#keep') hashed_id = doc.at('a')['href'][1..-1] assert_not_nil doc.at("\##{hashed_id}") end end def test_reset_contenteditable html = <<-___
    Test
    ___ [:nokogiri, :hpricot].each do |adapter| pm = Premailer.new(html, :with_html_string => true, :reset_contenteditable => true, :adapter => adapter) pm.to_inline_css doc = pm.processed_doc assert_nil doc.at('#editable')['contenteditable'], "#{adapter}: contenteditable attribute not removed" end end def test_carriage_returns_as_entities html = <<-html \n\r

    test

    \n\r

    test

    html [:nokogiri, :hpricot].each do |adapter| pm = Premailer.new(html, :with_html_string => true, :adapter => adapter) assert_match /\r/, pm.to_inline_css end end def test_advanced_selectors remote_setup('base.html', :adapter => :nokogiri) assert_match /italic/, @doc.at('h2 + h3')['style'] assert_match /italic/, @doc.at('p[attr~=quote]')['style'] assert_match /italic/, @doc.at('ul li:first-of-type')['style'] remote_setup('base.html', :adapter => :hpricot) assert_match /italic/, @doc.at('p[@attr~="quote"]')['style'] assert_match /italic/, @doc.at('ul li:first-of-type')['style'] end def test_premailer_related_attributes html = <
    Test
    END_HTML [:nokogiri, :hpricot].each do |adapter| pm = Premailer.new(html, :with_html_string => true, :adapter => adapter) pm.to_inline_css doc = pm.processed_doc assert_equal '500', doc.at('table')['width'] assert_equal '20', doc.at('td')['height'] end end def test_include_link_tags_option local_setup('base.html', :adapter => :nokogiri, :include_link_tags => true) assert_match /1\.231/, @doc.at('body').attributes['style'].to_s assert_match /display: none/, @doc.at('.hide').attributes['style'].to_s local_setup('base.html', :adapter => :nokogiri, :include_link_tags => false) assert_no_match /1\.231/, @doc.at('body').attributes['style'].to_s assert_match /display: none/, @doc.at('.hide').attributes['style'].to_s end def test_include_style_tags_option local_setup('base.html', :adapter => :nokogiri, :include_style_tags => true) assert_match /1\.231/, @doc.at('body').attributes['style'].to_s assert_match /display: block/, @doc.at('#iphone').attributes['style'].to_s local_setup('base.html', :adapter => :nokogiri, :include_style_tags => false) assert_match /1\.231/, @doc.at('body').attributes['style'].to_s assert_no_match /display: block/, @doc.at('#iphone').attributes['style'].to_s end def test_input_encoding html_special_characters = "Ää, Öö, Üü" expected_html = "\n

    " + html_special_characters + "

    \n" pm = Premailer.new(html_special_characters, :with_html_string => true, :adapter => :nokogiri, :input_encoding => "UTF-8") assert_equal expected_html, pm.to_inline_css end # output_encoding option should return HTML Entities when set to US-ASCII def test_output_encoding html_special_characters = "©" html_entities_characters = "©" expected_html = "\n

    " + html_entities_characters + "

    \n" pm = Premailer.new(html_special_characters, :output_encoding => "US-ASCII", :with_html_string => true, :adapter => :nokogiri, :input_encoding => "UTF-8"); assert_equal expected_html, pm.to_inline_css end def test_meta_encoding_downcase meta_encoding = '' expected_html = Regexp.new(Regexp.escape(''), Regexp::IGNORECASE) pm = Premailer.new(meta_encoding, :with_html_string => true, :adapter => :nokogiri, :input_encoding => "utf-8") assert_match expected_html, pm.to_inline_css end def test_meta_encoding_upcase meta_encoding = '' expected_html = Regexp.new(Regexp.escape(''), Regexp::IGNORECASE) pm = Premailer.new(meta_encoding, :with_html_string => true, :adapter => :nokogiri, :input_encoding => "UTF-8") assert_match expected_html, pm.to_inline_css end def test_htmlentities html_entities = "’" expected_html = "\n

    '

    \n" pm = Premailer.new(html_entities, :with_html_string => true, :adapter => :nokogiri, :replace_html_entities => true) assert_equal expected_html, pm.to_inline_css end # If a line other than the first line in the html string begins with a URI # Premailer should not identify the html string as a URI. Otherwise the following # exception would be raised: ActionView::Template::Error: bad URI(is not URI?) def test_line_starting_with_uri_in_html_with_linked_css files_base = File.expand_path(File.dirname(__FILE__)) + '/files/' html_string = IO.read(File.join(files_base, 'html_with_uri.html')) assert_nothing_raised do premailer = Premailer.new(html_string, :with_html_string => true) premailer.to_inline_css end end def test_empty_html_nokogiri html = "" css = "a:hover {color:red;}" assert_nothing_raised do pm = Premailer.new(html, :with_html_string => true, :css_string => css, :adapter => :nokogiri) pm.to_inline_css end end end premailer-1.8.6/test/test_warnings.rb0000644000175000017500000000504412703352566021203 0ustar balasankarcbalasankarc# encoding: UTF-8 require File.expand_path(File.dirname(__FILE__)) + '/helper' class TestWarnings < Premailer::TestCase def test_element_warnings html = <
    Test
    END_HTML [:nokogiri, :hpricot].each do |adapter| warnings = get_warnings(html, adapter) assert_equal 2, warnings.length assert warnings.any? { |w| w[:message] == 'form HTML element'} assert warnings.any? { |w| w[:message] == 'link HTML element'} end end def test_css_warnings html = <
    Test
    END_HTML [:nokogiri, :hpricot].each do |adapter| warnings = get_warnings(html, adapter) assert_equal 2, warnings.length assert warnings.any? { |w| w[:message] == 'height CSS property'} assert warnings.any? { |w| w[:message] == 'margin CSS property'} end end def test_css_aliased_warnings html = <
    Test
    END_HTML [:nokogiri, :hpricot].each do |adapter| warnings = get_warnings(html, adapter) assert_equal 1, warnings.length assert warnings.any? { |w| w[:message] == 'margin-top CSS property'} end end def test_attribute_warnings html = < END_HTML [:nokogiri, :hpricot].each do |adapter| warnings = get_warnings(html, adapter) assert_equal 1, warnings.length assert warnings.any? { |w| w[:message] == 'ismap HTML attribute'} end end def test_warn_level html = <
    Test
    END_HTML [:nokogiri, :hpricot].each do |adapter| warnings = get_warnings(html, adapter, Premailer::Warnings::SAFE) assert_equal 2, warnings.length end [:nokogiri, :hpricot].each do |adapter| warnings = get_warnings(html, adapter, Premailer::Warnings::POOR) assert_equal 1, warnings.length end end protected def get_warnings(html, adapter = :nokogiri, warn_level = Premailer::Warnings::SAFE) pm = Premailer.new(html, {:adpater => adapter, :with_html_string => true, :warn_level => warn_level}) pm.to_inline_css pm.check_client_support end end premailer-1.8.6/test/future_tests.rb0000644000175000017500000000312112703352566021042 0ustar balasankarcbalasankarc# encoding: UTF-8 require File.expand_path(File.dirname(__FILE__)) + '/helper' class TestPremailer < Premailer::TestCase def test_related_attributes flunk 'Not implemented' local_setup # h1 { text-align: center; } assert_equal 'center', @doc.at('h1')['align'] # td { vertical-align: top; } assert_equal 'top', @doc.at('td')['valign'] # p { vertical-align: top; } -- not allowed assert_nil @doc.at('p')['valign'] # no align attr is specified for

    elements, so it should not appear assert_nil @doc.at('p.unaligned')['align'] # .contact { background: #9EC03B url("contact_bg.png") repeat 0 0; } assert_equal '#9EC03B', @doc.at('td.contact')['bgcolor'] # body { background-color: #9EBF00; } assert_equal '#9EBF00', @doc.at('body')['bgcolor'] end def test_merging_cellpadding flunk 'Not implemented' local_setup('cellpadding.html', {:prefer_cellpadding => true}) assert_equal '0', @doc.at('#t1')['cellpadding'] assert_match /padding\:/i, @doc.at('#t1 td')['style'] assert_equal '5', @doc.at('#t2')['cellpadding'] assert_no_match /padding\:/i, @doc.at('#t2 td')['style'] assert_nil @doc.at('#t3')['cellpadding'] assert_match /padding\:/i, @doc.at('#t3 td')['style'] assert_nil @doc.at('#t4')['cellpadding'] assert_match /padding\:/i, @doc.at('#t4a')['style'] assert_match /padding\:/i, @doc.at('#t4b')['style'] end def test_preserving_media_queries flunk 'Not implemented' local_setup assert_match /display\: none/i, @doc.at('#iphone')['style'] end end premailer-1.8.6/test/files/0000755000175000017500000000000012703352566017066 5ustar balasankarcbalasankarcpremailer-1.8.6/test/files/iso-8859-2.html0000644000175000017500000000011212703352566021312 0ustar balasankarcbalasankarcIn Hungary we use some special accented characters: . premailer-1.8.6/test/files/base.html0000644000175000017500000001306612703352566020674 0ustar balasankarcbalasankarc Premailer Test

    This line should be hidden.

    This is an iPhone style.

    Having trouble reading this newsletter? Click here to see it in your browser
     
       

    Premailer Test

     

    Lorem ipsum dolor

    Suspendisse id velit vitae ligula volutpat condimentum

    Morbi commodo, ipsum sed

    ImageLorem ipsum dolor sit amet, consectetuer adipiscing elit. Morbi commodo, ipsum sed pharetra gravida, orci magna rhoncus neque, id pulvinar odio lorem non turpis. Nullam sit amet enim. Suspendisse id velit vitae ligula volutpat condimentum. Aliquam erat volutpat. Sed quis velit. Nulla facilisi. Nulla libero.

    Here’s a quote. Here’s a quote. “Here’s a quote in quotes”.

    Nullam sit amet enim. Suspendisse id velit vitae ligula volutpat condimentum. Aliquam erat volutpat. Sed quis velit. Nulla facilisi.

    Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Morbi commodo, ipsum sed pharetra gravida, orci magna rhoncus neque, id pulvinar odio lorem non turpis. Nullam sit amet enim. Suspendisse id velit vitae ligula volutpat condimentum. Aliquam erat volutpat. Sed quis velit. Nulla facilisi. Nulla libero.

    “Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Morbi commodo, ipsum sed pharetra gravida, orci magna rhoncus neque, id pulvinar odio lorem non turpis.”

    Aliquam erat volutpat. Sed quis velit. Nulla facilisi. Nulla libero.

    Link tests

    Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Morbi commodo, ipsum sed pharetra gravida, orci magna rhoncus neque, id pulvinar odio lorem non turpis.

     

     

    ---

       
     
     
     

    Premailer Test
    by Dialect
    Vancouver Island, British Columbia
    250 555.2222

     
     
     
         
     
     
    Newsletter communications by
    Dialect
    Click here to unsubscribe
    premailer-1.8.6/test/files/noimport.css0000644000175000017500000000042112703352566021444 0ustar balasankarcbalasankarc/* * Premailer styles - should not import * * Copyright (c) 2009 Dialect Communications Group (dialect.ca) * * $Package: Premailer $ * $Date: 2009-02-09 17:15:56 -0800 (Mon, 09 Feb 2009) $WCDATE$ $ * $Rev: 95 $WCREV$ $ */ body { background: none red !important; }premailer-1.8.6/test/files/inc/0000755000175000017500000000000012703352566017637 5ustar balasankarcbalasankarcpremailer-1.8.6/test/files/inc/2009-placeholder.png0000644000175000017500000000156312703352566023224 0ustar balasankarcbalasankarcPNG  IHDR\tEXtSoftwareAdobe ImageReadyqe<IDATxNAafwA)1$?ijw6,;3`ljJM e4nO̙ B=*|gqk\^{-GKs} !$GF{uyZ޺1z=M ѥYVLwRJ siR9gC|jYrD GrD Gr9"G#r9"G#r9"G#r9#9#9#9A2;|͇Z>×ɑIղAAA GrD GrD GrD G#r9"GxbʑH)AAA GrD GrD GrD G#r9"G#r9"G#r9"G#9#9#9#AAArD GrD GrD Gr9"G#r9"G#r9"G#r4rD GrD GrD G#r9"G#r9"G#r9"G#9#9#(L1 AAArD GrD GrD Gr9"G#r9"G#r9"G#r9#9#9#9TOvc4N?c᪹2D,kr9"G#rcLMu톟ᅹp]Cݷ} ?CeBM|Z͈K.Cϯ^WaYwïeͥ`RjRx|s:[bZfIENDB`premailer-1.8.6/test/files/dots_h.gif0000644000175000017500000000007412703352566021036 0ustar balasankarcbalasankarcGIF89aTem!,T Ddx [|;s;premailer-1.8.6/test/files/styles.css0000644000175000017500000000547412703352566021135 0ustar balasankarcbalasankarc/* * Premailer styles * * Copyright (c) 2009 Dialect Communications Group (dialect.ca) * * $Package: Premailer $ * $Date: 2009-02-09 17:15:56 -0800 (Mon, 09 Feb 2009) $WCDATE$ $ * $Rev: 95 $WCREV$ $ */ @import "noimport.css" print; /*** structure and table cells ***/ body{font:13px/1.231 "Arial",sans-serif;color: #fff;background-color: #9EBF00;} #wrapper { width: 100%; margin: 2em 0; background-color: #9EBF00; color: #fff; } .container { margin: 0 auto; line-height: 130%; color: #4d4d4d; text-align: left; } .frame { background-color: #b6d93f; font-size: 1px; line-height: 1px; } .hairline { background-color: #9ebf00; font-size: 1px; line-height: 1px; } .masthead, .gutter { color: #999; background-color: #fff; } .content { line-height: 158%; color: #999; background-color: #fff; } #webversion, #footer { margin: 0 auto; text-align: center; font-size: 85%; } /*** general styles ***/ h1, h1 a, h2, h2 a { color: #9ebf00; } h1 span { padding: 0 .5em; background: #fff; } h1 { margin: 32px 0 19px; font: bold 85% "Verdana", sans-serif; text-transform: uppercase; text-align: center; letter-spacing: .1em; background: transparent url("dots_h.gif") repeat-x 0 55%; } h2 { margin: 0 0 .4em; font: normal 205%/109% "Arial", sans-serif; } h3, h3 a { color: #808080; } h3 { margin: 0 0 .1em; font: normal 165%/109% "Arial", sans-serif; } table{ border-collapse:collapse;border-spacing:0; border: 0; } caption,th,td {text-align:left;font-weight:normal; margin: 0; padding: 0; } pre,code,kbd,samp,tt{font-family:monospace;line-height:100%;} th, td { vertical-align: top; } a { text-decoration: none; } blockquote { margin: 0; padding: 5px 30px; text-align: center; } blockquote, blockquote p { font: italic 16px/145% "Georgia", serif; } p, blockquote { color: #999; } p { margin: 0 0 1em; font: normal 100%/158% "Arial", sans-serif; vertical-align: top; } .hide { text-align: center; color: red; font-size: 150%; } /*** specific elements ***/ h2 + h3 { font-style: italic;} p[attr~=quote] { font-style: italic;} ul li:first-of-type { font-style: italic;} .content p a, .content li a { color: #8AAD09; text-decoration: underline; } .content p.dt { margin-bottom: .8em; font: italic 95%/135% "Arial", sans-serif; } img.right { float: right; margin: 0 0 30px 20px; } .contact { text-align: center; background: #9EC03B url("contact_bg.png") repeat 0 0; } .contact, .contact p, .contact a { color: #fff; text-decoration: none; } .contact p { margin-bottom: 0; line-height: 140%; } .contact a:hover { text-decoration: underline; } #webversion, #webversion a { font: bold 12px/28px "Trebuchet", "Trebuchet MS", serif; color: #fff; background: #9ebf00; } #credit { padding-bottom: 20px; } #credit, #credit a { color: #fff; font: normal 10px/13px "Verdana", sans-serif; text-align: center; } #contact_info { padding: 5px; }premailer-1.8.6/test/files/iso-8859-5.html0000644000175000017500000000021512703352566021321 0ustar balasankarcbalasankarc

    premailer-1.8.6/test/files/contact_bg.png0000644000175000017500000000136612703352566021705 0ustar balasankarcbalasankarcPNG  IHDRotEXtSoftwareAdobe ImageReadyqe<IDATxAN0@Q܅ B jIX!6'}}۟}Ϭcj7kաsP'>.m0ʧcB&sx;f_^3t4S{^6 (/}eM..]NF67;Vxy\^Oyz/_?oq8'4ԭDmVԝG[wnh\=6+#ּ~b|r6#̫#M׊17x.Wx[ߨ)))))j j j j ))))j j j j ))))j j j j ))))j j j j ))))j j j j ))))j j j j ))))j j j j ))))j j j ߗ>sݪIENDB`premailer-1.8.6/test/files/html_with_uri.html0000644000175000017500000000031212703352566022626 0ustar balasankarcbalasankarc

    The following line should not make this html be identified as a URI http://foobar.com

    premailer-1.8.6/test/files/ignore.html0000644000175000017500000000054712703352566021245 0ustar balasankarcbalasankarc Should ignore link and style elements with data attribute

    Content

    premailer-1.8.6/test/files/import.css0000644000175000017500000000037512703352566021117 0ustar balasankarcbalasankarc/* * Premailer styles - should import * * Copyright (c) 2009 Dialect Communications Group (dialect.ca) * * $Package: Premailer $ * $Date: 2009-02-09 17:15:56 -0800 (Mon, 09 Feb 2009) $WCDATE$ $ * $Rev: 95 $WCREV$ $ */ .hide { display: none; } premailer-1.8.6/test/files/html4.html0000644000175000017500000000116112703352566021003 0ustar balasankarcbalasankarc Title

    Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
    Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

    premailer-1.8.6/test/files/no_css.html0000644000175000017500000000047112703352566021242 0ustar balasankarcbalasankarc Premailer No CSS Test

    This line should be hidden.

    premailer-1.8.6/test/files/xhtml.html0000644000175000017500000000121612703352566021110 0ustar balasankarcbalasankarc Title

    Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
    Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

    premailer-1.8.6/test/files/dots_end.png0000644000175000017500000000056712703352566021403 0ustar balasankarcbalasankarcPNG  IHDRNNhtEXtSoftwareAdobe ImageReadyqe<IDATxء 0DQ `G0 MZ4H e@Pv@Pve@e@Pv@Pve@e@Pv@Pve@e@PvePvPq1a1c0'GI}(;(;(;(;(;(;(;(;ow 0BxIENDB`premailer-1.8.6/test/files/chars.html0000644000175000017500000000017512703352566021057 0ustar balasankarcbalasankarc

    cédille cé & garçon garçon à à   & ©

    premailer-1.8.6/test/files/dialect.png0000644000175000017500000000153712703352566021207 0ustar balasankarcbalasankarcPNG  IHDR<#GktEXtSoftwareAdobe ImageReadyqe<IDATxMkQ8TMP ##n*u!3ٹ]PteRE7T ڔJG!B4ǹ2d F03;qޝuwp( ?qb nfA=y"<գy r>No/̟F8:;zѸ^$$s TH`B h2M/MsGehÁGdu֯v/qܰl\dev 'ztnTWs#+,0xܝ <$L~T hd5 u&Ee su^ FPmcsh&D},#lgcJ0 @+ @+ @w%wxIENDB`premailer-1.8.6/test/files/ignore.css0000644000175000017500000000003212703352566021056 0ustar balasankarcbalasankarcbody { color: orange; } premailer-1.8.6/rakefile.rb0000644000175000017500000000303312703352566017113 0ustar balasankarcbalasankarcrequire 'rake' require 'rake/testtask' require "bundler/gem_tasks" require 'yard' GEM_ROOT = File.dirname(__FILE__).freeze unless defined?(GEM_ROOT) lib_path = File.expand_path('lib', GEM_ROOT) $LOAD_PATH.unshift(lib_path) unless $LOAD_PATH.include? lib_path require 'premailer/version' desc 'Parse a URL and write out the output.' task :inline do require 'premailer' url = ENV['url'] output = ENV['output'] if !url or url.empty? or !output or output.empty? puts 'Usage: rake inline url=http://example.com/ output=output.html' exit end premailer = Premailer.new(url, :warn_level => Premailer::Warnings::SAFE, :verbose => true, :adapter => :nokogiri) File.open(output, "w") do |fout| fout.puts premailer.to_inline_css end puts "Succesfully parsed '#{url}' into '#{output}'" puts premailer.warnings.length.to_s + ' CSS warnings were found' end task :text do require 'premailer' url = ENV['url'] output = ENV['output'] if !url or url.empty? or !output or output.empty? puts 'Usage: rake text url=http://example.com/ output=output.txt' exit end premailer = Premailer.new(url, :warn_level => Premailer::Warnings::SAFE) File.open(output, "w") do |fout| fout.puts premailer.to_plain_text end puts "Succesfully parsed '#{url}' into '#{output}'" end Rake::TestTask.new do |t| t.test_files = FileList['test/test_*.rb'] t.verbose = false end YARD::Rake::YardocTask.new do |yard| yard.options << "--title='Premailer #{Premailer::VERSION} Documentation'" end task :default => [:test] premailer-1.8.6/misc/0000755000175000017500000000000012703352566015740 5ustar balasankarcbalasankarcpremailer-1.8.6/misc/client_support.yaml0000644000175000017500000001545512703352566021710 0ustar balasankarcbalasankarc# Capabilities of e-mail clients # # Sources # * http://campaignmonitor.com/css/ # * http://www.campaignmonitor.com/blog/archives/2007/04/a_guide_to_css_support_in_emai_2.html # * http://www.campaignmonitor.com/blog/archives/2007/11/do_image_maps_work_in_html_ema.html # * http://www.campaignmonitor.com/blog/archives/2007/11/how_forms_perform_in_html_emai.html # * http://www.xavierfrenette.com/articles/css-support-in-webmail/ # * http://www.email-standards.org/ # Updated 2008-08-26 # # Support: 1 = SAFE, 2 = POOR, 3 = RISKY elements: map: support: 2 unsupported_in: [GMail] area: support: 2 unsupported_in: [GMail] form: support: 3 unsupported_in: [Mobile Me, Old Yahoo, AOL, Live Mail, Outlook 07, Outlook 03] link: support: 2 unsupported_in: [GMail, Hotmail, Old Yahoo] attributes: ismap: support: 2 unsupported_in: [GMail] css_properties: color: unsupported_in: [Eudora] support_level: 92% support: 1 font-size: unsupported_in: [Eudora] support_level: 92% support: 1 font-style: unsupported_in: [Eudora] support_level: 92% support: 1 font-weight: unsupported_in: [Eudora] support_level: 92% support: 1 text-align: unsupported_in: [Eudora] support_level: 92% support: 1 text-decoration: unsupported_in: [Eudora] support_level: 92% support: 1 background-color: unsupported_in: [Notes 6, Eudora] support_level: 85% support: 2 border: &border_shorthand unsupported_in: [Notes 6, Eudora] support_level: 85% support: 2 border-bottom: *border_shorthand border-left: *border_shorthand border-right: *border_shorthand border-top: *border_shorthand display: unsupported_in: [Outlook 07, Eudora] support_level: 85% support: 2 font-family: unsupported_in: [Eudora, Old GMail, New GMail] support_level: 92% support: 2 font-variant: unsupported_in: [Notes 6, Eudora] support_level: 85% support: 2 letter-spacing: unsupported_in: [Notes 6, Eudora] support_level: 85% support: 2 line-height: unsupported_in: [Notes 6, Eudora] support_level: 85% support: 2 padding: &padding_shorthand unsupported_in: [Notes 6, Eudora] support_level: 85% support: 2 padding-bottom: *padding_shorthand padding-left: *padding_shorthand padding-right: *padding_shorthand padding-top: *padding_shorthand table-layout: unsupported_in: [Notes 6, Eudora] support_level: 85% support: 2 text-indent: unsupported_in: [Notes 6, Eudora] support_level: 85% support: 2 text-transform: unsupported_in: [Notes 6, Eudora] support_level: 85% support: 2 border-collapse: unsupported_in: [Entourage 2004, Notes 6, Eudora] support_level: 77% support: 3 clear: unsupported_in: [Outlook 07, Notes 6, Eudora] support_level: 77% support: 3 direction: unsupported_in: [Outlook 07, Entourage 2004, Eudora, New GMail] support_level: 77% support: 3 float: unsupported_in: [Outlook 07, Eudora, Old GMail] support_level: 85% support: 3 vertical-align: unsupported_in: [Outlook 07, Notes 6, Eudora] support_level: 77% support: 3 width: unsupported_in: [Outlook 07, Notes 6, Eudora] support_level: 77% support: 3 word-spacing: unsupported_in: [Outlook 07, Notes 6, Eudora] support_level: 77% support: 3 height: unsupported_in: [Outlook 07, Notes 6, Eudora, Old GMail] support_level: 77% support: 3 list-style-type: unsupported_in: [Outlook 07, Eudora, Hotmail] support_level: 85% support: 3 overflow: unsupported_in: [Outlook 07, Entourage 2004, Notes 6, Eudora] support_level: 69% support: 3 visibility: unsupported_in: [Outlook 07, Notes 6, Eudora, Old GMail, New GMail, aolWeb] support_level: 77% support: 3 white-space: unsupported_in: [Outlook 03, Windows Mail, AOL 9, AOL 10, Notes 6, Eudora, Mobile Me] support_level: 54% support: 3 background-image: unsupported_in: [Outlook 07, Notes 6, Eudora, Old GMail, New GMail, Live Mail] support_level: 77% support: 3 background-repeat: unsupported_in: [Outlook 07, Notes 6, Eudora, Old GMail, New GMail, Live Mail] support_level: 77% support: 3 clip: unsupported_in: [Outlook 07, Notes 6, Eudora, New Yahoo, New GMail, Live Mail, Mobile Me] support_level: 77% support: 3 cursor: unsupported_in: [Outlook 07, Entourage 2004, Notes 6, Eudora, Old GMail, New GMail] support_level: 69% support: 3 list-style-image: unsupported_in: [Outlook 07, Notes 6, Eudora, Old GMail, New GMail, Live Mail] support_level: 77% support: 3 list-style-position: unsupported_in: [Outlook 07, Notes 6, Eudora, Old Yahoo, Hotmail] support_level: 77% support: 3 margin: &margin_shorthand unsupported_in: [AOL 9, Notes 6, Eudora, Live Mail, Hotmail] support_level: 77% support: 3 margin-bottom: *margin_shorthand margin-left: *margin_shorthand margin-right: *margin_shorthand margin-top: *margin_shorthand z-index: unsupported_in: [Notes 6, Eudora, New Yahoo, Old GMail, New GMail, Live Mail] support_level: 85% support: 3 left: unsupported_in: [Outlook 07, Notes 6, Eudora, New Yahoo, Old GMail, New GMail, Live Mail] support_level: 77% support: 3 right: unsupported_in: [Outlook 07, Notes 6, Eudora, New Yahoo, Old GMail, New GMail, Live Mail] support_level: 77% support: 3 top: unsupported_in: [Outlook 07, Notes 6, Eudora, New Yahoo, Old GMail, New GMail, Live Mail] support_level: 77% support: 3 background-position: unsupported_in: [Outlook 07, Notes 6, Eudora, Old Yahoo, Old GMail, New GMail, Live Mail, Hotmail] support_level: 77% support: 3 border-spacing: unsupported_in: [Outlook 03, Outlook 07, Windows Mail, Entourage 2004, AOL 10, Notes 6, Eudora, Live Mail, Hotmail] support_level: 46% support: 3 bottom: unsupported_in: [Outlook 07, AOL 9, Notes 6, Eudora, New Yahoo, Old GMail, New GMail, Live Mail] support_level: 69% support: 3 empty-cells: unsupported_in: [Outlook 03, Outlook 07, Windows Mail, Entourage 2004, AOL 9, AOL 10, Notes 6, Eudora, Hotmail] support_level: 38% support: 3 position: unsupported_in: [Outlook 07, Notes 6, Eudora, Old Yahoo, New Yahoo, Old GMail, New GMail, Live Mail, Hotmail, Mobile Me] support_level: 77% support: 3 caption-side: unsupported_in: [Outlook 03, Outlook 07, Windows Mail, Mac Mail, Entourage 2004, Entourage 2008, AOL 9, AOL 10, AOL Desktop for Mac, Notes 6, Eudora, New Yahoo, Hotmail] support_level: 15% support: 3 opacity: unsupported_in: [Outlook 03, Outlook 07, Windows Mail, Entourage 2004, Notes 6, Eudora, New Yahoo, Old GMail, New GMail, Live Mail, Hotmail] support_level: 54% support: 3 premailer-1.8.6/lib/0000755000175000017500000000000012703352566015553 5ustar balasankarcbalasankarcpremailer-1.8.6/lib/premailer/0000755000175000017500000000000012703352566017533 5ustar balasankarcbalasankarcpremailer-1.8.6/lib/premailer/adapter.rb0000644000175000017500000000321312703352566021477 0ustar balasankarcbalasankarc class Premailer # Manages the adapter classes. Currently supports: # # * nokogiri # * hpricot module Adapter autoload :Hpricot, 'premailer/adapter/hpricot' autoload :Nokogiri, 'premailer/adapter/nokogiri' # adapter to required file mapping. REQUIREMENT_MAP = [ ["hpricot", :hpricot], ["nokogiri", :nokogiri], ] # Returns the adapter to use. def self.use return @use if @use self.use = self.default @use end # The default adapter based on what you currently have loaded and # installed. First checks to see if any adapters are already loaded, # then checks to see which are installed if none are loaded. # @raise [RuntimeError] unless suitable adapter found. def self.default return :hpricot if defined?(::Hpricot) return :nokogiri if defined?(::Nokogiri) REQUIREMENT_MAP.each do |(library, adapter)| begin require library return adapter rescue LoadError next end end raise RuntimeError.new("No suitable adapter for Premailer was found, please install hpricot or nokogiri") end # Sets the adapter to use. # @raise [ArgumentError] unless the adapter exists. def self.use=(new_adapter) @use = find(new_adapter) end # Returns an adapter. # @raise [ArgumentError] unless the adapter exists. def self.find(adapter) return adapter if adapter.is_a?(Module) Premailer::Adapter.const_get("#{adapter.to_s.split('_').map{|s| s.capitalize}.join('')}") rescue NameError raise ArgumentError, "Invalid adapter: #{adapter}" end end end premailer-1.8.6/lib/premailer/executor.rb0000644000175000017500000000525212703352566021722 0ustar balasankarcbalasankarcrequire 'optparse' require 'premailer' # defaults options = { :base_url => nil, :link_query_string => nil, :remove_classes => false, :verbose => false, :line_length => 65 } mode = :html opts = OptionParser.new do |opts| opts.banner = "Improve the rendering of HTML emails by making CSS inline among other things. Takes a path to a local file, a URL or a pipe as input.\n\n" opts.define_head "Usage: premailer [options]" opts.separator "" opts.separator "Examples:" opts.separator " premailer http://example.com/ > out.html" opts.separator " premailer http://example.com/ --mode txt > out.txt" opts.separator " cat input.html | premailer -q src=email > out.html" opts.separator " premailer ./public/index.html" opts.separator "" opts.separator "Options:" opts.on("--mode MODE", [:html, :txt], "Output: html or txt") do |v| mode = v end opts.on("-b", "--base-url STRING", String, "Base URL, useful for local files") do |v| options[:base_url] = v end opts.on("-q", "--query-string STRING", String, "Query string to append to links") do |v| options[:link_query_string] = v end opts.on("--css FILE,FILE", Array, "Additional CSS stylesheets") do |v| options[:css] = v end opts.on("-r", "--remove-classes", "Remove HTML classes") do |v| options[:remove_classes] = v end opts.on("-j", "--remove-scripts", "Remove