diff --git a/components/plugins/renderer/webview_plugin.cc b/components/plugins/renderer/webview_plugin.cc index b6ddb46033241a..05611db29fa03b 100644 --- a/components/plugins/renderer/webview_plugin.cc +++ b/components/plugins/renderer/webview_plugin.cc @@ -57,7 +57,8 @@ WebViewPlugin::WebViewPlugin(content::RenderView* render_view, web_view_(WebView::create(this)), finished_loading_(false), focused_(false), - is_painting_(false) { + is_painting_(false), + is_resizing_(false) { // ApplyWebPreferences before making a WebLocalFrame so that the frame sees a // consistent view of our preferences. content::RenderView::ApplyWebPreferences(preferences, web_view_); @@ -199,14 +200,22 @@ void WebViewPlugin::updateGeometry(const WebRect& window_rect, const WebRect& unobscured_rect, const WebVector& cut_outs_rects, bool is_visible) { + base::AutoReset is_resizing( + &is_resizing_, true); + if (static_cast(window_rect) != rect_) { rect_ = window_rect; WebSize newSize(window_rect.width, window_rect.height); web_view_->resize(newSize); } - if (delegate_) + if (delegate_) { delegate_->OnUnobscuredRectUpdate(gfx::Rect(unobscured_rect)); + // The delegate may have dirtied style and layout of the WebView. + // See for example the resizePoster function in plugin_poster.html. + // Run the lifecycle now so that it is clean. + web_view_->updateAllLifecyclePhases(); + } } void WebViewPlugin::updateFocus(bool focused, blink::WebFocusType focus_type) { @@ -293,6 +302,14 @@ void WebViewPlugin::didChangeCursor(const WebCursorInfo& cursor) { } void WebViewPlugin::scheduleAnimation() { + // Resizes must be self-contained: any lifecycle updating must + // be triggerd from within the WebView or this WebViewPlugin. + // This is because this WebViewPlugin is contained in another + // Web View which may be in the middle of updating its lifecycle, + // but after layout is done, and it is illegal to dirty earlier + // lifecycle stages during later ones. + if (is_resizing_) + return; if (container_) { // This should never happen; see also crbug.com/545039 for context. CHECK(!is_painting_); diff --git a/components/plugins/renderer/webview_plugin.h b/components/plugins/renderer/webview_plugin.h index a2682cb6723a00..4f86b6d4279508 100644 --- a/components/plugins/renderer/webview_plugin.h +++ b/components/plugins/renderer/webview_plugin.h @@ -178,6 +178,7 @@ class WebViewPlugin : public blink::WebPlugin, bool finished_loading_; bool focused_; bool is_painting_; + bool is_resizing_; }; #endif // COMPONENTS_PLUGINS_RENDERER_WEBVIEW_PLUGIN_H_ diff --git a/third_party/WebKit/Source/core/frame/FrameView.cpp b/third_party/WebKit/Source/core/frame/FrameView.cpp index 94efad2e1d6b50..fdb16e9dcfdbbf 100644 --- a/third_party/WebKit/Source/core/frame/FrameView.cpp +++ b/third_party/WebKit/Source/core/frame/FrameView.cpp @@ -1797,6 +1797,8 @@ void FrameView::scheduleRelayout() if (!shouldThrottleRendering()) page()->animator().scheduleVisualUpdate(m_frame.get()); + // TODO(chrishtr): this is dangerous and probably incorrect, since layout can be rescheduled during + // the lifecycle in cases such as change of containing block chain. Remove it. lifecycle().ensureStateAtMost(DocumentLifecycle::StyleClean); }