Class: Dommy::Event

Inherits:
Object
  • Object
show all
Includes:
Bridge::Methods
Defined in:
lib/dommy/event.rb

Constant Summary collapse

NONE =
0
CAPTURING_PHASE =
1
AT_TARGET =
2
BUBBLING_PHASE =
3

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Bridge::Methods

included

Constructor Details

#initialize(type, init = nil) ⇒ Event

Returns a new instance of Event.



281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
# File 'lib/dommy/event.rb', line 281

def initialize(type, init = nil)
  @type = type.to_s
  @bubbles = !!read_init(init, "bubbles")
  @cancelable = !!read_init(init, "cancelable")
  @composed = !!read_init(init, "composed")
  @default_prevented = false
  @propagation_stopped = false
  @immediate_propagation_stopped = false
  @target = nil
  @current_target = nil
  @event_phase = NONE
  @composed_path = []
  # `timeStamp` is the high-resolution timestamp at construction
  # in ms (browser uses performance.now). We use monotonic time
  # for determinism across spec runs.
  @time_stamp = (Process.clock_gettime(Process::CLOCK_MONOTONIC) * 1000.0)
  @trusted = false
end

Instance Attribute Details

#typeObject (readonly)

Returns the value of attribute type.



307
308
309
# File 'lib/dommy/event.rb', line 307

def type
  @type
end

Instance Method Details

#__internal_clear_propagation_flags__Object

End-of-dispatch cleanup: the dispatch algorithm unsets the stop-propagation and stop-immediate-propagation flags (but NOT the canceled flag), so the same event object can be dispatched again. A stopPropagation() issued before the next dispatch is still honored — only the post-dispatch state is cleared here.



334
335
336
337
338
# File 'lib/dommy/event.rb', line 334

def __internal_clear_propagation_flags__
  @propagation_stopped = false
  @immediate_propagation_stopped = false
  nil
end

#__internal_mark_trusted__Object

Mark this event as UA-generated (‘isTrusted === true`). Used by the host for events it fires itself (e.g. AbortSignal’s “abort”).



302
303
304
305
# File 'lib/dommy/event.rb', line 302

def __internal_mark_trusted__
  @trusted = true
  self
end

#__internal_prepare_for_dispatch__(target) ⇒ Object



325
326
327
# File 'lib/dommy/event.rb', line 325

def __internal_prepare_for_dispatch__(target)
  @target ||= target
end

#__internal_record_path__(targets) ⇒ Object

Filled in by EventTarget#dispatch_event as the event walks the bubble path so ‘composedPath()` returns the right list.

Per spec, ‘load` events do not propagate to the Window when composed paths are computed (resource-finished signal stays at the target).



456
457
458
459
460
461
462
# File 'lib/dommy/event.rb', line 456

def __internal_record_path__(targets)
  @composed_path = if @type == "load"
    targets.reject { |t| t.is_a?(Window) }
  else
    targets
  end
end

#__internal_set_current_target__(target) ⇒ Object



340
341
342
# File 'lib/dommy/event.rb', line 340

def __internal_set_current_target__(target)
  @current_target = target
end

#__internal_set_dispatch_flag__(flag) ⇒ Object

Set while the event is being dispatched, so initEvent() can short-circuit.



429
430
431
432
# File 'lib/dommy/event.rb', line 429

def __internal_set_dispatch_flag__(flag)
  @dispatch_flag = flag
  nil
end

#__internal_set_event_phase__(phase) ⇒ Object



344
345
346
# File 'lib/dommy/event.rb', line 344

def __internal_set_event_phase__(phase)
  @event_phase = phase
end

#__js_call__(method, args) ⇒ Object



406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
# File 'lib/dommy/event.rb', line 406

def __js_call__(method, args)
  case method
  when "preventDefault"
    @default_prevented = true if @cancelable
    nil
  when "stopPropagation"
    @propagation_stopped = true
    nil
  when "stopImmediatePropagation"
    @propagation_stopped = true
    @immediate_propagation_stopped = true
    nil
  when "composedPath"
    @composed_path.dup
  when "initEvent"
    # WebIDL: the `type` argument is mandatory.
    raise Bridge::TypeError, "initEvent requires a type argument" if args.empty?

    init_event(args[0], args[1], args[2])
  end
end

#__js_get__(key) ⇒ Object



348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
# File 'lib/dommy/event.rb', line 348

def __js_get__(key)
  case key
  when "type"
    @type
  when "bubbles"
    @bubbles
  when "cancelable"
    @cancelable
  when "composed"
    @composed
  when "defaultPrevented"
    @default_prevented
  when "returnValue"
    # Legacy alias: false once the default has been prevented, else true.
    !@default_prevented
  when "isTrusted"
    # Script-created events are untrusted; a UA-fired event (e.g. an
    # AbortSignal's "abort") is marked trusted via __internal_mark_trusted__.
    @trusted == true
  when "target", "srcElement"
    # srcElement is a legacy alias of target — null (not undefined) when unset.
    @target
  when "currentTarget"
    @current_target
  when "timeStamp"
    @time_stamp
  when "cancelBubble"
    @propagation_stopped
  when "eventPhase"
    event_phase
  else
    # An unknown property reads back as JS `undefined`, not `null` — e.g. a
    # non-dictionary member passed to the constructor (`new Event("x", {sweet:
    # 1}).sweet`) is not reflected on the event. Genuinely-null DOM attributes
    # (target/currentTarget/…) are explicit cases above and still return nil.
    Bridge::UNDEFINED
  end
end

#__js_set__(key, value) ⇒ Object



387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
# File 'lib/dommy/event.rb', line 387

def __js_set__(key, value)
  case key
  when "cancelBubble"
    # Setting to truthy stops propagation; spec quirk that
    # `cancelBubble = false` does NOT un-stop (browser observation).
    @propagation_stopped = true if value
  when "returnValue"
    # Legacy alias: returnValue = false cancels the event (like
    # preventDefault); a truthy value does not un-cancel.
    @default_prevented = true if !value && @cancelable
  else
    return Bridge::UNHANDLED
  end

  nil
end

#bubbles?Boolean

Returns:

  • (Boolean)


309
310
311
# File 'lib/dommy/event.rb', line 309

def bubbles?
  @bubbles
end

#default_prevented?Boolean

Returns:

  • (Boolean)


313
314
315
# File 'lib/dommy/event.rb', line 313

def default_prevented?
  @default_prevented
end

#immediate_propagation_stopped?Boolean

Returns:

  • (Boolean)


321
322
323
# File 'lib/dommy/event.rb', line 321

def immediate_propagation_stopped?
  @immediate_propagation_stopped
end

#init_event(type, bubbles = false, cancelable = false) ⇒ Object

Deprecated ‘Event#initEvent(type, bubbles, cancelable)` — older browsers used `document.createEvent(“Event”).initEvent(…)`. Resets internal flags as a side effect.



437
438
439
440
441
442
443
444
445
446
447
448
# File 'lib/dommy/event.rb', line 437

def init_event(type, bubbles = false, cancelable = false)
  # Spec: initEvent is a no-op while the event is being dispatched.
  return nil if @dispatch_flag

  @type = type.to_s
  @bubbles = !!bubbles
  @cancelable = !!cancelable
  @default_prevented = false
  @propagation_stopped = false
  @immediate_propagation_stopped = false
  nil
end

#propagation_stopped?Boolean

Returns:

  • (Boolean)


317
318
319
# File 'lib/dommy/event.rb', line 317

def propagation_stopped?
  @propagation_stopped
end