jpmobile 6.1.2 → 7.1.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.
Files changed (63) hide show
  1. checksums.yaml +4 -4
  2. data/.circleci/config.yml +12 -4
  3. data/.rubocop.yml +174 -1
  4. data/.ruby-version +1 -1
  5. data/Gemfile +11 -0
  6. data/Gemfile.lock +220 -166
  7. data/README.md +27 -21
  8. data/Rakefile +1 -1
  9. data/jpmobile.gemspec +6 -13
  10. data/lib/jpmobile/datum_conv.rb +7 -7
  11. data/lib/jpmobile/docomo_guid.rb +2 -2
  12. data/lib/jpmobile/email.rb +2 -2
  13. data/lib/jpmobile/fallback_view_selector.rb +2 -2
  14. data/lib/jpmobile/filter.rb +4 -2
  15. data/lib/jpmobile/hook_action_view.rb +3 -3
  16. data/lib/jpmobile/hook_template_details_requested.rb +12 -0
  17. data/lib/jpmobile/mail.rb +3 -3
  18. data/lib/jpmobile/mailer.rb +4 -5
  19. data/lib/jpmobile/method_less_action_support.rb +11 -0
  20. data/lib/jpmobile/mobile/abstract_mobile.rb +1 -1
  21. data/lib/jpmobile/mobile/android_tablet.rb +1 -1
  22. data/lib/jpmobile/mobile/au.rb +4 -6
  23. data/lib/jpmobile/mobile/softbank.rb +3 -1
  24. data/lib/jpmobile/path_set.rb +10 -36
  25. data/lib/jpmobile/position.rb +6 -6
  26. data/lib/jpmobile/rails.rb +8 -2
  27. data/lib/jpmobile/resolver.rb +47 -6
  28. data/lib/jpmobile/template_details.rb +38 -0
  29. data/lib/jpmobile/trans_sid.rb +2 -2
  30. data/lib/jpmobile/util.rb +1 -1
  31. data/lib/jpmobile/version.rb +1 -1
  32. data/lib/jpmobile/view_selector.rb +5 -6
  33. data/lib/jpmobile.rb +13 -0
  34. data/lib/tasks/jpmobile_tasks.rake +4 -5
  35. data/renovate.json +6 -0
  36. data/spec/rack/jpmobile/mobile_by_ua_spec.rb +1 -0
  37. data/spec/rack/jpmobile/params_filter_spec.rb +6 -6
  38. data/spec/unit/decorated_mail_spec.rb +1 -1
  39. data/spec/unit/email_spec.rb +1 -1
  40. data/spec/unit/mail_spec.rb +4 -4
  41. data/spec/unit/receive_mail_spec.rb +30 -30
  42. data/spec/unit/util_spec.rb +1 -1
  43. data/test/rails/overrides/Gemfile.jpmobile +4 -0
  44. data/test/rails/overrides/app/controllers/method_less_action_support_controller.rb +3 -0
  45. data/test/rails/overrides/app/controllers/mobile_spec_controller.rb +1 -1
  46. data/test/rails/overrides/app/controllers/template_path_controller.rb +3 -0
  47. data/test/rails/overrides/app/mailers/decorated_mailer.rb +1 -1
  48. data/test/rails/overrides/app/views/method_less_action_support/index_smart_phone.html.erb +0 -0
  49. data/test/rails/overrides/app/views/mobile_spec/mobile_not_exist.html.erb +3 -0
  50. data/test/rails/overrides/config/routes.rb +5 -1
  51. data/test/rails/overrides/spec/controllers/mobile_spec_controller_spec.rb +3 -3
  52. data/test/rails/overrides/spec/rails_helper.rb +2 -2
  53. data/test/rails/overrides/spec/requests/filter_spec.rb +106 -0
  54. data/test/rails/overrides/spec/requests/method_less_action_support_spec.rb +29 -0
  55. data/test/rails/overrides/spec/requests/pc_spec.rb +3 -2
  56. data/test/rails/overrides/spec/requests/template_path_spec.rb +1 -1
  57. data/test/rails/overrides/spec/{features → system}/admin/top_spec.rb +2 -2
  58. data/test/rails/overrides/spec/{features → system}/filter_spec.rb +2 -7
  59. data/test/rails/overrides/spec/system/support/cuprite_setup.rb +12 -0
  60. data/test/rails/overrides/spec/system_helper.rb +3 -0
  61. data/test/sinatra/guestbook.rb +0 -1
  62. metadata +26 -342
  63. data/test/rails/overrides/app/views/mobile_spec/no_mobile.html.erb +0 -3
@@ -42,6 +42,8 @@ module Jpmobile
42
42
  Regexp.escape('application/xhtml+xm'),
43
43
  )
44
44
 
