OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |