Bug 969372: part1: Change the prototype of FreezableElementEnumerator in nsIDocument from nsIContent to nsISupports, and rename it to ActivityObservers. r=roc

This commit is contained in:
Benjamin Chen 2014-06-19 10:09:35 +08:00
parent 74c23d0b7e
commit 8bffd58059
15 changed files with 131 additions and 72 deletions

View File

@ -1124,8 +1124,8 @@ protected:
Attr* GetAttributeNodeNSInternal(const nsAString& aNamespaceURI,
const nsAString& aLocalName);
inline void RegisterFreezableElement();
inline void UnregisterFreezableElement();
inline void RegisterActivityObserver();
inline void UnregisterActivityObserver();
/**
* Add/remove this element to the documents id cache

View File

@ -14,15 +14,15 @@ namespace mozilla {
namespace dom {
inline void
Element::RegisterFreezableElement()
Element::RegisterActivityObserver()
{
OwnerDoc()->RegisterFreezableElement(this);
OwnerDoc()->RegisterActivityObserver(this);
}
inline void
Element::UnregisterFreezableElement()
Element::UnregisterActivityObserver()
{
OwnerDoc()->UnregisterFreezableElement(this);
OwnerDoc()->UnregisterActivityObserver(this);
}
}

View File

@ -1697,10 +1697,17 @@ public:
*/
bool IsActive() const { return mDocumentContainer && !mRemovedFromDocShell; }
void RegisterFreezableElement(nsIContent* aContent);
bool UnregisterFreezableElement(nsIContent* aContent);
typedef void (* FreezableElementEnumerator)(nsIContent*, void*);
void EnumerateFreezableElements(FreezableElementEnumerator aEnumerator,
/**
* Register/Unregister the ActivityObserver into mActivityObservers to listen
* the document's activity changes such as OnPageHide, visibility, activity.
* The ActivityObserver objects can be nsIObjectLoadingContent or
* nsIDocumentActivity or HTMLMEdiaElement.
*/
void RegisterActivityObserver(nsISupports* aSupports);
bool UnregisterActivityObserver(nsISupports* aSupports);
// Enumerate all the observers in mActivityObservers by the aEnumerator.
typedef void (* ActivityObserverEnumerator)(nsISupports*, void*);
void EnumerateActivityObservers(ActivityObserverEnumerator aEnumerator,
void* aData);
// Indicates whether mAnimationController has been (lazily) initialized.
@ -2385,11 +2392,12 @@ protected:
nsRefPtr<nsHTMLStyleSheet> mAttrStyleSheet;
nsRefPtr<nsHTMLCSSStyleSheet> mStyleAttrStyleSheet;
// The set of all object, embed, applet, video and audio elements for
// which this is the owner document. (They might not be in the document.)
// The set of all object, embed, applet, video/audio elements or
// nsIObjectLoadingContent or nsIDocumentActivity for which this is the
// owner document. (They might not be in the document.)
// These are non-owning pointers, the elements are responsible for removing
// themselves when they go away.
nsAutoPtr<nsTHashtable<nsPtrHashKey<nsIContent> > > mFreezableElements;
nsAutoPtr<nsTHashtable<nsPtrHashKey<nsISupports> > > mActivityObservers;
// The set of all links that need their status resolved. Links must add themselves
// to this set by calling RegisterPendingLinkUpdate when added to a document and must

View File

@ -6567,12 +6567,13 @@ nsContentUtils::HaveEqualPrincipals(nsIDocument* aDoc1, nsIDocument* aDoc2)
}
static void
CheckForWindowedPlugins(nsIContent* aContent, void* aResult)
CheckForWindowedPlugins(nsISupports* aSupports, void* aResult)
{
if (!aContent->IsInDoc()) {
nsCOMPtr<nsIContent> content(do_QueryInterface(aSupports));
if (!content || !content->IsInDoc()) {
return;
}
nsCOMPtr<nsIObjectLoadingContent> olc(do_QueryInterface(aContent));
nsCOMPtr<nsIObjectLoadingContent> olc(do_QueryInterface(content));
if (!olc) {
return;
}
@ -6592,7 +6593,7 @@ static bool
DocTreeContainsWindowedPlugins(nsIDocument* aDoc, void* aResult)
{
if (!nsContentUtils::IsChromeDoc(aDoc)) {
aDoc->EnumerateFreezableElements(CheckForWindowedPlugins, aResult);
aDoc->EnumerateActivityObservers(CheckForWindowedPlugins, aResult);
}
if (*static_cast<bool*>(aResult)) {
// Return false to stop iteration, we found a windowed plugin.

View File

@ -219,6 +219,7 @@
#include "nsCharSeparatedTokenizer.h"
#include "mozilla/dom/XPathEvaluator.h"
#include "nsIDocumentEncoder.h"
#include "nsIDocumentActivity.h"
#include "nsIStructuredCloneContainer.h"
#include "nsIMutableArray.h"
#include "nsContentPermissionHelper.h"
@ -4357,18 +4358,24 @@ nsDocument::SetScopeObject(nsIGlobalObject* aGlobal)
}
static void
NotifyActivityChanged(nsIContent *aContent, void *aUnused)
NotifyActivityChanged(nsISupports *aSupports, void *aUnused)
{
nsCOMPtr<nsIDOMHTMLMediaElement> domMediaElem(do_QueryInterface(aContent));
nsCOMPtr<nsIDOMHTMLMediaElement> domMediaElem(do_QueryInterface(aSupports));
if (domMediaElem) {
HTMLMediaElement* mediaElem = static_cast<HTMLMediaElement*>(aContent);
nsCOMPtr<nsIContent> content(do_QueryInterface(domMediaElem));
MOZ_ASSERT(content, "aSupports is not a content");
HTMLMediaElement* mediaElem = static_cast<HTMLMediaElement*>(content.get());
mediaElem->NotifyOwnerDocumentActivityChanged();
}
nsCOMPtr<nsIObjectLoadingContent> objectLoadingContent(do_QueryInterface(aContent));
nsCOMPtr<nsIObjectLoadingContent> objectLoadingContent(do_QueryInterface(aSupports));
if (objectLoadingContent) {
nsObjectLoadingContent* olc = static_cast<nsObjectLoadingContent*>(objectLoadingContent.get());
olc->NotifyOwnerDocumentActivityChanged();
}
nsCOMPtr<nsIDocumentActivity> objectDocumentActivity(do_QueryInterface(aSupports));
if (objectDocumentActivity) {
objectDocumentActivity->NotifyOwnerDocumentActivityChanged();
}
}
void
@ -4380,7 +4387,7 @@ nsIDocument::SetContainer(nsDocShell* aContainer)
mDocumentContainer = WeakPtr<nsDocShell>();
}
EnumerateFreezableElements(NotifyActivityChanged, nullptr);
EnumerateActivityObservers(NotifyActivityChanged, nullptr);
if (!aContainer) {
return;
}
@ -8511,7 +8518,7 @@ nsDocument::RemovedFromDocShell()
return;
mRemovedFromDocShell = true;
EnumerateFreezableElements(NotifyActivityChanged, nullptr);
EnumerateActivityObservers(NotifyActivityChanged, nullptr);
uint32_t i, count = mChildren.ChildCount();
for (i = 0; i < count; ++i) {
@ -8763,7 +8770,7 @@ nsDocument::OnPageShow(bool aPersisted,
{
mVisible = true;
EnumerateFreezableElements(NotifyActivityChanged, nullptr);
EnumerateActivityObservers(NotifyActivityChanged, nullptr);
EnumerateExternalResources(NotifyPageShow, &aPersisted);
Element* root = GetRootElement();
@ -8892,7 +8899,7 @@ nsDocument::OnPageHide(bool aPersisted,
UpdateVisibilityState();
EnumerateExternalResources(NotifyPageHide, &aPersisted);
EnumerateFreezableElements(NotifyActivityChanged, nullptr);
EnumerateActivityObservers(NotifyActivityChanged, nullptr);
if (IsFullScreenDoc()) {
// If this document was fullscreen, we should exit fullscreen in this
@ -9589,48 +9596,48 @@ nsDocument::SetChangeScrollPosWhenScrollingToRef(bool aValue)
}
void
nsIDocument::RegisterFreezableElement(nsIContent* aContent)
nsIDocument::RegisterActivityObserver(nsISupports* aSupports)
{
if (!mFreezableElements) {
mFreezableElements = new nsTHashtable<nsPtrHashKey<nsIContent> >();
if (!mFreezableElements)
if (!mActivityObservers) {
mActivityObservers = new nsTHashtable<nsPtrHashKey<nsISupports> >();
if (!mActivityObservers)
return;
}
mFreezableElements->PutEntry(aContent);
mActivityObservers->PutEntry(aSupports);
}
bool
nsIDocument::UnregisterFreezableElement(nsIContent* aContent)
nsIDocument::UnregisterActivityObserver(nsISupports* aSupports)
{
if (!mFreezableElements)
if (!mActivityObservers)
return false;
if (!mFreezableElements->GetEntry(aContent))
if (!mActivityObservers->GetEntry(aSupports))
return false;
mFreezableElements->RemoveEntry(aContent);
mActivityObservers->RemoveEntry(aSupports);
return true;
}
struct EnumerateFreezablesData {
nsIDocument::FreezableElementEnumerator mEnumerator;
struct EnumerateActivityObserversData {
nsIDocument::ActivityObserverEnumerator mEnumerator;
void* mData;
};
static PLDHashOperator
EnumerateFreezables(nsPtrHashKey<nsIContent>* aEntry, void* aData)
EnumerateObservers(nsPtrHashKey<nsISupports>* aEntry, void* aData)
{
EnumerateFreezablesData* data = static_cast<EnumerateFreezablesData*>(aData);
EnumerateActivityObserversData* data = static_cast<EnumerateActivityObserversData*>(aData);
data->mEnumerator(aEntry->GetKey(), data->mData);
return PL_DHASH_NEXT;
}
void
nsIDocument::EnumerateFreezableElements(FreezableElementEnumerator aEnumerator,
nsIDocument::EnumerateActivityObservers(ActivityObserverEnumerator aEnumerator,
void* aData)
{
if (!mFreezableElements)
if (!mActivityObservers)
return;
EnumerateFreezablesData data = { aEnumerator, aData };
mFreezableElements->EnumerateEntries(EnumerateFreezables, &data);
EnumerateActivityObserversData data = { aEnumerator, aData };
mActivityObservers->EnumerateEntries(EnumerateObservers, &data);
}
void
@ -11826,7 +11833,7 @@ nsDocument::UpdateVisibilityState()
/* bubbles = */ true,
/* cancelable = */ false);
EnumerateFreezableElements(NotifyActivityChanged, nullptr);
EnumerateActivityObservers(NotifyActivityChanged, nullptr);
}
}

View File

@ -471,7 +471,7 @@ nsNodeUtils::CloneAndAdopt(nsINode *aNode, bool aClone, bool aDeep,
if (aNode->IsElement()) {
Element* element = aNode->AsElement();
oldDoc->ClearBoxObjectFor(element);
wasRegistered = oldDoc->UnregisterFreezableElement(element);
wasRegistered = oldDoc->UnregisterActivityObserver(element);
}
aNode->mNodeInfo.swap(newNodeInfo);
@ -484,7 +484,7 @@ nsNodeUtils::CloneAndAdopt(nsINode *aNode, bool aClone, bool aDeep,
// XXX what if oldDoc is null, we don't know if this should be
// registered or not! Can that really happen?
if (wasRegistered) {
newDoc->RegisterFreezableElement(aNode->AsElement());
newDoc->RegisterActivityObserver(aNode->AsElement());
}
nsPIDOMWindow* window = newDoc->GetInnerWindow();

View File

@ -2031,7 +2031,7 @@ HTMLMediaElement::HTMLMediaElement(already_AddRefed<nsINodeInfo>& aNodeInfo)
mPaused.SetOuter(this);
RegisterFreezableElement();
RegisterActivityObserver();
NotifyOwnerDocumentActivityChanged();
}
@ -2043,7 +2043,7 @@ HTMLMediaElement::~HTMLMediaElement()
if (mVideoFrameContainer) {
mVideoFrameContainer->ForgetElement();
}
UnregisterFreezableElement();
UnregisterActivityObserver();
if (mDecoder) {
ShutdownDecoder();
}

View File

@ -29,7 +29,7 @@ HTMLObjectElement::HTMLObjectElement(already_AddRefed<nsINodeInfo>& aNodeInfo,
: nsGenericHTMLFormElement(aNodeInfo),
mIsDoneAddingChildren(!aFromParser)
{
RegisterFreezableElement();
RegisterActivityObserver();
SetIsNetworkCreated(aFromParser == FROM_PARSER_NETWORK);
// <object> is always barred from constraint validation.
@ -41,7 +41,7 @@ HTMLObjectElement::HTMLObjectElement(already_AddRefed<nsINodeInfo>& aNodeInfo,
HTMLObjectElement::~HTMLObjectElement()
{
UnregisterFreezableElement();
UnregisterActivityObserver();
DestroyImageLoadingContent();
}

View File

@ -28,7 +28,7 @@ HTMLSharedObjectElement::HTMLSharedObjectElement(already_AddRefed<nsINodeInfo>&
: nsGenericHTMLElement(aNodeInfo),
mIsDoneAddingChildren(mNodeInfo->Equals(nsGkAtoms::embed) || !aFromParser)
{
RegisterFreezableElement();
RegisterActivityObserver();
SetIsNetworkCreated(aFromParser == FROM_PARSER_NETWORK);
// By default we're in the loading state
@ -57,7 +57,7 @@ HTMLSharedObjectElement::SetItemValueText(const nsAString& aValue)
HTMLSharedObjectElement::~HTMLSharedObjectElement()
{
UnregisterFreezableElement();
UnregisterActivityObserver();
DestroyImageLoadingContent();
}

View File

@ -92,6 +92,7 @@ EXPORTS += [
'MediaStreamGraph.h',
'MediaTaskQueue.h',
'MP3FrameParser.h',
'nsIDocumentActivity.h',
'RtspMediaResource.h',
'SharedBuffer.h',
'SharedThreadPool.h',

View File

@ -0,0 +1,29 @@
/* -*- 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/. */
#ifndef nsIDocumentActivity_h__
#define nsIDocumentActivity_h__
#include "nsISupports.h"
#define NS_IDOCUMENTACTIVITY_IID \
{ 0x9b9f584e, 0xefa8, 0x11e3, \
{ 0xbb, 0x74, 0x5e, 0xdd, 0x1d, 0x5d, 0x46, 0xb0 } }
class nsIDocumentActivity : public nsISupports
{
public:
NS_DECLARE_STATIC_IID_ACCESSOR(NS_IDOCUMENTACTIVITY_IID)
virtual void NotifyOwnerDocumentActivityChanged() = 0;
};
NS_DEFINE_STATIC_IID_ACCESSOR(nsIDocumentActivity, NS_IDOCUMENTACTIVITY_IID)
/* Use this macro when declaring classes that implement this interface. */
#define NS_DECL_NSIDOCUMENTACTIVITY \
virtual void NotifyOwnerDocumentActivityChanged() MOZ_OVERRIDE;
#endif /* nsIDocumentActivity_h__ */

View File

@ -8398,9 +8398,9 @@ PresShell::RemoveOverrideStyleSheet(nsIStyleSheet *aSheet)
}
static void
FreezeElement(nsIContent *aContent, void * /* unused */)
FreezeElement(nsISupports *aSupports, void * /* unused */)
{
nsCOMPtr<nsIObjectLoadingContent> olc(do_QueryInterface(aContent));
nsCOMPtr<nsIObjectLoadingContent> olc(do_QueryInterface(aSupports));
if (olc) {
olc->StopPluginInstance();
}
@ -8423,7 +8423,7 @@ PresShell::Freeze()
MaybeReleaseCapturingContent();
mDocument->EnumerateFreezableElements(FreezeElement, nullptr);
mDocument->EnumerateActivityObservers(FreezeElement, nullptr);
if (mCaret) {
SetCaretEnabled(false);
@ -8472,9 +8472,9 @@ PresShell::FireOrClearDelayedEvents(bool aFireEvents)
}
static void
ThawElement(nsIContent *aContent, void *aShell)
ThawElement(nsISupports *aSupports, void *aShell)
{
nsCOMPtr<nsIObjectLoadingContent> olc(do_QueryInterface(aContent));
nsCOMPtr<nsIObjectLoadingContent> olc(do_QueryInterface(aSupports));
if (olc) {
olc->AsyncStartPluginInstance();
}
@ -8499,7 +8499,7 @@ PresShell::Thaw()
presContext->RefreshDriver()->Thaw();
}
mDocument->EnumerateFreezableElements(ThawElement, this);
mDocument->EnumerateActivityObservers(ThawElement, this);
if (mDocument)
mDocument->EnumerateSubDocuments(ThawSubDocument, nullptr);
@ -10384,9 +10384,14 @@ SetExternalResourceIsActive(nsIDocument* aDocument, void* aClosure)
}
static void
SetPluginIsActive(nsIContent* aContent, void* aClosure)
SetPluginIsActive(nsISupports* aSupports, void* aClosure)
{
nsIFrame *frame = aContent->GetPrimaryFrame();
nsCOMPtr<nsIContent> content(do_QueryInterface(aSupports));
if (!content) {
return;
}
nsIFrame *frame = content->GetPrimaryFrame();
nsIObjectFrame *objectFrame = do_QueryFrame(frame);
if (objectFrame) {
objectFrame->SetIsDocumentActive(*static_cast<bool*>(aClosure));
@ -10408,7 +10413,7 @@ PresShell::SetIsActive(bool aIsActive)
// Propagate state-change to my resource documents' PresShells
mDocument->EnumerateExternalResources(SetExternalResourceIsActive,
&aIsActive);
mDocument->EnumerateFreezableElements(SetPluginIsActive,
mDocument->EnumerateActivityObservers(SetPluginIsActive,
&aIsActive);
nsresult rv = UpdateImageLockingState();
#ifdef ACCESSIBILITY

View File

@ -1989,13 +1989,17 @@ nsObjectFrame::GetNextObjectFrame(nsPresContext* aPresContext, nsIFrame* aRoot)
}
/*static*/ void
nsObjectFrame::BeginSwapDocShells(nsIContent* aContent, void*)
nsObjectFrame::BeginSwapDocShells(nsISupports* aSupports, void*)
{
NS_PRECONDITION(aContent, "");
NS_PRECONDITION(aSupports, "");
nsCOMPtr<nsIContent> content(do_QueryInterface(aSupports));
if (!content) {
return;
}
// This function is called from a document content enumerator so we need
// to filter out the nsObjectFrames and ignore the rest.
nsIObjectFrame* obj = do_QueryFrame(aContent->GetPrimaryFrame());
nsIObjectFrame* obj = do_QueryFrame(content->GetPrimaryFrame());
if (!obj)
return;
@ -2006,13 +2010,17 @@ nsObjectFrame::BeginSwapDocShells(nsIContent* aContent, void*)
}
/*static*/ void
nsObjectFrame::EndSwapDocShells(nsIContent* aContent, void*)
nsObjectFrame::EndSwapDocShells(nsISupports* aSupports, void*)
{
NS_PRECONDITION(aContent, "");
NS_PRECONDITION(aSupports, "");
nsCOMPtr<nsIContent> content(do_QueryInterface(aSupports));
if (!content) {
return;
}
// This function is called from a document content enumerator so we need
// to filter out the nsObjectFrames and ignore the rest.
nsIObjectFrame* obj = do_QueryFrame(aContent->GetPrimaryFrame());
nsIObjectFrame* obj = do_QueryFrame(content->GetPrimaryFrame());
if (!obj)
return;

View File

@ -182,17 +182,17 @@ public:
nsRect GetPaintedRect(nsDisplayPlugin* aItem);
/**
* If aContent has a nsObjectFrame, then prepare it for a DocShell swap.
* If aSupports has a nsObjectFrame, then prepare it for a DocShell swap.
* @see nsSubDocumentFrame::BeginSwapDocShells.
* There will be a call to EndSwapDocShells after we were moved to the
* new view tree.
*/
static void BeginSwapDocShells(nsIContent* aContent, void*);
static void BeginSwapDocShells(nsISupports* aSupports, void*);
/**
* If aContent has a nsObjectFrame, then set it up after a DocShell swap.
* If aSupports has a nsObjectFrame, then set it up after a DocShell swap.
* @see nsSubDocumentFrame::EndSwapDocShells.
*/
static void EndSwapDocShells(nsIContent* aContent, void*);
static void EndSwapDocShells(nsISupports* aSupports, void*);
nsIWidget* GetWidget() MOZ_OVERRIDE { return mInnerView ? mWidget : nullptr; }

View File

@ -1004,7 +1004,7 @@ BeginSwapDocShellsForDocument(nsIDocument* aDocument, void*)
::DestroyDisplayItemDataForFrames(rootFrame);
}
}
aDocument->EnumerateFreezableElements(
aDocument->EnumerateActivityObservers(
nsObjectFrame::BeginSwapDocShells, nullptr);
aDocument->EnumerateSubDocuments(BeginSwapDocShellsForDocument, nullptr);
return true;
@ -1101,7 +1101,7 @@ EndSwapDocShellsForDocument(nsIDocument* aDocument, void*)
}
}
aDocument->EnumerateFreezableElements(
aDocument->EnumerateActivityObservers(
nsObjectFrame::EndSwapDocShells, nullptr);
aDocument->EnumerateSubDocuments(EndSwapDocShellsForDocument, nullptr);
return true;