mobylette 2.3 → 3.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/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
|