Skip to content

Commit c869443

Browse files
authored
Merge pull request #95 from opal/staging
Refactor the cookie module
2 parents 0bfb495 + bf5e9e6 commit c869443

File tree

3 files changed

+70
-33
lines changed

3 files changed

+70
-33
lines changed

CHANGELOG.md

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
## 0.3.2
2+
* Cookie: refactor the module
3+
* Note in documentation it's available as `$document.cookies` and it's the preferred way to access it
4+
* Always encode a cookie with JSON, unless a new parameter `raw:` is provided
5+
6+
## 0.3.1
7+
* Element#inner_dom: Reduce flickering - first build tree, then insert it
8+
* NodeSet#to_a to be aliased to #to_ary

opal/browser/cookies.rb

+61-32
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
require 'stringio'
2-
31
module Browser
42

53
# Allows manipulation of browser cookies.
@@ -8,10 +6,19 @@ module Browser
86
#
97
# Usage:
108
#
11-
# cookies = Browser::Cookies.new(`document`)
9+
# cookies = $document.cookies
1210
# cookies["my-cookie"] = "monster"
1311
# cookies.delete("my-cookie")
1412
#
13+
# By default, cookies are stored JSON-encoded. You can supply a `raw:` option
14+
# whenever you need to access/write the cookies in a raw way, eg.
15+
#
16+
# cookies["my-other-cookie", raw: true] = 123
17+
#
18+
# You can also set this option while referencing $document.cookies, eg.
19+
#
20+
# cookies = $document.cookies(raw: true)
21+
# cookies["my-other-cookie"] = 123
1522
class Cookies
1623
# Default cookie options.
1724
DEFAULT = {
@@ -26,24 +33,34 @@ class Cookies
2633
# Create a new {Cookies} wrapper.
2734
#
2835
# @param document [native] the native document object
29-
def initialize(document)
36+
# @param options [Hash] the default cookie options
37+
def initialize(document, options = {})
3038
@document = document
31-
@options = DEFAULT.dup
39+
@options = DEFAULT.merge(options)
3240
end
3341

3442
# Access the cookie with the given name.
3543
#
3644
# @param name [String] the name of the cookie
45+
# @param options [Hash] the options for the cookie
46+
#
47+
# @option options [Boolean] :raw get a raw cookie value, don't encode it with JSON
3748
#
3849
# @return [Object]
39-
def [](name)
50+
def [](name, options = {})
51+
options = @options.merge(options)
52+
4053
matches = `#@document.cookie`.scan(/#{Regexp.escape(FormData.encode(name))}=([^;]*)/)
4154

4255
return if matches.empty?
4356

44-
result = matches.flatten.map {|value|
45-
JSON.parse(FormData.decode(value))
46-
}
57+
result = matches.flatten.map do |value|
58+
if options[:raw]
59+
FormData.decode(value)
60+
else
61+
JSON.parse(FormData.decode(value))
62+
end
63+
end
4764

4865
result.length == 1 ? result.first : result
4966
end
@@ -54,70 +71,82 @@ def [](name)
5471
# @param value [Object] the data to set
5572
# @param options [Hash] the options for the cookie
5673
#
74+
# @option options [Boolean] :raw don't encode a value with JSON
5775
# @option options [Integer] :max_age the max age of the cookie in seconds
5876
# @option options [Time] :expires the expire date
5977
# @option options [String] :path the path the cookie is valid on
6078
# @option options [String] :domain the domain the cookie is valid on
6179
# @option options [Boolean] :secure whether the cookie is secure or not
62-
def []=(name, value, options = {})
63-
string = value.is_a?(String) ? value : JSON.dump(value)
64-
encoded_value = encode(name, string, @options.merge(options))
80+
def []=(name, options = {}, value)
81+
options = @options.merge(options)
82+
if options[:raw]
83+
string = value.to_s
84+
else
85+
string = JSON.dump(value)
86+
end
87+
encoded_value = encode(name, string, options)
6588
`#@document.cookie = #{encoded_value}`
6689
end
6790

6891
# Delete a cookie.
6992
#
7093
# @param name [String] the name of the cookie
71-
def delete(name)
94+
def delete(name, _options = {})
7295
`#@document.cookie = #{encode name, '', expires: Time.now}`
7396
end
7497

7598
# @!attribute [r] keys
7699
# @return [Array<String>] all the cookie names
77-
def keys
78-
Array(`#@document.cookie.split(/; /)`).map {|cookie|
100+
def keys(_options = {})
101+
Array(`#@document.cookie.split(/; /)`).map do |cookie|
79102
cookie.split(/\s*=\s*/).first
80-
}
103+
end
81104
end
82105

83106
# @!attribute [r] values
84107
# @return [Array] all the cookie values
85-
def values
86-
keys.map {|key|
87-
self[key]
88-
}
108+
def values(options = {})
109+
options = @options.merge(options)
110+
keys.map do |key|
111+
self[key, options]
112+
end
89113
end
90114

91115
# Enumerate the cookies.
92116
#
93117
# @yieldparam key [String] the name of the cookie
94118
# @yieldparam value [String] the value of the cookie
95119
#
120+
# @param options [Hash] the options for the cookie
121+
#
122+
# @option options [Boolean] :raw don't encode a value with JSON
123+
#
96124
# @return [self]
97-
def each(&block)
98-
return enum_for :each unless block
125+
def each(options = {}, &block)
126+
return enum_for :each, options unless block
127+
options = @options.merge(options)
99128

100-
keys.each {|key|
101-
yield key, self[key]
102-
}
129+
keys.each do |key|
130+
yield key, self[key, options]
131+
end
103132

104133
self
105134
end
106135

107136
# Delete all the cookies
108137
#
109138
# @return [self]
110-
def clear
111-
keys.each {|key|
139+
def clear(_options = {})
140+
keys.each do |key|
112141
delete key
113-
}
142+
end
114143

115144
self
116145
end
117146

118147
protected
119148
def encode(key, value, options = {})
120-
io = StringIO.new
149+
io = []
121150

122151
io << FormData.encode(key) << ?= << FormData.encode(value) << '; '
123152

@@ -127,15 +156,15 @@ def encode(key, value, options = {})
127156
io << 'domain=' << options[:domain] << '; ' if options[:domain]
128157
io << 'secure' if options[:secure]
129158

130-
io.string
159+
io.join
131160
end
132161
end
133162

134163
class DOM::Document < DOM::Element
135164
# @!attribute [r] cookies
136165
# @return [Cookies] the cookies for the document
137-
def cookies
138-
Cookies.new(@native) if defined?(`#@native.cookie`)
166+
def cookies(options = {})
167+
Cookies.new(@native, options) if defined?(`#@native.cookie`)
139168
end
140169
end
141170

opal/browser/version.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
module Browser
2-
VERSION = '0.3.1'
2+
VERSION = '0.3.2'
33
end

0 commit comments

Comments
 (0)