Use pointer-events: none on the treecol contents, which is the only remaining user of this. This is similar to how we've dealt with similar previous usage of this that are now gone from the tree. Differential Revision: https://phabricator.services.mozilla.com/D168961
162 lines
4.9 KiB
C++
162 lines
4.9 KiB
C++
/* -*- 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/. */
|
|
|
|
#include "nsTreeColFrame.h"
|
|
|
|
#include "mozilla/ComputedStyle.h"
|
|
#include "mozilla/ErrorResult.h"
|
|
#include "mozilla/PresShell.h"
|
|
#include "mozilla/dom/XULTreeElement.h"
|
|
#include "mozilla/CSSOrderAwareFrameIterator.h"
|
|
#include "nsCOMPtr.h"
|
|
#include "nsGkAtoms.h"
|
|
#include "nsIContent.h"
|
|
#include "nsNameSpaceManager.h"
|
|
#include "nsTreeColumns.h"
|
|
#include "nsDisplayList.h"
|
|
#include "nsTreeBodyFrame.h"
|
|
#include "nsXULElement.h"
|
|
|
|
using namespace mozilla;
|
|
using namespace mozilla::dom;
|
|
|
|
//
|
|
// NS_NewTreeColFrame
|
|
//
|
|
// Creates a new col frame
|
|
//
|
|
nsIFrame* NS_NewTreeColFrame(PresShell* aPresShell, ComputedStyle* aStyle) {
|
|
return new (aPresShell) nsTreeColFrame(aStyle, aPresShell->GetPresContext());
|
|
}
|
|
|
|
NS_IMPL_FRAMEARENA_HELPERS(nsTreeColFrame)
|
|
|
|
// Destructor
|
|
nsTreeColFrame::~nsTreeColFrame() = default;
|
|
|
|
void nsTreeColFrame::Init(nsIContent* aContent, nsContainerFrame* aParent,
|
|
nsIFrame* aPrevInFlow) {
|
|
nsBoxFrame::Init(aContent, aParent, aPrevInFlow);
|
|
InvalidateColumns();
|
|
}
|
|
|
|
void nsTreeColFrame::DestroyFrom(nsIFrame* aDestructRoot,
|
|
PostDestroyData& aPostDestroyData) {
|
|
InvalidateColumns(false);
|
|
nsBoxFrame::DestroyFrom(aDestructRoot, aPostDestroyData);
|
|
}
|
|
|
|
nsresult nsTreeColFrame::AttributeChanged(int32_t aNameSpaceID,
|
|
nsAtom* aAttribute,
|
|
int32_t aModType) {
|
|
nsresult rv =
|
|
nsBoxFrame::AttributeChanged(aNameSpaceID, aAttribute, aModType);
|
|
|
|
if (aAttribute == nsGkAtoms::primary) {
|
|
InvalidateColumns();
|
|
}
|
|
|
|
return rv;
|
|
}
|
|
|
|
void nsTreeColFrame::SetXULBounds(nsBoxLayoutState& aBoxLayoutState,
|
|
const nsRect& aRect,
|
|
bool aRemoveOverflowArea) {
|
|
nscoord oldWidth = mRect.width;
|
|
|
|
nsBoxFrame::SetXULBounds(aBoxLayoutState, aRect, aRemoveOverflowArea);
|
|
if (mRect.width != oldWidth) {
|
|
RefPtr<XULTreeElement> tree = GetTree();
|
|
if (tree) {
|
|
tree->Invalidate();
|
|
}
|
|
}
|
|
}
|
|
|
|
XULTreeElement* nsTreeColFrame::GetTree() {
|
|
nsIContent* parent = mContent->GetParent();
|
|
return parent ? XULTreeElement::FromNodeOrNull(parent->GetParent()) : nullptr;
|
|
}
|
|
|
|
void nsTreeColFrame::InvalidateColumns(bool aCanWalkFrameTree) {
|
|
RefPtr<XULTreeElement> tree = GetTree();
|
|
if (!tree) {
|
|
return;
|
|
}
|
|
|
|
nsTreeBodyFrame* body = aCanWalkFrameTree
|
|
? tree->GetTreeBodyFrame(FlushType::None)
|
|
: tree->GetCachedTreeBodyFrame();
|
|
|
|
if (!body) {
|
|
return;
|
|
}
|
|
|
|
RefPtr<nsTreeColumns> columns = body->Columns();
|
|
if (!columns) {
|
|
return;
|
|
}
|
|
|
|
columns->InvalidateColumns();
|
|
}
|
|
|
|
namespace mozilla {
|
|
|
|
class nsDisplayXULTreeColSplitterTarget final : public nsDisplayItem {
|
|
public:
|
|
nsDisplayXULTreeColSplitterTarget(nsDisplayListBuilder* aBuilder,
|
|
nsIFrame* aFrame)
|
|
: nsDisplayItem(aBuilder, aFrame) {
|
|
MOZ_COUNT_CTOR(nsDisplayXULTreeColSplitterTarget);
|
|
}
|
|
MOZ_COUNTED_DTOR_OVERRIDE(nsDisplayXULTreeColSplitterTarget)
|
|
|
|
void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
|
|
HitTestState* aState, nsTArray<nsIFrame*>* aOutFrames) override;
|
|
NS_DISPLAY_DECL_NAME("XULTreeColSplitterTarget",
|
|
TYPE_XUL_TREE_COL_SPLITTER_TARGET)
|
|
};
|
|
|
|
void nsDisplayXULTreeColSplitterTarget::HitTest(
|
|
nsDisplayListBuilder* aBuilder, const nsRect& aRect, HitTestState* aState,
|
|
nsTArray<nsIFrame*>* aOutFrames) {
|
|
nsRect rect = aRect - ToReferenceFrame();
|
|
// If we are in either in the first 4 pixels or the last 4 pixels, we're going
|
|
// to do something really strange. Check for an adjacent splitter.
|
|
bool left = false;
|
|
bool right = false;
|
|
if (mFrame->GetSize().width - nsPresContext::CSSPixelsToAppUnits(4) <=
|
|
rect.XMost()) {
|
|
right = true;
|
|
} else if (nsPresContext::CSSPixelsToAppUnits(4) > rect.x) {
|
|
left = true;
|
|
}
|
|
|
|
// Swap left and right for RTL trees in order to find the correct splitter
|
|
if (mFrame->StyleVisibility()->mDirection == StyleDirection::Rtl) {
|
|
std::swap(left, right);
|
|
}
|
|
|
|
if (left || right) {
|
|
nsIFrame* child = nsBoxFrame::SlowOrdinalGroupAwareSibling(mFrame, right);
|
|
// We are a header. Look for the correct splitter.
|
|
if (child && child->GetContent()->IsXULElement(nsGkAtoms::splitter)) {
|
|
aOutFrames->AppendElement(child);
|
|
}
|
|
}
|
|
}
|
|
|
|
} // namespace mozilla
|
|
|
|
void nsTreeColFrame::BuildDisplayListForChildren(
|
|
nsDisplayListBuilder* aBuilder, const nsDisplayListSet& aLists) {
|
|
nsBoxFrame::BuildDisplayListForChildren(aBuilder, aLists);
|
|
if (aBuilder->IsForEventDelivery()) {
|
|
aLists.Content()->AppendNewToTop<nsDisplayXULTreeColSplitterTarget>(
|
|
aBuilder, this);
|
|
}
|
|
}
|