Skip to content

Commit

Permalink
Replace URI with Addressable::URI, drop wrong sorting of attributes. …
Browse files Browse the repository at this point in the history
…Drop last semicolon from attributes. Update tests.
  • Loading branch information
akzhan committed Mar 9, 2017
1 parent 33557cb commit d135e0b
Show file tree
Hide file tree
Showing 12 changed files with 31 additions and 131 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Expand Up @@ -9,3 +9,5 @@
/pkg/
/.bundle/
/*.sublime-*
/Gemfile.lock

1 change: 0 additions & 1 deletion .travis.yml
Expand Up @@ -4,7 +4,6 @@ branches:
only: master
matrix:
fast_finish: true
before_install: rm Gemfile.lock
language: ruby
rvm:
- 2.1.9
Expand Down
77 changes: 0 additions & 77 deletions Gemfile.lock

This file was deleted.

1 change: 1 addition & 0 deletions lib/premailer.rb
Expand Up @@ -2,6 +2,7 @@
require 'open-uri'
require 'digest/md5'
require 'cgi'
require 'addressable'
require 'css_parser'

require 'premailer/adapter'
Expand Down
7 changes: 2 additions & 5 deletions lib/premailer/adapter/nokogiri.rb
Expand Up @@ -77,7 +77,7 @@ def to_inline_css
if Premailer::RELATED_ATTRIBUTES.has_key?(el.name) && @options[:css_to_attributes]
Premailer::RELATED_ATTRIBUTES[el.name].each do |css_att, html_att|
if el[html_att].nil? and not merged[css_att].empty?
new_html_att = merged[css_att].gsub(/url\(['|"](.*)['|"]\)/, '\1').gsub(/;$|\s*!important/, '').strip
new_html_att = merged[css_att].gsub(/url\(['"](.*)['"]\)/, '\1').gsub(/;$|\s*!important/, '').strip
el[html_att] = css_att.end_with?('color') && @options[:rgb_to_hex_attributes] ? ensure_hex(new_html_att) : new_html_att
end
unless @options[:preserve_style_attribute]
Expand All @@ -91,10 +91,7 @@ def to_inline_css
merged.create_shorthand! if @options[:create_shorthands]

# write the inline STYLE attribute
# split by ';' but ignore those in brackets
attributes = Premailer.escape_string(merged.declarations_to_s).split(/;(?![^(]*\))/).map(&:strip)
attributes = attributes.map { |attr| [attr.split(':').first, attr] }.sort_by { |pair| pair.first }.map { |pair| pair[1] }
el['style'] = attributes.join('; ') + ";"
el['style'] = merged.declarations_to_s
end

doc = write_unmergable_css_rules(doc, @unmergable_rules)
Expand Down
7 changes: 2 additions & 5 deletions lib/premailer/adapter/nokogiri_fast.rb
Expand Up @@ -79,7 +79,7 @@ def to_inline_css
if Premailer::RELATED_ATTRIBUTES.has_key?(el.name) && @options[:css_to_attributes]
Premailer::RELATED_ATTRIBUTES[el.name].each do |css_att, html_att|
if el[html_att].nil? and not merged[css_att].empty?
new_html_att = merged[css_att].gsub(/url\(['|"](.*)['|"]\)/, '\1').gsub(/;$|\s*!important/, '').strip
new_html_att = merged[css_att].gsub(/url\(['"](.*)['"]\)/, '\1').gsub(/;$|\s*!important/, '').strip
el[html_att] = css_att.end_with?('color') && @options[:rgb_to_hex_attributes] ? ensure_hex(new_html_att) : new_html_att
end
unless @options[:preserve_style_attribute]
Expand All @@ -93,10 +93,7 @@ def to_inline_css
merged.create_shorthand! if @options[:create_shorthands]

# write the inline STYLE attribute
# split by ';' but ignore those in brackets
attributes = Premailer.escape_string(merged.declarations_to_s).split(/;(?![^(]*\))/).map(&:strip)
attributes = attributes.map { |attr| [attr.split(':').first, attr] }.sort_by { |pair| pair.first }.map { |pair| pair[1] }
el['style'] = attributes.join('; ') + ";"
el['style'] = merged.declarations_to_s
end

doc = write_unmergable_css_rules(doc, @unmergable_rules)
Expand Down
6 changes: 2 additions & 4 deletions lib/premailer/adapter/nokogumbo.rb
Expand Up @@ -77,7 +77,7 @@ def to_inline_css
if Premailer::RELATED_ATTRIBUTES.has_key?(el.name) && @options[:css_to_attributes]
Premailer::RELATED_ATTRIBUTES[el.name].each do |css_att, html_att|
if el[html_att].nil? and not merged[css_att].empty?
new_html_att = merged[css_att].gsub(/url\(['|"](.*)['|"]\)/, '\1').gsub(/;$|\s*!important/, '').strip
new_html_att = merged[css_att].gsub(/url\(['"](.*)['"]\)/, '\1').gsub(/;$|\s*!important/, '').strip
el[html_att] = css_att.end_with?('color') && @options[:rgb_to_hex_attributes] ? ensure_hex(new_html_att) : new_html_att
end
unless @options[:preserve_style_attribute]
Expand All @@ -91,9 +91,7 @@ def to_inline_css
merged.create_shorthand! if @options[:create_shorthands]

# write the inline STYLE attribute
attributes = Premailer.escape_string(merged.declarations_to_s).split(';').map(&:strip)
attributes = attributes.map { |attr| [attr.split(':').first, attr] }.sort_by { |pair| pair.first }.map { |pair| pair[1] }
el['style'] = attributes.join('; ') + ";"
el['style'] = merged.declarations_to_s
end

doc = write_unmergable_css_rules(doc, @unmergable_rules)
Expand Down
26 changes: 13 additions & 13 deletions lib/premailer/premailer.rb
Expand Up @@ -221,9 +221,9 @@ def initialize(html, options = {})
@unmergable_rules = nil

if @options[:base_url]
@base_url = URI.parse(@options.delete(:base_url))
@base_url = Addressable::URI.parse(@options.delete(:base_url))
elsif not @is_local_file
@base_url = URI.parse(@html_file)
@base_url = Addressable::URI.parse(@html_file)
end

@css_parser = CssParser::Parser.new({
Expand Down Expand Up @@ -369,7 +369,7 @@ def append_query_string(doc, qs)
next if href[0,1] =~ /[\#\{\[\<\%]/ # don't bother with anchors or special-looking links

begin
href = URI.parse(href)
href = Addressable::URI.parse(href)

if current_host and href.host != nil and href.host != current_host
$stderr.puts "Skipping append_query_string for: #{href.to_s} because host is no good" if @options[:verbose]
Expand All @@ -389,7 +389,7 @@ def append_query_string(doc, qs)
end

el['href'] = href.to_s
rescue URI::Error => e
rescue Addressable::URI::InvalidURIError => e
$stderr.puts "Skipping append_query_string for: #{href.to_s} (#{e.message})" if @options[:verbose]
next
end
Expand All @@ -415,7 +415,7 @@ def is_xhtml?
#
# Returns a document.
def convert_inline_links(doc, base_uri) # :nodoc:
base_uri = URI.parse(base_uri) unless base_uri.kind_of?(URI)
base_uri = Addressable::URI.parse(base_uri) unless base_uri.kind_of?(Addressable::URI)

append_qs = @options[:link_query_string] || ''
escape_attrs = @options[:escape_url_attributes]
Expand All @@ -434,21 +434,21 @@ def convert_inline_links(doc, base_uri) # :nodoc:

if tag.attributes[attribute].to_s =~ /^http/i
begin
merged = URI.parse(tag.attributes[attribute])
merged = Addressable::URI.parse(tag.attributes[attribute])
rescue; next; end
else
begin
merged = Premailer.resolve_link(tag.attributes[attribute].to_s, base_uri)
rescue
begin
next unless escape_attrs
merged = Premailer.resolve_link(URI.escape(tag.attributes[attribute].to_s), base_uri)
merged = Premailer.resolve_link(Addressable::URI.escape(tag.attributes[attribute].to_s), base_uri)
rescue; end
end
end

# make sure 'merged' is a URI
merged = URI.parse(merged.to_s) unless merged.kind_of?(URI)
merged = Addressable::URI.parse(merged.to_s) unless merged.kind_of?(Addressable::URI)
tag[attribute] = merged.to_s
end # end of each tag
end # end of each attrs
Expand Down Expand Up @@ -476,12 +476,12 @@ def self.resolve_link(path, base_path) # :nodoc:
if path =~ /\A(?:(https?|ftp|file):)\/\//i
resolved = path
Premailer.canonicalize(resolved)
elsif base_path.kind_of?(URI)
resolved = base_path.merge(path)
elsif base_path.kind_of?(Addressable::URI)
resolved = base_path.join(path)
Premailer.canonicalize(resolved)
elsif base_path.kind_of?(String) and base_path =~ /\A(?:(?:https?|ftp|file):)\/\//i
resolved = URI.parse(base_path)
resolved = resolved.merge(path)
resolved = Addressable::URI.parse(base_path)
resolved = resolved.join(path)
Premailer.canonicalize(resolved)
else
File.expand_path(path, File.dirname(base_path))
Expand All @@ -500,7 +500,7 @@ def self.local_data?(data)

# from http://www.ruby-forum.com/topic/140101
def self.canonicalize(uri) # :nodoc:
u = uri.kind_of?(URI) ? uri : URI.parse(uri.to_s)
u = uri.kind_of?(Addressable::URI) ? uri : Addressable::URI.parse(uri.to_s)
u.normalize!
newpath = u.path
while newpath.gsub!(%r{([^/]+)/\.\./?}) { |match|
Expand Down
2 changes: 1 addition & 1 deletion test/helper.rb
Expand Up @@ -9,7 +9,7 @@ class Premailer::TestCase < Minitest::Test

def setup
stub_request(:any, /premailer\.dev\/*/).to_return do |request|
file_path = BASE_PATH + URI.parse(request.uri).path
file_path = BASE_PATH + Addressable::URI.parse(request.uri).path
if File.exists?(file_path)
{ :status => 200, :body => File.open(file_path) }
else
Expand Down
10 changes: 5 additions & 5 deletions test/test_links.rb
Expand Up @@ -43,7 +43,7 @@ def test_appending_link_query_string
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)
uri = Addressable::URI.parse(href)
assert_match qs, uri.query, "missing query string for #{el.to_s}"
end

