Backed out 3 changesets (bug 1482389) for build bustages in nsDOMAttributeMap.h CLOSED TREE

Backed out changeset c1cfc595892f (bug 1482389)
Backed out changeset bd20e420f257 (bug 1482389)
Backed out changeset af06731b5203 (bug 1482389)

--HG--
rename : dom/chrome-webidl/XULTreeElement.webidl => dom/webidl/TreeBoxObject.webidl
rename : dom/xul/XULTreeElement.cpp => layout/xul/tree/TreeBoxObject.cpp
rename : dom/xul/XULTreeElement.h => layout/xul/tree/TreeBoxObject.h
This commit is contained in:
Noemi Erli 2019-01-09 16:00:19 +02:00
Родитель 1ac8081516
Коммит e79ee45812
79 изменённых файлов: 1393 добавлений и 962 удалений

Просмотреть файл

@ -32,7 +32,7 @@
#include "nsComponentManagerUtils.h" #include "nsComponentManagerUtils.h"
#include "XULTreeElement.h" #include "nsITreeBoxObject.h"
#include "nsTreeColumns.h" #include "nsTreeColumns.h"
#include "mozilla/dom/Element.h" #include "mozilla/dom/Element.h"
#include "mozilla/dom/HTMLLabelElement.h" #include "mozilla/dom/HTMLLabelElement.h"
@ -63,10 +63,11 @@ bool nsCoreUtils::HasClickListener(nsIContent *aContent) {
listenerManager->HasListenersFor(nsGkAtoms::onmouseup)); listenerManager->HasListenersFor(nsGkAtoms::onmouseup));
} }
void nsCoreUtils::DispatchClickEvent(XULTreeElement *aTree, void nsCoreUtils::DispatchClickEvent(nsITreeBoxObject *aTreeBoxObj,
int32_t aRowIndex, nsTreeColumn *aColumn, int32_t aRowIndex, nsTreeColumn *aColumn,
const nsAString &aPseudoElt) { const nsAString &aPseudoElt) {
RefPtr<dom::Element> tcElm = aTree->GetTreeBody(); RefPtr<dom::Element> tcElm;
aTreeBoxObj->GetTreeBody(getter_AddRefs(tcElm));
if (!tcElm) return; if (!tcElm) return;
Document *document = tcElm->GetUncomposedDoc(); Document *document = tcElm->GetUncomposedDoc();
@ -76,15 +77,13 @@ void nsCoreUtils::DispatchClickEvent(XULTreeElement *aTree,
if (!presShell) return; if (!presShell) return;
// Ensure row is visible. // Ensure row is visible.
aTree->EnsureRowIsVisible(aRowIndex); aTreeBoxObj->EnsureRowIsVisible(aRowIndex);
// Calculate x and y coordinates. // Calculate x and y coordinates.
nsresult rv; int32_t x = 0, y = 0, width = 0, height = 0;
nsIntRect rect = nsresult rv = aTreeBoxObj->GetCoordsForCellItem(
aTree->GetCoordsForCellItem(aRowIndex, aColumn, aPseudoElt, rv); aRowIndex, aColumn, aPseudoElt, &x, &y, &width, &height);
if (NS_FAILED(rv)) { if (NS_FAILED(rv)) return;
return;
}
nsCOMPtr<nsIBoxObject> tcBoxObj = nsCOMPtr<nsIBoxObject> tcBoxObj =
nsXULElement::FromNode(tcElm)->GetBoxObject(IgnoreErrors()); nsXULElement::FromNode(tcElm)->GetBoxObject(IgnoreErrors());
@ -104,9 +103,9 @@ void nsCoreUtils::DispatchClickEvent(XULTreeElement *aTree,
RefPtr<nsPresContext> presContext = presShell->GetPresContext(); RefPtr<nsPresContext> presContext = presShell->GetPresContext();
int32_t cnvdX = presContext->CSSPixelsToDevPixels(tcX + int32_t(rect.x) + 1) + int32_t cnvdX = presContext->CSSPixelsToDevPixels(tcX + x + 1) +
presContext->AppUnitsToDevPixels(offset.x); presContext->AppUnitsToDevPixels(offset.x);
int32_t cnvdY = presContext->CSSPixelsToDevPixels(tcY + int32_t(rect.y) + 1) + int32_t cnvdY = presContext->CSSPixelsToDevPixels(tcY + y + 1) +
presContext->AppUnitsToDevPixels(offset.y); presContext->AppUnitsToDevPixels(offset.y);
// XUL is just desktop, so there is no real reason for senfing touch events. // XUL is just desktop, so there is no real reason for senfing touch events.
@ -426,20 +425,26 @@ void nsCoreUtils::GetLanguageFor(nsIContent *aContent, nsIContent *aRootContent,
} }
already_AddRefed<nsIBoxObject> nsCoreUtils::GetTreeBodyBoxObject( already_AddRefed<nsIBoxObject> nsCoreUtils::GetTreeBodyBoxObject(
XULTreeElement *aTree) { nsITreeBoxObject *aTreeBoxObj) {
RefPtr<dom::Element> tcElm = aTree->GetTreeBody(); RefPtr<dom::Element> tcElm;
aTreeBoxObj->GetTreeBody(getter_AddRefs(tcElm));
RefPtr<nsXULElement> tcXULElm = nsXULElement::FromNodeOrNull(tcElm); RefPtr<nsXULElement> tcXULElm = nsXULElement::FromNodeOrNull(tcElm);
if (!tcXULElm) return nullptr; if (!tcXULElm) return nullptr;
return tcXULElm->GetBoxObject(IgnoreErrors()); return tcXULElm->GetBoxObject(IgnoreErrors());
} }
XULTreeElement *nsCoreUtils::GetTree(nsIContent *aContent) { already_AddRefed<nsITreeBoxObject> nsCoreUtils::GetTreeBoxObject(
nsIContent *aContent) {
// Find DOMNode's parents recursively until reach the <tree> tag // Find DOMNode's parents recursively until reach the <tree> tag
nsIContent *currentContent = aContent; nsIContent *currentContent = aContent;
while (currentContent) { while (currentContent) {
if (currentContent->NodeInfo()->Equals(nsGkAtoms::tree, kNameSpaceID_XUL)) { if (currentContent->NodeInfo()->Equals(nsGkAtoms::tree, kNameSpaceID_XUL)) {
return XULTreeElement::FromNode(currentContent); // We will get the nsITreeBoxObject from the tree node
RefPtr<nsXULElement> xulElement = nsXULElement::FromNode(currentContent);
nsCOMPtr<nsIBoxObject> box = xulElement->GetBoxObject(IgnoreErrors());
nsCOMPtr<nsITreeBoxObject> treeBox(do_QueryInterface(box));
if (treeBox) return treeBox.forget();
} }
currentContent = currentContent->GetFlattenedTreeParent(); currentContent = currentContent->GetFlattenedTreeParent();
} }
@ -448,8 +453,9 @@ XULTreeElement *nsCoreUtils::GetTree(nsIContent *aContent) {
} }
already_AddRefed<nsTreeColumn> nsCoreUtils::GetFirstSensibleColumn( already_AddRefed<nsTreeColumn> nsCoreUtils::GetFirstSensibleColumn(
XULTreeElement *aTree) { nsITreeBoxObject *aTree) {
RefPtr<nsTreeColumns> cols = aTree->GetColumns(); RefPtr<nsTreeColumns> cols;
aTree->GetColumns(getter_AddRefs(cols));
if (!cols) return nullptr; if (!cols) return nullptr;
RefPtr<nsTreeColumn> column = cols->GetFirstColumn(); RefPtr<nsTreeColumn> column = cols->GetFirstColumn();
@ -458,10 +464,11 @@ already_AddRefed<nsTreeColumn> nsCoreUtils::GetFirstSensibleColumn(
return column.forget(); return column.forget();
} }
uint32_t nsCoreUtils::GetSensibleColumnCount(XULTreeElement *aTree) { uint32_t nsCoreUtils::GetSensibleColumnCount(nsITreeBoxObject *aTree) {
uint32_t count = 0; uint32_t count = 0;
RefPtr<nsTreeColumns> cols = aTree->GetColumns(); RefPtr<nsTreeColumns> cols;
aTree->GetColumns(getter_AddRefs(cols));
if (!cols) return count; if (!cols) return count;
nsTreeColumn *column = cols->GetFirstColumn(); nsTreeColumn *column = cols->GetFirstColumn();
@ -476,7 +483,7 @@ uint32_t nsCoreUtils::GetSensibleColumnCount(XULTreeElement *aTree) {
} }
already_AddRefed<nsTreeColumn> nsCoreUtils::GetSensibleColumnAt( already_AddRefed<nsTreeColumn> nsCoreUtils::GetSensibleColumnAt(
XULTreeElement *aTree, uint32_t aIndex) { nsITreeBoxObject *aTree, uint32_t aIndex) {
uint32_t idx = aIndex; uint32_t idx = aIndex;
nsCOMPtr<nsTreeColumn> column = GetFirstSensibleColumn(aTree); nsCOMPtr<nsTreeColumn> column = GetFirstSensibleColumn(aTree);

Просмотреть файл

@ -21,14 +21,9 @@ class nsTreeColumn;
class nsIBoxObject; class nsIBoxObject;
class nsIFrame; class nsIFrame;
class nsIDocShell; class nsIDocShell;
class nsITreeBoxObject;
class nsIWidget; class nsIWidget;
namespace mozilla {
namespace dom {
class XULTreeElement;
}
} // namespace mozilla
/** /**
* Core utils. * Core utils.
*/ */
@ -50,13 +45,13 @@ class nsCoreUtils {
/** /**
* Dispatch click event to XUL tree cell. * Dispatch click event to XUL tree cell.
* *
* @param aTree [in] tree * @param aTreeBoxObj [in] tree box object
* @param aRowIndex [in] row index * @param aRowIndex [in] row index
* @param aColumn [in] column object * @param aColumn [in] column object
* @param aPseudoElm [in] pseudo element inside the cell, see * @param aPseudoElm [in] pseudo elemenet inside the cell, see
* nsITreeBoxObject for available values * nsITreeBoxObject for available values
*/ */
static void DispatchClickEvent(mozilla::dom::XULTreeElement *aTree, static void DispatchClickEvent(nsITreeBoxObject *aTreeBoxObj,
int32_t aRowIndex, nsTreeColumn *aColumn, int32_t aRowIndex, nsTreeColumn *aColumn,
const nsAString &aPseudoElt = EmptyString()); const nsAString &aPseudoElt = EmptyString());
@ -242,32 +237,33 @@ class nsCoreUtils {
nsAString &aLanguage); nsAString &aLanguage);
/** /**
* Return box object for XUL treechildren element of the given tree. * Return box object for XUL treechildren element by tree box object.
*/ */
static already_AddRefed<nsIBoxObject> GetTreeBodyBoxObject( static already_AddRefed<nsIBoxObject> GetTreeBodyBoxObject(
mozilla::dom::XULTreeElement *aTree); nsITreeBoxObject *aTreeBoxObj);
/** /**
* Return tree from any levels DOMNode under the XUL tree. * Return tree box object from any levels DOMNode under the XUL tree.
*/ */
static mozilla::dom::XULTreeElement *GetTree(nsIContent *aContent); static already_AddRefed<nsITreeBoxObject> GetTreeBoxObject(
nsIContent *aContent);
/** /**
* Return first sensible column for the given tree box object. * Return first sensible column for the given tree box object.
*/ */
static already_AddRefed<nsTreeColumn> GetFirstSensibleColumn( static already_AddRefed<nsTreeColumn> GetFirstSensibleColumn(
mozilla::dom::XULTreeElement *aTree); nsITreeBoxObject *aTree);
/** /**
* Return sensible columns count for the given tree box object. * Return sensible columns count for the given tree box object.
*/ */
static uint32_t GetSensibleColumnCount(mozilla::dom::XULTreeElement *aTree); static uint32_t GetSensibleColumnCount(nsITreeBoxObject *aTree);
/** /**
* Return sensible column at the given index for the given tree box object. * Return sensible column at the given index for the given tree box object.
*/ */
static already_AddRefed<nsTreeColumn> GetSensibleColumnAt( static already_AddRefed<nsTreeColumn> GetSensibleColumnAt(
mozilla::dom::XULTreeElement *aTree, uint32_t aIndex); nsITreeBoxObject *aTree, uint32_t aIndex);
/** /**
* Return next sensible column for the given column. * Return next sensible column for the given column.

Просмотреть файл

@ -49,7 +49,7 @@
{ {
var treeNode = getNode("tree"); var treeNode = getNode("tree");
var treeBodyNode = treeNode.treeBody; var treeBodyNode = treeNode.boxObject.treeBody;
var tree = getAccessible(treeNode); var tree = getAccessible(treeNode);
var expandedTreeItem = tree.getChildAt(2); var expandedTreeItem = tree.getChildAt(2);

Просмотреть файл

@ -69,7 +69,7 @@
{ {
var treeNode = getNode("tabletree"); var treeNode = getNode("tabletree");
var treeBodyNode = treeNode.treeBody; var treeBodyNode = treeNode.boxObject.treeBody;
treeNode.focus(); treeNode.focus();
var tree = getAccessible(treeNode); var tree = getAccessible(treeNode);

Просмотреть файл

@ -157,7 +157,7 @@
{ {
this.invoke = function setTreeView_invoke() this.invoke = function setTreeView_invoke()
{ {
gTree.view = gView; gTreeBox.view = gView;
} }
this.getID = function setTreeView_getID() { return "set tree view"; } this.getID = function setTreeView_getID() { return "set tree view"; }
@ -176,7 +176,7 @@
this.invoke = function insertRow_invoke() this.invoke = function insertRow_invoke()
{ {
gView.appendItem("last"); gView.appendItem("last");
gTree.rowCountChanged(0, 1); gTreeBox.rowCountChanged(0, 1);
} }
this.eventSeq = this.eventSeq =
@ -229,7 +229,7 @@
for (var i = 0; i < gView.rowCount; i++) for (var i = 0; i < gView.rowCount; i++)
gView.setCellText(i, firstCol, "hey " + String(i) + "x0"); gView.setCellText(i, firstCol, "hey " + String(i) + "x0");
gTree.invalidateColumn(firstCol); gTreeBox.invalidateColumn(firstCol);
} }
this.eventSeq = this.eventSeq =
@ -266,7 +266,7 @@
column = column.getNext(); column = column.getNext();
} }
gTree.invalidateRow(1); gTreeBox.invalidateRow(1);
} }
this.eventSeq = this.eventSeq =
@ -287,6 +287,7 @@
// Test // Test
var gTree = null; var gTree = null;
var gTreeBox = null;
var gTreeView = null; var gTreeView = null;
var gQueue = null; var gQueue = null;
@ -297,6 +298,7 @@
{ {
// Initialize the tree // Initialize the tree
gTree = document.getElementById("tree"); gTree = document.getElementById("tree");
gTreeBox = gTree.treeBoxObject;
gView = new nsTableTreeView(5); gView = new nsTableTreeView(5);
// Perform actions // Perform actions

Просмотреть файл

@ -38,8 +38,9 @@
hitTest(tree, treecols, treecol1); hitTest(tree, treecols, treecol1);
// tree rows and cells // tree rows and cells
var treeBodyBoxObj = tree.treeBody.boxObject; var treeBoxObject = tree.treeBoxObject;
var rect = tree.getCoordsForCellItem(1, tree.columns[0], "cell"); var treeBodyBoxObj = tree.treeBoxObject.treeBody.boxObject;
var rect = treeBoxObject.getCoordsForCellItem(1, tree.columns[0], "cell");
var treeAcc = getAccessible(tree, [nsIAccessibleTable]); var treeAcc = getAccessible(tree, [nsIAccessibleTable]);
var cellAcc = treeAcc.getCellAt(1, 0); var cellAcc = treeAcc.getCellAt(1, 0);

Просмотреть файл

@ -71,8 +71,9 @@
] ]
}; };
var treeBoxObject = aTree.treeBoxObject;
var view = aTree.view; var view = aTree.view;
var columnCount = aTree.columns.count; var columnCount = treeBoxObject.columns.count;
for (var idx = 0; idx < columnCount; idx++) for (var idx = 0; idx < columnCount; idx++)
accTreeForColumns.children.push({ COLUMNHEADER: [ ] }); accTreeForColumns.children.push({ COLUMNHEADER: [ ] });

Просмотреть файл

@ -48,9 +48,8 @@ class XULTreeGridCellAccessibleWrap : public XULTreeGridCellAccessible,
public: public:
XULTreeGridCellAccessibleWrap(nsIContent* aContent, DocAccessible* aDoc, XULTreeGridCellAccessibleWrap(nsIContent* aContent, DocAccessible* aDoc,
XULTreeGridRowAccessible* aRowAcc, XULTreeGridRowAccessible* aRowAcc,
dom::XULTreeElement* aTree, nsITreeBoxObject* aTree, nsITreeView* aTreeView,
nsITreeView* aTreeView, int32_t aRow, int32_t aRow, nsTreeColumn* aColumn)
nsTreeColumn* aColumn)
: XULTreeGridCellAccessible(aContent, aDoc, aRowAcc, aTree, aTreeView, : XULTreeGridCellAccessible(aContent, aDoc, aRowAcc, aTree, aTreeView,
aRow, aColumn), aRow, aColumn),
ia2AccessibleTableCell(this) {} ia2AccessibleTableCell(this) {}

Просмотреть файл

@ -31,7 +31,6 @@
#include "nsTreeBodyFrame.h" #include "nsTreeBodyFrame.h"
#include "nsTreeColumns.h" #include "nsTreeColumns.h"
#include "nsTreeUtils.h" #include "nsTreeUtils.h"
#include "mozilla/dom/XULTreeElementBinding.h"
using namespace mozilla::a11y; using namespace mozilla::a11y;
@ -49,7 +48,7 @@ XULTreeAccessible::XULTreeAccessible(nsIContent* aContent, DocAccessible* aDoc,
nsCOMPtr<nsITreeView> view = aTreeFrame->GetExistingView(); nsCOMPtr<nsITreeView> view = aTreeFrame->GetExistingView();
mTreeView = view; mTreeView = view;
mTree = nsCoreUtils::GetTree(aContent); mTree = nsCoreUtils::GetTreeBoxObject(aContent);
NS_ASSERTION(mTree, "Can't get mTree!\n"); NS_ASSERTION(mTree, "Can't get mTree!\n");
nsIContent* parentContent = mContent->GetParent(); nsIContent* parentContent = mContent->GetParent();
@ -114,7 +113,8 @@ void XULTreeAccessible::Value(nsString& aValue) const {
if (currentIndex >= 0) { if (currentIndex >= 0) {
RefPtr<nsTreeColumn> keyCol; RefPtr<nsTreeColumn> keyCol;
RefPtr<nsTreeColumns> cols = mTree->GetColumns(); RefPtr<nsTreeColumns> cols;
mTree->GetColumns(getter_AddRefs(cols));
if (cols) keyCol = cols->GetKeyColumn(); if (cols) keyCol = cols->GetKeyColumn();
mTreeView->GetCellText(currentIndex, keyCol, aValue); mTreeView->GetCellText(currentIndex, keyCol, aValue);
@ -171,21 +171,23 @@ Accessible* XULTreeAccessible::ChildAtPoint(int32_t aX, int32_t aY,
int32_t clientX = presContext->DevPixelsToIntCSSPixels(aX) - rootRect.X(); int32_t clientX = presContext->DevPixelsToIntCSSPixels(aX) - rootRect.X();
int32_t clientY = presContext->DevPixelsToIntCSSPixels(aY) - rootRect.Y(); int32_t clientY = presContext->DevPixelsToIntCSSPixels(aY) - rootRect.Y();
ErrorResult rv; int32_t row = -1;
dom::TreeCellInfo cellInfo; RefPtr<nsTreeColumn> column;
mTree->GetCellAt(clientX, clientY, cellInfo, rv); nsAutoString childEltUnused;
mTree->GetCellAt(clientX, clientY, &row, getter_AddRefs(column),
childEltUnused);
// If we failed to find tree cell for the given point then it might be // If we failed to find tree cell for the given point then it might be
// tree columns. // tree columns.
if (cellInfo.mRow == -1 || !cellInfo.mCol) if (row == -1 || !column)
return AccessibleWrap::ChildAtPoint(aX, aY, aWhichChild); return AccessibleWrap::ChildAtPoint(aX, aY, aWhichChild);
Accessible* child = GetTreeItemAccessible(cellInfo.mRow); Accessible* child = GetTreeItemAccessible(row);
if (aWhichChild == eDeepestChild && child) { if (aWhichChild == eDeepestChild && child) {
// Look for accessible cell for the found item accessible. // Look for accessible cell for the found item accessible.
RefPtr<XULTreeItemAccessibleBase> treeitem = do_QueryObject(child); RefPtr<XULTreeItemAccessibleBase> treeitem = do_QueryObject(child);
Accessible* cell = treeitem->GetCellAccessible(cellInfo.mCol); Accessible* cell = treeitem->GetCellAccessible(column);
if (cell) child = cell; if (cell) child = cell;
} }
@ -522,7 +524,8 @@ void XULTreeAccessible::TreeViewInvalidated(int32_t aStartRow, int32_t aEndRow,
endRow = rowCount - 1; endRow = rowCount - 1;
} }
RefPtr<nsTreeColumns> treeColumns = mTree->GetColumns(); RefPtr<nsTreeColumns> treeColumns;
mTree->GetColumns(getter_AddRefs(treeColumns));
if (!treeColumns) return; if (!treeColumns) return;
int32_t endCol = aEndCol; int32_t endCol = aEndCol;
@ -584,7 +587,7 @@ already_AddRefed<Accessible> XULTreeAccessible::CreateTreeItemAccessible(
XULTreeItemAccessibleBase::XULTreeItemAccessibleBase( XULTreeItemAccessibleBase::XULTreeItemAccessibleBase(
nsIContent* aContent, DocAccessible* aDoc, Accessible* aParent, nsIContent* aContent, DocAccessible* aDoc, Accessible* aParent,
dom::XULTreeElement* aTree, nsITreeView* aTreeView, int32_t aRow) nsITreeBoxObject* aTree, nsITreeView* aTreeView, int32_t aRow)
: AccessibleWrap(aContent, aDoc), : AccessibleWrap(aContent, aDoc),
mTree(aTree), mTree(aTree),
mTreeView(aTreeView), mTreeView(aTreeView),
@ -622,19 +625,23 @@ nsIntRect XULTreeItemAccessibleBase::BoundsInCSSPixels() const {
RefPtr<nsTreeColumn> column = nsCoreUtils::GetFirstSensibleColumn(mTree); RefPtr<nsTreeColumn> column = nsCoreUtils::GetFirstSensibleColumn(mTree);
nsresult rv; int32_t x = 0, y = 0, width = 0, height = 0;
nsIntRect rect = nsresult rv = mTree->GetCoordsForCellItem(mRow, column, EmptyString(), &x, &y,
mTree->GetCoordsForCellItem(mRow, column, NS_LITERAL_STRING("cell"), rv); &width, &height);
if (NS_FAILED(rv)) { if (NS_FAILED(rv)) {
return nsIntRect(); return nsIntRect();
} }
boxObj->GetWidth(&rect.width); boxObj->GetWidth(&width);
int32_t tcX = 0, tcY = 0; int32_t tcX = 0, tcY = 0;
boxObj->GetScreenX(&tcX); boxObj->GetScreenX(&tcX);
boxObj->GetScreenY(&tcY); boxObj->GetScreenY(&tcY);
return nsIntRect(tcX, rect.y + tcY, rect.width, rect.height);
x = tcX;
y += tcY;
return nsIntRect(x, y, width, height);
} }
nsRect XULTreeItemAccessibleBase::BoundsInAppUnits() const { nsRect XULTreeItemAccessibleBase::BoundsInAppUnits() const {
@ -799,8 +806,9 @@ uint64_t XULTreeItemAccessibleBase::NativeState() const {
if (FocusMgr()->IsFocused(this)) state |= states::FOCUSED; if (FocusMgr()->IsFocused(this)) state |= states::FOCUSED;
// invisible state // invisible state
int32_t firstVisibleRow = mTree->GetFirstVisibleRow(); int32_t firstVisibleRow, lastVisibleRow;
int32_t lastVisibleRow = mTree->GetLastVisibleRow(); mTree->GetFirstVisibleRow(&firstVisibleRow);
mTree->GetLastVisibleRow(&lastVisibleRow);
if (mRow < firstVisibleRow || mRow > lastVisibleRow) if (mRow < firstVisibleRow || mRow > lastVisibleRow)
state |= states::INVISIBLE; state |= states::INVISIBLE;
@ -829,7 +837,8 @@ void XULTreeItemAccessibleBase::DispatchClickEvent(
nsIContent* aContent, uint32_t aActionIndex) const { nsIContent* aContent, uint32_t aActionIndex) const {
if (IsDefunct()) return; if (IsDefunct()) return;
RefPtr<nsTreeColumns> columns = mTree->GetColumns(); RefPtr<nsTreeColumns> columns;
mTree->GetColumns(getter_AddRefs(columns));
if (!columns) return; if (!columns) return;
// Get column and pseudo element. // Get column and pseudo element.
@ -865,7 +874,8 @@ bool XULTreeItemAccessibleBase::IsExpandable() const {
bool isEmpty = false; bool isEmpty = false;
mTreeView->IsContainerEmpty(mRow, &isEmpty); mTreeView->IsContainerEmpty(mRow, &isEmpty);
if (!isEmpty) { if (!isEmpty) {
RefPtr<nsTreeColumns> columns = mTree->GetColumns(); RefPtr<nsTreeColumns> columns;
mTree->GetColumns(getter_AddRefs(columns));
if (columns) { if (columns) {
nsTreeColumn* primaryColumn = columns->GetPrimaryColumn(); nsTreeColumn* primaryColumn = columns->GetPrimaryColumn();
if (primaryColumn && !nsCoreUtils::IsColumnHidden(primaryColumn)) if (primaryColumn && !nsCoreUtils::IsColumnHidden(primaryColumn))
@ -896,7 +906,7 @@ void XULTreeItemAccessibleBase::GetCellName(nsTreeColumn* aColumn,
XULTreeItemAccessible::XULTreeItemAccessible( XULTreeItemAccessible::XULTreeItemAccessible(
nsIContent* aContent, DocAccessible* aDoc, Accessible* aParent, nsIContent* aContent, DocAccessible* aDoc, Accessible* aParent,
dom::XULTreeElement* aTree, nsITreeView* aTreeView, int32_t aRow) nsITreeBoxObject* aTree, nsITreeView* aTreeView, int32_t aRow)
: XULTreeItemAccessibleBase(aContent, aDoc, aParent, aTree, aTreeView, : XULTreeItemAccessibleBase(aContent, aDoc, aParent, aTree, aTreeView,
aRow) { aRow) {
mStateFlags |= eNoKidsFromDOM; mStateFlags |= eNoKidsFromDOM;
@ -936,7 +946,8 @@ void XULTreeItemAccessible::Shutdown() {
} }
role XULTreeItemAccessible::NativeRole() const { role XULTreeItemAccessible::NativeRole() const {
RefPtr<nsTreeColumns> columns = mTree->GetColumns(); RefPtr<nsTreeColumns> columns;
mTree->GetColumns(getter_AddRefs(columns));
if (!columns) { if (!columns) {
NS_ERROR("No tree columns object in the tree!"); NS_ERROR("No tree columns object in the tree!");
return roles::NOTHING; return roles::NOTHING;
@ -976,9 +987,10 @@ Accessible* XULTreeColumAccessible::GetSiblingAtOffset(int32_t aOffset,
if (aError) *aError = NS_OK; // fail peacefully if (aError) *aError = NS_OK; // fail peacefully
RefPtr<dom::XULTreeElement> tree = nsCoreUtils::GetTree(mContent); nsCOMPtr<nsITreeBoxObject> tree = nsCoreUtils::GetTreeBoxObject(mContent);
if (tree) { if (tree) {
nsCOMPtr<nsITreeView> treeView = tree->GetView(); nsCOMPtr<nsITreeView> treeView;
tree->GetView(getter_AddRefs(treeView));
if (treeView) { if (treeView) {
int32_t rowCount = 0; int32_t rowCount = 0;
treeView->GetRowCount(&rowCount); treeView->GetRowCount(&rowCount);

Просмотреть файл

@ -6,9 +6,9 @@
#ifndef mozilla_a11y_XULTreeAccessible_h__ #ifndef mozilla_a11y_XULTreeAccessible_h__
#define mozilla_a11y_XULTreeAccessible_h__ #define mozilla_a11y_XULTreeAccessible_h__
#include "nsITreeBoxObject.h"
#include "nsITreeView.h" #include "nsITreeView.h"
#include "XULListboxAccessible.h" #include "XULListboxAccessible.h"
#include "mozilla/dom/XULTreeElement.h"
class nsTreeBodyFrame; class nsTreeBodyFrame;
class nsTreeColumn; class nsTreeColumn;
@ -114,7 +114,7 @@ class XULTreeAccessible : public AccessibleWrap {
virtual already_AddRefed<Accessible> CreateTreeItemAccessible( virtual already_AddRefed<Accessible> CreateTreeItemAccessible(
int32_t aRow) const; int32_t aRow) const;
RefPtr<dom::XULTreeElement> mTree; nsCOMPtr<nsITreeBoxObject> mTree;
nsITreeView* mTreeView; nsITreeView* mTreeView;
mutable AccessibleHashtable mAccessibleCache; mutable AccessibleHashtable mAccessibleCache;
}; };
@ -133,7 +133,7 @@ class XULTreeAccessible : public AccessibleWrap {
class XULTreeItemAccessibleBase : public AccessibleWrap { class XULTreeItemAccessibleBase : public AccessibleWrap {
public: public:
XULTreeItemAccessibleBase(nsIContent* aContent, DocAccessible* aDoc, XULTreeItemAccessibleBase(nsIContent* aContent, DocAccessible* aDoc,
Accessible* aParent, dom::XULTreeElement* aTree, Accessible* aParent, nsITreeBoxObject* aTree,
nsITreeView* aTreeView, int32_t aRow); nsITreeView* aTreeView, int32_t aRow);
// nsISupports and cycle collection // nsISupports and cycle collection
@ -207,7 +207,7 @@ class XULTreeItemAccessibleBase : public AccessibleWrap {
*/ */
void GetCellName(nsTreeColumn* aColumn, nsAString& aName) const; void GetCellName(nsTreeColumn* aColumn, nsAString& aName) const;
RefPtr<dom::XULTreeElement> mTree; nsCOMPtr<nsITreeBoxObject> mTree;
nsITreeView* mTreeView; nsITreeView* mTreeView;
int32_t mRow; int32_t mRow;
}; };
@ -221,7 +221,7 @@ NS_DEFINE_STATIC_IID_ACCESSOR(XULTreeItemAccessibleBase,
class XULTreeItemAccessible : public XULTreeItemAccessibleBase { class XULTreeItemAccessible : public XULTreeItemAccessibleBase {
public: public:
XULTreeItemAccessible(nsIContent* aContent, DocAccessible* aDoc, XULTreeItemAccessible(nsIContent* aContent, DocAccessible* aDoc,
Accessible* aParent, dom::XULTreeElement* aTree, Accessible* aParent, nsITreeBoxObject* aTree,
nsITreeView* aTreeView, int32_t aRow); nsITreeView* aTreeView, int32_t aRow);
// nsISupports and cycle collection // nsISupports and cycle collection

Просмотреть файл

@ -23,7 +23,6 @@
#include "nsComponentManagerUtils.h" #include "nsComponentManagerUtils.h"
#include "mozilla/dom/Element.h" #include "mozilla/dom/Element.h"
#include "mozilla/dom/TreeColumnBinding.h" #include "mozilla/dom/TreeColumnBinding.h"
#include "mozilla/dom/XULTreeElementBinding.h"
using namespace mozilla::a11y; using namespace mozilla::a11y;
using namespace mozilla; using namespace mozilla;
@ -170,7 +169,8 @@ void XULTreeGridAccessible::UnselectRow(uint32_t aRowIdx) {
// XULTreeGridAccessible: Accessible implementation // XULTreeGridAccessible: Accessible implementation
role XULTreeGridAccessible::NativeRole() const { role XULTreeGridAccessible::NativeRole() const {
RefPtr<nsTreeColumns> treeColumns = mTree->GetColumns(); RefPtr<nsTreeColumns> treeColumns;
mTree->GetColumns(getter_AddRefs(treeColumns));
if (!treeColumns) { if (!treeColumns) {
NS_ERROR("No treecolumns object for tree!"); NS_ERROR("No treecolumns object for tree!");
return roles::NOTHING; return roles::NOTHING;
@ -199,7 +199,7 @@ already_AddRefed<Accessible> XULTreeGridAccessible::CreateTreeItemAccessible(
XULTreeGridRowAccessible::XULTreeGridRowAccessible( XULTreeGridRowAccessible::XULTreeGridRowAccessible(
nsIContent* aContent, DocAccessible* aDoc, Accessible* aTreeAcc, nsIContent* aContent, DocAccessible* aDoc, Accessible* aTreeAcc,
dom::XULTreeElement* aTree, nsITreeView* aTreeView, int32_t aRow) nsITreeBoxObject* aTree, nsITreeView* aTreeView, int32_t aRow)
: XULTreeItemAccessibleBase(aContent, aDoc, aTreeAcc, aTree, aTreeView, : XULTreeItemAccessibleBase(aContent, aDoc, aTreeAcc, aTree, aTreeView,
aRow), aRow),
mAccessibleCache(kDefaultTreeCacheLength) { mAccessibleCache(kDefaultTreeCacheLength) {
@ -268,14 +268,16 @@ Accessible* XULTreeGridRowAccessible::ChildAtPoint(
int32_t clientX = presContext->DevPixelsToIntCSSPixels(aX) - rootRect.X(); int32_t clientX = presContext->DevPixelsToIntCSSPixels(aX) - rootRect.X();
int32_t clientY = presContext->DevPixelsToIntCSSPixels(aY) - rootRect.Y(); int32_t clientY = presContext->DevPixelsToIntCSSPixels(aY) - rootRect.Y();
ErrorResult rv; int32_t row = -1;
dom::TreeCellInfo cellInfo; RefPtr<nsTreeColumn> column;
mTree->GetCellAt(clientX, clientY, cellInfo, rv); nsAutoString childEltUnused;
mTree->GetCellAt(clientX, clientY, &row, getter_AddRefs(column),
childEltUnused);
// Return if we failed to find tree cell in the row for the given point. // Return if we failed to find tree cell in the row for the given point.
if (cellInfo.mRow != mRow || !cellInfo.mCol) return nullptr; if (row != mRow || !column) return nullptr;
return GetCellAccessible(cellInfo.mCol); return GetCellAccessible(column);
} }
Accessible* XULTreeGridRowAccessible::GetChildAt(uint32_t aIndex) const { Accessible* XULTreeGridRowAccessible::GetChildAt(uint32_t aIndex) const {
@ -312,7 +314,8 @@ XULTreeGridCellAccessible* XULTreeGridRowAccessible::GetCellAccessible(
void XULTreeGridRowAccessible::RowInvalidated(int32_t aStartColIdx, void XULTreeGridRowAccessible::RowInvalidated(int32_t aStartColIdx,
int32_t aEndColIdx) { int32_t aEndColIdx) {
RefPtr<nsTreeColumns> treeColumns = mTree->GetColumns(); RefPtr<nsTreeColumns> treeColumns;
mTree->GetColumns(getter_AddRefs(treeColumns));
if (!treeColumns) return; if (!treeColumns) return;
bool nameChanged = false; bool nameChanged = false;
@ -334,7 +337,7 @@ void XULTreeGridRowAccessible::RowInvalidated(int32_t aStartColIdx,
XULTreeGridCellAccessible::XULTreeGridCellAccessible( XULTreeGridCellAccessible::XULTreeGridCellAccessible(
nsIContent* aContent, DocAccessible* aDoc, nsIContent* aContent, DocAccessible* aDoc,
XULTreeGridRowAccessible* aRowAcc, dom::XULTreeElement* aTree, XULTreeGridRowAccessible* aRowAcc, nsITreeBoxObject* aTree,
nsITreeView* aTreeView, int32_t aRow, nsTreeColumn* aColumn) nsITreeView* aTreeView, int32_t aRow, nsTreeColumn* aColumn)
: LeafAccessible(aContent, aDoc), : LeafAccessible(aContent, aDoc),
mTree(aTree), mTree(aTree),
@ -407,9 +410,9 @@ nsIntRect XULTreeGridCellAccessible::BoundsInCSSPixels() const {
return nsIntRect(); return nsIntRect();
} }
nsresult rv; int32_t x = 0, y = 0, width = 0, height = 0;
nsIntRect rect = nsresult rv = mTree->GetCoordsForCellItem(
mTree->GetCoordsForCellItem(mRow, mColumn, NS_LITERAL_STRING("cell"), rv); mRow, mColumn, NS_LITERAL_STRING("cell"), &x, &y, &width, &height);
if (NS_FAILED(rv)) { if (NS_FAILED(rv)) {
return nsIntRect(); return nsIntRect();
} }
@ -417,7 +420,10 @@ nsIntRect XULTreeGridCellAccessible::BoundsInCSSPixels() const {
int32_t tcX = 0, tcY = 0; int32_t tcX = 0, tcY = 0;
boxObj->GetScreenX(&tcX); boxObj->GetScreenX(&tcX);
boxObj->GetScreenY(&tcY); boxObj->GetScreenY(&tcY);
return nsIntRect(rect.x + tcX, rect.y + tcY, rect.width, rect.height); x += tcX;
y += tcY;
return nsIntRect(x, y, width, height);
} }
nsRect XULTreeGridCellAccessible::BoundsInAppUnits() const { nsRect XULTreeGridCellAccessible::BoundsInAppUnits() const {

Просмотреть файл

@ -70,7 +70,7 @@ class XULTreeGridRowAccessible final : public XULTreeItemAccessibleBase {
using Accessible::GetChildAt; using Accessible::GetChildAt;
XULTreeGridRowAccessible(nsIContent* aContent, DocAccessible* aDoc, XULTreeGridRowAccessible(nsIContent* aContent, DocAccessible* aDoc,
Accessible* aParent, dom::XULTreeElement* aTree, Accessible* aParent, nsITreeBoxObject* aTree,
nsITreeView* aTreeView, int32_t aRow); nsITreeView* aTreeView, int32_t aRow);
// nsISupports and cycle collection // nsISupports and cycle collection
@ -112,7 +112,7 @@ class XULTreeGridCellAccessible : public LeafAccessible,
public: public:
XULTreeGridCellAccessible(nsIContent* aContent, DocAccessible* aDoc, XULTreeGridCellAccessible(nsIContent* aContent, DocAccessible* aDoc,
XULTreeGridRowAccessible* aRowAcc, XULTreeGridRowAccessible* aRowAcc,
dom::XULTreeElement* aTree, nsITreeView* aTreeView, nsITreeBoxObject* aTree, nsITreeView* aTreeView,
int32_t aRow, nsTreeColumn* aColumn); int32_t aRow, nsTreeColumn* aColumn);
// nsISupports // nsISupports
@ -172,7 +172,7 @@ class XULTreeGridCellAccessible : public LeafAccessible,
enum { eAction_Click = 0 }; enum { eAction_Click = 0 };
RefPtr<dom::XULTreeElement> mTree; nsCOMPtr<nsITreeBoxObject> mTree;
nsITreeView* mTreeView; nsITreeView* mTreeView;
int32_t mRow; int32_t mRow;

Просмотреть файл

@ -786,11 +786,12 @@ var BookmarksEventHandler = {
if (aDocument.tooltipNode.localName == "treechildren") { if (aDocument.tooltipNode.localName == "treechildren") {
var tree = aDocument.tooltipNode.parentNode; var tree = aDocument.tooltipNode.parentNode;
var cell = tree.getCellAt(aEvent.clientX, aEvent.clientY); var tbo = tree.treeBoxObject;
var cell = tbo.getCellAt(aEvent.clientX, aEvent.clientY);
if (cell.row == -1) if (cell.row == -1)
return false; return false;
node = tree.view.nodeForTreeIndex(cell.row); node = tree.view.nodeForTreeIndex(cell.row);
cropped = tree.isCellCropped(cell.row, cell.col); cropped = tbo.isCellCropped(cell.row, cell.col);
} else { } else {
// Check whether the tooltipNode is a Places node. // Check whether the tooltipNode is a Places node.
// In such a case use it, otherwise check for targetURI attribute. // In such a case use it, otherwise check for targetURI attribute.

Просмотреть файл

@ -582,11 +582,10 @@ function onBeginLinkDrag(event, urlField, descField) {
return; return;
var tree = event.target; var tree = event.target;
if (tree.localName != "tree") { if (!("treeBoxObject" in tree))
tree = tree.parentNode; tree = tree.parentNode;
}
var row = tree.getRowAt(event.clientX, event.clientY); var row = tree.treeBoxObject.getRowAt(event.clientX, event.clientY);
if (row == -1) if (row == -1)
return; return;
@ -994,7 +993,7 @@ function doCopy() {
var elem = document.commandDispatcher.focusedElement; var elem = document.commandDispatcher.focusedElement;
if (elem && elem.localName == "tree") { if (elem && "treeBoxObject" in elem) {
var view = elem.view; var view = elem.view;
var selection = view.selection; var selection = view.selection;
var text = [], tmp = ""; var text = [], tmp = "";
@ -1028,10 +1027,9 @@ function doSelectAllMedia() {
function doSelectAll() { function doSelectAll() {
var elem = document.commandDispatcher.focusedElement; var elem = document.commandDispatcher.focusedElement;
if (elem && elem.localName == "tree") { if (elem && "treeBoxObject" in elem)
elem.view.selection.selectAll(); elem.view.selection.selectAll();
} }
}
function selectImage() { function selectImage() {
if (!gImageElement) if (!gImageElement)
@ -1047,7 +1045,7 @@ function selectImage() {
gImageElement.height == image.height && gImageElement.height == image.height &&
gImageElement.imageText == image.imageText) { gImageElement.imageText == image.imageText) {
tree.view.selection.select(i); tree.view.selection.select(i);
tree.ensureRowIsVisible(i); tree.treeBoxObject.ensureRowIsVisible(i);
tree.focus(); tree.focus();
return; return;
} }

Просмотреть файл

@ -101,11 +101,11 @@ function checkTreeCoords()
var tree = $("tree"); var tree = $("tree");
var treechildren = $("treechildren"); var treechildren = $("treechildren");
tree.currentIndex = 0; tree.currentIndex = 0;
tree.scrollToRow(0); tree.treeBoxObject.scrollToRow(0);
synthesizeMouse(treechildren, 10, tree.rowHeight + 2, { }); synthesizeMouse(treechildren, 10, tree.treeBoxObject.rowHeight + 2, { });
tree.scrollToRow(2); tree.treeBoxObject.scrollToRow(2);
synthesizeMouse(treechildren, 10, tree.rowHeight + 2, { }); synthesizeMouse(treechildren, 10, tree.treeBoxObject.rowHeight + 2, { });
} }
var tests = [ var tests = [

Просмотреть файл

@ -21,7 +21,7 @@ function testFirstPartyDomain(pageInfo) {
for (let i = 0; i < 3; i++) { for (let i = 0; i < 3; i++) {
info("imagetree select " + i); info("imagetree select " + i);
tree.view.selection.select(i); tree.view.selection.select(i);
tree.ensureRowIsVisible(i); tree.treeBoxObject.ensureRowIsVisible(i);
tree.focus(); tree.focus();
let preview = pageInfo.document.getElementById("thepreviewimage"); let preview = pageInfo.document.getElementById("thepreviewimage");

Просмотреть файл

@ -937,7 +937,8 @@ var PlacesUIUtils = {
return; return;
let tree = event.target.parentNode; let tree = event.target.parentNode;
let cell = tree.getCellAt(event.clientX, event.clientY); let tbo = tree.treeBoxObject;
let cell = tbo.getCellAt(event.clientX, event.clientY);
if (cell.row == -1 || cell.childElt == "twisty") if (cell.row == -1 || cell.childElt == "twisty")
return; return;
@ -947,7 +948,7 @@ var PlacesUIUtils = {
// before the tree item icon (that is, to the left or right of it in // before the tree item icon (that is, to the left or right of it in
// LTR and RTL modes, respectively) from the click target area. // LTR and RTL modes, respectively) from the click target area.
let win = tree.ownerGlobal; let win = tree.ownerGlobal;
let rect = tree.getCoordsForCellItem(cell.row, cell.col, "image"); let rect = tbo.getCoordsForCellItem(cell.row, cell.col, "image");
let isRTL = win.getComputedStyle(tree).direction == "rtl"; let isRTL = win.getComputedStyle(tree).direction == "rtl";
let mouseInGutter = isRTL ? event.clientX > rect.x let mouseInGutter = isRTL ? event.clientX > rect.x
: event.clientX < rect.x; : event.clientX < rect.x;
@ -955,23 +956,23 @@ var PlacesUIUtils = {
let metaKey = AppConstants.platform === "macosx" ? event.metaKey let metaKey = AppConstants.platform === "macosx" ? event.metaKey
: event.ctrlKey; : event.ctrlKey;
let modifKey = metaKey || event.shiftKey; let modifKey = metaKey || event.shiftKey;
let isContainer = tree.view.isContainer(cell.row); let isContainer = tbo.view.isContainer(cell.row);
let openInTabs = isContainer && let openInTabs = isContainer &&
(event.button == 1 || (event.button == 0 && modifKey)) && (event.button == 1 || (event.button == 0 && modifKey)) &&
PlacesUtils.hasChildURIs(tree.view.nodeForTreeIndex(cell.row)); PlacesUtils.hasChildURIs(tree.view.nodeForTreeIndex(cell.row));
if (event.button == 0 && isContainer && !openInTabs) { if (event.button == 0 && isContainer && !openInTabs) {
tree.view.toggleOpenState(cell.row); tbo.view.toggleOpenState(cell.row);
} else if (!mouseInGutter && openInTabs && } else if (!mouseInGutter && openInTabs &&
event.originalTarget.localName == "treechildren") { event.originalTarget.localName == "treechildren") {
tree.view.selection.select(cell.row); tbo.view.selection.select(cell.row);
this.openMultipleLinksInTabs(tree.selectedNode, event, tree); this.openMultipleLinksInTabs(tree.selectedNode, event, tree);
} else if (!mouseInGutter && !isContainer && } else if (!mouseInGutter && !isContainer &&
event.originalTarget.localName == "treechildren") { event.originalTarget.localName == "treechildren") {
// Clear all other selection since we're loading a link now. We must // Clear all other selection since we're loading a link now. We must
// do this *before* attempting to load the link since openURL uses // do this *before* attempting to load the link since openURL uses
// selection as an indication of which link to load. // selection as an indication of which link to load.
tree.view.selection.select(cell.row); tbo.view.selection.select(cell.row);
this.openNodeWithEvent(tree.selectedNode, event); this.openNodeWithEvent(tree.selectedNode, event);
} }
}, },
@ -994,7 +995,7 @@ var PlacesUIUtils = {
return; return;
let tree = treechildren.parentNode; let tree = treechildren.parentNode;
let cell = tree.getCellAt(event.clientX, event.clientY); let cell = tree.treeBoxObject.getCellAt(event.clientX, event.clientY);
// cell.row is -1 when the mouse is hovering an empty area within the tree. // cell.row is -1 when the mouse is hovering an empty area within the tree.
// To avoid showing a URL from a previously hovered node for a currently // To avoid showing a URL from a previously hovered node for a currently

Просмотреть файл

@ -24,7 +24,7 @@
<destructor><![CDATA[ <destructor><![CDATA[
// Break the treeviewer->result->treeviewer cycle. // Break the treeviewer->result->treeviewer cycle.
// Note: unsetting the result's viewer also unsets // Note: unsetting the result's viewer also unsets
// the viewer's reference to our tree. // the viewer's reference to our treeBoxObject.
var result = this.result; var result = this.result;
if (result) { if (result) {
result.root.containerOpen = false; result.root.containerOpen = false;
@ -56,18 +56,13 @@
<property name="view"> <property name="view">
<getter><![CDATA[ <getter><![CDATA[
try { try {
/* eslint-disable no-undef */ return this.treeBoxObject.view.wrappedJSObject || null;
return Object.getOwnPropertyDescriptor(XULTreeElement.prototype, "view").get.
call(this).wrappedJSObject || null;
/* eslint-enable no-undef */
} catch (e) { } catch (e) {
return null; return null;
} }
]]></getter> ]]></getter>
<setter><![CDATA[ <setter><![CDATA[
/* eslint-disable no-undef */ return this.treeBoxObject.view = val;
return Object.getOwnPropertyDescriptor(XULTreeElement.prototype, "view").set.call(this, val);
/* eslint-enable no-undef */
]]></setter> ]]></setter>
</property> </property>
@ -129,7 +124,7 @@
let treeView = new PlacesTreeView(this.flatList, callback, this._controller); let treeView = new PlacesTreeView(this.flatList, callback, this._controller);
// Observer removal is done within the view itself. When the tree // Observer removal is done within the view itself. When the tree
// goes away, view.setTree(null) is called, which then // goes away, treeboxobject calls view.setTree(null), which then
// calls removeObserver. // calls removeObserver.
result.addObserver(treeView); result.addObserver(treeView);
this.view = treeView; this.view = treeView;
@ -269,7 +264,7 @@
view.selection.select(index); view.selection.select(index);
// ... and ensure it's visible, not scrolled off somewhere. // ... and ensure it's visible, not scrolled off somewhere.
this.ensureRowIsVisible(index); this.treeBoxObject.ensureRowIsVisible(index);
]]></body> ]]></body>
</method> </method>
@ -761,7 +756,7 @@
if (event.target.localName != "treechildren") if (event.target.localName != "treechildren")
return; return;
let cell = this.getCellAt(event.clientX, event.clientY); let cell = this.treeBoxObject.getCellAt(event.clientX, event.clientY);
let node = cell.row != -1 ? let node = cell.row != -1 ?
this.view.nodeForTreeIndex(cell.row) : this.view.nodeForTreeIndex(cell.row) :
this.result.root; this.result.root;
@ -770,9 +765,10 @@
// We have to calculate the orientation since view.canDrop will use // We have to calculate the orientation since view.canDrop will use
// it and we want to be consistent with the dropfeedback. // it and we want to be consistent with the dropfeedback.
let rowHeight = this.rowHeight; let tbo = this.treeBoxObject;
let eventY = event.clientY - this.treeBody.boxObject.y - let rowHeight = tbo.rowHeight;
rowHeight * (cell.row - this.getFirstVisibleRow()); let eventY = event.clientY - tbo.treeBody.boxObject.y -
rowHeight * (cell.row - tbo.getFirstVisibleRow());
let orientation = Ci.nsITreeView.DROP_BEFORE; let orientation = Ci.nsITreeView.DROP_BEFORE;

Просмотреть файл

@ -883,7 +883,7 @@ PlacesTreeView.prototype = {
// If we are currently editing, don't invalidate the container until we // If we are currently editing, don't invalidate the container until we
// finish. // finish.
if (this._tree.getAttribute("editing")) { if (this._tree.element.getAttribute("editing")) {
if (!this._editingObservers) { if (!this._editingObservers) {
this._editingObservers = new Map(); this._editingObservers = new Map();
} }
@ -896,7 +896,7 @@ PlacesTreeView.prototype = {
this._editingObservers.delete(aContainer); this._editingObservers.delete(aContainer);
}); });
mutationObserver.observe(this._tree, { mutationObserver.observe(this._tree.element, {
attributes: true, attributes: true,
attributeFilter: ["editing"], attributeFilter: ["editing"],
}); });
@ -1348,7 +1348,7 @@ PlacesTreeView.prototype = {
// since this information is specific to the tree view. // since this information is specific to the tree view.
let ip = this._getInsertionPoint(aRow, aOrientation); let ip = this._getInsertionPoint(aRow, aOrientation);
if (ip) { if (ip) {
PlacesControllerDragHelper.onDrop(ip, aDataTransfer, this._tree) PlacesControllerDragHelper.onDrop(ip, aDataTransfer, this._tree.element)
.catch(Cu.reportError) .catch(Cu.reportError)
.then(() => { .then(() => {
// We should only clear the drop target once // We should only clear the drop target once

Просмотреть файл

@ -50,7 +50,7 @@ var testForgetThisSiteVisibility = async function(selectionCount) {
let popupShown = promisePopupShown(contextmenu); let popupShown = promisePopupShown(contextmenu);
// Get cell coordinates. // Get cell coordinates.
let rect = tree.getCoordsForCellItem(0, tree.columns[0], "text"); let rect = tree.treeBoxObject.getCoordsForCellItem(0, tree.columns[0], "text");
// Initiate a context menu for the selected cell. // Initiate a context menu for the selected cell.
EventUtils.synthesizeMouse(tree.body, rect.x + rect.width / 2, rect.y + rect.height / 2, {type: "contextmenu", button: 2}, organizer); EventUtils.synthesizeMouse(tree.body, rect.x + rect.width / 2, rect.y + rect.height / 2, {type: "contextmenu", button: 2}, organizer);
await popupShown; await popupShown;

Просмотреть файл

@ -83,11 +83,11 @@ add_task(async function test_open_folder_in_tabs() {
function mouseEventOnCell(aTree, aRowIndex, aColumnIndex, aEventDetails) { function mouseEventOnCell(aTree, aRowIndex, aColumnIndex, aEventDetails) {
var selection = aTree.view.selection; var selection = aTree.view.selection;
selection.select(aRowIndex); selection.select(aRowIndex);
aTree.ensureRowIsVisible(aRowIndex); aTree.treeBoxObject.ensureRowIsVisible(aRowIndex);
var column = aTree.columns[aColumnIndex]; var column = aTree.columns[aColumnIndex];
// get cell coordinates // get cell coordinates
var rect = aTree.getCoordsForCellItem(aRowIndex, column, "text"); var rect = aTree.treeBoxObject.getCoordsForCellItem(aRowIndex, column, "text");
EventUtils.synthesizeMouse(aTree.body, rect.x, rect.y, EventUtils.synthesizeMouse(aTree.body, rect.x, rect.y,
aEventDetails, gLibrary); aEventDetails, gLibrary);

Просмотреть файл

@ -200,11 +200,11 @@ add_task(async function test_all() {
function mouseEventOnCell(aTree, aRowIndex, aColumnIndex, aEventDetails) { function mouseEventOnCell(aTree, aRowIndex, aColumnIndex, aEventDetails) {
var selection = aTree.view.selection; var selection = aTree.view.selection;
selection.select(aRowIndex); selection.select(aRowIndex);
aTree.ensureRowIsVisible(aRowIndex); aTree.treeBoxObject.ensureRowIsVisible(aRowIndex);
var column = aTree.columns[aColumnIndex]; var column = aTree.columns[aColumnIndex];
// get cell coordinates // get cell coordinates
var rect = aTree.getCoordsForCellItem(aRowIndex, column, "text"); var rect = aTree.treeBoxObject.getCoordsForCellItem(aRowIndex, column, "text");
EventUtils.synthesizeMouse(aTree.body, rect.x, rect.y, EventUtils.synthesizeMouse(aTree.body, rect.x, rect.y,
aEventDetails, gLibrary); aEventDetails, gLibrary);

Просмотреть файл

@ -129,11 +129,11 @@ add_task(async function test_warnOnOpenLinks() {
function mouseEventOnCell(aTree, aRowIndex, aColumnIndex, aEventDetails) { function mouseEventOnCell(aTree, aRowIndex, aColumnIndex, aEventDetails) {
var selection = aTree.view.selection; var selection = aTree.view.selection;
selection.select(aRowIndex); selection.select(aRowIndex);
aTree.ensureRowIsVisible(aRowIndex); aTree.treeBoxObject.ensureRowIsVisible(aRowIndex);
var column = aTree.columns[aColumnIndex]; var column = aTree.columns[aColumnIndex];
// get cell coordinates // get cell coordinates
var rect = aTree.getCoordsForCellItem(aRowIndex, column, "text"); var rect = aTree.treeBoxObject.getCoordsForCellItem(aRowIndex, column, "text");
EventUtils.synthesizeMouse(aTree.body, rect.x, rect.y, EventUtils.synthesizeMouse(aTree.body, rect.x, rect.y,
aEventDetails, gLibrary); aEventDetails, gLibrary);

Просмотреть файл

@ -96,8 +96,9 @@ add_task(async function test_remove_bookmark_from_library() {
let popupShownPromise = BrowserTestUtils.waitForEvent(contextMenu, "popupshown"); let popupShownPromise = BrowserTestUtils.waitForEvent(contextMenu, "popupshown");
let treeBoxObject = library.ContentTree.view.treeBoxObject;
let firstColumn = library.ContentTree.view.columns[0]; let firstColumn = library.ContentTree.view.columns[0];
let firstBookmarkRect = library.ContentTree.view.getCoordsForCellItem(0, firstColumn, "bm0"); let firstBookmarkRect = treeBoxObject.getCoordsForCellItem(0, firstColumn, "bm0");
EventUtils.synthesizeMouse( EventUtils.synthesizeMouse(
library.ContentTree.view.body, library.ContentTree.view.body,

Просмотреть файл

@ -109,7 +109,8 @@ async function getRectForSidebarItem(guid) {
let tree = sidebar.contentDocument.getElementById("bookmarks-view"); let tree = sidebar.contentDocument.getElementById("bookmarks-view");
tree.selectItems([guid]); tree.selectItems([guid]);
let treerect = tree.getBoundingClientRect(); let treerect = tree.getBoundingClientRect();
let cellrect = tree.getCoordsForCellItem(tree.currentIndex, tree.columns[0], "cell"); let cellrect = tree.treeBoxObject.
getCoordsForCellItem(tree.currentIndex, tree.columns[0], "cell");
// Adjust the position for the tree and sidebar. // Adjust the position for the tree and sidebar.
return { return {

Просмотреть файл

@ -66,15 +66,16 @@ function promiseClipboard(aPopulateClipboardFn, aFlavor) {
} }
function synthesizeClickOnSelectedTreeCell(aTree, aOptions) { function synthesizeClickOnSelectedTreeCell(aTree, aOptions) {
if (aTree.view.selection.count < 1) let tbo = aTree.treeBoxObject;
if (tbo.view.selection.count < 1)
throw new Error("The test node should be successfully selected"); throw new Error("The test node should be successfully selected");
// Get selection rowID. // Get selection rowID.
let min = {}, max = {}; let min = {}, max = {};
aTree.view.selection.getRangeAt(0, min, max); tbo.view.selection.getRangeAt(0, min, max);
let rowID = min.value; let rowID = min.value;
aTree.ensureRowIsVisible(rowID); tbo.ensureRowIsVisible(rowID);
// Calculate the click coordinates. // Calculate the click coordinates.
var rect = aTree.getCoordsForCellItem(rowID, aTree.columns[0], "text"); var rect = tbo.getCoordsForCellItem(rowID, aTree.columns[0], "text");
var x = rect.x + rect.width / 2; var x = rect.x + rect.width / 2;
var y = rect.y + rect.height / 2; var y = rect.y + rect.height / 2;
// Simulate the click. // Simulate the click.

Просмотреть файл

@ -48,7 +48,7 @@
tree.place = `place:type=${Ci.nsINavHistoryQueryOptions.RESULTS_AS_LEFT_PANE_QUERY}&excludeItems=1&expandQueries=0`; tree.place = `place:type=${Ci.nsINavHistoryQueryOptions.RESULTS_AS_LEFT_PANE_QUERY}&excludeItems=1&expandQueries=0`;
// The query-property is set on the title column for each row. // The query-property is set on the title column for each row.
let titleColumn = tree.columns.getColumnAt(0); let titleColumn = tree.treeBoxObject.columns.getColumnAt(0);
// Open All Bookmarks // Open All Bookmarks
tree.selectItems([PlacesUtils.virtualAllBookmarksGuid]); tree.selectItems([PlacesUtils.virtualAllBookmarksGuid]);

Просмотреть файл

@ -400,8 +400,9 @@ var gSearchPane = {
function onDragEngineStart(event) { function onDragEngineStart(event) {
var selectedIndex = gEngineView.selectedIndex; var selectedIndex = gEngineView.selectedIndex;
var tree = document.getElementById("engineList"); var tree = document.getElementById("engineList");
let cell = tree.getCellAt(event.clientX, event.clientY); var row = { }, col = { }, child = { };
if (selectedIndex >= 0 && !gEngineView.isCheckBox(cell.row, cell.col)) { tree.treeBoxObject.getCellAt(event.clientX, event.clientY, row, col, child);
if (selectedIndex >= 0 && !gEngineView.isCheckBox(row.value, col.value)) {
event.dataTransfer.setData(ENGINE_FLAVOR, selectedIndex.toString()); event.dataTransfer.setData(ENGINE_FLAVOR, selectedIndex.toString());
event.dataTransfer.effectAllowed = "move"; event.dataTransfer.effectAllowed = "move";
} }

Просмотреть файл

@ -26,7 +26,7 @@ add_task(async function checkCertExportWorks() {
let doc = dialogWin.document; let doc = dialogWin.document;
doc.getElementById("certmanagertabs").selectedTab = doc.getElementById("ca_tab"); doc.getElementById("certmanagertabs").selectedTab = doc.getElementById("ca_tab");
let expectedCert; let expectedCert;
let treeView = doc.getElementById("ca-tree").view; let treeView = doc.getElementById("ca-tree").treeBoxObject.view;
// Select any which cert. Ignore parent rows (ie rows without certs): // Select any which cert. Ignore parent rows (ie rows without certs):
for (let i = 0; i < treeView.rowCount; i++) { for (let i = 0; i < treeView.rowCount; i++) {
treeView.selection.select(i); treeView.selection.select(i);

Просмотреть файл

@ -18,8 +18,8 @@ function Tree(aId, aData) {
} }
Tree.prototype = { Tree.prototype = {
get tree() { get boxObject() {
return this._tree; return this._tree.treeBoxObject;
}, },
get isEmpty() { get isEmpty() {
return !this._data.length; return !this._data.length;
@ -131,7 +131,7 @@ var gTranslationExceptions = {
if (!this._sites.length) if (!this._sites.length)
return; return;
let removed = this._sites.splice(0, this._sites.length); let removed = this._sites.splice(0, this._sites.length);
this._siteTree.tree.rowCountChanged(0, -removed.length); this._siteTree.boxObject.rowCountChanged(0, -removed.length);
} else { } else {
let perm = aSubject.QueryInterface(Ci.nsIPermission); let perm = aSubject.QueryInterface(Ci.nsIPermission);
if (perm.type != kPermissionType) if (perm.type != kPermissionType)
@ -142,15 +142,15 @@ var gTranslationExceptions = {
return; return;
this._sites.push(perm.principal.origin); this._sites.push(perm.principal.origin);
this._sites.sort(); this._sites.sort();
let tree = this._siteTree.tree; let boxObject = this._siteTree.boxObject;
tree.rowCountChanged(0, 1); boxObject.rowCountChanged(0, 1);
tree.invalidate(); boxObject.invalidate();
} else if (aData == "deleted") { } else if (aData == "deleted") {
let index = this._sites.indexOf(perm.principal.origin); let index = this._sites.indexOf(perm.principal.origin);
if (index == -1) if (index == -1)
return; return;
this._sites.splice(index, 1); this._sites.splice(index, 1);
this._siteTree.tree.rowCountChanged(index, -1); this._siteTree.boxObject.rowCountChanged(index, -1);
this.onSiteSelected(); this.onSiteSelected();
return; return;
} }
@ -160,10 +160,10 @@ var gTranslationExceptions = {
this._langs = this.getLanguageExceptions(); this._langs = this.getLanguageExceptions();
let change = this._langs.length - this._langTree.rowCount; let change = this._langs.length - this._langTree.rowCount;
this._langTree._data = this._langs; this._langTree._data = this._langs;
let tree = this._langTree.tree; let boxObject = this._langTree.boxObject;
if (change) if (change)
tree.rowCountChanged(0, change); boxObject.rowCountChanged(0, change);
tree.invalidate(); boxObject.invalidate();
this.onLanguageSelected(); this.onLanguageSelected();
} }
}, },
@ -211,7 +211,7 @@ var gTranslationExceptions = {
return; return;
let removedSites = this._sites.splice(0, this._sites.length); let removedSites = this._sites.splice(0, this._sites.length);
this._siteTree.tree.rowCountChanged(0, -removedSites.length); this._siteTree.boxObject.rowCountChanged(0, -removedSites.length);
for (let origin of removedSites) { for (let origin of removedSites) {
let principal = Services.scriptSecurityManager.createCodebasePrincipalFromOrigin(origin); let principal = Services.scriptSecurityManager.createCodebasePrincipalFromOrigin(origin);

Просмотреть файл

@ -41,11 +41,11 @@ async function middleClickTest(win) {
is(tree.view.rowCount, 3, "There should be three items"); is(tree.view.rowCount, 3, "There should be three items");
// click on the first tab item // click on the first tab item
var rect = tree.getCoordsForCellItem(1, tree.columns[1], "text"); var rect = tree.treeBoxObject.getCoordsForCellItem(1, tree.columns[1], "text");
EventUtils.synthesizeMouse(tree.body, rect.x, rect.y, { button: 1 }, EventUtils.synthesizeMouse(tree.body, rect.x, rect.y, { button: 1 },
browser.contentWindow); browser.contentWindow);
// click on the second tab item // click on the second tab item
rect = tree.getCoordsForCellItem(2, tree.columns[1], "text"); rect = tree.treeBoxObject.getCoordsForCellItem(2, tree.columns[1], "text");
EventUtils.synthesizeMouse(tree.body, rect.x, rect.y, { button: 1 }, EventUtils.synthesizeMouse(tree.body, rect.x, rect.y, { button: 1 },
browser.contentWindow); browser.contentWindow);

Просмотреть файл

@ -267,13 +267,13 @@
#ifdef MOZ_XUL #ifdef MOZ_XUL
#include "mozilla/dom/XULBroadcastManager.h" #include "mozilla/dom/XULBroadcastManager.h"
#include "mozilla/dom/XULPersist.h" #include "mozilla/dom/XULPersist.h"
#include "mozilla/dom/TreeBoxObject.h"
#include "nsIXULWindow.h" #include "nsIXULWindow.h"
#include "nsXULCommandDispatcher.h" #include "nsXULCommandDispatcher.h"
#include "nsXULPopupManager.h" #include "nsXULPopupManager.h"
#include "nsIDocShellTreeOwner.h" #include "nsIDocShellTreeOwner.h"
#endif #endif
#include "nsIPresShellInlines.h" #include "nsIPresShellInlines.h"
#include "mozilla/dom/BoxObject.h"
#include "mozilla/DocLoadingTimelineMarker.h" #include "mozilla/DocLoadingTimelineMarker.h"
@ -5892,7 +5892,21 @@ already_AddRefed<BoxObject> Document::GetBoxObjectFor(Element* aElement,
return boxObject.forget(); return boxObject.forget();
} }
int32_t namespaceID;
RefPtr<nsAtom> tag = BindingManager()->ResolveTag(aElement, &namespaceID);
#ifdef MOZ_XUL
if (namespaceID == kNameSpaceID_XUL) {
if (tag == nsGkAtoms::tree) {
boxObject = new TreeBoxObject();
} else {
boxObject = new BoxObject(); boxObject = new BoxObject();
}
} else
#endif // MOZ_XUL
{
boxObject = new BoxObject();
}
boxObject->Init(aElement); boxObject->Init(aElement);
entry.OrInsert([&boxObject]() { return boxObject; }); entry.OrInsert([&boxObject]() { return boxObject; });

Просмотреть файл

@ -60,7 +60,6 @@
#include "mozilla/dom/XULMenuElementBinding.h" #include "mozilla/dom/XULMenuElementBinding.h"
#include "mozilla/dom/XULPopupElementBinding.h" #include "mozilla/dom/XULPopupElementBinding.h"
#include "mozilla/dom/XULTextElementBinding.h" #include "mozilla/dom/XULTextElementBinding.h"
#include "mozilla/dom/XULTreeElementBinding.h"
#include "mozilla/dom/Promise.h" #include "mozilla/dom/Promise.h"
#include "mozilla/dom/WebIDLGlobalNameHash.h" #include "mozilla/dom/WebIDLGlobalNameHash.h"
#include "mozilla/dom/WorkerPrivate.h" #include "mozilla/dom/WorkerPrivate.h"
@ -3621,8 +3620,6 @@ bool HTMLConstructor(JSContext* aCx, unsigned aArgc, JS::Value* aVp,
cb = XULMenuElement_Binding::GetConstructorObject; cb = XULMenuElement_Binding::GetConstructorObject;
} else if (definition->mLocalName == nsGkAtoms::scrollbox) { } else if (definition->mLocalName == nsGkAtoms::scrollbox) {
cb = XULScrollElement_Binding::GetConstructorObject; cb = XULScrollElement_Binding::GetConstructorObject;
} else if (definition->mLocalName == nsGkAtoms::tree) {
cb = XULTreeElement_Binding::GetConstructorObject;
} else { } else {
cb = XULElement_Binding::GetConstructorObject; cb = XULElement_Binding::GetConstructorObject;
} }

Просмотреть файл

@ -58,8 +58,7 @@ WEBIDL_FILES = [
'XULFrameElement.webidl', 'XULFrameElement.webidl',
'XULMenuElement.webidl', 'XULMenuElement.webidl',
'XULScrollElement.webidl', 'XULScrollElement.webidl',
'XULTextElement.webidl', 'XULTextElement.webidl'
'XULTreeElement.webidl'
] ]
if CONFIG['MOZ_PLACES']: if CONFIG['MOZ_PLACES']:

Просмотреть файл

@ -1283,8 +1283,6 @@ var interfaceNamesInGlobalScope =
{name: "XULScrollElement", insecureContext: true, xbl: true}, {name: "XULScrollElement", insecureContext: true, xbl: true},
// IMPORTANT: Do not change this list without review from a DOM peer! // IMPORTANT: Do not change this list without review from a DOM peer!
{name: "XULTextElement", insecureContext: true, xbl: true}, {name: "XULTextElement", insecureContext: true, xbl: true},
// IMPORTANT: Do not change this list without review from a DOM peer!
{name: "XULTreeElement", insecureContext: true, xbl: true},
// IMPORTANT: Do not change this list without review from a DOM peer! // IMPORTANT: Do not change this list without review from a DOM peer!
]; ];
// IMPORTANT: Do not change the list above without review from a DOM peer! // IMPORTANT: Do not change the list above without review from a DOM peer!

Просмотреть файл

@ -13,9 +13,9 @@ dictionary TreeCellInfo {
DOMString childElt = ""; DOMString childElt = "";
}; };
[HTMLConstructor, Func="IsChromeOrXBL"] [NoInterfaceObject]
interface XULTreeElement : XULElement interface TreeBoxObject : BoxObject {
{
/** /**
* Obtain the columns. * Obtain the columns.
*/ */
@ -131,12 +131,25 @@ interface XULTreeElement : XULElement
[Throws] [Throws]
TreeCellInfo getCellAt(long x, long y); TreeCellInfo getCellAt(long x, long y);
/**
* DEPRECATED: please use above version
*/
[Throws]
void getCellAt(long x, long y, object row, object column, object childElt);
/** /**
* Find the coordinates of an element within a specific cell. * Find the coordinates of an element within a specific cell.
*/ */
[Throws] [Throws]
DOMRect? getCoordsForCellItem(long row, TreeColumn col, DOMString element); DOMRect? getCoordsForCellItem(long row, TreeColumn col, DOMString element);
/**
* DEPRECATED: Please use above version
*/
[Throws]
void getCoordsForCellItem(long row, TreeColumn col, DOMString element,
object x, object y, object width, object height);
/** /**
* Determine if the text of a cell is being cropped or not. * Determine if the text of a cell is being cropped or not.
*/ */

Просмотреть файл

@ -7,7 +7,7 @@ interface TreeColumns {
/** /**
* The tree widget for these columns. * The tree widget for these columns.
*/ */
readonly attribute XULTreeElement? tree; readonly attribute TreeBoxObject? tree;
/** /**
* The number of columns. * The number of columns.

Просмотреть файл

@ -140,7 +140,7 @@ interface TreeView
* Called during initialization to link the view to the front end box object. * Called during initialization to link the view to the front end box object.
*/ */
[Throws] [Throws]
void setTree(XULTreeElement? tree); void setTree(TreeBoxObject? tree);
/** /**
* Called on the view when an item is opened or closed. * Called on the view when an item is opened or closed.

Просмотреть файл

@ -897,6 +897,7 @@ WEBIDL_FILES = [
'TouchEvent.webidl', 'TouchEvent.webidl',
'TouchList.webidl', 'TouchList.webidl',
'TransitionEvent.webidl', 'TransitionEvent.webidl',
'TreeBoxObject.webidl',
'TreeColumn.webidl', 'TreeColumn.webidl',
'TreeColumns.webidl', 'TreeColumns.webidl',
'TreeContentView.webidl', 'TreeContentView.webidl',

Просмотреть файл

@ -1,417 +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 "nsCOMPtr.h"
#include "nsTreeContentView.h"
#include "nsITreeSelection.h"
#include "ChildIterator.h"
#include "nsError.h"
#include "nsTreeBodyFrame.h"
#include "mozilla/dom/DOMRect.h"
#include "mozilla/dom/BindingUtils.h"
#include "mozilla/dom/Element.h"
#include "mozilla/dom/ToJSValue.h"
#include "mozilla/dom/XULTreeElement.h"
#include "mozilla/dom/XULTreeElementBinding.h"
namespace mozilla {
namespace dom {
NS_IMPL_ISUPPORTS_CYCLE_COLLECTION_INHERITED_0(XULTreeElement, nsXULElement)
NS_IMPL_CYCLE_COLLECTION_INHERITED(XULTreeElement, nsXULElement, mView)
JSObject* XULTreeElement::WrapNode(JSContext* aCx,
JS::Handle<JSObject*> aGivenProto) {
return XULTreeElement_Binding::Wrap(aCx, this, aGivenProto);
}
void XULTreeElement::UnbindFromTree(bool aDeep, bool aNullParent) {
// Drop the view's ref to us.
if (mView) {
nsCOMPtr<nsITreeSelection> sel;
mView->GetSelection(getter_AddRefs(sel));
if (sel) {
sel->SetTree(nullptr);
}
mView->SetTree(nullptr); // Break the circular ref between the view and us.
}
mView = nullptr;
nsXULElement::UnbindFromTree(aDeep, aNullParent);
}
void XULTreeElement::DestroyContent() {
// Drop the view's ref to us.
if (mView) {
nsCOMPtr<nsITreeSelection> sel;
mView->GetSelection(getter_AddRefs(sel));
if (sel) {
sel->SetTree(nullptr);
}
mView->SetTree(nullptr); // Break the circular ref between the view and us.
}
mView = nullptr;
nsXULElement::DestroyContent();
}
static nsIContent* FindBodyElement(nsIContent* aParent) {
mozilla::dom::FlattenedChildIterator iter(aParent);
for (nsIContent* content = iter.GetNextChild(); content;
content = iter.GetNextChild()) {
mozilla::dom::NodeInfo* ni = content->NodeInfo();
if (ni->Equals(nsGkAtoms::treechildren, kNameSpaceID_XUL)) {
return content;
} else if (ni->Equals(nsGkAtoms::tree, kNameSpaceID_XUL)) {
// There are nesting tree elements. Only the innermost should
// find the treechilren.
return nullptr;
} else if (content->IsElement() &&
!ni->Equals(nsGkAtoms::_template, kNameSpaceID_XUL)) {
nsIContent* result = FindBodyElement(content);
if (result) return result;
}
}
return nullptr;
}
nsTreeBodyFrame* XULTreeElement::GetTreeBodyFrame(bool aFlushLayout) {
nsCOMPtr<nsIContent> kungFuDeathGrip = this; // keep a reference
RefPtr<Document> doc = GetUncomposedDoc();
// Make sure our frames are up to date, and layout as needed. We
// have to do this before checking for our cached mTreeBody, since
// it might go away on style flush, and in any case if aFlushLayout
// is true we need to make sure to flush no matter what.
// XXXbz except that flushing style when we were not asked to flush
// layout here breaks things. See bug 585123.
if (aFlushLayout && doc) {
doc->FlushPendingNotifications(FlushType::Layout);
}
if (mTreeBody) {
// Have one cached already.
return mTreeBody;
}
if (!aFlushLayout && doc) {
doc->FlushPendingNotifications(FlushType::Frames);
}
nsCOMPtr<nsIContent> tree = FindBodyElement(this);
if (tree) {
mTreeBody = do_QueryFrame(tree->GetPrimaryFrame());
}
return mTreeBody;
}
already_AddRefed<nsITreeView> XULTreeElement::GetView() {
if (!mTreeBody) {
if (!GetTreeBodyFrame()) {
return nullptr;
}
if (mView) {
nsCOMPtr<nsITreeView> view;
// Our new frame needs to initialise itself
mTreeBody->GetView(getter_AddRefs(view));
return view.forget();
}
}
if (!mView) {
// No tree builder, create a tree content view.
if (NS_FAILED(NS_NewTreeContentView(getter_AddRefs(mView)))) {
return nullptr;
}
// Initialise the frame and view
mTreeBody->SetView(mView);
}
return do_AddRef(mView);
}
void XULTreeElement::SetView(nsITreeView* aView, CallerType aCallerType,
ErrorResult& aRv) {
if (aCallerType != CallerType::System) {
// Don't trust views coming from random places.
aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
return;
}
mView = aView;
nsTreeBodyFrame* body = GetTreeBodyFrame();
if (body) {
body->SetView(aView);
}
}
bool XULTreeElement::Focused() {
nsTreeBodyFrame* body = GetTreeBodyFrame();
if (body) {
return body->GetFocused();
}
return false;
}
void XULTreeElement::SetFocused(bool aFocused) {
nsTreeBodyFrame* body = GetTreeBodyFrame();
if (body) {
body->SetFocused(aFocused);
}
}
already_AddRefed<Element> XULTreeElement::GetTreeBody() {
nsTreeBodyFrame* body = GetTreeBodyFrame();
if (body) {
nsCOMPtr<Element> element;
body->GetTreeBody(getter_AddRefs(element));
return element.forget();
}
return nullptr;
}
already_AddRefed<nsTreeColumns> XULTreeElement::GetColumns() {
nsTreeBodyFrame* body = GetTreeBodyFrame();
if (body) {
return body->Columns();
}
return nullptr;
}
int32_t XULTreeElement::RowHeight() {
nsTreeBodyFrame* body = GetTreeBodyFrame();
if (body) {
return body->RowHeight();
}
return 0;
}
int32_t XULTreeElement::RowWidth() {
nsTreeBodyFrame* body = GetTreeBodyFrame();
if (body) {
return body->RowWidth();
}
return 0;
}
int32_t XULTreeElement::GetFirstVisibleRow() {
nsTreeBodyFrame* body = GetTreeBodyFrame();
if (body) {
return body->FirstVisibleRow();
}
return 0;
}
int32_t XULTreeElement::GetLastVisibleRow() {
nsTreeBodyFrame* body = GetTreeBodyFrame();
if (body) {
return body->LastVisibleRow();
}
return 0;
}
int32_t XULTreeElement::HorizontalPosition() {
nsTreeBodyFrame* body = GetTreeBodyFrame();
if (body) {
return body->GetHorizontalPosition();
}
return 0;
}
int32_t XULTreeElement::GetPageLength() {
nsTreeBodyFrame* body = GetTreeBodyFrame();
if (body) {
return body->PageLength();
}
return 0;
}
void XULTreeElement::EnsureRowIsVisible(int32_t aRow) {
nsTreeBodyFrame* body = GetTreeBodyFrame();
if (body) {
body->EnsureRowIsVisible(aRow);
}
}
void XULTreeElement::EnsureCellIsVisible(int32_t aRow, nsTreeColumn* aCol,
ErrorResult& aRv) {
nsTreeBodyFrame* body = GetTreeBodyFrame();
if (body) {
nsresult rv = body->EnsureCellIsVisible(aRow, aCol);
if (NS_FAILED(rv)) {
aRv.Throw(rv);
}
}
}
void XULTreeElement::ScrollToRow(int32_t aRow) {
nsTreeBodyFrame* body = GetTreeBodyFrame(true);
if (!body) {
return;
}
body->ScrollToRow(aRow);
}
void XULTreeElement::ScrollByLines(int32_t aNumLines) {
nsTreeBodyFrame* body = GetTreeBodyFrame();
if (!body) {
return;
}
body->ScrollByLines(aNumLines);
}
void XULTreeElement::ScrollByPages(int32_t aNumPages) {
nsTreeBodyFrame* body = GetTreeBodyFrame();
if (body) {
body->ScrollByPages(aNumPages);
}
}
void XULTreeElement::Invalidate() {
nsTreeBodyFrame* body = GetTreeBodyFrame();
if (body) {
body->Invalidate();
}
}
void XULTreeElement::InvalidateColumn(nsTreeColumn* aCol) {
nsTreeBodyFrame* body = GetTreeBodyFrame();
if (body) {
body->InvalidateColumn(aCol);
}
}
void XULTreeElement::InvalidateRow(int32_t aIndex) {
nsTreeBodyFrame* body = GetTreeBodyFrame();
if (body) {
body->InvalidateRow(aIndex);
}
}
void XULTreeElement::InvalidateCell(int32_t aRow, nsTreeColumn* aCol) {
nsTreeBodyFrame* body = GetTreeBodyFrame();
if (body) {
body->InvalidateCell(aRow, aCol);
}
}
void XULTreeElement::InvalidateRange(int32_t aStart, int32_t aEnd) {
nsTreeBodyFrame* body = GetTreeBodyFrame();
if (body) {
body->InvalidateRange(aStart, aEnd);
}
}
int32_t XULTreeElement::GetRowAt(int32_t x, int32_t y) {
nsTreeBodyFrame* body = GetTreeBodyFrame();
if (!body) {
return 0;
}
return body->GetRowAt(x, y);
}
void XULTreeElement::GetCellAt(int32_t aX, int32_t aY, TreeCellInfo& aRetVal,
ErrorResult& aRv) {
aRetVal.mRow = 0;
aRetVal.mCol = nullptr;
nsTreeBodyFrame* body = GetTreeBodyFrame();
if (body) {
nsAutoCString element;
body->GetCellAt(aX, aY, &aRetVal.mRow, getter_AddRefs(aRetVal.mCol),
element);
CopyUTF8toUTF16(element, aRetVal.mChildElt);
}
}
nsIntRect XULTreeElement::GetCoordsForCellItem(int32_t aRow, nsTreeColumn* aCol,
const nsAString& aElement,
nsresult& rv) {
rv = NS_OK;
nsIntRect rect;
nsTreeBodyFrame* body = GetTreeBodyFrame();
NS_ConvertUTF16toUTF8 element(aElement);
if (body) {
rv = body->GetCoordsForCellItem(aRow, aCol, element, &rect.x, &rect.y,
&rect.width, &rect.height);
}
return rect;
}
already_AddRefed<DOMRect> XULTreeElement::GetCoordsForCellItem(
int32_t aRow, nsTreeColumn& aCol, const nsAString& aElement,
ErrorResult& aRv) {
nsresult rv;
nsIntRect rect = GetCoordsForCellItem(aRow, &aCol, aElement, rv);
aRv = rv;
RefPtr<DOMRect> domRect =
new DOMRect(this, rect.x, rect.y, rect.width, rect.height);
return domRect.forget();
}
bool XULTreeElement::IsCellCropped(int32_t aRow, nsTreeColumn* aCol,
ErrorResult& aRv) {
bool cropped = false;
nsTreeBodyFrame* body = GetTreeBodyFrame();
if (body) {
aRv = body->IsCellCropped(aRow, aCol, &cropped);
}
return cropped;
}
void XULTreeElement::RowCountChanged(int32_t aIndex, int32_t aDelta) {
nsTreeBodyFrame* body = GetTreeBodyFrame();
if (body) {
body->RowCountChanged(aIndex, aDelta);
}
}
void XULTreeElement::BeginUpdateBatch() {
nsTreeBodyFrame* body = GetTreeBodyFrame();
if (body) {
body->BeginUpdateBatch();
}
}
void XULTreeElement::EndUpdateBatch() {
nsTreeBodyFrame* body = GetTreeBodyFrame();
if (body) {
body->EndUpdateBatch();
}
}
void XULTreeElement::ClearStyleAndImageCaches() {
nsTreeBodyFrame* body = GetTreeBodyFrame();
if (body) {
body->ClearStyleAndImageCaches();
}
}
void XULTreeElement::RemoveImageCacheEntry(int32_t aRowIndex,
nsTreeColumn& aCol,
ErrorResult& aRv) {
if (NS_WARN_IF(aRowIndex < 0)) {
aRv.Throw(NS_ERROR_INVALID_ARG);
return;
}
nsTreeBodyFrame* body = GetTreeBodyFrame();
if (body) {
body->RemoveImageCacheEntry(aRowIndex, &aCol);
}
}
} // namespace dom
} // namespace mozilla

Просмотреть файл

@ -30,7 +30,6 @@ if CONFIG['MOZ_XUL']:
'XULScrollElement.h', 'XULScrollElement.h',
'XULTextElement.h', 'XULTextElement.h',
'XULTooltipElement.h', 'XULTooltipElement.h',
'XULTreeElement.h',
] ]
UNIFIED_SOURCES += [ UNIFIED_SOURCES += [
@ -51,7 +50,6 @@ if CONFIG['MOZ_XUL']:
'XULScrollElement.cpp', 'XULScrollElement.cpp',
'XULTextElement.cpp', 'XULTextElement.cpp',
'XULTooltipElement.cpp', 'XULTooltipElement.cpp',
'XULTreeElement.cpp',
] ]
XPIDL_SOURCES += [ XPIDL_SOURCES += [
@ -75,7 +73,6 @@ LOCAL_INCLUDES += [
'/layout/generic', '/layout/generic',
'/layout/style', '/layout/style',
'/layout/xul', '/layout/xul',
'/layout/xul/tree',
] ]
FINAL_LIBRARY = 'xul' FINAL_LIBRARY = 'xul'

Просмотреть файл

@ -78,7 +78,6 @@
#include "XULMenuElement.h" #include "XULMenuElement.h"
#include "XULPopupElement.h" #include "XULPopupElement.h"
#include "XULScrollElement.h" #include "XULScrollElement.h"
#include "XULTreeElement.h"
#include "mozilla/dom/XULElementBinding.h" #include "mozilla/dom/XULElementBinding.h"
#include "mozilla/dom/BoxObject.h" #include "mozilla/dom/BoxObject.h"
@ -171,10 +170,6 @@ nsXULElement* nsXULElement::Construct(
return new XULScrollElement(nodeInfo.forget()); return new XULScrollElement(nodeInfo.forget());
} }
if (nodeInfo->Equals(nsGkAtoms::tree)) {
return new XULTreeElement(nodeInfo.forget());
}
return NS_NewBasicXULElement(nodeInfo.forget()); return NS_NewBasicXULElement(nodeInfo.forget());
} }

Просмотреть файл

@ -10,7 +10,6 @@
#include "nsXULPrototypeDocument.h" #include "nsXULPrototypeDocument.h"
#include "nsIServiceManager.h" #include "nsIServiceManager.h"
#include "nsIURI.h" #include "nsIURI.h"
#include "nsNetUtil.h"
#include "nsIFile.h" #include "nsIFile.h"
#include "nsIMemoryReporter.h" #include "nsIMemoryReporter.h"

Просмотреть файл

@ -136,13 +136,15 @@
#ifdef MOZ_XUL #ifdef MOZ_XUL
#include "nsMenuFrame.h" #include "nsMenuFrame.h"
#include "nsTreeBodyFrame.h" #include "nsTreeBodyFrame.h"
#include "XULTreeElement.h" #include "nsIBoxObject.h"
#include "nsITreeBoxObject.h"
#include "nsMenuPopupFrame.h" #include "nsMenuPopupFrame.h"
#include "nsTreeColumns.h" #include "nsTreeColumns.h"
#include "nsIDOMXULMultSelectCntrlEl.h" #include "nsIDOMXULMultSelectCntrlEl.h"
#include "nsIDOMXULSelectCntrlItemEl.h" #include "nsIDOMXULSelectCntrlItemEl.h"
#include "nsIDOMXULMenuListElement.h" #include "nsIDOMXULMenuListElement.h"
#include "nsXULElement.h" #include "nsXULElement.h"
#include "mozilla/dom/BoxObject.h"
#endif // MOZ_XUL #endif // MOZ_XUL
#include "mozilla/layers/CompositorBridgeChild.h" #include "mozilla/layers/CompositorBridgeChild.h"
@ -7975,23 +7977,28 @@ void PresShell::GetCurrentItemAndPositionForElement(
int32_t currentIndex; int32_t currentIndex;
multiSelect->GetCurrentIndex(&currentIndex); multiSelect->GetCurrentIndex(&currentIndex);
if (currentIndex >= 0) { if (currentIndex >= 0) {
RefPtr<XULTreeElement> tree = XULTreeElement::FromNode(focusedContent); RefPtr<nsXULElement> xulElement = nsXULElement::FromNode(focusedContent);
if (xulElement) {
nsCOMPtr<nsIBoxObject> box = xulElement->GetBoxObject(IgnoreErrors());
nsCOMPtr<nsITreeBoxObject> treeBox(do_QueryInterface(box));
// Tree view special case (tree items have no frames) // Tree view special case (tree items have no frames)
// Get the focused row and add its coordinates, which are already in // Get the focused row and add its coordinates, which are already in
// pixels // pixels
// XXX Boris, should we create a new interface so that this doesn't // XXX Boris, should we create a new interface so that this doesn't
// need to know about trees? Something like nsINodelessChildCreator // need to know about trees? Something like nsINodelessChildCreator
// which could provide the current focus coordinates? // which could provide the current focus coordinates?
if (tree) { if (treeBox) {
tree->EnsureRowIsVisible(currentIndex); treeBox->EnsureRowIsVisible(currentIndex);
int32_t firstVisibleRow = tree->GetFirstVisibleRow(); int32_t firstVisibleRow, rowHeight;
int32_t rowHeight = tree->RowHeight(); treeBox->GetFirstVisibleRow(&firstVisibleRow);
treeBox->GetRowHeight(&rowHeight);
extraTreeY += nsPresContext::CSSPixelsToAppUnits( extraTreeY += nsPresContext::CSSPixelsToAppUnits(
(currentIndex - firstVisibleRow + 1) * rowHeight); (currentIndex - firstVisibleRow + 1) * rowHeight);
istree = true; istree = true;
RefPtr<nsTreeColumns> cols = tree->GetColumns(); RefPtr<nsTreeColumns> cols;
treeBox->GetColumns(getter_AddRefs(cols));
if (cols) { if (cols) {
nsTreeColumn* col = cols->GetFirstColumn(); nsTreeColumn* col = cols->GetFirstColumn();
if (col) { if (col) {
@ -8006,6 +8013,7 @@ void PresShell::GetCurrentItemAndPositionForElement(
multiSelect->GetCurrentItem(getter_AddRefs(item)); multiSelect->GetCurrentItem(getter_AddRefs(item));
} }
} }
}
} else { } else {
// don't check menulists as the selected item will be inside a popup. // don't check menulists as the selected item will be inside a popup.
nsCOMPtr<nsIDOMXULMenuListElement> menulist = nsCOMPtr<nsIDOMXULMenuListElement> menulist =

Просмотреть файл

@ -185,4 +185,5 @@ ABSTRACT_FRAME_ID(nsIStatefulFrame)
ABSTRACT_FRAME_ID(nsITableCellLayout) ABSTRACT_FRAME_ID(nsITableCellLayout)
ABSTRACT_FRAME_ID(nsITableLayout) ABSTRACT_FRAME_ID(nsITableLayout)
ABSTRACT_FRAME_ID(nsITextControlFrame) ABSTRACT_FRAME_ID(nsITextControlFrame)
ABSTRACT_FRAME_ID(nsITreeBoxObject)
ABSTRACT_FRAME_ID(nsSVGDisplayableFrame) ABSTRACT_FRAME_ID(nsSVGDisplayableFrame)

Просмотреть файл

@ -9,7 +9,7 @@ function boom()
{ {
try { try {
var tree = document.getElementById("tree"); var tree = document.getElementById("tree");
var col = tree.columns.getFirstColumn(); var col = tree.treeBoxObject.columns.getFirstColumn();
var treecols = document.getElementById("treecols"); var treecols = document.getElementById("treecols");
treecols.parentNode.removeChild(treecols); treecols.parentNode.removeChild(treecols);
var x = col.x; var x = col.x;

Просмотреть файл

@ -33,7 +33,6 @@
#include "mozilla/dom/BoxObject.h" #include "mozilla/dom/BoxObject.h"
#include "mozilla/dom/MouseEvent.h" #include "mozilla/dom/MouseEvent.h"
#include "mozilla/dom/TreeColumnBinding.h" #include "mozilla/dom/TreeColumnBinding.h"
#include "mozilla/dom/XULTreeElementBinding.h"
#include "mozilla/TextEvents.h" #include "mozilla/TextEvents.h"
using namespace mozilla; using namespace mozilla;
@ -333,11 +332,16 @@ void nsXULTooltipListener::CheckTreeBodyMove(MouseEvent* aMouseEvent) {
bx = doc->GetBoxObjectFor(doc->GetRootElement(), ignored); bx = doc->GetBoxObjectFor(doc->GetRootElement(), ignored);
} }
RefPtr<XULTreeElement> tree = GetSourceTree(); nsCOMPtr<nsITreeBoxObject> obx;
if (bx && tree) { GetSourceTreeBoxObject(getter_AddRefs(obx));
if (bx && obx) {
int32_t x = aMouseEvent->ScreenX(CallerType::System); int32_t x = aMouseEvent->ScreenX(CallerType::System);
int32_t y = aMouseEvent->ScreenY(CallerType::System); int32_t y = aMouseEvent->ScreenY(CallerType::System);
int32_t row;
RefPtr<nsTreeColumn> col;
nsAutoString obj;
// subtract off the documentElement's boxObject // subtract off the documentElement's boxObject
int32_t boxX, boxY; int32_t boxX, boxY;
bx->GetScreenX(&boxX); bx->GetScreenX(&boxX);
@ -345,12 +349,7 @@ void nsXULTooltipListener::CheckTreeBodyMove(MouseEvent* aMouseEvent) {
x -= boxX; x -= boxX;
y -= boxY; y -= boxY;
ErrorResult rv; obx->GetCellAt(x, y, &row, getter_AddRefs(col), obj);
TreeCellInfo cellInfo;
tree->GetCellAt(x, y, cellInfo, rv);
int32_t row = cellInfo.mRow;
RefPtr<nsTreeColumn> col = cellInfo.mCol;
// determine if we are going to need a titletip // determine if we are going to need a titletip
// XXX check the disabletitletips attribute on the tree content // XXX check the disabletitletips attribute on the tree content
@ -359,9 +358,9 @@ void nsXULTooltipListener::CheckTreeBodyMove(MouseEvent* aMouseEvent) {
if (col) { if (col) {
colType = col->Type(); colType = col->Type();
} }
if (row >= 0 && cellInfo.mChildElt.EqualsLiteral("text") && if (row >= 0 && obj.EqualsLiteral("text") &&
colType != TreeColumn_Binding::TYPE_PASSWORD) { colType != TreeColumn_Binding::TYPE_PASSWORD) {
mNeedTitletip = tree->IsCellCropped(row, col, rv); obx->IsCellCropped(row, col, &mNeedTitletip);
} }
nsCOMPtr<nsIContent> currentTooltip = do_QueryReferent(mCurrentTooltip); nsCOMPtr<nsIContent> currentTooltip = do_QueryReferent(mCurrentTooltip);
@ -435,9 +434,29 @@ nsresult nsXULTooltipListener::ShowTooltip() {
} }
#ifdef MOZ_XUL #ifdef MOZ_XUL
static void SetTitletipLabel(XULTreeElement* aTree, Element* aTooltip, // XXX: "This stuff inside DEBUG_crap could be used to make tree tooltips work
// in the future."
#ifdef DEBUG_crap
static void GetTreeCellCoords(nsITreeBoxObject* aTreeBox,
nsIContent* aSourceNode, int32_t aRow,
nsTreeColumn* aCol, int32_t* aX, int32_t* aY) {
int32_t junk;
aTreeBox->GetCoordsForCellItem(aRow, aCol, EmptyCString(), aX, aY, &junk,
&junk);
RefPtr<nsXULElement> xulEl = nsXULElement::FromNode(aSourceNode);
nsCOMPtr<nsIBoxObject> bx = xulEl->GetBoxObject(IgnoreErrors());
int32_t myX, myY;
bx->GetX(&myX);
bx->GetY(&myY);
*aX += myX;
*aY += myY;
}
#endif
static void SetTitletipLabel(nsITreeBoxObject* aTreeBox, Element* aTooltip,
int32_t aRow, nsTreeColumn* aCol) { int32_t aRow, nsTreeColumn* aCol) {
nsCOMPtr<nsITreeView> view = aTree->GetView(); nsCOMPtr<nsITreeView> view;
aTreeBox->GetView(getter_AddRefs(view));
if (view) { if (view) {
nsAutoString label; nsAutoString label;
#ifdef DEBUG #ifdef DEBUG
@ -456,9 +475,10 @@ void nsXULTooltipListener::LaunchTooltip() {
#ifdef MOZ_XUL #ifdef MOZ_XUL
if (mIsSourceTree && mNeedTitletip) { if (mIsSourceTree && mNeedTitletip) {
RefPtr<XULTreeElement> tree = GetSourceTree(); nsCOMPtr<nsITreeBoxObject> obx;
GetSourceTreeBoxObject(getter_AddRefs(obx));
SetTitletipLabel(tree, currentTooltip, mLastTreeRow, mLastTreeCol); SetTitletipLabel(obx, currentTooltip, mLastTreeRow, mLastTreeCol);
if (!(currentTooltip = do_QueryReferent(mCurrentTooltip))) { if (!(currentTooltip = do_QueryReferent(mCurrentTooltip))) {
// Because of mutation events, currentTooltip can be null. // Because of mutation events, currentTooltip can be null.
return; return;
@ -677,14 +697,24 @@ void nsXULTooltipListener::sTooltipCallback(nsITimer* aTimer, void* aListener) {
} }
#ifdef MOZ_XUL #ifdef MOZ_XUL
XULTreeElement* nsXULTooltipListener::GetSourceTree() { nsresult nsXULTooltipListener::GetSourceTreeBoxObject(
nsITreeBoxObject** aBoxObject) {
*aBoxObject = nullptr;
nsCOMPtr<nsIContent> sourceNode = do_QueryReferent(mSourceNode); nsCOMPtr<nsIContent> sourceNode = do_QueryReferent(mSourceNode);
if (mIsSourceTree && sourceNode) { if (mIsSourceTree && sourceNode) {
RefPtr<XULTreeElement> xulEl = RefPtr<nsXULElement> xulEl =
XULTreeElement::FromNodeOrNull(sourceNode->GetParent()); nsXULElement::FromNodeOrNull(sourceNode->GetParent());
return xulEl; if (xulEl) {
nsCOMPtr<nsIBoxObject> bx = xulEl->GetBoxObject(IgnoreErrors());
nsCOMPtr<nsITreeBoxObject> obx(do_QueryInterface(bx));
if (obx) {
*aBoxObject = obx;
NS_ADDREF(*aBoxObject);
return NS_OK;
} }
}
return nullptr; }
return NS_ERROR_FAILURE;
} }
#endif #endif

Просмотреть файл

@ -12,7 +12,7 @@
#include "nsCOMPtr.h" #include "nsCOMPtr.h"
#include "nsString.h" #include "nsString.h"
#ifdef MOZ_XUL #ifdef MOZ_XUL
#include "XULTreeElement.h" #include "nsITreeBoxObject.h"
#endif #endif
#include "nsIWeakReferenceUtils.h" #include "nsIWeakReferenceUtils.h"
#include "mozilla/Attributes.h" #include "mozilla/Attributes.h"
@ -53,7 +53,7 @@ class nsXULTooltipListener final : public nsIDOMEventListener {
#ifdef MOZ_XUL #ifdef MOZ_XUL
void CheckTreeBodyMove(mozilla::dom::MouseEvent* aMouseEvent); void CheckTreeBodyMove(mozilla::dom::MouseEvent* aMouseEvent);
mozilla::dom::XULTreeElement* GetSourceTree(); nsresult GetSourceTreeBoxObject(nsITreeBoxObject** aBoxObject);
#endif #endif
nsresult ShowTooltip(); nsresult ShowTooltip();

Просмотреть файл

@ -0,0 +1,509 @@
/* -*- 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/dom/TreeBoxObject.h"
#include "nsCOMPtr.h"
#include "nsXULElement.h"
#include "nsTreeContentView.h"
#include "nsITreeSelection.h"
#include "ChildIterator.h"
#include "nsError.h"
#include "nsTreeBodyFrame.h"
#include "mozilla/dom/TreeBoxObjectBinding.h"
#include "mozilla/dom/DOMRect.h"
#include "mozilla/dom/BindingUtils.h"
#include "mozilla/dom/Element.h"
#include "mozilla/dom/ToJSValue.h"
namespace mozilla {
namespace dom {
NS_IMPL_CYCLE_COLLECTION_INHERITED(TreeBoxObject, BoxObject, mView)
NS_IMPL_ADDREF_INHERITED(TreeBoxObject, BoxObject)
NS_IMPL_RELEASE_INHERITED(TreeBoxObject, BoxObject)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(TreeBoxObject)
NS_INTERFACE_MAP_ENTRY(nsITreeBoxObject)
NS_INTERFACE_MAP_END_INHERITING(BoxObject)
void TreeBoxObject::Clear() {
ClearCachedValues();
// Drop the view's ref to us.
if (mView) {
nsCOMPtr<nsITreeSelection> sel;
mView->GetSelection(getter_AddRefs(sel));
if (sel) sel->SetTree(nullptr);
mView->SetTree(nullptr); // Break the circular ref between the view and us.
}
mView = nullptr;
BoxObject::Clear();
}
TreeBoxObject::TreeBoxObject() : mTreeBody(nullptr) {}
TreeBoxObject::~TreeBoxObject() {}
static nsIContent* FindBodyElement(nsIContent* aParent) {
mozilla::dom::FlattenedChildIterator iter(aParent);
for (nsIContent* content = iter.GetNextChild(); content;
content = iter.GetNextChild()) {
mozilla::dom::NodeInfo* ni = content->NodeInfo();
if (ni->Equals(nsGkAtoms::treechildren, kNameSpaceID_XUL)) {
return content;
} else if (ni->Equals(nsGkAtoms::tree, kNameSpaceID_XUL)) {
// There are nesting tree elements. Only the innermost should
// find the treechilren.
return nullptr;
} else if (content->IsElement() &&
!ni->Equals(nsGkAtoms::_template, kNameSpaceID_XUL)) {
nsIContent* result = FindBodyElement(content);
if (result) return result;
}
}
return nullptr;
}
nsTreeBodyFrame* TreeBoxObject::GetTreeBodyFrame(bool aFlushLayout) {
// Make sure our frames are up to date, and layout as needed. We
// have to do this before checking for our cached mTreeBody, since
// it might go away on style flush, and in any case if aFlushLayout
// is true we need to make sure to flush no matter what.
// XXXbz except that flushing style when we were not asked to flush
// layout here breaks things. See bug 585123.
nsIFrame* frame = nullptr;
if (aFlushLayout) {
frame = GetFrame(aFlushLayout);
if (!frame) return nullptr;
}
if (mTreeBody) {
// Have one cached already.
return mTreeBody;
}
if (!aFlushLayout) {
frame = GetFrame(aFlushLayout);
if (!frame) return nullptr;
}
// Iterate over our content model children looking for the body.
nsCOMPtr<nsIContent> content = FindBodyElement(frame->GetContent());
if (!content) return nullptr;
frame = content->GetPrimaryFrame();
if (!frame) return nullptr;
// Make sure that the treebodyframe has a pointer to |this|.
nsTreeBodyFrame* treeBody = do_QueryFrame(frame);
NS_ENSURE_TRUE(treeBody && treeBody->GetTreeBoxObject() == this, nullptr);
mTreeBody = treeBody;
return mTreeBody;
}
NS_IMETHODIMP
TreeBoxObject::GetView(nsITreeView** aView) {
if (!mTreeBody) {
if (!GetTreeBodyFrame()) {
// Don't return an uninitialised view
*aView = nullptr;
return NS_OK;
}
if (mView)
// Our new frame needs to initialise itself
return mTreeBody->GetView(aView);
}
if (!mView) {
RefPtr<nsXULElement> xulele = nsXULElement::FromNodeOrNull(mContent);
if (xulele) {
// No tree builder, create a tree content view.
nsresult rv = NS_NewTreeContentView(getter_AddRefs(mView));
NS_ENSURE_SUCCESS(rv, rv);
// Initialise the frame and view
mTreeBody->SetView(mView);
}
}
NS_IF_ADDREF(*aView = mView);
return NS_OK;
}
already_AddRefed<nsITreeView> TreeBoxObject::GetView(CallerType /* unused */) {
nsCOMPtr<nsITreeView> view;
GetView(getter_AddRefs(view));
return view.forget();
}
NS_IMETHODIMP
TreeBoxObject::SetView(nsITreeView* aView) {
ErrorResult rv;
SetView(aView, CallerType::System, rv);
return rv.StealNSResult();
}
void TreeBoxObject::SetView(nsITreeView* aView, CallerType aCallerType,
ErrorResult& aRv) {
if (aCallerType != CallerType::System) {
// Don't trust views coming from random places.
aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
return;
}
mView = aView;
nsTreeBodyFrame* body = GetTreeBodyFrame();
if (body) body->SetView(aView);
}
bool TreeBoxObject::Focused() {
nsTreeBodyFrame* body = GetTreeBodyFrame();
if (body) return body->GetFocused();
return false;
}
NS_IMETHODIMP TreeBoxObject::GetFocused(bool* aFocused) {
*aFocused = Focused();
return NS_OK;
}
NS_IMETHODIMP TreeBoxObject::SetFocused(bool aFocused) {
nsTreeBodyFrame* body = GetTreeBodyFrame();
if (body) return body->SetFocused(aFocused);
return NS_OK;
}
NS_IMETHODIMP TreeBoxObject::GetTreeBody(Element** aElement) {
*aElement = nullptr;
nsTreeBodyFrame* body = GetTreeBodyFrame();
if (body) return body->GetTreeBody(aElement);
return NS_OK;
}
already_AddRefed<Element> TreeBoxObject::GetTreeBody() {
RefPtr<Element> el;
GetTreeBody(getter_AddRefs(el));
return el.forget();
}
already_AddRefed<nsTreeColumns> TreeBoxObject::GetColumns() {
nsTreeBodyFrame* body = GetTreeBodyFrame();
if (body) return body->Columns();
return nullptr;
}
NS_IMETHODIMP TreeBoxObject::GetColumns(nsTreeColumns** aColumns) {
*aColumns = GetColumns().take();
return NS_OK;
}
int32_t TreeBoxObject::RowHeight() {
nsTreeBodyFrame* body = GetTreeBodyFrame();
if (body) return body->RowHeight();
return 0;
}
int32_t TreeBoxObject::RowWidth() {
nsTreeBodyFrame* body = GetTreeBodyFrame();
if (body) return body->RowWidth();
return 0;
}
NS_IMETHODIMP TreeBoxObject::GetRowHeight(int32_t* aRowHeight) {
*aRowHeight = RowHeight();
return NS_OK;
}
NS_IMETHODIMP TreeBoxObject::GetRowWidth(int32_t* aRowWidth) {
*aRowWidth = RowWidth();
return NS_OK;
}
int32_t TreeBoxObject::GetFirstVisibleRow() {
nsTreeBodyFrame* body = GetTreeBodyFrame();
if (body) return body->FirstVisibleRow();
return 0;
}
NS_IMETHODIMP TreeBoxObject::GetFirstVisibleRow(int32_t* aFirstVisibleRow) {
*aFirstVisibleRow = GetFirstVisibleRow();
return NS_OK;
}
int32_t TreeBoxObject::GetLastVisibleRow() {
nsTreeBodyFrame* body = GetTreeBodyFrame();
if (body) return body->LastVisibleRow();
return 0;
}
NS_IMETHODIMP TreeBoxObject::GetLastVisibleRow(int32_t* aLastVisibleRow) {
*aLastVisibleRow = GetLastVisibleRow();
return NS_OK;
}
int32_t TreeBoxObject::HorizontalPosition() {
nsTreeBodyFrame* body = GetTreeBodyFrame();
if (body) return body->GetHorizontalPosition();
return 0;
}
int32_t TreeBoxObject::GetPageLength() {
nsTreeBodyFrame* body = GetTreeBodyFrame();
if (body) return body->PageLength();
return 0;
}
NS_IMETHODIMP
TreeBoxObject::EnsureRowIsVisible(int32_t aRow) {
nsTreeBodyFrame* body = GetTreeBodyFrame();
if (body) return body->EnsureRowIsVisible(aRow);
return NS_OK;
}
void TreeBoxObject::EnsureCellIsVisible(int32_t aRow, nsTreeColumn* aCol,
ErrorResult& aRv) {
nsTreeBodyFrame* body = GetTreeBodyFrame();
if (body) {
nsresult rv = body->EnsureCellIsVisible(aRow, aCol);
if (NS_FAILED(rv)) {
aRv.Throw(rv);
}
}
}
void TreeBoxObject::ScrollToRow(int32_t aRow) {
nsTreeBodyFrame* body = GetTreeBodyFrame(true);
if (!body) {
return;
}
body->ScrollToRow(aRow);
}
void TreeBoxObject::ScrollByLines(int32_t aNumLines) {
nsTreeBodyFrame* body = GetTreeBodyFrame();
if (!body) {
return;
}
body->ScrollByLines(aNumLines);
}
void TreeBoxObject::ScrollByPages(int32_t aNumPages) {
nsTreeBodyFrame* body = GetTreeBodyFrame();
if (body) body->ScrollByPages(aNumPages);
}
NS_IMETHODIMP TreeBoxObject::Invalidate() {
nsTreeBodyFrame* body = GetTreeBodyFrame();
if (body) return body->Invalidate();
return NS_OK;
}
NS_IMETHODIMP
TreeBoxObject::InvalidateColumn(nsTreeColumn* aCol) {
nsTreeBodyFrame* body = GetTreeBodyFrame();
if (body) return body->InvalidateColumn(aCol);
return NS_OK;
}
NS_IMETHODIMP
TreeBoxObject::InvalidateRow(int32_t aIndex) {
nsTreeBodyFrame* body = GetTreeBodyFrame();
if (body) return body->InvalidateRow(aIndex);
return NS_OK;
}
NS_IMETHODIMP
TreeBoxObject::InvalidateCell(int32_t aRow, nsTreeColumn* aCol) {
nsTreeBodyFrame* body = GetTreeBodyFrame();
if (body) return body->InvalidateCell(aRow, aCol);
return NS_OK;
}
NS_IMETHODIMP
TreeBoxObject::InvalidateRange(int32_t aStart, int32_t aEnd) {
nsTreeBodyFrame* body = GetTreeBodyFrame();
if (body) return body->InvalidateRange(aStart, aEnd);
return NS_OK;
}
int32_t TreeBoxObject::GetRowAt(int32_t x, int32_t y) {
nsTreeBodyFrame* body = GetTreeBodyFrame();
if (!body) {
return 0;
}
return body->GetRowAt(x, y);
}
NS_IMETHODIMP
TreeBoxObject::GetCellAt(int32_t aX, int32_t aY, int32_t* aRow,
nsTreeColumn** aCol, nsAString& aChildElt) {
*aRow = 0;
*aCol = nullptr;
nsTreeBodyFrame* body = GetTreeBodyFrame();
if (body) {
nsAutoCString element;
nsresult retval = body->GetCellAt(aX, aY, aRow, aCol, element);
CopyUTF8toUTF16(element, aChildElt);
return retval;
}
return NS_OK;
}
void TreeBoxObject::GetCellAt(int32_t x, int32_t y, TreeCellInfo& aRetVal,
ErrorResult& aRv) {
GetCellAt(x, y, &aRetVal.mRow, getter_AddRefs(aRetVal.mCol),
aRetVal.mChildElt);
}
void TreeBoxObject::GetCellAt(JSContext* cx, int32_t x, int32_t y,
JS::Handle<JSObject*> rowOut,
JS::Handle<JSObject*> colOut,
JS::Handle<JSObject*> childEltOut,
ErrorResult& aRv) {
int32_t row;
RefPtr<nsTreeColumn> col;
nsAutoString childElt;
GetCellAt(x, y, &row, getter_AddRefs(col), childElt);
JS::Rooted<JS::Value> v(cx);
if (!ToJSValue(cx, row, &v) || !JS_SetProperty(cx, rowOut, "value", v)) {
aRv.Throw(NS_ERROR_XPC_CANT_SET_OUT_VAL);
return;
}
if (!dom::WrapObject(cx, col, &v) ||
!JS_SetProperty(cx, colOut, "value", v)) {
aRv.Throw(NS_ERROR_XPC_CANT_SET_OUT_VAL);
return;
}
if (!ToJSValue(cx, childElt, &v) ||
!JS_SetProperty(cx, childEltOut, "value", v)) {
aRv.Throw(NS_ERROR_XPC_CANT_SET_OUT_VAL);
return;
}
}
NS_IMETHODIMP
TreeBoxObject::GetCoordsForCellItem(int32_t aRow, nsTreeColumn* aCol,
const nsAString& aElement, int32_t* aX,
int32_t* aY, int32_t* aWidth,
int32_t* aHeight) {
*aX = *aY = *aWidth = *aHeight = 0;
nsTreeBodyFrame* body = GetTreeBodyFrame();
NS_ConvertUTF16toUTF8 element(aElement);
if (body)
return body->GetCoordsForCellItem(aRow, aCol, element, aX, aY, aWidth,
aHeight);
return NS_OK;
}
already_AddRefed<DOMRect> TreeBoxObject::GetCoordsForCellItem(
int32_t row, nsTreeColumn& col, const nsAString& element,
ErrorResult& aRv) {
int32_t x, y, w, h;
GetCoordsForCellItem(row, &col, element, &x, &y, &w, &h);
RefPtr<DOMRect> rect = new DOMRect(mContent, x, y, w, h);
return rect.forget();
}
void TreeBoxObject::GetCoordsForCellItem(
JSContext* cx, int32_t row, nsTreeColumn& col, const nsAString& element,
JS::Handle<JSObject*> xOut, JS::Handle<JSObject*> yOut,
JS::Handle<JSObject*> widthOut, JS::Handle<JSObject*> heightOut,
ErrorResult& aRv) {
int32_t x, y, w, h;
GetCoordsForCellItem(row, &col, element, &x, &y, &w, &h);
JS::Rooted<JS::Value> v(cx, JS::Int32Value(x));
if (!JS_SetProperty(cx, xOut, "value", v)) {
aRv.Throw(NS_ERROR_XPC_CANT_SET_OUT_VAL);
return;
}
v.setInt32(y);
if (!JS_SetProperty(cx, yOut, "value", v)) {
aRv.Throw(NS_ERROR_XPC_CANT_SET_OUT_VAL);
return;
}
v.setInt32(w);
if (!JS_SetProperty(cx, widthOut, "value", v)) {
aRv.Throw(NS_ERROR_XPC_CANT_SET_OUT_VAL);
return;
}
v.setInt32(h);
if (!JS_SetProperty(cx, heightOut, "value", v)) {
aRv.Throw(NS_ERROR_XPC_CANT_SET_OUT_VAL);
return;
}
}
NS_IMETHODIMP
TreeBoxObject::IsCellCropped(int32_t aRow, nsTreeColumn* aCol,
bool* aIsCropped) {
*aIsCropped = false;
nsTreeBodyFrame* body = GetTreeBodyFrame();
if (body) return body->IsCellCropped(aRow, aCol, aIsCropped);
return NS_OK;
}
bool TreeBoxObject::IsCellCropped(int32_t row, nsTreeColumn* col,
ErrorResult& aRv) {
bool ret;
aRv = IsCellCropped(row, col, &ret);
return ret;
}
NS_IMETHODIMP
TreeBoxObject::RowCountChanged(int32_t aIndex, int32_t aDelta) {
nsTreeBodyFrame* body = GetTreeBodyFrame();
if (body) return body->RowCountChanged(aIndex, aDelta);
return NS_OK;
}
NS_IMETHODIMP
TreeBoxObject::BeginUpdateBatch() {
nsTreeBodyFrame* body = GetTreeBodyFrame();
if (body) return body->BeginUpdateBatch();
return NS_OK;
}
NS_IMETHODIMP
TreeBoxObject::EndUpdateBatch() {
nsTreeBodyFrame* body = GetTreeBodyFrame();
if (body) return body->EndUpdateBatch();
return NS_OK;
}
NS_IMETHODIMP
TreeBoxObject::ClearStyleAndImageCaches() {
nsTreeBodyFrame* body = GetTreeBodyFrame();
if (body) return body->ClearStyleAndImageCaches();
return NS_OK;
}
void TreeBoxObject::RemoveImageCacheEntry(int32_t aRowIndex, nsTreeColumn& aCol,
ErrorResult& aRv) {
if (NS_WARN_IF(aRowIndex < 0)) {
aRv.Throw(NS_ERROR_INVALID_ARG);
return;
}
nsTreeBodyFrame* body = GetTreeBodyFrame();
if (body) {
body->RemoveImageCacheEntry(aRowIndex, &aCol);
}
}
void TreeBoxObject::ClearCachedValues() { mTreeBody = nullptr; }
JSObject* TreeBoxObject::WrapObject(JSContext* aCx,
JS::Handle<JSObject*> aGivenProto) {
return TreeBoxObject_Binding::Wrap(aCx, this, aGivenProto);
}
} // namespace dom
} // namespace mozilla

Просмотреть файл

@ -4,16 +4,12 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * 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/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef XULTreeElement_h__ #ifndef mozilla_dom_TreeBoxObject_h
#define XULTreeElement_h__ #define mozilla_dom_TreeBoxObject_h
#include "mozilla/Attributes.h" #include "mozilla/dom/BoxObject.h"
#include "mozilla/ErrorResult.h"
#include "nsCycleCollectionParticipant.h"
#include "nsWrapperCache.h"
#include "nsString.h"
#include "nsXULElement.h"
#include "nsITreeView.h" #include "nsITreeView.h"
#include "nsITreeBoxObject.h"
class nsTreeBodyFrame; class nsTreeBodyFrame;
class nsTreeColumn; class nsTreeColumn;
@ -26,27 +22,28 @@ struct TreeCellInfo;
class DOMRect; class DOMRect;
enum class CallerType : uint32_t; enum class CallerType : uint32_t;
class XULTreeElement final : public nsXULElement { class TreeBoxObject final : public BoxObject, public nsITreeBoxObject {
public: public:
explicit XULTreeElement(already_AddRefed<mozilla::dom::NodeInfo> &&aNodeInfo)
: nsXULElement(std::move(aNodeInfo)),
mCachedFirstVisibleRow(0),
mTreeBody(nullptr) {}
NS_IMPL_FROMNODE_WITH_TAG(XULTreeElement, kNameSpaceID_XUL, tree)
NS_DECL_ISUPPORTS_INHERITED NS_DECL_ISUPPORTS_INHERITED
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(XULTreeElement, nsXULElement) NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(TreeBoxObject, BoxObject)
NS_DECL_NSITREEBOXOBJECT
TreeBoxObject();
nsTreeBodyFrame* GetTreeBodyFrame(bool aFlushLayout = false); nsTreeBodyFrame* GetTreeBodyFrame(bool aFlushLayout = false);
nsTreeBodyFrame* GetCachedTreeBodyFrame() { return mTreeBody; } nsTreeBodyFrame* GetCachedTreeBodyFrame() { return mTreeBody; }
// NS_PIBOXOBJECT interfaces
virtual void Clear() override;
virtual void ClearCachedValues() override;
// WebIDL
virtual JSObject* WrapObject(JSContext* aCx,
JS::Handle<JSObject*> aGivenProto) override;
already_AddRefed<nsTreeColumns> GetColumns(); already_AddRefed<nsTreeColumns> GetColumns();
already_AddRefed<nsITreeView> GetView(CallerType /* unused */) { already_AddRefed<nsITreeView> GetView(CallerType /* unused */);
return GetView();
}
already_AddRefed<nsITreeView> GetView();
void SetView(nsITreeView* arg, CallerType aCallerType, ErrorResult& aRv); void SetView(nsITreeView* arg, CallerType aCallerType, ErrorResult& aRv);
@ -78,8 +75,6 @@ class XULTreeElement final : public nsXULElement {
void GetCellAt(int32_t x, int32_t y, TreeCellInfo& aRetVal, ErrorResult& aRv); void GetCellAt(int32_t x, int32_t y, TreeCellInfo& aRetVal, ErrorResult& aRv);
nsIntRect GetCoordsForCellItem(int32_t aRow, nsTreeColumn* aCol,
const nsAString& aElement, nsresult& rv);
already_AddRefed<DOMRect> GetCoordsForCellItem(int32_t row, nsTreeColumn& col, already_AddRefed<DOMRect> GetCoordsForCellItem(int32_t row, nsTreeColumn& col,
const nsAString& element, const nsAString& element,
ErrorResult& aRv); ErrorResult& aRv);
@ -88,38 +83,37 @@ class XULTreeElement final : public nsXULElement {
void RemoveImageCacheEntry(int32_t row, nsTreeColumn& col, ErrorResult& aRv); void RemoveImageCacheEntry(int32_t row, nsTreeColumn& col, ErrorResult& aRv);
void SetFocused(bool aFocused); // Deprecated APIs from old IDL
void EnsureRowIsVisible(int32_t index); void GetCellAt(JSContext* cx, int32_t x, int32_t y,
void Invalidate(void); JS::Handle<JSObject*> rowOut, JS::Handle<JSObject*> colOut,
void InvalidateColumn(nsTreeColumn* col); JS::Handle<JSObject*> childEltOut, ErrorResult& aRv);
void InvalidateRow(int32_t index);
void InvalidateCell(int32_t row, nsTreeColumn* col);
void InvalidateRange(int32_t startIndex, int32_t endIndex);
void RowCountChanged(int32_t index, int32_t count);
void BeginUpdateBatch(void);
void EndUpdateBatch(void);
void ClearStyleAndImageCaches(void);
virtual void UnbindFromTree(bool aDeep, bool aNullParent) override; void GetCoordsForCellItem(JSContext* cx, int32_t row, nsTreeColumn& col,
virtual void DestroyContent() override; const nsAString& element,
JS::Handle<JSObject*> xOut,
JS::Handle<JSObject*> yOut,
JS::Handle<JSObject*> widthOut,
JS::Handle<JSObject*> heightOut, ErrorResult& aRv);
void BodyDestroyed(int32_t aFirstVisibleRow) { // Same signature (except for nsresult return type) as the XPIDL impls
mTreeBody = nullptr; // void Invalidate();
mCachedFirstVisibleRow = aFirstVisibleRow; // void BeginUpdateBatch();
} // void EndUpdateBatch();
// void ClearStyleAndImageCaches();
int32_t GetCachedTopVisibleRow() { return mCachedFirstVisibleRow; } // void SetFocused(bool arg);
// void EnsureRowIsVisible(int32_t index);
// void InvalidateColumn(nsTreeColumn* col);
// void InvalidateRow(int32_t index);
// void InvalidateCell(int32_t row, nsTreeColumn* col);
// void InvalidateRange(int32_t startIndex, int32_t endIndex);
// void RowCountChanged(int32_t index, int32_t count);
protected: protected:
int32_t mCachedFirstVisibleRow;
nsTreeBodyFrame* mTreeBody; nsTreeBodyFrame* mTreeBody;
nsCOMPtr<nsITreeView> mView; nsCOMPtr<nsITreeView> mView;
virtual ~XULTreeElement() {} private:
~TreeBoxObject();
JSObject *WrapNode(JSContext *aCx,
JS::Handle<JSObject *> aGivenProto) override;
}; };
} // namespace dom } // namespace dom

Просмотреть файл

@ -8,6 +8,7 @@ with Files('**'):
BUG_COMPONENT = ('Core', 'XUL') BUG_COMPONENT = ('Core', 'XUL')
XPIDL_SOURCES += [ XPIDL_SOURCES += [
'nsITreeBoxObject.idl',
'nsITreeSelection.idl', 'nsITreeSelection.idl',
'nsITreeView.idl', 'nsITreeView.idl',
] ]
@ -20,6 +21,10 @@ EXPORTS += [
'nsTreeUtils.h', 'nsTreeUtils.h',
] ]
EXPORTS.mozilla.dom += [
'TreeBoxObject.h'
]
UNIFIED_SOURCES += [ UNIFIED_SOURCES += [
'nsTreeBodyFrame.cpp', 'nsTreeBodyFrame.cpp',
'nsTreeColFrame.cpp', 'nsTreeColFrame.cpp',
@ -29,6 +34,7 @@ UNIFIED_SOURCES += [
'nsTreeSelection.cpp', 'nsTreeSelection.cpp',
'nsTreeStyleCache.cpp', 'nsTreeStyleCache.cpp',
'nsTreeUtils.cpp', 'nsTreeUtils.cpp',
'TreeBoxObject.cpp',
] ]
FINAL_LIBRARY = 'xul' FINAL_LIBRARY = 'xul'

Просмотреть файл

@ -0,0 +1,123 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* 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 "nsISupports.idl"
interface nsITreeView;
webidl Element;
webidl TreeColumn;
webidl TreeColumns;
/**
* This interface cannot become builtinclass until bug 1438525 is fixed.
*/
[scriptable, uuid(f3da0c5e-51f5-45f0-b2cd-6be3ab6847ae)]
interface nsITreeBoxObject : nsISupports
{
/**
* Obtain the columns.
*/
readonly attribute TreeColumns columns;
/**
* The view that backs the tree and that supplies it with its data.
* It is dynamically settable, either using a view attribute on the
* tree tag or by setting this attribute to a new value.
*/
attribute nsITreeView view;
/**
* Whether or not we are currently focused.
*/
attribute boolean focused;
/**
* Obtain the treebody content node
*/
readonly attribute Element treeBody;
/**
* Obtain the height of a row.
*/
readonly attribute long rowHeight;
/**
* Obtain the width of a row.
*/
readonly attribute long rowWidth;
/**
* Get the index of the first visible row.
*/
long getFirstVisibleRow();
/**
* Get the index of the last visible row.
*/
long getLastVisibleRow();
/**
* Ensures that a row at a given index is visible.
*/
void ensureRowIsVisible(in long index);
/**
* Invalidation methods for fine-grained painting control.
*/
void invalidate();
void invalidateColumn(in TreeColumn col);
void invalidateRow(in long index);
void invalidateCell(in long row, in TreeColumn col);
void invalidateRange(in long startIndex, in long endIndex);
/**
* A hit test that can tell you what cell the mouse is over. Row is the row index
* hit, returns -1 for invalid mouse coordinates. ColID is the column hit.
* ChildElt is the pseudoelement hit: this can have values of
* "cell", "twisty", "image", and "text".
*
* The coordinate system is the client coordinate system for the
* document this boxObject lives in, and the units are CSS pixels.
*/
void getCellAt(in long x, in long y, out long row, out TreeColumn col, out AString childElt);
/**
* Find the coordinates of an element within a specific cell.
*/
void getCoordsForCellItem(in long row, in TreeColumn col, in AString element,
out long x, out long y, out long width, out long height);
/**
* Determine if the text of a cell is being cropped or not.
*/
boolean isCellCropped(in long row, in TreeColumn col);
/**
* The view is responsible for calling these notification methods when
* rows are added or removed. Index is the position at which the new
* rows were added or at which rows were removed. For
* non-contiguous additions/removals, this method should be called multiple times.
*/
void rowCountChanged(in long index, in long count);
/**
* Notify the tree that the view is about to perform a batch
* update, that is, add, remove or invalidate several rows at once.
* This must be followed by calling endUpdateBatch(), otherwise the tree
* will get out of sync.
*/
void beginUpdateBatch();
/**
* Notify the tree that the view has completed a batch update.
*/
void endUpdateBatch();
/**
* Called on a theme switch to flush out the tree's style and image caches.
*/
void clearStyleAndImageCaches();
};

Просмотреть файл

@ -3,9 +3,9 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * 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/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "nsISupports.idl" interface nsITreeBoxObject;
webidl XULTreeElement; #include "nsISupports.idl"
[scriptable, uuid(ab6fe746-300b-4ab4-abb9-1c0e3977874c)] [scriptable, uuid(ab6fe746-300b-4ab4-abb9-1c0e3977874c)]
interface nsITreeSelection : nsISupports interface nsITreeSelection : nsISupports
@ -13,7 +13,7 @@ interface nsITreeSelection : nsISupports
/** /**
* The tree widget for this selection. * The tree widget for this selection.
*/ */
attribute XULTreeElement tree; attribute nsITreeBoxObject tree;
/** /**
* This attribute is a boolean indicating single selection. * This attribute is a boolean indicating single selection.

Просмотреть файл

@ -5,11 +5,11 @@
#include "nsISupports.idl" #include "nsISupports.idl"
interface nsITreeBoxObject;
interface nsITreeSelection; interface nsITreeSelection;
webidl DataTransfer; webidl DataTransfer;
webidl TreeColumn; webidl TreeColumn;
webidl XULTreeElement;
[scriptable, uuid(091116f0-0bdc-4b32-b9c8-c8d5a37cb088)] [scriptable, uuid(091116f0-0bdc-4b32-b9c8-c8d5a37cb088)]
interface nsITreeView : nsISupports interface nsITreeView : nsISupports
@ -130,7 +130,7 @@ interface nsITreeView : nsISupports
/** /**
* Called during initialization to link the view to the front end box object. * Called during initialization to link the view to the front end box object.
*/ */
void setTree(in XULTreeElement tree); void setTree(in nsITreeBoxObject tree);
/** /**
* Called on the view when an item is opened or closed. * Called on the view when an item is opened or closed.

Просмотреть файл

@ -33,6 +33,7 @@
#include "gfxContext.h" #include "gfxContext.h"
#include "nsIContent.h" #include "nsIContent.h"
#include "mozilla/ComputedStyle.h" #include "mozilla/ComputedStyle.h"
#include "nsIBoxObject.h"
#include "mozilla/dom/Document.h" #include "mozilla/dom/Document.h"
#include "nsCSSRendering.h" #include "nsCSSRendering.h"
#include "nsString.h" #include "nsString.h"
@ -41,7 +42,6 @@
#include "nsViewManager.h" #include "nsViewManager.h"
#include "nsVariant.h" #include "nsVariant.h"
#include "nsWidgetsCID.h" #include "nsWidgetsCID.h"
#include "nsIFrameInlines.h"
#include "nsBoxFrame.h" #include "nsBoxFrame.h"
#include "nsIURL.h" #include "nsIURL.h"
#include "nsBoxLayoutState.h" #include "nsBoxLayoutState.h"
@ -61,6 +61,7 @@
#include "mozilla/dom/Event.h" #include "mozilla/dom/Event.h"
#include "mozilla/dom/ScriptSettings.h" #include "mozilla/dom/ScriptSettings.h"
#include "mozilla/dom/ToJSValue.h" #include "mozilla/dom/ToJSValue.h"
#include "mozilla/dom/TreeBoxObject.h"
#include "mozilla/dom/TreeColumnBinding.h" #include "mozilla/dom/TreeColumnBinding.h"
#include <algorithm> #include <algorithm>
#include "ScrollbarActivity.h" #include "ScrollbarActivity.h"
@ -158,8 +159,7 @@ void nsTreeBodyFrame::Init(nsIContent* aContent, nsContainerFrame* aParent,
mIndentation = GetIndentation(); mIndentation = GetIndentation();
mRowHeight = GetRowHeight(); mRowHeight = GetRowHeight();
// Call GetBaseElement so that mTree is assigned. EnsureBoxObject();
GetBaseElement();
if (LookAndFeel::GetInt(LookAndFeel::eIntID_UseOverlayScrollbars) != 0) { if (LookAndFeel::GetInt(LookAndFeel::eIntID_UseOverlayScrollbars) != 0) {
mScrollbarActivity = mScrollbarActivity =
@ -170,15 +170,15 @@ void nsTreeBodyFrame::Init(nsIContent* aContent, nsContainerFrame* aParent,
nsSize nsTreeBodyFrame::GetXULMinSize(nsBoxLayoutState& aBoxLayoutState) { nsSize nsTreeBodyFrame::GetXULMinSize(nsBoxLayoutState& aBoxLayoutState) {
EnsureView(); EnsureView();
RefPtr<XULTreeElement> tree(GetBaseElement()); Element* baseElement = GetBaseElement();
nsSize min(0, 0); nsSize min(0, 0);
int32_t desiredRows; int32_t desiredRows;
if (MOZ_UNLIKELY(!tree)) { if (MOZ_UNLIKELY(!baseElement)) {
desiredRows = 0; desiredRows = 0;
} else { } else {
nsAutoString rows; nsAutoString rows;
tree->GetAttr(kNameSpaceID_None, nsGkAtoms::rows, rows); baseElement->GetAttr(kNameSpaceID_None, nsGkAtoms::rows, rows);
if (!rows.IsEmpty()) { if (!rows.IsEmpty()) {
nsresult err; nsresult err;
desiredRows = rows.ToInteger(&err); desiredRows = rows.ToInteger(&err);
@ -248,8 +248,21 @@ void nsTreeBodyFrame::DestroyFrom(nsIFrame* aDestructRoot,
if (mColumns) mColumns->SetTree(nullptr); if (mColumns) mColumns->SetTree(nullptr);
if (mTree) { // Save off our info into the box object.
mTree->BodyDestroyed(mTopRowIndex); nsCOMPtr<nsPIBoxObject> box(do_QueryInterface(mTreeBoxObject));
if (box) {
if (mTopRowIndex > 0) {
nsAutoString topRowStr;
topRowStr.AssignLiteral("topRow");
nsAutoString topRow;
topRow.AppendInt(mTopRowIndex);
box->SetProperty(topRowStr.get(), topRow.get());
}
// Always null out the cached tree body frame.
box->ClearCachedValues();
mTreeBoxObject = nullptr; // Drop our ref here.
} }
if (mView) { if (mView) {
@ -263,6 +276,33 @@ void nsTreeBodyFrame::DestroyFrom(nsIFrame* aDestructRoot,
nsLeafBoxFrame::DestroyFrom(aDestructRoot, aPostDestroyData); nsLeafBoxFrame::DestroyFrom(aDestructRoot, aPostDestroyData);
} }
void nsTreeBodyFrame::EnsureBoxObject() {
if (!mTreeBoxObject) {
nsIContent* parent = GetBaseElement();
if (parent) {
Document* nsDoc = parent->GetComposedDoc();
if (!nsDoc) // there may be no document, if we're called from Destroy()
return;
ErrorResult ignored;
nsCOMPtr<nsIBoxObject> box =
nsDoc->GetBoxObjectFor(parent->AsElement(), ignored);
// Ensure that we got a native box object.
nsCOMPtr<nsPIBoxObject> pBox = do_QueryInterface(box);
if (pBox) {
nsCOMPtr<nsITreeBoxObject> realTreeBoxObject = do_QueryInterface(pBox);
if (realTreeBoxObject) {
nsTreeBodyFrame* innerTreeBoxObject =
static_cast<dom::TreeBoxObject*>(realTreeBoxObject.get())
->GetCachedTreeBodyFrame();
NS_ENSURE_TRUE_VOID(!innerTreeBoxObject ||
innerTreeBoxObject == this);
mTreeBoxObject = realTreeBoxObject;
}
}
}
}
}
void nsTreeBodyFrame::EnsureView() { void nsTreeBodyFrame::EnsureView() {
if (!mView) { if (!mView) {
if (PresShell()->IsReflowLocked()) { if (PresShell()->IsReflowLocked()) {
@ -272,14 +312,16 @@ void nsTreeBodyFrame::EnsureView() {
} }
return; return;
} }
nsCOMPtr<nsIBoxObject> box = do_QueryInterface(mTreeBoxObject);
if (box) {
AutoWeakFrame weakFrame(this); AutoWeakFrame weakFrame(this);
nsCOMPtr<nsITreeView> treeView;
RefPtr<XULTreeElement> tree = GetBaseElement(); mTreeBoxObject->GetView(getter_AddRefs(treeView));
if (tree) {
nsCOMPtr<nsITreeView> treeView = tree->GetView();
if (treeView && weakFrame.IsAlive()) { if (treeView && weakFrame.IsAlive()) {
int32_t rowIndex = tree->GetCachedTopVisibleRow(); nsString rowStr;
box->GetProperty(u"topRow", getter_Copies(rowStr));
nsresult error;
int32_t rowIndex = rowStr.ToInteger(&error);
// Set our view. // Set our view.
SetView(treeView); SetView(treeView);
@ -289,6 +331,10 @@ void nsTreeBodyFrame::EnsureView() {
// XXX is this optimal if we haven't laid out yet? // XXX is this optimal if we haven't laid out yet?
ScrollToRow(rowIndex); ScrollToRow(rowIndex);
NS_ENSURE_TRUE_VOID(weakFrame.IsAlive()); NS_ENSURE_TRUE_VOID(weakFrame.IsAlive());
// Clear out the property info for the top row, but we always keep the
// view current.
box->RemoveProperty(u"topRow");
} }
} }
} }
@ -338,7 +384,7 @@ bool nsTreeBodyFrame::ReflowFinished() {
if (mTopRowIndex > lastPageTopRow) if (mTopRowIndex > lastPageTopRow)
ScrollToRowInternal(parts, lastPageTopRow); ScrollToRowInternal(parts, lastPageTopRow);
XULTreeElement* treeContent = GetBaseElement(); Element* treeContent = GetBaseElement();
if (treeContent && treeContent->AttrValueIs( if (treeContent && treeContent->AttrValueIs(
kNameSpaceID_None, nsGkAtoms::keepcurrentinview, kNameSpaceID_None, nsGkAtoms::keepcurrentinview,
nsGkAtoms::_true, eCaseMatters)) { nsGkAtoms::_true, eCaseMatters)) {
@ -395,7 +441,7 @@ nsresult nsTreeBodyFrame::SetView(nsITreeView* aView) {
// necessarily entail a full invalidation of the tree. // necessarily entail a full invalidation of the tree.
Invalidate(); Invalidate();
RefPtr<XULTreeElement> treeContent = GetBaseElement(); nsIContent* treeContent = GetBaseElement();
if (treeContent) { if (treeContent) {
#ifdef ACCESSIBILITY #ifdef ACCESSIBILITY
nsAccessibilityService* accService = nsIPresShell::AccService(); nsAccessibilityService* accService = nsIPresShell::AccService();
@ -412,15 +458,15 @@ nsresult nsTreeBodyFrame::SetView(nsITreeView* aView) {
nsCOMPtr<nsITreeSelection> sel; nsCOMPtr<nsITreeSelection> sel;
mView->GetSelection(getter_AddRefs(sel)); mView->GetSelection(getter_AddRefs(sel));
if (sel) { if (sel) {
sel->SetTree(treeContent); sel->SetTree(mTreeBoxObject);
} else { } else {
NS_NewTreeSelection(treeContent, getter_AddRefs(sel)); NS_NewTreeSelection(mTreeBoxObject, getter_AddRefs(sel));
mView->SetSelection(sel); mView->SetSelection(sel);
} }
// View, meet the tree. // View, meet the tree.
AutoWeakFrame weakFrame(this); AutoWeakFrame weakFrame(this);
mView->SetTree(treeContent); mView->SetTree(mTreeBoxObject);
NS_ENSURE_STATE(weakFrame.IsAlive()); NS_ENSURE_STATE(weakFrame.IsAlive());
mView->GetRowCount(&mRowCount); mView->GetRowCount(&mRowCount);
@ -640,8 +686,8 @@ static void FindScrollParts(nsIFrame* aCurrFrame,
nsTreeBodyFrame::ScrollParts nsTreeBodyFrame::GetScrollParts() { nsTreeBodyFrame::ScrollParts nsTreeBodyFrame::GetScrollParts() {
ScrollParts result = {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}; ScrollParts result = {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr};
XULTreeElement* tree = GetBaseElement(); nsIContent* baseElement = GetBaseElement();
nsIFrame* treeFrame = tree ? tree->GetPrimaryFrame() : nullptr; nsIFrame* treeFrame = baseElement ? baseElement->GetPrimaryFrame() : nullptr;
if (treeFrame) { if (treeFrame) {
// The way we do this, searching through the entire frame subtree, is pretty // The way we do this, searching through the entire frame subtree, is pretty
// dumb! We should know where these frames are. // dumb! We should know where these frames are.
@ -1740,10 +1786,10 @@ void nsTreeBodyFrame::PrefillPropertyArray(int32_t aRowIndex,
else else
mScratchArray.AppendElement((nsStaticAtom*)nsGkAtoms::even); mScratchArray.AppendElement((nsStaticAtom*)nsGkAtoms::even);
XULTreeElement* tree = GetBaseElement(); Element* baseContent = GetBaseElement();
if (tree && tree->HasAttr(kNameSpaceID_None, nsGkAtoms::editing)) { if (baseContent &&
baseContent->HasAttr(kNameSpaceID_None, nsGkAtoms::editing))
mScratchArray.AppendElement((nsStaticAtom*)nsGkAtoms::editing); mScratchArray.AppendElement((nsStaticAtom*)nsGkAtoms::editing);
}
// multiple columns // multiple columns
if (mColumns->GetColumnAt(1)) if (mColumns->GetColumnAt(1))
@ -2531,8 +2577,8 @@ void nsTreeBodyFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
aLists.Content()->AppendToTop(item); aLists.Content()->AppendToTop(item);
#ifdef XP_MACOSX #ifdef XP_MACOSX
XULTreeElement* tree = GetBaseElement(); nsIContent* baseElement = GetBaseElement();
nsIFrame* treeFrame = tree ? tree->GetPrimaryFrame() : nullptr; nsIFrame* treeFrame = baseElement ? baseElement->GetPrimaryFrame() : nullptr;
nsCOMPtr<nsITreeSelection> selection; nsCOMPtr<nsITreeSelection> selection;
mView->GetSelection(getter_AddRefs(selection)); mView->GetSelection(getter_AddRefs(selection));
nsITheme* theme = PresContext()->GetTheme(); nsITheme* theme = PresContext()->GetTheme();
@ -3914,21 +3960,18 @@ ComputedStyle* nsTreeBodyFrame::GetPseudoComputedStyle(
aPseudoElement, mScratchArray); aPseudoElement, mScratchArray);
} }
XULTreeElement* nsTreeBodyFrame::GetBaseElement() { Element* nsTreeBodyFrame::GetBaseElement() {
if (!mTree) {
nsIFrame* parent = GetParent(); nsIFrame* parent = GetParent();
while (parent) { while (parent) {
nsIContent* content = parent->GetContent(); nsIContent* content = parent->GetContent();
if (content && content->IsXULElement(nsGkAtoms::tree)) { if (content && content->IsXULElement(nsGkAtoms::tree)) {
mTree = XULTreeElement::FromNodeOrNull(content->AsElement()); return content->AsElement();
break;
} }
parent = parent->GetInFlowParent(); parent = parent->GetParent();
}
} }
return mTree; return nullptr;
} }
nsresult nsTreeBodyFrame::ClearStyleAndImageCaches() { nsresult nsTreeBodyFrame::ClearStyleAndImageCaches() {
@ -4197,10 +4240,10 @@ static void InitCustomEvent(CustomEvent* aEvent, const nsAString& aType,
} }
void nsTreeBodyFrame::FireRowCountChangedEvent(int32_t aIndex, int32_t aCount) { void nsTreeBodyFrame::FireRowCountChangedEvent(int32_t aIndex, int32_t aCount) {
RefPtr<XULTreeElement> tree(GetBaseElement()); nsCOMPtr<nsIContent> content(GetBaseElement());
if (!tree) return; if (!content) return;
RefPtr<Document> doc = tree->OwnerDoc(); nsCOMPtr<Document> doc = content->OwnerDoc();
MOZ_ASSERT(doc); MOZ_ASSERT(doc);
RefPtr<Event> event = doc->CreateEvent(NS_LITERAL_STRING("customevent"), RefPtr<Event> event = doc->CreateEvent(NS_LITERAL_STRING("customevent"),
@ -4228,7 +4271,7 @@ void nsTreeBodyFrame::FireRowCountChangedEvent(int32_t aIndex, int32_t aCount) {
event->SetTrusted(true); event->SetTrusted(true);
RefPtr<AsyncEventDispatcher> asyncDispatcher = RefPtr<AsyncEventDispatcher> asyncDispatcher =
new AsyncEventDispatcher(tree, event); new AsyncEventDispatcher(content, event);
asyncDispatcher->PostDOMEvent(); asyncDispatcher->PostDOMEvent();
} }
@ -4236,10 +4279,10 @@ void nsTreeBodyFrame::FireInvalidateEvent(int32_t aStartRowIdx,
int32_t aEndRowIdx, int32_t aEndRowIdx,
nsTreeColumn* aStartCol, nsTreeColumn* aStartCol,
nsTreeColumn* aEndCol) { nsTreeColumn* aEndCol) {
RefPtr<XULTreeElement> tree(GetBaseElement()); nsCOMPtr<nsIContent> content(GetBaseElement());
if (!tree) return; if (!content) return;
RefPtr<Document> doc = tree->OwnerDoc(); nsCOMPtr<Document> doc = content->OwnerDoc();
RefPtr<Event> event = doc->CreateEvent(NS_LITERAL_STRING("customevent"), RefPtr<Event> event = doc->CreateEvent(NS_LITERAL_STRING("customevent"),
CallerType::System, IgnoreErrors()); CallerType::System, IgnoreErrors());
@ -4279,7 +4322,7 @@ void nsTreeBodyFrame::FireInvalidateEvent(int32_t aStartRowIdx,
event->SetTrusted(true); event->SetTrusted(true);
RefPtr<AsyncEventDispatcher> asyncDispatcher = RefPtr<AsyncEventDispatcher> asyncDispatcher =
new AsyncEventDispatcher(tree, event); new AsyncEventDispatcher(content, event);
asyncDispatcher->PostDOMEvent(); asyncDispatcher->PostDOMEvent();
} }
#endif #endif

Просмотреть файл

@ -184,8 +184,10 @@ class nsTreeBodyFrame final : public nsLeafBoxFrame,
const nsRect& aDirtyRect, nsPoint aPt, const nsRect& aDirtyRect, nsPoint aPt,
nsDisplayListBuilder* aBuilder); nsDisplayListBuilder* aBuilder);
nsITreeBoxObject* GetTreeBoxObject() const { return mTreeBoxObject; }
// Get the base element, <tree> // Get the base element, <tree>
mozilla::dom::XULTreeElement* GetBaseElement(); mozilla::dom::Element* GetBaseElement();
bool GetVerticalOverflow() const { return mVerticalOverflow; } bool GetVerticalOverflow() const { return mVerticalOverflow; }
bool GetHorizontalOverflow() const { return mHorizontalOverflow; } bool GetHorizontalOverflow() const { return mHorizontalOverflow; }
@ -369,6 +371,9 @@ class nsTreeBodyFrame final : public nsLeafBoxFrame,
// Convert client pixels into appunits in our coordinate space. // Convert client pixels into appunits in our coordinate space.
nsPoint AdjustClientCoordsToBoxCoordSpace(int32_t aX, int32_t aY); nsPoint AdjustClientCoordsToBoxCoordSpace(int32_t aX, int32_t aY);
// Cache the box object
void EnsureBoxObject();
void EnsureView(); void EnsureView();
nsresult GetCellWidth(int32_t aRow, nsTreeColumn* aCol, nsresult GetCellWidth(int32_t aRow, nsTreeColumn* aCol,
@ -525,8 +530,8 @@ class nsTreeBodyFrame final : public nsLeafBoxFrame,
RefPtr<ScrollbarActivity> mScrollbarActivity; RefPtr<ScrollbarActivity> mScrollbarActivity;
// The <tree> element containing this treebody. // The cached box object parent.
RefPtr<mozilla::dom::XULTreeElement> mTree; nsCOMPtr<nsITreeBoxObject> mTreeBoxObject;
// Cached column information. // Cached column information.
RefPtr<nsTreeColumns> mColumns; RefPtr<nsTreeColumns> mColumns;

Просмотреть файл

@ -10,7 +10,9 @@
#include "nsIContent.h" #include "nsIContent.h"
#include "mozilla/ComputedStyle.h" #include "mozilla/ComputedStyle.h"
#include "nsNameSpaceManager.h" #include "nsNameSpaceManager.h"
#include "nsIBoxObject.h"
#include "mozilla/ErrorResult.h" #include "mozilla/ErrorResult.h"
#include "mozilla/dom/TreeBoxObject.h"
#include "nsTreeColumns.h" #include "nsTreeColumns.h"
#include "nsDisplayList.h" #include "nsDisplayList.h"
#include "nsTreeBodyFrame.h" #include "nsTreeBodyFrame.h"
@ -137,27 +139,43 @@ void nsTreeColFrame::SetXULBounds(nsBoxLayoutState& aBoxLayoutState,
nsBoxFrame::SetXULBounds(aBoxLayoutState, aRect, aRemoveOverflowArea); nsBoxFrame::SetXULBounds(aBoxLayoutState, aRect, aRemoveOverflowArea);
if (mRect.width != oldWidth) { if (mRect.width != oldWidth) {
RefPtr<XULTreeElement> tree = GetTree(); nsITreeBoxObject* treeBoxObject = GetTreeBoxObject();
if (tree) { if (treeBoxObject) {
tree->Invalidate(); treeBoxObject->Invalidate();
} }
} }
} }
XULTreeElement* nsTreeColFrame::GetTree() { nsITreeBoxObject* nsTreeColFrame::GetTreeBoxObject() {
nsITreeBoxObject* result = nullptr;
nsIContent* parent = mContent->GetParent(); nsIContent* parent = mContent->GetParent();
return parent ? XULTreeElement::FromNodeOrNull(parent->GetParent()) : nullptr; if (parent) {
nsIContent* grandParent = parent->GetParent();
RefPtr<nsXULElement> treeElement =
nsXULElement::FromNodeOrNull(grandParent);
if (treeElement) {
nsCOMPtr<nsIBoxObject> boxObject =
treeElement->GetBoxObject(IgnoreErrors());
nsCOMPtr<nsITreeBoxObject> treeBoxObject = do_QueryInterface(boxObject);
result = treeBoxObject.get();
}
}
return result;
} }
void nsTreeColFrame::InvalidateColumns(bool aCanWalkFrameTree) { void nsTreeColFrame::InvalidateColumns(bool aCanWalkFrameTree) {
RefPtr<XULTreeElement> tree = GetTree(); nsITreeBoxObject* treeBoxObject = GetTreeBoxObject();
if (tree) { if (treeBoxObject) {
RefPtr<nsTreeColumns> columns; RefPtr<nsTreeColumns> columns;
if (aCanWalkFrameTree) { if (aCanWalkFrameTree) {
columns = tree->GetColumns(); treeBoxObject->GetColumns(getter_AddRefs(columns));
} else { } else {
nsTreeBodyFrame* body = tree->GetCachedTreeBodyFrame(); nsTreeBodyFrame* body =
static_cast<mozilla::dom::TreeBoxObject*>(treeBoxObject)
->GetCachedTreeBodyFrame();
if (body) { if (body) {
columns = body->Columns(); columns = body->Columns();
} }

Просмотреть файл

@ -8,11 +8,7 @@
#include "mozilla/ComputedStyle.h" #include "mozilla/ComputedStyle.h"
#include "nsBoxFrame.h" #include "nsBoxFrame.h"
namespace mozilla { class nsITreeBoxObject;
namespace dom {
class XULTreeElement;
}
} // namespace mozilla
nsIFrame* NS_NewTreeColFrame(nsIPresShell* aPresShell, nsIFrame* NS_NewTreeColFrame(nsIPresShell* aPresShell,
mozilla::ComputedStyle* aStyle); mozilla::ComputedStyle* aStyle);
@ -47,9 +43,9 @@ class nsTreeColFrame final : public nsBoxFrame {
virtual ~nsTreeColFrame(); virtual ~nsTreeColFrame();
/** /**
* @return the tree that this column belongs to, or nullptr. * @return the tree box object of the tree this column belongs to, or nullptr.
*/ */
mozilla::dom::XULTreeElement* GetTree(); nsITreeBoxObject* GetTreeBoxObject();
/** /**
* Helper method that gets the TreeColumns object this column belongs to * Helper method that gets the TreeColumns object this column belongs to

Просмотреть файл

@ -13,6 +13,7 @@
#include "nsContentUtils.h" #include "nsContentUtils.h"
#include "nsTreeBodyFrame.h" #include "nsTreeBodyFrame.h"
#include "mozilla/dom/Element.h" #include "mozilla/dom/Element.h"
#include "mozilla/dom/TreeBoxObject.h"
#include "mozilla/dom/TreeColumnBinding.h" #include "mozilla/dom/TreeColumnBinding.h"
#include "mozilla/dom/TreeColumnsBinding.h" #include "mozilla/dom/TreeColumnsBinding.h"
@ -259,12 +260,10 @@ nsIContent* nsTreeColumns::GetParentObject() const {
return dom::TreeColumns_Binding::Wrap(aCx, this, aGivenProto); return dom::TreeColumns_Binding::Wrap(aCx, this, aGivenProto);
} }
XULTreeElement* nsTreeColumns::GetTree() const { dom::TreeBoxObject* nsTreeColumns::GetTree() const {
if (!mTree) { return mTree ? static_cast<mozilla::dom::TreeBoxObject*>(
return nullptr; mTree->GetTreeBoxObject())
} : nullptr;
return XULTreeElement::FromNodeOrNull(mTree->GetBaseElement());
} }
uint32_t nsTreeColumns::Count() { uint32_t nsTreeColumns::Count() {
@ -445,8 +444,6 @@ nsTreeColumn* nsTreeColumns::GetPrimaryColumn() {
void nsTreeColumns::EnsureColumns() { void nsTreeColumns::EnsureColumns() {
if (mTree && !mFirstColumn) { if (mTree && !mFirstColumn) {
nsIContent* treeContent = mTree->GetBaseElement(); nsIContent* treeContent = mTree->GetBaseElement();
if (!treeContent) return;
nsIContent* colsContent = nsIContent* colsContent =
nsTreeUtils::GetDescendantChild(treeContent, nsGkAtoms::treecols); nsTreeUtils::GetDescendantChild(treeContent, nsGkAtoms::treecols);
if (!colsContent) return; if (!colsContent) return;

Просмотреть файл

@ -7,6 +7,7 @@
#ifndef nsTreeColumns_h__ #ifndef nsTreeColumns_h__
#define nsTreeColumns_h__ #define nsTreeColumns_h__
#include "nsITreeBoxObject.h"
#include "mozilla/Attributes.h" #include "mozilla/Attributes.h"
#include "mozilla/RefPtr.h" #include "mozilla/RefPtr.h"
#include "nsCoord.h" #include "nsCoord.h"
@ -26,7 +27,7 @@ namespace mozilla {
class ErrorResult; class ErrorResult;
namespace dom { namespace dom {
class Element; class Element;
class XULTreeElement; class TreeBoxObject;
} // namespace dom } // namespace dom
} // namespace mozilla } // namespace mozilla
@ -161,7 +162,7 @@ class nsTreeColumns final : public nsISupports, public nsWrapperCache {
JS::Handle<JSObject*> aGivenProto) override; JS::Handle<JSObject*> aGivenProto) override;
// WebIDL // WebIDL
mozilla::dom::XULTreeElement* GetTree() const; mozilla::dom::TreeBoxObject* GetTree() const;
uint32_t Count(); uint32_t Count();
uint32_t Length() { return Count(); } uint32_t Length() { return Count(); }

Просмотреть файл

@ -6,6 +6,7 @@
#include "nsNameSpaceManager.h" #include "nsNameSpaceManager.h"
#include "nsGkAtoms.h" #include "nsGkAtoms.h"
#include "nsIBoxObject.h"
#include "nsTreeUtils.h" #include "nsTreeUtils.h"
#include "nsTreeContentView.h" #include "nsTreeContentView.h"
#include "ChildIterator.h" #include "ChildIterator.h"
@ -15,6 +16,7 @@
#include "nsTreeColumns.h" #include "nsTreeColumns.h"
#include "mozilla/ErrorResult.h" #include "mozilla/ErrorResult.h"
#include "mozilla/dom/Element.h" #include "mozilla/dom/Element.h"
#include "mozilla/dom/TreeBoxObject.h"
#include "mozilla/dom/TreeContentViewBinding.h" #include "mozilla/dom/TreeContentViewBinding.h"
#include "nsServiceManagerUtils.h" #include "nsServiceManagerUtils.h"
#include "mozilla/dom/Document.h" #include "mozilla/dom/Document.h"
@ -80,7 +82,10 @@ class Row {
// document's observer list. // document's observer list.
nsTreeContentView::nsTreeContentView(void) nsTreeContentView::nsTreeContentView(void)
: mTree(nullptr), mSelection(nullptr), mDocument(nullptr) {} : mBoxObject(nullptr),
mSelection(nullptr),
mRoot(nullptr),
mDocument(nullptr) {}
nsTreeContentView::~nsTreeContentView(void) { nsTreeContentView::~nsTreeContentView(void) {
// Remove ourselves from mDocument's observers. // Remove ourselves from mDocument's observers.
@ -94,8 +99,8 @@ nsresult NS_NewTreeContentView(nsITreeView** aResult) {
return NS_OK; return NS_OK;
} }
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(nsTreeContentView, mTree, mSelection, NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(nsTreeContentView, mBoxObject, mSelection,
mBody) mRoot, mBody)
NS_IMPL_CYCLE_COLLECTING_ADDREF(nsTreeContentView) NS_IMPL_CYCLE_COLLECTING_ADDREF(nsTreeContentView)
NS_IMPL_CYCLE_COLLECTING_RELEASE(nsTreeContentView) NS_IMPL_CYCLE_COLLECTING_RELEASE(nsTreeContentView)
@ -113,7 +118,7 @@ JSObject* nsTreeContentView::WrapObject(JSContext* aCx,
return TreeContentView_Binding::Wrap(aCx, this, aGivenProto); return TreeContentView_Binding::Wrap(aCx, this, aGivenProto);
} }
nsISupports* nsTreeContentView::GetParentObject() { return mTree; } nsISupports* nsTreeContentView::GetParentObject() { return mBoxObject; }
NS_IMETHODIMP NS_IMETHODIMP
nsTreeContentView::GetRowCount(int32_t* aRowCount) { nsTreeContentView::GetRowCount(int32_t* aRowCount) {
@ -500,25 +505,43 @@ nsTreeContentView::GetCellText(int32_t aRow, nsTreeColumn* aCol,
return rv.StealNSResult(); return rv.StealNSResult();
} }
void nsTreeContentView::SetTree(XULTreeElement* aTree, ErrorResult& aError) { void nsTreeContentView::SetTree(TreeBoxObject* aTree, ErrorResult& aError) {
aError = SetTree(aTree); aError = SetTree(aTree);
} }
NS_IMETHODIMP NS_IMETHODIMP
nsTreeContentView::SetTree(XULTreeElement* aTree) { nsTreeContentView::SetTree(nsITreeBoxObject* aTree) {
ClearRows(); ClearRows();
mTree = aTree; mBoxObject = aTree;
MOZ_ASSERT(!mRoot, "mRoot should have been cleared out by ClearRows");
if (aTree) { if (aTree) {
// Get our root element
nsCOMPtr<nsIBoxObject> boxObject = do_QueryInterface(mBoxObject);
if (!boxObject) {
mBoxObject = nullptr;
return NS_ERROR_INVALID_ARG;
}
{ // Scope for element
RefPtr<dom::Element> element;
boxObject->GetElement(getter_AddRefs(element));
mRoot = element.forget();
NS_ENSURE_STATE(mRoot);
}
// Add ourselves to document's observers. // Add ourselves to document's observers.
Document* document = mTree->GetComposedDoc(); Document* document = mRoot->GetComposedDoc();
if (document) { if (document) {
document->AddObserver(this); document->AddObserver(this);
mDocument = document; mDocument = document;
} }
RefPtr<dom::Element> bodyElement = mTree->GetTreeBody(); RefPtr<dom::Element> bodyElement;
mBoxObject->GetTreeBody(getter_AddRefs(bodyElement));
if (bodyElement) { if (bodyElement) {
mBody = bodyElement.forget(); mBody = bodyElement.forget();
int32_t index = 0; int32_t index = 0;
@ -556,7 +579,7 @@ nsTreeContentView::ToggleOpenState(int32_t aIndex) {
void nsTreeContentView::CycleHeader(nsTreeColumn& aColumn, void nsTreeContentView::CycleHeader(nsTreeColumn& aColumn,
ErrorResult& aError) { ErrorResult& aError) {
if (!mTree) return; if (!mRoot) return;
RefPtr<Element> column = aColumn.Element(); RefPtr<Element> column = aColumn.Element();
nsAutoString sort; nsAutoString sort;
@ -583,7 +606,7 @@ void nsTreeContentView::CycleHeader(nsTreeColumn& aColumn,
sortdirection.Append(' '); sortdirection.Append(' ');
sortdirection += hints; sortdirection += hints;
XULWidgetSort(mTree, sort, sortdirection); XULWidgetSort(mRoot, sort, sortdirection);
} }
} }
@ -726,9 +749,10 @@ void nsTreeContentView::AttributeChanged(dom::Element* aElement,
// Make sure this notification concerns us. // Make sure this notification concerns us.
// First check the tag to see if it's one that we care about. // First check the tag to see if it's one that we care about.
if (aElement == mTree || aElement == mBody) {
mTree->ClearStyleAndImageCaches(); if (mBoxObject && (aElement == mRoot || aElement == mBody)) {
mTree->Invalidate(); mBoxObject->ClearStyleAndImageCaches();
mBoxObject->Invalidate();
} }
// We don't consider non-XUL nodes. // We don't consider non-XUL nodes.
@ -763,7 +787,7 @@ void nsTreeContentView::AttributeChanged(dom::Element* aElement,
if (hidden && index >= 0) { if (hidden && index >= 0) {
// Hide this row along with its children. // Hide this row along with its children.
int32_t count = RemoveRow(index); int32_t count = RemoveRow(index);
if (mTree) mTree->RowCountChanged(index, -count); if (mBoxObject) mBoxObject->RowCountChanged(index, -count);
} else if (!hidden && index < 0) { } else if (!hidden && index < 0) {
// Show this row along with its children. // Show this row along with its children.
nsCOMPtr<nsIContent> parent = aElement->GetParent(); nsCOMPtr<nsIContent> parent = aElement->GetParent();
@ -777,11 +801,12 @@ void nsTreeContentView::AttributeChanged(dom::Element* aElement,
if (aElement->IsXULElement(nsGkAtoms::treecol)) { if (aElement->IsXULElement(nsGkAtoms::treecol)) {
if (aAttribute == nsGkAtoms::properties) { if (aAttribute == nsGkAtoms::properties) {
if (mTree) { if (mBoxObject) {
RefPtr<nsTreeColumns> cols = mTree->GetColumns(); RefPtr<nsTreeColumns> cols;
mBoxObject->GetColumns(getter_AddRefs(cols));
if (cols) { if (cols) {
RefPtr<nsTreeColumn> col = cols->GetColumnFor(aElement); RefPtr<nsTreeColumn> col = cols->GetColumnFor(aElement);
mTree->InvalidateColumn(col); mBoxObject->InvalidateColumn(col);
} }
} }
} }
@ -794,7 +819,7 @@ void nsTreeContentView::AttributeChanged(dom::Element* aElement,
aElement->AttrValueIs(kNameSpaceID_None, nsGkAtoms::container, aElement->AttrValueIs(kNameSpaceID_None, nsGkAtoms::container,
nsGkAtoms::_true, eCaseMatters); nsGkAtoms::_true, eCaseMatters);
row->SetContainer(isContainer); row->SetContainer(isContainer);
if (mTree) mTree->InvalidateRow(index); if (mBoxObject) mBoxObject->InvalidateRow(index);
} else if (aAttribute == nsGkAtoms::open) { } else if (aAttribute == nsGkAtoms::open) {
bool isOpen = aElement->AttrValueIs(kNameSpaceID_None, nsGkAtoms::open, bool isOpen = aElement->AttrValueIs(kNameSpaceID_None, nsGkAtoms::open,
nsGkAtoms::_true, eCaseMatters); nsGkAtoms::_true, eCaseMatters);
@ -808,14 +833,14 @@ void nsTreeContentView::AttributeChanged(dom::Element* aElement,
aElement->AttrValueIs(kNameSpaceID_None, nsGkAtoms::empty, aElement->AttrValueIs(kNameSpaceID_None, nsGkAtoms::empty,
nsGkAtoms::_true, eCaseMatters); nsGkAtoms::_true, eCaseMatters);
row->SetEmpty(isEmpty); row->SetEmpty(isEmpty);
if (mTree) mTree->InvalidateRow(index); if (mBoxObject) mBoxObject->InvalidateRow(index);
} }
} }
} else if (aElement->IsXULElement(nsGkAtoms::treeseparator)) { } else if (aElement->IsXULElement(nsGkAtoms::treeseparator)) {
int32_t index = FindContent(aElement); int32_t index = FindContent(aElement);
if (index >= 0) { if (index >= 0) {
if (aAttribute == nsGkAtoms::properties && mTree) { if (aAttribute == nsGkAtoms::properties && mBoxObject) {
mTree->InvalidateRow(index); mBoxObject->InvalidateRow(index);
} }
} }
} else if (aElement->IsXULElement(nsGkAtoms::treerow)) { } else if (aElement->IsXULElement(nsGkAtoms::treerow)) {
@ -823,8 +848,8 @@ void nsTreeContentView::AttributeChanged(dom::Element* aElement,
nsCOMPtr<nsIContent> parent = aElement->GetParent(); nsCOMPtr<nsIContent> parent = aElement->GetParent();
if (parent) { if (parent) {
int32_t index = FindContent(parent); int32_t index = FindContent(parent);
if (index >= 0 && mTree) { if (index >= 0 && mBoxObject) {
mTree->InvalidateRow(index); mBoxObject->InvalidateRow(index);
} }
} }
} }
@ -837,9 +862,9 @@ void nsTreeContentView::AttributeChanged(dom::Element* aElement,
nsCOMPtr<nsIContent> grandParent = parent->GetParent(); nsCOMPtr<nsIContent> grandParent = parent->GetParent();
if (grandParent && grandParent->IsXULElement()) { if (grandParent && grandParent->IsXULElement()) {
int32_t index = FindContent(grandParent); int32_t index = FindContent(grandParent);
if (index >= 0 && mTree) { if (index >= 0 && mBoxObject) {
// XXX Should we make an effort to invalidate only cell ? // XXX Should we make an effort to invalidate only cell ?
mTree->InvalidateRow(index); mBoxObject->InvalidateRow(index);
} }
} }
} }
@ -887,10 +912,10 @@ void nsTreeContentView::ContentInserted(nsIContent* aChild) {
if (index >= 0) { if (index >= 0) {
Row* row = mRows[index].get(); Row* row = mRows[index].get();
row->SetEmpty(false); row->SetEmpty(false);
if (mTree) mTree->InvalidateRow(index); if (mBoxObject) mBoxObject->InvalidateRow(index);
if (row->IsContainer() && row->IsOpen()) { if (row->IsContainer() && row->IsOpen()) {
int32_t count = EnsureSubtree(index); int32_t count = EnsureSubtree(index);
if (mTree) mTree->RowCountChanged(index + 1, count); if (mBoxObject) mBoxObject->RowCountChanged(index + 1, count);
} }
} }
} else if (aChild->IsAnyOfXULElements(nsGkAtoms::treeitem, } else if (aChild->IsAnyOfXULElements(nsGkAtoms::treeitem,
@ -898,12 +923,12 @@ void nsTreeContentView::ContentInserted(nsIContent* aChild) {
InsertRowFor(container, aChild); InsertRowFor(container, aChild);
} else if (aChild->IsXULElement(nsGkAtoms::treerow)) { } else if (aChild->IsXULElement(nsGkAtoms::treerow)) {
int32_t index = FindContent(container); int32_t index = FindContent(container);
if (index >= 0 && mTree) mTree->InvalidateRow(index); if (index >= 0 && mBoxObject) mBoxObject->InvalidateRow(index);
} else if (aChild->IsXULElement(nsGkAtoms::treecell)) { } else if (aChild->IsXULElement(nsGkAtoms::treecell)) {
nsCOMPtr<nsIContent> parent = container->GetParent(); nsCOMPtr<nsIContent> parent = container->GetParent();
if (parent) { if (parent) {
int32_t index = FindContent(parent); int32_t index = FindContent(parent);
if (index >= 0 && mTree) mTree->InvalidateRow(index); if (index >= 0 && mBoxObject) mBoxObject->InvalidateRow(index);
} }
} }
} }
@ -944,9 +969,9 @@ void nsTreeContentView::ContentRemoved(nsIContent* aChild,
row->SetEmpty(true); row->SetEmpty(true);
int32_t count = RemoveSubtree(index); int32_t count = RemoveSubtree(index);
// Invalidate also the row to update twisty. // Invalidate also the row to update twisty.
if (mTree) { if (mBoxObject) {
mTree->InvalidateRow(index); mBoxObject->InvalidateRow(index);
mTree->RowCountChanged(index + 1, -count); mBoxObject->RowCountChanged(index + 1, -count);
} }
} }
} else if (aChild->IsAnyOfXULElements(nsGkAtoms::treeitem, } else if (aChild->IsAnyOfXULElements(nsGkAtoms::treeitem,
@ -954,16 +979,16 @@ void nsTreeContentView::ContentRemoved(nsIContent* aChild,
int32_t index = FindContent(aChild); int32_t index = FindContent(aChild);
if (index >= 0) { if (index >= 0) {
int32_t count = RemoveRow(index); int32_t count = RemoveRow(index);
if (mTree) mTree->RowCountChanged(index, -count); if (mBoxObject) mBoxObject->RowCountChanged(index, -count);
} }
} else if (aChild->IsXULElement(nsGkAtoms::treerow)) { } else if (aChild->IsXULElement(nsGkAtoms::treerow)) {
int32_t index = FindContent(container); int32_t index = FindContent(container);
if (index >= 0 && mTree) mTree->InvalidateRow(index); if (index >= 0 && mBoxObject) mBoxObject->InvalidateRow(index);
} else if (aChild->IsXULElement(nsGkAtoms::treecell)) { } else if (aChild->IsXULElement(nsGkAtoms::treecell)) {
nsCOMPtr<nsIContent> parent = container->GetParent(); nsCOMPtr<nsIContent> parent = container->GetParent();
if (parent) { if (parent) {
int32_t index = FindContent(parent); int32_t index = FindContent(parent);
if (index >= 0 && mTree) mTree->InvalidateRow(index); if (index >= 0 && mBoxObject) mBoxObject->InvalidateRow(index);
} }
} }
} }
@ -1150,7 +1175,8 @@ void nsTreeContentView::InsertRowFor(nsIContent* aParent, nsIContent* aChild) {
GetIndexInSubtree(aParent, aChild, &index); GetIndexInSubtree(aParent, aChild, &index);
int32_t count = InsertRow(grandParentIndex, index, aChild); int32_t count = InsertRow(grandParentIndex, index, aChild);
if (mTree) mTree->RowCountChanged(grandParentIndex + index + 1, count); if (mBoxObject)
mBoxObject->RowCountChanged(grandParentIndex + index + 1, count);
} }
} }
@ -1195,6 +1221,7 @@ int32_t nsTreeContentView::RemoveRow(int32_t aIndex) {
void nsTreeContentView::ClearRows() { void nsTreeContentView::ClearRows() {
mRows.Clear(); mRows.Clear();
mRoot = nullptr;
mBody = nullptr; mBody = nullptr;
// Remove ourselves from mDocument's observers. // Remove ourselves from mDocument's observers.
if (mDocument) { if (mDocument) {
@ -1208,9 +1235,9 @@ void nsTreeContentView::OpenContainer(int32_t aIndex) {
row->SetOpen(true); row->SetOpen(true);
int32_t count = EnsureSubtree(aIndex); int32_t count = EnsureSubtree(aIndex);
if (mTree) { if (mBoxObject) {
mTree->InvalidateRow(aIndex); mBoxObject->InvalidateRow(aIndex);
mTree->RowCountChanged(aIndex + 1, count); mBoxObject->RowCountChanged(aIndex + 1, count);
} }
} }
@ -1219,9 +1246,9 @@ void nsTreeContentView::CloseContainer(int32_t aIndex) {
row->SetOpen(false); row->SetOpen(false);
int32_t count = RemoveSubtree(aIndex); int32_t count = RemoveSubtree(aIndex);
if (mTree) { if (mBoxObject) {
mTree->InvalidateRow(aIndex); mBoxObject->InvalidateRow(aIndex);
mTree->RowCountChanged(aIndex + 1, -count); mBoxObject->RowCountChanged(aIndex + 1, -count);
} }
} }

Просмотреть файл

@ -10,6 +10,7 @@
#include "nsCycleCollectionParticipant.h" #include "nsCycleCollectionParticipant.h"
#include "nsTArray.h" #include "nsTArray.h"
#include "nsStubDocumentObserver.h" #include "nsStubDocumentObserver.h"
#include "nsITreeBoxObject.h"
#include "nsITreeView.h" #include "nsITreeView.h"
#include "nsITreeSelection.h" #include "nsITreeSelection.h"
#include "mozilla/Attributes.h" #include "mozilla/Attributes.h"
@ -24,7 +25,7 @@ namespace dom {
class DataTransfer; class DataTransfer;
class Document; class Document;
class Element; class Element;
class XULTreeElement; class TreeBoxObject;
} // namespace dom } // namespace dom
} // namespace mozilla } // namespace mozilla
@ -75,7 +76,7 @@ class nsTreeContentView final : public nsITreeView,
mozilla::ErrorResult& aError); mozilla::ErrorResult& aError);
void GetCellText(int32_t aRow, nsTreeColumn& aColumn, nsAString& aText, void GetCellText(int32_t aRow, nsTreeColumn& aColumn, nsAString& aText,
mozilla::ErrorResult& aError); mozilla::ErrorResult& aError);
void SetTree(mozilla::dom::XULTreeElement* aTree, void SetTree(mozilla::dom::TreeBoxObject* aTree,
mozilla::ErrorResult& aError); mozilla::ErrorResult& aError);
void ToggleOpenState(int32_t aRow, mozilla::ErrorResult& aError); void ToggleOpenState(int32_t aRow, mozilla::ErrorResult& aError);
void CycleHeader(nsTreeColumn& aColumn, mozilla::ErrorResult& aError); void CycleHeader(nsTreeColumn& aColumn, mozilla::ErrorResult& aError);
@ -155,8 +156,9 @@ class nsTreeContentView final : public nsITreeView,
private: private:
bool IsValidRowIndex(int32_t aRowIndex); bool IsValidRowIndex(int32_t aRowIndex);
RefPtr<mozilla::dom::XULTreeElement> mTree; nsCOMPtr<nsITreeBoxObject> mBoxObject;
nsCOMPtr<nsITreeSelection> mSelection; nsCOMPtr<nsITreeSelection> mSelection;
nsCOMPtr<Element> mRoot;
nsCOMPtr<nsIContent> mBody; nsCOMPtr<nsIContent> mBody;
mozilla::dom::Document* mDocument; // WEAK mozilla::dom::Document* mDocument; // WEAK
nsTArray<mozilla::UniquePtr<Row>> mRows; nsTArray<mozilla::UniquePtr<Row>> mRows;

Просмотреть файл

@ -5,7 +5,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "nsTreeImageListener.h" #include "nsTreeImageListener.h"
#include "XULTreeElement.h" #include "nsITreeBoxObject.h"
#include "imgIRequest.h" #include "imgIRequest.h"
#include "imgIContainer.h" #include "imgIContainer.h"
#include "nsIContent.h" #include "nsIContent.h"
@ -80,8 +80,7 @@ void nsTreeImageListener::Invalidate() {
// this image. // this image.
for (int32_t i = currArea->GetMin(); i <= currArea->GetMax(); ++i) { for (int32_t i = currArea->GetMin(); i <= currArea->GetMax(); ++i) {
if (mTreeFrame) { if (mTreeFrame) {
RefPtr<XULTreeElement> tree = nsITreeBoxObject* tree = mTreeFrame->GetTreeBoxObject();
XULTreeElement::FromNodeOrNull(mTreeFrame->GetBaseElement());
if (tree) { if (tree) {
tree->InvalidateCell(i, currArea->GetCol()); tree->InvalidateCell(i, currArea->GetCol());
} }

Просмотреть файл

@ -9,7 +9,7 @@
#include "nsCOMPtr.h" #include "nsCOMPtr.h"
#include "nsTreeSelection.h" #include "nsTreeSelection.h"
#include "nsIBoxObject.h" #include "nsIBoxObject.h"
#include "XULTreeElement.h" #include "nsITreeBoxObject.h"
#include "nsITreeView.h" #include "nsITreeView.h"
#include "nsString.h" #include "nsString.h"
#include "nsIContent.h" #include "nsIContent.h"
@ -177,10 +177,10 @@ struct nsTreeRange {
} }
} }
static void InvalidateRanges(XULTreeElement* aTree, static void InvalidateRanges(nsITreeBoxObject* aTree,
nsTArray<int32_t>& aRanges) { nsTArray<int32_t>& aRanges) {
if (aTree) { if (aTree) {
RefPtr<nsXULElement> tree = aTree; nsCOMPtr<nsITreeBoxObject> tree = aTree;
for (uint32_t i = 0; i < aRanges.Length(); i += 2) { for (uint32_t i = 0; i < aRanges.Length(); i += 2) {
aTree->InvalidateRange(aRanges[i], aRanges[i + 1]); aTree->InvalidateRange(aRanges[i], aRanges[i + 1]);
} }
@ -226,7 +226,7 @@ struct nsTreeRange {
} }
}; };
nsTreeSelection::nsTreeSelection(XULTreeElement* aTree) nsTreeSelection::nsTreeSelection(nsITreeBoxObject* aTree)
: mTree(aTree), : mTree(aTree),
mSuppressed(false), mSuppressed(false),
mCurrentIndex(-1), mCurrentIndex(-1),
@ -249,27 +249,33 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsTreeSelection)
NS_INTERFACE_MAP_ENTRY(nsISupports) NS_INTERFACE_MAP_ENTRY(nsISupports)
NS_INTERFACE_MAP_END NS_INTERFACE_MAP_END
NS_IMETHODIMP nsTreeSelection::GetTree(XULTreeElement** aTree) { NS_IMETHODIMP nsTreeSelection::GetTree(nsITreeBoxObject** aTree) {
NS_IF_ADDREF(*aTree = mTree); NS_IF_ADDREF(*aTree = mTree);
return NS_OK; return NS_OK;
} }
NS_IMETHODIMP nsTreeSelection::SetTree(XULTreeElement* aTree) { NS_IMETHODIMP nsTreeSelection::SetTree(nsITreeBoxObject* aTree) {
if (mSelectTimer) { if (mSelectTimer) {
mSelectTimer->Cancel(); mSelectTimer->Cancel();
mSelectTimer = nullptr; mSelectTimer = nullptr;
} }
mTree = aTree; // Make sure aTree really implements nsITreeBoxObject and nsIBoxObject!
nsCOMPtr<nsIBoxObject> bo = do_QueryInterface(aTree);
mTree = do_QueryInterface(bo);
NS_ENSURE_STATE(mTree == aTree);
return NS_OK; return NS_OK;
} }
NS_IMETHODIMP nsTreeSelection::GetSingle(bool* aSingle) { NS_IMETHODIMP nsTreeSelection::GetSingle(bool* aSingle) {
if (!mTree) { nsCOMPtr<nsIContent> content = GetContent();
if (!content) {
return NS_ERROR_NULL_POINTER; return NS_ERROR_NULL_POINTER;
} }
*aSingle = mTree->AttrValueIs(kNameSpaceID_None, nsGkAtoms::seltype, *aSingle =
content->IsElement() && content->AsElement()->AttrValueIs(
kNameSpaceID_None, nsGkAtoms::seltype,
NS_LITERAL_STRING("single"), eCaseMatters); NS_LITERAL_STRING("single"), eCaseMatters);
return NS_OK; return NS_OK;
@ -296,8 +302,10 @@ NS_IMETHODIMP nsTreeSelection::TimedSelect(int32_t aIndex, int32_t aMsec) {
if (!mSuppressed) { if (!mSuppressed) {
if (mSelectTimer) mSelectTimer->Cancel(); if (mSelectTimer) mSelectTimer->Cancel();
nsIEventTarget* target = nsIEventTarget* target = nullptr;
mTree->OwnerDoc()->EventTargetFor(TaskCategory::Other); if (nsCOMPtr<nsIContent> content = GetContent()) {
target = content->OwnerDoc()->EventTargetFor(TaskCategory::Other);
}
NS_NewTimerWithFuncCallback(getter_AddRefs(mSelectTimer), SelectCallback, NS_NewTimerWithFuncCallback(getter_AddRefs(mSelectTimer), SelectCallback,
this, aMsec, nsITimer::TYPE_ONE_SHOT, this, aMsec, nsITimer::TYPE_ONE_SHOT,
"nsTreeSelection::SelectCallback", target); "nsTreeSelection::SelectCallback", target);
@ -466,7 +474,8 @@ NS_IMETHODIMP nsTreeSelection::InvertSelection() {
NS_IMETHODIMP nsTreeSelection::SelectAll() { NS_IMETHODIMP nsTreeSelection::SelectAll() {
if (!mTree) return NS_OK; if (!mTree) return NS_OK;
nsCOMPtr<nsITreeView> view = mTree->GetView(); nsCOMPtr<nsITreeView> view;
mTree->GetView(getter_AddRefs(view));
if (!view) return NS_OK; if (!view) return NS_OK;
int32_t rowCount; int32_t rowCount;
@ -563,13 +572,19 @@ NS_IMETHODIMP nsTreeSelection::SetCurrentIndex(int32_t aIndex) {
if (aIndex != -1) mTree->InvalidateRow(aIndex); if (aIndex != -1) mTree->InvalidateRow(aIndex);
// Fire DOMMenuItemActive or DOMMenuItemInactive event for tree. // Fire DOMMenuItemActive or DOMMenuItemInactive event for tree.
NS_ENSURE_STATE(mTree); nsCOMPtr<nsIBoxObject> boxObject = do_QueryInterface(mTree);
NS_ASSERTION(boxObject, "no box object!");
if (!boxObject) return NS_ERROR_UNEXPECTED;
RefPtr<dom::Element> treeElt;
boxObject->GetElement(getter_AddRefs(treeElt));
NS_ENSURE_STATE(treeElt);
NS_NAMED_LITERAL_STRING(DOMMenuItemActive, "DOMMenuItemActive"); NS_NAMED_LITERAL_STRING(DOMMenuItemActive, "DOMMenuItemActive");
NS_NAMED_LITERAL_STRING(DOMMenuItemInactive, "DOMMenuItemInactive"); NS_NAMED_LITERAL_STRING(DOMMenuItemInactive, "DOMMenuItemInactive");
RefPtr<AsyncEventDispatcher> asyncDispatcher = new AsyncEventDispatcher( RefPtr<AsyncEventDispatcher> asyncDispatcher = new AsyncEventDispatcher(
mTree, (aIndex != -1 ? DOMMenuItemActive : DOMMenuItemInactive), treeElt, (aIndex != -1 ? DOMMenuItemActive : DOMMenuItemInactive),
CanBubble::eYes, ChromeOnlyDispatch::eNo); CanBubble::eYes, ChromeOnlyDispatch::eNo);
return asyncDispatcher->PostDOMEvent(); return asyncDispatcher->PostDOMEvent();
} }
@ -698,8 +713,15 @@ nsTreeSelection::GetShiftSelectPivot(int32_t* aIndex) {
nsresult nsTreeSelection::FireOnSelectHandler() { nsresult nsTreeSelection::FireOnSelectHandler() {
if (mSuppressed || !mTree) return NS_OK; if (mSuppressed || !mTree) return NS_OK;
nsCOMPtr<nsIBoxObject> boxObject = do_QueryInterface(mTree);
NS_ASSERTION(boxObject, "no box object!");
if (!boxObject) return NS_ERROR_UNEXPECTED;
RefPtr<dom::Element> elt;
boxObject->GetElement(getter_AddRefs(elt));
NS_ENSURE_STATE(elt);
RefPtr<AsyncEventDispatcher> asyncDispatcher = RefPtr<AsyncEventDispatcher> asyncDispatcher =
new AsyncEventDispatcher(mTree, NS_LITERAL_STRING("select"), new AsyncEventDispatcher(elt, NS_LITERAL_STRING("select"),
CanBubble::eYes, ChromeOnlyDispatch::eNo); CanBubble::eYes, ChromeOnlyDispatch::eNo);
asyncDispatcher->RunDOMEventWhenSafe(); asyncDispatcher->RunDOMEventWhenSafe();
return NS_OK; return NS_OK;
@ -714,9 +736,21 @@ void nsTreeSelection::SelectCallback(nsITimer* aTimer, void* aClosure) {
} }
} }
already_AddRefed<nsIContent> nsTreeSelection::GetContent() {
if (!mTree) {
return nullptr;
}
nsCOMPtr<nsIBoxObject> boxObject = do_QueryInterface(mTree);
RefPtr<dom::Element> element;
boxObject->GetElement(getter_AddRefs(element));
return element.forget();
}
/////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////
nsresult NS_NewTreeSelection(XULTreeElement* aTree, nsresult NS_NewTreeSelection(nsITreeBoxObject* aTree,
nsITreeSelection** aResult) { nsITreeSelection** aResult) {
*aResult = new nsTreeSelection(aTree); *aResult = new nsTreeSelection(aTree);
if (!*aResult) return NS_ERROR_OUT_OF_MEMORY; if (!*aResult) return NS_ERROR_OUT_OF_MEMORY;

Просмотреть файл

@ -11,14 +11,14 @@
#include "nsITimer.h" #include "nsITimer.h"
#include "nsCycleCollectionParticipant.h" #include "nsCycleCollectionParticipant.h"
#include "mozilla/Attributes.h" #include "mozilla/Attributes.h"
#include "XULTreeElement.h"
class nsITreeBoxObject;
class nsTreeColumn; class nsTreeColumn;
struct nsTreeRange; struct nsTreeRange;
class nsTreeSelection final : public nsINativeTreeSelection { class nsTreeSelection final : public nsINativeTreeSelection {
public: public:
explicit nsTreeSelection(mozilla::dom::XULTreeElement* aTree); explicit nsTreeSelection(nsITreeBoxObject* aTree);
NS_DECL_CYCLE_COLLECTING_ISUPPORTS NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_CLASS(nsTreeSelection) NS_DECL_CYCLE_COLLECTION_CLASS(nsTreeSelection)
@ -36,8 +36,12 @@ class nsTreeSelection final : public nsINativeTreeSelection {
static void SelectCallback(nsITimer* aTimer, void* aClosure); static void SelectCallback(nsITimer* aTimer, void* aClosure);
protected: protected:
// The tree will hold on to us through the view and let go when it dies. // Helper function to get the content node associated with mTree.
RefPtr<mozilla::dom::XULTreeElement> mTree; already_AddRefed<nsIContent> GetContent();
// Members
nsCOMPtr<nsITreeBoxObject> mTree; // The tree will hold on to us through the
// view and let go when it dies.
bool mSuppressed; // Whether or not we should be firing onselect events. bool mSuppressed; // Whether or not we should be firing onselect events.
int32_t mCurrentIndex; // The item to draw the rect around. The last one int32_t mCurrentIndex; // The item to draw the rect around. The last one
@ -50,7 +54,7 @@ class nsTreeSelection final : public nsINativeTreeSelection {
nsCOMPtr<nsITimer> mSelectTimer; nsCOMPtr<nsITimer> mSelectTimer;
}; };
nsresult NS_NewTreeSelection(mozilla::dom::XULTreeElement* aTree, nsresult NS_NewTreeSelection(nsITreeBoxObject* aTree,
nsITreeSelection** aResult); nsITreeSelection** aResult);
#endif #endif

Просмотреть файл

@ -255,7 +255,7 @@ nsNSSASN1Tree::GetDisplayData(uint32_t index, nsAString& _retval) {
} }
NS_IMETHODIMP NS_IMETHODIMP
nsNSSASN1Tree::SetTree(mozilla::dom::XULTreeElement* tree) { nsNSSASN1Tree::SetTree(nsITreeBoxObject* tree) {
// Note: |tree| is allowed to be null. // Note: |tree| is allowed to be null.
mTree = tree; mTree = tree;
return NS_OK; return NS_OK;

Просмотреть файл

@ -10,9 +10,9 @@
#include "nsIASN1Object.h" #include "nsIASN1Object.h"
#include "nsIASN1Sequence.h" #include "nsIASN1Sequence.h"
#include "nsITreeView.h" #include "nsITreeView.h"
#include "nsITreeBoxObject.h"
#include "nsITreeSelection.h" #include "nsITreeSelection.h"
#include "nsCOMPtr.h" #include "nsCOMPtr.h"
#include "mozilla/dom/XULTreeElement.h"
// 4bfaa9f0-1dd2-11b2-afae-a82cbaa0b606 // 4bfaa9f0-1dd2-11b2-afae-a82cbaa0b606
#define NS_NSSASN1OUTINER_CID \ #define NS_NSSASN1OUTINER_CID \
@ -48,7 +48,7 @@ class nsNSSASN1Tree : public nsIASN1Tree {
nsCOMPtr<nsIASN1Object> mASN1Object; nsCOMPtr<nsIASN1Object> mASN1Object;
nsCOMPtr<nsITreeSelection> mSelection; nsCOMPtr<nsITreeSelection> mSelection;
RefPtr<mozilla::dom::XULTreeElement> mTree; nsCOMPtr<nsITreeBoxObject> mTree;
void InitNodes(); void InitNodes();
void InitChildsRecursively(myNode *n); void InitChildsRecursively(myNode *n);

Просмотреть файл

@ -999,7 +999,7 @@ nsCertTree::GetCellText(int32_t row, nsTreeColumn *col, nsAString &_retval) {
} }
NS_IMETHODIMP NS_IMETHODIMP
nsCertTree::SetTree(mozilla::dom::XULTreeElement *tree) { nsCertTree::SetTree(nsITreeBoxObject *tree) {
mTree = tree; mTree = tree;
return NS_OK; return NS_OK;
} }

Просмотреть файл

@ -9,6 +9,7 @@
#include "nsIServiceManager.h" #include "nsIServiceManager.h"
#include "nsICertTree.h" #include "nsICertTree.h"
#include "nsITreeView.h" #include "nsITreeView.h"
#include "nsITreeBoxObject.h"
#include "nsITreeSelection.h" #include "nsITreeSelection.h"
#include "nsIMutableArray.h" #include "nsIMutableArray.h"
#include "nsNSSComponent.h" #include "nsNSSComponent.h"
@ -17,7 +18,6 @@
#include "nsIX509CertDB.h" #include "nsIX509CertDB.h"
#include "nsCertOverrideService.h" #include "nsCertOverrideService.h"
#include "mozilla/Attributes.h" #include "mozilla/Attributes.h"
#include "mozilla/dom/XULTreeElement.h"
typedef struct treeArrayElStr treeArrayEl; typedef struct treeArrayElStr treeArrayEl;
@ -116,7 +116,7 @@ class nsCertTree : public nsICertTree {
static const uint32_t kInitialCacheLength = 64; static const uint32_t kInitialCacheLength = 64;
nsTArray<RefPtr<nsCertTreeDispInfo> > mDispInfo; nsTArray<RefPtr<nsCertTreeDispInfo> > mDispInfo;
RefPtr<mozilla::dom::XULTreeElement> mTree; nsCOMPtr<nsITreeBoxObject> mTree;
nsCOMPtr<nsITreeSelection> mSelection; nsCOMPtr<nsITreeSelection> mSelection;
treeArrayEl *mTreeArray; treeArrayEl *mTreeArray;
int32_t mNumOrgs; int32_t mNumOrgs;

Просмотреть файл

@ -49,7 +49,7 @@ let signonReloadDisplay = {
if (filterField && filterField.value != "") { if (filterField && filterField.value != "") {
FilterPasswords(); FilterPasswords();
} }
signonsTree.ensureRowIsVisible(signonsTree.view.selection.currentIndex); signonsTree.treeBoxObject.ensureRowIsVisible(signonsTree.view.selection.currentIndex);
break; break;
} }
Services.obs.notifyObservers(null, "passwordmgr-dialog-updated"); Services.obs.notifyObservers(null, "passwordmgr-dialog-updated");
@ -191,7 +191,7 @@ let signonsTreeView = {
table[row][field] = value; table[row][field] = value;
table[row].timePasswordChanged = Date.now(); table[row].timePasswordChanged = Date.now();
Services.logins.modifyLogin(existingLogin, table[row]); Services.logins.modifyLogin(existingLogin, table[row]);
signonsTree.invalidateRow(row); signonsTree.treeBoxObject.invalidateRow(row);
} }
if (col.id == "userCol") { if (col.id == "userCol") {
@ -264,9 +264,9 @@ function SortTree(column, ascending) {
} }
// display the results // display the results
signonsTree.invalidate(); signonsTree.treeBoxObject.invalidate();
if (selectedRow >= 0) { if (selectedRow >= 0) {
signonsTree.ensureRowIsVisible(selectedRow); signonsTree.treeBoxObject.ensureRowIsVisible(selectedRow);
} }
} }
@ -358,7 +358,7 @@ function DeleteSignon() {
} }
table.splice(j, k - j); table.splice(j, k - j);
view.rowCount -= k - j; view.rowCount -= k - j;
tree.rowCountChanged(j, j - k); tree.treeBoxObject.rowCountChanged(j, j - k);
} }
} }
@ -402,8 +402,9 @@ function DeleteAllSignons() {
// update the tree view and notify the tree // update the tree view and notify the tree
view.rowCount = 0; view.rowCount = 0;
signonsTree.rowCountChanged(0, -deletedSignons.length); let box = signonsTree.treeBoxObject;
signonsTree.invalidate(); box.rowCountChanged(0, -deletedSignons.length);
box.invalidate();
// disable buttons // disable buttons
removeButton.setAttribute("disabled", "true"); removeButton.setAttribute("disabled", "true");
@ -515,7 +516,7 @@ function SignonClearFilter() {
// Clear the Tree Display // Clear the Tree Display
signonsTreeView.rowCount = 0; signonsTreeView.rowCount = 0;
signonsTree.rowCountChanged(0, -signonsTreeView._filterSet.length); signonsTree.treeBoxObject.rowCountChanged(0, -signonsTreeView._filterSet.length);
signonsTreeView._filterSet = []; signonsTreeView._filterSet = [];
// Just reload the list to make sure deletions are respected // Just reload the list to make sure deletions are respected
@ -594,10 +595,10 @@ function FilterPasswords() {
// Clear the display // Clear the display
let oldRowCount = signonsTreeView.rowCount; let oldRowCount = signonsTreeView.rowCount;
signonsTreeView.rowCount = 0; signonsTreeView.rowCount = 0;
signonsTree.rowCountChanged(0, -oldRowCount); signonsTree.treeBoxObject.rowCountChanged(0, -oldRowCount);
// Set up the filtered display // Set up the filtered display
signonsTreeView.rowCount = signonsTreeView._filterSet.length; signonsTreeView.rowCount = signonsTreeView._filterSet.length;
signonsTree.rowCountChanged(0, signonsTreeView.rowCount); signonsTree.treeBoxObject.rowCountChanged(0, signonsTreeView.rowCount);
// if the view is not empty then select the first item // if the view is not empty then select the first item
if (signonsTreeView.rowCount > 0) if (signonsTreeView.rowCount > 0)

Просмотреть файл

@ -22,7 +22,8 @@ function getPassword(row) {
} }
function synthesizeDblClickOnCell(aTree, column, row) { function synthesizeDblClickOnCell(aTree, column, row) {
let rect = aTree.getCoordsForCellItem(row, aTree.columns[column], "text"); let tbo = aTree.treeBoxObject;
let rect = tbo.getCoordsForCellItem(row, aTree.columns[column], "text");
let x = rect.x + rect.width / 2; let x = rect.x + rect.width / 2;
let y = rect.y + rect.height / 2; let y = rect.y + rect.height / 2;
// Simulate the double click. // Simulate the double click.

Просмотреть файл

@ -245,7 +245,7 @@ function checkPopup()
isRoundedX(menurect.left, bodyrect.left + contextMenuOffsetX, isRoundedX(menurect.left, bodyrect.left + contextMenuOffsetX,
"tree selection keyboard left"); "tree selection keyboard left");
isRoundedY(menurect.top, bodyrect.top + isRoundedY(menurect.top, bodyrect.top +
tree.rowHeight * 3 + contextMenuOffsetY, tree.treeBoxObject.rowHeight * 3 + contextMenuOffsetY,
"tree selection keyboard top"); "tree selection keyboard top");
} }
} }

Просмотреть файл

@ -49,7 +49,7 @@ function treeClick()
synthesizeMouseExpectEvent($("treechildren"), 2, 2, { }, $("treechildren"), "click", ""); synthesizeMouseExpectEvent($("treechildren"), 2, 2, { }, $("treechildren"), "click", "");
is(tree.currentIndex, 0, "selectedIndex after click"); is(tree.currentIndex, 0, "selectedIndex after click");
var rect = tree.getCoordsForCellItem(1, tree.columns.address, ""); var rect = tree.treeBoxObject.getCoordsForCellItem(1, tree.columns.address, "");
synthesizeMouseExpectEvent($("treechildren"), rect.x, rect.y + 2, synthesizeMouseExpectEvent($("treechildren"), rect.x, rect.y + 2,
{ }, $("treechildren"), "click", ""); { }, $("treechildren"), "click", "");
is(tree.currentIndex, 1, "selectedIndex after second click " + rect.x + "," + rect.y); is(tree.currentIndex, 1, "selectedIndex after second click " + rect.x + "," + rect.y);

Просмотреть файл

@ -82,8 +82,8 @@ function init()
{ {
var tree = document.getElementById("tree-view"); var tree = document.getElementById("tree-view");
tree.view = view; tree.view = view;
tree.ensureRowIsVisible(0); tree.treeBoxObject.ensureRowIsVisible(0);
is(tree.getFirstVisibleRow(), 0, "first visible after ensureRowIsVisible on load"); is(tree.treeBoxObject.getFirstVisibleRow(), 0, "first visible after ensureRowIsVisible on load");
tree.setAttribute("rows", "4"); tree.setAttribute("rows", "4");
setTimeout(testtag_tree, 0, "tree-view", "treechildren-view", "multiple", "simple", "tree view"); setTimeout(testtag_tree, 0, "tree-view", "treechildren-view", "multiple", "simple", "tree view");

Просмотреть файл

@ -113,12 +113,12 @@ function checkTreeCoords()
var tree = $("tree"); var tree = $("tree");
var treechildren = $("treechildren"); var treechildren = $("treechildren");
tree.currentIndex = 0; tree.currentIndex = 0;
tree.scrollToRow(0); tree.treeBoxObject.scrollToRow(0);
synthesizeMouse(treechildren, 10, tree.rowHeight + 2, { }); synthesizeMouse(treechildren, 10, tree.treeBoxObject.rowHeight + 2, { });
is(tree.currentIndex, 1, "tree selection"); is(tree.currentIndex, 1, "tree selection");
tree.scrollToRow(2); tree.treeBoxObject.scrollToRow(2);
synthesizeMouse(treechildren, 10, tree.rowHeight + 2, { }); synthesizeMouse(treechildren, 10, tree.treeBoxObject.rowHeight + 2, { });
is(tree.currentIndex, 3, "tree selection after scroll"); is(tree.currentIndex, 3, "tree selection after scroll");
} }

Просмотреть файл

@ -354,32 +354,32 @@ function testtag_tree_TreeSelection_UI(tree, testid, multiple) {
testtag_tree_TreeSelection_State(tree, testid + "key down at end", 7, [7], 0); testtag_tree_TreeSelection_State(tree, testid + "key down at end", 7, [7], 0);
// pressing keys while at the edge of the visible rows should scroll the list // pressing keys while at the edge of the visible rows should scroll the list
tree.scrollToRow(4); tree.treeBoxObject.scrollToRow(4);
selection.select(4); selection.select(4);
synthesizeKeyExpectEvent("VK_UP", {}, tree, "!select", "key up with scroll"); synthesizeKeyExpectEvent("VK_UP", {}, tree, "!select", "key up with scroll");
is(tree.getFirstVisibleRow(), 3, testid + "key up with scroll"); is(tree.treeBoxObject.getFirstVisibleRow(), 3, testid + "key up with scroll");
tree.scrollToRow(0); tree.treeBoxObject.scrollToRow(0);
selection.select(3); selection.select(3);
synthesizeKeyExpectEvent("VK_DOWN", {}, tree, "!select", "key down with scroll"); synthesizeKeyExpectEvent("VK_DOWN", {}, tree, "!select", "key down with scroll");
is(tree.getFirstVisibleRow(), 1, testid + "key down with scroll"); is(tree.treeBoxObject.getFirstVisibleRow(), 1, testid + "key down with scroll");
// accel key and cursor movement adjust currentIndex but should not change // accel key and cursor movement adjust currentIndex but should not change
// the selection. In single selection mode, the selection will not change, // the selection. In single selection mode, the selection will not change,
// but instead will just scroll up or down a line // but instead will just scroll up or down a line
tree.scrollToRow(0); tree.treeBoxObject.scrollToRow(0);
selection.select(1); selection.select(1);
synthesizeKeyExpectEvent("VK_DOWN", { accelKey: true }, tree, "!select", "key down with accel"); synthesizeKeyExpectEvent("VK_DOWN", { accelKey: true }, tree, "!select", "key down with accel");
testtag_tree_TreeSelection_State(tree, testid + "key down with accel", multiple ? 2 : 1, [1]); testtag_tree_TreeSelection_State(tree, testid + "key down with accel", multiple ? 2 : 1, [1]);
if (!multiple) if (!multiple)
is(tree.getFirstVisibleRow(), 1, testid + "key down with accel and scroll"); is(tree.treeBoxObject.getFirstVisibleRow(), 1, testid + "key down with accel and scroll");
tree.scrollToRow(4); tree.treeBoxObject.scrollToRow(4);
selection.select(4); selection.select(4);
synthesizeKeyExpectEvent("VK_UP", { accelKey: true }, tree, "!select", "key up with accel"); synthesizeKeyExpectEvent("VK_UP", { accelKey: true }, tree, "!select", "key up with accel");
testtag_tree_TreeSelection_State(tree, testid + "key up with accel", multiple ? 3 : 4, [4]); testtag_tree_TreeSelection_State(tree, testid + "key up with accel", multiple ? 3 : 4, [4]);
if (!multiple) if (!multiple)
is(tree.getFirstVisibleRow(), 3, testid + "key up with accel and scroll"); is(tree.treeBoxObject.getFirstVisibleRow(), 3, testid + "key up with accel and scroll");
// do this three times, one for each state of pageUpOrDownMovesSelection, // do this three times, one for each state of pageUpOrDownMovesSelection,
// and then once with the accel key pressed // and then once with the accel key pressed
@ -395,7 +395,7 @@ function testtag_tree_TreeSelection_UI(tree, testid, multiple) {
if (t == 2) if (t == 2)
moveselection = !moveselection; moveselection = !moveselection;
tree.scrollToRow(4); tree.treeBoxObject.scrollToRow(4);
selection.currentIndex = 6; selection.currentIndex = 6;
selection.select(6); selection.select(6);
var expected = moveselection ? 4 : 6; var expected = moveselection ? 4 : 6;
@ -413,7 +413,7 @@ function testtag_tree_TreeSelection_UI(tree, testid, multiple) {
testtag_tree_TreeSelection_State(tree, testid + "key page up at start" + testidmod, testtag_tree_TreeSelection_State(tree, testid + "key page up at start" + testidmod,
expected, [expected], 0); expected, [expected], 0);
tree.scrollToRow(0); tree.treeBoxObject.scrollToRow(0);
selection.currentIndex = 1; selection.currentIndex = 1;
selection.select(1); selection.select(1);
expected = moveselection ? 3 : 1; expected = moveselection ? 3 : 1;
@ -435,23 +435,23 @@ function testtag_tree_TreeSelection_UI(tree, testid, multiple) {
tree.pageUpOrDownMovesSelection = !tree.pageUpOrDownMovesSelection; tree.pageUpOrDownMovesSelection = !tree.pageUpOrDownMovesSelection;
} }
tree.scrollToRow(4); tree.treeBoxObject.scrollToRow(4);
selection.select(6); selection.select(6);
synthesizeKeyExpectEvent("VK_HOME", {}, tree, "!select", "key home"); synthesizeKeyExpectEvent("VK_HOME", {}, tree, "!select", "key home");
testtag_tree_TreeSelection_State(tree, testid + "key home", 0, [0], 0); testtag_tree_TreeSelection_State(tree, testid + "key home", 0, [0], 0);
tree.scrollToRow(0); tree.treeBoxObject.scrollToRow(0);
selection.select(1); selection.select(1);
synthesizeKeyExpectEvent("VK_END", {}, tree, "!select", "key end"); synthesizeKeyExpectEvent("VK_END", {}, tree, "!select", "key end");
testtag_tree_TreeSelection_State(tree, testid + "key end", 7, [7], 4); testtag_tree_TreeSelection_State(tree, testid + "key end", 7, [7], 4);
// in single selection mode, the selection doesn't change in this case // in single selection mode, the selection doesn't change in this case
tree.scrollToRow(4); tree.treeBoxObject.scrollToRow(4);
selection.select(6); selection.select(6);
synthesizeKeyExpectEvent("VK_HOME", { accelKey: true }, tree, "!select", "key home with accel"); synthesizeKeyExpectEvent("VK_HOME", { accelKey: true }, tree, "!select", "key home with accel");
testtag_tree_TreeSelection_State(tree, testid + "key home with accel", multiple ? 0 : 6, [6], 0); testtag_tree_TreeSelection_State(tree, testid + "key home with accel", multiple ? 0 : 6, [6], 0);
tree.scrollToRow(0); tree.treeBoxObject.scrollToRow(0);
selection.select(1); selection.select(1);
synthesizeKeyExpectEvent("VK_END", { accelKey: true }, tree, "!select", "key end with accel"); synthesizeKeyExpectEvent("VK_END", { accelKey: true }, tree, "!select", "key end with accel");
testtag_tree_TreeSelection_State(tree, testid + "key end with accel", multiple ? 7 : 1, [1], 4); testtag_tree_TreeSelection_State(tree, testid + "key end with accel", multiple ? 7 : 1, [1], 4);
@ -487,7 +487,7 @@ function testtag_tree_TreeSelection_UI(tree, testid, multiple) {
// If the top or bottom visible row is the current row, pressing shift and // If the top or bottom visible row is the current row, pressing shift and
// page down / page up selects one page up or one page down. Otherwise, the // page down / page up selects one page up or one page down. Otherwise, the
// selection is made to the top or bottom of the visible area. // selection is made to the top or bottom of the visible area.
tree.scrollToRow(lastidx - 3); tree.treeBoxObject.scrollToRow(lastidx - 3);
selection.currentIndex = 6; selection.currentIndex = 6;
selection.select(6); selection.select(6);
synthesizeKeyExpectEvent("VK_PAGE_UP", { shiftKey: true }, tree, eventExpected, "key shift page up"); synthesizeKeyExpectEvent("VK_PAGE_UP", { shiftKey: true }, tree, eventExpected, "key shift page up");
@ -507,7 +507,7 @@ function testtag_tree_TreeSelection_UI(tree, testid, multiple) {
3, [3, 4, 5, 6]); 3, [3, 4, 5, 6]);
} }
tree.scrollToRow(1); tree.treeBoxObject.scrollToRow(1);
selection.currentIndex = 2; selection.currentIndex = 2;
selection.select(2); selection.select(2);
synthesizeKeyExpectEvent("VK_PAGE_DOWN", { shiftKey: true }, tree, eventExpected, "key shift page down"); synthesizeKeyExpectEvent("VK_PAGE_DOWN", { shiftKey: true }, tree, eventExpected, "key shift page down");
@ -528,7 +528,7 @@ function testtag_tree_TreeSelection_UI(tree, testid, multiple) {
// test when page down / page up is pressed when the view is scrolled such // test when page down / page up is pressed when the view is scrolled such
// that the selection is not visible // that the selection is not visible
if (multiple) { if (multiple) {
tree.scrollToRow(3); tree.treeBoxObject.scrollToRow(3);
selection.currentIndex = 1; selection.currentIndex = 1;
selection.select(1); selection.select(1);
synthesizeKeyExpectEvent("VK_PAGE_DOWN", { shiftKey: true }, tree, eventExpected, synthesizeKeyExpectEvent("VK_PAGE_DOWN", { shiftKey: true }, tree, eventExpected,
@ -536,7 +536,7 @@ function testtag_tree_TreeSelection_UI(tree, testid, multiple) {
testtag_tree_TreeSelection_State(tree, testid + "key shift page down with view scrolled down" + testidmod, testtag_tree_TreeSelection_State(tree, testid + "key shift page down with view scrolled down" + testidmod,
6, [1, 2, 3, 4, 5, 6], 3); 6, [1, 2, 3, 4, 5, 6], 3);
tree.scrollToRow(2); tree.treeBoxObject.scrollToRow(2);
selection.currentIndex = 6; selection.currentIndex = 6;
selection.select(6); selection.select(6);
synthesizeKeyExpectEvent("VK_PAGE_UP", { shiftKey: true }, tree, eventExpected, synthesizeKeyExpectEvent("VK_PAGE_UP", { shiftKey: true }, tree, eventExpected,
@ -544,7 +544,7 @@ function testtag_tree_TreeSelection_UI(tree, testid, multiple) {
testtag_tree_TreeSelection_State(tree, testid + "key shift page up with view scrolled up" + testidmod, testtag_tree_TreeSelection_State(tree, testid + "key shift page up with view scrolled up" + testidmod,
2, [2, 3, 4, 5, 6], 2); 2, [2, 3, 4, 5, 6], 2);
tree.scrollToRow(2); tree.treeBoxObject.scrollToRow(2);
selection.currentIndex = 0; selection.currentIndex = 0;
selection.select(0); selection.select(0);
// don't expect the select event, as the selection won't have changed // don't expect the select event, as the selection won't have changed
@ -553,7 +553,7 @@ function testtag_tree_TreeSelection_UI(tree, testid, multiple) {
testtag_tree_TreeSelection_State(tree, testid + "key shift page up at start with view scrolled down" + testidmod, testtag_tree_TreeSelection_State(tree, testid + "key shift page up at start with view scrolled down" + testidmod,
0, [0], 0); 0, [0], 0);
tree.scrollToRow(0); tree.treeBoxObject.scrollToRow(0);
selection.currentIndex = 7; selection.currentIndex = 7;
selection.select(7); selection.select(7);
// don't expect the select event, as the selection won't have changed // don't expect the select event, as the selection won't have changed
@ -566,13 +566,13 @@ function testtag_tree_TreeSelection_UI(tree, testid, multiple) {
tree.pageUpOrDownMovesSelection = !tree.pageUpOrDownMovesSelection; tree.pageUpOrDownMovesSelection = !tree.pageUpOrDownMovesSelection;
} }
tree.scrollToRow(4); tree.treeBoxObject.scrollToRow(4);
selection.select(5); selection.select(5);
synthesizeKeyExpectEvent("VK_HOME", { shiftKey: true }, tree, eventExpected, "key shift home"); synthesizeKeyExpectEvent("VK_HOME", { shiftKey: true }, tree, eventExpected, "key shift home");
testtag_tree_TreeSelection_State(tree, testid + "key shift home", testtag_tree_TreeSelection_State(tree, testid + "key shift home",
multiple ? 0 : 5, multiple ? [0, 1, 2, 3, 4, 5] : [5], multiple ? 0 : 4); multiple ? 0 : 5, multiple ? [0, 1, 2, 3, 4, 5] : [5], multiple ? 0 : 4);
tree.scrollToRow(0); tree.treeBoxObject.scrollToRow(0);
selection.select(3); selection.select(3);
synthesizeKeyExpectEvent("VK_END", { shiftKey: true }, tree, eventExpected, "key shift end"); synthesizeKeyExpectEvent("VK_END", { shiftKey: true }, tree, eventExpected, "key shift end");
testtag_tree_TreeSelection_State(tree, testid + "key shift end", testtag_tree_TreeSelection_State(tree, testid + "key shift end",
@ -591,7 +591,7 @@ function testtag_tree_TreeSelection_UI(tree, testid, multiple) {
} }
// check that clicking on a row selects it // check that clicking on a row selects it
tree.scrollToRow(0); tree.treeBoxObject.scrollToRow(0);
selection.select(2); selection.select(2);
selection.currentIndex = 2; selection.currentIndex = 2;
if (0) { // XXXndeakin disable these tests for now if (0) { // XXXndeakin disable these tests for now
@ -848,7 +848,7 @@ function testtag_tree_TreeSelection_State(tree, testid, current, selected, viewi
is(tree.currentIndex, current, testid + " currentIndex"); is(tree.currentIndex, current, testid + " currentIndex");
is(selection.currentIndex, current, testid + " TreeSelection currentIndex"); is(selection.currentIndex, current, testid + " TreeSelection currentIndex");
if (viewidx !== null && viewidx !== undefined) if (viewidx !== null && viewidx !== undefined)
is(tree.getFirstVisibleRow(), viewidx, testid + " first visible row"); is(tree.treeBoxObject.getFirstVisibleRow(), viewidx, testid + " first visible row");
var actualSelected = []; var actualSelected = [];
var count = tree.view.rowCount; var count = tree.view.rowCount;
@ -945,38 +945,38 @@ function testtag_tree_wheel(aTree) {
WheelEvent.DOM_DELTA_PAGE, // 2 WheelEvent.DOM_DELTA_PAGE, // 2
]; ];
function helper(aStart, aDelta, aIntDelta, aDeltaMode) { function helper(aStart, aDelta, aIntDelta, aDeltaMode) {
aTree.scrollToRow(aStart); aTree.treeBoxObject.scrollToRow(aStart);
var expected; var expected;
if (!aIntDelta) { if (!aIntDelta) {
expected = aStart; expected = aStart;
} else if (aDeltaMode != WheelEvent.DOM_DELTA_PAGE) { } else if (aDeltaMode != WheelEvent.DOM_DELTA_PAGE) {
expected = aStart + aIntDelta; expected = aStart + aIntDelta;
} else if (aIntDelta > 0) { } else if (aIntDelta > 0) {
expected = aStart + aTree.getPageLength(); expected = aStart + aTree.treeBoxObject.getPageLength();
} else { } else {
expected = aStart - aTree.getPageLength(); expected = aStart - aTree.treeBoxObject.getPageLength();
} }
if (expected < 0) { if (expected < 0) {
expected = 0; expected = 0;
} }
if (expected > aTree.view.rowCount - aTree.getPageLength()) { if (expected > aTree.view.rowCount - aTree.treeBoxObject.getPageLength()) {
expected = aTree.view.rowCount - aTree.getPageLength(); expected = aTree.view.rowCount - aTree.treeBoxObject.getPageLength();
} }
synthesizeWheel(aTree.body, 1, 1, synthesizeWheel(aTree.body, 1, 1,
{ deltaMode: aDeltaMode, deltaY: aDelta, { deltaMode: aDeltaMode, deltaY: aDelta,
lineOrPageDeltaY: aIntDelta }); lineOrPageDeltaY: aIntDelta });
is(aTree.getFirstVisibleRow(), expected, is(aTree.treeBoxObject.getFirstVisibleRow(), expected,
"testtag_tree_wheel: vertical, starting " + aStart + "testtag_tree_wheel: vertical, starting " + aStart +
" delta " + aDelta + " lineOrPageDelta " + aIntDelta + " delta " + aDelta + " lineOrPageDelta " + aIntDelta +
" aDeltaMode " + aDeltaMode); " aDeltaMode " + aDeltaMode);
aTree.scrollToRow(aStart); aTree.treeBoxObject.scrollToRow(aStart);
// Check that horizontal scrolling has no effect // Check that horizontal scrolling has no effect
synthesizeWheel(aTree.body, 1, 1, synthesizeWheel(aTree.body, 1, 1,
{ deltaMode: aDeltaMode, deltaX: aDelta, { deltaMode: aDeltaMode, deltaX: aDelta,
lineOrPageDeltaX: aIntDelta }); lineOrPageDeltaX: aIntDelta });
is(aTree.getFirstVisibleRow(), aStart, is(aTree.treeBoxObject.getFirstVisibleRow(), aStart,
"testtag_tree_wheel: horizontal, starting " + aStart + "testtag_tree_wheel: horizontal, starting " + aStart +
" delta " + aDelta + " lineOrPageDelta " + aIntDelta + " delta " + aDelta + " lineOrPageDelta " + aIntDelta +
" aDeltaMode " + aDeltaMode); " aDeltaMode " + aDeltaMode);
@ -1075,7 +1075,7 @@ function checkColumns(aTree, aReference, aMessage) {
} }
function mouseOnCell(tree, row, column, testname) { function mouseOnCell(tree, row, column, testname) {
var rect = tree.getCoordsForCellItem(row, column, "text"); var rect = tree.boxObject.getCoordsForCellItem(row, column, "text");
synthesizeMouseExpectEvent(tree.body, rect.x, rect.y, {}, tree, "select", testname); synthesizeMouseExpectEvent(tree.body, rect.x, rect.y, {}, tree, "select", testname);
} }
@ -1098,10 +1098,10 @@ function mouseDblClickOnCell(tree, row, column, testname) {
// select the row we will edit // select the row we will edit
var selection = tree.view.selection; var selection = tree.view.selection;
selection.select(row); selection.select(row);
tree.ensureRowIsVisible(row); tree.treeBoxObject.ensureRowIsVisible(row);
// get cell coordinates // get cell coordinates
var rect = tree.getCoordsForCellItem(row, column, "text"); var rect = tree.treeBoxObject.getCoordsForCellItem(row, column, "text");
synthesizeMouse(tree.body, rect.x, rect.y, { clickCount: 2 }); synthesizeMouse(tree.body, rect.x, rect.y, { clickCount: 2 });
} }

Просмотреть файл

@ -11,7 +11,7 @@ var gTreeUtils = {
aItems.splice(0, aItems.length); aItems.splice(0, aItems.length);
var oldCount = aView.rowCount; var oldCount = aView.rowCount;
aView._rowCount = 0; aView._rowCount = 0;
aTree.rowCountChanged(0, -oldCount); aTree.treeBoxObject.rowCountChanged(0, -oldCount);
}, },
deleteSelectedItems(aTree, aView, aItems, aDeletedItems) { deleteSelectedItems(aTree, aView, aItems, aDeletedItems) {
@ -37,13 +37,13 @@ var gTreeUtils = {
aItems.splice(i, j - i); aItems.splice(i, j - i);
nextSelection = j < aView.rowCount ? j - 1 : j - 2; nextSelection = j < aView.rowCount ? j - 1 : j - 2;
aView._rowCount -= j - i; aView._rowCount -= j - i;
aTree.rowCountChanged(i, i - j); aTree.treeBoxObject.rowCountChanged(i, i - j);
} }
} }
if (aItems.length) { if (aItems.length) {
selection.select(nextSelection); selection.select(nextSelection);
aTree.ensureRowIsVisible(nextSelection); aTree.treeBoxObject.ensureRowIsVisible(nextSelection);
aTree.focus(); aTree.focus();
} }
selection.selectEventsSuppressed = false; selection.selectEventsSuppressed = false;
@ -65,8 +65,8 @@ var gTreeUtils = {
aTree.view.selection.clearSelection(); aTree.view.selection.clearSelection();
aTree.view.selection.select(0); aTree.view.selection.select(0);
aTree.invalidate(); aTree.treeBoxObject.invalidate();
aTree.ensureRowIsVisible(0); aTree.treeBoxObject.ensureRowIsVisible(0);
return ascending; return ascending;
}, },

Просмотреть файл

@ -22,7 +22,7 @@
!this.parentNode.pageUpOrDownMovesSelection) && !this.parentNode.pageUpOrDownMovesSelection) &&
!event.shiftKey && !event.metaKey) || !event.shiftKey && !event.metaKey) ||
this.parentNode.view.selection.single) { this.parentNode.view.selection.single) {
var b = this.parentNode; var b = this.parentNode.treeBoxObject;
var cell = b.getCellAt(event.clientX, event.clientY); var cell = b.getCellAt(event.clientX, event.clientY);
var view = this.parentNode.view; var view = this.parentNode.view;
@ -65,7 +65,7 @@
if (event.button != 0) { return; } if (event.button != 0) { return; }
if (this.parentNode.disabled) if (this.parentNode.disabled)
return; return;
var b = this.parentNode; var b = this.parentNode.treeBoxObject;
var cell = b.getCellAt(event.clientX, event.clientY); var cell = b.getCellAt(event.clientX, event.clientY);
var view = this.parentNode.view; var view = this.parentNode.view;
@ -126,14 +126,14 @@
this.addEventListener("dblclick", (event) => { this.addEventListener("dblclick", (event) => {
if (this.parentNode.disabled) if (this.parentNode.disabled)
return; return;
var tree = this.parentNode; var tbo = this.parentNode.treeBoxObject;
var view = this.parentNode.view; var view = this.parentNode.view;
var row = view.selection.currentIndex; var row = view.selection.currentIndex;
if (row == -1) if (row == -1)
return; return;
var cell = tree.getCellAt(event.clientX, event.clientY); var cell = tbo.getCellAt(event.clientX, event.clientY);
if (cell.childElt != "twisty") { if (cell.childElt != "twisty") {
this.parentNode.startEditing(row, cell.col); this.parentNode.startEditing(row, cell.col);
@ -316,12 +316,12 @@
col.mTargetCol.removeAttribute("insertbefore"); col.mTargetCol.removeAttribute("insertbefore");
col.mTargetCol.removeAttribute("insertafter"); col.mTargetCol.removeAttribute("insertafter");
column = tree.columns.getColumnFor(col.mTargetCol); column = tree.columns.getColumnFor(col.mTargetCol);
tree.invalidateColumn(column); tree.treeBoxObject.invalidateColumn(column);
sib = col.mTargetCol._previousVisibleColumn; sib = col.mTargetCol._previousVisibleColumn;
if (sib) { if (sib) {
sib.removeAttribute("insertafter"); sib.removeAttribute("insertafter");
column = tree.columns.getColumnFor(sib); column = tree.columns.getColumnFor(sib);
tree.invalidateColumn(column); tree.treeBoxObject.invalidateColumn(column);
} }
col.mTargetCol = null; col.mTargetCol = null;
col.mTargetDir = null; col.mTargetDir = null;
@ -337,11 +337,11 @@
if (sib) { if (sib) {
sib.setAttribute("insertafter", "true"); sib.setAttribute("insertafter", "true");
column = tree.columns.getColumnFor(sib); column = tree.columns.getColumnFor(sib);
tree.invalidateColumn(column); tree.treeBoxObject.invalidateColumn(column);
} }
} }
column = tree.columns.getColumnFor(targetCol); column = tree.columns.getColumnFor(targetCol);
tree.invalidateColumn(column); tree.treeBoxObject.invalidateColumn(column);
col.mTargetCol = targetCol; col.mTargetCol = targetCol;
col.mTargetDir = pos.value; col.mTargetDir = pos.value;
} }
@ -381,7 +381,7 @@
} }
// repaint to remove lines // repaint to remove lines
col.parentNode.parentNode.invalidate(); col.parentNode.parentNode.treeBoxObject.invalidate();
col.mTargetCol = null; col.mTargetCol = null;
} }

Просмотреть файл

@ -38,8 +38,15 @@
</content> </content>
<implementation implements="nsIDOMXULMultiSelectControlElement"> <implementation implements="nsIDOMXULMultiSelectControlElement">
<property name="columns"
onget="return this.treeBoxObject.columns;"/>
<property name="view"
onget="return this.treeBoxObject.view"
onset="return this.treeBoxObject.view = val;"/>
<property name="body" <property name="body"
onget="return this.treeBody;"/> onget="return this.treeBoxObject.treeBody;"/>
<property name="editable" <property name="editable"
onget="return this.getAttribute('editable') == 'true';" onget="return this.getAttribute('editable') == 'true';"
@ -58,6 +65,10 @@
onget="return this.view ? this.view.selection.currentIndex: - 1;" onget="return this.view ? this.view.selection.currentIndex: - 1;"
onset="if (this.view) return this.view.selection.currentIndex = val; return val;"/> onset="if (this.view) return this.view.selection.currentIndex = val; return val;"/>
<property name="treeBoxObject"
onget="return this.boxObject;"
readonly="true"/>
<field name="pageUpOrDownMovesSelection"> <field name="pageUpOrDownMovesSelection">
!/Mac/.test(navigator.platform) !/Mac/.test(navigator.platform)
</field> </field>
@ -182,7 +193,7 @@
if (isRTL) if (isRTL)
columns.reverse(); columns.reverse();
var currentX = this.boxObject.x; var currentX = this.boxObject.x;
var adjustedX = aX + this.horizontalPosition; var adjustedX = aX + this.treeBoxObject.horizontalPosition;
for (var i = 0; i < columns.length; ++i) { for (var i = 0; i < columns.length; ++i) {
col = columns[i]; col = columns[i];
var cw = col.element.boxObject.width; var cw = col.element.boxObject.width;
@ -288,13 +299,14 @@
var input = this.inputField; var input = this.inputField;
this.ensureCellIsVisible(row, column); var box = this.treeBoxObject;
box.ensureCellIsVisible(row, column);
// Get the coordinates of the text inside the cell. // Get the coordinates of the text inside the cell.
var textRect = this.getCoordsForCellItem(row, column, "text"); var textRect = box.getCoordsForCellItem(row, column, "text");
// Get the coordinates of the cell itself. // Get the coordinates of the cell itself.
var cellRect = this.getCoordsForCellItem(row, column, "cell"); var cellRect = box.getCoordsForCellItem(row, column, "cell");
// Calculate the top offset of the textbox. // Calculate the top offset of the textbox.
var style = window.getComputedStyle(input); var style = window.getComputedStyle(input);
@ -328,7 +340,7 @@
this._editingColumn = column; this._editingColumn = column;
this.setAttribute("editing", "true"); this.setAttribute("editing", "true");
this.invalidateCell(row, column); box.invalidateCell(row, column);
return true; return true;
]]> ]]>
</body> </body>
@ -370,7 +382,7 @@
return; return;
if (event.getModifierState("Accel") && this.view.selection.single) { if (event.getModifierState("Accel") && this.view.selection.single) {
this.scrollByLines(offset); this.treeBoxObject.scrollByLines(offset);
return; return;
} }
@ -385,7 +397,7 @@
this.view.selection.timedSelect(c, this._selectDelay); this.view.selection.timedSelect(c, this._selectDelay);
else // Ctrl+Up/Down moves the anchor without selecting else // Ctrl+Up/Down moves the anchor without selecting
this.currentIndex = c; this.currentIndex = c;
this.ensureRowIsVisible(c); this.treeBoxObject.ensureRowIsVisible(c);
]]> ]]>
</body> </body>
</method> </method>
@ -402,7 +414,7 @@
return; return;
if (this.view.selection.single) { if (this.view.selection.single) {
this.scrollByLines(offset); this.treeBoxObject.scrollByLines(offset);
return; return;
} }
@ -423,7 +435,7 @@
// Extend the selection from the existing pivot, if any // Extend the selection from the existing pivot, if any
this.view.selection.rangedSelect(-1, c + offset, this.view.selection.rangedSelect(-1, c + offset,
event.getModifierState("Accel")); event.getModifierState("Accel"));
this.ensureRowIsVisible(c + offset); this.treeBoxObject.ensureRowIsVisible(c + offset);
]]> ]]>
</body> </body>
@ -441,7 +453,7 @@
return; return;
if (this.pageUpOrDownMovesSelection == event.getModifierState("Accel")) { if (this.pageUpOrDownMovesSelection == event.getModifierState("Accel")) {
this.scrollByPages(offset); this.treeBoxObject.scrollByPages(offset);
return; return;
} }
@ -455,23 +467,23 @@
return; return;
if (c == edge && this.view.selection.isSelected(c)) { if (c == edge && this.view.selection.isSelected(c)) {
this.ensureRowIsVisible(c); this.treeBoxObject.ensureRowIsVisible(c);
return; return;
} }
var i = this.getFirstVisibleRow(); var i = this.treeBoxObject.getFirstVisibleRow();
var p = this.getPageLength(); var p = this.treeBoxObject.getPageLength();
if (offset > 0) { if (offset > 0) {
i += p - 1; i += p - 1;
if (c >= i) { if (c >= i) {
i = c + p; i = c + p;
this.ensureRowIsVisible(i > edge ? edge : i); this.treeBoxObject.ensureRowIsVisible(i > edge ? edge : i);
} }
i = i > edge ? edge : i; i = i > edge ? edge : i;
} else if (c <= i) { } else if (c <= i) {
i = c <= p ? 0 : c - p; i = c <= p ? 0 : c - p;
this.ensureRowIsVisible(i); this.treeBoxObject.ensureRowIsVisible(i);
} }
this.view.selection.timedSelect(i, this._selectDelay); this.view.selection.timedSelect(i, this._selectDelay);
]]> ]]>
@ -502,17 +514,17 @@
if (c == -1) if (c == -1)
return; return;
if (c == edge && this.view.selection.isSelected(c)) { if (c == edge && this.view.selection.isSelected(c)) {
this.ensureRowIsVisible(edge); this.treeBoxObject.ensureRowIsVisible(edge);
return; return;
} }
var i = this.getFirstVisibleRow(); var i = this.treeBoxObject.getFirstVisibleRow();
var p = this.getPageLength(); var p = this.treeBoxObject.getPageLength();
if (offset > 0) { if (offset > 0) {
i += p - 1; i += p - 1;
if (c >= i) { if (c >= i) {
i = c + p; i = c + p;
this.ensureRowIsVisible(i > edge ? edge : i); this.treeBoxObject.ensureRowIsVisible(i > edge ? edge : i);
} }
// Extend the selection from the existing pivot, if any // Extend the selection from the existing pivot, if any
this.view.selection.rangedSelect(-1, i > edge ? edge : i, event.getModifierState("Accel")); this.view.selection.rangedSelect(-1, i > edge ? edge : i, event.getModifierState("Accel"));
@ -521,7 +533,7 @@
if (c <= i) { if (c <= i) {
i = c <= p ? 0 : c - p; i = c <= p ? 0 : c - p;
this.ensureRowIsVisible(i); this.treeBoxObject.ensureRowIsVisible(i);
} }
// Extend the selection from the existing pivot, if any // Extend the selection from the existing pivot, if any
this.view.selection.rangedSelect(-1, i, event.getModifierState("Accel")); this.view.selection.rangedSelect(-1, i, event.getModifierState("Accel"));
@ -554,7 +566,7 @@
else if (!this.view.selection.single) else if (!this.view.selection.single)
this.currentIndex = edge; this.currentIndex = edge;
this.ensureRowIsVisible(edge); this.treeBoxObject.ensureRowIsVisible(edge);
]]> ]]>
</body> </body>
</method> </method>
@ -582,7 +594,7 @@
// -1 doesn't work here, so using currentIndex instead // -1 doesn't work here, so using currentIndex instead
this.view.selection.rangedSelect(this.currentIndex, edge, event.getModifierState("Accel")); this.view.selection.rangedSelect(this.currentIndex, edge, event.getModifierState("Accel"));
this.ensureRowIsVisible(edge); this.treeBoxObject.ensureRowIsVisible(edge);
]]> ]]>
</body> </body>
</method> </method>
@ -627,10 +639,10 @@
if (event.touches.length == 1 && if (event.touches.length == 1 &&
this._touchY >= 0) { this._touchY >= 0) {
var deltaY = this._touchY - event.touches[0].screenY; var deltaY = this._touchY - event.touches[0].screenY;
var lines = Math.trunc(deltaY / this.rowHeight); var lines = Math.trunc(deltaY / this.treeBoxObject.rowHeight);
if (Math.abs(lines) > 0) { if (Math.abs(lines) > 0) {
this.scrollByLines(lines); this.treeBoxObject.scrollByLines(lines);
deltaY -= lines * this.rowHeight; deltaY -= lines * this.treeBoxObject.rowHeight;
this._touchY = event.touches[0].screenY + deltaY; this._touchY = event.touches[0].screenY + deltaY;
} }
event.preventDefault(); event.preventDefault();
@ -662,11 +674,11 @@
var rows = event.detail; var rows = event.detail;
if (rows == UIEvent.SCROLL_PAGE_UP) if (rows == UIEvent.SCROLL_PAGE_UP)
this.scrollByPages(-1); this.treeBoxObject.scrollByPages(-1);
else if (rows == UIEvent.SCROLL_PAGE_DOWN) else if (rows == UIEvent.SCROLL_PAGE_DOWN)
this.scrollByPages(1); this.treeBoxObject.scrollByPages(1);
else else
this.scrollByLines(rows); this.treeBoxObject.scrollByLines(rows);
]]> ]]>
</handler> </handler>
<handler event="MozSwipeGesture" preventdefault="true"> <handler event="MozSwipeGesture" preventdefault="true">
@ -680,7 +692,7 @@
targetRow = this.view.rowCount - 1; targetRow = this.view.rowCount - 1;
// Fall through for actual action // Fall through for actual action
case event.DIRECTION_UP: case event.DIRECTION_UP:
this.ensureRowIsVisible(targetRow); this.treeBoxObject.ensureRowIsVisible(targetRow);
break; break;
} }
]]> ]]>
@ -689,13 +701,13 @@
action="if (event.originalTarget == this) this.stopEditing(true);"/> action="if (event.originalTarget == this) this.stopEditing(true);"/>
<handler event="focus"> <handler event="focus">
<![CDATA[ <![CDATA[
this.focused = true; this.treeBoxObject.focused = true;
if (this.currentIndex == -1 && this.view.rowCount > 0) { if (this.currentIndex == -1 && this.view.rowCount > 0) {
this.currentIndex = this.getFirstVisibleRow(); this.currentIndex = this.treeBoxObject.getFirstVisibleRow();
} }
]]> ]]>
</handler> </handler>
<handler event="blur" action="this.focused = false;"/> <handler event="blur" action="this.treeBoxObject.focused = false;"/>
<handler event="blur" phase="capturing" <handler event="blur" phase="capturing"
action="if (event.originalTarget == this.inputField.inputField) this.stopEditing(true);"/> action="if (event.originalTarget == this.inputField.inputField) this.stopEditing(true);"/>
<handler event="keydown" keycode="VK_RETURN"> <handler event="keydown" keycode="VK_RETURN">
@ -730,7 +742,7 @@
var parentIndex = this.view.getParentIndex(this.currentIndex); var parentIndex = this.view.getParentIndex(this.currentIndex);
if (parentIndex >= 0) { if (parentIndex >= 0) {
this.view.selection.select(parentIndex); this.view.selection.select(parentIndex);
this.ensureRowIsVisible(parentIndex); this.treeBoxObject.ensureRowIsVisible(parentIndex);
event.preventDefault(); event.preventDefault();
} }
]]> ]]>
@ -756,7 +768,7 @@
// The getParentIndex test above ensures that the children // The getParentIndex test above ensures that the children
// are already populated and ready. // are already populated and ready.
this.view.selection.timedSelect(c, this._selectDelay); this.view.selection.timedSelect(c, this._selectDelay);
this.ensureRowIsVisible(c); this.treeBoxObject.ensureRowIsVisible(c);
event.preventDefault(); event.preventDefault();
} }
]]> ]]>
@ -863,7 +875,7 @@
var l = this._keyNavigate(event); var l = this._keyNavigate(event);
if (l >= 0) { if (l >= 0) {
this.view.selection.timedSelect(l, this._selectDelay); this.view.selection.timedSelect(l, this._selectDelay);
this.ensureRowIsVisible(l); this.treeBoxObject.ensureRowIsVisible(l);
} }
event.preventDefault(); event.preventDefault();
} }