1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* ***** BEGIN LICENSE BLOCK *****
3 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
5 * The contents of this file are subject to the Mozilla Public License Version
6 * 1.1 (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 * http://www.mozilla.org/MPL/
10 * Software distributed under the License is distributed on an "AS IS" basis,
11 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 * for the specific language governing rights and limitations under the
15 * The Original Code is mozilla.org code.
17 * The Initial Developer of the Original Code is
18 * Netscape Communications Corporation.
19 * Portions created by the Initial Developer are Copyright (C) 1998
20 * the Initial Developer. All Rights Reserved.
24 * Alternatively, the contents of this file may be used under the terms of
25 * either of the GNU General Public License Version 2 or later (the "GPL"),
26 * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
27 * in which case the provisions of the GPL or the LGPL are applicable instead
28 * of those above. If you wish to allow use of your version of this file only
29 * under the terms of either the GPL or the LGPL, and not to allow others to
30 * use your version of this file under the terms of the MPL, indicate your
31 * decision by deleting the provisions above and replace them with the notice
32 * and other provisions required by the GPL or the LGPL. If you do not delete
33 * the provisions above, a recipient may use your version of this file under
34 * the terms of any one of the MPL, the GPL or the LGPL.
36 * ***** END LICENSE BLOCK ***** */
38 /* rendering object that goes directly inside the document's scrollbars */
40 #include "nsIServiceManager.h"
41 #include "nsHTMLParts.h"
42 #include "nsHTMLContainerFrame.h"
43 #include "nsCSSRendering.h"
44 #include "nsPresContext.h"
45 #include "nsStyleContext.h"
47 #include "nsIViewManager.h"
48 #include "nsIRenderingContext.h"
49 #include "nsGUIEvent.h"
50 #include "nsStyleConsts.h"
51 #include "nsGkAtoms.h"
52 #include "nsIEventStateManager.h"
53 #include "nsIDeviceContext.h"
54 #include "nsIPresShell.h"
55 #include "nsIScrollPositionListener.h"
56 #include "nsDisplayList.h"
57 #include "nsAbsoluteContainingBlock.h"
60 #include "nsIDOMWindowInternal.h"
61 #include "nsIFocusController.h"
62 #include "nsIScrollableFrame.h"
63 #include "nsIScrollableView.h"
64 #include "nsIDocShell.h"
65 #include "nsICanvasFrame.h"
68 //#define DEBUG_CANVAS_FOCUS
71 #define CANVAS_ABS_POS_CHILD_LIST NS_CONTAINER_LIST_COUNT_INCL_OC
78 * The root frame is the parent frame for the document element's frame.
79 * It only supports having a single child frame which must be an area
82 class CanvasFrame
: public nsHTMLContainerFrame
,
83 public nsIScrollPositionListener
,
84 public nsICanvasFrame
{
86 CanvasFrame(nsStyleContext
* aContext
)
87 : nsHTMLContainerFrame(aContext
), mDoPaintFocus(PR_FALSE
),
88 mAbsoluteContainer(nsGkAtoms::absoluteList
) {}
91 NS_IMETHOD
QueryInterface(const nsIID
& aIID
, void** aInstancePtr
);
93 NS_IMETHOD
Init(nsIContent
* aContent
,
95 nsIFrame
* aPrevInFlow
);
96 virtual void Destroy();
98 NS_IMETHOD
SetInitialChildList(nsIAtom
* aListName
,
99 nsIFrame
* aChildList
);
100 NS_IMETHOD
AppendFrames(nsIAtom
* aListName
,
101 nsIFrame
* aFrameList
);
102 NS_IMETHOD
InsertFrames(nsIAtom
* aListName
,
103 nsIFrame
* aPrevFrame
,
104 nsIFrame
* aFrameList
);
105 NS_IMETHOD
RemoveFrame(nsIAtom
* aListName
,
106 nsIFrame
* aOldFrame
);
108 virtual nsIAtom
* GetAdditionalChildListName(PRInt32 aIndex
) const;
109 virtual nsIFrame
* GetFirstChild(nsIAtom
* aListName
) const;
111 virtual nscoord
GetMinWidth(nsIRenderingContext
*aRenderingContext
);
112 virtual nscoord
GetPrefWidth(nsIRenderingContext
*aRenderingContext
);
113 NS_IMETHOD
Reflow(nsPresContext
* aPresContext
,
114 nsHTMLReflowMetrics
& aDesiredSize
,
115 const nsHTMLReflowState
& aReflowState
,
116 nsReflowStatus
& aStatus
);
117 virtual PRBool
IsContainingBlock() const { return PR_TRUE
; }
118 virtual PRBool
IsFrameOfType(PRUint32 aFlags
) const
120 return nsHTMLContainerFrame::IsFrameOfType(aFlags
&
121 ~(nsIFrame::eCanContainOverflowContainers
));
124 NS_IMETHOD
BuildDisplayList(nsDisplayListBuilder
* aBuilder
,
125 const nsRect
& aDirtyRect
,
126 const nsDisplayListSet
& aLists
);
128 void PaintFocus(nsIRenderingContext
& aRenderingContext
, nsPoint aPt
);
130 // nsIScrollPositionListener
131 NS_IMETHOD
ScrollPositionWillChange(nsIScrollableView
* aScrollable
, nscoord aX
, nscoord aY
);
132 virtual void ViewPositionDidChange(nsIScrollableView
* aScrollable
) {}
133 NS_IMETHOD
ScrollPositionDidChange(nsIScrollableView
* aScrollable
, nscoord aX
, nscoord aY
);
136 NS_IMETHOD
SetHasFocus(PRBool aHasFocus
);
139 * Get the "type" of the frame
141 * @see nsGkAtoms::canvasFrame
143 virtual nsIAtom
* GetType() const;
145 virtual nsresult
StealFrame(nsPresContext
* aPresContext
,
149 NS_ASSERTION(!aForceNormal
, "No-one should be passing this in here");
151 // CanvasFrame keeps overflow container continuations of its child
152 // frame in main child list
153 nsresult rv
= nsContainerFrame::StealFrame(aPresContext
, aChild
, PR_TRUE
);
155 rv
= nsContainerFrame::StealFrame(aPresContext
, aChild
);
161 NS_IMETHOD
GetFrameName(nsAString
& aResult
) const;
163 NS_IMETHOD
GetContentForEvent(nsPresContext
* aPresContext
,
165 nsIContent
** aContent
);
167 nsRect
CanvasArea() const;
170 virtual PRIntn
GetSkipSides() const;
173 PRPackedBool mDoPaintFocus
;
174 nsCOMPtr
<nsIViewManager
> mViewManager
;
175 nsAbsoluteContainingBlock mAbsoluteContainer
;
178 NS_IMETHOD_(nsrefcnt
) AddRef() { return NS_OK
; }
179 NS_IMETHOD_(nsrefcnt
) Release() { return NS_OK
; }
183 //----------------------------------------------------------------------
186 NS_NewCanvasFrame(nsIPresShell
* aPresShell
, nsStyleContext
* aContext
)
188 return new (aPresShell
)CanvasFrame(aContext
);
191 //--------------------------------------------------------------
192 // Frames are not refcounted, no need to AddRef
194 CanvasFrame::QueryInterface(const nsIID
& aIID
, void** aInstancePtr
)
196 NS_PRECONDITION(aInstancePtr
, "null out param");
198 if (aIID
.Equals(NS_GET_IID(nsIScrollPositionListener
))) {
199 *aInstancePtr
= static_cast<nsIScrollPositionListener
*>(this);
202 if (aIID
.Equals(NS_GET_IID(nsICanvasFrame
))) {
203 *aInstancePtr
= static_cast<nsICanvasFrame
*>(this);
207 return nsHTMLContainerFrame::QueryInterface(aIID
, aInstancePtr
);
211 CanvasFrame::Init(nsIContent
* aContent
,
213 nsIFrame
* aPrevInFlow
)
215 nsresult rv
= nsHTMLContainerFrame::Init(aContent
, aParent
, aPrevInFlow
);
217 mViewManager
= PresContext()->GetViewManager();
219 nsIScrollableView
* scrollingView
= nsnull
;
220 mViewManager
->GetRootScrollableView(&scrollingView
);
222 scrollingView
->AddScrollPositionListener(this);
229 CanvasFrame::Destroy()
231 mAbsoluteContainer
.DestroyFrames(this);
233 nsIScrollableView
* scrollingView
= nsnull
;
234 mViewManager
->GetRootScrollableView(&scrollingView
);
236 scrollingView
->RemoveScrollPositionListener(this);
239 nsHTMLContainerFrame::Destroy();
243 CanvasFrame::ScrollPositionWillChange(nsIScrollableView
* aScrollable
, nscoord aX
, nscoord aY
)
245 #ifdef DEBUG_CANVAS_FOCUS
247 PRBool hasFocus
= PR_FALSE
;
248 nsCOMPtr
<nsIViewObserver
> observer
;
249 mViewManager
->GetViewObserver(*getter_AddRefs(observer
));
250 nsCOMPtr
<nsIPresShell
> shell
= do_QueryInterface(observer
);
251 nsCOMPtr
<nsPresContext
> context
;
252 shell
->GetPresContext(getter_AddRefs(context
));
253 nsCOMPtr
<nsISupports
> container
;
254 context
->GetContainer(getter_AddRefs(container
));
255 nsCOMPtr
<nsIDocShell
> docShell(do_QueryInterface(container
));
257 docShell
->GetHasFocus(&hasFocus
);
259 printf("SPWC: %p HF: %s mDoPaintFocus: %s\n", docShell
.get(), hasFocus
?"Y":"N", mDoPaintFocus
?"Y":"N");
264 mDoPaintFocus
= PR_FALSE
;
265 mViewManager
->UpdateAllViews(NS_VMREFRESH_NO_SYNC
);
271 CanvasFrame::ScrollPositionDidChange(nsIScrollableView
* aScrollable
, nscoord aX
, nscoord aY
)
277 CanvasFrame::SetHasFocus(PRBool aHasFocus
)
279 if (mDoPaintFocus
!= aHasFocus
) {
280 mDoPaintFocus
= aHasFocus
;
281 mViewManager
->UpdateAllViews(NS_VMREFRESH_NO_SYNC
);
287 CanvasFrame::SetInitialChildList(nsIAtom
* aListName
,
288 nsIFrame
* aChildList
)
290 if (nsGkAtoms::absoluteList
== aListName
)
291 return mAbsoluteContainer
.SetInitialChildList(this, aListName
, aChildList
);
293 NS_ASSERTION(aListName
|| !aChildList
|| !aChildList
->GetNextSibling(),
294 "Primary child list can have at most one frame in it");
295 return nsHTMLContainerFrame::SetInitialChildList(aListName
, aChildList
);
299 CanvasFrame::AppendFrames(nsIAtom
* aListName
,
300 nsIFrame
* aFrameList
)
304 if (nsGkAtoms::absoluteList
== aListName
)
305 return mAbsoluteContainer
.AppendFrames(this, aListName
, aFrameList
);
307 NS_ASSERTION(!aListName
, "unexpected child list name");
308 NS_PRECONDITION(mFrames
.IsEmpty(), "already have a child frame");
310 // We only support unnamed principal child list
311 rv
= NS_ERROR_INVALID_ARG
;
313 } else if (!mFrames
.IsEmpty()) {
314 // We only allow a single child frame
315 rv
= NS_ERROR_FAILURE
;
318 // Insert the new frames
320 nsFrame::VerifyDirtyBitSet(aFrameList
);
322 mFrames
.AppendFrame(nsnull
, aFrameList
);
324 rv
= PresContext()->PresShell()->
325 FrameNeedsReflow(this, nsIPresShell::eTreeChange
,
326 NS_FRAME_HAS_DIRTY_CHILDREN
);
333 CanvasFrame::InsertFrames(nsIAtom
* aListName
,
334 nsIFrame
* aPrevFrame
,
335 nsIFrame
* aFrameList
)
339 if (nsGkAtoms::absoluteList
== aListName
)
340 return mAbsoluteContainer
.InsertFrames(this, aListName
, aPrevFrame
, aFrameList
);
342 // Because we only support a single child frame inserting is the same
344 NS_PRECONDITION(!aPrevFrame
, "unexpected previous sibling frame");
346 rv
= NS_ERROR_UNEXPECTED
;
348 rv
= AppendFrames(aListName
, aFrameList
);
355 CanvasFrame::RemoveFrame(nsIAtom
* aListName
,
360 if (nsGkAtoms::absoluteList
== aListName
)
361 return mAbsoluteContainer
.RemoveFrame(this, aListName
, aOldFrame
);
363 NS_ASSERTION(!aListName
, "unexpected child list name");
365 // We only support the unnamed principal child list
366 rv
= NS_ERROR_INVALID_ARG
;
368 } else if (aOldFrame
== mFrames
.FirstChild()) {
369 // It's our one and only child frame
370 // Damage the area occupied by the deleted frame
371 // The child of the canvas probably can't have an outline, but why bother
372 // thinking about that?
373 Invalidate(aOldFrame
->GetOverflowRect() + aOldFrame
->GetPosition());
375 // Remove the frame and destroy it
376 mFrames
.DestroyFrame(aOldFrame
);
378 rv
= PresContext()->PresShell()->
379 FrameNeedsReflow(this, nsIPresShell::eTreeChange
,
380 NS_FRAME_HAS_DIRTY_CHILDREN
);
382 rv
= NS_ERROR_FAILURE
;
389 CanvasFrame::GetAdditionalChildListName(PRInt32 aIndex
) const
391 if (CANVAS_ABS_POS_CHILD_LIST
== aIndex
)
392 return nsGkAtoms::absoluteList
;
394 return nsHTMLContainerFrame::GetAdditionalChildListName(aIndex
);
398 CanvasFrame::GetFirstChild(nsIAtom
* aListName
) const
400 if (nsGkAtoms::absoluteList
== aListName
)
401 return mAbsoluteContainer
.GetFirstChild();
403 return nsHTMLContainerFrame::GetFirstChild(aListName
);
406 nsRect
CanvasFrame::CanvasArea() const
408 nsRect
result(GetOverflowRect());
410 nsIScrollableFrame
*scrollableFrame
;
411 CallQueryInterface(GetParent(), &scrollableFrame
);
412 if (scrollableFrame
) {
413 nsIScrollableView
* scrollableView
= scrollableFrame
->GetScrollableView();
414 nsRect vcr
= scrollableView
->View()->GetBounds();
415 result
.UnionRect(result
, nsRect(nsPoint(0, 0), vcr
.Size()));
421 * Override nsDisplayBackground methods so that we pass aBGClipRect to
422 * PaintBackground, covering the whole overflow area.
424 class nsDisplayCanvasBackground
: public nsDisplayBackground
{
426 nsDisplayCanvasBackground(nsIFrame
*aFrame
)
427 : nsDisplayBackground(aFrame
)
431 virtual nsRect
GetBounds(nsDisplayListBuilder
* aBuilder
)
433 CanvasFrame
* frame
= static_cast<CanvasFrame
*>(mFrame
);
434 return frame
->CanvasArea() + aBuilder
->ToReferenceFrame(mFrame
);
437 virtual void Paint(nsDisplayListBuilder
* aBuilder
,
438 nsIRenderingContext
* aCtx
, const nsRect
& aDirtyRect
)
440 CanvasFrame
* frame
= static_cast<CanvasFrame
*>(mFrame
);
441 nsPoint offset
= aBuilder
->ToReferenceFrame(mFrame
);
442 nsRect bgClipRect
= frame
->CanvasArea() + offset
;
443 nsCSSRendering::PaintBackground(mFrame
->PresContext(), *aCtx
, mFrame
,
445 nsRect(offset
, mFrame
->GetSize()),
446 *mFrame
->GetStyleBorder(),
447 *mFrame
->GetStylePadding(),
448 mFrame
->HonorPrintBackgroundSettings(),
452 NS_DISPLAY_DECL_NAME("CanvasBackground")
456 * A display item to paint the focus ring for the document.
458 * The only reason this can't use nsDisplayGeneric is overriding GetBounds.
460 class nsDisplayCanvasFocus
: public nsDisplayItem
{
462 nsDisplayCanvasFocus(CanvasFrame
*aFrame
)
463 : nsDisplayItem(aFrame
)
467 virtual nsRect
GetBounds(nsDisplayListBuilder
* aBuilder
)
469 // This is an overestimate, but that's not a problem.
470 CanvasFrame
* frame
= static_cast<CanvasFrame
*>(mFrame
);
471 return frame
->CanvasArea() + aBuilder
->ToReferenceFrame(mFrame
);
474 virtual void Paint(nsDisplayListBuilder
* aBuilder
,
475 nsIRenderingContext
* aCtx
, const nsRect
& aDirtyRect
)
477 CanvasFrame
* frame
= static_cast<CanvasFrame
*>(mFrame
);
478 frame
->PaintFocus(*aCtx
, aBuilder
->ToReferenceFrame(mFrame
));
481 NS_DISPLAY_DECL_NAME("CanvasFocus")
485 CanvasFrame::BuildDisplayList(nsDisplayListBuilder
* aBuilder
,
486 const nsRect
& aDirtyRect
,
487 const nsDisplayListSet
& aLists
)
491 if (GetPrevInFlow()) {
492 DisplayOverflowContainers(aBuilder
, aDirtyRect
, aLists
);
495 aBuilder
->MarkFramesForDisplayList(this, mAbsoluteContainer
.GetFirstChild(), aDirtyRect
);
497 // Force a background to be shown. We may have a background propagated to us,
498 // in which case GetStyleBackground wouldn't have the right background
499 // and the code in nsFrame::DisplayBorderBackgroundOutline might not give us
501 // We don't have any border or outline, and our background draws over
502 // the overflow area, so just add nsDisplayCanvasBackground instead of
503 // calling DisplayBorderBackgroundOutline.
504 if (IsVisibleForPainting(aBuilder
)) {
505 rv
= aLists
.BorderBackground()->AppendNewToTop(new (aBuilder
)
506 nsDisplayCanvasBackground(this));
507 NS_ENSURE_SUCCESS(rv
, rv
);
511 for (kid
= GetFirstChild(nsnull
); kid
; kid
= kid
->GetNextSibling()) {
512 // Put our child into its own pseudo-stack.
513 rv
= BuildDisplayListForChild(aBuilder
, kid
, aDirtyRect
, aLists
,
514 DISPLAY_CHILD_FORCE_PSEUDO_STACKING_CONTEXT
);
515 NS_ENSURE_SUCCESS(rv
, rv
);
518 #ifdef DEBUG_CANVAS_FOCUS
519 nsCOMPtr
<nsIContent
> focusContent
;
520 aPresContext
->EventStateManager()->
521 GetFocusedContent(getter_AddRefs(focusContent
));
523 PRBool hasFocus
= PR_FALSE
;
524 nsCOMPtr
<nsISupports
> container
;
525 aPresContext
->GetContainer(getter_AddRefs(container
));
526 nsCOMPtr
<nsIDocShell
> docShell(do_QueryInterface(container
));
528 docShell
->GetHasFocus(&hasFocus
);
529 printf("%p - CanvasFrame::Paint R:%d,%d,%d,%d DR: %d,%d,%d,%d\n", this,
530 mRect
.x
, mRect
.y
, mRect
.width
, mRect
.height
,
531 aDirtyRect
.x
, aDirtyRect
.y
, aDirtyRect
.width
, aDirtyRect
.height
);
533 printf("%p - Focus: %s c: %p DoPaint:%s\n", docShell
.get(), hasFocus
?"Y":"N",
534 focusContent
.get(), mDoPaintFocus
?"Y":"N");
539 // Only paint the focus if we're visible
540 if (!GetStyleVisibility()->IsVisible())
543 return aLists
.Outlines()->AppendNewToTop(new (aBuilder
)
544 nsDisplayCanvasFocus(this));
548 CanvasFrame::PaintFocus(nsIRenderingContext
& aRenderingContext
, nsPoint aPt
)
550 nsRect
focusRect(aPt
, GetSize());
552 nsIScrollableFrame
*scrollableFrame
;
553 CallQueryInterface(GetParent(), &scrollableFrame
);
555 if (scrollableFrame
) {
556 nsIScrollableView
* scrollableView
= scrollableFrame
->GetScrollableView();
557 nsRect vcr
= scrollableView
->View()->GetBounds();
558 focusRect
.width
= vcr
.width
;
559 focusRect
.height
= vcr
.height
;
561 scrollableView
->GetScrollPosition(x
, y
);
566 // XXX use the root frame foreground color, but should we find BODY frame
567 // for HTML documents?
568 nsIFrame
* root
= mFrames
.FirstChild();
569 const nsStyleColor
* color
=
570 root
? root
->GetStyleContext()->GetStyleColor() :
571 mStyleContext
->GetStyleColor();
573 NS_ERROR("current color cannot be found");
577 nsCSSRendering::PaintFocus(PresContext(), aRenderingContext
,
578 focusRect
, color
->mColor
);
581 /* virtual */ nscoord
582 CanvasFrame::GetMinWidth(nsIRenderingContext
*aRenderingContext
)
585 DISPLAY_MIN_WIDTH(this, result
);
586 if (mFrames
.IsEmpty())
589 result
= mFrames
.FirstChild()->GetMinWidth(aRenderingContext
);
593 /* virtual */ nscoord
594 CanvasFrame::GetPrefWidth(nsIRenderingContext
*aRenderingContext
)
597 DISPLAY_PREF_WIDTH(this, result
);
598 if (mFrames
.IsEmpty())
601 result
= mFrames
.FirstChild()->GetPrefWidth(aRenderingContext
);
606 CanvasFrame::Reflow(nsPresContext
* aPresContext
,
607 nsHTMLReflowMetrics
& aDesiredSize
,
608 const nsHTMLReflowState
& aReflowState
,
609 nsReflowStatus
& aStatus
)
611 DO_GLOBAL_REFLOW_COUNT("CanvasFrame");
612 DISPLAY_REFLOW(aPresContext
, this, aReflowState
, aDesiredSize
, aStatus
);
613 NS_FRAME_TRACE_REFLOW_IN("CanvasFrame::Reflow");
615 // Initialize OUT parameter
616 aStatus
= NS_FRAME_COMPLETE
;
618 CanvasFrame
* prevCanvasFrame
= static_cast<CanvasFrame
*>
620 if (prevCanvasFrame
) {
621 nsIFrame
* overflow
= prevCanvasFrame
->GetOverflowFrames(aPresContext
, PR_TRUE
);
623 NS_ASSERTION(!overflow
->GetNextSibling(),
624 "must have doc root as canvas frame's only child");
625 nsHTMLContainerFrame::ReparentFrameView(aPresContext
, overflow
, prevCanvasFrame
, this);
626 // Prepend overflow to the our child list. There may already be
627 // children placeholders for fixed-pos elements, which don't get
628 // reflowed but must not be lost until the canvas frame is destroyed.
629 mFrames
.InsertFrames(this, nsnull
, overflow
);
633 // Reflow our one and only normal child frame. It's either the root
634 // element's frame or a placeholder for that frame, if the root element
635 // is abs-pos or fixed-pos. We may have additional children which
636 // are placeholders for continuations of fixed-pos content, but those
637 // don't need to be reflowed. The normal child is always comes before
638 // the fixed-pos placeholders, because we insert it at the start
639 // of the child list, above.
640 nsHTMLReflowMetrics kidDesiredSize
;
641 if (mFrames
.IsEmpty()) {
642 // We have no child frame, so return an empty size
643 aDesiredSize
.width
= aDesiredSize
.height
= 0;
645 nsIFrame
* kidFrame
= mFrames
.FirstChild();
646 PRBool kidDirty
= (kidFrame
->GetStateBits() & NS_FRAME_IS_DIRTY
) != 0;
648 nsHTMLReflowState
kidReflowState(aPresContext
, aReflowState
, kidFrame
,
649 nsSize(aReflowState
.availableWidth
,
650 aReflowState
.availableHeight
));
652 if (aReflowState
.mFlags
.mVResize
&&
653 (kidFrame
->GetStateBits() & NS_FRAME_CONTAINS_RELATIVE_HEIGHT
)) {
654 // Tell our kid it's being vertically resized too. Bit of a
655 // hack for framesets.
656 kidReflowState
.mFlags
.mVResize
= PR_TRUE
;
659 nsPoint
kidPt(kidReflowState
.mComputedMargin
.left
,
660 kidReflowState
.mComputedMargin
.top
);
661 // Apply CSS relative positioning
662 const nsStyleDisplay
* styleDisp
= kidFrame
->GetStyleDisplay();
663 if (NS_STYLE_POSITION_RELATIVE
== styleDisp
->mPosition
) {
664 kidPt
+= nsPoint(kidReflowState
.mComputedOffsets
.left
,
665 kidReflowState
.mComputedOffsets
.top
);
669 ReflowChild(kidFrame
, aPresContext
, kidDesiredSize
, kidReflowState
,
670 kidPt
.x
, kidPt
.y
, 0, aStatus
);
672 // Complete the reflow and position and size the child frame
673 FinishReflowChild(kidFrame
, aPresContext
, &kidReflowState
, kidDesiredSize
,
674 kidPt
.x
, kidPt
.y
, 0);
676 if (!NS_FRAME_IS_FULLY_COMPLETE(aStatus
)) {
677 nsIFrame
* nextFrame
= kidFrame
->GetNextInFlow();
678 NS_ASSERTION(nextFrame
|| aStatus
& NS_FRAME_REFLOW_NEXTINFLOW
,
679 "If it's incomplete and has no nif yet, it must flag a nif reflow.");
681 nsresult rv
= nsHTMLContainerFrame::CreateNextInFlow(aPresContext
,
682 this, kidFrame
, nextFrame
);
683 NS_ENSURE_SUCCESS(rv
, rv
);
684 kidFrame
->SetNextSibling(nextFrame
->GetNextSibling());
685 nextFrame
->SetNextSibling(nsnull
);
686 SetOverflowFrames(aPresContext
, nextFrame
);
687 // Root overflow containers will be normal children of
688 // the canvas frame, but that's ok because there
689 // aren't any other frames we need to isolate them from
692 if (NS_FRAME_OVERFLOW_IS_INCOMPLETE(aStatus
)) {
693 nextFrame
->AddStateBits(NS_FRAME_IS_OVERFLOW_CONTAINER
);
697 // If the child frame was just inserted, then we're responsible for making sure
700 // But we have a new child, which will affect our background, so
701 // invalidate our whole rect.
702 // Note: Even though we request to be sized to our child's size, our
703 // scroll frame ensures that we are always the size of the viewport.
704 // Also note: GetPosition() on a CanvasFrame is always going to return
705 // (0, 0). We only want to invalidate GetRect() since GetOverflowRect()
706 // could also include overflow to our top and left (out of the viewport)
707 // which doesn't need to be painted.
708 nsIFrame
* viewport
= PresContext()->GetPresShell()->GetRootFrame();
709 viewport
->Invalidate(nsRect(nsPoint(0, 0), viewport
->GetSize()));
712 // Return our desired size (which doesn't matter)
713 aDesiredSize
.width
= aReflowState
.ComputedWidth();
714 aDesiredSize
.height
= aReflowState
.ComputedHeight();
716 aDesiredSize
.mOverflowArea
.UnionRect(
717 nsRect(0, 0, aDesiredSize
.width
, aDesiredSize
.height
),
718 kidDesiredSize
.mOverflowArea
+ kidPt
);
720 if (mAbsoluteContainer
.HasAbsoluteFrames()) {
721 PRBool widthChanged
= aDesiredSize
.width
!= mRect
.width
;
722 PRBool heightChanged
= aDesiredSize
.height
!= mRect
.height
;
724 mAbsoluteContainer
.Reflow(this, aPresContext
, aReflowState
, aStatus
,
725 aDesiredSize
.width
, aDesiredSize
.height
,
726 PR_TRUE
, widthChanged
, heightChanged
,
728 aDesiredSize
.mOverflowArea
.UnionRect(aDesiredSize
.mOverflowArea
, absPosBounds
);
732 if (prevCanvasFrame
) {
733 ReflowOverflowContainerChildren(aPresContext
, aReflowState
,
734 aDesiredSize
.mOverflowArea
, 0,
738 FinishAndStoreOverflow(&aDesiredSize
);
740 NS_FRAME_TRACE_REFLOW_OUT("CanvasFrame::Reflow", aStatus
);
741 NS_FRAME_SET_TRUNCATION(aStatus
, aReflowState
, aDesiredSize
);
746 CanvasFrame::GetSkipSides() const
752 CanvasFrame::GetType() const
754 return nsGkAtoms::canvasFrame
;
758 CanvasFrame::GetContentForEvent(nsPresContext
* aPresContext
,
760 nsIContent
** aContent
)
762 NS_ENSURE_ARG_POINTER(aContent
);
763 nsresult rv
= nsFrame::GetContentForEvent(aPresContext
,
766 if (NS_FAILED(rv
) || !*aContent
) {
767 nsIFrame
* kid
= mFrames
.FirstChild();
769 rv
= kid
->GetContentForEvent(aPresContext
,
780 CanvasFrame::GetFrameName(nsAString
& aResult
) const
782 return MakeFrameName(NS_LITERAL_STRING("Canvas"), aResult
);