Skip to content

Commit

Permalink
Add Tablet classes
Browse files Browse the repository at this point in the history
  • Loading branch information
rust committed May 9, 2012
1 parent 9df719a commit 4d98536
Show file tree
Hide file tree
Showing 14 changed files with 187 additions and 35 deletions.
7 changes: 6 additions & 1 deletion lib/jpmobile.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,19 @@ module Mobile
autoload :Emobile, 'jpmobile/mobile/emobile'
autoload :Willcom, 'jpmobile/mobile/willcom'
autoload :Ddipocket, 'jpmobile/mobile/ddipocket'

autoload :SmartPhone, 'jpmobile/mobile/smart_phone'
autoload :Iphone, 'jpmobile/mobile/iphone'
autoload :Android, 'jpmobile/mobile/android'
autoload :WindowsPhone, 'jpmobile/mobile/windows_phone'

autoload :Tablet, 'jpmobile/mobile/tablet'
autoload :AndroidTablet, 'jpmobile/mobile/android_tablet'
autoload :Ipad, 'jpmobile/mobile/ipad'

autoload :Display, 'jpmobile/mobile/display'

DEFAULT_CARRIERS = %w(Docomo Au Softbank Vodafone Emobile Willcom Ddipocket Iphone Android WindowsPhone)
DEFAULT_CARRIERS = %w(Docomo Au Softbank Vodafone Emobile Willcom Ddipocket Ipad AndroidTablet Iphone Android WindowsPhone)

def self.carriers
@carriers ||= DEFAULT_CARRIERS.dup
Expand Down
84 changes: 51 additions & 33 deletions lib/jpmobile/mobile/abstract_mobile.rb
Original file line number Diff line number Diff line change
Expand Up @@ -29,16 +29,6 @@ def ident_subscriber; nil; end
# 端末を識別する文字列があれば返す。
def ident_device; nil; end

# 当該キャリアのIPアドレス帯域からのアクセスであれば +true+ を返す。
# そうでなければ +false+ を返す。
# IP空間が定義されていない場合は +nil+ を返す。
def self.valid_ip? remote_addr
@ip_list ||= ip_address_class
return false unless @ip_list

@ip_list.valid_ip?(remote_addr)
end

def valid_ip?
@__valid_ip ||= self.class.valid_ip? @request.ip
end
Expand All @@ -60,6 +50,11 @@ def smart_phone?
false
end

# tablet かどうか
def tablet?
false
end

# Jpmobile::Rack::Filter を適用するかどうか
def apply_filter?
true
Expand Down Expand Up @@ -90,15 +85,18 @@ def variants
gsub(/Jpmobile::/, '').
gsub(/AbstractMobile::/, '').
gsub(/Mobile::SmartPhone/, 'smart_phone').
gsub(/Mobile::Tablet/, 'tablet').
gsub(/::/, '_').
gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2').
gsub(/([a-z\d])([A-Z])/, '\1_\2').
downcase
klass =~ /abstract/ ? "mobile" : klass
end

if @_variants.include?("smart_phone")
@_variants = @_variants.reject{|v| v == "mobile"}.map{|v| v.gsub(/mobile/, "smart_phone")}
if @_variants.include?('tablet')
@_variants = @_variants.reject{|v| v == "mobile"}.map{|v| v.gsub(/mobile_/, "tablet_")}
elsif @_variants.include?("smart_phone")
@_variants = @_variants.reject{|v| v == "mobile"}.map{|v| v.gsub(/mobile_/, "smart_phone_")}
end

@_variants || []
Expand Down Expand Up @@ -174,10 +172,47 @@ def decorated?
@decorated
end

# リクエストがこのクラスに属するか調べる
# メソッド名に関して非常に不安
def self.check_carrier(env)
self::USER_AGENT_REGEXP && env['HTTP_USER_AGENT'] =~ self::USER_AGENT_REGEXP
class << self
# 当該キャリアのIPアドレス帯域からのアクセスであれば +true+ を返す。
# そうでなければ +false+ を返す。
# IP空間が定義されていない場合は +nil+ を返す。
def valid_ip? remote_addr
@ip_list ||= ip_address_class
return false unless @ip_list

@ip_list.valid_ip?(remote_addr)
end

