File: mobile-fu.rb

package info (click to toggle)
ruby-mobile-fu 1.4.0%2Bgithub-6
  • links: PTS, VCS
  • area: main
  • in suites: experimental
  • size: 168 kB
  • sloc: ruby: 206; makefile: 2
file content (203 lines) | stat: -rw-r--r-- 6,706 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
require 'mobile-fu/tablet'
require 'rails'
require 'rack/mobile-detect'

module MobileFu
  autoload :Helper, 'mobile-fu/helper'

  class Railtie < Rails::Railtie
    initializer "mobile-fu.configure" do |app|
      app.config.middleware.use Rack::MobileDetect
    end

    if Rails::VERSION::MAJOR >= 3
      initializer "mobile-fu.action_controller" do |app|
        ActiveSupport.on_load :action_controller do
          include ActionController::MobileFu
        end
      end

      initializer "mobile-fu.action_view" do |app|
        ActiveSupport.on_load :action_view do
          include MobileFu::Helper
          alias_method :stylesheet_link_tag_without_mobilization, :stylesheet_link_tag
          alias_method :stylesheet_link_tag, :stylesheet_link_tag_with_mobilization
        end
      end
    end

    Mime::Type.register_alias "text/html", :mobile
    Mime::Type.register_alias "text/html", :tablet
  end
end

module ActionController
  module MobileFu

    def self.included(base)
      base.extend ClassMethods
    end

    module ClassMethods

      # Add this to one of your controllers to use MobileFu.
      #
      #    class ApplicationController < ActionController::Base
      #      has_mobile_fu
      #    end
      #
      # If you don't want mobile_fu to set the request format automatically,
      # you can pass false here.
      #
      #    class ApplicationController < ActionController::Base
      #      has_mobile_fu false
      #    end
      #
      def has_mobile_fu(set_request_format = true)
        include ActionController::MobileFu::InstanceMethods

        before_action :set_request_format if set_request_format

        helper_method :is_mobile_device?
        helper_method :is_tablet_device?
        helper_method :in_mobile_view?
        helper_method :in_tablet_view?
        helper_method :is_device?
        helper_method :mobile_device
      end

      # Add this to your controllers to prevent the mobile format from being set for specific actions
      #   class AwesomeController < ApplicationController
      #     has_no_mobile_fu_for :index
      #
      #     def index
      #       # Mobile format will not be set, even if user is on a mobile device
      #     end
      #
      #     def show
      #       # Mobile format will be set as normal here if user is on a mobile device
      #     end
      #   end
      def has_no_mobile_fu_for(*actions)
        @mobile_exempt_actions = actions
      end

      # Add this to your controllers to only let those actions use the mobile format
      # this method has priority over the #has_no_mobile_fu_for
      #   class AwesomeController < ApplicationController
      #     has_mobile_fu_for :index
      #
      #     def index
      #       # Mobile format will be set as normal here if user is on a mobile device
      #     end
      #
      #     def show
      #       # Mobile format will not be set, even if user is on a mobile device
      #     end
      #   end
      def has_mobile_fu_for(*actions)
        @mobile_include_actions = actions
      end
    end

    module InstanceMethods
      def set_request_format(force_mobile = false)
        force_mobile ? force_mobile_format : set_mobile_format
      end
      alias :set_device_type :set_request_format

      # Forces the request format to be :mobile
      def force_mobile_format
        unless request.xhr?
          request.format = :mobile
          session[:mobile_view] = true if session[:mobile_view].nil?
        end
      end

      # Forces the request format to be :tablet
      def force_tablet_format
        unless request.xhr?
          request.format = :tablet
          session[:tablet_view] = true if session[:tablet_view].nil?
        end
      end

      # Determines the request format based on whether the device is mobile or if
      # the user has opted to use either the 'Standard' view or 'Mobile' view or
      # 'Tablet' view.

      def set_mobile_format
        return unless request.format
        if request.format.html? && mobile_action? && is_mobile_device? && !request.xhr?
          request.format = :mobile unless session[:mobile_view] == false
          session[:mobile_view] = true if session[:mobile_view].nil?
        elsif request.format.html? && mobile_action? && is_tablet_device? && !request.xhr?
          request.format = :tablet unless session[:tablet_view] == false
          session[:tablet_view] = true if session[:tablet_view].nil?
        end
      end

      # Returns either true or false depending on whether or not the format of the
      # request is either :mobile or not.

      def in_mobile_view?
        return false unless request.format
        request.format.to_sym == :mobile
      end

      # Returns either true or false depending on whether or not the format of the
      # request is either :tablet or not.

      def in_tablet_view?
        return false unless request.format
        request.format.to_sym == :tablet
      end

      # Returns either true or false depending on whether or not the user agent of
      # the device making the request is matched to a device in our regex.

      def is_tablet_device?
        ::MobileFu::Tablet.is_a_tablet_device? request.user_agent
      end

      def is_mobile_device?
        !is_tablet_device? && !!mobile_device
      end

      def mobile_device
        request.headers['X_MOBILE_DEVICE']
      end

      # Can check for a specific user agent
      # e.g., is_device?('iphone') or is_device?('mobileexplorer')

      def is_device?(type)
        request.user_agent.to_s.downcase.include? type.to_s.downcase
      end

      # Returns true if current action is supposed to use mobile format
      # See #has_mobile_fu_for
      def mobile_action?
        if self.class.instance_variable_get("@mobile_include_actions").nil? #Now we know we dont have any includes, maybe excludes?
          return !mobile_exempt?
        else
          self.class.instance_variable_get("@mobile_include_actions").try(:include?, params[:action].try(:to_sym))
        end
      end

      # Returns true if current action isn't supposed to use mobile format
      # See #has_no_mobile_fu_for

      def mobile_exempt?
        self.class.instance_variable_get("@mobile_exempt_actions").try(:include?, params[:action].try(:to_sym))
      end
    end
  end
end

if Rails::VERSION::MAJOR < 3
  ActionController::Base.send :include, ActionController::MobileFu
  ActionView::Base.send :include, MobileFu::Helper
  ActionView::Base.send :alias_method, :stylesheet_link_tag_without_mobilization, :stylesheet_link_tag
  ActionView::Base.send :alias_method, :stylesheet_link_tag, :stylesheet_link_tag_with_mobilization
end