forked from carezone/mobylette
-
Notifications
You must be signed in to change notification settings - Fork 0
/
respond_to_mobile_requests.rb
135 lines (113 loc) · 5.42 KB
/
respond_to_mobile_requests.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
module Mobylette
module Controllers
# Mobylette::Controllers::RespondToMobileRequests includes the respond_to_mobile_requests
# to your ActionController::Base.
#
# The respond_to_mobile_requests method enables the controller mobile handling
module RespondToMobileRequests
extend ActiveSupport::Concern
included do
helper_method :is_mobile_request?
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'
end
module ClassMethods
# This method enables the controller do handle mobile requests
#
# You must add this to every controller you want to respond differently to mobile devices,
# or make it application wide calling it from the ApplicationController
#
# Options:
# * :fall_back => :html
# You may pass a fall_back option to the method, it will force the render
# to look for that other format, in case there is not a .mobile file for the view.
# By default, it will fall back to the format of the original request.
# If you don't want fall back at all, pass :fall_back => false
# * :skip_xhr_requests => true/false
# By default this is set to true. When a xhr request enters in, it will skip the
# mobile verification. This will let your ajax calls to work as intended.
# You may disable this (actually you will have to) if you are using JQuery Mobile, or
# other js framework that uses ajax. To disable, set :skip_xhr_requests => false
# * :ignore_mobile_view_path => true/false
# False by default. This will force rails to look for the mobile views in the
# app/mobile_views path before app/views. This behavior is only for mobile requests.
# You may ignore this path aswell, it is just an extra organization option you have.
#
def respond_to_mobile_requests(options = {})
return if self.included_modules.include?(Mobylette::Controllers::RespondToMobileRequestsMethods)
options.reverse_merge!({
:skip_xhr_requests => true,
:ignore_mobile_view_path => false
})
cattr_accessor :mobylette_options
# works on 1.9, but not on 1.8
#valid_options = [:fall_back, :skip_xhr_requests, :ignore_mobile_view_path]
#self.mobylette_options = options.reject {|option| !valid_options.include?(option)}
self.mobylette_options = options
self.send(:include, Mobylette::Controllers::RespondToMobileRequestsMethods)
end
end
module InstanceMethods
private
# :doc:
# 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}/
end
# :doc:
# This helper returns exclusively if the current format is mobile or not
def is_mobile_view?
true if (request.format.to_s == "mobile") or (params[:format] == "mobile")
end
end
end
# RespondToMobileRequestsMethods is included by respond_to_mobile_requests
#
# This will check if the request is from a mobile device and change
# the request format to :mobile
module RespondToMobileRequestsMethods
extend ActiveSupport::Concern
included do
before_filter :handle_mobile
end
module InstanceMethods
private
# Returns true if this request should be treated as a mobile request
def respond_as_mobile?
processing_xhr_requests? and (force_mobile_by_session? or is_mobile_request? or (params[:format] == 'mobile'))
end
# Returns true if the visitor has de force_mobile session
def force_mobile_by_session?
session[:mobylette_override] == :force_mobile
end
# Returns true only if treating XHR requests (when skip_xhr_requests are set to false) or
# or when this is a non xhr request
def processing_xhr_requests?
not self.mobylette_options[:skip_xhr_requests] && request.xhr?
end
# :doc:
# Changes the request.form to :mobile, when the request is from
# a mobile device
def handle_mobile
return if session[:mobylette_override] == :ignore_mobile
if respond_as_mobile?
unless self.mobylette_options[:ignore_mobile_view_path]
prepend_view_path File.join(Rails.root, 'app', 'mobile_views')
end
original_format = request.format.to_sym
request.format = :mobile
if self.mobylette_options[:fall_back] != false
request.formats << Mime::Type.new(self.mobylette_options[:fall_back] || original_format)
end
end
end
end
end
end
end