summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorleviw <leviw@chromium.org>2016-02-17 23:34:50 -0800
committerCommit bot <commit-bot@chromium.org>2016-02-18 07:35:41 +0000
commiteec0a93f429b9797678ca67f8359ea65a6496ca3 (patch)
tree1eb6c811768483343f9bae5a79cbed6bb0dfba4d
parent67f195ef19365fce612b2d84799a2c7b26c2df96 (diff)
downloadchromium_src-eec0a93f429b9797678ca67f8359ea65a6496ca3.zip
chromium_src-eec0a93f429b9797678ca67f8359ea65a6496ca3.tar.gz
chromium_src-eec0a93f429b9797678ca67f8359ea65a6496ca3.tar.bz2
Ensure WebView plugins run their lifecycle even absent main frame Layout
The PluginView method layoutIfNeeded causes WebView plugins to update their entire lifecycle, but we only call that if their layout is dirtied. In the presence of some style changes, they can need invalidation or compositing updates without layout, and our recursive lifecycle update missed WebView plugins as it only recurses through the Frame tree. This change always updates child plugins when FrameView::updateStyleAndLayoutIfNeededRecursive is called. BUG=545039 Review URL: https://codereview.chromium.org/1708923002 Cr-Commit-Position: refs/heads/master@{#376114}
-rw-r--r--third_party/WebKit/LayoutTests/fast/plugins/webview-plugin-updates-without-layout-expected.txt1
-rw-r--r--third_party/WebKit/LayoutTests/fast/plugins/webview-plugin-updates-without-layout.html19
-rw-r--r--third_party/WebKit/Source/core/frame/FrameView.cpp13
3 files changed, 33 insertions, 0 deletions
diff --git a/third_party/WebKit/LayoutTests/fast/plugins/webview-plugin-updates-without-layout-expected.txt b/third_party/WebKit/LayoutTests/fast/plugins/webview-plugin-updates-without-layout-expected.txt
new file mode 100644
index 0000000..e8cafe5
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/plugins/webview-plugin-updates-without-layout-expected.txt
@@ -0,0 +1 @@
+ Test passes if no crash.
diff --git a/third_party/WebKit/LayoutTests/fast/plugins/webview-plugin-updates-without-layout.html b/third_party/WebKit/LayoutTests/fast/plugins/webview-plugin-updates-without-layout.html
new file mode 100644
index 0000000..d6ab5ff
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/plugins/webview-plugin-updates-without-layout.html
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<style>
+html:first-letter { color: papayawhip; }
+</style>
+<script>
+function boom() {
+ if (window.testRunner)
+ testRunner.dumpAsText();
+
+ // Trigger a full-document style recalc.
+ document.getElementsByTagName("style")[0].disabled = true;
+ // Force the style to update without running the rest of the lifecycle.
+ document.querySelector("embed").align;
+}
+</script>
+<body onload="boom()">
+<embed type="html">
+Test passes if no crash.
+
diff --git a/third_party/WebKit/Source/core/frame/FrameView.cpp b/third_party/WebKit/Source/core/frame/FrameView.cpp
index 6bd87f9..b1fd652 100644
--- a/third_party/WebKit/Source/core/frame/FrameView.cpp
+++ b/third_party/WebKit/Source/core/frame/FrameView.cpp
@@ -80,6 +80,7 @@
#include "core/paint/FramePainter.h"
#include "core/paint/PaintLayer.h"
#include "core/paint/PaintPropertyTreeBuilder.h"
+#include "core/plugins/PluginView.h"
#include "core/style/ComputedStyle.h"
#include "core/svg/SVGDocumentExtensions.h"
#include "core/svg/SVGSVGElement.h"
@@ -2435,6 +2436,7 @@ void FrameView::scheduleVisualUpdateForPaintInvalidationIfNeeded()
// Otherwise the paint invalidation will be handled in paint invalidation phase of this cycle.
}
+// TODO(leviw): We don't assert lifecycle information from documents in child PluginViews.
void FrameView::updateLifecyclePhasesInternal(LifeCycleUpdateOption phases)
{
Optional<TemporaryChange<bool>> isUpdatingAllLifecyclePhasesScope;
@@ -2622,6 +2624,17 @@ void FrameView::updateStyleAndLayoutIfNeededRecursive()
if (needsLayout())
layout();
+ // WebView plugins need to update regardless of whether the LayoutEmbeddedObject
+ // that owns them needed layout.
+ // TODO(leviw): This currently runs the entire lifecycle on plugin WebViews. We
+ // should have a way to only run these other Documents to the same lifecycle stage
+ // as this frame.
+ const ChildrenWidgetSet* viewChildren = children();
+ for (const RefPtrWillBeMember<Widget>& child : *viewChildren) {
+ if ((*child).isPluginContainer())
+ toPluginView(child.get())->layoutIfNeeded();
+ }
+
// FIXME: Calling layout() shouldn't trigger script execution or have any
// observable effects on the frame tree but we're not quite there yet.
WillBeHeapVector<RefPtrWillBeMember<FrameView>> frameViews;