galakei 0.5.1 → 0.6.0

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/Gemfile CHANGED
@@ -4,6 +4,7 @@ source "http://rubygems.org"
4
4
  gemspec
5
5
 
6
6
  group :development, :test do
7
+ gem 'rails'
7
8
  gem 'rspec', '>= 2.5.0'
8
9
  gem 'capybara'
9
10
  gem 'steak'
data/README.md CHANGED
@@ -22,6 +22,44 @@ Old docomo handsets [don't support external stylesheets](http://www.keitai-dev.n
22
22
  # outputted html
23
23
  <div style="background-color: blue;"><h1><span style="color:red;">Foo</span></h1>/div>
24
24
 
25
+ Furthermore, the css border property is supported through the "spacer.gif" technique.
26
+
27
+ # css file
28
+ div { border-bottom: 5px solid #000000; }
29
+
30
+ # source html
31
+ <div>Foo</div>
32
+
33
+ # outputted html
34
+ <div>Foo</div>
35
+ <img src="/galakei/spacer/000000" width="100%" height="5">
36
+
37
+ This will generate a 1px by 1px image, emulating the effect of borders on old docomo handsets.
38
+
39
+ ### Maintaing sessions
40
+
41
+ Old docomo handsets [don't support cookies](http://www.keitai-dev.net/Cookies). Furthermore, although Softbank and Au handsets support cookies, when accessing SSL pages, different cookies may be used. Galakei works around this by injecting a session id parameter into your URLs and forms (as long as you use a standard rails method for creating them). To enable this functionality, you will need to modify your session_store.rb initializer to allow the use of session parameters and use a non cookie-based store.
42
+
43
+ MyApp::Application.config.session_store :active_record_store, :key => '_sid', :cookie_only => false
44
+
45
+ You'll also need to enable this option in galakei
46
+
47
+ config.galakei.session_id_parameter = true
48
+
49
+ ### Emoji
50
+
51
+ Easily use [Emoji](http://www.keitai-dev.net/Emoji) in your templates with emoji_table! emoji_table will return the correct emoji for your browser, including normal PC browsers:
52
+
53
+ emoji_table.white_smiling_face # "☺"
54
+
55
+ ### Alternate galakei views
56
+
57
+ Have a PC site that you want to add galakei templates for? Put your views in app/views.galakei and they'll be used in preference to your normal app/views
58
+
59
+ ### haml
60
+
61
+ haml is great for building galakei sites, as it enforces well formed markup. galakei takes care of setting the haml template format for you, so you'll generate xhtml.
62
+
25
63
  ## Thanks
26
64
 
27
65
  * To [jpmobile](https://github.com/jpmobile/jpmobile) for offering the most mature Rails plugin for Rails
@@ -0,0 +1,9 @@
1
+ class Galakei::SpacerController < ActionController::Base
2
+ def create
3
+ respond_to do |format|
4
+ format.gif do
5
+ send_data(Galakei::Spacer.new(params[:color]).create, :disposition => "inline", :type => :gif)
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1 @@
1
+ Mime::Type.register 'image/gif', :gif
data/config/routes.rb ADDED
@@ -0,0 +1,3 @@
1
+ Rails.application.routes.draw do
2
+ match 'galakei/spacer/:color' => 'galakei/spacer#create', :defaults => { :format => :gif }
3
+ end
data/galakei.gemspec CHANGED
@@ -5,7 +5,7 @@ Gem::Specification.new do |s|
5
5
  s.name = "galakei"
6
6
  s.version = Galakei::VERSION
7
7
  s.platform = Gem::Platform::RUBY
8
- s.authors = ["Paul McMahon", "Michael Reinsch"]
8
+ s.authors = ["Paul McMahon", "Michael Reinsch", "Yuki Akamatsu"]
9
9
  s.email = "info@mobalean.com"
10
10
  s.homepage = "http://www.mobalean.com"
11
11
  s.summary = "Japanese feature phones support"
@@ -9,15 +9,26 @@ class Galakei::DocomoCss::InlineStylesheet
9
9
  return if stylesheets.empty?
10
10
  stylesheets.each do |e|
11
11
  e.unlink
12
- parser = CssParser::Parser.new
13
- uri = URI.parse(e['href'])
14
- uri.scheme = controller.request.scheme unless uri.scheme
15
- uri.host = controller.request.host unless uri.host
16
- uri.port = controller.request.port unless uri.port
17
- parser.load_uri!(uri)
18
- stylesheet = Galakei::DocomoCss::Stylesheet.new(parser)
12
+ stylesheet = Galakei::DocomoCss::Stylesheet.new(parser(e['href']))
19
13
  stylesheet.apply(doc)
20
14
  end
21
15
  controller.response.body = doc.to_xhtml(:encoding => doc.encoding)
22
16
  end
17
+
18
+ private
19
+ def self.parser(href)
20
+ parser = CssParser::Parser.new
21
+ uri = URI.parse(href)
22
+ if uri.host && uri.scheme && uri.port
23
+ parser.load_uri!(uri)
24
+ else
25
+ parser.load_file!(path(href))
26
+ end
27
+ return parser
28
+ end
29
+
30
+ def self.path(href)
31
+ base_path = href.gsub(ActionController::Base.asset_host || '', '').gsub(/\?\d+/,'')
32
+ File.join(Rails.root, 'public', base_path)
33
+ end
23
34
  end
@@ -30,40 +30,103 @@ EOD
30
30
 
31
31
  private
32
32
 
33
- def merge_style(e, s)
34
- if e["style"]
35
- e['style'] += ";" unless e['style'] =~ /;\Z/
36
- e['style'] += s
33
+ def embed_style(doc, ruleset, selector)
34
+ doc.css(selector).each do |e|
35
+ styles = []
36
+ ruleset.each_declaration do |property, value, is_important|
37
+ styles << [property,value]
38
+ end
39
+ apply_element_specific_style(e, styles)
40
+ end
41
+ end
42
+
43
+ def apply_element_specific_style(element, styles)
44
+ style_adapters = case element.name
45
+ when /^h\d$/
46
+ [BorderAdapter, BackGroundAdapter, FontAdapter]
47
+ when 'p'
48
+ [BackGroundAdapter, FontAdapter]
49
+ when 'div'
50
+ [BorderAdapter]
37
51
  else
38
- e["style"] = s
52
+ []
53
+ end
54
+ styles.each do |property,value|
55
+ applicable_styles = style_adapters.find_all {|s| s.apply?(property)}
56
+ applicable_styles = [ CssInliner ] if applicable_styles.empty?
57
+ applicable_styles.each {|s| s.apply(element, property, value) }
39
58
  end
40
59
  end
41
60
 
42
- def wrap_all_children(e, s)
43
- new_parent = e.document.parse(s).first
44
- e.children.each {|f| new_parent.add_child(f)}
45
- e.add_child(new_parent)
61
+ class GenericAdapter
62
+ private
63
+ def self.merge_style(element,property, value)
64
+ style = "#{property}: #{value};"
65
+ if element['style']
66
+ element['style'] += ";" unless element['style'] =~ /;\Z/
67
+ element['style'] += style
68
+ else
69
+ element["style"] = style
70
+ end
71
+ end
46
72
  end
47
73
 
48
- def embed_style(doc, ruleset, selector)
49
- doc.css(selector).each do |e|
50
- ruleset.each_declaration do |property, value, is_important|
51
- s = "#{property}: #{value};"
52
- if selector =~ /^(h\d|p)[^\s]*$/
53
- if %w[color font-size].include?(property)
54
- wrap_all_children(e, '<span>')
55
- merge_style(e.children.first, s)
56
- elsif %w[background-color].include?(property)
57
- div = Nokogiri.make("<div>")
58
- merge_style(div, s)
59
- e.replace(div)
60
- div.add_child(e)
61
- else
62
- merge_style(e, s)
63
- end
64
- else
65
- merge_style(e, s)
66
- end
74
+ class CssInliner < GenericAdapter
75
+ def self.apply(element, property, value)
76
+ merge_style(element,property,value)
77
+ end
78
+ end
79
+
80
+ class FontAdapter < GenericAdapter
81
+ def self.apply?(property)
82
+ %w[color font-size].include?(property)
83
+ end
84
+
85
+ def self.apply(element, property, value)
86
+ wrap_all_children(element, '<span>')
87
+ merge_style(element.children.first, property, value)
88
+ end
89
+
90
+ private
91
+
92
+ def self.wrap_all_children(element, tag)
93
+ new_parent = element.document.parse(tag).first
94
+ element.children.each {|f| new_parent.add_child(f)}
95
+ element.add_child(new_parent)
96
+ end
97
+ end
98
+
99
+ class BackGroundAdapter < GenericAdapter
100
+ def self.apply?(property)
101
+ property == 'background-color'
102
+ end
103
+
104
+ def self.apply(element, property, value)
105
+ div = Nokogiri.make("<div>")
106
+ merge_style(div,property,value)
107
+ element.replace(div)
108
+ div.add_child(element)
109
+ end
110
+ end
111
+
112
+ class BorderAdapter < GenericAdapter
113
+ def self.apply?(property)
114
+ %w[border border-top border-bottom].include?(property)
115
+ end
116
+
117
+ def self.apply(element, property,value)
118
+ color = value.split(/\s/).last.split('#').last
119
+ thickness = value.match(/(\d+)px/)[1]
120
+ img = Galakei::Spacer.new(color).img_tag(:height => thickness)
121
+
122
+ case property
123
+ when 'border'
124
+ element.after(img)
125
+ element.before(img)
126
+ when 'border-top'
127
+ element.before(img)
128
+ when 'border-bottom'
129
+ element.after(img)
67
130
  end
68
131
  end
69
132
  end
@@ -2,44 +2,44 @@ require 'active_support/core_ext/string/output_safety'
2
2
  module Galakei
3
3
  class EmojiTable
4
4
  MAPPING = {
5
- :black_sun_with_rays => %w[2600 E63E E488 E04A],
6
- :cloud => %w[2601 E63F E48D E049],
7
- :black_telephon => %w[260E E687 E596 E009],
8
- :white_smiling_face => %w[263A E6F0 E4FB E414],
9
- :persevering_face => %w[1F623 E72B EAC2 E406],
10
- :left_pointing_magnifying_glass => %w[1F50D E6DC E518 E114],
11
- :envelope => %w[2709 E6D3 E521 E103],
12
- :envelope_with_downwards_arrow_above => %w[1F4E9 E6CF EB62 E103],
13
- :footprints => %w[1F463 E698 EB2A E536],
14
- :pencil => %w[270F E719 E4A1 E301],
15
- :key => %w[1F511 E6D9 E519 E03F],
16
- :alarm_clock => %w[23F0 E6BA E594 E02D],
17
- :four_leaf_clover => %w[1F340 E741 E513 E110],
18
- :warning_sign => %w[26A0 E737 E481 E252],
19
- :winking_face => %w[1F609 E729 E5C3 E405],
20
- :smiling_face_with_open_mouth => %w[1F603 E6F0 E471 E057],
21
- :house_building => %w[1F3E0 E663 E4AB E036],
22
- :squared_new => %w[1F195 E6DD E5B5 E212],
23
- :sparkle => %w[2747 E6FA E46C E32E],
24
- :copyright_sign => %w[00A9 E731 E558 E24E],
25
- :registered_sign => %w[00AE E736 E559 E24F],
26
- :trade_mark_sign => %w[2122 E732 E54E E537],
27
- :hash_key => [ %w[0023 20E3] ] + %w[E6E0 EB84 E210],
28
- :keycap_1 => [ %w[0031 20E3] ] + %w[E6E2 E522 E21C],
29
- :keycap_2 => [ %w[0032 20E3] ] + %w[E6E3 E523 E21D],
30
- :keycap_3 => [ %w[0033 20E3] ] + %w[E6E4 E524 E21E],
31
- :keycap_4 => [ %w[0034 20E3] ] + %w[E6E5 E525 E21F],
32
- :keycap_5 => [ %w[0035 20E3] ] + %w[E6E6 E526 E220],
33
- :keycap_6 => [ %w[0036 20E3] ] + %w[E6E7 E527 E221],
34
- :keycap_7 => [ %w[0037 20E3] ] + %w[E6E8 E528 E222],
35
- :keycap_8 => [ %w[0040 20E3] ] + %w[E6E9 E529 E223],
36
- :keycap_9 => [ %w[0041 20E3] ] + %w[E6EA E52A E224],
37
- :keycap_0 => [ %w[0030 20E3] ] + %w[E6EB E52C E225],
5
+ :black_sun_with_rays => %w[2600 E63E E488 E04A EF60],
6
+ :cloud => %w[2601 E63F E48D E049 EF65],
7
+ :black_telephon => %w[260E E687 E596 E009 F0B3],
8
+ :white_smiling_face => %w[263A E6F0 E4FB E414 EFD4],
9
+ :persevering_face => %w[1F623 E72B EAC2 E406 EC96],
10
+ :left_pointing_magnifying_glass => %w[1F50D E6DC E518 E114 EFF1],
11
+ :envelope => %w[2709 E6D3 E521 E103 EFFA],
12
+ :envelope_with_downwards_arrow_above => %w[1F4E9 E6CF EB62 E103 ED66],
13
+ :footprints => %w[1F463 E698 EB2A E536 ECEB],
14
+ :pencil => %w[270F E719 E4A1 E301 EF79],
15
+ :key => %w[1F511 E6D9 E519 E03F EFF2],
16
+ :alarm_clock => %w[23F0 E6BA E594 E02D F0B1],
17
+ :four_leaf_clover => %w[1F340 E741 E513 E110 EFEC],
18
+ :warning_sign => %w[26A0 E737 E481 E252 EF59],
19
+ :winking_face => %w[1F609 E729 E5C3 E405 F0F3],
20
+ :smiling_face_with_open_mouth => %w[1F603 E6F0 E471 E057 EF49],
21
+ :house_building => %w[1F3E0 E663 E4AB E036 EF84],
22
+ :squared_new => %w[1F195 E6DD E5B5 E212 F0E5],
23
+ :sparkle => %w[2747 E6FA E46C E32E EF44],
24
+ :copyright_sign => %w[00A9 E731 E558 E24E F074],
25
+ :registered_sign => %w[00AE E736 E559 E24F F075],
26
+ :trade_mark_sign => %w[2122 E732 E54E E537 F06A],
27
+ :hash_key => [ %w[0023 20E3] ] + %w[E6E0 EB84 E210 ED89],
28
+ :keycap_1 => [ %w[0031 20E3] ] + %w[E6E2 E522 E21C EFFB],
29
+ :keycap_2 => [ %w[0032 20E3] ] + %w[E6E3 E523 E21D EFFC],
30
+ :keycap_3 => [ %w[0033 20E3] ] + %w[E6E4 E524 E21E F040],
31
+ :keycap_4 => [ %w[0034 20E3] ] + %w[E6E5 E525 E21F F041],
32
+ :keycap_5 => [ %w[0035 20E3] ] + %w[E6E6 E526 E220 F042],
33
+ :keycap_6 => [ %w[0036 20E3] ] + %w[E6E7 E527 E221 F043],
34
+ :keycap_7 => [ %w[0037 20E3] ] + %w[E6E8 E528 E222 F044],
35
+ :keycap_8 => [ %w[0040 20E3] ] + %w[E6E9 E529 E223 F045],
36
+ :keycap_9 => [ %w[0041 20E3] ] + %w[E6EA E52A E224 F046],
37
+ :keycap_0 => [ %w[0030 20E3] ] + %w[E6EB E52C E225 F047],
38
38
  }
39
39
  MAPPING.each do |k,v|
40
40
  MAPPING[k] = v.map do |a|
41
41
  a = [ a ] if a.is_a?(String)
42
- a.map {|s| "&#x#{s};"}.join.html_safe
42
+ a.map{|s| ("0x" + s).hex}.pack("U*")
43
43
  end
44
44
  define_method k do
45
45
  MAPPING[k][@carrier]
@@ -59,9 +59,11 @@ module Galakei
59
59
  end
60
60
 
61
61
  def self.au
62
- @au ||= EmojiTable.new(2)
62
+ @au ||= EmojiTable.new(4)
63
63
  end
64
64
 
65
+
66
+
65
67
  def self.softbank
66
68
  @softbank ||= EmojiTable.new(3)
67
69
  end
@@ -0,0 +1,4 @@
1
+ module Galakei
2
+ class Engine < ::Rails::Engine #:nodoc:
3
+ end
4
+ end
@@ -0,0 +1,23 @@
1
+ # coding: utf-8
2
+ class Galakei::Filter::NonStandardChar < Galakei::Filter::Base
3
+ def self.inject(klass)
4
+ this_class = self
5
+ klass.after_filter self, :if => lambda {|c| this_class.condition?(c) }
6
+ end
7
+
8
+ def condition?
9
+ response.content_type =~ %r{text/html|application/xhtml+xml}
10
+ end
11
+
12
+ def filter
13
+ body = response.body
14
+ full_dot = "\u30FB"
15
+ half_dot = "\uFF65"
16
+ body.gsub!("&middot;", full_dot) if request.docomo?
17
+ body.gsub!("\u00B7", half_dot) unless request.softbank?
18
+ body.gsub!("&#xFF65;", half_dot) if request.au?
19
+ body.gsub!("&#x30FB;", full_dot) if request.au?
20
+ body.gsub!("&sdot;", half_dot)
21
+ response.body = body
22
+ end
23
+ end
@@ -1,10 +1,10 @@
1
1
  module Galakei
2
2
  module HelperMethods
3
+ include ActionView::Helpers::RawOutputHelper
3
4
  def self.included(klass)
4
5
  klass.helper_method :galakei?
5
6
  klass.helper_method :emoji_table
6
- end
7
-
7
+ end
8
8
  protected
9
9
 
10
10
  def galakei?
@@ -1,10 +1,10 @@
1
1
  module Galakei
2
- class Railtie < Rails::Railtie
2
+ class Railtie < ::Rails::Railtie
3
3
  config.galakei = ActiveSupport::OrderedOptions.new
4
4
  initializer "galakei.extend.action_controller" do |app|
5
5
  ActiveSupport.on_load :action_controller do
6
6
  include Galakei::HelperMethods
7
- filters = %w[Views ContentType]
7
+ filters = %w[Views ContentType NonStandardChar]
8
8
  filters << :Haml if defined?(Haml)
9
9
  filters.each {|f| Galakei::Filter.const_get(f).inject(self) }
10
10
  end
@@ -0,0 +1,33 @@
1
+ module Galakei
2
+ class Spacer
3
+ HEX = [
4
+ '47494638396101000100f70000',
5
+ 'f'*1530,
6
+ '2c000000000100010000080400010404003b'
7
+ ]
8
+
9
+ def initialize(color)
10
+ @color = color.gsub('#','')
11
+ end
12
+
13
+ def create
14
+ num = hex.size
15
+ raise 'invalid hex' if num % 2 != 0
16
+ bin = ''
17
+ (num/2).times do |i|
18
+ bin += (hex[2 * (i + 1) - 2,2]).to_i(16).chr
19
+ end
20
+ return bin
21
+ end
22
+
23
+ def hex
24
+ HEX[0] + @color + HEX[1] + HEX[2]
25
+ end
26
+
27
+ def img_tag(options = {})
28
+ width = options[:width] || '100%'
29
+ height = options[:height] || 1
30
+ "<img src='/galakei/spacer/#{@color}' width='#{width}' height='#{height}'>"
31
+ end
32
+ end
33
+ end
@@ -1,3 +1,3 @@
1
1
  module Galakei
2
- VERSION = "0.5.1"
2
+ VERSION = "0.6.0"
3
3
  end
data/lib/galakei.rb CHANGED
@@ -1,5 +1,6 @@
1
1
  if defined?(Rails)
2
2
  require 'galakei/railtie'
3
+ require 'galakei/engine'
3
4
  require 'galakei/use_rack_request_to_extract_sid'
4
5
  end
5
6
  require 'galakei/request'
@@ -12,10 +13,12 @@ module Galakei
12
13
  autoload :InputMode, "galakei/input_mode"
13
14
  autoload :EmojiTable, "galakei/emoji_table"
14
15
  autoload :SessionIdParameterInForm, "galakei/session_id_parameter_in_form"
16
+ autoload :Spacer, "galakei/spacer"
15
17
  module Filter
16
18
  autoload :Base, "galakei/filter/base"
17
19
  autoload :ContentType, "galakei/filter/content_type"
18
20
  autoload :Haml, "galakei/filter/haml"
19
21
  autoload :Views, "galakei/filter/views"
22
+ autoload :NonStandardChar, "galakei/filter/non_standard_char"
20
23
  end
21
24
  end
@@ -1,7 +1,6 @@
1
1
  require File.expand_path(File.dirname(__FILE__) + "/../spec_helper")
2
2
  require "steak"
3
3
  require 'capybara/rspec'
4
- require File.expand_path(File.dirname(__FILE__) + "/app/fake")
5
4
 
6
5
  Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
7
6
 
@@ -30,17 +30,21 @@ end
30
30
 
31
31
  feature 'inlining of css' do
32
32
  scenario 'requesting simple page for docomo', :driver => :docomo do
33
- FakeWeb.register_uri(:get, 'http://www.example.com/stylesheets/docomo_css/simple.css', :body => "span { color: red }")
33
+ parser = CssParser::Parser.new
34
+ parser.add_block!('span { color: red}')
35
+ Galakei::DocomoCss::InlineStylesheet.stub(:parser) { parser }
34
36
  visit '/docomo_css/simple'
35
37
  find("span")["style"].should == "color: red;"
36
38
  page.should_not have_xpath("//link")
37
39
  end
40
+
38
41
  scenario 'requesting external page for docomo', :driver => :docomo do
39
42
  FakeWeb.register_uri(:get, 'http://www.galakei.com/external.css', :body => "span { color: red }")
40
43
  visit '/docomo_css/external'
41
44
  find("span")["style"].should == "color: red;"
42
45
  page.should_not have_xpath("//link")
43
46
  end
47
+
44
48
  %w[au softbank docomo_2_0].each do |carrier|
45
49
  scenario "requesting simple page for #{carrier}", :driver => carrier.to_sym do
46
50
  visit '/docomo_css/simple'
@@ -10,21 +10,21 @@ end
10
10
  feature 'emoji table' do
11
11
  scenario 'for docomo', :driver => :docomo do
12
12
  visit '/emoji'
13
- page.body.should match("&#xE63E;")
13
+ page.body.should match("\uE63E")
14
14
  end
15
15
 
16
16
  scenario 'for au', :driver => :au do
17
17
  visit '/emoji'
18
- page.body.should match("&#xE488;")
18
+ page.body.should match("\uEF60")
19
19
  end
20
20
 
21
21
  scenario 'for softbank', :driver => :softbank do
22
22
  visit '/emoji'
23
- page.body.should match("&#xE04A;")
23
+ page.body.should match("\uE04A")
24
24
  end
25
25
 
26
26
  scenario 'for non galakei' do
27
27
  visit '/emoji'
28
- page.body.should match("&#x2600;")
28
+ page.body.should match("\u2600")
29
29
  end
30
30
  end
@@ -0,0 +1,81 @@
1
+ # encoding: UTF-8
2
+ require File.expand_path(File.dirname(__FILE__) + '/acceptance_helper')
3
+
4
+ class NonStandardCharController < ApplicationController
5
+ def middot
6
+ render :inline => '&middot;'
7
+ end
8
+
9
+ def latin
10
+ render :inline => "\u00B7"
11
+ end
12
+
13
+ def harf_entity
14
+ render :inline => "&#xFF65;"
15
+ end
16
+
17
+ def full_entity
18
+ render :inline => "&#x30FB;"
19
+ end
20
+
21
+ def sdot
22
+ render :inline => "&sdot;"
23
+ end
24
+ end
25
+
26
+ feature 'nakaguro' do
27
+ scenario "Do convert &middot for docomo", :driver => :docomo do
28
+ visit '/non_standard_char/middot'
29
+ page.body.should == "\u30FB"
30
+ end
31
+
32
+ %w[softbank au].each do |s|
33
+ scenario "Do not convert &middot for #{s}", :driver => s.to_sym do
34
+ visit '/non_standard_char/middot'
35
+ page.body.should == "&middot;"
36
+ end
37
+ end
38
+
39
+ %w[au docomo].each do |s|
40
+ scenario "Do convert latin dot(\u00B7) for #{s}", :driver => s.to_sym do
41
+ visit '/non_standard_char/latin'
42
+ page.body.should == "\uFF65"
43
+ end
44
+ end
45
+
46
+ scenario "Do not convert latin dot(\u00B7) for softbank", :driver => :softbank do
47
+ visit '/non_standard_char/latin'
48
+ page.body.should == "\u00B7"
49
+ end
50
+
51
+ %w[softbank docomo].each do |s|
52
+ scenario "Do not convert &#xFF65 for #{s}", :driver => s.to_sym do
53
+ visit '/non_standard_char/harf_entity'
54
+ page.body.should == "&#xFF65;"
55
+ end
56
+ end
57
+
58
+ scenario "Do convert &#xFF65 for au", :driver => :au do
59
+ visit '/non_standard_char/harf_entity'
60
+ page.body.should == "\uFF65"
61
+ end
62
+
63
+ %w[docomo softbank].each do |s|
64
+ scenario "Do not convert &#x30FB for #{s}", :driver => s.to_sym do
65
+ visit '/non_standard_char/full_entity'
66
+ page.body.should == "&#x30FB;"
67
+ end
68
+ end
69
+
70
+ scenario "Do convert &#x30FB for au", :driver => :au do
71
+ visit '/non_standard_char/full_entity'
72
+ page.body.should == "\u30FB"
73
+ end
74
+
75
+ %w[softbank au docomo].each do |s|
76
+ scenario "Do convert &sdot; to \uFF65 for #{s}", :driver => s.to_sym do
77
+ visit '/non_standard_char/sdot'
78
+ page.body.should == "\uFF65"
79
+ end
80
+ end
81
+ end
@@ -4,6 +4,7 @@ require 'action_controller/railtie'
4
4
  require 'action_view/railtie'
5
5
  require 'haml'
6
6
  require 'galakei/railtie'
7
+ require 'galakei/engine'
7
8
 
8
9
  # database
9
10
  ActiveRecord::Base.configurations = {'test' => {:adapter => 'sqlite3', :database => ':memory:'}}
@@ -0,0 +1,9 @@
1
+ require 'spec_helper'
2
+
3
+ describe Galakei::SpacerController do
4
+ before do
5
+ get :create, :color => '#000000', :format => :gif
6
+ end
7
+ subject { response }
8
+ its(:content_type) { should eq 'image/gif' }
9
+ end
@@ -1,5 +1,5 @@
1
1
  require 'spec_helper'
2
- require "nokogiri"
2
+ require 'nokogiri'
3
3
 
4
4
  describe Galakei::DocomoCss::Stylesheet do
5
5
  context "simple stylesheet" do
@@ -45,6 +45,7 @@ describe Galakei::DocomoCss::Stylesheet do
45
45
  doc.to_s.should == %q{<div class="alC" style="background-color: red;text-align: center;">foo</div>}
46
46
  end
47
47
  end
48
+
48
49
  context "stylesheet with pseudo style" do
49
50
  before do
50
51
  parser = CssParser::Parser.new
@@ -86,6 +87,7 @@ EOD
86
87
  #{tag}.color { color: red; }
87
88
  #{tag}.fontsize { font-size: x-small; }
88
89
  #{tag}.backgroundcolor { background-color: blue; }
90
+ .classonly { line-height: 1px; }
89
91
  EOD
90
92
  @stylesheet = described_class.new(parser)
91
93
  end
@@ -113,6 +115,12 @@ EOD
113
115
  @stylesheet.apply(doc)
114
116
  doc.at("//div").to_s.should == %Q{<div style="background-color: blue;"><#{tag} class="backgroundcolor">foo</#{tag}></div>}
115
117
  end
118
+
119
+ it "should applied css of tag omitted" do
120
+ doc = Nokogiri::HTML("<#{tag} class='classonly'>foo</#{tag}>")
121
+ @stylesheet.apply(doc)
122
+ doc.at("//#{tag}").to_s.should == %Q{<#{tag} class="classonly" style="line-height: 1px;">foo</#{tag}>}
123
+ end
116
124
  end
117
125
  end
118
126
 
@@ -137,4 +145,121 @@ EOD
137
145
  doc.at("//h1").to_s.should == %q{<h1><span style="color: red;">foo</span></h1>}
138
146
  end
139
147
  end
148
+
149
+ shared_examples_for 'border' do
150
+ it 'applied border' do
151
+ elm = subject
152
+ elm.previous_sibling.to_s.should == @img
153
+ elm.next_sibling.to_s.should == @img
154
+ end
155
+ end
156
+
157
+ shared_examples_for 'not border' do
158
+ it "don't applied border" do
159
+ elm = subject
160
+ elm.previous_sibling.to_s.should_not == @img
161
+ elm.next_sibling.to_s.should_not == @img
162
+ end
163
+ end
164
+
165
+ shared_examples_for 'border bottom' do
166
+ it 'applied border bottom' do
167
+ elm = subject
168
+ elm.previous_sibling.to_s.should_not == @img
169
+ elm.next_sibling.to_s.should == @img
170
+ end
171
+ end
172
+
173
+ shared_examples_for 'border top' do
174
+ it 'applied border top' do
175
+ elm = subject
176
+ elm.previous_sibling.to_s.should == @img
177
+ elm.next_sibling.to_s.should_not == @img
178
+ end
179
+ end
180
+
181
+ context 'border css applied to div' do
182
+ let(:body) { "<div>test</div>" }
183
+ before do
184
+ parser = CssParser::Parser.new
185
+ parser.add_block!(css)
186
+ @stylesheet = described_class.new(parser)
187
+ @doc = Nokogiri::HTML(body)
188
+ @stylesheet.apply(@doc)
189
+ @img = %q[<img src="/galakei/spacer/000000" width="100%" height="1">]
190
+ end
191
+ subject { @doc.at('//div') }
192
+
193
+ context 'border' do
194
+ let(:css) { "div { border: 1px solid #000000; } "}
195
+ it_should_behave_like 'border'
196
+ end
197
+
198
+ context 'border-top' do
199
+ let(:css) { "div { border-top: 1px solid #000000; } "}
200
+ it_should_behave_like 'border top'
201
+ end
202
+
203
+ context 'border-bottom' do
204
+ let(:css) { "div { border-bottom: 1px solid #000000; } "}
205
+ it_should_behave_like 'border bottom'
206
+ end
207
+
208
+ context 'bordre with class' do
209
+ let(:css) { ".border { border: 1px solid #000000; }" }
210
+ let(:body) { "<div class='border'>test</div>" }
211
+ it_should_behave_like 'border'
212
+ end
213
+
214
+ context 'border-bottom with height' do
215
+ let(:css) { "div { border-bottom: 5px solid #000000; } "}
216
+ it 'applied border bottom' do
217
+ subject.next_sibling.to_s.should == %q[<img src="/galakei/spacer/000000" width="100%" height="5">]
218
+ end
219
+ end
220
+ end
221
+
222
+ context 'border css applied to h(n)' do
223
+ before do
224
+ parser = CssParser::Parser.new
225
+ parser.add_block!(css)
226
+ @stylesheet = described_class.new(parser)
227
+ @doc = Nokogiri::HTML("<h1>test</h1>")
228
+ @stylesheet.apply(@doc)
229
+ @img = %q[<img src="/galakei/spacer/000000" width="100%" height="1">]
230
+ end
231
+ subject { @doc.at("//h1") }
232
+
233
+ context 'border' do
234
+ let(:css) { "h1 { border: 1px solid #000000; } "}
235
+ it_should_behave_like 'border'
236
+ end
237
+
238
+ context 'border-top' do
239
+ let(:css) { "h1 { border-top: 1px solid #000000; } "}
240
+ it_should_behave_like 'border top'
241
+ end
242
+
243
+ context 'border-bottom' do
244
+ let(:css) { "h1 { border-bottom: 1px solid #000000; } "}
245
+ it_should_behave_like 'border bottom'
246
+ end
247
+ end
248
+
249
+ context 'border css applied to p' do
250
+ before do
251
+ parser = CssParser::Parser.new
252
+ parser.add_block!(css)
253
+ @stylesheet = described_class.new(parser)
254
+ @doc = Nokogiri::HTML("<p>test</p>")
255
+ @stylesheet.apply(@doc)
256
+ @img = %q[<img src="/galakei/spacer/000000" width="100%" height="1">]
257
+ end
258
+ subject { @doc.at("//p") }
259
+
260
+ context 'border' do
261
+ let(:css) { "p { border: 1px solid #000000; } "}
262
+ it_should_behave_like 'not border'
263
+ end
264
+ end
140
265
  end
@@ -6,14 +6,14 @@ describe Galakei::EmojiTable do
6
6
  end
7
7
 
8
8
  it "should handle single-character unicode" do
9
- @unicode.black_sun_with_rays.should == "&#x2600;"
10
- @docomo.black_sun_with_rays.should == "&#xE63E;"
11
- @softbank.black_sun_with_rays.should == "&#xE04A;"
12
- @au.black_sun_with_rays.should == "&#xE488;"
9
+ @unicode.black_sun_with_rays.should == "\u2600"
10
+ @docomo.black_sun_with_rays.should == "\uE63E"
11
+ @softbank.black_sun_with_rays.should == "\uE04A"
12
+ @au.black_sun_with_rays.should == "\uEF60"
13
13
  end
14
14
 
15
15
  it "should handle multi-character unicode" do
16
- @unicode.hash_key.should == "&#x0023;&#x20E3;"
17
- @docomo.hash_key.should == "&#xE6E0;"
16
+ @unicode.hash_key.should == "\u{0023 20E3}"
17
+ @docomo.hash_key.should == "\uE6E0"
18
18
  end
19
19
  end
@@ -0,0 +1,21 @@
1
+ require 'spec_helper'
2
+
3
+ describe Galakei::Spacer do
4
+ describe 'initialize' do
5
+ it 'should can initialize' do
6
+ expect {
7
+ described_class.new('#000000')
8
+ }.to_not raise_error
9
+ end
10
+ end
11
+
12
+ describe 'output img_tag' do
13
+ subject { described_class.new('#000000').img_tag }
14
+ it { should == %q[<img src='/galakei/spacer/000000' width='100%' height='1'>] }
15
+ end
16
+
17
+ describe 'create image binary' do
18
+ subject { described_class.new('#000000').create }
19
+ it { should_not be_nil }
20
+ end
21
+ end
data/spec/spec_helper.rb CHANGED
@@ -1,6 +1,8 @@
1
1
  $:.unshift File.expand_path('../../lib', __FILE__)
2
2
 
3
3
  require 'galakei'
4
+ require File.expand_path(File.dirname(__FILE__) + "/app/fake")
5
+ require 'rspec/rails'
4
6
 
5
7
  def env_for(device_name)
6
8
  user_agent = {
metadata CHANGED
@@ -4,18 +4,19 @@ version: !ruby/object:Gem::Version
4
4
  prerelease: false
5
5
  segments:
6
6
  - 0
7
- - 5
8
- - 1
9
- version: 0.5.1
7
+ - 6
8
+ - 0
9
+ version: 0.6.0
10
10
  platform: ruby
11
11
  authors:
12
12
  - Paul McMahon
13
13
  - Michael Reinsch
14
+ - Yuki Akamatsu
14
15
  autorequire:
15
16
  bindir: bin
16
17
  cert_chain: []
17
18
 
18
- date: 2011-04-06 00:00:00 +09:00
19
+ date: 2011-04-15 00:00:00 +09:00
19
20
  default_executable:
20
21
  dependencies:
21
22
  - !ruby/object:Gem::Dependency
@@ -75,6 +76,9 @@ files:
75
76
  - LICENSE
76
77
  - README.md
77
78
  - Rakefile
79
+ - app/controllers/galakei/spacer_controller.rb
80
+ - config/initializers/mime_types.rb
81
+ - config/routes.rb
78
82
  - galakei.gemspec
79
83
  - lib/galakei.rb
80
84
  - lib/galakei/docomo_css.rb
@@ -83,9 +87,11 @@ files:
83
87
  - lib/galakei/docomo_css/stylesheet.rb
84
88
  - lib/galakei/email.rb
85
89
  - lib/galakei/emoji_table.rb
90
+ - lib/galakei/engine.rb
86
91
  - lib/galakei/filter/base.rb
87
92
  - lib/galakei/filter/content_type.rb
88
93
  - lib/galakei/filter/haml.rb
94
+ - lib/galakei/filter/non_standard_char.rb
89
95
  - lib/galakei/filter/views.rb
90
96
  - lib/galakei/helper_methods.rb
91
97
  - lib/galakei/input_mode.rb
@@ -96,26 +102,30 @@ files:
96
102
  - lib/galakei/session_id_parameter/in_url.rb
97
103
  - lib/galakei/session_id_parameter/railtie.rb
98
104
  - lib/galakei/shoulda_macros.rb
105
+ - lib/galakei/spacer.rb
99
106
  - lib/galakei/use_rack_request_to_extract_sid.rb
100
107
  - lib/galakei/version.rb
101
108
  - spec/acceptance/acceptance_helper.rb
102
- - spec/acceptance/app/.gitignore
103
- - spec/acceptance/app/app/views/haml/index.html.haml
104
- - spec/acceptance/app/app/views/layouts/application.html.haml
105
- - spec/acceptance/app/fake.rb
106
109
  - spec/acceptance/docomo_css_spec.rb
107
110
  - spec/acceptance/emoji_table_spec.rb
108
111
  - spec/acceptance/haml_spec.rb
109
112
  - spec/acceptance/handset_detection_spec.rb
110
113
  - spec/acceptance/input_mode_spec.rb
114
+ - spec/acceptance/non_standard_char_spec.rb
111
115
  - spec/acceptance/session_spec.rb
112
116
  - spec/acceptance/support/capybara_ssl_fix.rb
113
117
  - spec/acceptance/support/handsets.rb
114
118
  - spec/acceptance/views_spec.rb
119
+ - spec/app/.gitignore
120
+ - spec/app/app/views/haml/index.html.haml
121
+ - spec/app/app/views/layouts/application.html.haml
122
+ - spec/app/fake.rb
123
+ - spec/controllers/galakei/spacer_controller_spec.rb
115
124
  - spec/galakei/docomo_css/stylesheet_spec.rb
116
125
  - spec/galakei/emoji_table_spec.rb
117
126
  - spec/galakei/filter/content_type_spec.rb
118
127
  - spec/galakei/request_spec.rb
128
+ - spec/galakei/spacer_spec.rb
119
129
  - spec/spec_helper.rb
120
130
  has_rdoc: true
121
131
  homepage: http://www.mobalean.com
File without changes