class Jpmobile::HankakuFilter

Constants

ALLOWED_CONTENT_TYPE_REGEXP

Public Class Methods

hankaku_format(str) click to toggle source
# File lib/jpmobile/filter.rb, line 46
def hankaku_format(str)
  replace_chars(str, zen_to_han_table)
end
new(options = {}) click to toggle source
# File lib/jpmobile/filter.rb, line 66
def initialize(options = {})
  @options = {
    input: false,
  }.merge(options)

  @controller = nil
end
zenkaku_format(str) click to toggle source
# File lib/jpmobile/filter.rb, line 50
def zenkaku_format(str)
  replace_chars(str, han_to_zen_table)
end

Private Class Methods

han_to_zen_table() click to toggle source
# File lib/jpmobile/filter.rb, line 61
def han_to_zen_table
  @han_to_zen_table ||= zen_to_han_table.invert
end
replace_chars(str, table) click to toggle source
# File lib/jpmobile/filter.rb, line 56
def replace_chars(str, table)
  @regexp_cache ||= {}.compare_by_identity
  str.gsub(@regexp_cache[table] ||= Regexp.union(table.keys), table)
end

Public Instance Methods

after(controller) click to toggle source

内部コードから外部コードに変換

# File lib/jpmobile/filter.rb, line 83
def after(controller)
  @controller = controller
  if apply_outgoing? && @controller.response.body.is_a?(String)
    @controller.response.body = to_external(@controller.response.body)
  end
end
before(controller) click to toggle source
# File lib/jpmobile/filter.rb, line 74
def before(controller)
  @controller = controller

  if apply_incoming?
    @controller.params = convert_parameters(@controller.params.dup)
  end
end

Private Instance Methods

apply_incoming?() click to toggle source

入出力フィルタの適用条件

# File lib/jpmobile/filter.rb, line 93
def apply_incoming?
  @controller.request.mobile?
end
apply_outgoing?() click to toggle source
# File lib/jpmobile/filter.rb, line 97
def apply_outgoing?
  @controller.request.mobile? &&
    @controller.response.content_type&.match?(ALLOWED_CONTENT_TYPE_REGEXP)
end
convert_parameters(params) click to toggle source
# File lib/jpmobile/filter.rb, line 171
def convert_parameters(params)
  return to_internal(params) unless params.respond_to?(:each)

  case params
  when Array
    params.map do |v|
      if v.respond_to?(:each)
        convert_parameters(v)
      else
        to_internal(v)
      end
    end
  else
    params.each do |k, v|
      params[k] =
        if v.respond_to?(:each)
          convert_parameters(v)
        else
          to_internal(v)
        end
    end
  end
end
convert_text_content(document) click to toggle source

再帰的に探す

# File lib/jpmobile/filter.rb, line 145
def convert_text_content(document)
  document.children.each do |element|
    if element.is_a?(Nokogiri::XML::Text)
      unless element.parent.node_name == 'textarea'
        # textarea 以外のテキストなら content を変換
        element.content = filter(:hankaku, element.content)
      end
    elsif (element.node_name == 'input') && %w[submit reset button].include?(element['type'])
      # テキスト以外でもボタンの value は変換
      element['value'] = filter(:hankaku, element['value'])
    elsif element.children.any?
      # 子要素があれば再帰的に変換
      element = convert_text_content(element)
    end
    element
  end

  document
end
default_charset() click to toggle source
# File lib/jpmobile/filter.rb, line 165
def default_charset
  if @controller.request.mobile?
    @controller.request.mobile.default_charset
  end
end
filter(method, str) click to toggle source
# File lib/jpmobile/filter.rb, line 127
def filter(method, str)
  str = str.dup

  # 一度UTF-8に変換
  before_encoding = str.encoding
  str.force_encoding('UTF-8')

  str = self.class.send("#{method}_format", str)

  # 元に戻す
  if before_encoding
    str.force_encoding(before_encoding)
  end

  str
end
to_external(str) click to toggle source
# File lib/jpmobile/filter.rb, line 106
def to_external(str)
  if @options[:input]
    encoding = (str =~ /^\s*<[^Hh>]*html/)
    nokogiri_klass =
      (str =~ /^\s*<[^Hh>]*html/) ? Nokogiri::HTML::Document : Nokogiri::HTML::DocumentFragment
    doc = if encoding
            nokogiri_klass.parse(str, nil, 'UTF-8')
          else
            nokogiri_klass.parse(str)
          end

    doc = convert_text_content(doc)

    html = doc.to_html.gsub("\xc2\xa0", '&nbsp;')
    html = html.gsub(/charset=[a-z0-9\-]+/i, "charset=#{default_charset}") if default_charset
    html
  else
    filter(:hankaku, str)
  end
end
to_internal(str) click to toggle source
# File lib/jpmobile/filter.rb, line 102
def to_internal(str)
  filter(:zenkaku, str)
end