plugins: Allow a plugin to dictate whether it can receive drag events or not.

https://bugs.webkit.org/show_bug.cgi?id=99355

Patch by Sadrul Habib Chowdhury <sadrul@chromium.org> on 2012-10-17
Reviewed by Tony Chang.

Source/WebCore:

When doing a drag over a plugin, ask the plugin whether it can accept
drag/drop to decide whether drag/drop is possible or not. At present,
plugins do not receive drag events through WebCore (i.e. various
implementations of PluginView::handleMouseEvent ignores the
drop-events). This change makes it possible for the ports to ask the
plugin first to decide whether it can (or wants to) accept drag events.
The default implementation remains the same, i.e. plugins do not receive
drag events. For chromium, the overridden implementation uses the
WebPlugin interface to check whether the plugin can accept drag events.

* html/HTMLPlugInElement.cpp:
(WebCore::HTMLPlugInElement::canProcessDrag):
(WebCore):
* html/HTMLPlugInElement.h:
(WebCore):
(HTMLPlugInElement):
* page/DragController.cpp:
(WebCore::DragController::canProcessDrag):
* plugins/PluginViewBase.h:
(WebCore):
(WebCore::PluginViewBase::canProcessDrag):

Source/WebKit/chromium:

Introduce WebPlugin::canProcessDrag() and use that to implement PluginViewBase::canProcessDrag.

* public/WebPlugin.h:
(WebKit::WebPlugin::canProcessDrag):
(WebPlugin):
* src/WebPluginContainerImpl.cpp:
(WebKit::WebPluginContainerImpl::canProcessDrag):
(WebKit):
(WebKit::WebPluginContainerImpl::handleMouseEvent):
* src/WebPluginContainerImpl.h:
(WebPluginContainerImpl):

Tools:

Update the TestWebPlugin to implement the new |canProcessDrag| interface.

* DumpRenderTree/chromium/TestWebPlugin.h:
(TestWebPlugin::canProcessDrag):

LayoutTests:

Update test to not set contentEditable on the plugin anymore.

