Class: Dommy::MutationObserver
- Inherits:
-
Object
- Object
- Dommy::MutationObserver
- Includes:
- Bridge::Methods
- Defined in:
- lib/dommy/mutation_observer.rb
Instance Method Summary collapse
- #__js_call__(method, args) ⇒ Object
-
#add_transient(root_wrapped, source_entry) ⇒ Object
Register a transient registered observer for a node just removed from an observed subtree (see @transients).
- #enqueue(record) ⇒ Object
-
#find_matching_entry(target_wrapped) ⇒ Object
Find the observer entry that matches target_wrapped.
-
#initialize(window, callback) ⇒ MutationObserver
constructor
A new instance of MutationObserver.
-
#matches_wrapped?(target_wrapped) ⇒ Boolean
Matches a wrapped target against this observer's scope.
-
#records ⇒ Object
Public: introspection used by linkedom-style tests that peek at pending records without draining (
observer.records[0]).
Methods included from Bridge::Methods
Constructor Details
#initialize(window, callback) ⇒ MutationObserver
Returns a new instance of MutationObserver.
73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 |
# File 'lib/dommy/mutation_observer.rb', line 73 def initialize(window, callback) @window = window @document = window.document @callback = callback @observed = [] @records = [] @scheduled = false @registered_docs = [] # Transient registered observers (WHATWG DOM): when a node is removed from # an observed subtree, its subtree keeps being observed until the next # microtask checkpoint, so mutations inside the just-removed subtree (e.g. # removing its children in the same task) are still recorded. Each entry is # { root: wrapped removed node, source: the registration that matched }. @transients = [] end |
Instance Method Details
#__js_call__(method, args) ⇒ Object
91 92 93 94 95 96 97 98 99 100 |
# File 'lib/dommy/mutation_observer.rb', line 91 def __js_call__(method, args) case method when "observe" observe(args[0], args[1]) when "disconnect" disconnect when "takeRecords" take_records end end |
#add_transient(root_wrapped, source_entry) ⇒ Object
Register a transient registered observer for a node just removed from an observed subtree (see @transients). Carries the matched registration's options so subsequent mutations inside the removed subtree record the same types. Deduped by node identity.
137 138 139 140 141 142 143 |
# File 'lib/dommy/mutation_observer.rb', line 137 def add_transient(root_wrapped, source_entry) return unless root_wrapped && source_entry && source_entry[:subtree] return if @transients.any? { |t| t[:root].equal?(root_wrapped) } @transients << {root: root_wrapped, source: source_entry} nil end |
#enqueue(record) ⇒ Object
145 146 147 148 149 150 151 152 |
# File 'lib/dommy/mutation_observer.rb', line 145 def enqueue(record) @records << record return nil if @scheduled @scheduled = true @window.scheduler.queue_microtask(proc { flush }) nil end |
#find_matching_entry(target_wrapped) ⇒ Object
Find the observer entry that matches target_wrapped. Returns the entry with options (attributes, attributeFilter, etc.) or nil if target doesn't match any observed scope.
111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 |
# File 'lib/dommy/mutation_observer.rb', line 111 def find_matching_entry(target_wrapped) entry = @observed.find do |e| observed_wrapped = e[:target] next false unless observed_wrapped if observed_wrapped.is_a?(Document) Internal::ObserverMatcher.matches_document?(target_wrapped, subtree: e[:subtree]) else Internal::ObserverMatcher.matches?(observed_wrapped, target_wrapped, subtree: e[:subtree]) end end return entry if entry # A transient registered observer matches the removed node itself and its # (now-detached) descendants, with the source registration's options. transient = @transients.find do |t| root = t[:root] root && (root.equal?(target_wrapped) || Internal::ObserverMatcher.matches?(root, target_wrapped, subtree: true)) end transient && transient[:source] end |
#matches_wrapped?(target_wrapped) ⇒ Boolean
Matches a wrapped target against this observer's scope. Called by MutationCoordinator.
104 105 106 |
# File 'lib/dommy/mutation_observer.rb', line 104 def matches_wrapped?(target_wrapped) find_matching_entry(target_wrapped) != nil end |
#records ⇒ Object
Public: introspection used by linkedom-style tests that peek at
pending records without draining (observer.records[0]).
156 157 158 |
# File 'lib/dommy/mutation_observer.rb', line 156 def records @records.dup end |