Bug 1392891 - Part 1: Make it possible to create nsContentList objects that don't observe DOM mutations; r=smaug

This commit is contained in:
Ehsan Akhgari 2017-08-26 22:26:55 -04:00
Родитель ebaa749322
Коммит d4f7cc1e85
2 изменённых файлов: 31 добавлений и 12 удалений

Просмотреть файл

@ -422,7 +422,8 @@ nsContentList::nsContentList(nsINode* aRootNode,
int32_t aMatchNameSpaceId, int32_t aMatchNameSpaceId,
nsIAtom* aHTMLMatchAtom, nsIAtom* aHTMLMatchAtom,
nsIAtom* aXMLMatchAtom, nsIAtom* aXMLMatchAtom,
bool aDeep) bool aDeep,
bool aLiveList)
: nsBaseContentList(), : nsBaseContentList(),
mRootNode(aRootNode), mRootNode(aRootNode),
mMatchNameSpaceId(aMatchNameSpaceId), mMatchNameSpaceId(aMatchNameSpaceId),
@ -434,7 +435,8 @@ nsContentList::nsContentList(nsINode* aRootNode,
mState(LIST_DIRTY), mState(LIST_DIRTY),
mDeep(aDeep), mDeep(aDeep),
mFuncMayDependOnAttr(false), mFuncMayDependOnAttr(false),
mIsHTMLDocument(aRootNode->OwnerDoc()->IsHTMLDocument()) mIsHTMLDocument(aRootNode->OwnerDoc()->IsHTMLDocument()),
mIsLiveList(aLiveList)
{ {
NS_ASSERTION(mRootNode, "Must have root"); NS_ASSERTION(mRootNode, "Must have root");
if (nsGkAtoms::_asterisk == mHTMLMatchAtom) { if (nsGkAtoms::_asterisk == mHTMLMatchAtom) {
@ -444,7 +446,9 @@ nsContentList::nsContentList(nsINode* aRootNode,
else { else {
mMatchAll = false; mMatchAll = false;
} }
mRootNode->AddMutationObserver(this); if (mIsLiveList) {
mRootNode->AddMutationObserver(this);
}
// We only need to flush if we're in an non-HTML document, since the // We only need to flush if we're in an non-HTML document, since the
// HTML5 parser doesn't need flushing. Further, if we're not in a // HTML5 parser doesn't need flushing. Further, if we're not in a
@ -462,7 +466,8 @@ nsContentList::nsContentList(nsINode* aRootNode,
bool aDeep, bool aDeep,
nsIAtom* aMatchAtom, nsIAtom* aMatchAtom,
int32_t aMatchNameSpaceId, int32_t aMatchNameSpaceId,
bool aFuncMayDependOnAttr) bool aFuncMayDependOnAttr,
bool aLiveList)
: nsBaseContentList(), : nsBaseContentList(),
mRootNode(aRootNode), mRootNode(aRootNode),
mMatchNameSpaceId(aMatchNameSpaceId), mMatchNameSpaceId(aMatchNameSpaceId),
@ -475,10 +480,13 @@ nsContentList::nsContentList(nsINode* aRootNode,
mMatchAll(false), mMatchAll(false),
mDeep(aDeep), mDeep(aDeep),
mFuncMayDependOnAttr(aFuncMayDependOnAttr), mFuncMayDependOnAttr(aFuncMayDependOnAttr),
mIsHTMLDocument(false) mIsHTMLDocument(false),
mIsLiveList(aLiveList)
{ {
NS_ASSERTION(mRootNode, "Must have root"); NS_ASSERTION(mRootNode, "Must have root");
mRootNode->AddMutationObserver(this); if (mIsLiveList) {
mRootNode->AddMutationObserver(this);
}
// We only need to flush if we're in an non-HTML document, since the // We only need to flush if we're in an non-HTML document, since the
// HTML5 parser doesn't need flushing. Further, if we're not in a // HTML5 parser doesn't need flushing. Further, if we're not in a
@ -492,7 +500,7 @@ nsContentList::nsContentList(nsINode* aRootNode,
nsContentList::~nsContentList() nsContentList::~nsContentList()
{ {
RemoveFromHashtable(); RemoveFromHashtable();
if (mRootNode) { if (mIsLiveList && mRootNode) {
mRootNode->RemoveMutationObserver(this); mRootNode->RemoveMutationObserver(this);
} }
@ -646,7 +654,7 @@ void
nsContentList::LastRelease() nsContentList::LastRelease()
{ {
RemoveFromCaches(); RemoveFromCaches();
if (mRootNode) { if (mIsLiveList && mRootNode) {
mRootNode->RemoveMutationObserver(this); mRootNode->RemoveMutationObserver(this);
mRootNode = nullptr; mRootNode = nullptr;
} }
@ -1246,6 +1254,7 @@ nsLabelsNodeList::MaybeResetRoot(nsINode* aRootNode)
return; return;
} }
MOZ_ASSERT(mIsLiveList, "nsLabelsNodeList is always a live list");
if (mRootNode) { if (mRootNode) {
mRootNode->RemoveMutationObserver(this); mRootNode->RemoveMutationObserver(this);
} }

Просмотреть файл

@ -251,8 +251,8 @@ struct nsContentListKey
#define LIST_LAZY 2 #define LIST_LAZY 2
/** /**
* Class that implements a live NodeList that matches Elements in the * Class that implements a possibly live NodeList that matches Elements
* tree based on some criterion. * in the tree based on some criterion.
*/ */
class nsContentList : public nsBaseContentList, class nsContentList : public nsBaseContentList,
public nsIHTMLCollection, public nsIHTMLCollection,
@ -276,12 +276,15 @@ public:
* @param aDeep If false, then look only at children of the root, nothing * @param aDeep If false, then look only at children of the root, nothing
* deeper. If true, then look at the whole subtree rooted at * deeper. If true, then look at the whole subtree rooted at
* our root. * our root.
* @param aLiveList Whether the created list should be a live list observing
* mutations to the DOM tree.
*/ */
nsContentList(nsINode* aRootNode, nsContentList(nsINode* aRootNode,
int32_t aMatchNameSpaceId, int32_t aMatchNameSpaceId,
nsIAtom* aHTMLMatchAtom, nsIAtom* aHTMLMatchAtom,
nsIAtom* aXMLMatchAtom, nsIAtom* aXMLMatchAtom,
bool aDeep = true); bool aDeep = true,
bool aLiveList = true);
/** /**
* @param aRootNode The node under which to limit our search. * @param aRootNode The node under which to limit our search.
@ -298,6 +301,8 @@ public:
* @param aMatchNameSpaceId a namespace id to be passed back to aFunc * @param aMatchNameSpaceId a namespace id to be passed back to aFunc
* @param aFuncMayDependOnAttr a boolean that indicates whether this list is * @param aFuncMayDependOnAttr a boolean that indicates whether this list is
* sensitive to attribute changes. * sensitive to attribute changes.
* @param aLiveList Whether the created list should be a live list observing
* mutations to the DOM tree.
*/ */
nsContentList(nsINode* aRootNode, nsContentList(nsINode* aRootNode,
nsContentListMatchFunc aFunc, nsContentListMatchFunc aFunc,
@ -306,7 +311,8 @@ public:
bool aDeep = true, bool aDeep = true,
nsIAtom* aMatchAtom = nullptr, nsIAtom* aMatchAtom = nullptr,
int32_t aMatchNameSpaceId = kNameSpaceID_None, int32_t aMatchNameSpaceId = kNameSpaceID_None,
bool aFuncMayDependOnAttr = true); bool aFuncMayDependOnAttr = true,
bool aLiveList = true);
// nsWrapperCache // nsWrapperCache
using nsWrapperCache::GetWrapperPreserveColor; using nsWrapperCache::GetWrapperPreserveColor;
@ -517,6 +523,10 @@ protected:
* when doing function matching, always false otherwise. * when doing function matching, always false otherwise.
*/ */
uint8_t mIsHTMLDocument : 1; uint8_t mIsHTMLDocument : 1;
/**
* Whether the list observes mutations to the DOM tree.
*/
const uint8_t mIsLiveList : 1;
#ifdef DEBUG_CONTENT_LIST #ifdef DEBUG_CONTENT_LIST
void AssertInSync(); void AssertInSync();