docomo_css 0.4.6 → 0.4.8

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/.gitignore ADDED
@@ -0,0 +1,4 @@
1
+ *.swp
2
+ pkg/*
3
+ rdoc/*
4
+ *.gem
data/Rakefile ADDED
@@ -0,0 +1,24 @@
1
+ require 'bundler'
2
+ require 'rake/testtask'
3
+ require 'rake/rdoctask'
4
+ Bundler::GemHelper.install_tasks
5
+
6
+ desc 'Default: run unit tests.'
7
+ task :default => :test
8
+
9
+ desc 'Test the docomo_css plugin.'
10
+ Rake::TestTask.new(:test) do |t|
11
+ t.libs << 'lib'
12
+ t.libs << 'test'
13
+ t.pattern = 'test/**/*_test.rb'
14
+ t.verbose = true
15
+ end
16
+
17
+ desc 'Generate documentation for the docomo_css plugin.'
18
+ Rake::RDocTask.new(:rdoc) do |rdoc|
19
+ rdoc.rdoc_dir = 'rdoc'
20
+ rdoc.title = 'DocomoCss'
21
+ rdoc.options << '--line-numbers' << '--inline-source'
22
+ rdoc.rdoc_files.include('README.rdoc')
23
+ rdoc.rdoc_files.include('lib/**/*.rb')
24
+ end
@@ -0,0 +1,23 @@
1
+ $:.push File.expand_path("../lib", __FILE__)
2
+ require "docomo_css/version"
3
+
4
+ Gem::Specification.new do |s|
5
+ s.name = 'docomo_css'
6
+ s.version = DocomoCss::Version
7
+ s.platform = Gem::Platform::RUBY
8
+ s.authors = ["milk1000cc", "Paul McMahon"]
9
+ s.email = 'info@milk1000.cc'
10
+ s.homepage = 'http://www.milk1000.cc/'
11
+ s.summary = 'CSS inliner'
12
+ s.description = 'Inlines CSS so that you can use external CSS with docomo handsets.'
13
+
14
+ s.files = `git ls-files`.split("\n")
15
+ s.require_path = 'lib'
16
+ s.rubyforge_project = "galakei"
17
+
18
+ s.rdoc_options = ["--charset=UTF-8"]
19
+
20
+ s.add_dependency 'nokogiri', ">= 0"
21
+ s.add_dependency 'tiny_css', "~> 0.1.3"
22
+ s.add_dependency 'rails', ">= 3.0.0"
23
+ end
@@ -20,9 +20,9 @@ module DocomoCss
20
20
 
21
21
  def embed_css(body)
22
22
  doc = Nokogiri::HTML(body)
23
- unless doc.encoding
24
- doc.at("/html/head").add_child("<!-- Please explicitly specify the encoding of your document as below. Assuming UTF-8. -->")
25
- doc.at("/html/head").add_child("<meta content='application/xhtml+xml;charset=UTF-8' http-equiv='content-type' />")
23
+ if doc.encoding.nil? && head = doc.at("/html/head")
24
+ head.add_child("<!-- Please explicitly specify the encoding of your document as below. Assuming UTF-8. -->")
25
+ head.add_child("<meta content='application/xhtml+xml;charset=UTF-8' http-equiv='content-type' />")
26
26
  doc.encoding = "UTF-8"
27
27
  end
28
28
 
@@ -1,3 +1,3 @@
1
1
  module DocomoCss
2
- Version = "0.4.6"
2
+ Version = "0.4.8"
3
3
  end