# リクエストがこのクラスに属するか調べる
# メソッド名に関して非常に不安
def check_carrier(env)
user_agent_regexp && user_agent_regexp.match(env['HTTP_USER_AGENT'])
end

def user_agent_regexp
@_user_agent_regexp ||= self::USER_AGENT_REGEXP
end

def add_user_agent_regexp(regexp)
@_user_agent_regexp = Regexp.union(user_agent_regexp, regexp)
end

def carrier(env)
::Jpmobile::Mobile.carriers.each do |const|
c = ::Jpmobile::Mobile.const_get(const)
if c.check_carrier(env)
res = ::Rack::Request.new(env)
return c.new(env, res)
end
end

nil
end

#
def ip_address_class
eval("::Jpmobile::Mobile::IpAddresses::#{self.to_s.split(/::/).last}").new rescue nil
end
end

#XXX: lib/jpmobile.rbのautoloadで先に各キャリアの定数を定義しているから動くのです
Expand All @@ -190,18 +225,6 @@ def self.check_carrier(env)
end
end

def self.carrier(env)
::Jpmobile::Mobile.carriers.each do |const|
c = ::Jpmobile::Mobile.const_get(const)
if c.check_carrier(env)
res = ::Rack::Request.new(env)
return c.new(env, res)
end
end

nil
end

private
# リクエストのパラメータ。
def params
Expand All @@ -211,10 +234,5 @@ def params
@request.params
end
end

#
def self.ip_address_class
eval("::Jpmobile::Mobile::IpAddresses::#{self.to_s.split(/::/).last}").new rescue nil
end
end
end
10 changes: 10 additions & 0 deletions lib/jpmobile/mobile/android_tablet.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# -*- coding: utf-8 -*-
# =Android

module Jpmobile::Mobile
# ==AndroidTablet
class AndroidTablet < Tablet
# 対応するUser-Agentの正規表現
USER_AGENT_REGEXP = Regexp.union(/(?!Android.+Mobile)Android/, /Android.+SC-01C/)
end
end
10 changes: 10 additions & 0 deletions lib/jpmobile/mobile/ipad.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# -*- coding: utf-8 -*-
# =Android

module Jpmobile::Mobile
# ==iPad
class Ipad < Tablet
# 対応するUser-Agentの正規表現
USER_AGENT_REGEXP = /iPad/
end
end
16 changes: 16 additions & 0 deletions lib/jpmobile/mobile/tablet.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# -*- coding: utf-8 -*-
# =タブレットの親クラス

module Jpmobile::Mobile
class Tablet < SmartPhone
# smartphone なので true
def smart_phone?
true
end

# tablet なので true
def tablet?
true
end
end
end
5 changes: 4 additions & 1 deletion spec/rack/jpmobile/mobile_by_ua_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,11 @@
[ Jpmobile::Mobile::Iphone , 'Mozilla/5.0 (iPhone; U; CPU iPhone OS 3_0 like Mac OS X; ja-jp) AppleWebKit/528.18 (KHTML, like Gecko) Version/4.0 Mobile/7A341 Safari/528.16' ],
[ Jpmobile::Mobile::Android , 'Mozilla/5.0 (Linux; U; Android 1.6; ja-jp; SonyEriccsonSO-01B Build/R1EA018) AppleWebKit/528.5+ (KHTML, like Gecko) Version/3.1.2 Mobile Safari/525.20.1' ],
[ Jpmobile::Mobile::WindowsPhone , 'Mozilla/4.0 (Compatible; MSIE 6.0; Windows NT 5.1 T-01A_6.5; Windows Phone 6.5)' ],
[ Jpmobile::Mobile::Ipad , 'Mozilla/5.0 (iPad; U; CPU OS 4_3 like Mac OS X; ja-jp) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8F191 Safari/6533.18.5'],
[ Jpmobile::Mobile::AndroidTablet, 'Mozilla/5.0 (Linux; U; Android 2.2; ja-jp; SC-01C Build/FROYO) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1'],
[ Jpmobile::Mobile::AndroidTablet, 'Mozilla/5.0 (Linux; U; Android 3.2; ja-jp; Sony Tablet S Build/THMAS11002) AppleWebKit/534.13 (KHTML, like Gecko) Version/4.0 Safari/534.13'],
].each do |carrier, user_agent|
it '#mobile should return #{carrier} when take #{user_agent} as UserAgent' do
it "#mobile should return #{carrier} when take #{user_agent} as UserAgent" do
res = Rack::MockRequest.env_for(
'http://jpmobile-rails.org/',
'HTTP_USER_AGENT' => user_agent)
Expand Down
12 changes: 12 additions & 0 deletions test/rails/overrides/app/controllers/template_path_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,17 @@ def show
def optioned_index
render :action => "index"
end

