Implement mechanism to detect (partially) hidden blocked plugins.
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 3 Jul 2013 23:56:23 +0000 (23:56 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 3 Jul 2013 23:56:23 +0000 (23:56 +0000)
https://bugs.webkit.org/show_bug.cgi?id=117998

Patch by Gordon Sheridan <gordon_sheridan@apple.com> on 2013-07-03
Reviewed by Dean Jackson.

Source/WebCore:

* rendering/RenderEmbeddedObject.cpp:
(WebCore::RenderEmbeddedObject::replacementTextRect):
Added private method for calculating the size of the replacement text for blocked plugins.

(WebCore::RenderEmbeddedObject::isReplacementObscured):
Added public method to determine if the EMBED element used for a blocked plugin is inaccessible to the user.
* rendering/RenderEmbeddedObject.h:
Declare the two new methods mentioned above.

* WebCore.exp.in:
Export RenderEmbeddedObject::isReplacementObscured().

Source/WebKit2:

* Shared/Plugins/Netscape/PluginInformation.h:
* Shared/Plugins/Netscape/PluginInformation.cpp:
(WebKit::plugInInformationReplacementObscuredKey):
Add key for plugInInformation dictionaries.

(WebKit::createPluginInformationDictionary):
Add boolean parameter identifying whether the replacement for a blocked plugin is obscured, and add it to the dictionary.

* Shared/API/c/WKPluginInformation.h:
* Shared/API/c/WKPluginInformation.cpp:
(WKPluginInformationReplacementObscuredKey):
Provide the C API for the plugInInformationReplacementObscuredKey().

* UIProcess/WebPageProxy.h:
* UIProcess/WebPageProxy.cpp:
(WebKit::WebPageProxy::didBlockInsecurePluginVersion):
Add bool replacementObscured parameter to pass on argument to createPluginInformationDictionary().

* UIProcess/WebPageProxy.messages.in:
Add bool replacementObscured parameter to DidBlockInsecurePluginVersion() message.

* WebProcess/WebPage/WebPage.cpp:
(WebKit::WebPage::createPlugin):
Invoke isReplacementObscured() method for blocked plugins.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@152382 268f45cc-cd09-0410-ab3c-d52691b4dbfc

13 files changed:
Source/WebCore/ChangeLog
Source/WebCore/WebCore.exp.in
Source/WebCore/rendering/RenderEmbeddedObject.cpp
Source/WebCore/rendering/RenderEmbeddedObject.h
Source/WebKit2/ChangeLog
Source/WebKit2/Shared/API/c/WKPluginInformation.cpp
Source/WebKit2/Shared/API/c/WKPluginInformation.h
Source/WebKit2/Shared/Plugins/Netscape/PluginInformation.cpp
Source/WebKit2/Shared/Plugins/Netscape/PluginInformation.h
Source/WebKit2/UIProcess/WebPageProxy.cpp
Source/WebKit2/UIProcess/WebPageProxy.h
Source/WebKit2/UIProcess/WebPageProxy.messages.in
Source/WebKit2/WebProcess/WebPage/WebPage.cpp

index d1595cf..c2b7489 100644 (file)
@@ -1,3 +1,22 @@
+2013-07-03  Gordon Sheridan  <gordon_sheridan@apple.com>
+
+        Implement mechanism to detect (partially) hidden blocked plugins.
+        https://bugs.webkit.org/show_bug.cgi?id=117998
+
+        Reviewed by Dean Jackson.
+
+        * rendering/RenderEmbeddedObject.cpp:
+        (WebCore::RenderEmbeddedObject::replacementTextRect):
+        Added private method for calculating the size of the replacement text for blocked plugins.
+
+        (WebCore::RenderEmbeddedObject::isReplacementObscured):
+        Added public method to determine if the EMBED element used for a blocked plugin is inaccessible to the user.
+        * rendering/RenderEmbeddedObject.h:
+        Declare the two new methods mentioned above.
+
+        * WebCore.exp.in:
+        Export RenderEmbeddedObject::isReplacementObscured().
+
 2013-07-03  Jessie Berlin  <jberlin@apple.com>
 
         Speculative build fix after r152340.
index 8c82932..33586a2 100644 (file)
@@ -666,6 +666,7 @@ __ZN7WebCore20DisplaySleepDisablerD1Ev
 __ZN7WebCore20NodeRenderingContextC1EPNS_4NodeE
 __ZN7WebCore20NodeRenderingContextD1Ev
 __ZN7WebCore20RenderEmbeddedObject29setPluginUnavailabilityReasonENS0_26PluginUnavailabilityReasonE
+__ZNK7WebCore20RenderEmbeddedObject21isReplacementObscuredEv
 __ZN7WebCore20ResourceHandleClient16didReceiveBufferEPNS_14ResourceHandleEN3WTF10PassRefPtrINS_12SharedBufferEEEi
 __ZN7WebCore20ResourceHandleClient20willSendRequestAsyncEPNS_14ResourceHandleERKNS_15ResourceRequestERKNS_16ResourceResponseE
 __ZN7WebCore20ResourceHandleClient22willCacheResponseAsyncEPNS_14ResourceHandleEP19NSCachedURLResponse
index e9f0f7e..528e5af 100644 (file)
@@ -49,6 +49,7 @@
 #include "Path.h"
 #include "PlatformMouseEvent.h"
 #include "PluginViewBase.h"
+#include "RenderLayer.h"
 #include "RenderTheme.h"
 #include "RenderView.h"
 #include "RenderWidgetProtector.h"
@@ -277,6 +278,86 @@ bool RenderEmbeddedObject::getReplacementTextGeometry(const LayoutPoint& accumul
     return true;
 }
 
+LayoutRect RenderEmbeddedObject::replacementTextRect(const LayoutPoint& accumulatedOffset) const
+{
+    FloatRect contentRect;
+    Path path;
+    FloatRect replacementTextRect;
+    Font font;
+    TextRun run("", 0);
+    float textWidth;
+    if (getReplacementTextGeometry(accumulatedOffset, contentRect, path, replacementTextRect, font, run, textWidth))
+        return LayoutRect(replacementTextRect);
+    
+    return LayoutRect();
+}
+
+bool RenderEmbeddedObject::isReplacementObscured() const
+{
+    // Return whether or not the replacement content for blocked plugins is accessible to the user.
+    
+    // Check the opacity of each layer containing the element or its ancestors.
+    float opacity = 1.0;
+    for (RenderLayer* layer = enclosingLayer(); layer; layer = layer->parent()) {
+        RenderLayerModelObject* renderer = layer->renderer();
+        RenderStyle* style = renderer->style();
+        opacity *= style->opacity();
+        if (opacity < 0.1)
+            return true;
+    }
+
+    // Calculate the absolute rect for the blocked plugin replacement text.
+    IntRect absoluteBoundingBox = absoluteBoundingBoxRect();
+    LayoutPoint absoluteLocation(absoluteBoundingBox.location());
+    LayoutRect rect = replacementTextRect(absoluteLocation);
+    if (rect.isEmpty())
+        return true;
+
+    RenderView* docRenderer = document()->renderView();
+    ASSERT(docRenderer);
+    if (!docRenderer)
+        return true;
+    
+    HitTestRequest request(HitTestRequest::ReadOnly | HitTestRequest::Active | HitTestRequest::IgnoreClipping | HitTestRequest::DisallowShadowContent);
+    HitTestResult result;
+    HitTestLocation location;
+    
+    LayoutUnit x = rect.x();
+    LayoutUnit y = rect.y();
+    LayoutUnit width = rect.width();
+    LayoutUnit height = rect.height();
+    
+    // Hit test the center and near the corners of the replacement text to ensure
+    // it is visible and is not masked by other elements.
+    bool hit = false;
+    location = LayoutPoint(x + width / 2, y + height / 2);
+    hit = docRenderer->hitTest(request, location, result);
+    if (!hit || result.innerNode() != node())
+        return true;
+    
+    location = LayoutPoint(x, y);
+    hit = docRenderer->hitTest(request, location, result);
+    if (!hit || result.innerNode() != node())
+        return true;
+    
+    location = LayoutPoint(x + width, y);
+    hit = docRenderer->hitTest(request, location, result);
+    if (!hit || result.innerNode() != node())
+        return true;
+    
+    location = LayoutPoint(x + width, y + height);
+    hit = docRenderer->hitTest(request, location, result);
+    if (!hit || result.innerNode() != node())
+        return true;
+    
+    location = LayoutPoint(x, y + height);
+    hit = docRenderer->hitTest(request, location, result);
+    if (!hit || result.innerNode() != node())
+        return true;
+
+    return false;
+}
+
 void RenderEmbeddedObject::layout()
 {
     StackStats::LayoutCheckPoint layoutCheckPoint;
index 91e44d5..158a3d0 100644 (file)
@@ -52,6 +52,8 @@ public:
 
     void handleUnavailablePluginIndicatorEvent(Event*);
 
+    bool isReplacementObscured() const;
+
 #if USE(ACCELERATED_COMPOSITING)
     virtual bool allowsAcceleratedCompositing() const;
 #endif
@@ -90,6 +92,7 @@ private:
     bool isInUnavailablePluginIndicator(MouseEvent*) const;
     bool isInUnavailablePluginIndicator(const LayoutPoint&) const;
     bool getReplacementTextGeometry(const LayoutPoint& accumulatedOffset, FloatRect& contentRect, Path&, FloatRect& replacementTextRect, Font&, TextRun&, float& textWidth) const;
+    LayoutRect replacementTextRect(const LayoutPoint&) const;
 
     virtual bool canHaveChildren() const;
     virtual RenderObjectChildList* virtualChildren() { return children(); }
index a151f28..19095cf 100644 (file)
@@ -1,3 +1,35 @@
+2013-07-03  Gordon Sheridan  <gordon_sheridan@apple.com>
+
+        Implement mechanism to detect (partially) hidden blocked plugins.
+        https://bugs.webkit.org/show_bug.cgi?id=117998
+
+        Reviewed by Dean Jackson.
+
+        * Shared/Plugins/Netscape/PluginInformation.h:
+        * Shared/Plugins/Netscape/PluginInformation.cpp:
+        (WebKit::plugInInformationReplacementObscuredKey):
+        Add key for plugInInformation dictionaries.
+
+        (WebKit::createPluginInformationDictionary):
+        Add boolean parameter identifying whether the replacement for a blocked plugin is obscured, and add it to the dictionary.
+
+        * Shared/API/c/WKPluginInformation.h:
+        * Shared/API/c/WKPluginInformation.cpp:
+        (WKPluginInformationReplacementObscuredKey):
+        Provide the C API for the plugInInformationReplacementObscuredKey().
+
+        * UIProcess/WebPageProxy.h:
+        * UIProcess/WebPageProxy.cpp:
+        (WebKit::WebPageProxy::didBlockInsecurePluginVersion):
+        Add bool replacementObscured parameter to pass on argument to createPluginInformationDictionary().
+
+        * UIProcess/WebPageProxy.messages.in:
+        Add bool replacementObscured parameter to DidBlockInsecurePluginVersion() message.
+
+        * WebProcess/WebPage/WebPage.cpp:
+        (WebKit::WebPage::createPlugin):
+        Invoke isReplacementObscured() method for blocked plugins.
+
 2013-07-03  Alexey Proskuryakov  <ap@apple.com>
 
         <rdar://problem/14271105> Flash Player: deny ipc-posix-sem 59918130
@@ -36,6 +68,7 @@
         (WebKit::WebTextCheckerClient::checkSpellingOfString):
         (WebKit::WebTextCheckerClient::checkGrammarOfString):
 
+
 2013-07-03  Sergio Villar Senin  <svillar@igalia.com>
 
         [GTK][WK2] SIGSEV in WebKit::WebPageContextMenuClient::customContextMenuItemSelected
index 48b8456..d4cc39c 100644 (file)
@@ -115,3 +115,9 @@ WKStringRef WKPlugInInformationPageContainsNonPlayingInstanceOfPlugInKey()
     static WebString* key = WebString::create(plugInInformationPageContainsNonPlayingInstanceOfPlugInKey()).leakRef();
     return toAPI(key);
 }
+
+WKStringRef WKPlugInInformationReplacementObscuredKey()
+{
+    static WebString* key = WebString::create(plugInInformationReplacementObscuredKey()).leakRef();
+    return toAPI(key);
+}
index 2b3f879..47a42e2 100644 (file)
@@ -79,6 +79,9 @@ WK_EXPORT WKStringRef WKPluginInformationPluginURLKey();
 /* Value type: WKBooleanRef */
 WK_EXPORT WKStringRef WKPlugInInformationPageContainsNonPlayingInstanceOfPlugInKey();
 
+/* Value type: WKBooleanRef */
+WK_EXPORT WKStringRef WKPlugInInformationReplacementObscuredKey();
+
 #ifdef __cplusplus
 }
 #endif
