mirror of
https://github.com/roytam1/palemoon27.git
synced 2026-05-26 14:18:48 +00:00
393bc6639f
- Bug 1209162 - Create OriginAttributes subtypes. IGNORE IDL r=sicking. (c2cbe04ef3) - Bug 1220570 - Potential cookie lost while downgrading from Aurora 44 to 43. r=jduell (1a0111c842) - Bug 1217456: Add a security flag for controlling redirects. Use this flag in fetch() implementation. r=bkelly,jduell (79d449e479) - Bug 1112040 - Add a mochitest. r=bholley (566a05f720) - Bug 1171215 - Compute third-partyness in the loadinfo instead of nsIHttpChannelInternal so that other protocols correctly respect the third-party cookie pref. r=sicking/ckerschb (06f7a10a83) - better backport of Bug 485941 - Stack overflow using overly-deep XML tree (DoS). r=bzbarsky (ac43feeffa) - Bug 1182546 - Use channel->Open2() in parser/htmlparser/nsExpatDriver.cpp (r=bz) (42768f373a) - Bug 1163435 part 1 - [css-grid][css-flexbox] Propagate an explicit CB width/height to the reflow state to resolve percentage lengths for grid items properly. Resolve percent against the size in the same axis for abs.pos. children too. r=dholbert (a55463fb05) - Bug 1163435 part 2 - tests. (bb683c5fc6) - Bug 1223282 - Make NS_AUTOMARGIN be a different value than NS_UNCONSTRAINEDSIZE to avoid having clamped huge margin values be interpreted as auto margins. r=roc (4cdfe0f277) - Bug 1224230 - Explicitly store the lineContainer's writing mode in InlineIntrinsicISizeData. r=dbaron (6474515223) - Bug 1221043. Revert to including trailing whitespace for accessibility APIs. r=marcoz,mats (406018c163) - Bug 1227113 - Fix some indentation issues in ServiceWorkerManager, r=janv (2b343bde09) - Bug 1223116 P1 Expose nsIServiceWorkerManager.shouldReportToWindow(). r=catalinb (02899e429d) - Bug 1226441 - Part 1: Add wpt test verifying fetch event waits for activate to complete; r=catalinb (e8eb3e6e7a) - Bug 1209865 - Add gecko profiler marker when mark() of User Timing API is called. r=baku (f48d76e395) - Bug 1169068 - Performance.translateTime(), r=bz (38cd1c31b2) - Bug 1226441 - Part 2: Delay functional event dispatch until service worker is activated; r=catalinb (778cd3dd24) - Bug 1178233 - [non-e10s] The update process doesn't work within about:serviceworkers in non-e10s mode. Test. r=baku (4f8b6f53f8) - Bug 1188545 - Disable unstable test: test_aboutserviceworkers.html. a=testonly (4bbe106693) - Bug 1219255 - We should be able to attach to a service worker;r=amarchesini (0d6b71b4ec) - Bug 1222464 - Part 2: Implement FetchEvent.clientId; r=jdm (9c8abd62dd) - Bug 1218150 - Mark the members of Clients as NewObject; r=bzbarsky (b6b00a586c) - Bug 1222464 - Part 3: Implement Clients.get(); r=jdm (f5ca60d801) - Bug 1222464 - Part 1: Save a client ID for top-level navigations on the docshell and assign it as the document ID when we start loading the document; r=jdm (7dcb5ce2b6) - Bug 1218141 - Add some SameObject and NewObject annotations to ServiceWorkerGlobalScope; r=bzbarsky (5019f58c7a) - Bug 1218190 - Add a pref to enable Clients.openWindow, r=catalinb (dbb6d007dd) - Bug 1218142 - Remove ServiceWorkerGlobalScope.onbeforeevicted/onevicted; r=bzbarsky (029de6f8ec) - Bug 1218146 - Move WindowClient.frameType to Client.frameType; r=bzbarsky (00f0211276) - Bug 1218147 - Make WindowClient.focus() NewObject; r=bzbarsky (3c6aea4b67) - Bug 1189659 - Part 1 - Continue service worker job queue when life cycle events expire. r=bkelly (aa09cd9c60) - Bug 1227932 - Fix Service Workers SoftUpdate and registration.update code paths. r=ehsan (24567b23c0) - Bug 1189659 - Part 2 - Remove set of scopes being updated from ServiceWorkerManager. r=bkelly (ce581b095c) - Bug 1189659 - Part 3 - Use separate synchronization queues for service worker register jobs and install jobs. r=bkelly (9c408a22ed) - Bug 1189659 - Part 4 - Fix race in test_install_event.html. r=bkelly (3186ffb808) - Bug 1189659 - Part 5 - Fix race in skip-waiting.https.html and add some logging for SkipWaitingFlag in ServiceWorkerManager. r=ehsan (4e5ddda6f3) - Bug 1229056 - Implement ClientQueryOptions.includeUncontrolled; r=jdm (dbe56aa60d) - namespace (3b0863d42d) - Bug 1201127 - Return the same ServiceWorkerRegistration object from service worker APIs dealing with the same underlying registration object; r=jdm (c542688ae0) - Bug 1171583 - Remove mutable warning from |nsSimpleURI::SetUserPass|. r=bz (73934deaad) - Bug 1206199 - Extend channelwrapper to mediate OnStartRequest, OnStopRequest, OnDataAvailable (r=sicking) (758a7ec65c) - Bug 1186783 (part 4) - Replace nsBaseHashtable::EnumerateRead() calls in netwerk/ with iterators. r=valentin. (681bdba278) - Bug 1186783 (part 3) - Replace nsBaseHashtable::EnumerateRead() calls in netwerk/ with iterators. r=valentin. (76b8b7191e) - Bug 1186783 (part 2) - Replace nsBaseHashtable::EnumerateRead() calls in netwerk/ with iterators. r=valentin. (5c0743ac49) - Bug 1186783 (part 1) - Replace nsBaseHashtable::EnumerateRead() calls in netwerk/ with iterators. r=valentin. (952cc720cc) - Bug 1186783 (part 5) - Replace nsBaseHashtable::EnumerateRead() calls in netwerk/ with iterators. r=valentin. (25b9735c52) - Bug 1186783 (part 1) - Replace nsBaseHashtable::EnumerateRead() calls in netwerk/. r=michal. (ae52425809) - Bug 1186783 (follow-up) - Bustage fix for Gonk. (d4a1b769bd) - add back some hotfix stuff, even if unused (fe32076c5b) - Bug 1068087: Switch about:plugins to run remotely. r=mconley (bc4316dd03) - Bug 1214058: Part 1 - Add a simplified JSON-based add-on update protocol. r=Mossop (a3198884d5) - Bug 1214058: Part 2 - Run add-on update tests against comparable JSON and RDF manifests. r=Mossop (aa6a796e6f) - Bug 1152977 - Enable by default DEAA for desktop platforms that use OpenGL compositor. r=jmuizelaar (bfa9efd5c8)
461 lines
15 KiB
C++
461 lines
15 KiB
C++
/* -*- 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/. */
|
|
|
|
#include "NotificationController.h"
|
|
|
|
#include "DocAccessible-inl.h"
|
|
#include "DocAccessibleChild.h"
|
|
#include "TextLeafAccessible.h"
|
|
#include "TextUpdater.h"
|
|
|
|
#include "mozilla/dom/TabChild.h"
|
|
#include "mozilla/dom/Element.h"
|
|
#include "mozilla/Telemetry.h"
|
|
|
|
using namespace mozilla;
|
|
using namespace mozilla::a11y;
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
// NotificationCollector
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
NotificationController::NotificationController(DocAccessible* aDocument,
|
|
nsIPresShell* aPresShell) :
|
|
EventQueue(aDocument), mObservingState(eNotObservingRefresh),
|
|
mPresShell(aPresShell)
|
|
{
|
|
// Schedule initial accessible tree construction.
|
|
ScheduleProcessing();
|
|
}
|
|
|
|
NotificationController::~NotificationController()
|
|
{
|
|
NS_ASSERTION(!mDocument, "Controller wasn't shutdown properly!");
|
|
if (mDocument)
|
|
Shutdown();
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
// NotificationCollector: AddRef/Release and cycle collection
|
|
|
|
NS_IMPL_CYCLE_COLLECTING_NATIVE_ADDREF(NotificationController)
|
|
NS_IMPL_CYCLE_COLLECTING_NATIVE_RELEASE(NotificationController)
|
|
|
|
NS_IMPL_CYCLE_COLLECTION_CLASS(NotificationController)
|
|
|
|
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(NotificationController)
|
|
if (tmp->mDocument)
|
|
tmp->Shutdown();
|
|
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)
|
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mEvents)
|
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mRelocations)
|
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
|
|
|
NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(NotificationController, AddRef)
|
|
NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(NotificationController, Release)
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
// NotificationCollector: public
|
|
|
|
void
|
|
NotificationController::Shutdown()
|
|
{
|
|
if (mObservingState != eNotObservingRefresh &&
|
|
mPresShell->RemoveRefreshObserver(this, Flush_Display)) {
|
|
mObservingState = eNotObservingRefresh;
|
|
}
|
|
|
|
// Shutdown handling child documents.
|
|
int32_t childDocCount = mHangingChildDocuments.Length();
|
|
for (int32_t idx = childDocCount - 1; idx >= 0; idx--) {
|
|
if (!mHangingChildDocuments[idx]->IsDefunct())
|
|
mHangingChildDocuments[idx]->Shutdown();
|
|
}
|
|
|
|
mHangingChildDocuments.Clear();
|
|
|
|
mDocument = nullptr;
|
|
mPresShell = nullptr;
|
|
|
|
mTextHash.Clear();
|
|
mContentInsertions.Clear();
|
|
mNotifications.Clear();
|
|
mEvents.Clear();
|
|
mRelocations.Clear();
|
|
}
|
|
|
|
void
|
|
NotificationController::ScheduleChildDocBinding(DocAccessible* aDocument)
|
|
{
|
|
// Schedule child document binding to the tree.
|
|
mHangingChildDocuments.AppendElement(aDocument);
|
|
ScheduleProcessing();
|
|
}
|
|
|
|
void
|
|
NotificationController::ScheduleContentInsertion(Accessible* aContainer,
|
|
nsIContent* aStartChildNode,
|
|
nsIContent* aEndChildNode)
|
|
{
|
|
RefPtr<ContentInsertion> insertion = new ContentInsertion(mDocument,
|
|
aContainer);
|
|
if (insertion && insertion->InitChildList(aStartChildNode, aEndChildNode) &&
|
|
mContentInsertions.AppendElement(insertion)) {
|
|
ScheduleProcessing();
|
|
}
|
|
}
|
|
|
|
void
|
|
NotificationController::ScheduleProcessing()
|
|
{
|
|
// If notification flush isn't planed yet start notification flush
|
|
// asynchronously (after style and layout).
|
|
if (mObservingState == eNotObservingRefresh) {
|
|
if (mPresShell->AddRefreshObserver(this, Flush_Display))
|
|
mObservingState = eRefreshObserving;
|
|
}
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
// NotificationCollector: protected
|
|
|
|
bool
|
|
NotificationController::IsUpdatePending()
|
|
{
|
|
return mPresShell->IsLayoutFlushObserver() ||
|
|
mObservingState == eRefreshProcessingForUpdate ||
|
|
mContentInsertions.Length() != 0 || mNotifications.Length() != 0 ||
|
|
mTextHash.Count() != 0 ||
|
|
!mDocument->HasLoadState(DocAccessible::eTreeConstructed);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
// NotificationCollector: private
|
|
|
|
void
|
|
NotificationController::WillRefresh(mozilla::TimeStamp aTime)
|
|
{
|
|
Telemetry::AutoTimer<Telemetry::A11Y_UPDATE_TIME> updateTimer;
|
|
|
|
// If the document accessible that notification collector was created for is
|
|
// now shut down, don't process notifications anymore.
|
|
NS_ASSERTION(mDocument,
|
|
"The document was shut down while refresh observer is attached!");
|
|
if (!mDocument)
|
|
return;
|
|
|
|
if (mObservingState == eRefreshProcessing ||
|
|
mObservingState == eRefreshProcessingForUpdate)
|
|
return;
|
|
|
|
// Any generic notifications should be queued if we're processing content
|
|
// insertions or generic notifications.
|
|
mObservingState = eRefreshProcessingForUpdate;
|
|
|
|
// Initial accessible tree construction.
|
|
if (!mDocument->HasLoadState(DocAccessible::eTreeConstructed)) {
|
|
// If document is not bound to parent at this point then the document is not
|
|
// ready yet (process notifications later).
|
|
if (!mDocument->IsBoundToParent()) {
|
|
mObservingState = eRefreshObserving;
|
|
return;
|
|
}
|
|
|
|
#ifdef A11Y_LOG
|
|
if (logging::IsEnabled(logging::eTree)) {
|
|
logging::MsgBegin("TREE", "initial tree created");
|
|
logging::Address("document", mDocument);
|
|
logging::MsgEnd();
|
|
}
|
|
#endif
|
|
|
|
mDocument->DoInitialUpdate();
|
|
|
|
NS_ASSERTION(mContentInsertions.Length() == 0,
|
|
"Pending content insertions while initial accessible tree isn't created!");
|
|
}
|
|
|
|
// Initialize scroll support if needed.
|
|
if (!(mDocument->mDocFlags & DocAccessible::eScrollInitialized))
|
|
mDocument->AddScrollListener();
|
|
|
|
// Process content inserted notifications to update the tree. Process other
|
|
// notifications like DOM events and then flush event queue. If any new
|
|
// notifications are queued during this processing then they will be processed
|
|
// on next refresh. If notification processing queues up new events then they
|
|
// are processed in this refresh. If events processing queues up new events
|
|
// then new events are processed on next refresh.
|
|
// Note: notification processing or event handling may shut down the owning
|
|
// 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)
|
|
return;
|
|
}
|
|
|
|
// Process rendered text change notifications.
|
|
for (auto iter = mTextHash.Iter(); !iter.Done(); iter.Next()) {
|
|
nsCOMPtrHashKey<nsIContent>* entry = iter.Get();
|
|
nsIContent* textNode = entry->GetKey();
|
|
Accessible* textAcc = mDocument->GetAccessible(textNode);
|
|
|
|
// If the text node is not in tree or doesn't have frame then this case should
|
|
// have been handled already by content removal notifications.
|
|
nsINode* containerNode = textNode->GetParentNode();
|
|
if (!containerNode) {
|
|
NS_ASSERTION(!textAcc,
|
|
"Text node was removed but accessible is kept alive!");
|
|
continue;
|
|
}
|
|
|
|
nsIFrame* textFrame = textNode->GetPrimaryFrame();
|
|
if (!textFrame) {
|
|
NS_ASSERTION(!textAcc,
|
|
"Text node isn't rendered but accessible is kept alive!");
|
|
continue;
|
|
}
|
|
|
|
nsIContent* containerElm = containerNode->IsElement() ?
|
|
containerNode->AsElement() : nullptr;
|
|
|
|
nsIFrame::RenderedText text = textFrame->GetRenderedText(0,
|
|
UINT32_MAX, nsIFrame::TextOffsetType::OFFSETS_IN_CONTENT_TEXT,
|
|
nsIFrame::TrailingWhitespace::DONT_TRIM_TRAILING_WHITESPACE);
|
|
|
|
// Remove text accessible if rendered text is empty.
|
|
if (textAcc) {
|
|
if (text.mString.IsEmpty()) {
|
|
#ifdef A11Y_LOG
|
|
if (logging::IsEnabled(logging::eTree | logging::eText)) {
|
|
logging::MsgBegin("TREE", "text node lost its content");
|
|
logging::Node("container", containerElm);
|
|
logging::Node("content", textNode);
|
|
logging::MsgEnd();
|
|
}
|
|
#endif
|
|
|
|
mDocument->ContentRemoved(containerElm, textNode);
|
|
continue;
|
|
}
|
|
|
|
// Update text of the accessible and fire text change events.
|
|
#ifdef A11Y_LOG
|
|
if (logging::IsEnabled(logging::eText)) {
|
|
logging::MsgBegin("TEXT", "text may be changed");
|
|
logging::Node("container", containerElm);
|
|
logging::Node("content", textNode);
|
|
logging::MsgEntry("old text '%s'",
|
|
NS_ConvertUTF16toUTF8(textAcc->AsTextLeaf()->Text()).get());
|
|
logging::MsgEntry("new text: '%s'",
|
|
NS_ConvertUTF16toUTF8(text.mString).get());
|
|
logging::MsgEnd();
|
|
}
|
|
#endif
|
|
|
|
TextUpdater::Run(mDocument, textAcc->AsTextLeaf(), text.mString);
|
|
continue;
|
|
}
|
|
|
|
// Append an accessible if rendered text is not empty.
|
|
if (!text.mString.IsEmpty()) {
|
|
#ifdef A11Y_LOG
|
|
if (logging::IsEnabled(logging::eTree | logging::eText)) {
|
|
logging::MsgBegin("TREE", "text node gains new content");
|
|
logging::Node("container", containerElm);
|
|
logging::Node("content", textNode);
|
|
logging::MsgEnd();
|
|
}
|
|
#endif
|
|
|
|
// Make sure the text node is in accessible document still.
|
|
Accessible* container = mDocument->GetAccessibleOrContainer(containerNode);
|
|
NS_ASSERTION(container,
|
|
"Text node having rendered text hasn't accessible document!");
|
|
if (container) {
|
|
nsTArray<nsCOMPtr<nsIContent> > insertedContents;
|
|
insertedContents.AppendElement(textNode);
|
|
mDocument->ProcessContentInserted(container, &insertedContents);
|
|
}
|
|
}
|
|
}
|
|
mTextHash.Clear();
|
|
|
|
// Bind hanging child documents.
|
|
uint32_t hangingDocCnt = mHangingChildDocuments.Length();
|
|
nsTArray<RefPtr<DocAccessible>> newChildDocs;
|
|
for (uint32_t idx = 0; idx < hangingDocCnt; idx++) {
|
|
DocAccessible* childDoc = mHangingChildDocuments[idx];
|
|
if (childDoc->IsDefunct())
|
|
continue;
|
|
|
|
nsIContent* ownerContent = mDocument->DocumentNode()->
|
|
FindContentForSubDocument(childDoc->DocumentNode());
|
|
if (ownerContent) {
|
|
Accessible* outerDocAcc = mDocument->GetAccessible(ownerContent);
|
|
if (outerDocAcc && outerDocAcc->AppendChild(childDoc)) {
|
|
if (mDocument->AppendChildDocument(childDoc)) {
|
|
newChildDocs.AppendElement(Move(mHangingChildDocuments[idx]));
|
|
continue;
|
|
}
|
|
|
|
outerDocAcc->RemoveChild(childDoc);
|
|
}
|
|
|
|
// Failed to bind the child document, destroy it.
|
|
childDoc->Shutdown();
|
|
}
|
|
}
|
|
|
|
mHangingChildDocuments.Clear();
|
|
|
|
// If the document is ready and all its subdocuments are completely loaded
|
|
// then process the document load.
|
|
if (mDocument->HasLoadState(DocAccessible::eReady) &&
|
|
!mDocument->HasLoadState(DocAccessible::eCompletelyLoaded) &&
|
|
hangingDocCnt == 0) {
|
|
uint32_t childDocCnt = mDocument->ChildDocumentCount(), childDocIdx = 0;
|
|
for (; childDocIdx < childDocCnt; childDocIdx++) {
|
|
DocAccessible* childDoc = mDocument->GetChildDocumentAt(childDocIdx);
|
|
if (!childDoc->HasLoadState(DocAccessible::eCompletelyLoaded))
|
|
break;
|
|
}
|
|
|
|
if (childDocIdx == childDocCnt) {
|
|
mDocument->ProcessLoad();
|
|
if (!mDocument)
|
|
return;
|
|
}
|
|
}
|
|
|
|
// Process only currently queued generic notifications.
|
|
nsTArray < RefPtr<Notification> > notifications;
|
|
notifications.SwapElements(mNotifications);
|
|
|
|
uint32_t notificationCount = notifications.Length();
|
|
for (uint32_t idx = 0; idx < notificationCount; idx++) {
|
|
notifications[idx]->Process();
|
|
if (!mDocument)
|
|
return;
|
|
}
|
|
|
|
// Process invalidation list of the document after all accessible tree
|
|
// modification are done.
|
|
mDocument->ProcessInvalidationList();
|
|
|
|
// We cannot rely on DOM tree to keep aria-owns relations updated. Make
|
|
// a validation to remove dead links.
|
|
mDocument->ValidateARIAOwned();
|
|
|
|
// Process relocation list.
|
|
for (uint32_t idx = 0; idx < mRelocations.Length(); idx++) {
|
|
mDocument->DoARIAOwnsRelocation(mRelocations[idx]);
|
|
}
|
|
mRelocations.Clear();
|
|
|
|
// If a generic notification occurs after this point then we may be allowed to
|
|
// process it synchronously. However we do not want to reenter if fireing
|
|
// events causes script to run.
|
|
mObservingState = eRefreshProcessing;
|
|
|
|
ProcessEventQueue();
|
|
|
|
if (IPCAccessibilityActive()) {
|
|
size_t newDocCount = newChildDocs.Length();
|
|
for (size_t i = 0; i < newDocCount; i++) {
|
|
DocAccessible* childDoc = newChildDocs[i];
|
|
Accessible* parent = childDoc->Parent();
|
|
DocAccessibleChild* parentIPCDoc = mDocument->IPCDoc();
|
|
uint64_t id = reinterpret_cast<uintptr_t>(parent->UniqueID());
|
|
MOZ_ASSERT(id);
|
|
DocAccessibleChild* ipcDoc = childDoc->IPCDoc();
|
|
if (ipcDoc) {
|
|
parentIPCDoc->SendBindChildDoc(ipcDoc, id);
|
|
continue;
|
|
}
|
|
|
|
ipcDoc = new DocAccessibleChild(childDoc);
|
|
childDoc->SetIPCDoc(ipcDoc);
|
|
nsCOMPtr<nsITabChild> tabChild =
|
|
do_GetInterface(mDocument->DocumentNode()->GetDocShell());
|
|
static_cast<TabChild*>(tabChild.get())->
|
|
SendPDocAccessibleConstructor(ipcDoc, parentIPCDoc, id);
|
|
}
|
|
}
|
|
|
|
mObservingState = eRefreshObserving;
|
|
if (!mDocument)
|
|
return;
|
|
|
|
// Stop further processing if there are no new notifications of any kind or
|
|
// events and document load is processed.
|
|
if (mContentInsertions.IsEmpty() && mNotifications.IsEmpty() &&
|
|
mEvents.IsEmpty() && mTextHash.Count() == 0 &&
|
|
mHangingChildDocuments.IsEmpty() &&
|
|
mDocument->HasLoadState(DocAccessible::eCompletelyLoaded) &&
|
|
mPresShell->RemoveRefreshObserver(this, Flush_Display)) {
|
|
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();
|
|
}
|
|
|