45
+ CONVERT_TARGET_ELEMENTS = %w[submit reset button].freeze
46
+
45
47
  class << self
46
48
  def hankaku_format(str)
47
49
  replace_chars(str, zen_to_han_table)
@@ -117,7 +119,7 @@ module Jpmobile
117
119
  doc = convert_text_content(doc)
118
120
 
119
121
  html = doc.to_html.gsub("\xc2\xa0", '&nbsp;')
120
- html = html.gsub(/charset=[a-z0-9\-]+/i, "charset=#{default_charset}") if default_charset
122
+ html = html.gsub(/charset=[a-z0-9-]+/i, "charset=#{default_charset}") if default_charset
121
123
  html
122
124
  else
123
125
  filter(:hankaku, str)
@@ -149,7 +151,7 @@ module Jpmobile
149
151
  # textarea 以外のテキストなら content を変換
150
152
  element.content = filter(:hankaku, element.content)
151
153
  end
152
- elsif (element.node_name == 'input') && %w[submit reset button].include?(element['type'])
154
+ elsif (element.node_name == 'input') && CONVERT_TARGET_ELEMENTS.include?(element['type'])
153
155
  # テキスト以外でもボタンの value は変換
154
156
  element['value'] = filter(:hankaku, element['value'])
155
157
  elsif element.children.any?
@@ -1,4 +1,4 @@
1
- #:stopdoc:
1
+ # :stopdoc:
2
2
  # helperを追加
3
3
  # ActionView で trans_sid を有効にする
4
4
  ActionView::Base.class_eval do
@@ -6,7 +6,7 @@ ActionView::Base.class_eval do
6
6
 
7
7
  delegate :default_url_options, to: :controller unless respond_to?(:default_url_options)
8
8
  end
9
- #:startdoc:
9
+ # :startdoc:
10
10
 
11
11
  # :stopdoc:
12
12
  # accept-charset に charset を変更できるようにする
@@ -19,4 +19,4 @@ module Jpmobile
19
19
  end
20
20
  end
21
21
  end
22
- #:startdoc:
22
+ # :startdoc:
@@ -0,0 +1,12 @@
1
+ module Jpmobile
2
+ module HookTemplateDetailsRequested
3
+ attr_reader :mobile, :mobile_idx
4
+
5
+ def initialize(locale:, handlers:, formats:, variants:, mobile:)
6
+ super(locale: locale, handlers: handlers, formats: formats, variants: variants)
7
+
8
+ @mobile = mobile.map(&:to_sym)
9
+ @mobile_idx = build_idx_hash(@mobile)
10
+ end
11
+ end
12
+ end
data/lib/jpmobile/mail.rb CHANGED
@@ -55,7 +55,7 @@ module Mail
55
55
 
56
56
  def parse_message_with_jpmobile
57
57
  _crlf_raw_source = raw_source.encode(raw_source.encoding, universal_newline: true).encode!(raw_source.encoding, crlf_newline: true)
