Class: URIPattern::ConstructorStringParser

Inherits:
Object
  • Object
show all
Defined in:
lib/uri_pattern/url_parser.rb

Overview

Implements the WHATWG URLPattern “constructor string parser” state machine. urlpattern.spec.whatwg.org/#constructor-string-parsing

Walks the (regexp-coalesced) token list with a state machine, recording each component into ‘result` as it is delimited. Component keys use the spec names (`:search` / `:hash`); URLParser.split_pattern maps them to `:query` / `:fragment`.

Constant Summary collapse

NON_SPECIAL_CHAR_TYPES =
%i[char escaped_char invalid_char].freeze
SEARCH_PREFIX_BLOCKERS =
%i[name regexp close asterisk].freeze

Instance Method Summary collapse

Constructor Details

#initialize(input, tokens) ⇒ ConstructorStringParser

Returns a new instance of ConstructorStringParser.



239
240
241
242
243
244
245
246
247
248
249
250
# File 'lib/uri_pattern/url_parser.rb', line 239

def initialize(input, tokens)
  @input = input
  @tokens = tokens
  @result = {}
  @component_start = 0
  @token_index = 0
  @token_increment = 1
  @group_depth = 0
  @ipv6_depth = 0
  @protocol_special = false
  @state = :init
end

Instance Method Details

#parseObject



252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
# File 'lib/uri_pattern/url_parser.rb', line 252

def parse
  while @token_index < @tokens.length
    @token_increment = 1

    if current.type == :end
      case @state
      when :init
        rewind
        if hash_prefix?
          change_state(:hash, 1)
        elsif search_prefix?
          change_state(:search, 1)
        else
          change_state(:pathname, 0)
        end
        @token_index += @token_increment
        next
      when :authority
        rewind_and_set_state(:hostname)
        @token_index += @token_increment
        next
      else
        change_state(:done, 0)
        break
      end
    end

    if group_open?
      @group_depth += 1
      @token_index += @token_increment
      next
    end

    if @group_depth.positive?
      if group_close?
        @group_depth -= 1
      else
        @token_index += @token_increment
        next
      end
    end

    step_state

    @token_index += @token_increment
  end

  @result[:port] = "" if @result.key?(:hostname) && !@result.key?(:port)
  @result
end