1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117
|
/* -*- 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 AnchorPositioningUtils_h__
#define AnchorPositioningUtils_h__
#include "mozilla/Maybe.h"
#include "nsRect.h"
#include "nsTHashMap.h"
class nsAtom;
class nsIFrame;
template <class T>
class nsTArray;
namespace mozilla {
struct AnchorPosInfo {
// Border-box of the anchor frame, offset against `mContainingBlock`'s padding
// box.
nsRect mRect;
const nsIFrame* mContainingBlock;
};
// Resolved anchor positioning data.
struct AnchorPosResolutionData {
// Size of the referenced anchor.
nsSize mSize;
// Origin of the referenced anchor, w.r.t. containing block at the time of
// resolution. Includes scroll offsets, for now.
// Nothing if the anchor did not resolve, or if the anchor was only referred
// to by its size.
mozilla::Maybe<nsPoint> mOrigin;
};
// Data required for an anchor positioned frame, including:
// * If valid anchors are found,
// * Cached offset/size resolution, if resolution was valid,
// * TODO(dshin, bug 1968745): Compensating for scroll [1]
// * TODO(dshin, bug 1987962): Default scroll shift [2]
//
// [1]: https://drafts.csswg.org/css-anchor-position-1/#compensate-for-scroll
// [2]: https://drafts.csswg.org/css-anchor-position-1/#default-scroll-shift
class AnchorPosReferenceData {
private:
using Map =
nsTHashMap<RefPtr<const nsAtom>, mozilla::Maybe<AnchorPosResolutionData>>;
public:
using Value = mozilla::Maybe<AnchorPosResolutionData>;
AnchorPosReferenceData() = default;
AnchorPosReferenceData(const AnchorPosReferenceData&) = delete;
AnchorPosReferenceData(AnchorPosReferenceData&&) = default;
AnchorPosReferenceData& operator=(const AnchorPosReferenceData&) = delete;
AnchorPosReferenceData& operator=(AnchorPosReferenceData&&) = default;
struct Result {
bool mAlreadyResolved;
Value* mEntry;
};
Result InsertOrModify(const nsAtom* aAnchorName, bool aNeedOffset);
const Value* Lookup(const nsAtom* aAnchorName) const;
bool IsEmpty() const { return mMap.IsEmpty(); }
Map::const_iterator begin() const { return mMap.cbegin(); }
Map::const_iterator end() const { return mMap.cend(); }
private:
Map mMap;
};
struct StylePositionArea;
struct StylePositionTryFallbacksTryTactic;
class WritingMode;
/**
* AnchorPositioningUtils is a namespace class used for various anchor
* positioning helper functions that are useful in multiple places.
* The goal is to avoid code duplication and to avoid having too
* many helpers in nsLayoutUtils.
*/
struct AnchorPositioningUtils {
/**
* Finds the first acceptable frame from the list of possible anchor frames
* following https://drafts.csswg.org/css-anchor-position-1/#target
*/
static nsIFrame* FindFirstAcceptableAnchor(
const nsAtom* aName, const nsIFrame* aPositionedFrame,
const nsTArray<nsIFrame*>& aPossibleAnchorFrames);
static Maybe<AnchorPosInfo> GetAnchorPosRect(
const nsIFrame* aAbsoluteContainingBlock, const nsIFrame* aAnchor,
bool aCBRectIsvalid,
Maybe<AnchorPosResolutionData>* aReferencedAnchorsEntry);
/**
* Adjust the containing block rect for the 'position-area' property.
* https://drafts.csswg.org/css-anchor-position-1/#position-area
*/
static nsRect AdjustAbsoluteContainingBlockRectForPositionArea(
nsIFrame* aPositionedFrame, nsIFrame* aContainingBlock,
const nsRect& aCBRect, AnchorPosReferenceData* aAnchorPosReferenceData,
const StylePositionArea& aPositionArea,
const StylePositionTryFallbacksTryTactic* aFallbackTactic);
};
} // namespace mozilla
#endif // AnchorPositioningUtils_h__
|