Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Support user agent exceptions

  • Loading branch information...
commit cca7a7b765e6462da2fe0687c79330217901bbbe 1 parent 8dd1176
Jon Larkowski and Sandro Turriate authored l4rk committed
View
70 lib/mobylette/controllers/respond_to_mobile_requests.rb
@@ -13,11 +13,58 @@ module RespondToMobileRequests
helper_method :is_mobile_view?
# List of mobile agents, from mobile_fu (https://github.com/brendanlim/mobile-fu)
- MOBILE_USER_AGENTS = 'palm|blackberry|nokia|phone|midp|mobi|symbian|chtml|ericsson|minimo|' +
- 'audiovox|motorola|samsung|telit|upg1|windows ce|ucweb|astel|plucker|' +
- 'x320|x240|j2me|sgh|portable|sprint|docomo|kddi|softbank|android|mmp|' +
- 'pdxgw|netfront|xiino|vodafone|portalmmm|sagem|mot-|sie-|ipod|up\\.b|' +
- 'webos|amoi|novarra|cdm|alcatel|pocket|iphone|mobileexplorer|mobile'
+ MOBILE_USER_AGENTS = %w(
+ alcatel
+ amoi
+ android
+ astel
+ audiovox
+ blackberry
+ cdm
+ chtml
+ docomo
+ ericsson
+ ipad
+ iphone
+ ipod
+ j2me
+ kddi
+ midp
+ minimo
+ mmp
+ mobi
+ mobile
+ mobileexplorer
+ mot-
+ motorola
+ netfront
+ nokia
+ novarra
+ palm
+ pdxgw
+ phone
+ plucker
+ pocket
+ portable
+ portalmmm
+ sagem
+ samsung
+ sgh
+ sie-
+ softbank
+ sprint
+ symbian
+ telit
+ ucweb
+ up.b
+ upg1
+ vodafone
+ webos
+ windows\ ce
+ x240
+ x320
+ xiino
+ )
end
module ClassMethods
@@ -49,6 +96,7 @@ def respond_to_mobile_requests(options = {})
# works on 1.9, but not on 1.8
#valid_options = [:fall_back, :skip_xhr_requests]
#self.mobylette_options = options.reject {|option| !valid_options.include?(option)}
+ options[:except] = Array(options[:except])
self.mobylette_options = options
self.send(:include, Mobylette::Controllers::RespondToMobileRequestsMethods)
@@ -61,7 +109,7 @@ def respond_to_mobile_requests(options = {})
# This helper returns exclusively if the request's user_aget is from a mobile
# device or not.
def is_mobile_request?
- request.user_agent.to_s.downcase =~ /#{MOBILE_USER_AGENTS}/
+ request.user_agent.to_s.downcase =~ Regexp.union(MOBILE_USER_AGENTS)
end
# :doc:
@@ -86,7 +134,15 @@ module RespondToMobileRequestsMethods
# Returns true if this request should be treated as a mobile request
def respond_as_mobile?
- processing_xhr_requests? and skip_mobile_param_not_present? and (force_mobile_by_session? or is_mobile_request? or (params[:format] == 'mobile'))
+ processing_xhr_requests? and skip_mobile_param_not_present? and (force_mobile_by_session? or allow_mobile_response? or (params[:format] == 'mobile'))
+ end
+
+ def allow_mobile_response?
+ user_agent_included? && is_mobile_request?
+ end
+
+ def user_agent_included?
+ request.user_agent.to_s.downcase !~ Regexp.union(self.class.mobylette_options[:except])
end
# Returns true if the visitor has de force_mobile session
View
21 spec/controllers/except_mobile_browers_controller_spec.rb
@@ -0,0 +1,21 @@
+require 'spec_helper'
+
+describe ExceptMobileBrowsersController do
+ # This controller calls respond_to_mobile_requests with {:except => :ipad}
+ # Index action has views for html, and mobile
+
+ render_views
+
+ it "renders an html view for the iPad" do
+ force_mobile_request_agent "iPad"
+ get :index
+ response.body.should contain("HTML VIEW")
+ end
+
+ it "renders a mobile view for other mobile devices" do
+ force_mobile_request_agent
+ get :index
+ response.body.should contain("MOBILE VIEW")
+ end
+
+end
View
3  spec/dummy/app/controllers/except_mobile_browsers_controller.rb
@@ -0,0 +1,3 @@
+class ExceptMobileBrowsersController < ApplicationController
+ respond_to_mobile_requests :except => :ipad
+end
View
1  spec/dummy/app/views/except_mobile_browsers/index.html.erb
@@ -0,0 +1 @@
+IN HTML VIEW
View
1  spec/dummy/app/views/except_mobile_browsers/index.mobile.erb
@@ -0,0 +1 @@
+IN MOBILE VIEW
View
2  spec/dummy/config/routes.rb
@@ -10,6 +10,8 @@
get "respond_to_test(.:format)" => "home#respond_to_test"
get "no_mobile_view(.:format)" => "home#no_mobile_view"
+ get "exceptions/index" => "except_mobile_browsers#index"
+
get "load_from_mobile_path" => "view_path#index"
get "ignore_mobile_path" => "ignore_mobile_path#index"
View
47 spec/respond_to_mobile_requests_spec.rb
@@ -0,0 +1,47 @@
+require 'spec_helper'
+
+describe Mobylette::Controllers::RespondToMobileRequests do
+ def new_controller(user_agent = 'iPad')
+ Class.new(ActionController::Base) do
+ include Mobylette::Controllers::RespondToMobileRequests
+
+ define_method :request do
+ OpenStruct.new(:user_agent => user_agent, :xhr? => false)
+ end
+
+ def params
+ {}
+ end
+
+ def session
+ {}
+ end
+ end
+ end
+
+ let(:controller) { new_controller }
+
+ it "supports a single exception" do
+ controller.respond_to_mobile_requests :except => :ipad
+ controller.mobylette_options[:except].should == [:ipad]
+ end
+
+ it "supports multiple exceptions" do
+ controller.respond_to_mobile_requests :except => [:ipad, :android]
+ controller.mobylette_options[:except].should == [:ipad, :android]
+ end
+
+ describe "when iPad is excepted" do
+
+ it "remains a mobile request" do
+ controller.respond_to_mobile_requests :except => :ipad
+ controller.new.send(:is_mobile_request?).should be_true
+ end
+
+ it "does not respond as mobile" do
+ controller.respond_to_mobile_requests :except => :ipad
+ controller.new.send(:respond_as_mobile?).should be_false
+ end
+
+ end
+end
Please sign in to comment.
Something went wrong with that request. Please try again.