58
- header_part, body_part = _crlf_raw_source.lstrip.split(/#{CRLF}#{CRLF}|#{CRLF}#{WSP}*#{CRLF}(?!#{WSP})/m, 2)
58
+ header_part, body_part = _crlf_raw_source.lstrip.split(/#{CRLF}#{CRLF}|#{CRLF}#{WSP}*#{CRLF}(?!#{WSP})/mo, 2)
59
59
  # header_part, body_part = raw_source.lstrip.split(HEADER_SEPARATOR, 2)
60
60
 
61
61
  self.header = header_part
@@ -202,7 +202,7 @@ module Mail
202
202
  end
203
203
 
204
204
  unless self.header['Content-Type'].sub_type == 'mixed'
205
- self.header['Content-Type'] = self.content_type.gsub(/#{self.header['Content-Type'].sub_type}/, 'mixed')
205
+ self.header['Content-Type'] = self.content_type.gsub(/#{self.header["Content-Type"].sub_type}/, 'mixed')
206
206
  end
207
207
  self.parts.clear
208
208
  self.body = nil
@@ -277,7 +277,7 @@ module Mail
277
277
  end
278
278
 
279
279
  def parse_message_with_jpmobile
280
- header_part, body_part = raw_source.split(/#{CRLF}#{WSP}*#{CRLF}/m, 2)
280
+ header_part, body_part = raw_source.split(/#{CRLF}#{WSP}*#{CRLF}/mo, 2)
281
281
 
282
282
  self.header = if header_part && header_part.match(HEADER_LINE)
283
283
  header_part
@@ -1,17 +1,16 @@
1
1
  require 'jpmobile/mail'
2
2
  require 'jpmobile/lookup_context'
3
3
 
4
- Jpmobile::Email.japanese_mail_address_regexp = Regexp.new(/\.jp(?:[^a-zA-Z.\-]|$)/)
4
+ Jpmobile::Email.japanese_mail_address_regexp = Regexp.new(/\.jp(?:[^a-zA-Z.-]|$)/)
5
5
 
6
6
  module Jpmobile
7
7
  module Mailer
8
8
  class Base < ActionMailer::Base
9
- self._view_paths = self._view_paths.dup
10
- self.view_paths.unshift(Jpmobile::Resolver.new(File.join(::Rails.root, 'app/views')))
9
+ self.prepend_view_path(Jpmobile::Resolver.new(File.join(::Rails.root, 'app/views')))
11
10
 
12
11
  def mail(headers = {}, &block)
13
12
  tos = headers[:to] || self.default_params[:to]
14
- tos = tos.split(/,/)
13
+ tos = tos.split(',')
15
14
 
16
15
  @mobile = if tos.size == 1
17
16
  # for mobile
@@ -37,7 +36,7 @@ module Jpmobile
37
36
  class << self
38
37
  protected
39
38
 
40
- def set_payload_for_mail(payload, mail) #:nodoc:
39
+ def set_payload_for_mail(payload, mail) # :nodoc:
41
40
  super
42
41
 
43
42
  payload[:mail] = Jpmobile::Util.ascii_8bit(mail.encoded).gsub(/\r\n/, "\n")
@@ -0,0 +1,11 @@
1
+ module Jpmobile
2
+ module MethodLessActionSupport
3
+ def template_exists?(*args, **kwargs, &block)
4
+ super(
5
+ *args,
6
+ **kwargs.reverse_merge(mobile: request.mobile&.variants || []),
7
+ &block
8
+ )
9
+ end
10
+ end
11
+ end
@@ -242,7 +242,7 @@ module Jpmobile::Mobile
242
242
  end
243
243
 
244
244
  def ip_address_class
245
- Object.const_get("::Jpmobile::Mobile::IpAddresses::#{self.to_s.split(/::/).last}").new
245
+ Object.const_get("::Jpmobile::Mobile::IpAddresses::#{self.to_s.split("::").last}").new
246
246
  rescue
247
247
  nil
248
248
  end
@@ -6,6 +6,6 @@ module Jpmobile::Mobile
6
6
  include Jpmobile::Mobile::GoogleEmoticon
7
7
 
8
8
  # 対応するUser-Agentの正規表現
9
- USER_AGENT_REGEXP = Regexp.union(/(?!Android.+Mobile)Android/, /Android.+SC-01C/)
9
+ USER_AGENT_REGEXP = Regexp.union(/^(?!.+Mobile).+(?=Android).+$/, /Android.+SC-01C/)
10
10
  end
11
11
  end
@@ -15,6 +15,8 @@ module Jpmobile::Mobile
15
15
  # GPS取得に対応していないデバイスID
16
16
  GPS_UNSUPPORTED_DEVICE_ID = %w[PT21 KC26 SN28 SN26 KC23 SA28 TS25 SA25 SA24 SN23 ST14 KC15 SN22 KC14 ST13 SN17 SY15 CA14 HI14 TS14 KC13 SN15 SN16 SY14 ST12 TS13 CA13 MA13 HI13 SN13 SY13 SN12 SN14 ST11 DN11 SY12 KCTE TST9 KCU1 SYT5 KCTD TST8 TST7 KCTC SYT4 KCTB KCTA TST6 KCT9 TST5 TST4 KCT8 SYT3 KCT7 MIT1 MAT3 KCT6 TST3 KCT5 KCT4 SYT2 MAT1 MAT2 TST2 KCT3 KCT2 KCT1 TST1 SYT1].freeze
17
17
 
18
+ TARGET_PARAMS = %w[ver datum unit lat lon alt time smaj smin vert majaa fm].freeze
19
+
18
20
  # EZ番号(サブスクライバID)があれば返す。無ければ +nil+ を返す。
19
21
  def subno
20
22
  @request.env['HTTP_X_UP_SUBNO']
@@ -27,7 +29,7 @@ module Jpmobile::Mobile
27
29
  return @__posotion = nil if params['lat'].nil? || params['lat'] == '' || params['lon'].nil? || params['lon'] == ''
28
30
 
29
31
  l = Jpmobile::Position.new
30
- l.options = params.select {|x, _| %w[ver datum unit lat lon alt time smaj smin vert majaa fm].include?(x) }
32
+ l.options = params.select {|x, _| TARGET_PARAMS.include?(x) }
31
33
  case params['unit']
32
34
  when '1'
33
35
  l.lat = params['lat'].to_f
@@ -83,11 +85,7 @@ module Jpmobile::Mobile
83
85
  'none'
84
86
  end
85
87
 
86
- if protocol.start_with?('https')
87
- false
88
- else
89
- true
90
- end
88
+ !protocol.start_with?('https')
91
89
  end
92
90
 
93
91
  # 文字コード変換
@@ -13,6 +13,8 @@ module Jpmobile::Mobile
13
13
  # テキスト部分の content-transfer-encoding
14
14
  MAIL_CONTENT_TRANSFER_ENCODING = '8bit'.freeze
15
15
 
16
+ TARGET_PARAMS = ['pos', 'geo', 'x-acr'].freeze
17
+
16
18
  # 製造番号を返す。無ければ +nil+ を返す。
17
19
  def serial_number
18
20
  @request.env['HTTP_USER_AGENT'] =~ /SN(.+?) /
@@ -36,7 +38,7 @@ module Jpmobile::Mobile
36
38
  l = Jpmobile::Position.new
37
39
  l.lat = ((Regexp.last_match(1) == 'N') ? 1 : -1) * Jpmobile::Position.dms2deg(Regexp.last_match(2), Regexp.last_match(3), Regexp.last_match(4))
38
40
  l.lon = ((Regexp.last_match(5) == 'E') ? 1 : -1) * Jpmobile::Position.dms2deg(Regexp.last_match(6), Regexp.last_match(7), Regexp.last_match(8))
39
- l.options = params.select {|x, _| ['pos', 'geo', 'x-acr'].include?(x) }
41
+ l.options = params.select {|x, _| TARGET_PARAMS.include?(x) }
40
42
 
41
43
  @__position = l
42
44
  end
@@ -1,41 +1,15 @@
1
1
  module Jpmobile
2
- class PathSet < Array
3
- %w[initialize << concat insert push unshift].each do |method|
4
- class_eval <<-METHOD, __FILE__, __LINE__ + 1
5
- def #{method}(*args)
6
- super
7
- typecast!
8
- end
9
- METHOD
10
- end
2
+ class PathSet < ActionView::PathSet
3
+ private
11
4
 
12
- def find(path, prefix = nil, partial = false, details = {}, key = nil)
13
- template = find_all(path, prefix, partial, details, key).first
14
- raise MissingTemplate.new(self, "#{prefix}/#{path}", details, partial) unless template
15
-
16
- template
17
- end
18
-
19
- def find_all(*args)
20
- each do |resolver|
21
- templates = resolver.find_all(*args)
22
- return templates unless templates.empty?
23
- end
24
- []
25
- end
26
-
27
- def exists?(*args)
28
- find_all(*args).any?
29
- end
30
-
31
- protected
32
-
33
- def typecast!
34
- each_with_index do |path, i|
35
- path = path.to_s if path.is_a?(Pathname)
36
- next unless path.is_a?(String)
37
-
38
- self[i] = Jpmobile::Resolver.new(path)
5
+ def typecast(paths)
6
+ paths.map do |path|
7
+ case path
8
+ when Pathname, String
9
+ Jpmobile::Resolver.new path.to_s
10
+ else
11
+ super(paths)
12
+ end
39
13
  end
40
14
  end
41
15
  end
@@ -10,7 +10,7 @@ end
10
10
  module Jpmobile
11
11
  # 位置情報
12
12
  class Position
13
- if Object.const_defined?('GeoKit')
13
+ if Object.const_defined?(:GeoKit)
14
14
  # GeoKitが読み込まれている場合はMappableにする
15
15
  include ::GeoKit::Mappable
16
16
  def self.acts_as_mappable
@@ -27,17 +27,17 @@ module Jpmobile
27
27
  :lng
28
28
  end
29
29
  end
30
+ # 度分秒を度に変換する。
31
+ def self.dms2deg(d, m, s)
32
+ d.to_i + (m.to_i.to_f / 60) + (s.to_f / 3600)
33
+ end
34
+
30
35
  def initialize
31
36
  @lat = nil
32
37
  @lon = nil
33
38
  @options = {}
34
39
  end
35
40
 
36
- # 度分秒を度に変換する。
37
- def self.dms2deg(d, m, s)
38
- d.to_i + m.to_i.to_f / 60 + s.to_f / 3600
39
- end
40
-
41
41
  # 日本測地系から世界測地系に変換する。
42
42
  def tokyo2wgs84!
43
43
  @lat, @lon = DatumConv.tky2jgd(@lat, @lon)
@@ -2,18 +2,24 @@ ActiveSupport.on_load(:action_controller) do
2
2
  require 'jpmobile/docomo_guid'
3
3
  require 'jpmobile/filter'
4
4
  require 'jpmobile/helpers'
5
+ require 'jpmobile/method_less_action_support'
5
6
  require 'jpmobile/trans_sid'
6
- require 'jpmobile/hook_test_request'
7
7
  ActionDispatch::Request.prepend Jpmobile::Encoding
8
8
  ActionDispatch::Request.include Jpmobile::RequestWithMobile
9
9
  ActionController::Base.prepend Jpmobile::FallbackViewSelector
10
10
  ActionController::Base.prepend Jpmobile::TransSidRedirecting
11
+
12
+ if Rails.env.test?
13
+ require 'jpmobile/hook_test_request'
14
+ end
11
15
  end
12
16
 
13
17
  ActiveSupport.on_load(:action_view) do
14
18
  require 'jpmobile/hook_action_view'
19
+ require 'jpmobile/hook_template_details_requested'
15
20
 
16
21
  self.prepend Jpmobile::HtmlOptionsWithAcceptCharset
22
+ ActionView::TemplateDetails::Requested.prepend Jpmobile::HookTemplateDetailsRequested
17
23
  end
18
24
 
19
25
  ActiveSupport.on_load(:after_initialize) do
@@ -31,7 +37,7 @@ end
31
37
 
32
38
  ActiveSupport.on_load(:before_configuration) do
33
39
  # MobileCarrierのみデフォルトで有効
34
- config.middleware.insert_after ActionDispatch::Flash, ::Jpmobile::MobileCarrier
40
+ config.middleware.insert_after ActionDispatch::Flash, Jpmobile::MobileCarrier
35
41
 
36
42
  Rails::Application::Configuration.include Jpmobile::Configuration::RailsConfiguration
37
43
  end
@@ -1,14 +1,55 @@
1
1
  module Jpmobile
2
2
  class Resolver < ::ActionView::FileSystemResolver
3
- EXTENSIONS = [:locale, :formats, :handlers, :mobile].freeze
4
- DEFAULT_PATTERN = ':prefix/:action{_:mobile,}{.:locale,}{.:formats,}{+:variants,}{.:handlers,}'.freeze
5
-
6
3
  def initialize(path)
7
- raise ArgumentError, 'path already is a Resolver class' if path.is_a?(Resolver)
4
+ super(path)
5
+
6
+ @path_parser = Jpmobile::Resolver::PathParser.new
7
+ end
8
8
 
9
+ def clear_cache
9
10
  super
10
- @pattern = DEFAULT_PATTERN
11
- @path = File.expand_path(path)
11
+
12
+ @path_parser = Jpmobile::Resolver::PathParser.new
13
+ end
14
+
15
+ class PathParser < ::ActionView::Resolver::PathParser
16
+ def build_path_regex
17
+ handlers = Regexp.union(::ActionView::Template::Handlers.extensions.map(&:to_s))
18
+ formats = Regexp.union(::ActionView::Template::Types.symbols.map(&:to_s))
19
+ available_locales = I18n.available_locales.map(&:to_s)
20
+ regular_locales = [/[a-z]{2}(?:[-_][A-Z]{2})?/]
21
+ locales = Regexp.union(available_locales + regular_locales)
22
+ variants = '[^.]*'
23
+
24
+ mobile = Jpmobile::Mobile.all_variants.map {|x| Regexp.escape(x) }.join('|')
25
+
26
+ %r{
27
+ \A
28
+ (?:(?<prefix>.*)/)?
29
+ (?<partial>_)?
30
+ (?<action>.*?)
31
+ (?:_(?<mobile>#{mobile}))??
32
+ (?:\.(?<locale>#{locales}))??
33
+ (?:\.(?<format>#{formats}))??
34
+ (?:\+(?<variant>#{variants}))??
35
+ (?:\.(?<handler>#{handlers}))?
36
+ \z
37
+ }x
38
+ end
39
+
40
+ def parse(path)
41
+ @regex ||= build_path_regex
42
+ match = @regex.match(path)
43
+ path = ActionView::TemplatePath.build(match[:action], match[:prefix] || '', !!match[:partial])
44
+ details = Jpmobile::TemplateDetails.new(
45
+ match[:locale]&.to_sym,
46
+ match[:handler]&.to_sym,
47
+ match[:format]&.to_sym,
48
+ match[:variant]&.to_sym,
49
+ match[:mobile]&.to_sym,
50
+ )
51
+ ParsedPath.new(path, details)
52
+ end
12
53
  end
13
54
  end
14
55
  end
@@ -0,0 +1,38 @@
1
+ module Jpmobile
2
+ class TemplateDetails < ActionView::TemplateDetails
3
+ def initialize(locale, handler, format, variant, mobile)
4
+ @mobile = mobile
5
+
6
+ super(locale, handler, format, variant)
7
+ end
8
+
9
+ def matches?(requested)
10
+ requested.formats_idx[@format] &&
11
+ requested.locale_idx[@locale] &&
12
+ requested.variants_idx[@variant] &&
13
+ requested.handlers_idx[@handler] &&
14
+ requested.mobile_idx[@mobile]
15
+ end
16
+
17
+ def sort_key_for(requested)
18
+ [
19
+ requested.formats_idx[@format],
20
+ requested.locale_idx[@locale],
21
+ requested.variants_idx[@variant],
22
+ requested.mobile_idx[@mobile],
23
+ requested.handlers_idx[@handler],
24
+ ]
25
+ end
26
+
27
+ class Requested < ActionView::TemplateDetails::Requested
28
+ attr_reader :mobile, :mobile_idx
29
+
30
+ def initialize(locale:, handlers:, formats:, variants:, mobile:)
31
+ super(locale: locale, handlers: handlers, formats: formats, variants: variants)
32
+
33
+ @mobile = mobile.map(&:to_sym)
34
+ @mobile_idx = build_idx_hash(mobile)
35
+ end
36
+ end
37
+ end
38
+ end
@@ -66,7 +66,7 @@ module Jpmobile
66
66
 
67
67
  module TransSidRedirecting
68
68
  def redirect_to(options = {}, response_status = {})
69
- if apply_trans_sid? && jpmobile_session_id && options != :back && options !~ /^\w[\w+.-]*:.*/
69
+ if apply_trans_sid? && jpmobile_session_id
70
70
  case options
71
71
  when String
72
72
  unless options.match?(/#{session_key}/)
@@ -91,7 +91,7 @@ module Jpmobile
91
91
  end
92
92
 
93
93
  module ActionController
94
- class Metal #:nodoc:
94
+ class Metal # :nodoc:
95
95
  class_attribute :trans_sid_mode
96
96
 
97
97
  class << self
data/lib/jpmobile/util.rb CHANGED
@@ -291,7 +291,7 @@ module Jpmobile
291
291
  def split_text(str, size = 15)
292
292
  return nil if str.nil? || (str == '')
293
293
 
294
- [str[0..(size - 1)], str[size..-1]]
294
+ [str[0..(size - 1)], str[size..]]
295
295
  end
296
296
 
297
297
  def invert_table(hash)
@@ -1,3 +1,3 @@
1
1
  module Jpmobile
2
- VERSION = '6.1.2'.freeze
2
+ VERSION = '7.1.0'.freeze
3
3
  end
@@ -1,12 +1,11 @@
1
1
  module Jpmobile
2
2
  module ViewSelector
3
- def self.included(base)
4
- base.class_eval do
5
- before_action :register_mobile
3
+ extend ActiveSupport::Concern
6
4
 
7
- self._view_paths = self._view_paths.dup
8
- self.view_paths.unshift(*self.view_paths.map {|resolver| Jpmobile::Resolver.new(resolver.to_path) })
9
- end
5
+ included do
6
+ before_action :register_mobile
7
+
8
+ self.view_paths = Jpmobile::PathSet.new(self.view_paths.paths.map(&:path))
10
9
  end
11
10
 
12
11
  def register_mobile
data/lib/jpmobile.rb CHANGED
@@ -48,9 +48,19 @@ module Jpmobile
48
48
  end
49
49
 
50
50
  def self.carriers=(ary)
51
+ @all_variants = nil
52
+
51
53
  @carriers = ary
52
54
  end
53
55
 
56
+ def self.all_variants
57
+ return @all_variants if @all_variants
58
+
59
+ @all_variants = carriers.map {|carrier|
60
+ Jpmobile::Mobile.const_get(carrier).new({}, {}).variants
61
+ }.flatten.uniq
62
+ end
63
+
54
64
  require 'jpmobile/mobile/abstract_mobile'
55
65
  end
56
66
 
@@ -63,6 +73,9 @@ module Jpmobile
63
73
  autoload :Mailer, 'jpmobile/mailer'
64
74
  autoload :Resolver, 'jpmobile/resolver'
65
75
 
76
+ autoload :PathSet, 'jpmobile/path_set'
77
+ autoload :TemplateDetails, 'jpmobile/template_details'
78
+
66
79
  autoload :ViewSelector, 'jpmobile/view_selector'
67
80
  autoload :FallbackViewSelector, 'jpmobile/fallback_view_selector'
68
81
 
@@ -84,12 +84,10 @@ namespace :test do
84
84
  unless skip
85
85
  # for cookie_only option
86
86
  config_path = File.join(rails_root, 'config', 'initializers', 'session_store.rb')
87
- File.open(config_path, 'w') do |file|
88
- file.write <<-SESSION_CONFIG
87
+ File.write(config_path, <<-SESSION_CONFIG)
89
88
  Rails.application.config.session_store :active_record_store, :key => '_session_id'
90
89
  Rails.application.config.session_options = { :cookie_only => false }
91
- SESSION_CONFIG
92
- end
90
+ SESSION_CONFIG
93
91
  end
94
92
 
95
93
  unless skip
@@ -112,12 +110,13 @@ namespace :test do
112
110
 
113
111
  system 'bundle install'
114
112
  system 'bin/rails db:migrate RAILS_ENV=test' unless skip
115
- system 'bin/rails spec'
113
+ system 'bin/rails spec', exception: true
116
114
 
117
115
  ENV.replace(original_env)
118
116
  end
119
117
  end
120
118
  end
119
+
121
120
  desc 'Run sinatra on jpmobile tests'
122
121
  Rake::TestTask.new(:sinatra) do |t|
123
122
  t.libs << 'lib'
data/renovate.json ADDED
@@ -0,0 +1,6 @@
1
+ {
2
+ "$schema": "https://docs.renovatebot.com/renovate-schema.json",
3
+ "extends": [
4
+ "config:base"
5
+ ]
6
+ }
@@ -17,6 +17,7 @@ describe Jpmobile::MobileCarrier do
17
17
  [Jpmobile::Mobile::Emobile, 'emobile/1.0.0 (H11T; like Gecko; Wireless) NetFront/3.4'],
18
18
  [Jpmobile::Mobile::Iphone, 'Mozilla/5.0 (iPhone; U; CPU iPhone OS 3_0 like Mac OS X; ja-jp) AppleWebKit/528.18 (KHTML, like Gecko) Version/4.0 Mobile/7A341 Safari/528.16'],
19
19
  [Jpmobile::Mobile::Android, 'Mozilla/5.0 (Linux; U; Android 1.6; ja-jp; SonyEriccsonSO-01B Build/R1EA018) AppleWebKit/528.5+ (KHTML, like Gecko) Version/3.1.2 Mobile Safari/525.20.1'],
20
+ [Jpmobile::Mobile::Android, 'Mozilla/5.0 (Linux; Android 9; ANE-LX2J Build/HUAWEIANE-LX2J; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/88.0.4324.93 Mobile Safari/537.36 Instagram 172.0.0.21.123 Android (28/9; 480dpi; 1080x2060; HUAWEI; ANE-LX2J; HWANE; hi6250; ja_JP; 269790805)'],
20
21
  [Jpmobile::Mobile::WindowsPhone, 'Mozilla/4.0 (Compatible; MSIE 6.0; Windows NT 5.1 T-01A_6.5; Windows Phone 6.5)'],
21
22
  [Jpmobile::Mobile::BlackBerry, 'BlackBerry9000/4.6.0.224 Profile/MIDP-2.0 Configuration/CLDC-1.1 VendorID/220'],
22
23
  [Jpmobile::Mobile::Ipad, 'Mozilla/5.0 (iPad; U; CPU OS 4_3 like Mac OS X; ja-jp) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8F191 Safari/6533.18.5'],
@@ -20,7 +20,7 @@ describe Jpmobile::ParamsFilter do
20
20
  context 'Shift_JIS 変換の ' do
21
21
  before(:each) do
22
22
  @query_string = @query_params.map {|k, v|
23
- '%s=%s' % [::Rack::Utils.escape(utf8_to_sjis(k)), ::Rack::Utils.escape(utf8_to_sjis(v))]
23
+ '%s=%s' % [Rack::Utils.escape(utf8_to_sjis(k)), Rack::Utils.escape(utf8_to_sjis(v))]
24
24
  }.join('&')
25
25
  @form_string = @form_params.map {|k, v|
26
26
  '%s=%s' % [utf8_to_sjis(k), utf8_to_sjis(v)]
@@ -75,7 +75,7 @@ describe Jpmobile::ParamsFilter do
75
75
  context 'UTF-8 の' do
76
76
  before(:each) do
77
77
  @query_string = @query_params.map {|k, v|
78
- '%s=%s' % [::Rack::Utils.escape(k), ::Rack::Utils.escape(v)]
78
+ '%s=%s' % [Rack::Utils.escape(k), Rack::Utils.escape(v)]
79
79
  }.join('&')
80
80
  @form_string = @form_params.map {|k, v|
81
81
  '%s=%s' % [k, v]
@@ -109,7 +109,7 @@ describe Jpmobile::ParamsFilter do
109
109
  context '絵文字変換' do
110
110
  context 'docomo の場合' do
111
111
  it 'Shift_JIS 絵文字がUTF-8に変換されること' do
112
- query_string = 'hoge=' + ::Rack::Utils.escape(sjis("\xf8\x9f"))
112
+ query_string = 'hoge=' + Rack::Utils.escape(sjis("\xf8\x9f"))
113
113
  form_string = 'foo=' + sjis("\xf8\xa1")
114
114
 
115
115
  res = Rack::MockRequest.env_for(
@@ -131,7 +131,7 @@ describe Jpmobile::ParamsFilter do
131
131
 
132
132
  context 'au の場合' do
133
133
  it 'Shift_JIS 絵文字がUTF-8に変換されること' do
134
- query_string = 'hoge=' + ::Rack::Utils.escape(sjis("\xf6\x59"))
134
+ query_string = 'hoge=' + Rack::Utils.escape(sjis("\xf6\x59"))
135
135
  form_string = 'foo=' + sjis("\xf6\xfb")
136
136
 
137
137
  res = Rack::MockRequest.env_for(
@@ -153,7 +153,7 @@ describe Jpmobile::ParamsFilter do
153
153
 
154
154
  context 'Softbank の場合' do
155
155
  it 'UTF-8 絵文字がUTF-8に変換されること' do
156
- query_string = ascii_8bit('hoge=' + ::Rack::Utils.escape([0xe001].pack('U')))
156
+ query_string = ascii_8bit('hoge=' + Rack::Utils.escape([0xe001].pack('U')))
157
157
  form_string = ascii_8bit('foo=' + [0xe21c].pack('U'))
158
158
 
159
159
  res = Rack::MockRequest.env_for(
@@ -178,7 +178,7 @@ describe Jpmobile::ParamsFilter do
178
178
  context '値として' do
179
179
  it '+ が入ってるものが正確に取得できること(token)' do
180
180
  token = 'lm/3Pu6RrY+kp8hsnEWp2xygYLInZIxwsB3UWeksaHQ='
181
- form_string = ascii_8bit("foo=#{::Rack::Utils.escape(token)}")
181
+ form_string = ascii_8bit("foo=#{Rack::Utils.escape(token)}")
182
182
 
183
183
  res = Rack::MockRequest.env_for(
184
184
  '/',
@@ -14,7 +14,7 @@ describe 'decorated mails' do
14
14
  @mail.from = 'ちはやふる <info@jpmobile-rails.org>'
15
15
  @mail.to = 'むすめふさほせ <info+to@jpmobile-rails.org>'
16
16
 
17
- @photo = File.open(File.join(__dir__, 'email-fixtures/photo.jpg')).read
17
+ @photo = File.read(File.join(__dir__, 'email-fixtures/photo.jpg'))
18
18
  @mail.attachments.inline['photo.jpg'] = @photo
19
19
  @inline_url = @mail.attachments['photo.jpg'].url
20
20
  end
@@ -56,7 +56,7 @@ describe 'Jpmobile::Email' do
56
56
 
57
57
  describe 'japanese_mail_address_regexp' do
58
58
  before do
59
- Jpmobile::Email.japanese_mail_address_regexp = Regexp.new(/\.jp(?:[^a-zA-Z.\-]|$)/)
59
+ Jpmobile::Email.japanese_mail_address_regexp = Regexp.new(/\.jp(?:[^a-zA-Z.-]|$)/)
60
60
  end
61
61
 
62
62
  it '#detect_from_mail_header should return Jpmobile::Mobile::AbstractMobile when the header contains .jp address' do
@@ -285,7 +285,7 @@ describe 'Jpmobile::Mail' do
285
285
  @mobile = Jpmobile::Mobile::AbstractMobile.new(nil, nil)
286
286
  @mail.mobile = @mobile
287
287
  @mail.to = 'むすめふさほせ <info+to@jpmobile-rails.org>'
288
- @photo = File.open(File.join(__dir__, 'email-fixtures/photo.jpg')).read
288
+ @photo = File.read(File.join(__dir__, 'email-fixtures/photo.jpg'))
289
289
  end
290
290
 
291
291
  it 'should encodes itself successfully' do
@@ -318,7 +318,7 @@ describe 'Jpmobile::Mail' do
318
318
  @mobile = Jpmobile::Mobile::AbstractMobile.new(nil, nil)
319
319
  @mail.mobile = @mobile
320
320
  @mail.to = 'むすめふさほせ <info+to@jpmobile-rails.org>'
321
- @photo = File.open(File.join(__dir__, 'email-fixtures/photo.jpg')).read
321
+ @photo = File.read(File.join(__dir__, 'email-fixtures/photo.jpg'))
322
322
  end
323
323
 
324
324
  it 'wave dash converting correctly' do
@@ -345,8 +345,8 @@ describe 'Jpmobile::Mail' do
345
345
  @mail.delivery_method :smtp,
346
346
  {
347
347
  enable_starttls_auto: false,
348
- user_name: ENV['MAILTRAP_USERNAME'],
349
- password: ENV['MAILTRAP_PASSWORD'],
348
+ user_name: ENV.fetch('MAILTRAP_USERNAME', nil),
349
+ password: ENV.fetch('MAILTRAP_PASSWORD', nil),
350
350
  address: 'smtp.mailtrap.io',
351
351
  domain: 'smtp.mailtrap.io',
352
352
  port: '2525',