зеркало из https://github.com/mozilla/gecko-dev.git
Merge mozilla-central to mozilla-inbound
This commit is contained in:
Коммит
858c0c3001
|
@ -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); }
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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 =
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
Загрузка…
Ссылка в новой задаче