1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/layout/generic/nsFrameSetFrame.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,1698 @@ 1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +/* rendering object for HTML <frameset> elements */ 1.10 + 1.11 +#include "nsFrameSetFrame.h" 1.12 + 1.13 +#include "mozilla/DebugOnly.h" 1.14 +#include "mozilla/Likely.h" 1.15 + 1.16 +#include "nsGenericHTMLElement.h" 1.17 +#include "nsAttrValueInlines.h" 1.18 +#include "nsLeafFrame.h" 1.19 +#include "nsContainerFrame.h" 1.20 +#include "nsPresContext.h" 1.21 +#include "nsIPresShell.h" 1.22 +#include "nsGkAtoms.h" 1.23 +#include "nsStyleConsts.h" 1.24 +#include "nsStyleContext.h" 1.25 +#include "nsHTMLParts.h" 1.26 +#include "nsRenderingContext.h" 1.27 +#include "nsIDOMMutationEvent.h" 1.28 +#include "nsNameSpaceManager.h" 1.29 +#include "nsCSSAnonBoxes.h" 1.30 +#include "nsAutoPtr.h" 1.31 +#include "nsStyleSet.h" 1.32 +#include "mozilla/dom/Element.h" 1.33 +#include "nsDisplayList.h" 1.34 +#include "nsNodeUtils.h" 1.35 +#include "mozAutoDocUpdate.h" 1.36 +#include "mozilla/Preferences.h" 1.37 +#include "mozilla/dom/HTMLFrameSetElement.h" 1.38 +#include "mozilla/LookAndFeel.h" 1.39 +#include "mozilla/MouseEvents.h" 1.40 +#include "nsSubDocumentFrame.h" 1.41 + 1.42 +using namespace mozilla; 1.43 +using namespace mozilla::dom; 1.44 + 1.45 +// masks for mEdgeVisibility 1.46 +#define LEFT_VIS 0x0001 1.47 +#define RIGHT_VIS 0x0002 1.48 +#define TOP_VIS 0x0004 1.49 +#define BOTTOM_VIS 0x0008 1.50 +#define ALL_VIS 0x000F 1.51 +#define NONE_VIS 0x0000 1.52 + 1.53 +/******************************************************************************* 1.54 + * nsFramesetDrag 1.55 + ******************************************************************************/ 1.56 +nsFramesetDrag::nsFramesetDrag() 1.57 +{ 1.58 + UnSet(); 1.59 +} 1.60 + 1.61 +void nsFramesetDrag::Reset(bool aVertical, 1.62 + int32_t aIndex, 1.63 + int32_t aChange, 1.64 + nsHTMLFramesetFrame* aSource) 1.65 +{ 1.66 + mVertical = aVertical; 1.67 + mIndex = aIndex; 1.68 + mChange = aChange; 1.69 + mSource = aSource; 1.70 +} 1.71 + 1.72 +void nsFramesetDrag::UnSet() 1.73 +{ 1.74 + mVertical = true; 1.75 + mIndex = -1; 1.76 + mChange = 0; 1.77 + mSource = nullptr; 1.78 +} 1.79 + 1.80 +/******************************************************************************* 1.81 + * nsHTMLFramesetBorderFrame 1.82 + ******************************************************************************/ 1.83 +class nsHTMLFramesetBorderFrame : public nsLeafFrame 1.84 +{ 1.85 +public: 1.86 + NS_DECL_FRAMEARENA_HELPERS 1.87 + 1.88 +#ifdef DEBUG_FRAME_DUMP 1.89 + virtual nsresult GetFrameName(nsAString& aResult) const MOZ_OVERRIDE; 1.90 +#endif 1.91 + 1.92 + virtual nsresult HandleEvent(nsPresContext* aPresContext, 1.93 + WidgetGUIEvent* aEvent, 1.94 + nsEventStatus* aEventStatus) MOZ_OVERRIDE; 1.95 + 1.96 + virtual nsresult GetCursor(const nsPoint& aPoint, 1.97 + nsIFrame::Cursor& aCursor) MOZ_OVERRIDE; 1.98 + 1.99 + virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder, 1.100 + const nsRect& aDirtyRect, 1.101 + const nsDisplayListSet& aLists) MOZ_OVERRIDE; 1.102 + 1.103 + virtual nsresult Reflow(nsPresContext* aPresContext, 1.104 + nsHTMLReflowMetrics& aDesiredSize, 1.105 + const nsHTMLReflowState& aReflowState, 1.106 + nsReflowStatus& aStatus) MOZ_OVERRIDE; 1.107 + 1.108 + bool GetVisibility() { return mVisibility || mVisibilityOverride; } 1.109 + void SetVisibility(bool aVisibility); 1.110 + void SetColor(nscolor aColor); 1.111 + 1.112 + void PaintBorder(nsRenderingContext& aRenderingContext, nsPoint aPt); 1.113 + 1.114 +protected: 1.115 + nsHTMLFramesetBorderFrame(nsStyleContext* aContext, int32_t aWidth, bool aVertical, bool aVisible); 1.116 + virtual ~nsHTMLFramesetBorderFrame(); 1.117 + virtual nscoord GetIntrinsicWidth() MOZ_OVERRIDE; 1.118 + virtual nscoord GetIntrinsicHeight() MOZ_OVERRIDE; 1.119 + 1.120 + // the prev and next neighbors are indexes into the row (for a horizontal border) or col (for 1.121 + // a vertical border) of nsHTMLFramesetFrames or nsHTMLFrames 1.122 + int32_t mPrevNeighbor; 1.123 + int32_t mNextNeighbor; 1.124 + nscolor mColor; 1.125 + int32_t mWidth; 1.126 + bool mVertical; 1.127 + bool mVisibility; 1.128 + bool mVisibilityOverride; 1.129 + bool mCanResize; 1.130 + friend class nsHTMLFramesetFrame; 1.131 +}; 1.132 +/******************************************************************************* 1.133 + * nsHTMLFramesetBlankFrame 1.134 + ******************************************************************************/ 1.135 +class nsHTMLFramesetBlankFrame : public nsLeafFrame 1.136 +{ 1.137 +public: 1.138 + NS_DECL_QUERYFRAME_TARGET(nsHTMLFramesetBlankFrame) 1.139 + NS_DECL_QUERYFRAME 1.140 + NS_DECL_FRAMEARENA_HELPERS 1.141 + 1.142 +#ifdef DEBUG_FRAME_DUMP 1.143 + virtual nsresult GetFrameName(nsAString& aResult) const MOZ_OVERRIDE 1.144 + { 1.145 + return MakeFrameName(NS_LITERAL_STRING("FramesetBlank"), aResult); 1.146 + } 1.147 +#endif 1.148 + 1.149 + virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder, 1.150 + const nsRect& aDirtyRect, 1.151 + const nsDisplayListSet& aLists) MOZ_OVERRIDE; 1.152 + 1.153 + virtual nsresult Reflow(nsPresContext* aPresContext, 1.154 + nsHTMLReflowMetrics& aDesiredSize, 1.155 + const nsHTMLReflowState& aReflowState, 1.156 + nsReflowStatus& aStatus) MOZ_OVERRIDE; 1.157 + 1.158 +protected: 1.159 + nsHTMLFramesetBlankFrame(nsStyleContext* aContext) : nsLeafFrame(aContext) {} 1.160 + virtual ~nsHTMLFramesetBlankFrame(); 1.161 + virtual nscoord GetIntrinsicWidth() MOZ_OVERRIDE; 1.162 + virtual nscoord GetIntrinsicHeight() MOZ_OVERRIDE; 1.163 + 1.164 + friend class nsHTMLFramesetFrame; 1.165 + friend class nsHTMLFrameset; 1.166 +}; 1.167 + 1.168 +/******************************************************************************* 1.169 + * nsHTMLFramesetFrame 1.170 + ******************************************************************************/ 1.171 +bool nsHTMLFramesetFrame::gDragInProgress = false; 1.172 +#define kFrameResizePref "layout.frames.force_resizability" 1.173 +#define DEFAULT_BORDER_WIDTH_PX 6 1.174 + 1.175 +nsHTMLFramesetFrame::nsHTMLFramesetFrame(nsStyleContext* aContext) 1.176 + : nsContainerFrame(aContext) 1.177 +{ 1.178 + mNumRows = 0; 1.179 + mRowSizes = nullptr; 1.180 + mNumCols = 0; 1.181 + mColSizes = nullptr; 1.182 + mEdgeVisibility = 0; 1.183 + mParentFrameborder = eFrameborder_Yes; // default 1.184 + mParentBorderWidth = -1; // default not set 1.185 + mParentBorderColor = NO_COLOR; // default not set 1.186 + mFirstDragPoint.x = mFirstDragPoint.y = 0; 1.187 + mMinDrag = nsPresContext::CSSPixelsToAppUnits(2); 1.188 + mNonBorderChildCount = 0; 1.189 + mNonBlankChildCount = 0; 1.190 + mDragger = nullptr; 1.191 + mChildCount = 0; 1.192 + mTopLevelFrameset = nullptr; 1.193 + mEdgeColors.Set(NO_COLOR); 1.194 + mVerBorders = nullptr; 1.195 + mHorBorders = nullptr; 1.196 + mChildFrameborder = nullptr; 1.197 + mChildBorderColors = nullptr; 1.198 + mForceFrameResizability = false; 1.199 +} 1.200 + 1.201 +nsHTMLFramesetFrame::~nsHTMLFramesetFrame() 1.202 +{ 1.203 + delete[] mRowSizes; 1.204 + delete[] mColSizes; 1.205 + delete[] mVerBorders; 1.206 + delete[] mHorBorders; 1.207 + delete[] mChildFrameborder; 1.208 + delete[] mChildBorderColors; 1.209 + 1.210 + Preferences::UnregisterCallback(FrameResizePrefCallback, 1.211 + kFrameResizePref, this); 1.212 +} 1.213 + 1.214 +NS_QUERYFRAME_HEAD(nsHTMLFramesetFrame) 1.215 + NS_QUERYFRAME_ENTRY(nsHTMLFramesetFrame) 1.216 +NS_QUERYFRAME_TAIL_INHERITING(nsContainerFrame) 1.217 + 1.218 +// static 1.219 +void 1.220 +nsHTMLFramesetFrame::FrameResizePrefCallback(const char* aPref, void* aClosure) 1.221 +{ 1.222 + nsHTMLFramesetFrame *frame = 1.223 + reinterpret_cast<nsHTMLFramesetFrame *>(aClosure); 1.224 + 1.225 + nsIDocument* doc = frame->mContent->GetDocument(); 1.226 + mozAutoDocUpdate updateBatch(doc, UPDATE_CONTENT_MODEL, true); 1.227 + if (doc) { 1.228 + nsNodeUtils::AttributeWillChange(frame->GetContent()->AsElement(), 1.229 + kNameSpaceID_None, 1.230 + nsGkAtoms::frameborder, 1.231 + nsIDOMMutationEvent::MODIFICATION); 1.232 + } 1.233 + 1.234 + frame->mForceFrameResizability = 1.235 + Preferences::GetBool(kFrameResizePref, frame->mForceFrameResizability); 1.236 + 1.237 + frame->RecalculateBorderResize(); 1.238 + if (doc) { 1.239 + nsNodeUtils::AttributeChanged(frame->GetContent()->AsElement(), 1.240 + kNameSpaceID_None, 1.241 + nsGkAtoms::frameborder, 1.242 + nsIDOMMutationEvent::MODIFICATION); 1.243 + } 1.244 +} 1.245 + 1.246 +void 1.247 +nsHTMLFramesetFrame::Init(nsIContent* aContent, 1.248 + nsIFrame* aParent, 1.249 + nsIFrame* aPrevInFlow) 1.250 +{ 1.251 + nsContainerFrame::Init(aContent, aParent, aPrevInFlow); 1.252 + // find the highest ancestor that is a frameset 1.253 + nsIFrame* parentFrame = GetParent(); 1.254 + mTopLevelFrameset = this; 1.255 + while (parentFrame) { 1.256 + nsHTMLFramesetFrame* frameset = do_QueryFrame(parentFrame); 1.257 + if (frameset) { 1.258 + mTopLevelFrameset = frameset; 1.259 + parentFrame = parentFrame->GetParent(); 1.260 + } else { 1.261 + break; 1.262 + } 1.263 + } 1.264 + 1.265 + nsPresContext* presContext = PresContext(); 1.266 + nsIPresShell* shell = presContext->PresShell(); 1.267 + 1.268 + nsFrameborder frameborder = GetFrameBorder(); 1.269 + int32_t borderWidth = GetBorderWidth(presContext, false); 1.270 + nscolor borderColor = GetBorderColor(); 1.271 + 1.272 + // Get the rows= cols= data 1.273 + HTMLFrameSetElement* ourContent = HTMLFrameSetElement::FromContent(mContent); 1.274 + NS_ASSERTION(ourContent, "Someone gave us a broken frameset element!"); 1.275 + const nsFramesetSpec* rowSpecs = nullptr; 1.276 + const nsFramesetSpec* colSpecs = nullptr; 1.277 + // GetRowSpec and GetColSpec can fail, but when they do they set 1.278 + // mNumRows and mNumCols respectively to 0, so we deal with it fine. 1.279 + ourContent->GetRowSpec(&mNumRows, &rowSpecs); 1.280 + ourContent->GetColSpec(&mNumCols, &colSpecs); 1.281 + 1.282 + // Maximum value of mNumRows and mNumCols is NS_MAX_FRAMESET_SPEC_COUNT 1.283 + PR_STATIC_ASSERT(NS_MAX_FRAMESET_SPEC_COUNT < UINT_MAX / sizeof(nscoord)); 1.284 + mRowSizes = new nscoord[mNumRows]; 1.285 + mColSizes = new nscoord[mNumCols]; 1.286 + 1.287 + // Ensure we can't overflow numCells 1.288 + PR_STATIC_ASSERT(NS_MAX_FRAMESET_SPEC_COUNT < INT32_MAX / NS_MAX_FRAMESET_SPEC_COUNT); 1.289 + int32_t numCells = mNumRows*mNumCols; 1.290 + 1.291 + PR_STATIC_ASSERT(NS_MAX_FRAMESET_SPEC_COUNT < UINT_MAX / sizeof(nsHTMLFramesetBorderFrame*)); 1.292 + mVerBorders = new nsHTMLFramesetBorderFrame*[mNumCols]; // 1 more than number of ver borders 1.293 + 1.294 + for (int verX = 0; verX < mNumCols; verX++) 1.295 + mVerBorders[verX] = nullptr; 1.296 + 1.297 + mHorBorders = new nsHTMLFramesetBorderFrame*[mNumRows]; // 1 more than number of hor borders 1.298 + 1.299 + for (int horX = 0; horX < mNumRows; horX++) 1.300 + mHorBorders[horX] = nullptr; 1.301 + 1.302 + PR_STATIC_ASSERT(NS_MAX_FRAMESET_SPEC_COUNT 1.303 + < UINT_MAX / sizeof(int32_t) / NS_MAX_FRAMESET_SPEC_COUNT); 1.304 + PR_STATIC_ASSERT(NS_MAX_FRAMESET_SPEC_COUNT 1.305 + < UINT_MAX / sizeof(nsFrameborder) / NS_MAX_FRAMESET_SPEC_COUNT); 1.306 + PR_STATIC_ASSERT(NS_MAX_FRAMESET_SPEC_COUNT 1.307 + < UINT_MAX / sizeof(nsBorderColor) / NS_MAX_FRAMESET_SPEC_COUNT); 1.308 + mChildFrameborder = new nsFrameborder[numCells]; 1.309 + mChildBorderColors = new nsBorderColor[numCells]; 1.310 + 1.311 + // create the children frames; skip content which isn't <frameset> or <frame> 1.312 + mChildCount = 0; // number of <frame> or <frameset> children 1.313 + nsIFrame* frame; 1.314 + 1.315 + // number of any type of children 1.316 + uint32_t numChildren = mContent->GetChildCount(); 1.317 + 1.318 + for (uint32_t childX = 0; childX < numChildren; childX++) { 1.319 + if (mChildCount == numCells) { // we have more <frame> or <frameset> than cells 1.320 + // Clear the lazy bits in the remaining children. Also clear 1.321 + // the restyle flags, like nsCSSFrameConstructor::ProcessChildren does. 1.322 + for (uint32_t i = childX; i < numChildren; i++) { 1.323 + nsIContent *child = mContent->GetChildAt(i); 1.324 + child->UnsetFlags(NODE_DESCENDANTS_NEED_FRAMES | NODE_NEEDS_FRAME); 1.325 + if (child->IsElement()) { 1.326 + child->UnsetFlags(ELEMENT_ALL_RESTYLE_FLAGS); 1.327 + } 1.328 + } 1.329 + break; 1.330 + } 1.331 + nsIContent *child = mContent->GetChildAt(childX); 1.332 + child->UnsetFlags(NODE_DESCENDANTS_NEED_FRAMES | NODE_NEEDS_FRAME); 1.333 + // Also clear the restyle flags in the child like 1.334 + // nsCSSFrameConstructor::ProcessChildren does. 1.335 + if (child->IsElement()) { 1.336 + child->UnsetFlags(ELEMENT_ALL_RESTYLE_FLAGS); 1.337 + } 1.338 + 1.339 + // IMPORTANT: This must match the conditions in 1.340 + // nsCSSFrameConstructor::ContentAppended/Inserted/Removed 1.341 + if (!child->IsHTML()) 1.342 + continue; 1.343 + 1.344 + nsIAtom *tag = child->Tag(); 1.345 + if (tag == nsGkAtoms::frameset || tag == nsGkAtoms::frame) { 1.346 + nsRefPtr<nsStyleContext> kidSC; 1.347 + 1.348 + kidSC = shell->StyleSet()->ResolveStyleFor(child->AsElement(), 1.349 + mStyleContext); 1.350 + if (tag == nsGkAtoms::frameset) { 1.351 + frame = NS_NewHTMLFramesetFrame(shell, kidSC); 1.352 + 1.353 + nsHTMLFramesetFrame* childFrame = (nsHTMLFramesetFrame*)frame; 1.354 + childFrame->SetParentFrameborder(frameborder); 1.355 + childFrame->SetParentBorderWidth(borderWidth); 1.356 + childFrame->SetParentBorderColor(borderColor); 1.357 + frame->Init(child, this, nullptr); 1.358 + 1.359 + mChildBorderColors[mChildCount].Set(childFrame->GetBorderColor()); 1.360 + } else { // frame 1.361 + frame = NS_NewSubDocumentFrame(shell, kidSC); 1.362 + 1.363 + frame->Init(child, this, nullptr); 1.364 + 1.365 + mChildFrameborder[mChildCount] = GetFrameBorder(child); 1.366 + mChildBorderColors[mChildCount].Set(GetBorderColor(child)); 1.367 + } 1.368 + child->SetPrimaryFrame(frame); 1.369 + 1.370 + mFrames.AppendFrame(nullptr, frame); 1.371 + 1.372 + mChildCount++; 1.373 + } 1.374 + } 1.375 + 1.376 + mNonBlankChildCount = mChildCount; 1.377 + // add blank frames for frameset cells that had no content provided 1.378 + for (int blankX = mChildCount; blankX < numCells; blankX++) { 1.379 + nsRefPtr<nsStyleContext> pseudoStyleContext; 1.380 + pseudoStyleContext = shell->StyleSet()-> 1.381 + ResolveAnonymousBoxStyle(nsCSSAnonBoxes::framesetBlank, mStyleContext); 1.382 + 1.383 + // XXX the blank frame is using the content of its parent - at some point it 1.384 + // should just have null content, if we support that 1.385 + nsHTMLFramesetBlankFrame* blankFrame = new (shell) nsHTMLFramesetBlankFrame(pseudoStyleContext); 1.386 + 1.387 + blankFrame->Init(mContent, this, nullptr); 1.388 + 1.389 + mFrames.AppendFrame(nullptr, blankFrame); 1.390 + 1.391 + mChildBorderColors[mChildCount].Set(NO_COLOR); 1.392 + mChildCount++; 1.393 + } 1.394 + 1.395 + mNonBorderChildCount = mChildCount; 1.396 +} 1.397 + 1.398 +nsresult 1.399 +nsHTMLFramesetFrame::SetInitialChildList(ChildListID aListID, 1.400 + nsFrameList& aChildList) 1.401 +{ 1.402 + // We do this weirdness where we create our child frames in Init(). On the 1.403 + // other hand, we're going to get a SetInitialChildList() with an empty list 1.404 + // and null list name after the frame constructor is done creating us. So 1.405 + // just ignore that call. 1.406 + if (aListID == kPrincipalList && aChildList.IsEmpty()) { 1.407 + return NS_OK; 1.408 + } 1.409 + 1.410 + return nsContainerFrame::SetInitialChildList(aListID, aChildList); 1.411 +} 1.412 + 1.413 +// XXX should this try to allocate twips based on an even pixel boundary? 1.414 +void nsHTMLFramesetFrame::Scale(nscoord aDesired, 1.415 + int32_t aNumIndicies, 1.416 + int32_t* aIndicies, 1.417 + int32_t aNumItems, 1.418 + int32_t* aItems) 1.419 +{ 1.420 + int32_t actual = 0; 1.421 + int32_t i, j; 1.422 + // get the actual total 1.423 + for (i = 0; i < aNumIndicies; i++) { 1.424 + j = aIndicies[i]; 1.425 + actual += aItems[j]; 1.426 + } 1.427 + 1.428 + if (actual > 0) { 1.429 + float factor = (float)aDesired / (float)actual; 1.430 + actual = 0; 1.431 + // scale the items up or down 1.432 + for (i = 0; i < aNumIndicies; i++) { 1.433 + j = aIndicies[i]; 1.434 + aItems[j] = NSToCoordRound((float)aItems[j] * factor); 1.435 + actual += aItems[j]; 1.436 + } 1.437 + } else if (aNumIndicies != 0) { 1.438 + // All the specs say zero width, but we have to fill up space 1.439 + // somehow. Distribute it equally. 1.440 + nscoord width = NSToCoordRound((float)aDesired / (float)aNumIndicies); 1.441 + actual = width * aNumIndicies; 1.442 + for (i = 0; i < aNumIndicies; i++) { 1.443 + aItems[aIndicies[i]] = width; 1.444 + } 1.445 + } 1.446 + 1.447 + if (aNumIndicies > 0 && aDesired != actual) { 1.448 + int32_t unit = (aDesired > actual) ? 1 : -1; 1.449 + for (i=0; (i < aNumIndicies) && (aDesired != actual); i++) { 1.450 + j = aIndicies[i]; 1.451 + if (j < aNumItems) { 1.452 + aItems[j] += unit; 1.453 + actual += unit; 1.454 + } 1.455 + } 1.456 + } 1.457 +} 1.458 + 1.459 + 1.460 +/** 1.461 + * Translate the rows/cols specs into an array of integer sizes for 1.462 + * each cell in the frameset. Sizes are allocated based on the priorities of the 1.463 + * specifier - fixed sizes have the highest priority, percentage sizes have the next 1.464 + * highest priority and relative sizes have the lowest. 1.465 + */ 1.466 +void nsHTMLFramesetFrame::CalculateRowCol(nsPresContext* aPresContext, 1.467 + nscoord aSize, 1.468 + int32_t aNumSpecs, 1.469 + const nsFramesetSpec* aSpecs, 1.470 + nscoord* aValues) 1.471 +{ 1.472 + // aNumSpecs maximum value is NS_MAX_FRAMESET_SPEC_COUNT 1.473 + PR_STATIC_ASSERT(NS_MAX_FRAMESET_SPEC_COUNT < UINT_MAX / sizeof(int32_t)); 1.474 + 1.475 + int32_t fixedTotal = 0; 1.476 + int32_t numFixed = 0; 1.477 + nsAutoArrayPtr<int32_t> fixed(new int32_t[aNumSpecs]); 1.478 + int32_t numPercent = 0; 1.479 + nsAutoArrayPtr<int32_t> percent(new int32_t[aNumSpecs]); 1.480 + int32_t relativeSums = 0; 1.481 + int32_t numRelative = 0; 1.482 + nsAutoArrayPtr<int32_t> relative(new int32_t[aNumSpecs]); 1.483 + 1.484 + if (MOZ_UNLIKELY(!fixed || !percent || !relative)) { 1.485 + return; // NS_ERROR_OUT_OF_MEMORY 1.486 + } 1.487 + 1.488 + int32_t i, j; 1.489 + 1.490 + // initialize the fixed, percent, relative indices, allocate the fixed sizes and zero the others 1.491 + for (i = 0; i < aNumSpecs; i++) { 1.492 + aValues[i] = 0; 1.493 + switch (aSpecs[i].mUnit) { 1.494 + case eFramesetUnit_Fixed: 1.495 + aValues[i] = nsPresContext::CSSPixelsToAppUnits(aSpecs[i].mValue); 1.496 + fixedTotal += aValues[i]; 1.497 + fixed[numFixed] = i; 1.498 + numFixed++; 1.499 + break; 1.500 + case eFramesetUnit_Percent: 1.501 + percent[numPercent] = i; 1.502 + numPercent++; 1.503 + break; 1.504 + case eFramesetUnit_Relative: 1.505 + relative[numRelative] = i; 1.506 + numRelative++; 1.507 + relativeSums += aSpecs[i].mValue; 1.508 + break; 1.509 + } 1.510 + } 1.511 + 1.512 + // scale the fixed sizes if they total too much (or too little and there aren't any percent or relative) 1.513 + if ((fixedTotal > aSize) || ((fixedTotal < aSize) && (0 == numPercent) && (0 == numRelative))) { 1.514 + Scale(aSize, numFixed, fixed, aNumSpecs, aValues); 1.515 + return; 1.516 + } 1.517 + 1.518 + int32_t percentMax = aSize - fixedTotal; 1.519 + int32_t percentTotal = 0; 1.520 + // allocate the percentage sizes from what is left over from the fixed allocation 1.521 + for (i = 0; i < numPercent; i++) { 1.522 + j = percent[i]; 1.523 + aValues[j] = NSToCoordRound((float)aSpecs[j].mValue * (float)aSize / 100.0f); 1.524 + percentTotal += aValues[j]; 1.525 + } 1.526 + 1.527 + // scale the percent sizes if they total too much (or too little and there aren't any relative) 1.528 + if ((percentTotal > percentMax) || ((percentTotal < percentMax) && (0 == numRelative))) { 1.529 + Scale(percentMax, numPercent, percent, aNumSpecs, aValues); 1.530 + return; 1.531 + } 1.532 + 1.533 + int32_t relativeMax = percentMax - percentTotal; 1.534 + int32_t relativeTotal = 0; 1.535 + // allocate the relative sizes from what is left over from the percent allocation 1.536 + for (i = 0; i < numRelative; i++) { 1.537 + j = relative[i]; 1.538 + aValues[j] = NSToCoordRound((float)aSpecs[j].mValue * (float)relativeMax / (float)relativeSums); 1.539 + relativeTotal += aValues[j]; 1.540 + } 1.541 + 1.542 + // scale the relative sizes if they take up too much or too little 1.543 + if (relativeTotal != relativeMax) { 1.544 + Scale(relativeMax, numRelative, relative, aNumSpecs, aValues); 1.545 + } 1.546 +} 1.547 + 1.548 + 1.549 +/** 1.550 + * Translate the rows/cols integer sizes into an array of specs for 1.551 + * each cell in the frameset. Reverse of CalculateRowCol() behaviour. 1.552 + * This allows us to maintain the user size info through reflows. 1.553 + */ 1.554 +void nsHTMLFramesetFrame::GenerateRowCol(nsPresContext* aPresContext, 1.555 + nscoord aSize, 1.556 + int32_t aNumSpecs, 1.557 + const nsFramesetSpec* aSpecs, 1.558 + nscoord* aValues, 1.559 + nsString& aNewAttr) 1.560 +{ 1.561 + int32_t i; 1.562 + 1.563 + for (i = 0; i < aNumSpecs; i++) { 1.564 + if (!aNewAttr.IsEmpty()) 1.565 + aNewAttr.Append(char16_t(',')); 1.566 + 1.567 + switch (aSpecs[i].mUnit) { 1.568 + case eFramesetUnit_Fixed: 1.569 + aNewAttr.AppendInt(nsPresContext::AppUnitsToIntCSSPixels(aValues[i])); 1.570 + break; 1.571 + case eFramesetUnit_Percent: // XXX Only accurate to 1%, need 1 pixel 1.572 + case eFramesetUnit_Relative: 1.573 + // Add 0.5 to the percentage to make rounding work right. 1.574 + aNewAttr.AppendInt(uint32_t((100.0*aValues[i])/aSize + 0.5)); 1.575 + aNewAttr.Append(char16_t('%')); 1.576 + break; 1.577 + } 1.578 + } 1.579 +} 1.580 + 1.581 +int32_t nsHTMLFramesetFrame::GetBorderWidth(nsPresContext* aPresContext, 1.582 + bool aTakeForcingIntoAccount) 1.583 +{ 1.584 + bool forcing = mForceFrameResizability && aTakeForcingIntoAccount; 1.585 + 1.586 + if (!forcing) { 1.587 + nsFrameborder frameborder = GetFrameBorder(); 1.588 + if (frameborder == eFrameborder_No) { 1.589 + return 0; 1.590 + } 1.591 + } 1.592 + nsGenericHTMLElement *content = nsGenericHTMLElement::FromContent(mContent); 1.593 + 1.594 + if (content) { 1.595 + const nsAttrValue* attr = content->GetParsedAttr(nsGkAtoms::border); 1.596 + if (attr) { 1.597 + int32_t intVal = 0; 1.598 + if (attr->Type() == nsAttrValue::eInteger) { 1.599 + intVal = attr->GetIntegerValue(); 1.600 + if (intVal < 0) { 1.601 + intVal = 0; 1.602 + } 1.603 + } 1.604 + 1.605 + if (forcing && intVal == 0) { 1.606 + intVal = DEFAULT_BORDER_WIDTH_PX; 1.607 + } 1.608 + return nsPresContext::CSSPixelsToAppUnits(intVal); 1.609 + } 1.610 + } 1.611 + 1.612 + if (mParentBorderWidth > 0 || 1.613 + (mParentBorderWidth == 0 && !forcing)) { 1.614 + return mParentBorderWidth; 1.615 + } 1.616 + 1.617 + return nsPresContext::CSSPixelsToAppUnits(DEFAULT_BORDER_WIDTH_PX); 1.618 +} 1.619 + 1.620 +void 1.621 +nsHTMLFramesetFrame::GetDesiredSize(nsPresContext* aPresContext, 1.622 + const nsHTMLReflowState& aReflowState, 1.623 + nsHTMLReflowMetrics& aDesiredSize) 1.624 +{ 1.625 + nsHTMLFramesetFrame* framesetParent = do_QueryFrame(GetParent()); 1.626 + if (nullptr == framesetParent) { 1.627 + if (aPresContext->IsPaginated()) { 1.628 + // XXX This needs to be changed when framesets paginate properly 1.629 + aDesiredSize.Width() = aReflowState.AvailableWidth(); 1.630 + aDesiredSize.Height() = aReflowState.AvailableHeight(); 1.631 + } else { 1.632 + nsRect area = aPresContext->GetVisibleArea(); 1.633 + 1.634 + aDesiredSize.Width() = area.width; 1.635 + aDesiredSize.Height() = area.height; 1.636 + } 1.637 + } else { 1.638 + nsSize size; 1.639 + framesetParent->GetSizeOfChild(this, size); 1.640 + aDesiredSize.Width() = size.width; 1.641 + aDesiredSize.Height() = size.height; 1.642 + } 1.643 +} 1.644 + 1.645 +// only valid for non border children 1.646 +void nsHTMLFramesetFrame::GetSizeOfChildAt(int32_t aIndexInParent, 1.647 + nsSize& aSize, 1.648 + nsIntPoint& aCellIndex) 1.649 +{ 1.650 + int32_t row = aIndexInParent / mNumCols; 1.651 + int32_t col = aIndexInParent - (row * mNumCols); // remainder from dividing index by mNumCols 1.652 + if ((row < mNumRows) && (col < mNumCols)) { 1.653 + aSize.width = mColSizes[col]; 1.654 + aSize.height = mRowSizes[row]; 1.655 + aCellIndex.x = col; 1.656 + aCellIndex.y = row; 1.657 + } else { 1.658 + aSize.width = aSize.height = 0; 1.659 + aCellIndex.x = aCellIndex.y = 0; 1.660 + } 1.661 +} 1.662 + 1.663 +// only valid for non border children 1.664 +void nsHTMLFramesetFrame::GetSizeOfChild(nsIFrame* aChild, 1.665 + nsSize& aSize) 1.666 +{ 1.667 + // Reflow only creates children frames for <frameset> and <frame> content. 1.668 + // this assumption is used here 1.669 + int i = 0; 1.670 + for (nsIFrame* child = mFrames.FirstChild(); child; 1.671 + child = child->GetNextSibling()) { 1.672 + if (aChild == child) { 1.673 + nsIntPoint ignore; 1.674 + GetSizeOfChildAt(i, aSize, ignore); 1.675 + return; 1.676 + } 1.677 + i++; 1.678 + } 1.679 + aSize.width = 0; 1.680 + aSize.height = 0; 1.681 +} 1.682 + 1.683 + 1.684 +nsresult nsHTMLFramesetFrame::HandleEvent(nsPresContext* aPresContext, 1.685 + WidgetGUIEvent* aEvent, 1.686 + nsEventStatus* aEventStatus) 1.687 +{ 1.688 + NS_ENSURE_ARG_POINTER(aEventStatus); 1.689 + if (mDragger) { 1.690 + // the nsFramesetBorderFrame has captured NS_MOUSE_DOWN 1.691 + switch (aEvent->message) { 1.692 + case NS_MOUSE_MOVE: 1.693 + MouseDrag(aPresContext, aEvent); 1.694 + break; 1.695 + case NS_MOUSE_BUTTON_UP: 1.696 + if (aEvent->AsMouseEvent()->button == WidgetMouseEvent::eLeftButton) { 1.697 + EndMouseDrag(aPresContext); 1.698 + } 1.699 + break; 1.700 + } 1.701 + *aEventStatus = nsEventStatus_eConsumeNoDefault; 1.702 + } else { 1.703 + *aEventStatus = nsEventStatus_eIgnore; 1.704 + } 1.705 + return NS_OK; 1.706 +} 1.707 + 1.708 +nsresult 1.709 +nsHTMLFramesetFrame::GetCursor(const nsPoint& aPoint, 1.710 + nsIFrame::Cursor& aCursor) 1.711 +{ 1.712 + if (mDragger) { 1.713 + aCursor.mCursor = (mDragger->mVertical) ? NS_STYLE_CURSOR_EW_RESIZE : NS_STYLE_CURSOR_NS_RESIZE; 1.714 + } else { 1.715 + aCursor.mCursor = NS_STYLE_CURSOR_DEFAULT; 1.716 + } 1.717 + return NS_OK; 1.718 +} 1.719 + 1.720 +void 1.721 +nsHTMLFramesetFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, 1.722 + const nsRect& aDirtyRect, 1.723 + const nsDisplayListSet& aLists) 1.724 +{ 1.725 + BuildDisplayListForInline(aBuilder, aDirtyRect, aLists); 1.726 + 1.727 + if (mDragger && aBuilder->IsForEventDelivery()) { 1.728 + aLists.Content()->AppendNewToTop( 1.729 + new (aBuilder) nsDisplayEventReceiver(aBuilder, this)); 1.730 + } 1.731 +} 1.732 + 1.733 +void 1.734 +nsHTMLFramesetFrame::ReflowPlaceChild(nsIFrame* aChild, 1.735 + nsPresContext* aPresContext, 1.736 + const nsHTMLReflowState& aReflowState, 1.737 + nsPoint& aOffset, 1.738 + nsSize& aSize, 1.739 + nsIntPoint* aCellIndex) 1.740 +{ 1.741 + // reflow the child 1.742 + nsHTMLReflowState reflowState(aPresContext, aReflowState, aChild, aSize); 1.743 + reflowState.SetComputedWidth(std::max(0, aSize.width - reflowState.ComputedPhysicalBorderPadding().LeftRight())); 1.744 + reflowState.SetComputedHeight(std::max(0, aSize.height - reflowState.ComputedPhysicalBorderPadding().TopBottom())); 1.745 + nsHTMLReflowMetrics metrics(aReflowState); 1.746 + metrics.Width() = aSize.width; 1.747 + metrics.Height() = aSize.height; 1.748 + nsReflowStatus status; 1.749 + 1.750 + ReflowChild(aChild, aPresContext, metrics, reflowState, aOffset.x, 1.751 + aOffset.y, 0, status); 1.752 + NS_ASSERTION(NS_FRAME_IS_COMPLETE(status), "bad status"); 1.753 + 1.754 + // Place and size the child 1.755 + metrics.Width() = aSize.width; 1.756 + metrics.Height() = aSize.height; 1.757 + FinishReflowChild(aChild, aPresContext, metrics, nullptr, aOffset.x, aOffset.y, 0); 1.758 +} 1.759 + 1.760 +static 1.761 +nsFrameborder GetFrameBorderHelper(nsGenericHTMLElement* aContent) 1.762 +{ 1.763 + if (nullptr != aContent) { 1.764 + const nsAttrValue* attr = aContent->GetParsedAttr(nsGkAtoms::frameborder); 1.765 + if (attr && attr->Type() == nsAttrValue::eEnum) { 1.766 + switch (attr->GetEnumValue()) 1.767 + { 1.768 + case NS_STYLE_FRAME_YES: 1.769 + case NS_STYLE_FRAME_1: 1.770 + return eFrameborder_Yes; 1.771 + break; 1.772 + 1.773 + case NS_STYLE_FRAME_NO: 1.774 + case NS_STYLE_FRAME_0: 1.775 + return eFrameborder_No; 1.776 + break; 1.777 + } 1.778 + } 1.779 + } 1.780 + return eFrameborder_Notset; 1.781 +} 1.782 + 1.783 +nsFrameborder nsHTMLFramesetFrame::GetFrameBorder() 1.784 +{ 1.785 + nsFrameborder result = eFrameborder_Notset; 1.786 + nsGenericHTMLElement *content = nsGenericHTMLElement::FromContent(mContent); 1.787 + 1.788 + if (content) { 1.789 + result = GetFrameBorderHelper(content); 1.790 + } 1.791 + if (eFrameborder_Notset == result) { 1.792 + return mParentFrameborder; 1.793 + } 1.794 + return result; 1.795 +} 1.796 + 1.797 +nsFrameborder nsHTMLFramesetFrame::GetFrameBorder(nsIContent* aContent) 1.798 +{ 1.799 + nsFrameborder result = eFrameborder_Notset; 1.800 + 1.801 + nsGenericHTMLElement *content = nsGenericHTMLElement::FromContent(aContent); 1.802 + 1.803 + if (content) { 1.804 + result = GetFrameBorderHelper(content); 1.805 + } 1.806 + if (eFrameborder_Notset == result) { 1.807 + return GetFrameBorder(); 1.808 + } 1.809 + return result; 1.810 +} 1.811 + 1.812 +nscolor nsHTMLFramesetFrame::GetBorderColor() 1.813 +{ 1.814 + nsGenericHTMLElement *content = nsGenericHTMLElement::FromContent(mContent); 1.815 + 1.816 + if (content) { 1.817 + const nsAttrValue* attr = content->GetParsedAttr(nsGkAtoms::bordercolor); 1.818 + if (attr) { 1.819 + nscolor color; 1.820 + if (attr->GetColorValue(color)) { 1.821 + return color; 1.822 + } 1.823 + } 1.824 + } 1.825 + 1.826 + return mParentBorderColor; 1.827 +} 1.828 + 1.829 +nscolor nsHTMLFramesetFrame::GetBorderColor(nsIContent* aContent) 1.830 +{ 1.831 + nsGenericHTMLElement *content = nsGenericHTMLElement::FromContent(aContent); 1.832 + 1.833 + if (content) { 1.834 + const nsAttrValue* attr = content->GetParsedAttr(nsGkAtoms::bordercolor); 1.835 + if (attr) { 1.836 + nscolor color; 1.837 + if (attr->GetColorValue(color)) { 1.838 + return color; 1.839 + } 1.840 + } 1.841 + } 1.842 + return GetBorderColor(); 1.843 +} 1.844 + 1.845 +nsresult 1.846 +nsHTMLFramesetFrame::Reflow(nsPresContext* aPresContext, 1.847 + nsHTMLReflowMetrics& aDesiredSize, 1.848 + const nsHTMLReflowState& aReflowState, 1.849 + nsReflowStatus& aStatus) 1.850 +{ 1.851 + DO_GLOBAL_REFLOW_COUNT("nsHTMLFramesetFrame"); 1.852 + DISPLAY_REFLOW(aPresContext, this, aReflowState, aDesiredSize, aStatus); 1.853 + nsIPresShell *shell = aPresContext->PresShell(); 1.854 + nsStyleSet *styleSet = shell->StyleSet(); 1.855 + 1.856 + mParent->AddStateBits(NS_FRAME_CONTAINS_RELATIVE_HEIGHT); 1.857 + 1.858 + //printf("FramesetFrame2::Reflow %X (%d,%d) \n", this, aReflowState.AvailableWidth(), aReflowState.AvailableHeight()); 1.859 + // Always get the size so that the caller knows how big we are 1.860 + GetDesiredSize(aPresContext, aReflowState, aDesiredSize); 1.861 + 1.862 + nscoord width = (aDesiredSize.Width() <= aReflowState.AvailableWidth()) 1.863 + ? aDesiredSize.Width() : aReflowState.AvailableWidth(); 1.864 + nscoord height = (aDesiredSize.Height() <= aReflowState.AvailableHeight()) 1.865 + ? aDesiredSize.Height() : aReflowState.AvailableHeight(); 1.866 + 1.867 + bool firstTime = (GetStateBits() & NS_FRAME_FIRST_REFLOW) != 0; 1.868 + if (firstTime) { 1.869 + Preferences::RegisterCallback(FrameResizePrefCallback, 1.870 + kFrameResizePref, this); 1.871 + mForceFrameResizability = Preferences::GetBool(kFrameResizePref); 1.872 + } 1.873 + 1.874 + // subtract out the width of all of the potential borders. There are 1.875 + // only borders between <frame>s. There are none on the edges (e.g the 1.876 + // leftmost <frame> has no left border). 1.877 + int32_t borderWidth = GetBorderWidth(aPresContext, true); 1.878 + 1.879 + width -= (mNumCols - 1) * borderWidth; 1.880 + if (width < 0) width = 0; 1.881 + 1.882 + height -= (mNumRows - 1) * borderWidth; 1.883 + if (height < 0) height = 0; 1.884 + 1.885 + HTMLFrameSetElement* ourContent = HTMLFrameSetElement::FromContent(mContent); 1.886 + NS_ASSERTION(ourContent, "Someone gave us a broken frameset element!"); 1.887 + const nsFramesetSpec* rowSpecs = nullptr; 1.888 + const nsFramesetSpec* colSpecs = nullptr; 1.889 + int32_t rows = 0; 1.890 + int32_t cols = 0; 1.891 + ourContent->GetRowSpec(&rows, &rowSpecs); 1.892 + ourContent->GetColSpec(&cols, &colSpecs); 1.893 + // If the number of cols or rows has changed, the frame for the frameset 1.894 + // will be re-created. 1.895 + if (mNumRows != rows || mNumCols != cols) { 1.896 + aStatus = NS_FRAME_COMPLETE; 1.897 + mDrag.UnSet(); 1.898 + NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize); 1.899 + return NS_OK; 1.900 + } 1.901 + 1.902 + CalculateRowCol(aPresContext, width, mNumCols, colSpecs, mColSizes); 1.903 + CalculateRowCol(aPresContext, height, mNumRows, rowSpecs, mRowSizes); 1.904 + 1.905 + nsAutoArrayPtr<bool> verBordersVis; // vertical borders visibility 1.906 + nsAutoArrayPtr<nscolor> verBorderColors; 1.907 + nsAutoArrayPtr<bool> horBordersVis; // horizontal borders visibility 1.908 + nsAutoArrayPtr<nscolor> horBorderColors; 1.909 + nscolor borderColor = GetBorderColor(); 1.910 + nsFrameborder frameborder = GetFrameBorder(); 1.911 + 1.912 + if (firstTime) { 1.913 + // Check for overflow in memory allocations using mNumCols and mNumRows 1.914 + // which have a maxium value of NS_MAX_FRAMESET_SPEC_COUNT. 1.915 + PR_STATIC_ASSERT(NS_MAX_FRAMESET_SPEC_COUNT < UINT_MAX / sizeof(bool)); 1.916 + PR_STATIC_ASSERT(NS_MAX_FRAMESET_SPEC_COUNT < UINT_MAX / sizeof(nscolor)); 1.917 + 1.918 + verBordersVis = new bool[mNumCols]; 1.919 + NS_ENSURE_TRUE(verBordersVis, NS_ERROR_OUT_OF_MEMORY); 1.920 + verBorderColors = new nscolor[mNumCols]; 1.921 + NS_ENSURE_TRUE(verBorderColors, NS_ERROR_OUT_OF_MEMORY); 1.922 + for (int verX = 0; verX < mNumCols; verX++) { 1.923 + verBordersVis[verX] = false; 1.924 + verBorderColors[verX] = NO_COLOR; 1.925 + } 1.926 + 1.927 + horBordersVis = new bool[mNumRows]; 1.928 + NS_ENSURE_TRUE(horBordersVis, NS_ERROR_OUT_OF_MEMORY); 1.929 + horBorderColors = new nscolor[mNumRows]; 1.930 + NS_ENSURE_TRUE(horBorderColors, NS_ERROR_OUT_OF_MEMORY); 1.931 + for (int horX = 0; horX < mNumRows; horX++) { 1.932 + horBordersVis[horX] = false; 1.933 + horBorderColors[horX] = NO_COLOR; 1.934 + } 1.935 + } 1.936 + 1.937 + // reflow the children 1.938 + int32_t lastRow = 0; 1.939 + int32_t lastCol = 0; 1.940 + int32_t borderChildX = mNonBorderChildCount; // index of border children 1.941 + nsHTMLFramesetBorderFrame* borderFrame = nullptr; 1.942 + nsPoint offset(0,0); 1.943 + nsSize size, lastSize; 1.944 + nsIFrame* child = mFrames.FirstChild(); 1.945 + 1.946 + for (int32_t childX = 0; childX < mNonBorderChildCount; childX++) { 1.947 + nsIntPoint cellIndex; 1.948 + GetSizeOfChildAt(childX, size, cellIndex); 1.949 + 1.950 + if (lastRow != cellIndex.y) { // changed to next row 1.951 + offset.x = 0; 1.952 + offset.y += lastSize.height; 1.953 + if (firstTime) { // create horizontal border 1.954 + 1.955 + nsRefPtr<nsStyleContext> pseudoStyleContext; 1.956 + pseudoStyleContext = styleSet-> 1.957 + ResolveAnonymousBoxStyle(nsCSSAnonBoxes::horizontalFramesetBorder, 1.958 + mStyleContext); 1.959 + 1.960 + borderFrame = new (shell) nsHTMLFramesetBorderFrame(pseudoStyleContext, 1.961 + borderWidth, 1.962 + false, 1.963 + false); 1.964 + borderFrame->Init(mContent, this, nullptr); 1.965 + mChildCount++; 1.966 + mFrames.AppendFrame(nullptr, borderFrame); 1.967 + mHorBorders[cellIndex.y-1] = borderFrame; 1.968 + // set the neighbors for determining drag boundaries 1.969 + borderFrame->mPrevNeighbor = lastRow; 1.970 + borderFrame->mNextNeighbor = cellIndex.y; 1.971 + } else { 1.972 + borderFrame = (nsHTMLFramesetBorderFrame*)mFrames.FrameAt(borderChildX); 1.973 + borderFrame->mWidth = borderWidth; 1.974 + borderChildX++; 1.975 + } 1.976 + nsSize borderSize(aDesiredSize.Width(), borderWidth); 1.977 + ReflowPlaceChild(borderFrame, aPresContext, aReflowState, offset, borderSize); 1.978 + borderFrame = nullptr; 1.979 + offset.y += borderWidth; 1.980 + } else { 1.981 + if (cellIndex.x > 0) { // moved to next col in same row 1.982 + if (0 == cellIndex.y) { // in 1st row 1.983 + if (firstTime) { // create vertical border 1.984 + 1.985 + nsRefPtr<nsStyleContext> pseudoStyleContext; 1.986 + pseudoStyleContext = styleSet-> 1.987 + ResolveAnonymousBoxStyle(nsCSSAnonBoxes::verticalFramesetBorder, 1.988 + mStyleContext); 1.989 + 1.990 + borderFrame = new (shell) nsHTMLFramesetBorderFrame(pseudoStyleContext, 1.991 + borderWidth, 1.992 + true, 1.993 + false); 1.994 + borderFrame->Init(mContent, this, nullptr); 1.995 + mChildCount++; 1.996 + mFrames.AppendFrame(nullptr, borderFrame); 1.997 + mVerBorders[cellIndex.x-1] = borderFrame; 1.998 + // set the neighbors for determining drag boundaries 1.999 + borderFrame->mPrevNeighbor = lastCol; 1.1000 + borderFrame->mNextNeighbor = cellIndex.x; 1.1001 + } else { 1.1002 + borderFrame = (nsHTMLFramesetBorderFrame*)mFrames.FrameAt(borderChildX); 1.1003 + borderFrame->mWidth = borderWidth; 1.1004 + borderChildX++; 1.1005 + } 1.1006 + nsSize borderSize(borderWidth, aDesiredSize.Height()); 1.1007 + ReflowPlaceChild(borderFrame, aPresContext, aReflowState, offset, borderSize); 1.1008 + borderFrame = nullptr; 1.1009 + } 1.1010 + offset.x += borderWidth; 1.1011 + } 1.1012 + } 1.1013 + 1.1014 + ReflowPlaceChild(child, aPresContext, aReflowState, offset, size, &cellIndex); 1.1015 + 1.1016 + if (firstTime) { 1.1017 + int32_t childVis; 1.1018 + nsHTMLFramesetFrame* framesetFrame = do_QueryFrame(child); 1.1019 + nsSubDocumentFrame* subdocFrame; 1.1020 + if (framesetFrame) { 1.1021 + childVis = framesetFrame->mEdgeVisibility; 1.1022 + mChildBorderColors[childX] = framesetFrame->mEdgeColors; 1.1023 + } else if ((subdocFrame = do_QueryFrame(child))) { 1.1024 + if (eFrameborder_Yes == mChildFrameborder[childX]) { 1.1025 + childVis = ALL_VIS; 1.1026 + } else if (eFrameborder_No == mChildFrameborder[childX]) { 1.1027 + childVis = NONE_VIS; 1.1028 + } else { // notset 1.1029 + childVis = (eFrameborder_No == frameborder) ? NONE_VIS : ALL_VIS; 1.1030 + } 1.1031 + } else { // blank 1.1032 + DebugOnly<nsHTMLFramesetBlankFrame*> blank; 1.1033 + MOZ_ASSERT(blank = do_QueryFrame(child), "unexpected child frame type"); 1.1034 + childVis = NONE_VIS; 1.1035 + } 1.1036 + nsBorderColor childColors = mChildBorderColors[childX]; 1.1037 + // set the visibility, color of our edge borders based on children 1.1038 + if (0 == cellIndex.x) { 1.1039 + if (!(mEdgeVisibility & LEFT_VIS)) { 1.1040 + mEdgeVisibility |= (LEFT_VIS & childVis); 1.1041 + } 1.1042 + if (NO_COLOR == mEdgeColors.mLeft) { 1.1043 + mEdgeColors.mLeft = childColors.mLeft; 1.1044 + } 1.1045 + } 1.1046 + if (0 == cellIndex.y) { 1.1047 + if (!(mEdgeVisibility & TOP_VIS)) { 1.1048 + mEdgeVisibility |= (TOP_VIS & childVis); 1.1049 + } 1.1050 + if (NO_COLOR == mEdgeColors.mTop) { 1.1051 + mEdgeColors.mTop = childColors.mTop; 1.1052 + } 1.1053 + } 1.1054 + if (mNumCols-1 == cellIndex.x) { 1.1055 + if (!(mEdgeVisibility & RIGHT_VIS)) { 1.1056 + mEdgeVisibility |= (RIGHT_VIS & childVis); 1.1057 + } 1.1058 + if (NO_COLOR == mEdgeColors.mRight) { 1.1059 + mEdgeColors.mRight = childColors.mRight; 1.1060 + } 1.1061 + } 1.1062 + if (mNumRows-1 == cellIndex.y) { 1.1063 + if (!(mEdgeVisibility & BOTTOM_VIS)) { 1.1064 + mEdgeVisibility |= (BOTTOM_VIS & childVis); 1.1065 + } 1.1066 + if (NO_COLOR == mEdgeColors.mBottom) { 1.1067 + mEdgeColors.mBottom = childColors.mBottom; 1.1068 + } 1.1069 + } 1.1070 + // set the visibility of borders that the child may affect 1.1071 + if (childVis & RIGHT_VIS) { 1.1072 + verBordersVis[cellIndex.x] = true; 1.1073 + } 1.1074 + if (childVis & BOTTOM_VIS) { 1.1075 + horBordersVis[cellIndex.y] = true; 1.1076 + } 1.1077 + if ((cellIndex.x > 0) && (childVis & LEFT_VIS)) { 1.1078 + verBordersVis[cellIndex.x-1] = true; 1.1079 + } 1.1080 + if ((cellIndex.y > 0) && (childVis & TOP_VIS)) { 1.1081 + horBordersVis[cellIndex.y-1] = true; 1.1082 + } 1.1083 + // set the colors of borders that the child may affect 1.1084 + if (NO_COLOR == verBorderColors[cellIndex.x]) { 1.1085 + verBorderColors[cellIndex.x] = mChildBorderColors[childX].mRight; 1.1086 + } 1.1087 + if (NO_COLOR == horBorderColors[cellIndex.y]) { 1.1088 + horBorderColors[cellIndex.y] = mChildBorderColors[childX].mBottom; 1.1089 + } 1.1090 + if ((cellIndex.x > 0) && (NO_COLOR == verBorderColors[cellIndex.x-1])) { 1.1091 + verBorderColors[cellIndex.x-1] = mChildBorderColors[childX].mLeft; 1.1092 + } 1.1093 + if ((cellIndex.y > 0) && (NO_COLOR == horBorderColors[cellIndex.y-1])) { 1.1094 + horBorderColors[cellIndex.y-1] = mChildBorderColors[childX].mTop; 1.1095 + } 1.1096 + } 1.1097 + lastRow = cellIndex.y; 1.1098 + lastCol = cellIndex.x; 1.1099 + lastSize = size; 1.1100 + offset.x += size.width; 1.1101 + child = child->GetNextSibling(); 1.1102 + } 1.1103 + 1.1104 + if (firstTime) { 1.1105 + nscolor childColor; 1.1106 + // set the visibility, color, mouse sensitivity of borders 1.1107 + for (int verX = 0; verX < mNumCols-1; verX++) { 1.1108 + if (mVerBorders[verX]) { 1.1109 + mVerBorders[verX]->SetVisibility(verBordersVis[verX]); 1.1110 + if (mForceFrameResizability) { 1.1111 + mVerBorders[verX]->mVisibilityOverride = true; 1.1112 + } else { 1.1113 + SetBorderResize(mVerBorders[verX]); 1.1114 + } 1.1115 + childColor = (NO_COLOR == verBorderColors[verX]) ? borderColor : verBorderColors[verX]; 1.1116 + mVerBorders[verX]->SetColor(childColor); 1.1117 + } 1.1118 + } 1.1119 + for (int horX = 0; horX < mNumRows-1; horX++) { 1.1120 + if (mHorBorders[horX]) { 1.1121 + mHorBorders[horX]->SetVisibility(horBordersVis[horX]); 1.1122 + if (mForceFrameResizability) { 1.1123 + mHorBorders[horX]->mVisibilityOverride = true; 1.1124 + } else { 1.1125 + SetBorderResize(mHorBorders[horX]); 1.1126 + } 1.1127 + childColor = (NO_COLOR == horBorderColors[horX]) ? borderColor : horBorderColors[horX]; 1.1128 + mHorBorders[horX]->SetColor(childColor); 1.1129 + } 1.1130 + } 1.1131 + 1.1132 + delete[] mChildFrameborder; 1.1133 + delete[] mChildBorderColors; 1.1134 + 1.1135 + mChildFrameborder = nullptr; 1.1136 + mChildBorderColors = nullptr; 1.1137 + } 1.1138 + 1.1139 + aStatus = NS_FRAME_COMPLETE; 1.1140 + mDrag.UnSet(); 1.1141 + 1.1142 + aDesiredSize.SetOverflowAreasToDesiredBounds(); 1.1143 + FinishAndStoreOverflow(&aDesiredSize); 1.1144 + 1.1145 + NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize); 1.1146 + return NS_OK; 1.1147 +} 1.1148 + 1.1149 +nsIAtom* 1.1150 +nsHTMLFramesetFrame::GetType() const 1.1151 +{ 1.1152 + return nsGkAtoms::frameSetFrame; 1.1153 +} 1.1154 + 1.1155 +#ifdef DEBUG_FRAME_DUMP 1.1156 +nsresult 1.1157 +nsHTMLFramesetFrame::GetFrameName(nsAString& aResult) const 1.1158 +{ 1.1159 + return MakeFrameName(NS_LITERAL_STRING("Frameset"), aResult); 1.1160 +} 1.1161 +#endif 1.1162 + 1.1163 +bool 1.1164 +nsHTMLFramesetFrame::IsLeaf() const 1.1165 +{ 1.1166 + // We handle constructing our kids manually 1.1167 + return true; 1.1168 +} 1.1169 + 1.1170 +bool 1.1171 +nsHTMLFramesetFrame::CanResize(bool aVertical, 1.1172 + bool aLeft) 1.1173 +{ 1.1174 + int32_t childX; 1.1175 + int32_t startX; 1.1176 + if (aVertical) { 1.1177 + startX = (aLeft) ? 0 : mNumCols-1; 1.1178 + for (childX = startX; childX < mNonBorderChildCount; childX += mNumCols) { 1.1179 + if (!CanChildResize(aVertical, aLeft, childX)) { 1.1180 + return false; 1.1181 + } 1.1182 + } 1.1183 + } else { 1.1184 + startX = (aLeft) ? 0 : (mNumRows - 1) * mNumCols; 1.1185 + int32_t endX = startX + mNumCols; 1.1186 + for (childX = startX; childX < endX; childX++) { 1.1187 + if (!CanChildResize(aVertical, aLeft, childX)) { 1.1188 + return false; 1.1189 + } 1.1190 + } 1.1191 + } 1.1192 + return true; 1.1193 +} 1.1194 + 1.1195 +bool 1.1196 +nsHTMLFramesetFrame::GetNoResize(nsIFrame* aChildFrame) 1.1197 +{ 1.1198 + nsIContent* content = aChildFrame->GetContent(); 1.1199 + 1.1200 + return content && content->HasAttr(kNameSpaceID_None, nsGkAtoms::noresize); 1.1201 +} 1.1202 + 1.1203 +bool 1.1204 +nsHTMLFramesetFrame::CanChildResize(bool aVertical, bool aLeft, int32_t aChildX) 1.1205 +{ 1.1206 + nsIFrame* child = mFrames.FrameAt(aChildX); 1.1207 + nsHTMLFramesetFrame* frameset = do_QueryFrame(child); 1.1208 + return frameset ? frameset->CanResize(aVertical, aLeft) : !GetNoResize(child); 1.1209 +} 1.1210 + 1.1211 +// This calculates and sets the resizability of all border frames 1.1212 + 1.1213 +void 1.1214 +nsHTMLFramesetFrame::RecalculateBorderResize() 1.1215 +{ 1.1216 + if (!mContent) { 1.1217 + return; 1.1218 + } 1.1219 + 1.1220 + PR_STATIC_ASSERT(NS_MAX_FRAMESET_SPEC_COUNT < INT32_MAX / NS_MAX_FRAMESET_SPEC_COUNT); 1.1221 + PR_STATIC_ASSERT(NS_MAX_FRAMESET_SPEC_COUNT 1.1222 + < UINT_MAX / sizeof(int32_t) / NS_MAX_FRAMESET_SPEC_COUNT); 1.1223 + // set the visibility and mouse sensitivity of borders 1.1224 + int32_t verX; 1.1225 + for (verX = 0; verX < mNumCols-1; verX++) { 1.1226 + if (mVerBorders[verX]) { 1.1227 + mVerBorders[verX]->mCanResize = true; 1.1228 + if (mForceFrameResizability) { 1.1229 + mVerBorders[verX]->mVisibilityOverride = true; 1.1230 + } else { 1.1231 + mVerBorders[verX]->mVisibilityOverride = false; 1.1232 + SetBorderResize(mVerBorders[verX]); 1.1233 + } 1.1234 + } 1.1235 + } 1.1236 + int32_t horX; 1.1237 + for (horX = 0; horX < mNumRows-1; horX++) { 1.1238 + if (mHorBorders[horX]) { 1.1239 + mHorBorders[horX]->mCanResize = true; 1.1240 + if (mForceFrameResizability) { 1.1241 + mHorBorders[horX]->mVisibilityOverride = true; 1.1242 + } else { 1.1243 + mHorBorders[horX]->mVisibilityOverride = false; 1.1244 + SetBorderResize(mHorBorders[horX]); 1.1245 + } 1.1246 + } 1.1247 + } 1.1248 +} 1.1249 + 1.1250 +void 1.1251 +nsHTMLFramesetFrame::SetBorderResize(nsHTMLFramesetBorderFrame* aBorderFrame) 1.1252 +{ 1.1253 + if (aBorderFrame->mVertical) { 1.1254 + for (int rowX = 0; rowX < mNumRows; rowX++) { 1.1255 + int32_t childX = aBorderFrame->mPrevNeighbor + (rowX * mNumCols); 1.1256 + if (!CanChildResize(true, false, childX) || 1.1257 + !CanChildResize(true, true, childX+1)) { 1.1258 + aBorderFrame->mCanResize = false; 1.1259 + } 1.1260 + } 1.1261 + } else { 1.1262 + int32_t childX = aBorderFrame->mPrevNeighbor * mNumCols; 1.1263 + int32_t endX = childX + mNumCols; 1.1264 + for (; childX < endX; childX++) { 1.1265 + if (!CanChildResize(false, false, childX)) { 1.1266 + aBorderFrame->mCanResize = false; 1.1267 + } 1.1268 + } 1.1269 + endX = endX + mNumCols; 1.1270 + for (; childX < endX; childX++) { 1.1271 + if (!CanChildResize(false, true, childX)) { 1.1272 + aBorderFrame->mCanResize = false; 1.1273 + } 1.1274 + } 1.1275 + } 1.1276 +} 1.1277 + 1.1278 +void 1.1279 +nsHTMLFramesetFrame::StartMouseDrag(nsPresContext* aPresContext, 1.1280 + nsHTMLFramesetBorderFrame* aBorder, 1.1281 + WidgetGUIEvent* aEvent) 1.1282 +{ 1.1283 +#if 0 1.1284 + int32_t index; 1.1285 + IndexOf(aBorder, index); 1.1286 + NS_ASSERTION((nullptr != aBorder) && (index >= 0), "invalid dragger"); 1.1287 +#endif 1.1288 + 1.1289 + nsIPresShell::SetCapturingContent(GetContent(), CAPTURE_IGNOREALLOWED); 1.1290 + 1.1291 + mDragger = aBorder; 1.1292 + 1.1293 + mFirstDragPoint = LayoutDeviceIntPoint::ToUntyped(aEvent->refPoint); 1.1294 + 1.1295 + // Store the original frame sizes 1.1296 + if (mDragger->mVertical) { 1.1297 + mPrevNeighborOrigSize = mColSizes[mDragger->mPrevNeighbor]; 1.1298 + mNextNeighborOrigSize = mColSizes[mDragger->mNextNeighbor]; 1.1299 + } else { 1.1300 + mPrevNeighborOrigSize = mRowSizes[mDragger->mPrevNeighbor]; 1.1301 + mNextNeighborOrigSize = mRowSizes[mDragger->mNextNeighbor]; 1.1302 + } 1.1303 + 1.1304 + gDragInProgress = true; 1.1305 +} 1.1306 + 1.1307 + 1.1308 +void 1.1309 +nsHTMLFramesetFrame::MouseDrag(nsPresContext* aPresContext, 1.1310 + WidgetGUIEvent* aEvent) 1.1311 +{ 1.1312 + // if the capture ended, reset the drag state 1.1313 + if (nsIPresShell::GetCapturingContent() != GetContent()) { 1.1314 + mDragger = nullptr; 1.1315 + gDragInProgress = false; 1.1316 + return; 1.1317 + } 1.1318 + 1.1319 + int32_t change; // measured positive from left-to-right or top-to-bottom 1.1320 + nsWeakFrame weakFrame(this); 1.1321 + if (mDragger->mVertical) { 1.1322 + change = aPresContext->DevPixelsToAppUnits(aEvent->refPoint.x - mFirstDragPoint.x); 1.1323 + if (change > mNextNeighborOrigSize - mMinDrag) { 1.1324 + change = mNextNeighborOrigSize - mMinDrag; 1.1325 + } else if (change <= mMinDrag - mPrevNeighborOrigSize) { 1.1326 + change = mMinDrag - mPrevNeighborOrigSize; 1.1327 + } 1.1328 + mColSizes[mDragger->mPrevNeighbor] = mPrevNeighborOrigSize + change; 1.1329 + mColSizes[mDragger->mNextNeighbor] = mNextNeighborOrigSize - change; 1.1330 + 1.1331 + if (change != 0) { 1.1332 + // Recompute the specs from the new sizes. 1.1333 + nscoord width = mRect.width - (mNumCols - 1) * GetBorderWidth(aPresContext, true); 1.1334 + HTMLFrameSetElement* ourContent = HTMLFrameSetElement::FromContent(mContent); 1.1335 + NS_ASSERTION(ourContent, "Someone gave us a broken frameset element!"); 1.1336 + const nsFramesetSpec* colSpecs = nullptr; 1.1337 + ourContent->GetColSpec(&mNumCols, &colSpecs); 1.1338 + nsAutoString newColAttr; 1.1339 + GenerateRowCol(aPresContext, width, mNumCols, colSpecs, mColSizes, 1.1340 + newColAttr); 1.1341 + // Setting the attr will trigger a reflow 1.1342 + mContent->SetAttr(kNameSpaceID_None, nsGkAtoms::cols, newColAttr, true); 1.1343 + } 1.1344 + } else { 1.1345 + change = aPresContext->DevPixelsToAppUnits(aEvent->refPoint.y - mFirstDragPoint.y); 1.1346 + if (change > mNextNeighborOrigSize - mMinDrag) { 1.1347 + change = mNextNeighborOrigSize - mMinDrag; 1.1348 + } else if (change <= mMinDrag - mPrevNeighborOrigSize) { 1.1349 + change = mMinDrag - mPrevNeighborOrigSize; 1.1350 + } 1.1351 + mRowSizes[mDragger->mPrevNeighbor] = mPrevNeighborOrigSize + change; 1.1352 + mRowSizes[mDragger->mNextNeighbor] = mNextNeighborOrigSize - change; 1.1353 + 1.1354 + if (change != 0) { 1.1355 + // Recompute the specs from the new sizes. 1.1356 + nscoord height = mRect.height - (mNumRows - 1) * GetBorderWidth(aPresContext, true); 1.1357 + HTMLFrameSetElement* ourContent = HTMLFrameSetElement::FromContent(mContent); 1.1358 + NS_ASSERTION(ourContent, "Someone gave us a broken frameset element!"); 1.1359 + const nsFramesetSpec* rowSpecs = nullptr; 1.1360 + ourContent->GetRowSpec(&mNumRows, &rowSpecs); 1.1361 + nsAutoString newRowAttr; 1.1362 + GenerateRowCol(aPresContext, height, mNumRows, rowSpecs, mRowSizes, 1.1363 + newRowAttr); 1.1364 + // Setting the attr will trigger a reflow 1.1365 + mContent->SetAttr(kNameSpaceID_None, nsGkAtoms::rows, newRowAttr, true); 1.1366 + } 1.1367 + } 1.1368 + 1.1369 + ENSURE_TRUE(weakFrame.IsAlive()); 1.1370 + if (change != 0) { 1.1371 + mDrag.Reset(mDragger->mVertical, mDragger->mPrevNeighbor, change, this); 1.1372 + } 1.1373 +} 1.1374 + 1.1375 +void 1.1376 +nsHTMLFramesetFrame::EndMouseDrag(nsPresContext* aPresContext) 1.1377 +{ 1.1378 + nsIPresShell::SetCapturingContent(nullptr, 0); 1.1379 + mDragger = nullptr; 1.1380 + gDragInProgress = false; 1.1381 +} 1.1382 + 1.1383 +nsIFrame* 1.1384 +NS_NewHTMLFramesetFrame(nsIPresShell* aPresShell, nsStyleContext* aContext) 1.1385 +{ 1.1386 +#ifdef DEBUG 1.1387 + const nsStyleDisplay* disp = aContext->StyleDisplay(); 1.1388 + NS_ASSERTION(!disp->IsAbsolutelyPositionedStyle() && !disp->IsFloatingStyle(), 1.1389 + "Framesets should not be positioned and should not float"); 1.1390 +#endif 1.1391 + 1.1392 + return new (aPresShell) nsHTMLFramesetFrame(aContext); 1.1393 +} 1.1394 + 1.1395 +NS_IMPL_FRAMEARENA_HELPERS(nsHTMLFramesetFrame) 1.1396 + 1.1397 +/******************************************************************************* 1.1398 + * nsHTMLFramesetBorderFrame 1.1399 + ******************************************************************************/ 1.1400 +nsHTMLFramesetBorderFrame::nsHTMLFramesetBorderFrame(nsStyleContext* aContext, 1.1401 + int32_t aWidth, 1.1402 + bool aVertical, 1.1403 + bool aVisibility) 1.1404 + : nsLeafFrame(aContext), mWidth(aWidth), mVertical(aVertical), mVisibility(aVisibility) 1.1405 +{ 1.1406 + mVisibilityOverride = false; 1.1407 + mCanResize = true; 1.1408 + mColor = NO_COLOR; 1.1409 + mPrevNeighbor = 0; 1.1410 + mNextNeighbor = 0; 1.1411 +} 1.1412 + 1.1413 +nsHTMLFramesetBorderFrame::~nsHTMLFramesetBorderFrame() 1.1414 +{ 1.1415 + //printf("nsHTMLFramesetBorderFrame destructor %p \n", this); 1.1416 +} 1.1417 + 1.1418 +NS_IMPL_FRAMEARENA_HELPERS(nsHTMLFramesetBorderFrame) 1.1419 + 1.1420 +nscoord nsHTMLFramesetBorderFrame::GetIntrinsicWidth() 1.1421 +{ 1.1422 + // No intrinsic width 1.1423 + return 0; 1.1424 +} 1.1425 + 1.1426 +nscoord nsHTMLFramesetBorderFrame::GetIntrinsicHeight() 1.1427 +{ 1.1428 + // No intrinsic height 1.1429 + return 0; 1.1430 +} 1.1431 + 1.1432 +void nsHTMLFramesetBorderFrame::SetVisibility(bool aVisibility) 1.1433 +{ 1.1434 + mVisibility = aVisibility; 1.1435 +} 1.1436 + 1.1437 +void nsHTMLFramesetBorderFrame::SetColor(nscolor aColor) 1.1438 +{ 1.1439 + mColor = aColor; 1.1440 +} 1.1441 + 1.1442 + 1.1443 +nsresult 1.1444 +nsHTMLFramesetBorderFrame::Reflow(nsPresContext* aPresContext, 1.1445 + nsHTMLReflowMetrics& aDesiredSize, 1.1446 + const nsHTMLReflowState& aReflowState, 1.1447 + nsReflowStatus& aStatus) 1.1448 +{ 1.1449 + DO_GLOBAL_REFLOW_COUNT("nsHTMLFramesetBorderFrame"); 1.1450 + DISPLAY_REFLOW(aPresContext, this, aReflowState, aDesiredSize, aStatus); 1.1451 + 1.1452 + // Override Reflow(), since we don't want to deal with what our 1.1453 + // computed values are. 1.1454 + SizeToAvailSize(aReflowState, aDesiredSize); 1.1455 + 1.1456 + aDesiredSize.SetOverflowAreasToDesiredBounds(); 1.1457 + aStatus = NS_FRAME_COMPLETE; 1.1458 + return NS_OK; 1.1459 +} 1.1460 + 1.1461 +class nsDisplayFramesetBorder : public nsDisplayItem { 1.1462 +public: 1.1463 + nsDisplayFramesetBorder(nsDisplayListBuilder* aBuilder, 1.1464 + nsHTMLFramesetBorderFrame* aFrame) 1.1465 + : nsDisplayItem(aBuilder, aFrame) { 1.1466 + MOZ_COUNT_CTOR(nsDisplayFramesetBorder); 1.1467 + } 1.1468 +#ifdef NS_BUILD_REFCNT_LOGGING 1.1469 + virtual ~nsDisplayFramesetBorder() { 1.1470 + MOZ_COUNT_DTOR(nsDisplayFramesetBorder); 1.1471 + } 1.1472 +#endif 1.1473 + 1.1474 + // REVIEW: see old GetFrameForPoint 1.1475 + // Receives events in its bounds 1.1476 + virtual void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect, 1.1477 + HitTestState* aState, 1.1478 + nsTArray<nsIFrame*> *aOutFrames) MOZ_OVERRIDE { 1.1479 + aOutFrames->AppendElement(mFrame); 1.1480 + } 1.1481 + virtual void Paint(nsDisplayListBuilder* aBuilder, 1.1482 + nsRenderingContext* aCtx) MOZ_OVERRIDE; 1.1483 + NS_DISPLAY_DECL_NAME("FramesetBorder", TYPE_FRAMESET_BORDER) 1.1484 +}; 1.1485 + 1.1486 +void nsDisplayFramesetBorder::Paint(nsDisplayListBuilder* aBuilder, 1.1487 + nsRenderingContext* aCtx) 1.1488 +{ 1.1489 + static_cast<nsHTMLFramesetBorderFrame*>(mFrame)-> 1.1490 + PaintBorder(*aCtx, ToReferenceFrame()); 1.1491 +} 1.1492 + 1.1493 +void 1.1494 +nsHTMLFramesetBorderFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, 1.1495 + const nsRect& aDirtyRect, 1.1496 + const nsDisplayListSet& aLists) 1.1497 +{ 1.1498 + aLists.Content()->AppendNewToTop( 1.1499 + new (aBuilder) nsDisplayFramesetBorder(aBuilder, this)); 1.1500 +} 1.1501 + 1.1502 +void nsHTMLFramesetBorderFrame::PaintBorder(nsRenderingContext& aRenderingContext, 1.1503 + nsPoint aPt) 1.1504 +{ 1.1505 + nscolor WHITE = NS_RGB(255, 255, 255); 1.1506 + 1.1507 + nscolor bgColor = 1.1508 + LookAndFeel::GetColor(LookAndFeel::eColorID_WidgetBackground, 1.1509 + NS_RGB(200,200,200)); 1.1510 + nscolor fgColor = 1.1511 + LookAndFeel::GetColor(LookAndFeel::eColorID_WidgetForeground, 1.1512 + NS_RGB(0,0,0)); 1.1513 + nscolor hltColor = 1.1514 + LookAndFeel::GetColor(LookAndFeel::eColorID_Widget3DHighlight, 1.1515 + NS_RGB(255,255,255)); 1.1516 + nscolor sdwColor = 1.1517 + LookAndFeel::GetColor(LookAndFeel::eColorID_Widget3DShadow, 1.1518 + NS_RGB(128,128,128)); 1.1519 + 1.1520 + nsRenderingContext::AutoPushTranslation 1.1521 + translate(&aRenderingContext, aPt); 1.1522 + 1.1523 + nscoord widthInPixels = nsPresContext::AppUnitsToIntCSSPixels(mWidth); 1.1524 + nscoord pixelWidth = nsPresContext::CSSPixelsToAppUnits(1); 1.1525 + 1.1526 + if (widthInPixels <= 0) 1.1527 + return; 1.1528 + 1.1529 + nsPoint start(0,0); 1.1530 + nsPoint end((mVertical) ? 0 : mRect.width, (mVertical) ? mRect.height : 0); 1.1531 + 1.1532 + nscolor color = WHITE; 1.1533 + if (mVisibility || mVisibilityOverride) { 1.1534 + color = (NO_COLOR == mColor) ? bgColor : mColor; 1.1535 + } 1.1536 + aRenderingContext.SetColor(color); 1.1537 + // draw grey or white first 1.1538 + for (int i = 0; i < widthInPixels; i++) { 1.1539 + aRenderingContext.DrawLine (start, end); 1.1540 + if (mVertical) { 1.1541 + start.x += pixelWidth; 1.1542 + end.x = start.x; 1.1543 + } else { 1.1544 + start.y += pixelWidth; 1.1545 + end.y = start.y; 1.1546 + } 1.1547 + } 1.1548 + 1.1549 + if (!mVisibility && !mVisibilityOverride) 1.1550 + return; 1.1551 + 1.1552 + if (widthInPixels >= 5) { 1.1553 + aRenderingContext.SetColor(hltColor); 1.1554 + start.x = (mVertical) ? pixelWidth : 0; 1.1555 + start.y = (mVertical) ? 0 : pixelWidth; 1.1556 + end.x = (mVertical) ? start.x : mRect.width; 1.1557 + end.y = (mVertical) ? mRect.height : start.y; 1.1558 + aRenderingContext.DrawLine(start, end); 1.1559 + } 1.1560 + 1.1561 + if (widthInPixels >= 2) { 1.1562 + aRenderingContext.SetColor(sdwColor); 1.1563 + start.x = (mVertical) ? mRect.width - (2 * pixelWidth) : 0; 1.1564 + start.y = (mVertical) ? 0 : mRect.height - (2 * pixelWidth); 1.1565 + end.x = (mVertical) ? start.x : mRect.width; 1.1566 + end.y = (mVertical) ? mRect.height : start.y; 1.1567 + aRenderingContext.DrawLine(start, end); 1.1568 + } 1.1569 + 1.1570 + if (widthInPixels >= 1) { 1.1571 + aRenderingContext.SetColor(fgColor); 1.1572 + start.x = (mVertical) ? mRect.width - pixelWidth : 0; 1.1573 + start.y = (mVertical) ? 0 : mRect.height - pixelWidth; 1.1574 + end.x = (mVertical) ? start.x : mRect.width; 1.1575 + end.y = (mVertical) ? mRect.height : start.y; 1.1576 + aRenderingContext.DrawLine(start, end); 1.1577 + } 1.1578 +} 1.1579 + 1.1580 + 1.1581 +nsresult 1.1582 +nsHTMLFramesetBorderFrame::HandleEvent(nsPresContext* aPresContext, 1.1583 + WidgetGUIEvent* aEvent, 1.1584 + nsEventStatus* aEventStatus) 1.1585 +{ 1.1586 + NS_ENSURE_ARG_POINTER(aEventStatus); 1.1587 + *aEventStatus = nsEventStatus_eIgnore; 1.1588 + 1.1589 + //XXX Mouse setting logic removed. The remaining logic should also move. 1.1590 + if (!mCanResize) { 1.1591 + return NS_OK; 1.1592 + } 1.1593 + 1.1594 + if (aEvent->message == NS_MOUSE_BUTTON_DOWN && 1.1595 + aEvent->AsMouseEvent()->button == WidgetMouseEvent::eLeftButton) { 1.1596 + nsHTMLFramesetFrame* parentFrame = do_QueryFrame(GetParent()); 1.1597 + if (parentFrame) { 1.1598 + parentFrame->StartMouseDrag(aPresContext, this, aEvent); 1.1599 + *aEventStatus = nsEventStatus_eConsumeNoDefault; 1.1600 + } 1.1601 + } 1.1602 + return NS_OK; 1.1603 +} 1.1604 + 1.1605 +nsresult 1.1606 +nsHTMLFramesetBorderFrame::GetCursor(const nsPoint& aPoint, 1.1607 + nsIFrame::Cursor& aCursor) 1.1608 +{ 1.1609 + if (!mCanResize) { 1.1610 + aCursor.mCursor = NS_STYLE_CURSOR_DEFAULT; 1.1611 + } else { 1.1612 + aCursor.mCursor = (mVertical) ? NS_STYLE_CURSOR_EW_RESIZE : NS_STYLE_CURSOR_NS_RESIZE; 1.1613 + } 1.1614 + return NS_OK; 1.1615 +} 1.1616 + 1.1617 +#ifdef DEBUG_FRAME_DUMP 1.1618 +nsresult nsHTMLFramesetBorderFrame::GetFrameName(nsAString& aResult) const 1.1619 +{ 1.1620 + return MakeFrameName(NS_LITERAL_STRING("FramesetBorder"), aResult); 1.1621 +} 1.1622 +#endif 1.1623 + 1.1624 +/******************************************************************************* 1.1625 + * nsHTMLFramesetBlankFrame 1.1626 + ******************************************************************************/ 1.1627 + 1.1628 +NS_QUERYFRAME_HEAD(nsHTMLFramesetBlankFrame) 1.1629 + NS_QUERYFRAME_ENTRY(nsHTMLFramesetBlankFrame) 1.1630 +NS_QUERYFRAME_TAIL_INHERITING(nsLeafFrame) 1.1631 + 1.1632 +NS_IMPL_FRAMEARENA_HELPERS(nsHTMLFramesetBlankFrame) 1.1633 + 1.1634 +nsHTMLFramesetBlankFrame::~nsHTMLFramesetBlankFrame() 1.1635 +{ 1.1636 + //printf("nsHTMLFramesetBlankFrame destructor %p \n", this); 1.1637 +} 1.1638 + 1.1639 +nscoord nsHTMLFramesetBlankFrame::GetIntrinsicWidth() 1.1640 +{ 1.1641 + // No intrinsic width 1.1642 + return 0; 1.1643 +} 1.1644 + 1.1645 +nscoord nsHTMLFramesetBlankFrame::GetIntrinsicHeight() 1.1646 +{ 1.1647 + // No intrinsic height 1.1648 + return 0; 1.1649 +} 1.1650 + 1.1651 +nsresult 1.1652 +nsHTMLFramesetBlankFrame::Reflow(nsPresContext* aPresContext, 1.1653 + nsHTMLReflowMetrics& aDesiredSize, 1.1654 + const nsHTMLReflowState& aReflowState, 1.1655 + nsReflowStatus& aStatus) 1.1656 +{ 1.1657 + DO_GLOBAL_REFLOW_COUNT("nsHTMLFramesetBlankFrame"); 1.1658 + 1.1659 + // Override Reflow(), since we don't want to deal with what our 1.1660 + // computed values are. 1.1661 + SizeToAvailSize(aReflowState, aDesiredSize); 1.1662 + 1.1663 + aDesiredSize.SetOverflowAreasToDesiredBounds(); 1.1664 + aStatus = NS_FRAME_COMPLETE; 1.1665 + return NS_OK; 1.1666 +} 1.1667 + 1.1668 +class nsDisplayFramesetBlank : public nsDisplayItem { 1.1669 +public: 1.1670 + nsDisplayFramesetBlank(nsDisplayListBuilder* aBuilder, 1.1671 + nsIFrame* aFrame) : 1.1672 + nsDisplayItem(aBuilder, aFrame) { 1.1673 + MOZ_COUNT_CTOR(nsDisplayFramesetBlank); 1.1674 + } 1.1675 +#ifdef NS_BUILD_REFCNT_LOGGING 1.1676 + virtual ~nsDisplayFramesetBlank() { 1.1677 + MOZ_COUNT_DTOR(nsDisplayFramesetBlank); 1.1678 + } 1.1679 +#endif 1.1680 + 1.1681 + virtual void Paint(nsDisplayListBuilder* aBuilder, 1.1682 + nsRenderingContext* aCtx) MOZ_OVERRIDE; 1.1683 + NS_DISPLAY_DECL_NAME("FramesetBlank", TYPE_FRAMESET_BLANK) 1.1684 +}; 1.1685 + 1.1686 +void nsDisplayFramesetBlank::Paint(nsDisplayListBuilder* aBuilder, 1.1687 + nsRenderingContext* aCtx) 1.1688 +{ 1.1689 + nscolor white = NS_RGB(255,255,255); 1.1690 + aCtx->SetColor(white); 1.1691 + aCtx->FillRect(mVisibleRect); 1.1692 +} 1.1693 + 1.1694 +void 1.1695 +nsHTMLFramesetBlankFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, 1.1696 + const nsRect& aDirtyRect, 1.1697 + const nsDisplayListSet& aLists) 1.1698 +{ 1.1699 + aLists.Content()->AppendNewToTop( 1.1700 + new (aBuilder) nsDisplayFramesetBlank(aBuilder, this)); 1.1701 +}