mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Merge mozilla-central to mozilla-inbound
This commit is contained in:
commit
57fe127515
@ -35,7 +35,7 @@ MOCHITEST_BROWSER_TESTS = \
|
||||
browser_dbg_propertyview-09.js \
|
||||
browser_dbg_propertyview-10.js \
|
||||
browser_dbg_propertyview-edit.js \
|
||||
browser_dbg_reload-same-script.js \
|
||||
$(warning browser_dbg_reload-same-script.js temporarily disabled due to oranges, see bug 780198 & bug 782179) \
|
||||
browser_dbg_panesize.js \
|
||||
browser_dbg_panesize-inner.js \
|
||||
browser_dbg_stack-01.js \
|
||||
|
@ -69,6 +69,7 @@ class nsWindowSizes;
|
||||
namespace mozilla {
|
||||
namespace css {
|
||||
class Loader;
|
||||
class ImageLoader;
|
||||
} // namespace css
|
||||
|
||||
namespace dom {
|
||||
@ -78,8 +79,8 @@ class Element;
|
||||
} // namespace mozilla
|
||||
|
||||
#define NS_IDOCUMENT_IID \
|
||||
{ 0xbd70ee06, 0x2a7d, 0x4258, \
|
||||
{ 0x86, 0x4b, 0xbd, 0x28, 0xad, 0x9f, 0xd1, 0x41 } }
|
||||
{ 0xdb888523, 0x541f, 0x49e3, \
|
||||
{ 0xa9, 0x71, 0xb5, 0xea, 0xd1, 0xf0, 0xc3, 0xcf } }
|
||||
|
||||
// Flag for AddStyleSheet().
|
||||
#define NS_STYLESHEET_FROM_CATALOG (1 << 0)
|
||||
@ -585,6 +586,13 @@ public:
|
||||
return mCSSLoader;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get this document's StyleImageLoader. This is guaranteed to not return null.
|
||||
*/
|
||||
mozilla::css::ImageLoader* StyleImageLoader() const {
|
||||
return mStyleImageLoader;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the channel that was passed to StartDocumentLoad or Reset for this
|
||||
* document. Note that this may be null in some cases (eg if
|
||||
@ -1739,6 +1747,7 @@ protected:
|
||||
// We hold a strong reference to mNodeInfoManager through mNodeInfo
|
||||
nsNodeInfoManager* mNodeInfoManager; // [STRONG]
|
||||
nsRefPtr<mozilla::css::Loader> mCSSLoader;
|
||||
mozilla::css::ImageLoader* mStyleImageLoader; // [STRONG]
|
||||
nsHTMLStyleSheet* mAttrStyleSheet;
|
||||
|
||||
// The set of all object, embed, applet, video and audio elements for
|
||||
|
@ -34,7 +34,7 @@ interface nsIFrame;
|
||||
* sufficient, when combined with the imageBlockingStatus information.)
|
||||
*/
|
||||
|
||||
[scriptable, uuid(f7debb84-2854-4731-a57b-1bd752ad71f8)]
|
||||
[scriptable, uuid(4bf1a7c5-6edb-4191-a257-e31a90f6aa85)]
|
||||
interface nsIImageLoadingContent : imgIDecoderObserver
|
||||
{
|
||||
/**
|
||||
@ -156,9 +156,4 @@ interface nsIImageLoadingContent : imgIDecoderObserver
|
||||
* as PR_FALSE to revert ImageState() to its original behaviour.
|
||||
*/
|
||||
void forceImageState(in boolean aForce, in unsigned long long aState);
|
||||
|
||||
/**
|
||||
* We need to be notified when our document changes.
|
||||
*/
|
||||
[noscript, notxpcom] void NotifyOwnerDocumentChanged(in nsIDocument aOldDoc);
|
||||
};
|
||||
|
@ -20,8 +20,8 @@ class Element;
|
||||
} // namespace mozilla
|
||||
|
||||
#define NS_IMUTATION_OBSERVER_IID \
|
||||
{ 0x85eea794, 0xed8e, 0x4e1b, \
|
||||
{ 0xa1, 0x28, 0xd0, 0x93, 0x00, 0xae, 0x51, 0xaa } }
|
||||
{ 0x16fe5e3e, 0xeadc, 0x4312, \
|
||||
{ 0x9d, 0x44, 0xb6, 0xbe, 0xdd, 0x6b, 0x54, 0x74 } }
|
||||
|
||||
/**
|
||||
* Information details about a characterdata change. Basically, we
|
||||
@ -192,6 +192,20 @@ public:
|
||||
nsIAtom* aAttribute,
|
||||
PRInt32 aModType) = 0;
|
||||
|
||||
/**
|
||||
* Notification that an attribute of an element has been
|
||||
* set to the value it already had.
|
||||
*
|
||||
* @param aDocument The owner-document of aContent.
|
||||
* @param aElement The element whose attribute changed
|
||||
* @param aNameSpaceID The namespace id of the changed attribute
|
||||
* @param aAttribute The name of the changed attribute
|
||||
*/
|
||||
virtual void AttributeSetToCurrentValue(nsIDocument* aDocument,
|
||||
mozilla::dom::Element* aElement,
|
||||
PRInt32 aNameSpaceID,
|
||||
nsIAtom* aAttribute) {}
|
||||
|
||||
/**
|
||||
* Notification that one or more content nodes have been appended to the
|
||||
* child list of another node in the tree.
|
||||
|
@ -1672,6 +1672,21 @@ extern const nsIID kThisPtrOffsetsSID;
|
||||
NS_OFFSET_AND_INTERFACE_TABLE_END \
|
||||
NS_OFFSET_AND_INTERFACE_TABLE_TO_MAP_SEGUE
|
||||
|
||||
#define NS_NODE_INTERFACE_TABLE9(_class, _i1, _i2, _i3, _i4, _i5, _i6, _i7, \
|
||||
_i8, _i9) \
|
||||
NS_NODE_OFFSET_AND_INTERFACE_TABLE_BEGIN(_class) \
|
||||
NS_INTERFACE_TABLE_ENTRY(_class, _i1) \
|
||||
NS_INTERFACE_TABLE_ENTRY(_class, _i2) \
|
||||
NS_INTERFACE_TABLE_ENTRY(_class, _i3) \
|
||||
NS_INTERFACE_TABLE_ENTRY(_class, _i4) \
|
||||
NS_INTERFACE_TABLE_ENTRY(_class, _i5) \
|
||||
NS_INTERFACE_TABLE_ENTRY(_class, _i6) \
|
||||
NS_INTERFACE_TABLE_ENTRY(_class, _i7) \
|
||||
NS_INTERFACE_TABLE_ENTRY(_class, _i8) \
|
||||
NS_INTERFACE_TABLE_ENTRY(_class, _i9) \
|
||||
NS_OFFSET_AND_INTERFACE_TABLE_END \
|
||||
NS_OFFSET_AND_INTERFACE_TABLE_TO_MAP_SEGUE
|
||||
|
||||
|
||||
NS_DEFINE_STATIC_IID_ACCESSOR(nsINode, NS_INODE_IID)
|
||||
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include "mozilla/dom/Element.h"
|
||||
#include "nsClassHashtable.h"
|
||||
#include "nsNodeUtils.h"
|
||||
#include "nsIDOMMutationEvent.h"
|
||||
|
||||
class nsDOMMutationObserver;
|
||||
|
||||
@ -273,6 +274,16 @@ public:
|
||||
NS_DECL_NSIMUTATIONOBSERVER_CONTENTINSERTED
|
||||
NS_DECL_NSIMUTATIONOBSERVER_CONTENTREMOVED
|
||||
NS_DECL_NSIMUTATIONOBSERVER_NODEWILLBEDESTROYED
|
||||
|
||||
virtual void AttributeSetToCurrentValue(nsIDocument* aDocument,
|
||||
mozilla::dom::Element* aElement,
|
||||
PRInt32 aNameSpaceID,
|
||||
nsIAtom* aAttribute)
|
||||
{
|
||||
// We can reuse AttributeWillChange implementation.
|
||||
AttributeWillChange(aDocument, aElement, aNameSpaceID, aAttribute,
|
||||
nsIDOMMutationEvent::MODIFICATION);
|
||||
}
|
||||
};
|
||||
|
||||
NS_DEFINE_STATIC_IID_ACCESSOR(nsMutationReceiver, NS_MUTATION_OBSERVER_IID)
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include "nsIObserver.h"
|
||||
#include "nsIBaseWindow.h"
|
||||
#include "mozilla/css/Loader.h"
|
||||
#include "mozilla/css/ImageLoader.h"
|
||||
#include "nsIDocShell.h"
|
||||
#include "nsIDocShellTreeItem.h"
|
||||
#include "nsIScriptRuntime.h"
|
||||
@ -1645,6 +1646,11 @@ nsDocument::~nsDocument()
|
||||
mCSSLoader->DropDocumentReference();
|
||||
}
|
||||
|
||||
if (mStyleImageLoader) {
|
||||
mStyleImageLoader->DropDocumentReference();
|
||||
NS_RELEASE(mStyleImageLoader);
|
||||
}
|
||||
|
||||
delete mHeaderData;
|
||||
|
||||
if (mBoxObjectTable) {
|
||||
@ -1975,7 +1981,7 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||
nsresult
|
||||
nsDocument::Init()
|
||||
{
|
||||
if (mCSSLoader || mNodeInfoManager || mScriptLoader) {
|
||||
if (mCSSLoader || mStyleImageLoader || mNodeInfoManager || mScriptLoader) {
|
||||
return NS_ERROR_ALREADY_INITIALIZED;
|
||||
}
|
||||
|
||||
@ -1999,8 +2005,11 @@ nsDocument::Init()
|
||||
// Assume we're not quirky, until we know otherwise
|
||||
mCSSLoader->SetCompatibilityMode(eCompatibility_FullStandards);
|
||||
|
||||
mStyleImageLoader = new mozilla::css::ImageLoader(this);
|
||||
NS_ADDREF(mStyleImageLoader);
|
||||
|
||||
mNodeInfoManager = new nsNodeInfoManager();
|
||||
nsresult rv = mNodeInfoManager->Init(this);
|
||||
nsresult rv = mNodeInfoManager->Init(this);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// mNodeInfo keeps NodeInfoManager alive!
|
||||
|
@ -288,7 +288,6 @@ NS_INTERFACE_MAP_END
|
||||
|
||||
nsFrameLoader::nsFrameLoader(Element* aOwner, bool aNetworkCreated)
|
||||
: mOwnerContent(aOwner)
|
||||
, mDetachedSubdocViews(nullptr)
|
||||
, mDepthTooGreat(false)
|
||||
, mIsTopLevelContent(false)
|
||||
, mDestroyCalled(false)
|
||||
@ -2378,18 +2377,3 @@ nsFrameLoader::SetRemoteBrowser(nsITabParent* aTabParent)
|
||||
ShowRemoteFrame(nsIntSize(0, 0));
|
||||
}
|
||||
|
||||
void
|
||||
nsFrameLoader::SetDetachedSubdocView(nsIView* aDetachedViews,
|
||||
nsIDocument* aContainerDoc)
|
||||
{
|
||||
mDetachedSubdocViews = aDetachedViews;
|
||||
mContainerDocWhileDetached = aContainerDoc;
|
||||
}
|
||||
|
||||
nsIView*
|
||||
nsFrameLoader::GetDetachedSubdocView(nsIDocument** aContainerDoc) const
|
||||
{
|
||||
NS_IF_ADDREF(*aContainerDoc = mContainerDocWhileDetached);
|
||||
return mDetachedSubdocViews;
|
||||
}
|
||||
|
||||
|
@ -268,25 +268,6 @@ public:
|
||||
*/
|
||||
void SetRemoteBrowser(nsITabParent* aTabParent);
|
||||
|
||||
/**
|
||||
* Stashes a detached view on the frame loader. We do this when we're
|
||||
* destroying the nsSubDocumentFrame. If the nsSubdocumentFrame is
|
||||
* being reframed we'll restore the detached view when it's recreated,
|
||||
* otherwise we'll discard the old presentation and set the detached
|
||||
* subdoc view to null. aContainerDoc is the document containing the
|
||||
* the subdoc frame. This enables us to detect when the containing
|
||||
* document has changed during reframe, so we can discard the presentation
|
||||
* in that case.
|
||||
*/
|
||||
void SetDetachedSubdocView(nsIView* aDetachedView,
|
||||
nsIDocument* aContainerDoc);
|
||||
|
||||
/**
|
||||
* Retrieves the detached view and the document containing the view,
|
||||
* as set by SetDetachedSubdocView().
|
||||
*/
|
||||
nsIView* GetDetachedSubdocView(nsIDocument** aContainerDoc) const;
|
||||
|
||||
private:
|
||||
|
||||
void SetOwnerContent(mozilla::dom::Element* aContent);
|
||||
@ -345,16 +326,6 @@ public:
|
||||
nsRefPtr<nsFrameMessageManager> mMessageManager;
|
||||
nsCOMPtr<nsIInProcessContentFrameMessageManager> mChildMessageManager;
|
||||
private:
|
||||
// Stores the root view of the subdocument while the subdocument is being
|
||||
// reframed. Used to restore the presentation after reframing.
|
||||
nsIView* mDetachedSubdocViews;
|
||||
// Stores the containing document of the frame corresponding to this
|
||||
// frame loader. This is reference is kept valid while the subframe's
|
||||
// presentation is detached and stored in mDetachedSubdocViews. This
|
||||
// enables us to detect whether the frame has moved documents during
|
||||
// a reframe, so that we know not to restore the presentation.
|
||||
nsCOMPtr<nsIDocument> mContainerDocWhileDetached;
|
||||
|
||||
bool mDepthTooGreat : 1;
|
||||
bool mIsTopLevelContent : 1;
|
||||
bool mDestroyCalled : 1;
|
||||
|
@ -35,6 +35,10 @@ public:
|
||||
}
|
||||
|
||||
// nsIContent overrides
|
||||
virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
||||
nsIContent* aBindingParent,
|
||||
bool aCompileEventHandlers);
|
||||
virtual void UnbindFromTree(bool aDeep, bool aNullParent);
|
||||
virtual nsEventStates IntrinsicState() const;
|
||||
|
||||
private:
|
||||
@ -44,8 +48,12 @@ public:
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
};
|
||||
|
||||
NS_IMPL_ISUPPORTS_INHERITED3(nsGenConImageContent, nsXMLElement,
|
||||
nsIImageLoadingContent, imgIContainerObserver, imgIDecoderObserver)
|
||||
NS_IMPL_ISUPPORTS_INHERITED4(nsGenConImageContent,
|
||||
nsXMLElement,
|
||||
nsIImageLoadingContent,
|
||||
imgIContainerObserver,
|
||||
imgIDecoderObserver,
|
||||
imgIOnloadBlocker)
|
||||
|
||||
nsresult
|
||||
NS_NewGenConImageContent(nsIContent** aResult, already_AddRefed<nsINodeInfo> aNodeInfo,
|
||||
@ -67,6 +75,28 @@ nsGenConImageContent::~nsGenConImageContent()
|
||||
DestroyImageLoadingContent();
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsGenConImageContent::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
||||
nsIContent* aBindingParent,
|
||||
bool aCompileEventHandlers)
|
||||
{
|
||||
nsresult rv;
|
||||
rv = nsXMLElement::BindToTree(aDocument, aParent, aBindingParent,
|
||||
aCompileEventHandlers);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsImageLoadingContent::BindToTree(aDocument, aParent, aBindingParent,
|
||||
aCompileEventHandlers);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
nsGenConImageContent::UnbindFromTree(bool aDeep, bool aNullParent)
|
||||
{
|
||||
nsImageLoadingContent::UnbindFromTree(aDeep, aNullParent);
|
||||
nsXMLElement::UnbindFromTree(aDeep, aNullParent);
|
||||
}
|
||||
|
||||
nsEventStates
|
||||
nsGenConImageContent::IntrinsicState() const
|
||||
{
|
||||
|
@ -1883,13 +1883,7 @@ nsGenericElement::MaybeCheckSameAttrVal(PRInt32 aNamespaceID,
|
||||
}
|
||||
bool valueMatches = aValue.EqualsAsStrings(*info.mValue);
|
||||
if (valueMatches && aPrefix == info.mName->GetPrefix()) {
|
||||
if (OwnerDoc()->MayHaveDOMMutationObservers()) {
|
||||
// For backward compatibility, don't fire mutation events
|
||||
// when setting an attribute to its old value.
|
||||
*aHasListeners = false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
modification = true;
|
||||
}
|
||||
@ -1920,8 +1914,8 @@ nsGenericElement::SetAttr(PRInt32 aNamespaceID, nsIAtom* aName,
|
||||
nsAttrValueOrString value(aValue);
|
||||
nsAttrValue oldValue;
|
||||
|
||||
if (MaybeCheckSameAttrVal(aNamespaceID, aName, aPrefix, value, aNotify,
|
||||
oldValue, &modType, &hasListeners)) {
|
||||
if (OnlyNotifySameValueSet(aNamespaceID, aName, aPrefix, value, aNotify,
|
||||
oldValue, &modType, &hasListeners)) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -1967,8 +1961,8 @@ nsGenericElement::SetParsedAttr(PRInt32 aNamespaceID, nsIAtom* aName,
|
||||
nsAttrValueOrString value(aParsedValue);
|
||||
nsAttrValue oldValue;
|
||||
|
||||
if (MaybeCheckSameAttrVal(aNamespaceID, aName, aPrefix, value, aNotify,
|
||||
oldValue, &modType, &hasListeners)) {
|
||||
if (OnlyNotifySameValueSet(aNamespaceID, aName, aPrefix, value, aNotify,
|
||||
oldValue, &modType, &hasListeners)) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -36,7 +36,7 @@
|
||||
#include "nsIInlineEventHandlers.h"
|
||||
#include "mozilla/CORSMode.h"
|
||||
#include "mozilla/Attributes.h"
|
||||
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsISMILAttr.h"
|
||||
|
||||
class nsIDOMAttr;
|
||||
@ -102,6 +102,22 @@ public:
|
||||
const nsAttrValueOrString& aValue,
|
||||
bool aNotify, nsAttrValue& aOldValue,
|
||||
PRUint8* aModType, bool* aHasListeners);
|
||||
|
||||
bool OnlyNotifySameValueSet(PRInt32 aNamespaceID, nsIAtom* aName,
|
||||
nsIAtom* aPrefix,
|
||||
const nsAttrValueOrString& aValue,
|
||||
bool aNotify, nsAttrValue& aOldValue,
|
||||
PRUint8* aModType, bool* aHasListeners)
|
||||
{
|
||||
if (MaybeCheckSameAttrVal(aNamespaceID, aName, aPrefix, aValue, aNotify,
|
||||
aOldValue, aModType, aHasListeners)) {
|
||||
nsAutoScriptBlocker scriptBlocker;
|
||||
nsNodeUtils::AttributeSetToCurrentValue(this, aNamespaceID, aName);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual nsresult SetAttr(PRInt32 aNameSpaceID, nsIAtom* aName, nsIAtom* aPrefix,
|
||||
const nsAString& aValue, bool aNotify);
|
||||
virtual nsresult SetParsedAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
|
||||
|
@ -72,7 +72,9 @@ static void PrintReqURL(imgIRequest* req) {
|
||||
|
||||
|
||||
nsImageLoadingContent::nsImageLoadingContent()
|
||||
: mObserverList(nullptr),
|
||||
: mCurrentRequestFlags(0),
|
||||
mPendingRequestFlags(0),
|
||||
mObserverList(nullptr),
|
||||
mImageBlockingStatus(nsIContentPolicy::ACCEPT),
|
||||
mLoadingEnabled(true),
|
||||
mIsImageStateForced(false),
|
||||
@ -81,10 +83,7 @@ nsImageLoadingContent::nsImageLoadingContent()
|
||||
mBroken(true),
|
||||
mUserDisabled(false),
|
||||
mSuppressed(false),
|
||||
mBlockingOnload(false),
|
||||
mNewRequestsWillNeedAnimationReset(false),
|
||||
mPendingRequestNeedsResetAnimation(false),
|
||||
mCurrentRequestNeedsResetAnimation(false),
|
||||
mStateChangerDepth(0),
|
||||
mCurrentRequestRegistered(false),
|
||||
mPendingRequestRegistered(false)
|
||||
@ -153,23 +152,6 @@ nsImageLoadingContent::OnStartDecode(imgIRequest* aRequest)
|
||||
{
|
||||
NS_ENSURE_TRUE(nsContentUtils::IsCallerChrome(), NS_ERROR_NOT_AVAILABLE);
|
||||
|
||||
// Onload blocking. This only applies for the current request.
|
||||
if (aRequest == mCurrentRequest) {
|
||||
|
||||
// Determine whether this is a background request (this can be the case
|
||||
// with multipart/x-mixed-replace images, for example).
|
||||
PRUint32 loadFlags;
|
||||
nsresult rv = aRequest->GetLoadFlags(&loadFlags);
|
||||
bool background =
|
||||
(NS_SUCCEEDED(rv) && (loadFlags & nsIRequest::LOAD_BACKGROUND));
|
||||
|
||||
// Block onload for non-background requests
|
||||
if (!background) {
|
||||
NS_ABORT_IF_FALSE(!mBlockingOnload, "Shouldn't already be blocking");
|
||||
SetBlockingOnload(true);
|
||||
}
|
||||
}
|
||||
|
||||
LOOP_OVER_OBSERVERS(OnStartDecode(aRequest));
|
||||
return NS_OK;
|
||||
}
|
||||
@ -215,10 +197,6 @@ nsImageLoadingContent::OnStopFrame(imgIRequest* aRequest,
|
||||
{
|
||||
NS_ENSURE_TRUE(nsContentUtils::IsCallerChrome(), NS_ERROR_NOT_AVAILABLE);
|
||||
|
||||
// If we're blocking a load, one frame is enough
|
||||
if (aRequest == mCurrentRequest)
|
||||
SetBlockingOnload(false);
|
||||
|
||||
LOOP_OVER_OBSERVERS(OnStopFrame(aRequest, aFrame));
|
||||
return NS_OK;
|
||||
}
|
||||
@ -229,15 +207,6 @@ nsImageLoadingContent::OnStopContainer(imgIRequest* aRequest,
|
||||
{
|
||||
NS_ENSURE_TRUE(nsContentUtils::IsCallerChrome(), NS_ERROR_NOT_AVAILABLE);
|
||||
|
||||
// This is really hacky. We need to handle the case where we start decoding,
|
||||
// block onload, but then hit an error before we get to our first frame. In
|
||||
// theory we would just hook in at OnStopDecode, but OnStopDecode is broken
|
||||
// until we fix bug 505385. OnStopContainer is actually going away at that
|
||||
// point. So for now we take advantage of the fact that OnStopContainer is
|
||||
// always fired in the decoders at the same time as OnStopDecode.
|
||||
if (aRequest == mCurrentRequest)
|
||||
SetBlockingOnload(false);
|
||||
|
||||
LOOP_OVER_OBSERVERS(OnStopContainer(aRequest, aContainer));
|
||||
return NS_OK;
|
||||
}
|
||||
@ -292,7 +261,9 @@ nsImageLoadingContent::OnStopDecode(imgIRequest* aRequest,
|
||||
// initial paint delay (for example, being in the bfcache), but we probably
|
||||
// aren't loading images in those situations.
|
||||
|
||||
nsIDocument* doc = GetOurDocument();
|
||||
// XXXkhuey should this be GetOurCurrentDoc? Decoding if we're not in
|
||||
// the document seems silly.
|
||||
nsIDocument* doc = GetOurOwnerDoc();
|
||||
nsIPresShell* shell = doc ? doc->GetShell() : nullptr;
|
||||
if (shell && shell->IsVisible() &&
|
||||
(!shell->DidInitialReflow() || shell->IsPaintingSuppressed())) {
|
||||
@ -307,7 +278,7 @@ nsImageLoadingContent::OnStopDecode(imgIRequest* aRequest,
|
||||
FireEvent(NS_LITERAL_STRING("error"));
|
||||
}
|
||||
|
||||
nsCOMPtr<nsINode> thisNode = do_QueryInterface(this);
|
||||
nsCOMPtr<nsINode> thisNode = do_QueryInterface(static_cast<nsIImageLoadingContent*>(this));
|
||||
nsSVGEffects::InvalidateDirectRenderingObservers(thisNode->AsElement());
|
||||
|
||||
return NS_OK;
|
||||
@ -551,7 +522,7 @@ nsImageLoadingContent::LoadImageWithChannel(nsIChannel* aChannel,
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDocument> doc = GetOurDocument();
|
||||
nsCOMPtr<nsIDocument> doc = GetOurOwnerDoc();
|
||||
if (!doc) {
|
||||
// Don't bother
|
||||
return NS_OK;
|
||||
@ -596,33 +567,47 @@ NS_IMETHODIMP nsImageLoadingContent::ForceReload()
|
||||
return LoadImage(currentURI, true, true, nullptr, nsIRequest::VALIDATE_ALWAYS);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsImageLoadingContent::BlockOnload(imgIRequest* aRequest)
|
||||
{
|
||||
if (aRequest != mCurrentRequest) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsIDocument* doc = GetOurCurrentDoc();
|
||||
if (doc) {
|
||||
doc->BlockOnload();
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsImageLoadingContent::UnblockOnload(imgIRequest* aRequest)
|
||||
{
|
||||
if (aRequest != mCurrentRequest) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsIDocument* doc = GetOurCurrentDoc();
|
||||
if (doc) {
|
||||
doc->UnblockOnload(false);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* Non-interface methods
|
||||
*/
|
||||
|
||||
void
|
||||
nsImageLoadingContent::NotifyOwnerDocumentChanged(nsIDocument *aOldDoc)
|
||||
{
|
||||
// If we had a document before, unregister ourselves with it.
|
||||
if (aOldDoc) {
|
||||
if (mCurrentRequest)
|
||||
aOldDoc->RemoveImage(mCurrentRequest);
|
||||
if (mPendingRequest)
|
||||
aOldDoc->RemoveImage(mPendingRequest);
|
||||
}
|
||||
|
||||
// Re-track the images
|
||||
TrackImage(mCurrentRequest);
|
||||
TrackImage(mPendingRequest);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsImageLoadingContent::LoadImage(const nsAString& aNewURI,
|
||||
bool aForce,
|
||||
bool aNotify)
|
||||
{
|
||||
// First, get a document (needed for security checks and the like)
|
||||
nsIDocument* doc = GetOurDocument();
|
||||
nsIDocument* doc = GetOurOwnerDoc();
|
||||
if (!doc) {
|
||||
// No reason to bother, I think...
|
||||
return NS_OK;
|
||||
@ -670,11 +655,11 @@ nsImageLoadingContent::LoadImage(nsIURI* aNewURI,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_ASSERTION(!aDocument || aDocument == GetOurDocument(),
|
||||
NS_ASSERTION(!aDocument || aDocument == GetOurOwnerDoc(),
|
||||
"Bogus document passed in");
|
||||
// First, get a document (needed for security checks and the like)
|
||||
if (!aDocument) {
|
||||
aDocument = GetOurDocument();
|
||||
aDocument = GetOurOwnerDoc();
|
||||
if (!aDocument) {
|
||||
// No reason to bother, I think...
|
||||
return NS_OK;
|
||||
@ -705,7 +690,7 @@ nsImageLoadingContent::LoadImage(nsIURI* aNewURI,
|
||||
// We use the principal of aDocument to avoid having to QI |this| an extra
|
||||
// time. It should always be the same as the principal of this node.
|
||||
#ifdef DEBUG
|
||||
nsCOMPtr<nsIContent> thisContent = do_QueryInterface(this);
|
||||
nsCOMPtr<nsIContent> thisContent = do_QueryInterface(static_cast<nsIImageLoadingContent*>(this));
|
||||
NS_ABORT_IF_FALSE(thisContent &&
|
||||
thisContent->NodePrincipal() == aDocument->NodePrincipal(),
|
||||
"Principal mismatch?");
|
||||
@ -713,8 +698,11 @@ nsImageLoadingContent::LoadImage(nsIURI* aNewURI,
|
||||
|
||||
// Are we blocked?
|
||||
PRInt16 cpDecision = nsIContentPolicy::REJECT_REQUEST;
|
||||
nsContentUtils::CanLoadImage(aNewURI, this, aDocument,
|
||||
aDocument->NodePrincipal(), &cpDecision);
|
||||
nsContentUtils::CanLoadImage(aNewURI,
|
||||
static_cast<nsIImageLoadingContent*>(this),
|
||||
aDocument,
|
||||
aDocument->NodePrincipal(),
|
||||
&cpDecision);
|
||||
if (!NS_CP_ACCEPTED(cpDecision)) {
|
||||
FireEvent(NS_LITERAL_STRING("error"));
|
||||
SetBlockedRequest(aNewURI, cpDecision);
|
||||
@ -820,7 +808,7 @@ nsImageLoadingContent::UpdateImageState(bool aNotify)
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIContent> thisContent = do_QueryInterface(this);
|
||||
nsCOMPtr<nsIContent> thisContent = do_QueryInterface(static_cast<nsIImageLoadingContent*>(this));
|
||||
if (!thisContent) {
|
||||
return;
|
||||
}
|
||||
@ -882,18 +870,30 @@ nsImageLoadingContent::UseAsPrimaryRequest(imgIRequest* aRequest,
|
||||
}
|
||||
|
||||
nsIDocument*
|
||||
nsImageLoadingContent::GetOurDocument()
|
||||
nsImageLoadingContent::GetOurOwnerDoc()
|
||||
{
|
||||
nsCOMPtr<nsIContent> thisContent = do_QueryInterface(this);
|
||||
nsCOMPtr<nsIContent> thisContent =
|
||||
do_QueryInterface(static_cast<nsIImageLoadingContent*>(this));
|
||||
NS_ENSURE_TRUE(thisContent, nullptr);
|
||||
|
||||
return thisContent->OwnerDoc();
|
||||
}
|
||||
|
||||
nsIDocument*
|
||||
nsImageLoadingContent::GetOurCurrentDoc()
|
||||
{
|
||||
nsCOMPtr<nsIContent> thisContent =
|
||||
do_QueryInterface(static_cast<nsIImageLoadingContent*>(this));
|
||||
NS_ENSURE_TRUE(thisContent, nullptr);
|
||||
|
||||
return thisContent->GetCurrentDoc();
|
||||
}
|
||||
|
||||
nsIFrame*
|
||||
nsImageLoadingContent::GetOurPrimaryFrame()
|
||||
{
|
||||
nsCOMPtr<nsIContent> thisContent = do_QueryInterface(this);
|
||||
nsCOMPtr<nsIContent> thisContent =
|
||||
do_QueryInterface(static_cast<nsIImageLoadingContent*>(this));
|
||||
return thisContent->GetPrimaryFrame();
|
||||
}
|
||||
|
||||
@ -916,7 +916,7 @@ nsImageLoadingContent::StringToURI(const nsAString& aSpec,
|
||||
NS_PRECONDITION(aURI, "Null out param");
|
||||
|
||||
// (1) Get the base URI
|
||||
nsCOMPtr<nsIContent> thisContent = do_QueryInterface(this);
|
||||
nsCOMPtr<nsIContent> thisContent = do_QueryInterface(static_cast<nsIImageLoadingContent*>(this));
|
||||
NS_ASSERTION(thisContent, "An image loading content must be an nsIContent");
|
||||
nsCOMPtr<nsIURI> baseURL = thisContent->GetBaseURI();
|
||||
|
||||
@ -938,7 +938,7 @@ nsImageLoadingContent::FireEvent(const nsAString& aEventType)
|
||||
// loops in cases when onLoad handlers reset the src and the new src is in
|
||||
// cache.
|
||||
|
||||
nsCOMPtr<nsINode> thisNode = do_QueryInterface(this);
|
||||
nsCOMPtr<nsINode> thisNode = do_QueryInterface(static_cast<nsIImageLoadingContent*>(this));
|
||||
|
||||
nsRefPtr<nsAsyncDOMEvent> event =
|
||||
new nsLoadBlockingAsyncDOMEvent(thisNode, aEventType, false, false);
|
||||
@ -996,7 +996,9 @@ nsImageLoadingContent::PrepareCurrentRequest()
|
||||
// Get rid of anything that was there previously.
|
||||
ClearCurrentRequest(NS_ERROR_IMAGE_SRC_CHANGED);
|
||||
|
||||
mCurrentRequestNeedsResetAnimation = mNewRequestsWillNeedAnimationReset;
|
||||
if (mNewRequestsWillNeedAnimationReset) {
|
||||
mCurrentRequestFlags |= REQUEST_NEEDS_ANIMATION_RESET;
|
||||
}
|
||||
|
||||
// Return a reference.
|
||||
return mCurrentRequest;
|
||||
@ -1008,7 +1010,9 @@ nsImageLoadingContent::PreparePendingRequest()
|
||||
// Get rid of anything that was there previously.
|
||||
ClearPendingRequest(NS_ERROR_IMAGE_SRC_CHANGED);
|
||||
|
||||
mPendingRequestNeedsResetAnimation = mNewRequestsWillNeedAnimationReset;
|
||||
if (mNewRequestsWillNeedAnimationReset) {
|
||||
mPendingRequestFlags |= REQUEST_NEEDS_ANIMATION_RESET;
|
||||
}
|
||||
|
||||
// Return a reference.
|
||||
return mPendingRequest;
|
||||
@ -1054,8 +1058,8 @@ nsImageLoadingContent::MakePendingRequestCurrent()
|
||||
|
||||
PrepareCurrentRequest() = mPendingRequest;
|
||||
mPendingRequest = nullptr;
|
||||
mCurrentRequestNeedsResetAnimation = mPendingRequestNeedsResetAnimation;
|
||||
mPendingRequestNeedsResetAnimation = false;
|
||||
mCurrentRequestFlags = mPendingRequestFlags;
|
||||
mPendingRequestFlags = 0;
|
||||
ResetAnimationIfNeeded();
|
||||
}
|
||||
|
||||
@ -1080,11 +1084,7 @@ nsImageLoadingContent::ClearCurrentRequest(nsresult aReason)
|
||||
UntrackImage(mCurrentRequest);
|
||||
mCurrentRequest->CancelAndForgetObserver(aReason);
|
||||
mCurrentRequest = nullptr;
|
||||
mCurrentRequestNeedsResetAnimation = false;
|
||||
|
||||
// We only block onload during the decoding of "current" images. This one is
|
||||
// going away, so we should unblock unconditionally here.
|
||||
SetBlockingOnload(false);
|
||||
mCurrentRequestFlags = 0;
|
||||
}
|
||||
|
||||
void
|
||||
@ -1107,7 +1107,7 @@ nsImageLoadingContent::ClearPendingRequest(nsresult aReason)
|
||||
UntrackImage(mPendingRequest);
|
||||
mPendingRequest->CancelAndForgetObserver(aReason);
|
||||
mPendingRequest = nullptr;
|
||||
mPendingRequestNeedsResetAnimation = false;
|
||||
mPendingRequestFlags = 0;
|
||||
}
|
||||
|
||||
bool*
|
||||
@ -1125,12 +1125,13 @@ nsImageLoadingContent::GetRegisteredFlagForRequest(imgIRequest* aRequest)
|
||||
void
|
||||
nsImageLoadingContent::ResetAnimationIfNeeded()
|
||||
{
|
||||
if (mCurrentRequest && mCurrentRequestNeedsResetAnimation) {
|
||||
if (mCurrentRequest &&
|
||||
(mCurrentRequestFlags & REQUEST_NEEDS_ANIMATION_RESET)) {
|
||||
nsCOMPtr<imgIContainer> container;
|
||||
mCurrentRequest->GetImage(getter_AddRefs(container));
|
||||
if (container)
|
||||
container->ResetAnimation();
|
||||
mCurrentRequestNeedsResetAnimation = false;
|
||||
mCurrentRequestFlags &= ~REQUEST_NEEDS_ANIMATION_RESET;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1148,25 +1149,33 @@ nsImageLoadingContent::HaveSize(imgIRequest *aImage)
|
||||
}
|
||||
|
||||
void
|
||||
nsImageLoadingContent::SetBlockingOnload(bool aBlocking)
|
||||
nsImageLoadingContent::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
||||
nsIContent* aBindingParent,
|
||||
bool aCompileEventHandlers)
|
||||
{
|
||||
// If we're already in the desired state, we have nothing to do
|
||||
if (mBlockingOnload == aBlocking)
|
||||
// We may be entering the document, so if our image should be tracked,
|
||||
// track it.
|
||||
if (!aDocument)
|
||||
return;
|
||||
|
||||
// Get the document
|
||||
nsIDocument* doc = GetOurDocument();
|
||||
if (mCurrentRequestFlags & REQUEST_SHOULD_BE_TRACKED)
|
||||
aDocument->AddImage(mCurrentRequest);
|
||||
if (mPendingRequestFlags & REQUEST_SHOULD_BE_TRACKED)
|
||||
aDocument->AddImage(mPendingRequest);
|
||||
}
|
||||
|
||||
if (doc) {
|
||||
// Take the appropriate action
|
||||
if (aBlocking)
|
||||
doc->BlockOnload();
|
||||
else
|
||||
doc->UnblockOnload(false);
|
||||
void
|
||||
nsImageLoadingContent::UnbindFromTree(bool aDeep, bool aNullParent)
|
||||
{
|
||||
// We may be leaving the document, so if our image is tracked, untrack it.
|
||||
nsCOMPtr<nsIDocument> doc = GetOurCurrentDoc();
|
||||
if (!doc)
|
||||
return;
|
||||
|
||||
// Update our state
|
||||
mBlockingOnload = aBlocking;
|
||||
}
|
||||
if (mCurrentRequestFlags & REQUEST_SHOULD_BE_TRACKED)
|
||||
doc->RemoveImage(mCurrentRequest);
|
||||
if (mPendingRequestFlags & REQUEST_SHOULD_BE_TRACKED)
|
||||
doc->RemoveImage(mPendingRequest);
|
||||
}
|
||||
|
||||
nsresult
|
||||
@ -1175,7 +1184,15 @@ nsImageLoadingContent::TrackImage(imgIRequest* aImage)
|
||||
if (!aImage)
|
||||
return NS_OK;
|
||||
|
||||
nsIDocument* doc = GetOurDocument();
|
||||
MOZ_ASSERT(aImage == mCurrentRequest || aImage == mPendingRequest,
|
||||
"Why haven't we heard of this request?");
|
||||
if (aImage == mCurrentRequest) {
|
||||
mCurrentRequestFlags |= REQUEST_SHOULD_BE_TRACKED;
|
||||
} else {
|
||||
mPendingRequestFlags |= REQUEST_SHOULD_BE_TRACKED;
|
||||
}
|
||||
|
||||
nsIDocument* doc = GetOurCurrentDoc();
|
||||
if (doc)
|
||||
return doc->AddImage(aImage);
|
||||
return NS_OK;
|
||||
@ -1187,10 +1204,18 @@ nsImageLoadingContent::UntrackImage(imgIRequest* aImage)
|
||||
if (!aImage)
|
||||
return NS_OK;
|
||||
|
||||
MOZ_ASSERT(aImage == mCurrentRequest || aImage == mPendingRequest,
|
||||
"Why haven't we heard of this request?");
|
||||
if (aImage == mCurrentRequest) {
|
||||
mCurrentRequestFlags &= ~REQUEST_SHOULD_BE_TRACKED;
|
||||
} else {
|
||||
mPendingRequestFlags &= ~REQUEST_SHOULD_BE_TRACKED;
|
||||
}
|
||||
|
||||
// If GetOurDocument() returns null here, we've outlived our document.
|
||||
// That's fine, because the document empties out the tracker and unlocks
|
||||
// all locked images on destruction.
|
||||
nsIDocument* doc = GetOurDocument();
|
||||
nsIDocument* doc = GetOurCurrentDoc();
|
||||
if (doc)
|
||||
return doc->RemoveImage(aImage);
|
||||
return NS_OK;
|
||||
|
@ -15,6 +15,7 @@
|
||||
|
||||
#include "imgIContainerObserver.h"
|
||||
#include "imgIDecoderObserver.h"
|
||||
#include "imgIOnloadBlocker.h"
|
||||
#include "mozilla/CORSMode.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsContentUtils.h" // NS_CONTENT_DELETE_LIST_MEMBER
|
||||
@ -27,7 +28,8 @@ class nsIDocument;
|
||||
class imgILoader;
|
||||
class nsIIOService;
|
||||
|
||||
class nsImageLoadingContent : public nsIImageLoadingContent
|
||||
class nsImageLoadingContent : public nsIImageLoadingContent,
|
||||
public imgIOnloadBlocker
|
||||
{
|
||||
/* METHODS */
|
||||
public:
|
||||
@ -37,6 +39,7 @@ public:
|
||||
NS_DECL_IMGICONTAINEROBSERVER
|
||||
NS_DECL_IMGIDECODEROBSERVER
|
||||
NS_DECL_NSIIMAGELOADINGCONTENT
|
||||
NS_DECL_IMGIONLOADBLOCKER
|
||||
|
||||
protected:
|
||||
/**
|
||||
@ -87,13 +90,14 @@ protected:
|
||||
nsLoadFlags aLoadFlags = nsIRequest::LOAD_NORMAL);
|
||||
|
||||
/**
|
||||
* helper to get the document for this content (from the nodeinfo
|
||||
* and such). Not named GetDocument to prevent ambiguous method
|
||||
* names in subclasses
|
||||
* helpers to get the document for this content (from the nodeinfo
|
||||
* and such). Not named GetOwnerDoc/GetCurrentDoc to prevent ambiguous
|
||||
* method names in subclasses
|
||||
*
|
||||
* @return the document we belong to
|
||||
*/
|
||||
nsIDocument* GetOurDocument();
|
||||
nsIDocument* GetOurOwnerDoc();
|
||||
nsIDocument* GetOurCurrentDoc();
|
||||
|
||||
/**
|
||||
* Helper function to get the frame associated with this content. Not named
|
||||
@ -152,6 +156,11 @@ protected:
|
||||
*/
|
||||
virtual mozilla::CORSMode GetCORSMode();
|
||||
|
||||
// Subclasses are *required* to call BindToTree/UnbindFromTree.
|
||||
void BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
||||
nsIContent* aBindingParent, bool aCompileEventHandlers);
|
||||
void UnbindFromTree(bool aDeep, bool aNullParent);
|
||||
|
||||
private:
|
||||
/**
|
||||
* Struct used to manage the image observers.
|
||||
@ -308,6 +317,16 @@ protected:
|
||||
/* MEMBERS */
|
||||
nsCOMPtr<imgIRequest> mCurrentRequest;
|
||||
nsCOMPtr<imgIRequest> mPendingRequest;
|
||||
PRUint32 mCurrentRequestFlags;
|
||||
PRUint32 mPendingRequestFlags;
|
||||
|
||||
enum {
|
||||
// Set if the request needs
|
||||
REQUEST_NEEDS_ANIMATION_RESET = 0x00000001U,
|
||||
// Set if the request should be tracked. This is true if the request is
|
||||
// not tracked iff this node is not in the document.
|
||||
REQUEST_SHOULD_BE_TRACKED = 0x00000002U
|
||||
};
|
||||
|
||||
// If the image was blocked or if there was an error loading, it's nice to
|
||||
// still keep track of what the URI was despite not having an imgIRequest.
|
||||
@ -349,11 +368,6 @@ private:
|
||||
bool mUserDisabled : 1;
|
||||
bool mSuppressed : 1;
|
||||
|
||||
/**
|
||||
* Whether we're currently blocking document load.
|
||||
*/
|
||||
bool mBlockingOnload : 1;
|
||||
|
||||
protected:
|
||||
/**
|
||||
* A hack to get animations to reset, see bug 594771. On requests
|
||||
@ -366,9 +380,6 @@ protected:
|
||||
bool mNewRequestsWillNeedAnimationReset : 1;
|
||||
|
||||
private:
|
||||
bool mPendingRequestNeedsResetAnimation : 1;
|
||||
bool mCurrentRequestNeedsResetAnimation : 1;
|
||||
|
||||
/* The number of nested AutoStateChangers currently tracking our state. */
|
||||
PRUint8 mStateChangerDepth;
|
||||
|
||||
|
@ -28,7 +28,6 @@
|
||||
#ifdef MOZ_MEDIA
|
||||
#include "nsHTMLMediaElement.h"
|
||||
#endif // MOZ_MEDIA
|
||||
#include "nsImageLoadingContent.h"
|
||||
#include "jsgc.h"
|
||||
#include "nsWrapperCacheInlines.h"
|
||||
#include "nsObjectLoadingContent.h"
|
||||
@ -108,6 +107,16 @@ nsNodeUtils::AttributeChanged(Element* aElement,
|
||||
aModType));
|
||||
}
|
||||
|
||||
void
|
||||
nsNodeUtils::AttributeSetToCurrentValue(Element* aElement,
|
||||
PRInt32 aNameSpaceID,
|
||||
nsIAtom* aAttribute)
|
||||
{
|
||||
nsIDocument* doc = aElement->OwnerDoc();
|
||||
IMPL_MUTATION_NOTIFICATION(AttributeSetToCurrentValue, aElement,
|
||||
(doc, aElement, aNameSpaceID, aAttribute));
|
||||
}
|
||||
|
||||
void
|
||||
nsNodeUtils::ContentAppended(nsIContent* aContainer,
|
||||
nsIContent* aFirstNewContent,
|
||||
@ -511,16 +520,9 @@ nsNodeUtils::CloneAndAdopt(nsINode *aNode, bool aClone, bool aDeep,
|
||||
olc->NotifyOwnerDocumentActivityChanged();
|
||||
}
|
||||
}
|
||||
|
||||
// nsImageLoadingContent needs to know when its document changes
|
||||
if (oldDoc != newDoc) {
|
||||
nsCOMPtr<nsIImageLoadingContent> imageContent(do_QueryInterface(aNode));
|
||||
if (imageContent) {
|
||||
imageContent->NotifyOwnerDocumentChanged(oldDoc);
|
||||
}
|
||||
if (oldDoc->MayHaveDOMMutationObservers()) {
|
||||
newDoc->SetMayHaveDOMMutationObservers();
|
||||
}
|
||||
|
||||
if (oldDoc != newDoc && oldDoc->MayHaveDOMMutationObservers()) {
|
||||
newDoc->SetMayHaveDOMMutationObservers();
|
||||
}
|
||||
|
||||
if (elem) {
|
||||
|
@ -64,6 +64,16 @@ public:
|
||||
PRInt32 aNameSpaceID,
|
||||
nsIAtom* aAttribute,
|
||||
PRInt32 aModType);
|
||||
/**
|
||||
* Send AttributeSetToCurrentValue notifications to nsIMutationObservers.
|
||||
* @param aElement Element whose data changed
|
||||
* @param aNameSpaceID Namespace of the attribute
|
||||
* @param aAttribute Local-name of the attribute
|
||||
* @see nsIMutationObserver::AttributeSetToCurrentValue
|
||||
*/
|
||||
static void AttributeSetToCurrentValue(mozilla::dom::Element* aElement,
|
||||
PRInt32 aNameSpaceID,
|
||||
nsIAtom* aAttribute);
|
||||
|
||||
/**
|
||||
* Send ContentAppended notifications to nsIMutationObservers
|
||||
|
@ -605,10 +605,13 @@ nsObjectLoadingContent::IsSupportedDocument(const nsCString& aMimeType)
|
||||
|
||||
nsresult
|
||||
nsObjectLoadingContent::BindToTree(nsIDocument* aDocument,
|
||||
nsIContent* /*aParent*/,
|
||||
nsIContent* /*aBindingParent*/,
|
||||
bool /*aCompileEventHandlers*/)
|
||||
nsIContent* aParent,
|
||||
nsIContent* aBindingParent,
|
||||
bool aCompileEventHandlers)
|
||||
{
|
||||
nsImageLoadingContent::BindToTree(aDocument, aParent, aBindingParent,
|
||||
aCompileEventHandlers);
|
||||
|
||||
if (aDocument) {
|
||||
return aDocument->AddPlugin(this);
|
||||
}
|
||||
@ -616,8 +619,10 @@ nsObjectLoadingContent::BindToTree(nsIDocument* aDocument,
|
||||
}
|
||||
|
||||
void
|
||||
nsObjectLoadingContent::UnbindFromTree(bool /*aDeep*/, bool /*aNullParent*/)
|
||||
nsObjectLoadingContent::UnbindFromTree(bool aDeep, bool aNullParent)
|
||||
{
|
||||
nsImageLoadingContent::UnbindFromTree(aDeep, aNullParent);
|
||||
|
||||
nsCOMPtr<nsIContent> thisContent =
|
||||
do_QueryInterface(static_cast<nsIObjectLoadingContent*>(this));
|
||||
MOZ_ASSERT(thisContent);
|
||||
@ -635,7 +640,8 @@ nsObjectLoadingContent::UnbindFromTree(bool /*aDeep*/, bool /*aNullParent*/)
|
||||
if (appShell) {
|
||||
appShell->RunInStableState(event);
|
||||
}
|
||||
} else {
|
||||
} else if (mType != eType_Image) {
|
||||
// nsImageLoadingContent handles the image case.
|
||||
// Reset state and clear pending events
|
||||
/// XXX(johns): The implementation for GenericFrame notes that ideally we
|
||||
/// would keep the docshell around, but trash the frameloader
|
||||
|
@ -43,6 +43,7 @@ MOCHITEST_CHROME_FILES = \
|
||||
test_bug752226-3.xul \
|
||||
test_bug752226-4.xul \
|
||||
test_bug682305.html \
|
||||
test_bug780199.xul \
|
||||
$(NULL)
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
51
content/base/test/chrome/test_bug780199.xul
Normal file
51
content/base/test/chrome/test_bug780199.xul
Normal file
@ -0,0 +1,51 @@
|
||||
<?xml version="1.0"?>
|
||||
<?xml-stylesheet type="text/css" href="chrome://global/skin"?>
|
||||
<?xml-stylesheet type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"?>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=780199
|
||||
-->
|
||||
<window title="Mozilla Bug 780199"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
onload="test()">
|
||||
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
|
||||
|
||||
<!-- test results are displayed in the html:body -->
|
||||
<body xmlns="http://www.w3.org/1999/xhtml">
|
||||
<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=780199"
|
||||
target="_blank">Mozilla Bug 780199</a>
|
||||
</body>
|
||||
|
||||
<!-- test code goes here -->
|
||||
<script type="application/javascript">
|
||||
<![CDATA[
|
||||
|
||||
/** Test for Bug 780199 **/
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
var b;
|
||||
|
||||
function callback(r) {
|
||||
is(r[0].type, "attributes");
|
||||
is(r[0].oldValue, b.getAttribute("src"));
|
||||
setTimeout(continueTest, 500);
|
||||
}
|
||||
|
||||
function continueTest() {
|
||||
// Check that a new page wasn't loaded.
|
||||
is(b.contentDocument.documentElement.textContent, "testvalue");
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
function test() {
|
||||
b = document.getElementById("b");
|
||||
var m = MutationObserver(callback);
|
||||
m.observe(b, { attributes: true, attributeOldValue: true });
|
||||
b.contentDocument.documentElement.textContent = "testvalue";
|
||||
b.setAttribute("src", b.getAttribute("src"));
|
||||
}
|
||||
|
||||
]]>
|
||||
</script>
|
||||
<browser id="b" src="data:text/plain,initial"/>
|
||||
</window>
|
@ -89,12 +89,13 @@ DOMCI_NODE_DATA(HTMLImageElement, nsHTMLImageElement)
|
||||
|
||||
// QueryInterface implementation for nsHTMLImageElement
|
||||
NS_INTERFACE_TABLE_HEAD(nsHTMLImageElement)
|
||||
NS_HTML_CONTENT_INTERFACE_TABLE5(nsHTMLImageElement,
|
||||
NS_HTML_CONTENT_INTERFACE_TABLE6(nsHTMLImageElement,
|
||||
nsIDOMHTMLImageElement,
|
||||
nsIJSNativeInitializer,
|
||||
imgIDecoderObserver,
|
||||
nsIImageLoadingContent,
|
||||
imgIContainerObserver)
|
||||
imgIContainerObserver,
|
||||
imgIOnloadBlocker)
|
||||
NS_HTML_CONTENT_INTERFACE_TABLE_TO_MAP_SEGUE(nsHTMLImageElement,
|
||||
nsGenericHTMLElement)
|
||||
NS_HTML_CONTENT_INTERFACE_TABLE_TAIL_CLASSINFO(HTMLImageElement)
|
||||
@ -407,6 +408,9 @@ nsHTMLImageElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
||||
aCompileEventHandlers);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsImageLoadingContent::BindToTree(aDocument, aParent, aBindingParent,
|
||||
aCompileEventHandlers);
|
||||
|
||||
if (HasAttr(kNameSpaceID_None, nsGkAtoms::src)) {
|
||||
// FIXME: Bug 660963 it would be nice if we could just have
|
||||
// ClearBrokenState update our state and do it fast...
|
||||
@ -424,6 +428,13 @@ nsHTMLImageElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
||||
return rv;
|
||||
}
|
||||
|
||||
void
|
||||
nsHTMLImageElement::UnbindFromTree(bool aDeep, bool aNullParent)
|
||||
{
|
||||
nsImageLoadingContent::UnbindFromTree(aDeep, aNullParent);
|
||||
nsGenericHTMLElement::UnbindFromTree(aDeep, aNullParent);
|
||||
}
|
||||
|
||||
void
|
||||
nsHTMLImageElement::MaybeLoadImage()
|
||||
{
|
||||
|
@ -91,6 +91,7 @@ public:
|
||||
virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
||||
nsIContent* aBindingParent,
|
||||
bool aCompileEventHandlers);
|
||||
virtual void UnbindFromTree(bool aDeep, bool aNullParent);
|
||||
|
||||
virtual nsEventStates IntrinsicState() const;
|
||||
virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
|
||||
|
@ -615,13 +615,14 @@ DOMCI_NODE_DATA(HTMLInputElement, nsHTMLInputElement)
|
||||
|
||||
// QueryInterface implementation for nsHTMLInputElement
|
||||
NS_INTERFACE_TABLE_HEAD_CYCLE_COLLECTION_INHERITED(nsHTMLInputElement)
|
||||
NS_HTML_CONTENT_INTERFACE_TABLE8(nsHTMLInputElement,
|
||||
NS_HTML_CONTENT_INTERFACE_TABLE9(nsHTMLInputElement,
|
||||
nsIDOMHTMLInputElement,
|
||||
nsITextControlElement,
|
||||
nsIPhonetic,
|
||||
imgIDecoderObserver,
|
||||
nsIImageLoadingContent,
|
||||
imgIContainerObserver,
|
||||
imgIOnloadBlocker,
|
||||
nsIDOMNSEditableElement,
|
||||
nsIConstraintValidation)
|
||||
NS_HTML_CONTENT_INTERFACE_TABLE_TO_MAP_SEGUE(nsHTMLInputElement,
|
||||
@ -2494,6 +2495,9 @@ nsHTMLInputElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
||||
aCompileEventHandlers);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsImageLoadingContent::BindToTree(aDocument, aParent, aBindingParent,
|
||||
aCompileEventHandlers);
|
||||
|
||||
if (mType == NS_FORM_INPUT_IMAGE) {
|
||||
// Our base URI may have changed; claim that our URI changed, and the
|
||||
// nsImageLoadingContent will decide whether a new image load is warranted.
|
||||
@ -2540,6 +2544,7 @@ nsHTMLInputElement::UnbindFromTree(bool aDeep, bool aNullParent)
|
||||
WillRemoveFromRadioGroup();
|
||||
}
|
||||
|
||||
nsImageLoadingContent::UnbindFromTree(aDeep, aNullParent);
|
||||
nsGenericHTMLFormElement::UnbindFromTree(aDeep, aNullParent);
|
||||
|
||||
// GetCurrentDoc is returning nullptr so we can update the value
|
||||
|
@ -206,6 +206,7 @@ NS_INTERFACE_TABLE_HEAD_CYCLE_COLLECTION_INHERITED(nsHTMLObjectElement)
|
||||
NS_INTERFACE_TABLE_ENTRY(nsHTMLObjectElement, nsIFrameLoaderOwner)
|
||||
NS_INTERFACE_TABLE_ENTRY(nsHTMLObjectElement, nsIObjectLoadingContent)
|
||||
NS_INTERFACE_TABLE_ENTRY(nsHTMLObjectElement, nsIImageLoadingContent)
|
||||
NS_INTERFACE_TABLE_ENTRY(nsHTMLObjectElement, imgIOnloadBlocker)
|
||||
NS_INTERFACE_TABLE_ENTRY(nsHTMLObjectElement, imgIContainerObserver)
|
||||
NS_INTERFACE_TABLE_ENTRY(nsHTMLObjectElement, nsIInterfaceRequestor)
|
||||
NS_INTERFACE_TABLE_ENTRY(nsHTMLObjectElement, nsIChannelEventSink)
|
||||
|
@ -254,6 +254,7 @@ NS_INTERFACE_TABLE_HEAD_CYCLE_COLLECTION_INHERITED(nsHTMLSharedObjectElement)
|
||||
NS_INTERFACE_TABLE_ENTRY(nsHTMLSharedObjectElement, nsIObjectLoadingContent)
|
||||
NS_INTERFACE_TABLE_ENTRY(nsHTMLSharedObjectElement, imgIDecoderObserver)
|
||||
NS_INTERFACE_TABLE_ENTRY(nsHTMLSharedObjectElement, nsIImageLoadingContent)
|
||||
NS_INTERFACE_TABLE_ENTRY(nsHTMLSharedObjectElement, imgIOnloadBlocker)
|
||||
NS_INTERFACE_TABLE_ENTRY(nsHTMLSharedObjectElement, nsIInterfaceRequestor)
|
||||
NS_INTERFACE_TABLE_ENTRY(nsHTMLSharedObjectElement, nsIChannelEventSink)
|
||||
NS_OFFSET_AND_INTERFACE_TABLE_END
|
||||
|
@ -5494,11 +5494,12 @@ NS_IMPL_RELEASE_INHERITED(nsSVGFEImageElement,nsSVGFEImageElementBase)
|
||||
DOMCI_NODE_DATA(SVGFEImageElement, nsSVGFEImageElement)
|
||||
|
||||
NS_INTERFACE_TABLE_HEAD(nsSVGFEImageElement)
|
||||
NS_NODE_INTERFACE_TABLE8(nsSVGFEImageElement, nsIDOMNode, nsIDOMElement,
|
||||
NS_NODE_INTERFACE_TABLE9(nsSVGFEImageElement, nsIDOMNode, nsIDOMElement,
|
||||
nsIDOMSVGElement,
|
||||
nsIDOMSVGFilterPrimitiveStandardAttributes,
|
||||
nsIDOMSVGFEImageElement, nsIDOMSVGURIReference,
|
||||
imgIDecoderObserver, nsIImageLoadingContent)
|
||||
imgIDecoderObserver, nsIImageLoadingContent,
|
||||
imgIOnloadBlocker)
|
||||
NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(SVGFEImageElement)
|
||||
NS_INTERFACE_MAP_END_INHERITING(nsSVGFEImageElementBase)
|
||||
|
||||
@ -5608,6 +5609,9 @@ nsSVGFEImageElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
||||
aCompileEventHandlers);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsImageLoadingContent::BindToTree(aDocument, aParent, aBindingParent,
|
||||
aCompileEventHandlers);
|
||||
|
||||
if (mStringAttributes[HREF].IsExplicitlySet()) {
|
||||
// FIXME: Bug 660963 it would be nice if we could just have
|
||||
// ClearBrokenState update our state and do it fast...
|
||||
@ -5619,6 +5623,13 @@ nsSVGFEImageElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
void
|
||||
nsSVGFEImageElement::UnbindFromTree(bool aDeep, bool aNullParent)
|
||||
{
|
||||
nsImageLoadingContent::UnbindFromTree(aDeep, aNullParent);
|
||||
nsSVGFEImageElementBase::UnbindFromTree(aDeep, aNullParent);
|
||||
}
|
||||
|
||||
nsEventStates
|
||||
nsSVGFEImageElement::IntrinsicState() const
|
||||
|
@ -264,6 +264,7 @@ public:
|
||||
virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
||||
nsIContent* aBindingParent,
|
||||
bool aCompileEventHandlers);
|
||||
virtual void UnbindFromTree(bool aDeep, bool aNullParent);
|
||||
virtual nsEventStates IntrinsicState() const;
|
||||
|
||||
// imgIDecoderObserver
|
||||
|
@ -39,11 +39,11 @@ NS_IMPL_RELEASE_INHERITED(nsSVGImageElement,nsSVGImageElementBase)
|
||||
DOMCI_NODE_DATA(SVGImageElement, nsSVGImageElement)
|
||||
|
||||
NS_INTERFACE_TABLE_HEAD(nsSVGImageElement)
|
||||
NS_NODE_INTERFACE_TABLE8(nsSVGImageElement, nsIDOMNode, nsIDOMElement,
|
||||
NS_NODE_INTERFACE_TABLE9(nsSVGImageElement, nsIDOMNode, nsIDOMElement,
|
||||
nsIDOMSVGElement, nsIDOMSVGTests,
|
||||
nsIDOMSVGImageElement,
|
||||
nsIDOMSVGURIReference, imgIDecoderObserver,
|
||||
nsIImageLoadingContent)
|
||||
nsIImageLoadingContent, imgIOnloadBlocker)
|
||||
NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(SVGImageElement)
|
||||
NS_INTERFACE_MAP_END_INHERITING(nsSVGImageElementBase)
|
||||
|
||||
@ -183,6 +183,9 @@ nsSVGImageElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
||||
aCompileEventHandlers);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsImageLoadingContent::BindToTree(aDocument, aParent, aBindingParent,
|
||||
aCompileEventHandlers);
|
||||
|
||||
if (mStringAttributes[HREF].IsExplicitlySet()) {
|
||||
// FIXME: Bug 660963 it would be nice if we could just have
|
||||
// ClearBrokenState update our state and do it fast...
|
||||
@ -195,6 +198,13 @@ nsSVGImageElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
||||
return rv;
|
||||
}
|
||||
|
||||
void
|
||||
nsSVGImageElement::UnbindFromTree(bool aDeep, bool aNullParent)
|
||||
{
|
||||
nsImageLoadingContent::UnbindFromTree(aDeep, aNullParent);
|
||||
nsSVGImageElementBase::UnbindFromTree(aDeep, aNullParent);
|
||||
}
|
||||
|
||||
nsEventStates
|
||||
nsSVGImageElement::IntrinsicState() const
|
||||
{
|
||||
|
@ -49,6 +49,7 @@ public:
|
||||
virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
||||
nsIContent* aBindingParent,
|
||||
bool aCompileEventHandlers);
|
||||
virtual void UnbindFromTree(bool aDeep, bool aNullParent);
|
||||
|
||||
virtual nsEventStates IntrinsicState() const;
|
||||
|
||||
|
@ -23,6 +23,7 @@ XPIDLSRCS = \
|
||||
imgIDecoderObserver.idl \
|
||||
imgIEncoder.idl \
|
||||
imgILoader.idl \
|
||||
imgIOnloadBlocker.idl \
|
||||
imgIRequest.idl \
|
||||
imgITools.idl \
|
||||
$(NULL)
|
||||
|
64
image/public/imgIOnloadBlocker.idl
Normal file
64
image/public/imgIOnloadBlocker.idl
Normal file
@ -0,0 +1,64 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Mozilla Foundation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2012
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Kyle Huey <me@kylehuey.com> (original author)
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsISupports.idl"
|
||||
|
||||
interface imgIRequest;
|
||||
|
||||
[uuid(dc126d90-0ee0-4683-b942-2fa66e443abc)]
|
||||
interface imgIOnloadBlocker : nsISupports
|
||||
{
|
||||
/**
|
||||
* blockOnload
|
||||
* Called when it is appropriate to block onload for the given imgIRequest.
|
||||
*
|
||||
* @param aRequest
|
||||
* The request that should block onload.
|
||||
*/
|
||||
void blockOnload(in imgIRequest aRequest);
|
||||
|
||||
/**
|
||||
* unblockOnload
|
||||
* Called when it is appropriate to unblock onload for the given
|
||||
* imgIRequest.
|
||||
*
|
||||
* @param aRequest
|
||||
* The request that should unblock onload.
|
||||
*/
|
||||
void unblockOnload(in imgIRequest aRequest);
|
||||
};
|
@ -55,7 +55,6 @@ static PRLogModuleInfo *gCompressedImageAccountingLog = PR_NewLogModule ("Compre
|
||||
static bool gInitializedPrefCaches = false;
|
||||
static PRUint32 gDecodeBytesAtATime = 0;
|
||||
static PRUint32 gMaxMSBeforeYield = 0;
|
||||
static PRUint32 gMaxBytesForSyncDecode = 0;
|
||||
|
||||
static void
|
||||
InitPrefCaches()
|
||||
@ -64,8 +63,6 @@ InitPrefCaches()
|
||||
"image.mem.decode_bytes_at_a_time", 200000);
|
||||
Preferences::AddUintVarCache(&gMaxMSBeforeYield,
|
||||
"image.mem.max_ms_before_yield", 400);
|
||||
Preferences::AddUintVarCache(&gMaxBytesForSyncDecode,
|
||||
"image.mem.max_bytes_for_sync_decode", 150000);
|
||||
gInitializedPrefCaches = true;
|
||||
}
|
||||
|
||||
@ -480,18 +477,8 @@ RasterImage::ExtractFrame(PRUint32 aWhichFrame,
|
||||
img->mHasBeenDecoded = true;
|
||||
img->mFrameDecodeFlags = aFlags & DECODE_FLAGS_MASK;
|
||||
|
||||
if (img->mFrameDecodeFlags != mFrameDecodeFlags) {
|
||||
// if we can't discard, then we're screwed; we have no way
|
||||
// to re-decode. Similarly if we aren't allowed to do a sync
|
||||
// decode.
|
||||
if (!(aFlags & FLAG_SYNC_DECODE))
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
if (!CanForciblyDiscard() || mDecoder || mAnim)
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
ForceDiscard();
|
||||
|
||||
mFrameDecodeFlags = img->mFrameDecodeFlags;
|
||||
}
|
||||
if (!ApplyDecodeFlags(aFlags))
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
|
||||
// If a synchronous decode was requested, do it
|
||||
if (aFlags & FLAG_SYNC_DECODE) {
|
||||
@ -768,19 +755,8 @@ RasterImage::CopyFrame(PRUint32 aWhichFrame,
|
||||
|
||||
nsresult rv;
|
||||
|
||||
PRUint32 desiredDecodeFlags = aFlags & DECODE_FLAGS_MASK;
|
||||
if (desiredDecodeFlags != mFrameDecodeFlags) {
|
||||
// if we can't discard, then we're screwed; we have no way
|
||||
// to re-decode. Similarly if we aren't allowed to do a sync
|
||||
// decode.
|
||||
if (!(aFlags & FLAG_SYNC_DECODE))
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
if (!CanForciblyDiscard() || mDecoder || mAnim)
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
ForceDiscard();
|
||||
|
||||
mFrameDecodeFlags = desiredDecodeFlags;
|
||||
}
|
||||
if (!ApplyDecodeFlags(aFlags))
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
|
||||
// If requested, synchronously flush any data we have lying around to the decoder
|
||||
if (aFlags & FLAG_SYNC_DECODE) {
|
||||
@ -841,24 +817,8 @@ RasterImage::GetFrame(PRUint32 aWhichFrame,
|
||||
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
if (mDecoded) {
|
||||
// If we have decoded data, and it is not a perfect match for what we are
|
||||
// looking for, we must discard to be able to generate the proper data.
|
||||
PRUint32 desiredDecodeFlags = aFlags & DECODE_FLAGS_MASK;
|
||||
if (desiredDecodeFlags != mFrameDecodeFlags) {
|
||||
// if we can't discard, then we're screwed; we have no way
|
||||
// to re-decode. Similarly if we aren't allowed to do a sync
|
||||
// decode.
|
||||
if (!(aFlags & FLAG_SYNC_DECODE))
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
if (!CanForciblyDiscard() || mDecoder || mAnim)
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
|
||||
ForceDiscard();
|
||||
|
||||
mFrameDecodeFlags = desiredDecodeFlags;
|
||||
}
|
||||
}
|
||||
if (!ApplyDecodeFlags(aFlags))
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
|
||||
// If the caller requested a synchronous decode, do it
|
||||
if (aFlags & FLAG_SYNC_DECODE) {
|
||||
@ -1085,6 +1045,27 @@ RasterImage::InternalAddFrame(PRUint32 framenum,
|
||||
return rv;
|
||||
}
|
||||
|
||||
bool
|
||||
RasterImage::ApplyDecodeFlags(PRUint32 aNewFlags)
|
||||
{
|
||||
if (mFrameDecodeFlags == (aNewFlags & DECODE_FLAGS_MASK))
|
||||
return true; // Not asking very much of us here.
|
||||
|
||||
if (mDecoded) {
|
||||
// if we can't discard, then we're screwed; we have no way
|
||||
// to re-decode. Similarly if we aren't allowed to do a sync
|
||||
// decode.
|
||||
if (!(aNewFlags & FLAG_SYNC_DECODE))
|
||||
return false;
|
||||
if (!CanForciblyDiscard() || mDecoder || mAnim)
|
||||
return false;
|
||||
ForceDiscard();
|
||||
}
|
||||
|
||||
mFrameDecodeFlags = aNewFlags & DECODE_FLAGS_MASK;
|
||||
return true;
|
||||
}
|
||||
|
||||
nsresult
|
||||
RasterImage::SetSize(PRInt32 aWidth, PRInt32 aHeight)
|
||||
{
|
||||
@ -2478,9 +2459,13 @@ RasterImage::RequestDecode()
|
||||
if (mBytesDecoded == mSourceData.Length())
|
||||
return NS_OK;
|
||||
|
||||
// If it's a smallish image, it's not worth it to do things async
|
||||
if (!mDecoded && !mInDecoder && mHasSourceData && (mSourceData.Length() < gMaxBytesForSyncDecode))
|
||||
return SyncDecode();
|
||||
// If we can do decoding now, do so. Small images will decode completely,
|
||||
// large images will decode a bit and post themselves to the event loop
|
||||
// to finish decoding.
|
||||
if (!mDecoded && !mInDecoder && mHasSourceData) {
|
||||
DecodeWorker::Singleton()->DecodeABitOf(this);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// If we get this far, dispatch the worker. We do this instead of starting
|
||||
// any immediate decoding to guarantee that all our decode notifications are
|
||||
@ -2912,6 +2897,25 @@ RasterImage::DecodeWorker::RequestDecode(RasterImage* aImg)
|
||||
EnsurePendingInEventLoop();
|
||||
}
|
||||
|
||||
void
|
||||
RasterImage::DecodeWorker::DecodeABitOf(RasterImage* aImg)
|
||||
{
|
||||
TimeStamp eventStart = TimeStamp::Now();
|
||||
|
||||
do {
|
||||
DecodeSomeOfImage(aImg);
|
||||
|
||||
// If we aren't yet finished decoding and we have more data in hand, add
|
||||
// this request to the back of the priority list.
|
||||
if (aImg->mDecoder &&
|
||||
!aImg->mError &&
|
||||
!aImg->IsDecodeFinished() &&
|
||||
aImg->mSourceData.Length() > aImg->mBytesDecoded) {
|
||||
RequestDecode(aImg);
|
||||
}
|
||||
} while ((TimeStamp::Now() - eventStart).ToMilliseconds() <= gMaxMSBeforeYield);
|
||||
}
|
||||
|
||||
void
|
||||
RasterImage::DecodeWorker::EnsurePendingInEventLoop()
|
||||
{
|
||||
|
@ -394,6 +394,12 @@ private:
|
||||
*/
|
||||
void RequestDecode(RasterImage* aImg);
|
||||
|
||||
/**
|
||||
* Decode aImg for a short amount of time, and post the remainder to the
|
||||
* queue.
|
||||
*/
|
||||
void DecodeABitOf(RasterImage* aImg);
|
||||
|
||||
/**
|
||||
* Give this image ASAP priority; it will be decoded before all non-ASAP
|
||||
* images. You can call MarkAsASAP before or after you call RequestDecode
|
||||
@ -566,6 +572,8 @@ private:
|
||||
PRUint8 **imageData, PRUint32 *imageLength,
|
||||
PRUint32 **paletteData, PRUint32 *paletteLength);
|
||||
|
||||
bool ApplyDecodeFlags(PRUint32 aNewFlags);
|
||||
|
||||
private: // data
|
||||
|
||||
nsIntSize mSize;
|
||||
|
@ -83,7 +83,7 @@ imgRequest::imgRequest() :
|
||||
mValidator(nullptr), mImageSniffers("image-sniffing-services"),
|
||||
mInnerWindowId(0), mCORSMode(imgIRequest::CORS_NONE),
|
||||
mDecodeRequested(false), mIsMultiPartChannel(false), mGotData(false),
|
||||
mIsInCache(false)
|
||||
mIsInCache(false), mBlockingOnload(false)
|
||||
{
|
||||
// Register our pref observers if we haven't yet.
|
||||
if (NS_UNLIKELY(!gInitializedPrefCaches)) {
|
||||
@ -278,6 +278,18 @@ void imgRequest::Cancel(nsresult aStatus)
|
||||
LOG_SCOPE(gImgLog, "imgRequest::Cancel");
|
||||
|
||||
imgStatusTracker& statusTracker = GetStatusTracker();
|
||||
|
||||
if (mBlockingOnload) {
|
||||
mBlockingOnload = false;
|
||||
|
||||
statusTracker.RecordUnblockOnload();
|
||||
|
||||
nsTObserverArray<imgRequestProxy*>::ForwardIterator iter(mObservers);
|
||||
while (iter.HasMore()) {
|
||||
statusTracker.SendUnblockOnload(iter.GetNext());
|
||||
}
|
||||
}
|
||||
|
||||
statusTracker.RecordCancel();
|
||||
|
||||
RemoveFromCache();
|
||||
@ -511,11 +523,24 @@ NS_IMETHODIMP imgRequest::OnStartDecode(imgIRequest *request)
|
||||
"OnStartDecode callback before we've created our image");
|
||||
|
||||
|
||||
mImage->GetStatusTracker().RecordStartDecode();
|
||||
imgStatusTracker& tracker = mImage->GetStatusTracker();
|
||||
tracker.RecordStartDecode();
|
||||
|
||||
nsTObserverArray<imgRequestProxy*>::ForwardIterator iter(mObservers);
|
||||
while (iter.HasMore()) {
|
||||
mImage->GetStatusTracker().SendStartDecode(iter.GetNext());
|
||||
tracker.SendStartDecode(iter.GetNext());
|
||||
}
|
||||
|
||||
if (!mIsMultiPartChannel) {
|
||||
MOZ_ASSERT(!mBlockingOnload);
|
||||
mBlockingOnload = true;
|
||||
|
||||
tracker.RecordBlockOnload();
|
||||
|
||||
nsTObserverArray<imgRequestProxy*>::ForwardIterator iter(mObservers);
|
||||
while (iter.HasMore()) {
|
||||
tracker.SendBlockOnload(iter.GetNext());
|
||||
}
|
||||
}
|
||||
|
||||
/* In the case of streaming jpegs, it is possible to get multiple OnStartDecodes which
|
||||
@ -602,11 +627,23 @@ NS_IMETHODIMP imgRequest::OnStopFrame(imgIRequest *request,
|
||||
NS_ABORT_IF_FALSE(mImage,
|
||||
"OnStopFrame callback before we've created our image");
|
||||
|
||||
mImage->GetStatusTracker().RecordStopFrame(frame);
|
||||
imgStatusTracker& tracker = mImage->GetStatusTracker();
|
||||
tracker.RecordStopFrame(frame);
|
||||
|
||||
nsTObserverArray<imgRequestProxy*>::ForwardIterator iter(mObservers);
|
||||
while (iter.HasMore()) {
|
||||
mImage->GetStatusTracker().SendStopFrame(iter.GetNext(), frame);
|
||||
tracker.SendStopFrame(iter.GetNext(), frame);
|
||||
}
|
||||
|
||||
if (mBlockingOnload) {
|
||||
mBlockingOnload = false;
|
||||
|
||||
tracker.RecordUnblockOnload();
|
||||
|
||||
nsTObserverArray<imgRequestProxy*>::ForwardIterator iter(mObservers);
|
||||
while (iter.HasMore()) {
|
||||
tracker.SendUnblockOnload(iter.GetNext());
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
@ -620,11 +657,29 @@ NS_IMETHODIMP imgRequest::OnStopContainer(imgIRequest *request,
|
||||
NS_ABORT_IF_FALSE(mImage,
|
||||
"OnDataContainer callback before we've created our image");
|
||||
|
||||
mImage->GetStatusTracker().RecordStopContainer(image);
|
||||
imgStatusTracker& tracker = mImage->GetStatusTracker();
|
||||
tracker.RecordStopContainer(image);
|
||||
|
||||
nsTObserverArray<imgRequestProxy*>::ForwardIterator iter(mObservers);
|
||||
while (iter.HasMore()) {
|
||||
mImage->GetStatusTracker().SendStopContainer(iter.GetNext(), image);
|
||||
tracker.SendStopContainer(iter.GetNext(), image);
|
||||
}
|
||||
|
||||
// This is really hacky. We need to handle the case where we start decoding,
|
||||
// block onload, but then hit an error before we get to our first frame. In
|
||||
// theory we would just hook in at OnStopDecode, but OnStopDecode is broken
|
||||
// until we fix bug 505385. OnStopContainer is actually going away at that
|
||||
// point. So for now we take advantage of the fact that OnStopContainer is
|
||||
// always fired in the decoders at the same time as OnStopDecode.
|
||||
if (mBlockingOnload) {
|
||||
mBlockingOnload = false;
|
||||
|
||||
tracker.RecordUnblockOnload();
|
||||
|
||||
nsTObserverArray<imgRequestProxy*>::ForwardIterator iter(mObservers);
|
||||
while (iter.HasMore()) {
|
||||
tracker.SendUnblockOnload(iter.GetNext());
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
|
@ -230,6 +230,7 @@ private:
|
||||
bool mIsMultiPartChannel : 1;
|
||||
bool mGotData : 1;
|
||||
bool mIsInCache : 1;
|
||||
bool mBlockingOnload : 1;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -5,6 +5,7 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "imgRequestProxy.h"
|
||||
#include "imgIOnloadBlocker.h"
|
||||
|
||||
#include "nsIInputStream.h"
|
||||
#include "nsIComponentManager.h"
|
||||
@ -771,6 +772,34 @@ void imgRequestProxy::OnStopRequest(bool lastPart)
|
||||
}
|
||||
}
|
||||
|
||||
void imgRequestProxy::BlockOnload()
|
||||
{
|
||||
#ifdef PR_LOGGING
|
||||
nsCAutoString name;
|
||||
GetName(name);
|
||||
LOG_FUNC_WITH_PARAM(gImgLog, "imgRequestProxy::BlockOnload", "name", name.get());
|
||||
#endif
|
||||
|
||||
nsCOMPtr<imgIOnloadBlocker> blocker = do_QueryInterface(mListener);
|
||||
if (blocker) {
|
||||
blocker->BlockOnload(this);
|
||||
}
|
||||
}
|
||||
|
||||
void imgRequestProxy::UnblockOnload()
|
||||
{
|
||||
#ifdef PR_LOGGING
|
||||
nsCAutoString name;
|
||||
GetName(name);
|
||||
LOG_FUNC_WITH_PARAM(gImgLog, "imgRequestProxy::UnblockOnload", "name", name.get());
|
||||
#endif
|
||||
|
||||
nsCOMPtr<imgIOnloadBlocker> blocker = do_QueryInterface(mListener);
|
||||
if (blocker) {
|
||||
blocker->UnblockOnload(this);
|
||||
}
|
||||
}
|
||||
|
||||
void imgRequestProxy::NullOutListener()
|
||||
{
|
||||
// If we have animation consumers, then they don't matter anymore
|
||||
|
@ -153,6 +153,10 @@ protected:
|
||||
void OnStartRequest();
|
||||
void OnStopRequest(bool aLastPart);
|
||||
|
||||
/* non-virtual imgIOnloadBlocker methods */
|
||||
void BlockOnload();
|
||||
void UnblockOnload();
|
||||
|
||||
/* Finish up canceling ourselves */
|
||||
void DoCancel(nsresult status);
|
||||
|
||||
|
@ -200,6 +200,10 @@ imgStatusTracker::SyncNotify(imgRequestProxy* proxy)
|
||||
if (mState & stateDecodeStarted)
|
||||
proxy->OnStartDecode();
|
||||
|
||||
// BlockOnload
|
||||
if (mState & stateBlockingOnload)
|
||||
proxy->BlockOnload();
|
||||
|
||||
if (mImage) {
|
||||
PRInt16 imageType = mImage->GetType();
|
||||
// Send frame messages (OnStartFrame, OnDataAvailable, OnStopFrame)
|
||||
@ -483,6 +487,7 @@ imgStatusTracker::RecordStartRequest()
|
||||
mState &= ~stateDecodeStarted;
|
||||
mState &= ~stateDecodeStopped;
|
||||
mState &= ~stateRequestStopped;
|
||||
mState &= ~stateBlockingOnload;
|
||||
|
||||
mState |= stateRequestStarted;
|
||||
}
|
||||
@ -515,3 +520,33 @@ imgStatusTracker::SendStopRequest(imgRequestProxy* aProxy, bool aLastPart, nsres
|
||||
aProxy->OnStopRequest(aLastPart);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
imgStatusTracker::RecordBlockOnload()
|
||||
{
|
||||
MOZ_ASSERT(!(mState & stateBlockingOnload));
|
||||
mState |= stateBlockingOnload;
|
||||
}
|
||||
|
||||
void
|
||||
imgStatusTracker::SendBlockOnload(imgRequestProxy* aProxy)
|
||||
{
|
||||
if (!aProxy->NotificationsDeferred()) {
|
||||
aProxy->BlockOnload();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
imgStatusTracker::RecordUnblockOnload()
|
||||
{
|
||||
MOZ_ASSERT(mState & stateBlockingOnload);
|
||||
mState &= ~stateBlockingOnload;
|
||||
}
|
||||
|
||||
void
|
||||
imgStatusTracker::SendUnblockOnload(imgRequestProxy* aProxy)
|
||||
{
|
||||
if (!aProxy->NotificationsDeferred()) {
|
||||
aProxy->UnblockOnload();
|
||||
}
|
||||
}
|
||||
|
@ -31,7 +31,8 @@ enum {
|
||||
stateDecodeStarted = PR_BIT(2),
|
||||
stateDecodeStopped = PR_BIT(3),
|
||||
stateFrameStopped = PR_BIT(4),
|
||||
stateRequestStopped = PR_BIT(5)
|
||||
stateRequestStopped = PR_BIT(5),
|
||||
stateBlockingOnload = PR_BIT(6)
|
||||
};
|
||||
|
||||
/*
|
||||
@ -141,6 +142,15 @@ public:
|
||||
void RecordStopRequest(bool aLastPart, nsresult aStatus);
|
||||
void SendStopRequest(imgRequestProxy* aProxy, bool aLastPart, nsresult aStatus);
|
||||
|
||||
/* non-virtual imgIOnloadBlocker methods */
|
||||
// NB: If UnblockOnload is sent, and then we are asked to replay the
|
||||
// notifications, we will not send a BlockOnload/UnblockOnload pair. This
|
||||
// is different from all the other notifications.
|
||||
void RecordBlockOnload();
|
||||
void SendBlockOnload(imgRequestProxy* aProxy);
|
||||
void RecordUnblockOnload();
|
||||
void SendUnblockOnload(imgRequestProxy* aProxy);
|
||||
|
||||
private:
|
||||
friend class imgStatusNotifyRunnable;
|
||||
friend class imgRequestNotifyRunnable;
|
||||
|
@ -1,7 +1,7 @@
|
||||
# Colormangement
|
||||
|
||||
# test for bug 489133, test for bug 460520
|
||||
== invalid-chrm.png invalid-chrm-ref.png
|
||||
== invalid-whitepoint.png invalid-chrm-ref.png
|
||||
random-if(bug685516) == invalid-chrm.png invalid-chrm-ref.png
|
||||
random-if(bug685516) == invalid-whitepoint.png invalid-chrm-ref.png
|
||||
# test for bug 488955
|
||||
== trc-type.html trc-type-ref.html
|
||||
random-if(bug685516) == trc-type.html trc-type-ref.html
|
||||
|
@ -1,23 +1,23 @@
|
||||
# GIF tests
|
||||
|
||||
# tests for bug 519589
|
||||
== 1bit-255-trans.gif 1bit-255-trans.png
|
||||
== in-colormap-trans.gif in-colormap-trans.png
|
||||
== out-of-colormap-trans.gif out-of-colormap-trans.png
|
||||
random-if(bug685516) == 1bit-255-trans.gif 1bit-255-trans.png
|
||||
random-if(bug685516) == in-colormap-trans.gif in-colormap-trans.png
|
||||
random-if(bug685516) == out-of-colormap-trans.gif out-of-colormap-trans.png
|
||||
|
||||
# a GIF file that uses the comment extension
|
||||
== comment.gif comment.png
|
||||
random-if(bug685516) == comment.gif comment.png
|
||||
|
||||
# a GIF file with a background smaller than the size of the canvas
|
||||
== small-background-size.gif small-background-size-ref.gif
|
||||
== small-background-size-2.gif small-background-size-2-ref.gif
|
||||
random-if(bug685516) == small-background-size.gif small-background-size-ref.gif
|
||||
random-if(bug685516) == small-background-size-2.gif small-background-size-2-ref.gif
|
||||
|
||||
# a transparent gif that disposes previous frames with clear; we must properly
|
||||
# clear each frame to pass.
|
||||
random == delaytest.html?transparent-animation.gif transparent-animation-finalframe.gif # incorrect timing dependence (bug 558678)
|
||||
|
||||
# test for bug 641198
|
||||
== test_bug641198.html animation2a-finalframe.gif
|
||||
random-if(bug685516) == test_bug641198.html animation2a-finalframe.gif
|
||||
|
||||
# webcam-simulacrum.mgif is a hand-edited file containing red.gif and blue.gif,
|
||||
# concatenated together with the relevant headers for
|
||||
@ -41,4 +41,4 @@ random == delaytest.html?transparent-animation.gif transparent-animation-finalfr
|
||||
# won't be in the text of the contents themselves. --$(boundary)\r\n means
|
||||
# "Here is the beginning of a boundary," and --$(boundary)-- means "All done
|
||||
# sending you parts.")
|
||||
HTTP == webcam.html blue.gif
|
||||
random-if(bug685516) HTTP == webcam.html blue.gif
|
||||
|
@ -1,29 +1,29 @@
|
||||
# JPEG tests
|
||||
|
||||
# Images of various sizes.
|
||||
== jpg-size-1x1.jpg jpg-size-1x1.png
|
||||
== jpg-size-2x2.jpg jpg-size-2x2.png
|
||||
== jpg-size-3x3.jpg jpg-size-3x3.png
|
||||
== jpg-size-4x4.jpg jpg-size-4x4.png
|
||||
== jpg-size-5x5.jpg jpg-size-5x5.png
|
||||
== jpg-size-6x6.jpg jpg-size-6x6.png
|
||||
== jpg-size-7x7.jpg jpg-size-7x7.png
|
||||
== jpg-size-8x8.jpg jpg-size-8x8.png
|
||||
== jpg-size-9x9.jpg jpg-size-9x9.png
|
||||
== jpg-size-15x15.jpg jpg-size-15x15.png
|
||||
== jpg-size-16x16.jpg jpg-size-16x16.png
|
||||
== jpg-size-17x17.jpg jpg-size-17x17.png
|
||||
== jpg-size-31x31.jpg jpg-size-31x31.png
|
||||
== jpg-size-32x32.jpg jpg-size-32x32.png
|
||||
== jpg-size-33x33.jpg jpg-size-33x33.png
|
||||
random-if(bug685516) == jpg-size-1x1.jpg jpg-size-1x1.png
|
||||
random-if(bug685516) == jpg-size-2x2.jpg jpg-size-2x2.png
|
||||
random-if(bug685516) == jpg-size-3x3.jpg jpg-size-3x3.png
|
||||
random-if(bug685516) == jpg-size-4x4.jpg jpg-size-4x4.png
|
||||
random-if(bug685516) == jpg-size-5x5.jpg jpg-size-5x5.png
|
||||
random-if(bug685516) == jpg-size-6x6.jpg jpg-size-6x6.png
|
||||
random-if(bug685516) == jpg-size-7x7.jpg jpg-size-7x7.png
|
||||
random-if(bug685516) == jpg-size-8x8.jpg jpg-size-8x8.png
|
||||
random-if(bug685516) == jpg-size-9x9.jpg jpg-size-9x9.png
|
||||
random-if(bug685516) == jpg-size-15x15.jpg jpg-size-15x15.png
|
||||
random-if(bug685516) == jpg-size-16x16.jpg jpg-size-16x16.png
|
||||
random-if(bug685516) == jpg-size-17x17.jpg jpg-size-17x17.png
|
||||
random-if(bug685516) == jpg-size-31x31.jpg jpg-size-31x31.png
|
||||
random-if(bug685516) == jpg-size-32x32.jpg jpg-size-32x32.png
|
||||
random-if(bug685516) == jpg-size-33x33.jpg jpg-size-33x33.png
|
||||
# Progressive encoding
|
||||
== jpg-progressive.jpg jpg-progressive.png
|
||||
random-if(bug685516) == jpg-progressive.jpg jpg-progressive.png
|
||||
# Grayscale colorspace
|
||||
== jpg-gray.jpg jpg-gray.png
|
||||
random-if(bug685516) == jpg-gray.jpg jpg-gray.png
|
||||
# CMYK colorspace
|
||||
== jpg-cmyk-1.jpg jpg-cmyk-1.png
|
||||
== jpg-cmyk-2.jpg jpg-cmyk-2.png
|
||||
== jpg-srgb-icc.jpg jpg-srgb-icc.png
|
||||
random-if(bug685516) == jpg-cmyk-1.jpg jpg-cmyk-1.png
|
||||
random-if(bug685516) == jpg-cmyk-2.jpg jpg-cmyk-2.png
|
||||
random-if(bug685516) == jpg-srgb-icc.jpg jpg-srgb-icc.png
|
||||
|
||||
# webcam-simulacrum.mjpg is a hand-edited file containing red.jpg and blue.jpg,
|
||||
# concatenated together with the relevant headers for
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
|
||||
# basn0g01 - black & white
|
||||
== basn0g01.png basn0g01.html
|
||||
random-if(bug685516) == basn0g01.png basn0g01.html
|
||||
# basn0g02 - 2 bit (4 level) grayscale
|
||||
fails-if(Android) == basn0g02.png basn0g02.html
|
||||
# basn0g04 - 4 bit (16 level) grayscale
|
||||
@ -18,7 +18,7 @@ fails-if(Android) == basn2c16.png basn2c16.html
|
||||
# basn3p01 - 1 bit (2 color) paletted
|
||||
fails-if(Android) == basn3p01.png basn3p01.html
|
||||
# basn3p02 - 2 bit (4 color) paletted
|
||||
== basn3p02.png basn3p02.html
|
||||
random-if(bug685516) == basn3p02.png basn3p02.html
|
||||
# basn3p04 - 4 bit (16 color) paletted
|
||||
fails-if(Android) == basn3p04.png basn3p04.html
|
||||
# basn3p08 - 8 bit (256 color) paletted
|
||||
|
@ -1,22 +1,22 @@
|
||||
# PngSuite - Image filtering
|
||||
|
||||
# f00n0g08 - grayscale, no interlacing, filter-type 0
|
||||
== f00n0g08.png f00n0g08.html
|
||||
random-if(bug685516) == f00n0g08.png f00n0g08.html
|
||||
# f00n2c08 - color, no interlacing, filter-type 0
|
||||
== f00n2c08.png f00n2c08.html
|
||||
random-if(bug685516) == f00n2c08.png f00n2c08.html
|
||||
# f01n0g08 - grayscale, no interlacing, filter-type 1
|
||||
== f01n0g08.png f01n0g08.html
|
||||
random-if(bug685516) == f01n0g08.png f01n0g08.html
|
||||
# f01n2c08 - color, no interlacing, filter-type 1
|
||||
== f01n2c08.png f01n2c08.html
|
||||
random-if(bug685516) == f01n2c08.png f01n2c08.html
|
||||
# f02n0g08 - grayscale, no interlacing, filter-type 2
|
||||
== f02n0g08.png f02n0g08.html
|
||||
random-if(bug685516) == f02n0g08.png f02n0g08.html
|
||||
# f02n2c08 - color, no interlacing, filter-type 2
|
||||
== f02n2c08.png f02n2c08.html
|
||||
random-if(bug685516) == f02n2c08.png f02n2c08.html
|
||||
# f03n0g08 - grayscale, no interlacing, filter-type 3
|
||||
== f03n0g08.png f03n0g08.html
|
||||
random-if(bug685516) == f03n0g08.png f03n0g08.html
|
||||
# f03n2c08 - color, no interlacing, filter-type 3
|
||||
== f03n2c08.png f03n2c08.html
|
||||
random-if(bug685516) == f03n2c08.png f03n2c08.html
|
||||
# f04n0g08 - grayscale, no interlacing, filter-type 4
|
||||
== f04n0g08.png f04n0g08.html
|
||||
random-if(bug685516) == f04n0g08.png f04n0g08.html
|
||||
# f04n2c08 - color, no interlacing, filter-type 4
|
||||
== f04n2c08.png f04n2c08.html
|
||||
random-if(bug685516) == f04n2c08.png f04n2c08.html
|
||||
|
@ -4,13 +4,13 @@
|
||||
# versions look identical, so they share a common HTML reference file.
|
||||
|
||||
# s01i3p01 - 1x1 paletted file, interlaced
|
||||
== s01i3p01.png s01_3p01.html
|
||||
random-if(bug685516) == s01i3p01.png s01_3p01.html
|
||||
# s01n3p01 - 1x1 paletted file, no interlacing
|
||||
== s01n3p01.png s01_3p01.html
|
||||
random-if(bug685516) == s01n3p01.png s01_3p01.html
|
||||
# s02i3p01 - 2x2 paletted file, interlaced
|
||||
== s02i3p01.png s02_3p01.html
|
||||
random-if(bug685516) == s02i3p01.png s02_3p01.html
|
||||
# s02n3p01 - 2x2 paletted file, no interlacing
|
||||
== s02n3p01.png s02_3p01.html
|
||||
random-if(bug685516) == s02n3p01.png s02_3p01.html
|
||||
# s03i3p01 - 3x3 paletted file, interlaced
|
||||
fails-if(Android) == s03i3p01.png s03_3p01.html
|
||||
# s03n3p01 - 3x3 paletted file, no interlacing
|
||||
|
@ -1,8 +1,8 @@
|
||||
# z00n2c08 - color, no interlacing, compression level 0 (none)
|
||||
== z00n2c08.png z00n2c08.html
|
||||
random-if(bug685516) == z00n2c08.png z00n2c08.html
|
||||
# z03n2c08 - color, no interlacing, compression level 3
|
||||
== z03n2c08.png z03n2c08.html
|
||||
random-if(bug685516) == z03n2c08.png z03n2c08.html
|
||||
# z06n2c08 - color, no interlacing, compression level 6 (default)
|
||||
== z06n2c08.png z06n2c08.html
|
||||
random-if(bug685516) == z06n2c08.png z06n2c08.html
|
||||
# z09n2c08 - color, no interlacing, compression level 9 (maximum)
|
||||
== z09n2c08.png z09n2c08.html
|
||||
random-if(bug685516) == z09n2c08.png z09n2c08.html
|
||||
|
@ -75,7 +75,7 @@ function ImageListener(start_callback, stop_callback)
|
||||
|
||||
// We have to cancel the request when we're done with it to break any
|
||||
// reference loops!
|
||||
aRequest.cancel(0);
|
||||
aRequest.cancelAndForgetObserver(0);
|
||||
|
||||
this.state |= STOP_REQUEST;
|
||||
|
||||
|
@ -77,7 +77,6 @@ CPPSRCS = \
|
||||
nsFrameManager.cpp \
|
||||
nsFrameIterator.cpp \
|
||||
nsGenConList.cpp \
|
||||
nsImageLoader.cpp \
|
||||
nsLayoutDebugger.cpp \
|
||||
nsLayoutHistoryState.cpp \
|
||||
nsLayoutUtils.cpp \
|
||||
|
@ -45,8 +45,10 @@
|
||||
#include "gfxDrawable.h"
|
||||
#include "sampler.h"
|
||||
#include "nsCSSRenderingBorders.h"
|
||||
#include "mozilla/css/ImageLoader.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::css;
|
||||
|
||||
// To avoid storing this data on nsInlineFrame (bloat) and to avoid
|
||||
// recalculating this for each frame in a continuation (perf), hold
|
||||
@ -2271,7 +2273,17 @@ nsCSSRendering::PaintBackgroundWithSC(nsPresContext* aPresContext,
|
||||
// Ensure we get invalidated for loads of the image. We need to do
|
||||
// this here because this might be the only code that knows about the
|
||||
// association of the style data with the frame.
|
||||
aPresContext->SetupBackgroundImageLoaders(aForFrame, bg);
|
||||
if (aBackgroundSC != aForFrame->GetStyleContext()) {
|
||||
ImageLoader* loader = aPresContext->Document()->StyleImageLoader();
|
||||
|
||||
NS_FOR_VISIBLE_BACKGROUND_LAYERS_BACK_TO_FRONT(i, bg) {
|
||||
if (bg->mLayers[i].mImage.GetType() == eStyleImageType_Image) {
|
||||
imgIRequest *image = bg->mLayers[i].mImage.GetImageData();
|
||||
|
||||
loader->AssociateRequestToFrame(image, aForFrame);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// The background color is rendered over the entire dirty area,
|
||||
// even if the image isn't.
|
||||
@ -2574,9 +2586,11 @@ DrawBorderImage(nsPresContext* aPresContext,
|
||||
// XXX We shouldn't really... since if anybody is passing in a
|
||||
// different style, they'll potentially have the wrong size for the
|
||||
// border too.
|
||||
aPresContext->SetupBorderImageLoaders(aForFrame, &aStyleBorder);
|
||||
|
||||
imgIRequest *req = aStyleBorder.GetBorderImage();
|
||||
ImageLoader* loader = aPresContext->Document()->StyleImageLoader();
|
||||
|
||||
// If this fails there's not much we can do ...
|
||||
loader->AssociateRequestToFrame(req, aForFrame);
|
||||
|
||||
// Get the actual image.
|
||||
|
||||
|
@ -1,250 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* 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/. */
|
||||
|
||||
/* class to notify frames of background image loads */
|
||||
|
||||
#include "nsImageLoader.h"
|
||||
|
||||
#include "imgILoader.h"
|
||||
|
||||
#include "nsIURI.h"
|
||||
#include "nsILoadGroup.h"
|
||||
#include "nsNetUtil.h"
|
||||
|
||||
#include "nsPresContext.h"
|
||||
#include "nsIPresShell.h"
|
||||
#include "nsIFrame.h"
|
||||
#include "nsIContent.h"
|
||||
|
||||
#include "imgIContainer.h"
|
||||
|
||||
#include "nsStyleContext.h"
|
||||
#include "nsGkAtoms.h"
|
||||
#include "nsLayoutUtils.h"
|
||||
|
||||
// Paint forcing
|
||||
#include "prenv.h"
|
||||
|
||||
NS_IMPL_ISUPPORTS2(nsImageLoader, imgIDecoderObserver, imgIContainerObserver)
|
||||
|
||||
nsImageLoader::nsImageLoader(nsIFrame *aFrame, PRUint32 aActions,
|
||||
nsImageLoader *aNextLoader)
|
||||
: mFrame(aFrame),
|
||||
mActions(aActions),
|
||||
mNextLoader(aNextLoader),
|
||||
mRequestRegistered(false)
|
||||
{
|
||||
}
|
||||
|
||||
nsImageLoader::~nsImageLoader()
|
||||
{
|
||||
Destroy();
|
||||
}
|
||||
|
||||
/* static */ already_AddRefed<nsImageLoader>
|
||||
nsImageLoader::Create(nsIFrame *aFrame, imgIRequest *aRequest,
|
||||
PRUint32 aActions, nsImageLoader *aNextLoader)
|
||||
{
|
||||
nsRefPtr<nsImageLoader> loader =
|
||||
new nsImageLoader(aFrame, aActions, aNextLoader);
|
||||
|
||||
loader->Load(aRequest);
|
||||
|
||||
return loader.forget();
|
||||
}
|
||||
|
||||
void
|
||||
nsImageLoader::Destroy()
|
||||
{
|
||||
// Destroy the chain with only one level of recursion.
|
||||
nsRefPtr<nsImageLoader> list = mNextLoader;
|
||||
mNextLoader = nullptr;
|
||||
while (list) {
|
||||
nsRefPtr<nsImageLoader> todestroy = list;
|
||||
list = todestroy->mNextLoader;
|
||||
todestroy->mNextLoader = nullptr;
|
||||
todestroy->Destroy();
|
||||
}
|
||||
|
||||
if (mRequest && mFrame) {
|
||||
nsLayoutUtils::DeregisterImageRequest(mFrame->PresContext(), mRequest,
|
||||
&mRequestRegistered);
|
||||
}
|
||||
|
||||
mFrame = nullptr;
|
||||
|
||||
if (mRequest) {
|
||||
mRequest->CancelAndForgetObserver(NS_ERROR_FAILURE);
|
||||
}
|
||||
|
||||
mRequest = nullptr;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsImageLoader::Load(imgIRequest *aImage)
|
||||
{
|
||||
NS_ASSERTION(!mRequest, "can't reuse image loaders");
|
||||
NS_ASSERTION(mFrame, "not initialized");
|
||||
NS_ASSERTION(aImage, "must have non-null image");
|
||||
|
||||
if (!mFrame)
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
|
||||
if (!aImage)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
// Deregister mRequest from the refresh driver, since it is no longer
|
||||
// going to be managed by this nsImageLoader.
|
||||
nsPresContext* presContext = mFrame->PresContext();
|
||||
|
||||
nsLayoutUtils::DeregisterImageRequest(presContext, mRequest,
|
||||
&mRequestRegistered);
|
||||
|
||||
// Make sure to clone into a temporary, then set mRequest, since
|
||||
// cloning may notify and we don't want to trigger paints from this
|
||||
// code.
|
||||
nsCOMPtr<imgIRequest> newRequest;
|
||||
nsresult rv = aImage->Clone(this, getter_AddRefs(newRequest));
|
||||
mRequest.swap(newRequest);
|
||||
|
||||
if (mRequest) {
|
||||
nsLayoutUtils::RegisterImageRequestIfAnimated(presContext, mRequest,
|
||||
&mRequestRegistered);
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsImageLoader::OnStartContainer(imgIRequest *aRequest,
|
||||
imgIContainer *aImage)
|
||||
{
|
||||
NS_ABORT_IF_FALSE(aImage, "Who's calling us then?");
|
||||
|
||||
/* Get requested animation policy from the pres context:
|
||||
* normal = 0
|
||||
* one frame = 1
|
||||
* one loop = 2
|
||||
*/
|
||||
aImage->SetAnimationMode(mFrame->PresContext()->ImageAnimationMode());
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsImageLoader::OnStopFrame(imgIRequest *aRequest,
|
||||
PRUint32 aFrame)
|
||||
{
|
||||
if (!mFrame)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
if (!mRequest) {
|
||||
// We're in the middle of a paint anyway
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Take requested actions
|
||||
if (mActions & ACTION_REDRAW_ON_DECODE) {
|
||||
DoRedraw(nullptr);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsImageLoader::OnImageIsAnimated(imgIRequest *aRequest)
|
||||
{
|
||||
// Register with the refresh driver now that we are aware that
|
||||
// we are animated.
|
||||
nsLayoutUtils::RegisterImageRequest(mFrame->PresContext(),
|
||||
aRequest, &mRequestRegistered);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsImageLoader::OnStopRequest(imgIRequest *aRequest,
|
||||
bool aLastPart)
|
||||
{
|
||||
if (!mFrame)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
if (!mRequest) {
|
||||
// We're in the middle of a paint anyway
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Take requested actions
|
||||
if (mActions & ACTION_REDRAW_ON_LOAD) {
|
||||
DoRedraw(nullptr);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsImageLoader::FrameChanged(imgIRequest *aRequest,
|
||||
imgIContainer *aContainer,
|
||||
const nsIntRect *aDirtyRect)
|
||||
{
|
||||
if (!mFrame)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
if (!mRequest) {
|
||||
// We're in the middle of a paint anyway
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_ASSERTION(aRequest == mRequest, "This is a neat trick.");
|
||||
|
||||
nsRect r = aDirtyRect->IsEqualInterior(nsIntRect::GetMaxSizedIntRect()) ?
|
||||
nsRect(nsPoint(0, 0), mFrame->GetSize()) :
|
||||
aDirtyRect->ToAppUnits(nsPresContext::AppUnitsPerCSSPixel());
|
||||
|
||||
DoRedraw(&r);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
nsImageLoader::DoRedraw(const nsRect* aDamageRect)
|
||||
{
|
||||
// NOTE: It is not sufficient to invalidate only the size of the image:
|
||||
// the image may be tiled!
|
||||
// The best option is to call into the frame, however lacking this
|
||||
// we have to at least invalidate the frame's bounds, hence
|
||||
// as long as we have a frame we'll use its size.
|
||||
//
|
||||
|
||||
// Invalidate the entire frame
|
||||
// XXX We really only need to invalidate the client area of the frame...
|
||||
|
||||
nsRect bounds(nsPoint(0, 0), mFrame->GetSize());
|
||||
|
||||
if (mFrame->GetType() == nsGkAtoms::canvasFrame) {
|
||||
// The canvas's background covers the whole viewport.
|
||||
bounds = mFrame->GetVisualOverflowRect();
|
||||
}
|
||||
|
||||
// XXX this should be ok, but there is some crappy ass bug causing it not to work
|
||||
// XXX seems related to the "body fixup rule" dealing with the canvas and body frames...
|
||||
#if 0
|
||||
// Invalidate the entire frame only if the frame has a tiled background
|
||||
// image, otherwise just invalidate the intersection of the frame's bounds
|
||||
// with the damaged rect.
|
||||
nsStyleContext* styleContext;
|
||||
mFrame->GetStyleContext(&styleContext);
|
||||
const nsStyleBackground* bg = styleContext->GetStyleBackground();
|
||||
|
||||
if ((bg->mBackgroundFlags & NS_STYLE_BG_IMAGE_NONE) ||
|
||||
(bg->mBackgroundRepeat == NS_STYLE_BG_REPEAT_OFF)) {
|
||||
// The frame does not have a background image so we are free
|
||||
// to invalidate only the intersection of the damage rect and
|
||||
// the frame's bounds.
|
||||
|
||||
if (aDamageRect) {
|
||||
bounds.IntersectRect(*aDamageRect, bounds);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
if (mFrame->GetStyleVisibility()->IsVisible()) {
|
||||
mFrame->Invalidate(bounds);
|
||||
}
|
||||
}
|
@ -1,82 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* 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/. */
|
||||
|
||||
/* class to notify frames of background and border image loads */
|
||||
|
||||
#include "nsStubImageDecoderObserver.h"
|
||||
|
||||
class nsIFrame;
|
||||
class nsIURI;
|
||||
|
||||
#include "imgIRequest.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsAutoPtr.h"
|
||||
|
||||
/**
|
||||
* Image loaders pass notifications for background and border image
|
||||
* loading and animation on to the frames.
|
||||
*
|
||||
* Each frame's image loaders form a linked list.
|
||||
*/
|
||||
class nsImageLoader : public nsStubImageDecoderObserver
|
||||
{
|
||||
private:
|
||||
nsImageLoader(nsIFrame *aFrame, PRUint32 aActions,
|
||||
nsImageLoader *aNextLoader);
|
||||
virtual ~nsImageLoader();
|
||||
|
||||
public:
|
||||
/*
|
||||
* Flags to specify actions that can be taken for the image at various
|
||||
* times. Reflows always occur before redraws. "Decode" refers to one
|
||||
* frame being available, whereas "load" refers to all the data being loaded
|
||||
* from the network.
|
||||
*/
|
||||
enum {
|
||||
ACTION_REDRAW_ON_DECODE = 0x01,
|
||||
ACTION_REDRAW_ON_LOAD = 0x02,
|
||||
};
|
||||
static already_AddRefed<nsImageLoader>
|
||||
Create(nsIFrame *aFrame, imgIRequest *aRequest,
|
||||
PRUint32 aActions, nsImageLoader *aNextLoader);
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
// imgIDecoderObserver (override nsStubImageDecoderObserver)
|
||||
NS_IMETHOD OnStartContainer(imgIRequest *aRequest, imgIContainer *aImage);
|
||||
NS_IMETHOD OnStopFrame(imgIRequest *aRequest, PRUint32 aFrame);
|
||||
NS_IMETHOD OnStopRequest(imgIRequest *aRequest, bool aLastPart);
|
||||
NS_IMETHOD OnImageIsAnimated(imgIRequest *aRequest);
|
||||
// Do not override OnDataAvailable since background images are not
|
||||
// displayed incrementally; they are displayed after the entire image
|
||||
// has been loaded.
|
||||
// Note: Images referenced by the <img> element are displayed
|
||||
// incrementally in nsImageFrame.cpp.
|
||||
|
||||
// imgIContainerObserver (override nsStubImageDecoderObserver)
|
||||
NS_IMETHOD FrameChanged(imgIRequest *aRequest,
|
||||
imgIContainer *aContainer,
|
||||
const nsIntRect *aDirtyRect);
|
||||
|
||||
void Destroy();
|
||||
|
||||
imgIRequest *GetRequest() { return mRequest; }
|
||||
nsImageLoader *GetNextLoader() { return mNextLoader; }
|
||||
|
||||
private:
|
||||
nsresult Load(imgIRequest *aImage);
|
||||
/* if aDamageRect is nullptr, the whole frame is redrawn. */
|
||||
void DoRedraw(const nsRect* aDamageRect);
|
||||
|
||||
nsIFrame *mFrame;
|
||||
nsCOMPtr<imgIRequest> mRequest;
|
||||
PRUint32 mActions;
|
||||
nsRefPtr<nsImageLoader> mNextLoader;
|
||||
|
||||
// This is a boolean flag indicating whether or not the current image request
|
||||
// has been registered with the refresh driver.
|
||||
bool mRequestRegistered;
|
||||
};
|
@ -14,7 +14,6 @@
|
||||
#include "nsIContentViewer.h"
|
||||
#include "nsPIDOMWindow.h"
|
||||
#include "nsStyleSet.h"
|
||||
#include "nsImageLoader.h"
|
||||
#include "nsIContent.h"
|
||||
#include "nsIFrame.h"
|
||||
#include "nsIURL.h"
|
||||
@ -63,6 +62,7 @@
|
||||
#include "FrameLayerBuilder.h"
|
||||
#include "nsDOMMediaQueryList.h"
|
||||
#include "nsSMILAnimationController.h"
|
||||
#include "mozilla/css/ImageLoader.h"
|
||||
|
||||
#ifdef IBMBIDI
|
||||
#include "nsBidiPresUtils.h"
|
||||
@ -162,14 +162,6 @@ IsVisualCharset(const nsCString& aCharset)
|
||||
}
|
||||
#endif // IBMBIDI
|
||||
|
||||
|
||||
static PLDHashOperator
|
||||
destroy_loads(nsIFrame* aKey, nsRefPtr<nsImageLoader>& aData, void* closure)
|
||||
{
|
||||
aData->Destroy();
|
||||
return PL_DHASH_NEXT;
|
||||
}
|
||||
|
||||
#include "nsContentCID.h"
|
||||
|
||||
// NOTE! nsPresContext::operator new() zeroes out all members, so don't
|
||||
@ -307,28 +299,12 @@ NS_INTERFACE_MAP_END
|
||||
NS_IMPL_CYCLE_COLLECTING_ADDREF(nsPresContext)
|
||||
NS_IMPL_CYCLE_COLLECTING_RELEASE(nsPresContext)
|
||||
|
||||
static PLDHashOperator
|
||||
TraverseImageLoader(nsIFrame* aKey, nsRefPtr<nsImageLoader>& aData,
|
||||
void* aClosure)
|
||||
{
|
||||
nsCycleCollectionTraversalCallback *cb =
|
||||
static_cast<nsCycleCollectionTraversalCallback*>(aClosure);
|
||||
|
||||
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(*cb, "mImageLoaders[i] item");
|
||||
cb->NoteXPCOMChild(aData);
|
||||
|
||||
return PL_DHASH_NEXT;
|
||||
}
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsPresContext)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mDocument);
|
||||
// NS_IMPL_CYCLE_COLLECTION_TRAVERSE_RAWPTR(mDeviceContext); // not xpcom
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR_AMBIGUOUS(mEventManager, nsIObserver);
|
||||
// NS_IMPL_CYCLE_COLLECTION_TRAVERSE_RAWPTR(mLanguage); // an atom
|
||||
|
||||
for (PRUint32 i = 0; i < IMAGE_LOAD_TYPE_COUNT; ++i)
|
||||
tmp->mImageLoaders[i].Enumerate(TraverseImageLoader, &cb);
|
||||
|
||||
// We own only the items in mDOMMediaQueryLists that have listeners;
|
||||
// this reference is managed by their AddListener and RemoveListener
|
||||
// methods.
|
||||
@ -915,10 +891,6 @@ nsPresContext::Init(nsDeviceContext* aDeviceContext)
|
||||
mDeviceContext->FlushFontCache();
|
||||
mCurAppUnitsPerDevPixel = AppUnitsPerDevPixel();
|
||||
|
||||
for (PRUint32 i = 0; i < IMAGE_LOAD_TYPE_COUNT; ++i) {
|
||||
mImageLoaders[i].Init();
|
||||
}
|
||||
|
||||
mEventManager = new nsEventStateManager();
|
||||
|
||||
mTransitionManager = new nsTransitionManager(this);
|
||||
@ -1091,18 +1063,6 @@ nsPresContext::SetShell(nsIPresShell* aShell)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsPresContext::DestroyImageLoaders()
|
||||
{
|
||||
// Destroy image loaders. This is important to do when frames are being
|
||||
// destroyed because imageloaders can have pointers to frames and we don't
|
||||
// want those pointers to outlive the destruction of the frame arena.
|
||||
for (PRUint32 i = 0; i < IMAGE_LOAD_TYPE_COUNT; ++i) {
|
||||
mImageLoaders[i].Enumerate(destroy_loads, nullptr);
|
||||
mImageLoaders[i].Clear();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsPresContext::DoChangeCharSet(const nsCString& aCharSet)
|
||||
{
|
||||
@ -1252,18 +1212,6 @@ static void SetImgAnimModeOnImgReq(imgIRequest* aImgReq, PRUint16 aMode)
|
||||
}
|
||||
}
|
||||
|
||||
// Enumeration call back for HashTable
|
||||
static PLDHashOperator
|
||||
set_animation_mode(nsIFrame* aKey, nsRefPtr<nsImageLoader>& aData, void* closure)
|
||||
{
|
||||
for (nsImageLoader *loader = aData; loader;
|
||||
loader = loader->GetNextLoader()) {
|
||||
imgIRequest* imgReq = loader->GetRequest();
|
||||
SetImgAnimModeOnImgReq(imgReq, (PRUint16)NS_PTR_TO_INT32(closure));
|
||||
}
|
||||
return PL_DHASH_NEXT;
|
||||
}
|
||||
|
||||
// IMPORTANT: Assumption is that all images for a Presentation
|
||||
// have the same Animation Mode (pavlov said this was OK)
|
||||
//
|
||||
@ -1318,15 +1266,13 @@ nsPresContext::SetImageAnimationModeInternal(PRUint16 aMode)
|
||||
if (!IsDynamic())
|
||||
return;
|
||||
|
||||
// Set the mode on the image loaders.
|
||||
for (PRUint32 i = 0; i < IMAGE_LOAD_TYPE_COUNT; ++i)
|
||||
mImageLoaders[i].Enumerate(set_animation_mode, NS_INT32_TO_PTR(aMode));
|
||||
|
||||
// Now walk the content tree and set the animation mode
|
||||
// on all the images.
|
||||
if (mShell != nullptr) {
|
||||
nsIDocument *doc = mShell->GetDocument();
|
||||
if (doc) {
|
||||
doc->StyleImageLoader()->SetAnimationMode(aMode);
|
||||
|
||||
Element *rootElement = doc->GetRootElement();
|
||||
if (rootElement) {
|
||||
SetImgAnimations(rootElement, aMode);
|
||||
@ -1437,68 +1383,6 @@ nsPresContext::ScreenWidthInchesForFontInflation(bool* aChanged)
|
||||
return deviceWidthInches;
|
||||
}
|
||||
|
||||
void
|
||||
nsPresContext::SetImageLoaders(nsIFrame* aTargetFrame,
|
||||
ImageLoadType aType,
|
||||
nsImageLoader* aImageLoaders)
|
||||
{
|
||||
NS_ASSERTION(mShell || !aImageLoaders,
|
||||
"Shouldn't add new image loader after the shell is gone");
|
||||
|
||||
nsRefPtr<nsImageLoader> oldLoaders;
|
||||
mImageLoaders[aType].Get(aTargetFrame, getter_AddRefs(oldLoaders));
|
||||
|
||||
if (aImageLoaders) {
|
||||
mImageLoaders[aType].Put(aTargetFrame, aImageLoaders);
|
||||
} else if (oldLoaders) {
|
||||
mImageLoaders[aType].Remove(aTargetFrame);
|
||||
}
|
||||
|
||||
if (oldLoaders)
|
||||
oldLoaders->Destroy();
|
||||
}
|
||||
|
||||
void
|
||||
nsPresContext::SetupBackgroundImageLoaders(nsIFrame* aFrame,
|
||||
const nsStyleBackground* aStyleBackground)
|
||||
{
|
||||
nsRefPtr<nsImageLoader> loaders;
|
||||
NS_FOR_VISIBLE_BACKGROUND_LAYERS_BACK_TO_FRONT(i, aStyleBackground) {
|
||||
if (aStyleBackground->mLayers[i].mImage.GetType() == eStyleImageType_Image) {
|
||||
PRUint32 actions = nsImageLoader::ACTION_REDRAW_ON_DECODE;
|
||||
imgIRequest *image = aStyleBackground->mLayers[i].mImage.GetImageData();
|
||||
loaders = nsImageLoader::Create(aFrame, image, actions, loaders);
|
||||
}
|
||||
}
|
||||
SetImageLoaders(aFrame, BACKGROUND_IMAGE, loaders);
|
||||
}
|
||||
|
||||
void
|
||||
nsPresContext::SetupBorderImageLoaders(nsIFrame* aFrame,
|
||||
const nsStyleBorder* aStyleBorder)
|
||||
{
|
||||
// We get called the first time we try to draw a border-image, and
|
||||
// also when the border image changes (including when it changes from
|
||||
// non-null to null).
|
||||
imgIRequest *borderImage = aStyleBorder->GetBorderImage();
|
||||
if (!borderImage) {
|
||||
SetImageLoaders(aFrame, BORDER_IMAGE, nullptr);
|
||||
return;
|
||||
}
|
||||
|
||||
PRUint32 actions = nsImageLoader::ACTION_REDRAW_ON_LOAD;
|
||||
nsRefPtr<nsImageLoader> loader =
|
||||
nsImageLoader::Create(aFrame, borderImage, actions, nullptr);
|
||||
SetImageLoaders(aFrame, BORDER_IMAGE, loader);
|
||||
}
|
||||
|
||||
void
|
||||
nsPresContext::StopImagesFor(nsIFrame* aTargetFrame)
|
||||
{
|
||||
for (PRUint32 i = 0; i < IMAGE_LOAD_TYPE_COUNT; ++i)
|
||||
SetImageLoaders(aTargetFrame, ImageLoadType(i), nullptr);
|
||||
}
|
||||
|
||||
void
|
||||
nsPresContext::SetContainer(nsISupports* aHandler)
|
||||
{
|
||||
@ -2226,6 +2110,8 @@ NotifyDidPaintSubdocumentCallback(nsIDocument* aDocument, void* aData)
|
||||
void
|
||||
nsPresContext::NotifyDidPaintForSubtree()
|
||||
{
|
||||
Document()->StyleImageLoader()->NotifyPaint();
|
||||
|
||||
if (!mFireAfterPaintEvents)
|
||||
return;
|
||||
mFireAfterPaintEvents = false;
|
||||
@ -2475,13 +2361,13 @@ nsRootPresContext::~nsRootPresContext()
|
||||
}
|
||||
|
||||
void
|
||||
nsRootPresContext::RegisterPluginForGeometryUpdates(nsIContent* aPlugin)
|
||||
nsRootPresContext::RegisterPluginForGeometryUpdates(nsObjectFrame* aPlugin)
|
||||
{
|
||||
mRegisteredPlugins.PutEntry(aPlugin);
|
||||
}
|
||||
|
||||
void
|
||||
nsRootPresContext::UnregisterPluginForGeometryUpdates(nsIContent* aPlugin)
|
||||
nsRootPresContext::UnregisterPluginForGeometryUpdates(nsObjectFrame* aPlugin)
|
||||
{
|
||||
mRegisteredPlugins.RemoveEntry(aPlugin);
|
||||
}
|
||||
@ -2496,14 +2382,10 @@ struct PluginGeometryClosure {
|
||||
nsTArray<nsIWidget::Configuration>* mOutputConfigurations;
|
||||
};
|
||||
static PLDHashOperator
|
||||
PluginBoundsEnumerator(nsRefPtrHashKey<nsIContent>* aEntry, void* userArg)
|
||||
PluginBoundsEnumerator(nsPtrHashKey<nsObjectFrame>* aEntry, void* userArg)
|
||||
{
|
||||
PluginGeometryClosure* closure = static_cast<PluginGeometryClosure*>(userArg);
|
||||
nsObjectFrame* f = static_cast<nsObjectFrame*>(aEntry->GetKey()->GetPrimaryFrame());
|
||||
if (!f) {
|
||||
NS_WARNING("Null frame in PluginBoundsEnumerator");
|
||||
return PL_DHASH_NEXT;
|
||||
}
|
||||
nsObjectFrame* f = aEntry->GetKey();
|
||||
nsRect fBounds = f->GetContentRect() +
|
||||
f->GetParent()->GetOffsetToCrossDoc(closure->mRootFrame);
|
||||
PRInt32 APD = f->PresContext()->AppUnitsPerDevPixel();
|
||||
@ -2784,13 +2666,9 @@ nsRootPresContext::RequestUpdatePluginGeometry(nsIFrame* aFrame)
|
||||
}
|
||||
|
||||
static PLDHashOperator
|
||||
PluginDidSetGeometryEnumerator(nsRefPtrHashKey<nsIContent>* aEntry, void* userArg)
|
||||
PluginDidSetGeometryEnumerator(nsPtrHashKey<nsObjectFrame>* aEntry, void* userArg)
|
||||
{
|
||||
nsObjectFrame* f = static_cast<nsObjectFrame*>(aEntry->GetKey()->GetPrimaryFrame());
|
||||
if (!f) {
|
||||
NS_WARNING("Null frame in PluginDidSetGeometryEnumerator");
|
||||
return PL_DHASH_NEXT;
|
||||
}
|
||||
nsObjectFrame* f = aEntry->GetKey();
|
||||
f->DidSetWidgetGeometry();
|
||||
return PL_DHASH_NEXT;
|
||||
}
|
||||
|
@ -32,7 +32,6 @@
|
||||
#include "mozilla/TimeStamp.h"
|
||||
#include "prclist.h"
|
||||
|
||||
class nsImageLoader;
|
||||
#ifdef IBMBIDI
|
||||
class nsBidiPresUtils;
|
||||
#endif // IBMBIDI
|
||||
@ -360,49 +359,6 @@ public:
|
||||
bool GetFocusRingOnAnything() const { return mFocusRingOnAnything; }
|
||||
PRUint8 GetFocusRingStyle() const { return mFocusRingStyle; }
|
||||
|
||||
/**
|
||||
* The types of image load types that the pres context needs image
|
||||
* loaders to track invalidation for.
|
||||
*/
|
||||
enum ImageLoadType {
|
||||
BACKGROUND_IMAGE,
|
||||
BORDER_IMAGE,
|
||||
IMAGE_LOAD_TYPE_COUNT
|
||||
};
|
||||
|
||||
/**
|
||||
* Set the list of image loaders that track invalidation for a
|
||||
* specific frame and type of image. This list will replace any
|
||||
* previous list for that frame and image type (and null will remove
|
||||
* any previous list).
|
||||
*/
|
||||
NS_HIDDEN_(void) SetImageLoaders(nsIFrame* aTargetFrame,
|
||||
ImageLoadType aType,
|
||||
nsImageLoader* aImageLoaders);
|
||||
|
||||
/**
|
||||
* Make an appropriate SetImageLoaders call (including potentially
|
||||
* with null aImageLoaders) given that aFrame draws its background
|
||||
* based on aStyleBackground.
|
||||
*/
|
||||
NS_HIDDEN_(void) SetupBackgroundImageLoaders(nsIFrame* aFrame,
|
||||
const nsStyleBackground*
|
||||
aStyleBackground);
|
||||
|
||||
/**
|
||||
* Make an appropriate SetImageLoaders call (including potentially
|
||||
* with null aImageLoaders) given that aFrame draws its border
|
||||
* based on aStyleBorder.
|
||||
*/
|
||||
NS_HIDDEN_(void) SetupBorderImageLoaders(nsIFrame* aFrame,
|
||||
const nsStyleBorder* aStyleBorder);
|
||||
|
||||
/**
|
||||
* This method is called when a frame is being destroyed to
|
||||
* ensure that the image loads get disassociated from the prescontext
|
||||
*/
|
||||
NS_HIDDEN_(void) StopImagesFor(nsIFrame* aTargetFrame);
|
||||
|
||||
NS_HIDDEN_(void) SetContainer(nsISupports* aContainer);
|
||||
|
||||
virtual NS_HIDDEN_(already_AddRefed<nsISupports>) GetContainerExternal() const;
|
||||
@ -933,8 +889,6 @@ public:
|
||||
}
|
||||
inline void ForgetUpdatePluginGeometryFrame(nsIFrame* aFrame);
|
||||
|
||||
void DestroyImageLoaders();
|
||||
|
||||
bool GetContainsUpdatePluginGeometryFrame()
|
||||
{
|
||||
return mContainsUpdatePluginGeometryFrame;
|
||||
@ -1106,9 +1060,6 @@ public:
|
||||
|
||||
protected:
|
||||
|
||||
nsRefPtrHashtable<nsPtrHashKey<nsIFrame>, nsImageLoader>
|
||||
mImageLoaders[IMAGE_LOAD_TYPE_COUNT];
|
||||
|
||||
nsWeakPtr mContainer;
|
||||
|
||||
PRCList mDOMMediaQueryLists;
|
||||
@ -1276,13 +1227,13 @@ public:
|
||||
* Callers must call UnregisterPluginForGeometryUpdates before
|
||||
* the aPlugin frame is destroyed.
|
||||
*/
|
||||
void RegisterPluginForGeometryUpdates(nsIContent* aPlugin);
|
||||
void RegisterPluginForGeometryUpdates(nsObjectFrame* aPlugin);
|
||||
/**
|
||||
* Stops a plugin receiving geometry updates (position and clip
|
||||
* region). If the plugin was not already registered, this does
|
||||
* nothing.
|
||||
*/
|
||||
void UnregisterPluginForGeometryUpdates(nsIContent* aPlugin);
|
||||
void UnregisterPluginForGeometryUpdates(nsObjectFrame* aPlugin);
|
||||
|
||||
/**
|
||||
* Iterate through all plugins that are registered for geometry updates
|
||||
@ -1386,7 +1337,7 @@ protected:
|
||||
|
||||
nsCOMPtr<nsITimer> mNotifyDidPaintTimer;
|
||||
nsCOMPtr<nsITimer> mUpdatePluginGeometryTimer;
|
||||
nsTHashtable<nsRefPtrHashKey<nsIContent> > mRegisteredPlugins;
|
||||
nsTHashtable<nsPtrHashKey<nsObjectFrame> > mRegisteredPlugins;
|
||||
// if mNeedsToUpdatePluginGeometry is set, then this is the frame to
|
||||
// use as the root of the subtree to search for plugin updates, or
|
||||
// null to use the root frame of this prescontext
|
||||
|
@ -172,6 +172,7 @@
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "mozilla/Telemetry.h"
|
||||
#include "sampler.h"
|
||||
#include "mozilla/css/ImageLoader.h"
|
||||
|
||||
#include "Layers.h"
|
||||
#include "nsAsyncDOMEvent.h"
|
||||
@ -1956,11 +1957,10 @@ PresShell::FireResizeEvent()
|
||||
void
|
||||
PresShell::SetIgnoreFrameDestruction(bool aIgnore)
|
||||
{
|
||||
if (mPresContext) {
|
||||
// We need to destroy the image loaders first, as they won't be
|
||||
// notified when frames are destroyed once this setting takes effect.
|
||||
// (See bug 673984)
|
||||
mPresContext->DestroyImageLoaders();
|
||||
if (mDocument) {
|
||||
// We need to tell the ImageLoader to drop all its references to frames
|
||||
// because they're about to go away and it won't get notifications of that.
|
||||
mDocument->StyleImageLoader()->ClearAll();
|
||||
}
|
||||
mIgnoreFrameDestruction = aIgnore;
|
||||
}
|
||||
@ -1973,7 +1973,7 @@ PresShell::NotifyDestroyingFrame(nsIFrame* aFrame)
|
||||
mPresContext->ForgetUpdatePluginGeometryFrame(aFrame);
|
||||
|
||||
if (!mIgnoreFrameDestruction) {
|
||||
mPresContext->StopImagesFor(aFrame);
|
||||
mDocument->StyleImageLoader()->DropRequestsForFrame(aFrame);
|
||||
|
||||
mFrameConstructor->NotifyDestroyingFrame(aFrame);
|
||||
|
||||
|
@ -96,10 +96,12 @@
|
||||
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "mozilla/LookAndFeel.h"
|
||||
#include "mozilla/css/ImageLoader.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::layers;
|
||||
using namespace mozilla::layout;
|
||||
using namespace mozilla::css;
|
||||
|
||||
// Struct containing cached metrics for box-wrapped frames.
|
||||
struct nsBoxLayoutMetrics
|
||||
@ -697,27 +699,50 @@ EqualImages(imgIRequest *aOldImage, imgIRequest *aNewImage)
|
||||
/* virtual */ void
|
||||
nsFrame::DidSetStyleContext(nsStyleContext* aOldStyleContext)
|
||||
{
|
||||
if (aOldStyleContext) {
|
||||
// If the old context had a background image image and new context
|
||||
// does not have the same image, clear the image load notifier
|
||||
// (which keeps the image loading, if it still is) for the frame.
|
||||
// We want to do this conservatively because some frames paint their
|
||||
// backgrounds from some other frame's style data, and we don't want
|
||||
// to clear those notifiers unless we have to. (They'll be reset
|
||||
// when we paint, although we could miss a notification in that
|
||||
// interval.)
|
||||
const nsStyleBackground *oldBG = aOldStyleContext->GetStyleBackground();
|
||||
const nsStyleBackground *newBG = GetStyleBackground();
|
||||
ImageLoader* imageLoader = PresContext()->Document()->StyleImageLoader();
|
||||
|
||||
// If the old context had a background image image and new context
|
||||
// does not have the same image, clear the image load notifier
|
||||
// (which keeps the image loading, if it still is) for the frame.
|
||||
// We want to do this conservatively because some frames paint their
|
||||
// backgrounds from some other frame's style data, and we don't want
|
||||
// to clear those notifiers unless we have to. (They'll be reset
|
||||
// when we paint, although we could miss a notification in that
|
||||
// interval.)
|
||||
const nsStyleBackground *oldBG = aOldStyleContext ?
|
||||
aOldStyleContext->GetStyleBackground() :
|
||||
nullptr;
|
||||
const nsStyleBackground *newBG = GetStyleBackground();
|
||||
if (oldBG) {
|
||||
NS_FOR_VISIBLE_BACKGROUND_LAYERS_BACK_TO_FRONT(i, oldBG) {
|
||||
// If there is an image in oldBG that's not in newBG, drop it.
|
||||
if (i >= newBG->mImageCount ||
|
||||
oldBG->mLayers[i].mImage != newBG->mLayers[i].mImage) {
|
||||
// stop the image loading for the frame, the image has changed
|
||||
PresContext()->SetImageLoaders(this,
|
||||
nsPresContext::BACKGROUND_IMAGE, nullptr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
const nsStyleImage& oldImage = oldBG->mLayers[i].mImage;
|
||||
if (oldImage.GetType() != eStyleImageType_Image) {
|
||||
continue;
|
||||
}
|
||||
|
||||
imageLoader->DisassociateRequestFromFrame(oldImage.GetImageData(),
|
||||
this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NS_FOR_VISIBLE_BACKGROUND_LAYERS_BACK_TO_FRONT(i, newBG) {
|
||||
// If there is an image in newBG that's not in oldBG, add it.
|
||||
if (!oldBG || i >= oldBG->mImageCount ||
|
||||
newBG->mLayers[i].mImage != oldBG->mLayers[i].mImage) {
|
||||
const nsStyleImage& newImage = newBG->mLayers[i].mImage;
|
||||
if (newImage.GetType() != eStyleImageType_Image) {
|
||||
continue;
|
||||
}
|
||||
|
||||
imageLoader->AssociateRequestToFrame(newImage.GetImageData(), this);
|
||||
}
|
||||
}
|
||||
|
||||
if (aOldStyleContext) {
|
||||
// If we detect a change on margin, padding or border, we store the old
|
||||
// values on the frame itself between now and reflow, so if someone
|
||||
// calls GetUsed(Margin|Border|Padding)() before the next reflow, we
|
||||
@ -756,6 +781,7 @@ nsFrame::DidSetStyleContext(nsStyleContext* aOldStyleContext)
|
||||
imgIRequest *oldBorderImage = aOldStyleContext
|
||||
? aOldStyleContext->GetStyleBorder()->GetBorderImage()
|
||||
: nullptr;
|
||||
imgIRequest *newBorderImage = GetStyleBorder()->GetBorderImage();
|
||||
// FIXME (Bug 759996): The following is no longer true.
|
||||
// For border-images, we can't be as conservative (we need to set the
|
||||
// new loaders if there has been any change) since the CalcDifference
|
||||
@ -770,9 +796,14 @@ nsFrame::DidSetStyleContext(nsStyleContext* aOldStyleContext)
|
||||
// is loaded) and paint. We also don't really care about any callers
|
||||
// who try to paint borders with a different style context, because
|
||||
// they won't have the correct size for the border either.
|
||||
if (!EqualImages(oldBorderImage, GetStyleBorder()->GetBorderImage())) {
|
||||
if (!EqualImages(oldBorderImage, newBorderImage)) {
|
||||
// stop and restart the image loading/notification
|
||||
PresContext()->SetupBorderImageLoaders(this, GetStyleBorder());
|
||||
if (oldBorderImage) {
|
||||
imageLoader->DisassociateRequestFromFrame(oldBorderImage, this);
|
||||
}
|
||||
if (newBorderImage) {
|
||||
imageLoader->AssociateRequestToFrame(newBorderImage, this);
|
||||
}
|
||||
}
|
||||
|
||||
// If the page contains markup that overrides text direction, and
|
||||
|
@ -431,7 +431,7 @@ nsObjectFrame::PrepForDrawing(nsIWidget *aWidget)
|
||||
}
|
||||
#endif
|
||||
|
||||
rpc->RegisterPluginForGeometryUpdates(mContent);
|
||||
rpc->RegisterPluginForGeometryUpdates(this);
|
||||
rpc->RequestUpdatePluginGeometry(this);
|
||||
|
||||
// Here we set the background color for this widget because some plugins will use
|
||||
@ -451,7 +451,7 @@ nsObjectFrame::PrepForDrawing(nsIWidget *aWidget)
|
||||
FixupWindow(GetContentRectRelativeToSelf().Size());
|
||||
|
||||
#ifndef XP_MACOSX
|
||||
rpc->RegisterPluginForGeometryUpdates(mContent);
|
||||
rpc->RegisterPluginForGeometryUpdates(this);
|
||||
rpc->RequestUpdatePluginGeometry(this);
|
||||
#endif
|
||||
}
|
||||
@ -739,26 +739,32 @@ void
|
||||
nsObjectFrame::SetInstanceOwner(nsPluginInstanceOwner* aOwner)
|
||||
{
|
||||
mInstanceOwner = aOwner;
|
||||
if (mInstanceOwner) {
|
||||
return;
|
||||
}
|
||||
nsRootPresContext* rpc = PresContext()->GetRootPresContext();
|
||||
if (rpc) {
|
||||
rpc->UnregisterPluginForGeometryUpdates(mContent);
|
||||
}
|
||||
if (mWidget && mInnerView) {
|
||||
mInnerView->DetachWidgetEventHandler(mWidget);
|
||||
// Make sure the plugin is hidden in case an update of plugin geometry
|
||||
// hasn't happened since this plugin became hidden.
|
||||
nsIWidget* parent = mWidget->GetParent();
|
||||
if (parent) {
|
||||
nsTArray<nsIWidget::Configuration> configurations;
|
||||
this->GetEmptyClipConfiguration(&configurations);
|
||||
parent->ConfigureChildren(configurations);
|
||||
if (!mInstanceOwner) {
|
||||
nsRootPresContext* rpc = PresContext()->GetRootPresContext();
|
||||
if (rpc) {
|
||||
if (mWidget) {
|
||||
if (mInnerView) {
|
||||
mInnerView->DetachWidgetEventHandler(mWidget);
|
||||
|
||||
mWidget->Show(false);
|
||||
mWidget->Enable(false);
|
||||
mWidget->SetParent(nullptr);
|
||||
rpc->UnregisterPluginForGeometryUpdates(this);
|
||||
// Make sure the plugin is hidden in case an update of plugin geometry
|
||||
// hasn't happened since this plugin became hidden.
|
||||
nsIWidget* parent = mWidget->GetParent();
|
||||
if (parent) {
|
||||
nsTArray<nsIWidget::Configuration> configurations;
|
||||
this->GetEmptyClipConfiguration(&configurations);
|
||||
parent->ConfigureChildren(configurations);
|
||||
|
||||
mWidget->Show(false);
|
||||
mWidget->Enable(false);
|
||||
mWidget->SetParent(nullptr);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
#ifndef XP_MACOSX
|
||||
rpc->UnregisterPluginForGeometryUpdates(this);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2213,7 +2219,7 @@ nsObjectFrame::BeginSwapDocShells(nsIContent* aContent, void*)
|
||||
"Plugin windows must not be toplevel");
|
||||
nsRootPresContext* rootPC = objectFrame->PresContext()->GetRootPresContext();
|
||||
NS_ASSERTION(rootPC, "unable to unregister the plugin frame");
|
||||
rootPC->UnregisterPluginForGeometryUpdates(aContent);
|
||||
rootPC->UnregisterPluginForGeometryUpdates(objectFrame);
|
||||
}
|
||||
|
||||
/*static*/ void
|
||||
@ -2239,7 +2245,7 @@ nsObjectFrame::EndSwapDocShells(nsIContent* aContent, void*)
|
||||
objectFrame->CallSetWindow();
|
||||
|
||||
// Register for geometry updates and make a request.
|
||||
rootPC->RegisterPluginForGeometryUpdates(aContent);
|
||||
rootPC->RegisterPluginForGeometryUpdates(objectFrame);
|
||||
rootPC->RequestUpdatePluginGeometry(objectFrame);
|
||||
}
|
||||
}
|
||||
|
@ -117,12 +117,6 @@ private:
|
||||
nsWeakFrame mFrame;
|
||||
};
|
||||
|
||||
static void
|
||||
InsertViewsInReverseOrder(nsIView* aSibling, nsIView* aParent);
|
||||
|
||||
static void
|
||||
EndSwapDocShellsForViews(nsIView* aView);
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSubDocumentFrame::Init(nsIContent* aContent,
|
||||
nsIFrame* aParent,
|
||||
@ -152,28 +146,6 @@ nsSubDocumentFrame::Init(nsIContent* aContent,
|
||||
}
|
||||
EnsureInnerView();
|
||||
|
||||
// If we have a detached subdoc's root view on our frame loader, re-insert
|
||||
// it into the view tree. This happens when we've been reframed, and
|
||||
// ensures the presentation persists across reframes. If the frame element
|
||||
// has changed documents however, we blow away the presentation.
|
||||
nsRefPtr<nsFrameLoader> frameloader = FrameLoader();
|
||||
if (frameloader) {
|
||||
nsCOMPtr<nsIDocument> oldContainerDoc;
|
||||
nsIView* detachedViews =
|
||||
frameloader->GetDetachedSubdocView(getter_AddRefs(oldContainerDoc));
|
||||
if (detachedViews) {
|
||||
if (oldContainerDoc == aContent->OwnerDoc()) {
|
||||
// Restore stashed presentation.
|
||||
::InsertViewsInReverseOrder(detachedViews, mInnerView);
|
||||
::EndSwapDocShellsForViews(mInnerView->GetFirstChild());
|
||||
} else {
|
||||
// Presentation is for a different document, don't restore it.
|
||||
frameloader->Hide();
|
||||
}
|
||||
}
|
||||
frameloader->SetDetachedSubdocView(nullptr, nullptr);
|
||||
}
|
||||
|
||||
// Set the primary frame now so that
|
||||
// DocumentViewerImpl::FindContainerView called by ShowViewer below
|
||||
// can find it if necessary.
|
||||
@ -786,49 +758,6 @@ NS_NewSubDocumentFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
|
||||
|
||||
NS_IMPL_FRAMEARENA_HELPERS(nsSubDocumentFrame)
|
||||
|
||||
class nsHideViewer : public nsRunnable {
|
||||
public:
|
||||
nsHideViewer(nsIContent* aFrameElement,
|
||||
nsFrameLoader* aFrameLoader,
|
||||
nsIPresShell* aPresShell,
|
||||
bool aHideViewerIfFrameless)
|
||||
: mFrameElement(aFrameElement),
|
||||
mFrameLoader(aFrameLoader),
|
||||
mPresShell(aPresShell),
|
||||
mHideViewerIfFrameless(aHideViewerIfFrameless)
|
||||
{
|
||||
NS_ASSERTION(mFrameElement, "Must have a frame element");
|
||||
NS_ASSERTION(mFrameLoader, "Must have a frame loader");
|
||||
NS_ASSERTION(mPresShell, "Must have a presshell");
|
||||
}
|
||||
|
||||
NS_IMETHOD Run()
|
||||
{
|
||||
// Flush frames, to ensure any pending display:none changes are made.
|
||||
// Note it can be unsafe to flush if we've destroyed the presentation
|
||||
// for some other reason, like if we're shutting down.
|
||||
if (!mPresShell->IsDestroying()) {
|
||||
mPresShell->FlushPendingNotifications(Flush_Frames);
|
||||
}
|
||||
nsIFrame* frame = mFrameElement->GetPrimaryFrame();
|
||||
if (!frame && mHideViewerIfFrameless) {
|
||||
// The frame element has no nsIFrame. Hide the nsFrameLoader,
|
||||
// which destroys the presentation.
|
||||
mFrameLoader->SetDetachedSubdocView(nullptr, nullptr);
|
||||
mFrameLoader->Hide();
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
private:
|
||||
nsCOMPtr<nsIContent> mFrameElement;
|
||||
nsRefPtr<nsFrameLoader> mFrameLoader;
|
||||
nsCOMPtr<nsIPresShell> mPresShell;
|
||||
bool mHideViewerIfFrameless;
|
||||
};
|
||||
|
||||
static nsIView*
|
||||
BeginSwapDocShellsForViews(nsIView* aSibling);
|
||||
|
||||
void
|
||||
nsSubDocumentFrame::DestroyFrom(nsIFrame* aDestructRoot)
|
||||
{
|
||||
@ -836,27 +765,19 @@ nsSubDocumentFrame::DestroyFrom(nsIFrame* aDestructRoot)
|
||||
PresContext()->PresShell()->CancelReflowCallback(this);
|
||||
mPostedReflowCallback = false;
|
||||
}
|
||||
|
||||
// Detach the subdocument's views and stash them in the frame loader.
|
||||
// We can then reattach them if we're being reframed (for example if
|
||||
// the frame has been made position:fixed).
|
||||
nsFrameLoader* frameloader = FrameLoader();
|
||||
if (frameloader) {
|
||||
nsIView* detachedViews = ::BeginSwapDocShellsForViews(mInnerView->GetFirstChild());
|
||||
frameloader->SetDetachedSubdocView(detachedViews, mContent->OwnerDoc());
|
||||
|
||||
// We call nsFrameLoader::HideViewer() in a script runner so that we can
|
||||
// safely determine whether the frame is being reframed or destroyed.
|
||||
nsContentUtils::AddScriptRunner(
|
||||
new nsHideViewer(mContent,
|
||||
mFrameLoader,
|
||||
PresContext()->PresShell(),
|
||||
(mDidCreateDoc || mCallingShow)));
|
||||
}
|
||||
|
||||
HideViewer();
|
||||
|
||||
nsLeafFrame::DestroyFrom(aDestructRoot);
|
||||
}
|
||||
|
||||
void
|
||||
nsSubDocumentFrame::HideViewer()
|
||||
{
|
||||
if (mFrameLoader && (mDidCreateDoc || mCallingShow))
|
||||
mFrameLoader->Hide();
|
||||
}
|
||||
|
||||
nsIntSize
|
||||
nsSubDocumentFrame::GetMarginAttributes()
|
||||
{
|
||||
|
@ -119,9 +119,8 @@ protected:
|
||||
|
||||
virtual int GetSkipSides() const;
|
||||
|
||||
// Show our document viewer. The document viewer is hidden via a script
|
||||
// runner, so that we can save and restore the presentation if we're
|
||||
// being reframed.
|
||||
// Hide or show our document viewer
|
||||
void HideViewer();
|
||||
void ShowViewer();
|
||||
|
||||
/* Obtains the frame we should use for intrinsic size information if we are
|
||||
|
@ -14,7 +14,6 @@ include $(DEPTH)/config/autoconf.mk
|
||||
# in the list below, we make sure that the tests that require focus
|
||||
# run before test_plugin_clipping, which can steal focus for its window.
|
||||
MOCHITEST_FILES = \
|
||||
test_contained_plugin_transplant.html \
|
||||
bug344830_testembed.svg \
|
||||
plugin_clipping_helper.xhtml \
|
||||
plugin_clipping_helper2.xhtml \
|
||||
|
@ -1,40 +0,0 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=775965
|
||||
-->
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Test for Bug 775965</title>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
<body onload="run();">
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=775965">Mozilla Bug 775965</a>
|
||||
<p id="display"></p>
|
||||
<div id="content">
|
||||
|
||||
<iframe id="iframe1" src="data:text/html,<embed type='application/x-test' width='200' height='200'></embed>"></iframe>
|
||||
<iframe id="iframe2"></iframe>
|
||||
|
||||
</div>
|
||||
<pre id="test">
|
||||
<script type="application/javascript">
|
||||
|
||||
/** Test for Bug 775965 **/
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
function run() {
|
||||
var iframe1 = document.getElementById("iframe1");
|
||||
var iframe2 = document.getElementById("iframe2");
|
||||
iframe1.parentNode.removeChild(iframe1);
|
||||
iframe1.style.position = "fixed";
|
||||
iframe2.contentDocument.body.appendChild(iframe1);
|
||||
setTimeout(function() { ok(true, "We didn't crash!"); SimpleTest.finish(); }, 0);
|
||||
}
|
||||
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,2 @@
|
||||
<!DOCTYPE html>
|
||||
<img src="really-big-background.png" style="width: 1600px; height: 1200px; position: absolute;">
|
2
layout/reftests/backgrounds/really-big-background.html
Normal file
2
layout/reftests/backgrounds/really-big-background.html
Normal file
@ -0,0 +1,2 @@
|
||||
<!DOCTYPE html>
|
||||
<img style="background-image: url(really-big-background.png); width: 1600px; height: 1200px; position: absolute;"></img>
|
BIN
layout/reftests/backgrounds/really-big-background.png
Normal file
BIN
layout/reftests/backgrounds/really-big-background.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 184 KiB |
@ -1,91 +1,91 @@
|
||||
include gradient/reftest.list
|
||||
include vector/reftest.list
|
||||
|
||||
== layers-stacking-order.xhtml layers-stacking-order-ref.xhtml
|
||||
== layers-layer-count-cascade-1.xhtml layers-layer-count-1-ref.xhtml
|
||||
== layers-layer-count-inheritance-1.xhtml layers-layer-count-1-ref.xhtml
|
||||
== layers-layer-count-cascade-2.xhtml layers-layer-count-2-ref.xhtml
|
||||
== layers-layer-count-inheritance-2.xhtml layers-layer-count-2-ref.xhtml
|
||||
random-if(bug685516) == layers-stacking-order.xhtml layers-stacking-order-ref.xhtml
|
||||
random-if(bug685516) == layers-layer-count-cascade-1.xhtml layers-layer-count-1-ref.xhtml
|
||||
random-if(bug685516) == layers-layer-count-inheritance-1.xhtml layers-layer-count-1-ref.xhtml
|
||||
random-if(bug685516) == layers-layer-count-cascade-2.xhtml layers-layer-count-2-ref.xhtml
|
||||
random-if(bug685516) == layers-layer-count-inheritance-2.xhtml layers-layer-count-2-ref.xhtml
|
||||
== viewport-translucent-color-1.html viewport-translucent-color-ref.html
|
||||
fails-if(Android) == viewport-translucent-color-2.html viewport-translucent-color-ref.html
|
||||
fails-if(Android) == viewport-translucent-color-3.html viewport-translucent-color-ref.html
|
||||
!= viewport-translucent-color-ref.html about:blank
|
||||
== iframe-translucent-color-1.html iframe-translucent-color-ref.html
|
||||
== translucent-color-1.html translucent-color-ref.html
|
||||
== translucent-color-2.html translucent-color-ref.html
|
||||
== translucent-color-3.html translucent-color-ref.html
|
||||
random-if(bug685516) == iframe-translucent-color-1.html iframe-translucent-color-ref.html
|
||||
random-if(bug685516) == translucent-color-1.html translucent-color-ref.html
|
||||
random-if(bug685516) == translucent-color-2.html translucent-color-ref.html
|
||||
random-if(bug685516) == translucent-color-3.html translucent-color-ref.html
|
||||
!= translucent-color-ref.html about:blank
|
||||
== root-element-display-none-1.html root-element-display-none-ref.html
|
||||
== continuous-inline-1a.html continuous-inline-1-ref.html
|
||||
== continuous-inline-1b.html continuous-inline-1-ref.html
|
||||
== continuous-inline-1c.html continuous-inline-1-ref.html
|
||||
== continuous-inline-1d.html continuous-inline-1-ref.html
|
||||
== continuous-inline-2a.html continuous-inline-2-ref.html
|
||||
== continuous-inline-2b.html continuous-inline-2-ref.html
|
||||
== continuous-inline-3.html continuous-inline-3-ref.html
|
||||
== continuous-inline-4a.html continuous-inline-4-ref.html
|
||||
== continuous-inline-4b.html continuous-inline-4-ref.html
|
||||
== continuous-inline-5a.html continuous-inline-5-ref.html
|
||||
== continuous-inline-5b.html continuous-inline-5-ref.html
|
||||
== background-redraw-237766.html background-redraw-237766-ref.html
|
||||
random-if(bug685516) == continuous-inline-1a.html continuous-inline-1-ref.html
|
||||
random-if(bug685516) == continuous-inline-1b.html continuous-inline-1-ref.html
|
||||
random-if(bug685516) == continuous-inline-1c.html continuous-inline-1-ref.html
|
||||
random-if(bug685516) == continuous-inline-1d.html continuous-inline-1-ref.html
|
||||
random-if(bug685516) == continuous-inline-2a.html continuous-inline-2-ref.html
|
||||
random-if(bug685516) == continuous-inline-2b.html continuous-inline-2-ref.html
|
||||
random-if(bug685516) == continuous-inline-3.html continuous-inline-3-ref.html
|
||||
random-if(bug685516) == continuous-inline-4a.html continuous-inline-4-ref.html
|
||||
random-if(bug685516) == continuous-inline-4b.html continuous-inline-4-ref.html
|
||||
random-if(bug685516) == continuous-inline-5a.html continuous-inline-5-ref.html
|
||||
random-if(bug685516) == continuous-inline-5b.html continuous-inline-5-ref.html
|
||||
random-if(bug685516) == background-redraw-237766.html background-redraw-237766-ref.html
|
||||
|
||||
== background-clip-1.html background-clip-1-ref.html
|
||||
== background-clip-2.html background-clip-2-ref.html
|
||||
random-if(bug685516) == background-clip-1.html background-clip-1-ref.html
|
||||
random-if(bug685516) == background-clip-2.html background-clip-2-ref.html
|
||||
|
||||
== background-position-1a.html background-position-1-ref.html
|
||||
== background-position-1b.html background-position-1-ref.html
|
||||
== background-position-1c.html background-position-1-ref.html
|
||||
== background-position-2a.html background-position-2-ref.html
|
||||
== background-position-2b.html background-position-2-ref.html
|
||||
== background-position-3a.html background-position-3-ref.html
|
||||
== background-position-3b.html background-position-3-ref.html
|
||||
== background-position-4a.html background-position-4-ref.html
|
||||
== background-position-4b.html background-position-4-ref.html
|
||||
== background-position-4c.html background-position-4-ref.html
|
||||
== background-position-5.html background-position-5-ref.html
|
||||
== background-position-6.html background-position-6-ref.html
|
||||
== background-position-7.html background-position-7-ref.html
|
||||
== background-position-8.html background-position-8-ref.html
|
||||
random-if(bug685516) == background-position-1a.html background-position-1-ref.html
|
||||
random-if(bug685516) == background-position-1b.html background-position-1-ref.html
|
||||
random-if(bug685516) == background-position-1c.html background-position-1-ref.html
|
||||
random-if(bug685516) == background-position-2a.html background-position-2-ref.html
|
||||
random-if(bug685516) == background-position-2b.html background-position-2-ref.html
|
||||
random-if(bug685516) == background-position-3a.html background-position-3-ref.html
|
||||
random-if(bug685516) == background-position-3b.html background-position-3-ref.html
|
||||
random-if(bug685516) == background-position-4a.html background-position-4-ref.html
|
||||
random-if(bug685516) == background-position-4b.html background-position-4-ref.html
|
||||
random-if(bug685516) == background-position-4c.html background-position-4-ref.html
|
||||
random-if(bug685516) == background-position-5.html background-position-5-ref.html
|
||||
random-if(bug685516) == background-position-6.html background-position-6-ref.html
|
||||
random-if(bug685516) == background-position-7.html background-position-7-ref.html
|
||||
random-if(bug685516) == background-position-8.html background-position-8-ref.html
|
||||
|
||||
== background-size-auto-auto.html background-size-auto-ref.html
|
||||
== background-size-auto.html background-size-auto-ref.html
|
||||
== background-size-contain.html background-size-contain-ref.html
|
||||
== background-size-cover.html background-size-cover-ref.html
|
||||
== background-size-auto-length.html background-size-auto-length-ref.html
|
||||
== background-size-length-auto.html background-size-auto-length-ref.html
|
||||
== background-size-length.html background-size-auto-length-ref.html
|
||||
== background-size-auto-percent.html background-size-auto-length-ref.html
|
||||
== background-size-percent-auto.html background-size-auto-length-ref.html
|
||||
== background-size-percent.html background-size-auto-length-ref.html
|
||||
== background-size-length-percent.html background-size-length-percent-ref.html
|
||||
== background-size-percent-length.html background-size-length-percent-ref.html
|
||||
== background-size-percent-percent.html background-size-percent-percent-ref.html
|
||||
== background-size-length-length.html background-size-length-length-ref.html
|
||||
== background-size-percent-percent-stretch.html background-size-percent-percent-stretch-ref.html
|
||||
random-if(bug685516) == background-size-auto-auto.html background-size-auto-ref.html
|
||||
random-if(bug685516) == background-size-auto.html background-size-auto-ref.html
|
||||
random-if(bug685516) == background-size-contain.html background-size-contain-ref.html
|
||||
random-if(bug685516) == background-size-cover.html background-size-cover-ref.html
|
||||
random-if(bug685516) == background-size-auto-length.html background-size-auto-length-ref.html
|
||||
random-if(bug685516) == background-size-length-auto.html background-size-auto-length-ref.html
|
||||
random-if(bug685516) == background-size-length.html background-size-auto-length-ref.html
|
||||
random-if(bug685516) == background-size-auto-percent.html background-size-auto-length-ref.html
|
||||
random-if(bug685516) == background-size-percent-auto.html background-size-auto-length-ref.html
|
||||
random-if(bug685516) == background-size-percent.html background-size-auto-length-ref.html
|
||||
random-if(bug685516) == background-size-length-percent.html background-size-length-percent-ref.html
|
||||
random-if(bug685516) == background-size-percent-length.html background-size-length-percent-ref.html
|
||||
random-if(bug685516) == background-size-percent-percent.html background-size-percent-percent-ref.html
|
||||
random-if(bug685516) == background-size-length-length.html background-size-length-length-ref.html
|
||||
random-if(bug685516) == background-size-percent-percent-stretch.html background-size-percent-percent-stretch-ref.html
|
||||
|
||||
== background-size-body-percent-percent.html background-size-body-percent-percent-ref.html
|
||||
== background-size-body-percent-percent-no-repeat.html background-size-body-percent-percent-ref.html
|
||||
== background-size-body-percent-percent-not-fixed.html background-size-body-percent-percent-ref.html
|
||||
== background-size-body-cover.html background-size-body-cover-ref.html
|
||||
== background-size-body-cover-no-repeat.html background-size-body-cover-ref.html
|
||||
!= background-size-body-cover-not-fixed.html background-size-body-cover-ref.html
|
||||
!= background-size-body-cover-not-fixed.html background-size-body-single-not-fixed.html
|
||||
random-if(bug685516) == background-size-body-percent-percent.html background-size-body-percent-percent-ref.html
|
||||
random-if(bug685516) == background-size-body-percent-percent-no-repeat.html background-size-body-percent-percent-ref.html
|
||||
random-if(bug685516) == background-size-body-percent-percent-not-fixed.html background-size-body-percent-percent-ref.html
|
||||
random-if(bug685516) == background-size-body-cover.html background-size-body-cover-ref.html
|
||||
random-if(bug685516) == background-size-body-cover-no-repeat.html background-size-body-cover-ref.html
|
||||
random-if(bug685516) != background-size-body-cover-not-fixed.html background-size-body-cover-ref.html
|
||||
random-if(bug685516) != background-size-body-cover-not-fixed.html background-size-body-single-not-fixed.html
|
||||
|
||||
# relies on reftest window having greater height than width
|
||||
== background-size-body-contain.html background-size-body-cover-ref.html
|
||||
!= background-size-body-contain-no-repeat.html background-size-body-cover-ref.html
|
||||
!= background-size-body-contain-not-fixed.html background-size-body-cover-ref.html
|
||||
!= background-size-body-cover-not-fixed.html background-size-body-contain-not-fixed.html
|
||||
random-if(bug685516) == background-size-body-contain.html background-size-body-cover-ref.html
|
||||
random-if(bug685516) != background-size-body-contain-no-repeat.html background-size-body-cover-ref.html
|
||||
random-if(bug685516) != background-size-body-contain-not-fixed.html background-size-body-cover-ref.html
|
||||
random-if(bug685516) != background-size-body-cover-not-fixed.html background-size-body-contain-not-fixed.html
|
||||
|
||||
!= background-size-body-percent-percent-overflow.html background-size-body-percent-percent-overflow-ref.html
|
||||
random-if(bug685516) != background-size-body-percent-percent-overflow.html background-size-body-percent-percent-overflow-ref.html
|
||||
|
||||
== background-size-zoom-no-repeat.html background-size-zoom-no-repeat-ref.html
|
||||
random-if(bug685516) == background-size-zoom-no-repeat.html background-size-zoom-no-repeat-ref.html
|
||||
|
||||
== background-size-contain-clip-padding.html background-size-contain-clip-padding-ref.html
|
||||
== background-size-contain-clip-border.html background-size-contain-clip-border-ref.html
|
||||
== background-size-contain-position-fifty-fifty.html background-size-contain-position-fifty-fifty-ref.html
|
||||
== background-size-contain-clip-padding-origin-border.html background-size-contain-clip-padding-origin-border-ref.html
|
||||
== background-size-contain-clip-padding-origin-border-padding.html background-size-contain-clip-padding-origin-border-padding-ref.html
|
||||
random-if(bug685516) == background-size-contain-clip-padding.html background-size-contain-clip-padding-ref.html
|
||||
random-if(bug685516) == background-size-contain-clip-border.html background-size-contain-clip-border-ref.html
|
||||
random-if(bug685516) == background-size-contain-position-fifty-fifty.html background-size-contain-position-fifty-fifty-ref.html
|
||||
random-if(bug685516) == background-size-contain-clip-padding-origin-border.html background-size-contain-clip-padding-origin-border-ref.html
|
||||
random-if(bug685516) == background-size-contain-clip-padding-origin-border-padding.html background-size-contain-clip-padding-origin-border-padding-ref.html
|
||||
|
||||
# -moz-background-inline-policy is touchy and hard to test due to stretching
|
||||
# artifacts and the difficulty of covering exact lines, and its CSS3 analog is
|
||||
@ -101,16 +101,16 @@ fails-if(Android) == viewport-translucent-color-3.html viewport-translucent-colo
|
||||
!= background-size-cover-continuous.html background-size-cover-bounding-box.html
|
||||
!= background-size-cover-each-box.html background-size-cover-bounding-box.html
|
||||
|
||||
== background-size-monster-ch.html background-size-monster-ref.html
|
||||
== background-size-monster-cm.html background-size-monster-ref.html
|
||||
== background-size-monster-em.html background-size-monster-ref.html
|
||||
== background-size-monster-ex.html background-size-monster-ref.html
|
||||
== background-size-monster-inches.html background-size-monster-ref.html
|
||||
== background-size-monster-mm.html background-size-monster-ref.html
|
||||
== background-size-monster-pc.html background-size-monster-ref.html
|
||||
== background-size-monster-pt.html background-size-monster-ref.html
|
||||
== background-size-monster-px.html background-size-monster-ref.html
|
||||
== background-size-monster-rem.html background-size-monster-ref.html
|
||||
random-if(bug685516) == background-size-monster-ch.html background-size-monster-ref.html
|
||||
random-if(bug685516) == background-size-monster-cm.html background-size-monster-ref.html
|
||||
random-if(bug685516) == background-size-monster-em.html background-size-monster-ref.html
|
||||
random-if(bug685516) == background-size-monster-ex.html background-size-monster-ref.html
|
||||
random-if(bug685516) == background-size-monster-inches.html background-size-monster-ref.html
|
||||
random-if(bug685516) == background-size-monster-mm.html background-size-monster-ref.html
|
||||
random-if(bug685516) == background-size-monster-pc.html background-size-monster-ref.html
|
||||
random-if(bug685516) == background-size-monster-pt.html background-size-monster-ref.html
|
||||
random-if(bug685516) == background-size-monster-px.html background-size-monster-ref.html
|
||||
random-if(bug685516) == background-size-monster-rem.html background-size-monster-ref.html
|
||||
|
||||
# There seems to be a pixel-snapping problem here, where the repeated background
|
||||
# image isn't being snapped at its boundaries. Note that the boundaries within
|
||||
@ -122,9 +122,11 @@ fails == background-size-zoom-repeat.html background-size-zoom-repeat-ref.html
|
||||
# -moz-default-background-color and -moz-default-color (bug 591341)
|
||||
== background-moz-default-background-color.html background-moz-default-background-color-ref.html
|
||||
|
||||
== fixed-bg-with-transform-outside-viewport-1.html fixed-bg-with-transform-outside-viewport-ref.html
|
||||
random-if(bug685516) == fixed-bg-with-transform-outside-viewport-1.html fixed-bg-with-transform-outside-viewport-ref.html
|
||||
|
||||
HTTP == root-background-1.html root-background-ref.html
|
||||
random-if(bug685516) HTTP == root-background-1.html root-background-ref.html
|
||||
HTTP != root-background-1.html about:blank
|
||||
|
||||
== background-repeat-1-ref.html background-repeat-1.html
|
||||
== really-big-background.html really-big-background-ref.html
|
||||
|
||||
random-if(bug685516) == background-repeat-1-ref.html background-repeat-1.html
|
||||
|
@ -19,9 +19,9 @@
|
||||
== abspos-non-replaced-width-offset-margin.html abspos-non-replaced-width-offset-margin-ref.html
|
||||
== abspos-replaced-width-offset-margin.html abspos-replaced-width-offset-margin-ref.html
|
||||
HTTP(..) == CSS21-t100301.xhtml CSS21-t100301-ref.xhtml
|
||||
== CSS21-t100303.xhtml CSS21-t100303-ref.xhtml
|
||||
== CSS21-t100303-simple.xhtml CSS21-t100303-ref.xhtml
|
||||
== CSS21-t100801-vertical-align.xhtml CSS21-t100801-vertical-align-ref.xhtml
|
||||
random-if(bug685516) == CSS21-t100303.xhtml CSS21-t100303-ref.xhtml
|
||||
random-if(bug685516) == CSS21-t100303-simple.xhtml CSS21-t100303-ref.xhtml
|
||||
random-if(bug685516) == CSS21-t100801-vertical-align.xhtml CSS21-t100801-vertical-align-ref.xhtml
|
||||
== clip-auto.html clip-auto-ref.html
|
||||
== clip-rect-auto.html clip-rect-auto-ref.html
|
||||
== width-rounding.html width-rounding-ref.html
|
||||
|
@ -1,6 +1,6 @@
|
||||
== background-image-gradient-1.html background-image-gradient-1-ref.html
|
||||
== background-position-1.html background-position-1-ref.html
|
||||
== background-size-1.html background-size-1-ref.html
|
||||
random-if(bug685516) == background-image-gradient-1.html background-image-gradient-1-ref.html
|
||||
random-if(bug685516) == background-position-1.html background-position-1-ref.html
|
||||
random-if(bug685516) == background-size-1.html background-size-1-ref.html
|
||||
== border-radius-1.html border-radius-1-ref.html
|
||||
== height-block-1.html height-block-1-ref.html
|
||||
== height-table-1.html height-table-1-ref.html
|
||||
|
@ -1,16 +1,16 @@
|
||||
== background-common-usage-floating-point.html background-common-usage-ref.html
|
||||
== background-common-usage-percent.html background-common-usage-ref.html
|
||||
== background-common-usage-pixel.html background-common-usage-ref.html
|
||||
== background-draw-nothing-empty-rect.html background-draw-nothing-ref.html
|
||||
== background-draw-nothing-invalid-syntax.html background-draw-nothing-ref.html
|
||||
asserts(0-2) == background-draw-nothing-malformed-images.html background-draw-nothing-ref.html # Bug 576419
|
||||
== background-monster-rect.html background-monster-rect-ref.html
|
||||
== background-over-size-rect.html background-over-size-rect-ref.html
|
||||
== background-test-parser.html background-test-parser-ref.html
|
||||
== background-with-other-properties.html background-with-other-properties-ref.html
|
||||
== background-zoom-1.html background-zoom-1-ref.html
|
||||
== background-zoom-2.html background-zoom-2-ref.html
|
||||
== background-zoom-3.html background-zoom-3-ref.html
|
||||
== background-zoom-4.html background-zoom-4-ref.html
|
||||
== dom-api-computed-style.html dom-api-ref.html
|
||||
== dom-api.html dom-api-ref.html
|
||||
random-if(bug685516) == background-common-usage-floating-point.html background-common-usage-ref.html
|
||||
random-if(bug685516) == background-common-usage-percent.html background-common-usage-ref.html
|
||||
random-if(bug685516) == background-common-usage-pixel.html background-common-usage-ref.html
|
||||
random-if(bug685516) == background-draw-nothing-empty-rect.html background-draw-nothing-ref.html
|
||||
random-if(bug685516) == background-draw-nothing-invalid-syntax.html background-draw-nothing-ref.html
|
||||
random-if(bug685516) asserts(0-2) == background-draw-nothing-malformed-images.html background-draw-nothing-ref.html # Bug 576419
|
||||
random-if(bug685516) == background-monster-rect.html background-monster-rect-ref.html
|
||||
random-if(bug685516) == background-over-size-rect.html background-over-size-rect-ref.html
|
||||
random-if(bug685516) == background-test-parser.html background-test-parser-ref.html
|
||||
random-if(bug685516) == background-with-other-properties.html background-with-other-properties-ref.html
|
||||
random-if(bug685516) == background-zoom-1.html background-zoom-1-ref.html
|
||||
random-if(bug685516) == background-zoom-2.html background-zoom-2-ref.html
|
||||
random-if(bug685516) == background-zoom-3.html background-zoom-3-ref.html
|
||||
random-if(bug685516) == background-zoom-4.html background-zoom-4-ref.html
|
||||
random-if(bug685516) == dom-api-computed-style.html dom-api-ref.html
|
||||
random-if(bug685516) == dom-api.html dom-api-ref.html
|
||||
|
@ -1,4 +1,4 @@
|
||||
== background-image-zoom-1.html background-image-zoom-1-ref.html
|
||||
random-if(bug685516) == background-image-zoom-1.html background-image-zoom-1-ref.html
|
||||
== background-image-zoom-2.html about:blank
|
||||
== image-zoom-1.html image-zoom-1-ref.html
|
||||
== image-zoom-2.html image-zoom-1-ref.html
|
||||
|
@ -50,33 +50,33 @@
|
||||
== border-top-6.html border-top-10-ref.html
|
||||
|
||||
!= background-image-base.html background-image-height-10-ref.html
|
||||
== background-image-height-4.html background-image-base.html
|
||||
== background-image-height-5.html background-image-height-10-ref.html
|
||||
== background-image-height-6.html background-image-height-10-ref.html
|
||||
random-if(bug685516) == background-image-height-4.html background-image-base.html
|
||||
random-if(bug685516) == background-image-height-5.html background-image-height-10-ref.html
|
||||
random-if(bug685516) == background-image-height-6.html background-image-height-10-ref.html
|
||||
!= background-image-base.html background-image-top-10-ref.html
|
||||
== background-image-top-4.html background-image-base.html
|
||||
== background-image-top-5.html background-image-top-10-ref.html
|
||||
== background-image-top-6.html background-image-top-10-ref.html
|
||||
random-if(bug685516) == background-image-top-4.html background-image-base.html
|
||||
random-if(bug685516) == background-image-top-5.html background-image-top-10-ref.html
|
||||
random-if(bug685516) == background-image-top-6.html background-image-top-10-ref.html
|
||||
!= background-image-base.html background-image-width-10-ref.html
|
||||
== background-image-width-4.html background-image-base.html
|
||||
== background-image-width-5.html background-image-width-10-ref.html
|
||||
== background-image-width-6.html background-image-width-10-ref.html
|
||||
random-if(bug685516) == background-image-width-4.html background-image-base.html
|
||||
random-if(bug685516) == background-image-width-5.html background-image-width-10-ref.html
|
||||
random-if(bug685516) == background-image-width-6.html background-image-width-10-ref.html
|
||||
!= background-image-base.html background-image-left-10-ref.html
|
||||
== background-image-left-4.html background-image-base.html
|
||||
== background-image-left-5.html background-image-left-10-ref.html
|
||||
== background-image-left-6.html background-image-left-10-ref.html
|
||||
== background-image-top-height-4.html background-image-height-4.html
|
||||
== background-image-top-height-5.html background-image-height-5.html
|
||||
== background-image-top-height-6.html background-image-height-6.html
|
||||
== background-image-left-width-4.html background-image-width-4.html
|
||||
== background-image-left-width-5.html background-image-width-5.html
|
||||
== background-image-left-width-6.html background-image-width-6.html
|
||||
== background-image-height-top-4.html background-image-height-4.html
|
||||
== background-image-height-top-5.html background-image-height-5.html
|
||||
== background-image-height-top-6.html background-image-height-6.html
|
||||
== background-image-width-left-4.html background-image-width-4.html
|
||||
== background-image-width-left-5.html background-image-width-5.html
|
||||
== background-image-width-left-6.html background-image-width-6.html
|
||||
random-if(bug685516) == background-image-left-4.html background-image-base.html
|
||||
random-if(bug685516) == background-image-left-5.html background-image-left-10-ref.html
|
||||
random-if(bug685516) == background-image-left-6.html background-image-left-10-ref.html
|
||||
random-if(bug685516) == background-image-top-height-4.html background-image-height-4.html
|
||||
random-if(bug685516) == background-image-top-height-5.html background-image-height-5.html
|
||||
random-if(bug685516) == background-image-top-height-6.html background-image-height-6.html
|
||||
random-if(bug685516) == background-image-left-width-4.html background-image-width-4.html
|
||||
random-if(bug685516) == background-image-left-width-5.html background-image-width-5.html
|
||||
random-if(bug685516) == background-image-left-width-6.html background-image-width-6.html
|
||||
random-if(bug685516) == background-image-height-top-4.html background-image-height-4.html
|
||||
random-if(bug685516) == background-image-height-top-5.html background-image-height-5.html
|
||||
random-if(bug685516) == background-image-height-top-6.html background-image-height-6.html
|
||||
random-if(bug685516) == background-image-width-left-4.html background-image-width-4.html
|
||||
random-if(bug685516) == background-image-width-left-5.html background-image-width-5.html
|
||||
random-if(bug685516) == background-image-width-left-6.html background-image-width-6.html
|
||||
|
||||
|
||||
# These all fail due bug 371180, plus a bunch of other bugs that ought to be filed.
|
||||
@ -167,7 +167,7 @@ fails == collapsed-border-top-6.html border-top-10-ref.html
|
||||
== rounded-background-color-width-left-5.html rounded-background-color-width-5.html
|
||||
== rounded-background-color-width-left-6.html rounded-background-color-width-6.html
|
||||
|
||||
fails-if(cocoaWidget) == background-image-tiling.html background-image-tiling-ref.html # probably bug 379317
|
||||
random-if(bug685516) fails-if(cocoaWidget) == background-image-tiling.html background-image-tiling-ref.html # probably bug 379317
|
||||
|
||||
!= border-image-width-0.html border-image-width-10.html
|
||||
random-if(Android) == border-image-width-4.html border-image-width-0.html # bug 661996
|
||||
|
@ -96,7 +96,7 @@ skip-if(!browserIsRemote) == test-displayport-bg.html test-displayport-ref.html
|
||||
# IPC Position-fixed frames/layers test
|
||||
# Fixed layers are temporarily disabled (bug 656167).
|
||||
#skip-if(!browserIsRemote) == test-pos-fixed.html test-pos-fixed-ref.html
|
||||
skip-if(!browserIsRemote) == test-bg-attachment-fixed.html test-bg-attachment-fixed-ref.html
|
||||
#skip-if(!browserIsRemote) == test-bg-attachment-fixed.html test-bg-attachment-fixed-ref.html
|
||||
skip-if(!browserIsRemote) == test-pos-fixed-transform.html test-pos-fixed-transform-ref.html
|
||||
|
||||
# reftest syntax: require-or
|
||||
|
@ -1,8 +1,8 @@
|
||||
HTTP == fixed-1.html fixed-1.html?ref
|
||||
HTTP == fixed-opacity-1.html fixed-opacity-1.html?ref
|
||||
HTTP == fixed-opacity-2.html fixed-opacity-2.html?ref
|
||||
HTTP == fixed-text-1.html fixed-text-1.html?ref
|
||||
HTTP == fixed-text-2.html fixed-text-2.html?ref
|
||||
random-if(bug685516) HTTP == fixed-opacity-1.html fixed-opacity-1.html?ref
|
||||
random-if(bug685516) HTTP == fixed-opacity-2.html fixed-opacity-2.html?ref
|
||||
random-if(bug685516) HTTP == fixed-text-1.html fixed-text-1.html?ref
|
||||
random-if(bug685516) HTTP == fixed-text-2.html fixed-text-2.html?ref
|
||||
random-if(Android&&!browserIsRemote) == iframe-border-radius.html iframe-border-radius-ref.html # bug 760269
|
||||
random-if(Android) HTTP == image-1.html image-1.html?ref
|
||||
random-if(Android&&!browserIsRemote) HTTP == opacity-mixed-scrolling-1.html opacity-mixed-scrolling-1.html?ref # bug 760269
|
||||
|
@ -18,7 +18,7 @@ include zoom/reftest.list
|
||||
|
||||
# Tests with -moz-image-rect()
|
||||
== background-image-rect-1svg.html lime100x100-ref.html
|
||||
== background-image-rect-1png.html lime100x100-ref.html
|
||||
random-if(bug685516) == background-image-rect-1png.html lime100x100-ref.html
|
||||
== background-image-rect-2.html lime100x100-ref.html
|
||||
|
||||
# Test for border-image
|
||||
|
@ -28,30 +28,30 @@ asserts-if(gtk2Widget,0-6) != backgr_border-table-quirks.html empty.html
|
||||
# would also be good to test table-header-group and table-footer-group
|
||||
# (and rows and row groups in the presence of their reordering)
|
||||
# Also need to test different values of background-origin and background-clip.
|
||||
== border-separate-table-cell.html border-separate-table-cell-ref.html
|
||||
== border-separate-table-column-group.html border-separate-table-column-group-ref.html
|
||||
== border-separate-table-column.html border-separate-table-column-ref.html
|
||||
== border-separate-table-row-group.html border-separate-table-row-group-ref.html
|
||||
== border-separate-table-row.html border-separate-table-row-ref.html
|
||||
== border-separate-table.html border-separate-table-ref.html
|
||||
== border-collapse-table-cell.html border-collapse-table-cell-ref.html
|
||||
== border-collapse-table-column-group.html border-collapse-table-column-group-ref.html
|
||||
== border-collapse-table-column.html border-collapse-table-column-ref.html
|
||||
== border-collapse-table-row-group.html border-collapse-table-row-group-ref.html
|
||||
== border-collapse-table-row.html border-collapse-table-row-ref.html
|
||||
== border-collapse-table.html border-collapse-table-ref.html
|
||||
== border-collapse-opacity-table-cell.html border-collapse-opacity-table-cell-ref.html
|
||||
random-if(bug685516) == border-separate-table-cell.html border-separate-table-cell-ref.html
|
||||
random-if(bug685516) == border-separate-table-column-group.html border-separate-table-column-group-ref.html
|
||||
random-if(bug685516) == border-separate-table-column.html border-separate-table-column-ref.html
|
||||
random-if(bug685516) == border-separate-table-row-group.html border-separate-table-row-group-ref.html
|
||||
random-if(bug685516) == border-separate-table-row.html border-separate-table-row-ref.html
|
||||
random-if(bug685516) == border-separate-table.html border-separate-table-ref.html
|
||||
random-if(bug685516) == border-collapse-table-cell.html border-collapse-table-cell-ref.html
|
||||
random-if(bug685516) == border-collapse-table-column-group.html border-collapse-table-column-group-ref.html
|
||||
random-if(bug685516) == border-collapse-table-column.html border-collapse-table-column-ref.html
|
||||
random-if(bug685516) == border-collapse-table-row-group.html border-collapse-table-row-group-ref.html
|
||||
random-if(bug685516) == border-collapse-table-row.html border-collapse-table-row-ref.html
|
||||
random-if(bug685516) == border-collapse-table.html border-collapse-table-ref.html
|
||||
random-if(bug685516) == border-collapse-opacity-table-cell.html border-collapse-opacity-table-cell-ref.html
|
||||
fails == border-collapse-opacity-table-column-group.html border-collapse-opacity-table-column-group-ref.html # bug 424274
|
||||
fails == border-collapse-opacity-table-column.html border-collapse-opacity-table-column-ref.html # bug 424274
|
||||
== border-collapse-opacity-table-row-group.html border-collapse-opacity-table-row-group-ref.html
|
||||
== border-collapse-opacity-table-row.html border-collapse-opacity-table-row-ref.html
|
||||
== border-collapse-opacity-table.html border-collapse-opacity-table-ref.html
|
||||
== border-separate-opacity-table-cell.html border-separate-opacity-table-cell-ref.html
|
||||
random-if(bug685516) == border-collapse-opacity-table-row-group.html border-collapse-opacity-table-row-group-ref.html
|
||||
random-if(bug685516) == border-collapse-opacity-table-row.html border-collapse-opacity-table-row-ref.html
|
||||
random-if(bug685516) == border-collapse-opacity-table.html border-collapse-opacity-table-ref.html
|
||||
random-if(bug685516) == border-separate-opacity-table-cell.html border-separate-opacity-table-cell-ref.html
|
||||
fails == border-separate-opacity-table-column-group.html border-separate-opacity-table-column-group-ref.html # bug 424274
|
||||
fails == border-separate-opacity-table-column.html border-separate-opacity-table-column-ref.html # bug 424274
|
||||
== border-separate-opacity-table-row-group.html border-separate-opacity-table-row-group-ref.html
|
||||
== border-separate-opacity-table-row.html border-separate-opacity-table-row-ref.html
|
||||
== border-separate-opacity-table.html border-separate-opacity-table-ref.html
|
||||
random-if(bug685516) == border-separate-opacity-table-row-group.html border-separate-opacity-table-row-group-ref.html
|
||||
random-if(bug685516) == border-separate-opacity-table-row.html border-separate-opacity-table-row-ref.html
|
||||
random-if(bug685516) == border-separate-opacity-table.html border-separate-opacity-table-ref.html
|
||||
!= scrollable-rowgroup-collapse-background.html scrollable-rowgroup-collapse-notref.html
|
||||
!= scrollable-rowgroup-collapse-border.html scrollable-rowgroup-collapse-notref.html
|
||||
!= scrollable-rowgroup-separate-background.html scrollable-rowgroup-separate-notref.html
|
||||
|
452
layout/style/ImageLoader.cpp
Normal file
452
layout/style/ImageLoader.cpp
Normal file
@ -0,0 +1,452 @@
|
||||
/* 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).
|
||||
*/
|
||||
|
||||
#include "mozilla/css/ImageLoader.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsLayoutUtils.h"
|
||||
#include "nsError.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace css {
|
||||
|
||||
/* static */ PLDHashOperator
|
||||
ImageLoader::SetAnimationModeEnumerator(nsISupports* aKey, FrameSet* aValue,
|
||||
void* aClosure)
|
||||
{
|
||||
imgIRequest* request = static_cast<imgIRequest*>(aKey);
|
||||
|
||||
PRUint16* mode = static_cast<PRUint16*>(aClosure);
|
||||
|
||||
#ifdef DEBUG
|
||||
{
|
||||
nsCOMPtr<imgIRequest> debugRequest = do_QueryInterface(aKey);
|
||||
NS_ASSERTION(debugRequest == request, "This is bad");
|
||||
}
|
||||
#endif
|
||||
|
||||
nsCOMPtr<imgIContainer> container;
|
||||
request->GetImage(getter_AddRefs(container));
|
||||
if (!container) {
|
||||
return PL_DHASH_NEXT;
|
||||
}
|
||||
|
||||
// This can fail if the image is in error, and we don't care.
|
||||
container->SetAnimationMode(*mode);
|
||||
|
||||
return PL_DHASH_NEXT;
|
||||
}
|
||||
|
||||
void
|
||||
ImageLoader::DropDocumentReference()
|
||||
{
|
||||
ClearAll();
|
||||
mDocument = nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
ImageLoader::AssociateRequestToFrame(imgIRequest* aRequest,
|
||||
nsIFrame* aFrame)
|
||||
{
|
||||
MOZ_ASSERT(mRequestToFrameMap.IsInitialized() &&
|
||||
mFrameToRequestMap.IsInitialized() &&
|
||||
mImages.IsInitialized());
|
||||
|
||||
nsCOMPtr<imgIDecoderObserver> observer;
|
||||
aRequest->GetDecoderObserver(getter_AddRefs(observer));
|
||||
if (!observer) {
|
||||
// The request has already been canceled, so ignore it. This is ok because
|
||||
// we're not going to get any more notifications from a canceled request.
|
||||
return;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(observer == this);
|
||||
|
||||
FrameSet* frameSet = nullptr;
|
||||
if (mRequestToFrameMap.Get(aRequest, &frameSet)) {
|
||||
NS_ASSERTION(frameSet, "This should never be null!");
|
||||
}
|
||||
|
||||
if (!frameSet) {
|
||||
nsAutoPtr<FrameSet> newFrameSet(new FrameSet());
|
||||
|
||||
mRequestToFrameMap.Put(aRequest, newFrameSet);
|
||||
frameSet = newFrameSet.forget();
|
||||
}
|
||||
|
||||
RequestSet* requestSet = nullptr;
|
||||
if (mFrameToRequestMap.Get(aFrame, &requestSet)) {
|
||||
NS_ASSERTION(requestSet, "This should never be null");
|
||||
}
|
||||
|
||||
if (!requestSet) {
|
||||
nsAutoPtr<RequestSet> newRequestSet(new RequestSet());
|
||||
|
||||
mFrameToRequestMap.Put(aFrame, newRequestSet);
|
||||
requestSet = newRequestSet.forget();
|
||||
}
|
||||
|
||||
// Add these to the sets, but only if they're not already there.
|
||||
PRUint32 i;
|
||||
if (!frameSet->GreatestIndexLtEq(aFrame, i)) {
|
||||
frameSet->InsertElementAt(i, aFrame);
|
||||
}
|
||||
if (!requestSet->GreatestIndexLtEq(aRequest, i)) {
|
||||
requestSet->InsertElementAt(i, aRequest);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ImageLoader::MaybeRegisterCSSImage(nsCSSValue::Image* aImage)
|
||||
{
|
||||
NS_ASSERTION(aImage, "This should never be null!");
|
||||
|
||||
bool found = false;
|
||||
aImage->mRequests.GetWeak(mDocument, &found);
|
||||
if (found) {
|
||||
// This document already has a request.
|
||||
return;
|
||||
}
|
||||
|
||||
imgIRequest* canonicalRequest = aImage->mRequests.GetWeak(nullptr);
|
||||
if (!canonicalRequest) {
|
||||
// The image was blocked or something.
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<imgIRequest> request;
|
||||
|
||||
// Ignore errors here. If cloning fails for some reason we'll put a null
|
||||
// entry in the hash and we won't keep trying to clone.
|
||||
mInClone = true;
|
||||
canonicalRequest->Clone(this, getter_AddRefs(request));
|
||||
mInClone = false;
|
||||
|
||||
aImage->mRequests.Put(mDocument, request);
|
||||
|
||||
AddImage(aImage);
|
||||
}
|
||||
|
||||
void
|
||||
ImageLoader::DeregisterCSSImage(nsCSSValue::Image* aImage)
|
||||
{
|
||||
RemoveImage(aImage);
|
||||
}
|
||||
|
||||
void
|
||||
ImageLoader::DisassociateRequestFromFrame(imgIRequest* aRequest,
|
||||
nsIFrame* aFrame)
|
||||
{
|
||||
FrameSet* frameSet = nullptr;
|
||||
RequestSet* requestSet = nullptr;
|
||||
|
||||
MOZ_ASSERT(mRequestToFrameMap.IsInitialized() &&
|
||||
mFrameToRequestMap.IsInitialized() &&
|
||||
mImages.IsInitialized());
|
||||
|
||||
#ifdef DEBUG
|
||||
{
|
||||
nsCOMPtr<imgIDecoderObserver> observer;
|
||||
aRequest->GetDecoderObserver(getter_AddRefs(observer));
|
||||
MOZ_ASSERT(!observer || observer == this);
|
||||
}
|
||||
#endif
|
||||
|
||||
mRequestToFrameMap.Get(aRequest, &frameSet);
|
||||
mFrameToRequestMap.Get(aFrame, &requestSet);
|
||||
|
||||
if (frameSet) {
|
||||
frameSet->RemoveElementSorted(aFrame);
|
||||
}
|
||||
if (requestSet) {
|
||||
requestSet->RemoveElementSorted(aRequest);
|
||||
}
|
||||
|
||||
if (frameSet && !frameSet->Length()) {
|
||||
mRequestToFrameMap.Remove(aRequest);
|
||||
|
||||
nsPresContext* presContext = GetPresContext();
|
||||
if (presContext) {
|
||||
nsLayoutUtils::DeregisterImageRequest(presContext,
|
||||
aRequest,
|
||||
nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
if (requestSet && !requestSet->Length()) {
|
||||
mFrameToRequestMap.Remove(aFrame);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ImageLoader::DropRequestsForFrame(nsIFrame* aFrame)
|
||||
{
|
||||
RequestSet* requestSet = nullptr;
|
||||
if (!mFrameToRequestMap.Get(aFrame, &requestSet)) {
|
||||
return;
|
||||
}
|
||||
|
||||
NS_ASSERTION(requestSet, "This should never be null");
|
||||
|
||||
RequestSet frozenRequestSet(*requestSet);
|
||||
for (RequestSet::size_type i = frozenRequestSet.Length(); i != 0; --i) {
|
||||
imgIRequest* request = frozenRequestSet.ElementAt(i - 1);
|
||||
|
||||
DisassociateRequestFromFrame(request, aFrame);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ImageLoader::SetAnimationMode(PRUint16 aMode)
|
||||
{
|
||||
NS_ASSERTION(aMode == imgIContainer::kNormalAnimMode ||
|
||||
aMode == imgIContainer::kDontAnimMode ||
|
||||
aMode == imgIContainer::kLoopOnceAnimMode,
|
||||
"Wrong Animation Mode is being set!");
|
||||
|
||||
mRequestToFrameMap.EnumerateRead(SetAnimationModeEnumerator, &aMode);
|
||||
}
|
||||
|
||||
static PLDHashOperator
|
||||
ClearImageHashSet(nsPtrHashKey<nsCSSValue::Image>* aKey, void* aClosure)
|
||||
{
|
||||
nsIDocument* doc = static_cast<nsIDocument*>(aClosure);
|
||||
nsCSSValue::Image* image = aKey->GetKey();
|
||||
|
||||
imgIRequest* request = image->mRequests.GetWeak(doc);
|
||||
if (request) {
|
||||
request->CancelAndForgetObserver(NS_BINDING_ABORTED);
|
||||
}
|
||||
|
||||
image->mRequests.Remove(doc);
|
||||
|
||||
return PL_DHASH_REMOVE;
|
||||
}
|
||||
|
||||
void
|
||||
ImageLoader::ClearAll()
|
||||
{
|
||||
mRequestToFrameMap.Clear();
|
||||
mFrameToRequestMap.Clear();
|
||||
mImages.EnumerateEntries(&ClearImageHashSet, mDocument);
|
||||
}
|
||||
|
||||
void
|
||||
ImageLoader::LoadImage(nsIURI* aURI, nsIPrincipal* aOriginPrincipal,
|
||||
nsIURI* aReferrer, nsCSSValue::Image* aImage)
|
||||
{
|
||||
NS_ASSERTION(aImage->mRequests.Count() == 0, "Huh?");
|
||||
|
||||
aImage->mRequests.Put(nullptr, nullptr);
|
||||
|
||||
if (!aURI) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!nsContentUtils::CanLoadImage(aURI, mDocument, mDocument,
|
||||
aOriginPrincipal)) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<imgIRequest> request;
|
||||
nsContentUtils::LoadImage(aURI, mDocument, aOriginPrincipal, aReferrer,
|
||||
nullptr, nsIRequest::LOAD_NORMAL,
|
||||
getter_AddRefs(request));
|
||||
|
||||
if (!request) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<imgIRequest> clonedRequest;
|
||||
mInClone = true;
|
||||
nsresult rv = request->Clone(this, getter_AddRefs(clonedRequest));
|
||||
mInClone = false;
|
||||
|
||||
if (NS_FAILED(rv)) {
|
||||
return;
|
||||
}
|
||||
|
||||
aImage->mRequests.Put(nullptr, request);
|
||||
aImage->mRequests.Put(mDocument, clonedRequest);
|
||||
|
||||
AddImage(aImage);
|
||||
}
|
||||
|
||||
void
|
||||
ImageLoader::AddImage(nsCSSValue::Image* aImage)
|
||||
{
|
||||
NS_ASSERTION(!mImages.Contains(aImage), "Huh?");
|
||||
if (!mImages.PutEntry(aImage)) {
|
||||
NS_RUNTIMEABORT("OOM");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ImageLoader::RemoveImage(nsCSSValue::Image* aImage)
|
||||
{
|
||||
NS_ASSERTION(mImages.Contains(aImage), "Huh?");
|
||||
mImages.RemoveEntry(aImage);
|
||||
}
|
||||
|
||||
nsPresContext*
|
||||
ImageLoader::GetPresContext()
|
||||
{
|
||||
if (!mDocument) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsIPresShell* shell = mDocument->GetShell();
|
||||
if (!shell) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return shell->GetPresContext();
|
||||
}
|
||||
|
||||
void
|
||||
ImageLoader::DoRedraw(FrameSet* aFrameSet)
|
||||
{
|
||||
NS_ASSERTION(aFrameSet, "Must have a frame set");
|
||||
NS_ASSERTION(mDocument, "Should have returned earlier!");
|
||||
NS_ASSERTION(mHavePainted, "Should have returned earlier!");
|
||||
|
||||
FrameSet::size_type length = aFrameSet->Length();
|
||||
for (FrameSet::size_type i = 0; i < length; i++) {
|
||||
nsIFrame* frame = aFrameSet->ElementAt(i);
|
||||
|
||||
// NOTE: It is not sufficient to invalidate only the size of the image:
|
||||
// the image may be tiled!
|
||||
// The best option is to call into the frame, however lacking this
|
||||
// we have to at least invalidate the frame's bounds, hence
|
||||
// as long as we have a frame we'll use its size.
|
||||
//
|
||||
|
||||
// Invalidate the entire frame
|
||||
// XXX We really only need to invalidate the client area of the frame...
|
||||
|
||||
nsRect bounds(nsPoint(0, 0), frame->GetSize());
|
||||
|
||||
if (frame->GetType() == nsGkAtoms::canvasFrame) {
|
||||
// The canvas's background covers the whole viewport.
|
||||
bounds = frame->GetVisualOverflowRect();
|
||||
}
|
||||
|
||||
if (frame->GetStyleVisibility()->IsVisible()) {
|
||||
frame->Invalidate(bounds);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMPL_ADDREF(ImageLoader)
|
||||
NS_IMPL_RELEASE(ImageLoader)
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN(ImageLoader)
|
||||
NS_INTERFACE_MAP_ENTRY(imgIDecoderObserver)
|
||||
NS_INTERFACE_MAP_ENTRY(imgIContainerObserver)
|
||||
NS_INTERFACE_MAP_ENTRY(imgIOnloadBlocker)
|
||||
NS_INTERFACE_MAP_END
|
||||
|
||||
NS_IMETHODIMP
|
||||
ImageLoader::OnStartContainer(imgIRequest* aRequest, imgIContainer* aImage)
|
||||
{
|
||||
nsPresContext* presContext = GetPresContext();
|
||||
if (!presContext) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
aImage->SetAnimationMode(presContext->ImageAnimationMode());
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
ImageLoader::OnImageIsAnimated(imgIRequest* aRequest)
|
||||
{
|
||||
// NB: Don't ignore this when cloning, it's our only chance to register
|
||||
// the request with the refresh driver.
|
||||
if (!mDocument) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Register with the refresh driver now that we are aware that
|
||||
// we are animated.
|
||||
nsPresContext* presContext = GetPresContext();
|
||||
if (presContext) {
|
||||
nsLayoutUtils::RegisterImageRequest(presContext,
|
||||
aRequest,
|
||||
nullptr);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
ImageLoader::OnStopFrame(imgIRequest *aRequest, PRUint32 aFrame)
|
||||
{
|
||||
if (!mDocument || !mHavePainted || mInClone) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
FrameSet* frameSet = nullptr;
|
||||
if (!mRequestToFrameMap.Get(aRequest, &frameSet)) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_ASSERTION(frameSet, "This should never be null!");
|
||||
|
||||
DoRedraw(frameSet);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
ImageLoader::FrameChanged(imgIRequest *aRequest,
|
||||
imgIContainer *aContainer,
|
||||
const nsIntRect *aDirtyRect)
|
||||
{
|
||||
if (!mDocument || !mHavePainted || mInClone) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
FrameSet* frameSet = nullptr;
|
||||
if (!mRequestToFrameMap.Get(aRequest, &frameSet)) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_ASSERTION(frameSet, "This should never be null!");
|
||||
|
||||
DoRedraw(frameSet);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
ImageLoader::BlockOnload(imgIRequest* aRequest)
|
||||
{
|
||||
if (!mDocument) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
mDocument->BlockOnload();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
ImageLoader::UnblockOnload(imgIRequest* aRequest)
|
||||
{
|
||||
if (!mDocument) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
mDocument->UnblockOnload(false);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
} // namespace css
|
||||
} // namespace mozilla
|
131
layout/style/ImageLoader.h
Normal file
131
layout/style/ImageLoader.h
Normal file
@ -0,0 +1,131 @@
|
||||
/* 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).
|
||||
|
||||
#include "nsAutoPtr.h"
|
||||
#include "nsClassHashtable.h"
|
||||
#include "nsHashKeys.h"
|
||||
#include "nsInterfaceHashtable.h"
|
||||
#include "nsCSSValue.h"
|
||||
#include "imgIRequest.h"
|
||||
#include "imgIOnloadBlocker.h"
|
||||
#include "nsStubImageDecoderObserver.h"
|
||||
|
||||
class nsIFrame;
|
||||
class nsIDocument;
|
||||
class nsPresContext;
|
||||
class nsIURI;
|
||||
class nsIPrincipal;
|
||||
|
||||
namespace mozilla {
|
||||
namespace css {
|
||||
|
||||
class ImageLoader : public nsStubImageDecoderObserver,
|
||||
public imgIOnloadBlocker {
|
||||
public:
|
||||
ImageLoader(nsIDocument* aDocument)
|
||||
: mDocument(aDocument),
|
||||
mHavePainted(false),
|
||||
mInClone(false)
|
||||
{
|
||||
MOZ_ASSERT(mDocument);
|
||||
|
||||
mRequestToFrameMap.Init();
|
||||
mFrameToRequestMap.Init();
|
||||
mImages.Init();
|
||||
}
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_IMGIONLOADBLOCKER
|
||||
|
||||
// imgIDecoderObserver (override nsStubImageDecoderObserver)
|
||||
NS_IMETHOD OnStartContainer(imgIRequest *aRequest, imgIContainer *aImage);
|
||||
NS_IMETHOD OnStopFrame(imgIRequest *aRequest, PRUint32 aFrame);
|
||||
NS_IMETHOD OnImageIsAnimated(imgIRequest *aRequest);
|
||||
// Do not override OnDataAvailable since background images are not
|
||||
// displayed incrementally; they are displayed after the entire image
|
||||
// has been loaded.
|
||||
|
||||
// imgIContainerObserver (override nsStubImageDecoderObserver)
|
||||
NS_IMETHOD FrameChanged(imgIRequest* aRequest,
|
||||
imgIContainer *aContainer,
|
||||
const nsIntRect *aDirtyRect);
|
||||
|
||||
inline void NotifyPaint()
|
||||
{
|
||||
mHavePainted = true;
|
||||
}
|
||||
|
||||
void DropDocumentReference();
|
||||
|
||||
void MaybeRegisterCSSImage(nsCSSValue::Image* aImage);
|
||||
void DeregisterCSSImage(nsCSSValue::Image* aImage);
|
||||
|
||||
void AssociateRequestToFrame(imgIRequest* aRequest,
|
||||
nsIFrame* aFrame);
|
||||
|
||||
void DisassociateRequestFromFrame(imgIRequest* aRequest,
|
||||
nsIFrame* aFrame);
|
||||
|
||||
void DropRequestsForFrame(nsIFrame* aFrame);
|
||||
|
||||
void SetAnimationMode(PRUint16 aMode);
|
||||
|
||||
void ClearAll();
|
||||
|
||||
void LoadImage(nsIURI* aURI, nsIPrincipal* aPrincipal, nsIURI* aReferrer,
|
||||
nsCSSValue::Image* aCSSValue);
|
||||
|
||||
void DestroyRequest(imgIRequest* aRequest);
|
||||
|
||||
private:
|
||||
// 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;
|
||||
typedef nsTHashtable<nsPtrHashKey<nsCSSValue::Image> > ImageHashSet;
|
||||
typedef nsClassHashtable<nsISupportsHashKey,
|
||||
FrameSet> RequestToFrameMap;
|
||||
typedef nsClassHashtable<nsPtrHashKey<nsIFrame>,
|
||||
RequestSet> FrameToRequestMap;
|
||||
|
||||
void AddImage(nsCSSValue::Image* aCSSImage);
|
||||
void RemoveImage(nsCSSValue::Image* aCSSImage);
|
||||
|
||||
nsPresContext* GetPresContext();
|
||||
|
||||
void DoRedraw(FrameSet* aFrameSet);
|
||||
|
||||
static PLDHashOperator
|
||||
SetAnimationModeEnumerator(nsISupports* aKey, FrameSet* aValue,
|
||||
void* aClosure);
|
||||
|
||||
// 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;
|
||||
|
||||
// Have we painted yet? If not, no need to deliver notifications.
|
||||
bool mHavePainted;
|
||||
|
||||
// Are we cloning? If so, ignore any notifications we get.
|
||||
bool mInClone;
|
||||
};
|
||||
|
||||
} // namespace css
|
||||
} // namespace mozilla
|
@ -72,6 +72,7 @@ EXPORTS = \
|
||||
EXPORTS_mozilla/css = \
|
||||
Declaration.h \
|
||||
GroupRule.h \
|
||||
ImageLoader.h \
|
||||
ImportRule.h \
|
||||
Loader.h \
|
||||
NameSpaceRule.h \
|
||||
@ -85,6 +86,7 @@ CPPSRCS = \
|
||||
nsCSSDataBlock.cpp \
|
||||
Declaration.cpp \
|
||||
nsCSSKeywords.cpp \
|
||||
ImageLoader.cpp \
|
||||
Loader.cpp \
|
||||
nsAnimationManager.cpp \
|
||||
nsCSSParser.cpp \
|
||||
|
@ -10,6 +10,7 @@
|
||||
|
||||
#include "nsCSSDataBlock.h"
|
||||
#include "mozilla/css/Declaration.h"
|
||||
#include "mozilla/css/ImageLoader.h"
|
||||
#include "nsRuleData.h"
|
||||
#include "nsStyleSet.h"
|
||||
#include "nsStyleContext.h"
|
||||
@ -47,16 +48,25 @@ ShouldIgnoreColors(nsRuleData *aRuleData)
|
||||
static void
|
||||
TryToStartImageLoadOnValue(const nsCSSValue& aValue, nsIDocument* aDocument)
|
||||
{
|
||||
MOZ_ASSERT(aDocument);
|
||||
|
||||
if (aValue.GetUnit() == eCSSUnit_URL) {
|
||||
aValue.StartImageLoad(aDocument);
|
||||
}
|
||||
else if (aValue.GetUnit() == eCSSUnit_Image) {
|
||||
// If we already have a request, see if this document needs to clone it.
|
||||
imgIRequest* request = aValue.GetImageValue(nullptr);
|
||||
|
||||
if (request) {
|
||||
aDocument->StyleImageLoader()->MaybeRegisterCSSImage(aValue.GetImageStructValue());
|
||||
}
|
||||
}
|
||||
else if (aValue.EqualsFunction(eCSSKeyword__moz_image_rect)) {
|
||||
nsCSSValue::Array* arguments = aValue.GetArrayValue();
|
||||
NS_ABORT_IF_FALSE(arguments->Count() == 6, "unexpected num of arguments");
|
||||
|
||||
const nsCSSValue& image = arguments->Item(1);
|
||||
if (image.GetUnit() == eCSSUnit_URL)
|
||||
image.StartImageLoad(aDocument);
|
||||
TryToStartImageLoadOnValue(image, aDocument);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include "nsStyleUtil.h"
|
||||
#include "CSSCalc.h"
|
||||
#include "nsNetUtil.h"
|
||||
#include "mozilla/css/ImageLoader.h"
|
||||
|
||||
namespace css = mozilla::css;
|
||||
|
||||
@ -240,10 +241,10 @@ double nsCSSValue::GetAngleValueInRadians() const
|
||||
}
|
||||
}
|
||||
|
||||
imgIRequest* nsCSSValue::GetImageValue() const
|
||||
imgIRequest* nsCSSValue::GetImageValue(nsIDocument* aDocument) const
|
||||
{
|
||||
NS_ABORT_IF_FALSE(mUnit == eCSSUnit_Image, "not an Image value");
|
||||
return mValue.mImage->mRequest;
|
||||
return mValue.mImage->mRequests.GetWeak(aDocument);
|
||||
}
|
||||
|
||||
nscoord nsCSSValue::GetFixedLength(nsPresContext* aPresContext) const
|
||||
@ -1701,17 +1702,41 @@ nsCSSValue::Image::Image(nsIURI* aURI, nsStringBuffer* aString,
|
||||
if (aDocument->GetOriginalDocument()) {
|
||||
aDocument = aDocument->GetOriginalDocument();
|
||||
}
|
||||
if (aURI &&
|
||||
nsContentUtils::CanLoadImage(aURI, aDocument, aDocument,
|
||||
aOriginPrincipal)) {
|
||||
nsContentUtils::LoadImage(aURI, aDocument, aOriginPrincipal, aReferrer,
|
||||
nullptr, nsIRequest::LOAD_NORMAL,
|
||||
getter_AddRefs(mRequest));
|
||||
|
||||
mRequests.Init();
|
||||
|
||||
aDocument->StyleImageLoader()->LoadImage(aURI, aOriginPrincipal, aReferrer,
|
||||
this);
|
||||
}
|
||||
|
||||
static PLDHashOperator
|
||||
ClearRequestHashtable(nsISupports* aKey, nsCOMPtr<imgIRequest>& aValue,
|
||||
void* aClosure)
|
||||
{
|
||||
nsCSSValue::Image* image = static_cast<nsCSSValue::Image*>(aClosure);
|
||||
nsIDocument* doc = static_cast<nsIDocument*>(aKey);
|
||||
|
||||
#ifdef DEBUG
|
||||
{
|
||||
nsCOMPtr<nsIDocument> slowDoc = do_QueryInterface(aKey);
|
||||
MOZ_ASSERT(slowDoc == doc);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (doc) {
|
||||
doc->StyleImageLoader()->DeregisterCSSImage(image);
|
||||
}
|
||||
|
||||
if (aValue) {
|
||||
aValue->CancelAndForgetObserver(NS_BINDING_ABORTED);
|
||||
}
|
||||
|
||||
return PL_DHASH_REMOVE;
|
||||
}
|
||||
|
||||
nsCSSValue::Image::~Image()
|
||||
{
|
||||
mRequests.Enumerate(&ClearRequestHashtable, this);
|
||||
}
|
||||
|
||||
nsCSSValueGradientStop::nsCSSValueGradientStop()
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include "nsCSSProperty.h"
|
||||
#include "nsColor.h"
|
||||
#include "nsCoord.h"
|
||||
#include "nsInterfaceHashtable.h"
|
||||
#include "nsString.h"
|
||||
#include "nsStringBuffer.h"
|
||||
#include "nsTArray.h"
|
||||
@ -26,6 +27,8 @@ class nsIDocument;
|
||||
class nsIPrincipal;
|
||||
class nsPresContext;
|
||||
class nsIURI;
|
||||
template <class T>
|
||||
class nsPtrHashKey;
|
||||
|
||||
// Deletes a linked list iteratively to avoid blowing up the stack (bug 456196).
|
||||
#define NS_CSS_DELETE_LIST_MEMBER(type_, ptr_, member_) \
|
||||
@ -354,6 +357,12 @@ public:
|
||||
return mValue.mURL;
|
||||
}
|
||||
|
||||
Image* GetImageStructValue() const
|
||||
{
|
||||
NS_ABORT_IF_FALSE(mUnit == eCSSUnit_Image, "not an Image value");
|
||||
return mValue.mImage;
|
||||
}
|
||||
|
||||
const PRUnichar* GetOriginalURLValue() const
|
||||
{
|
||||
NS_ABORT_IF_FALSE(mUnit == eCSSUnit_URL || mUnit == eCSSUnit_Image,
|
||||
@ -366,7 +375,7 @@ public:
|
||||
// Not making this inline because that would force us to include
|
||||
// imgIRequest.h, which leads to REQUIRES hell, since this header is included
|
||||
// all over.
|
||||
imgIRequest* GetImageValue() const;
|
||||
imgIRequest* GetImageValue(nsIDocument* aDocument) const;
|
||||
|
||||
nscoord GetFixedLength(nsPresContext* aPresContext) const;
|
||||
nscoord GetPixelLength() const;
|
||||
@ -485,7 +494,7 @@ public:
|
||||
|
||||
// Inherit operator== from nsCSSValue::URL
|
||||
|
||||
nsCOMPtr<imgIRequest> mRequest; // null == image load blocked or somehow failed
|
||||
nsInterfaceHashtable<nsISupportsHashKey, imgIRequest> mRequests;
|
||||
|
||||
// Override AddRef and Release to not only log ourselves correctly, but
|
||||
// also so that we delete correctly without a virtual destructor
|
||||
|
@ -64,6 +64,12 @@ using namespace mozilla::dom;
|
||||
method_(req); \
|
||||
}
|
||||
|
||||
#define NS_SET_IMAGE_REQUEST_WITH_DOC(method_, context_, requestgetter_) \
|
||||
{ \
|
||||
nsIDocument* doc = (context_)->PresContext()->Document(); \
|
||||
NS_SET_IMAGE_REQUEST(method_, context_, requestgetter_(doc)) \
|
||||
}
|
||||
|
||||
/*
|
||||
* For storage of an |nsRuleNode|'s children in a PLDHashTable.
|
||||
*/
|
||||
@ -937,9 +943,9 @@ static void SetStyleImageToImageRect(nsStyleContext* aStyleContext,
|
||||
|
||||
// <uri>
|
||||
if (arr->Item(1).GetUnit() == eCSSUnit_Image) {
|
||||
NS_SET_IMAGE_REQUEST(aResult.SetImageData,
|
||||
aStyleContext,
|
||||
arr->Item(1).GetImageValue())
|
||||
NS_SET_IMAGE_REQUEST_WITH_DOC(aResult.SetImageData,
|
||||
aStyleContext,
|
||||
arr->Item(1).GetImageValue)
|
||||
} else {
|
||||
NS_WARNING("nsCSSValue::Image::Image() failed?");
|
||||
}
|
||||
@ -969,9 +975,9 @@ static void SetStyleImage(nsStyleContext* aStyleContext,
|
||||
|
||||
switch (aValue.GetUnit()) {
|
||||
case eCSSUnit_Image:
|
||||
NS_SET_IMAGE_REQUEST(aResult.SetImageData,
|
||||
aStyleContext,
|
||||
aValue.GetImageValue())
|
||||
NS_SET_IMAGE_REQUEST_WITH_DOC(aResult.SetImageData,
|
||||
aStyleContext,
|
||||
aValue.GetImageValue)
|
||||
break;
|
||||
case eCSSUnit_Function:
|
||||
if (aValue.EqualsFunction(eCSSKeyword__moz_image_rect)) {
|
||||
@ -3947,9 +3953,10 @@ nsRuleNode::ComputeUserInterfaceData(void* aStartStruct,
|
||||
cursorUnit).get());
|
||||
const nsCSSValueList* list = cursorValue->GetListValue();
|
||||
const nsCSSValueList* list2 = list;
|
||||
nsIDocument* doc = aContext->PresContext()->Document();
|
||||
PRUint32 arrayLength = 0;
|
||||
for ( ; list->mValue.GetUnit() == eCSSUnit_Array; list = list->mNext)
|
||||
if (list->mValue.GetArrayValue()->Item(0).GetImageValue())
|
||||
if (list->mValue.GetArrayValue()->Item(0).GetImageValue(doc))
|
||||
++arrayLength;
|
||||
|
||||
if (arrayLength != 0) {
|
||||
@ -3961,7 +3968,7 @@ nsRuleNode::ComputeUserInterfaceData(void* aStartStruct,
|
||||
list2->mValue.GetUnit() == eCSSUnit_Array;
|
||||
list2 = list2->mNext) {
|
||||
nsCSSValue::Array *arr = list2->mValue.GetArrayValue();
|
||||
imgIRequest *req = arr->Item(0).GetImageValue();
|
||||
imgIRequest *req = arr->Item(0).GetImageValue(doc);
|
||||
if (req) {
|
||||
item->SetImage(req);
|
||||
if (arr->Item(1).GetUnit() != eCSSUnit_Null) {
|
||||
@ -6046,8 +6053,9 @@ nsRuleNode::ComputeBorderData(void* aStartStruct,
|
||||
// border-image-source
|
||||
const nsCSSValue* borderImageSource = aRuleData->ValueForBorderImageSource();
|
||||
if (borderImageSource->GetUnit() == eCSSUnit_Image) {
|
||||
NS_SET_IMAGE_REQUEST(border->SetBorderImage, aContext,
|
||||
borderImageSource->GetImageValue());
|
||||
NS_SET_IMAGE_REQUEST_WITH_DOC(border->SetBorderImage,
|
||||
aContext,
|
||||
borderImageSource->GetImageValue);
|
||||
} else if (borderImageSource->GetUnit() == eCSSUnit_Inherit) {
|
||||
canStoreInRuleTree = false;
|
||||
NS_SET_IMAGE_REQUEST(border->SetBorderImage, aContext,
|
||||
@ -6301,9 +6309,9 @@ nsRuleNode::ComputeListData(void* aStartStruct,
|
||||
// list-style-image: url, none, inherit
|
||||
const nsCSSValue* imageValue = aRuleData->ValueForListStyleImage();
|
||||
if (eCSSUnit_Image == imageValue->GetUnit()) {
|
||||
NS_SET_IMAGE_REQUEST(list->SetListStyleImage,
|
||||
aContext,
|
||||
imageValue->GetImageValue())
|
||||
NS_SET_IMAGE_REQUEST_WITH_DOC(list->SetListStyleImage,
|
||||
aContext,
|
||||
imageValue->GetImageValue)
|
||||
}
|
||||
else if (eCSSUnit_None == imageValue->GetUnit() ||
|
||||
eCSSUnit_Initial == imageValue->GetUnit()) {
|
||||
@ -6727,7 +6735,9 @@ nsRuleNode::ComputeContentData(void* aStartStruct,
|
||||
}
|
||||
data.mType = type;
|
||||
if (type == eStyleContentType_Image) {
|
||||
NS_SET_IMAGE_REQUEST(data.SetImage, aContext, value.GetImageValue());
|
||||
NS_SET_IMAGE_REQUEST_WITH_DOC(data.SetImage,
|
||||
aContext,
|
||||
value.GetImageValue);
|
||||
}
|
||||
else if (type <= eStyleContentType_Attr) {
|
||||
value.GetStringValue(buffer);
|
||||
|
@ -213,6 +213,8 @@ nsTableCellFrame::AttributeChanged(PRInt32 aNameSpaceID,
|
||||
/* virtual */ void
|
||||
nsTableCellFrame::DidSetStyleContext(nsStyleContext* aOldStyleContext)
|
||||
{
|
||||
nsContainerFrame::DidSetStyleContext(aOldStyleContext);
|
||||
|
||||
if (!aOldStyleContext) //avoid this on init
|
||||
return;
|
||||
|
||||
|
@ -54,6 +54,8 @@ nsTableColFrame::SetColType(nsTableColType aType)
|
||||
/* virtual */ void
|
||||
nsTableColFrame::DidSetStyleContext(nsStyleContext* aOldStyleContext)
|
||||
{
|
||||
nsSplittableFrame::DidSetStyleContext(aOldStyleContext);
|
||||
|
||||
if (!aOldStyleContext) //avoid this on init
|
||||
return;
|
||||
|
||||
|
@ -155,6 +155,8 @@ nsTableColGroupFrame::SetInitialChildList(ChildListID aListID,
|
||||
/* virtual */ void
|
||||
nsTableColGroupFrame::DidSetStyleContext(nsStyleContext* aOldStyleContext)
|
||||
{
|
||||
nsContainerFrame::DidSetStyleContext(aOldStyleContext);
|
||||
|
||||
if (!aOldStyleContext) //avoid this on init
|
||||
return;
|
||||
|
||||
|
@ -2023,6 +2023,8 @@ nsTableFrame::GetCollapsedWidth(nsMargin aBorderPadding)
|
||||
/* virtual */ void
|
||||
nsTableFrame::DidSetStyleContext(nsStyleContext* aOldStyleContext)
|
||||
{
|
||||
nsContainerFrame::DidSetStyleContext(aOldStyleContext);
|
||||
|
||||
if (!aOldStyleContext) //avoid this on init
|
||||
return;
|
||||
|
||||
|
@ -158,6 +158,8 @@ nsTableRowFrame::Init(nsIContent* aContent,
|
||||
/* virtual */ void
|
||||
nsTableRowFrame::DidSetStyleContext(nsStyleContext* aOldStyleContext)
|
||||
{
|
||||
nsContainerFrame::DidSetStyleContext(aOldStyleContext);
|
||||
|
||||
if (!aOldStyleContext) //avoid this on init
|
||||
return;
|
||||
|
||||
|
@ -1337,6 +1337,8 @@ nsTableRowGroupFrame::Reflow(nsPresContext* aPresContext,
|
||||
/* virtual */ void
|
||||
nsTableRowGroupFrame::DidSetStyleContext(nsStyleContext* aOldStyleContext)
|
||||
{
|
||||
nsContainerFrame::DidSetStyleContext(aOldStyleContext);
|
||||
|
||||
if (!aOldStyleContext) //avoid this on init
|
||||
return;
|
||||
|
||||
|
@ -608,6 +608,7 @@ function BuildConditionSandbox(aURL) {
|
||||
// Tests shouldn't care about this except for when they need to
|
||||
// crash the content process
|
||||
sandbox.browserIsRemote = gBrowserIsRemote;
|
||||
sandbox.bug685516 = sandbox.browserIsRemote && sandbox.Android;
|
||||
|
||||
if (!gDumpedConditionSandbox) {
|
||||
dump("REFTEST INFO | Dumping JSON representation of sandbox \n");
|
||||
|
@ -3502,9 +3502,6 @@ pref("image.mem.decode_bytes_at_a_time", 4096);
|
||||
// The longest time we can spend in an iteration of an async decode
|
||||
pref("image.mem.max_ms_before_yield", 5);
|
||||
|
||||
// The maximum source data size for which we auto sync decode
|
||||
pref("image.mem.max_bytes_for_sync_decode", 150000);
|
||||
|
||||
// The maximum amount of decoded image data we'll willingly keep around (we
|
||||
// might keep around more than this, but we'll try to get down to this value).
|
||||
pref("image.mem.max_decoded_image_kb", 51200);
|
||||
|
Loading…
Reference in New Issue
Block a user