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 : }
|