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