Bug 417561, disable tagging of Talkback now we have prebuilt packages, r=rhelmer
[mozilla-1.9.git] / layout / generic / nsHTMLFrame.cpp
blobf01a2a03ada3d2507915e660ce47eff09d8978d6
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
13 * License.
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.
22 * Contributor(s):
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"
46 #include "nsIView.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"
58 // for focus
59 #include "nsIDOMWindowInternal.h"
60 #include "nsIFocusController.h"
61 #include "nsIScrollableFrame.h"
62 #include "nsIScrollableView.h"
63 #include "nsIDocShell.h"
64 #include "nsICanvasFrame.h"
66 #ifdef DEBUG_rods
67 //#define DEBUG_CANVAS_FOCUS
68 #endif
70 // Interface IDs
72 /**
73 * Root frame class.
75 * The root frame is the parent frame for the document element's frame.
76 * It only supports having a single child frame which must be an area
77 * frame
79 class CanvasFrame : public nsHTMLContainerFrame,
80 public nsIScrollPositionListener,
81 public nsICanvasFrame {
82 public:
83 CanvasFrame(nsStyleContext* aContext)
84 : nsHTMLContainerFrame(aContext), mDoPaintFocus(PR_FALSE) {}
86 // nsISupports
87 NS_IMETHOD QueryInterface(const nsIID& aIID, void** aInstancePtr);
89 NS_IMETHOD Init(nsIContent* aContent,
90 nsIFrame* aParent,
91 nsIFrame* aPrevInFlow);
92 virtual void Destroy();
94 NS_IMETHOD AppendFrames(nsIAtom* aListName,
95 nsIFrame* aFrameList);
96 NS_IMETHOD InsertFrames(nsIAtom* aListName,
97 nsIFrame* aPrevFrame,
98 nsIFrame* aFrameList);
99 NS_IMETHOD RemoveFrame(nsIAtom* aListName,
100 nsIFrame* aOldFrame);
102 virtual nscoord GetMinWidth(nsIRenderingContext *aRenderingContext);
103 virtual nscoord GetPrefWidth(nsIRenderingContext *aRenderingContext);
104 NS_IMETHOD Reflow(nsPresContext* aPresContext,
105 nsHTMLReflowMetrics& aDesiredSize,
106 const nsHTMLReflowState& aReflowState,
107 nsReflowStatus& aStatus);
108 virtual PRBool IsContainingBlock() const { return PR_TRUE; }
110 NS_IMETHOD BuildDisplayList(nsDisplayListBuilder* aBuilder,
111 const nsRect& aDirtyRect,
112 const nsDisplayListSet& aLists);
114 void PaintFocus(nsIRenderingContext& aRenderingContext, nsPoint aPt);
116 // nsIScrollPositionListener
117 NS_IMETHOD ScrollPositionWillChange(nsIScrollableView* aScrollable, nscoord aX, nscoord aY);
118 NS_IMETHOD ScrollPositionDidChange(nsIScrollableView* aScrollable, nscoord aX, nscoord aY);
120 // nsICanvasFrame
121 NS_IMETHOD SetHasFocus(PRBool aHasFocus);
124 * Get the "type" of the frame
126 * @see nsGkAtoms::canvasFrame
128 virtual nsIAtom* GetType() const;
130 #ifdef DEBUG
131 NS_IMETHOD GetFrameName(nsAString& aResult) const;
132 #endif
133 NS_IMETHOD GetContentForEvent(nsPresContext* aPresContext,
134 nsEvent* aEvent,
135 nsIContent** aContent);
137 nsRect CanvasArea() const;
139 protected:
140 virtual PRIntn GetSkipSides() const;
142 // Data members
143 PRPackedBool mDoPaintFocus;
144 nsCOMPtr<nsIViewManager> mViewManager;
146 private:
147 NS_IMETHOD_(nsrefcnt) AddRef() { return NS_OK; }
148 NS_IMETHOD_(nsrefcnt) Release() { return NS_OK; }
152 //----------------------------------------------------------------------
154 nsIFrame*
155 NS_NewCanvasFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
157 return new (aPresShell)CanvasFrame(aContext);
160 //--------------------------------------------------------------
161 // Frames are not refcounted, no need to AddRef
162 NS_IMETHODIMP
163 CanvasFrame::QueryInterface(const nsIID& aIID, void** aInstancePtr)
165 NS_PRECONDITION(aInstancePtr, "null out param");
167 if (aIID.Equals(NS_GET_IID(nsIScrollPositionListener))) {
168 *aInstancePtr = static_cast<nsIScrollPositionListener*>(this);
169 return NS_OK;
171 if (aIID.Equals(NS_GET_IID(nsICanvasFrame))) {
172 *aInstancePtr = static_cast<nsICanvasFrame*>(this);
173 return NS_OK;
176 return nsHTMLContainerFrame::QueryInterface(aIID, aInstancePtr);
179 NS_IMETHODIMP
180 CanvasFrame::Init(nsIContent* aContent,
181 nsIFrame* aParent,
182 nsIFrame* aPrevInFlow)
184 nsresult rv = nsHTMLContainerFrame::Init(aContent, aParent, aPrevInFlow);
186 mViewManager = PresContext()->GetViewManager();
188 nsIScrollableView* scrollingView = nsnull;
189 mViewManager->GetRootScrollableView(&scrollingView);
190 if (scrollingView) {
191 scrollingView->AddScrollPositionListener(this);
194 return rv;
197 void
198 CanvasFrame::Destroy()
200 nsIScrollableView* scrollingView = nsnull;
201 mViewManager->GetRootScrollableView(&scrollingView);
202 if (scrollingView) {
203 scrollingView->RemoveScrollPositionListener(this);
206 nsHTMLContainerFrame::Destroy();
209 NS_IMETHODIMP
210 CanvasFrame::ScrollPositionWillChange(nsIScrollableView* aScrollable, nscoord aX, nscoord aY)
212 #ifdef DEBUG_CANVAS_FOCUS
214 PRBool hasFocus = PR_FALSE;
215 nsCOMPtr<nsIViewObserver> observer;
216 mViewManager->GetViewObserver(*getter_AddRefs(observer));
217 nsCOMPtr<nsIPresShell> shell = do_QueryInterface(observer);
218 nsCOMPtr<nsPresContext> context;
219 shell->GetPresContext(getter_AddRefs(context));
220 nsCOMPtr<nsISupports> container;
221 context->GetContainer(getter_AddRefs(container));
222 nsCOMPtr<nsIDocShell> docShell(do_QueryInterface(container));
223 if (docShell) {
224 docShell->GetHasFocus(&hasFocus);
226 printf("SPWC: %p HF: %s mDoPaintFocus: %s\n", docShell.get(), hasFocus?"Y":"N", mDoPaintFocus?"Y":"N");
228 #endif
230 if (mDoPaintFocus) {
231 mDoPaintFocus = PR_FALSE;
232 mViewManager->UpdateAllViews(NS_VMREFRESH_NO_SYNC);
234 return NS_OK;
237 NS_IMETHODIMP
238 CanvasFrame::ScrollPositionDidChange(nsIScrollableView* aScrollable, nscoord aX, nscoord aY)
240 return NS_OK;
243 NS_IMETHODIMP
244 CanvasFrame::SetHasFocus(PRBool aHasFocus)
246 if (mDoPaintFocus != aHasFocus) {
247 mDoPaintFocus = aHasFocus;
248 nsIViewManager* vm = PresContext()->PresShell()->GetViewManager();
249 if (vm) {
250 vm->UpdateAllViews(NS_VMREFRESH_NO_SYNC);
253 return NS_OK;
256 NS_IMETHODIMP
257 CanvasFrame::AppendFrames(nsIAtom* aListName,
258 nsIFrame* aFrameList)
260 nsresult rv;
262 NS_ASSERTION(!aListName, "unexpected child list name");
263 NS_PRECONDITION(mFrames.IsEmpty(), "already have a child frame");
264 if (aListName) {
265 // We only support unnamed principal child list
266 rv = NS_ERROR_INVALID_ARG;
268 } else if (!mFrames.IsEmpty()) {
269 // We only allow a single child frame
270 rv = NS_ERROR_FAILURE;
272 } else {
273 // Insert the new frames
274 #ifdef NS_DEBUG
275 nsFrame::VerifyDirtyBitSet(aFrameList);
276 #endif
277 mFrames.AppendFrame(nsnull, aFrameList);
279 rv = PresContext()->PresShell()->
280 FrameNeedsReflow(this, nsIPresShell::eTreeChange,
281 NS_FRAME_HAS_DIRTY_CHILDREN);
284 return rv;
287 NS_IMETHODIMP
288 CanvasFrame::InsertFrames(nsIAtom* aListName,
289 nsIFrame* aPrevFrame,
290 nsIFrame* aFrameList)
292 nsresult rv;
294 // Because we only support a single child frame inserting is the same
295 // as appending
296 NS_PRECONDITION(!aPrevFrame, "unexpected previous sibling frame");
297 if (aPrevFrame) {
298 rv = NS_ERROR_UNEXPECTED;
299 } else {
300 rv = AppendFrames(aListName, aFrameList);
303 return rv;
306 NS_IMETHODIMP
307 CanvasFrame::RemoveFrame(nsIAtom* aListName,
308 nsIFrame* aOldFrame)
310 nsresult rv;
312 NS_ASSERTION(!aListName, "unexpected child list name");
313 if (aListName) {
314 // We only support the unnamed principal child list
315 rv = NS_ERROR_INVALID_ARG;
317 } else if (aOldFrame == mFrames.FirstChild()) {
318 // It's our one and only child frame
319 // Damage the area occupied by the deleted frame
320 // The child of the canvas probably can't have an outline, but why bother
321 // thinking about that?
322 Invalidate(aOldFrame->GetOverflowRect() + aOldFrame->GetPosition(), PR_FALSE);
324 // Remove the frame and destroy it
325 mFrames.DestroyFrame(aOldFrame);
327 rv = PresContext()->PresShell()->
328 FrameNeedsReflow(this, nsIPresShell::eTreeChange,
329 NS_FRAME_HAS_DIRTY_CHILDREN);
330 } else {
331 rv = NS_ERROR_FAILURE;
334 return rv;
337 nsRect CanvasFrame::CanvasArea() const
339 nsRect result(GetOverflowRect());
341 nsIScrollableFrame *scrollableFrame;
342 CallQueryInterface(GetParent(), &scrollableFrame);
343 if (scrollableFrame) {
344 nsIScrollableView* scrollableView = scrollableFrame->GetScrollableView();
345 nsRect vcr = scrollableView->View()->GetBounds();
346 result.UnionRect(result, nsRect(nsPoint(0, 0), vcr.Size()));
348 return result;
352 * Override nsDisplayBackground methods so that we pass aBGClipRect to
353 * PaintBackground, covering the whole overflow area.
355 class nsDisplayCanvasBackground : public nsDisplayBackground {
356 public:
357 nsDisplayCanvasBackground(nsIFrame *aFrame)
358 : nsDisplayBackground(aFrame)
362 virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder)
364 CanvasFrame* frame = static_cast<CanvasFrame*>(mFrame);
365 return frame->CanvasArea() + aBuilder->ToReferenceFrame(mFrame);
368 virtual void Paint(nsDisplayListBuilder* aBuilder,
369 nsIRenderingContext* aCtx, const nsRect& aDirtyRect)
371 CanvasFrame* frame = static_cast<CanvasFrame*>(mFrame);
372 nsPoint offset = aBuilder->ToReferenceFrame(mFrame);
373 nsRect bgClipRect = frame->CanvasArea() + offset;
374 nsCSSRendering::PaintBackground(mFrame->PresContext(), *aCtx, mFrame,
375 aDirtyRect,
376 nsRect(offset, mFrame->GetSize()),
377 *mFrame->GetStyleBorder(),
378 *mFrame->GetStylePadding(),
379 mFrame->HonorPrintBackgroundSettings(),
380 &bgClipRect);
383 NS_DISPLAY_DECL_NAME("CanvasBackground")
387 * A display item to paint the focus ring for the document.
389 * The only reason this can't use nsDisplayGeneric is overriding GetBounds.
391 class nsDisplayCanvasFocus : public nsDisplayItem {
392 public:
393 nsDisplayCanvasFocus(CanvasFrame *aFrame)
394 : nsDisplayItem(aFrame)
398 virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder)
400 // This is an overestimate, but that's not a problem.
401 CanvasFrame* frame = static_cast<CanvasFrame*>(mFrame);
402 return frame->CanvasArea() + aBuilder->ToReferenceFrame(mFrame);
405 virtual void Paint(nsDisplayListBuilder* aBuilder,
406 nsIRenderingContext* aCtx, const nsRect& aDirtyRect)
408 CanvasFrame* frame = static_cast<CanvasFrame*>(mFrame);
409 frame->PaintFocus(*aCtx, aBuilder->ToReferenceFrame(mFrame));
412 NS_DISPLAY_DECL_NAME("CanvasFocus")
415 NS_IMETHODIMP
416 CanvasFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
417 const nsRect& aDirtyRect,
418 const nsDisplayListSet& aLists)
420 nsresult rv;
421 // Force a background to be shown. We may have a background propagated to us,
422 // in which case GetStyleBackground wouldn't have the right background
423 // and the code in nsFrame::DisplayBorderBackgroundOutline might not give us
424 // a background.
425 // We don't have any border or outline, and our background draws over
426 // the overflow area, so just add nsDisplayCanvasBackground instead of
427 // calling DisplayBorderBackgroundOutline.
428 if (IsVisibleForPainting(aBuilder)) {
429 rv = aLists.BorderBackground()->AppendNewToTop(new (aBuilder)
430 nsDisplayCanvasBackground(this));
431 NS_ENSURE_SUCCESS(rv, rv);
434 nsIFrame* kid = GetFirstChild(nsnull);
435 if (kid) {
436 // Put our child into its own pseudo-stack.
437 rv = BuildDisplayListForChild(aBuilder, kid, aDirtyRect, aLists,
438 DISPLAY_CHILD_FORCE_PSEUDO_STACKING_CONTEXT);
439 NS_ENSURE_SUCCESS(rv, rv);
442 #ifdef DEBUG_CANVAS_FOCUS
443 nsCOMPtr<nsIContent> focusContent;
444 aPresContext->EventStateManager()->
445 GetFocusedContent(getter_AddRefs(focusContent));
447 PRBool hasFocus = PR_FALSE;
448 nsCOMPtr<nsISupports> container;
449 aPresContext->GetContainer(getter_AddRefs(container));
450 nsCOMPtr<nsIDocShell> docShell(do_QueryInterface(container));
451 if (docShell) {
452 docShell->GetHasFocus(&hasFocus);
453 printf("%p - CanvasFrame::Paint R:%d,%d,%d,%d DR: %d,%d,%d,%d\n", this,
454 mRect.x, mRect.y, mRect.width, mRect.height,
455 aDirtyRect.x, aDirtyRect.y, aDirtyRect.width, aDirtyRect.height);
457 printf("%p - Focus: %s c: %p DoPaint:%s\n", docShell.get(), hasFocus?"Y":"N",
458 focusContent.get(), mDoPaintFocus?"Y":"N");
459 #endif
461 if (!mDoPaintFocus)
462 return NS_OK;
463 // Only paint the focus if we're visible
464 if (!GetStyleVisibility()->IsVisible())
465 return NS_OK;
467 return aLists.Outlines()->AppendNewToTop(new (aBuilder)
468 nsDisplayCanvasFocus(this));
471 void
472 CanvasFrame::PaintFocus(nsIRenderingContext& aRenderingContext, nsPoint aPt)
474 nsRect focusRect(aPt, GetSize());
476 nsIScrollableFrame *scrollableFrame;
477 CallQueryInterface(GetParent(), &scrollableFrame);
479 if (scrollableFrame) {
480 nsIScrollableView* scrollableView = scrollableFrame->GetScrollableView();
481 nsRect vcr = scrollableView->View()->GetBounds();
482 focusRect.width = vcr.width;
483 focusRect.height = vcr.height;
484 nscoord x,y;
485 scrollableView->GetScrollPosition(x, y);
486 focusRect.x += x;
487 focusRect.y += y;
490 nsStyleOutline outlineStyle(PresContext());
491 outlineStyle.SetOutlineStyle(NS_STYLE_BORDER_STYLE_DOTTED);
492 outlineStyle.SetOutlineInitialColor();
494 // XXX use the root frame foreground color, but should we find BODY frame
495 // for HTML documents?
496 nsIFrame* root = mFrames.FirstChild();
497 const nsStyleColor* color =
498 root ? root->GetStyleContext()->GetStyleColor() :
499 mStyleContext->GetStyleColor();
500 if (!color) {
501 NS_ERROR("current color cannot be found");
502 return;
505 // XXX the CSS border for links is specified as 2px, but it
506 // is only drawn as 1px. Match this here.
507 nscoord onePixel = nsPresContext::CSSPixelsToAppUnits(1);
509 nsRect borderInside(focusRect.x + onePixel,
510 focusRect.y + onePixel,
511 focusRect.width - 2 * onePixel,
512 focusRect.height - 2 * onePixel);
514 nsCSSRendering::DrawDashedSides(0, aRenderingContext,
515 focusRect, color,
516 nsnull, &outlineStyle,
517 PR_TRUE, focusRect,
518 borderInside, 0,
519 nsnull);
522 /* virtual */ nscoord
523 CanvasFrame::GetMinWidth(nsIRenderingContext *aRenderingContext)
525 nscoord result;
526 DISPLAY_MIN_WIDTH(this, result);
527 if (mFrames.IsEmpty())
528 result = 0;
529 else
530 result = mFrames.FirstChild()->GetMinWidth(aRenderingContext);
531 return result;
534 /* virtual */ nscoord
535 CanvasFrame::GetPrefWidth(nsIRenderingContext *aRenderingContext)
537 nscoord result;
538 DISPLAY_PREF_WIDTH(this, result);
539 if (mFrames.IsEmpty())
540 result = 0;
541 else
542 result = mFrames.FirstChild()->GetPrefWidth(aRenderingContext);
543 return result;
546 NS_IMETHODIMP
547 CanvasFrame::Reflow(nsPresContext* aPresContext,
548 nsHTMLReflowMetrics& aDesiredSize,
549 const nsHTMLReflowState& aReflowState,
550 nsReflowStatus& aStatus)
552 DO_GLOBAL_REFLOW_COUNT("CanvasFrame");
553 DISPLAY_REFLOW(aPresContext, this, aReflowState, aDesiredSize, aStatus);
554 NS_FRAME_TRACE_REFLOW_IN("CanvasFrame::Reflow");
556 // Initialize OUT parameter
557 aStatus = NS_FRAME_COMPLETE;
559 // Reflow our one and only child frame
560 nsHTMLReflowMetrics kidDesiredSize;
561 if (mFrames.IsEmpty()) {
562 // We have no child frame, so return an empty size
563 aDesiredSize.width = aDesiredSize.height = 0;
564 } else {
565 nsIFrame* kidFrame = mFrames.FirstChild();
566 PRBool kidDirty = (kidFrame->GetStateBits() & NS_FRAME_IS_DIRTY) != 0;
568 // We must specify an unconstrained available height, because constrained
569 // is only for when we're paginated...
570 nsHTMLReflowState kidReflowState(aPresContext, aReflowState, kidFrame,
571 nsSize(aReflowState.availableWidth,
572 NS_UNCONSTRAINEDSIZE));
574 if (aReflowState.mFlags.mVResize &&
575 (kidFrame->GetStateBits() & NS_FRAME_CONTAINS_RELATIVE_HEIGHT)) {
576 // Tell our kid it's being vertically resized too. Bit of a
577 // hack for framesets.
578 kidReflowState.mFlags.mVResize = PR_TRUE;
581 // Reflow the frame
582 ReflowChild(kidFrame, aPresContext, kidDesiredSize, kidReflowState,
583 kidReflowState.mComputedMargin.left, kidReflowState.mComputedMargin.top,
584 0, aStatus);
586 // Complete the reflow and position and size the child frame
587 FinishReflowChild(kidFrame, aPresContext, &kidReflowState, kidDesiredSize,
588 kidReflowState.mComputedMargin.left,
589 kidReflowState.mComputedMargin.top, 0);
591 // If the child frame was just inserted, then we're responsible for making sure
592 // it repaints
593 if (kidDirty) {
594 // But we have a new child, which will affect our background, so
595 // invalidate our whole rect.
596 // Note: Even though we request to be sized to our child's size, our
597 // scroll frame ensures that we are always the size of the viewport.
598 // Also note: GetPosition() on a CanvasFrame is always going to return
599 // (0, 0). We only want to invalidate GetRect() since GetOverflowRect()
600 // could also include overflow to our top and left (out of the viewport)
601 // which doesn't need to be painted.
602 nsIFrame* viewport = PresContext()->GetPresShell()->GetRootFrame();
603 viewport->Invalidate(nsRect(nsPoint(0, 0), viewport->GetSize()));
606 // Return our desired size (which doesn't matter)
607 aDesiredSize.width = aReflowState.availableWidth;
608 aDesiredSize.height = kidDesiredSize.height +
609 kidReflowState.mComputedMargin.TopBottom();
611 aDesiredSize.mOverflowArea.UnionRect(
612 nsRect(0, 0, aDesiredSize.width, aDesiredSize.height),
613 kidDesiredSize.mOverflowArea +
614 nsPoint(kidReflowState.mComputedMargin.left,
615 kidReflowState.mComputedMargin.top));
616 FinishAndStoreOverflow(&aDesiredSize);
619 NS_FRAME_TRACE_REFLOW_OUT("CanvasFrame::Reflow", aStatus);
620 NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize);
621 return NS_OK;
624 PRIntn
625 CanvasFrame::GetSkipSides() const
627 return 0;
630 nsIAtom*
631 CanvasFrame::GetType() const
633 return nsGkAtoms::canvasFrame;
636 NS_IMETHODIMP
637 CanvasFrame::GetContentForEvent(nsPresContext* aPresContext,
638 nsEvent* aEvent,
639 nsIContent** aContent)
641 NS_ENSURE_ARG_POINTER(aContent);
642 nsresult rv = nsFrame::GetContentForEvent(aPresContext,
643 aEvent,
644 aContent);
645 if (NS_FAILED(rv) || !*aContent) {
646 nsIFrame* kid = mFrames.FirstChild();
647 if (kid) {
648 rv = kid->GetContentForEvent(aPresContext,
649 aEvent,
650 aContent);
654 return rv;
657 #ifdef DEBUG
658 NS_IMETHODIMP
659 CanvasFrame::GetFrameName(nsAString& aResult) const
661 return MakeFrameName(NS_LITERAL_STRING("Canvas"), aResult);
663 #endif