diff options
| author | leviw <leviw@chromium.org> | 2016-02-17 23:34:50 -0800 |
|---|---|---|
| committer | Commit bot <commit-bot@chromium.org> | 2016-02-18 07:35:41 +0000 |
| commit | eec0a93f429b9797678ca67f8359ea65a6496ca3 (patch) | |
| tree | 1eb6c811768483343f9bae5a79cbed6bb0dfba4d | |
| parent | 67f195ef19365fce612b2d84799a2c7b26c2df96 (diff) | |
| download | chromium_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}
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; |