def full_path_partial
end

def smart_phone_only
end

def with_tblt
end

def with_ipd
end
end

Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<h1>smart_phone_only.html.erb</h1>
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<h1>smart_phone_only_smart_phone.html.erb</h1>
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<h1>with_ipd.html.erb</h1>
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<h1>with_ipd_tablet_ipad.html.erb</h1>
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<h1>with_tblt.html.erb</h1>
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<h1>with_tblt_tablet.html.erb</h1>
72 changes: 72 additions & 0 deletions test/rails/overrides/spec/requests/template_path_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,78 @@
end
end

context 'only smart_phone view' do
context 'iPadからのアクセスの場合' do
before do
@user_agent = 'Mozilla/5.0 (iPad; U; CPU OS 4_3 like Mac OS X; ja-jp) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8F191 Safari/6533.18.5'
end
it 'smart_phone_only.html.erbが使用されること' do
get '/template_path/smart_phone_only', {}, {'HTTP_USER_AGENT' => @user_agent}

response.should have_tag('h1', :content => 'smart_phone_only_smart_phone.html.erb')
end
end

context 'Android Tabletからのアクセスの場合' do
before do
@user_agent = 'Mozilla/5.0 (Linux; U; Android 2.2; ja-jp; SC-01C Build/FROYO) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1'
end
it 'smart_phone_only.html.erbが使用されること' do
get '/template_path/smart_phone_only', {}, {'HTTP_USER_AGENT' => @user_agent}

response.should have_tag('h1', :content => 'smart_phone_only_smart_phone.html.erb')
end
end
end

context 'with_tblt view' do
context 'iPadからのアクセスの場合' do
before do
@user_agent = 'Mozilla/5.0 (iPad; U; CPU OS 4_3 like Mac OS X; ja-jp) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8F191 Safari/6533.18.5'
end
it 'with_tblt_tablet.html.erbが使用されること' do
get '/template_path/with_tblt', {}, {'HTTP_USER_AGENT' => @user_agent}

response.should have_tag('h1', :content => 'with_tblt_tablet.html.erb')
end
end

context 'Android Tabletからのアクセスの場合' do
before do
@user_agent = 'Mozilla/5.0 (Linux; U; Android 2.2; ja-jp; SC-01C Build/FROYO) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1'
end
it 'with_tblt_tablet.html.erbが使用されること' do
get '/template_path/with_tblt', {}, {'HTTP_USER_AGENT' => @user_agent}

response.should have_tag('h1', :content => 'with_tblt_tablet.html.erb')
end
end
end

context 'with_ipd view' do
context 'iPadからのアクセスの場合' do
before do
@user_agent = 'Mozilla/5.0 (iPad; U; CPU OS 4_3 like Mac OS X; ja-jp) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8F191 Safari/6533.18.5'
end
it 'with_ipd_tablet_ipad.html.erbが使用されること' do
get '/template_path/with_ipd', {}, {'HTTP_USER_AGENT' => @user_agent}

response.should have_tag('h1', :content => 'with_ipd_tablet_ipad.html.erb')
end
end

context 'Android Tabletからのアクセスの場合' do
before do
@user_agent = 'Mozilla/5.0 (Linux; U; Android 2.2; ja-jp; SC-01C Build/FROYO) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1'
end
it 'with_ipd.html.erbが使用されること' do
get '/template_path/with_ipd', {}, {'HTTP_USER_AGENT' => @user_agent}

response.should have_tag('h1', :content => 'with_ipd.html.erb')
end
end
end

context "partial" do
context "PCからのアクセスの場合" do
before do
Expand Down

0 comments on commit 4d98536

Please sign in to comment.