docomo_css 0.0.1

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,3 @@
1
+ *.swp
2
+ pkg/*
3
+ rdoc/*
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2008 milk1000cc
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,83 @@
1
+ = DocomoCss
2
+
3
+ docomo_css is a CSS in-liner.
4
+
5
+ Most handsets for the Japanese cell-phone carrier DoCoMo cannot use external
6
+ style sheets, such as
7
+
8
+ <link rel="stylesheet" /> style css, only can use in-line CSS.
9
+
10
+ Instead, every element must use its own style attribute, for example
11
+
12
+ <div style="font-size:x-small">
13
+
14
+ docomo_css works around this by inlining all CSS automatically for you.
15
+
16
+ Furthermore, DoCoMo phones have a number of limitations about how you can style
17
+ elements. For instance, the following will not be rendered properly.
18
+
19
+ <h1 style="color:red">Foo</h1>
20
+
21
+ However, this can be worked around by doing the following
22
+
23
+ <h1><span style="color:red">Foo</span></h1>
24
+
25
+ This library will automatically do this transformation for you if you apply css styles to unsupported elements like h1.
26
+
27
+ == Install
28
+
29
+ sudo gem install milk1000cc-docomo_css --source=http://gems.github.com
30
+
31
+ == Usage
32
+
33
+ # app/controllers/articles_controller.rb
34
+ class ArticlesController < ApplicationController
35
+ docomo_filter # please add this
36
+ ...
37
+ end
38
+
39
+ # app/views/articles/index.html.erb
40
+ <html>
41
+ <head>
42
+ <%= stylesheet_link_tag 'foo', :media => 'handheld, tty' %>
43
+ </head>
44
+ <body>
45
+ <h1>Header</h1>
46
+ <div class="title">bar</div>
47
+ </body>
48
+ </html>
49
+
50
+ # public/stylesheets/foo.css
51
+ .title {
52
+ color: red;
53
+ }
54
+
55
+ h1 {
56
+ color:blue:
57
+ }
58
+
59
+ # result
60
+ <html>
61
+ <head>
62
+ <%= stylesheet_link_tag 'foo', :media => 'handheld, tty' %>
63
+ </head>
64
+ <body>
65
+ <h1><span style="color:blue">Header</span></h1>
66
+ <div class="title" style="color:red">bar</div>
67
+ </body>
68
+ </html>
69
+
70
+ In addition to the basic usage, you may also provide the css inliner with additional directive by adding a docomo_css attribute to the style tag.
71
+
72
+ Options for the value of this docomo_css are
73
+
74
+ * ignore - this stylesheet will not be inlined
75
+ * remove_after_inline - remove the link to this stylesheet after processing it
76
+
77
+ == Author
78
+
79
+ Copyright (c) 2008 milk1000cc, released under the MIT license
80
+
81
+ milk1000cc <mailto:info@milk1000.cc>
82
+
83
+ Gem, refactorings, and additions by Paul McMahon <mailto:paul@mobalean.com>
data/Rakefile ADDED
@@ -0,0 +1,38 @@
1
+ require 'rake'
2
+ require 'rake/testtask'
3
+ require 'rake/rdoctask'
4
+
5
+ desc 'Default: run unit tests.'
6
+ task :default => :test
7
+
8
+ desc 'Test the docomo_css plugin.'
9
+ Rake::TestTask.new(:test) do |t|
10
+ t.libs << 'lib'
11
+ t.pattern = 'test/**/*_test.rb'
12
+ t.verbose = true
13
+ end
14
+
15
+ desc 'Generate documentation for the docomo_css plugin.'
16
+ Rake::RDocTask.new(:rdoc) do |rdoc|
17
+ rdoc.rdoc_dir = 'rdoc'
18
+ rdoc.title = 'DocomoCss'
19
+ rdoc.options << '--line-numbers' << '--inline-source'
20
+ rdoc.rdoc_files.include('README.rdoc')
21
+ rdoc.rdoc_files.include('lib/**/*.rb')
22
+ end
23
+
24
+ begin
25
+ require 'jeweler'
26
+ Jeweler::Tasks.new do |s|
27
+ s.name = "docomo_css"
28
+ s.summary = "CSS inliner"
29
+ s.description = "Inlines CSS so that you can use external CSS with docomo handsets."
30
+ s.email = "info@milk1000.cc"
31
+ s.homepage = "http://www.milk1000.cc/"
32
+ s.authors = ["milk1000cc", "Paul McMahon"]
33
+ s.add_dependency 'hpricot'
34
+ s.add_dependency 'milk1000cc-tiny_css'
35
+ end
36
+ rescue LoadError
37
+ puts "Jeweler not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
38
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.0.1
@@ -0,0 +1,54 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = %q{docomo_css}
5
+ s.version = "0.0.1"
6
+
7
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
8
+ s.authors = ["milk1000cc", "Paul McMahon"]
9
+ s.date = %q{2009-06-11}
10
+ s.description = %q{Inlines CSS so that you can use external CSS with docomo handsets.}
11
+ s.email = %q{info@milk1000.cc}
12
+ s.extra_rdoc_files = [
13
+ "README.rdoc"
14
+ ]
15
+ s.files = [
16
+ ".gitignore",
17
+ "MIT-LICENSE",
18
+ "README.rdoc",
19
+ "Rakefile",
20
+ "VERSION",
21
+ "docomo_css.gemspec",
22
+ "init.rb",
23
+ "install.rb",
24
+ "lib/docomo_css.rb",
25
+ "rails/init.rb",
26
+ "test/docomo_css_test.rb",
27
+ "uninstall.rb"
28
+ ]
29
+ s.has_rdoc = true
30
+ s.homepage = %q{http://www.milk1000.cc/}
31
+ s.rdoc_options = ["--charset=UTF-8"]
32
+ s.require_paths = ["lib"]
33
+ s.rubygems_version = %q{1.3.1}
34
+ s.summary = %q{CSS inliner}
35
+ s.test_files = [
36
+ "test/docomo_css_test.rb"
37
+ ]
38
+
39
+ if s.respond_to? :specification_version then
40
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
41
+ s.specification_version = 2
42
+
43
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
44
+ s.add_runtime_dependency(%q<hpricot>, [">= 0"])
45
+ s.add_runtime_dependency(%q<tiny_css>, [">= 0"])
46
+ else
47
+ s.add_dependency(%q<hpricot>, [">= 0"])
48
+ s.add_dependency(%q<tiny_css>, [">= 0"])
49
+ end
50
+ else
51
+ s.add_dependency(%q<hpricot>, [">= 0"])
52
+ s.add_dependency(%q<tiny_css>, [">= 0"])
53
+ end
54
+ end
data/init.rb ADDED
@@ -0,0 +1,2 @@
1
+ require 'docomo_css/rails'
2
+ ActionController::Base.send :include, DocomoCss::Rails
data/install.rb ADDED
@@ -0,0 +1 @@
1
+ # Install hook code here
data/lib/docomo_css.rb ADDED
@@ -0,0 +1,130 @@
1
+ require 'hpricot'
2
+ require 'tiny_css'
3
+
4
+ module DocomoCss
5
+
6
+ def self.handlers
7
+ unless defined?(@handlers)
8
+ element_handler = UnsupportedElementHandler.new(
9
+ (1..6).map {|i| "h#{i}"} + %w{p},
10
+ %w{font-size color})
11
+ @handlers = Hash.new {|h,k| h[k] = DefaultHandler.new(k, element_handler)}
12
+ ["a:link", "a:focus", "a:visited"].each do |k|
13
+ @handlers[k] = PseudoSelectorHandler.new(k)
14
+ end
15
+ end
16
+ @handlers
17
+ end
18
+
19
+ def self.inline_css(content, css_dir)
20
+ content.gsub!(/&#(\d+);/, 'HTMLCSSINLINERESCAPE\1::::::::')
21
+
22
+ doc = Hpricot(content)
23
+
24
+ linknodes = doc/'//link[@rel="stylesheet"]'
25
+ linknodes.each do |linknode|
26
+ href = linknode['href']
27
+ next unless href && allowed_media_type?(linknode['media'])
28
+ if linknode['docomo_css'] == "ignore"
29
+ linknode.remove_attribute('docomo_css')
30
+ next
31
+ end
32
+
33
+ cssfile = File.join(css_dir, href)
34
+ cssfile.gsub!(/\?.+/, '')
35
+ css = TinyCss.new.read(cssfile)
36
+
37
+ style_style = TinyCss.new
38
+ css.style.each do |selector, style|
39
+ handlers[selector].replace(doc, style_style, style)
40
+ end
41
+ unless style_style.style.keys.empty?
42
+ style = %(<style type="text/css">#{ style_style.write_string }</style>)
43
+ (doc/('head')).append style
44
+ end
45
+ end
46
+ doc.search('//link[@docomo_css="remove_after_inline"]').remove
47
+
48
+ content = doc.to_html
49
+
50
+ content.gsub!(/HTMLCSSINLINERESCAPE(\d+)::::::::/, '&#\1;')
51
+ content
52
+ end
53
+
54
+ def self.allowed_media_type?(s)
55
+ s.nil? || s =~ /handheld|all|tty/
56
+ end
57
+
58
+ class Handler
59
+ def initialize(selector)
60
+ @selector = selector
61
+ end
62
+ end
63
+
64
+ class PseudoSelectorHandler < Handler
65
+ def replace(doc, style_style, style)
66
+ style_style.style[@selector] = style
67
+ end
68
+ end
69
+
70
+ class DefaultHandler < Handler
71
+ def initialize(selector, element_handler)
72
+ super(selector)
73
+ @element_handler = element_handler
74
+ end
75
+
76
+ def replace(doc, style_style, style)
77
+ (doc/(@selector)).each do |element|
78
+ @element_handler.add_style(element, style)
79
+ end
80
+ end
81
+ end
82
+
83
+ class UnsupportedElementHandler
84
+ def initialize(unsupported_elements, unsupported_styles)
85
+ @unsupported_elements = unsupported_elements
86
+ @unsupported_styles = unsupported_styles
87
+ end
88
+
89
+ def add_style(element, style)
90
+ if @unsupported_elements.include?(element.name)
91
+ unsupported = TinyCss::OrderedHash.new
92
+ supported = TinyCss::OrderedHash.new
93
+ style.each do |k,v|
94
+ s = @unsupported_styles.include?(k) ? unsupported : supported
95
+ s[k] = v
96
+ end
97
+
98
+ #TODO: unit test
99
+ _add_style(element, supported) unless supported.keys.empty?
100
+
101
+ unless unsupported.keys.empty?
102
+ # BUG: assumes source contains no span wrapped in selector
103
+ wrapped_children = element.search("span")
104
+ if wrapped_children.empty?
105
+ element.search("/").wrap("<span></span>")
106
+ wrapped_children = element.search("span")
107
+ end
108
+ wrapped_children.each do |c|
109
+ add_style(c, unsupported)
110
+ end
111
+ end
112
+ else
113
+ _add_style(element, style)
114
+ end
115
+ end
116
+
117
+ def _add_style(element, style)
118
+ style_attr = element[:style]
119
+ style_attr = (!style_attr) ? stringify_style(style) :
120
+ [style_attr, stringify_style(style)].join(';')
121
+ element[:style] = style_attr
122
+ end
123
+
124
+ private
125
+
126
+ def stringify_style(style)
127
+ style.map { |k, v| "#{ k }:#{ v }" }.join ';'
128
+ end
129
+ end
130
+ end
data/rails/init.rb ADDED
@@ -0,0 +1,2 @@
1
+ require 'docomo_css/rails'
2
+ ActionController::Base.send :include, DocomoCss::Rails
@@ -0,0 +1,46 @@
1
+ require 'test/unit'
2
+ require 'rubygems'
3
+ $LOAD_PATH << File.join(File.dirname(__FILE__), '..', 'lib')
4
+ require 'docomo_css'
5
+
6
+ class DocomoCssTest < Test::Unit::TestCase
7
+ def self.data_path
8
+ File.join(File.dirname(__FILE__), "data")
9
+ end
10
+
11
+ Dir.glob(File.join(data_path, "html", "*")) do |f|
12
+ s = File.basename(f,".html")
13
+ define_method("test_#{s}") do
14
+ e = expected(s)
15
+ i = inline(s)
16
+ e_lines = e.split("\n")
17
+ i_lines = i.split("\n")
18
+ e_lines.each_with_index do |s,j|
19
+ assert_equal(s, i_lines[j])
20
+ end
21
+ assert_equal e, i, "#{s} did not match"
22
+ end
23
+ end
24
+
25
+ def inline(file_name)
26
+ DocomoCss.inline_css(html(file_name), data_path)
27
+ end
28
+
29
+ def html(file_name)
30
+ read_html("html", file_name)
31
+ end
32
+
33
+ def expected(file_name)
34
+ read_html("expected_html", file_name)
35
+ end
36
+
37
+ def read_html(dir, file_name)
38
+ File.open(File.join(data_path, dir, "#{file_name}.html")) do |f|
39
+ f.read
40
+ end
41
+ end
42
+
43
+ def data_path
44
+ self.class.data_path
45
+ end
46
+ end
data/uninstall.rb ADDED
@@ -0,0 +1 @@
1
+ # Uninstall hook code here
metadata ADDED
@@ -0,0 +1,106 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: docomo_css
3
+ version: !ruby/object:Gem::Version
4
+ hash: 29
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 0
9
+ - 1
10
+ version: 0.0.1
11
+ platform: ruby
12
+ authors:
13
+ - milk1000cc
14
+ - Paul McMahon
15
+ autorequire:
16
+ bindir: bin
17
+ cert_chain: []
18
+
19
+ date: 2009-06-11 00:00:00 +09:00
20
+ default_executable:
21
+ dependencies:
22
+ - !ruby/object:Gem::Dependency
23
+ name: hpricot
24
+ prerelease: false
25
+ requirement: &id001 !ruby/object:Gem::Requirement
26
+ none: false
27
+ requirements:
28
+ - - ">="
29
+ - !ruby/object:Gem::Version
30
+ hash: 3
31
+ segments:
32
+ - 0
33
+ version: "0"
34
+ type: :runtime
35
+ version_requirements: *id001
36
+ - !ruby/object:Gem::Dependency
37
+ name: tiny_css
38
+ prerelease: false
39
+ requirement: &id002 !ruby/object:Gem::Requirement
40
+ none: false
41
+ requirements:
42
+ - - ">="
43
+ - !ruby/object:Gem::Version
44
+ hash: 3
45
+ segments:
46
+ - 0
47
+ version: "0"
48
+ type: :runtime
49
+ version_requirements: *id002
50
+ description: Inlines CSS so that you can use external CSS with docomo handsets.
51
+ email: info@milk1000.cc
52
+ executables: []
53
+
54
+ extensions: []
55
+
56
+ extra_rdoc_files:
57
+ - README.rdoc
58
+ files:
59
+ - .gitignore
60
+ - MIT-LICENSE
61
+ - README.rdoc
62
+ - Rakefile
63
+ - VERSION
64
+ - docomo_css.gemspec
65
+ - init.rb
66
+ - install.rb
67
+ - lib/docomo_css.rb
68
+ - rails/init.rb
69
+ - test/docomo_css_test.rb
70
+ - uninstall.rb
71
+ has_rdoc: true
72
+ homepage: http://www.milk1000.cc/
73
+ licenses: []
74
+
75
+ post_install_message:
76
+ rdoc_options:
77
+ - --charset=UTF-8
78
+ require_paths:
79
+ - lib
80
+ required_ruby_version: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ">="
84
+ - !ruby/object:Gem::Version
85
+ hash: 3
86
+ segments:
87
+ - 0
88
+ version: "0"
89
+ required_rubygems_version: !ruby/object:Gem::Requirement
90
+ none: false
91
+ requirements:
92
+ - - ">="
93
+ - !ruby/object:Gem::Version
94
+ hash: 3
95
+ segments:
96
+ - 0
97
+ version: "0"
98
+ requirements: []
99
+
100
+ rubyforge_project:
101
+ rubygems_version: 1.3.7
102
+ signing_key:
103
+ specification_version: 2
104
+ summary: CSS inliner
105
+ test_files:
106
+ - test/docomo_css_test.rb