Merge mozilla-central to mozilla-inbound

This commit is contained in:
Ed Morley 2012-02-28 02:55:32 +00:00
commit 0610770d3b
11 changed files with 65 additions and 34 deletions

View File

@ -89,8 +89,7 @@ class Element;
} // namespace mozilla
enum {
// This bit will be set if the node has a listener manager in the listener
// manager hash
// This bit will be set if the node has a listener manager.
NODE_HAS_LISTENERMANAGER = 0x00000001U,
// Whether this node has had any properties set on it
@ -1308,6 +1307,7 @@ public:
{ SetBoolFlag(NodeIsPurpleRoot, aValue); }
bool IsPurpleRoot() const { return GetBoolFlag(NodeIsPurpleRoot); }
bool HasListenerManager() { return HasFlag(NODE_HAS_LISTENERMANAGER); }
protected:
void SetParentIsContent(bool aValue) { SetBoolFlag(ParentIsContent, aValue); }
void SetInDocument() { SetBoolFlag(IsInDocument); }

View File

@ -1636,6 +1636,7 @@ nsDocument::~nsDocument()
if (mListenerManager) {
mListenerManager->Disconnect();
UnsetFlags(NODE_HAS_LISTENERMANAGER);
}
if (mScriptLoader) {
@ -1950,6 +1951,7 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsDocument)
if (tmp->mListenerManager) {
tmp->mListenerManager->Disconnect();
tmp->UnsetFlags(NODE_HAS_LISTENERMANAGER);
tmp->mListenerManager = nsnull;
}
@ -6215,6 +6217,7 @@ nsDocument::GetListenerManager(bool aCreateIfNotFound)
if (!mListenerManager && aCreateIfNotFound) {
mListenerManager =
new nsEventListenerManager(static_cast<nsIDOMEventTarget*>(this));
SetFlags(NODE_HAS_LISTENERMANAGER);
}
return mListenerManager;

View File

@ -1268,7 +1268,8 @@ nsINode::Traverse(nsINode *tmp, nsCycleCollectionTraversalCallback &cb)
nsNodeUtils::TraverseUserData(tmp, cb);
}
if (tmp->HasFlag(NODE_HAS_LISTENERMANAGER)) {
if (tmp->NodeType() != nsIDOMNode::DOCUMENT_NODE &&
tmp->HasFlag(NODE_HAS_LISTENERMANAGER)) {
nsContentUtils::TraverseListenerManager(tmp, cb);
}
@ -1286,7 +1287,8 @@ nsINode::Unlink(nsINode *tmp)
slots->Unlink();
}
if (tmp->HasFlag(NODE_HAS_LISTENERMANAGER)) {
if (tmp->NodeType() != nsIDOMNode::DOCUMENT_NODE &&
tmp->HasFlag(NODE_HAS_LISTENERMANAGER)) {
nsContentUtils::RemoveListenerManager(tmp);
tmp->UnsetFlags(NODE_HAS_LISTENERMANAGER);
}
@ -3383,7 +3385,7 @@ nsIContent::PreHandleEvent(nsEventChainPreVisitor& aVisitor)
{
//FIXME! Document how this event retargeting works, Bug 329124.
aVisitor.mCanHandle = true;
aVisitor.mMayHaveListenerManager = HasFlag(NODE_HAS_LISTENERMANAGER);
aVisitor.mMayHaveListenerManager = HasListenerManager();
// Don't propagate mouseover and mouseout events when mouse is moving
// inside native anonymous content.
@ -4636,7 +4638,7 @@ ShouldClearPurple(nsIContent* aContent)
return true;
}
if (aContent->GetListenerManager(false)) {
if (aContent->HasListenerManager()) {
return true;
}

View File

@ -282,7 +282,8 @@ nsNodeUtils::LastRelease(nsINode* aNode)
}
aNode->UnsetFlags(NODE_HAS_PROPERTIES);
if (aNode->HasFlag(NODE_HAS_LISTENERMANAGER)) {
if (aNode->NodeType() != nsIDOMNode::DOCUMENT_NODE &&
aNode->HasFlag(NODE_HAS_LISTENERMANAGER)) {
#ifdef DEBUG
if (nsContentUtils::IsInitialized()) {
nsEventListenerManager* manager =

View File

@ -556,7 +556,7 @@ nsObjectLoadingContent::nsObjectLoadingContent()
, mNetworkCreated(true)
// If plugins.click_to_play is false, plugins should always play
, mShouldPlay(!mozilla::Preferences::GetBool("plugins.click_to_play", false))
, mSrcStreamLoadInitiated(false)
, mSrcStreamLoading(false)
, mFallbackReason(ePluginOtherState)
{
}
@ -692,8 +692,6 @@ nsObjectLoadingContent::OnStartRequest(nsIRequest *aRequest,
{
SAMPLE_LABEL("nsObjectLoadingContent", "OnStartRequest");
mSrcStreamLoadInitiated = true;
if (aRequest != mChannel || !aRequest) {
// This is a bit of an edge case - happens when a new load starts before the
// previous one got here
@ -883,7 +881,7 @@ nsObjectLoadingContent::OnStartRequest(nsIRequest *aRequest,
if (!pluginHost) {
return NS_ERROR_NOT_AVAILABLE;
}
pluginHost->InstantiatePluginForChannel(chan, this, getter_AddRefs(mFinalListener));
pluginHost->CreateListenerForChannel(chan, this, getter_AddRefs(mFinalListener));
break;
}
case eType_Loading:
@ -906,7 +904,9 @@ nsObjectLoadingContent::OnStartRequest(nsIRequest *aRequest,
if (mFinalListener) {
mType = newType;
mSrcStreamLoading = true;
rv = mFinalListener->OnStartRequest(aRequest, aContext);
mSrcStreamLoading = false;
if (NS_FAILED(rv)) {
#ifdef XP_MACOSX
// Shockwave on Mac is special and returns an error here even when it
@ -2111,7 +2111,6 @@ nsObjectLoadingContent::PlayPlugin()
if (!nsContentUtils::IsCallerChrome())
return NS_OK;
mSrcStreamLoadInitiated = false;
mShouldPlay = true;
return LoadObject(mURI, true, mContentType, true);
}

View File

@ -151,7 +151,7 @@ class nsObjectLoadingContent : public nsImageLoadingContent
void NotifyOwnerDocumentActivityChanged();
bool SrcStreamLoadInitiated() { return mSrcStreamLoadInitiated; };
bool SrcStreamLoading() { return mSrcStreamLoading; };
protected:
/**
@ -401,9 +401,12 @@ class nsObjectLoadingContent : public nsImageLoadingContent
// This is used for click-to-play plugins.
bool mShouldPlay : 1;
// Used to indicate that a stream for a src/data attribute has been
// initiated so that we don't do it twice.
bool mSrcStreamLoadInitiated;
// Used to track when we might try to instantiate a plugin instance based on
// a src data stream being delivered to this object. When this is true we don't
// want plugin instance instantiation code to attempt to load src data again or
// we'll deliver duplicate streams. Should be cleared when we are not loading
// src data.
bool mSrcStreamLoading;
// A specific state that caused us to fallback
PluginSupportState mFallbackReason;

View File

@ -181,6 +181,7 @@ static PRUint32 sForgetSkippableBeforeCC = 0;
static PRUint32 sPreviousSuspectedCount = 0;
static bool sCleanupSinceLastGC = true;
static bool sNeedsFullCC = false;
nsScriptNameSpaceManager *gNameSpaceManager;
@ -3340,6 +3341,7 @@ nsJSContext::CycleCollectNow(nsICycleCollectorListener *aListener,
sRemovedPurples = 0;
sForgetSkippableBeforeCC = 0;
sCleanupSinceLastGC = true;
sNeedsFullCC = false;
}
// static
@ -3395,7 +3397,8 @@ CCTimerFired(nsITimer *aTimer, void *aClosure)
} else {
sPreviousSuspectedCount = 0;
nsJSContext::KillCCTimer();
if (nsCycleCollector_suspectedCount() > 500 ||
if (sNeedsFullCC ||
nsCycleCollector_suspectedCount() > 500 ||
sLastCCEndTime + NS_CC_FORCED < PR_Now()) {
nsJSContext::CycleCollectNow();
}
@ -3493,7 +3496,8 @@ nsJSContext::MaybePokeCC()
return;
}
if (nsCycleCollector_suspectedCount() > 100 ||
if (sNeedsFullCC ||
nsCycleCollector_suspectedCount() > 100 ||
sLastCCEndTime + NS_CC_FORCED < PR_Now()) {
sCCTimerFireCount = 0;
CallCreateInstance("@mozilla.org/timer;1", &sCCTimer);
@ -3608,6 +3612,7 @@ DOMGCSliceCallback(JSRuntime *aRt, js::GCProgress aProgress, const js::GCDescrip
// If this was a full GC, poke the CC to run soon.
if (!aDesc.isCompartment) {
sGCHasRun = true;
sNeedsFullCC = true;
nsJSContext::MaybePokeCC();
}
}
@ -3721,6 +3726,7 @@ nsJSRuntime::Startup()
sLoadingInProgress = false;
sCCollectedWaitingForGC = 0;
sPostGCEventsToConsole = false;
sNeedsFullCC = false;
gNameSpaceManager = nsnull;
sRuntimeService = nsnull;
sRuntime = nsnull;

View File

@ -932,9 +932,9 @@ nsPluginHost::GetPluginTempDir(nsIFile **aDir)
return sPluginTempDir->Clone(aDir);
}
nsresult nsPluginHost::InstantiatePluginForChannel(nsIChannel* aChannel,
nsObjectLoadingContent* aContent,
nsIStreamListener** aListener)
nsresult nsPluginHost::CreateListenerForChannel(nsIChannel* aChannel,
nsObjectLoadingContent* aContent,
nsIStreamListener** aListener)
{
NS_PRECONDITION(aChannel && aContent,
"Invalid arguments to InstantiatePluginForChannel");
@ -1068,7 +1068,7 @@ nsPluginHost::InstantiateEmbeddedPlugin(const char *aMimeType, nsIURI* aURL,
// if we don't have a MIME type at this point, we still have one more chance by
// opening the stream and seeing if the server hands one back
if (!aMimeType) {
if (bCanHandleInternally && !aContent->SrcStreamLoadInitiated()) {
if (bCanHandleInternally && !aContent->SrcStreamLoading()) {
NewEmbeddedPluginStream(aURL, aContent, nsnull);
}
return NS_ERROR_FAILURE;
@ -1096,7 +1096,7 @@ nsPluginHost::InstantiateEmbeddedPlugin(const char *aMimeType, nsIURI* aURL,
// no need to check for "data" as it would have been converted to "src"
const char *value;
bool havedata = NS_SUCCEEDED(pti->GetAttribute("SRC", &value));
if (havedata && !isJava && bCanHandleInternally && !aContent->SrcStreamLoadInitiated()) {
if (havedata && !isJava && bCanHandleInternally && !aContent->SrcStreamLoading()) {
NewEmbeddedPluginStream(aURL, nsnull, instance.get());
}
}

View File

@ -113,9 +113,9 @@ public:
nsresult Init();
nsresult Destroy();
nsresult LoadPlugins();
nsresult InstantiatePluginForChannel(nsIChannel* aChannel,
nsObjectLoadingContent* aContent,
nsIStreamListener** aListener);
nsresult CreateListenerForChannel(nsIChannel* aChannel,
nsObjectLoadingContent* aContent,
nsIStreamListener** aListener);
nsresult SetUpPluginInstance(const char *aMimeType,
nsIURI *aURL,
nsIPluginInstanceOwner *aOwner);

View File

@ -101,26 +101,27 @@ nsFormFillController::nsFormFillController() :
struct PwmgrInputsEnumData
{
PwmgrInputsEnumData(nsIMutationObserver* aMutationObserver, nsIDocument* aDoc)
: mMutationObserver(aMutationObserver), mDoc(aDoc) {}
PwmgrInputsEnumData(nsFormFillController* aFFC, nsIDocument* aDoc)
: mFFC(aFFC), mDoc(aDoc) {}
nsIMutationObserver* mMutationObserver;
nsFormFillController* mFFC;
nsCOMPtr<nsIDocument> mDoc;
};
nsFormFillController::~nsFormFillController()
{
PwmgrInputsEnumData ed(this, nsnull);
mPwmgrInputs.Enumerate(RemoveForDocumentEnumerator, &ed);
if (mListNode) {
mListNode->RemoveMutationObserver(this);
mListNode = nsnull;
}
if (mFocusedInputNode) {
mFocusedInputNode->RemoveMutationObserver(this);
MaybeRemoveMutationObserver(mFocusedInputNode);
mFocusedInputNode = nsnull;
mFocusedInput = nsnull;
}
PwmgrInputsEnumData ed(this, nsnull);
mPwmgrInputs.Enumerate(RemoveForDocumentEnumerator, &ed);
// Remove ourselves as a focus listener from all cached docShells
PRUint32 count;
mDocShells->Count(&count);
@ -221,6 +222,17 @@ nsFormFillController::NodeWillBeDestroyed(const nsINode* aNode)
}
}
void
nsFormFillController::MaybeRemoveMutationObserver(nsINode* aNode)
{
// Nodes being tracked in mPwmgrInputs will have their observers removed when
// they stop being tracked.
bool dummy;
if (!mPwmgrInputs.Get(aNode, &dummy)) {
aNode->RemoveMutationObserver(this);
}
}
////////////////////////////////////////////////////////////////////////
//// nsIFormFillController
@ -796,7 +808,10 @@ nsFormFillController::RemoveForDocumentEnumerator(const nsINode* aKey,
{
PwmgrInputsEnumData* ed = static_cast<PwmgrInputsEnumData*>(aUserData);
if (aKey && (!ed->mDoc || aKey->OwnerDoc() == ed->mDoc)) {
const_cast<nsINode*>(aKey)->RemoveMutationObserver(ed->mMutationObserver);
// mFocusedInputNode's observer is tracked separately, don't remove it here.
if (aKey != ed->mFFC->mFocusedInputNode) {
const_cast<nsINode*>(aKey)->RemoveMutationObserver(ed->mFFC);
}
return PL_DHASH_REMOVE;
}
return PL_DHASH_NEXT;
@ -1105,7 +1120,7 @@ nsFormFillController::StopControllingInput()
mController->SetInput(nsnull);
if (mFocusedInputNode) {
mFocusedInputNode->RemoveMutationObserver(this);
MaybeRemoveMutationObserver(mFocusedInputNode);
mFocusedInputNode = nsnull;
mFocusedInput = nsnull;
}

View File

@ -101,6 +101,8 @@ protected:
inline nsIDOMWindow *GetWindowForDocShell(nsIDocShell *aDocShell);
inline PRInt32 GetIndexOfDocShell(nsIDocShell *aDocShell);
void MaybeRemoveMutationObserver(nsINode* aNode);
static PLDHashOperator RemoveForDocumentEnumerator(const nsINode* aKey,
bool& aEntry,
void* aUserData);