зеркало из 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 "nsNetUtil.h"
|
||||||
#include "nsAsyncDOMEvent.h"
|
#include "nsAsyncDOMEvent.h"
|
||||||
#include "nsGenericElement.h"
|
#include "nsGenericElement.h"
|
||||||
|
#include "nsImageFrame.h"
|
||||||
|
|
||||||
#include "nsIPresShell.h"
|
#include "nsIPresShell.h"
|
||||||
#include "nsEventStates.h"
|
#include "nsEventStates.h"
|
||||||
|
@ -300,10 +301,7 @@ nsImageLoadingContent::OnStopDecode(imgIRequest* aRequest,
|
||||||
|
|
||||||
// If the pending request is loaded, switch to it.
|
// If the pending request is loaded, switch to it.
|
||||||
if (aRequest == mPendingRequest) {
|
if (aRequest == mPendingRequest) {
|
||||||
PrepareCurrentRequest() = mPendingRequest;
|
MakePendingRequestCurrent();
|
||||||
mPendingRequest = nsnull;
|
|
||||||
mCurrentRequestNeedsResetAnimation = mPendingRequestNeedsResetAnimation;
|
|
||||||
mPendingRequestNeedsResetAnimation = false;
|
|
||||||
}
|
}
|
||||||
NS_ABORT_IF_FALSE(aRequest == mCurrentRequest,
|
NS_ABORT_IF_FALSE(aRequest == mCurrentRequest,
|
||||||
"One way or another, we should be current by now");
|
"One way or another, we should be current by now");
|
||||||
|
@ -792,6 +790,26 @@ nsImageLoadingContent::LoadImage(nsIURI* aNewURI,
|
||||||
getter_AddRefs(req));
|
getter_AddRefs(req));
|
||||||
if (NS_SUCCEEDED(rv)) {
|
if (NS_SUCCEEDED(rv)) {
|
||||||
TrackImage(req);
|
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 {
|
} else {
|
||||||
// If we don't have a current URI, we might as well store this URI so people
|
// 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.
|
// know what we tried (and failed) to load.
|
||||||
|
@ -1046,6 +1064,16 @@ nsImageLoadingContent::PreparePendingRequest()
|
||||||
return mPendingRequest;
|
return mPendingRequest;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nsImageLoadingContent::MakePendingRequestCurrent()
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(mPendingRequest);
|
||||||
|
PrepareCurrentRequest() = mPendingRequest;
|
||||||
|
mPendingRequest = nsnull;
|
||||||
|
mCurrentRequestNeedsResetAnimation = mPendingRequestNeedsResetAnimation;
|
||||||
|
mPendingRequestNeedsResetAnimation = false;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
nsImageLoadingContent::ClearCurrentRequest(nsresult aReason)
|
nsImageLoadingContent::ClearCurrentRequest(nsresult aReason)
|
||||||
{
|
{
|
||||||
|
|
|
@ -297,6 +297,12 @@ protected:
|
||||||
nsCOMPtr<imgIRequest>& PrepareCurrentRequest();
|
nsCOMPtr<imgIRequest>& PrepareCurrentRequest();
|
||||||
nsCOMPtr<imgIRequest>& PreparePendingRequest();
|
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.
|
* Cancels and nulls-out the "current" and "pending" requests if they exist.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -642,10 +642,6 @@ nsImageFrame::OnStopDecode(imgIRequest *aRequest,
|
||||||
nsresult aStatus,
|
nsresult aStatus,
|
||||||
const PRUnichar *aStatusArg)
|
const PRUnichar *aStatusArg)
|
||||||
{
|
{
|
||||||
nsPresContext *presContext = PresContext();
|
|
||||||
nsIPresShell *presShell = presContext->GetPresShell();
|
|
||||||
NS_ASSERTION(presShell, "No PresShell.");
|
|
||||||
|
|
||||||
// Check what request type we're dealing with
|
// Check what request type we're dealing with
|
||||||
nsCOMPtr<nsIImageLoadingContent> imageLoader = do_QueryInterface(mContent);
|
nsCOMPtr<nsIImageLoadingContent> imageLoader = do_QueryInterface(mContent);
|
||||||
NS_ASSERTION(imageLoader, "Who's notifying us??");
|
NS_ASSERTION(imageLoader, "Who's notifying us??");
|
||||||
|
@ -657,41 +653,49 @@ nsImageFrame::OnStopDecode(imgIRequest *aRequest,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (loadType == nsIImageLoadingContent::PENDING_REQUEST) {
|
if (loadType == nsIImageLoadingContent::PENDING_REQUEST) {
|
||||||
// May have to switch sizes here!
|
NotifyNewCurrentRequest(aRequest, aStatus);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return NS_OK;
|
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
|
nsresult
|
||||||
nsImageFrame::FrameChanged(imgIRequest *aRequest,
|
nsImageFrame::FrameChanged(imgIRequest *aRequest,
|
||||||
imgIContainer *aContainer,
|
imgIContainer *aContainer,
|
||||||
|
|
|
@ -62,6 +62,7 @@ class nsDisplayImage;
|
||||||
class nsPresContext;
|
class nsPresContext;
|
||||||
class nsImageFrame;
|
class nsImageFrame;
|
||||||
class nsTransform2D;
|
class nsTransform2D;
|
||||||
|
class nsImageLoadingContent;
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
namespace layers {
|
namespace layers {
|
||||||
|
@ -250,6 +251,7 @@ protected:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
friend class nsImageListener;
|
friend class nsImageListener;
|
||||||
|
friend class nsImageLoadingContent;
|
||||||
nsresult OnStartContainer(imgIRequest *aRequest, imgIContainer *aImage);
|
nsresult OnStartContainer(imgIRequest *aRequest, imgIContainer *aImage);
|
||||||
nsresult OnDataAvailable(imgIRequest *aRequest, bool aCurrentFrame,
|
nsresult OnDataAvailable(imgIRequest *aRequest, bool aCurrentFrame,
|
||||||
const nsIntRect *rect);
|
const nsIntRect *rect);
|
||||||
|
@ -259,6 +261,10 @@ protected:
|
||||||
nsresult FrameChanged(imgIRequest *aRequest,
|
nsresult FrameChanged(imgIRequest *aRequest,
|
||||||
imgIContainer *aContainer,
|
imgIContainer *aContainer,
|
||||||
const nsIntRect *aDirtyRect);
|
const nsIntRect *aDirtyRect);
|
||||||
|
/**
|
||||||
|
* Notification that aRequest will now be the current request.
|
||||||
|
*/
|
||||||
|
void NotifyNewCurrentRequest(imgIRequest *aRequest, nsresult aStatus);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// random helpers
|
// random helpers
|
||||||
|
|
Двоичный файл не отображается.
После Ширина: | Высота: | Размер: 118 B |
Двоичный файл не отображается.
После Ширина: | Высота: | Размер: 110 B |
|
@ -3,3 +3,7 @@
|
||||||
== image-zoom-1.html image-zoom-1-ref.html
|
== image-zoom-1.html image-zoom-1-ref.html
|
||||||
== image-zoom-2.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
|
== 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>
|
Загрузка…
Ссылка в новой задаче