mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1242989 - keep content insertions in a hash, r=tbsaunde
This commit is contained in:
parent
1ddcd0e16e
commit
ca3cb36d0e
@ -52,7 +52,16 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(NotificationController)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mHangingChildDocuments)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mContentInsertions)
|
||||
for (auto it = tmp->mContentInsertions.ConstIter(); !it.Done(); it.Next()) {
|
||||
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mContentInsertions key");
|
||||
cb.NoteXPCOMChild(it.Key());
|
||||
nsTArray<nsCOMPtr<nsIContent>>* list = it.UserData();
|
||||
for (uint32_t i = 0; i < list->Length(); i++) {
|
||||
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb,
|
||||
"mContentInsertions value item");
|
||||
cb.NoteXPCOMChild(list->ElementAt(i));
|
||||
}
|
||||
}
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mEvents)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mRelocations)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||
@ -103,10 +112,23 @@ NotificationController::ScheduleContentInsertion(Accessible* aContainer,
|
||||
nsIContent* aStartChildNode,
|
||||
nsIContent* aEndChildNode)
|
||||
{
|
||||
RefPtr<ContentInsertion> insertion = new ContentInsertion(mDocument,
|
||||
aContainer);
|
||||
if (insertion && insertion->InitChildList(aStartChildNode, aEndChildNode) &&
|
||||
mContentInsertions.AppendElement(insertion)) {
|
||||
nsTArray<nsCOMPtr<nsIContent>>* list =
|
||||
mContentInsertions.LookupOrAdd(aContainer);
|
||||
|
||||
bool needsProcessing = false;
|
||||
nsIContent* node = aStartChildNode;
|
||||
while (node != aEndChildNode) {
|
||||
// Notification triggers for content insertion even if no content was
|
||||
// actually inserted, check if the given content has a frame to discard
|
||||
// this case early.
|
||||
if (node->GetPrimaryFrame()) {
|
||||
if (list->AppendElement(node))
|
||||
needsProcessing = true;
|
||||
}
|
||||
node = node->GetNextSibling();
|
||||
}
|
||||
|
||||
if (needsProcessing) {
|
||||
ScheduleProcessing();
|
||||
}
|
||||
}
|
||||
@ -130,7 +152,7 @@ NotificationController::IsUpdatePending()
|
||||
{
|
||||
return mPresShell->IsLayoutFlushObserver() ||
|
||||
mObservingState == eRefreshProcessingForUpdate ||
|
||||
mContentInsertions.Length() != 0 || mNotifications.Length() != 0 ||
|
||||
mContentInsertions.Count() != 0 || mNotifications.Length() != 0 ||
|
||||
mTextHash.Count() != 0 ||
|
||||
!mDocument->HasLoadState(DocAccessible::eTreeConstructed);
|
||||
}
|
||||
@ -178,7 +200,7 @@ NotificationController::WillRefresh(mozilla::TimeStamp aTime)
|
||||
|
||||
mDocument->DoInitialUpdate();
|
||||
|
||||
NS_ASSERTION(mContentInsertions.Length() == 0,
|
||||
NS_ASSERTION(mContentInsertions.Count() == 0,
|
||||
"Pending content insertions while initial accessible tree isn't created!");
|
||||
}
|
||||
|
||||
@ -196,15 +218,13 @@ NotificationController::WillRefresh(mozilla::TimeStamp aTime)
|
||||
// document accessible.
|
||||
|
||||
// Process only currently queued content inserted notifications.
|
||||
nsTArray<RefPtr<ContentInsertion> > contentInsertions;
|
||||
contentInsertions.SwapElements(mContentInsertions);
|
||||
|
||||
uint32_t insertionCount = contentInsertions.Length();
|
||||
for (uint32_t idx = 0; idx < insertionCount; idx++) {
|
||||
contentInsertions[idx]->Process();
|
||||
if (!mDocument)
|
||||
for (auto iter = mContentInsertions.ConstIter(); !iter.Done(); iter.Next()) {
|
||||
mDocument->ProcessContentInserted(iter.Key(), iter.UserData());
|
||||
if (!mDocument) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
mContentInsertions.Clear();
|
||||
|
||||
// Process rendered text change notifications.
|
||||
for (auto iter = mTextHash.Iter(); !iter.Done(); iter.Next()) {
|
||||
@ -403,7 +423,7 @@ NotificationController::WillRefresh(mozilla::TimeStamp aTime)
|
||||
|
||||
// Stop further processing if there are no new notifications of any kind or
|
||||
// events and document load is processed.
|
||||
if (mContentInsertions.IsEmpty() && mNotifications.IsEmpty() &&
|
||||
if (mContentInsertions.Count() == 0 && mNotifications.IsEmpty() &&
|
||||
mEvents.IsEmpty() && mTextHash.Count() == 0 &&
|
||||
mHangingChildDocuments.IsEmpty() &&
|
||||
mDocument->HasLoadState(DocAccessible::eCompletelyLoaded) &&
|
||||
@ -411,53 +431,3 @@ NotificationController::WillRefresh(mozilla::TimeStamp aTime)
|
||||
mObservingState = eNotObservingRefresh;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// NotificationController: content inserted notification
|
||||
|
||||
NotificationController::ContentInsertion::
|
||||
ContentInsertion(DocAccessible* aDocument, Accessible* aContainer) :
|
||||
mDocument(aDocument), mContainer(aContainer)
|
||||
{
|
||||
}
|
||||
|
||||
bool
|
||||
NotificationController::ContentInsertion::
|
||||
InitChildList(nsIContent* aStartChildNode, nsIContent* aEndChildNode)
|
||||
{
|
||||
bool haveToUpdate = false;
|
||||
|
||||
nsIContent* node = aStartChildNode;
|
||||
while (node != aEndChildNode) {
|
||||
// Notification triggers for content insertion even if no content was
|
||||
// actually inserted, check if the given content has a frame to discard
|
||||
// this case early.
|
||||
if (node->GetPrimaryFrame()) {
|
||||
if (mInsertedContent.AppendElement(node))
|
||||
haveToUpdate = true;
|
||||
}
|
||||
|
||||
node = node->GetNextSibling();
|
||||
}
|
||||
|
||||
return haveToUpdate;
|
||||
}
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION(NotificationController::ContentInsertion,
|
||||
mContainer)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(NotificationController::ContentInsertion,
|
||||
AddRef)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(NotificationController::ContentInsertion,
|
||||
Release)
|
||||
|
||||
void
|
||||
NotificationController::ContentInsertion::Process()
|
||||
{
|
||||
mDocument->ProcessContentInserted(mContainer, &mInsertedContent);
|
||||
|
||||
mDocument = nullptr;
|
||||
mContainer = nullptr;
|
||||
mInsertedContent.Clear();
|
||||
}
|
||||
|
||||
|
@ -247,44 +247,10 @@ private:
|
||||
nsTArray<RefPtr<DocAccessible> > mHangingChildDocuments;
|
||||
|
||||
/**
|
||||
* Storage for content inserted notification information.
|
||||
* Pending accessible tree update notifications for content insertions.
|
||||
*/
|
||||
class ContentInsertion
|
||||
{
|
||||
public:
|
||||
ContentInsertion(DocAccessible* aDocument, Accessible* aContainer);
|
||||
|
||||
NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(ContentInsertion)
|
||||
NS_DECL_CYCLE_COLLECTION_NATIVE_CLASS(ContentInsertion)
|
||||
|
||||
bool InitChildList(nsIContent* aStartChildNode, nsIContent* aEndChildNode);
|
||||
void Process();
|
||||
|
||||
protected:
|
||||
virtual ~ContentInsertion() { mDocument = nullptr; }
|
||||
|
||||
private:
|
||||
ContentInsertion();
|
||||
ContentInsertion(const ContentInsertion&);
|
||||
ContentInsertion& operator = (const ContentInsertion&);
|
||||
|
||||
// The document used to process content insertion, matched to document of
|
||||
// the notification controller that this notification belongs to, therefore
|
||||
// it's ok to keep it as weak ref.
|
||||
DocAccessible* mDocument;
|
||||
|
||||
// The container accessible that content insertion occurs within.
|
||||
RefPtr<Accessible> mContainer;
|
||||
|
||||
// Array of inserted contents.
|
||||
nsTArray<nsCOMPtr<nsIContent> > mInsertedContent;
|
||||
};
|
||||
|
||||
/**
|
||||
* A pending accessible tree update notifications for content insertions.
|
||||
* Don't make this an AutoTArray; we use SwapElements() on it.
|
||||
*/
|
||||
nsTArray<RefPtr<ContentInsertion> > mContentInsertions;
|
||||
nsClassHashtable<nsRefPtrHashKey<Accessible>,
|
||||
nsTArray<nsCOMPtr<nsIContent>>> mContentInsertions;
|
||||
|
||||
template<class T>
|
||||
class nsCOMPtrHashKey : public PLDHashEntryHdr
|
||||
@ -311,7 +277,7 @@ private:
|
||||
};
|
||||
|
||||
/**
|
||||
* A pending accessible tree update notifications for rendered text changes.
|
||||
* Pending accessible tree update notifications for rendered text changes.
|
||||
*/
|
||||
nsTHashtable<nsCOMPtrHashKey<nsIContent> > mTextHash;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user