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

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

Issue 2408333004: Move persistent gesture state to Document, add DocumentUserGestureToken (Closed)
Patch Set: a Created 4 years, 2 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
1 /* 1 /*
2 * Copyright (C) 2011, 2012 Google Inc. All rights reserved. 2 * Copyright (C) 2011, 2012 Google Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are 5 * modification, are permitted provided that the following conditions are
6 * met: 6 * met:
7 * 7 *
8 * * Redistributions of source code must retain the above copyright 8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above 10 * * Redistributions in binary form must reproduce the above
(...skipping 17 matching lines...) Expand all
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */ 29 */
30 30
31 #include "web/WebViewImpl.h" 31 #include "web/WebViewImpl.h"
32 32
33 #include "core/CSSValueKeywords.h" 33 #include "core/CSSValueKeywords.h"
34 #include "core/HTMLNames.h" 34 #include "core/HTMLNames.h"
35 #include "core/InputTypeNames.h" 35 #include "core/InputTypeNames.h"
36 #include "core/clipboard/DataObject.h" 36 #include "core/clipboard/DataObject.h"
37 #include "core/dom/Document.h" 37 #include "core/dom/Document.h"
38 #include "core/dom/DocumentUserGestureToken.h"
38 #include "core/dom/Fullscreen.h" 39 #include "core/dom/Fullscreen.h"
39 #include "core/dom/LayoutTreeBuilderTraversal.h" 40 #include "core/dom/LayoutTreeBuilderTraversal.h"
40 #include "core/dom/Text.h" 41 #include "core/dom/Text.h"
41 #include "core/editing/EditingUtilities.h" 42 #include "core/editing/EditingUtilities.h"
42 #include "core/editing/Editor.h" 43 #include "core/editing/Editor.h"
43 #include "core/editing/FrameSelection.h" 44 #include "core/editing/FrameSelection.h"
44 #include "core/editing/InputMethodController.h" 45 #include "core/editing/InputMethodController.h"
45 #include "core/editing/iterators/TextIterator.h" 46 #include "core/editing/iterators/TextIterator.h"
46 #include "core/editing/markers/DocumentMarkerController.h" 47 #include "core/editing/markers/DocumentMarkerController.h"
47 #include "core/editing/serializers/HTMLInterchange.h" 48 #include "core/editing/serializers/HTMLInterchange.h"
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after
255 256
256 static bool shouldUseExternalPopupMenus = false; 257 static bool shouldUseExternalPopupMenus = false;
257 258
258 namespace { 259 namespace {
259 260
260 class UserGestureNotifier { 261 class UserGestureNotifier {
261 public: 262 public:
262 // If a UserGestureIndicator is created for a user gesture since the last 263 // If a UserGestureIndicator is created for a user gesture since the last
263 // page load and *userGestureObserved is false, the UserGestureNotifier 264 // page load and *userGestureObserved is false, the UserGestureNotifier
264 // will notify the client and set *userGestureObserved to true. 265 // will notify the client and set *userGestureObserved to true.
265 UserGestureNotifier(WebAutofillClient*, bool* userGestureObserved); 266 UserGestureNotifier(WebLocalFrameImpl*, bool* userGestureObserved);
266 ~UserGestureNotifier(); 267 ~UserGestureNotifier();
267 268
268 private: 269 private:
269 WebAutofillClient* const m_client; 270 Persistent<WebLocalFrameImpl> m_frame;
270 bool* const m_userGestureObserved; 271 bool* const m_userGestureObserved;
271 }; 272 };
272 273
273 UserGestureNotifier::UserGestureNotifier(WebAutofillClient* client, 274 UserGestureNotifier::UserGestureNotifier(WebLocalFrameImpl* frame,
274 bool* userGestureObserved) 275 bool* userGestureObserved)
275 : m_client(client), m_userGestureObserved(userGestureObserved) { 276 : m_frame(frame), m_userGestureObserved(userGestureObserved) {
276 DCHECK(m_userGestureObserved); 277 DCHECK(m_userGestureObserved);
277 } 278 }
278 279
279 UserGestureNotifier::~UserGestureNotifier() { 280 UserGestureNotifier::~UserGestureNotifier() {
280 if (!*m_userGestureObserved && 281 if (!*m_userGestureObserved &&
281 UserGestureIndicator::processedUserGestureSinceLoad()) { 282 m_frame->frame()->document()->hasReceivedUserGesture()) {
282 *m_userGestureObserved = true; 283 *m_userGestureObserved = true;
283 if (m_client) 284 if (m_frame && m_frame->autofillClient())
284 m_client->firstUserGestureObserved(); 285 m_frame->autofillClient()->firstUserGestureObserved();
Rick Byers 2016/10/17 17:02:47 Is there a notifier per frame? You should probabl
Nate Chapin 2016/10/18 23:26:33 Yes, the notifier is per-frame, and UserGestureNot
ojan 2016/10/18 23:40:25 I suspect it's not OK since a lot of times passwor
Mathieu 2016/10/19 17:20:31 Ojan is correct. More and more payments and passwo
285 } 286 }
286 } 287 }
287 288
288 class EmptyEventListener final : public EventListener { 289 class EmptyEventListener final : public EventListener {
289 public: 290 public:
290 static EmptyEventListener* create() { return new EmptyEventListener(); } 291 static EmptyEventListener* create() { return new EmptyEventListener(); }
291 292
292 bool operator==(const EventListener& other) const override { 293 bool operator==(const EventListener& other) const override {
293 return this == &other; 294 return this == &other;
294 } 295 }
(...skipping 1921 matching lines...) Expand 10 before | Expand all | Expand 10 after
2216 2217
2217 WebInputEventResult WebViewImpl::handleInputEvent( 2218 WebInputEventResult WebViewImpl::handleInputEvent(
2218 const WebInputEvent& inputEvent) { 2219 const WebInputEvent& inputEvent) {
2219 // TODO(dcheng): The fact that this is getting called when there is no local 2220 // TODO(dcheng): The fact that this is getting called when there is no local
2220 // main frame is problematic and probably indicates a bug in the input event 2221 // main frame is problematic and probably indicates a bug in the input event
2221 // routing code. 2222 // routing code.
2222 if (!mainFrameImpl()) 2223 if (!mainFrameImpl())
2223 return WebInputEventResult::NotHandled; 2224 return WebInputEventResult::NotHandled;
2224 2225
2225 WebAutofillClient* autofillClient = mainFrameImpl()->autofillClient(); 2226 WebAutofillClient* autofillClient = mainFrameImpl()->autofillClient();
2226 UserGestureNotifier notifier(autofillClient, &m_userGestureObserved); 2227 UserGestureNotifier notifier(mainFrameImpl(), &m_userGestureObserved);
2227 // On the first input event since page load, |notifier| instructs the 2228 // On the first input event since page load, |notifier| instructs the
2228 // autofill client to unblock values of password input fields of any forms 2229 // autofill client to unblock values of password input fields of any forms
2229 // on the page. There is a single input event, GestureTap, which can both 2230 // on the page. There is a single input event, GestureTap, which can both
2230 // be the first event after page load, and cause a form submission. In that 2231 // be the first event after page load, and cause a form submission. In that
2231 // case, the form submission happens before the autofill client is told 2232 // case, the form submission happens before the autofill client is told
2232 // to unblock the password values, and so the password values are not 2233 // to unblock the password values, and so the password values are not
2233 // submitted. To avoid that, GestureTap is handled explicitly: 2234 // submitted. To avoid that, GestureTap is handled explicitly:
2234 if (inputEvent.type == WebInputEvent::GestureTap && autofillClient) { 2235 if (inputEvent.type == WebInputEvent::GestureTap && autofillClient) {
2235 m_userGestureObserved = true; 2236 m_userGestureObserved = true;
2236 autofillClient->firstUserGestureObserved(); 2237 autofillClient->firstUserGestureObserved();
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
2287 AtomicString eventType; 2288 AtomicString eventType;
2288 switch (inputEvent.type) { 2289 switch (inputEvent.type) {
2289 case WebInputEvent::MouseMove: 2290 case WebInputEvent::MouseMove:
2290 eventType = EventTypeNames::mousemove; 2291 eventType = EventTypeNames::mousemove;
2291 break; 2292 break;
2292 case WebInputEvent::MouseLeave: 2293 case WebInputEvent::MouseLeave:
2293 eventType = EventTypeNames::mouseout; 2294 eventType = EventTypeNames::mouseout;
2294 break; 2295 break;
2295 case WebInputEvent::MouseDown: 2296 case WebInputEvent::MouseDown:
2296 eventType = EventTypeNames::mousedown; 2297 eventType = EventTypeNames::mousedown;
2297 gestureIndicator = wrapUnique(new UserGestureIndicator( 2298 gestureIndicator = wrapUnique(
2298 UserGestureToken::create(UserGestureToken::NewGesture))); 2299 new UserGestureIndicator(DocumentUserGestureToken::create(
2300 &node->document(), UserGestureToken::NewGesture)));
2299 m_mouseCaptureGestureToken = gestureIndicator->currentToken(); 2301 m_mouseCaptureGestureToken = gestureIndicator->currentToken();
2300 break; 2302 break;
2301 case WebInputEvent::MouseUp: 2303 case WebInputEvent::MouseUp:
2302 eventType = EventTypeNames::mouseup; 2304 eventType = EventTypeNames::mouseup;
2303 gestureIndicator = wrapUnique( 2305 gestureIndicator = wrapUnique(
2304 new UserGestureIndicator(m_mouseCaptureGestureToken.release())); 2306 new UserGestureIndicator(m_mouseCaptureGestureToken.release()));
2305 break; 2307 break;
2306 default: 2308 default:
2307 NOTREACHED(); 2309 NOTREACHED();
2308 } 2310 }
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after
2461 } 2463 }
2462 2464
2463 // A keypress event is canceled. If an ongoing composition exists, then the 2465 // A keypress event is canceled. If an ongoing composition exists, then the
2464 // keydown event should have arisen from a handled key (e.g., backspace). 2466 // keydown event should have arisen from a handled key (e.g., backspace).
2465 // In this case we ignore the cancellation and continue; otherwise (no 2467 // In this case we ignore the cancellation and continue; otherwise (no
2466 // ongoing composition) we exit and signal success only for attempts to 2468 // ongoing composition) we exit and signal success only for attempts to
2467 // clear the composition. 2469 // clear the composition.
2468 if (m_suppressNextKeypressEvent && !inputMethodController.hasComposition()) 2470 if (m_suppressNextKeypressEvent && !inputMethodController.hasComposition())
2469 return text.isEmpty(); 2471 return text.isEmpty();
2470 2472
2471 UserGestureIndicator gestureIndicator( 2473 UserGestureIndicator gestureIndicator(DocumentUserGestureToken::create(
2472 UserGestureToken::create(UserGestureToken::NewGesture)); 2474 focused->document(), UserGestureToken::NewGesture));
2473 2475
2474 // When the range of composition underlines overlap with the range between 2476 // When the range of composition underlines overlap with the range between
2475 // selectionStart and selectionEnd, WebKit somehow won't paint the selection 2477 // selectionStart and selectionEnd, WebKit somehow won't paint the selection
2476 // at all (see InlineTextBox::paint() function in InlineTextBox.cpp). 2478 // at all (see InlineTextBox::paint() function in InlineTextBox.cpp).
2477 // But the selection range actually takes effect. 2479 // But the selection range actually takes effect.
2478 inputMethodController.setComposition( 2480 inputMethodController.setComposition(
2479 String(text), CompositionUnderlineVectorBuilder(underlines), 2481 String(text), CompositionUnderlineVectorBuilder(underlines),
2480 selectionStart, selectionEnd); 2482 selectionStart, selectionEnd);
2481 2483
2482 return text.isEmpty() || inputMethodController.hasComposition(); 2484 return text.isEmpty() || inputMethodController.hasComposition();
(...skipping 10 matching lines...) Expand all
2493 if (WebPlugin* plugin = focusedPluginIfInputMethodSupported(focused)) 2495 if (WebPlugin* plugin = focusedPluginIfInputMethodSupported(focused))
2494 return plugin->finishComposingText(selectionBehavior); 2496 return plugin->finishComposingText(selectionBehavior);
2495 2497
2496 return focused->inputMethodController().finishComposingText( 2498 return focused->inputMethodController().finishComposingText(
2497 selectionBehavior == KeepSelection 2499 selectionBehavior == KeepSelection
2498 ? InputMethodController::KeepSelection 2500 ? InputMethodController::KeepSelection
2499 : InputMethodController::DoNotKeepSelection); 2501 : InputMethodController::DoNotKeepSelection);
2500 } 2502 }
2501 2503
2502 bool WebViewImpl::commitText(const WebString& text, int relativeCaretPosition) { 2504 bool WebViewImpl::commitText(const WebString& text, int relativeCaretPosition) {
2503 UserGestureIndicator gestureIndicator(
2504 UserGestureToken::create(UserGestureToken::NewGesture));
2505 2505
2506 LocalFrame* focused = focusedLocalFrameAvailableForIme(); 2506 LocalFrame* focused = focusedLocalFrameAvailableForIme();
2507 if (!focused) 2507 if (!focused)
2508 return false; 2508 return false;
2509 2509
2510 UserGestureIndicator gestureIndicator(DocumentUserGestureToken::create(
2511 focused->document(), UserGestureToken::NewGesture));
2512
2510 if (WebPlugin* plugin = focusedPluginIfInputMethodSupported(focused)) 2513 if (WebPlugin* plugin = focusedPluginIfInputMethodSupported(focused))
2511 return plugin->commitText(text, relativeCaretPosition); 2514 return plugin->commitText(text, relativeCaretPosition);
2512 2515
2513 // TODO(xiaochengh): The use of updateStyleAndLayoutIgnorePendingStylesheets 2516 // TODO(xiaochengh): The use of updateStyleAndLayoutIgnorePendingStylesheets
2514 // needs to be audited. See http://crbug.com/590369 for more details. 2517 // needs to be audited. See http://crbug.com/590369 for more details.
2515 focused->document()->updateStyleAndLayoutIgnorePendingStylesheets(); 2518 focused->document()->updateStyleAndLayoutIgnorePendingStylesheets();
2516 2519
2517 return focused->inputMethodController().commitText(text, 2520 return focused->inputMethodController().commitText(text,
2518 relativeCaretPosition); 2521 relativeCaretPosition);
2519 } 2522 }
(...skipping 1326 matching lines...) Expand 10 before | Expand all | Expand 10 after
3846 void WebViewImpl::dragTargetDrop(const WebDragData& webDragData, 3849 void WebViewImpl::dragTargetDrop(const WebDragData& webDragData,
3847 const WebPoint& pointInViewport, 3850 const WebPoint& pointInViewport,
3848 const WebPoint& screenPoint, 3851 const WebPoint& screenPoint,
3849 int modifiers) { 3852 int modifiers) {
3850 WebPoint pointInRootFrame( 3853 WebPoint pointInRootFrame(
3851 page()->frameHost().visualViewport().viewportToRootFrame( 3854 page()->frameHost().visualViewport().viewportToRootFrame(
3852 pointInViewport)); 3855 pointInViewport));
3853 3856
3854 DCHECK(m_currentDragData); 3857 DCHECK(m_currentDragData);
3855 m_currentDragData = DataObject::create(webDragData); 3858 m_currentDragData = DataObject::create(webDragData);
3856 3859 UserGestureNotifier notifier(mainFrameImpl(), &m_userGestureObserved);
3857 WebAutofillClient* autofillClient =
3858 mainFrameImpl() ? mainFrameImpl()->autofillClient() : 0;
3859 UserGestureNotifier notifier(autofillClient, &m_userGestureObserved);
3860 3860
3861 // If this webview transitions from the "drop accepting" state to the "not 3861 // If this webview transitions from the "drop accepting" state to the "not
3862 // accepting" state, then our IPC message reply indicating that may be in- 3862 // accepting" state, then our IPC message reply indicating that may be in-
3863 // flight, or else delayed by javascript processing in this webview. If a 3863 // flight, or else delayed by javascript processing in this webview. If a
3864 // drop happens before our IPC reply has reached the browser process, then 3864 // drop happens before our IPC reply has reached the browser process, then
3865 // the browser forwards the drop to this webview. So only allow a drop to 3865 // the browser forwards the drop to this webview. So only allow a drop to
3866 // proceed if our webview m_dragOperation state is not DragOperationNone. 3866 // proceed if our webview m_dragOperation state is not DragOperationNone.
3867 3867
3868 if (m_dragOperation == 3868 if (m_dragOperation ==
3869 WebDragOperationNone) { // IPC RACE CONDITION: do not allow this drop. 3869 WebDragOperationNone) { // IPC RACE CONDITION: do not allow this drop.
3870 dragTargetDragLeave(); 3870 dragTargetDragLeave();
3871 return; 3871 return;
3872 } 3872 }
3873 3873
3874 m_currentDragData->setModifiers(modifiers); 3874 m_currentDragData->setModifiers(modifiers);
3875 DragData dragData(m_currentDragData.get(), pointInRootFrame, screenPoint, 3875 DragData dragData(m_currentDragData.get(), pointInRootFrame, screenPoint,
3876 static_cast<DragOperation>(m_operationsAllowed)); 3876 static_cast<DragOperation>(m_operationsAllowed));
3877 3877
3878 UserGestureIndicator gesture(
Nate Chapin 2016/10/13 20:03:19 Moved to DragController.
3879 UserGestureToken::create(UserGestureToken::NewGesture));
3880 m_page->dragController().performDrag(&dragData); 3878 m_page->dragController().performDrag(&dragData);
3881 3879
3882 m_dragOperation = WebDragOperationNone; 3880 m_dragOperation = WebDragOperationNone;
3883 m_currentDragData = nullptr; 3881 m_currentDragData = nullptr;
3884 } 3882 }
3885 3883
3886 void WebViewImpl::spellingMarkers(WebVector<uint32_t>* markers) { 3884 void WebViewImpl::spellingMarkers(WebVector<uint32_t>* markers) {
3887 Vector<uint32_t> result; 3885 Vector<uint32_t> result;
3888 for (Frame* frame = m_page->mainFrame(); frame; 3886 for (Frame* frame = m_page->mainFrame(); frame;
3889 frame = frame->tree().traverseNext()) { 3887 frame = frame->tree().traverseNext()) {
(...skipping 775 matching lines...) Expand 10 before | Expand all | Expand 10 after
4665 if (m_layerTreeView) 4663 if (m_layerTreeView)
4666 m_layerTreeView->setVisible(isVisible); 4664 m_layerTreeView->setVisible(isVisible);
4667 } 4665 }
4668 4666
4669 void WebViewImpl::pointerLockMouseEvent(const WebInputEvent& event) { 4667 void WebViewImpl::pointerLockMouseEvent(const WebInputEvent& event) {
4670 std::unique_ptr<UserGestureIndicator> gestureIndicator; 4668 std::unique_ptr<UserGestureIndicator> gestureIndicator;
4671 AtomicString eventType; 4669 AtomicString eventType;
4672 switch (event.type) { 4670 switch (event.type) {
4673 case WebInputEvent::MouseDown: 4671 case WebInputEvent::MouseDown:
4674 eventType = EventTypeNames::mousedown; 4672 eventType = EventTypeNames::mousedown;
4675 gestureIndicator = wrapUnique(new UserGestureIndicator( 4673 if (!page() || !page()->pointerLockController().element())
4676 UserGestureToken::create(UserGestureToken::NewGesture))); 4674 break;
4675 gestureIndicator =
4676 wrapUnique(new UserGestureIndicator(DocumentUserGestureToken::create(
4677 &page()->pointerLockController().element()->document(),
4678 UserGestureToken::NewGesture)));
4677 m_pointerLockGestureToken = gestureIndicator->currentToken(); 4679 m_pointerLockGestureToken = gestureIndicator->currentToken();
4678 break; 4680 break;
4679 case WebInputEvent::MouseUp: 4681 case WebInputEvent::MouseUp:
4680 eventType = EventTypeNames::mouseup; 4682 eventType = EventTypeNames::mouseup;
4681 gestureIndicator = wrapUnique( 4683 gestureIndicator = wrapUnique(
4682 new UserGestureIndicator(m_pointerLockGestureToken.release())); 4684 new UserGestureIndicator(m_pointerLockGestureToken.release()));
4683 break; 4685 break;
4684 case WebInputEvent::MouseMove: 4686 case WebInputEvent::MouseMove:
4685 eventType = EventTypeNames::mousemove; 4687 eventType = EventTypeNames::mousemove;
4686 break; 4688 break;
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
4742 if (focusedFrame->localFrameRoot() != mainFrameImpl()->frame()) 4744 if (focusedFrame->localFrameRoot() != mainFrameImpl()->frame())
4743 return nullptr; 4745 return nullptr;
4744 return focusedFrame; 4746 return focusedFrame;
4745 } 4747 }
4746 4748
4747 LocalFrame* WebViewImpl::focusedLocalFrameAvailableForIme() const { 4749 LocalFrame* WebViewImpl::focusedLocalFrameAvailableForIme() const {
4748 return m_imeAcceptEvents ? focusedLocalFrameInWidget() : nullptr; 4750 return m_imeAcceptEvents ? focusedLocalFrameInWidget() : nullptr;
4749 } 4751 }
4750 4752
4751 } // namespace blink 4753 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698