Traverse into subdocuments when mapping plugin rects from absolute to local space.

BUG=560707,564087

Review URL: https://codereview.chromium.org/1567623007

Cr-Commit-Position: refs/heads/master@{#368145}
(cherry picked from commit ef3591c447091eae0e5a12e4b7baac7bd5fe707a)

Review URL: https://codereview.chromium.org/1563303005 .

Cr-Commit-Position: refs/branch-heads/2564@{#511}
Cr-Branched-From: 1283eca15bd9f772387f75241576cde7bdec7f54-refs/heads/master@{#359700}
diff --git a/third_party/WebKit/LayoutTests/TestExpectations b/third_party/WebKit/LayoutTests/TestExpectations
index 77b75de..6214093 100644
--- a/third_party/WebKit/LayoutTests/TestExpectations
+++ b/third_party/WebKit/LayoutTests/TestExpectations
@@ -1472,3 +1472,5 @@
 crbug.com/568678 [ XP ] virtual/syncpaint/paint/roundedrects/input-with-rounded-rect-and-shadow.html [ NeedsRebaseline ]
 
 crbug.com/568678 [ XP ] virtual/gpu/fast/canvas/canvas-scale-strokePath-shadow.html [ Failure ]
+
+crbug.com/560707 plugins/plugin-clip-subframe.html [ NeedsRebaseline ]
\ No newline at end of file
diff --git a/third_party/WebKit/Source/web/WebPluginContainerImpl.cpp b/third_party/WebKit/Source/web/WebPluginContainerImpl.cpp
index e538e06..6ab87d3 100644
--- a/third_party/WebKit/Source/web/WebPluginContainerImpl.cpp
+++ b/third_party/WebKit/Source/web/WebPluginContainerImpl.cpp
@@ -968,7 +968,7 @@
 
     LayoutBox* box = toLayoutBox(ownerElement->layoutObject());
 
-    // Plugin frameRects are in absolute screen space.
+    // Plugin frameRects are in absolute space within their frame.
     IntRect frameRectInOwnerElementSpace = box->absoluteToLocalQuad(FloatRect(frameRect()), UseTransforms).enclosingBoundingBox();
 
     LayoutRect unclippedAbsoluteRect(frameRectInOwnerElementSpace);
@@ -986,8 +986,8 @@
     clippedLocalRect.intersect(rootView->frameView()->visibleContentRect());
 
     // TODO(chrishtr): intentionally ignore transform, because the positioning of frameRect() does also. This is probably wrong.
-    unclippedIntLocalRect = box->absoluteToLocalQuad(FloatRect(unclippedIntLocalRect)).enclosingBoundingBox();
-    clippedLocalRect = box->absoluteToLocalQuad(FloatRect(clippedLocalRect)).enclosingBoundingBox();
+    unclippedIntLocalRect = box->absoluteToLocalQuad(FloatRect(unclippedIntLocalRect), TraverseDocumentBoundaries).enclosingBoundingBox();
+    clippedLocalRect = box->absoluteToLocalQuad(FloatRect(clippedLocalRect), TraverseDocumentBoundaries).enclosingBoundingBox();
 }
 
 void WebPluginContainerImpl::calculateGeometry(IntRect& windowRect, IntRect& clipRect, IntRect& unobscuredRect, Vector<IntRect>& cutOutRects)
@@ -1006,4 +1006,4 @@
         cutOutRects[i].move(-frameRect().x(), -frameRect().y());
 }
 
-} // namespace blinkf
+} // namespace blink
diff --git a/third_party/WebKit/Source/web/WebPluginContainerImpl.h b/third_party/WebKit/Source/web/WebPluginContainerImpl.h
index dad54db..3b91b96 100644
--- a/third_party/WebKit/Source/web/WebPluginContainerImpl.h
+++ b/third_party/WebKit/Source/web/WebPluginContainerImpl.h
@@ -199,6 +199,8 @@
         const IntRect& frameRect,
         Vector<IntRect>& cutOutRects);
 
