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 /* rendering object for HTML <frameset> elements */
8 
9 #ifndef nsHTMLFrameset_h___
10 #define nsHTMLFrameset_h___
11 
12 #include "mozilla/Attributes.h"
13 #include "mozilla/UniquePtr.h"
14 #include "nsContainerFrame.h"
15 #include "nsColor.h"
16 
17 class nsIContent;
18 class nsPresContext;
19 struct nsRect;
20 struct nsSize;
21 class nsAtom;
22 class nsHTMLFramesetBorderFrame;
23 class nsHTMLFramesetFrame;
24 
25 #define NO_COLOR 0xFFFFFFFA
26 
27 // defined at HTMLFrameSetElement.h
28 struct nsFramesetSpec;
29 
30 struct nsBorderColor {
31   nscolor mLeft;
32   nscolor mRight;
33   nscolor mTop;
34   nscolor mBottom;
35 
nsBorderColornsBorderColor36   nsBorderColor() { Set(NO_COLOR); }
37   ~nsBorderColor() = default;
SetnsBorderColor38   void Set(nscolor aColor) { mLeft = mRight = mTop = mBottom = aColor; }
39 };
40 
41 enum nsFrameborder {
42   eFrameborder_Yes = 0,
43   eFrameborder_No,
44   eFrameborder_Notset
45 };
46 
47 struct nsFramesetDrag {
48   nsHTMLFramesetFrame* mSource;  // frameset whose border was dragged to cause
49                                  // the resize
50   int32_t mIndex;   // index of left col or top row of effected area
51   int32_t mChange;  // pos for left to right or top to bottom, neg otherwise
52   bool mVertical;   // vertical if true, otherwise horizontal
53 
54   nsFramesetDrag();
55   void Reset(bool aVertical, int32_t aIndex, int32_t aChange,
56              nsHTMLFramesetFrame* aSource);
57   void UnSet();
58 };
59 
60 /*******************************************************************************
61  * nsHTMLFramesetFrame
62  ******************************************************************************/
63 class nsHTMLFramesetFrame final : public nsContainerFrame {
64  public:
65   NS_DECL_QUERYFRAME
66   NS_DECL_FRAMEARENA_HELPERS(nsHTMLFramesetFrame)
67 
68   explicit nsHTMLFramesetFrame(ComputedStyle* aStyle,
69                                nsPresContext* aPresContext);
70 
71   virtual ~nsHTMLFramesetFrame();
72 
73   virtual void Init(nsIContent* aContent, nsContainerFrame* aParent,
74                     nsIFrame* aPrevInFlow) override;
75 
76   virtual void SetInitialChildList(ChildListID aListID,
77                                    nsFrameList& aChildList) override;
78 
79   static bool gDragInProgress;
80 
81   void GetSizeOfChild(nsIFrame* aChild, mozilla::WritingMode aWM,
82                       mozilla::LogicalSize& aSize);
83 
84   void GetSizeOfChildAt(int32_t aIndexInParent, mozilla::WritingMode aWM,
85                         mozilla::LogicalSize& aSize, nsIntPoint& aCellIndex);
86 
87   virtual nsresult HandleEvent(nsPresContext* aPresContext,
88                                mozilla::WidgetGUIEvent* aEvent,
89                                nsEventStatus* aEventStatus) override;
90 
91   mozilla::Maybe<Cursor> GetCursor(const nsPoint&) override;
92 
93   virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder,
94                                 const nsDisplayListSet& aLists) override;
95 
96   virtual void Reflow(nsPresContext* aPresContext, ReflowOutput& aDesiredSize,
97                       const ReflowInput& aReflowInput,
98                       nsReflowStatus& aStatus) override;
99 
100 #ifdef DEBUG_FRAME_DUMP
101   virtual nsresult GetFrameName(nsAString& aResult) const override;
102 #endif
103 
104   void StartMouseDrag(nsPresContext* aPresContext,
105                       nsHTMLFramesetBorderFrame* aBorder,
106                       mozilla::WidgetGUIEvent* aEvent);
107 
108   void MouseDrag(nsPresContext* aPresContext, mozilla::WidgetGUIEvent* aEvent);
109 
110   void EndMouseDrag(nsPresContext* aPresContext);
111 
GetParentFrameborder()112   nsFrameborder GetParentFrameborder() { return mParentFrameborder; }
113 
SetParentFrameborder(nsFrameborder aValue)114   void SetParentFrameborder(nsFrameborder aValue) {
115     mParentFrameborder = aValue;
116   }
117 
GetDrag()118   nsFramesetDrag& GetDrag() { return mDrag; }
119 
120   void RecalculateBorderResize();
121 
122  protected:
123   void Scale(nscoord aDesired, int32_t aNumIndicies, int32_t* aIndicies,
124              int32_t aNumItems, int32_t* aItems);
125 
126   void CalculateRowCol(nsPresContext* aPresContext, nscoord aSize,
127                        int32_t aNumSpecs, const nsFramesetSpec* aSpecs,
128                        nscoord* aValues);
129 
130   void GenerateRowCol(nsPresContext* aPresContext, nscoord aSize,
131                       int32_t aNumSpecs, const nsFramesetSpec* aSpecs,
132                       nscoord* aValues, nsString& aNewAttr);
133 
134   virtual void GetDesiredSize(nsPresContext* aPresContext,
135                               const ReflowInput& aReflowInput,
136                               ReflowOutput& aDesiredSize);
137 
138   int32_t GetBorderWidth(nsPresContext* aPresContext,
139                          bool aTakeForcingIntoAccount);
140 
GetParentBorderWidth()141   int32_t GetParentBorderWidth() { return mParentBorderWidth; }
142 
SetParentBorderWidth(int32_t aWidth)143   void SetParentBorderWidth(int32_t aWidth) { mParentBorderWidth = aWidth; }
144 
GetParentBorderColor()145   nscolor GetParentBorderColor() { return mParentBorderColor; }
146 
SetParentBorderColor(nscolor aColor)147   void SetParentBorderColor(nscolor aColor) { mParentBorderColor = aColor; }
148 
149   nsFrameborder GetFrameBorder();
150 
151   nsFrameborder GetFrameBorder(nsIContent* aContent);
152 
153   nscolor GetBorderColor();
154 
155   nscolor GetBorderColor(nsIContent* aFrameContent);
156 
157   bool GetNoResize(nsIFrame* aChildFrame);
158 
159   void ReflowPlaceChild(nsIFrame* aChild, nsPresContext* aPresContext,
160                         const ReflowInput& aReflowInput, nsPoint& aOffset,
161                         nsSize& aSize, nsIntPoint* aCellIndex = 0);
162 
163   bool CanResize(bool aVertical, bool aLeft);
164 
165   bool CanChildResize(bool aVertical, bool aLeft, int32_t aChildX);
166 
167   void SetBorderResize(nsHTMLFramesetBorderFrame* aBorderFrame);
168 
169   template <typename T, class D = mozilla::DefaultDelete<T>>
170   using UniquePtr = mozilla::UniquePtr<T, D>;
171 
172   nsFramesetDrag mDrag;
173   nsBorderColor mEdgeColors;
174   nsHTMLFramesetBorderFrame* mDragger;
175   nsHTMLFramesetFrame* mTopLevelFrameset;
176   UniquePtr<nsHTMLFramesetBorderFrame*[]> mVerBorders;  // vertical borders
177   UniquePtr<nsHTMLFramesetBorderFrame*[]> mHorBorders;  // horizontal borders
178   UniquePtr<nsFrameborder[]>
179       mChildFrameborder;  // the frameborder attr of children
180   UniquePtr<nsBorderColor[]> mChildBorderColors;
181   UniquePtr<nscoord[]> mRowSizes;  // currently computed row sizes
182   UniquePtr<nscoord[]> mColSizes;  // currently computed col sizes
183   mozilla::LayoutDeviceIntPoint mFirstDragPoint;
184   int32_t mNumRows;
185   int32_t mNumCols;
186   int32_t mNonBorderChildCount;
187   int32_t mNonBlankChildCount;
188   int32_t mEdgeVisibility;
189   nsFrameborder mParentFrameborder;
190   nscolor mParentBorderColor;
191   int32_t mParentBorderWidth;
192   int32_t mPrevNeighborOrigSize;  // used during resize
193   int32_t mNextNeighborOrigSize;
194   int32_t mMinDrag;
195   int32_t mChildCount;
196 };
197 
198 #endif
199