summaryrefslogtreecommitdiffstats
path: root/layout/generic/nsIFrame.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'layout/generic/nsIFrame.cpp')
-rw-r--r--layout/generic/nsIFrame.cpp87
1 files changed, 72 insertions, 15 deletions
diff --git a/layout/generic/nsIFrame.cpp b/layout/generic/nsIFrame.cpp
index 27f09b84f6..28c328c9e2 100644
--- a/layout/generic/nsIFrame.cpp
+++ b/layout/generic/nsIFrame.cpp
@@ -19,6 +19,7 @@
#include "mozilla/DebugOnly.h"
#include "mozilla/DisplayPortUtils.h"
#include "mozilla/EventForwards.h"
+#include "mozilla/FocusModel.h"
#include "mozilla/dom/CSSAnimation.h"
#include "mozilla/dom/CSSTransition.h"
#include "mozilla/dom/ContentVisibilityAutoStateChangeEvent.h"
@@ -4928,12 +4929,14 @@ bool nsIFrame::MovingCaretToEventPointAllowedIfSecondaryButtonEvent(
: aContentAtEventPoint.GetClosestNativeAnonymousSubtreeRoot());
if (Selection* selection =
aFrameSelection.GetSelection(SelectionType::eNormal)) {
- const bool selectionIsCollapsed = selection->IsCollapsed();
- // If right click in a selection range, we should not collapse selection.
- if (!selectionIsCollapsed &&
- nsContentUtils::IsPointInSelection(
- *selection, aContentAtEventPoint,
- static_cast<uint32_t>(aOffsetAtEventPoint))) {
+ const bool selectionIsCollapsed =
+ selection->AreNormalAndCrossShadowBoundaryRangesCollapsed();
+ // If right click in a selection range, we should not collapse
+ // selection.
+ if (!selectionIsCollapsed && nsContentUtils::IsPointInSelection(
+ *selection, aContentAtEventPoint,
+ static_cast<uint32_t>(aOffsetAtEventPoint),
+ true /* aAllowCrossShadowBoundary */)) {
return false;
}
const bool wantToPreventMoveCaret =
@@ -7889,7 +7892,7 @@ nsRect nsIFrame::GetNormalRect() const {
nsRect nsIFrame::GetBoundingClientRect() {
return nsLayoutUtils::GetAllInFlowRectsUnion(
this, nsLayoutUtils::GetContainingBlockForClientRect(this),
- nsLayoutUtils::RECTS_ACCOUNT_FOR_TRANSFORMS);
+ nsLayoutUtils::GetAllInFlowRectsFlag::AccountForTransforms);
}
nsPoint nsIFrame::GetPositionIgnoringScrolling() const {
@@ -7950,8 +7953,19 @@ OverflowAreas nsIFrame::GetActualAndNormalOverflowAreasRelativeToParent()
}
const OverflowAreas overflows = GetOverflowAreas();
- OverflowAreas actualAndNormalOverflows = overflows + GetPosition();
- actualAndNormalOverflows.UnionWith(overflows + GetNormalPosition());
+ OverflowAreas actualAndNormalOverflows = overflows + GetNormalPosition();
+ if (IsRelativelyPositioned()) {
+ actualAndNormalOverflows.UnionWith(overflows + GetPosition());
+ } else {
+ // For sticky positioned elements, we only use the normal position for the
+ // scrollable overflow. This avoids circular dependencies between sticky
+ // positioned elements and their scroll container. (The scroll position and
+ // the scroll container's size impact the sticky position, so we don't want
+ // the sticky position to impact them.)
+ MOZ_ASSERT(IsStickyPositioned());
+ actualAndNormalOverflows.UnionWith(
+ OverflowAreas(overflows.InkOverflow() + GetPosition(), nsRect()));
+ }
return actualAndNormalOverflows;
}
@@ -8008,7 +8022,7 @@ bool nsIFrame::UpdateOverflow() {
if (nsView* view = GetView()) {
// Make sure the frame's view is properly sized.
nsViewManager* vm = view->GetViewManager();
- vm->ResizeView(view, overflowAreas.InkOverflow(), true);
+ vm->ResizeView(view, overflowAreas.InkOverflow());
}
return true;
@@ -10795,7 +10809,7 @@ bool nsIFrame::IsFocusableDueToScrollFrame() {
return true;
}
-Focusable nsIFrame::IsFocusable(bool aWithMouse, bool aCheckVisibility) {
+Focusable nsIFrame::IsFocusable(IsFocusableFlags aFlags) {
// cannot focus content in print preview mode. Only the root can be focused,
// but that's handled elsewhere.
if (PresContext()->Type() == nsPresContext::eContext_PrintPreview) {
@@ -10806,7 +10820,8 @@ Focusable nsIFrame::IsFocusable(bool aWithMouse, bool aCheckVisibility) {
return {};
}
- if (aCheckVisibility && !IsVisibleConsideringAncestors()) {
+ if (!(aFlags & IsFocusableFlags::IgnoreVisibility) &&
+ !IsVisibleConsideringAncestors()) {
return {};
}
@@ -10826,14 +10841,14 @@ Focusable nsIFrame::IsFocusable(bool aWithMouse, bool aCheckVisibility) {
// As a legacy special-case, -moz-user-focus controls focusability and
// tabability of XUL elements in some circumstances (which default to
// -moz-user-focus: ignore).
- auto focusability = xul->GetXULFocusability(aWithMouse);
+ auto focusability = xul->GetXULFocusability(aFlags);
focusable.mFocusable =
focusability.mForcedFocusable.valueOr(uf == StyleUserFocus::Normal);
if (focusable) {
focusable.mTabIndex = focusability.mForcedTabIndexIfFocusable.valueOr(0);
}
} else {
- focusable = mContent->IsFocusableWithoutStyle(aWithMouse);
+ focusable = mContent->IsFocusableWithoutStyle(aFlags);
}
if (focusable) {
@@ -10841,7 +10856,8 @@ Focusable nsIFrame::IsFocusable(bool aWithMouse, bool aCheckVisibility) {
}
// If we're focusing with the mouse we never focus scroll areas.
- if (!aWithMouse && IsFocusableDueToScrollFrame()) {
+ if (!(aFlags & IsFocusableFlags::WithMouse) &&
+ IsFocusableDueToScrollFrame()) {
return {true, 0};
}
@@ -11627,6 +11643,47 @@ bool nsIFrame::HasUnreflowedContainerQueryAncestor() const {
return false;
}
+bool nsIFrame::ShouldBreakBefore(
+ const ReflowInput::BreakType aBreakType) const {
+ const auto* display = StyleDisplay();
+ return ShouldBreakBetween(display, display->mBreakBefore, aBreakType);
+}
+
+bool nsIFrame::ShouldBreakAfter(const ReflowInput::BreakType aBreakType) const {
+ const auto* display = StyleDisplay();
+ return ShouldBreakBetween(display, display->mBreakAfter, aBreakType);
+}
+
+bool nsIFrame::ShouldBreakBetween(
+ const nsStyleDisplay* aDisplay, const StyleBreakBetween aBreakBetween,
+ const ReflowInput::BreakType aBreakType) const {
+ const bool shouldBreakBetween = [&] {
+ switch (aBreakBetween) {
+ case StyleBreakBetween::Always:
+ return true;
+ case StyleBreakBetween::Auto:
+ case StyleBreakBetween::Avoid:
+ return false;
+ case StyleBreakBetween::Page:
+ case StyleBreakBetween::Left:
+ case StyleBreakBetween::Right:
+ return aBreakType == ReflowInput::BreakType::Page;
+ }
+ MOZ_ASSERT_UNREACHABLE("Unknown break-between value!");
+ return false;
+ }();
+
+ if (!shouldBreakBetween) {
+ return false;
+ }
+ if (IsAbsolutelyPositioned(aDisplay)) {
+ // 'break-before' and 'break-after' properties does not apply to
+ // absolutely-positioned boxes.
+ return false;
+ }
+ return true;
+}
+
#ifdef DEBUG
static void GetTagName(nsIFrame* aFrame, nsIContent* aContent, int aResultSize,
char* aResult) {