Bug 1519960, add a previousColumn property for tree columns so that tree drag and drop will work without box objects, r=bzbarsky
authorNeil Deakin <neil@mozilla.com>
Thu, 07 Mar 2019 17:57:18 -0500
changeset 520880 bcc72374b769d03abf6eb717dcccec843066284b
parent 520879 759b643e17a91925deeefab4bcd97535625066cb
child 520881 5e8cc2d02203362b91e84197585de9a82eeeff64
push id10862
push userffxbld-merge
push dateMon, 11 Mar 2019 13:01:11 +0000
treeherdermozilla-beta@a2e7f5c935da [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbzbarsky
bugs1519960
milestone67.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1519960, add a previousColumn property for tree columns so that tree drag and drop will work without box objects, r=bzbarsky
dom/webidl/TreeColumn.webidl
layout/xul/tree/nsTreeColumns.cpp
layout/xul/tree/nsTreeColumns.h
toolkit/content/widgets/tree.js
--- a/dom/webidl/TreeColumn.webidl
+++ b/dom/webidl/TreeColumn.webidl
@@ -23,11 +23,17 @@ interface TreeColumn {
   const short TYPE_TEXT                = 1;
   const short TYPE_CHECKBOX            = 2;
   const short TYPE_PASSWORD            = 3;
   readonly attribute short type;
 
   TreeColumn? getNext();
   TreeColumn? getPrevious();
 
+  /**
+   * Returns the previous displayed column, if any, accounting for
+   * the ordinals set on the columns.
+   */
+  readonly attribute TreeColumn? previousColumn;
+
   [Throws]
   void invalidate();
 };
--- a/layout/xul/tree/nsTreeColumns.cpp
+++ b/layout/xul/tree/nsTreeColumns.cpp
@@ -231,16 +231,32 @@ int32_t nsTreeColumn::GetWidth(mozilla::
   if (NS_WARN_IF(!frame)) {
     aRv.Throw(NS_ERROR_FAILURE);
     return 0;
   }
 
   return nsPresContext::AppUnitsToIntCSSPixels(frame->GetRect().width);
 }
 
+already_AddRefed<nsTreeColumn> nsTreeColumn::GetPreviousColumn() {
+  nsIFrame* frame = GetFrame();
+  while (frame) {
+    frame = frame->GetPrevSibling();
+    if (frame && frame->GetContent()->IsElement()) {
+      RefPtr<nsTreeColumn> column =
+        mColumns->GetColumnFor(frame->GetContent()->AsElement());
+      if (column) {
+        return column.forget();
+      }
+    }
+  }
+
+  return nullptr;
+}
+
 nsTreeColumns::nsTreeColumns(nsTreeBodyFrame* aTree) : mTree(aTree) {}
 
 nsTreeColumns::~nsTreeColumns() { nsTreeColumns::InvalidateColumns(); }
 
 NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_0(nsTreeColumns)
 
 // QueryInterface implementation for nsTreeColumns
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsTreeColumns)
--- a/layout/xul/tree/nsTreeColumns.h
+++ b/layout/xul/tree/nsTreeColumns.h
@@ -66,16 +66,18 @@ class nsTreeColumn final : public nsISup
   bool Primary() const { return mIsPrimary; }
   bool Cycler() const { return mIsCycler; }
   bool Editable() const { return mIsEditable; }
   int16_t Type() const { return mType; }
 
   nsTreeColumn* GetNext() const { return mNext; }
   nsTreeColumn* GetPrevious() const { return mPrevious; }
 
+  already_AddRefed<nsTreeColumn> GetPreviousColumn();
+
   void Invalidate(mozilla::ErrorResult& aRv);
 
   friend class nsTreeBodyFrame;
   friend class nsTreeColumns;
 
  protected:
   ~nsTreeColumn();
   nsIFrame* GetFrame();
--- a/toolkit/content/widgets/tree.js
+++ b/toolkit/content/widgets/tree.js
@@ -330,25 +330,26 @@
       var val = this.getAttribute("ordinal");
       if (val == "")
         return "1";
 
       return "" + (val == "0" ? 0 : parseInt(val));
     }
 
     get _previousVisibleColumn() {
-      var sib = this.boxObject.previousSibling;
+      var tree = this.parentNode.parentNode;
+      let sib = tree.columns.getColumnFor(this).previousColumn;
       while (sib) {
-        if (sib.localName == "treecol" &&
-            sib.getBoundingClientRect().width > 0 &&
-            sib.parentNode == this.parentNode) {
-          return sib;
+        if (sib.element && sib.element.getBoundingClientRect().width > 0) {
+          return sib.element;
         }
-        sib = sib.boxObject.previousSibling;
+
+        sib = sib.previousColumn;
       }
+
       return null;
     }
 
     _onDragMouseMove(aEvent) {
       var col = document.treecolDragging;
       if (!col) return;
 
       // determine if we have moved the mouse far enough