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 16 matching lines...) Expand all Loading... |
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
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/clipboard/DataObject.h" | 35 #include "core/clipboard/DataObject.h" |
36 #include "core/dom/Document.h" | 36 #include "core/dom/Document.h" |
| 37 #include "core/dom/DocumentUserGestureToken.h" |
37 #include "core/dom/Fullscreen.h" | 38 #include "core/dom/Fullscreen.h" |
38 #include "core/dom/LayoutTreeBuilderTraversal.h" | 39 #include "core/dom/LayoutTreeBuilderTraversal.h" |
39 #include "core/dom/Text.h" | 40 #include "core/dom/Text.h" |
40 #include "core/editing/EditingUtilities.h" | 41 #include "core/editing/EditingUtilities.h" |
41 #include "core/editing/Editor.h" | 42 #include "core/editing/Editor.h" |
42 #include "core/editing/FrameSelection.h" | 43 #include "core/editing/FrameSelection.h" |
43 #include "core/editing/InputMethodController.h" | 44 #include "core/editing/InputMethodController.h" |
44 #include "core/editing/iterators/TextIterator.h" | 45 #include "core/editing/iterators/TextIterator.h" |
45 #include "core/editing/markers/DocumentMarkerController.h" | 46 #include "core/editing/markers/DocumentMarkerController.h" |
46 #include "core/editing/serializers/HTMLInterchange.h" | 47 #include "core/editing/serializers/HTMLInterchange.h" |
(...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
253 | 254 |
254 static bool shouldUseExternalPopupMenus = false; | 255 static bool shouldUseExternalPopupMenus = false; |
255 | 256 |
256 namespace { | 257 namespace { |
257 | 258 |
258 class UserGestureNotifier { | 259 class UserGestureNotifier { |
259 public: | 260 public: |
260 // If a UserGestureIndicator is created for a user gesture since the last | 261 // If a UserGestureIndicator is created for a user gesture since the last |
261 // page load and *userGestureObserved is false, the UserGestureNotifier | 262 // page load and *userGestureObserved is false, the UserGestureNotifier |
262 // will notify the client and set *userGestureObserved to true. | 263 // will notify the client and set *userGestureObserved to true. |
263 UserGestureNotifier(WebAutofillClient*, bool* userGestureObserved); | 264 UserGestureNotifier(WebLocalFrameImpl*, bool* userGestureObserved); |
264 ~UserGestureNotifier(); | 265 ~UserGestureNotifier(); |
265 | 266 |
266 private: | 267 private: |
267 WebAutofillClient* const m_client; | 268 Persistent<WebLocalFrameImpl> m_frame; |
268 bool* const m_userGestureObserved; | 269 bool* const m_userGestureObserved; |
269 }; | 270 }; |
270 | 271 |
271 UserGestureNotifier::UserGestureNotifier(WebAutofillClient* client, | 272 UserGestureNotifier::UserGestureNotifier(WebLocalFrameImpl* frame, |
272 bool* userGestureObserved) | 273 bool* userGestureObserved) |
273 : m_client(client), m_userGestureObserved(userGestureObserved) { | 274 : m_frame(frame), m_userGestureObserved(userGestureObserved) { |
274 DCHECK(m_userGestureObserved); | 275 DCHECK(m_userGestureObserved); |
275 } | 276 } |
276 | 277 |
277 UserGestureNotifier::~UserGestureNotifier() { | 278 UserGestureNotifier::~UserGestureNotifier() { |
278 if (!*m_userGestureObserved && | 279 if (!*m_userGestureObserved && |
279 UserGestureIndicator::processedUserGestureSinceLoad()) { | 280 m_frame->frame()->document()->hasReceivedUserGesture()) { |
280 *m_userGestureObserved = true; | 281 *m_userGestureObserved = true; |
281 if (m_client) | 282 if (m_frame && m_frame->autofillClient()) |
282 m_client->firstUserGestureObserved(); | 283 m_frame->autofillClient()->firstUserGestureObserved(); |
283 } | 284 } |
284 } | 285 } |
285 | 286 |
286 class EmptyEventListener final : public EventListener { | 287 class EmptyEventListener final : public EventListener { |
287 public: | 288 public: |
288 static EmptyEventListener* create() { return new EmptyEventListener(); } | 289 static EmptyEventListener* create() { return new EmptyEventListener(); } |
289 | 290 |
290 bool operator==(const EventListener& other) const override { | 291 bool operator==(const EventListener& other) const override { |
291 return this == &other; | 292 return this == &other; |
292 } | 293 } |
(...skipping 1921 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2214 | 2215 |
2215 WebInputEventResult WebViewImpl::handleInputEvent( | 2216 WebInputEventResult WebViewImpl::handleInputEvent( |
2216 const WebInputEvent& inputEvent) { | 2217 const WebInputEvent& inputEvent) { |
2217 // TODO(dcheng): The fact that this is getting called when there is no local | 2218 // TODO(dcheng): The fact that this is getting called when there is no local |
2218 // main frame is problematic and probably indicates a bug in the input event | 2219 // main frame is problematic and probably indicates a bug in the input event |
2219 // routing code. | 2220 // routing code. |
2220 if (!mainFrameImpl()) | 2221 if (!mainFrameImpl()) |
2221 return WebInputEventResult::NotHandled; | 2222 return WebInputEventResult::NotHandled; |
2222 | 2223 |
2223 WebAutofillClient* autofillClient = mainFrameImpl()->autofillClient(); | 2224 WebAutofillClient* autofillClient = mainFrameImpl()->autofillClient(); |
2224 UserGestureNotifier notifier(autofillClient, &m_userGestureObserved); | 2225 UserGestureNotifier notifier(mainFrameImpl(), &m_userGestureObserved); |
2225 // On the first input event since page load, |notifier| instructs the | 2226 // On the first input event since page load, |notifier| instructs the |
2226 // autofill client to unblock values of password input fields of any forms | 2227 // autofill client to unblock values of password input fields of any forms |
2227 // on the page. There is a single input event, GestureTap, which can both | 2228 // on the page. There is a single input event, GestureTap, which can both |
2228 // be the first event after page load, and cause a form submission. In that | 2229 // be the first event after page load, and cause a form submission. In that |
2229 // case, the form submission happens before the autofill client is told | 2230 // case, the form submission happens before the autofill client is told |
2230 // to unblock the password values, and so the password values are not | 2231 // to unblock the password values, and so the password values are not |
2231 // submitted. To avoid that, GestureTap is handled explicitly: | 2232 // submitted. To avoid that, GestureTap is handled explicitly: |
2232 if (inputEvent.type == WebInputEvent::GestureTap && autofillClient) { | 2233 if (inputEvent.type == WebInputEvent::GestureTap && autofillClient) { |
2233 m_userGestureObserved = true; | 2234 m_userGestureObserved = true; |
2234 autofillClient->firstUserGestureObserved(); | 2235 autofillClient->firstUserGestureObserved(); |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2285 AtomicString eventType; | 2286 AtomicString eventType; |
2286 switch (inputEvent.type) { | 2287 switch (inputEvent.type) { |
2287 case WebInputEvent::MouseMove: | 2288 case WebInputEvent::MouseMove: |
2288 eventType = EventTypeNames::mousemove; | 2289 eventType = EventTypeNames::mousemove; |
2289 break; | 2290 break; |
2290 case WebInputEvent::MouseLeave: | 2291 case WebInputEvent::MouseLeave: |
2291 eventType = EventTypeNames::mouseout; | 2292 eventType = EventTypeNames::mouseout; |
2292 break; | 2293 break; |
2293 case WebInputEvent::MouseDown: | 2294 case WebInputEvent::MouseDown: |
2294 eventType = EventTypeNames::mousedown; | 2295 eventType = EventTypeNames::mousedown; |
2295 gestureIndicator = wrapUnique(new UserGestureIndicator( | 2296 gestureIndicator = wrapUnique( |
2296 UserGestureToken::create(UserGestureToken::NewGesture))); | 2297 new UserGestureIndicator(DocumentUserGestureToken::create( |
| 2298 &node->document(), UserGestureToken::NewGesture))); |
2297 m_mouseCaptureGestureToken = gestureIndicator->currentToken(); | 2299 m_mouseCaptureGestureToken = gestureIndicator->currentToken(); |
2298 break; | 2300 break; |
2299 case WebInputEvent::MouseUp: | 2301 case WebInputEvent::MouseUp: |
2300 eventType = EventTypeNames::mouseup; | 2302 eventType = EventTypeNames::mouseup; |
2301 gestureIndicator = wrapUnique( | 2303 gestureIndicator = wrapUnique( |
2302 new UserGestureIndicator(m_mouseCaptureGestureToken.release())); | 2304 new UserGestureIndicator(m_mouseCaptureGestureToken.release())); |
2303 break; | 2305 break; |
2304 default: | 2306 default: |
2305 NOTREACHED(); | 2307 NOTREACHED(); |
2306 } | 2308 } |
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2459 } | 2461 } |
2460 | 2462 |
2461 // A keypress event is canceled. If an ongoing composition exists, then the | 2463 // A keypress event is canceled. If an ongoing composition exists, then the |
2462 // keydown event should have arisen from a handled key (e.g., backspace). | 2464 // keydown event should have arisen from a handled key (e.g., backspace). |
2463 // In this case we ignore the cancellation and continue; otherwise (no | 2465 // In this case we ignore the cancellation and continue; otherwise (no |
2464 // ongoing composition) we exit and signal success only for attempts to | 2466 // ongoing composition) we exit and signal success only for attempts to |
2465 // clear the composition. | 2467 // clear the composition. |
2466 if (m_suppressNextKeypressEvent && !inputMethodController.hasComposition()) | 2468 if (m_suppressNextKeypressEvent && !inputMethodController.hasComposition()) |
2467 return text.isEmpty(); | 2469 return text.isEmpty(); |
2468 | 2470 |
2469 UserGestureIndicator gestureIndicator( | 2471 UserGestureIndicator gestureIndicator(DocumentUserGestureToken::create( |
2470 UserGestureToken::create(UserGestureToken::NewGesture)); | 2472 focused->document(), UserGestureToken::NewGesture)); |
2471 | 2473 |
2472 // When the range of composition underlines overlap with the range between | 2474 // When the range of composition underlines overlap with the range between |
2473 // selectionStart and selectionEnd, WebKit somehow won't paint the selection | 2475 // selectionStart and selectionEnd, WebKit somehow won't paint the selection |
2474 // at all (see InlineTextBox::paint() function in InlineTextBox.cpp). | 2476 // at all (see InlineTextBox::paint() function in InlineTextBox.cpp). |
2475 // But the selection range actually takes effect. | 2477 // But the selection range actually takes effect. |
2476 inputMethodController.setComposition( | 2478 inputMethodController.setComposition( |
2477 String(text), CompositionUnderlineVectorBuilder(underlines), | 2479 String(text), CompositionUnderlineVectorBuilder(underlines), |
2478 selectionStart, selectionEnd); | 2480 selectionStart, selectionEnd); |
2479 | 2481 |
2480 return text.isEmpty() || inputMethodController.hasComposition(); | 2482 return text.isEmpty() || inputMethodController.hasComposition(); |
(...skipping 10 matching lines...) Expand all Loading... |
2491 if (WebPlugin* plugin = focusedPluginIfInputMethodSupported(focused)) | 2493 if (WebPlugin* plugin = focusedPluginIfInputMethodSupported(focused)) |
2492 return plugin->finishComposingText(selectionBehavior); | 2494 return plugin->finishComposingText(selectionBehavior); |
2493 | 2495 |
2494 return focused->inputMethodController().finishComposingText( | 2496 return focused->inputMethodController().finishComposingText( |
2495 selectionBehavior == KeepSelection | 2497 selectionBehavior == KeepSelection |
2496 ? InputMethodController::KeepSelection | 2498 ? InputMethodController::KeepSelection |
2497 : InputMethodController::DoNotKeepSelection); | 2499 : InputMethodController::DoNotKeepSelection); |
2498 } | 2500 } |
2499 | 2501 |
2500 bool WebViewImpl::commitText(const WebString& text, int relativeCaretPosition) { | 2502 bool WebViewImpl::commitText(const WebString& text, int relativeCaretPosition) { |
2501 UserGestureIndicator gestureIndicator( | |
2502 UserGestureToken::create(UserGestureToken::NewGesture)); | |
2503 | |
2504 LocalFrame* focused = focusedLocalFrameAvailableForIme(); | 2503 LocalFrame* focused = focusedLocalFrameAvailableForIme(); |
2505 if (!focused) | 2504 if (!focused) |
2506 return false; | 2505 return false; |
2507 | 2506 |
| 2507 UserGestureIndicator gestureIndicator(DocumentUserGestureToken::create( |
| 2508 focused->document(), UserGestureToken::NewGesture)); |
| 2509 |
2508 if (WebPlugin* plugin = focusedPluginIfInputMethodSupported(focused)) | 2510 if (WebPlugin* plugin = focusedPluginIfInputMethodSupported(focused)) |
2509 return plugin->commitText(text, relativeCaretPosition); | 2511 return plugin->commitText(text, relativeCaretPosition); |
2510 | 2512 |
2511 // TODO(xiaochengh): The use of updateStyleAndLayoutIgnorePendingStylesheets | 2513 // TODO(xiaochengh): The use of updateStyleAndLayoutIgnorePendingStylesheets |
2512 // needs to be audited. See http://crbug.com/590369 for more details. | 2514 // needs to be audited. See http://crbug.com/590369 for more details. |
2513 focused->document()->updateStyleAndLayoutIgnorePendingStylesheets(); | 2515 focused->document()->updateStyleAndLayoutIgnorePendingStylesheets(); |
2514 | 2516 |
2515 return focused->inputMethodController().commitText(text, | 2517 return focused->inputMethodController().commitText(text, |
2516 relativeCaretPosition); | 2518 relativeCaretPosition); |
2517 } | 2519 } |
(...skipping 1134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3652 void WebViewImpl::dragTargetDrop(const WebDragData& webDragData, | 3654 void WebViewImpl::dragTargetDrop(const WebDragData& webDragData, |
3653 const WebPoint& pointInViewport, | 3655 const WebPoint& pointInViewport, |
3654 const WebPoint& screenPoint, | 3656 const WebPoint& screenPoint, |
3655 int modifiers) { | 3657 int modifiers) { |
3656 WebPoint pointInRootFrame( | 3658 WebPoint pointInRootFrame( |
3657 page()->frameHost().visualViewport().viewportToRootFrame( | 3659 page()->frameHost().visualViewport().viewportToRootFrame( |
3658 pointInViewport)); | 3660 pointInViewport)); |
3659 | 3661 |
3660 DCHECK(m_currentDragData); | 3662 DCHECK(m_currentDragData); |
3661 m_currentDragData = DataObject::create(webDragData); | 3663 m_currentDragData = DataObject::create(webDragData); |
3662 | 3664 UserGestureNotifier notifier(mainFrameImpl(), &m_userGestureObserved); |
3663 WebAutofillClient* autofillClient = | |
3664 mainFrameImpl() ? mainFrameImpl()->autofillClient() : 0; | |
3665 UserGestureNotifier notifier(autofillClient, &m_userGestureObserved); | |
3666 | 3665 |
3667 // If this webview transitions from the "drop accepting" state to the "not | 3666 // If this webview transitions from the "drop accepting" state to the "not |
3668 // accepting" state, then our IPC message reply indicating that may be in- | 3667 // accepting" state, then our IPC message reply indicating that may be in- |
3669 // flight, or else delayed by javascript processing in this webview. If a | 3668 // flight, or else delayed by javascript processing in this webview. If a |
3670 // drop happens before our IPC reply has reached the browser process, then | 3669 // drop happens before our IPC reply has reached the browser process, then |
3671 // the browser forwards the drop to this webview. So only allow a drop to | 3670 // the browser forwards the drop to this webview. So only allow a drop to |
3672 // proceed if our webview m_dragOperation state is not DragOperationNone. | 3671 // proceed if our webview m_dragOperation state is not DragOperationNone. |
3673 | 3672 |
3674 if (m_dragOperation == | 3673 if (m_dragOperation == |
3675 WebDragOperationNone) { // IPC RACE CONDITION: do not allow this drop. | 3674 WebDragOperationNone) { // IPC RACE CONDITION: do not allow this drop. |
3676 dragTargetDragLeave(); | 3675 dragTargetDragLeave(); |
3677 return; | 3676 return; |
3678 } | 3677 } |
3679 | 3678 |
3680 m_currentDragData->setModifiers(modifiers); | 3679 m_currentDragData->setModifiers(modifiers); |
3681 DragData dragData(m_currentDragData.get(), pointInRootFrame, screenPoint, | 3680 DragData dragData(m_currentDragData.get(), pointInRootFrame, screenPoint, |
3682 static_cast<DragOperation>(m_operationsAllowed)); | 3681 static_cast<DragOperation>(m_operationsAllowed)); |
3683 | 3682 |
3684 UserGestureIndicator gesture( | |
3685 UserGestureToken::create(UserGestureToken::NewGesture)); | |
3686 m_page->dragController().performDrag(&dragData); | 3683 m_page->dragController().performDrag(&dragData); |
3687 | 3684 |
3688 m_dragOperation = WebDragOperationNone; | 3685 m_dragOperation = WebDragOperationNone; |
3689 m_currentDragData = nullptr; | 3686 m_currentDragData = nullptr; |
3690 } | 3687 } |
3691 | 3688 |
3692 void WebViewImpl::spellingMarkers(WebVector<uint32_t>* markers) { | 3689 void WebViewImpl::spellingMarkers(WebVector<uint32_t>* markers) { |
3693 Vector<uint32_t> result; | 3690 Vector<uint32_t> result; |
3694 for (Frame* frame = m_page->mainFrame(); frame; | 3691 for (Frame* frame = m_page->mainFrame(); frame; |
3695 frame = frame->tree().traverseNext()) { | 3692 frame = frame->tree().traverseNext()) { |
(...skipping 775 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4471 if (m_layerTreeView) | 4468 if (m_layerTreeView) |
4472 m_layerTreeView->setVisible(isVisible); | 4469 m_layerTreeView->setVisible(isVisible); |
4473 } | 4470 } |
4474 | 4471 |
4475 void WebViewImpl::pointerLockMouseEvent(const WebInputEvent& event) { | 4472 void WebViewImpl::pointerLockMouseEvent(const WebInputEvent& event) { |
4476 std::unique_ptr<UserGestureIndicator> gestureIndicator; | 4473 std::unique_ptr<UserGestureIndicator> gestureIndicator; |
4477 AtomicString eventType; | 4474 AtomicString eventType; |
4478 switch (event.type) { | 4475 switch (event.type) { |
4479 case WebInputEvent::MouseDown: | 4476 case WebInputEvent::MouseDown: |
4480 eventType = EventTypeNames::mousedown; | 4477 eventType = EventTypeNames::mousedown; |
4481 gestureIndicator = wrapUnique(new UserGestureIndicator( | 4478 if (!page() || !page()->pointerLockController().element()) |
4482 UserGestureToken::create(UserGestureToken::NewGesture))); | 4479 break; |
| 4480 gestureIndicator = |
| 4481 wrapUnique(new UserGestureIndicator(DocumentUserGestureToken::create( |
| 4482 &page()->pointerLockController().element()->document(), |
| 4483 UserGestureToken::NewGesture))); |
4483 m_pointerLockGestureToken = gestureIndicator->currentToken(); | 4484 m_pointerLockGestureToken = gestureIndicator->currentToken(); |
4484 break; | 4485 break; |
4485 case WebInputEvent::MouseUp: | 4486 case WebInputEvent::MouseUp: |
4486 eventType = EventTypeNames::mouseup; | 4487 eventType = EventTypeNames::mouseup; |
4487 gestureIndicator = wrapUnique( | 4488 gestureIndicator = wrapUnique( |
4488 new UserGestureIndicator(m_pointerLockGestureToken.release())); | 4489 new UserGestureIndicator(m_pointerLockGestureToken.release())); |
4489 break; | 4490 break; |
4490 case WebInputEvent::MouseMove: | 4491 case WebInputEvent::MouseMove: |
4491 eventType = EventTypeNames::mousemove; | 4492 eventType = EventTypeNames::mousemove; |
4492 break; | 4493 break; |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4548 if (focusedFrame->localFrameRoot() != mainFrameImpl()->frame()) | 4549 if (focusedFrame->localFrameRoot() != mainFrameImpl()->frame()) |
4549 return nullptr; | 4550 return nullptr; |
4550 return focusedFrame; | 4551 return focusedFrame; |
4551 } | 4552 } |
4552 | 4553 |
4553 LocalFrame* WebViewImpl::focusedLocalFrameAvailableForIme() const { | 4554 LocalFrame* WebViewImpl::focusedLocalFrameAvailableForIme() const { |
4554 return m_imeAcceptEvents ? focusedLocalFrameInWidget() : nullptr; | 4555 return m_imeAcceptEvents ? focusedLocalFrameInWidget() : nullptr; |
4555 } | 4556 } |
4556 | 4557 |
4557 } // namespace blink | 4558 } // namespace blink |
OLD | NEW |