Bug 1348050 - Part 3: Mark channel as urgent-start for loading image. r=baku,mayhemer
This part is mainly to mark the channel as urgent-start if src related attributes in HTMLImageElement and HTMLInputElement is set and the channel is open due to user interaction. Unfortunately, we cannot just check the event state just after creating channel since some loading image tasks will be queue and execute in stable state. Thus, I store the event state in elements and pass it to the place where create the channel. MozReview-Commit-ID: GBdAkPfVzsn
This commit is contained in:
@@ -302,7 +302,8 @@ nsContextMenuInfo::GetBackgroundImageRequestInternal(nsIDOMNode* aDOMNode,
|
||||
doc->GetReferrerPolicy(), principal, nullptr,
|
||||
nullptr, nullptr, nullptr, nsIRequest::LOAD_NORMAL,
|
||||
nullptr, nsIContentPolicy::TYPE_INTERNAL_IMAGE,
|
||||
EmptyString(), aRequest);
|
||||
EmptyString(),
|
||||
/* aUseUrgentStartForChannel */ false, aRequest);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3512,7 +3512,8 @@ nsContentUtils::LoadImage(nsIURI* aURI, nsINode* aContext,
|
||||
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");
|
||||
@@ -3551,6 +3552,7 @@ nsContentUtils::LoadImage(nsIURI* aURI, nsINode* aContext,
|
||||
nullptr, /* cache key */
|
||||
aContentPolicyType, /* content policy type */
|
||||
initiatorType, /* the load initiator */
|
||||
aUseUrgentStartForChannel, /* urgent-start flag */
|
||||
aRequest);
|
||||
}
|
||||
|
||||
|
||||
@@ -769,6 +769,8 @@ public:
|
||||
* @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,
|
||||
@@ -781,7 +783,8 @@ public:
|
||||
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.
|
||||
|
||||
@@ -44,6 +44,7 @@
|
||||
|
||||
#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"
|
||||
@@ -92,6 +93,7 @@ nsImageLoadingContent::nsImageLoadingContent()
|
||||
mUserDisabled(false),
|
||||
mSuppressed(false),
|
||||
mNewRequestsWillNeedAnimationReset(false),
|
||||
mUseUrgentStartForChannel(false),
|
||||
mStateChangerDepth(0),
|
||||
mCurrentRequestRegistered(false),
|
||||
mPendingRequestRegistered(false)
|
||||
@@ -884,7 +886,12 @@ nsImageLoadingContent::LoadImage(nsIURI* aNewURI,
|
||||
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.
|
||||
|
||||
@@ -455,6 +455,13 @@ protected:
|
||||
*/
|
||||
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;
|
||||
|
||||
@@ -79,9 +79,11 @@ namespace dom {
|
||||
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();
|
||||
@@ -91,6 +93,7 @@ public:
|
||||
{
|
||||
if (mElement->mPendingImageLoadTask == this) {
|
||||
mElement->mPendingImageLoadTask = nullptr;
|
||||
mElement->mUseUrgentStartForChannel = mUseUrgentStartForChannel;
|
||||
mElement->LoadSelectedImage(true, true, mAlwaysLoad);
|
||||
}
|
||||
mDocument->UnblockOnload(false);
|
||||
@@ -106,6 +109,10 @@ private:
|
||||
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)
|
||||
@@ -410,6 +417,10 @@ HTMLImageElement::AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName,
|
||||
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()) {
|
||||
@@ -424,9 +435,17 @@ HTMLImageElement::AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName,
|
||||
}
|
||||
} 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);
|
||||
}
|
||||
|
||||
@@ -505,6 +524,10 @@ HTMLImageElement::SetAttr(int32_t aNameSpaceID, nsIAtom* aName,
|
||||
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) {
|
||||
@@ -562,6 +585,10 @@ HTMLImageElement::SetAttr(int32_t aNameSpaceID, nsIAtom* aName,
|
||||
// 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
|
||||
@@ -600,6 +627,10 @@ HTMLImageElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
||||
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
|
||||
@@ -612,6 +643,10 @@ HTMLImageElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
||||
// 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();
|
||||
@@ -830,6 +865,10 @@ HTMLImageElement::CopyInnerTo(Element* aDest, bool aPreallocateChildren)
|
||||
// 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));
|
||||
}
|
||||
@@ -913,7 +952,9 @@ HTMLImageElement::QueueImageLoadTask(bool 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;
|
||||
|
||||
@@ -1361,6 +1361,10 @@ HTMLInputElement::BeforeSetAttr(int32_t aNameSpaceID, nsIAtom* aName,
|
||||
} 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
|
||||
@@ -5101,6 +5105,10 @@ HTMLInputElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
||||
// 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();
|
||||
@@ -5292,6 +5300,10 @@ HTMLInputElement::HandleTypeChange(uint8_t aNewType, bool aNotify)
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
|
||||
#include "mozilla/dom/SVGFEImageElement.h"
|
||||
|
||||
#include "mozilla/EventStateManager.h"
|
||||
#include "mozilla/EventStates.h"
|
||||
#include "mozilla/dom/SVGFEImageElementBinding.h"
|
||||
#include "mozilla/dom/SVGFilterElement.h"
|
||||
@@ -91,6 +92,9 @@ SVGFEImageElement::LoadSVGImage(bool aForce, bool aNotify)
|
||||
}
|
||||
}
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
* 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"
|
||||
@@ -133,6 +134,10 @@ SVGImageElement::LoadSVGImage(bool aForce, bool aNotify)
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
#include "nsStreamUtils.h"
|
||||
#include "nsIHttpChannel.h"
|
||||
#include "nsICacheInfoChannel.h"
|
||||
#include "nsIClassOfService.h"
|
||||
#include "nsIInterfaceRequestor.h"
|
||||
#include "nsIInterfaceRequestorUtils.h"
|
||||
#include "nsIProgressEventSink.h"
|
||||
@@ -2089,6 +2090,7 @@ imgLoader::LoadImageXPCOM(nsIURI* aURI,
|
||||
aCacheKey,
|
||||
aContentPolicyType,
|
||||
EmptyString(),
|
||||
/* aUseUrgentStartForChannel */ false,
|
||||
&proxy);
|
||||
*_retval = proxy;
|
||||
return rv;
|
||||
@@ -2108,6 +2110,7 @@ imgLoader::LoadImage(nsIURI* aURI,
|
||||
nsISupports* aCacheKey,
|
||||
nsContentPolicyType aContentPolicyType,
|
||||
const nsAString& initiatorType,
|
||||
bool aUseUrgentStartForChannel,
|
||||
imgRequestProxy** _retval)
|
||||
{
|
||||
MOZ_RELEASE_ASSERT(NS_IsMainThread());
|
||||
@@ -2277,6 +2280,11 @@ imgLoader::LoadImage(nsIURI* aURI,
|
||||
("[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,
|
||||
|
||||
@@ -307,6 +307,7 @@ public:
|
||||
nsISupports* aCacheKey,
|
||||
nsContentPolicyType aContentPolicyType,
|
||||
const nsAString& initiatorType,
|
||||
bool aUseUrgentStartForChannel,
|
||||
imgRequestProxy** _retval);
|
||||
|
||||
MOZ_MUST_USE nsresult
|
||||
|
||||
@@ -2230,6 +2230,7 @@ nsImageFrame::LoadIcon(const nsAString& aSpec,
|
||||
nullptr,
|
||||
contentPolicyType,
|
||||
EmptyString(),
|
||||
false, /* aUseUrgentStartForChannel */
|
||||
aRequest);
|
||||
}
|
||||
|
||||
|
||||
@@ -319,6 +319,7 @@ nsMenuItemIconX::LoadIcon(nsIURI* aIconURI)
|
||||
mLoadingPrincipal, loadGroup, this,
|
||||
mContent, document, nsIRequest::LOAD_NORMAL, nullptr,
|
||||
mContentType, EmptyString(),
|
||||
/* aUseUrgentStartForChannel */ false,
|
||||
getter_AddRefs(mIconRequest));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user