зеркало из https://github.com/mozilla/pjs.git
Bug 721659. Update the width/height of an image synchronously when src is set to something that was preloaded. r=bholley
This commit is contained in:
Родитель
187666328d
Коммит
21f5f2e536
|
@ -61,6 +61,7 @@
|
|||
#include "nsNetUtil.h"
|
||||
#include "nsAsyncDOMEvent.h"
|
||||
#include "nsGenericElement.h"
|
||||
#include "nsImageFrame.h"
|
||||
|
||||
#include "nsIPresShell.h"
|
||||
#include "nsEventStates.h"
|
||||
|
@ -300,10 +301,7 @@ nsImageLoadingContent::OnStopDecode(imgIRequest* aRequest,
|
|||
|
||||
// If the pending request is loaded, switch to it.
|
||||
if (aRequest == mPendingRequest) {
|
||||
PrepareCurrentRequest() = mPendingRequest;
|
||||
mPendingRequest = nsnull;
|
||||
mCurrentRequestNeedsResetAnimation = mPendingRequestNeedsResetAnimation;
|
||||
mPendingRequestNeedsResetAnimation = false;
|
||||
MakePendingRequestCurrent();
|
||||
}
|
||||
NS_ABORT_IF_FALSE(aRequest == mCurrentRequest,
|
||||
"One way or another, we should be current by now");
|
||||
|
@ -792,6 +790,26 @@ nsImageLoadingContent::LoadImage(nsIURI* aNewURI,
|
|||
getter_AddRefs(req));
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
TrackImage(req);
|
||||
|
||||
// Handle cases when we just ended up with a pending request but it's
|
||||
// already done. In that situation we have to synchronously switch that
|
||||
// request to being the current request, because websites depend on that
|
||||
// behavior.
|
||||
if (req == mPendingRequest) {
|
||||
PRUint32 pendingLoadStatus;
|
||||
rv = req->GetImageStatus(&pendingLoadStatus);
|
||||
if (NS_SUCCEEDED(rv) &&
|
||||
(pendingLoadStatus & imgIRequest::STATUS_LOAD_COMPLETE)) {
|
||||
MakePendingRequestCurrent();
|
||||
MOZ_ASSERT(mCurrentRequest,
|
||||
"How could we not have a current request here?");
|
||||
|
||||
nsImageFrame *f = do_QueryFrame(GetOurPrimaryFrame());
|
||||
if (f) {
|
||||
f->NotifyNewCurrentRequest(mCurrentRequest, NS_OK);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// If we don't have a current URI, we might as well store this URI so people
|
||||
// know what we tried (and failed) to load.
|
||||
|
@ -1046,6 +1064,16 @@ nsImageLoadingContent::PreparePendingRequest()
|
|||
return mPendingRequest;
|
||||
}
|
||||
|
||||
void
|
||||
nsImageLoadingContent::MakePendingRequestCurrent()
|
||||
{
|
||||
MOZ_ASSERT(mPendingRequest);
|
||||
PrepareCurrentRequest() = mPendingRequest;
|
||||
mPendingRequest = nsnull;
|
||||
mCurrentRequestNeedsResetAnimation = mPendingRequestNeedsResetAnimation;
|
||||
mPendingRequestNeedsResetAnimation = false;
|
||||
}
|
||||
|
||||
void
|
||||
nsImageLoadingContent::ClearCurrentRequest(nsresult aReason)
|
||||
{
|
||||
|
|
|
@ -297,6 +297,12 @@ protected:
|
|||
nsCOMPtr<imgIRequest>& PrepareCurrentRequest();
|
||||
nsCOMPtr<imgIRequest>& PreparePendingRequest();
|
||||
|
||||
/**
|
||||
* Switch our pending request to be our current request.
|
||||
* mPendingRequest must be non-null!
|
||||
*/
|
||||
void MakePendingRequestCurrent();
|
||||
|
||||
/**
|
||||
* Cancels and nulls-out the "current" and "pending" requests if they exist.
|
||||
*/
|
||||
|
|
|
@ -642,10 +642,6 @@ nsImageFrame::OnStopDecode(imgIRequest *aRequest,
|
|||
nsresult aStatus,
|
||||
const PRUnichar *aStatusArg)
|
||||
{
|
||||
nsPresContext *presContext = PresContext();
|
||||
nsIPresShell *presShell = presContext->GetPresShell();
|
||||
NS_ASSERTION(presShell, "No PresShell.");
|
||||
|
||||
// Check what request type we're dealing with
|
||||
nsCOMPtr<nsIImageLoadingContent> imageLoader = do_QueryInterface(mContent);
|
||||
NS_ASSERTION(imageLoader, "Who's notifying us??");
|
||||
|
@ -657,41 +653,49 @@ nsImageFrame::OnStopDecode(imgIRequest *aRequest,
|
|||
}
|
||||
|
||||
if (loadType == nsIImageLoadingContent::PENDING_REQUEST) {
|
||||
// May have to switch sizes here!
|
||||
bool intrinsicSizeChanged = true;
|
||||
if (NS_SUCCEEDED(aStatus)) {
|
||||
nsCOMPtr<imgIContainer> imageContainer;
|
||||
aRequest->GetImage(getter_AddRefs(imageContainer));
|
||||
NS_ASSERTION(imageContainer, "Successful load with no container?");
|
||||
intrinsicSizeChanged = UpdateIntrinsicSize(imageContainer);
|
||||
intrinsicSizeChanged = UpdateIntrinsicRatio(imageContainer) ||
|
||||
intrinsicSizeChanged;
|
||||
}
|
||||
else {
|
||||
// Have to size to 0,0 so that GetDesiredSize recalculates the size
|
||||
mIntrinsicSize.width.SetCoordValue(0);
|
||||
mIntrinsicSize.height.SetCoordValue(0);
|
||||
mIntrinsicRatio.SizeTo(0, 0);
|
||||
}
|
||||
|
||||
if (mState & IMAGE_GOTINITIALREFLOW) { // do nothing if we haven't gotten the initial reflow yet
|
||||
if (!(mState & IMAGE_SIZECONSTRAINED) && intrinsicSizeChanged) {
|
||||
if (presShell) {
|
||||
presShell->FrameNeedsReflow(this, nsIPresShell::eStyleChange,
|
||||
NS_FRAME_IS_DIRTY);
|
||||
}
|
||||
} else {
|
||||
nsSize s = GetSize();
|
||||
nsRect r(0, 0, s.width, s.height);
|
||||
// Update border+content to account for image change
|
||||
Invalidate(r);
|
||||
}
|
||||
}
|
||||
NotifyNewCurrentRequest(aRequest, aStatus);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
nsImageFrame::NotifyNewCurrentRequest(imgIRequest *aRequest,
|
||||
nsresult aStatus)
|
||||
{
|
||||
// May have to switch sizes here!
|
||||
bool intrinsicSizeChanged = true;
|
||||
if (NS_SUCCEEDED(aStatus)) {
|
||||
nsCOMPtr<imgIContainer> imageContainer;
|
||||
aRequest->GetImage(getter_AddRefs(imageContainer));
|
||||
NS_ASSERTION(imageContainer, "Successful load with no container?");
|
||||
intrinsicSizeChanged = UpdateIntrinsicSize(imageContainer);
|
||||
intrinsicSizeChanged = UpdateIntrinsicRatio(imageContainer) ||
|
||||
intrinsicSizeChanged;
|
||||
}
|
||||
else {
|
||||
// Have to size to 0,0 so that GetDesiredSize recalculates the size
|
||||
mIntrinsicSize.width.SetCoordValue(0);
|
||||
mIntrinsicSize.height.SetCoordValue(0);
|
||||
mIntrinsicRatio.SizeTo(0, 0);
|
||||
}
|
||||
|
||||
if (mState & IMAGE_GOTINITIALREFLOW) { // do nothing if we haven't gotten the initial reflow yet
|
||||
if (!(mState & IMAGE_SIZECONSTRAINED) && intrinsicSizeChanged) {
|
||||
nsIPresShell *presShell = PresContext()->GetPresShell();
|
||||
if (presShell) {
|
||||
presShell->FrameNeedsReflow(this, nsIPresShell::eStyleChange,
|
||||
NS_FRAME_IS_DIRTY);
|
||||
}
|
||||
} else {
|
||||
nsSize s = GetSize();
|
||||
nsRect r(0, 0, s.width, s.height);
|
||||
// Update border+content to account for image change
|
||||
Invalidate(r);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsImageFrame::FrameChanged(imgIRequest *aRequest,
|
||||
imgIContainer *aContainer,
|
||||
|
|
|
@ -62,6 +62,7 @@ class nsDisplayImage;
|
|||
class nsPresContext;
|
||||
class nsImageFrame;
|
||||
class nsTransform2D;
|
||||
class nsImageLoadingContent;
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
@ -250,6 +251,7 @@ protected:
|
|||
|
||||
protected:
|
||||
friend class nsImageListener;
|
||||
friend class nsImageLoadingContent;
|
||||
nsresult OnStartContainer(imgIRequest *aRequest, imgIContainer *aImage);
|
||||
nsresult OnDataAvailable(imgIRequest *aRequest, bool aCurrentFrame,
|
||||
const nsIntRect *rect);
|
||||
|
@ -259,6 +261,10 @@ protected:
|
|||
nsresult FrameChanged(imgIRequest *aRequest,
|
||||
imgIContainer *aContainer,
|
||||
const nsIntRect *aDirtyRect);
|
||||
/**
|
||||
* Notification that aRequest will now be the current request.
|
||||
*/
|
||||
void NotifyNewCurrentRequest(imgIRequest *aRequest, nsresult aStatus);
|
||||
|
||||
private:
|
||||
// random helpers
|
||||
|
|
Двоичный файл не отображается.
После Ширина: | Высота: | Размер: 118 B |
Двоичный файл не отображается.
После Ширина: | Высота: | Размер: 110 B |
|
@ -3,3 +3,7 @@
|
|||
== image-zoom-1.html image-zoom-1-ref.html
|
||||
== image-zoom-2.html image-zoom-1-ref.html
|
||||
== invalid-url-image-1.html invalid-url-image-1-ref.html
|
||||
== sync-image-switch-1a.html sync-image-switch-1-ref.html
|
||||
== sync-image-switch-1b.html sync-image-switch-1-ref.html
|
||||
== sync-image-switch-1c.html sync-image-switch-1-ref.html
|
||||
== sync-image-switch-1d.html sync-image-switch-1-ref.html
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<img src="blue-32x32.png">
|
||||
</html>
|
|
@ -0,0 +1,16 @@
|
|||
<!DOCTYPE html>
|
||||
<html class="reftest-wait">
|
||||
<img src="blue-16x20.png">
|
||||
<script>
|
||||
var otherImageSrc = "blue-32x32.png"
|
||||
window.onload = function() {
|
||||
var img = document.querySelector("img");
|
||||
img.src = otherImageSrc;
|
||||
img.style.width = img.naturalWidth + "px";
|
||||
img.style.height = img.naturalHeight + "px";
|
||||
document.documentElement.className = "";
|
||||
}
|
||||
var otherImage = new Image;
|
||||
otherImage.src = otherImageSrc;
|
||||
</script>
|
||||
</html>
|
|
@ -0,0 +1,16 @@
|
|||
<!DOCTYPE html>
|
||||
<html class="reftest-wait">
|
||||
<img src="blue-16x20.png">
|
||||
<script>
|
||||
var otherImageSrc = "blue-32x32.png"
|
||||
window.onload = function() {
|
||||
var img = document.querySelector("img");
|
||||
img.src = otherImageSrc;
|
||||
img.style.width = img.width + "px";
|
||||
img.style.height = img.height + "px";
|
||||
document.documentElement.className = "";
|
||||
}
|
||||
var otherImage = new Image;
|
||||
otherImage.src = otherImageSrc;
|
||||
</script>
|
||||
</html>
|
|
@ -0,0 +1,16 @@
|
|||
<!DOCTYPE html>
|
||||
<html class="reftest-wait">
|
||||
<input type="image" src="blue-16x20.png">
|
||||
<script>
|
||||
var otherImageSrc = "blue-32x32.png"
|
||||
window.onload = function() {
|
||||
var img = document.querySelector("input");
|
||||
img.src = otherImageSrc;
|
||||
img.style.width = img.naturalWidth + "px";
|
||||
img.style.height = img.naturalHeight + "px";
|
||||
document.documentElement.className = "";
|
||||
}
|
||||
var otherImage = new Image;
|
||||
otherImage.src = otherImageSrc;
|
||||
</script>
|
||||
</html>
|
|
@ -0,0 +1,16 @@
|
|||
<!DOCTYPE html>
|
||||
<html class="reftest-wait">
|
||||
<input type="image" src="blue-16x20.png">
|
||||
<script>
|
||||
var otherImageSrc = "blue-32x32.png"
|
||||
window.onload = function() {
|
||||
var img = document.querySelector("input");
|
||||
img.src = otherImageSrc;
|
||||
img.style.width = img.width + "px";
|
||||
img.style.height = img.height + "px";
|
||||
document.documentElement.className = "";
|
||||
}
|
||||
var otherImage = new Image;
|
||||
otherImage.src = otherImageSrc;
|
||||
</script>
|
||||
</html>
|
Загрузка…
Ссылка в новой задаче