Merge mozilla-central to mozilla-inbound

This commit is contained in:
Ed Morley 2012-08-15 19:00:48 +01:00
commit 57fe127515
87 changed files with 1685 additions and 1197 deletions

View File

@ -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 \

View File

@ -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

View File

@ -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);
};

View File

@ -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.

View File

@ -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)

View File

@ -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)

View File

@ -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!

View File

@ -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;
}

View File

@ -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;

View File

@ -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
{

View File

@ -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;
}

View File

@ -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,

View File

@ -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;

View File

@ -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;

View File

@ -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) {

View File

@ -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

View File

@ -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

View File

@ -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

View 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>

View File

@ -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()
{

View File

@ -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;

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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
{

View File

@ -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;

View File

@ -23,6 +23,7 @@ XPIDLSRCS = \
imgIDecoderObserver.idl \
imgIEncoder.idl \
imgILoader.idl \
imgIOnloadBlocker.idl \
imgIRequest.idl \
imgITools.idl \
$(NULL)

View 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);
};

View File

@ -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()
{

View File

@ -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;

View File

@ -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;

View File

@ -230,6 +230,7 @@ private:
bool mIsMultiPartChannel : 1;
bool mGotData : 1;
bool mIsInCache : 1;
bool mBlockingOnload : 1;
};
#endif

View File

@ -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

View File

@ -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);

View File

@ -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();
}
}

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -77,7 +77,6 @@ CPPSRCS = \
nsFrameManager.cpp \
nsFrameIterator.cpp \
nsGenConList.cpp \
nsImageLoader.cpp \
nsLayoutDebugger.cpp \
nsLayoutHistoryState.cpp \
nsLayoutUtils.cpp \

View File

@ -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.

View File

@ -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);
}
}

View File

@ -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;
};

View File

@ -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;
}

View File

@ -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

View File

@ -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);

View File

@ -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

View File

@ -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);
}
}

View File

@ -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()
{

View File

@ -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

View File

@ -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 \

View File

@ -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>

View File

@ -0,0 +1,2 @@
<!DOCTYPE html>
<img src="really-big-background.png" style="width: 1600px; height: 1200px; position: absolute;">

View File

@ -0,0 +1,2 @@
<!DOCTYPE html>
<img style="background-image: url(really-big-background.png); width: 1600px; height: 1200px; position: absolute;"></img>

Binary file not shown.

After

Width:  |  Height:  |  Size: 184 KiB

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View 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
View 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

View File

@ -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 \

View File

@ -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);
}
}

View File

@ -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()

View File

@ -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

View File

@ -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);

View File

@ -213,6 +213,8 @@ nsTableCellFrame::AttributeChanged(PRInt32 aNameSpaceID,
/* virtual */ void
nsTableCellFrame::DidSetStyleContext(nsStyleContext* aOldStyleContext)
{
nsContainerFrame::DidSetStyleContext(aOldStyleContext);
if (!aOldStyleContext) //avoid this on init
return;

View File

@ -54,6 +54,8 @@ nsTableColFrame::SetColType(nsTableColType aType)
/* virtual */ void
nsTableColFrame::DidSetStyleContext(nsStyleContext* aOldStyleContext)
{
nsSplittableFrame::DidSetStyleContext(aOldStyleContext);
if (!aOldStyleContext) //avoid this on init
return;

View File

@ -155,6 +155,8 @@ nsTableColGroupFrame::SetInitialChildList(ChildListID aListID,
/* virtual */ void
nsTableColGroupFrame::DidSetStyleContext(nsStyleContext* aOldStyleContext)
{
nsContainerFrame::DidSetStyleContext(aOldStyleContext);
if (!aOldStyleContext) //avoid this on init
return;

View File

@ -2023,6 +2023,8 @@ nsTableFrame::GetCollapsedWidth(nsMargin aBorderPadding)
/* virtual */ void
nsTableFrame::DidSetStyleContext(nsStyleContext* aOldStyleContext)
{
nsContainerFrame::DidSetStyleContext(aOldStyleContext);
if (!aOldStyleContext) //avoid this on init
return;

View File

@ -158,6 +158,8 @@ nsTableRowFrame::Init(nsIContent* aContent,
/* virtual */ void
nsTableRowFrame::DidSetStyleContext(nsStyleContext* aOldStyleContext)
{
nsContainerFrame::DidSetStyleContext(aOldStyleContext);
if (!aOldStyleContext) //avoid this on init
return;

View File

@ -1337,6 +1337,8 @@ nsTableRowGroupFrame::Reflow(nsPresContext* aPresContext,
/* virtual */ void
nsTableRowGroupFrame::DidSetStyleContext(nsStyleContext* aOldStyleContext)
{
nsContainerFrame::DidSetStyleContext(aOldStyleContext);
if (!aOldStyleContext) //avoid this on init
return;

View File

@ -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");

View File

@ -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);