tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

DepthOrderedFrameList.cpp (2683B)


      1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
      3 /* This Source Code Form is subject to the terms of the Mozilla Public
      4 * License, v. 2.0. If a copy of the MPL was not distributed with this
      5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      6 
      7 #include "DepthOrderedFrameList.h"
      8 
      9 #include "nsContainerFrame.h"
     10 #include "nsIFrame.h"
     11 
     12 namespace mozilla {
     13 
     14 void DepthOrderedFrameList::Add(nsIFrame* aFrame) {
     15  MOZ_ASSERT(aFrame);
     16 
     17  if (auto p = mFrames.lookupForAdd(aFrame)) {
     18    // We don't expect the depth of a frame in the list to change.
     19    MOZ_ASSERT(p->value() == aFrame->GetDepthInFrameTree());
     20  } else {
     21    if (!mFrames.add(p, aFrame, aFrame->GetDepthInFrameTree())) {
     22      NS_WARNING("failed to add frame to DepthOrderedFrameList");
     23    }
     24    if (mFrames.count() == 1) {
     25      // We just added the first frame, so can directly set up mSortedFrames.
     26      // (Lists that only contain a single frame are common.)
     27      MOZ_ASSERT(mSortedFrames.IsEmpty());
     28      mSortedFrames.AppendElement(FrameAndDepth{aFrame, p->value()});
     29    } else {
     30      // Clear mSortedFrames, so that we'll rebuild it when needed.
     31      mSortedFrames.ClearAndRetainStorage();
     32    }
     33  }
     34 }
     35 
     36 nsIFrame* DepthOrderedFrameList::PopShallowestRoot() {
     37  MOZ_ASSERT(!mFrames.empty(), "no frames in list!");
     38 
     39  EnsureSortedList();
     40 
     41  // List is sorted in order of decreasing depth, so there are no shallower
     42  // frames than the last one.
     43  const FrameAndDepth& lastFAD = mSortedFrames.PopLastElement();
     44  nsIFrame* frame = lastFAD.mFrame;
     45  // We don't expect frame to change depths.
     46  MOZ_ASSERT(frame->GetDepthInFrameTree() == lastFAD.mDepth);
     47  // Keep the hashtable in sync with the sorted list.
     48  mFrames.remove(frame);
     49  return frame;
     50 }
     51 
     52 bool DepthOrderedFrameList::FrameIsAncestorOfAnyElement(
     53    nsIFrame* aFrame) const {
     54  MOZ_ASSERT(aFrame);
     55 
     56  // Look for a path from any element to aFrame, following GetParent(). This
     57  // check mirrors what FrameNeedsReflow() would have done if the reflow root
     58  // didn't get in the way.
     59  for (auto iter = mFrames.iter(); !iter.done(); iter.next()) {
     60    nsIFrame* f = iter.get().key();
     61    do {
     62      if (f == aFrame) {
     63        return true;
     64      }
     65      f = f->GetParent();
     66    } while (f);
     67  }
     68 
     69  return false;
     70 }
     71 
     72 void DepthOrderedFrameList::BuildSortedList() const {
     73  MOZ_ASSERT(mSortedFrames.IsEmpty());
     74 
     75  mSortedFrames.SetCapacity(mFrames.count());
     76  for (auto iter = mFrames.iter(); !iter.done(); iter.next()) {
     77    mSortedFrames.AppendElement(
     78        FrameAndDepth{iter.get().key(), iter.get().value()});
     79  }
     80  mSortedFrames.Sort();
     81 }
     82 
     83 }  // namespace mozilla