Commit 0d34540a authored by Kashav Madan's avatar Kashav Madan
Browse files

Bug 1703692 - Use ChildOffset to build the offset path for flushes, r=nika

We can't rely on the Children list since it may have been cleared on shutdown.
Since we don't clear parent edges, walking the parent chain and using
mChildOffset works.

Differential Revision: https://phabricator.services.mozilla.com/D118384
parent 68ff4469
Loading
Loading
Loading
Loading
+11 −0
Original line number Diff line number Diff line
@@ -3266,6 +3266,17 @@ void BrowsingContext::AddDeprioritizedLoadRunner(nsIRunnable* aRunner) {
      EventQueuePriority::Idle);
}

bool BrowsingContext::GetOffsetPath(nsTArray<uint32_t>& aPath) const {
  for (const BrowsingContext* current = this; current && current->GetParent();
       current = current->GetParent()) {
    if (current->CreatedDynamically()) {
      return false;
    }
    aPath.AppendElement(current->ChildOffset());
  }
  return true;
}

void BrowsingContext::GetHistoryID(JSContext* aCx,
                                   JS::MutableHandle<JS::Value> aVal,
                                   ErrorResult& aError) {
+2 −0
Original line number Diff line number Diff line
@@ -755,6 +755,8 @@ class BrowsingContext : public nsILoadContext, public nsWrapperCache {

  int32_t ChildOffset() const { return mChildOffset; }

  bool GetOffsetPath(nsTArray<uint32_t>& aPath) const;

  const OriginAttributes& OriginAttributesRef() { return mOriginAttributes; }
  nsresult SetOriginAttributes(const OriginAttributes& aAttrs);

+9 −36
Original line number Diff line number Diff line
@@ -1158,33 +1158,6 @@ void WindowGlobalParent::FinishAccumulatingPageUseCounters() {
  mPageUseCounters = nullptr;
}

// Collect the path from aContext up to its parent. Returns true if any context
// in the chain isn't a child of its parent
static bool GetPath(BrowsingContext* aContext,
                    FallibleTArray<uint32_t>& aPath) {
  bool missingContext = false;

  BrowsingContext* current = aContext;
  while (current) {
    BrowsingContext* parent = current->GetParent();
    if (parent) {
      auto children = parent->Children();
      auto result = std::find(children.cbegin(), children.cend(), current);
      if (result == children.cend()) {
        missingContext = true;
      }

      if (!aPath.AppendElement(std::distance(children.cbegin(), result),
                               fallible)) {
        break;
      }
    }
    current = parent;
  }

  return missingContext;
}

static void GetFormData(JSContext* aCx, const sessionstore::FormData& aFormData,
                        nsIURI* aDocumentURI, SessionStoreFormData& aUpdate) {
  if (!aFormData.hasData()) {
@@ -1266,12 +1239,6 @@ nsresult WindowGlobalParent::WriteFormDataAndScrollToSessionStore(

  RootedDictionary<SessionStoreWindowStateChange> windowState(jsapi.cx());

  if (GetPath(context, windowState.mPath)) {
    // If a context in the parent chain from the current context is
    // missing, do nothing.
    return NS_OK;
  }

  if (aFormData) {
    GetFormData(jsapi.cx(), *aFormData, mDocumentURI,
                windowState.mFormdata.Construct());
@@ -1284,6 +1251,12 @@ nsresult WindowGlobalParent::WriteFormDataAndScrollToSessionStore(
    }
  }

  nsTArray<uint32_t> path;
  if (!context->GetOffsetPath(path)) {
    return NS_OK;
  }

  windowState.mPath = std::move(path);
  windowState.mHasChildren.Construct() = !context->Children().IsEmpty();

  JS::RootedValue update(jsapi.cx());
@@ -1317,12 +1290,12 @@ nsresult WindowGlobalParent::ResetSessionStore(uint32_t aEpoch) {

  RootedDictionary<SessionStoreWindowStateChange> windowState(jsapi.cx());

  if (GetPath(context, windowState.mPath)) {
    // If a context in the parent chain from the current context is
    // missing, do nothing.
  nsTArray<uint32_t> path;
  if (!context->GetOffsetPath(path)) {
    return NS_OK;
  }

  windowState.mPath = std::move(path);
  windowState.mHasChildren.Construct() = false;
  windowState.mFormdata.Construct();
  windowState.mScroll.Construct();
+4 −10
Original line number Diff line number Diff line
@@ -19,20 +19,14 @@ bool SessionStoreRestoreData::IsEmpty() {

SessionStoreRestoreData* SessionStoreRestoreData::FindDataForChild(
    BrowsingContext* aContext) {
  nsTArray<uint32_t> offsets;
  for (const BrowsingContext* current = aContext;
       current && current->GetParent(); current = current->GetParent()) {
    // Don't bother continuing if any frame in our chain was created
    // dynamically.
    if (current->ChildOffset() < 0) {
  nsTArray<uint32_t> path;
  if (!aContext->GetOffsetPath(path)) {
    return nullptr;
  }
    offsets.AppendElement(current->ChildOffset());
  }

  SessionStoreRestoreData* data = this;

  for (uint32_t offset : Reversed(offsets)) {
  for (uint32_t offset : Reversed(path)) {
    if (!data || data->mChildren.Length() <= offset ||
        !data->mChildren[offset] || data->mChildren[offset]->IsEmpty()) {
      return nullptr;