Module: Browser::FormData::Converter

Included in:
Browser::FormData
Defined in:
opal/browser/form_data.rb

Instance Method Summary collapse

Instance Method Details

#build_form_data(hash) ⇒ FormData

Convert a query Hash to a FormData instance

Returns:

  • (FormData)

    the instance of FormData


115
116
117
118
119
# File 'opal/browser/form_data.rb', line 115

def build_form_data(hash)
  fd = FormData.create
  flatten(hash).each { |k,v| fd << [k,v] }
  fd
end

#build_query(hash, sep = ?&) ⇒ String

Convert a query Hash to a query string

Returns:

  • (String)

    the string encoded as URI


108
109
110
# File 'opal/browser/form_data.rb', line 108

def build_query(hash, sep=?&)
  flatten(hash).map { |k,v| encode(k) + ?= + encode(v.to_s) }.join(sep)
end

#contain_files?(hash) ⇒ Boolean

Checks if a query Hash contains any files.

Returns:

  • (Boolean)

101
102
103
# File 'opal/browser/form_data.rb', line 101

def contain_files?(hash)
  flatten(hash).any? { |k,v| [File, Blob].include?(v.class) }
end

#decode(string) ⇒ String

Decode as URI component.

Returns:

  • (String)

    the string decoded as URI component


17
18
19
# File 'opal/browser/form_data.rb', line 17

def decode(string)
  `decodeURIComponent(#{string})`
end

#decode_uri(string) ⇒ String

Decode as URI.

Returns:

  • (String)

    the string decoded as URI


31
32
33
# File 'opal/browser/form_data.rb', line 31

def decode_uri(string)
  `decodeURI(#{string})`
end

#encode(string) ⇒ String

Encode as URI component.

Returns:

  • (String)

    the string encoded for usage as URI component


10
11
12
# File 'opal/browser/form_data.rb', line 10

def encode(string)
  `encodeURIComponent(#{string})`
end

#encode_uri(string) ⇒ String

Encode as URI.

Returns:

  • (String)

    the string encoded as URI


24
25
26
# File 'opal/browser/form_data.rb', line 24

def encode_uri(string)
  `encodeURI(#{string})`
end

#flatten(value, key = "") ⇒ Object

Flattens a hash to build a flat array, later to be formatted to produce a nested query.

This code should be compatible with what Rack::Utils#build_nested_query [1] does.

[1] https://github.com/rack/rack/blob/master/lib/rack/utils.rb


42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# File 'opal/browser/form_data.rb', line 42

def flatten(value, key="")
  case value
  when Hash
    out = []
    value.each do |k,v|
      k = "#{key}[#{k}]" if key != ''
      out += flatten(v,k)
    end
    out
  when Array
    out = []
    value.each do |v|
      k = "#{key}[]"
      out += flatten(v,k)
    end
    out
  else
    [[key,value]]
  end
end

#from_native(n) ⇒ String, ...

Converts a JS native value to a wrapped one if possible.

Returns:


131
132
133
134
135
136
137
138
139
140
141
142
# File 'opal/browser/form_data.rb', line 131

def from_native(n)
  %x{
    var c = #{n}.constructor;
    if (c === File) {
      #{n = File.new(n)}
    }
    else if (c === Blob) {
      #{n = Blob.new(n)}
    }
  }
  n
end

#parse_query(string, sep = ?&) ⇒ Hash

Convert a query string to a query Hash

Returns:

  • (Hash)

    the query hash


124
125
126
# File 'opal/browser/form_data.rb', line 124

def parse_query(string, sep=?&)
  unflatten(string.split(sep).map { |s| s.split(?=).map(&method(:decode)) })
end

#unflatten(array) ⇒ Object

Converts a flat array to a Hash.

This code should be compatible with what Rack::Utils#parse_nested_query [1] does.

[1] https://github.com/rack/rack/blob/master/lib/rack/utils.rb


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
# File 'opal/browser/form_data.rb', line 69

def unflatten(array)
  out = {}
  array.each do |k,v|
    path = [k.split("[").first] + k.scan(/\[(.*?)\]/).flatten
    c = out

    set = proc { |v,weak| } # Do nothing for the first level

    path.each do |i|
      case i
      when "" # Array
        set.([], true)
        set = proc do |v,weak|
          c << v
          c = c.last
        end
      else # Hash
        set.({}, true)
        set = proc do |v,weak|
          c[i] ||= v
          c[i] = v if !weak
          c = c[i]
        end
      end
    end
    set.(v, false)

  end
  out
end