uri-whatwg_parser 0.2.1 → 0.3.1

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: bc2c1e5428af4eaed582a417234dec63ac59554af14bbbbd1cc0c3017e8e32b9
4
- data.tar.gz: 749b4ba051cb58a73f0ef8ebe64d6426a4d1f0803176641ff75af539757130c1
3
+ metadata.gz: 340c89cc9b0c80699547d7daa0a33c3c081250ebee1dd1178a36ee288a484a22
4
+ data.tar.gz: 961034f93393490c76ad015aea1524b27b5955ef38112892d50b2a1e15a3ac50
5
5
  SHA512:
6
- metadata.gz: a28ffa266d8013c02ed0da9bfd285eaff113527772019a135ddd092310b942c01b6beab710336d37665f8ec3dcc18829edad14a0a97168ef1fc3c651148eb4f0
7
- data.tar.gz: 1ba90031895fe24a39b1ae7ff127ea7af821cb39a0801b83234c40b63801c9ee6c886f1bb0e423bc9c6e9c817d31bea29661db7e22978c8b66891b9864a953f4
6
+ metadata.gz: 987525847dbe6f04d4a2a4c3c8e338d57ebd964d4312528bc16e5e515ba7460922c3fedf08a4151227dbd1fbca11be4af38db6db53e1d741992460fd89c86bd0
7
+ data.tar.gz: 12eae3fe44a8136aa66a55d1aa7e12b172980ae96470f890e34e721fae4c1f3f23155ff1a2e1db305ce2f239cdf239a7db43fe5feb153eb11f3f230c09fd77a4
data/CHANGELOG.md CHANGED
@@ -1,3 +1,14 @@
1
+ ## 0.3.1
2
+
3
+ * Fix a bug of parsing Windows drive letter
4
+ * Correctly set a password when a username is nil
5
+ * Fix setter methods behavior with `URI object created by `build` method
6
+
7
+ ## 0.3.0
8
+
9
+ * Fix several incorrect parsing processes
10
+ * Fix serialize URL
11
+
1
12
  ## 0.2.1
2
13
 
3
14
  * Improve the performance of `parse`
data/README.md CHANGED
@@ -1,8 +1,7 @@
1
1
  # URI::WhatwgParser
2
-
3
2
  Ruby implementation of the [WHATWG URL Living Standard](https://url.spec.whatwg.org/).
4
3
 
5
- The latest revision that this package implements of the standard is [13 January 2026](https://url.spec.whatwg.org/commit-snapshots/b6b3251fe911ab33d68fb051efe0e4d39ae4145e/).
4
+ The latest revision that this package implements of the standard is [14 April 2026](https://url.spec.whatwg.org/commit-snapshots/b11d73b8caefe90403afe19210db05acba897722/)
6
5
 
7
6
  ## Installation
8
7
 
@@ -27,10 +26,6 @@ After checking out the repo, run `bin/setup` to install dependencies. Then, run
27
26
 
28
27
  To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
29
28
 
30
- ## TODO
31
-
32
- * Support validations
33
-
34
29
  ## Contributing
35
30
 
36
31
  Bug reports and pull requests are welcome on GitHub at https://github.com/y-yagi/uri-whatwg_parser.
@@ -3,16 +3,11 @@ require "uri/generic"
3
3
  module URI
4
4
  class WhatwgParser
5
5
  module Generic
6
- def initialize(scheme,
7
- userinfo, host, port, registry,
8
- path, opaque,
9
- query,
10
- fragment,
11
- parser = DEFAULT_PARSER,
12
- arg_check = false)
13
-
14
- return super unless URI::DEFAULT_PARSER.is_a?(URI::WhatwgParser)
15
- return super if registry
6
+ def initialize(scheme, userinfo, host, port, registry, path, opaque, query, fragment, parser = DEFAULT_PARSER, arg_check = false)
7
+ @parsed_by_whatwg_parser = parser.is_a?(URI::WhatwgParser)
8
+ unless parser.is_a?(URI::WhatwgParser)
9
+ return super(scheme, userinfo, host, port, registry, path, opaque, query, fragment, URI::RFC3986_PARSER, arg_check)
10
+ end
16
11
 
17
12
  @scheme = nil
18
13
  @user = nil
@@ -20,6 +15,7 @@ module URI
20
15
  @host = nil
21
16
  @port = nil
22
17
  @path = nil
18
+ @raw_path = nil
23
19
  @query = nil
24
20
  @opaque = nil
25
21
  @fragment = nil
@@ -30,66 +26,69 @@ module URI
30
26
  self.set_port(port)
31
27
  self.set_userinfo(userinfo)
32
28
  self.set_path(path)
33
- self.query = query
29
+ @query = query
34
30
  self.set_opaque(opaque)
35
- self.fragment=(fragment)
31
+ @fragment = fragment
32
+ @raw_path = parser&.path
36
33
 
37
34
  self.set_path("") if !@path && !@opaque
38
- DEFAULT_PARSER.parse(to_s) if arg_check
35
+ parser.parse(to_s) if arg_check
39
36
 
40
37
  @scheme&.freeze
41
38
  self.set_port(self.default_port) if self.default_port && !@port
42
39
  end
43
40
 
44
41
  def merge(oth)
45
- URI::DEFAULT_PARSER.join(self.to_s, oth.to_s)
42
+ return super unless @parsed_by_whatwg_parser
43
+
44
+ parser.join(self.to_s, oth.to_s)
46
45
  end
47
46
  alias + merge
48
47
 
49
48
  def scheme=(v)
50
- return super unless URI::DEFAULT_PARSER.is_a?(URI::WhatwgParser)
49
+ return super unless @parsed_by_whatwg_parser
51
50
  return if v.nil? || v.empty?
52
51
 
53
- parse_result = URI::DEFAULT_PARSER.split("#{v}:", url: self, state_override: :scheme_start_state)
52
+ parse_result = parser.split("#{v}:", url: self, state_override: :scheme_start_state)
54
53
  set_scheme(parse_result[0])
55
54
  set_port(parse_result[3])
56
55
  end
57
56
 
58
57
  def user=(v)
59
- return super unless URI::DEFAULT_PARSER.is_a?(URI::WhatwgParser)
58
+ return super unless @parsed_by_whatwg_parser
60
59
  return v unless v
61
60
 
62
61
  if host.nil? || host.empty? || scheme == "file"
63
62
  raise InvalidURIError, "cannot set user when host is nil or file schme"
64
63
  end
65
- set_user(URI::DEFAULT_PARSER.utf8_percent_encode_string(v, URI::WhatwgParser::USERINFO_PERCENT_ENCODE_SET))
64
+ set_user(parser.utf8_percent_encode_string(v, URI::WhatwgParser::USERINFO_PERCENT_ENCODE_SET))
66
65
  end
67
66
 
68
67
  def password=(v)
69
- return super unless URI::DEFAULT_PARSER.is_a?(URI::WhatwgParser)
68
+ return super unless @parsed_by_whatwg_parser
70
69
  return v unless v
71
70
 
72
71
  if host.nil? || host.empty? || scheme == "file"
73
72
  raise InvalidURIError, "cannot set password when host is nil or file schme"
74
73
  end
75
- set_password(URI::DEFAULT_PARSER.utf8_percent_encode_string(v, URI::WhatwgParser::USERINFO_PERCENT_ENCODE_SET))
74
+ set_password(parser.utf8_percent_encode_string(v, URI::WhatwgParser::USERINFO_PERCENT_ENCODE_SET))
76
75
  end
77
76
 
78
77
  def host=(v)
79
- return super unless URI::DEFAULT_PARSER.is_a?(URI::WhatwgParser)
78
+ return super unless @parsed_by_whatwg_parser
80
79
  return if v.nil?
81
80
 
82
81
  if @opaque
83
- raise InvalidURIError, "cannot set host with registry or opaque"
82
+ raise InvalidURIError, "cannot set host with opaque"
84
83
  end
85
84
 
86
- parse_result = URI::DEFAULT_PARSER.split(v.to_s, url: self, state_override: :host_state)
85
+ parse_result = parser.split(v.to_s, url: self, state_override: :host_state)
87
86
  set_host(parse_result[2])
88
87
  set_port(parse_result[3])
89
88
  end
90
89
 
91
90
  def port=(v)
92
- return super unless URI::DEFAULT_PARSER.is_a?(URI::WhatwgParser)
91
+ return super unless @parsed_by_whatwg_parser
93
92
  return if v.nil?
94
93
 
95
94
  if v.to_s.empty?
@@ -101,24 +100,55 @@ module URI
101
100
  raise InvalidURIError, "cannot set port when host is nil or scheme is file"
102
101
  end
103
102
 
104
- parse_result = URI::DEFAULT_PARSER.split("#{v}:", url: self, state_override: :port_state)
103
+ parse_result = parser.split("#{v}:", url: self, state_override: :port_state)
105
104
  set_port(parse_result[3])
106
105
  end
107
106
 
108
107
  def path=(v)
109
- return super unless URI::DEFAULT_PARSER.is_a?(URI::WhatwgParser)
108
+ return super unless @parsed_by_whatwg_parser
110
109
  return if v.nil?
111
110
 
112
111
  if @opaque
113
112
  raise InvalidURIError, "path conflicts with opaque"
114
113
  end
115
114
 
116
- parse_result = URI::DEFAULT_PARSER.split(v.to_s, url: self, state_override: :path_start_state)
115
+ parse_result = parser.split(v.to_s, url: self, state_override: :path_start_state)
116
+ @raw_path = parser.path
117
117
  set_path(parse_result[5])
118
118
  end
119
119
 
120
+ def query=(v)
121
+ return super unless @parsed_by_whatwg_parser
122
+
123
+ if v.nil? || v.empty?
124
+ @query = nil
125
+ return
126
+ end
127
+
128
+ v = v.start_with?("?") ? v[1..-1] : v
129
+ @query = +""
130
+
131
+ parse_result = parser.split(v, url: self, state_override: :query_state)
132
+ @query = parse_result[7].to_s
133
+ end
134
+
135
+ def fragment=(v)
136
+ return super unless @parsed_by_whatwg_parser
137
+
138
+ if v.nil? || v.empty?
139
+ @fragment = nil
140
+ return
141
+ end
142
+
143
+ v = v.start_with?("#") ? v[1..-1] : v
144
+ @fragment = +""
145
+
146
+ parse_result = parser.split(v, url: self, state_override: :fragment_state)
147
+ @fragment = parse_result[8].to_s
148
+ end
149
+
120
150
  def userinfo=(userinfo)
121
- return super unless URI::DEFAULT_PARSER.is_a?(URI::WhatwgParser)
151
+ return super unless @parsed_by_whatwg_parser
122
152
 
123
153
  user, password = split_userinfo(userinfo)
124
154
  self.user = user
@@ -126,17 +156,59 @@ module URI
126
156
  end
127
157
 
128
158
  def check_opaque(v)
129
- return super unless URI::DEFAULT_PARSER.is_a?(URI::WhatwgParser)
159
+ return super unless @parsed_by_whatwg_parser
160
+
130
161
  return v unless v
131
162
 
132
- if @host || @port || @user || @path
133
- raise InvalidURIError, "cannot set opaque with host, port, userinfo or path"
163
+ if @host || @port || @user
164
+ raise InvalidURIError, "cannot set opaque with host, port, or userinfo"
134
165
  end
135
166
 
136
167
  self.set_opaque(v)
137
- DEFAULT_PARSER.parse(to_s)
168
+ # NOTE: WHATWG URL Living Standard doesn't define "opaque" setter. So parse a URL whole.
169
+ parser.parse(to_s)
138
170
  true
139
171
  end
172
+
173
+ def to_s
174
+ return super unless @parsed_by_whatwg_parser
175
+
176
+ str = "".dup
177
+ if @scheme
178
+ str << @scheme
179
+ str << ":"
180
+ end
181
+
182
+ if @host || %w[file postgres].include?(@scheme)
183
+ str << "//"
184
+ end
185
+ if self.userinfo
186
+ str << self.userinfo
187
+ str << "@"
188
+ end
189
+ if @host
190
+ str << @host
191
+ end
192
+ if @port && @port != self.default_port
193
+ str << ":"
194
+ str << @port.to_s
195
+ end
196
+ if @host.nil? && @opaque.nil? && @raw_path && @raw_path.length > 1 && @raw_path[0] == ""
197
+ str << "/."
198
+ end
199
+ str << @path if @path
200
+ str << @opaque if @opaque
201
+ if @query
202
+ str << "?"
203
+ str << @query
204
+ end
205
+
206
+ if @fragment
207
+ str << "#"
208
+ str << @fragment
209
+ end
210
+ str
211
+ end
140
212
  end
141
213
  end
142
214
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module URI
4
4
  class WhatwgParser
5
- VERSION = "0.2.1"
5
+ VERSION = "0.3.1"
6
6
  end
7
7
  end
@@ -25,7 +25,7 @@ module URI
25
25
 
26
26
  WINDOWS_DRIVE_LETTER = Regexp.new("\\A([a-zA-Z][:|])\\z")
27
27
  NORMALIZED_WINDOWS_DRIVE_LETTER = Regexp.new("\\A([a-zA-Z][:])\\z")
28
- STARTS_WITH_WINDOWS_DRIVE_LETTER = Regexp.new("\\A([a-zA-Z][:|])(?:[/\\?#])?\\z")
28
+ FILE_OTHERWISE_CODE_POINTS = Set["/", "\\", "?", "#"]
29
29
 
30
30
  VALID_SIGNS_FOR_SCHEME = Set["+", "-", "."]
31
31
  DELIMITER_SIGNS = Set["/", "?", "#"]
@@ -36,6 +36,8 @@ module URI
36
36
  ASCII_ALPHA_UPPERCASE = Set.new(("A".."Z").to_a)
37
37
  ASCII_DIGIT = Set.new(("0".."9").to_a)
38
38
 
39
+ attr_reader :path
40
+
39
41
  def initialize
40
42
  reset
41
43
  @host_parser = HostParser.new
@@ -46,7 +48,7 @@ module URI
46
48
  end
47
49
 
48
50
  def parse(input, base: nil, url: nil, state_override: nil) # :nodoc:
49
- URI.for(*self.split(input, base: base, url: url, state_override: state_override))
51
+ URI.for(*self.split(input, base: base, url: url, state_override: state_override), self)
50
52
  end
51
53
 
52
54
  def split(input, base: nil, url: nil, state_override: nil) # :nodoc:
@@ -54,8 +56,8 @@ module URI
54
56
  @base = nil
55
57
  if base != nil
56
58
  ary = split(base, base: nil)
57
- @base = { scheme: ary[0], userinfo: ary[1], host: ary[2], port: ary[3], registry: ary[4], path: ary[5], opaque: ary[6], query: ary[7], fragment: ary[8]}
58
- @base_paths = @paths
59
+ @base = { scheme: ary[0], userinfo: ary[1], host: ary[2], port: ary[3], query: ary[7], fragment: ary[8]}
60
+ @base_path = @path
59
61
  reset
60
62
  end
61
63
 
@@ -94,9 +96,19 @@ module URI
94
96
  @pos += 1
95
97
  end
96
98
 
97
- userinfo = [@username, @password].compact.reject(&:empty?).join(":")
98
- path = "/#{@paths.join("/")}" if @paths && !@paths.empty?
99
- [@parse_result[:scheme], userinfo, @parse_result[:host], @parse_result[:port], @parse_result[:registry], path, @parse_result[:opaque], @parse_result[:query], @parse_result[:fragment]]
99
+ if @password
100
+ userinfo = "#{@username}:#{@password}"
101
+ else
102
+ userinfo = @username
103
+ end
104
+ if @path
105
+ if @path.is_a?(Array)
106
+ path = "/#{@path.join("/")}"
107
+ else
108
+ opaque = @path
109
+ end
110
+ end
111
+ [@parse_result[:scheme], userinfo, @parse_result[:host], @parse_result[:port], nil, path, opaque, @parse_result[:query], @parse_result[:fragment]]
100
112
  end
101
113
 
102
114
  def join(*uris)
@@ -143,10 +155,10 @@ module URI
143
155
  @at_sign_seen = nil
144
156
  @password_token_seen = nil
145
157
  @inside_brackets = nil
146
- @paths = nil
158
+ @path = nil
147
159
  @username = nil
148
160
  @password = nil
149
- @parse_result = { scheme: nil, host: nil, port: nil, registry: nil, path: nil, opaque: nil, query: nil, fragment: nil }
161
+ @parse_result = {}
150
162
  @state_override = nil
151
163
  @state = :scheme_start_state
152
164
  @special_url = nil
@@ -207,7 +219,7 @@ module URI
207
219
  @state = :path_or_authority_state
208
220
  @pos += 1
209
221
  else
210
- @parse_result[:opaque] = +""
222
+ @path = +""
211
223
  @state = :opaque_path_state
212
224
  end
213
225
  elsif @state_override.nil?
@@ -220,14 +232,14 @@ module URI
220
232
  end
221
233
 
222
234
  def no_scheme_state(c)
223
- raise ParseError, "scheme is missing" if @base.nil? || (!@base[:opaque].nil? && c != "#")
235
+ raise ParseError, "scheme is missing" if @base.nil? || (has_opaque_path?(@base_path) && c != "#")
224
236
 
225
- if !@base[:opaque].nil? && c == "#"
237
+ if has_opaque_path?(@base_path) && c == "#"
226
238
  @parse_result[:scheme] = @base[:scheme]
227
239
  @special_url = special_url?(@base[:scheme])
228
- @paths = @base_paths
240
+ @path = @base_path
229
241
  @parse_result[:query] = @base[:query]
230
- @parse_result[:fragment] = nil
242
+ @parse_result[:fragment] = +""
231
243
  @state = :fragment_state
232
244
  elsif @base[:scheme] != "file"
233
245
  @state = :relative_state
@@ -268,14 +280,14 @@ module URI
268
280
  @username, @password = @base[:userinfo].split(":") if @base[:userinfo]
269
281
  @parse_result[:host] = @base[:host]
270
282
  @parse_result[:port] = @base[:port]
271
- @paths = @base_paths
283
+ @path = @base_path
272
284
  @parse_result[:query] = @base[:query]
273
285
 
274
286
  if c == "?"
275
- @parse_result[:query] = nil
287
+ @parse_result[:query] = +""
276
288
  @state = :query_state
277
289
  elsif c == "#"
278
- @parse_result[:fragment] = nil
290
+ @parse_result[:fragment] = +""
279
291
  @state = :fragment_state
280
292
  elsif !c.nil?
281
293
  @parse_result[:query] = nil
@@ -386,7 +398,7 @@ module URI
386
398
  @buffer << c
387
399
  elsif c.nil? || DELIMITER_SIGNS.include?(c) || (@special_url && c == "\\") || @state_override
388
400
  unless @buffer.empty?
389
- port = Integer(@buffer, 10)
401
+ port = @buffer.to_i
390
402
  raise ParseError, "port is invalid value" if port < 0 || port > 65535
391
403
  if SPECIAL_SCHEME[@parse_result[:scheme]] == port
392
404
  @parse_result[:port] = nil
@@ -401,7 +413,6 @@ module URI
401
413
  end
402
414
  end
403
415
 
404
- raise ParseError, "port is invalid value" if @state_override
405
416
  @state = :path_start_state
406
417
  @pos -= 1
407
418
  else
@@ -413,24 +424,24 @@ module URI
413
424
  @parse_result[:scheme] = "file"
414
425
  @special_url = true
415
426
  @parse_result[:host] = nil
416
-
417
427
  if c == "/" || c == "\\"
418
428
  @state = :file_slash_state
419
429
  elsif !@base.nil? && @base[:scheme] == "file"
420
430
  @parse_result[:host] = @base[:host]
431
+ @path = @base_path
421
432
  @parse_result[:query] = @base[:query]
422
433
  if c == "?"
423
- @parse_result[:query] = nil
434
+ @parse_result[:query] = +""
424
435
  @state = :query_state
425
436
  elsif c == "#"
426
- @parse_result[:fragment] = nil
437
+ @parse_result[:fragment] = +""
427
438
  @state = :fragment_state
428
439
  elsif !c.nil?
429
440
  @parse_result[:query] = nil
430
441
  if !starts_with_windows_drive_letter?(rest)
431
442
  shorten_url_path
432
443
  else
433
- @paths = nil
444
+ @path = nil
434
445
  end
435
446
  @state = :path_state
436
447
  @pos -= 1
@@ -447,11 +458,9 @@ module URI
447
458
  else
448
459
  if !@base.nil? && @base[:scheme] == "file"
449
460
  @parse_result[:host] = @base[:host]
450
- if !starts_with_windows_drive_letter?(rest) && @base_paths && normalized_windows_drive_letter?(@base_paths[0])
451
- if @paths.nil?
452
- @paths ||= []
453
- @paths[0] = @base_paths[0]
454
- end
461
+ if !starts_with_windows_drive_letter?(rest) && @base_path && normalized_windows_drive_letter?(@base_path[0])
462
+ @path = [] if @path.nil?
463
+ @path << @base_path[0]
455
464
  end
456
465
  end
457
466
  @state = :path_state
@@ -493,45 +502,47 @@ module URI
493
502
  @pos -= 1 if c != "/" && c != "\\"
494
503
  @state = :path_state
495
504
  elsif !@state_override && c == "?"
505
+ @parse_result[:query] = +""
496
506
  @state = :query_state
497
507
  elsif !@state_override && c == "#"
508
+ @parse_result[:fragment] = +""
498
509
  @state = :fragment_state
499
510
  elsif c != nil
500
511
  @pos -= 1 if c != "/"
501
512
  @state = :path_state
502
513
  elsif @state_override && @parse_result[:host].nil?
503
- @paths ||= []
504
- @paths << ""
514
+ @path ||= []
515
+ @path << ""
505
516
  end
506
517
  end
507
518
 
508
519
  def path_state(c)
509
- @paths ||= []
520
+ @path ||= []
510
521
 
511
522
  if (c.nil? || c == "/") || (@special_url && c == "\\") || (!@state_override && (c == "?" || c == "#"))
512
523
  if double_dot_path_segments?(@buffer)
513
524
  shorten_url_path
514
525
 
515
526
  if c != "/" && !(@special_url && c == "\\")
516
- @paths << ""
527
+ @path << ""
517
528
  end
518
529
  elsif single_dot_path_segments?(@buffer) && c != "/" && !((@special_url && c == "\\"))
519
- @paths << ""
530
+ @path << ""
520
531
  elsif !single_dot_path_segments?(@buffer)
521
- if @parse_result[:scheme] == "file" && @paths.empty? && windows_drive_letter?(@buffer)
532
+ if @parse_result[:scheme] == "file" && @path.empty? && windows_drive_letter?(@buffer)
522
533
  @buffer[1] = ":"
523
534
  end
524
535
 
525
- @paths << @buffer
536
+ @path << @buffer
526
537
  end
527
538
 
528
539
  @buffer = +""
529
540
 
530
541
  if c == "?"
531
- @parse_result[:query] = nil
542
+ @parse_result[:query] = +""
532
543
  @state = :query_state
533
544
  elsif c == "#"
534
- @parse_result[:frament] = nil
545
+ @parse_result[:fragment] = +""
535
546
  @state = :fragment_state
536
547
  end
537
548
  else
@@ -541,20 +552,20 @@ module URI
541
552
 
542
553
  def opaque_path_state(c)
543
554
  if c == "?"
544
- @parse_result[:query] = nil
555
+ @parse_result[:query] = +""
545
556
  @state = :query_state
546
557
  elsif c == "#"
547
- @parse_result[:fragment] = nil
558
+ @parse_result[:fragment] = +""
548
559
  @state = :fragment_state
549
560
  elsif c == " "
550
561
  first_of_rest = @input_chars[@pos + 1]
551
562
  if first_of_rest == "?" || first_of_rest == "#"
552
- @parse_result[:opaque] << "%20"
563
+ @path += "%20"
553
564
  else
554
- @parse_result[:opaque] << " "
565
+ @path += " "
555
566
  end
556
567
  elsif !c.nil?
557
- @parse_result[:opaque] << utf8_percent_encode(c, C0_CONTROL_PERCENT_ENCODE_SET)
568
+ @path += utf8_percent_encode(c, C0_CONTROL_PERCENT_ENCODE_SET)
558
569
  end
559
570
  end
560
571
 
@@ -564,7 +575,10 @@ module URI
564
575
  # TODO: We need to consider encoding here.
565
576
  @parse_result[:query] = utf8_percent_encode_string(@buffer, query_percent_encode_set)
566
577
  @buffer.clear
567
- @state = :fragment_state if c == "#"
578
+ if c == "#"
579
+ @parse_result[:fragment] = +""
580
+ @state = :fragment_state
581
+ end
568
582
  elsif !c.nil?
569
583
  @buffer << c
570
584
  end
@@ -580,7 +594,9 @@ module URI
580
594
  end
581
595
 
582
596
  def starts_with_windows_drive_letter?(str)
583
- STARTS_WITH_WINDOWS_DRIVE_LETTER.match?(str)
597
+ return false if str.length < 2
598
+ return false unless windows_drive_letter?(str[0, 2])
599
+ str.length == 2 || FILE_OTHERWISE_CODE_POINTS.include?(str[2])
584
600
  end
585
601
 
586
602
  def normalized_windows_drive_letter?(str)
@@ -600,9 +616,9 @@ module URI
600
616
  end
601
617
 
602
618
  def shorten_url_path
603
- return if @paths.nil?
604
- return if @parse_result[:scheme] == "file" && @paths.length == 1 && normalized_windows_drive_letter?(@paths.first)
605
- @paths.pop
619
+ return if @path.nil? || @path.is_a?(String)
620
+ return if @parse_result[:scheme] == "file" && @path.length == 1 && normalized_windows_drive_letter?(@path.first)
621
+ @path.pop
606
622
  end
607
623
 
608
624
  def includes_credentials?
@@ -610,7 +626,7 @@ module URI
610
626
  end
611
627
 
612
628
  def rest
613
- @input_chars[@pos + 1..]&.join
629
+ @input_chars[@pos..]&.join
614
630
  end
615
631
 
616
632
  def convert_to_uri(uri)
@@ -638,6 +654,10 @@ module URI
638
654
  end
639
655
  end
640
656
  end
657
+
658
+ def has_opaque_path?(path)
659
+ path.is_a?(String)
660
+ end
641
661
  end
642
662
 
643
663
  WHATWG_PARSER = URI::WhatwgParser.new
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: uri-whatwg_parser
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yuji Yaginuma
@@ -66,14 +66,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
66
66
  requirements:
67
67
  - - ">="
68
68
  - !ruby/object:Gem::Version
69
- version: 3.2.0
69
+ version: 3.0.0
70
70
  required_rubygems_version: !ruby/object:Gem::Requirement
71
71
  requirements:
72
72
  - - ">="
73
73
  - !ruby/object:Gem::Version
74
74
  version: '0'
75
75
  requirements: []
76
- rubygems_version: 4.0.3
76
+ rubygems_version: 4.0.10
77
77
  specification_version: 4
78
78
  summary: Ruby implementation of the WHATWG URL Living Standard
79
79
  test_files: []