LCOV - code coverage report
Current view: top level - layout/generic - nsFrameSetFrame.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 0 796 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 76 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2             : /* This Source Code Form is subject to the terms of the Mozilla Public
       3             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       4             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       5             : 
       6             : /* rendering object for HTML <frameset> elements */
       7             : 
       8             : #include "nsFrameSetFrame.h"
       9             : 
      10             : #include "gfxContext.h"
      11             : #include "gfxUtils.h"
      12             : #include "mozilla/DebugOnly.h"
      13             : #include "mozilla/gfx/2D.h"
      14             : #include "mozilla/gfx/Helpers.h"
      15             : #include "mozilla/Likely.h"
      16             : 
      17             : #include "nsGenericHTMLElement.h"
      18             : #include "nsAttrValueInlines.h"
      19             : #include "nsLeafFrame.h"
      20             : #include "nsContainerFrame.h"
      21             : #include "nsLayoutUtils.h"
      22             : #include "nsPresContext.h"
      23             : #include "nsIPresShell.h"
      24             : #include "nsGkAtoms.h"
      25             : #include "nsStyleConsts.h"
      26             : #include "nsStyleContext.h"
      27             : #include "nsHTMLParts.h"
      28             : #include "nsIDOMMutationEvent.h"
      29             : #include "nsNameSpaceManager.h"
      30             : #include "nsCSSAnonBoxes.h"
      31             : #include "mozilla/StyleSetHandle.h"
      32             : #include "mozilla/StyleSetHandleInlines.h"
      33             : #include "mozilla/dom/Element.h"
      34             : #include "nsDisplayList.h"
      35             : #include "nsNodeUtils.h"
      36             : #include "mozAutoDocUpdate.h"
      37             : #include "mozilla/Preferences.h"
      38             : #include "mozilla/dom/HTMLFrameSetElement.h"
      39             : #include "mozilla/LookAndFeel.h"
      40             : #include "mozilla/MouseEvents.h"
      41             : #include "nsSubDocumentFrame.h"
      42             : 
      43             : using namespace mozilla;
      44             : using namespace mozilla::dom;
      45             : using namespace mozilla::gfx;
      46             : 
      47             : // masks for mEdgeVisibility
      48             : #define LEFT_VIS   0x0001
      49             : #define RIGHT_VIS  0x0002
      50             : #define TOP_VIS    0x0004
      51             : #define BOTTOM_VIS 0x0008
      52             : #define ALL_VIS    0x000F
      53             : #define NONE_VIS   0x0000
      54             : 
      55             : /*******************************************************************************
      56             :  * nsFramesetDrag
      57             :  ******************************************************************************/
      58           0 : nsFramesetDrag::nsFramesetDrag()
      59             : {
      60           0 :   UnSet();
      61           0 : }
      62             : 
      63           0 : void nsFramesetDrag::Reset(bool                 aVertical,
      64             :                            int32_t              aIndex,
      65             :                            int32_t              aChange,
      66             :                            nsHTMLFramesetFrame* aSource)
      67             : {
      68           0 :   mVertical = aVertical;
      69           0 :   mIndex    = aIndex;
      70           0 :   mChange   = aChange;
      71           0 :   mSource   = aSource;
      72           0 : }
      73             : 
      74           0 : void nsFramesetDrag::UnSet()
      75             : {
      76           0 :   mVertical = true;
      77           0 :   mIndex    = -1;
      78           0 :   mChange   = 0;
      79           0 :   mSource   = nullptr;
      80           0 : }
      81             : 
      82             : /*******************************************************************************
      83             :  * nsHTMLFramesetBorderFrame
      84             :  ******************************************************************************/
      85             : class nsHTMLFramesetBorderFrame final : public nsLeafFrame
      86             : {
      87             : public:
      88           0 :   NS_DECL_FRAMEARENA_HELPERS(nsHTMLFramesetBorderFrame)
      89             : 
      90             : #ifdef DEBUG_FRAME_DUMP
      91             :   virtual nsresult GetFrameName(nsAString& aResult) const override;
      92             : #endif
      93             : 
      94             :   virtual nsresult HandleEvent(nsPresContext* aPresContext,
      95             :                                WidgetGUIEvent* aEvent,
      96             :                                nsEventStatus* aEventStatus) override;
      97             : 
      98             :   virtual nsresult GetCursor(const nsPoint&    aPoint,
      99             :                              nsIFrame::Cursor& aCursor) override;
     100             : 
     101             :   virtual void BuildDisplayList(nsDisplayListBuilder*   aBuilder,
     102             :                                 const nsRect&           aDirtyRect,
     103             :                                 const nsDisplayListSet& aLists) override;
     104             : 
     105             :   virtual void Reflow(nsPresContext*           aPresContext,
     106             :                           ReflowOutput&     aDesiredSize,
     107             :                           const ReflowInput& aReflowInput,
     108             :                           nsReflowStatus&          aStatus) override;
     109             : 
     110             :   bool GetVisibility() { return mVisibility; }
     111             :   void SetVisibility(bool aVisibility);
     112             :   void SetColor(nscolor aColor);
     113             : 
     114             :   void PaintBorder(DrawTarget* aDrawTarget, nsPoint aPt);
     115             : 
     116             : protected:
     117             :   nsHTMLFramesetBorderFrame(nsStyleContext* aContext, int32_t aWidth, bool aVertical, bool aVisible);
     118             :   virtual ~nsHTMLFramesetBorderFrame();
     119             :   virtual nscoord GetIntrinsicISize() override;
     120             :   virtual nscoord GetIntrinsicBSize() override;
     121             : 
     122             :   // the prev and next neighbors are indexes into the row (for a horizontal border) or col (for
     123             :   // a vertical border) of nsHTMLFramesetFrames or nsHTMLFrames
     124             :   int32_t mPrevNeighbor;
     125             :   int32_t mNextNeighbor;
     126             :   nscolor mColor;
     127             :   int32_t mWidth;
     128             :   bool mVertical;
     129             :   bool mVisibility;
     130             :   bool mCanResize;
     131             :   friend class nsHTMLFramesetFrame;
     132             : };
     133             : /*******************************************************************************
     134             :  * nsHTMLFramesetBlankFrame
     135             :  ******************************************************************************/
     136             : class nsHTMLFramesetBlankFrame final : public nsLeafFrame
     137             : {
     138             : public:
     139             :   NS_DECL_QUERYFRAME
     140           0 :   NS_DECL_FRAMEARENA_HELPERS(nsHTMLFramesetBlankFrame)
     141             : 
     142             : #ifdef DEBUG_FRAME_DUMP
     143           0 :   virtual nsresult GetFrameName(nsAString& aResult) const override
     144             :   {
     145           0 :     return MakeFrameName(NS_LITERAL_STRING("FramesetBlank"), aResult);
     146             :   }
     147             : #endif
     148             : 
     149             :   virtual void BuildDisplayList(nsDisplayListBuilder*   aBuilder,
     150             :                                 const nsRect&           aDirtyRect,
     151             :                                 const nsDisplayListSet& aLists) override;
     152             : 
     153             :   virtual void Reflow(nsPresContext*           aPresContext,
     154             :                           ReflowOutput&     aDesiredSize,
     155             :                           const ReflowInput& aReflowInput,
     156             :                           nsReflowStatus&          aStatus) override;
     157             : 
     158             : protected:
     159           0 :   explicit nsHTMLFramesetBlankFrame(nsStyleContext* aContext)
     160           0 :     : nsLeafFrame(aContext, kClassID)
     161           0 :   {}
     162             : 
     163             :   virtual ~nsHTMLFramesetBlankFrame();
     164             :   virtual nscoord GetIntrinsicISize() override;
     165             :   virtual nscoord GetIntrinsicBSize() override;
     166             : 
     167             :   friend class nsHTMLFramesetFrame;
     168             :   friend class nsHTMLFrameset;
     169             : };
     170             : 
     171             : /*******************************************************************************
     172             :  * nsHTMLFramesetFrame
     173             :  ******************************************************************************/
     174             : bool    nsHTMLFramesetFrame::gDragInProgress = false;
     175             : #define DEFAULT_BORDER_WIDTH_PX 6
     176             : 
     177           0 : nsHTMLFramesetFrame::nsHTMLFramesetFrame(nsStyleContext* aContext)
     178           0 :   : nsContainerFrame(aContext, kClassID)
     179             : {
     180           0 :   mNumRows             = 0;
     181           0 :   mNumCols             = 0;
     182           0 :   mEdgeVisibility      = 0;
     183           0 :   mParentFrameborder   = eFrameborder_Yes; // default
     184           0 :   mParentBorderWidth   = -1; // default not set
     185           0 :   mParentBorderColor   = NO_COLOR; // default not set
     186           0 :   mFirstDragPoint.x     = mFirstDragPoint.y = 0;
     187           0 :   mMinDrag             = nsPresContext::CSSPixelsToAppUnits(2);
     188           0 :   mNonBorderChildCount = 0;
     189           0 :   mNonBlankChildCount  = 0;
     190           0 :   mDragger             = nullptr;
     191           0 :   mChildCount          = 0;
     192           0 :   mTopLevelFrameset    = nullptr;
     193           0 :   mEdgeColors.Set(NO_COLOR);
     194           0 : }
     195             : 
     196           0 : nsHTMLFramesetFrame::~nsHTMLFramesetFrame()
     197             : {
     198           0 : }
     199             : 
     200           0 : NS_QUERYFRAME_HEAD(nsHTMLFramesetFrame)
     201           0 :   NS_QUERYFRAME_ENTRY(nsHTMLFramesetFrame)
     202           0 : NS_QUERYFRAME_TAIL_INHERITING(nsContainerFrame)
     203             : 
     204             : void
     205           0 : nsHTMLFramesetFrame::Init(nsIContent*       aContent,
     206             :                           nsContainerFrame* aParent,
     207             :                           nsIFrame*         aPrevInFlow)
     208             : {
     209           0 :   nsContainerFrame::Init(aContent, aParent, aPrevInFlow);
     210             :   // find the highest ancestor that is a frameset
     211           0 :   nsIFrame* parentFrame = GetParent();
     212           0 :   mTopLevelFrameset = this;
     213           0 :   while (parentFrame) {
     214           0 :     nsHTMLFramesetFrame* frameset = do_QueryFrame(parentFrame);
     215           0 :     if (frameset) {
     216           0 :       mTopLevelFrameset = frameset;
     217           0 :       parentFrame = parentFrame->GetParent();
     218             :     } else {
     219           0 :       break;
     220             :     }
     221             :   }
     222             : 
     223           0 :   nsPresContext* presContext = PresContext();
     224           0 :   nsIPresShell* shell = presContext->PresShell();
     225             : 
     226           0 :   nsFrameborder  frameborder = GetFrameBorder();
     227           0 :   int32_t borderWidth = GetBorderWidth(presContext, false);
     228           0 :   nscolor borderColor = GetBorderColor();
     229             : 
     230             :   // Get the rows= cols= data
     231           0 :   HTMLFrameSetElement* ourContent = HTMLFrameSetElement::FromContent(mContent);
     232           0 :   NS_ASSERTION(ourContent, "Someone gave us a broken frameset element!");
     233           0 :   const nsFramesetSpec* rowSpecs = nullptr;
     234           0 :   const nsFramesetSpec* colSpecs = nullptr;
     235             :   // GetRowSpec and GetColSpec can fail, but when they do they set
     236             :   // mNumRows and mNumCols respectively to 0, so we deal with it fine.
     237           0 :   ourContent->GetRowSpec(&mNumRows, &rowSpecs);
     238           0 :   ourContent->GetColSpec(&mNumCols, &colSpecs);
     239             : 
     240             :   static_assert(NS_MAX_FRAMESET_SPEC_COUNT < UINT_MAX / sizeof(nscoord),
     241             :                 "Maximum value of mNumRows and mNumCols is NS_MAX_FRAMESET_SPEC_COUNT");
     242           0 :   mRowSizes  = MakeUnique<nscoord[]>(mNumRows);
     243           0 :   mColSizes  = MakeUnique<nscoord[]>(mNumCols);
     244             : 
     245             :   static_assert(NS_MAX_FRAMESET_SPEC_COUNT < INT32_MAX / NS_MAX_FRAMESET_SPEC_COUNT,
     246             :                 "Should not overflow numCells");
     247           0 :   int32_t numCells = mNumRows*mNumCols;
     248             : 
     249             :   static_assert(NS_MAX_FRAMESET_SPEC_COUNT < UINT_MAX / sizeof(nsHTMLFramesetBorderFrame*),
     250             :                 "Should not overflow nsHTMLFramesetBorderFrame");
     251           0 :   mVerBorders    = MakeUnique<nsHTMLFramesetBorderFrame*[]>(mNumCols);  // 1 more than number of ver borders
     252             : 
     253           0 :   for (int verX  = 0; verX < mNumCols; verX++)
     254           0 :     mVerBorders[verX]    = nullptr;
     255             : 
     256           0 :   mHorBorders    = MakeUnique<nsHTMLFramesetBorderFrame*[]>(mNumRows);  // 1 more than number of hor borders
     257             : 
     258           0 :   for (int horX = 0; horX < mNumRows; horX++)
     259           0 :     mHorBorders[horX]    = nullptr;
     260             : 
     261             :   static_assert(NS_MAX_FRAMESET_SPEC_COUNT
     262             :                    < UINT_MAX / sizeof(int32_t) / NS_MAX_FRAMESET_SPEC_COUNT,
     263             :                 "Should not overflow numCells");
     264             :   static_assert(NS_MAX_FRAMESET_SPEC_COUNT
     265             :                    < UINT_MAX / sizeof(nsFrameborder) / NS_MAX_FRAMESET_SPEC_COUNT,
     266             :                 "Should not overflow numCells");
     267             :   static_assert(NS_MAX_FRAMESET_SPEC_COUNT
     268             :                    < UINT_MAX / sizeof(nsBorderColor) / NS_MAX_FRAMESET_SPEC_COUNT,
     269             :                 "Should not overflow numCells");
     270           0 :   mChildFrameborder  = MakeUnique<nsFrameborder[]>(numCells);
     271           0 :   mChildBorderColors  = MakeUnique<nsBorderColor[]>(numCells);
     272             : 
     273             :   // create the children frames; skip content which isn't <frameset> or <frame>
     274           0 :   mChildCount = 0; // number of <frame> or <frameset> children
     275             :   nsIFrame* frame;
     276             : 
     277             :   // number of any type of children
     278           0 :   uint32_t numChildren = mContent->GetChildCount();
     279             : 
     280           0 :   for (uint32_t childX = 0; childX < numChildren; childX++) {
     281           0 :     if (mChildCount == numCells) { // we have more <frame> or <frameset> than cells
     282             :       // Clear the lazy bits in the remaining children.  Also clear
     283             :       // the restyle flags, like nsCSSFrameConstructor::ProcessChildren does.
     284           0 :       for (uint32_t i = childX; i < numChildren; i++) {
     285           0 :         nsIContent *child = mContent->GetChildAt(i);
     286           0 :         child->UnsetFlags(NODE_DESCENDANTS_NEED_FRAMES | NODE_NEEDS_FRAME);
     287           0 :         child->UnsetRestyleFlagsIfGecko();
     288             :       }
     289           0 :       break;
     290             :     }
     291           0 :     nsIContent *child = mContent->GetChildAt(childX);
     292           0 :     child->UnsetFlags(NODE_DESCENDANTS_NEED_FRAMES | NODE_NEEDS_FRAME);
     293             :     // Also clear the restyle flags in the child like
     294             :     // nsCSSFrameConstructor::ProcessChildren does.
     295           0 :     child->UnsetRestyleFlagsIfGecko();
     296             : 
     297             :     // IMPORTANT: This must match the conditions in
     298             :     // nsCSSFrameConstructor::ContentAppended/Inserted/Removed
     299           0 :     if (!child->IsHTMLElement())
     300           0 :       continue;
     301             : 
     302           0 :     if (child->IsAnyOfHTMLElements(nsGkAtoms::frameset, nsGkAtoms::frame)) {
     303           0 :       RefPtr<nsStyleContext> kidSC;
     304             : 
     305           0 :       kidSC = shell->StyleSet()->ResolveStyleFor(child->AsElement(),
     306             :                                                  mStyleContext,
     307           0 :                                                  LazyComputeBehavior::Allow);
     308           0 :       if (child->IsHTMLElement(nsGkAtoms::frameset)) {
     309           0 :         frame = NS_NewHTMLFramesetFrame(shell, kidSC);
     310             : 
     311           0 :         nsHTMLFramesetFrame* childFrame = (nsHTMLFramesetFrame*)frame;
     312           0 :         childFrame->SetParentFrameborder(frameborder);
     313           0 :         childFrame->SetParentBorderWidth(borderWidth);
     314           0 :         childFrame->SetParentBorderColor(borderColor);
     315           0 :         frame->Init(child, this, nullptr);
     316             : 
     317           0 :         mChildBorderColors[mChildCount].Set(childFrame->GetBorderColor());
     318             :       } else { // frame
     319           0 :         frame = NS_NewSubDocumentFrame(shell, kidSC);
     320             : 
     321           0 :         frame->Init(child, this, nullptr);
     322             : 
     323           0 :         mChildFrameborder[mChildCount] = GetFrameBorder(child);
     324           0 :         mChildBorderColors[mChildCount].Set(GetBorderColor(child));
     325             :       }
     326           0 :       child->SetPrimaryFrame(frame);
     327             : 
     328           0 :       mFrames.AppendFrame(nullptr, frame);
     329             : 
     330           0 :       mChildCount++;
     331             :     }
     332             :   }
     333             : 
     334           0 :   mNonBlankChildCount = mChildCount;
     335             :   // add blank frames for frameset cells that had no content provided
     336           0 :   for (int blankX = mChildCount; blankX < numCells; blankX++) {
     337           0 :     RefPtr<nsStyleContext> pseudoStyleContext;
     338           0 :     pseudoStyleContext = shell->StyleSet()->
     339           0 :       ResolveNonInheritingAnonymousBoxStyle(nsCSSAnonBoxes::framesetBlank);
     340             : 
     341             :     // XXX the blank frame is using the content of its parent - at some point it
     342             :     // should just have null content, if we support that
     343           0 :     nsHTMLFramesetBlankFrame* blankFrame = new (shell) nsHTMLFramesetBlankFrame(pseudoStyleContext);
     344             : 
     345           0 :     blankFrame->Init(mContent, this, nullptr);
     346             : 
     347           0 :     mFrames.AppendFrame(nullptr, blankFrame);
     348             : 
     349           0 :     mChildBorderColors[mChildCount].Set(NO_COLOR);
     350           0 :     mChildCount++;
     351             :   }
     352             : 
     353           0 :   mNonBorderChildCount = mChildCount;
     354           0 : }
     355             : 
     356             : void
     357           0 : nsHTMLFramesetFrame::SetInitialChildList(ChildListID  aListID,
     358             :                                          nsFrameList& aChildList)
     359             : {
     360             :   // We do this weirdness where we create our child frames in Init().  On the
     361             :   // other hand, we're going to get a SetInitialChildList() with an empty list
     362             :   // and null list name after the frame constructor is done creating us.  So
     363             :   // just ignore that call.
     364           0 :   if (aListID == kPrincipalList && aChildList.IsEmpty()) {
     365           0 :     return;
     366             :   }
     367             : 
     368           0 :   nsContainerFrame::SetInitialChildList(aListID, aChildList);
     369             : }
     370             : 
     371             : // XXX should this try to allocate twips based on an even pixel boundary?
     372           0 : void nsHTMLFramesetFrame::Scale(nscoord  aDesired,
     373             :                                 int32_t  aNumIndicies,
     374             :                                 int32_t* aIndicies,
     375             :                                 int32_t  aNumItems,
     376             :                                 int32_t* aItems)
     377             : {
     378           0 :   int32_t actual = 0;
     379             :   int32_t i, j;
     380             :   // get the actual total
     381           0 :   for (i = 0; i < aNumIndicies; i++) {
     382           0 :     j = aIndicies[i];
     383           0 :     actual += aItems[j];
     384             :   }
     385             : 
     386           0 :   if (actual > 0) {
     387           0 :     float factor = (float)aDesired / (float)actual;
     388           0 :     actual = 0;
     389             :     // scale the items up or down
     390           0 :     for (i = 0; i < aNumIndicies; i++) {
     391           0 :       j = aIndicies[i];
     392           0 :       aItems[j] = NSToCoordRound((float)aItems[j] * factor);
     393           0 :       actual += aItems[j];
     394             :     }
     395           0 :   } else if (aNumIndicies != 0) {
     396             :     // All the specs say zero width, but we have to fill up space
     397             :     // somehow.  Distribute it equally.
     398           0 :     nscoord width = NSToCoordRound((float)aDesired / (float)aNumIndicies);
     399           0 :     actual = width * aNumIndicies;
     400           0 :     for (i = 0; i < aNumIndicies; i++) {
     401           0 :       aItems[aIndicies[i]] = width;
     402             :     }
     403             :   }
     404             : 
     405           0 :   if (aNumIndicies > 0 && aDesired != actual) {
     406           0 :     int32_t unit = (aDesired > actual) ? 1 : -1;
     407           0 :     for (i=0; (i < aNumIndicies) && (aDesired != actual); i++) {
     408           0 :       j = aIndicies[i];
     409           0 :       if (j < aNumItems) {
     410           0 :         aItems[j] += unit;
     411           0 :         actual += unit;
     412             :       }
     413             :     }
     414             :   }
     415           0 : }
     416             : 
     417             : 
     418             : /**
     419             :   * Translate the rows/cols specs into an array of integer sizes for
     420             :   * each cell in the frameset. Sizes are allocated based on the priorities of the
     421             :   * specifier - fixed sizes have the highest priority, percentage sizes have the next
     422             :   * highest priority and relative sizes have the lowest.
     423             :   */
     424           0 : void nsHTMLFramesetFrame::CalculateRowCol(nsPresContext*        aPresContext,
     425             :                                           nscoord               aSize,
     426             :                                           int32_t               aNumSpecs,
     427             :                                           const nsFramesetSpec* aSpecs,
     428             :                                           nscoord*              aValues)
     429             : {
     430             :   static_assert(NS_MAX_FRAMESET_SPEC_COUNT < UINT_MAX / sizeof(int32_t),
     431             :                 "aNumSpecs maximum value is NS_MAX_FRAMESET_SPEC_COUNT");
     432             : 
     433           0 :   int32_t  fixedTotal = 0;
     434           0 :   int32_t  numFixed = 0;
     435           0 :   auto fixed = MakeUnique<int32_t[]>(aNumSpecs);
     436           0 :   int32_t  numPercent = 0;
     437           0 :   auto percent = MakeUnique<int32_t[]>(aNumSpecs);
     438           0 :   int32_t  relativeSums = 0;
     439           0 :   int32_t  numRelative = 0;
     440           0 :   auto relative = MakeUnique<int32_t[]>(aNumSpecs);
     441             : 
     442           0 :   if (MOZ_UNLIKELY(!fixed || !percent || !relative)) {
     443           0 :     return; // NS_ERROR_OUT_OF_MEMORY
     444             :   }
     445             : 
     446             :   int32_t i, j;
     447             : 
     448             :   // initialize the fixed, percent, relative indices, allocate the fixed sizes and zero the others
     449           0 :   for (i = 0; i < aNumSpecs; i++) {
     450           0 :     aValues[i] = 0;
     451           0 :     switch (aSpecs[i].mUnit) {
     452             :       case eFramesetUnit_Fixed:
     453           0 :         aValues[i] = nsPresContext::CSSPixelsToAppUnits(aSpecs[i].mValue);
     454           0 :         fixedTotal += aValues[i];
     455           0 :         fixed[numFixed] = i;
     456           0 :         numFixed++;
     457           0 :         break;
     458             :       case eFramesetUnit_Percent:
     459           0 :         percent[numPercent] = i;
     460           0 :         numPercent++;
     461           0 :         break;
     462             :       case eFramesetUnit_Relative:
     463           0 :         relative[numRelative] = i;
     464           0 :         numRelative++;
     465           0 :         relativeSums += aSpecs[i].mValue;
     466           0 :         break;
     467             :     }
     468             :   }
     469             : 
     470             :   // scale the fixed sizes if they total too much (or too little and there aren't any percent or relative)
     471           0 :   if ((fixedTotal > aSize) || ((fixedTotal < aSize) && (0 == numPercent) && (0 == numRelative))) {
     472           0 :     Scale(aSize, numFixed, fixed.get(), aNumSpecs, aValues);
     473           0 :     return;
     474             :   }
     475             : 
     476           0 :   int32_t percentMax = aSize - fixedTotal;
     477           0 :   int32_t percentTotal = 0;
     478             :   // allocate the percentage sizes from what is left over from the fixed allocation
     479           0 :   for (i = 0; i < numPercent; i++) {
     480           0 :     j = percent[i];
     481           0 :     aValues[j] = NSToCoordRound((float)aSpecs[j].mValue * (float)aSize / 100.0f);
     482           0 :     percentTotal += aValues[j];
     483             :   }
     484             : 
     485             :   // scale the percent sizes if they total too much (or too little and there aren't any relative)
     486           0 :   if ((percentTotal > percentMax) || ((percentTotal < percentMax) && (0 == numRelative))) {
     487           0 :     Scale(percentMax, numPercent, percent.get(), aNumSpecs, aValues);
     488           0 :     return;
     489             :   }
     490             : 
     491           0 :   int32_t relativeMax = percentMax - percentTotal;
     492           0 :   int32_t relativeTotal = 0;
     493             :   // allocate the relative sizes from what is left over from the percent allocation
     494           0 :   for (i = 0; i < numRelative; i++) {
     495           0 :     j = relative[i];
     496           0 :     aValues[j] = NSToCoordRound((float)aSpecs[j].mValue * (float)relativeMax / (float)relativeSums);
     497           0 :     relativeTotal += aValues[j];
     498             :   }
     499             : 
     500             :   // scale the relative sizes if they take up too much or too little
     501           0 :   if (relativeTotal != relativeMax) {
     502           0 :     Scale(relativeMax, numRelative, relative.get(), aNumSpecs, aValues);
     503             :   }
     504             : }
     505             : 
     506             : 
     507             : /**
     508             :   * Translate the rows/cols integer sizes into an array of specs for
     509             :   * each cell in the frameset.  Reverse of CalculateRowCol() behaviour.
     510             :   * This allows us to maintain the user size info through reflows.
     511             :   */
     512           0 : void nsHTMLFramesetFrame::GenerateRowCol(nsPresContext*        aPresContext,
     513             :                                          nscoord               aSize,
     514             :                                          int32_t               aNumSpecs,
     515             :                                          const nsFramesetSpec* aSpecs,
     516             :                                          nscoord*              aValues,
     517             :                                          nsString&             aNewAttr)
     518             : {
     519             :   int32_t i;
     520             : 
     521           0 :   for (i = 0; i < aNumSpecs; i++) {
     522           0 :     if (!aNewAttr.IsEmpty())
     523           0 :       aNewAttr.Append(char16_t(','));
     524             : 
     525           0 :     switch (aSpecs[i].mUnit) {
     526             :       case eFramesetUnit_Fixed:
     527           0 :         aNewAttr.AppendInt(nsPresContext::AppUnitsToIntCSSPixels(aValues[i]));
     528           0 :         break;
     529             :       case eFramesetUnit_Percent: // XXX Only accurate to 1%, need 1 pixel
     530             :       case eFramesetUnit_Relative:
     531             :         // Add 0.5 to the percentage to make rounding work right.
     532           0 :         aNewAttr.AppendInt(uint32_t((100.0*aValues[i])/aSize + 0.5));
     533           0 :         aNewAttr.Append(char16_t('%'));
     534           0 :         break;
     535             :     }
     536             :   }
     537           0 : }
     538             : 
     539           0 : int32_t nsHTMLFramesetFrame::GetBorderWidth(nsPresContext* aPresContext,
     540             :                                             bool aTakeForcingIntoAccount)
     541             : {
     542           0 :   nsFrameborder frameborder = GetFrameBorder();
     543           0 :   if (frameborder == eFrameborder_No) {
     544           0 :     return 0;
     545             :   }
     546           0 :   nsGenericHTMLElement *content = nsGenericHTMLElement::FromContent(mContent);
     547             : 
     548           0 :   if (content) {
     549           0 :     const nsAttrValue* attr = content->GetParsedAttr(nsGkAtoms::border);
     550           0 :     if (attr) {
     551           0 :       int32_t intVal = 0;
     552           0 :       if (attr->Type() == nsAttrValue::eInteger) {
     553           0 :         intVal = attr->GetIntegerValue();
     554           0 :         if (intVal < 0) {
     555           0 :           intVal = 0;
     556             :         }
     557             :       }
     558             : 
     559           0 :       return nsPresContext::CSSPixelsToAppUnits(intVal);
     560             :     }
     561             :   }
     562             : 
     563           0 :   if (mParentBorderWidth >= 0) {
     564           0 :     return mParentBorderWidth;
     565             :   }
     566             : 
     567           0 :   return nsPresContext::CSSPixelsToAppUnits(DEFAULT_BORDER_WIDTH_PX);
     568             : }
     569             : 
     570             : void
     571           0 : nsHTMLFramesetFrame::GetDesiredSize(nsPresContext*           aPresContext,
     572             :                                     const ReflowInput& aReflowInput,
     573             :                                     ReflowOutput&     aDesiredSize)
     574             : {
     575           0 :   WritingMode wm = aReflowInput.GetWritingMode();
     576           0 :   LogicalSize desiredSize(wm);
     577           0 :   nsHTMLFramesetFrame* framesetParent = do_QueryFrame(GetParent());
     578           0 :   if (nullptr == framesetParent) {
     579           0 :     if (aPresContext->IsPaginated()) {
     580             :       // XXX This needs to be changed when framesets paginate properly
     581           0 :       desiredSize.ISize(wm) = aReflowInput.AvailableISize();
     582           0 :       desiredSize.BSize(wm) = aReflowInput.AvailableBSize();
     583             :     } else {
     584           0 :       LogicalSize area(wm, aPresContext->GetVisibleArea().Size());
     585             : 
     586           0 :       desiredSize.ISize(wm) = area.ISize(wm);
     587           0 :       desiredSize.BSize(wm) = area.BSize(wm);
     588             :     }
     589             :   } else {
     590           0 :     LogicalSize size(wm);
     591           0 :     framesetParent->GetSizeOfChild(this, wm, size);
     592           0 :     desiredSize.ISize(wm) = size.ISize(wm);
     593           0 :     desiredSize.BSize(wm) = size.BSize(wm);
     594             :   }
     595           0 :   aDesiredSize.SetSize(wm, desiredSize);
     596           0 : }
     597             : 
     598             : // only valid for non border children
     599           0 : void nsHTMLFramesetFrame::GetSizeOfChildAt(int32_t  aIndexInParent,
     600             :                                            WritingMode aWM,
     601             :                                            LogicalSize&  aSize,
     602             :                                            nsIntPoint& aCellIndex)
     603             : {
     604           0 :   int32_t row = aIndexInParent / mNumCols;
     605           0 :   int32_t col = aIndexInParent - (row * mNumCols); // remainder from dividing index by mNumCols
     606           0 :   if ((row < mNumRows) && (col < mNumCols)) {
     607           0 :     aSize.ISize(aWM) = mColSizes[col];
     608           0 :     aSize.BSize(aWM) = mRowSizes[row];
     609           0 :     aCellIndex.x = col;
     610           0 :     aCellIndex.y = row;
     611             :   } else {
     612           0 :     aSize.SizeTo(aWM, 0, 0);
     613           0 :     aCellIndex.x = aCellIndex.y = 0;
     614             :   }
     615           0 : }
     616             : 
     617             : // only valid for non border children
     618           0 : void nsHTMLFramesetFrame::GetSizeOfChild(nsIFrame* aChild,
     619             :                                          WritingMode aWM,
     620             :                                          LogicalSize& aSize)
     621             : {
     622             :   // Reflow only creates children frames for <frameset> and <frame> content.
     623             :   // this assumption is used here
     624           0 :   int i = 0;
     625           0 :   for (nsIFrame* child : mFrames) {
     626           0 :     if (aChild == child) {
     627           0 :       nsIntPoint ignore;
     628           0 :       GetSizeOfChildAt(i, aWM, aSize, ignore);
     629           0 :       return;
     630             :     }
     631           0 :     i++;
     632             :   }
     633           0 :   aSize.SizeTo(aWM, 0, 0);
     634             : }
     635             : 
     636             : 
     637           0 : nsresult nsHTMLFramesetFrame::HandleEvent(nsPresContext* aPresContext,
     638             :                                            WidgetGUIEvent* aEvent,
     639             :                                            nsEventStatus* aEventStatus)
     640             : {
     641           0 :   NS_ENSURE_ARG_POINTER(aEventStatus);
     642           0 :   if (mDragger) {
     643             :     // the nsFramesetBorderFrame has captured NS_MOUSE_DOWN
     644           0 :     switch (aEvent->mMessage) {
     645             :       case eMouseMove:
     646           0 :         MouseDrag(aPresContext, aEvent);
     647           0 :         break;
     648             :       case eMouseUp:
     649           0 :         if (aEvent->AsMouseEvent()->button == WidgetMouseEvent::eLeftButton) {
     650           0 :           EndMouseDrag(aPresContext);
     651             :         }
     652           0 :         break;
     653             :       default:
     654           0 :         break;
     655             :     }
     656           0 :     *aEventStatus = nsEventStatus_eConsumeNoDefault;
     657             :   } else {
     658           0 :     *aEventStatus = nsEventStatus_eIgnore;
     659             :   }
     660           0 :   return NS_OK;
     661             : }
     662             : 
     663             : nsresult
     664           0 : nsHTMLFramesetFrame::GetCursor(const nsPoint&    aPoint,
     665             :                                nsIFrame::Cursor& aCursor)
     666             : {
     667           0 :   aCursor.mLoading = false;
     668           0 :   if (mDragger) {
     669           0 :     aCursor.mCursor = (mDragger->mVertical) ? NS_STYLE_CURSOR_EW_RESIZE : NS_STYLE_CURSOR_NS_RESIZE;
     670             :   } else {
     671           0 :     aCursor.mCursor = NS_STYLE_CURSOR_DEFAULT;
     672             :   }
     673           0 :   return NS_OK;
     674             : }
     675             : 
     676             : void
     677           0 : nsHTMLFramesetFrame::BuildDisplayList(nsDisplayListBuilder*   aBuilder,
     678             :                                       const nsRect&           aDirtyRect,
     679             :                                       const nsDisplayListSet& aLists)
     680             : {
     681           0 :   BuildDisplayListForInline(aBuilder, aDirtyRect, aLists);
     682             : 
     683           0 :   if (mDragger && aBuilder->IsForEventDelivery()) {
     684           0 :     aLists.Content()->AppendNewToTop(
     685           0 :       new (aBuilder) nsDisplayEventReceiver(aBuilder, this));
     686             :   }
     687           0 : }
     688             : 
     689             : void
     690           0 : nsHTMLFramesetFrame::ReflowPlaceChild(nsIFrame*                aChild,
     691             :                                       nsPresContext*           aPresContext,
     692             :                                       const ReflowInput& aReflowInput,
     693             :                                       nsPoint&                 aOffset,
     694             :                                       nsSize&                  aSize,
     695             :                                       nsIntPoint*              aCellIndex)
     696             : {
     697             :   // reflow the child
     698             :   ReflowInput reflowInput(aPresContext, aReflowInput, aChild,
     699           0 :                                 LogicalSize(aChild->GetWritingMode(), aSize));
     700           0 :   reflowInput.SetComputedWidth(std::max(0, aSize.width - reflowInput.ComputedPhysicalBorderPadding().LeftRight()));
     701           0 :   reflowInput.SetComputedHeight(std::max(0, aSize.height - reflowInput.ComputedPhysicalBorderPadding().TopBottom()));
     702           0 :   ReflowOutput reflowOutput(aReflowInput);
     703           0 :   reflowOutput.Width() = aSize.width;
     704           0 :   reflowOutput.Height() = aSize.height;
     705           0 :   nsReflowStatus status;
     706             : 
     707           0 :   ReflowChild(aChild, aPresContext, reflowOutput, reflowInput, aOffset.x,
     708           0 :               aOffset.y, 0, status);
     709           0 :   NS_ASSERTION(status.IsComplete(), "bad status");
     710             : 
     711             :   // Place and size the child
     712           0 :   reflowOutput.Width() = aSize.width;
     713           0 :   reflowOutput.Height() = aSize.height;
     714           0 :   FinishReflowChild(aChild, aPresContext, reflowOutput, nullptr, aOffset.x, aOffset.y, 0);
     715           0 : }
     716             : 
     717             : static
     718           0 : nsFrameborder GetFrameBorderHelper(nsGenericHTMLElement* aContent)
     719             : {
     720           0 :   if (nullptr != aContent) {
     721           0 :     const nsAttrValue* attr = aContent->GetParsedAttr(nsGkAtoms::frameborder);
     722           0 :     if (attr && attr->Type() == nsAttrValue::eEnum) {
     723           0 :       switch (attr->GetEnumValue())
     724             :       {
     725             :         case NS_STYLE_FRAME_YES:
     726             :         case NS_STYLE_FRAME_1:
     727           0 :           return eFrameborder_Yes;
     728             : 
     729             :         case NS_STYLE_FRAME_NO:
     730             :         case NS_STYLE_FRAME_0:
     731           0 :           return eFrameborder_No;
     732             :       }
     733             :     }
     734             :   }
     735           0 :   return eFrameborder_Notset;
     736             : }
     737             : 
     738           0 : nsFrameborder nsHTMLFramesetFrame::GetFrameBorder()
     739             : {
     740           0 :   nsFrameborder result = eFrameborder_Notset;
     741           0 :   nsGenericHTMLElement *content = nsGenericHTMLElement::FromContent(mContent);
     742             : 
     743           0 :   if (content) {
     744           0 :     result = GetFrameBorderHelper(content);
     745             :   }
     746           0 :   if (eFrameborder_Notset == result) {
     747           0 :     return mParentFrameborder;
     748             :   }
     749           0 :   return result;
     750             : }
     751             : 
     752           0 : nsFrameborder nsHTMLFramesetFrame::GetFrameBorder(nsIContent* aContent)
     753             : {
     754           0 :   nsFrameborder result = eFrameborder_Notset;
     755             : 
     756           0 :   nsGenericHTMLElement *content = nsGenericHTMLElement::FromContent(aContent);
     757             : 
     758           0 :   if (content) {
     759           0 :     result = GetFrameBorderHelper(content);
     760             :   }
     761           0 :   if (eFrameborder_Notset == result) {
     762           0 :     return GetFrameBorder();
     763             :   }
     764           0 :   return result;
     765             : }
     766             : 
     767           0 : nscolor nsHTMLFramesetFrame::GetBorderColor()
     768             : {
     769           0 :   nsGenericHTMLElement *content = nsGenericHTMLElement::FromContent(mContent);
     770             : 
     771           0 :   if (content) {
     772           0 :     const nsAttrValue* attr = content->GetParsedAttr(nsGkAtoms::bordercolor);
     773           0 :     if (attr) {
     774             :       nscolor color;
     775           0 :       if (attr->GetColorValue(color)) {
     776           0 :         return color;
     777             :       }
     778             :     }
     779             :   }
     780             : 
     781           0 :   return mParentBorderColor;
     782             : }
     783             : 
     784           0 : nscolor nsHTMLFramesetFrame::GetBorderColor(nsIContent* aContent)
     785             : {
     786           0 :   nsGenericHTMLElement *content = nsGenericHTMLElement::FromContent(aContent);
     787             : 
     788           0 :   if (content) {
     789           0 :     const nsAttrValue* attr = content->GetParsedAttr(nsGkAtoms::bordercolor);
     790           0 :     if (attr) {
     791             :       nscolor color;
     792           0 :       if (attr->GetColorValue(color)) {
     793           0 :         return color;
     794             :       }
     795             :     }
     796             :   }
     797           0 :   return GetBorderColor();
     798             : }
     799             : 
     800             : void
     801           0 : nsHTMLFramesetFrame::Reflow(nsPresContext*           aPresContext,
     802             :                             ReflowOutput&     aDesiredSize,
     803             :                             const ReflowInput& aReflowInput,
     804             :                             nsReflowStatus&          aStatus)
     805             : {
     806           0 :   MarkInReflow();
     807           0 :   DO_GLOBAL_REFLOW_COUNT("nsHTMLFramesetFrame");
     808           0 :   DISPLAY_REFLOW(aPresContext, this, aReflowInput, aDesiredSize, aStatus);
     809           0 :   nsIPresShell *shell = aPresContext->PresShell();
     810           0 :   StyleSetHandle styleSet = shell->StyleSet();
     811             : 
     812           0 :   GetParent()->AddStateBits(NS_FRAME_CONTAINS_RELATIVE_BSIZE);
     813             : 
     814             :   //printf("FramesetFrame2::Reflow %X (%d,%d) \n", this, aReflowInput.AvailableWidth(), aReflowInput.AvailableHeight());
     815             :   // Always get the size so that the caller knows how big we are
     816           0 :   GetDesiredSize(aPresContext, aReflowInput, aDesiredSize);
     817             : 
     818           0 :   nscoord width  = (aDesiredSize.Width() <= aReflowInput.AvailableWidth())
     819           0 :     ? aDesiredSize.Width() : aReflowInput.AvailableWidth();
     820           0 :   nscoord height = (aDesiredSize.Height() <= aReflowInput.AvailableHeight())
     821           0 :     ? aDesiredSize.Height() : aReflowInput.AvailableHeight();
     822             : 
     823             :   // We might be reflowed more than once with NS_FRAME_FIRST_REFLOW;
     824             :   // that's allowed.  (Though it will only happen for misuse of frameset
     825             :   // that includes it within other content.)  So measure firstTime by
     826             :   // what we care about, which is whether we've processed the data we
     827             :   // process below if firstTime is true.
     828           0 :   MOZ_ASSERT(!mChildFrameborder == !mChildBorderColors);
     829           0 :   bool firstTime = !!mChildFrameborder;
     830             : 
     831             :   // subtract out the width of all of the potential borders. There are
     832             :   // only borders between <frame>s. There are none on the edges (e.g the
     833             :   // leftmost <frame> has no left border).
     834           0 :   int32_t borderWidth = GetBorderWidth(aPresContext, true);
     835             : 
     836           0 :   width  -= (mNumCols - 1) * borderWidth;
     837           0 :   if (width < 0) width = 0;
     838             : 
     839           0 :   height -= (mNumRows - 1) * borderWidth;
     840           0 :   if (height < 0) height = 0;
     841             : 
     842           0 :   HTMLFrameSetElement* ourContent = HTMLFrameSetElement::FromContent(mContent);
     843           0 :   NS_ASSERTION(ourContent, "Someone gave us a broken frameset element!");
     844           0 :   const nsFramesetSpec* rowSpecs = nullptr;
     845           0 :   const nsFramesetSpec* colSpecs = nullptr;
     846           0 :   int32_t rows = 0;
     847           0 :   int32_t cols = 0;
     848           0 :   ourContent->GetRowSpec(&rows, &rowSpecs);
     849           0 :   ourContent->GetColSpec(&cols, &colSpecs);
     850             :   // If the number of cols or rows has changed, the frame for the frameset
     851             :   // will be re-created.
     852           0 :   if (mNumRows != rows || mNumCols != cols) {
     853           0 :     aStatus.Reset();
     854           0 :     mDrag.UnSet();
     855           0 :     NS_FRAME_SET_TRUNCATION(aStatus, aReflowInput, aDesiredSize);
     856           0 :     return;
     857             :   }
     858             : 
     859           0 :   CalculateRowCol(aPresContext, width, mNumCols, colSpecs, mColSizes.get());
     860           0 :   CalculateRowCol(aPresContext, height, mNumRows, rowSpecs, mRowSizes.get());
     861             : 
     862           0 :   UniquePtr<bool[]>  verBordersVis; // vertical borders visibility
     863           0 :   UniquePtr<nscolor[]> verBorderColors;
     864           0 :   UniquePtr<bool[]>  horBordersVis; // horizontal borders visibility
     865           0 :   UniquePtr<nscolor[]> horBorderColors;
     866           0 :   nscolor                 borderColor = GetBorderColor();
     867           0 :   nsFrameborder           frameborder = GetFrameBorder();
     868             : 
     869           0 :   if (firstTime) {
     870             :     // Check for overflow in memory allocations using mNumCols and mNumRows
     871             :     // which have a maxium value of NS_MAX_FRAMESET_SPEC_COUNT.
     872             :     static_assert(NS_MAX_FRAMESET_SPEC_COUNT < UINT_MAX / sizeof(bool),
     873             :                   "Check for overflow");
     874             :     static_assert(NS_MAX_FRAMESET_SPEC_COUNT < UINT_MAX / sizeof(nscolor),
     875             :                   "Check for overflow");
     876             : 
     877           0 :     verBordersVis = MakeUnique<bool[]>(mNumCols);
     878           0 :     verBorderColors = MakeUnique<nscolor[]>(mNumCols);
     879           0 :     for (int verX  = 0; verX < mNumCols; verX++) {
     880           0 :       verBordersVis[verX] = false;
     881           0 :       verBorderColors[verX] = NO_COLOR;
     882             :     }
     883             : 
     884           0 :     horBordersVis = MakeUnique<bool[]>(mNumRows);
     885           0 :     horBorderColors = MakeUnique<nscolor[]>(mNumRows);
     886           0 :     for (int horX = 0; horX < mNumRows; horX++) {
     887           0 :       horBordersVis[horX] = false;
     888           0 :       horBorderColors[horX] = NO_COLOR;
     889             :     }
     890             :   }
     891             : 
     892             :   // reflow the children
     893           0 :   int32_t lastRow = 0;
     894           0 :   int32_t lastCol = 0;
     895           0 :   int32_t borderChildX = mNonBorderChildCount; // index of border children
     896           0 :   nsHTMLFramesetBorderFrame* borderFrame = nullptr;
     897           0 :   nsPoint offset(0,0);
     898           0 :   nsSize size, lastSize;
     899           0 :   WritingMode wm = GetWritingMode();
     900           0 :   LogicalSize logicalSize(wm);
     901           0 :   nsIFrame* child = mFrames.FirstChild();
     902             : 
     903           0 :   for (int32_t childX = 0; childX < mNonBorderChildCount; childX++) {
     904           0 :     nsIntPoint cellIndex;
     905           0 :     GetSizeOfChildAt(childX, wm, logicalSize, cellIndex);
     906           0 :     size = logicalSize.GetPhysicalSize(wm);
     907             : 
     908           0 :     if (lastRow != cellIndex.y) {  // changed to next row
     909           0 :       offset.x = 0;
     910           0 :       offset.y += lastSize.height;
     911           0 :       if (firstTime) { // create horizontal border
     912             : 
     913           0 :         RefPtr<nsStyleContext> pseudoStyleContext;
     914             :         pseudoStyleContext = styleSet->
     915           0 :           ResolveNonInheritingAnonymousBoxStyle(nsCSSAnonBoxes::horizontalFramesetBorder);
     916             : 
     917           0 :         borderFrame = new (shell) nsHTMLFramesetBorderFrame(pseudoStyleContext,
     918             :                                                             borderWidth,
     919             :                                                             false,
     920           0 :                                                             false);
     921           0 :         borderFrame->Init(mContent, this, nullptr);
     922           0 :         mChildCount++;
     923           0 :         mFrames.AppendFrame(nullptr, borderFrame);
     924           0 :         mHorBorders[cellIndex.y-1] = borderFrame;
     925             :         // set the neighbors for determining drag boundaries
     926           0 :         borderFrame->mPrevNeighbor = lastRow;
     927           0 :         borderFrame->mNextNeighbor = cellIndex.y;
     928             :       } else {
     929           0 :         borderFrame = (nsHTMLFramesetBorderFrame*)mFrames.FrameAt(borderChildX);
     930           0 :         borderFrame->mWidth = borderWidth;
     931           0 :         borderChildX++;
     932             :       }
     933           0 :       nsSize borderSize(aDesiredSize.Width(), borderWidth);
     934           0 :       ReflowPlaceChild(borderFrame, aPresContext, aReflowInput, offset, borderSize);
     935           0 :       borderFrame = nullptr;
     936           0 :       offset.y += borderWidth;
     937             :     } else {
     938           0 :       if (cellIndex.x > 0) {  // moved to next col in same row
     939           0 :         if (0 == cellIndex.y) { // in 1st row
     940           0 :           if (firstTime) { // create vertical border
     941             : 
     942           0 :             RefPtr<nsStyleContext> pseudoStyleContext;
     943             :             pseudoStyleContext = styleSet->
     944           0 :               ResolveNonInheritingAnonymousBoxStyle(nsCSSAnonBoxes::verticalFramesetBorder);
     945             : 
     946           0 :             borderFrame = new (shell) nsHTMLFramesetBorderFrame(pseudoStyleContext,
     947             :                                                                 borderWidth,
     948             :                                                                 true,
     949           0 :                                                                 false);
     950           0 :             borderFrame->Init(mContent, this, nullptr);
     951           0 :             mChildCount++;
     952           0 :             mFrames.AppendFrame(nullptr, borderFrame);
     953           0 :             mVerBorders[cellIndex.x-1] = borderFrame;
     954             :             // set the neighbors for determining drag boundaries
     955           0 :             borderFrame->mPrevNeighbor = lastCol;
     956           0 :             borderFrame->mNextNeighbor = cellIndex.x;
     957             :           } else {
     958           0 :             borderFrame = (nsHTMLFramesetBorderFrame*)mFrames.FrameAt(borderChildX);
     959           0 :             borderFrame->mWidth = borderWidth;
     960           0 :             borderChildX++;
     961             :           }
     962           0 :           nsSize borderSize(borderWidth, aDesiredSize.Height());
     963           0 :           ReflowPlaceChild(borderFrame, aPresContext, aReflowInput, offset, borderSize);
     964           0 :           borderFrame = nullptr;
     965             :         }
     966           0 :         offset.x += borderWidth;
     967             :       }
     968             :     }
     969             : 
     970           0 :     ReflowPlaceChild(child, aPresContext, aReflowInput, offset, size, &cellIndex);
     971             : 
     972           0 :     if (firstTime) {
     973             :       int32_t childVis;
     974           0 :       nsHTMLFramesetFrame* framesetFrame = do_QueryFrame(child);
     975             :       nsSubDocumentFrame* subdocFrame;
     976           0 :       if (framesetFrame) {
     977           0 :         childVis = framesetFrame->mEdgeVisibility;
     978           0 :         mChildBorderColors[childX] = framesetFrame->mEdgeColors;
     979           0 :       } else if ((subdocFrame = do_QueryFrame(child))) {
     980           0 :         if (eFrameborder_Yes == mChildFrameborder[childX]) {
     981           0 :           childVis = ALL_VIS;
     982           0 :         } else if (eFrameborder_No == mChildFrameborder[childX]) {
     983           0 :           childVis = NONE_VIS;
     984             :         } else {  // notset
     985           0 :           childVis = (eFrameborder_No == frameborder) ? NONE_VIS : ALL_VIS;
     986             :         }
     987             :       } else {  // blank
     988             : #ifdef DEBUG
     989           0 :         nsHTMLFramesetBlankFrame* blank = do_QueryFrame(child);
     990           0 :         MOZ_ASSERT(blank, "unexpected child frame type");
     991             : #endif
     992           0 :         childVis = NONE_VIS;
     993             :       }
     994           0 :       nsBorderColor childColors = mChildBorderColors[childX];
     995             :       // set the visibility, color of our edge borders based on children
     996           0 :       if (0 == cellIndex.x) {
     997           0 :         if (!(mEdgeVisibility & LEFT_VIS)) {
     998           0 :           mEdgeVisibility |= (LEFT_VIS & childVis);
     999             :         }
    1000           0 :         if (NO_COLOR == mEdgeColors.mLeft) {
    1001           0 :           mEdgeColors.mLeft = childColors.mLeft;
    1002             :         }
    1003             :       }
    1004           0 :       if (0 == cellIndex.y) {
    1005           0 :         if (!(mEdgeVisibility & TOP_VIS)) {
    1006           0 :           mEdgeVisibility |= (TOP_VIS & childVis);
    1007             :         }
    1008           0 :         if (NO_COLOR == mEdgeColors.mTop) {
    1009           0 :           mEdgeColors.mTop = childColors.mTop;
    1010             :         }
    1011             :       }
    1012           0 :       if (mNumCols-1 == cellIndex.x) {
    1013           0 :         if (!(mEdgeVisibility & RIGHT_VIS)) {
    1014           0 :           mEdgeVisibility |= (RIGHT_VIS & childVis);
    1015             :         }
    1016           0 :         if (NO_COLOR == mEdgeColors.mRight) {
    1017           0 :           mEdgeColors.mRight = childColors.mRight;
    1018             :         }
    1019             :       }
    1020           0 :       if (mNumRows-1 == cellIndex.y) {
    1021           0 :         if (!(mEdgeVisibility & BOTTOM_VIS)) {
    1022           0 :           mEdgeVisibility |= (BOTTOM_VIS & childVis);
    1023             :         }
    1024           0 :         if (NO_COLOR == mEdgeColors.mBottom) {
    1025           0 :           mEdgeColors.mBottom = childColors.mBottom;
    1026             :         }
    1027             :       }
    1028             :       // set the visibility of borders that the child may affect
    1029           0 :       if (childVis & RIGHT_VIS) {
    1030           0 :         verBordersVis[cellIndex.x] = true;
    1031             :       }
    1032           0 :       if (childVis & BOTTOM_VIS) {
    1033           0 :         horBordersVis[cellIndex.y] = true;
    1034             :       }
    1035           0 :       if ((cellIndex.x > 0) && (childVis & LEFT_VIS)) {
    1036           0 :         verBordersVis[cellIndex.x-1] = true;
    1037             :       }
    1038           0 :       if ((cellIndex.y > 0) && (childVis & TOP_VIS)) {
    1039           0 :         horBordersVis[cellIndex.y-1] = true;
    1040             :       }
    1041             :       // set the colors of borders that the child may affect
    1042           0 :       if (NO_COLOR == verBorderColors[cellIndex.x]) {
    1043           0 :         verBorderColors[cellIndex.x] = mChildBorderColors[childX].mRight;
    1044             :       }
    1045           0 :       if (NO_COLOR == horBorderColors[cellIndex.y]) {
    1046           0 :         horBorderColors[cellIndex.y] = mChildBorderColors[childX].mBottom;
    1047             :       }
    1048           0 :       if ((cellIndex.x > 0) && (NO_COLOR == verBorderColors[cellIndex.x-1])) {
    1049           0 :         verBorderColors[cellIndex.x-1] = mChildBorderColors[childX].mLeft;
    1050             :       }
    1051           0 :       if ((cellIndex.y > 0) && (NO_COLOR == horBorderColors[cellIndex.y-1])) {
    1052           0 :         horBorderColors[cellIndex.y-1] = mChildBorderColors[childX].mTop;
    1053             :       }
    1054             :     }
    1055           0 :     lastRow  = cellIndex.y;
    1056           0 :     lastCol  = cellIndex.x;
    1057           0 :     lastSize = size;
    1058           0 :     offset.x += size.width;
    1059           0 :     child = child->GetNextSibling();
    1060             :   }
    1061             : 
    1062           0 :   if (firstTime) {
    1063             :     nscolor childColor;
    1064             :     // set the visibility, color, mouse sensitivity of borders
    1065           0 :     for (int verX = 0; verX < mNumCols-1; verX++) {
    1066           0 :       if (mVerBorders[verX]) {
    1067           0 :         mVerBorders[verX]->SetVisibility(verBordersVis[verX]);
    1068           0 :         SetBorderResize(mVerBorders[verX]);
    1069           0 :         childColor = (NO_COLOR == verBorderColors[verX]) ? borderColor : verBorderColors[verX];
    1070           0 :         mVerBorders[verX]->SetColor(childColor);
    1071             :       }
    1072             :     }
    1073           0 :     for (int horX = 0; horX < mNumRows-1; horX++) {
    1074           0 :       if (mHorBorders[horX]) {
    1075           0 :         mHorBorders[horX]->SetVisibility(horBordersVis[horX]);
    1076           0 :         SetBorderResize(mHorBorders[horX]);
    1077           0 :         childColor = (NO_COLOR == horBorderColors[horX]) ? borderColor : horBorderColors[horX];
    1078           0 :         mHorBorders[horX]->SetColor(childColor);
    1079             :       }
    1080             :     }
    1081             : 
    1082           0 :     mChildFrameborder.reset();
    1083           0 :     mChildBorderColors.reset();
    1084             :   }
    1085             : 
    1086           0 :   aStatus.Reset();
    1087           0 :   mDrag.UnSet();
    1088             : 
    1089           0 :   aDesiredSize.SetOverflowAreasToDesiredBounds();
    1090           0 :   FinishAndStoreOverflow(&aDesiredSize);
    1091             : 
    1092           0 :   NS_FRAME_SET_TRUNCATION(aStatus, aReflowInput, aDesiredSize);
    1093             : }
    1094             : 
    1095             : #ifdef DEBUG_FRAME_DUMP
    1096             : nsresult
    1097           0 : nsHTMLFramesetFrame::GetFrameName(nsAString& aResult) const
    1098             : {
    1099           0 :   return MakeFrameName(NS_LITERAL_STRING("Frameset"), aResult);
    1100             : }
    1101             : #endif
    1102             : 
    1103             : bool
    1104           0 : nsHTMLFramesetFrame::CanResize(bool aVertical,
    1105             :                                bool aLeft)
    1106             : {
    1107             :   int32_t childX;
    1108             :   int32_t startX;
    1109           0 :   if (aVertical) {
    1110           0 :     startX = (aLeft) ? 0 : mNumCols-1;
    1111           0 :     for (childX = startX; childX < mNonBorderChildCount; childX += mNumCols) {
    1112           0 :       if (!CanChildResize(aVertical, aLeft, childX)) {
    1113           0 :         return false;
    1114             :       }
    1115             :     }
    1116             :   } else {
    1117           0 :     startX = (aLeft) ? 0 : (mNumRows - 1) * mNumCols;
    1118           0 :     int32_t endX = startX + mNumCols;
    1119           0 :     for (childX = startX; childX < endX; childX++) {
    1120           0 :       if (!CanChildResize(aVertical, aLeft, childX)) {
    1121           0 :         return false;
    1122             :       }
    1123             :     }
    1124             :   }
    1125           0 :   return true;
    1126             : }
    1127             : 
    1128             : bool
    1129           0 : nsHTMLFramesetFrame::GetNoResize(nsIFrame* aChildFrame)
    1130             : {
    1131           0 :   nsIContent* content = aChildFrame->GetContent();
    1132             : 
    1133           0 :   return content && content->HasAttr(kNameSpaceID_None, nsGkAtoms::noresize);
    1134             : }
    1135             : 
    1136             : bool
    1137           0 : nsHTMLFramesetFrame::CanChildResize(bool aVertical, bool aLeft, int32_t aChildX)
    1138             : {
    1139           0 :   nsIFrame* child = mFrames.FrameAt(aChildX);
    1140           0 :   nsHTMLFramesetFrame* frameset = do_QueryFrame(child);
    1141           0 :   return frameset ? frameset->CanResize(aVertical, aLeft) : !GetNoResize(child);
    1142             : }
    1143             : 
    1144             : // This calculates and sets the resizability of all border frames
    1145             : 
    1146             : void
    1147           0 : nsHTMLFramesetFrame::RecalculateBorderResize()
    1148             : {
    1149           0 :   if (!mContent) {
    1150           0 :     return;
    1151             :   }
    1152             : 
    1153             :   static_assert(NS_MAX_FRAMESET_SPEC_COUNT < INT32_MAX / NS_MAX_FRAMESET_SPEC_COUNT,
    1154             :                 "Check for overflow");
    1155             :   static_assert(NS_MAX_FRAMESET_SPEC_COUNT
    1156             :                    < UINT_MAX / sizeof(int32_t) / NS_MAX_FRAMESET_SPEC_COUNT,
    1157             :                 "Check for overflow");
    1158             :   // set the visibility and mouse sensitivity of borders
    1159             :   int32_t verX;
    1160           0 :   for (verX = 0; verX < mNumCols-1; verX++) {
    1161           0 :     if (mVerBorders[verX]) {
    1162           0 :       mVerBorders[verX]->mCanResize = true;
    1163           0 :       SetBorderResize(mVerBorders[verX]);
    1164             :     }
    1165             :   }
    1166             :   int32_t horX;
    1167           0 :   for (horX = 0; horX < mNumRows-1; horX++) {
    1168           0 :     if (mHorBorders[horX]) {
    1169           0 :       mHorBorders[horX]->mCanResize = true;
    1170           0 :       SetBorderResize(mHorBorders[horX]);
    1171             :     }
    1172             :   }
    1173             : }
    1174             : 
    1175             : void
    1176           0 : nsHTMLFramesetFrame::SetBorderResize(nsHTMLFramesetBorderFrame* aBorderFrame)
    1177             : {
    1178           0 :   if (aBorderFrame->mVertical) {
    1179           0 :     for (int rowX = 0; rowX < mNumRows; rowX++) {
    1180           0 :       int32_t childX = aBorderFrame->mPrevNeighbor + (rowX * mNumCols);
    1181           0 :       if (!CanChildResize(true, false, childX) ||
    1182           0 :           !CanChildResize(true, true, childX+1)) {
    1183           0 :         aBorderFrame->mCanResize = false;
    1184             :       }
    1185             :     }
    1186             :   } else {
    1187           0 :     int32_t childX = aBorderFrame->mPrevNeighbor * mNumCols;
    1188           0 :     int32_t endX   = childX + mNumCols;
    1189           0 :     for (; childX < endX; childX++) {
    1190           0 :       if (!CanChildResize(false, false, childX)) {
    1191           0 :         aBorderFrame->mCanResize = false;
    1192             :       }
    1193             :     }
    1194           0 :     endX = endX + mNumCols;
    1195           0 :     for (; childX < endX; childX++) {
    1196           0 :       if (!CanChildResize(false, true, childX)) {
    1197           0 :         aBorderFrame->mCanResize = false;
    1198             :       }
    1199             :     }
    1200             :   }
    1201           0 : }
    1202             : 
    1203             : void
    1204           0 : nsHTMLFramesetFrame::StartMouseDrag(nsPresContext*             aPresContext,
    1205             :                                     nsHTMLFramesetBorderFrame* aBorder,
    1206             :                                     WidgetGUIEvent*            aEvent)
    1207             : {
    1208             : #if 0
    1209             :   int32_t index;
    1210             :   IndexOf(aBorder, index);
    1211             :   NS_ASSERTION((nullptr != aBorder) && (index >= 0), "invalid dragger");
    1212             : #endif
    1213             : 
    1214           0 :   nsIPresShell::SetCapturingContent(GetContent(), CAPTURE_IGNOREALLOWED);
    1215             : 
    1216           0 :   mDragger = aBorder;
    1217             : 
    1218           0 :   mFirstDragPoint = aEvent->mRefPoint;
    1219             : 
    1220             :   // Store the original frame sizes
    1221           0 :   if (mDragger->mVertical) {
    1222           0 :     mPrevNeighborOrigSize = mColSizes[mDragger->mPrevNeighbor];
    1223           0 :     mNextNeighborOrigSize = mColSizes[mDragger->mNextNeighbor];
    1224             :   } else {
    1225           0 :     mPrevNeighborOrigSize = mRowSizes[mDragger->mPrevNeighbor];
    1226           0 :     mNextNeighborOrigSize = mRowSizes[mDragger->mNextNeighbor];
    1227             :   }
    1228             : 
    1229           0 :   gDragInProgress = true;
    1230           0 : }
    1231             : 
    1232             : 
    1233             : void
    1234           0 : nsHTMLFramesetFrame::MouseDrag(nsPresContext* aPresContext,
    1235             :                                WidgetGUIEvent* aEvent)
    1236             : {
    1237             :   // if the capture ended, reset the drag state
    1238           0 :   if (nsIPresShell::GetCapturingContent() != GetContent()) {
    1239           0 :     mDragger = nullptr;
    1240           0 :     gDragInProgress = false;
    1241           0 :     return;
    1242             :   }
    1243             : 
    1244             :   int32_t change; // measured positive from left-to-right or top-to-bottom
    1245           0 :   AutoWeakFrame weakFrame(this);
    1246           0 :   if (mDragger->mVertical) {
    1247           0 :     change = aPresContext->DevPixelsToAppUnits(
    1248           0 :                              aEvent->mRefPoint.x - mFirstDragPoint.x);
    1249           0 :     if (change > mNextNeighborOrigSize - mMinDrag) {
    1250           0 :       change = mNextNeighborOrigSize - mMinDrag;
    1251           0 :     } else if (change <= mMinDrag - mPrevNeighborOrigSize) {
    1252           0 :       change = mMinDrag - mPrevNeighborOrigSize;
    1253             :     }
    1254           0 :     mColSizes[mDragger->mPrevNeighbor] = mPrevNeighborOrigSize + change;
    1255           0 :     mColSizes[mDragger->mNextNeighbor] = mNextNeighborOrigSize - change;
    1256             : 
    1257           0 :     if (change != 0) {
    1258             :       // Recompute the specs from the new sizes.
    1259           0 :       nscoord width = mRect.width - (mNumCols - 1) * GetBorderWidth(aPresContext, true);
    1260           0 :       HTMLFrameSetElement* ourContent = HTMLFrameSetElement::FromContent(mContent);
    1261           0 :       NS_ASSERTION(ourContent, "Someone gave us a broken frameset element!");
    1262           0 :       const nsFramesetSpec* colSpecs = nullptr;
    1263           0 :       ourContent->GetColSpec(&mNumCols, &colSpecs);
    1264           0 :       nsAutoString newColAttr;
    1265           0 :       GenerateRowCol(aPresContext, width, mNumCols, colSpecs, mColSizes.get(),
    1266           0 :                      newColAttr);
    1267             :       // Setting the attr will trigger a reflow
    1268           0 :       mContent->SetAttr(kNameSpaceID_None, nsGkAtoms::cols, newColAttr, true);
    1269             :     }
    1270             :   } else {
    1271           0 :     change = aPresContext->DevPixelsToAppUnits(
    1272           0 :                              aEvent->mRefPoint.y - mFirstDragPoint.y);
    1273           0 :     if (change > mNextNeighborOrigSize - mMinDrag) {
    1274           0 :       change = mNextNeighborOrigSize - mMinDrag;
    1275           0 :     } else if (change <= mMinDrag - mPrevNeighborOrigSize) {
    1276           0 :       change = mMinDrag - mPrevNeighborOrigSize;
    1277             :     }
    1278           0 :     mRowSizes[mDragger->mPrevNeighbor] = mPrevNeighborOrigSize + change;
    1279           0 :     mRowSizes[mDragger->mNextNeighbor] = mNextNeighborOrigSize - change;
    1280             : 
    1281           0 :     if (change != 0) {
    1282             :       // Recompute the specs from the new sizes.
    1283           0 :       nscoord height = mRect.height - (mNumRows - 1) * GetBorderWidth(aPresContext, true);
    1284           0 :       HTMLFrameSetElement* ourContent = HTMLFrameSetElement::FromContent(mContent);
    1285           0 :       NS_ASSERTION(ourContent, "Someone gave us a broken frameset element!");
    1286           0 :       const nsFramesetSpec* rowSpecs = nullptr;
    1287           0 :       ourContent->GetRowSpec(&mNumRows, &rowSpecs);
    1288           0 :       nsAutoString newRowAttr;
    1289           0 :       GenerateRowCol(aPresContext, height, mNumRows, rowSpecs, mRowSizes.get(),
    1290           0 :                      newRowAttr);
    1291             :       // Setting the attr will trigger a reflow
    1292           0 :       mContent->SetAttr(kNameSpaceID_None, nsGkAtoms::rows, newRowAttr, true);
    1293             :     }
    1294             :   }
    1295             : 
    1296           0 :   ENSURE_TRUE(weakFrame.IsAlive());
    1297           0 :   if (change != 0) {
    1298           0 :     mDrag.Reset(mDragger->mVertical, mDragger->mPrevNeighbor, change, this);
    1299             :   }
    1300             : }
    1301             : 
    1302             : void
    1303           0 : nsHTMLFramesetFrame::EndMouseDrag(nsPresContext* aPresContext)
    1304             : {
    1305           0 :   nsIPresShell::SetCapturingContent(nullptr, 0);
    1306           0 :   mDragger = nullptr;
    1307           0 :   gDragInProgress = false;
    1308           0 : }
    1309             : 
    1310             : nsIFrame*
    1311           0 : NS_NewHTMLFramesetFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
    1312             : {
    1313             : #ifdef DEBUG
    1314           0 :   const nsStyleDisplay* disp = aContext->StyleDisplay();
    1315           0 :   NS_ASSERTION(!disp->IsAbsolutelyPositionedStyle() && !disp->IsFloatingStyle(),
    1316             :                "Framesets should not be positioned and should not float");
    1317             : #endif
    1318             : 
    1319           0 :   return new (aPresShell) nsHTMLFramesetFrame(aContext);
    1320             : }
    1321             : 
    1322           0 : NS_IMPL_FRAMEARENA_HELPERS(nsHTMLFramesetFrame)
    1323             : 
    1324             : /*******************************************************************************
    1325             :  * nsHTMLFramesetBorderFrame
    1326             :  ******************************************************************************/
    1327           0 : nsHTMLFramesetBorderFrame::nsHTMLFramesetBorderFrame(nsStyleContext* aContext,
    1328             :                                                      int32_t aWidth,
    1329             :                                                      bool aVertical,
    1330           0 :                                                      bool aVisibility)
    1331             :   : nsLeafFrame(aContext, kClassID)
    1332             :   , mWidth(aWidth)
    1333             :   , mVertical(aVertical)
    1334           0 :   , mVisibility(aVisibility)
    1335             : {
    1336           0 :    mCanResize    = true;
    1337           0 :    mColor        = NO_COLOR;
    1338           0 :    mPrevNeighbor = 0;
    1339           0 :    mNextNeighbor = 0;
    1340           0 : }
    1341             : 
    1342           0 : nsHTMLFramesetBorderFrame::~nsHTMLFramesetBorderFrame()
    1343             : {
    1344             :   //printf("nsHTMLFramesetBorderFrame destructor %p \n", this);
    1345           0 : }
    1346             : 
    1347           0 : NS_IMPL_FRAMEARENA_HELPERS(nsHTMLFramesetBorderFrame)
    1348             : 
    1349           0 : nscoord nsHTMLFramesetBorderFrame::GetIntrinsicISize()
    1350             : {
    1351             :   // No intrinsic width
    1352           0 :   return 0;
    1353             : }
    1354             : 
    1355           0 : nscoord nsHTMLFramesetBorderFrame::GetIntrinsicBSize()
    1356             : {
    1357             :   // No intrinsic height
    1358           0 :   return 0;
    1359             : }
    1360             : 
    1361           0 : void nsHTMLFramesetBorderFrame::SetVisibility(bool aVisibility)
    1362             : {
    1363           0 :   mVisibility = aVisibility;
    1364           0 : }
    1365             : 
    1366           0 : void nsHTMLFramesetBorderFrame::SetColor(nscolor aColor)
    1367             : {
    1368           0 :   mColor = aColor;
    1369           0 : }
    1370             : 
    1371             : 
    1372             : void
    1373           0 : nsHTMLFramesetBorderFrame::Reflow(nsPresContext*           aPresContext,
    1374             :                                   ReflowOutput&     aDesiredSize,
    1375             :                                   const ReflowInput& aReflowInput,
    1376             :                                   nsReflowStatus&          aStatus)
    1377             : {
    1378           0 :   DO_GLOBAL_REFLOW_COUNT("nsHTMLFramesetBorderFrame");
    1379           0 :   DISPLAY_REFLOW(aPresContext, this, aReflowInput, aDesiredSize, aStatus);
    1380             : 
    1381             :   // Override Reflow(), since we don't want to deal with what our
    1382             :   // computed values are.
    1383           0 :   SizeToAvailSize(aReflowInput, aDesiredSize);
    1384             : 
    1385           0 :   aDesiredSize.SetOverflowAreasToDesiredBounds();
    1386           0 :   aStatus.Reset();
    1387           0 : }
    1388             : 
    1389             : class nsDisplayFramesetBorder : public nsDisplayItem {
    1390             : public:
    1391           0 :   nsDisplayFramesetBorder(nsDisplayListBuilder* aBuilder,
    1392             :                           nsHTMLFramesetBorderFrame* aFrame)
    1393           0 :     : nsDisplayItem(aBuilder, aFrame) {
    1394           0 :     MOZ_COUNT_CTOR(nsDisplayFramesetBorder);
    1395           0 :   }
    1396             : #ifdef NS_BUILD_REFCNT_LOGGING
    1397           0 :   virtual ~nsDisplayFramesetBorder() {
    1398           0 :     MOZ_COUNT_DTOR(nsDisplayFramesetBorder);
    1399           0 :   }
    1400             : #endif
    1401             : 
    1402             :   // REVIEW: see old GetFrameForPoint
    1403             :   // Receives events in its bounds
    1404           0 :   virtual void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
    1405             :                        HitTestState* aState,
    1406             :                        nsTArray<nsIFrame*> *aOutFrames) override {
    1407           0 :     aOutFrames->AppendElement(mFrame);
    1408           0 :   }
    1409             :   virtual void Paint(nsDisplayListBuilder* aBuilder,
    1410             :                      gfxContext* aCtx) override;
    1411           0 :   NS_DISPLAY_DECL_NAME("FramesetBorder", TYPE_FRAMESET_BORDER)
    1412             : };
    1413             : 
    1414           0 : void nsDisplayFramesetBorder::Paint(nsDisplayListBuilder* aBuilder,
    1415             :                                     gfxContext* aCtx)
    1416             : {
    1417           0 :   static_cast<nsHTMLFramesetBorderFrame*>(mFrame)->
    1418           0 :     PaintBorder(aCtx->GetDrawTarget(), ToReferenceFrame());
    1419           0 : }
    1420             : 
    1421             : void
    1422           0 : nsHTMLFramesetBorderFrame::BuildDisplayList(nsDisplayListBuilder*   aBuilder,
    1423             :                                             const nsRect&           aDirtyRect,
    1424             :                                             const nsDisplayListSet& aLists)
    1425             : {
    1426           0 :   aLists.Content()->AppendNewToTop(
    1427           0 :     new (aBuilder) nsDisplayFramesetBorder(aBuilder, this));
    1428           0 : }
    1429             : 
    1430           0 : void nsHTMLFramesetBorderFrame::PaintBorder(DrawTarget* aDrawTarget,
    1431             :                                             nsPoint aPt)
    1432             : {
    1433           0 :   nscoord widthInPixels = nsPresContext::AppUnitsToIntCSSPixels(mWidth);
    1434           0 :   nscoord pixelWidth    = nsPresContext::CSSPixelsToAppUnits(1);
    1435             : 
    1436           0 :   if (widthInPixels <= 0)
    1437           0 :     return;
    1438             : 
    1439           0 :   ColorPattern bgColor(ToDeviceColor(
    1440             :                  LookAndFeel::GetColor(LookAndFeel::eColorID_WidgetBackground,
    1441           0 :                                        NS_RGB(200, 200, 200))));
    1442             : 
    1443           0 :   ColorPattern fgColor(ToDeviceColor(
    1444             :                  LookAndFeel::GetColor(LookAndFeel::eColorID_WidgetForeground,
    1445           0 :                                        NS_RGB(0, 0, 0))));
    1446             : 
    1447           0 :   ColorPattern hltColor(ToDeviceColor(
    1448             :                  LookAndFeel::GetColor(LookAndFeel::eColorID_Widget3DHighlight,
    1449           0 :                                        NS_RGB(255, 255, 255))));
    1450             : 
    1451           0 :   ColorPattern sdwColor(ToDeviceColor(
    1452             :                  LookAndFeel::GetColor(LookAndFeel::eColorID_Widget3DShadow,
    1453           0 :                                        NS_RGB(128, 128, 128))));
    1454             : 
    1455           0 :   ColorPattern color(ToDeviceColor(NS_RGB(255, 255, 255))); // default to white
    1456           0 :   if (mVisibility) {
    1457           0 :     color = (NO_COLOR == mColor) ? bgColor :
    1458           0 :                                    ColorPattern(ToDeviceColor(mColor));
    1459             :   }
    1460             : 
    1461           0 :   int32_t appUnitsPerDevPixel = PresContext()->AppUnitsPerDevPixel();
    1462             : 
    1463           0 :   Point toRefFrame = NSPointToPoint(aPt, appUnitsPerDevPixel);
    1464             : 
    1465           0 :   AutoRestoreTransform autoRestoreTransform(aDrawTarget);
    1466             :   aDrawTarget->SetTransform(
    1467           0 :     aDrawTarget->GetTransform().PreTranslate(toRefFrame));
    1468             : 
    1469           0 :   nsPoint start(0, 0);
    1470           0 :   nsPoint end = mVertical ? nsPoint(0, mRect.height) : nsPoint(mRect.width, 0);
    1471             : 
    1472             :   // draw grey or white first
    1473           0 :   for (int i = 0; i < widthInPixels; i++) {
    1474           0 :     StrokeLineWithSnapping(start, end, appUnitsPerDevPixel, *aDrawTarget,
    1475           0 :                            color);
    1476           0 :     if (mVertical) {
    1477           0 :       start.x += pixelWidth;
    1478           0 :       end.x =  start.x;
    1479             :     } else {
    1480           0 :       start.y += pixelWidth;
    1481           0 :       end.y =  start.y;
    1482             :     }
    1483             :   }
    1484             : 
    1485           0 :   if (!mVisibility)
    1486           0 :     return;
    1487             : 
    1488           0 :   if (widthInPixels >= 5) {
    1489           0 :     start.x = (mVertical) ? pixelWidth : 0;
    1490           0 :     start.y = (mVertical) ? 0 : pixelWidth;
    1491           0 :     end.x   = (mVertical) ? start.x : mRect.width;
    1492           0 :     end.y   = (mVertical) ? mRect.height : start.y;
    1493           0 :     StrokeLineWithSnapping(start, end, appUnitsPerDevPixel, *aDrawTarget,
    1494           0 :                            hltColor);
    1495             :   }
    1496             : 
    1497           0 :   if (widthInPixels >= 2) {
    1498           0 :     start.x = (mVertical) ? mRect.width - (2 * pixelWidth) : 0;
    1499           0 :     start.y = (mVertical) ? 0 : mRect.height - (2 * pixelWidth);
    1500           0 :     end.x   = (mVertical) ? start.x : mRect.width;
    1501           0 :     end.y   = (mVertical) ? mRect.height : start.y;
    1502           0 :     StrokeLineWithSnapping(start, end, appUnitsPerDevPixel, *aDrawTarget,
    1503           0 :                            sdwColor);
    1504             :   }
    1505             : 
    1506           0 :   if (widthInPixels >= 1) {
    1507           0 :     start.x = (mVertical) ? mRect.width - pixelWidth : 0;
    1508           0 :     start.y = (mVertical) ? 0 : mRect.height - pixelWidth;
    1509           0 :     end.x   = (mVertical) ? start.x : mRect.width;
    1510           0 :     end.y   = (mVertical) ? mRect.height : start.y;
    1511           0 :     StrokeLineWithSnapping(start, end, appUnitsPerDevPixel, *aDrawTarget,
    1512           0 :                            fgColor);
    1513             :   }
    1514             : }
    1515             : 
    1516             : 
    1517             : nsresult
    1518           0 : nsHTMLFramesetBorderFrame::HandleEvent(nsPresContext* aPresContext,
    1519             :                                        WidgetGUIEvent* aEvent,
    1520             :                                        nsEventStatus* aEventStatus)
    1521             : {
    1522           0 :   NS_ENSURE_ARG_POINTER(aEventStatus);
    1523           0 :   *aEventStatus = nsEventStatus_eIgnore;
    1524             : 
    1525             :   //XXX Mouse setting logic removed.  The remaining logic should also move.
    1526           0 :   if (!mCanResize) {
    1527           0 :     return NS_OK;
    1528             :   }
    1529             : 
    1530           0 :   if (aEvent->mMessage == eMouseDown &&
    1531           0 :       aEvent->AsMouseEvent()->button == WidgetMouseEvent::eLeftButton) {
    1532           0 :     nsHTMLFramesetFrame* parentFrame = do_QueryFrame(GetParent());
    1533           0 :     if (parentFrame) {
    1534           0 :       parentFrame->StartMouseDrag(aPresContext, this, aEvent);
    1535           0 :       *aEventStatus = nsEventStatus_eConsumeNoDefault;
    1536             :     }
    1537             :   }
    1538           0 :   return NS_OK;
    1539             : }
    1540             : 
    1541             : nsresult
    1542           0 : nsHTMLFramesetBorderFrame::GetCursor(const nsPoint&    aPoint,
    1543             :                                      nsIFrame::Cursor& aCursor)
    1544             : {
    1545           0 :   aCursor.mLoading = false;
    1546           0 :   if (!mCanResize) {
    1547           0 :     aCursor.mCursor = NS_STYLE_CURSOR_DEFAULT;
    1548             :   } else {
    1549           0 :     aCursor.mCursor = (mVertical) ? NS_STYLE_CURSOR_EW_RESIZE : NS_STYLE_CURSOR_NS_RESIZE;
    1550             :   }
    1551           0 :   return NS_OK;
    1552             : }
    1553             : 
    1554             : #ifdef DEBUG_FRAME_DUMP
    1555           0 : nsresult nsHTMLFramesetBorderFrame::GetFrameName(nsAString& aResult) const
    1556             : {
    1557           0 :   return MakeFrameName(NS_LITERAL_STRING("FramesetBorder"), aResult);
    1558             : }
    1559             : #endif
    1560             : 
    1561             : /*******************************************************************************
    1562             :  * nsHTMLFramesetBlankFrame
    1563             :  ******************************************************************************/
    1564             : 
    1565           0 : NS_QUERYFRAME_HEAD(nsHTMLFramesetBlankFrame)
    1566           0 :   NS_QUERYFRAME_ENTRY(nsHTMLFramesetBlankFrame)
    1567           0 : NS_QUERYFRAME_TAIL_INHERITING(nsLeafFrame)
    1568             : 
    1569           0 : NS_IMPL_FRAMEARENA_HELPERS(nsHTMLFramesetBlankFrame)
    1570             : 
    1571           0 : nsHTMLFramesetBlankFrame::~nsHTMLFramesetBlankFrame()
    1572             : {
    1573             :   //printf("nsHTMLFramesetBlankFrame destructor %p \n", this);
    1574           0 : }
    1575             : 
    1576           0 : nscoord nsHTMLFramesetBlankFrame::GetIntrinsicISize()
    1577             : {
    1578             :   // No intrinsic width
    1579           0 :   return 0;
    1580             : }
    1581             : 
    1582           0 : nscoord nsHTMLFramesetBlankFrame::GetIntrinsicBSize()
    1583             : {
    1584             :   // No intrinsic height
    1585           0 :   return 0;
    1586             : }
    1587             : 
    1588             : void
    1589           0 : nsHTMLFramesetBlankFrame::Reflow(nsPresContext*           aPresContext,
    1590             :                                  ReflowOutput&     aDesiredSize,
    1591             :                                  const ReflowInput& aReflowInput,
    1592             :                                  nsReflowStatus&          aStatus)
    1593             : {
    1594           0 :   DO_GLOBAL_REFLOW_COUNT("nsHTMLFramesetBlankFrame");
    1595             : 
    1596             :   // Override Reflow(), since we don't want to deal with what our
    1597             :   // computed values are.
    1598           0 :   SizeToAvailSize(aReflowInput, aDesiredSize);
    1599             : 
    1600           0 :   aDesiredSize.SetOverflowAreasToDesiredBounds();
    1601           0 :   aStatus.Reset();
    1602           0 : }
    1603             : 
    1604             : class nsDisplayFramesetBlank : public nsDisplayItem {
    1605             : public:
    1606           0 :   nsDisplayFramesetBlank(nsDisplayListBuilder* aBuilder,
    1607           0 :                          nsIFrame* aFrame) :
    1608           0 :     nsDisplayItem(aBuilder, aFrame) {
    1609           0 :     MOZ_COUNT_CTOR(nsDisplayFramesetBlank);
    1610           0 :   }
    1611             : #ifdef NS_BUILD_REFCNT_LOGGING
    1612           0 :   virtual ~nsDisplayFramesetBlank() {
    1613           0 :     MOZ_COUNT_DTOR(nsDisplayFramesetBlank);
    1614           0 :   }
    1615             : #endif
    1616             : 
    1617             :   virtual void Paint(nsDisplayListBuilder* aBuilder,
    1618             :                      gfxContext* aCtx) override;
    1619           0 :   NS_DISPLAY_DECL_NAME("FramesetBlank", TYPE_FRAMESET_BLANK)
    1620             : };
    1621             : 
    1622           0 : void nsDisplayFramesetBlank::Paint(nsDisplayListBuilder* aBuilder,
    1623             :                                    gfxContext* aCtx)
    1624             : {
    1625           0 :   DrawTarget* drawTarget = aCtx->GetDrawTarget();
    1626           0 :   int32_t appUnitsPerDevPixel = mFrame->PresContext()->AppUnitsPerDevPixel();
    1627             :   Rect rect =
    1628           0 :     NSRectToSnappedRect(mVisibleRect, appUnitsPerDevPixel, *drawTarget);
    1629           0 :   ColorPattern white(ToDeviceColor(Color(1.f, 1.f, 1.f, 1.f)));
    1630           0 :   drawTarget->FillRect(rect, white);
    1631           0 : }
    1632             : 
    1633             : void
    1634           0 : nsHTMLFramesetBlankFrame::BuildDisplayList(nsDisplayListBuilder*   aBuilder,
    1635             :                                            const nsRect&           aDirtyRect,
    1636             :                                            const nsDisplayListSet& aLists)
    1637             : {
    1638           0 :   aLists.Content()->AppendNewToTop(
    1639           0 :     new (aBuilder) nsDisplayFramesetBlank(aBuilder, this));
    1640           0 : }

Generated by: LCOV version 1.13