Bug 1820634 - Remove nsTreeColFrame. r=Gijs
Layout-wise it doesn't have any special code. Only weirdness is: * Invalidation when size changes (we can do that with a ResizeObserver). * Weird paint retargetting to the splitter, which we can fix by using negative margins instead and using a regular splitter. Differential Revision: https://phabricator.services.mozilla.com/D171768
This commit is contained in:
@@ -201,8 +201,6 @@ static FrameCtorDebugFlags gFlags[] = {
|
||||
# define NUM_DEBUG_FLAGS (sizeof(gFlags) / sizeof(gFlags[0]))
|
||||
#endif
|
||||
|
||||
#include "nsTreeColFrame.h"
|
||||
|
||||
//------------------------------------------------------------------
|
||||
|
||||
nsIFrame* NS_NewLeafBoxFrame(PresShell* aPresShell, ComputedStyle* aStyle);
|
||||
@@ -4132,7 +4130,6 @@ nsCSSFrameConstructor::FindXULTagData(const Element& aElement,
|
||||
static constexpr FrameConstructionDataByTag sXULTagData[] = {
|
||||
SIMPLE_XUL_CREATE(image, NS_NewXULImageFrame),
|
||||
SIMPLE_XUL_CREATE(treechildren, NS_NewTreeBodyFrame),
|
||||
SIMPLE_XUL_CREATE(treecol, NS_NewTreeColFrame),
|
||||
SIMPLE_TAG_CHAIN(label,
|
||||
nsCSSFrameConstructor::FindXULLabelOrDescriptionData),
|
||||
SIMPLE_TAG_CHAIN(description,
|
||||
|
||||
@@ -126,7 +126,6 @@ FRAME_CLASSES = [
|
||||
Frame("nsTextControlFrame", "TextInput", LEAF),
|
||||
Frame("nsTextFrame", "Text", LEAF),
|
||||
Frame("nsTreeBodyFrame", "LeafBox", LEAF),
|
||||
Frame("nsTreeColFrame", "Box", NOT_LEAF),
|
||||
Frame("nsVideoFrame", "HTMLVideo", NOT_LEAF),
|
||||
Frame("nsXULScrollFrame", "Scroll", NOT_LEAF),
|
||||
Frame("ViewportFrame", "Viewport", NOT_LEAF),
|
||||
|
||||
@@ -15,14 +15,12 @@ XPIDL_SOURCES += [
|
||||
XPIDL_MODULE = "layout_xul_tree"
|
||||
|
||||
EXPORTS += [
|
||||
"nsTreeColFrame.h",
|
||||
"nsTreeColumns.h",
|
||||
"nsTreeUtils.h",
|
||||
]
|
||||
|
||||
UNIFIED_SOURCES += [
|
||||
"nsTreeBodyFrame.cpp",
|
||||
"nsTreeColFrame.cpp",
|
||||
"nsTreeColumns.cpp",
|
||||
"nsTreeContentView.cpp",
|
||||
"nsTreeImageListener.cpp",
|
||||
|
||||
@@ -1,161 +0,0 @@
|
||||
/* -*- 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);
|
||||
}
|
||||
}
|
||||
@@ -1,60 +0,0 @@
|
||||
/* -*- 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 "mozilla/Attributes.h"
|
||||
#include "mozilla/ComputedStyle.h"
|
||||
#include "nsBoxFrame.h"
|
||||
|
||||
namespace mozilla {
|
||||
class PresShell;
|
||||
namespace dom {
|
||||
class XULTreeElement;
|
||||
}
|
||||
} // namespace mozilla
|
||||
|
||||
nsIFrame* NS_NewTreeColFrame(mozilla::PresShell* aPresShell,
|
||||
mozilla::ComputedStyle* aStyle);
|
||||
|
||||
class nsTreeColFrame final : public nsBoxFrame {
|
||||
public:
|
||||
NS_DECL_FRAMEARENA_HELPERS(nsTreeColFrame)
|
||||
|
||||
explicit nsTreeColFrame(ComputedStyle* aStyle, nsPresContext* aPresContext)
|
||||
: nsBoxFrame(aStyle, aPresContext, kClassID) {}
|
||||
|
||||
virtual void Init(nsIContent* aContent, nsContainerFrame* aParent,
|
||||
nsIFrame* aPrevInFlow) override;
|
||||
|
||||
virtual void DestroyFrom(nsIFrame* aDestructRoot,
|
||||
PostDestroyData& aPostDestroyData) override;
|
||||
|
||||
virtual void BuildDisplayListForChildren(
|
||||
nsDisplayListBuilder* aBuilder, const nsDisplayListSet& aLists) override;
|
||||
|
||||
virtual nsresult AttributeChanged(int32_t aNameSpaceID, nsAtom* aAttribute,
|
||||
int32_t aModType) override;
|
||||
|
||||
virtual void SetXULBounds(nsBoxLayoutState& aBoxLayoutState,
|
||||
const nsRect& aRect,
|
||||
bool aRemoveOverflowArea = false) override;
|
||||
|
||||
friend nsIFrame* NS_NewTreeColFrame(mozilla::PresShell* aPresShell,
|
||||
ComputedStyle* aStyle);
|
||||
|
||||
protected:
|
||||
virtual ~nsTreeColFrame();
|
||||
|
||||
/**
|
||||
* @return the tree that this column belongs to, or nullptr.
|
||||
*/
|
||||
mozilla::dom::XULTreeElement* GetTree();
|
||||
|
||||
/**
|
||||
* Helper method that gets the TreeColumns object this column belongs to
|
||||
* and calls InvalidateColumns() on it.
|
||||
*/
|
||||
void InvalidateColumns(bool aCanWalkFrameTree = true);
|
||||
};
|
||||
@@ -203,7 +203,7 @@ class nsTreeColumns final : public nsISupports, public nsWrapperCache {
|
||||
/**
|
||||
* The first column in the list of columns. All of the columns are supposed
|
||||
* to be "alive", i.e. have a frame. This is achieved by clearing the columns
|
||||
* list each time an nsTreeColFrame is destroyed.
|
||||
* list each time a treecol changes size.
|
||||
*
|
||||
* XXX this means that new nsTreeColumn objects are unnecessarily created
|
||||
* for untouched columns.
|
||||
|
||||
@@ -302,6 +302,10 @@
|
||||
customElements.define("treecolpicker", MozTreecolPicker);
|
||||
|
||||
class MozTreecol extends MozElements.BaseControl {
|
||||
static get observedAttributes() {
|
||||
return ["primary"];
|
||||
}
|
||||
|
||||
static get inheritedAttributes() {
|
||||
return {
|
||||
".treecol-sortdirection": "sortdirection,hidden=hideheader",
|
||||
@@ -316,6 +320,19 @@
|
||||
`;
|
||||
}
|
||||
|
||||
get _tree() {
|
||||
return this.parentNode?.parentNode;
|
||||
}
|
||||
|
||||
_invalidate() {
|
||||
let tree = this._tree;
|
||||
if (!tree || !XULTreeElement.isInstance(tree)) {
|
||||
return;
|
||||
}
|
||||
tree.invalidate();
|
||||
tree.columns?.invalidateColumns();
|
||||
}
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
@@ -323,7 +340,7 @@
|
||||
if (event.button != 0) {
|
||||
return;
|
||||
}
|
||||
if (this.parentNode.parentNode.enableColumnDrag) {
|
||||
if (this._tree.enableColumnDrag) {
|
||||
var XUL_NS =
|
||||
"http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
|
||||
var cols = this.parentNode.getElementsByTagNameNS(XUL_NS, "treecol");
|
||||
@@ -361,7 +378,7 @@
|
||||
return;
|
||||
}
|
||||
|
||||
var tree = this.parentNode.parentNode;
|
||||
var tree = this._tree;
|
||||
if (tree.columns) {
|
||||
tree.view.cycleHeader(tree.columns.getColumnFor(this));
|
||||
}
|
||||
@@ -379,6 +396,20 @@
|
||||
if (this.hasAttribute("ordinal")) {
|
||||
this.style.MozBoxOrdinalGroup = this.getAttribute("ordinal");
|
||||
}
|
||||
|
||||
this._resizeObserver = new ResizeObserver(() => {
|
||||
this._invalidate();
|
||||
});
|
||||
this._resizeObserver.observe(this);
|
||||
}
|
||||
|
||||
disconnectedCallback() {
|
||||
this._resizeObserver?.unobserve(this);
|
||||
this._resizeObserver = null;
|
||||
}
|
||||
|
||||
attributeChangedCallback() {
|
||||
this._invalidate();
|
||||
}
|
||||
|
||||
set ordinal(val) {
|
||||
@@ -1198,7 +1229,10 @@
|
||||
for (i = 0; i < cols.length; ++i) {
|
||||
cols[i].ordinal = parseInt(cols[i].ordinal) - 2;
|
||||
}
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
this.columns.invalidateColumns();
|
||||
}
|
||||
|
||||
_getColumnAtX(aX, aThresh, aPos) {
|
||||
|
||||
@@ -672,13 +672,14 @@ menulist[popuponly] {
|
||||
/********** splitter **********/
|
||||
|
||||
.tree-splitter {
|
||||
width: 0;
|
||||
max-width: 0;
|
||||
margin-inline: -4px;
|
||||
width: 8px;
|
||||
max-width: 8px;
|
||||
min-width: 8px;
|
||||
appearance: none !important;
|
||||
min-width: 0 !important;
|
||||
min-height: 0 !important;
|
||||
border: none !important;
|
||||
-moz-box-ordinal-group: 2147483646;
|
||||
z-index: 2147483646;
|
||||
}
|
||||
|
||||
/******** scrollbar ********/
|
||||
|
||||
Reference in New Issue
Block a user