OSDN Git Service

Merge WebKit at r71558: Initial merge by git.
[android-x86/external-webkit.git] / WebKit / chromium / src / WebPluginContainerImpl.cpp
index 2cdf255..43d9757 100644 (file)
 
 #include "Chrome.h"
 #include "ChromeClientImpl.h"
+#include "PluginLayerChromium.h"
+#include "WebClipboard.h"
 #include "WebCursorInfo.h"
 #include "WebDataSourceImpl.h"
+#include "WebElement.h"
 #include "WebInputEvent.h"
 #include "WebInputEventConversion.h"
 #include "WebKit.h"
+#include "WebKitClient.h"
 #include "WebPlugin.h"
 #include "WebRect.h"
+#include "WebString.h"
+#include "WebURL.h"
 #include "WebURLError.h"
 #include "WebURLRequest.h"
 #include "WebVector.h"
+#include "WebViewImpl.h"
 #include "WrappedResourceResponse.h"
 
 #include "EventNames.h"
 #include "HTMLFormElement.h"
 #include "HTMLNames.h"
 #include "HTMLPlugInElement.h"
+#include "KeyboardCodes.h"
 #include "KeyboardEvent.h"
 #include "MouseEvent.h"
 #include "Page.h"
+#include "RenderBox.h"
 #include "ScrollView.h"
 #include "WheelEvent.h"
 
@@ -128,10 +137,10 @@ void WebPluginContainerImpl::invalidateRect(const IntRect& rect)
     parent()->hostWindow()->invalidateContentsAndWindow(damageRect, false /*immediate*/);
 }
 
-void WebPluginContainerImpl::setFocus()
+void WebPluginContainerImpl::setFocus(bool focused)
 {
-    Widget::setFocus();
-    m_webPlugin->updateFocus(true);
+    Widget::setFocus(focused);
+    m_webPlugin->updateFocus(focused);
 }
 
 void WebPluginContainerImpl::show()
@@ -165,6 +174,11 @@ void WebPluginContainerImpl::handleEvent(Event* event)
         handleWheelEvent(static_cast<WheelEvent*>(event));
     else if (event->isKeyboardEvent())
         handleKeyboardEvent(static_cast<KeyboardEvent*>(event));
+
+    // FIXME: it would be cleaner if Widget::handleEvent returned true/false and
+    // HTMLPluginElement called setDefaultHandled or defaultEventHandler.
+    if (!event->defaultHandled())
+        m_element->Node::defaultEventHandler(event);
 }
 
 void WebPluginContainerImpl::frameRectsChanged()
@@ -239,6 +253,19 @@ void WebPluginContainerImpl::printEnd()
     return m_webPlugin->printEnd();
 }
 
+void WebPluginContainerImpl::copy()
+{
+    if (!plugin()->hasSelection())
+        return;
+
+    webKitClient()->clipboard()->writeHTML(plugin()->selectionAsMarkup(), WebURL(), plugin()->selectionAsText(), false);
+}
+
+WebElement WebPluginContainerImpl::element()
+{
+    return WebElement(m_element);
+}
+
 void WebPluginContainerImpl::invalidate()
 {
     Widget::invalidate();
@@ -249,6 +276,25 @@ void WebPluginContainerImpl::invalidateRect(const WebRect& rect)
     invalidateRect(static_cast<IntRect>(rect));
 }
 
+void WebPluginContainerImpl::scrollRect(int dx, int dy, const WebRect& rect)
+{
+    Widget* parentWidget = parent();
+    if (parentWidget->isFrameView()) {
+        FrameView* parentFrameView = static_cast<FrameView*>(parentWidget);
+        if (!parentFrameView->isOverlapped()) {
+            IntRect damageRect = convertToContainingWindow(static_cast<IntRect>(rect));
+            IntSize scrollDelta(dx, dy);
+            // scroll() only uses the second rectangle, clipRect, and ignores the first
+            // rectangle.
+            parent()->hostWindow()->scroll(scrollDelta, damageRect, damageRect);
+            return;
+        }
+    }
+
+    // Use slow scrolling instead.
+    invalidateRect(rect);
+}
+
 void WebPluginContainerImpl::reportGeometry()
 {
     if (!parent())
@@ -261,6 +307,14 @@ void WebPluginContainerImpl::reportGeometry()
     m_webPlugin->updateGeometry(windowRect, clipRect, cutOutRects, isVisible());
 }
 
+void WebPluginContainerImpl::commitBackingTexture()
+{
+#if USE(ACCELERATED_COMPOSITING)
+    if (platformLayer())
+        platformLayer()->setNeedsDisplay();
+#endif
+}
+
 void WebPluginContainerImpl::clearScriptObjects()
 {
     Frame* frame = m_element->document()->frame();
@@ -323,6 +377,12 @@ void WebPluginContainerImpl::loadFrameRequest(
         SendReferrer);
 }
 
+void WebPluginContainerImpl::zoomLevelChanged(double zoomLevel)
+{
+    WebViewImpl* view = WebViewImpl::fromPage(m_element->document()->frame()->page());
+    view->fullFramePluginZoomLevelChanged(zoomLevel);
+}
+
 void WebPluginContainerImpl::didReceiveResponse(const ResourceResponse& response)
 {
     // Make sure that the plugin receives window geometry before data, or else
@@ -361,8 +421,33 @@ void WebPluginContainerImpl::willDestroyPluginLoadObserver(WebPluginLoadObserver
     m_pluginLoadObservers.remove(pos);
 }
 
+#if USE(ACCELERATED_COMPOSITING)
+WebCore::LayerChromium* WebPluginContainerImpl::platformLayer() const
+{
+    // FIXME: In the event of a context lost, the texture needs to be recreated on the compositor's
+    // context and rebound to the platform layer here.
+    unsigned backingTextureId = m_webPlugin->getBackingTextureId();
+    if (!backingTextureId)
+        return 0;
+
+    m_platformLayer->setTextureId(backingTextureId);
+
+    return m_platformLayer.get();
+}
+#endif
+
 // Private methods -------------------------------------------------------------
 
+WebPluginContainerImpl::WebPluginContainerImpl(WebCore::HTMLPlugInElement* element, WebPlugin* webPlugin)
+    : WebCore::PluginViewBase(0)
+    , m_element(element)
+    , m_webPlugin(webPlugin)
+#if USE(ACCELERATED_COMPOSITING)
+    , m_platformLayer(PluginLayerChromium::create(0))
+#endif
+{
+}
+
 WebPluginContainerImpl::~WebPluginContainerImpl()
 {
     for (size_t i = 0; i < m_pluginLoadObservers.size(); ++i)
@@ -378,7 +463,7 @@ void WebPluginContainerImpl::handleMouseEvent(MouseEvent* event)
     // in the call to HandleEvent. See http://b/issue?id=1362948
     FrameView* parentView = static_cast<FrameView*>(parent());
 
-    WebMouseEventBuilder webEvent(parentView, *event);
+    WebMouseEventBuilder webEvent(this, *event);
     if (webEvent.type == WebInputEvent::Undefined)
         return;
 
@@ -408,8 +493,7 @@ void WebPluginContainerImpl::handleMouseEvent(MouseEvent* event)
 
 void WebPluginContainerImpl::handleWheelEvent(WheelEvent* event)
 {
-    FrameView* parentView = static_cast<FrameView*>(parent());
-    WebMouseWheelEventBuilder webEvent(parentView, *event);
+    WebMouseWheelEventBuilder webEvent(this, *event);
     if (webEvent.type == WebInputEvent::Undefined)
         return;
 
@@ -424,6 +508,29 @@ void WebPluginContainerImpl::handleKeyboardEvent(KeyboardEvent* event)
     if (webEvent.type == WebInputEvent::Undefined)
         return;
 
+    if (webEvent.type == WebInputEvent::KeyDown) {
+#if defined(OS_MACOSX)
+        if (webEvent.modifiers == WebInputEvent::MetaKey
+#else
+        if (webEvent.modifiers == WebInputEvent::ControlKey
+#endif
+            && webEvent.windowsKeyCode == VKEY_C) {
+            copy();
+            event->setDefaultHandled();
+            return;
+        }
+    }
+
+    const WebInputEvent* currentInputEvent = WebViewImpl::currentInputEvent();
+
+    // Copy stashed info over, and only copy here in order not to interfere
+    // the ctrl-c logic above.
+    if (currentInputEvent
+        && WebInputEvent::isKeyboardEventType(currentInputEvent->type)) {
+        webEvent.modifiers |= currentInputEvent->modifiers &
+            (WebInputEvent::CapsLockOn | WebInputEvent::NumLockOn);
+    }
+
     WebCursorInfo cursorInfo;
     if (m_webPlugin->handleInputEvent(webEvent, cursorInfo))
         event->setDefaultHandled();
@@ -504,11 +611,20 @@ static bool checkStackOnTop(
                     return false;
             }
 
-            // For compatibility with IE: when the plugin is not positioned,
-            // it stacks behind the iframe, even if it's later in the
-            // document order.
-            if (ro2->style()->position() == StaticPosition)
+            // If the plugin does not have an explicit z-index it stacks behind the iframe.
+            // This is for maintaining compatibility with IE.
+            if (ro2->style()->position() == StaticPosition) {
+                // The 0'th elements of these RenderObject arrays represent the plugin node and
+                // the iframe.
+                const RenderObject* pluginRenderObject = pluginZstack[0];
+                const RenderObject* iframeRenderObject = iframeZstack[0];
+
+                if (pluginRenderObject->style() && iframeRenderObject->style()) {
+                    if (pluginRenderObject->style()->zIndex() > iframeRenderObject->style()->zIndex())
+                        return false;
+                }
                 return true;
+            }
 
             // Inspect the document order.  Later order means higher
             // stacking.