1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4  * License, v. 2.0. If a copy of the MPL was not distributed with this
5  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 
7 #ifndef nsTreeBodyFrame_h
8 #define nsTreeBodyFrame_h
9 
10 #include "mozilla/AtomArray.h"
11 #include "mozilla/Attributes.h"
12 
13 #include "nsLeafBoxFrame.h"
14 #include "nsITreeView.h"
15 #include "nsIScrollbarMediator.h"
16 #include "nsITimer.h"
17 #include "nsIReflowCallback.h"
18 #include "nsTArray.h"
19 #include "nsTreeStyleCache.h"
20 #include "nsTreeColumns.h"
21 #include "nsTHashMap.h"
22 #include "nsTHashSet.h"
23 #include "imgIRequest.h"
24 #include "imgINotificationObserver.h"
25 #include "nsScrollbarFrame.h"
26 #include "nsThreadUtils.h"
27 #include "mozilla/LookAndFeel.h"
28 
29 class nsFontMetrics;
30 class nsOverflowChecker;
31 class nsTreeImageListener;
32 
33 namespace mozilla {
34 class PresShell;
35 namespace layout {
36 class ScrollbarActivity;
37 }  // namespace layout
38 }  // namespace mozilla
39 
40 // An entry in the tree's image cache
41 struct nsTreeImageCacheEntry {
42   nsTreeImageCacheEntry() = default;
nsTreeImageCacheEntrynsTreeImageCacheEntry43   nsTreeImageCacheEntry(imgIRequest* aRequest,
44                         imgINotificationObserver* aListener)
45       : request(aRequest), listener(aListener) {}
46 
47   nsCOMPtr<imgIRequest> request;
48   nsCOMPtr<imgINotificationObserver> listener;
49 };
50 
51 // The actual frame that paints the cells and rows.
52 class nsTreeBodyFrame final : public nsLeafBoxFrame,
53                               public nsIScrollbarMediator,
54                               public nsIReflowCallback {
55   typedef mozilla::layout::ScrollbarActivity ScrollbarActivity;
56   typedef mozilla::image::ImgDrawResult ImgDrawResult;
57 
58  public:
59   explicit nsTreeBodyFrame(ComputedStyle* aStyle, nsPresContext* aPresContext);
60   ~nsTreeBodyFrame();
61 
62   NS_DECL_QUERYFRAME
63   NS_DECL_FRAMEARENA_HELPERS(nsTreeBodyFrame)
64 
65   // Callback handler methods for refresh driver based animations.
66   // Calls to these functions are forwarded from nsTreeImageListener. These
67   // mirror how nsImageFrame works.
68   void OnImageIsAnimated(imgIRequest* aRequest);
69 
70   // non-virtual signatures like nsITreeBodyFrame
Columns()71   already_AddRefed<nsTreeColumns> Columns() const {
72     RefPtr<nsTreeColumns> cols = mColumns;
73     return cols.forget();
74   }
GetExistingView()75   already_AddRefed<nsITreeView> GetExistingView() const {
76     nsCOMPtr<nsITreeView> view = mView;
77     return view.forget();
78   }
79   nsresult GetView(nsITreeView** aView);
80   nsresult SetView(nsITreeView* aView);
GetFocused()81   bool GetFocused() const { return mFocused; }
82   nsresult SetFocused(bool aFocused);
83   nsresult GetTreeBody(mozilla::dom::Element** aElement);
84   int32_t RowHeight() const;
85   int32_t RowWidth();
86   int32_t GetHorizontalPosition() const;
87   mozilla::Maybe<mozilla::CSSIntRegion> GetSelectionRegion();
FirstVisibleRow()88   int32_t FirstVisibleRow() const { return mTopRowIndex; }
LastVisibleRow()89   int32_t LastVisibleRow() const { return mTopRowIndex + mPageLength; }
PageLength()90   int32_t PageLength() const { return mPageLength; }
91   nsresult EnsureRowIsVisible(int32_t aRow);
92   nsresult EnsureCellIsVisible(int32_t aRow, nsTreeColumn* aCol);
93   void ScrollToRow(int32_t aRow);
94   void ScrollByLines(int32_t aNumLines);
95   void ScrollByPages(int32_t aNumPages);
96   nsresult Invalidate();
97   nsresult InvalidateColumn(nsTreeColumn* aCol);
98   nsresult InvalidateRow(int32_t aRow);
99   nsresult InvalidateCell(int32_t aRow, nsTreeColumn* aCol);
100   nsresult InvalidateRange(int32_t aStart, int32_t aEnd);
101   int32_t GetRowAt(int32_t aX, int32_t aY);
102   nsresult GetCellAt(int32_t aX, int32_t aY, int32_t* aRow, nsTreeColumn** aCol,
103                      nsACString& aChildElt);
104   nsresult GetCoordsForCellItem(int32_t aRow, nsTreeColumn* aCol,
105                                 const nsACString& aElt, int32_t* aX,
106                                 int32_t* aY, int32_t* aWidth, int32_t* aHeight);
107   nsresult IsCellCropped(int32_t aRow, nsTreeColumn* aCol, bool* aResult);
108   nsresult RowCountChanged(int32_t aIndex, int32_t aCount);
109   nsresult BeginUpdateBatch();
110   nsresult EndUpdateBatch();
111   nsresult ClearStyleAndImageCaches();
112   void RemoveImageCacheEntry(int32_t aRowIndex, nsTreeColumn* aCol);
113 
114   void CancelImageRequests();
115 
116   void ManageReflowCallback(const nsRect& aRect, nscoord aHorzWidth);
117 
118   virtual nsSize GetXULMinSize(nsBoxLayoutState& aBoxLayoutState) override;
119   virtual void SetXULBounds(nsBoxLayoutState& aBoxLayoutState,
120                             const nsRect& aRect,
121                             bool aRemoveOverflowArea = false) override;
122 
123   // nsIReflowCallback
124   virtual bool ReflowFinished() override;
125   virtual void ReflowCallbackCanceled() override;
126 
127   // nsIScrollbarMediator
128   virtual void ScrollByPage(nsScrollbarFrame* aScrollbar, int32_t aDirection,
129                             nsIScrollbarMediator::ScrollSnapMode aSnap =
130                                 nsIScrollbarMediator::DISABLE_SNAP) override;
131   virtual void ScrollByWhole(nsScrollbarFrame* aScrollbar, int32_t aDirection,
132                              nsIScrollbarMediator::ScrollSnapMode aSnap =
133                                  nsIScrollbarMediator::DISABLE_SNAP) override;
134   virtual void ScrollByLine(nsScrollbarFrame* aScrollbar, int32_t aDirection,
135                             nsIScrollbarMediator::ScrollSnapMode aSnap =
136                                 nsIScrollbarMediator::DISABLE_SNAP) override;
137   virtual void ScrollByUnit(nsScrollbarFrame* aScrollbar,
138                             mozilla::ScrollMode aMode, int32_t aDirection,
139                             mozilla::ScrollUnit aUnit,
140                             ScrollSnapMode aSnap = DISABLE_SNAP) override;
141   virtual void RepeatButtonScroll(nsScrollbarFrame* aScrollbar) override;
142   virtual void ThumbMoved(nsScrollbarFrame* aScrollbar, nscoord aOldPos,
143                           nscoord aNewPos) override;
ScrollbarReleased(nsScrollbarFrame * aScrollbar)144   virtual void ScrollbarReleased(nsScrollbarFrame* aScrollbar) override {}
VisibilityChanged(bool aVisible)145   virtual void VisibilityChanged(bool aVisible) override { Invalidate(); }
GetScrollbarBox(bool aVertical)146   virtual nsIFrame* GetScrollbarBox(bool aVertical) override {
147     ScrollParts parts = GetScrollParts();
148     return aVertical ? parts.mVScrollbar : parts.mHScrollbar;
149   }
150   virtual void ScrollbarActivityStarted() const override;
151   virtual void ScrollbarActivityStopped() const override;
IsScrollbarOnRight()152   virtual bool IsScrollbarOnRight() const override {
153     return StyleVisibility()->mDirection == mozilla::StyleDirection::Ltr;
154   }
ShouldSuppressScrollbarRepaints()155   virtual bool ShouldSuppressScrollbarRepaints() const override {
156     return false;
157   }
158 
159   // Overridden from nsIFrame to cache our pres context.
160   virtual void Init(nsIContent* aContent, nsContainerFrame* aParent,
161                     nsIFrame* aPrevInFlow) override;
162   virtual void DestroyFrom(nsIFrame* aDestructRoot,
163                            PostDestroyData& aPostDestroyData) override;
164 
165   mozilla::Maybe<Cursor> GetCursor(const nsPoint&) override;
166 
167   virtual nsresult HandleEvent(nsPresContext* aPresContext,
168                                mozilla::WidgetGUIEvent* aEvent,
169                                nsEventStatus* aEventStatus) override;
170 
171   virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder,
172                                 const nsDisplayListSet& aLists) override;
173 
174   virtual void DidSetComputedStyle(ComputedStyle* aOldComputedStyle) override;
175 
176   friend nsIFrame* NS_NewTreeBodyFrame(mozilla::PresShell* aPresShell);
177   friend class nsTreeColumn;
178 
179   struct ScrollParts {
180     nsScrollbarFrame* mVScrollbar;
181     RefPtr<mozilla::dom::Element> mVScrollbarContent;
182     nsScrollbarFrame* mHScrollbar;
183     RefPtr<mozilla::dom::Element> mHScrollbarContent;
184     nsIFrame* mColumnsFrame;
185     nsIScrollableFrame* mColumnsScrollFrame;
186   };
187 
188   ImgDrawResult PaintTreeBody(gfxContext& aRenderingContext,
189                               const nsRect& aDirtyRect, nsPoint aPt,
190                               nsDisplayListBuilder* aBuilder);
191 
192   // Get the base element, <tree>
193   mozilla::dom::XULTreeElement* GetBaseElement();
194 
GetVerticalOverflow()195   bool GetVerticalOverflow() const { return mVerticalOverflow; }
GetHorizontalOverflow()196   bool GetHorizontalOverflow() const { return mHorizontalOverflow; }
197 
198   // This returns the property array where atoms are stored for style during
199   // draw, whether the row currently being drawn is selected, hovered, etc.
GetPropertyArrayForCurrentDrawingItem()200   const mozilla::AtomArray& GetPropertyArrayForCurrentDrawingItem() {
201     return mScratchArray;
202   }
203 
204  protected:
205   friend class nsOverflowChecker;
206 
207   // This method paints a specific column background of the tree.
208   ImgDrawResult PaintColumn(nsTreeColumn* aColumn, const nsRect& aColumnRect,
209                             nsPresContext* aPresContext,
210                             gfxContext& aRenderingContext,
211                             const nsRect& aDirtyRect);
212 
213   // This method paints a single row in the tree.
214   ImgDrawResult PaintRow(int32_t aRowIndex, const nsRect& aRowRect,
215                          nsPresContext* aPresContext,
216                          gfxContext& aRenderingContext,
217                          const nsRect& aDirtyRect, nsPoint aPt,
218                          nsDisplayListBuilder* aBuilder);
219 
220   // This method paints a single separator in the tree.
221   ImgDrawResult PaintSeparator(int32_t aRowIndex, const nsRect& aSeparatorRect,
222                                nsPresContext* aPresContext,
223                                gfxContext& aRenderingContext,
224                                const nsRect& aDirtyRect);
225 
226   // This method paints a specific cell in a given row of the tree.
227   ImgDrawResult PaintCell(int32_t aRowIndex, nsTreeColumn* aColumn,
228                           const nsRect& aCellRect, nsPresContext* aPresContext,
229                           gfxContext& aRenderingContext,
230                           const nsRect& aDirtyRect, nscoord& aCurrX,
231                           nsPoint aPt, nsDisplayListBuilder* aBuilder);
232 
233   // This method paints the twisty inside a cell in the primary column of an
234   // tree.
235   ImgDrawResult PaintTwisty(int32_t aRowIndex, nsTreeColumn* aColumn,
236                             const nsRect& aTwistyRect,
237                             nsPresContext* aPresContext,
238                             gfxContext& aRenderingContext,
239                             const nsRect& aDirtyRect, nscoord& aRemainingWidth,
240                             nscoord& aCurrX);
241 
242   // This method paints the image inside the cell of an tree.
243   ImgDrawResult PaintImage(int32_t aRowIndex, nsTreeColumn* aColumn,
244                            const nsRect& aImageRect,
245                            nsPresContext* aPresContext,
246                            gfxContext& aRenderingContext,
247                            const nsRect& aDirtyRect, nscoord& aRemainingWidth,
248                            nscoord& aCurrX, nsDisplayListBuilder* aBuilder);
249 
250   // This method paints the text string inside a particular cell of the tree.
251   ImgDrawResult PaintText(int32_t aRowIndex, nsTreeColumn* aColumn,
252                           const nsRect& aTextRect, nsPresContext* aPresContext,
253                           gfxContext& aRenderingContext,
254                           const nsRect& aDirtyRect, nscoord& aCurrX);
255 
256   // This method paints the checkbox inside a particular cell of the tree.
257   ImgDrawResult PaintCheckbox(int32_t aRowIndex, nsTreeColumn* aColumn,
258                               const nsRect& aCheckboxRect,
259                               nsPresContext* aPresContext,
260                               gfxContext& aRenderingContext,
261                               const nsRect& aDirtyRect);
262 
263   // This method paints a drop feedback of the tree.
264   ImgDrawResult PaintDropFeedback(const nsRect& aDropFeedbackRect,
265                                   nsPresContext* aPresContext,
266                                   gfxContext& aRenderingContext,
267                                   const nsRect& aDirtyRect, nsPoint aPt);
268 
269   // This method is called with a specific ComputedStyle and rect to
270   // paint the background rect as if it were a full-blown frame.
271   ImgDrawResult PaintBackgroundLayer(ComputedStyle* aComputedStyle,
272                                      nsPresContext* aPresContext,
273                                      gfxContext& aRenderingContext,
274                                      const nsRect& aRect,
275                                      const nsRect& aDirtyRect);
276 
277   // An internal hit test.  aX and aY are expected to be in twips in the
278   // coordinate system of this frame.
279   int32_t GetRowAtInternal(nscoord aX, nscoord aY);
280 
281   // Check for bidi characters in the text, and if there are any, ensure
282   // that the prescontext is in bidi mode.
283   void CheckTextForBidi(nsAutoString& aText);
284 
285   void AdjustForCellText(nsAutoString& aText, int32_t aRowIndex,
286                          nsTreeColumn* aColumn, gfxContext& aRenderingContext,
287                          nsFontMetrics& aFontMetrics, nsRect& aTextRect);
288 
289   // A helper used when hit testing.
290   nsCSSAnonBoxPseudoStaticAtom* GetItemWithinCellAt(nscoord aX,
291                                                     const nsRect& aCellRect,
292                                                     int32_t aRowIndex,
293                                                     nsTreeColumn* aColumn);
294 
295   // An internal hit test.  aX and aY are expected to be in twips in the
296   // coordinate system of this frame.
297   void GetCellAt(nscoord aX, nscoord aY, int32_t* aRow, nsTreeColumn** aCol,
298                  nsCSSAnonBoxPseudoStaticAtom** aChildElt);
299 
300   // Retrieve the area for the twisty for a cell.
301   nsITheme* GetTwistyRect(int32_t aRowIndex, nsTreeColumn* aColumn,
302                           nsRect& aImageRect, nsRect& aTwistyRect,
303                           nsPresContext* aPresContext,
304                           ComputedStyle* aTwistyContext);
305 
306   // Fetch an image from the image cache.
307   nsresult GetImage(int32_t aRowIndex, nsTreeColumn* aCol, bool aUseContext,
308                     ComputedStyle* aComputedStyle, bool& aAllowImageRegions,
309                     imgIContainer** aResult);
310 
311   // Returns the size of a given image.   This size *includes* border and
312   // padding.  It does not include margins.
313   nsRect GetImageSize(int32_t aRowIndex, nsTreeColumn* aCol, bool aUseContext,
314                       ComputedStyle* aComputedStyle);
315 
316   // Returns the destination size of the image, not including borders and
317   // padding.
318   nsSize GetImageDestSize(ComputedStyle* aComputedStyle, bool useImageRegion,
319                           imgIContainer* image);
320 
321   // Returns the source rectangle of the image to be displayed.
322   nsRect GetImageSourceRect(ComputedStyle* aComputedStyle, bool useImageRegion,
323                             imgIContainer* image);
324 
325   // Returns the height of rows in the tree.
326   int32_t GetRowHeight();
327 
328   // Returns our indentation width.
329   int32_t GetIndentation();
330 
331   // Calculates our width/height once border and padding have been removed.
332   void CalcInnerBox();
333 
334   // Calculate the total width of our scrollable portion
335   nscoord CalcHorzWidth(const ScrollParts& aParts);
336 
337   // Looks up a ComputedStyle in the style cache.  On a cache miss we resolve
338   // the pseudo-styles passed in and place them into the cache.
339   ComputedStyle* GetPseudoComputedStyle(
340       nsCSSAnonBoxPseudoStaticAtom* aPseudoElement);
341 
342   // Retrieves the scrollbars and scrollview relevant to this treebody. We
343   // traverse the frame tree under our base element, in frame order, looking
344   // for the first relevant vertical scrollbar, horizontal scrollbar, and
345   // scrollable frame (with associated content and scrollable view). These
346   // are all volatile and should not be retained.
347   ScrollParts GetScrollParts();
348 
349   // Update the curpos of the scrollbar.
350   void UpdateScrollbars(const ScrollParts& aParts);
351 
352   // Update the maxpos of the scrollbar.
353   void InvalidateScrollbars(const ScrollParts& aParts,
354                             AutoWeakFrame& aWeakColumnsFrame);
355 
356   // Check overflow and generate events.
357   MOZ_CAN_RUN_SCRIPT_BOUNDARY void CheckOverflow(const ScrollParts& aParts);
358 
359   // Calls UpdateScrollbars, Invalidate aNeedsFullInvalidation if true,
360   // InvalidateScrollbars and finally CheckOverflow.
361   // returns true if the frame is still alive after the method call.
362   bool FullScrollbarsUpdate(bool aNeedsFullInvalidation);
363 
364   // Use to auto-fill some of the common properties without the view having to
365   // do it. Examples include container, open, selected, and focus.
366   void PrefillPropertyArray(int32_t aRowIndex, nsTreeColumn* aCol);
367 
368   // Our internal scroll method, used by all the public scroll methods.
369   nsresult ScrollInternal(const ScrollParts& aParts, int32_t aRow);
370   nsresult ScrollToRowInternal(const ScrollParts& aParts, int32_t aRow);
371   nsresult ScrollHorzInternal(const ScrollParts& aParts, int32_t aPosition);
372   nsresult EnsureRowIsVisibleInternal(const ScrollParts& aParts, int32_t aRow);
373 
374   // Convert client pixels into appunits in our coordinate space.
375   nsPoint AdjustClientCoordsToBoxCoordSpace(int32_t aX, int32_t aY);
376 
377   void EnsureView();
378 
379   nsresult GetCellWidth(int32_t aRow, nsTreeColumn* aCol,
380                         gfxContext* aRenderingContext, nscoord& aDesiredSize,
381                         nscoord& aCurrentSize);
382   nscoord CalcMaxRowWidth();
383 
384   // Translate the given rect horizontally from tree coordinates into the
385   // coordinate system of our nsTreeBodyFrame.  If clip is true, then clip the
386   // rect to its intersection with mInnerBox in the horizontal direction.
387   // Return whether the result has a nonempty intersection with mInnerBox
388   // after projecting both onto the horizontal coordinate axis.
389   bool OffsetForHorzScroll(nsRect& rect, bool clip);
390 
391   bool CanAutoScroll(int32_t aRowIndex);
392 
393   // Calc the row and above/below/on status given where the mouse currently is
394   // hovering. Also calc if we're in the region in which we want to auto-scroll
395   // the tree. A positive value of |aScrollLines| means scroll down, a negative
396   // value means scroll up, a zero value means that we aren't in drag scroll
397   // region.
398   void ComputeDropPosition(mozilla::WidgetGUIEvent* aEvent, int32_t* aRow,
399                            int16_t* aOrient, int16_t* aScrollLines);
400 
InvalidateDropFeedback(int32_t aRow,int16_t aOrientation)401   void InvalidateDropFeedback(int32_t aRow, int16_t aOrientation) {
402     InvalidateRow(aRow);
403     if (aOrientation != nsITreeView::DROP_ON)
404       InvalidateRow(aRow + aOrientation);
405   }
406 
407  public:
408   /**
409    * Remove an nsITreeImageListener from being tracked by this frame. Only tree
410    * image listeners that are created by this frame are tracked.
411    *
412    * @param aListener A pointer to an nsTreeImageListener to no longer
413    *        track.
414    */
415   void RemoveTreeImageListener(nsTreeImageListener* aListener);
416 
417  protected:
418   // Create a new timer. This method is used to delay various actions like
419   // opening/closing folders or tree scrolling.
420   // aID is type of the action, aFunc is the function to be called when
421   // the timer fires and aType is type of timer - one shot or repeating.
422   nsresult CreateTimer(const mozilla::LookAndFeel::IntID aID,
423                        nsTimerCallbackFunc aFunc, int32_t aType,
424                        nsITimer** aTimer, const char* aName);
425 
426   static void OpenCallback(nsITimer* aTimer, void* aClosure);
427 
428   static void CloseCallback(nsITimer* aTimer, void* aClosure);
429 
430   static void LazyScrollCallback(nsITimer* aTimer, void* aClosure);
431 
432   static void ScrollCallback(nsITimer* aTimer, void* aClosure);
433 
434   class ScrollEvent : public mozilla::Runnable {
435    public:
436     NS_DECL_NSIRUNNABLE
ScrollEvent(nsTreeBodyFrame * aInner)437     explicit ScrollEvent(nsTreeBodyFrame* aInner)
438         : mozilla::Runnable("nsTreeBodyFrame::ScrollEvent"), mInner(aInner) {}
Revoke()439     void Revoke() { mInner = nullptr; }
440 
441    private:
442     nsTreeBodyFrame* mInner;
443   };
444 
445   void PostScrollEvent();
446   void FireScrollEvent();
447 
448   /**
449    * Clear the pointer to this frame for all nsTreeImageListeners that were
450    * created by this frame.
451    */
452   void DetachImageListeners();
453 
454 #ifdef ACCESSIBILITY
455   /**
456    * Fires 'treeRowCountChanged' event asynchronously. The event is a
457    * CustomEvent that is used to expose the following information structures
458    * via a property bag.
459    *
460    * @param aIndex  the row index rows are added/removed from
461    * @param aCount  the number of added/removed rows (the sign points to
462    *                an operation, plus - addition, minus - removing)
463    */
464   void FireRowCountChangedEvent(int32_t aIndex, int32_t aCount);
465 
466   /**
467    * Fires 'treeInvalidated' event asynchronously. The event is a CustomEvent
468    * that is used to expose the information structures described by method
469    * arguments via a property bag.
470    *
471    * @param aStartRow  the start index of invalidated rows, -1 means that
472    *                   columns have been invalidated only
473    * @param aEndRow    the end index of invalidated rows, -1 means that columns
474    *                   have been invalidated only
475    * @param aStartCol  the start invalidated column, nullptr means that only
476    *                   rows have been invalidated
477    * @param aEndCol    the end invalidated column, nullptr means that rows have
478    *                   been invalidated only
479    */
480   void FireInvalidateEvent(int32_t aStartRow, int32_t aEndRow,
481                            nsTreeColumn* aStartCol, nsTreeColumn* aEndCol);
482 #endif
483 
484  protected:  // Data Members
485   class Slots {
486    public:
Slots()487     Slots()
488         : mDropAllowed(false),
489           mIsDragging(false),
490           mDropRow(-1),
491           mDropOrient(-1),
492           mScrollLines(0),
493           mDragAction(0) {}
494 
~Slots()495     ~Slots() {
496       if (mTimer) mTimer->Cancel();
497     }
498 
499     friend class nsTreeBodyFrame;
500 
501    protected:
502     // If the drop is actually allowed here or not.
503     bool mDropAllowed;
504 
505     // True while dragging over the tree.
506     bool mIsDragging;
507 
508     // The row the mouse is hovering over during a drop.
509     int32_t mDropRow;
510 
511     // Where we want to draw feedback (above/on this row/below) if allowed.
512     int16_t mDropOrient;
513 
514     // Number of lines to be scrolled.
515     int16_t mScrollLines;
516 
517     // The drag action that was received for this slot
518     uint32_t mDragAction;
519 
520     // Timer for opening/closing spring loaded folders or scrolling the tree.
521     nsCOMPtr<nsITimer> mTimer;
522 
523     // An array used to keep track of all spring loaded folders.
524     nsTArray<int32_t> mArray;
525   };
526 
527   Slots* mSlots;
528 
529   nsRevocableEventPtr<ScrollEvent> mScrollEvent;
530 
531   RefPtr<ScrollbarActivity> mScrollbarActivity;
532 
533   // The <tree> element containing this treebody.
534   RefPtr<mozilla::dom::XULTreeElement> mTree;
535 
536   // Cached column information.
537   RefPtr<nsTreeColumns> mColumns;
538 
539   // The current view for this tree widget.  We get all of our row and cell data
540   // from the view.
541   nsCOMPtr<nsITreeView> mView;
542 
543   // A cache of all the ComputedStyles we have seen for rows and cells of the
544   // tree.  This is a mapping from a list of atoms to a corresponding
545   // ComputedStyle.  This cache stores every combination that occurs in the
546   // tree, so for n distinct properties, this cache could have 2 to the n
547   // entries (the power set of all row properties).
548   nsTreeStyleCache mStyleCache;
549 
550   // A hashtable that maps from URLs to image request/listener pairs.  The URL
551   // is provided by the view or by the ComputedStyle. The ComputedStyle
552   // represents a resolved :-moz-tree-cell-image (or twisty) pseudo-element.
553   // It maps directly to an imgIRequest.
554   nsTHashMap<nsStringHashKey, nsTreeImageCacheEntry> mImageCache;
555 
556   // A scratch array used when looking up cached ComputedStyles.
557   mozilla::AtomArray mScratchArray;
558 
559   // The index of the first visible row and the # of rows visible onscreen.
560   // The tree only examines onscreen rows, starting from
561   // this index and going up to index+pageLength.
562   int32_t mTopRowIndex;
563   int32_t mPageLength;
564 
565   // The horizontal scroll position
566   nscoord mHorzPosition;
567 
568   // The original desired horizontal width before changing it and posting a
569   // reflow callback. In some cases, the desired horizontal width can first be
570   // different from the current desired horizontal width, only to return to
571   // the same value later during the same reflow. In this case, we can cancel
572   // the posted reflow callback and prevent an unnecessary reflow.
573   nscoord mOriginalHorzWidth;
574   // Our desired horizontal width (the width for which we actually have tree
575   // columns).
576   nscoord mHorzWidth;
577   // The amount by which to adjust the width of the last cell.
578   // This depends on whether or not the columnpicker and scrollbars are present.
579   nscoord mAdjustWidth;
580 
581   // Cached heights and indent info.
582   nsRect mInnerBox;  // 4-byte aligned
583   int32_t mRowHeight;
584   int32_t mIndentation;
585   nscoord mStringWidth;
586 
587   int32_t mUpdateBatchNest;
588 
589   // Cached row count.
590   int32_t mRowCount;
591 
592   // The row the mouse is hovering over.
593   int32_t mMouseOverRow;
594 
595   // Whether or not we're currently focused.
596   bool mFocused;
597 
598   // Do we have a fixed number of onscreen rows?
599   bool mHasFixedRowCount;
600 
601   bool mVerticalOverflow;
602   bool mHorizontalOverflow;
603 
604   bool mReflowCallbackPosted;
605 
606   // Set while we flush layout to take account of effects of
607   // overflow/underflow event handlers
608   bool mCheckingOverflow;
609 
610   // Hash set to keep track of which listeners we created and thus
611   // have pointers to us.
612   nsTHashSet<nsTreeImageListener*> mCreatedListeners;
613 
614 };  // class nsTreeBodyFrame
615 
616 #endif
617