gecko/layout/style/ImageLoader.h

126 lines
3.7 KiB
C
Raw Normal View History

/* 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/. */
// A class that handles style system image loads (other image loads are handled
// by the nodes in the content tree).
#ifndef mozilla_css_ImageLoader_h___
#define mozilla_css_ImageLoader_h___
#include "nsClassHashtable.h"
#include "nsHashKeys.h"
#include "nsTArray.h"
#include "imgIRequest.h"
#include "imgIOnloadBlocker.h"
#include "imgINotificationObserver.h"
#include "mozilla/Attributes.h"
class imgIContainer;
class nsIFrame;
class nsIDocument;
class nsPresContext;
class nsIURI;
class nsIPrincipal;
namespace mozilla {
namespace css {
struct ImageValue;
class ImageLoader MOZ_FINAL : public imgINotificationObserver,
public imgIOnloadBlocker {
public:
Bug 783162: Make mapped attributes hold the image alive. r=bz The nsCSSValue in nsGenericHTMLElement::MapBackgroundInto is a temporary. This causes a problem after Bug 697230 landed, because the nsCSSValue::Image we put into that value is destroyed once we're done doing style stuff. Previously the nsImageLoader would grab the request off the nsCSSValue::Image and hold it alive. Bug 697230 changed the behavior here; now when the nsCSSValue::Image is destroyed it tells the image loader to drop the request. The result is that all the references to the request are dropped and the frame is never told it has a background. The solution is to keep the nsCSSValue::Image alive longer. This patch adds two new types of nsAttrValue. The first is an nsCSSValue::URL. A ParseBackgroundAttribute method is added on nsGenericHTMLElement that the relevant elements (body/td/th/table/tr/tbody/thead/tfoot) call that parses background into an nsCSSValue::URL. The second is an nsCSSValue::Image. nsGenericHTMLElement::MapBackgroundInto attempts to convert the nsCSSValue::URL into an nsCSSValue::Image by kicking off the image load. The result is that image loads are only started when the element is actually visible. This also mirrors the way background-image works. This also allows us to fix two longstanding bugs in this code. Since MapBackgroundInto doesn't have a pointer to the actual element, it relied on grabbing the principal of the document. Now we can grab the principal of the node in ParseBackgroundAttribute. MapBackgroundInto also has no way to get at the element's base URI (to honor xml:base), which is now possible in ParseBackgroundAttribute. nsCSSValue::[Image|URL] have also been moved to be mozilla::css::[Image|URL]Value. nsAttrValue.h is included in external linkage code, so it can't include nsCSSValue.h to get the declarations of nsCSSValue::[Image|URL], and nested classes can't be forward declared. Moving the classes to a namespace solves the problem. Finally some old inoperative quirks mode code was removed. This code has done nothing since Bug 273078 was landed in 2004.
2012-08-24 10:50:49 -07:00
typedef mozilla::css::ImageValue Image;
explicit ImageLoader(nsIDocument* aDocument)
: mDocument(aDocument),
mInClone(false)
{
MOZ_ASSERT(mDocument);
}
NS_DECL_ISUPPORTS
NS_DECL_IMGIONLOADBLOCKER
NS_DECL_IMGINOTIFICATIONOBSERVER
void DropDocumentReference();
Bug 783162: Make mapped attributes hold the image alive. r=bz The nsCSSValue in nsGenericHTMLElement::MapBackgroundInto is a temporary. This causes a problem after Bug 697230 landed, because the nsCSSValue::Image we put into that value is destroyed once we're done doing style stuff. Previously the nsImageLoader would grab the request off the nsCSSValue::Image and hold it alive. Bug 697230 changed the behavior here; now when the nsCSSValue::Image is destroyed it tells the image loader to drop the request. The result is that all the references to the request are dropped and the frame is never told it has a background. The solution is to keep the nsCSSValue::Image alive longer. This patch adds two new types of nsAttrValue. The first is an nsCSSValue::URL. A ParseBackgroundAttribute method is added on nsGenericHTMLElement that the relevant elements (body/td/th/table/tr/tbody/thead/tfoot) call that parses background into an nsCSSValue::URL. The second is an nsCSSValue::Image. nsGenericHTMLElement::MapBackgroundInto attempts to convert the nsCSSValue::URL into an nsCSSValue::Image by kicking off the image load. The result is that image loads are only started when the element is actually visible. This also mirrors the way background-image works. This also allows us to fix two longstanding bugs in this code. Since MapBackgroundInto doesn't have a pointer to the actual element, it relied on grabbing the principal of the document. Now we can grab the principal of the node in ParseBackgroundAttribute. MapBackgroundInto also has no way to get at the element's base URI (to honor xml:base), which is now possible in ParseBackgroundAttribute. nsCSSValue::[Image|URL] have also been moved to be mozilla::css::[Image|URL]Value. nsAttrValue.h is included in external linkage code, so it can't include nsCSSValue.h to get the declarations of nsCSSValue::[Image|URL], and nested classes can't be forward declared. Moving the classes to a namespace solves the problem. Finally some old inoperative quirks mode code was removed. This code has done nothing since Bug 273078 was landed in 2004.
2012-08-24 10:50:49 -07:00
void MaybeRegisterCSSImage(Image* aImage);
void DeregisterCSSImage(Image* aImage);
void AssociateRequestToFrame(imgIRequest* aRequest,
nsIFrame* aFrame);
void DisassociateRequestFromFrame(imgIRequest* aRequest,
nsIFrame* aFrame);
void DropRequestsForFrame(nsIFrame* aFrame);
void SetAnimationMode(uint16_t aMode);
Bug 816498: Fix some things about background attribute handling that are still broken. r=bz As filed the bug is about table backgrounds failing to print. The root cause of this is that we load images from the original document, because print/print-preview documents (which are static clones of the original) cannot do loads. This results in an entry in the css::ImageValue's request table under the original document, but entry under the printing document. Then we do layout, try to get the request, and fail, and nothing is displayed. The solution to this is to force us to clone the request for the printing document if we're loading off the original document. I manually verified that this does not regress Bug 560235. While writing a test for this, we discovered another problem. The reftest print code does not actually use the printing codepath. Instead it takes an existing document, tears down its presshell, and creates a new presshell for printing. Fixing the above bug did not make the reftest print test pass because ImageLoader does not deal properly with presshell destruction/recreation. It assumes that when the presshell is destroyed all of the css::ImageValues can be cleared of their entries for that document. This fails for ImageValues for mapped attributes because they are held alive by the content tree. When a new presshell for this document is then created there is no entry for the document and thus no image request to paint. The fix for this is to only clear the frame to request and request to frame mapping hashtables and not to clear the document's entry on the ImageValue when the presshell is destroyed. The destruction of the ImageLoader (which is held from a strong reference on the document) is when those entries are removed. The final change is to change css::ImageValue's hashtable from holding a strong reference to the keys (which are documents) to holding raw pointer references. This is safe because we clear the relevant entry when the corresponding ImageLoader dies, and is needed to prevent a reference cycle that was being broken by presshell destruction. --HG-- rename : layout/reftests/backgrounds/table-background-ref.html => layout/reftests/backgrounds/table-background-print-ref.html rename : layout/reftests/backgrounds/table-background.html => layout/reftests/backgrounds/table-background-print.html
2013-02-23 06:59:43 -08:00
void ClearFrames();
void LoadImage(nsIURI* aURI, nsIPrincipal* aPrincipal, nsIURI* aReferrer,
Bug 783162: Make mapped attributes hold the image alive. r=bz The nsCSSValue in nsGenericHTMLElement::MapBackgroundInto is a temporary. This causes a problem after Bug 697230 landed, because the nsCSSValue::Image we put into that value is destroyed once we're done doing style stuff. Previously the nsImageLoader would grab the request off the nsCSSValue::Image and hold it alive. Bug 697230 changed the behavior here; now when the nsCSSValue::Image is destroyed it tells the image loader to drop the request. The result is that all the references to the request are dropped and the frame is never told it has a background. The solution is to keep the nsCSSValue::Image alive longer. This patch adds two new types of nsAttrValue. The first is an nsCSSValue::URL. A ParseBackgroundAttribute method is added on nsGenericHTMLElement that the relevant elements (body/td/th/table/tr/tbody/thead/tfoot) call that parses background into an nsCSSValue::URL. The second is an nsCSSValue::Image. nsGenericHTMLElement::MapBackgroundInto attempts to convert the nsCSSValue::URL into an nsCSSValue::Image by kicking off the image load. The result is that image loads are only started when the element is actually visible. This also mirrors the way background-image works. This also allows us to fix two longstanding bugs in this code. Since MapBackgroundInto doesn't have a pointer to the actual element, it relied on grabbing the principal of the document. Now we can grab the principal of the node in ParseBackgroundAttribute. MapBackgroundInto also has no way to get at the element's base URI (to honor xml:base), which is now possible in ParseBackgroundAttribute. nsCSSValue::[Image|URL] have also been moved to be mozilla::css::[Image|URL]Value. nsAttrValue.h is included in external linkage code, so it can't include nsCSSValue.h to get the declarations of nsCSSValue::[Image|URL], and nested classes can't be forward declared. Moving the classes to a namespace solves the problem. Finally some old inoperative quirks mode code was removed. This code has done nothing since Bug 273078 was landed in 2004.
2012-08-24 10:50:49 -07:00
Image* aCSSValue);
void DestroyRequest(imgIRequest* aRequest);
private:
~ImageLoader() {}
// We need to be able to look up the frames associated with a request (for
// delivering notifications) and the requests associated with a frame (when
// the frame goes away). Thus we maintain hashtables going both ways. These
// should always be in sync.
typedef nsTArray<nsIFrame*> FrameSet;
typedef nsTArray<nsCOMPtr<imgIRequest> > RequestSet;
Bug 783162: Make mapped attributes hold the image alive. r=bz The nsCSSValue in nsGenericHTMLElement::MapBackgroundInto is a temporary. This causes a problem after Bug 697230 landed, because the nsCSSValue::Image we put into that value is destroyed once we're done doing style stuff. Previously the nsImageLoader would grab the request off the nsCSSValue::Image and hold it alive. Bug 697230 changed the behavior here; now when the nsCSSValue::Image is destroyed it tells the image loader to drop the request. The result is that all the references to the request are dropped and the frame is never told it has a background. The solution is to keep the nsCSSValue::Image alive longer. This patch adds two new types of nsAttrValue. The first is an nsCSSValue::URL. A ParseBackgroundAttribute method is added on nsGenericHTMLElement that the relevant elements (body/td/th/table/tr/tbody/thead/tfoot) call that parses background into an nsCSSValue::URL. The second is an nsCSSValue::Image. nsGenericHTMLElement::MapBackgroundInto attempts to convert the nsCSSValue::URL into an nsCSSValue::Image by kicking off the image load. The result is that image loads are only started when the element is actually visible. This also mirrors the way background-image works. This also allows us to fix two longstanding bugs in this code. Since MapBackgroundInto doesn't have a pointer to the actual element, it relied on grabbing the principal of the document. Now we can grab the principal of the node in ParseBackgroundAttribute. MapBackgroundInto also has no way to get at the element's base URI (to honor xml:base), which is now possible in ParseBackgroundAttribute. nsCSSValue::[Image|URL] have also been moved to be mozilla::css::[Image|URL]Value. nsAttrValue.h is included in external linkage code, so it can't include nsCSSValue.h to get the declarations of nsCSSValue::[Image|URL], and nested classes can't be forward declared. Moving the classes to a namespace solves the problem. Finally some old inoperative quirks mode code was removed. This code has done nothing since Bug 273078 was landed in 2004.
2012-08-24 10:50:49 -07:00
typedef nsTHashtable<nsPtrHashKey<Image> > ImageHashSet;
typedef nsClassHashtable<nsISupportsHashKey,
FrameSet> RequestToFrameMap;
typedef nsClassHashtable<nsPtrHashKey<nsIFrame>,
RequestSet> FrameToRequestMap;
Bug 783162: Make mapped attributes hold the image alive. r=bz The nsCSSValue in nsGenericHTMLElement::MapBackgroundInto is a temporary. This causes a problem after Bug 697230 landed, because the nsCSSValue::Image we put into that value is destroyed once we're done doing style stuff. Previously the nsImageLoader would grab the request off the nsCSSValue::Image and hold it alive. Bug 697230 changed the behavior here; now when the nsCSSValue::Image is destroyed it tells the image loader to drop the request. The result is that all the references to the request are dropped and the frame is never told it has a background. The solution is to keep the nsCSSValue::Image alive longer. This patch adds two new types of nsAttrValue. The first is an nsCSSValue::URL. A ParseBackgroundAttribute method is added on nsGenericHTMLElement that the relevant elements (body/td/th/table/tr/tbody/thead/tfoot) call that parses background into an nsCSSValue::URL. The second is an nsCSSValue::Image. nsGenericHTMLElement::MapBackgroundInto attempts to convert the nsCSSValue::URL into an nsCSSValue::Image by kicking off the image load. The result is that image loads are only started when the element is actually visible. This also mirrors the way background-image works. This also allows us to fix two longstanding bugs in this code. Since MapBackgroundInto doesn't have a pointer to the actual element, it relied on grabbing the principal of the document. Now we can grab the principal of the node in ParseBackgroundAttribute. MapBackgroundInto also has no way to get at the element's base URI (to honor xml:base), which is now possible in ParseBackgroundAttribute. nsCSSValue::[Image|URL] have also been moved to be mozilla::css::[Image|URL]Value. nsAttrValue.h is included in external linkage code, so it can't include nsCSSValue.h to get the declarations of nsCSSValue::[Image|URL], and nested classes can't be forward declared. Moving the classes to a namespace solves the problem. Finally some old inoperative quirks mode code was removed. This code has done nothing since Bug 273078 was landed in 2004.
2012-08-24 10:50:49 -07:00
void AddImage(Image* aCSSImage);
void RemoveImage(Image* aCSSImage);
nsPresContext* GetPresContext();
void DoRedraw(FrameSet* aFrameSet);
static PLDHashOperator
SetAnimationModeEnumerator(nsISupports* aKey, FrameSet* aValue,
void* aClosure);
nsresult OnStartContainer(imgIRequest *aRequest, imgIContainer* aImage);
nsresult OnStopFrame(imgIRequest *aRequest);
nsresult OnImageIsAnimated(imgIRequest *aRequest);
nsresult FrameChanged(imgIRequest* aRequest);
// Do not override OnDataAvailable since background images are not
// displayed incrementally; they are displayed after the entire image
// has been loaded.
// A map of imgIRequests to the nsIFrames that are using them.
RequestToFrameMap mRequestToFrameMap;
// A map of nsIFrames to the imgIRequests they use.
FrameToRequestMap mFrameToRequestMap;
// A weak pointer to our document. Nulled out by DropDocumentReference.
nsIDocument* mDocument;
// The set of all nsCSSValue::Images (whether they're associated a frame or
// not). We'll need this when we go away to remove any requests associated
// with our document from those Images.
ImageHashSet mImages;
// Are we cloning? If so, ignore any notifications we get.
bool mInClone;
};
} // namespace css
} // namespace mozilla
#endif /* mozilla_css_ImageLoader_h___ */