Bug 1268182 - Allow image loads to short-circuit after selecting a source if the new source URL matches the previous one URL. r=echen

--HG--
extra : rebase_source : 0549f97a654bb1d4983aac0e93e30f1a1fc5864e
This commit is contained in:
Josh Matthews 2016-09-26 14:17:38 -04:00
parent feb1b8a1f3
commit 746c91d87a
3 changed files with 39 additions and 8 deletions

View File

@ -117,6 +117,7 @@ HTMLImageElement::HTMLImageElement(already_AddRefed<mozilla::dom::NodeInfo>& aNo
: nsGenericHTMLElement(aNodeInfo)
, mForm(nullptr)
, mInDocResponsiveContent(false)
, mCurrentDensity(1.0)
{
// We start out broken
AddStatesSilently(NS_EVENT_STATE_BROKEN);
@ -951,6 +952,19 @@ HTMLImageElement::InResponsiveMode()
HaveSrcsetOrInPicture();
}
bool
HTMLImageElement::SelectedSourceMatchesLast(nsIURI* aSelectedSource, double aSelectedDensity)
{
// If there was no selected source previously, we don't want to short-circuit the load.
// Similarly for if there is no newly selected source.
if (!mLastSelectedSource || !aSelectedSource) {
return false;
}
bool equal = false;
return NS_SUCCEEDED(mLastSelectedSource->Equals(aSelectedSource, &equal)) && equal &&
aSelectedDensity == mCurrentDensity;
}
nsresult
HTMLImageElement::LoadSelectedImage(bool aForce, bool aNotify, bool aAlwaysLoad)
{
@ -965,8 +979,15 @@ HTMLImageElement::LoadSelectedImage(bool aForce, bool aNotify, bool aAlwaysLoad)
}
}
nsCOMPtr<nsIURI> selectedSource;
double currentDensity = 1.0; // default to 1.0 for the src attribute case
if (mResponsiveSelector) {
nsCOMPtr<nsIURI> url = mResponsiveSelector->GetSelectedImageURL();
selectedSource = url;
currentDensity = mResponsiveSelector->GetSelectedImageDensity();
if (!aAlwaysLoad && SelectedSourceMatchesLast(selectedSource, currentDensity)) {
return NS_OK;
}
if (url) {
rv = LoadImage(url, aForce, aNotify, eImageLoadType_Imageset);
}
@ -976,6 +997,14 @@ HTMLImageElement::LoadSelectedImage(bool aForce, bool aNotify, bool aAlwaysLoad)
CancelImageRequests(aNotify);
rv = NS_OK;
} else {
nsIDocument* doc = GetOurOwnerDoc();
if (doc) {
StringToURI(src, doc, getter_AddRefs(selectedSource));
if (!aAlwaysLoad && SelectedSourceMatchesLast(selectedSource, currentDensity)) {
return NS_OK;
}
}
// If we have a srcset attribute or are in a <picture> element,
// we always use the Imageset load type, even if we parsed no
// valid responsive sources from either, per spec.
@ -984,6 +1013,8 @@ HTMLImageElement::LoadSelectedImage(bool aForce, bool aNotify, bool aAlwaysLoad)
: eImageLoadType_Normal);
}
}
mLastSelectedSource = selectedSource;
mCurrentDensity = currentDensity;
if (NS_FAILED(rv)) {
CancelImageRequests(aNotify);

View File

@ -292,6 +292,9 @@ protected:
// only mode after Bug 1076583
bool InResponsiveMode();
// True if the given URL and density equal the last URL and density that was loaded by this element.
bool SelectedSourceMatchesLast(nsIURI* aSelectedSource, double aSelectedDensity);
// Resolve and load the current mResponsiveSelector (responsive mode) or src
// attr image.
nsresult LoadSelectedImage(bool aForce, bool aNotify, bool aAlwaysLoad);
@ -363,6 +366,11 @@ private:
bool mInDocResponsiveContent;
RefPtr<ImageLoadTask> mPendingImageLoadTask;
// Last URL that was attempted to load by this element.
nsCOMPtr<nsIURI> mLastSelectedSource;
// Last pixel density that was selected.
double mCurrentDensity;
};
} // namespace dom

View File

@ -1,8 +0,0 @@
[viewport-change.html]
type: testharness
[picture: same URL in source (max-width:500px) and img, resize to wide]
expected: FAIL
[picture: same URL in source (max-width:500px) and img, resize to narrow]
expected: FAIL