| 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 |