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 1923 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 | |
2506 LocalFrame* focused = focusedLocalFrameAvailableForIme(); | 2505 LocalFrame* focused = focusedLocalFrameAvailableForIme(); |
2507 if (!focused) | 2506 if (!focused) |
2508 return false; | 2507 return false; |
2509 | 2508 |
| 2509 UserGestureIndicator gestureIndicator(DocumentUserGestureToken::create( |
| 2510 focused->document(), UserGestureToken::NewGesture)); |
| 2511 |
2510 if (WebPlugin* plugin = focusedPluginIfInputMethodSupported(focused)) | 2512 if (WebPlugin* plugin = focusedPluginIfInputMethodSupported(focused)) |
2511 return plugin->commitText(text, relativeCaretPosition); | 2513 return plugin->commitText(text, relativeCaretPosition); |
2512 | 2514 |
2513 // TODO(xiaochengh): The use of updateStyleAndLayoutIgnorePendingStylesheets | 2515 // TODO(xiaochengh): The use of updateStyleAndLayoutIgnorePendingStylesheets |
2514 // needs to be audited. See http://crbug.com/590369 for more details. | 2516 // needs to be audited. See http://crbug.com/590369 for more details. |
2515 focused->document()->updateStyleAndLayoutIgnorePendingStylesheets(); | 2517 focused->document()->updateStyleAndLayoutIgnorePendingStylesheets(); |
2516 | 2518 |
2517 return focused->inputMethodController().commitText(text, | 2519 return focused->inputMethodController().commitText(text, |
2518 relativeCaretPosition); | 2520 relativeCaretPosition); |
2519 } | 2521 } |
(...skipping 1134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3654 void WebViewImpl::dragTargetDrop(const WebDragData& webDragData, | 3656 void WebViewImpl::dragTargetDrop(const WebDragData& webDragData, |
3655 const WebPoint& pointInViewport, | 3657 const WebPoint& pointInViewport, |
3656 const WebPoint& screenPoint, | 3658 const WebPoint& screenPoint, |
3657 int modifiers) { | 3659 int modifiers) { |
3658 WebPoint pointInRootFrame( | 3660 WebPoint pointInRootFrame( |
3659 page()->frameHost().visualViewport().viewportToRootFrame( | 3661 page()->frameHost().visualViewport().viewportToRootFrame( |
3660 pointInViewport)); | 3662 pointInViewport)); |
3661 | 3663 |
3662 DCHECK(m_currentDragData); | 3664 DCHECK(m_currentDragData); |
3663 m_currentDragData = DataObject::create(webDragData); | 3665 m_currentDragData = DataObject::create(webDragData); |
3664 | 3666 UserGestureNotifier notifier(mainFrameImpl(), &m_userGestureObserved); |
3665 WebAutofillClient* autofillClient = | |
3666 mainFrameImpl() ? mainFrameImpl()->autofillClient() : 0; | |
3667 UserGestureNotifier notifier(autofillClient, &m_userGestureObserved); | |
3668 | 3667 |
3669 // If this webview transitions from the "drop accepting" state to the "not | 3668 // If this webview transitions from the "drop accepting" state to the "not |
3670 // accepting" state, then our IPC message reply indicating that may be in- | 3669 // accepting" state, then our IPC message reply indicating that may be in- |
3671 // flight, or else delayed by javascript processing in this webview. If a | 3670 // flight, or else delayed by javascript processing in this webview. If a |
3672 // drop happens before our IPC reply has reached the browser process, then | 3671 // drop happens before our IPC reply has reached the browser process, then |
3673 // the browser forwards the drop to this webview. So only allow a drop to | 3672 // the browser forwards the drop to this webview. So only allow a drop to |
3674 // proceed if our webview m_dragOperation state is not DragOperationNone. | 3673 // proceed if our webview m_dragOperation state is not DragOperationNone. |
3675 | 3674 |
3676 if (m_dragOperation == | 3675 if (m_dragOperation == |
3677 WebDragOperationNone) { // IPC RACE CONDITION: do not allow this drop. | 3676 WebDragOperationNone) { // IPC RACE CONDITION: do not allow this drop. |
3678 dragTargetDragLeave(); | 3677 dragTargetDragLeave(); |
3679 return; | 3678 return; |
3680 } | 3679 } |
3681 | 3680 |
3682 m_currentDragData->setModifiers(modifiers); | 3681 m_currentDragData->setModifiers(modifiers); |
3683 DragData dragData(m_currentDragData.get(), pointInRootFrame, screenPoint, | 3682 DragData dragData(m_currentDragData.get(), pointInRootFrame, screenPoint, |
3684 static_cast<DragOperation>(m_operationsAllowed)); | 3683 static_cast<DragOperation>(m_operationsAllowed)); |
3685 | 3684 |
3686 UserGestureIndicator gesture( | |
3687 UserGestureToken::create(UserGestureToken::NewGesture)); | |
3688 m_page->dragController().performDrag(&dragData); | 3685 m_page->dragController().performDrag(&dragData); |
3689 | 3686 |
3690 m_dragOperation = WebDragOperationNone; | 3687 m_dragOperation = WebDragOperationNone; |
3691 m_currentDragData = nullptr; | 3688 m_currentDragData = nullptr; |
3692 } | 3689 } |
3693 | 3690 |
3694 void WebViewImpl::spellingMarkers(WebVector<uint32_t>* markers) { | 3691 void WebViewImpl::spellingMarkers(WebVector<uint32_t>* markers) { |
3695 Vector<uint32_t> result; | 3692 Vector<uint32_t> result; |
3696 for (Frame* frame = m_page->mainFrame(); frame; | 3693 for (Frame* frame = m_page->mainFrame(); frame; |
3697 frame = frame->tree().traverseNext()) { | 3694 frame = frame->tree().traverseNext()) { |
(...skipping 776 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4474 if (m_layerTreeView) | 4471 if (m_layerTreeView) |
4475 m_layerTreeView->setVisible(isVisible); | 4472 m_layerTreeView->setVisible(isVisible); |
4476 } | 4473 } |
4477 | 4474 |
4478 void WebViewImpl::pointerLockMouseEvent(const WebInputEvent& event) { | 4475 void WebViewImpl::pointerLockMouseEvent(const WebInputEvent& event) { |
4479 std::unique_ptr<UserGestureIndicator> gestureIndicator; | 4476 std::unique_ptr<UserGestureIndicator> gestureIndicator; |
4480 AtomicString eventType; | 4477 AtomicString eventType; |
4481 switch (event.type) { | 4478 switch (event.type) { |
4482 case WebInputEvent::MouseDown: | 4479 case WebInputEvent::MouseDown: |
4483 eventType = EventTypeNames::mousedown; | 4480 eventType = EventTypeNames::mousedown; |
4484 gestureIndicator = wrapUnique(new UserGestureIndicator( | 4481 if (!page() || !page()->pointerLockController().element()) |
4485 UserGestureToken::create(UserGestureToken::NewGesture))); | 4482 break; |
| 4483 gestureIndicator = |
| 4484 wrapUnique(new UserGestureIndicator(DocumentUserGestureToken::create( |
| 4485 &page()->pointerLockController().element()->document(), |
| 4486 UserGestureToken::NewGesture))); |
4486 m_pointerLockGestureToken = gestureIndicator->currentToken(); | 4487 m_pointerLockGestureToken = gestureIndicator->currentToken(); |
4487 break; | 4488 break; |
4488 case WebInputEvent::MouseUp: | 4489 case WebInputEvent::MouseUp: |
4489 eventType = EventTypeNames::mouseup; | 4490 eventType = EventTypeNames::mouseup; |
4490 gestureIndicator = wrapUnique( | 4491 gestureIndicator = wrapUnique( |
4491 new UserGestureIndicator(m_pointerLockGestureToken.release())); | 4492 new UserGestureIndicator(m_pointerLockGestureToken.release())); |
4492 break; | 4493 break; |
4493 case WebInputEvent::MouseMove: | 4494 case WebInputEvent::MouseMove: |
4494 eventType = EventTypeNames::mousemove; | 4495 eventType = EventTypeNames::mousemove; |
4495 break; | 4496 break; |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4551 if (focusedFrame->localFrameRoot() != mainFrameImpl()->frame()) | 4552 if (focusedFrame->localFrameRoot() != mainFrameImpl()->frame()) |
4552 return nullptr; | 4553 return nullptr; |
4553 return focusedFrame; | 4554 return focusedFrame; |
4554 } | 4555 } |
4555 | 4556 |
4556 LocalFrame* WebViewImpl::focusedLocalFrameAvailableForIme() const { | 4557 LocalFrame* WebViewImpl::focusedLocalFrameAvailableForIme() const { |
4557 return m_imeAcceptEvents ? focusedLocalFrameInWidget() : nullptr; | 4558 return m_imeAcceptEvents ? focusedLocalFrameInWidget() : nullptr; |
4558 } | 4559 } |
4559 | 4560 |
4560 } // namespace blink | 4561 } // namespace blink |
OLD | NEW |