Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(31)

Side by Side Diff: third_party/WebKit/Source/web/WebFormElementObserverImpl.cpp

Issue 2865233003: Use an MutationObserver to check when a password form disappears after XHR (Closed)
Patch Set: updates Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2017 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "web/WebFormElementObserverImpl.h"
6
7 #include "core/css/CSSComputedStyleDeclaration.h"
8 #include "core/dom/MutationCallback.h"
9 #include "core/dom/MutationObserver.h"
10 #include "core/dom/MutationObserverInit.h"
11 #include "core/dom/MutationRecord.h"
12 #include "core/dom/StaticNodeList.h"
13 #include "core/html/HTMLElement.h"
14 #include "core/html/HTMLFormElement.h"
15 #include "core/html/HTMLInputElement.h"
16 #include "public/web/WebFormElement.h"
17 #include "public/web/WebInputElement.h"
18 #include "public/web/modules/password_manager/WebFormElementObserverCallback.h"
19
20 namespace blink {
21
22 class WebFormElementObserverImpl::ObserverCallback : public MutationCallback {
23 public:
24 ObserverCallback(HTMLElement&,
25 std::unique_ptr<WebFormElementObserverCallback>);
26 DECLARE_VIRTUAL_TRACE();
27
28 ExecutionContext* GetExecutionContext() const override;
29
30 void Disconnect();
31
32 private:
33 void Call(const HeapVector<Member<MutationRecord>>& records,
34 MutationObserver*) override;
35
36 Member<HTMLElement> element_;
37 Member<MutationObserver> mutation_observer_;
38 std::unique_ptr<WebFormElementObserverCallback> callback_;
39 };
40
41 WebFormElementObserverImpl::ObserverCallback::ObserverCallback(
42 HTMLElement& element,
43 std::unique_ptr<WebFormElementObserverCallback> callback)
44 : element_(&element), callback_(std::move(callback)) {
45 DCHECK(element.ownerDocument());
46 mutation_observer_ = MutationObserver::Create(this);
47
48 {
49 Vector<String> filter;
50 filter.ReserveCapacity(3);
51 filter.push_back(String("action"));
52 filter.push_back(String("class"));
53 filter.push_back(String("style"));
54 MutationObserverInit init;
55 init.setAttributes(true);
56 init.setAttributeFilter(filter);
57 mutation_observer_->observe(element_, init, ASSERT_NO_EXCEPTION);
58 }
59 {
60 MutationObserverInit init;
61 init.setChildList(true);
62 mutation_observer_->observe(element_->parentElement(), init,
63 ASSERT_NO_EXCEPTION);
64 }
65 }
66
67 ExecutionContext*
68 WebFormElementObserverImpl::ObserverCallback::GetExecutionContext() const {
69 return element_->ownerDocument();
70 }
71
72 void WebFormElementObserverImpl::ObserverCallback::Disconnect() {
73 mutation_observer_->disconnect();
74 callback_.reset();
75 }
76
77 void WebFormElementObserverImpl::ObserverCallback::Call(
78 const HeapVector<Member<MutationRecord>>& records,
79 MutationObserver*) {
80 for (const auto& record : records) {
81 if (record->type() == "childList") {
82 for (unsigned i = 0; i < record->removedNodes()->length(); ++i) {
83 if (record->removedNodes()->item(i) != element_)
84 continue;
85 callback_->ElementWasHiddenOrRemoved();
86 Disconnect();
87 return;
88 }
89 } else {
90 HTMLElement& element = *ToHTMLElement(record->target());
91 if (record->attributeName() == "action") {
92 // If the action was modified, we just assume that the form as
93 // submitted.
94 callback_->ElementWasHiddenOrRemoved();
95 Disconnect();
96 return;
97 }
98 // Otherwise, either "style" or "class" was modified. Check the
99 // computed style.
100 CSSComputedStyleDeclaration* style =
101 CSSComputedStyleDeclaration::Create(&element);
102 if (style->GetPropertyValue(CSSPropertyDisplay) == "none") {
103 callback_->ElementWasHiddenOrRemoved();
104 Disconnect();
105 return;
106 }
107 }
108 }
109 }
110
111 DEFINE_TRACE(WebFormElementObserverImpl::ObserverCallback) {
112 visitor->Trace(element_);
113 visitor->Trace(mutation_observer_);
114 MutationCallback::Trace(visitor);
115 }
116
117 WebFormElementObserver* WebFormElementObserver::Create(
118 WebFormElement& element,
119 std::unique_ptr<WebFormElementObserverCallback> callback) {
120 return new WebFormElementObserverImpl(*element.Unwrap<HTMLFormElement>(),
121 std::move(callback));
122 }
123
124 WebFormElementObserver* WebFormElementObserver::Create(
125 WebInputElement& element,
126 std::unique_ptr<WebFormElementObserverCallback> callback) {
127 return new WebFormElementObserverImpl(*element.Unwrap<HTMLInputElement>(),
128 std::move(callback));
129 }
130
131 WebFormElementObserverImpl::WebFormElementObserverImpl(
132 HTMLElement& element,
133 std::unique_ptr<WebFormElementObserverCallback> callback)
134 : self_keep_alive_(this) {
135 mutation_callback_ = new ObserverCallback(element, std::move(callback));
136 }
137
138 WebFormElementObserverImpl::~WebFormElementObserverImpl() {}
139
140 void WebFormElementObserverImpl::Disconnect() {
141 mutation_callback_->Disconnect();
142 mutation_callback_ = nullptr;
143 self_keep_alive_.Clear();
144 }
145
146 DEFINE_TRACE(WebFormElementObserverImpl) {
147 visitor->Trace(mutation_callback_);
148 }
149
150 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698