data/test/actual.html ADDED
@@ -0,0 +1,13 @@
1
+ <?xml version="1.0" encoding="Shift_JIS"?>
2
+ <!DOCTYPE html PUBLIC "-//i-mode group (ja)//DTD XHTML i-XHTML(Locale/Ver.=ja/2.3) 1.0//EN" "i-xhtml_4ja_10.dtd">
3
+ <html>
4
+ <head>
5
+ <meta http-equiv="Content-Type" content="application/xhtml+xml; charset=Shift_JIS" />
6
+ <link rel="stylesheet" href="/actual.css" />
7
+ </head>
8
+ <body>
9
+ <div class="content">
10
+ <a href="/">TOP</a>
11
+ </div>
12
+ </body>
13
+ </html>
@@ -0,0 +1,109 @@
1
+ require 'test_helper'
2
+ require 'tiny_css'
3
+ require File.join File.dirname(__FILE__), '..', '..', 'lib', 'docomo_css', 'embeddable_style'
4
+
5
+ class DocomoCss::EmbeddableStyleTest < Test::Unit::TestCase
6
+
7
+ def test_embed_style_in_div
8
+ doc = Nokogiri::HTML("<div>")
9
+ div = doc.at("div")
10
+ div.embed_style(style)
11
+ assert_equal '<div style="color:red"></div>', doc.at("body").children.to_html
12
+ end
13
+
14
+ def test_embed_style_in_h1_handles_empty_children
15
+ doc = Nokogiri::HTML("<h1>")
16
+ e = doc.at("h1")
17
+ e.embed_style(style)
18
+ assert_equal '<h1></h1>', doc.at("body").children.to_html
19
+ end
20
+
21
+ def test_embed_style_in_h1_handles_wrapping_of_color
22
+ doc = Nokogiri::HTML("<h1>foo</h1>")
23
+ e = doc.at("h1")
24
+ e.embed_style(style)
25
+ assert_equal '<h1><span style="color:red">foo</span></h1>', doc.at("body").children.to_html
26
+ end
27
+
28
+ def test_embed_style_obeys_inject_unsupported_styles
29
+ doc = Nokogiri::HTML("<h1>foo</h1>")
30
+ e = doc.at("h1")
31
+ e.embed_style(style, :inject_unsupported_styles => false)
32
+ assert_equal '<h1 style="color:red">foo</h1>', doc.at("body").children.to_html
33
+ end
34
+
35
+ def test_embed_style_in_h1_handles_wrapping_of_font_size
36
+ doc = Nokogiri::HTML("<h1>foo</h1>")
37
+ e = doc.at("h1")
38
+ e.embed_style(style('font-size', 'x-small'))
39
+ assert_equal '<h1><span style="font-size:x-small">foo</span></h1>', doc.at("body").children.to_html
40
+ end
41
+
42
+ def test_embed_style_in_h1_handles_wrapping_of_background_color
43
+ doc = Nokogiri::HTML("<h1>foo</h1>")
44
+ e = doc.at("h1")
45
+ e.embed_style(style('background-color', 'red'))
46
+ assert_equal '<div style="background-color:red"><h1>foo</h1></div>', doc.at("body").children.to_html
47
+ end
48
+
49
+ def test_embed_style_in_div_handles_existing_style_attribute
50
+ doc = Nokogiri::HTML("<div style='font-size:x-small'>foo</div>")
51
+ e = doc.at("div")
52
+ e.embed_style(style)
53
+ assert_equal '<div style="font-size:x-small;color:red">foo</div>', doc.at("body").children.to_html
54
+ end
55
+
56
+ def test_embed_style_in_h1_handles_style_in_h1
57
+ doc = Nokogiri::HTML("<h1 style='margin-top: 10px;'>foo</h1>")
58
+ e = doc.at("h1")
59
+ e.embed_style(style)
60
+ assert_equal %q{<h1 style="margin-top: 10px;"><span style="color:red">foo</span></h1>}, doc.at("body").children.to_html
61
+ end
62
+
63
+ def test_merge_style
64
+ e = Nokogiri.make("<h1>")
65
+ e.merge_style('color:red')
66
+ assert_equal '<h1 style="color:red"></h1>', e.to_html
67
+ e = Nokogiri.make('<h1 style="color:red">')
68
+ e.merge_style('font-size:small')
69
+ assert_equal '<h1 style="color:red;font-size:small"></h1>', e.to_html
70
+ e = Nokogiri.make('<h1 style="color:red;">')
71
+ e.merge_style('font-size:small')
72
+ assert_equal '<h1 style="color:red;font-size:small"></h1>', e.to_html
73
+ end
74
+
75
+ def test_embed_style_in_h1_handles_multiple_styles
76
+ doc = Nokogiri::HTML("<h1>foo</h1>")
77
+ e = doc.at("h1")
78
+ style = TinyCss::OrderedHash.new
79
+ style["font-size"] = "medium"
80
+ style["color"] = "#ffffff"
81
+ style["text-align"] = "center"
82
+ style["background"] = "#215f8b"
83
+ style["margin-top"] = "5px"
84
+ e.embed_style(style)
85
+ assert_equal %q{<div style="background:#215f8b"><h1 style="text-align:center;margin-top:5px"><span style="font-size:medium;color:#ffffff">foo</span></h1></div>}, doc.at("body").children.to_html
86
+ end
87
+
88
+ def test_embed_style_in_p_handles_color
89
+ doc = Nokogiri::HTML("<p>foo</p>")
90
+ e = doc.at("p")
91
+ e.embed_style(style)
92
+ assert_equal '<p><span style="color:red">foo</span></p>', doc.at("body").children.to_html
93
+ end
94
+
95
+ def test_embed_style_in_p_handles_background_color
96
+ doc = Nokogiri::HTML("<p>foo</p>")
97
+ e = doc.at("p")
98
+ e.embed_style(style('background-color', 'red'))
99
+ assert_equal '<div style="background-color:red"><p>foo</p></div>', doc.at("body").children.to_html
100
+ end
101
+
102
+ private
103
+
104
+ def style(attribute = 'color', value = 'red')
105
+ style = TinyCss::OrderedHash.new
106
+ style[attribute] = value
107
+ style
108
+ end
109
+ end
@@ -0,0 +1,211 @@
1
+ require 'test_helper'
2
+ require File.join File.dirname(__FILE__), '..', '..', 'lib', 'docomo_css', 'filter'
3
+
4
+ class DocomoCss::FilterTest < Test::Unit::TestCase
5
+ def setup
6
+ @filter = DocomoCss::Filter.new
7
+ end
8
+
9
+ def test_invalid_response_content_type
10
+ response = mock("invalid_response") do
11
+ expects(:content_type).returns('text/html').once
12
+ expects(:body).never
13
+ end
14
+ controller = stub("invalid_controller", :response => response)
15
+ @filter.after(controller)
16
+ end
17
+
18
+ def test_escape_numeric_character_reference
19
+ assert_equal "HTMLCSSINLINERESCAPE123456789::::::::", @filter.escape_numeric_character_reference("&#123456789;")
20
+ assert_equal "HTMLCSSINLINERESCAPEx123def::::::::", @filter.escape_numeric_character_reference("&#x123def;")
21
+ end
22
+
23
+ def test_unescape_numeric_character_reference
24
+ assert_equal "&#123456789;", @filter.unescape_numeric_character_reference("HTMLCSSINLINERESCAPE123456789::::::::")
25
+ assert_equal "&#x123def;", @filter.unescape_numeric_character_reference("HTMLCSSINLINERESCAPEx123def::::::::")
26
+ end
27
+
28
+ def test_pseudo_selectors
29
+ css = TinyCss.new.read_string(<<-CSS)
30
+ a:visited { color: FF00FF; }
31
+ CSS
32
+ assert_equal ["a:visited"], @filter.pseudo_selectors(css)
33
+
34
+ css = TinyCss.new.read_string(<<-CSS)
35
+ .purple { color: FF00FF; }
36
+ CSS
37
+ assert_equal [], @filter.pseudo_selectors(css)
38
+ end
39
+
40
+ def test_stylesheet_link_node
41
+ doc = Nokogiri::HTML(<<-HTML)
42
+ <link href="a.css"/>
43
+ <link href="b.css" rel="stylesheet"/>
44
+ HTML
45
+
46
+ @filter.stylesheet_link_node(doc).each do |node|
47
+ assert_equal 'b.css', node['href']
48
+ end
49
+ end
50
+
51
+ def test_extract_pseudo_style
52
+ css = TinyCss.new.read_string <<-CSS
53
+ a:link { color: red; }
54
+ a:focus { color: green; }
55
+ a:visited { color: blue; }
56
+ div.title { background-color: #999 }
57
+ CSS
58
+
59
+ pseudo_style = @filter.extract_pseudo_style css
60
+ assert_equal('red', pseudo_style.style['a:link']['color'])
61
+ assert_equal('green', pseudo_style.style['a:focus']['color'])
62
+ assert_equal('blue', pseudo_style.style['a:visited']['color'])
63
+ assert_equal('#999', css.style['div.title']['background-color'])
64
+ end
65
+
66
+ def test_embed_pseudo_style
67
+ css = TinyCss.new
68
+ assert_equal nil, @filter.embed_pseudo_style(nil, css)
69
+
70
+ css = TinyCss.new.read_string <<-CSS
71
+ a:link { color: red; }
72
+ a:focus { color: green; }
73
+ a:visited { color: blue; }
74
+ CSS
75
+
76
+ doc = Nokogiri::HTML <<-HTML
77
+ <html>
78
+ <head></head>
79
+ <body></body>
80
+ </html>
81
+ HTML
82
+ doc = @filter.embed_pseudo_style doc, css
83
+ assert_match %r'<style .*?/style>'m, doc.to_xhtml
84
+
85
+ doc = Nokogiri::HTML <<-HTML
86
+ <html>
87
+ <body></body>
88
+ </html>
89
+ HTML
90
+ assert_raise RuntimeError do
91
+ @filter.embed_pseudo_style doc, css
92
+ end
93
+ end
94
+
95
+ def test_embed_style
96
+ css = TinyCss.new.read_string <<-CSS
97
+ .title { color: red; }
98
+ CSS
99
+
100
+ doc = Nokogiri::HTML <<-HTML
101
+ <html>
102
+ <body>
103
+ <div class="title">bar</div>
104
+ </body>
105
+ </html>
106
+ HTML
107
+ @filter.embed_style doc, css
108
+ assert_match %r'style="color:red"', doc.to_xhtml
109
+
110
+ doc = Nokogiri::HTML <<-HTML
111
+ <html>
112
+ <body>
113
+ <div class="title" style="background-color:black">bar</div>
114
+ </body>
115
+ </html>
116
+ HTML
117
+ @filter.embed_style doc, css
118
+ assert_match %r'style="background-color:black;color:red"', doc.to_xhtml
119
+
120
+ doc = Nokogiri::HTML <<-HTML
121
+ <html>
122
+ <body>
123
+ <div class="title" style="background-color:silver;">bar</div>
124
+ </body>
125
+ </html>
126
+ HTML
127
+ @filter.embed_style doc, css
128
+ assert_match %r'style="background-color:silver;color:red"', doc.to_xhtml
129
+ end
130
+
131
+ def test_embed_style_in_multiple_h1s
132
+ css = TinyCss.new.read_string("h1 { color: red; }")
133
+
134
+ doc = Nokogiri::HTML("<h1>foo</h1><h1>bar</h1>")
135
+ @filter.embed_style doc, css
136
+ assert_match '<span style="color:red">foo</span>', doc.search('h1')[0].children.to_xhtml
137
+ assert_match '<span style="color:red">bar</span>', doc.search('h1')[1].children.to_xhtml
138
+ end
139
+
140
+ def test_xml_declare
141
+ doc = stub("doc", :encoding => "Shift_JIS")
142
+ assert_equal <<-XML, @filter.xml_declare(doc)
143
+ <?xml version="1.0" encoding="Shift_JIS"?>
144
+ XML
145
+
146
+ doc = stub("doc", :encoding => "UTF-8")
147
+ assert_equal <<-XML, @filter.xml_declare(doc)
148
+ <?xml version="1.0" encoding="UTF-8"?>
149
+ XML
150
+ end
151
+
152
+ def test_remove_xml_declare
153
+ assert_equal '', @filter.remove_xml_declare('<?xml version="1.0"?>')
154
+ assert_equal '', @filter.remove_xml_declare('<?xml encoding="Shift_JIS"?>')
155
+ assert_equal '', @filter.remove_xml_declare('<?xml version="1.0" encoding="Shift_JIS" ?>')
156
+ assert_equal '', @filter.remove_xml_declare('<?xml?>')
157
+ end
158
+
159
+ def test_output_with_docomo_1_0_browser
160
+ request = stub('request', :user_agent => 'DoCoMo/2.0 D905i(c100;TB;W24H17)')
161
+ response = stub("response") do
162
+ expects(:content_type).returns('application/xhtml+xml')
163
+ expects(:body).returns(File.open(File.join(File.dirname(__FILE__), '../actual.html'), 'rb'){ |f| f.read })
164
+ expects(:body=).with(File.open(File.join(File.dirname(__FILE__), '../expected.html'), 'rb'){ |f| f.read })
165
+ end
166
+ controller = stub("controller", :response => response, :request => request)
167
+
168
+ @filter.after(controller)
169
+ end
170
+
171
+ def test_output_with_docomo_1_0_browser_and_utf8_charset
172
+ request = stub('request', :user_agent => 'DoCoMo/2.0 D905i(c100;TB;W24H17)')
173
+ response = stub("response") do
174
+ expects(:content_type).returns('application/xhtml+xml; charset=utf-8')
175
+ expects(:body).returns(File.open(File.join(File.dirname(__FILE__), '../actual.html'), 'rb'){ |f| f.read })
176
+ expects(:body=).with(File.open(File.join(File.dirname(__FILE__), '../expected.html'), 'rb'){ |f| f.read })
177
+ end
178
+ controller = stub("controller", :response => response, :request => request)
179
+
180
+ @filter.after(controller)
181
+ end
182
+
183
+ def test_output_with_docomo_2_0_browser
184
+ request = stub('request', :user_agent => 'DoCoMo/2.0 N03B(c500;TB;W24H16)')
185
+ response = stub("response") do
186
+ expects(:content_type).returns('application/xhtml+xml')
187
+ expects(:body).never
188
+ end
189
+ controller = stub("controller", :response => response, :request => request)
190
+
191
+ @filter.after(controller)
192
+ end
193
+
194
+ def test_embed_css_detects_missing_character_encoding
195
+ xml = <<-EOD
196
+ <?xml version='1.0' encoding='utf-8' ?>
197
+ <!DOCTYPE html PUBLIC "-//WAPFORUM//DTD XHTML Mobile 1.2//EN" "http://www.openmobilealliance.org/tech/DTD/xhtml-mobile12.dtd">
198
+ <html lang='ja' xml:lang='ja' xmlns='http://www.w3.org/1999/xhtml'>
199
+ <head>
200
+ </head>
201
+ <body>
202
+ ほげ
203
+ </body>
204
+ </html>
205
+ EOD
206
+ encoded_body = @filter.embed_css(xml)
207
+ assert_match "ほげ", encoded_body
208
+ assert_match '<meta content="application/xhtml+xml;charset=UTF-8" http-equiv="content-type" />', encoded_body
209
+ assert_match '<!-- Please explicitly specify the encoding of your document as below. Assuming UTF-8. -->', encoded_body
210
+ end
211
+ end
@@ -0,0 +1,24 @@
1
+ require 'test_helper'
2
+ require File.join File.dirname(__FILE__), '..', '..', 'lib', 'docomo_css', 'stylesheet'
3
+
4
+ class DocomoCss::StylesheetTest < Test::Unit::TestCase
5
+ def test_css_path
6
+ ActionController::Base.stubs(:asset_host => nil)
7
+ href = "/stylesheets/all.css?1274411517"
8
+ stylesheet = DocomoCss::Stylesheet.new(href)
9
+ assert_equal "#{Rails.root}/public/stylesheets/all.css", stylesheet.path
10
+ end
11
+
12
+ def test_css_path_with_asset_host
13
+ ActionController::Base.stubs(:asset_host => "http://assets.example.com/")
14
+ href = "http://assets.example.com/stylesheets/all.css?1274411517"
15
+ stylesheet = DocomoCss::Stylesheet.new(href)
16
+ assert_equal "#{Rails.root}/public/stylesheets/all.css", stylesheet.path
17
+ end
18
+
19
+ def test_valid
20
+ assert !DocomoCss::Stylesheet.new(nil).valid?
21
+ assert !DocomoCss::Stylesheet.new("/all.css?1274411517").valid?
22
+ assert DocomoCss::Stylesheet.new("/actual.css?1274411517").valid?
23
+ end
24
+ end
@@ -0,0 +1,26 @@
1
+ <?xml version="1.0" encoding="Shift_JIS"?>
2
+ <!DOCTYPE html PUBLIC "-//i-mode group (ja)//DTD XHTML i-XHTML(Locale/Ver.=ja/2.3) 1.0//EN" "i-xhtml_4ja_10.dtd">
3
+ <html xmlns="http://www.w3.org/1999/xhtml">
4
+ <head>
5
+ <meta http-equiv="Content-Type" content="application/xhtml+xml; charset=Shift_JIS" />
6
+ <style type="text/css">
7
+ <![CDATA[
8
+ a:visited {
9
+ color: blue;
10
+ }
11
+ a:link {
12
+ color: red;
13
+ }
14
+ a:focus {
15
+ color: green;
16
+ }
17
+
18
+ ]]>
19
+ </style>
20
+ </head>
21
+ <body>
22
+ <div class="content" style="background-color:#999">
23
+ <a href="/">TOP</a>
24
+ </div>
25
+ </body>
26
+ </html>
@@ -0,0 +1,4 @@
1
+ a:link { color: red; }
2
+ a:focus { color: green; }
3
+ a:visited { color: blue; }
4
+ div.content { background-color: #999 }
@@ -0,0 +1,11 @@
1
+ require 'test/unit'
2
+ require 'rubygems'
3
+ require 'mocha'
4
+
5
+ Rails = Mocha::Mockery.instance.unnamed_mock
6
+ Rails.stubs(:root => File.dirname(__FILE__))
7
+
8
+ module ActionController
9
+ Base = Mocha::Mockery.instance.unnamed_mock
10
+ Base.stubs(:asset_host => nil)
11
+ end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: docomo_css
3
3
  version: !ruby/object:Gem::Version
4
- hash: 3
4
+ hash: 31
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
8
  - 4
9
- - 6
10
- version: 0.4.6
9
+ - 8
10
+ version: 0.4.8
11
11
  platform: ruby
12
12
  authors:
13
13
  - milk1000cc
@@ -16,7 +16,7 @@ autorequire:
16
16
  bindir: bin
17
17
  cert_chain: []
18
18
 
19
- date: 2011-03-09 00:00:00 +09:00
19
+ date: 2011-04-01 00:00:00 +09:00
20
20
  default_executable:
21
21
  dependencies:
22
22
  - !ruby/object:Gem::Dependency
@@ -74,14 +74,24 @@ extensions: []
74
74
  extra_rdoc_files: []
75
75
 
76
76
  files:
77
+ - .gitignore
77
78
  - MIT-LICENSE
78
79
  - README.rdoc
80
+ - Rakefile
81
+ - docomo_css.gemspec
82
+ - lib/docomo_css.rb
79
83
  - lib/docomo_css/embeddable_style.rb
80
84
  - lib/docomo_css/filter.rb
81
85
  - lib/docomo_css/railtie.rb
82
86
  - lib/docomo_css/stylesheet.rb
83
87
  - lib/docomo_css/version.rb
84
- - lib/docomo_css.rb
88
+ - test/actual.html
89
+ - test/docomo_css/emeddable_style_test.rb
90
+ - test/docomo_css/filter_test.rb
91
+ - test/docomo_css/stylesheet_test.rb
92
+ - test/expected.html
93
+ - test/public/actual.css
94
+ - test/test_helper.rb
85
95
  has_rdoc: true
86
96
  homepage: http://www.milk1000.cc/
87
97
  licenses: []
@@ -105,15 +115,13 @@ required_rubygems_version: !ruby/object:Gem::Requirement
105
115
  requirements:
106
116
  - - ">="
107
117
  - !ruby/object:Gem::Version
108
- hash: 23
118
+ hash: 3
109
119
  segments:
110
- - 1
111
- - 3
112
- - 6
113
- version: 1.3.6
120
+ - 0
121
+ version: "0"
114
122
  requirements: []
115
123
 
116
- rubyforge_project: docomo_css
124
+ rubyforge_project: galakei
117
125
  rubygems_version: 1.3.7
118
126
  signing_key:
119
127
  specification_version: 3