Commit 24ed0b56 authored by Keishi Hattori's avatar Keishi Hattori Committed by Commit Bot

Convert global MutationObserver data to per-agent

Convert the global MutationObserver data, active_mutation_observers, suspended_mutation_observers, and active_slot_change_list to per agent.

Introduces the MutationObserverNotifier class which is created for every WindowAgent.
MutationObserverNotifier now manages active_mutation_observers, suspended_mutation_observers, and active_slot_change_list.

Also the Document's agent is now set using the ContextDocument frame's WindowAgentFactory.
This is because some Documents such as those created with DOMImplementation.createHTMLDocument do not have a frame.
Some Documents created in unit tests have neither a ContextDocument nor a frame so we assign a new WindowAgent.
In theory agent's are tied to ExecutionContexts, and these Documents that do not have an ExecutionContext should not have their own WindowAgent.

Bug: 961186
Change-Id: Ie36a64791a3e1b424bcbf248b083fdf1bf5d465d
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1655412
Commit-Queue: Keishi Hattori <keishi@chromium.org>
Reviewed-by: default avatarDave Tapuska <dtapuska@chromium.org>
Reviewed-by: default avatarKouhei Ueno <kouhei@chromium.org>
Reviewed-by: default avatarYuta Kitamura <yutak@chromium.org>
Reviewed-by: default avatarHayato Ito <hayato@chromium.org>
Reviewed-by: default avatarKentaro Hara <haraken@chromium.org>
Cr-Commit-Position: refs/heads/master@{#669571}
parent 429351ba
...@@ -170,6 +170,8 @@ blink_core_sources("dom") { ...@@ -170,6 +170,8 @@ blink_core_sources("dom") {
"mutation_observer.h", "mutation_observer.h",
"mutation_observer_interest_group.cc", "mutation_observer_interest_group.cc",
"mutation_observer_interest_group.h", "mutation_observer_interest_group.h",
"mutation_observer_notifier.cc",
"mutation_observer_notifier.h",
"mutation_observer_registration.cc", "mutation_observer_registration.cc",
"mutation_observer_registration.h", "mutation_observer_registration.h",
"mutation_record.cc", "mutation_record.cc",
......
...@@ -115,6 +115,7 @@ ...@@ -115,6 +115,7 @@
#include "third_party/blink/renderer/core/dom/layout_tree_builder_traversal.h" #include "third_party/blink/renderer/core/dom/layout_tree_builder_traversal.h"
#include "third_party/blink/renderer/core/dom/live_node_list.h" #include "third_party/blink/renderer/core/dom/live_node_list.h"
#include "third_party/blink/renderer/core/dom/mutation_observer.h" #include "third_party/blink/renderer/core/dom/mutation_observer.h"
#include "third_party/blink/renderer/core/dom/mutation_observer_notifier.h"
#include "third_party/blink/renderer/core/dom/node_child_removal_tracker.h" #include "third_party/blink/renderer/core/dom/node_child_removal_tracker.h"
#include "third_party/blink/renderer/core/dom/node_computed_style.h" #include "third_party/blink/renderer/core/dom/node_computed_style.h"
#include "third_party/blink/renderer/core/dom/node_iterator.h" #include "third_party/blink/renderer/core/dom/node_iterator.h"
...@@ -745,20 +746,28 @@ Document::Document(const DocumentInit& initializer, ...@@ -745,20 +746,28 @@ Document::Document(const DocumentInit& initializer,
} }
InitSecurityContext(initializer); InitSecurityContext(initializer);
if (frame_) { if (frame_)
frame_->Client()->DidSetFramePolicyHeaders(GetSandboxFlags(), {}); frame_->Client()->DidSetFramePolicyHeaders(GetSandboxFlags(), {});
Document* context_document = ContextDocument();
if (context_document) {
Frame* context_document_frame = context_document->GetFrame();
CHECK(context_document_frame);
bool has_potential_universal_access_privilege = false; bool has_potential_universal_access_privilege = false;
if (Settings* settings = GetSettings()) { if (Settings* settings = context_document_frame->GetSettings()) {
// TODO(keishi): Also check if AllowUniversalAccessFromFileURLs might // TODO(keishi): Also check if AllowUniversalAccessFromFileURLs might
// dynamically change. // dynamically change.
if (!settings->GetWebSecurityEnabled() || if (!settings->GetWebSecurityEnabled() ||
settings->GetAllowUniversalAccessFromFileURLs()) settings->GetAllowUniversalAccessFromFileURLs())
has_potential_universal_access_privilege = true; has_potential_universal_access_privilege = true;
} }
SetAgent(frame_->window_agent_factory().GetAgentForOrigin( SetAgent(context_document_frame->window_agent_factory().GetAgentForOrigin(
has_potential_universal_access_privilege, GetIsolate(), has_potential_universal_access_privilege, GetIsolate(),
GetSecurityOrigin())); GetSecurityOrigin()));
} else {
// ContextDocument is null only for Documents created in unit tests.
// In that case, use a throw away WindowAgent.
SetAgent(MakeGarbageCollected<WindowAgent>(GetIsolate()));
} }
InitDNSPrefetch(); InitDNSPrefetch();
...@@ -6916,7 +6925,7 @@ void Document::TasksWereUnpaused() { ...@@ -6916,7 +6925,7 @@ void Document::TasksWereUnpaused() {
if (scripted_animation_controller_) if (scripted_animation_controller_)
scripted_animation_controller_->Unpause(); scripted_animation_controller_->Unpause();
MutationObserver::ResumeSuspendedObservers(); GetAgent().GetMutationObserverNotifier().ResumeSuspendedObservers();
if (dom_window_) if (dom_window_)
DOMWindowPerformance::performance(*dom_window_)->ResumeSuspendedObservers(); DOMWindowPerformance::performance(*dom_window_)->ResumeSuspendedObservers();
} }
...@@ -7895,6 +7904,10 @@ LazyLoadImageObserver& Document::EnsureLazyLoadImageObserver() { ...@@ -7895,6 +7904,10 @@ LazyLoadImageObserver& Document::EnsureLazyLoadImageObserver() {
return *lazy_load_image_observer_; return *lazy_load_image_observer_;
} }
WindowAgent& Document::GetAgent() {
return *static_cast<WindowAgent*>(ExecutionContext::GetAgent());
}
void Document::CountPotentialFeaturePolicyViolation( void Document::CountPotentialFeaturePolicyViolation(
mojom::FeaturePolicyFeature feature) const { mojom::FeaturePolicyFeature feature) const {
size_t index = static_cast<size_t>(feature); size_t index = static_cast<size_t>(feature);
......
...@@ -99,6 +99,7 @@ class CanvasFontCache; ...@@ -99,6 +99,7 @@ class CanvasFontCache;
class ChromeClient; class ChromeClient;
class Comment; class Comment;
class ComputedAccessibleNode; class ComputedAccessibleNode;
class WindowAgent;
class ComputedStyle; class ComputedStyle;
class ConsoleMessage; class ConsoleMessage;
class ContextFeatures; class ContextFeatures;
...@@ -1478,6 +1479,9 @@ class CORE_EXPORT Document : public ContainerNode, ...@@ -1478,6 +1479,9 @@ class CORE_EXPORT Document : public ContainerNode,
LazyLoadImageObserver& EnsureLazyLoadImageObserver(); LazyLoadImageObserver& EnsureLazyLoadImageObserver();
// Agent may be null for Documents created in unit tests.
WindowAgent& GetAgent();
// TODO(binji): See http://crbug.com/798572. This implementation shares the // TODO(binji): See http://crbug.com/798572. This implementation shares the
// same agent cluster ID for any one document. The proper implementation of // same agent cluster ID for any one document. The proper implementation of
// this function must follow the rules described here: // this function must follow the rules described here:
......
...@@ -36,10 +36,12 @@ ...@@ -36,10 +36,12 @@
#include "third_party/blink/renderer/bindings/core/v8/v8_mutation_callback.h" #include "third_party/blink/renderer/bindings/core/v8/v8_mutation_callback.h"
#include "third_party/blink/renderer/core/dom/document.h" #include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/dom/mutation_observer_init.h" #include "third_party/blink/renderer/core/dom/mutation_observer_init.h"
#include "third_party/blink/renderer/core/dom/mutation_observer_notifier.h"
#include "third_party/blink/renderer/core/dom/mutation_observer_registration.h" #include "third_party/blink/renderer/core/dom/mutation_observer_registration.h"
#include "third_party/blink/renderer/core/dom/mutation_record.h" #include "third_party/blink/renderer/core/dom/mutation_record.h"
#include "third_party/blink/renderer/core/dom/node.h" #include "third_party/blink/renderer/core/dom/node.h"
#include "third_party/blink/renderer/core/execution_context/execution_context.h" #include "third_party/blink/renderer/core/execution_context/execution_context.h"
#include "third_party/blink/renderer/core/execution_context/window_agent.h"
#include "third_party/blink/renderer/core/html/html_slot_element.h" #include "third_party/blink/renderer/core/html/html_slot_element.h"
#include "third_party/blink/renderer/core/probe/core_probes.h" #include "third_party/blink/renderer/core/probe/core_probes.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h" #include "third_party/blink/renderer/platform/bindings/exception_state.h"
...@@ -83,15 +85,6 @@ class MutationObserver::V8DelegateImpl final ...@@ -83,15 +85,6 @@ class MutationObserver::V8DelegateImpl final
Member<V8MutationCallback> callback_; Member<V8MutationCallback> callback_;
}; };
static unsigned g_observer_priority = 0;
struct MutationObserver::ObserverLessThan {
bool operator()(const Member<MutationObserver>& lhs,
const Member<MutationObserver>& rhs) {
return lhs->priority_ < rhs->priority_;
}
};
MutationObserver* MutationObserver::Create(Delegate* delegate) { MutationObserver* MutationObserver::Create(Delegate* delegate) {
DCHECK(IsMainThread()); DCHECK(IsMainThread());
return MakeGarbageCollected<MutationObserver>(delegate->GetExecutionContext(), return MakeGarbageCollected<MutationObserver>(delegate->GetExecutionContext(),
...@@ -108,9 +101,12 @@ MutationObserver* MutationObserver::Create(ScriptState* script_state, ...@@ -108,9 +101,12 @@ MutationObserver* MutationObserver::Create(ScriptState* script_state,
MutationObserver::MutationObserver(ExecutionContext* execution_context, MutationObserver::MutationObserver(ExecutionContext* execution_context,
Delegate* delegate) Delegate* delegate)
: ContextClient(execution_context), : ContextClient(execution_context), delegate_(delegate) {
delegate_(delegate), priority_ = GetDocument()
priority_(g_observer_priority++) {} ->GetAgent()
.GetMutationObserverNotifier()
.NextObserverPriority();
}
MutationObserver::~MutationObserver() { MutationObserver::~MutationObserver() {
CancelInspectorAsyncTasks(); CancelInspectorAsyncTasks();
...@@ -221,66 +217,35 @@ void MutationObserver::ObservationEnded( ...@@ -221,66 +217,35 @@ void MutationObserver::ObservationEnded(
registrations_.erase(registration); registrations_.erase(registration);
} }
static MutationObserverSet& ActiveMutationObservers() { // static
DEFINE_STATIC_LOCAL(Persistent<MutationObserverSet>, active_observers,
(MakeGarbageCollected<MutationObserverSet>()));
return *active_observers;
}
using SlotChangeList = HeapVector<Member<HTMLSlotElement>>;
// TODO(hayato): We should have a SlotChangeList for each unit of related
// similar-origin browsing context.
// https://html.spec.whatwg.org/C/#unit-of-related-similar-origin-browsing-contexts
static SlotChangeList& ActiveSlotChangeList() {
DEFINE_STATIC_LOCAL(Persistent<SlotChangeList>, slot_change_list,
(MakeGarbageCollected<SlotChangeList>()));
return *slot_change_list;
}
static MutationObserverSet& SuspendedMutationObservers() {
DEFINE_STATIC_LOCAL(Persistent<MutationObserverSet>, suspended_observers,
(MakeGarbageCollected<MutationObserverSet>()));
return *suspended_observers;
}
static void EnsureEnqueueMicrotask() {
if (ActiveMutationObservers().IsEmpty() && ActiveSlotChangeList().IsEmpty())
Microtask::EnqueueMicrotask(WTF::Bind(&MutationObserver::DeliverMutations));
}
void MutationObserver::EnqueueSlotChange(HTMLSlotElement& slot) { void MutationObserver::EnqueueSlotChange(HTMLSlotElement& slot) {
DCHECK(IsMainThread()); DCHECK(IsMainThread());
EnsureEnqueueMicrotask(); slot.GetDocument().GetAgent().GetMutationObserverNotifier().EnqueueSlotChange(
ActiveSlotChangeList().push_back(&slot); slot);
} }
// static
void MutationObserver::CleanSlotChangeList(Document& document) { void MutationObserver::CleanSlotChangeList(Document& document) {
SlotChangeList kept; document.GetAgent().GetMutationObserverNotifier().CleanSlotChangeList(
kept.ReserveCapacity(ActiveSlotChangeList().size()); document);
for (auto& slot : ActiveSlotChangeList()) {
if (slot->GetDocument() != document)
kept.push_back(slot);
}
ActiveSlotChangeList().swap(kept);
} }
static void ActivateObserver(MutationObserver* observer) { void MutationObserver::Activate() {
EnsureEnqueueMicrotask(); GetDocument()->GetAgent().GetMutationObserverNotifier().ActivateObserver(
ActiveMutationObservers().insert(observer); this);
} }
void MutationObserver::EnqueueMutationRecord(MutationRecord* mutation) { void MutationObserver::EnqueueMutationRecord(MutationRecord* mutation) {
DCHECK(IsMainThread()); DCHECK(IsMainThread());
records_.push_back(mutation); records_.push_back(mutation);
ActivateObserver(this); Activate();
probe::AsyncTaskScheduled(delegate_->GetExecutionContext(), mutation->type(), probe::AsyncTaskScheduled(delegate_->GetExecutionContext(), mutation->type(),
mutation); mutation);
} }
void MutationObserver::SetHasTransientRegistration() { void MutationObserver::SetHasTransientRegistration() {
DCHECK(IsMainThread()); DCHECK(IsMainThread());
ActivateObserver(this); Activate();
} }
HeapHashSet<Member<Node>> MutationObserver::GetObservedNodes() const { HeapHashSet<Member<Node>> MutationObserver::GetObservedNodes() const {
...@@ -326,52 +291,6 @@ void MutationObserver::Deliver() { ...@@ -326,52 +291,6 @@ void MutationObserver::Deliver() {
delegate_->Deliver(records, *this); delegate_->Deliver(records, *this);
} }
void MutationObserver::ResumeSuspendedObservers() {
DCHECK(IsMainThread());
if (SuspendedMutationObservers().IsEmpty())
return;
MutationObserverVector suspended;
CopyToVector(SuspendedMutationObservers(), suspended);
for (const auto& observer : suspended) {
if (!observer->ShouldBeSuspended()) {
SuspendedMutationObservers().erase(observer);
ActivateObserver(observer);
}
}
}
void MutationObserver::DeliverMutations() {
// These steps are defined in DOM Standard's "notify mutation observers".
// https://dom.spec.whatwg.org/#notify-mutation-observers
DCHECK(IsMainThread());
MutationObserverVector observers;
CopyToVector(ActiveMutationObservers(), observers);
ActiveMutationObservers().clear();
SlotChangeList slots;
slots.swap(ActiveSlotChangeList());
for (const auto& slot : slots)
slot->ClearSlotChangeEventEnqueued();
std::sort(observers.begin(), observers.end(), ObserverLessThan());
for (const auto& observer : observers) {
if (!observer->GetExecutionContext()) {
// The observer's execution context is already gone, as active observers
// intentionally do not hold their execution context. Do nothing then.
continue;
}
if (observer->ShouldBeSuspended())
SuspendedMutationObservers().insert(observer);
else
observer->Deliver();
}
for (const auto& slot : slots)
slot->DispatchSlotChangeEvent();
}
void MutationObserver::Trace(Visitor* visitor) { void MutationObserver::Trace(Visitor* visitor) {
visitor->Trace(delegate_); visitor->Trace(delegate_);
visitor->Trace(records_); visitor->Trace(records_);
......
...@@ -56,10 +56,8 @@ class Node; ...@@ -56,10 +56,8 @@ class Node;
class ScriptState; class ScriptState;
class V8MutationCallback; class V8MutationCallback;
using MutationObserverSet = HeapHashSet<Member<MutationObserver>>;
using MutationObserverRegistrationSet = using MutationObserverRegistrationSet =
HeapHashSet<WeakMember<MutationObserverRegistration>>; HeapHashSet<WeakMember<MutationObserverRegistration>>;
using MutationObserverVector = HeapVector<Member<MutationObserver>>;
using MutationRecordVector = HeapVector<Member<MutationRecord>>; using MutationRecordVector = HeapVector<Member<MutationRecord>>;
class CORE_EXPORT MutationObserver final class CORE_EXPORT MutationObserver final
...@@ -94,8 +92,6 @@ class CORE_EXPORT MutationObserver final ...@@ -94,8 +92,6 @@ class CORE_EXPORT MutationObserver final
static MutationObserver* Create(Delegate*); static MutationObserver* Create(Delegate*);
static MutationObserver* Create(ScriptState*, V8MutationCallback*); static MutationObserver* Create(ScriptState*, V8MutationCallback*);
static void ResumeSuspendedObservers();
static void DeliverMutations();
static void EnqueueSlotChange(HTMLSlotElement&); static void EnqueueSlotChange(HTMLSlotElement&);
static void CleanSlotChangeList(Document&); static void CleanSlotChangeList(Document&);
...@@ -118,12 +114,14 @@ class CORE_EXPORT MutationObserver final ...@@ -118,12 +114,14 @@ class CORE_EXPORT MutationObserver final
EAGERLY_FINALIZE(); EAGERLY_FINALIZE();
void Trace(Visitor*) override; void Trace(Visitor*) override;
private: // Methods to be used by MutationObserverNotifier
struct ObserverLessThan;
void Deliver(); void Deliver();
bool ShouldBeSuspended() const; bool ShouldBeSuspended() const;
void CancelInspectorAsyncTasks(); void CancelInspectorAsyncTasks();
unsigned priority() { return priority_; }
private:
void Activate();
Member<Delegate> delegate_; Member<Delegate> delegate_;
HeapVector<Member<MutationRecord>> records_; HeapVector<Member<MutationRecord>> records_;
......
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "third_party/blink/renderer/core/dom/mutation_observer_notifier.h"
#include "third_party/blink/renderer/core/dom/mutation_observer.h"
#include "third_party/blink/renderer/core/html/html_slot_element.h"
#include "third_party/blink/renderer/platform/bindings/microtask.h"
namespace blink {
MutationObserverNotifier::MutationObserverNotifier() {}
void MutationObserverNotifier::EnqueueSlotChange(HTMLSlotElement& slot) {
EnqueueMicrotaskIfNecessary();
active_slot_change_list_.push_back(&slot);
}
void MutationObserverNotifier::CleanSlotChangeList(Document& document) {
SlotChangeList kept;
kept.ReserveCapacity(active_slot_change_list_.size());
for (auto& slot : active_slot_change_list_) {
if (slot->GetDocument() != document)
kept.push_back(slot);
}
active_slot_change_list_.swap(kept);
}
void MutationObserverNotifier::ActivateObserver(MutationObserver* observer) {
EnqueueMicrotaskIfNecessary();
active_mutation_observers_.insert(observer);
}
void MutationObserverNotifier::EnqueueMicrotaskIfNecessary() {
if (microtask_enqueued_) {
return;
}
// If this is called before inserting the observer or slot, they should both
// be empty.
DCHECK(active_mutation_observers_.IsEmpty());
DCHECK(active_slot_change_list_.IsEmpty());
microtask_enqueued_ = true;
Microtask::EnqueueMicrotask(WTF::Bind(
&MutationObserverNotifier::DeliverMutations, WrapPersistent(this)));
}
struct MutationObserverNotifier::ObserverLessThan {
bool operator()(const Member<MutationObserver>& lhs,
const Member<MutationObserver>& rhs) {
return lhs->priority() < rhs->priority();
}
};
void MutationObserverNotifier::DeliverMutations() {
// These steps are defined in DOM Standard's "notify mutation observers".
// https://dom.spec.whatwg.org/#notify-mutation-observers
DCHECK(IsMainThread());
microtask_enqueued_ = false;
MutationObserverVector observers;
CopyToVector(active_mutation_observers_, observers);
active_mutation_observers_.clear();
SlotChangeList slots;
slots.swap(active_slot_change_list_);
for (const auto& slot : slots)
slot->ClearSlotChangeEventEnqueued();
std::sort(observers.begin(), observers.end(), ObserverLessThan());
for (const auto& observer : observers) {
if (!observer->GetExecutionContext()) {
// The observer's execution context is already gone, as active observers
// intentionally do not hold their execution context. Do nothing then.
continue;
}
if (observer->ShouldBeSuspended())
suspended_mutation_observers_.insert(observer);
else
observer->Deliver();
}
for (const auto& slot : slots)
slot->DispatchSlotChangeEvent();
}
void MutationObserverNotifier::ResumeSuspendedObservers() {
DCHECK(IsMainThread());
if (suspended_mutation_observers_.IsEmpty())
return;
MutationObserverVector suspended;
CopyToVector(suspended_mutation_observers_, suspended);
for (const auto& observer : suspended) {
if (!observer->ShouldBeSuspended()) {
suspended_mutation_observers_.erase(observer);
ActivateObserver(observer);
}
}
}
unsigned MutationObserverNotifier::NextObserverPriority() {
return ++last_observer_priority_;
}
void MutationObserverNotifier::Trace(Visitor* visitor) {
visitor->Trace(active_mutation_observers_);
visitor->Trace(suspended_mutation_observers_);
visitor->Trace(active_slot_change_list_);
}
} // namespace blink
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_DOM_MUTATION_OBSERVER_NOTIFIER_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_DOM_MUTATION_OBSERVER_NOTIFIER_H_
#include "third_party/blink/renderer/platform/heap/handle.h"
namespace blink {
class Document;
class MutationObserver;
class HTMLSlotElement;
// In charge of mutation observer related state that should be managed per
// WindowAgent.
class MutationObserverNotifier final
: public GarbageCollectedFinalized<MutationObserverNotifier> {
public:
MutationObserverNotifier();
void Trace(Visitor*);
void EnqueueSlotChange(HTMLSlotElement&);
void CleanSlotChangeList(Document&);
void ActivateObserver(MutationObserver*);
void ResumeSuspendedObservers();
// Returns the priority that should be assigned to the next MutationObserver.
unsigned NextObserverPriority();
// Callback called to deliver the accumulated mutations.
void DeliverMutations();
private:
struct ObserverLessThan;
// Schedules the DeliverMutations() callback if necessary.
void EnqueueMicrotaskIfNecessary();
using MutationObserverSet = HeapHashSet<Member<MutationObserver>>;
using SlotChangeList = HeapVector<Member<HTMLSlotElement>>;
using MutationObserverVector = HeapVector<Member<MutationObserver>>;
bool microtask_enqueued_ = false;
MutationObserverSet active_mutation_observers_;
MutationObserverSet suspended_mutation_observers_;
SlotChangeList active_slot_change_list_;
unsigned last_observer_priority_ = 0;
};
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_CORE_DOM_MUTATION_OBSERVER_NOTIFIER_H_
...@@ -3,18 +3,21 @@ ...@@ -3,18 +3,21 @@
// found in the LICENSE file. // found in the LICENSE file.
#include "third_party/blink/renderer/core/execution_context/window_agent.h" #include "third_party/blink/renderer/core/execution_context/window_agent.h"
#include "third_party/blink/renderer/core/dom/mutation_observer.h"
#include "third_party/blink/renderer/core/html/custom/custom_element_reaction_stack.h" #include "third_party/blink/renderer/core/dom/mutation_observer_notifier.h"
#include "third_party/blink/renderer/platform/scheduler/public/event_loop.h"
namespace blink { namespace blink {
WindowAgent::WindowAgent(v8::Isolate* isolate) : Agent(isolate) {} WindowAgent::WindowAgent(v8::Isolate* isolate)
: Agent(isolate),
mutation_observer_notifier_(
MakeGarbageCollected<MutationObserverNotifier>()) {}
WindowAgent::~WindowAgent() = default; WindowAgent::~WindowAgent() = default;
void WindowAgent::Trace(Visitor* visitor) { void WindowAgent::Trace(Visitor* visitor) {
Agent::Trace(visitor); Agent::Trace(visitor);
visitor->Trace(mutation_observer_notifier_);
} }
} // namespace blink } // namespace blink
...@@ -6,7 +6,6 @@ ...@@ -6,7 +6,6 @@
#define THIRD_PARTY_BLINK_RENDERER_CORE_EXECUTION_CONTEXT_WINDOW_AGENT_H_ #define THIRD_PARTY_BLINK_RENDERER_CORE_EXECUTION_CONTEXT_WINDOW_AGENT_H_
#include "third_party/blink/renderer/core/execution_context/agent.h" #include "third_party/blink/renderer/core/execution_context/agent.h"
#include "third_party/blink/renderer/platform/heap/heap.h"
namespace v8 { namespace v8 {
class Isolate; class Isolate;
...@@ -14,6 +13,8 @@ class Isolate; ...@@ -14,6 +13,8 @@ class Isolate;
namespace blink { namespace blink {
class MutationObserverNotifier;
// This corresponds to similar-origin window agent, that is shared by a group // This corresponds to similar-origin window agent, that is shared by a group
// of Documents that are mutually reachable and have the same-site origins. // of Documents that are mutually reachable and have the same-site origins.
// https://html.spec.whatwg.org/C#similar-origin-window-agent // https://html.spec.whatwg.org/C#similar-origin-window-agent
...@@ -29,10 +30,16 @@ class WindowAgent final : public Agent { ...@@ -29,10 +30,16 @@ class WindowAgent final : public Agent {
void Trace(blink::Visitor*) override; void Trace(blink::Visitor*) override;
MutationObserverNotifier& GetMutationObserverNotifier() {
return *mutation_observer_notifier_;
}
private: private:
// For MutationObserver.
Member<MutationObserverNotifier> mutation_observer_notifier_;
// TODO(tzik): Move per-agent data here with the correct granularity. // TODO(tzik): Move per-agent data here with the correct granularity.
// E.g. ActiveMutationObservers and CustomElementReactionStack should move // E.g. CustomElementReactionStack should move here.
// here.
}; };
} // namespace blink } // namespace blink
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment