mobylette 2.3 → 3.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +55 -15
- data/lib/mobylette.rb +2 -1
- data/lib/mobylette/devices.rb +47 -0
- data/lib/mobylette/mobile_user_agents.rb +75 -7
- data/lib/mobylette/resolvers/chained_fallback_resolver.rb +48 -0
- data/lib/mobylette/respond_to_mobile_requests.rb +75 -14
- data/lib/mobylette/version.rb +1 -1
- data/spec/dummy/log/development.log +116 -0
- data/spec/dummy/log/test.log +97 -0
- data/spec/dummy/tmp/cache/assets/C82/3E0/sprockets%2F48eb4ac616538f8f36870451073315da +14 -0
- data/spec/dummy/tmp/cache/assets/CE4/1C0/sprockets%2F18d93e1533d585b2f64ec90b33176ac9 +0 -0
- data/spec/dummy/tmp/cache/assets/CED/A70/sprockets%2F621683d8791730a9cc7ce45e17a7e46d +0 -0
- data/spec/dummy/tmp/cache/assets/CFC/200/sprockets%2F716f89d85d4855706b8a9abec1969c62 +16 -0
- data/spec/dummy/tmp/cache/assets/D32/A10/sprockets%2F13fe41fee1fe35b49d145bcc06610705 +0 -0
- data/spec/dummy/tmp/cache/assets/D54/ED0/sprockets%2F71c9fa01091d432b131da3bb73faf3d4 +16 -0
- data/spec/dummy/tmp/cache/assets/D84/210/sprockets%2Fabd0103ccec2b428ac62c94e4c40b384 +14 -0
- data/spec/dummy/tmp/cache/assets/E04/890/sprockets%2F2f5173deea6c795b8fdde723bb4b63af +0 -0
- data/spec/lib/devices_spec.rb +31 -0
- data/spec/lib/resolvers/chained_fallback_resolver_spec.rb +47 -0
- data/spec/lib/respond_to_mobile_requests/configuration_spec.rb +65 -0
- data/spec/lib/respond_to_mobile_requests_spec.rb +34 -29
- metadata +48 -16
- data/lib/mobylette/fallback_resolver.rb +0 -69
- data/spec/lib/fallback_resolver_spec.rb +0 -54
data/README.rdoc
CHANGED
@@ -44,34 +44,63 @@ After that, you may start adding your .mobile. views.
|
|
44
44
|
|
45
45
|
Returns if the current format is :mobile or not.
|
46
46
|
|
47
|
-
|
48
|
-
|
49
|
-
|
47
|
+
* ==== request_device?
|
48
|
+
|
49
|
+
Returns true/false if the current request comes from the device passed as parameter.
|
50
|
+
|
51
|
+
Examples:
|
52
|
+
request_device?(:iphone)
|
53
|
+
|
54
|
+
request_device?(:android)
|
55
|
+
|
56
|
+
Only :iphone, :ipad, :ios and :android are recognized by default. But you can add other devices, check configuration.
|
50
57
|
|
51
58
|
== Configuration
|
52
59
|
|
53
60
|
You can set the configuration with the mobylette_config method:
|
54
61
|
|
55
62
|
mobylette_config do |config|
|
56
|
-
|
63
|
+
config[:fallback_chains] = { mobile: [:mobile, :html] }
|
57
64
|
config[:skip_xhr_requests] = false
|
65
|
+
config[:mobile_user_agents] = proc { %r{iphone}i }
|
58
66
|
end
|
59
67
|
|
60
|
-
|
68
|
+
=== Custom User Agents
|
61
69
|
|
62
|
-
|
70
|
+
Mobylette works uppon detecting the user agent of the visitor browser. By default it will detect any mobile user agent. But you can customize this by passing a proc with a regex of any matching user agent you may wish.
|
63
71
|
|
64
|
-
|
65
|
-
|
66
|
-
|
72
|
+
mobylette_config do |config|
|
73
|
+
config[:mobile_user_agents] = proc { %r{iphone|ipad}i }
|
74
|
+
end
|
67
75
|
|
68
|
-
|
76
|
+
=== Fall Backs
|
69
77
|
|
70
|
-
|
71
|
-
|
72
|
-
|
78
|
+
Fall backs are handled as a chain of formats. By default the only chain is `:mobile => [:mobile, :html]`.
|
79
|
+
You can override this and add your own fall back chains using the `mobylette_config`.
|
80
|
+
|
81
|
+
mobylette_config do |config|
|
82
|
+
config[:fallback_chains] = {
|
83
|
+
mobile: [:mobile, :html],
|
84
|
+
iphone: [:iphone, :mobile, :html],
|
85
|
+
...
|
86
|
+
}
|
87
|
+
end
|
73
88
|
|
74
|
-
|
89
|
+
When you create a custom format with fall back chains, `:iphone` for example, you must register it as a Mime::Type:
|
90
|
+
|
91
|
+
# config/initializers/mime_types.rb
|
92
|
+
Mime::Type.register_alias 'text/html', :iphone
|
93
|
+
# this is very important, don't forget!
|
94
|
+
# :mobile is already registered!
|
95
|
+
|
96
|
+
If you don't want any fall backs, just set it to:
|
97
|
+
|
98
|
+
mobylette_config do |config|
|
99
|
+
config[:fallback_chains] = { mobile: [:mobile] }
|
100
|
+
end
|
101
|
+
|
102
|
+
|
103
|
+
=== XHR Requests
|
75
104
|
|
76
105
|
By default the mobile device verification will skip XHR requests, and these will be served as if mobylette wasn't there. You can override this behavior by setting the :skip_xhr_requests option to false on your controller:
|
77
106
|
|
@@ -81,6 +110,17 @@ By default the mobile device verification will skip XHR requests, and these will
|
|
81
110
|
|
82
111
|
You may need to use this if you are using JQuery mobile or something similar in your application.
|
83
112
|
|
113
|
+
=== Registering Mobile Devices
|
114
|
+
|
115
|
+
Mobylette 3.0+ has a `request_device?` helper. By default only :iphone, :ipad, :ios and :android devices come registered.
|
116
|
+
But you can register any device using the `mobylette_config` method:
|
117
|
+
|
118
|
+
mobylette_config do |config|
|
119
|
+
config[:devices] = { my_unique_phone: %r{UniquePhone 1.2.3}, ... }
|
120
|
+
end
|
121
|
+
|
122
|
+
Note: This will not add the device to the mobile user_agent detection. For that read #Custom User Agents.
|
123
|
+
|
84
124
|
== Skiping mobile filter
|
85
125
|
|
86
126
|
In the case you need to skip a mobile_request for been treated as mobile, you can pass the `skip_mobile=true` param to the url/request.
|
@@ -138,6 +178,6 @@ This will force the session_override value in the users session. Values possible
|
|
138
178
|
Friendly note: on your tests, call these functions BEFORE you make the request, otherwise they are useless =p
|
139
179
|
|
140
180
|
|
141
|
-
=
|
181
|
+
= License
|
142
182
|
|
143
183
|
MIT License. Copyright 2012 Tiago Scolari.
|
data/lib/mobylette.rb
CHANGED
@@ -2,8 +2,9 @@
|
|
2
2
|
# Rails automatic mobile request support
|
3
3
|
module Mobylette
|
4
4
|
require 'mobylette/respond_to_mobile_requests'
|
5
|
-
require 'mobylette/
|
5
|
+
require 'mobylette/resolvers/chained_fallback_resolver'
|
6
6
|
require 'mobylette/mobile_user_agents'
|
7
|
+
require 'mobylette/devices'
|
7
8
|
|
8
9
|
# TestHelpers
|
9
10
|
# require "mobylette/helmet"
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require 'singleton'
|
2
|
+
module Mobylette
|
3
|
+
class Devices
|
4
|
+
include Singleton
|
5
|
+
|
6
|
+
def initialize
|
7
|
+
@devices = {
|
8
|
+
android: %r{android}i,
|
9
|
+
android2: %r{android\s+2\.}i,
|
10
|
+
android3: %r{android\s+3\.}i,
|
11
|
+
android4: %r{android\s+4\.}i,
|
12
|
+
iphone: %r{iphone}i,
|
13
|
+
ipad: %r{ipad}i,
|
14
|
+
ios: %r{iphone|ipad}i,
|
15
|
+
ios3: %r{(iphone|ipad)\s+os\s+3_},
|
16
|
+
ios4: %r{(iphone|ipad)\s+os\s+4_},
|
17
|
+
ios5: %r{(iphone|ipad)\s+os\s+5_},
|
18
|
+
ios6: %r{(iphone|ipad)\s+os\s+6_}
|
19
|
+
}
|
20
|
+
end
|
21
|
+
|
22
|
+
# Register a new device to the
|
23
|
+
# devices list
|
24
|
+
#
|
25
|
+
# devices - hash defining a new device and it's regex.
|
26
|
+
# you may assign multiple devices here.
|
27
|
+
#
|
28
|
+
# Examples:
|
29
|
+
#
|
30
|
+
# register(iphone: /iphone/i)
|
31
|
+
# register(iphone: /iphone/i, ipad: /ipad/i)
|
32
|
+
#
|
33
|
+
def register(devices)
|
34
|
+
@devices.merge! devices
|
35
|
+
end
|
36
|
+
|
37
|
+
# Returns the regex for the device
|
38
|
+
#
|
39
|
+
def device(device)
|
40
|
+
@devices[device]
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def self.devices
|
45
|
+
Devices.instance
|
46
|
+
end
|
47
|
+
end
|
@@ -1,10 +1,78 @@
|
|
1
1
|
module Mobylette
|
2
|
-
|
2
|
+
|
3
|
+
# This is a mobile_user_agents object, you may pass your own implementation of this
|
4
|
+
# to the mobylette_config, it must return respond to call, returning a regexp
|
5
|
+
# for matching mobile user agents.
|
3
6
|
#
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
7
|
+
# mobylette_config do |config|
|
8
|
+
# config[:mobile_user_agents] = proc { /iphone|android/ }
|
9
|
+
# end
|
10
|
+
#
|
11
|
+
class MobileUserAgents
|
12
|
+
|
13
|
+
# Returns a list of mobile user agents
|
14
|
+
#
|
15
|
+
def call()
|
16
|
+
Regexp.union(DEFAULT_USER_AGENTS)
|
17
|
+
end
|
18
|
+
|
19
|
+
# List of all mobile user agents
|
20
|
+
#
|
21
|
+
DEFAULT_USER_AGENTS = %w(
|
22
|
+
palm
|
23
|
+
blackberry
|
24
|
+
nokia
|
25
|
+
phone
|
26
|
+
midp
|
27
|
+
mobi
|
28
|
+
symbian
|
29
|
+
chtml
|
30
|
+
ericsson
|
31
|
+
minimo
|
32
|
+
audiovox
|
33
|
+
motorola
|
34
|
+
samsung
|
35
|
+
telit
|
36
|
+
upg1
|
37
|
+
windows
|
38
|
+
ce
|
39
|
+
ucweb
|
40
|
+
astel
|
41
|
+
plucker
|
42
|
+
x320
|
43
|
+
x240
|
44
|
+
j2me
|
45
|
+
sgh
|
46
|
+
portable
|
47
|
+
sprint
|
48
|
+
docomo
|
49
|
+
kddi
|
50
|
+
softbank
|
51
|
+
android
|
52
|
+
mmp
|
53
|
+
pdxgw
|
54
|
+
netfront
|
55
|
+
xiino
|
56
|
+
vodafone
|
57
|
+
portalmmm
|
58
|
+
sagem
|
59
|
+
mot-
|
60
|
+
sie-
|
61
|
+
ipod
|
62
|
+
up.b
|
63
|
+
webos
|
64
|
+
amoi
|
65
|
+
novarra
|
66
|
+
cdm
|
67
|
+
alcatel
|
68
|
+
pocket
|
69
|
+
ipad
|
70
|
+
iphone
|
71
|
+
mobileexplorer
|
72
|
+
mobile
|
73
|
+
maemo
|
74
|
+
fennec
|
75
|
+
silk
|
76
|
+
)
|
77
|
+
end
|
10
78
|
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module Mobylette
|
2
|
+
module Resolvers
|
3
|
+
class ChainedFallbackResolver < ::ActionView::FileSystemResolver
|
4
|
+
|
5
|
+
# Initializes the fallback resolver with a default
|
6
|
+
# mobile format.
|
7
|
+
#
|
8
|
+
def initialize(formats = {})
|
9
|
+
@fallback_formats = formats.reverse_merge!({ mobile: [:mobile] })
|
10
|
+
super('app/views')
|
11
|
+
end
|
12
|
+
|
13
|
+
# Updates the fallback resolver replacing the
|
14
|
+
# fallback format hash.
|
15
|
+
#
|
16
|
+
# formats - hash of fallbacks, example:
|
17
|
+
#
|
18
|
+
# formats = {
|
19
|
+
# mobile: [:mobile, :html],
|
20
|
+
# iphone: [:iphone, :ios, :mobile, :html],
|
21
|
+
# android: [:android, :mobile],
|
22
|
+
# ...
|
23
|
+
# }
|
24
|
+
#
|
25
|
+
# It will add the fallback chain array of the
|
26
|
+
# request.format to the resolver.
|
27
|
+
#
|
28
|
+
# If the format.request is not defined in formats,
|
29
|
+
# it will behave as a normal FileSystemResovler.
|
30
|
+
#
|
31
|
+
def replace_fallback_formats_chain(formats)
|
32
|
+
@fallback_formats = formats.reverse_merge!({ mobile: [:mobile] })
|
33
|
+
end
|
34
|
+
|
35
|
+
# Public: finds the right template on the filesystem,
|
36
|
+
# using fallback if needed
|
37
|
+
#
|
38
|
+
def find_templates(name, prefix, partial, details)
|
39
|
+
# checks if the format has a fallback chain
|
40
|
+
if @fallback_formats.has_key?(details[:formats].first)
|
41
|
+
details = details.dup
|
42
|
+
details[:formats] = Array.wrap(@fallback_formats[details[:formats].first])
|
43
|
+
end
|
44
|
+
super(name, prefix, partial, details)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -18,6 +18,7 @@ module Mobylette
|
|
18
18
|
# mobylette_config do |config|
|
19
19
|
# config[:fall_back] = :html
|
20
20
|
# config[:skip_xhr_requests] = false
|
21
|
+
# config[:mobile_user_agents] = proc { /iphone/i }
|
21
22
|
# end
|
22
23
|
# ...
|
23
24
|
# end
|
@@ -30,18 +31,21 @@ module Mobylette
|
|
30
31
|
included do
|
31
32
|
helper_method :is_mobile_request?
|
32
33
|
helper_method :is_mobile_view?
|
34
|
+
helper_method :request_device?
|
33
35
|
|
34
36
|
before_filter :handle_mobile
|
35
37
|
|
36
38
|
cattr_accessor :mobylette_options
|
37
39
|
@@mobylette_options = Hash.new
|
38
|
-
@@mobylette_options[:skip_xhr_requests]
|
39
|
-
@@mobylette_options[:
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
40
|
+
@@mobylette_options[:skip_xhr_requests] = true
|
41
|
+
@@mobylette_options[:fallback_chains] = { mobile: [:mobile, :html] }
|
42
|
+
@@mobylette_options[:mobile_user_agents] = Mobylette::MobileUserAgents.new
|
43
|
+
@@mobylette_options[:devices] = Hash.new
|
44
|
+
|
45
|
+
cattr_accessor :mobylette_resolver
|
46
|
+
self.mobylette_resolver = Mobylette::Resolvers::ChainedFallbackResolver.new()
|
47
|
+
self.mobylette_resolver.replace_fallback_formats_chain(@@mobylette_options[:fallback_chains])
|
48
|
+
append_view_path self.mobylette_resolver
|
45
49
|
end
|
46
50
|
|
47
51
|
|
@@ -63,6 +67,14 @@ module Mobylette
|
|
63
67
|
# mobile verification. This will let your ajax calls to work as intended.
|
64
68
|
# You may disable this (actually you will have to) if you are using JQuery Mobile, or
|
65
69
|
# other js framework that uses ajax. To disable, set skip_xhr_requests: false
|
70
|
+
# * mobile_user_agents: proc { /user_agents_match/ }
|
71
|
+
# If you want to restrict the user agents that will be considered mobile devices,
|
72
|
+
# you can send a custom proc/object that returns the matching regex you wish.
|
73
|
+
# * devices: {device_name: /device_reg/, device2_name: /device2_reg/, ...}
|
74
|
+
# You may register devices for custom behavior by device.
|
75
|
+
# Once a device is registered you may call the helper request_device?(device_symb)
|
76
|
+
# to see if the request comes from that device or not.
|
77
|
+
# By default :iphone, :ipad, :ios and :android are already registered.
|
66
78
|
#
|
67
79
|
# Example Usage:
|
68
80
|
#
|
@@ -72,26 +84,64 @@ module Mobylette
|
|
72
84
|
# mobylette_config do |config|
|
73
85
|
# config[:fall_back] = :html
|
74
86
|
# config[:skip_xhr_requests] = false
|
87
|
+
# config[:mobile_user_agents] = proc { %r{iphone|android}i }
|
88
|
+
# config[:devices] = {cool_phone: %r{cool\s+phone} }
|
75
89
|
# end
|
76
90
|
# ...
|
77
91
|
# end
|
78
92
|
#
|
79
93
|
def mobylette_config
|
80
94
|
yield(self.mobylette_options)
|
81
|
-
|
95
|
+
configure_fallback_resolver(self.mobylette_options)
|
96
|
+
Mobylette.devices.register(self.mobylette_options[:devices]) if self.mobylette_options[:devices]
|
97
|
+
end
|
98
|
+
|
99
|
+
private
|
100
|
+
|
101
|
+
# Private: Configures how the resolver shall handle fallbacks.
|
102
|
+
#
|
103
|
+
# if options has a :fallback_chains key, it will use it
|
104
|
+
# as the fallback rules for the resolver, the format should
|
105
|
+
# be a hash, where each key defines a array of formats.
|
106
|
+
# Example:
|
107
|
+
# options[:fallback_chains]
|
108
|
+
# #=> { iphone: [:iphone, :mobile, :html], mobile: [:mobile, :html] }
|
109
|
+
#
|
110
|
+
# if there is no :fallback_chains, then it will look for a :fall_back
|
111
|
+
# key, that shall define only 1 fallback format to the mobile format.
|
112
|
+
# This keep compatibility with older versions.
|
113
|
+
# Example:
|
114
|
+
# options[:fall_back]
|
115
|
+
# #=> :html
|
116
|
+
#
|
117
|
+
def configure_fallback_resolver(options)
|
118
|
+
if options[:fall_back]
|
119
|
+
logger.warn "DEPRECATED > Mobylette: Please don't user :fall_back to configure fall backs any more. See the README for :fallback_chains instead."
|
120
|
+
self.mobylette_resolver.replace_fallback_formats_chain({ mobile: [:mobile, options[:fall_back]] })
|
121
|
+
else
|
122
|
+
if options[:fallback_chains]
|
123
|
+
self.mobylette_resolver.replace_fallback_formats_chain(options[:fallback_chains])
|
124
|
+
end
|
125
|
+
end
|
82
126
|
end
|
83
127
|
end
|
84
128
|
|
85
129
|
private
|
86
130
|
|
87
|
-
# :doc:
|
88
131
|
# Private: Tells if the request comes from a mobile user_agent or not
|
89
132
|
#
|
90
133
|
def is_mobile_request?
|
91
|
-
request.user_agent.to_s.downcase =~
|
134
|
+
request.user_agent.to_s.downcase =~ @@mobylette_options[:mobile_user_agents].call
|
135
|
+
end
|
136
|
+
|
137
|
+
# Private: Returns if this request comes from the informed device
|
138
|
+
#
|
139
|
+
# devive - device symbol. It must be previously registered as a device.
|
140
|
+
#
|
141
|
+
def request_device?(device)
|
142
|
+
(request.user_agent.to_s.downcase =~ (Mobylette.devices.device(device) || %r{not_to_be_matched_please}) ? true : false)
|
92
143
|
end
|
93
144
|
|
94
|
-
# :doc:
|
95
145
|
# Private: Helper method that tells if the currently view is mobile or not
|
96
146
|
#
|
97
147
|
def is_mobile_view?
|
@@ -137,15 +187,26 @@ module Mobylette
|
|
137
187
|
end
|
138
188
|
end
|
139
189
|
|
140
|
-
# :doc:
|
141
190
|
# Private: Process the request as mobile
|
142
191
|
#
|
143
192
|
def handle_mobile
|
144
193
|
return if session[:mobylette_override] == :ignore_mobile
|
145
|
-
|
146
194
|
if respond_as_mobile?
|
147
|
-
request.format =
|
195
|
+
request.format = set_mobile_format
|
196
|
+
end
|
197
|
+
end
|
198
|
+
|
199
|
+
# Private: Checks if there are fallback_chains defined.
|
200
|
+
# if there is, it will try to match the request browser
|
201
|
+
# agains a fallback_chain key.
|
202
|
+
#
|
203
|
+
def set_mobile_format
|
204
|
+
if self.mobylette_options[:fallback_chains]
|
205
|
+
self.mobylette_options[:fallback_chains].keys.each do |device|
|
206
|
+
return device if request_device?(device)
|
207
|
+
end
|
148
208
|
end
|
209
|
+
:mobile
|
149
210
|
end
|
150
211
|
|
151
212
|
end
|
data/lib/mobylette/version.rb
CHANGED
@@ -0,0 +1,116 @@
|
|
1
|
+
|
2
|
+
|
3
|
+
Started GET "/" for 127.0.0.1 at 2012-03-25 16:04:55 -0300
|
4
|
+
Processing by HomeController#index as HTML
|
5
|
+
Rendered home/index.html.erb within layouts/application (2.2ms)
|
6
|
+
Compiled application.css (0ms) (pid 45506)
|
7
|
+
Compiled application.js (0ms) (pid 45506)
|
8
|
+
Completed 200 OK in 25ms (Views: 24.5ms)
|
9
|
+
|
10
|
+
|
11
|
+
Started GET "/assets/application.css?body=1" for 127.0.0.1 at 2012-03-25 16:04:55 -0300
|
12
|
+
Served asset /application.css - 200 OK (5ms)
|
13
|
+
|
14
|
+
|
15
|
+
Started GET "/assets/application.js?body=1" for 127.0.0.1 at 2012-03-25 16:04:55 -0300
|
16
|
+
Served asset /application.js - 200 OK (3ms)
|
17
|
+
|
18
|
+
|
19
|
+
Started GET "/" for 192.168.0.5 at 2012-03-25 16:05:53 -0300
|
20
|
+
Processing by HomeController#index as HTML
|
21
|
+
Rendered home/index.mobile.erb within layouts/application (0.6ms)
|
22
|
+
Compiled application_mobile.css (0ms) (pid 45506)
|
23
|
+
Compiled application_mobile.js (0ms) (pid 45506)
|
24
|
+
Completed 200 OK in 30ms (Views: 29.3ms)
|
25
|
+
|
26
|
+
|
27
|
+
Started GET "/assets/application_mobile.css?body=1" for 192.168.0.5 at 2012-03-25 16:05:53 -0300
|
28
|
+
Served asset /application_mobile.css - 200 OK (5ms)
|
29
|
+
|
30
|
+
|
31
|
+
Started GET "/assets/application_mobile.js?body=1" for 192.168.0.5 at 2012-03-25 16:05:53 -0300
|
32
|
+
Served asset /application_mobile.js - 200 OK (2ms)
|
33
|
+
|
34
|
+
|
35
|
+
Started GET "/" for 127.0.0.1 at 2012-03-25 16:11:35 -0300
|
36
|
+
Processing by HomeController#index as HTML
|
37
|
+
Rendered home/index.html.erb within layouts/application (2.5ms)
|
38
|
+
Completed 200 OK in 34ms (Views: 33.9ms)
|
39
|
+
|
40
|
+
|
41
|
+
Started GET "/assets/application.css?body=1" for 127.0.0.1 at 2012-03-25 16:11:35 -0300
|
42
|
+
Served asset /application.css - 304 Not Modified (0ms)
|
43
|
+
|
44
|
+
|
45
|
+
Started GET "/assets/application.js?body=1" for 127.0.0.1 at 2012-03-25 16:11:35 -0300
|
46
|
+
Served asset /application.js - 304 Not Modified (0ms)
|
47
|
+
|
48
|
+
|
49
|
+
Started GET "/" for 192.168.0.5 at 2012-03-25 16:11:43 -0300
|
50
|
+
Processing by HomeController#index as HTML
|
51
|
+
Rendered home/index.mobile.erb within layouts/application (0.8ms)
|
52
|
+
Completed 200 OK in 8ms (Views: 8.1ms)
|
53
|
+
|
54
|
+
|
55
|
+
Started GET "/assets/application_mobile.css?body=1" for 192.168.0.5 at 2012-03-25 16:11:43 -0300
|
56
|
+
Served asset /application_mobile.css - 304 Not Modified (0ms)
|
57
|
+
|
58
|
+
|
59
|
+
Started GET "/assets/application_mobile.js?body=1" for 192.168.0.5 at 2012-03-25 16:11:43 -0300
|
60
|
+
Served asset /application_mobile.js - 304 Not Modified (0ms)
|
61
|
+
|
62
|
+
|
63
|
+
Started GET "/" for 127.0.0.1 at 2012-03-25 16:12:03 -0300
|
64
|
+
Processing by HomeController#index as HTML
|
65
|
+
Rendered home/index.html.erb within layouts/application (0.3ms)
|
66
|
+
Completed 200 OK in 26ms (Views: 25.6ms)
|
67
|
+
|
68
|
+
|
69
|
+
Started GET "/assets/application.css?body=1" for 127.0.0.1 at 2012-03-25 16:12:03 -0300
|
70
|
+
Served asset /application.css - 304 Not Modified (0ms)
|
71
|
+
|
72
|
+
|
73
|
+
Started GET "/assets/application.js?body=1" for 127.0.0.1 at 2012-03-25 16:12:03 -0300
|
74
|
+
Served asset /application.js - 304 Not Modified (0ms)
|
75
|
+
|
76
|
+
|
77
|
+
Started GET "/" for 127.0.0.1 at 2012-03-25 16:12:05 -0300
|
78
|
+
Processing by HomeController#index as HTML
|
79
|
+
Rendered home/index.html.erb within layouts/application (0.2ms)
|
80
|
+
Completed 200 OK in 4ms (Views: 3.7ms)
|
81
|
+
|
82
|
+
|
83
|
+
Started GET "/assets/application.css?body=1" for 127.0.0.1 at 2012-03-25 16:12:05 -0300
|
84
|
+
Served asset /application.css - 304 Not Modified (0ms)
|
85
|
+
|
86
|
+
|
87
|
+
Started GET "/assets/application.js?body=1" for 127.0.0.1 at 2012-03-25 16:12:05 -0300
|
88
|
+
Served asset /application.js - 304 Not Modified (0ms)
|
89
|
+
|
90
|
+
|
91
|
+
Started GET "/" for 127.0.0.1 at 2012-03-25 16:12:12 -0300
|
92
|
+
Processing by HomeController#index as HTML
|
93
|
+
Rendered home/index.html.erb within layouts/application (0.2ms)
|
94
|
+
Completed 200 OK in 4ms (Views: 3.6ms)
|
95
|
+
|
96
|
+
|
97
|
+
Started GET "/assets/application.css?body=1" for 127.0.0.1 at 2012-03-25 16:12:12 -0300
|
98
|
+
Served asset /application.css - 304 Not Modified (0ms)
|
99
|
+
|
100
|
+
|
101
|
+
Started GET "/assets/application.js?body=1" for 127.0.0.1 at 2012-03-25 16:12:12 -0300
|
102
|
+
Served asset /application.js - 304 Not Modified (0ms)
|
103
|
+
|
104
|
+
|
105
|
+
Started GET "/" for 192.168.0.5 at 2012-03-25 16:12:15 -0300
|
106
|
+
Processing by HomeController#index as HTML
|
107
|
+
Rendered home/index.mobile.erb within layouts/application (0.5ms)
|
108
|
+
Completed 200 OK in 4ms (Views: 3.7ms)
|
109
|
+
|
110
|
+
|
111
|
+
Started GET "/assets/application_mobile.css?body=1" for 192.168.0.5 at 2012-03-25 16:12:15 -0300
|
112
|
+
Served asset /application_mobile.css - 200 OK (1ms)
|
113
|
+
|
114
|
+
|
115
|
+
Started GET "/assets/application_mobile.js?body=1" for 192.168.0.5 at 2012-03-25 16:12:15 -0300
|
116
|
+
Served asset /application_mobile.js - 200 OK (0ms)
|
data/spec/dummy/log/test.log
CHANGED
@@ -0,0 +1,97 @@
|
|
1
|
+
Processing by DefaultFallbackController#index as HTML
|
2
|
+
Completed 200 OK in 19ms (Views: 17.9ms)
|
3
|
+
Processing by DefaultFallbackController#index as HTML
|
4
|
+
Completed 200 OK in 2ms (Views: 2.2ms)
|
5
|
+
Processing by DefaultFallbackController#test as HTML
|
6
|
+
Completed 200 OK in 2ms (Views: 2.0ms)
|
7
|
+
Processing by DefaultFallbackController#test as JS
|
8
|
+
Completed 200 OK in 8ms (Views: 7.4ms)
|
9
|
+
Processing by ForceFallbackController#index as HTML
|
10
|
+
Completed 200 OK in 4ms (Views: 3.4ms)
|
11
|
+
Processing by ForceFallbackController#index as HTML
|
12
|
+
Completed 200 OK in 2ms (Views: 1.8ms)
|
13
|
+
Processing by ForceFallbackController#test as HTML
|
14
|
+
Completed 200 OK in 2ms (Views: 1.8ms)
|
15
|
+
Processing by ForceFallbackController#test as HTML
|
16
|
+
Completed 200 OK in 1ms (Views: 0.9ms)
|
17
|
+
Processing by ForceFallbackController#test as JS
|
18
|
+
Completed 200 OK in 1ms (Views: 0.7ms)
|
19
|
+
Processing by HomeController#index as HTML
|
20
|
+
Completed 200 OK in 4ms (Views: 3.4ms)
|
21
|
+
Processing by HomeController#index as HTML
|
22
|
+
Completed 200 OK in 1ms (Views: 1.2ms)
|
23
|
+
Processing by HomeController#index as HTML
|
24
|
+
Completed 200 OK in 2ms (Views: 2.2ms)
|
25
|
+
Processing by HomeController#index as HTML
|
26
|
+
Completed 200 OK in 2ms (Views: 1.5ms)
|
27
|
+
Processing by HomeController#index as HTML
|
28
|
+
Completed 200 OK in 1ms (Views: 1.1ms)
|
29
|
+
Processing by HomeController#index as HTML
|
30
|
+
Completed 200 OK in 1ms (Views: 1.0ms)
|
31
|
+
Processing by HomeController#index as HTML
|
32
|
+
Completed 200 OK in 2ms (Views: 1.8ms)
|
33
|
+
Processing by HomeController#index as HTML
|
34
|
+
Completed 200 OK in 2ms (Views: 1.3ms)
|
35
|
+
Processing by HomeController#index as HTML
|
36
|
+
Completed 200 OK in 1ms (Views: 1.0ms)
|
37
|
+
Processing by HomeController#respond_to_test as HTML
|
38
|
+
Completed 200 OK in 2ms (Views: 1.7ms)
|
39
|
+
Processing by HomeController#respond_to_test as HTML
|
40
|
+
Completed 200 OK in 2ms (Views: 1.7ms)
|
41
|
+
Processing by HomeController#respond_to_test as MOBILE
|
42
|
+
Completed 200 OK in 1ms (Views: 0.9ms)
|
43
|
+
Processing by HomeController#index as JS
|
44
|
+
Completed 200 OK in 5ms (Views: 5.2ms)
|
45
|
+
Processing by HomeController#index as HTML
|
46
|
+
Completed 200 OK in 1ms (Views: 1.1ms)
|
47
|
+
Processing by HomeController#index as HTML
|
48
|
+
Completed 200 OK in 1ms (Views: 1.1ms)
|
49
|
+
Processing by HomeController#index as HTML
|
50
|
+
Parameters: {"skip_mobile"=>"true"}
|
51
|
+
Completed 200 OK in 1ms (Views: 1.1ms)
|
52
|
+
Processing by NoFallbackController#index as HTML
|
53
|
+
Completed 200 OK in 4ms (Views: 3.7ms)
|
54
|
+
Processing by NoFallbackController#index as HTML
|
55
|
+
Completed 200 OK in 3ms (Views: 2.5ms)
|
56
|
+
Processing by NoFallbackController#test as HTML
|
57
|
+
Completed 500 Internal Server Error in 1ms
|
58
|
+
Processing by NoFallbackController#test as HTML
|
59
|
+
Completed 500 Internal Server Error in 1ms
|
60
|
+
Processing by NoFallbackController#test as HTML
|
61
|
+
Completed 500 Internal Server Error in 1ms
|
62
|
+
Processing by SkipXhrRequestController#index as JS
|
63
|
+
Completed 200 OK in 6ms (Views: 5.3ms)
|
64
|
+
DEPRECATED > Mobylette: Please don't user :fall_back to configure fall backs any more. Read the README for :fallback_chains instead.
|
65
|
+
DEPRECATED > Mobylette: Please don't user :fall_back to configure fall backs any more. Read the README for :fallback_chains instead.
|
66
|
+
DEPRECATED > Mobylette: Please don't user :fall_back to configure fall backs any more. Read the README for :fallback_chains instead.
|
67
|
+
DEPRECATED > Mobylette: Please don't user :fall_back to configure fall backs any more. Read the README for :fallback_chains instead.
|
68
|
+
DEPRECATED > Mobylette: Please don't user :fall_back to configure fall backs any more. Read the README for :fallback_chains instead.
|
69
|
+
DEPRECATED > Mobylette: Please don't user :fall_back to configure fall backs any more. Read the README for :fallback_chains instead.
|
70
|
+
DEPRECATED > Mobylette: Please don't user :fall_back to configure fall backs any more. Read the README for :fallback_chains instead.
|
71
|
+
DEPRECATED > Mobylette: Please don't user :fall_back to configure fall backs any more. Read the README for :fallback_chains instead.
|
72
|
+
DEPRECATED > Mobylette: Please don't user :fall_back to configure fall backs any more. Read the README for :fallback_chains instead.
|
73
|
+
DEPRECATED > Mobylette: Please don't user :fall_back to configure fall backs any more. Read the README for :fallback_chains instead.
|
74
|
+
DEPRECATED > Mobylette: Please don't user :fall_back to configure fall backs any more. Read the README for :fallback_chains instead.
|
75
|
+
DEPRECATED > Mobylette: Please don't user :fall_back to configure fall backs any more. Read the README for :fallback_chains instead.
|
76
|
+
DEPRECATED > Mobylette: Please don't user :fall_back to configure fall backs any more. Read the README for :fallback_chains instead.
|
77
|
+
DEPRECATED > Mobylette: Please don't user :fall_back to configure fall backs any more. Read the README for :fallback_chains instead.
|
78
|
+
DEPRECATED > Mobylette: Please don't user :fall_back to configure fall backs any more. Read the README for :fallback_chains instead.
|
79
|
+
DEPRECATED > Mobylette: Please don't user :fall_back to configure fall backs any more. Read the README for :fallback_chains instead.
|
80
|
+
DEPRECATED > Mobylette: Please don't user :fall_back to configure fall backs any more. Read the README for :fallback_chains instead.
|
81
|
+
DEPRECATED > Mobylette: Please don't user :fall_back to configure fall backs any more. Read the README for :fallback_chains instead.
|
82
|
+
DEPRECATED > Mobylette: Please don't user :fall_back to configure fall backs any more. Read the README for :fallback_chains instead.
|
83
|
+
DEPRECATED > Mobylette: Please don't user :fall_back to configure fall backs any more. Read the README for :fallback_chains instead.
|
84
|
+
DEPRECATED > Mobylette: Please don't user :fall_back to configure fall backs any more. Read the README for :fallback_chains instead.
|
85
|
+
DEPRECATED > Mobylette: Please don't user :fall_back to configure fall backs any more. Read the README for :fallback_chains instead.
|
86
|
+
DEPRECATED > Mobylette: Please don't user :fall_back to configure fall backs any more. Read the README for :fallback_chains instead.
|
87
|
+
DEPRECATED > Mobylette: Please don't user :fall_back to configure fall backs any more. Read the README for :fallback_chains instead.
|
88
|
+
DEPRECATED > Mobylette: Please don't user :fall_back to configure fall backs any more. Read the README for :fallback_chains instead.
|
89
|
+
DEPRECATED > Mobylette: Please don't user :fall_back to configure fall backs any more. Read the README for :fallback_chains instead.
|
90
|
+
DEPRECATED > Mobylette: Please don't user :fall_back to configure fall backs any more. Read the README for :fallback_chains instead.
|
91
|
+
DEPRECATED > Mobylette: Please don't user :fall_back to configure fall backs any more. Read the README for :fallback_chains instead.
|
92
|
+
DEPRECATED > Mobylette: Please don't user :fall_back to configure fall backs any more. Read the README for :fallback_chains instead.
|
93
|
+
DEPRECATED > Mobylette: Please don't user :fall_back to configure fall backs any more. Read the README for :fallback_chains instead.
|
94
|
+
DEPRECATED > Mobylette: Please don't user :fall_back to configure fall backs any more. Read the README for :fallback_chains instead.
|
95
|
+
DEPRECATED > Mobylette: Please don't user :fall_back to configure fall backs any more. Read the README for :fallback_chains instead.
|
96
|
+
DEPRECATED > Mobylette: Please don't user :fall_back to configure fall backs any more. Read the README for :fallback_chains instead.
|
97
|
+
DEPRECATED > Mobylette: Please don't user :fall_back to configure fall backs any more. Read the README for :fallback_chains instead.
|
@@ -0,0 +1,14 @@
|
|
1
|
+
o: ActiveSupport::Cache::Entry :@compressedF:@expires_in0:@created_atf1332702353.878731:@value{ I"length:EFi�I"digest;
|
2
|
+
F"%769c3433f6bf172ce80327c044c94eb8I"source;
|
3
|
+
FI"�// This is a manifest file that'll be compiled into including all the files listed below.
|
4
|
+
// Add new JavaScript/Coffee code in separate files in this directory and they'll automatically
|
5
|
+
// be included in the compiled file accessible from http://example.com/assets/application.js
|
6
|
+
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
|
7
|
+
// the compiled file.
|
8
|
+
//
|
9
|
+
//
|
10
|
+
|
11
|
+
alert("MOBILE JS");
|
12
|
+
;
|
13
|
+
FI"
|
14
|
+
F"%34fa2587d444e6aea52cea430c668ccd
|
Binary file
|
Binary file
|
@@ -0,0 +1,16 @@
|
|
1
|
+
o: ActiveSupport::Cache::Entry :@compressedF:@expires_in0:@created_atf1332702353.869955:@value{ I"length:EFiaI"digest;
|
2
|
+
F"%7b5b4d1463c8ab2cd40517c7d780541aI"source;
|
3
|
+
FI"a/*
|
4
|
+
* This is the application mobile CSS
|
5
|
+
*
|
6
|
+
*
|
7
|
+
*
|
8
|
+
*/
|
9
|
+
|
10
|
+
|
11
|
+
body {
|
12
|
+
background-color: green;
|
13
|
+
}
|
14
|
+
;
|
15
|
+
FI"
|
16
|
+
F"%dcc110379513c5a0ef6f15e1c0fd77c0
|
Binary file
|
@@ -0,0 +1,16 @@
|
|
1
|
+
o: ActiveSupport::Cache::Entry :@compressedF:@expires_in0:@created_atf1332702295.254518:@value{ I"length:EFi`I"digest;
|
2
|
+
F"%da492739dcaff65c608e68791e24b0b5I"source;
|
3
|
+
FI"`/*
|
4
|
+
* This is a manifest file that'll automatically include all the stylesheets available in this directory
|
5
|
+
* and any sub-directories. You're free to add application-wide styles to this file and they'll appear at
|
6
|
+
* the top of the compiled file, but it's generally better to create a new file per style scope.
|
7
|
+
*/
|
8
|
+
|
9
|
+
|
10
|
+
|
11
|
+
body {
|
12
|
+
background-color: blue;
|
13
|
+
}
|
14
|
+
;
|
15
|
+
FI"
|
16
|
+
F"%4445ed39e85707f3677849c0aa9f18ed
|
@@ -0,0 +1,14 @@
|
|
1
|
+
o: ActiveSupport::Cache::Entry :@compressedF:@expires_in0:@created_atf1332702295.262975:@value{ I"length:EFi�I"digest;
|
2
|
+
F"%e9b5a652b2cb6afb7f4abf460034a746I"source;
|
3
|
+
FI"�// This is a manifest file that'll be compiled into including all the files listed below.
|
4
|
+
// Add new JavaScript/Coffee code in separate files in this directory and they'll automatically
|
5
|
+
// be included in the compiled file accessible from http://example.com/assets/application.js
|
6
|
+
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
|
7
|
+
// the compiled file.
|
8
|
+
//
|
9
|
+
//
|
10
|
+
|
11
|
+
alert("HTML JS");
|
12
|
+
;
|
13
|
+
FI"
|
14
|
+
F"%22b0e19566c0b533398b54fe8fbd3f62
|
Binary file
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Mobylette
|
4
|
+
describe Devices do
|
5
|
+
|
6
|
+
describe "#register" do
|
7
|
+
it "should accept a {key:value} and insert it into the devices list" do
|
8
|
+
Devices.instance.register(crazy_phone: /woot/)
|
9
|
+
Devices.instance.instance_variable_get("@devices")[:crazy_phone].should == /woot/
|
10
|
+
end
|
11
|
+
|
12
|
+
it "should accept more than one key:value" do
|
13
|
+
Devices.instance.register(awesomephone: /waat/, notthatcool: /sad/)
|
14
|
+
Devices.instance.instance_variable_get("@devices")[:awesomephone].should == /waat/
|
15
|
+
Devices.instance.instance_variable_get("@devices")[:notthatcool].should == /sad/
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
describe "#device" do
|
20
|
+
it "should return the regex for the informed device" do
|
21
|
+
Devices.instance.device(:iphone).should == /iphone/i
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
describe "#devices" do
|
27
|
+
it "should be an alias to Mobylette::Devices.instance" do
|
28
|
+
Mobylette.devices.should == Mobylette::Devices.instance
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Mobylette
|
4
|
+
module Resolvers
|
5
|
+
describe ChainedFallbackResolver do
|
6
|
+
|
7
|
+
describe "#find_templates" do
|
8
|
+
|
9
|
+
context "single fallback chain" do
|
10
|
+
[
|
11
|
+
{ mobile: [:mobile, :html]},
|
12
|
+
{ iphone: [:iphone, :mobile, :html]}
|
13
|
+
].each do |fallback_chain|
|
14
|
+
context "fallback chain = #{fallback_chain.to_s}" do
|
15
|
+
subject { Mobylette::Resolvers::ChainedFallbackResolver.new(fallback_chain) }
|
16
|
+
|
17
|
+
it "should change details[:formats] to the fallback array" do
|
18
|
+
details = { formats: [fallback_chain.keys.first] }
|
19
|
+
details.stub(:dup).and_return(details)
|
20
|
+
subject.find_templates("", "", "", details)
|
21
|
+
details[:formats].should == fallback_chain.values.first
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
context "multiple fallback chains" do
|
29
|
+
fallback_chains = {iphone: [:iphone, :mobile, :html], android: [:android, :html], mobile: [:mobile, :html]}
|
30
|
+
subject { Mobylette::Resolvers::ChainedFallbackResolver.new(fallback_chains) }
|
31
|
+
|
32
|
+
fallback_chains.each_pair do |format, fallback_array|
|
33
|
+
context "#{format} format" do
|
34
|
+
it "should change details[:formats] to the fallback array" do
|
35
|
+
details = { formats: [format] }
|
36
|
+
details.stub(:dup).and_return(details)
|
37
|
+
subject.find_templates("", "", "", details)
|
38
|
+
details[:formats].should == fallback_array
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Mobylette
|
4
|
+
describe RespondToMobileRequests do
|
5
|
+
describe 'Configuration' do
|
6
|
+
|
7
|
+
class MockConfigurationController < ActionController::Base
|
8
|
+
include Mobylette::RespondToMobileRequests
|
9
|
+
end
|
10
|
+
|
11
|
+
subject { MockConfigurationController.new }
|
12
|
+
|
13
|
+
describe "basic configuration delegation" do
|
14
|
+
|
15
|
+
describe "#mobilette_config" do
|
16
|
+
it "should set mobylette_options" do
|
17
|
+
subject.class.mobylette_config do |config|
|
18
|
+
config[:fallback_chains] = { mobile: [:mobile, :html, :js] }
|
19
|
+
config[:skip_xhr_requests] = false
|
20
|
+
end
|
21
|
+
subject.mobylette_options[:fallback_chains].should == { mobile: [:mobile, :html, :js] }
|
22
|
+
subject.mobylette_options[:skip_xhr_requests].should be_false
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
describe "devices" do
|
27
|
+
it "should register devices to Mobylette::Devices" do
|
28
|
+
subject.class.mobylette_config do |config|
|
29
|
+
config[:devices] = {phone1: %r{phone_1}, phone2: %r{phone_2}}
|
30
|
+
end
|
31
|
+
Mobylette::Devices.instance.device(:phone1).should == /phone_1/
|
32
|
+
Mobylette::Devices.instance.device(:phone2).should == /phone_2/
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
describe "fallbacks" do
|
37
|
+
context "compatibility with deprecated fall back" do
|
38
|
+
it "should configure the fallback device with only one fallback" do
|
39
|
+
mobylette_resolver = double("resolver", replace_fallback_formats_chain: "")
|
40
|
+
mobylette_resolver.should_receive(:replace_fallback_formats_chain).with({ mobile: [:mobile, :spec] })
|
41
|
+
subject.class.stub(:mobylette_resolver).and_return(mobylette_resolver)
|
42
|
+
subject.class.mobylette_config do |config|
|
43
|
+
config[:fall_back] = :spec
|
44
|
+
config[:fallback_chains] = { mobile: [:mobile, :mp3] }
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
context "chained fallback" do
|
50
|
+
it "should use the fallback chain" do
|
51
|
+
mobylette_resolver = double("resolver", replace_fallback_formats_chain: "")
|
52
|
+
mobylette_resolver.should_receive(:replace_fallback_formats_chain).with({ iphone: [:iphone, :mobile], mobile: [:mobile, :html] })
|
53
|
+
subject.class.stub(:mobylette_resolver).and_return(mobylette_resolver)
|
54
|
+
subject.class.mobylette_config do |config|
|
55
|
+
config[:fall_back] = nil # reset to the default state
|
56
|
+
config[:fallback_chains] = { iphone: [:iphone, :mobile], mobile: [:mobile, :html] }
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
@@ -5,39 +5,18 @@ module Mobylette
|
|
5
5
|
|
6
6
|
class MockController < ActionController::Base
|
7
7
|
include Mobylette::RespondToMobileRequests
|
8
|
-
|
9
|
-
mobylette_config do |config|
|
10
|
-
config[:fall_back] = :something
|
11
|
-
config[:skip_xhr_requests] = :something
|
12
|
-
end
|
13
8
|
end
|
14
9
|
|
15
10
|
subject { MockController.new }
|
16
11
|
|
17
|
-
describe "#mobilette_config" do
|
18
|
-
it "should have options configured" do
|
19
|
-
subject.mobylette_options[:fall_back].should == :something
|
20
|
-
subject.mobylette_options[:skip_xhr_requests].should == :something
|
21
|
-
end
|
22
|
-
|
23
|
-
it "should set mobylette_options" do
|
24
|
-
subject.class.mobylette_config do |config|
|
25
|
-
config[:fall_back] = :js
|
26
|
-
config[:skip_xhr_requests] = false
|
27
|
-
end
|
28
|
-
subject.mobylette_options[:fall_back].should == :js
|
29
|
-
subject.mobylette_options[:skip_xhr_requests].should be_false
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
12
|
describe "#is_mobile_request?" do
|
34
13
|
it "should be false for a normal request" do
|
35
14
|
subject.stub_chain(:request, :user_agent).and_return('some mozilla')
|
36
15
|
subject.send(:is_mobile_request?).should be_false
|
37
16
|
end
|
38
17
|
|
39
|
-
Mobylette::
|
40
|
-
agent.gsub!('
|
18
|
+
Mobylette::MobileUserAgents.new.call.to_s.split('|').each do |agent|
|
19
|
+
agent.gsub!('\\', '')
|
41
20
|
it "should be true for the agent #{agent}" do
|
42
21
|
subject.stub_chain(:request, :user_agent).and_return(agent)
|
43
22
|
subject.send(:is_mobile_request?).should be_true
|
@@ -220,13 +199,10 @@ module Mobylette
|
|
220
199
|
before(:each) do
|
221
200
|
subject.stub(:session).and_return({})
|
222
201
|
subject.stub(:respond_as_mobile?).and_return(true)
|
223
|
-
@
|
224
|
-
@format = mock("old_format")
|
225
|
-
@format.stub(:to_sym).and_return(:old_format)
|
226
|
-
@request.stub(:format).and_return(@format)
|
227
|
-
@request.stub(:format=).and_return { |new_value| @format = new_value }
|
202
|
+
@format = double("old_format", to_sym: :old_format)
|
228
203
|
@formats = []
|
229
|
-
@request
|
204
|
+
@request = double("request", user_agent: "android", format: @format, formats: @formats)
|
205
|
+
@request.stub(:format=).and_return { |new_value| @format = new_value }
|
230
206
|
subject.stub(:request).and_return(@request)
|
231
207
|
subject.mobylette_options[:fall_back] = false
|
232
208
|
end
|
@@ -238,5 +214,34 @@ module Mobylette
|
|
238
214
|
|
239
215
|
end
|
240
216
|
end
|
217
|
+
|
218
|
+
describe "#request_device?" do
|
219
|
+
it "should match a device" do
|
220
|
+
subject.stub_chain(:request, :user_agent).and_return('very custom browser WebKit')
|
221
|
+
Mobylette.devices.register(custom_phone: %r{custom\s+browser})
|
222
|
+
subject.send(:request_device?, :iphone).should be_false
|
223
|
+
subject.send(:request_device?, :custom_phone).should be_true
|
224
|
+
end
|
225
|
+
end
|
226
|
+
|
227
|
+
describe "#set_mobile_format" do
|
228
|
+
context "matching format in fallback chain" do
|
229
|
+
it "should return the request device format when it is in a chain" do
|
230
|
+
subject.mobylette_options[:fallback_chains] = { html: [:html, :htm], mp3: [:mp3, :wav, :mid] }
|
231
|
+
subject.stub(:request_device?).with(:mp3).and_return(true)
|
232
|
+
subject.stub(:request_device?).with(:html).and_return(false)
|
233
|
+
subject.send(:set_mobile_format).should == :mp3
|
234
|
+
end
|
235
|
+
end
|
236
|
+
|
237
|
+
context "not matching format in fallback chain" do
|
238
|
+
it "should return :mobile" do
|
239
|
+
subject.mobylette_options[:fallback_chains] = { html: [:html, :htm], mp3: [:mp3, :wav, :mid] }
|
240
|
+
subject.stub_chain(:request, :user_agent).and_return("android")
|
241
|
+
subject.send(:set_mobile_format).should == :mobile
|
242
|
+
end
|
243
|
+
end
|
244
|
+
end
|
245
|
+
|
241
246
|
end
|
242
247
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mobylette
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: '
|
4
|
+
version: '3.0'
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-
|
12
|
+
date: 2012-06-23 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: actionpack
|
16
|
-
requirement: &
|
16
|
+
requirement: &70192278087920 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: '3.0'
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *70192278087920
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: rspec
|
27
|
-
requirement: &
|
27
|
+
requirement: &70192278087140 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ! '>='
|
@@ -32,10 +32,10 @@ dependencies:
|
|
32
32
|
version: '0'
|
33
33
|
type: :development
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *70192278087140
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: rspec-rails
|
38
|
-
requirement: &
|
38
|
+
requirement: &70192278085780 !ruby/object:Gem::Requirement
|
39
39
|
none: false
|
40
40
|
requirements:
|
41
41
|
- - ! '>='
|
@@ -43,7 +43,18 @@ dependencies:
|
|
43
43
|
version: '0'
|
44
44
|
type: :development
|
45
45
|
prerelease: false
|
46
|
-
version_requirements: *
|
46
|
+
version_requirements: *70192278085780
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: debugger
|
49
|
+
requirement: &70192278084660 !ruby/object:Gem::Requirement
|
50
|
+
none: false
|
51
|
+
requirements:
|
52
|
+
- - ! '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
type: :development
|
56
|
+
prerelease: false
|
57
|
+
version_requirements: *70192278084660
|
47
58
|
description: Adds the mobile format for rendering views for mobile device.
|
48
59
|
email:
|
49
60
|
- tscolari@gmail.com
|
@@ -52,10 +63,11 @@ extensions: []
|
|
52
63
|
extra_rdoc_files: []
|
53
64
|
files:
|
54
65
|
- config/initializers/responders.rb
|
55
|
-
- lib/mobylette/
|
66
|
+
- lib/mobylette/devices.rb
|
56
67
|
- lib/mobylette/helmet.rb
|
57
68
|
- lib/mobylette/mobile_user_agents.rb
|
58
69
|
- lib/mobylette/railtie.rb
|
70
|
+
- lib/mobylette/resolvers/chained_fallback_resolver.rb
|
59
71
|
- lib/mobylette/respond_to_mobile_requests.rb
|
60
72
|
- lib/mobylette/version.rb
|
61
73
|
- lib/mobylette.rb
|
@@ -117,6 +129,7 @@ files:
|
|
117
129
|
- spec/dummy/config/routes.rb
|
118
130
|
- spec/dummy/config.ru
|
119
131
|
- spec/dummy/db/schema.rb
|
132
|
+
- spec/dummy/log/development.log
|
120
133
|
- spec/dummy/log/test.log
|
121
134
|
- spec/dummy/public/404.html
|
122
135
|
- spec/dummy/public/422.html
|
@@ -124,16 +137,24 @@ files:
|
|
124
137
|
- spec/dummy/public/favicon.ico
|
125
138
|
- spec/dummy/Rakefile
|
126
139
|
- spec/dummy/script/rails
|
140
|
+
- spec/dummy/tmp/cache/assets/C82/3E0/sprockets%2F48eb4ac616538f8f36870451073315da
|
141
|
+
- spec/dummy/tmp/cache/assets/CE4/1C0/sprockets%2F18d93e1533d585b2f64ec90b33176ac9
|
142
|
+
- spec/dummy/tmp/cache/assets/CED/A70/sprockets%2F621683d8791730a9cc7ce45e17a7e46d
|
143
|
+
- spec/dummy/tmp/cache/assets/CFC/200/sprockets%2F716f89d85d4855706b8a9abec1969c62
|
144
|
+
- spec/dummy/tmp/cache/assets/D32/A10/sprockets%2F13fe41fee1fe35b49d145bcc06610705
|
145
|
+
- spec/dummy/tmp/cache/assets/D54/ED0/sprockets%2F71c9fa01091d432b131da3bb73faf3d4
|
146
|
+
- spec/dummy/tmp/cache/assets/D84/210/sprockets%2Fabd0103ccec2b428ac62c94e4c40b384
|
147
|
+
- spec/dummy/tmp/cache/assets/E04/890/sprockets%2F2f5173deea6c795b8fdde723bb4b63af
|
127
148
|
- spec/integration/navigation_spec.rb
|
128
|
-
- spec/lib/
|
149
|
+
- spec/lib/devices_spec.rb
|
150
|
+
- spec/lib/resolvers/chained_fallback_resolver_spec.rb
|
151
|
+
- spec/lib/respond_to_mobile_requests/configuration_spec.rb
|
129
152
|
- spec/lib/respond_to_mobile_requests_spec.rb
|
130
153
|
- spec/mobylette_spec.rb
|
131
154
|
- spec/spec_helper.rb
|
132
155
|
homepage: https://github.com/tscolari/mobylette
|
133
156
|
licenses: []
|
134
|
-
post_install_message:
|
135
|
-
changed.\n Use include Mobylette::RespondToMobileRequests instead of respond_to_mobile_requests
|
136
|
-
now.\n Please refer to the readme for more information.\n **************************\n"
|
157
|
+
post_install_message:
|
137
158
|
rdoc_options: []
|
138
159
|
require_paths:
|
139
160
|
- lib
|
@@ -145,7 +166,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
145
166
|
version: '0'
|
146
167
|
segments:
|
147
168
|
- 0
|
148
|
-
hash:
|
169
|
+
hash: -96816333988164215
|
149
170
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
150
171
|
none: false
|
151
172
|
requirements:
|
@@ -154,7 +175,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
154
175
|
version: '0'
|
155
176
|
segments:
|
156
177
|
- 0
|
157
|
-
hash:
|
178
|
+
hash: -96816333988164215
|
158
179
|
requirements: []
|
159
180
|
rubyforge_project:
|
160
181
|
rubygems_version: 1.8.10
|
@@ -216,6 +237,7 @@ test_files:
|
|
216
237
|
- spec/dummy/config/routes.rb
|
217
238
|
- spec/dummy/config.ru
|
218
239
|
- spec/dummy/db/schema.rb
|
240
|
+
- spec/dummy/log/development.log
|
219
241
|
- spec/dummy/log/test.log
|
220
242
|
- spec/dummy/public/404.html
|
221
243
|
- spec/dummy/public/422.html
|
@@ -223,8 +245,18 @@ test_files:
|
|
223
245
|
- spec/dummy/public/favicon.ico
|
224
246
|
- spec/dummy/Rakefile
|
225
247
|
- spec/dummy/script/rails
|
248
|
+
- spec/dummy/tmp/cache/assets/C82/3E0/sprockets%2F48eb4ac616538f8f36870451073315da
|
249
|
+
- spec/dummy/tmp/cache/assets/CE4/1C0/sprockets%2F18d93e1533d585b2f64ec90b33176ac9
|
250
|
+
- spec/dummy/tmp/cache/assets/CED/A70/sprockets%2F621683d8791730a9cc7ce45e17a7e46d
|
251
|
+
- spec/dummy/tmp/cache/assets/CFC/200/sprockets%2F716f89d85d4855706b8a9abec1969c62
|
252
|
+
- spec/dummy/tmp/cache/assets/D32/A10/sprockets%2F13fe41fee1fe35b49d145bcc06610705
|
253
|
+
- spec/dummy/tmp/cache/assets/D54/ED0/sprockets%2F71c9fa01091d432b131da3bb73faf3d4
|
254
|
+
- spec/dummy/tmp/cache/assets/D84/210/sprockets%2Fabd0103ccec2b428ac62c94e4c40b384
|
255
|
+
- spec/dummy/tmp/cache/assets/E04/890/sprockets%2F2f5173deea6c795b8fdde723bb4b63af
|
226
256
|
- spec/integration/navigation_spec.rb
|
227
|
-
- spec/lib/
|
257
|
+
- spec/lib/devices_spec.rb
|
258
|
+
- spec/lib/resolvers/chained_fallback_resolver_spec.rb
|
259
|
+
- spec/lib/respond_to_mobile_requests/configuration_spec.rb
|
228
260
|
- spec/lib/respond_to_mobile_requests_spec.rb
|
229
261
|
- spec/mobylette_spec.rb
|
230
262
|
- spec/spec_helper.rb
|
@@ -1,69 +0,0 @@
|
|
1
|
-
module Mobylette
|
2
|
-
|
3
|
-
# This manages the fall back from mobile views
|
4
|
-
# It only interfers on requests where the format is :mobile,
|
5
|
-
# and in case there is no view for the mobile format, it
|
6
|
-
# will fall back to the any other format that is configurated.
|
7
|
-
#
|
8
|
-
# When you insert Mobylette::RespondToMobileRequests to a
|
9
|
-
# controller, this class will be the new resolver for that
|
10
|
-
# controller.
|
11
|
-
#
|
12
|
-
# By default this resolver will not fallback to any format.
|
13
|
-
# Only is @fallback_to is configurated (by use_fallback)
|
14
|
-
#
|
15
|
-
# You should not use this by yourself unless you know what
|
16
|
-
# you are doing.
|
17
|
-
#
|
18
|
-
# Examples:
|
19
|
-
#
|
20
|
-
# class SomeController < ApplicationController
|
21
|
-
# append_view_path Mobylette::FallbackResolver.new
|
22
|
-
# end
|
23
|
-
#
|
24
|
-
#
|
25
|
-
# ...
|
26
|
-
# my_controller_resolver = Mobylette::FallbackResolver.new
|
27
|
-
# my_controller_resolver.use_fallback(:html)
|
28
|
-
# ...
|
29
|
-
#
|
30
|
-
class FallbackResolver < ::ActionView::FileSystemResolver
|
31
|
-
|
32
|
-
def initialize
|
33
|
-
super('app/views')
|
34
|
-
end
|
35
|
-
|
36
|
-
# Public: Configures what fallback the resolver should use
|
37
|
-
#
|
38
|
-
# - fallback:
|
39
|
-
# * :html/:js/:xml/... => Falls back to that format
|
40
|
-
#
|
41
|
-
def use_fallback(fallback)
|
42
|
-
@fallback_to = fallback
|
43
|
-
end
|
44
|
-
|
45
|
-
# Public: finds the right template on the filesystem,
|
46
|
-
# using fallback if needed
|
47
|
-
#
|
48
|
-
def find_templates(name, prefix, partial, details)
|
49
|
-
if details[:formats].first == :mobile
|
50
|
-
details = details.dup
|
51
|
-
details[:formats] = Array.wrap(fallback_list)
|
52
|
-
end
|
53
|
-
|
54
|
-
super(name, prefix, partial, details)
|
55
|
-
end
|
56
|
-
|
57
|
-
private
|
58
|
-
|
59
|
-
# Private: formats array, in fall back order
|
60
|
-
#
|
61
|
-
def fallback_list
|
62
|
-
if @fallback_to
|
63
|
-
[:mobile, @fallback_to.to_sym]
|
64
|
-
else
|
65
|
-
[:mobile]
|
66
|
-
end
|
67
|
-
end
|
68
|
-
end
|
69
|
-
end
|
@@ -1,54 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
module Mobylette
|
4
|
-
describe FallbackResolver do
|
5
|
-
|
6
|
-
subject { FallbackResolver.new }
|
7
|
-
|
8
|
-
describe "#fallback_list" do
|
9
|
-
|
10
|
-
context "when use_fallback is set to false" do
|
11
|
-
it "should return only :mobile" do
|
12
|
-
subject.use_fallback(false)
|
13
|
-
subject.send(:fallback_list).should == [:mobile]
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
context "when use_fallback is set to any value" do
|
18
|
-
it "should return :mobile and the use_fallback value" do
|
19
|
-
subject.use_fallback(:somestuff)
|
20
|
-
subject.send(:fallback_list).should == [:mobile, :somestuff]
|
21
|
-
end
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
|
-
describe "#find_templates" do
|
26
|
-
before(:each) do
|
27
|
-
@formats = []
|
28
|
-
Array.stub(:wrap).and_return(@formats)
|
29
|
-
@details = {:formats => []}
|
30
|
-
@details.stub(:dup).and_return(@details)
|
31
|
-
end
|
32
|
-
|
33
|
-
context "mobile request" do
|
34
|
-
before(:each) { @details[:formats] = [:mobile] }
|
35
|
-
|
36
|
-
it "should set the details[:formats]" do
|
37
|
-
Array.should_receive(:wrap)
|
38
|
-
subject.find_templates('', '', '', @details)
|
39
|
-
@details[:formats].should == @formats
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
|
-
context "normal request" do
|
44
|
-
before(:each) { @details[:formats] = [:html] }
|
45
|
-
|
46
|
-
it "should not set the details[:formats]" do
|
47
|
-
subject.find_templates('', '', '', @details)
|
48
|
-
@details[:formats].should == [:html]
|
49
|
-
end
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
|
-
end
|
54
|
-
end
|