summaryrefslogtreecommitdiffstats
path: root/layout/base/nsFrameTraversal.h
diff options
context:
space:
mode:
Diffstat (limited to 'layout/base/nsFrameTraversal.h')
-rw-r--r--layout/base/nsFrameTraversal.h122
1 files changed, 122 insertions, 0 deletions
diff --git a/layout/base/nsFrameTraversal.h b/layout/base/nsFrameTraversal.h
new file mode 100644
index 0000000000..2226e60345
--- /dev/null
+++ b/layout/base/nsFrameTraversal.h
@@ -0,0 +1,122 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* 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/. */
+
+#ifndef NSFRAMETRAVERSAL_H
+#define NSFRAMETRAVERSAL_H
+
+#include <cstdint>
+#include "mozilla/Attributes.h"
+
+class nsIFrame;
+class nsPresContext;
+
+class MOZ_STACK_CLASS nsFrameIterator final {
+ public:
+ void First();
+ void Next();
+ nsIFrame* CurrentItem();
+ bool IsDone();
+
+ void Last();
+ void Prev();
+
+ inline nsIFrame* Traverse(bool aForward) {
+ if (aForward) {
+ Next();
+ } else {
+ Prev();
+ }
+ return CurrentItem();
+ };
+
+ enum class Type : uint8_t {
+ // only leaf nodes
+ Leaf,
+ // "open tag" order
+ PreOrder,
+ // "close tag" order
+ PostOrder,
+ };
+ nsFrameIterator(nsPresContext* aPresContext, nsIFrame* aStart, Type aType,
+ bool aVisual, bool aLockInScrollView, bool aFollowOOFs,
+ bool aSkipPopupChecks, nsIFrame* aLimiter = nullptr);
+ ~nsFrameIterator() = default;
+
+ protected:
+ void SetCurrent(nsIFrame* aFrame) { mCurrent = aFrame; }
+ nsIFrame* GetCurrent() { return mCurrent; }
+ nsIFrame* GetStart() { return mStart; }
+ nsIFrame* GetLast() { return mLast; }
+ void SetLast(nsIFrame* aFrame) { mLast = aFrame; }
+ int8_t GetOffEdge() { return mOffEdge; }
+ void SetOffEdge(int8_t aOffEdge) { mOffEdge = aOffEdge; }
+
+ /*
+ Our own versions of the standard frame tree navigation
+ methods, which, if the iterator is following out-of-flows,
+ apply the following rules for placeholder frames:
+
+ - If a frame HAS a placeholder frame, getting its parent
+ gets the placeholder's parent.
+
+ - If a frame's first child or next/prev sibling IS a
+ placeholder frame, then we instead return the real frame.
+
+ - If a frame HAS a placeholder frame, getting its next/prev
+ sibling gets the placeholder frame's next/prev sibling.
+
+ These are all applied recursively to support multiple levels of
+ placeholders.
+ */
+
+ nsIFrame* GetParentFrame(nsIFrame* aFrame);
+ // like GetParentFrame but returns null once a popup frame is reached
+ nsIFrame* GetParentFrameNotPopup(nsIFrame* aFrame);
+
+ nsIFrame* GetFirstChild(nsIFrame* aFrame);
+ nsIFrame* GetLastChild(nsIFrame* aFrame);
+
+ nsIFrame* GetNextSibling(nsIFrame* aFrame);
+ nsIFrame* GetPrevSibling(nsIFrame* aFrame);
+
+ /*
+ These methods are overridden by the bidi visual iterator to have the
+ semantics of "get first child in visual order", "get last child in visual
+ order", "get next sibling in visual order" and "get previous sibling in
+ visual order".
+ */
+
+ nsIFrame* GetFirstChildInner(nsIFrame* aFrame);
+ nsIFrame* GetLastChildInner(nsIFrame* aFrame);
+
+ nsIFrame* GetNextSiblingInner(nsIFrame* aFrame);
+ nsIFrame* GetPrevSiblingInner(nsIFrame* aFrame);
+
+ /**
+ * Return the placeholder frame for aFrame if it has one, otherwise return
+ * aFrame itself.
+ */
+ nsIFrame* GetPlaceholderFrame(nsIFrame* aFrame);
+ bool IsPopupFrame(nsIFrame* aFrame);
+
+ bool IsInvokerOpenPopoverFrame(nsIFrame* aFrame);
+
+ nsPresContext* const mPresContext;
+ const bool mLockScroll;
+ const bool mFollowOOFs;
+ const bool mSkipPopupChecks;
+ const bool mVisual;
+ const Type mType;
+
+ private:
+ nsIFrame* const mStart;
+ nsIFrame* mCurrent;
+ nsIFrame* mLast; // the last one that was in current;
+ nsIFrame* mLimiter;
+ int8_t mOffEdge; // 0= no -1 to far prev, 1 to far next;
+};
+
+#endif // NSFRAMETRAVERSAL_H