Commit 1adf6b49 authored by Vladimir Levin's avatar Vladimir Levin Committed by Commit Bot

HTMLPluginElement: Add object to frame view's update part if locked.

This patch ensures that when we delay the load because the plugins
need to be loaded and we're under a content-visibility lock, then
we add the object to be updated into frame view's list immediately

This is typically done during layout, but if layout is prevented then
we run into a possibility of delaying load event forever. Adding
the object to the update set immediately avoids the problem.

R=masonfreed@chromium.org

Bug: 1138128
Change-Id: I4d918c6bbdcd80aa6f01bf3b068acb64a93b0196
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2485671
Commit-Queue: vmpstr <vmpstr@chromium.org>
Reviewed-by: default avatarMason Freed <masonfreed@chromium.org>
Reviewed-by: default avatarStefan Zager <szager@chromium.org>
Cr-Commit-Position: refs/heads/master@{#820068}
parent eb6677cc
......@@ -1202,7 +1202,14 @@ void LocalFrameView::UpdateGeometry() {
}
void LocalFrameView::AddPartToUpdate(LayoutEmbeddedObject& object) {
DCHECK(IsInPerformLayout());
// This is typically called during layout to ensure we update plugins.
// However, if layout is blocked (e.g. by content-visibility), we can add the
// part to update during layout tree attachment (which is a part of style
// recalc).
DCHECK(IsInPerformLayout() ||
(DisplayLockUtilities::NearestLockedExclusiveAncestor(object) &&
frame_->GetDocument()->InStyleRecalc()));
// Tell the DOM element that it needs a Plugin update.
Node* node = object.GetNode();
DCHECK(node);
......
......@@ -29,6 +29,7 @@
#include "third_party/blink/renderer/bindings/core/v8/script_controller.h"
#include "third_party/blink/renderer/core/css/css_property_names.h"
#include "third_party/blink/renderer/core/css/style_change_reason.h"
#include "third_party/blink/renderer/core/display_lock/display_lock_utilities.h"
#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/dom/events/event.h"
#include "third_party/blink/renderer/core/dom/node.h"
......@@ -230,6 +231,15 @@ void HTMLPlugInElement::AttachLayoutTree(AttachContext& context) {
!GetLayoutEmbeddedObject()->ShowsUnavailablePluginIndicator() &&
GetObjectContentType() != ObjectContentType::kPlugin &&
!is_delaying_load_event_) {
// If we're in a content-visibility subtree that can prevent layout, then
// add our layout object to the frame view's update list. This is typically
// done during layout, but if we're blocking layout, we will never update
// the plugin and thus delay the load event indefinitely.
if (DisplayLockUtilities::NearestLockedExclusiveAncestor(*this)) {
auto* embedded_object = GetLayoutEmbeddedObject();
if (auto* frame_view = embedded_object->GetFrameView())
frame_view->AddPartToUpdate(*embedded_object);
}
is_delaying_load_event_ = true;
GetDocument().IncrementLoadEventDelayCount();
GetDocument().LoadPluginsSoon();
......
<!doctype html>
<meta charset="utf-8">
<title>HTML Test: The embed element represents a document</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<meta name="assert" content="Ensure document finishes load when focus is attempted before the embed is finished loading">
<style>
.hidden { content-visibility: hidden; }
</style>
<body>
<script>
async_test(t => {
window.onload = () => t.done();
}, "ensure onload happens");
</script>
<div class=hidden>
<embed id=target src="embed-iframe.html">
</div>
<script>
// Ensure we process style in the hidden object, which normally delays
// load until the embed object is finished loading.
target.focus();
</script>
</body>
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment