docomo_css 0.4.6 → 0.4.8

Sign up to get free protection for your applications and to get access to all the features.
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