* platform/chromium/plugins/drag-events-expected.txt:
* platform/chromium/plugins/drag-events.html:

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@131625 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent d18e7d0b
2012-10-17 Sadrul Habib Chowdhury <sadrul@chromium.org>
plugins: Allow a plugin to dictate whether it can receive drag events or not.
https://bugs.webkit.org/show_bug.cgi?id=99355
Reviewed by Tony Chang.
Update test to not set contentEditable on the plugin anymore.
* platform/chromium/plugins/drag-events-expected.txt:
* platform/chromium/plugins/drag-events.html:
2012-10-17 Christophe Dumez <christophe.dumez@intel.com>
xss-DENIED-xsl-document-securityOrigin.xml crashes with icon assertion
......
CONSOLE MESSAGE: line 25: Dragging over plugin_drag
Plugin received event: MouseEnter
Plugin received event: MouseMove
Plugin received event: DragEnter
......@@ -6,5 +7,14 @@ Plugin received event: DragLeave
Plugin received event: DragEnter
Plugin received event: DragOver
Plugin received event: DragDrop
Plugin received event: MouseLeave
CONSOLE MESSAGE: line 25: Dragging over plugin_editable
Plugin received event: MouseEnter
Plugin received event: MouseMove
Plugin received event: MouseLeave
CONSOLE MESSAGE: line 25: Dragging over plugin
Plugin received event: MouseEnter
Plugin received event: MouseMove
Plugin received event: MouseLeave
Some text to drag
......@@ -9,37 +9,48 @@
</head>
<body onload="test();">
<embed id="plugin" type="application/x-webkit-test-webplugin" contentEditable></embed>
<embed id="plugin_drag" type="application/x-webkit-test-webplugin" can-process-drag="true" contentEditable="false"></embed>
<embed id="plugin_editable" type="application/x-webkit-test-webplugin" contentEditable="true"></embed>
<embed id="plugin" type="application/x-webkit-test-webplugin"></embed>
<div id='text'><span>Some text to drag</span></div>
<script>
function dragOverPlugin(plugin) {
var div = document.getElementById('text');
div.focus();
getSelection().collapse(div, 0);
getSelection().modify('extend', 'forward', 'word');
console.log("Dragging over " + plugin.id);
var positionX = plugin.offsetLeft + plugin.offsetWidth / 2;
var positionY = plugin.offsetTop + plugin.offsetHeight / 2;
var startX = div.offsetLeft + div.firstChild.offsetWidth / 5;
var startY = div.offsetTop + div.offsetHeight / 2;;
// Drag into the plugin and drag out before dropping.
eventSender.dragMode = true;
eventSender.mouseMoveTo(startX, startY);
eventSender.mouseDown();
eventSender.leapForward(250);
eventSender.mouseMoveTo(positionX, positionY);
eventSender.mouseMoveTo(positionX + 2, positionY);
eventSender.mouseMoveTo(startX, startY);
eventSender.mouseMoveTo(positionX, positionY);
eventSender.mouseUp();
eventSender.leapForward(250);
eventSender.mouseMoveTo(startX, startY);
}
function test() {
if (!window.testRunner || !window.eventSender) {
document.write("This test does not work in manual mode.");
} else {
testRunner.dumpAsText();
var div = document.getElementById('text');
div.focus();
getSelection().collapse(div, 0);
getSelection().modify('extend', 'forward', 'word');
var positionX = plugin.offsetLeft + 10;
var positionY = plugin.offsetTop + 10;
var startX = div.offsetLeft + div.firstChild.offsetWidth / 5;
var startY = div.offsetTop + div.offsetHeight / 2;;
// Drag into the plugin and drag out before dropping.
eventSender.dragMode = true;
eventSender.mouseMoveTo(startX, startY);
eventSender.mouseDown();
eventSender.leapForward(250);
eventSender.mouseMoveTo(positionX, positionY);
eventSender.mouseMoveTo(positionX + 2, positionY);
eventSender.mouseMoveTo(startX, startY);
eventSender.mouseMoveTo(positionX, positionY);
eventSender.mouseUp();
dragOverPlugin(plugin_drag);
dragOverPlugin(plugin_editable);
dragOverPlugin(plugin);
}
}
</script>
......
2012-10-17 Sadrul Habib Chowdhury <sadrul@chromium.org>
plugins: Allow a plugin to dictate whether it can receive drag events or not.
https://bugs.webkit.org/show_bug.cgi?id=99355
Reviewed by Tony Chang.
When doing a drag over a plugin, ask the plugin whether it can accept
drag/drop to decide whether drag/drop is possible or not. At present,
plugins do not receive drag events through WebCore (i.e. various
implementations of PluginView::handleMouseEvent ignores the
drop-events). This change makes it possible for the ports to ask the
plugin first to decide whether it can (or wants to) accept drag events.
The default implementation remains the same, i.e. plugins do not receive
drag events. For chromium, the overridden implementation uses the
WebPlugin interface to check whether the plugin can accept drag events.
* html/HTMLPlugInElement.cpp:
(WebCore::HTMLPlugInElement::canProcessDrag):
(WebCore):
* html/HTMLPlugInElement.h:
(WebCore):
(HTMLPlugInElement):
* page/DragController.cpp:
(WebCore::DragController::canProcessDrag):
* plugins/PluginViewBase.h:
(WebCore):
(WebCore::PluginViewBase::canProcessDrag):
2012-10-17 Andreas Kling <kling@webkit.org>
Shrink EventTargetData by making firingEventListeners vector optional.
......
......@@ -72,6 +72,12 @@ HTMLPlugInElement::~HTMLPlugInElement()
#endif
}
bool HTMLPlugInElement::canProcessDrag() const
{
const PluginViewBase* plugin = pluginWidget() && pluginWidget()->isPluginViewBase() ? static_cast<const PluginViewBase*>(pluginWidget()) : 0;
return plugin ? plugin->canProcessDrag() : false;
}
void HTMLPlugInElement::detach()
{
m_instance.clear();
......
......@@ -66,6 +66,8 @@ public:
bool canContainRangeEndPoint() const { return false; }
bool canProcessDrag() const;
protected:
HTMLPlugInElement(const QualifiedName& tagName, Document*);
......
......@@ -48,6 +48,7 @@
#include "HTMLAnchorElement.h"
#include "HTMLInputElement.h"
#include "HTMLNames.h"
#include "HTMLPlugInElement.h"
#include "HitTestRequest.h"
#include "HitTestResult.h"
#include "Image.h"
......@@ -552,7 +553,11 @@ bool DragController::canProcessDrag(DragData* dragData)
if (dragData->containsFiles() && asFileInput(result.innerNonSharedNode()))
return true;
if (!result.innerNonSharedNode()->rendererIsEditable())
if (result.innerNonSharedNode()->isPluginElement()) {
HTMLPlugInElement* plugin = static_cast<HTMLPlugInElement*>(result.innerNonSharedNode());
if (!plugin->canProcessDrag() && !result.innerNonSharedNode()->rendererIsEditable())
return false;
} else if (!result.innerNonSharedNode()->rendererIsEditable())
return false;
if (m_didInitiateDrag && m_documentUnderMouse == m_dragInitiator && result.isSelected())
......
......@@ -61,6 +61,7 @@ public:
// FIXME: This is a hack that works around the fact that the WebKit2 PluginView isn't a ScrollableArea.
virtual bool wantsWheelEvents() { return false; }
virtual bool supportsKeyboardFocus() const { return false; }
virtual bool canProcessDrag() const { return false; }
protected:
explicit PluginViewBase(PlatformWidget widget = 0) : Widget(widget) { }
......
2012-10-17 Sadrul Habib Chowdhury <sadrul@chromium.org>
plugins: Allow a plugin to dictate whether it can receive drag events or not.
https://bugs.webkit.org/show_bug.cgi?id=99355
Reviewed by Tony Chang.
Introduce WebPlugin::canProcessDrag() and use that to implement PluginViewBase::canProcessDrag.
* public/WebPlugin.h:
(WebKit::WebPlugin::canProcessDrag):
(WebPlugin):
* src/WebPluginContainerImpl.cpp:
(WebKit::WebPluginContainerImpl::canProcessDrag):
(WebKit):
(WebKit::WebPluginContainerImpl::handleMouseEvent):
* src/WebPluginContainerImpl.h:
(WebPluginContainerImpl):
2012-10-17 Jian Li <jianli@chromium.org>
[chromium] Remove legacy members from WebDraggableRegion
......
......@@ -70,6 +70,8 @@ public:
virtual bool getFormValue(WebString&) { return false; }
virtual bool supportsKeyboardFocus() const { return false; }
virtual bool canProcessDrag() const { return false; }
virtual void paint(WebCanvas*, const WebRect&) = 0;
// Coordinates are relative to the containing window.
......
......@@ -577,6 +577,11 @@ bool WebPluginContainerImpl::supportsKeyboardFocus() const
return m_webPlugin->supportsKeyboardFocus();
}
bool WebPluginContainerImpl::canProcessDrag() const
{
return m_webPlugin->canProcessDrag();
}
void WebPluginContainerImpl::willDestroyPluginLoadObserver(WebPluginLoadObserver* observer)
{
size_t pos = m_pluginLoadObservers.find(observer);
......@@ -661,7 +666,8 @@ void WebPluginContainerImpl::handleMouseEvent(MouseEvent* event)
ASSERT(parent()->isFrameView());
if (event->isDragEvent()) {
handleDragEvent(event);
if (m_webPlugin->canProcessDrag())
handleDragEvent(event);
return;
}
......
......@@ -78,6 +78,7 @@ public:
// PluginViewBase methods
virtual bool getFormValue(String&);
virtual bool supportsKeyboardFocus() const;
virtual bool canProcessDrag() const;
// Widget methods
virtual void setFrameRect(const WebCore::IntRect&);
......
2012-10-17 Sadrul Habib Chowdhury <sadrul@chromium.org>
plugins: Allow a plugin to dictate whether it can receive drag events or not.
https://bugs.webkit.org/show_bug.cgi?id=99355
Reviewed by Tony Chang.
Update the TestWebPlugin to implement the new |canProcessDrag| interface.
* DumpRenderTree/chromium/TestWebPlugin.h:
(TestWebPlugin::canProcessDrag):
2012-10-17 Dominic Mazzoni <dmazzoni@google.com>
Unreviewed. Create an accessibility watchlist.
......
......@@ -125,6 +125,7 @@ TestWebPlugin::TestWebPlugin(WebKit::WebFrame* frame,
, m_context(0)
, m_acceptsTouchEvent(false)
, m_printEventDetails(false)
, m_canProcessDrag(false)
{
static const WebString kAttributePrimitive = WebString::fromUTF8("primitive");
static const WebString kAttributeBackgroundColor = WebString::fromUTF8("background-color");
......@@ -132,6 +133,7 @@ TestWebPlugin::TestWebPlugin(WebKit::WebFrame* frame,
static const WebString kAttributeOpacity = WebString::fromUTF8("opacity");
static const WebString kAttributeAcceptsTouch = WebString::fromUTF8("accepts-touch");
static const WebString kAttributePrintEventDetails = WebString::fromUTF8("print-event-details");
static const WebString kAttributeCanProcessDrag = WebString::fromUTF8("can-process-drag");
ASSERT(params.attributeNames.size() == params.attributeValues.size());
size_t size = params.attributeNames.size();
......@@ -151,6 +153,8 @@ TestWebPlugin::TestWebPlugin(WebKit::WebFrame* frame,
m_acceptsTouchEvent = parseBoolean(attributeValue);
else if (attributeName == kAttributePrintEventDetails)
m_printEventDetails = parseBoolean(attributeValue);
else if (attributeName == kAttributeCanProcessDrag)
m_canProcessDrag = parseBoolean(attributeValue);
}
}
......
......@@ -56,6 +56,7 @@ public:
virtual bool initialize(WebKit::WebPluginContainer*);
virtual void destroy();
virtual NPObject* scriptableObject() { return 0; }
virtual bool canProcessDrag() const { return m_canProcessDrag; }
virtual void paint(WebKit::WebCanvas*, const WebKit::WebRect&) { }
virtual void updateGeometry(const WebKit::WebRect& frameRect,
const WebKit::WebRect& clipRect,
......@@ -132,6 +133,7 @@ private:
bool m_acceptsTouchEvent;
bool m_printEventDetails;
bool m_canProcessDrag;
};
#endif // TestPepperPlugin_h
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment