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.
23 * Travis Bogard <travis@netscape.com>
24 * HÂkan Waara <hwaara@chello.se>
26 * Alternatively, the contents of this file may be used under the terms of
27 * either of the GNU General Public License Version 2 or later (the "GPL"),
28 * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
29 * in which case the provisions of the GPL or the LGPL are applicable instead
30 * of those above. If you wish to allow use of your version of this file only
31 * under the terms of either the GPL or the LGPL, and not to allow others to
32 * use your version of this file under the terms of the MPL, indicate your
33 * decision by deleting the provisions above and replace them with the notice
34 * and other provisions required by the GPL or the LGPL. If you do not delete
35 * the provisions above, a recipient may use your version of this file under
36 * the terms of any one of the MPL, the GPL or the LGPL.
38 * ***** END LICENSE BLOCK ***** */
41 * rendering object for replaced elements that contain a document, such
42 * as <frame>, <iframe>, and some <object>s
46 #include "nsLeafFrame.h"
47 #include "nsGenericHTMLElement.h"
48 #include "nsIDocShell.h"
49 #include "nsIDocShellLoadInfo.h"
50 #include "nsIDocShellTreeItem.h"
51 #include "nsIDocShellTreeNode.h"
52 #include "nsIDocShellTreeOwner.h"
53 #include "nsIBaseWindow.h"
54 #include "nsIContentViewer.h"
55 #include "nsIMarkupDocumentViewer.h"
56 #include "nsPresContext.h"
57 #include "nsIPresShell.h"
58 #include "nsIComponentManager.h"
59 #include "nsFrameManager.h"
60 #include "nsIStreamListener.h"
62 #include "nsNetUtil.h"
63 #include "nsIDocument.h"
65 #include "nsIViewManager.h"
66 #include "nsWidgetsCID.h"
67 #include "nsViewsCID.h"
68 #include "nsGkAtoms.h"
69 #include "nsStyleCoord.h"
70 #include "nsStyleContext.h"
71 #include "nsStyleConsts.h"
72 #include "nsFrameSetFrame.h"
73 #include "nsIDOMHTMLFrameElement.h"
74 #include "nsIDOMHTMLIFrameElement.h"
75 #include "nsIDOMXULElement.h"
76 #include "nsFrameLoader.h"
77 #include "nsIScriptSecurityManager.h"
78 #include "nsXPIDLString.h"
79 #include "nsIScrollable.h"
80 #include "nsINameSpaceManager.h"
81 #include "nsWeakReference.h"
82 #include "nsIDOMWindow.h"
83 #include "nsIDOMDocument.h"
84 #include "nsIRenderingContext.h"
85 #include "nsIFrameFrame.h"
86 #include "nsAutoPtr.h"
87 #include "nsIDOMNSHTMLDocument.h"
88 #include "nsDisplayList.h"
89 #include "nsUnicharUtils.h"
90 #include "nsIReflowCallback.h"
91 #include "nsIScrollableFrame.h"
92 #include "nsIObjectLoadingContent.h"
93 #include "nsLayoutUtils.h"
96 #include "nsXULPopupManager.h"
101 #include "nsIAccessibilityService.h"
103 #include "nsIServiceManager.h"
105 class AsyncFrameInit
;
107 static NS_DEFINE_CID(kCChildCID
, NS_CHILD_CID
);
109 /******************************************************************************
111 *****************************************************************************/
112 class nsSubDocumentFrame
: public nsLeafFrame
,
113 public nsIFrameFrame
,
114 public nsIReflowCallback
117 NS_DECL_FRAMEARENA_HELPERS
119 nsSubDocumentFrame(nsStyleContext
* aContext
);
122 NS_IMETHOD
GetFrameName(nsAString
& aResult
) const;
127 virtual nsIAtom
* GetType() const;
129 virtual PRBool
IsFrameOfType(PRUint32 aFlags
) const
131 // nsLeafFrame is already eReplacedContainsBlock, but that's somewhat bogus
132 return nsLeafFrame::IsFrameOfType(aFlags
&
133 ~(nsIFrame::eReplaced
| nsIFrame::eReplacedContainsBlock
));
136 NS_IMETHOD
Init(nsIContent
* aContent
,
138 nsIFrame
* aPrevInFlow
);
140 virtual void DestroyFrom(nsIFrame
* aDestructRoot
);
142 virtual nscoord
GetMinWidth(nsIRenderingContext
*aRenderingContext
);
143 virtual nscoord
GetPrefWidth(nsIRenderingContext
*aRenderingContext
);
145 virtual IntrinsicSize
GetIntrinsicSize();
146 virtual nsSize
GetIntrinsicRatio();
148 virtual nsSize
ComputeAutoSize(nsIRenderingContext
*aRenderingContext
,
149 nsSize aCBSize
, nscoord aAvailableWidth
,
150 nsSize aMargin
, nsSize aBorder
,
151 nsSize aPadding
, PRBool aShrinkWrap
);
153 virtual nsSize
ComputeSize(nsIRenderingContext
*aRenderingContext
,
154 nsSize aCBSize
, nscoord aAvailableWidth
,
155 nsSize aMargin
, nsSize aBorder
, nsSize aPadding
,
158 NS_IMETHOD
Reflow(nsPresContext
* aPresContext
,
159 nsHTMLReflowMetrics
& aDesiredSize
,
160 const nsHTMLReflowState
& aReflowState
,
161 nsReflowStatus
& aStatus
);
163 NS_IMETHOD
BuildDisplayList(nsDisplayListBuilder
* aBuilder
,
164 const nsRect
& aDirtyRect
,
165 const nsDisplayListSet
& aLists
);
167 NS_IMETHOD
AttributeChanged(PRInt32 aNameSpaceID
,
171 // if the content is "visibility:hidden", then just hide the view
172 // and all our contents. We don't extend "visibility:hidden" to
173 // the child content ourselves, since it belongs to a different
174 // document and CSS doesn't inherit in there.
175 virtual PRBool
SupportsVisibilityHidden() { return PR_FALSE
; }
178 virtual already_AddRefed
<nsAccessible
> CreateAccessible();
182 NS_IMETHOD
GetDocShell(nsIDocShell
**aDocShell
);
183 NS_IMETHOD
BeginSwapDocShells(nsIFrame
* aOther
);
184 virtual void EndSwapDocShells(nsIFrame
* aOther
);
185 virtual nsIFrame
* GetFrame() { return this; }
188 virtual PRBool
ReflowFinished();
189 virtual void ReflowCallbackCanceled();
192 friend class AsyncFrameInit
;
194 // Helper method to look up the HTML marginwidth & marginheight attributes
195 nsIntSize
GetMarginAttributes();
197 nsFrameLoader
* FrameLoader();
199 PRBool
IsInline() { return mIsInline
; }
200 nsIView
* CreateViewAndWidget(nsContentType aContentType
);
202 virtual nscoord
GetIntrinsicWidth();
203 virtual nscoord
GetIntrinsicHeight();
205 virtual PRIntn
GetSkipSides() const;
207 // Hide or show our document viewer
211 /* Obtains the frame we should use for intrinsic size information if we are
212 * an HTML <object>, <embed> or <applet> (a replaced element - not <iframe>)
213 * and our sub-document has an intrinsic size. The frame returned is the
214 * frame for the document element of the document we're embedding.
216 * Called "Obtain*" and not "Get*" because of comment on GetDocShell that
217 * says it should be called ObtainDocShell because of it's side effects.
219 nsIFrame
* ObtainIntrinsicSizeFrame();
221 nsRefPtr
<nsFrameLoader
> mFrameLoader
;
223 PRPackedBool mIsInline
;
224 PRPackedBool mPostedReflowCallback
;
225 PRPackedBool mDidCreateDoc
;
226 PRPackedBool mCallingShow
;
229 nsSubDocumentFrame::nsSubDocumentFrame(nsStyleContext
* aContext
)
230 : nsLeafFrame(aContext
)
231 , mIsInline(PR_FALSE
)
232 , mPostedReflowCallback(PR_FALSE
)
233 , mDidCreateDoc(PR_FALSE
)
234 , mCallingShow(PR_FALSE
)
239 already_AddRefed
<nsAccessible
>
240 nsSubDocumentFrame::CreateAccessible()
242 nsCOMPtr
<nsIAccessibilityService
> accService
= do_GetService("@mozilla.org/accessibilityService;1");
244 accService
->CreateOuterDocAccessible(mContent
, PresContext()->PresShell()) :
249 NS_QUERYFRAME_HEAD(nsSubDocumentFrame
)
250 NS_QUERYFRAME_ENTRY(nsIFrameFrame
)
251 NS_QUERYFRAME_TAIL_INHERITING(nsLeafFrame
)
253 class AsyncFrameInit
: public nsRunnable
256 AsyncFrameInit(nsIFrame
* aFrame
) : mFrame(aFrame
) {}
259 if (mFrame
.IsAlive()) {
260 static_cast<nsSubDocumentFrame
*>(mFrame
.GetFrame())->ShowViewer();
269 nsSubDocumentFrame::Init(nsIContent
* aContent
,
271 nsIFrame
* aPrevInFlow
)
273 // determine if we are a <frame> or <iframe>
275 nsCOMPtr
<nsIDOMHTMLFrameElement
> frameElem
= do_QueryInterface(aContent
);
276 mIsInline
= frameElem
? PR_FALSE
: PR_TRUE
;
279 nsresult rv
= nsLeafFrame::Init(aContent
, aParent
, aPrevInFlow
);
283 // We are going to create an inner view. If we need a view for the
284 // OuterFrame but we wait for the normal view creation path in
285 // nsCSSFrameConstructor, then we will lose because the inner view's
286 // parent will already have been set to some outer view (e.g., the
287 // canvas) when it really needs to have this frame's view as its
288 // parent. So, create this frame's view right away, whether we
289 // really need it or not, and the inner view will get it as the
292 rv
= nsHTMLContainerFrame::CreateViewForFrame(this, PR_TRUE
);
293 NS_ENSURE_SUCCESS(rv
, rv
);
295 nsIView
* view
= GetView();
297 if (aParent
->GetStyleDisplay()->mDisplay
== NS_STYLE_DISPLAY_DECK
298 && !view
->HasWidget()) {
299 view
->CreateWidget(kCChildCID
);
302 // Set the primary frame now so that
303 // DocumentViewerImpl::FindContainerView called by ShowViewer below
304 // can find it if necessary.
305 aContent
->SetPrimaryFrame(this);
307 nsContentUtils::AddScriptRunner(new AsyncFrameInit(this));
311 inline PRInt32
ConvertOverflow(PRUint8 aOverflow
)
314 case NS_STYLE_OVERFLOW_VISIBLE
:
315 case NS_STYLE_OVERFLOW_AUTO
:
316 return nsIScrollable::Scrollbar_Auto
;
317 case NS_STYLE_OVERFLOW_HIDDEN
:
318 case NS_STYLE_OVERFLOW_CLIP
:
319 return nsIScrollable::Scrollbar_Never
;
320 case NS_STYLE_OVERFLOW_SCROLL
:
321 return nsIScrollable::Scrollbar_Always
;
323 NS_NOTREACHED("invalid overflow value passed to ConvertOverflow");
324 return nsIScrollable::Scrollbar_Auto
;
328 nsSubDocumentFrame::ShowViewer()
334 if (!PresContext()->IsDynamic()) {
335 // We let the printing code take care of loading the document; just
336 // create a widget for it to use
337 (void) CreateViewAndWidget(eContentTypeContent
);
339 nsRefPtr
<nsFrameLoader
> frameloader
= FrameLoader();
341 nsIntSize margin
= GetMarginAttributes();
342 const nsStyleDisplay
* disp
= GetStyleDisplay();
343 nsWeakFrame
weakThis(this);
344 mCallingShow
= PR_TRUE
;
345 PRBool didCreateDoc
=
346 frameloader
->Show(margin
.width
, margin
.height
,
347 ConvertOverflow(disp
->mOverflowX
),
348 ConvertOverflow(disp
->mOverflowY
),
350 if (!weakThis
.IsAlive()) {
353 mCallingShow
= PR_FALSE
;
354 mDidCreateDoc
= didCreateDoc
;
360 nsSubDocumentFrame::GetSkipSides() const
366 nsSubDocumentFrame::BuildDisplayList(nsDisplayListBuilder
* aBuilder
,
367 const nsRect
& aDirtyRect
,
368 const nsDisplayListSet
& aLists
)
370 if (!IsVisibleForPainting(aBuilder
))
373 if (aBuilder
->IsForEventDelivery() &&
374 GetStyleVisibility()->mPointerEvents
== NS_STYLE_POINTER_EVENTS_NONE
)
377 nsresult rv
= DisplayBorderBackgroundOutline(aBuilder
, aLists
);
378 NS_ENSURE_SUCCESS(rv
, rv
);
382 nsIView
* subdocView
= mInnerView
->GetFirstChild();
386 nsCOMPtr
<nsIPresShell
> presShell
;
388 nsIFrame
* subdocRootFrame
=
389 static_cast<nsIFrame
*>(subdocView
->GetClientData());
391 if (subdocRootFrame
) {
392 presShell
= subdocRootFrame
->PresContext()->PresShell();
394 // During page transition mInnerView will sometimes have two children, the
395 // first being the new page that may not have any frame, and the second
396 // being the old page that will probably have a frame.
397 nsIView
* nextView
= subdocView
->GetNextSibling();
399 subdocRootFrame
= static_cast<nsIFrame
*>(nextView
->GetClientData());
401 if (subdocRootFrame
) {
402 subdocView
= nextView
;
403 presShell
= subdocRootFrame
->PresContext()->PresShell();
405 // If we don't have a frame we use this roundabout way to get the pres shell.
408 nsCOMPtr
<nsIDocShell
> docShell
;
409 mFrameLoader
->GetDocShell(getter_AddRefs(docShell
));
412 docShell
->GetPresShell(getter_AddRefs(presShell
));
418 nsPresContext
* presContext
= presShell
->GetPresContext();
420 nsDisplayList childItems
;
422 PRInt32 parentAPD
= PresContext()->AppUnitsPerDevPixel();
423 PRInt32 subdocAPD
= presContext
->AppUnitsPerDevPixel();
426 if (subdocRootFrame
) {
427 // get the dirty rect relative to the root frame of the subdoc
428 dirty
= aDirtyRect
+ GetOffsetToCrossDoc(subdocRootFrame
);
429 // and convert into the appunits of the subdoc
430 dirty
= dirty
.ConvertAppUnitsRoundOut(parentAPD
, subdocAPD
);
432 aBuilder
->EnterPresShell(subdocRootFrame
, dirty
);
435 // The subdocView's bounds are in appunits of the subdocument, so adjust
437 nsRect subdocBoundsInParentUnits
=
438 subdocView
->GetBounds().ConvertAppUnitsRoundOut(subdocAPD
, parentAPD
);
440 // Get the bounds of subdocView relative to the reference frame.
441 subdocBoundsInParentUnits
= subdocBoundsInParentUnits
+
442 mInnerView
->GetPosition() +
443 GetOffsetToCrossDoc(aBuilder
->ReferenceFrame());
445 if (subdocRootFrame
&& NS_SUCCEEDED(rv
)) {
446 rv
= subdocRootFrame
->
447 BuildDisplayListForStackingContext(aBuilder
, dirty
, &childItems
);
450 if (!aBuilder
->IsForEventDelivery()) {
451 // If we are going to use a displayzoom below then any items we put under
452 // it need to have underlying frames from the subdocument. So we need to
453 // calculate the bounds based on which frame will be the underlying frame
454 // for the canvas background color item.
456 if (subdocRootFrame
) {
457 nsPoint offset
= mInnerView
->GetPosition() +
458 GetOffsetToCrossDoc(aBuilder
->ReferenceFrame());
459 offset
= offset
.ConvertAppUnits(parentAPD
, subdocAPD
);
460 bounds
= subdocView
->GetBounds() + offset
;
462 bounds
= subdocBoundsInParentUnits
;
465 // If we are in print preview/page layout we want to paint the grey
466 // background behind the page, not the canvas color. The canvas color gets
467 // painted on the page itself.
468 if (nsLayoutUtils::NeedsPrintPreviewBackground(presContext
)) {
469 rv
= presShell
->AddPrintPreviewBackgroundItem(
470 *aBuilder
, childItems
, subdocRootFrame
? subdocRootFrame
: this,
473 // Add the canvas background color to the bottom of the list. This
474 // happens after we've built the list so that AddCanvasBackgroundColorItem
475 // can monkey with the contents if necessary.
476 rv
= presShell
->AddCanvasBackgroundColorItem(
477 *aBuilder
, childItems
, subdocRootFrame
? subdocRootFrame
: this,
478 bounds
, NS_RGBA(0,0,0,0), PR_TRUE
);
482 if (NS_SUCCEEDED(rv
)) {
483 if (subdocRootFrame
&& parentAPD
!= subdocAPD
) {
484 nsDisplayZoom
* zoomItem
=
485 new (aBuilder
) nsDisplayZoom(subdocRootFrame
, &childItems
,
486 subdocAPD
, parentAPD
);
487 childItems
.AppendToTop(zoomItem
);
489 // Clip children to the child root frame's rectangle
490 rv
= aLists
.Content()->AppendNewToTop(
491 new (aBuilder
) nsDisplayClip(this, this, &childItems
,
492 subdocBoundsInParentUnits
));
494 // delete childItems in case of OOM
495 childItems
.DeleteAll();
497 if (subdocRootFrame
) {
498 aBuilder
->LeavePresShell(subdocRootFrame
, dirty
);
505 nsSubDocumentFrame::GetIntrinsicWidth()
508 return 0; // HTML <frame> has no useful intrinsic width
511 if (mContent
->IsXUL()) {
512 return 0; // XUL <iframe> and <browser> have no useful intrinsic width
515 NS_ASSERTION(ObtainIntrinsicSizeFrame() == nsnull
,
516 "Intrinsic width should come from the embedded document.");
518 // We must be an HTML <iframe>. Default to a width of 300, for IE
519 // compat (and per CSS2.1 draft).
520 return nsPresContext::CSSPixelsToAppUnits(300);
524 nsSubDocumentFrame::GetIntrinsicHeight()
526 // <frame> processing does not use this routine, only <iframe>
527 NS_ASSERTION(IsInline(), "Shouldn't have been called");
529 if (mContent
->IsXUL()) {
533 NS_ASSERTION(ObtainIntrinsicSizeFrame() == nsnull
,
534 "Intrinsic height should come from the embedded document.");
536 // Use 150px, for compatibility with IE, and per CSS2.1 draft.
537 return nsPresContext::CSSPixelsToAppUnits(150);
541 NS_IMETHODIMP
nsSubDocumentFrame::GetFrameName(nsAString
& aResult
) const
543 return MakeFrameName(NS_LITERAL_STRING("FrameOuter"), aResult
);
548 nsSubDocumentFrame::GetType() const
550 return nsGkAtoms::subDocumentFrame
;
553 /* virtual */ nscoord
554 nsSubDocumentFrame::GetMinWidth(nsIRenderingContext
*aRenderingContext
)
557 DISPLAY_MIN_WIDTH(this, result
);
559 nsIFrame
* subDocRoot
= ObtainIntrinsicSizeFrame();
561 result
= subDocRoot
->GetMinWidth(aRenderingContext
);
563 result
= GetIntrinsicWidth();
569 /* virtual */ nscoord
570 nsSubDocumentFrame::GetPrefWidth(nsIRenderingContext
*aRenderingContext
)
573 DISPLAY_PREF_WIDTH(this, result
);
575 nsIFrame
* subDocRoot
= ObtainIntrinsicSizeFrame();
577 result
= subDocRoot
->GetPrefWidth(aRenderingContext
);
579 result
= GetIntrinsicWidth();
585 /* virtual */ nsIFrame::IntrinsicSize
586 nsSubDocumentFrame::GetIntrinsicSize()
588 nsIFrame
* subDocRoot
= ObtainIntrinsicSizeFrame();
590 return subDocRoot
->GetIntrinsicSize();
592 return nsLeafFrame::GetIntrinsicSize();
596 nsSubDocumentFrame::GetIntrinsicRatio()
598 nsIFrame
* subDocRoot
= ObtainIntrinsicSizeFrame();
600 return subDocRoot
->GetIntrinsicRatio();
602 return nsLeafFrame::GetIntrinsicRatio();
606 nsSubDocumentFrame::ComputeAutoSize(nsIRenderingContext
*aRenderingContext
,
607 nsSize aCBSize
, nscoord aAvailableWidth
,
608 nsSize aMargin
, nsSize aBorder
,
609 nsSize aPadding
, PRBool aShrinkWrap
)
612 return nsFrame::ComputeAutoSize(aRenderingContext
, aCBSize
,
613 aAvailableWidth
, aMargin
, aBorder
,
614 aPadding
, aShrinkWrap
);
617 return nsLeafFrame::ComputeAutoSize(aRenderingContext
, aCBSize
,
618 aAvailableWidth
, aMargin
, aBorder
,
619 aPadding
, aShrinkWrap
);
624 nsSubDocumentFrame::ComputeSize(nsIRenderingContext
*aRenderingContext
,
625 nsSize aCBSize
, nscoord aAvailableWidth
,
626 nsSize aMargin
, nsSize aBorder
, nsSize aPadding
,
629 nsIFrame
* subDocRoot
= ObtainIntrinsicSizeFrame();
631 return nsLayoutUtils::ComputeSizeWithIntrinsicDimensions(
632 aRenderingContext
, this,
633 subDocRoot
->GetIntrinsicSize(),
634 subDocRoot
->GetIntrinsicRatio(),
635 aCBSize
, aMargin
, aBorder
, aPadding
);
637 return nsLeafFrame::ComputeSize(aRenderingContext
, aCBSize
, aAvailableWidth
,
638 aMargin
, aBorder
, aPadding
, aShrinkWrap
);
642 nsSubDocumentFrame::Reflow(nsPresContext
* aPresContext
,
643 nsHTMLReflowMetrics
& aDesiredSize
,
644 const nsHTMLReflowState
& aReflowState
,
645 nsReflowStatus
& aStatus
)
647 DO_GLOBAL_REFLOW_COUNT("nsSubDocumentFrame");
648 DISPLAY_REFLOW(aPresContext
, this, aReflowState
, aDesiredSize
, aStatus
);
649 // printf("OuterFrame::Reflow %X (%d,%d) \n", this, aReflowState.availableWidth, aReflowState.availableHeight);
650 NS_FRAME_TRACE(NS_FRAME_TRACE_CALLS
,
651 ("enter nsSubDocumentFrame::Reflow: maxSize=%d,%d",
652 aReflowState
.availableWidth
, aReflowState
.availableHeight
));
654 aStatus
= NS_FRAME_COMPLETE
;
656 NS_ASSERTION(mContent
->GetPrimaryFrame() == this,
659 // "offset" is the offset of our content area from our frame's
661 nsPoint
offset(0, 0);
664 // XUL <iframe> or <browser>, or HTML <iframe>, <object> or <embed>
665 nsresult rv
= nsLeafFrame::DoReflow(aPresContext
, aDesiredSize
, aReflowState
,
667 NS_ENSURE_SUCCESS(rv
, rv
);
669 offset
= nsPoint(aReflowState
.mComputedBorderPadding
.left
,
670 aReflowState
.mComputedBorderPadding
.top
);
673 SizeToAvailSize(aReflowState
, aDesiredSize
);
676 nsSize
innerSize(aDesiredSize
.width
, aDesiredSize
.height
);
678 innerSize
.width
-= aReflowState
.mComputedBorderPadding
.LeftRight();
679 innerSize
.height
-= aReflowState
.mComputedBorderPadding
.TopBottom();
683 nsIViewManager
* vm
= mInnerView
->GetViewManager();
684 vm
->MoveViewTo(mInnerView
, offset
.x
, offset
.y
);
685 vm
->ResizeView(mInnerView
, nsRect(nsPoint(0, 0), innerSize
), PR_TRUE
);
688 // Determine if we need to repaint our border, background or outline
689 CheckInvalidateSizeChange(aDesiredSize
);
691 FinishAndStoreOverflow(&aDesiredSize
);
693 // Invalidate the frame contents
694 // XXX is this really needed?
695 nsRect
rect(nsPoint(0, 0), GetSize());
698 if (!aPresContext
->IsPaginated() && !mPostedReflowCallback
) {
699 PresContext()->PresShell()->PostReflowCallback(this);
700 mPostedReflowCallback
= PR_TRUE
;
703 // printf("OuterFrame::Reflow DONE %X (%d,%d)\n", this,
704 // aDesiredSize.width, aDesiredSize.height);
706 NS_FRAME_TRACE(NS_FRAME_TRACE_CALLS
,
707 ("exit nsSubDocumentFrame::Reflow: size=%d,%d status=%x",
708 aDesiredSize
.width
, aDesiredSize
.height
, aStatus
));
710 NS_FRAME_SET_TRUNCATION(aStatus
, aReflowState
, aDesiredSize
);
715 nsSubDocumentFrame::ReflowFinished()
718 nsWeakFrame
weakFrame(this);
720 mFrameLoader
->UpdatePositionAndSize(this);
722 if (weakFrame
.IsAlive()) {
723 // Make sure that we can post a reflow callback in the future.
724 mPostedReflowCallback
= PR_FALSE
;
731 nsSubDocumentFrame::ReflowCallbackCanceled()
733 mPostedReflowCallback
= PR_FALSE
;
737 nsSubDocumentFrame::AttributeChanged(PRInt32 aNameSpaceID
,
741 if (aNameSpaceID
!= kNameSpaceID_None
) {
745 // If the noResize attribute changes, dis/allow frame to be resized
746 if (aAttribute
== nsGkAtoms::noresize
) {
747 // Note that we're not doing content type checks, but that's ok -- if
748 // they'd fail we will just end up with a null framesetFrame.
749 if (mContent
->GetParent()->Tag() == nsGkAtoms::frameset
) {
750 nsIFrame
* parentFrame
= GetParent();
753 // There is no interface for nsHTMLFramesetFrame so QI'ing to
754 // concrete class, yay!
755 nsHTMLFramesetFrame
* framesetFrame
= do_QueryFrame(parentFrame
);
757 framesetFrame
->RecalculateBorderResize();
762 else if (aAttribute
== nsGkAtoms::type
) {
766 if (!mContent
->IsXUL()) {
770 // Note: This logic duplicates a lot of logic in
771 // nsFrameLoader::EnsureDocShell. We should fix that.
773 // Notify our enclosing chrome that our type has changed. We only do this
774 // if our parent is chrome, since in all other cases we're random content
775 // subframes and the treeowner shouldn't worry about us.
777 nsCOMPtr
<nsIDocShell
> docShell
;
778 mFrameLoader
->GetDocShell(getter_AddRefs(docShell
));
779 nsCOMPtr
<nsIDocShellTreeItem
> docShellAsItem(do_QueryInterface(docShell
));
780 if (!docShellAsItem
) {
784 nsCOMPtr
<nsIDocShellTreeItem
> parentItem
;
785 docShellAsItem
->GetParent(getter_AddRefs(parentItem
));
788 parentItem
->GetItemType(&parentType
);
790 if (parentType
!= nsIDocShellTreeItem::typeChrome
) {
794 nsCOMPtr
<nsIDocShellTreeOwner
> parentTreeOwner
;
795 parentItem
->GetTreeOwner(getter_AddRefs(parentTreeOwner
));
796 if (parentTreeOwner
) {
798 mContent
->GetAttr(kNameSpaceID_None
, nsGkAtoms::type
, value
);
800 PRBool is_primary
= value
.LowerCaseEqualsLiteral("content-primary");
803 // when a content panel is no longer primary, hide any open popups it may have
805 nsXULPopupManager
* pm
= nsXULPopupManager::GetInstance();
807 pm
->HidePopupsInDocShell(docShellAsItem
);
811 parentTreeOwner
->ContentShellRemoved(docShellAsItem
);
813 if (value
.LowerCaseEqualsLiteral("content") ||
814 StringBeginsWith(value
, NS_LITERAL_STRING("content-"),
815 nsCaseInsensitiveStringComparator())) {
816 PRBool is_targetable
= is_primary
||
817 value
.LowerCaseEqualsLiteral("content-targetable");
819 parentTreeOwner
->ContentShellAdded(docShellAsItem
, is_primary
,
820 is_targetable
, value
);
829 NS_NewSubDocumentFrame(nsIPresShell
* aPresShell
, nsStyleContext
* aContext
)
831 return new (aPresShell
) nsSubDocumentFrame(aContext
);
834 NS_IMPL_FRAMEARENA_HELPERS(nsSubDocumentFrame
)
837 nsSubDocumentFrame::DestroyFrom(nsIFrame
* aDestructRoot
)
839 if (mPostedReflowCallback
) {
840 PresContext()->PresShell()->CancelReflowCallback(this);
841 mPostedReflowCallback
= PR_FALSE
;
846 nsLeafFrame::DestroyFrom(aDestructRoot
);
850 nsSubDocumentFrame::HideViewer()
852 if (mFrameLoader
&& (mDidCreateDoc
|| mCallingShow
))
853 mFrameLoader
->Hide();
857 nsSubDocumentFrame::GetMarginAttributes()
859 nsIntSize
result(-1, -1);
860 nsGenericHTMLElement
*content
= nsGenericHTMLElement::FromContent(mContent
);
862 const nsAttrValue
* attr
= content
->GetParsedAttr(nsGkAtoms::marginwidth
);
863 if (attr
&& attr
->Type() == nsAttrValue::eInteger
)
864 result
.width
= attr
->GetIntegerValue();
865 attr
= content
->GetParsedAttr(nsGkAtoms::marginheight
);
866 if (attr
&& attr
->Type() == nsAttrValue::eInteger
)
867 result
.height
= attr
->GetIntegerValue();
873 nsSubDocumentFrame::FrameLoader()
875 nsIContent
* content
= GetContent();
880 nsCOMPtr
<nsIFrameLoaderOwner
> loaderOwner
= do_QueryInterface(content
);
882 nsCOMPtr
<nsIFrameLoader
> loader
;
883 loaderOwner
->GetFrameLoader(getter_AddRefs(loader
));
884 mFrameLoader
= static_cast<nsFrameLoader
*>(loader
.get());
890 // XXX this should be called ObtainDocShell or something like that,
891 // to indicate that it could have side effects
893 nsSubDocumentFrame::GetDocShell(nsIDocShell
**aDocShell
)
897 NS_ENSURE_STATE(FrameLoader());
898 return mFrameLoader
->GetDocShell(aDocShell
);
902 nsSubDocumentFrame::BeginSwapDocShells(nsIFrame
* aOther
)
904 if (!aOther
|| aOther
->GetType() != nsGkAtoms::subDocumentFrame
) {
905 return NS_ERROR_NOT_IMPLEMENTED
;
908 nsSubDocumentFrame
* other
= static_cast<nsSubDocumentFrame
*>(aOther
);
909 if (!mFrameLoader
|| !mDidCreateDoc
|| mCallingShow
||
910 !other
->mFrameLoader
|| !other
->mDidCreateDoc
) {
911 return NS_ERROR_NOT_IMPLEMENTED
;
917 mFrameLoader
.swap(other
->mFrameLoader
);
922 nsSubDocumentFrame::EndSwapDocShells(nsIFrame
* aOther
)
924 nsSubDocumentFrame
* other
= static_cast<nsSubDocumentFrame
*>(aOther
);
925 nsWeakFrame
weakThis(this);
926 nsWeakFrame
weakOther(aOther
);
930 // Now make sure we reflow both frames, in case their contents
931 // determine their size.
932 // And repaint them, for good measure, in case there's nothing
933 // interesting that happens during reflow.
934 if (weakThis
.IsAlive()) {
935 PresContext()->PresShell()->
936 FrameNeedsReflow(this, nsIPresShell::eTreeChange
, NS_FRAME_IS_DIRTY
);
937 InvalidateOverflowRect();
939 if (weakOther
.IsAlive()) {
940 other
->PresContext()->PresShell()->
941 FrameNeedsReflow(other
, nsIPresShell::eTreeChange
, NS_FRAME_IS_DIRTY
);
942 other
->InvalidateOverflowRect();
947 nsSubDocumentFrame::CreateViewAndWidget(nsContentType aContentType
)
950 // Nothing to do here
954 // create, init, set the parent of the view
955 nsIView
* outerView
= GetView();
956 NS_ASSERTION(outerView
, "Must have an outer view already");
957 nsRect
viewBounds(0, 0, 0, 0); // size will be fixed during reflow
959 nsIViewManager
* viewMan
= outerView
->GetViewManager();
960 nsIView
* innerView
= viewMan
->CreateView(viewBounds
, outerView
);
962 NS_ERROR("Could not create inner view");
965 mInnerView
= innerView
;
966 viewMan
->InsertChild(outerView
, innerView
, nsnull
, PR_TRUE
);
968 if (aContentType
!= eContentTypeContentFrame
) {
970 nsresult rv
= innerView
->CreateWidget(kCChildCID
, nsnull
, nsnull
,
971 PR_TRUE
, PR_TRUE
, aContentType
);
973 NS_WARNING("Couldn't create widget for frame.");
981 nsSubDocumentFrame::ObtainIntrinsicSizeFrame()
983 nsCOMPtr
<nsIObjectLoadingContent
> olc
= do_QueryInterface(GetContent());
985 // We are an HTML <object>, <embed> or <applet> (a replaced element).
987 // Try to get an nsIFrame for our sub-document's document element
988 nsIFrame
* subDocRoot
= nsnull
;
990 nsCOMPtr
<nsIDocShell
> docShell
;
991 GetDocShell(getter_AddRefs(docShell
));
993 nsCOMPtr
<nsIPresShell
> presShell
;
994 docShell
->GetPresShell(getter_AddRefs(presShell
));
996 nsIScrollableFrame
* scrollable
= presShell
->GetRootScrollFrameAsScrollable();
998 nsIFrame
* scrolled
= scrollable
->GetScrolledFrame();
1000 subDocRoot
= scrolled
->GetFirstChild(nsnull
);
1007 if (subDocRoot
&& subDocRoot
->GetContent() &&
1008 subDocRoot
->GetContent()->NodeInfo()->Equals(nsGkAtoms::svg
, kNameSpaceID_SVG
)) {
1009 return subDocRoot
; // SVG documents have an intrinsic size