--- a/docshell/base/nsContextMenuInfo.cpp
+++ b/docshell/base/nsContextMenuInfo.cpp
@@ -297,17 +297,18 @@ nsContextMenuInfo::GetBackgroundImageReq
imgLoader* il = imgLoader::NormalLoader();
NS_ENSURE_TRUE(il, NS_ERROR_FAILURE);
return il->LoadImage(bgUri, nullptr, nullptr,
doc->GetReferrerPolicy(), principal, nullptr,
nullptr, nullptr, nullptr, nsIRequest::LOAD_NORMAL,
nullptr, nsIContentPolicy::TYPE_INTERNAL_IMAGE,
- EmptyString(), aRequest);
+ EmptyString(),
+ /* aUseUrgentStartForChannel */ false, aRequest);
}
}
// bail if we encounter non-transparent background-color
computedStyle->GetPropertyCSSValue(NS_LITERAL_STRING("background-color"),
getter_AddRefs(cssValue));
primitiveValue = do_QueryInterface(cssValue);
if (primitiveValue) {
--- a/dom/base/nsContentUtils.cpp
+++ b/dom/base/nsContentUtils.cpp
@@ -3507,17 +3507,18 @@ nsContentUtils::IsImageInCache(nsIURI* a
nsresult
nsContentUtils::LoadImage(nsIURI* aURI, nsINode* aContext,
nsIDocument* aLoadingDocument,
nsIPrincipal* aLoadingPrincipal, nsIURI* aReferrer,
net::ReferrerPolicy aReferrerPolicy,
imgINotificationObserver* aObserver, int32_t aLoadFlags,
const nsAString& initiatorType,
imgRequestProxy** aRequest,
- uint32_t aContentPolicyType)
+ uint32_t aContentPolicyType,
+ bool aUseUrgentStartForChannel)
{
NS_PRECONDITION(aURI, "Must have a URI");
NS_PRECONDITION(aContext, "Must have a context");
NS_PRECONDITION(aLoadingDocument, "Must have a document");
NS_PRECONDITION(aLoadingPrincipal, "Must have a principal");
NS_PRECONDITION(aRequest, "Null out param");
imgLoader* imgLoader = GetImgLoaderForDocument(aLoadingDocument);
@@ -3546,16 +3547,17 @@ nsContentUtils::LoadImage(nsIURI* aURI,
loadGroup, /* loadgroup */
aObserver, /* imgINotificationObserver */
aContext, /* loading context */
aLoadingDocument, /* uniquification key */
aLoadFlags, /* load flags */
nullptr, /* cache key */
aContentPolicyType, /* content policy type */
initiatorType, /* the load initiator */
+ aUseUrgentStartForChannel, /* urgent-start flag */
aRequest);
}
// static
already_AddRefed<imgIContainer>
nsContentUtils::GetImageFromContent(nsIImageLoadingContent* aContent,
imgIRequest **aRequest)
{
--- a/dom/base/nsContentUtils.h
+++ b/dom/base/nsContentUtils.h
@@ -764,29 +764,32 @@ public:
* @param aLoadingPrincipal the principal doing the load
* @param aReferrer the referrer URI
* @param aReferrerPolicy the referrer-sending policy to use on channel
* creation
* @param aObserver the observer for the image load
* @param aLoadFlags the load flags to use. See nsIRequest
* @param [aContentPolicyType=nsIContentPolicy::TYPE_INTERNAL_IMAGE] (Optional)
* The CP content type to use
+ * @param aUseUrgentStartForChannel,(Optional) a flag to mark on channel if it
+ * is triggered by user input events.
* @return the imgIRequest for the image load
*/
static nsresult LoadImage(nsIURI* aURI,
nsINode* aContext,
nsIDocument* aLoadingDocument,
nsIPrincipal* aLoadingPrincipal,
nsIURI* aReferrer,
mozilla::net::ReferrerPolicy aReferrerPolicy,
imgINotificationObserver* aObserver,
int32_t aLoadFlags,
const nsAString& initiatorType,
imgRequestProxy** aRequest,
- uint32_t aContentPolicyType = nsIContentPolicy::TYPE_INTERNAL_IMAGE);
+ uint32_t aContentPolicyType = nsIContentPolicy::TYPE_INTERNAL_IMAGE,
+ bool aUseUrgentStartForChannel = false);
/**
* Obtain an image loader that respects the given document/channel's privacy status.
* Null document/channel arguments return the public image loader.
*/
static imgLoader* GetImgLoaderForDocument(nsIDocument* aDoc);
static imgLoader* GetImgLoaderForChannel(nsIChannel* aChannel,
nsIDocument* aContext);
--- a/dom/base/nsImageLoadingContent.cpp
+++ b/dom/base/nsImageLoadingContent.cpp
@@ -39,16 +39,17 @@
#include "nsLayoutUtils.h"
#include "nsIContentPolicy.h"
#include "nsSVGEffects.h"
#include "gfxPrefs.h"
#include "mozAutoDocUpdate.h"
#include "mozilla/AsyncEventDispatcher.h"
+#include "mozilla/EventStateManager.h"
#include "mozilla/EventStates.h"
#include "mozilla/dom/Element.h"
#include "mozilla/dom/ImageTracker.h"
#include "mozilla/dom/ScriptSettings.h"
#include "mozilla/Preferences.h"
#ifdef LoadImage
// Undefine LoadImage to prevent naming conflict with Windows.
@@ -87,16 +88,17 @@ nsImageLoadingContent::nsImageLoadingCon
mLoadingEnabled(true),
mIsImageStateForced(false),
mLoading(false),
// mBroken starts out true, since an image without a URI is broken....
mBroken(true),
mUserDisabled(false),
mSuppressed(false),
mNewRequestsWillNeedAnimationReset(false),
+ mUseUrgentStartForChannel(false),
mStateChangerDepth(0),
mCurrentRequestRegistered(false),
mPendingRequestRegistered(false)
{
if (!nsContentUtils::GetImgLoaderForChannel(nullptr, nullptr)) {
mLoadingEnabled = false;
}
@@ -879,17 +881,22 @@ nsImageLoadingContent::LoadImage(nsIURI*
thisNode,
aDocument,
aDocument->NodePrincipal(),
aDocument->GetDocumentURI(),
referrerPolicy,
this, loadFlags,
content->LocalName(),
getter_AddRefs(req),
- policyType);
+ policyType,
+ mUseUrgentStartForChannel);
+
+ // Reset the flag to avoid loading from XPCOM or somewhere again else without
+ // initiated by user interaction.
+ mUseUrgentStartForChannel = false;
// Tell the document to forget about the image preload, if any, for
// this URI, now that we might have another imgRequestProxy for it.
// That way if we get canceled later the image load won't continue.
aDocument->ForgetImagePreload(aNewURI);
if (NS_SUCCEEDED(rv)) {
TrackImage(req);
--- a/dom/base/nsImageLoadingContent.h
+++ b/dom/base/nsImageLoadingContent.h
@@ -450,16 +450,23 @@ protected:
* that originate from setting .src, we mark them for needing their animation
* reset when they are ready. mNewRequestsWillNeedAnimationReset is set to
* true while preparing such requests (as a hack around needing to change an
* interface), and the other two booleans store which of the current
* and pending requests are of the sort that need their animation restarted.
*/
bool mNewRequestsWillNeedAnimationReset : 1;
+ /**
+ * Flag to indicate whether the channel should be mark as urgent-start.
+ * It should be set in *Element and passed to nsContentUtils::LoadImage.
+ * True if we want to set nsIClassOfService::UrgentStart to the channel to
+ * get the response ASAP for better user responsiveness.
+ */
+ bool mUseUrgentStartForChannel;
private:
/* The number of nested AutoStateChangers currently tracking our state. */
uint8_t mStateChangerDepth;
// Flags to indicate whether each of the current and pending requests are
// registered with the refresh driver.
bool mCurrentRequestRegistered;
bool mPendingRequestRegistered;
--- a/dom/html/HTMLImageElement.cpp
+++ b/dom/html/HTMLImageElement.cpp
@@ -74,43 +74,50 @@ namespace mozilla {
namespace dom {
// Calls LoadSelectedImage on host element unless it has been superseded or
// canceled -- this is the synchronous section of "update the image data".
// https://html.spec.whatwg.org/multipage/embedded-content.html#update-the-image-data
class ImageLoadTask : public Runnable
{
public:
- ImageLoadTask(HTMLImageElement *aElement, bool aAlwaysLoad)
+ ImageLoadTask(HTMLImageElement *aElement, bool aAlwaysLoad,
+ bool aUseUrgentStartForChannel)
: mElement(aElement)
, mAlwaysLoad(aAlwaysLoad)
+ , mUseUrgentStartForChannel(aUseUrgentStartForChannel)
{
mDocument = aElement->OwnerDoc();
mDocument->BlockOnload();
}
NS_IMETHOD Run() override
{
if (mElement->mPendingImageLoadTask == this) {
mElement->mPendingImageLoadTask = nullptr;
+ mElement->mUseUrgentStartForChannel = mUseUrgentStartForChannel;
mElement->LoadSelectedImage(true, true, mAlwaysLoad);
}
mDocument->UnblockOnload(false);
return NS_OK;
}
bool AlwaysLoad() {
return mAlwaysLoad;
}
private:
~ImageLoadTask() {}
RefPtr<HTMLImageElement> mElement;
nsCOMPtr<nsIDocument> mDocument;
bool mAlwaysLoad;
+
+ // True if we want to set nsIClassOfService::UrgentStart to the channel to
+ // get the response ASAP for better user responsiveness.
+ bool mUseUrgentStartForChannel;
};
HTMLImageElement::HTMLImageElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
: nsGenericHTMLElement(aNodeInfo)
, mForm(nullptr)
, mInDocResponsiveContent(false)
, mCurrentDensity(1.0)
{
@@ -405,33 +412,45 @@ HTMLImageElement::AfterSetAttr(int32_t a
// parser or some such place; we'll get bound after all the attributes have
// been set, so we'll do the image load from BindToTree.
nsAttrValueOrString attrVal(aValue);
if (aName == nsGkAtoms::src &&
aNameSpaceID == kNameSpaceID_None &&
!aValue) {
+ // Mark channel as urgent-start before load image if the image load is
+ // initaiated by a user interaction.
+ mUseUrgentStartForChannel = EventStateManager::IsHandlingUserInput();
+
// SetAttr handles setting src since it needs to catch img.src =
// img.src, so we only need to handle the unset case
if (InResponsiveMode()) {
if (mResponsiveSelector &&
mResponsiveSelector->Content() == this) {
mResponsiveSelector->SetDefaultSource(NullString());
}
QueueImageLoadTask(true);
} else {
// Bug 1076583 - We still behave synchronously in the non-responsive case
CancelImageRequests(aNotify);
}
} else if (aName == nsGkAtoms::srcset &&
aNameSpaceID == kNameSpaceID_None) {
+ // Mark channel as urgent-start before load image if the image load is
+ // initaiated by a user interaction.
+ mUseUrgentStartForChannel = EventStateManager::IsHandlingUserInput();
+
PictureSourceSrcsetChanged(this, attrVal.String(), aNotify);
} else if (aName == nsGkAtoms::sizes &&
aNameSpaceID == kNameSpaceID_None) {
+ // Mark channel as urgent-start before load image if the image load is
+ // initaiated by a user interaction.
+ mUseUrgentStartForChannel = EventStateManager::IsHandlingUserInput();
+
PictureSourceSizesChanged(this, attrVal.String(), aNotify);
}
return nsGenericHTMLElement::AfterSetAttr(aNameSpaceID, aName,
aValue, aNotify);
}
nsresult
@@ -500,16 +519,20 @@ HTMLImageElement::SetAttr(int32_t aNameS
// If we are in responsive mode, we drop the forced reload behavior,
// but still trigger a image load task for img.src = img.src per
// spec.
//
// Both cases handle unsetting src in AfterSetAttr
if (aNameSpaceID == kNameSpaceID_None &&
aName == nsGkAtoms::src) {
+ // Mark channel as urgent-start before load image if the image load is
+ // initaiated by a user interaction.
+ mUseUrgentStartForChannel = EventStateManager::IsHandlingUserInput();
+
if (InResponsiveMode()) {
if (mResponsiveSelector &&
mResponsiveSelector->Content() == this) {
mResponsiveSelector->SetDefaultSource(aValue);
}
QueueImageLoadTask(true);
} else if (aNotify) {
// If aNotify is false, we are coming from the parser or some such place;
@@ -557,16 +580,20 @@ HTMLImageElement::SetAttr(int32_t aNameS
nsresult rv = nsGenericHTMLElement::SetAttr(aNameSpaceID, aName, aPrefix,
aValue, aNotify);
// Because we load image synchronously in non-responsive-mode, we need to do
// reload after the attribute has been set if the reload is triggerred by
// cross origin changing.
if (forceReload) {
+ // Mark channel as urgent-start before load image if the image load is
+ // initaiated by a user interaction.
+ mUseUrgentStartForChannel = EventStateManager::IsHandlingUserInput();
+
if (InResponsiveMode()) {
// per spec, full selection runs when this changes, even though
// it doesn't directly affect the source selection
QueueImageLoadTask(true);
} else {
// Bug 1076583 - We still use the older synchronous algorithm in
// non-responsive mode. Force a new load of the image with the
// new cross origin policy
@@ -595,28 +622,36 @@ HTMLImageElement::BindToTree(nsIDocument
}
if (HaveSrcsetOrInPicture()) {
if (aDocument && !mInDocResponsiveContent) {
aDocument->AddResponsiveContent(this);
mInDocResponsiveContent = true;
}
+ // Mark channel as urgent-start before load image if the image load is
+ // initaiated by a user interaction.
+ mUseUrgentStartForChannel = EventStateManager::IsHandlingUserInput();
+
// Run selection algorithm when an img element is inserted into a document
// in order to react to changes in the environment. See note of
// https://html.spec.whatwg.org/multipage/embedded-content.html#img-environment-changes
QueueImageLoadTask(false);
} else if (!InResponsiveMode() &&
HasAttr(kNameSpaceID_None, nsGkAtoms::src)) {
// We skip loading when our attributes were set from parser land,
// so trigger a aForce=false load now to check if things changed.
// This isn't necessary for responsive mode, since creating the
// image load task is asynchronous we don't need to take special
// care to avoid doing so when being filled by the parser.
+ // Mark channel as urgent-start before load image if the image load is
+ // initaiated by a user interaction.
+ mUseUrgentStartForChannel = EventStateManager::IsHandlingUserInput();
+
// FIXME: Bug 660963 it would be nice if we could just have
// ClearBrokenState update our state and do it fast...
ClearBrokenState();
RemoveStatesSilently(NS_EVENT_STATE_BROKEN);
// We still act synchronously for the non-responsive case (Bug
// 1076583), but still need to delay if it is unsafe to run
// script.
@@ -825,16 +860,20 @@ HTMLImageElement::CopyInnerTo(Element* a
if (!destIsStatic) {
// In SetAttr (called from nsGenericHTMLElement::CopyInnerTo), dest skipped
// doing the image load because we passed in false for aNotify. But we
// really do want it to do the load, so set it up to happen once the cloning
// reaches a stable state.
if (!dest->InResponsiveMode() &&
dest->HasAttr(kNameSpaceID_None, nsGkAtoms::src)) {
+ // Mark channel as urgent-start before load image if the image load is
+ // initaiated by a user interaction.
+ mUseUrgentStartForChannel = EventStateManager::IsHandlingUserInput();
+
nsContentUtils::AddScriptRunner(
NewRunnableMethod(dest, &HTMLImageElement::MaybeLoadImage));
}
}
return NS_OK;
}
@@ -908,17 +947,19 @@ HTMLImageElement::QueueImageLoadTask(boo
}
// Ensure that we don't overwrite a previous load request that requires
// a complete load to occur.
bool alwaysLoad = aAlwaysLoad;
if (mPendingImageLoadTask) {
alwaysLoad = alwaysLoad || mPendingImageLoadTask->AlwaysLoad();
}
- RefPtr<ImageLoadTask> task = new ImageLoadTask(this, alwaysLoad);
+ RefPtr<ImageLoadTask> task = new ImageLoadTask(this,
+ alwaysLoad,
+ mUseUrgentStartForChannel);
// The task checks this to determine if it was the last
// queued event, and so earlier tasks are implicitly canceled.
mPendingImageLoadTask = task;
nsContentUtils::RunInStableState(task.forget());
}
bool
HTMLImageElement::HaveSrcsetOrInPicture()
--- a/dom/html/HTMLInputElement.cpp
+++ b/dom/html/HTMLInputElement.cpp
@@ -1356,16 +1356,20 @@ HTMLInputElement::BeforeSetAttr(int32_t
if ((aName == nsGkAtoms::name ||
(aName == nsGkAtoms::type && !mForm)) &&
mType == NS_FORM_INPUT_RADIO &&
(mForm || mDoneCreating)) {
WillRemoveFromRadioGroup();
} else if (aNotify && aName == nsGkAtoms::src &&
mType == NS_FORM_INPUT_IMAGE) {
if (aValue) {
+ // Mark channel as urgent-start before load image if the image load is
+ // initaiated by a user interaction.
+ mUseUrgentStartForChannel = EventStateManager::IsHandlingUserInput();
+
LoadImage(aValue->String(), true, aNotify, eImageLoadType_Normal);
} else {
// Null value means the attr got unset; drop the image
CancelImageRequests(aNotify);
}
} else if (aNotify && aName == nsGkAtoms::disabled) {
mDisabledChanged = true;
} else if (aName == nsGkAtoms::dir &&
@@ -5096,16 +5100,20 @@ HTMLInputElement::BindToTree(nsIDocument
nsImageLoadingContent::BindToTree(aDocument, aParent, aBindingParent,
aCompileEventHandlers);
if (mType == NS_FORM_INPUT_IMAGE) {
// Our base URI may have changed; claim that our URI changed, and the
// nsImageLoadingContent will decide whether a new image load is warranted.
if (HasAttr(kNameSpaceID_None, nsGkAtoms::src)) {
+ // Mark channel as urgent-start before load image if the image load is
+ // initaiated by a user interaction.
+ mUseUrgentStartForChannel = EventStateManager::IsHandlingUserInput();
+
// FIXME: Bug 660963 it would be nice if we could just have
// ClearBrokenState update our state and do it fast...
ClearBrokenState();
RemoveStatesSilently(NS_EVENT_STATE_BROKEN);
nsContentUtils::AddScriptRunner(
NewRunnableMethod(this, &HTMLInputElement::MaybeLoadImage));
}
}
@@ -5287,16 +5295,20 @@ HTMLInputElement::HandleTypeChange(uint8
// We're no longer an image input. Cancel our image requests, if we have
// any.
CancelImageRequests(aNotify);
} else if (aNotify && mType == NS_FORM_INPUT_IMAGE) {
// We just got switched to be an image input; we should see
// whether we have an image to load;
nsAutoString src;
if (GetAttr(kNameSpaceID_None, nsGkAtoms::src, src)) {
+ // Mark channel as urgent-start before load image if the image load is
+ // initaiated by a user interaction.
+ mUseUrgentStartForChannel = EventStateManager::IsHandlingUserInput();
+
LoadImage(src, false, aNotify, eImageLoadType_Normal);
}
}
if (mType == NS_FORM_INPUT_PASSWORD && IsInComposedDoc()) {
AsyncEventDispatcher* dispatcher =
new AsyncEventDispatcher(this,
NS_LITERAL_STRING("DOMInputPasswordAdded"),
--- a/dom/svg/SVGFEImageElement.cpp
+++ b/dom/svg/SVGFEImageElement.cpp
@@ -1,16 +1,17 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/dom/SVGFEImageElement.h"
+#include "mozilla/EventStateManager.h"
#include "mozilla/EventStates.h"
#include "mozilla/dom/SVGFEImageElementBinding.h"
#include "mozilla/dom/SVGFilterElement.h"
#include "mozilla/gfx/2D.h"
#include "mozilla/RefPtr.h"
#include "nsContentUtils.h"
#include "nsLayoutUtils.h"
#include "nsSVGUtils.h"
@@ -86,16 +87,19 @@ SVGFEImageElement::LoadSVGImage(bool aFo
if (NS_SUCCEEDED(StringToURI(href, doc, getter_AddRefs(hrefAsURI)))) {
bool isEqual;
if (NS_SUCCEEDED(hrefAsURI->Equals(baseURI, &isEqual)) && isEqual) {
// Image URI matches our URI exactly! Bail out.
return NS_OK;
}
}
+ // Mark channel as urgent-start before load image if the image load is
+ // initaiated by a user interaction.
+ mUseUrgentStartForChannel = EventStateManager::IsHandlingUserInput();
return LoadImage(href, aForce, aNotify, eImageLoadType_Normal);
}
//----------------------------------------------------------------------
// EventTarget methods:
void
SVGFEImageElement::AsyncEventRunning(AsyncEventDispatcher* aEvent)
--- a/dom/svg/SVGImageElement.cpp
+++ b/dom/svg/SVGImageElement.cpp
@@ -1,15 +1,16 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/ArrayUtils.h"
+#include "mozilla/EventStateManager.h"
#include "mozilla/EventStates.h"
#include "mozilla/dom/SVGImageElement.h"
#include "mozilla/gfx/2D.h"
#include "nsCOMPtr.h"
#include "nsIURI.h"
#include "nsNetUtil.h"
#include "imgINotificationObserver.h"
@@ -128,16 +129,20 @@ SVGImageElement::LoadSVGImage(bool aForc
} else {
mStringAttributes[XLINK_HREF].GetAnimValue(href, this);
}
href.Trim(" \t\n\r");
if (baseURI && !href.IsEmpty())
NS_MakeAbsoluteURI(href, href, baseURI);
+ // Mark channel as urgent-start before load image if the image load is
+ // initaiated by a user interaction.
+ mUseUrgentStartForChannel = EventStateManager::IsHandlingUserInput();
+
return LoadImage(href, aForce, aNotify, eImageLoadType_Normal);
}
//----------------------------------------------------------------------
// EventTarget methods:
void
SVGImageElement::AsyncEventRunning(AsyncEventDispatcher* aEvent)
--- a/image/imgLoader.cpp
+++ b/image/imgLoader.cpp
@@ -25,16 +25,17 @@
#include "nsContentUtils.h"
#include "nsNetUtil.h"
#include "nsNetCID.h"
#include "nsIProtocolHandler.h"
#include "nsMimeTypes.h"
#include "nsStreamUtils.h"
#include "nsIHttpChannel.h"
#include "nsICacheInfoChannel.h"
+#include "nsIClassOfService.h"
#include "nsIInterfaceRequestor.h"
#include "nsIInterfaceRequestorUtils.h"
#include "nsIProgressEventSink.h"
#include "nsIChannelEventSink.h"
#include "nsIAsyncVerifyRedirectCallback.h"
#include "nsIFileURL.h"
#include "nsIFile.h"
#include "nsCRT.h"
@@ -2084,16 +2085,17 @@ imgLoader::LoadImageXPCOM(nsIURI* aURI,
aLoadGroup,
aObserver,
node,
doc,
aLoadFlags,
aCacheKey,
aContentPolicyType,
EmptyString(),
+ /* aUseUrgentStartForChannel */ false,
&proxy);
*_retval = proxy;
return rv;
}
nsresult
imgLoader::LoadImage(nsIURI* aURI,
nsIURI* aInitialDocumentURI,
@@ -2103,16 +2105,17 @@ imgLoader::LoadImage(nsIURI* aURI,
nsILoadGroup* aLoadGroup,
imgINotificationObserver* aObserver,
nsINode *aContext,
nsIDocument* aLoadingDocument,
nsLoadFlags aLoadFlags,
nsISupports* aCacheKey,
nsContentPolicyType aContentPolicyType,
const nsAString& initiatorType,
+ bool aUseUrgentStartForChannel,
imgRequestProxy** _retval)
{
MOZ_RELEASE_ASSERT(NS_IsMainThread());
VerifyCacheSizes();
NS_ASSERTION(aURI, "imgLoader::LoadImage -- NULL URI pointer");
@@ -2272,16 +2275,21 @@ imgLoader::LoadImage(nsIURI* aURI,
NewRequestAndEntry(forcePrincipalCheck, this, key,
getter_AddRefs(request),
getter_AddRefs(entry));
MOZ_LOG(gImgLog, LogLevel::Debug,
("[this=%p] imgLoader::LoadImage -- Created new imgRequest"
" [request=%p]\n", this, request.get()));
+ nsCOMPtr<nsIClassOfService> cos(do_QueryInterface(newChannel));
+ if (cos && aUseUrgentStartForChannel) {
+ cos->AddClassFlags(nsIClassOfService::UrgentStart);
+ }
+
nsCOMPtr<nsILoadGroup> channelLoadGroup;
newChannel->GetLoadGroup(getter_AddRefs(channelLoadGroup));
rv = request->Init(aURI, aURI, /* aHadInsecureRedirect = */ false,
channelLoadGroup, newChannel, entry, aLoadingDocument,
aLoadingPrincipal, corsmode, aReferrerPolicy);
if (NS_FAILED(rv)) {
return NS_ERROR_FAILURE;
}
--- a/image/imgLoader.h
+++ b/image/imgLoader.h
@@ -302,16 +302,17 @@ public:
nsILoadGroup* aLoadGroup,
imgINotificationObserver* aObserver,
nsINode* aContext,
nsIDocument* aLoadingDocument,
nsLoadFlags aLoadFlags,
nsISupports* aCacheKey,
nsContentPolicyType aContentPolicyType,
const nsAString& initiatorType,
+ bool aUseUrgentStartForChannel,
imgRequestProxy** _retval);
MOZ_MUST_USE nsresult
LoadImageWithChannel(nsIChannel* channel,
imgINotificationObserver* aObserver,
nsISupports* aCX,
nsIStreamListener** listener,
imgRequestProxy** _retval);
--- a/layout/generic/nsImageFrame.cpp
+++ b/layout/generic/nsImageFrame.cpp
@@ -2225,16 +2225,17 @@ nsImageFrame::LoadIcon(const nsAString&
loadGroup,
gIconLoad,
nullptr, /* No context */
nullptr, /* Not associated with any particular document */
loadFlags,
nullptr,
contentPolicyType,
EmptyString(),
+ false, /* aUseUrgentStartForChannel */
aRequest);
}
void
nsImageFrame::GetDocumentCharacterSet(nsACString& aCharset) const
{
if (mContent) {
NS_ASSERTION(mContent->GetComposedDoc(),
--- a/widget/cocoa/nsMenuItemIconX.mm
+++ b/widget/cocoa/nsMenuItemIconX.mm
@@ -315,16 +315,17 @@ nsMenuItemIconX::LoadIcon(nsIURI* aIconU
[mNativeMenuItem setImage:sPlaceholderIconImage];
}
nsresult rv = loader->LoadImage(aIconURI, nullptr, nullptr,
mozilla::net::RP_Unset,
mLoadingPrincipal, loadGroup, this,
mContent, document, nsIRequest::LOAD_NORMAL, nullptr,
mContentType, EmptyString(),
+ /* aUseUrgentStartForChannel */ false,
getter_AddRefs(mIconRequest));
if (NS_FAILED(rv)) return rv;
return NS_OK;
NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
}