Expand Down Expand Up @@ -111,21 +111,21 @@ def test_resolving_urls_from_string
end

def test_resolving_urls_from_uri
base_uri = URI.parse('http://example.com/')
base_uri = Addressable::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/')
base_uri = Addressable::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')
base_uri = Addressable::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/')
base_uri = Addressable::URI.parse('http://example.com/')
assert_equal 'http://example.com/path', Premailer.resolve_link(' path', base_uri)
end

Expand Down
19 changes: 1 addition & 18 deletions test/test_misc.rb
Expand Up @@ -254,7 +254,7 @@ def test_preserve_original_style_attribute
style5_style = style5.attributes['style'].to_s

assert_match /font-size: xx-large/, premailer.processed_doc.search('.style3').first.attributes['style'].to_s
assert_match /background: #000080/, style5_style
assert_match /background-color: #000080/, style5_style
assert_match /text-align: center/, style5_style
assert_match /#000080/, style5.attributes['bgcolor'].to_s
end
Expand Down Expand Up @@ -299,23 +299,6 @@ def test_handling_shorthand_auto_properties
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 = <<END_HTML
<html>
<style type="text/css">
#page { right: 10px; left: 5px }
</style>
<body>
<div id='page'>test</div>
</body>
</html>
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 = <<END_HTML
<html>
Expand Down
4 changes: 2 additions & 2 deletions test/test_premailer.rb
Expand Up @@ -110,7 +110,7 @@ def test_css_to_attributes
html = '<td style="background-color: #FFF;"></td>'
premailer = Premailer.new(html, {:with_html_string => true, :adapter => adapter, :css_to_attributes => true})
premailer.to_inline_css
assert_equal ';', premailer.processed_doc.search('td').first.attributes['style'].to_s
assert_equal '', premailer.processed_doc.search('td').first.attributes['style'].to_s
assert_equal '#FFF', premailer.processed_doc.search('td').first.attributes['bgcolor'].to_s
end
end
Expand All @@ -120,7 +120,7 @@ def test_avoid_changing_css_to_attributes
html = '<td style="background-color: #FFF;"></td>'
premailer = Premailer.new(html, {:with_html_string => true, :adapter => adapter, :css_to_attributes => false})
premailer.to_inline_css
assert_match /background: #FFF/, premailer.processed_doc.at_css('td').attributes['style'].to_s
assert_match /background-color: #FFF/, premailer.processed_doc.at_css('td').attributes['style'].to_s
end
end

Expand Down

2 comments on commit d135e0b

@grosser
Copy link
Contributor

@grosser grosser commented on d135e0b Mar 9, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please use PRs and don't just commit to master

@akzhan
Copy link
Member Author

@akzhan akzhan commented on d135e0b Mar 9, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will do.

Please sign in to comment.