icecat: add release icecat-140.9.0-1gnu1 for ecne

This commit is contained in:
Ark74 2026-03-28 14:10:24 -06:00
parent 8eb1f1732f
commit a5f93cb214
1197 changed files with 30593 additions and 15344 deletions

View file

@ -1768,11 +1768,12 @@ void DocAccessible::DoInitialUpdate() {
}
#endif
// Fire reorder event after the document tree is constructed. Note, since
// this reorder event is processed by parent document then events targeted to
// this document may be fired prior to this reorder event. If this is
// a problem then consider to keep event processing per tab document.
if (!IsRoot()) {
// Fire a reorder event on the OuterDocAccessible after the document tree is
// constructed. Note that since this reorder event is processed by the parent
// document, events targeted to this child document may be fired prior to this
// reorder event. We don't fire a reorder event for remote documents; the
// parent process handles that.
if (!IPCDoc() && !IsRoot()) {
RefPtr<AccReorderEvent> reorderEvent = new AccReorderEvent(LocalParent());
ParentDocument()->FireDelayedEvent(reorderEvent);
}

View file

@ -50,6 +50,7 @@ DocAccessibleParent::DocAccessibleParent()
mTopLevel(false),
mTopLevelInContentProcess(false),
mShutdown(false),
mIsInitialTreeDone(false),
mFocus(0),
mCaretId(0),
mCaretOffset(-1),
@ -145,7 +146,9 @@ mozilla::ipc::IPCResult DocAccessibleParent::ProcessShowEvent(
// Otherwise, clients might crawl the incomplete subtree and they won't get
// mutation events for the remaining pieces.
if (aComplete || root != child) {
AttachChild(parent, childIdx, child);
if (!AttachChild(parent, childIdx, child)) {
return IPC_FAIL(this, "failed to attach child");
}
}
}
@ -174,7 +177,9 @@ mozilla::ipc::IPCResult DocAccessibleParent::ProcessShowEvent(
MOZ_ASSERT(rootParent);
root = GetAccessible(mPendingShowChild);
MOZ_ASSERT(root);
AttachChild(rootParent, mPendingShowIndex, root);
if (!AttachChild(rootParent, mPendingShowIndex, root)) {
return IPC_FAIL(this, "failed to attach pending show child");
}
mPendingShowChild = 0;
mPendingShowParent = 0;
mPendingShowIndex = 0;
@ -234,6 +239,11 @@ RemoteAccessible* DocAccessibleParent::CreateAcc(
return nullptr;
}
if (aAccData.GenericTypes() & eDocument) {
MOZ_ASSERT_UNREACHABLE("Invalid acc type");
return nullptr;
}
newProxy = new RemoteAccessible(aAccData.ID(), this, aAccData.Role(),
aAccData.Type(), aAccData.GenericTypes(),
aAccData.RoleMapEntryIndex());
@ -246,9 +256,20 @@ RemoteAccessible* DocAccessibleParent::CreateAcc(
return newProxy;
}
void DocAccessibleParent::AttachChild(RemoteAccessible* aParent,
bool DocAccessibleParent::AttachChild(RemoteAccessible* aParent,
uint32_t aIndex,
RemoteAccessible* aChild) {
if (aChild->RemoteParent()) {
MOZ_ASSERT_UNREACHABLE(
"Attempt to attach child which already has a parent!");
return false;
}
if (aParent == aChild) {
MOZ_ASSERT_UNREACHABLE("Attempt to make an accessible its own child!");
return false;
}
aParent->AddChildAt(aIndex, aChild);
aChild->SetParent(aParent);
// ProxyCreated might have already been called if aChild is being moved.
@ -269,11 +290,16 @@ void DocAccessibleParent::AttachChild(RemoteAccessible* aParent,
}
MOZ_ASSERT(bridge->GetEmbedderAccessibleDoc() == this);
if (DocAccessibleParent* childDoc = bridge->GetDocAccessibleParent()) {
MOZ_DIAGNOSTIC_ASSERT(!childDoc->RemoteParent(),
"Pending OOP child doc shouldn't have parent "
"once new OuterDoc is attached");
AddChildDoc(childDoc, aChild->ID(), false);
}
return true;
});
}
return true;
}
void DocAccessibleParent::ShutdownOrPrepareForMove(RemoteAccessible* aAcc) {
@ -286,6 +312,10 @@ void DocAccessibleParent::ShutdownOrPrepareForMove(RemoteAccessible* aAcc) {
// the show event. For now, clear all of them by moving them to a temporary.
auto children{std::move(aAcc->mChildren)};
for (RemoteAccessible* child : children) {
if (child == aAcc) {
MOZ_ASSERT_UNREACHABLE(
"Somehow an accessible got added as a child of itself!");
}
ShutdownOrPrepareForMove(child);
}
}
@ -603,6 +633,18 @@ mozilla::ipc::IPCResult DocAccessibleParent::RecvMutationEvents(
mozilla::ipc::IPCResult DocAccessibleParent::RecvRequestAckMutationEvents() {
if (!mShutdown) {
if (!mIsInitialTreeDone) {
// This is the first request for an ACK, which means we now have the
// initial tree.
mIsInitialTreeDone = true;
// If this document is already bound to its embedder, fire a reorder event
// to notify the client that the embedded document is available. If not,
// this will be handled when this document is bound in AddChildDoc.
if (RemoteAccessible* parent = RemoteParent()) {
parent->Document()->FireEvent(parent,
nsIAccessibleEvent::EVENT_REORDER);
}
}
Unused << SendAckMutationEvents();
}
return IPC_OK();
@ -882,6 +924,11 @@ mozilla::ipc::IPCResult DocAccessibleParent::RecvBindChildDoc(
ipc::IPCResult DocAccessibleParent::AddChildDoc(DocAccessibleParent* aChildDoc,
uint64_t aParentID,
bool aCreating) {
if (aChildDoc->RemoteParent()) {
return IPC_FAIL(this,
"Attempt to add child doc which already has a parent");
}
// We do not use GetAccessible here because we want to be sure to not get the
// document it self.
ProxyEntry* e = mAccessibles.GetEntry(aParentID);
@ -930,11 +977,20 @@ ipc::IPCResult DocAccessibleParent::AddChildDoc(DocAccessibleParent* aChildDoc,
aChildDoc->SetEmulatedWindowHandle(mEmulatedWindowHandle);
}
#endif // defined(XP_WIN)
// We need to fire a reorder event on the outer doc accessible.
// For same-process documents, this is fired by the content process, but
// this isn't possible when the document is in a different process to its
// embedder.
// FireEvent fires both OS and XPCOM events.
}
// We need to fire a reorder event on the embedder. We do this here rather
// than in the content process for two reasons:
// 1. It isn't possible for the content process to fire a reorder event on the
// embedder when the embedded document is in a different process to its
// embedder.
// 2. Doing it here ensures that the event is fired after the child document
// is bound. Otherwise, there could be a short period where the content
// process has fired the reorder event, but the child document isn't bound
// yet.
// However, if the initial tree hasn't been received yet, we don't want to
// fire the reorder event yet. That gets handled in
// RecvRequestAckMutationEvents.
if (aChildDoc->mIsInitialTreeDone) {
FireEvent(outerDoc, nsIAccessibleEvent::EVENT_REORDER);
}

View file

@ -325,11 +325,14 @@ class DocAccessibleParent : public RemoteAccessible,
};
RemoteAccessible* CreateAcc(const AccessibleData& aAccData);
void AttachChild(RemoteAccessible* aParent, uint32_t aIndex,
bool AttachChild(RemoteAccessible* aParent, uint32_t aIndex,
RemoteAccessible* aChild);
[[nodiscard]] bool CheckDocTree() const;
xpcAccessibleGeneric* GetXPCAccessible(RemoteAccessible* aProxy);
/**
* Fire an event to both OS and XPCOM consumers.
*/
void FireEvent(RemoteAccessible* aAcc, const uint32_t& aType);
/**
@ -365,9 +368,10 @@ class DocAccessibleParent : public RemoteAccessible,
uint32_t mPendingShowIndex = 0;
nsTHashSet<uint64_t> mMovingIDs;
uint64_t mActorID;
bool mTopLevel;
bool mTopLevelInContentProcess;
bool mShutdown;
bool mTopLevel : 1;
bool mTopLevelInContentProcess : 1;
bool mShutdown : 1;
bool mIsInitialTreeDone : 1;
RefPtr<dom::CanonicalBrowsingContext> mBrowsingContext;
nsTHashSet<RefPtr<dom::BrowserBridgeParent>> mPendingOOPChildDocs;

View file

@ -11,6 +11,8 @@ support-files = [
["browser_hidden_iframe.js"]
https_first_disabled = true
["browser_iframe_recreation.js"]
["browser_nested_iframe.js"]
["browser_reframe_root.js"]

View file

@ -0,0 +1,29 @@
/* 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/. */
"use strict";
addAccessibleTask(
`test`,
async function testRecreation(browser, iframeDocAcc, topDocAcc) {
let iframe = findAccessibleChildByID(topDocAcc, DEFAULT_IFRAME_ID);
is(iframeDocAcc.parent, iframe, "iframe doc's parent is iframe");
// The ARIA role currently causes re-creation. If that ever changes, we'll
// need to switch to another technique here.
info("Change iframe's role to recreate it");
let shown = waitForEvent(EVENT_SHOW, DEFAULT_IFRAME_ID);
let reordered = waitForEvent(EVENT_REORDER, DEFAULT_IFRAME_ID);
await SpecialPowers.spawn(
topDocAcc.browsingContext,
[DEFAULT_IFRAME_ID],
id => {
content.document.getElementById(id).role = "foo";
}
);
iframe = (await shown).accessible;
await reordered;
is(iframeDocAcc.parent, iframe, "iframe doc's parent is iframe");
},
{ chrome: false, topLevel: false, iframe: true, remoteIframe: true }
);