Commit 7c08a1a3 authored by rajendrant's avatar rajendrant Committed by Commit Bot

Split placeholder image load checks and enables

Refactor the MaybeAllowImagePlaceholder() and MaybeAllowLazyLoadingImage()
functions to checks and enable the placeholder request bit separately.

This will help with lazyloading of CSS background images.

Bug: 846170
Change-Id: I07dd50db59287c290ff0a7f0cc726dc23ed882e8
Reviewed-on: https://chromium-review.googlesource.com/1178637
Commit-Queue: rajendrant <rajendrant@chromium.org>
Reviewed-by: default avatarScott Little <sclittle@chromium.org>
Reviewed-by: default avatarNate Chapin <japhet@chromium.org>
Reviewed-by: default avatarFredrik Söderquist <fs@opera.com>
Cr-Commit-Position: refs/heads/master@{#584252}
parent 57ffd0ad
layer at (0,0) size 800x600
LayoutView at (0,0) size 800x600
layer at (0,0) size 800x176
LayoutBlockFlow {HTML} at (0,0) size 800x176
LayoutBlockFlow {BODY} at (8,8) size 784x160
LayoutBlockFlow {DIV} at (0,0) size 40x40
LayoutBlockFlow {DIV} at (0,40) size 40x40
LayoutBlockFlow {DIV} at (0,80) size 40x40
LayoutBlockFlow {DIV} at (0,120) size 40x40
<!DOCTYPE html>
<style>
div {
width: 40px;
height: 40px;
}
</style>
<body>
<!-- This test verifies if CSS sprite image is shown, instead of placeholder image. -->
<div id="sprite1"></div>
<div id="sprite2"></div>
<div id="sprite3"></div>
<div id="sprite4"></div>
<script>
internals.settings.setFetchImagePlaceholders(true);
document.getElementById("sprite1").style.cssText = 'background: url(https://127.0.0.1:8443/resources/square200.png) 0 0;';
document.getElementById("sprite2").style.cssText = 'background: url(https://127.0.0.1:8443/resources/square200.png) 0 10px;';
document.getElementById("sprite3").style.cssText = 'background: url(https://127.0.0.1:8443/resources/square200.png) 10px 0;';
document.getElementById("sprite4").style.cssText = 'background: none, url(https://127.0.0.1:8443/resources/square200.png) 10px 10px;';
</script>
</body>
......@@ -127,8 +127,10 @@ StyleImage* CSSImageSetValue::CacheImage(
}
if (document.GetFrame() &&
placeholder_image_request_type == FetchParameters::kAllowPlaceholder)
document.GetFrame()->MaybeAllowImagePlaceholder(params);
placeholder_image_request_type == FetchParameters::kAllowPlaceholder &&
document.GetFrame()->IsClientLoFiAllowed(params.GetResourceRequest())) {
params.SetClientLoFiPlaceholder();
}
cached_image_ = StyleFetchedImageSet::Create(
ImageResourceContent::Fetch(params, document.Fetcher()),
......
......@@ -74,8 +74,10 @@ StyleImage* CSSImageValue::CacheImage(
}
if (document.GetFrame() &&
placeholder_image_request_type == FetchParameters::kAllowPlaceholder)
document.GetFrame()->MaybeAllowImagePlaceholder(params);
placeholder_image_request_type == FetchParameters::kAllowPlaceholder &&
document.GetFrame()->IsClientLoFiAllowed(params.GetResourceRequest())) {
params.SetClientLoFiPlaceholder();
}
cached_image_ = StyleFetchedImage::Create(document, params);
}
......
......@@ -104,7 +104,6 @@
#include "third_party/blink/renderer/platform/instrumentation/resource_coordinator/blink_resource_coordinator_base.h"
#include "third_party/blink/renderer/platform/instrumentation/resource_coordinator/frame_resource_coordinator.h"
#include "third_party/blink/renderer/platform/json/json_values.h"
#include "third_party/blink/renderer/platform/loader/fetch/fetch_parameters.h"
#include "third_party/blink/renderer/platform/loader/fetch/resource_fetcher.h"
#include "third_party/blink/renderer/platform/loader/fetch/resource_request.h"
#include "third_party/blink/renderer/platform/plugins/plugin_data.h"
......@@ -1266,43 +1265,26 @@ void ScopedFrameBlamer::LeaveContext() {
context->Leave();
}
void LocalFrame::MaybeAllowImagePlaceholder(FetchParameters& params) const {
if (GetSettings() && GetSettings()->GetFetchImagePlaceholders()) {
params.SetAllowImagePlaceholder();
return;
}
if (Client() &&
ShouldUseClientLoFiForRequest(params.GetResourceRequest(),
Client()->GetPreviewsStateForFrame())) {
params.MutableResourceRequest().SetPreviewsState(
params.GetResourceRequest().GetPreviewsState() |
WebURLRequest::kClientLoFiOn);
params.SetAllowImagePlaceholder();
}
bool LocalFrame::IsClientLoFiAllowed(const ResourceRequest& request) const {
return Client() && ShouldUseClientLoFiForRequest(
request, Client()->GetPreviewsStateForFrame());
}
bool LocalFrame::MaybeAllowLazyLoadingImage(FetchParameters& params) const {
bool LocalFrame::IsLazyLoadingImageAllowed() const {
if (!RuntimeEnabledFeatures::LazyImageLoadingEnabled())
return false;
if (params.GetPlaceholderImageRequestType() ==
FetchParameters::PlaceholderImageRequestType::kAllowPlaceholder) {
return false;
}
if (Owner() && !Owner()->ShouldLazyLoadChildren())
return false;
params.SetAllowImagePlaceholder();
return true;
}
}
WebURLLoaderFactory* LocalFrame::GetURLLoaderFactory() {
WebURLLoaderFactory* LocalFrame::GetURLLoaderFactory() {
if (!url_loader_factory_)
url_loader_factory_ = Client()->CreateURLLoaderFactory();
return url_loader_factory_.get();
}
}
WebPluginContainerImpl* LocalFrame::GetWebPluginContainer(Node* node) const {
WebPluginContainerImpl* LocalFrame::GetWebPluginContainer(Node* node) const {
if (GetDocument() && GetDocument()->IsPluginDocument()) {
return ToPluginDocument(GetDocument())->GetPluginView();
}
......@@ -1315,9 +1297,9 @@ WebPluginContainerImpl* LocalFrame::GetWebPluginContainer(Node* node) const {
return node->GetWebPluginContainer();
}
return nullptr;
}
}
void LocalFrame::SetViewportIntersectionFromParent(
void LocalFrame::SetViewportIntersectionFromParent(
const IntRect& viewport_intersection,
bool occluded_or_obscured) {
if (remote_viewport_intersection_ != viewport_intersection ||
......@@ -1329,9 +1311,9 @@ void LocalFrame::SetViewportIntersectionFromParent(
View()->ScheduleAnimation();
}
}
}
}
void LocalFrame::ForceSynchronousDocumentInstall(
void LocalFrame::ForceSynchronousDocumentInstall(
const AtomicString& mime_type,
scoped_refptr<SharedBuffer> data) {
CHECK(loader_.StateMachine()->IsDisplayingInitialEmptyDocument());
......@@ -1359,11 +1341,11 @@ void LocalFrame::ForceSynchronousDocumentInstall(
// message overlays (the other callers of this method).
if (GetDocument()->IsSVGDocument())
loader_.GetDocumentLoader()->GetUseCounter().DidCommitLoad(this);
}
}
bool LocalFrame::IsProvisional() const {
// Calling this after the frame is marked as completely detached is a bug, as
// this state can no longer be accurately calculated.
bool LocalFrame::IsProvisional() const {
// Calling this after the frame is marked as completely detached is a bug,
// as this state can no longer be accurately calculated.
CHECK_NE(FrameLifecycle::kDetached, lifecycle_.GetState());
if (IsMainFrame()) {
......@@ -1372,9 +1354,9 @@ bool LocalFrame::IsProvisional() const {
DCHECK(Owner());
return Owner()->ContentFrame() != this;
}
}
bool LocalFrame::IsUsingDataSavingPreview() const {
bool LocalFrame::IsUsingDataSavingPreview() const {
if (!Client())
return false;
......@@ -1384,9 +1366,9 @@ bool LocalFrame::IsUsingDataSavingPreview() const {
return previews_state &
(WebURLRequest::kServerLoFiOn | WebURLRequest::kClientLoFiOn |
WebURLRequest::kNoScriptOn);
}
}
ComputedAccessibleNode* LocalFrame::GetOrCreateComputedAccessibleNode(
ComputedAccessibleNode* LocalFrame::GetOrCreateComputedAccessibleNode(
AXID ax_id,
WebComputedAXTree* tree) {
if (computed_node_mapping_.find(ax_id) == computed_node_mapping_.end()) {
......@@ -1395,68 +1377,71 @@ ComputedAccessibleNode* LocalFrame::GetOrCreateComputedAccessibleNode(
computed_node_mapping_.insert(ax_id, node);
}
return computed_node_mapping_.at(ax_id);
}
}
void LocalFrame::PauseSubresourceLoading(
void LocalFrame::PauseSubresourceLoading(
blink::mojom::blink::PauseSubresourceLoadingHandleRequest request) {
auto handle = GetFrameScheduler()->GetPauseSubresourceLoadingHandle();
if (!handle)
return;
pause_handle_bindings_.AddBinding(std::move(handle), std::move(request));
}
}
void LocalFrame::ResumeSubresourceLoading() {
void LocalFrame::ResumeSubresourceLoading() {
pause_handle_bindings_.CloseAllBindings();
}
}
void LocalFrame::AnimateSnapFling(base::TimeTicks monotonic_time) {
void LocalFrame::AnimateSnapFling(base::TimeTicks monotonic_time) {
GetEventHandler().AnimateSnapFling(monotonic_time);
}
}
void LocalFrame::BindPreviewsResourceLoadingHintsRequest(
blink::mojom::blink::PreviewsResourceLoadingHintsReceiverRequest request) {
void LocalFrame::BindPreviewsResourceLoadingHintsRequest(
blink::mojom::blink::PreviewsResourceLoadingHintsReceiverRequest
request) {
DCHECK(!previews_resource_loading_hints_receiver_);
previews_resource_loading_hints_receiver_ =
std::make_unique<PreviewsResourceLoadingHintsReceiverImpl>(
std::move(request), GetDocument());
}
}
SmoothScrollSequencer& LocalFrame::GetSmoothScrollSequencer() {
SmoothScrollSequencer& LocalFrame::GetSmoothScrollSequencer() {
if (!IsLocalRoot())
return LocalFrameRoot().GetSmoothScrollSequencer();
if (!smooth_scroll_sequencer_)
smooth_scroll_sequencer_ = new SmoothScrollSequencer();
return *smooth_scroll_sequencer_;
}
}
ukm::UkmRecorder* LocalFrame::GetUkmRecorder() {
ukm::UkmRecorder* LocalFrame::GetUkmRecorder() {
Document* document = GetDocument();
if (!document)
return nullptr;
return document->UkmRecorder();
}
}
int64_t LocalFrame::GetUkmSourceId() {
int64_t LocalFrame::GetUkmSourceId() {
Document* document = GetDocument();
if (!document)
return ukm::kInvalidSourceId;
return document->UkmSourceID();
}
}
const mojom::blink::ReportingServiceProxyPtr& LocalFrame::GetReportingService()
const {
const mojom::blink::ReportingServiceProxyPtr&
LocalFrame::GetReportingService() const {
if (!reporting_service_) {
Platform::Current()->GetConnector()->BindInterface(
Platform::Current()->GetBrowserServiceName(), &reporting_service_);
}
return reporting_service_;
}
}
void LocalFrame::ReportFeaturePolicyViolation(
void LocalFrame::ReportFeaturePolicyViolation(
mojom::FeaturePolicyFeature feature) const {
const String& feature_name = GetNameForFeature(feature);
FeaturePolicyViolationReportBody* body = new FeaturePolicyViolationReportBody(
feature_name, "Feature policy violation", SourceLocation::Capture());
FeaturePolicyViolationReportBody* body =
new FeaturePolicyViolationReportBody(feature_name,
"Feature policy violation",
SourceLocation::Capture());
Report* report =
new Report("feature-policy", GetDocument()->Url().GetString(), body);
ReportingContext::From(GetDocument())->QueueReport(report);
......@@ -1471,6 +1456,6 @@ void LocalFrame::ReportFeaturePolicyViolation(
GetReportingService()->QueueFeaturePolicyViolationReport(
GetDocument()->Url(), feature_name, "Feature policy violation",
body->sourceFile(), line_number, column_number);
}
}
} // namespace blink
......@@ -73,7 +73,6 @@ class Editor;
class Element;
class EventHandler;
class EventHandlerRegistry;
class FetchParameters;
class FloatSize;
class FrameConsole;
class FrameResourceCoordinator;
......@@ -95,6 +94,7 @@ class Node;
class NodeTraversal;
class PerformanceMonitor;
class PluginData;
class ResourceRequest;
class ScriptController;
class SharedBuffer;
class SmoothScrollSequencer;
......@@ -290,15 +290,11 @@ class CORE_EXPORT LocalFrame final : public Frame,
AdTracker* GetAdTracker() { return ad_tracker_; }
void SetAdTrackerForTesting(AdTracker* ad_tracker);
// Convenience function to allow loading image placeholders for the request if
// either the flag in Settings() for using image placeholders is set, or if
// the embedder decides that Client Lo-Fi should be used for this request.
void MaybeAllowImagePlaceholder(FetchParameters&) const;
// Returns true if Client Lo-Fi should be used for this request.
bool IsClientLoFiAllowed(const ResourceRequest&) const;
// Convenience function to allow loading image placeholders for the request if
// lazyloading the image is possible. Returns if lazyloading the image is
// possible.
bool MaybeAllowLazyLoadingImage(FetchParameters&) const;
// Returns true if lazyloading the image is possible.
bool IsLazyLoadingImageAllowed() const;
// The returned value is a off-heap raw-ptr and should not be stored.
WebURLLoaderFactory* GetURLLoaderFactory();
......
......@@ -12,6 +12,16 @@
namespace blink {
namespace {
void MaybeAllowImagePlaceholder(DummyPageHolder* page_holder,
FetchParameters& params) {
if (page_holder->GetFrame().IsClientLoFiAllowed(params.GetResourceRequest()))
params.SetClientLoFiPlaceholder();
}
} // namespace
class TestLocalFrameClient : public EmptyLocalFrameClient {
public:
explicit TestLocalFrameClient(
......@@ -32,10 +42,10 @@ TEST(LocalFrameTest, MaybeAllowPlaceholderImageUsesSpecifiedRequestValue) {
request1.SetURL(KURL("http://insecure.com"));
request1.SetPreviewsState(WebURLRequest::kClientLoFiOn);
FetchParameters params1(request1);
DummyPageHolder::Create(IntSize(800, 600), nullptr,
new TestLocalFrameClient(WebURLRequest::kPreviewsOff))
->GetFrame()
.MaybeAllowImagePlaceholder(params1);
auto page_holder = DummyPageHolder::Create(
IntSize(800, 600), nullptr,
new TestLocalFrameClient(WebURLRequest::kPreviewsOff));
MaybeAllowImagePlaceholder(page_holder.get(), params1);
EXPECT_EQ(FetchParameters::kAllowPlaceholder,
params1.GetPlaceholderImageRequestType());
......@@ -43,11 +53,10 @@ TEST(LocalFrameTest, MaybeAllowPlaceholderImageUsesSpecifiedRequestValue) {
request2.SetURL(KURL("https://secure.com"));
request2.SetPreviewsState(WebURLRequest::kPreviewsOff);
FetchParameters params2(request2);
DummyPageHolder::Create(
auto page_holder2 = DummyPageHolder::Create(
IntSize(800, 600), nullptr,
new TestLocalFrameClient(WebURLRequest::kClientLoFiOn))
->GetFrame()
.MaybeAllowImagePlaceholder(params2);
new TestLocalFrameClient(WebURLRequest::kClientLoFiOn));
MaybeAllowImagePlaceholder(page_holder2.get(), params2);
EXPECT_EQ(FetchParameters::kDisallowPlaceholder,
params2.GetPlaceholderImageRequestType());
}
......@@ -60,7 +69,7 @@ TEST(LocalFrameTest, MaybeAllowPlaceholderImageUsesFramePreviewsState) {
std::unique_ptr<DummyPageHolder> page_holder = DummyPageHolder::Create(
IntSize(800, 600), nullptr,
new TestLocalFrameClient(WebURLRequest::kClientLoFiOn));
page_holder->GetFrame().MaybeAllowImagePlaceholder(params1);
MaybeAllowImagePlaceholder(page_holder.get(), params1);
EXPECT_EQ(FetchParameters::kAllowPlaceholder,
params1.GetPlaceholderImageRequestType());
EXPECT_TRUE(page_holder->GetFrame().IsUsingDataSavingPreview());
......@@ -72,7 +81,7 @@ TEST(LocalFrameTest, MaybeAllowPlaceholderImageUsesFramePreviewsState) {
std::unique_ptr<DummyPageHolder> page_holder2 = DummyPageHolder::Create(
IntSize(800, 600), nullptr,
new TestLocalFrameClient(WebURLRequest::kServerLitePageOn));
page_holder2->GetFrame().MaybeAllowImagePlaceholder(params2);
MaybeAllowImagePlaceholder(page_holder2.get(), params2);
EXPECT_EQ(FetchParameters::kDisallowPlaceholder,
params2.GetPlaceholderImageRequestType());
EXPECT_FALSE(page_holder2->GetFrame().IsUsingDataSavingPreview());
......@@ -84,12 +93,11 @@ TEST(LocalFrameTest,
request1.SetURL(KURL("https://secure.com"));
request1.SetPreviewsState(WebURLRequest::kPreviewsUnspecified);
FetchParameters params1(request1);
DummyPageHolder::Create(
auto page_holder = DummyPageHolder::Create(
IntSize(800, 600), nullptr,
new TestLocalFrameClient(WebURLRequest::kServerLoFiOn |
WebURLRequest::kClientLoFiOn))
->GetFrame()
.MaybeAllowImagePlaceholder(params1);
WebURLRequest::kClientLoFiOn));
MaybeAllowImagePlaceholder(page_holder.get(), params1);
EXPECT_EQ(FetchParameters::kAllowPlaceholder,
params1.GetPlaceholderImageRequestType());
......@@ -97,12 +105,11 @@ TEST(LocalFrameTest,
request2.SetURL(KURL("http://insecure.com"));
request2.SetPreviewsState(WebURLRequest::kPreviewsUnspecified);
FetchParameters params2(request2);
DummyPageHolder::Create(
auto page_holder2 = DummyPageHolder::Create(
IntSize(800, 600), nullptr,
new TestLocalFrameClient(WebURLRequest::kServerLoFiOn |
WebURLRequest::kClientLoFiOn))
->GetFrame()
.MaybeAllowImagePlaceholder(params2);
WebURLRequest::kClientLoFiOn));
MaybeAllowImagePlaceholder(page_holder2.get(), params2);
EXPECT_EQ(FetchParameters::kDisallowPlaceholder,
params2.GetPlaceholderImageRequestType());
}
......
......@@ -893,12 +893,6 @@
initial: false,
},
// Whether or not to issue range requests for images and show placeholders.
{
name: "fetchImagePlaceholders",
initial: false,
},
// Whether the frame is a presentation receiver and should expose
// `navigator.presentation.receiver`.
{
......
......@@ -218,8 +218,11 @@ Resource* DocumentLoader::StartPreload(Resource::Type type,
switch (type) {
case Resource::kImage:
if (frame_) {
frame_->MaybeAllowImagePlaceholder(params);
frame_->MaybeAllowLazyLoadingImage(params);
if (frame_->IsClientLoFiAllowed(params.GetResourceRequest())) {
params.SetClientLoFiPlaceholder();
} else if (frame_->IsLazyLoadingImageAllowed()) {
params.SetAllowImagePlaceholder();
}
}
resource = ImageResource::Fetch(params, Fetcher());
break;
......
......@@ -443,13 +443,16 @@ void ImageLoader::DoUpdateFromElement(BypassMainWorldBehavior bypass_behavior,
if (update_behavior != kUpdateForcedReload &&
lazy_image_load_state_ == LazyImageLoadState::kNone) {
const auto* frame = document.GetFrame();
frame->MaybeAllowImagePlaceholder(params);
auto* html_image = ToHTMLImageElementOrNull(GetElement());
if (html_image && html_image->ElementCreatedByParser() &&
frame->MaybeAllowLazyLoadingImage(params)) {
if (frame->IsClientLoFiAllowed(params.GetResourceRequest())) {
params.SetClientLoFiPlaceholder();
} else if (auto* html_image = ToHTMLImageElementOrNull(GetElement())) {
if (html_image->ElementCreatedByParser() &&
frame->IsLazyLoadingImageAllowed()) {
params.SetAllowImagePlaceholder();
lazy_image_load_state_ = LazyImageLoadState::kDeferred;
}
}
}
new_image_content = ImageResourceContent::Fetch(params, document.Fetcher());
......
......@@ -111,6 +111,12 @@ void FetchParameters::MakeSynchronous() {
options_.synchronous_policy = kRequestSynchronously;
}
void FetchParameters::SetClientLoFiPlaceholder() {
resource_request_.SetPreviewsState(resource_request_.GetPreviewsState() |
WebURLRequest::kClientLoFiOn);
SetAllowImagePlaceholder();
}
void FetchParameters::SetAllowImagePlaceholder() {
DCHECK_EQ(kDisallowPlaceholder, placeholder_image_request_type_);
if (!resource_request_.Url().ProtocolIsInHTTPFamily() ||
......
......@@ -178,9 +178,13 @@ class PLATFORM_EXPORT FetchParameters {
// Configures the request to load an image placeholder if the request is
// eligible (e.g. the url's protocol is HTTP, etc.). If this request is
// non-eligible, this method doesn't modify the ResourceRequest. Calling this
// method sets m_placeholderImageRequestType to the appropriate value.
// method sets placeholder_image_request_type_ to the appropriate value.
void SetAllowImagePlaceholder();
// Configures the request to load an image as a placeholder and sets the
// Client LoFi preview bit.
void SetClientLoFiPlaceholder();
private:
ResourceRequest resource_request_;
// |decoder_options_|'s ContentType is set to |kPlainTextContent| in
......
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