index 253f828..ecc8cb3 100644 (file)
@@ -106,6 +106,11 @@ String plugInInformationPageContainsNonPlayingInstanceOfPlugInKey()
     return ASCIILiteral("PlugInInformationPageContainsNonPlayingInstanceOfPlugIn");
 }
 
+String plugInInformationReplacementObscuredKey()
+{
+    return ASCIILiteral("PlugInInformationReplacementObscured");
+}
+
 void getPluginModuleInformation(const PluginModuleInfo& plugin, ImmutableDictionary::MapType& map)
 {
 #if ENABLE(NETSCAPE_PLUGIN_API)
@@ -135,7 +140,7 @@ PassRefPtr<ImmutableDictionary> createPlugInInformationDictionary(const PluginMo
     return ImmutableDictionary::adopt(map);
 }
 
-PassRefPtr<ImmutableDictionary> createPluginInformationDictionary(const PluginModuleInfo& plugin, const String& frameURLString, const String& mimeType, const String& pageURLString, const String& pluginspageAttributeURLString, const String& pluginURLString)
+PassRefPtr<ImmutableDictionary> createPluginInformationDictionary(const PluginModuleInfo& plugin, const String& frameURLString, const String& mimeType, const String& pageURLString, const String& pluginspageAttributeURLString, const String& pluginURLString, bool replacementObscured)
 {
     ImmutableDictionary::MapType map;
     getPluginModuleInformation(plugin, map);
@@ -150,6 +155,7 @@ PassRefPtr<ImmutableDictionary> createPluginInformationDictionary(const PluginMo
         map.set(pluginInformationPluginspageAttributeURLKey(), WebURL::create(pluginspageAttributeURLString));
     if (!pluginURLString.isEmpty())
         map.set(pluginInformationPluginURLKey(), WebURL::create(pluginURLString));
+    map.set(plugInInformationReplacementObscuredKey(), WebBoolean::create(replacementObscured));
 
     return ImmutableDictionary::adopt(map);
 }
index 0c129d1..9bac3cb 100644 (file)
@@ -50,9 +50,10 @@ String pluginInformationPageURLKey();
 String pluginInformationPluginspageAttributeURLKey();
 String pluginInformationPluginURLKey();
 String plugInInformationPageContainsNonPlayingInstanceOfPlugInKey();
+String plugInInformationReplacementObscuredKey();
 
 PassRefPtr<ImmutableDictionary> createPluginInformationDictionary(const PluginModuleInfo&);
-PassRefPtr<ImmutableDictionary> createPluginInformationDictionary(const PluginModuleInfo&, const String& frameURLString, const String& mimeType, const String& pageURLString, const String& pluginspageAttributeURLString, const String& pluginURLString);
+PassRefPtr<ImmutableDictionary> createPluginInformationDictionary(const PluginModuleInfo&, const String& frameURLString, const String& mimeType, const String& pageURLString, const String& pluginspageAttributeURLString, const String& pluginURLString, bool replacementObscured = false);
 PassRefPtr<ImmutableDictionary> createPluginInformationDictionary(const String& mimeType, const String& frameURLString, const String& pageURLString);
 PassRefPtr<ImmutableDictionary> createPlugInInformationDictionary(const PluginModuleInfo&, bool pageContainsNonPlayingInstanceOfPlugIn);
 
index d280dbc..7b6f198 100644 (file)
@@ -4207,14 +4207,14 @@ void WebPageProxy::didFailToInitializePlugin(const String& mimeType, const Strin
     m_loaderClient.didFailToInitializePlugin(this, createPluginInformationDictionary(mimeType, frameURLString, pageURLString).get());
 }
 
-void WebPageProxy::didBlockInsecurePluginVersion(const String& mimeType, const String& pluginURLString, const String& frameURLString, const String& pageURLString)
+void WebPageProxy::didBlockInsecurePluginVersion(const String& mimeType, const String& pluginURLString, const String& frameURLString, const String& pageURLString, bool replacementObscured)
 {
     RefPtr<ImmutableDictionary> pluginInformation;
 
 #if PLATFORM(MAC) && ENABLE(NETSCAPE_PLUGIN_API)
     String newMimeType = mimeType;
     PluginModuleInfo plugin = m_process->context()->pluginInfoStore().findPlugin(newMimeType, KURL(KURL(), pluginURLString));
-    pluginInformation = createPluginInformationDictionary(plugin, frameURLString, mimeType, pageURLString, String(), String());
+    pluginInformation = createPluginInformationDictionary(plugin, frameURLString, mimeType, pageURLString, String(), String(), replacementObscured);
 #else
     UNUSED_PARAM(pluginURLString);
 #endif
index a6fe224..a866176 100644 (file)
@@ -868,7 +868,7 @@ private:
     void didChangeScrollOffsetPinningForMainFrame(bool pinnedToLeftSide, bool pinnedToRightSide, bool pinnedToTopSide, bool pinnedToBottomSide);
     void didChangePageCount(unsigned);
     void didFailToInitializePlugin(const String& mimeType, const String& frameURLString, const String& pageURLString);
-    void didBlockInsecurePluginVersion(const String& mimeType, const String& pluginURLString, const String& frameURLString, const String& pageURLString);
+    void didBlockInsecurePluginVersion(const String& mimeType, const String& pluginURLString, const String& frameURLString, const String& pageURLString, bool replacementObscured);
     void setCanShortCircuitHorizontalWheelEvents(bool canShortCircuitHorizontalWheelEvents) { m_canShortCircuitHorizontalWheelEvents = canShortCircuitHorizontalWheelEvents; }
 
     void reattachToWebProcess();
index cf87485..fc2fc3e 100644 (file)
@@ -66,7 +66,7 @@ messages -> WebPageProxy {
     DidChangeScrollOffsetPinningForMainFrame(bool pinnedToLeftSide, bool pinnedToRightSide, bool pinnedToTopSide, bool pinnedToBottomSide)
     DidChangePageCount(unsigned pageCount);
     DidFailToInitializePlugin(WTF::String mimeType, WTF::String frameURLString, WTF::String pageURLString)
-    DidBlockInsecurePluginVersion(WTF::String mimeType, WTF::String pluginURLString, WTF::String frameURLString, WTF::String pageURLString)
+    DidBlockInsecurePluginVersion(WTF::String mimeType, WTF::String pluginURLString, WTF::String frameURLString, WTF::String pageURLString, bool replacementObscured)
     SetCanShortCircuitHorizontalWheelEvents(bool canShortCircuitHorizontalWheelEvents)
 
 #if PLATFORM(EFL)
index 3b1db78..afb6a45 100644 (file)
@@ -549,10 +549,14 @@ PassRefPtr<Plugin> WebPage::createPlugin(WebFrame* frame, HTMLPlugInElement* plu
         break;
 
     case PluginModuleBlocked:
-        if (pluginElement->renderer()->isEmbeddedObject())
-            toRenderEmbeddedObject(pluginElement->renderer())->setPluginUnavailabilityReason(RenderEmbeddedObject::InsecurePluginVersion);
+        bool replacementObscured = false;
+        if (pluginElement->renderer()->isEmbeddedObject()) {
+            RenderEmbeddedObject* renderObject = toRenderEmbeddedObject(pluginElement->renderer());
+            renderObject->setPluginUnavailabilityReason(RenderEmbeddedObject::InsecurePluginVersion);
+            replacementObscured = renderObject->isReplacementObscured();
+        }
 
-        send(Messages::WebPageProxy::DidBlockInsecurePluginVersion(parameters.mimeType, parameters.url.string(), frameURLString, pageURLString));
+        send(Messages::WebPageProxy::DidBlockInsecurePluginVersion(parameters.mimeType, parameters.url.string(), frameURLString, pageURLString, replacementObscured));
         return 0;
     }