mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-20 00:35:44 +00:00
Bug 1658341 - Copy nsSHentry::AddChild/RemoveChild/ReplaceChild to SessionHistoryEntry. r=smaug
This copies the code as is, so won't compile. The next patch changes the implementation so it compiles. Differential Revision: https://phabricator.services.mozilla.com/D86573
This commit is contained in:
parent
d7c6b2974f
commit
a35af34bfa
@ -686,14 +686,132 @@ SessionHistoryEntry::SetLoadTypeAsHistory() {
|
||||
NS_IMETHODIMP
|
||||
SessionHistoryEntry::AddChild(nsISHEntry* aChild, int32_t aOffset,
|
||||
bool aUseRemoteSubframes) {
|
||||
MOZ_CRASH("Need to implement this");
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
if (aChild) {
|
||||
NS_ENSURE_SUCCESS(aChild->SetParent(this), NS_ERROR_FAILURE);
|
||||
}
|
||||
|
||||
if (aOffset < 0) {
|
||||
mChildren.AppendObject(aChild);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//
|
||||
// Bug 52670: Ensure children are added in order.
|
||||
//
|
||||
// Later frames in the child list may load faster and get appended
|
||||
// before earlier frames, causing session history to be scrambled.
|
||||
// By growing the list here, they are added to the right position.
|
||||
//
|
||||
// Assert that aOffset will not be so high as to grow us a lot.
|
||||
//
|
||||
NS_ASSERTION(aOffset < (mChildren.Count() + 1023), "Large frames array!\n");
|
||||
|
||||
bool newChildIsDyn = aChild ? aChild->IsDynamicallyAdded() : false;
|
||||
|
||||
// If the new child is dynamically added, try to add it to aOffset, but if
|
||||
// there are non-dynamically added children, the child must be after those.
|
||||
if (newChildIsDyn) {
|
||||
int32_t lastNonDyn = aOffset - 1;
|
||||
for (int32_t i = aOffset; i < mChildren.Count(); ++i) {
|
||||
nsISHEntry* entry = mChildren[i];
|
||||
if (entry) {
|
||||
if (entry->IsDynamicallyAdded()) {
|
||||
break;
|
||||
} else {
|
||||
lastNonDyn = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
// InsertObjectAt allows only appending one object.
|
||||
// If aOffset is larger than Count(), we must first manually
|
||||
// set the capacity.
|
||||
if (aOffset > mChildren.Count()) {
|
||||
mChildren.SetCount(aOffset);
|
||||
}
|
||||
if (!mChildren.InsertObjectAt(aChild, lastNonDyn + 1)) {
|
||||
NS_WARNING("Adding a child failed!");
|
||||
aChild->SetParent(nullptr);
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
} else {
|
||||
// If the new child isn't dynamically added, it should be set to aOffset.
|
||||
// If there are dynamically added children before that, those must be
|
||||
// moved to be after aOffset.
|
||||
if (mChildren.Count() > 0) {
|
||||
int32_t start = std::min(mChildren.Count() - 1, aOffset);
|
||||
int32_t dynEntryIndex = -1;
|
||||
nsISHEntry* dynEntry = nullptr;
|
||||
for (int32_t i = start; i >= 0; --i) {
|
||||
nsISHEntry* entry = mChildren[i];
|
||||
if (entry) {
|
||||
if (entry->IsDynamicallyAdded()) {
|
||||
dynEntryIndex = i;
|
||||
dynEntry = entry;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (dynEntry) {
|
||||
nsCOMArray<nsISHEntry> tmp;
|
||||
tmp.SetCount(aOffset - dynEntryIndex + 1);
|
||||
mChildren.InsertObjectsAt(tmp, dynEntryIndex);
|
||||
NS_ASSERTION(mChildren[aOffset + 1] == dynEntry, "Whaat?");
|
||||
}
|
||||
}
|
||||
|
||||
// Make sure there isn't anything at aOffset.
|
||||
if (aOffset < mChildren.Count()) {
|
||||
nsISHEntry* oldChild = mChildren[aOffset];
|
||||
if (oldChild && oldChild != aChild) {
|
||||
// Under Fission, this can happen when a network-created iframe starts
|
||||
// out in-process, moves out-of-process, and then switches back. At that
|
||||
// point, we'll create a new network-created DocShell at the same index
|
||||
// where we already have an entry for the original network-created
|
||||
// DocShell.
|
||||
//
|
||||
// This should ideally stop being an issue once the Fission-aware
|
||||
// session history rewrite is complete.
|
||||
NS_ASSERTION(
|
||||
aUseRemoteSubframes,
|
||||
"Adding a child where we already have a child? This may misbehave");
|
||||
oldChild->SetParent(nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
mChildren.ReplaceObjectAt(aChild, aOffset);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
SessionHistoryEntry::RemoveChild(nsISHEntry* aChild) {
|
||||
MOZ_CRASH("Need to implement this");
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
NS_ENSURE_TRUE(aChild, NS_ERROR_FAILURE);
|
||||
bool childRemoved = false;
|
||||
if (aChild->IsDynamicallyAdded()) {
|
||||
childRemoved = mChildren.RemoveObject(aChild);
|
||||
} else {
|
||||
int32_t index = mChildren.IndexOfObject(aChild);
|
||||
if (index >= 0) {
|
||||
// Other alive non-dynamic child docshells still keep mChildOffset,
|
||||
// so we don't want to change the indices here.
|
||||
mChildren.ReplaceObjectAt(nullptr, index);
|
||||
childRemoved = true;
|
||||
}
|
||||
}
|
||||
if (childRemoved) {
|
||||
aChild->SetParent(nullptr);
|
||||
|
||||
// reduce the child count, i.e. remove empty children at the end
|
||||
for (int32_t i = mChildren.Count() - 1; i >= 0 && !mChildren[i]; --i) {
|
||||
if (!mChildren.RemoveObjectAt(i)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
@ -711,8 +829,24 @@ SessionHistoryEntry::GetChildSHEntryIfHasNoDynamicallyAddedChild(
|
||||
|
||||
NS_IMETHODIMP
|
||||
SessionHistoryEntry::ReplaceChild(nsISHEntry* aNewChild) {
|
||||
MOZ_CRASH("Need to implement this");
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
NS_ENSURE_STATE(aNewEntry);
|
||||
|
||||
nsID docshellID;
|
||||
aNewEntry->GetDocshellID(docshellID);
|
||||
|
||||
for (int32_t i = 0; i < mChildren.Count(); ++i) {
|
||||
if (mChildren[i]) {
|
||||
nsID childDocshellID;
|
||||
nsresult rv = mChildren[i]->GetDocshellID(childDocshellID);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (docshellID == childDocshellID) {
|
||||
mChildren[i]->SetParent(nullptr);
|
||||
mChildren.ReplaceObjectAt(aNewEntry, i);
|
||||
return aNewEntry->SetParent(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP_(void)
|
||||
|
Loading…
Reference in New Issue
Block a user