Class: Dommy::Event
- Inherits:
-
Object
- Object
- Dommy::Event
- Includes:
- Bridge::Methods
- Defined in:
- lib/dommy/event.rb
Direct Known Subclasses
BeforeUnloadEvent, ClipboardEvent, CloseEvent, CookieChangeEvent, CustomEvent, ErrorEvent, HashChangeEvent, InputEvent, MediaQueryListEvent, MessageEvent, PopStateEvent, ProgressEvent, PromiseRejectionEvent, SubmitEvent, ToggleEvent, TouchEvent, UIEvent
Constant Summary collapse
- NONE =
0- CAPTURING_PHASE =
1- AT_TARGET =
2- BUBBLING_PHASE =
3
Instance Attribute Summary collapse
-
#type ⇒ Object
readonly
Returns the value of attribute type.
Instance Method Summary collapse
-
#__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.
-
#__internal_mark_trusted__ ⇒ Object
Mark this event as UA-generated (
isTrusted === true). - #__internal_prepare_for_dispatch__(target) ⇒ Object
-
#__internal_record_path__(targets) ⇒ Object
Filled in by EventTarget#dispatch_event as the event walks the bubble path so
composedPath()returns the right list. -
#__internal_run_passive__ ⇒ Object
Run a block with the passive-listener flag set, so any preventDefault() inside it is neutralized.
- #__internal_set_current_target__(target) ⇒ Object
-
#__internal_set_dispatch_flag__(flag) ⇒ Object
Set while the event is being dispatched, so initEvent() can short-circuit.
- #__internal_set_event_phase__(phase) ⇒ Object
- #__js_call__(method, args) ⇒ Object
- #__js_get__(key) ⇒ Object
- #__js_set__(key, value) ⇒ Object
- #bubbles? ⇒ Boolean
- #default_prevented? ⇒ Boolean
- #immediate_propagation_stopped? ⇒ Boolean
-
#init_event(type, bubbles = false, cancelable = false) ⇒ Object
Deprecated
Event#initEvent(type, bubbles, cancelable)— older browsers useddocument.createEvent("Event").initEvent(...). -
#initialize(type, init = nil) ⇒ Event
constructor
A new instance of Event.
- #propagation_stopped? ⇒ Boolean
Methods included from Bridge::Methods
Constructor Details
#initialize(type, init = nil) ⇒ Event
Returns a new instance of Event.
375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 |
# File 'lib/dommy/event.rb', line 375 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 # Set while a passive listener runs, so preventDefault() is a no-op (per # the passive listener flag in the DOM spec). @in_passive_listener = 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
#type ⇒ Object (readonly)
Returns the value of attribute type.
404 405 406 |
# File 'lib/dommy/event.rb', line 404 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.
441 442 443 444 445 |
# File 'lib/dommy/event.rb', line 441 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").
399 400 401 402 |
# File 'lib/dommy/event.rb', line 399 def __internal_mark_trusted__ @trusted = true self end |
#__internal_prepare_for_dispatch__(target) ⇒ Object
432 433 434 |
# File 'lib/dommy/event.rb', line 432 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).
577 578 579 580 581 582 583 |
# File 'lib/dommy/event.rb', line 577 def __internal_record_path__(targets) @composed_path = if @type == "load" targets.reject { |t| t.is_a?(Window) } else targets end end |
#__internal_run_passive__ ⇒ Object
Run a block with the passive-listener flag set, so any preventDefault() inside it is neutralized. Restores the prior flag afterward.
424 425 426 427 428 429 430 |
# File 'lib/dommy/event.rb', line 424 def __internal_run_passive__ previous = @in_passive_listener @in_passive_listener = true yield ensure @in_passive_listener = previous end |
#__internal_set_current_target__(target) ⇒ Object
447 448 449 |
# File 'lib/dommy/event.rb', line 447 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.
550 551 552 553 |
# File 'lib/dommy/event.rb', line 550 def __internal_set_dispatch_flag__(flag) @dispatch_flag = flag nil end |
#__internal_set_event_phase__(phase) ⇒ Object
451 452 453 |
# File 'lib/dommy/event.rb', line 451 def __internal_set_event_phase__(phase) @event_phase = phase end |
#__js_call__(method, args) ⇒ Object
522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 |
# File 'lib/dommy/event.rb', line 522 def __js_call__(method, args) case method when "preventDefault" # A passive listener's preventDefault() is a no-op (DOM "passive listener # flag"), so the default action proceeds — what Stimulus's :passive # action option relies on. @default_prevented = true if @cancelable && !@in_passive_listener nil when "stopPropagation" @propagation_stopped = true nil when "stopImmediatePropagation" @propagation_stopped = true @immediate_propagation_stopped = true nil when "composedPath" # composedPath() is the event path only while the event is being # dispatched; once dispatch finishes (currentTarget is null) it is empty. @dispatch_flag ? @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
455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 |
# File 'lib/dommy/event.rb', line 455 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 "immediatePropagationStopped" # Non-standard, but real frameworks feature-detect it: Stimulus's # extendEvent does `"immediatePropagationStopped" in event` and, when # present, reads the flag directly instead of installing its own # tracking shim. Expose the live flag so that path stays correct (it # also keeps `"immediatePropagationStopped" in event` from being a # present-but-undefined no-op). @immediate_propagation_stopped when "eventPhase" event_phase else # An unknown property is genuinely absent: JS `undefined` and # `"x" in event` false — 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::ABSENT end end |
#__js_set__(key, value) ⇒ Object
503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 |
# File 'lib/dommy/event.rb', line 503 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
406 407 408 |
# File 'lib/dommy/event.rb', line 406 def bubbles? @bubbles end |
#default_prevented? ⇒ Boolean
410 411 412 |
# File 'lib/dommy/event.rb', line 410 def default_prevented? @default_prevented end |
#immediate_propagation_stopped? ⇒ Boolean
418 419 420 |
# File 'lib/dommy/event.rb', line 418 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.
558 559 560 561 562 563 564 565 566 567 568 569 |
# File 'lib/dommy/event.rb', line 558 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
414 415 416 |
# File 'lib/dommy/event.rb', line 414 def propagation_stopped? @propagation_stopped end |