Permalink
Browse files

docs and small tweaks

  • Loading branch information...
1 parent ce29f3e commit 35e9d9b400a91c124b3690007f7c23666cd60c4a @jistr committed Feb 13, 2012
View
@@ -1,3 +1,5 @@
/.bundle
+/.yardoc
+/doc
/Gemfile.lock
/vendor/ruby
View
@@ -0,0 +1 @@
+-m markdown
View
@@ -3,7 +3,18 @@
require "mobvious/config"
require "mobvious/manager"
+# A library (Rack middleware) to detect device types (mobile, tablet, desktop etc.)
+# from requests.
+#
+# See {Mobvious::Manager} for the actual Rack middleware.
+#
+# See {Mobvious::Config} for configuration options (and set them via calling
+# {Mobvious.config Mobvious.config}).
+#
+# See {Mobvious::Strategies} for predefined strategies or roll out your own.
module Mobvious
+ # An accessor for the global Mobvious configuration object.
+ # See {Config} for configuration options.
def self.config
@config ||= Mobvious::Config.new
end
@@ -1,15 +1,26 @@
module Mobvious
+ # Class encapsulating Mobvious configuration.
+ #
+ # Set configuration options them via calling {Mobvious.config Mobvious.config}.
class Config
+ # Creates a new configuration with no strategies and default device type `:desktop`.
def initialize()
self.clear
end
+ # Resets a configuration to no strategies and default device type `:desktop`.
def clear
@strategies = []
@default_device_type = :desktop
end
- attr_reader :strategies
+ # Strategies used to determine device type from a request. They are evaluated
+ # in the order they are inserted. Result of the first successful strategy
+ # (returning something else than nil) is used.
+ attr_accessor :strategies
+
+ # Default device type is used when no strategy was successful (all return nil
+ # or none is present).
attr_accessor :default_device_type
end
end
@@ -1,11 +1,23 @@
require 'rack'
module Mobvious
+ # Rack middleware that enables device type detection for requests.
+ #
+ # Use `Mobvious.config` to set which strategies to use.
+ #
+ # Look into `Mobvious::Strategies` for predefined strategies or write your own.
class Manager
+ # Create a new instance of this rack middleware.
+ #
+ # @param app Rack application that can be called.
def initialize(app)
@app = app
end
+ # Perform the device type detection and call the inner Rack application.
+ #
+ # @param env Rack environment.
+ # @return rack response `[status, headers, body]`
def call(env)
request = Rack::Request.new(env)
assign_device_type(request)
@@ -1,16 +1,39 @@
module Mobvious
module Strategies
+ # Mobvious device detection strategy that saves and loads a cookie that precisely
+ # specifies which device type should be used for current client.
+ #
+ # Usually, you will want to set the device type via cookie only when you are absolutely
+ # sure that user wants it this way (e.g. after manual switch between mobile/desktop
+ # interface versions performed by user). Also make sure to use this strategy with high
+ # priority, (e.g. put it before user-agent based detection) so it does not get overriden.
+ #
+ # Use `set_device_type_cookie` method to set the device type and the strategy will then
+ # recognize it on subsequent requests.
class Cookie
+ # Creates a new Cookie strategy instance.
+ #
+ # @param cookie_expires [Integer]
+ # Amount of seconds to hold device type cookie. Defaults to one year (365*24*60*60).
def initialize(cookie_expires = (365*24*60*60))
@cookie_expires = cookie_expires
end
+ # Gets device type using a pre-set cookie. Returns nil if the cookie is not set.
+ #
+ # @param request [Rack::Request]
+ # @return [Symbol] device type or nil
def get_device_type(request)
request.cookies['mobvious.device_type'].to_sym if request.cookies['mobvious.device_type']
end
+ # Automatically sets the device type cookie again to prolong its expiration date.
+ #
+ # @param request [Rack::Request]
+ # @param response [Rack::Response]
def response_callback(request, response)
- response_cookie_already_set = !!response.headers["Set-Cookie"] && !!response.headers["Set-Cookie"]["mobvious.device_type"]
+ response_cookie_already_set = !!response.headers["Set-Cookie"] &&
+ !!response.headers["Set-Cookie"]["mobvious.device_type"]
request_cookie = request.cookies['mobvious.device_type']
# re-set the cookie to renew the expiration date
@@ -19,6 +42,10 @@ def response_callback(request, response)
end
end
+ # Sets the device type cookie.
+ #
+ # @param response [Rack::Response]
+ # @param device_type [Symbol] A device type symbol (or string).
def set_device_type_cookie(response, device_type)
response.set_cookie('mobvious.device_type',
{ value: device_type.to_s, path: '/', expires: Time.now + @cookie_expires })
@@ -2,21 +2,38 @@
module Mobvious
module Strategies
+ # Mobvious device detection strategy that uses user-agent sniffing provided by
+ # the MobileESP library.
class Mobileesp
+ # Detection procedure that classifies mobile phones as `:mobile` and anything
+ # else as `:desktop`.
DEVICE_TYPES_MOBILE_DESKTOP = lambda {|mobileesp|
return :mobile if mobileesp.is_tier_generic_mobile || mobileesp.is_tier_iphone
return :desktop
}
+
+ # Detection procedure that classifies mobile phones as `:mobile`, tablets as
+ # `:tablet` and anything else as `:desktop`.
DEVICE_TYPES_MOBILE_TABLET_DESKTOP = lambda {|mobileesp|
return :mobile if mobileesp.is_tier_generic_mobile || mobileesp.is_tier_iphone
return :tablet if mobileesp.is_tier_tablet
return :desktop
}
+ # Creates a new instance of MobileESP strategy.
+ #
+ # @param detection_procedure
+ # A lambda function that gets one parameter (`MobileESP::UserAgentInfo` instance)
+ # and returns device type symbol or nil.
def initialize(detection_procedure = DEVICE_TYPES_MOBILE_DESKTOP)
@detection_procedure = detection_procedure
end
+ # Gets device type using user-agent sniffing. Can return nil if the used
+ # detection procedure does so.
+ #
+ # @param request [Rack::Request]
+ # @return [Symbol] device type or nil
def get_device_type(request)
mobileesp = MobileESP::UserAgentInfo.new(request.user_agent, request.accept)
@detection_procedure.call(mobileesp)
@@ -1,14 +1,24 @@
module Mobvious
module Strategies
+ # Mobvious device detection strategy that uses URL pattern matching.
class URL
- MOBILE_PATH_RULE = {
- /^\w+:\/\/m\./ => :mobile
- }
+ # Rule set with only one rule for domains that begin with `m.` matching as `:mobile`.
+ MOBILE_PATH_RULES = { /^\w+:\/\/m\./ => :mobile }
+ # Creates a new URL strategy instance.
+ #
+ # @param rules
+ # A hash containing regular expressions mapped to symbols. The regular expression
+ # is evaluated against the whole URL of the request (including `http://`). If matching,
+ # the corresponding symbol is returned as the device type.
def initialize(rules = MOBILE_PATH_RULE)
@rules = rules
end
+ # Gets device type using URL pattern matching. Returns nil if no match found.
+ #
+ # @param request [Rack::Request]
+ # @return [Symbol] device type or nil
def get_device_type(request)
@rules.each do |regex, device_type|
return device_type if request.url =~ regex
@@ -14,7 +14,7 @@ class URLSpec < MiniTest::Spec
'PATH_INFO' => '/some_path'
})
@request = Rack::Request.new(@env)
- @strategy = URL.new(URL::MOBILE_PATH_RULE)
+ @strategy = URL.new(URL::MOBILE_PATH_RULES)
end
it "returns the right device type when matching rule found" do

0 comments on commit 35e9d9b

Please sign in to comment.