blob: 91a656083d985593544d971c18fd9e5643382f86 [file] [log] [blame]
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "web/WebFrameWidgetBase.h"
#include "core/frame/FrameHost.h"
#include "core/frame/VisualViewport.h"
#include "core/page/DragActions.h"
#include "core/page/DragController.h"
#include "core/page/DragData.h"
#include "core/page/DragSession.h"
#include "core/page/Page.h"
#include "public/web/WebAutofillClient.h"
#include "public/web/WebDocument.h"
#include "web/WebLocalFrameImpl.h"
#include "web/WebViewImpl.h"
namespace blink {
WebDragOperation WebFrameWidgetBase::dragTargetDragEnter(
const WebDragData& webDragData,
const WebPoint& pointInViewport,
const WebPoint& screenPoint,
WebDragOperationsMask operationsAllowed,
int modifiers) {
DCHECK(!m_currentDragData);
m_currentDragData = DataObject::create(webDragData);
m_operationsAllowed = operationsAllowed;
return dragTargetDragEnterOrOver(pointInViewport, screenPoint, DragEnter,
modifiers);
}
WebDragOperation WebFrameWidgetBase::dragTargetDragOver(
const WebPoint& pointInViewport,
const WebPoint& screenPoint,
WebDragOperationsMask operationsAllowed,
int modifiers) {
m_operationsAllowed = operationsAllowed;
return dragTargetDragEnterOrOver(pointInViewport, screenPoint, DragOver,
modifiers);
}
void WebFrameWidgetBase::dragTargetDragLeave() {
DCHECK(m_currentDragData);
DragData dragData(m_currentDragData.get(), IntPoint(), IntPoint(),
static_cast<DragOperation>(m_operationsAllowed));
page()->dragController().dragExited(&dragData);
// FIXME: why is the drag scroll timer not stopped here?
m_dragOperation = WebDragOperationNone;
m_currentDragData = nullptr;
}
void WebFrameWidgetBase::dragTargetDrop(const WebDragData& webDragData,
const WebPoint& pointInViewport,
const WebPoint& screenPoint,
int modifiers) {
WebPoint pointInRootFrame(viewportToRootFrame(pointInViewport));
DCHECK(m_currentDragData);
m_currentDragData = DataObject::create(webDragData);
WebViewImpl::UserGestureNotifier notifier(view());
// If this webview transitions from the "drop accepting" state to the "not
// accepting" state, then our IPC message reply indicating that may be in-
// flight, or else delayed by javascript processing in this webview. If a
// drop happens before our IPC reply has reached the browser process, then
// the browser forwards the drop to this webview. So only allow a drop to
// proceed if our webview m_dragOperation state is not DragOperationNone.
if (m_dragOperation == WebDragOperationNone) {
// IPC RACE CONDITION: do not allow this drop.
dragTargetDragLeave();
return;
}
m_currentDragData->setModifiers(modifiers);
DragData dragData(m_currentDragData.get(), pointInRootFrame, screenPoint,
static_cast<DragOperation>(m_operationsAllowed));
page()->dragController().performDrag(&dragData);
m_dragOperation = WebDragOperationNone;
m_currentDragData = nullptr;
}
WebDragOperation WebFrameWidgetBase::dragTargetDragEnterOrOver(
const WebPoint& pointInViewport,
const WebPoint& screenPoint,
DragAction dragAction,
int modifiers) {
DCHECK(m_currentDragData);
WebPoint pointInRootFrame(viewportToRootFrame(pointInViewport));
m_currentDragData->setModifiers(modifiers);
DragData dragData(m_currentDragData.get(), pointInRootFrame, screenPoint,
static_cast<DragOperation>(m_operationsAllowed));
DragSession dragSession;
dragSession = page()->dragController().dragEnteredOrUpdated(&dragData);
DragOperation dropEffect = dragSession.operation;
// Mask the drop effect operation against the drag source's allowed
// operations.
if (!(dropEffect & dragData.draggingSourceOperationMask()))
dropEffect = DragOperationNone;
m_dragOperation = static_cast<WebDragOperation>(dropEffect);
return m_dragOperation;
}
WebPoint WebFrameWidgetBase::viewportToRootFrame(
const WebPoint& pointInViewport) const {
return page()->frameHost().visualViewport().viewportToRootFrame(
pointInViewport);
}
WebViewImpl* WebFrameWidgetBase::view() const {
return static_cast<WebLocalFrameImpl*>(localRoot())->viewImpl();
}
Page* WebFrameWidgetBase::page() const {
return view()->page();
}
} // namespace blink