+    friend class WebPluginContainerTest;
+
     RawPtrWillBeMember<HTMLPlugInElement> m_element;
     WebPlugin* m_webPlugin;
 #if !ENABLE(OILPAN)
diff --git a/third_party/WebKit/Source/web/tests/WebPluginContainerTest.cpp b/third_party/WebKit/Source/web/tests/WebPluginContainerTest.cpp
index 8eb471c..42d02331 100644
--- a/third_party/WebKit/Source/web/tests/WebPluginContainerTest.cpp
+++ b/third_party/WebKit/Source/web/tests/WebPluginContainerTest.cpp
@@ -73,6 +73,11 @@
         Platform::current()->unitTestSupport()->unregisterAllMockedURLs();
     }
 
+    void calculateGeometry(WebPluginContainerImpl* pluginContainerImpl, IntRect& windowRect, IntRect& clipRect, IntRect& unobscuredRect, Vector<IntRect>& cutOutRects)
+    {
+        pluginContainerImpl->calculateGeometry(windowRect, clipRect, unobscuredRect, cutOutRects);
+    }
+
 protected:
     std::string m_baseURL;
 };
@@ -404,6 +409,46 @@
     EXPECT_FALSE(pluginContainerImpl->isRectTopmost(rect));
 }
 
+#define EXPECT_RECT_EQ(expected, actual) \
+    do { \
+        const IntRect& actualRect = actual; \
+        EXPECT_EQ(expected.x(), actualRect.x()); \
+        EXPECT_EQ(expected.y(), actualRect.y()); \
+        EXPECT_EQ(expected.width(), actualRect.width()); \
+        EXPECT_EQ(expected.height(), actualRect.height()); \
+    } while (false)
+
+TEST_F(WebPluginContainerTest, ClippedRectsForIframedElement)
+{
+    URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("plugin_container.html"));
+    URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("plugin_containing_page.html"));
+
+    TestPluginWebFrameClient pluginWebFrameClient; // Must outlive webViewHelper.
+    FrameTestHelpers::WebViewHelper webViewHelper;
+    WebView* webView = webViewHelper.initializeAndLoad(m_baseURL + "plugin_containing_page.html", true, &pluginWebFrameClient);
+    ASSERT(webView);
+    webView->settings()->setPluginsEnabled(true);
+    webView->resize(WebSize(300, 300));
+    webView->updateAllLifecyclePhases();
+    runPendingTasks();
+
+    WebElement pluginElement = webView->mainFrame()->firstChild()->document().getElementById("translated-plugin");
+    RefPtrWillBeRawPtr<WebPluginContainerImpl> pluginContainerImpl = toWebPluginContainerImpl(pluginElement.pluginContainer());
+
+    ASSERT(pluginContainerImpl.get());
+    pluginContainerImpl->setFrameRect(IntRect(0, 0, 300, 300));
+
+    IntRect windowRect, clipRect, unobscuredRect;
+    Vector<IntRect> cutOutRects;
+    calculateGeometry(pluginContainerImpl.get(), windowRect, clipRect, unobscuredRect, cutOutRects);
+    EXPECT_RECT_EQ(IntRect(10, 210, 300, 300), windowRect);
+    EXPECT_RECT_EQ(IntRect(0, 0, 240, 90), clipRect);
+    EXPECT_RECT_EQ(IntRect(0, 0, 240, 160), unobscuredRect);
+
+    // Cause the plugin's frame to be detached.
+    webViewHelper.reset();
+}
+
 TEST_F(WebPluginContainerTest, TopmostAfterDetachTest)
 {
     static WebRect topmostRect(10, 10, 40, 40);
diff --git a/third_party/WebKit/Source/web/tests/data/plugin_containing_page.html b/third_party/WebKit/Source/web/tests/data/plugin_containing_page.html
new file mode 100644
index 0000000..a8765ad
--- /dev/null
+++ b/third_party/WebKit/Source/web/tests/data/plugin_containing_page.html
@@ -0,0 +1,3 @@
+<!doctype HTML>
+<div style="width: 200px; height: 200px"></div>
+<iframe src="plugin_container.html" height="160" width="240"></iframe>