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 /******************************************************************************
109 *****************************************************************************/
110 class nsSubDocumentFrame
: public nsLeafFrame
,
111 public nsIFrameFrame
,
112 public nsIReflowCallback
115 NS_DECL_FRAMEARENA_HELPERS
117 nsSubDocumentFrame(nsStyleContext
* aContext
);
120 NS_IMETHOD
GetFrameName(nsAString
& aResult
) const;
125 virtual nsIAtom
* GetType() const;
127 virtual PRBool
IsFrameOfType(PRUint32 aFlags
) const
129 // nsLeafFrame is already eReplacedContainsBlock, but that's somewhat bogus
130 return nsLeafFrame::IsFrameOfType(aFlags
&
131 ~(nsIFrame::eReplaced
| nsIFrame::eReplacedContainsBlock
));
134 NS_IMETHOD
Init(nsIContent
* aContent
,
136 nsIFrame
* aPrevInFlow
);
138 virtual void DestroyFrom(nsIFrame
* aDestructRoot
);
140 virtual nscoord
GetMinWidth(nsIRenderingContext
*aRenderingContext
);
141 virtual nscoord
GetPrefWidth(nsIRenderingContext
*aRenderingContext
);
143 virtual IntrinsicSize
GetIntrinsicSize();
144 virtual nsSize
GetIntrinsicRatio();
146 virtual nsSize
ComputeAutoSize(nsIRenderingContext
*aRenderingContext
,
147 nsSize aCBSize
, nscoord aAvailableWidth
,
148 nsSize aMargin
, nsSize aBorder
,
149 nsSize aPadding
, PRBool aShrinkWrap
);
151 virtual nsSize
ComputeSize(nsIRenderingContext
*aRenderingContext
,
152 nsSize aCBSize
, nscoord aAvailableWidth
,
153 nsSize aMargin
, nsSize aBorder
, nsSize aPadding
,
156 NS_IMETHOD
Reflow(nsPresContext
* aPresContext
,
157 nsHTMLReflowMetrics
& aDesiredSize
,
158 const nsHTMLReflowState
& aReflowState
,
159 nsReflowStatus
& aStatus
);
161 NS_IMETHOD
BuildDisplayList(nsDisplayListBuilder
* aBuilder
,
162 const nsRect
& aDirtyRect
,
163 const nsDisplayListSet
& aLists
);
165 NS_IMETHOD
AttributeChanged(PRInt32 aNameSpaceID
,
169 // if the content is "visibility:hidden", then just hide the view
170 // and all our contents. We don't extend "visibility:hidden" to
171 // the child content ourselves, since it belongs to a different
172 // document and CSS doesn't inherit in there.
173 virtual PRBool
SupportsVisibilityHidden() { return PR_FALSE
; }
176 virtual already_AddRefed
<nsAccessible
> CreateAccessible();
180 NS_IMETHOD
GetDocShell(nsIDocShell
**aDocShell
);
181 NS_IMETHOD
BeginSwapDocShells(nsIFrame
* aOther
);
182 virtual void EndSwapDocShells(nsIFrame
* aOther
);
183 virtual nsIFrame
* GetFrame() { return this; }
186 virtual PRBool
ReflowFinished();
187 virtual void ReflowCallbackCanceled();
190 friend class AsyncFrameInit
;
192 // Helper method to look up the HTML marginwidth & marginheight attributes
193 nsIntSize
GetMarginAttributes();
195 nsFrameLoader
* FrameLoader();
197 PRBool
IsInline() { return mIsInline
; }
198 nsIView
* CreateViewAndWidget(nsContentType aContentType
);
200 virtual nscoord
GetIntrinsicWidth();
201 virtual nscoord
GetIntrinsicHeight();
203 virtual PRIntn
GetSkipSides() const;
205 // Hide or show our document viewer
209 /* Obtains the frame we should use for intrinsic size information if we are
210 * an HTML <object>, <embed> or <applet> (a replaced element - not <iframe>)
211 * and our sub-document has an intrinsic size. The frame returned is the
212 * frame for the document element of the document we're embedding.
214 * Called "Obtain*" and not "Get*" because of comment on GetDocShell that
215 * says it should be called ObtainDocShell because of it's side effects.
217 nsIFrame
* ObtainIntrinsicSizeFrame();
219 nsRefPtr
<nsFrameLoader
> mFrameLoader
;
221 PRPackedBool mIsInline
;
222 PRPackedBool mPostedReflowCallback
;
223 PRPackedBool mDidCreateDoc
;
224 PRPackedBool mCallingShow
;
227 nsSubDocumentFrame::nsSubDocumentFrame(nsStyleContext
* aContext
)
228 : nsLeafFrame(aContext
)
229 , mIsInline(PR_FALSE
)
230 , mPostedReflowCallback(PR_FALSE
)
231 , mDidCreateDoc(PR_FALSE
)
232 , mCallingShow(PR_FALSE
)
237 already_AddRefed
<nsAccessible
>
238 nsSubDocumentFrame::CreateAccessible()
240 nsCOMPtr
<nsIAccessibilityService
> accService
= do_GetService("@mozilla.org/accessibilityService;1");
242 accService
->CreateOuterDocAccessible(mContent
, PresContext()->PresShell()) :
247 NS_QUERYFRAME_HEAD(nsSubDocumentFrame
)
248 NS_QUERYFRAME_ENTRY(nsIFrameFrame
)
249 NS_QUERYFRAME_TAIL_INHERITING(nsLeafFrame
)
251 class AsyncFrameInit
: public nsRunnable
254 AsyncFrameInit(nsIFrame
* aFrame
) : mFrame(aFrame
) {}
257 if (mFrame
.IsAlive()) {
258 static_cast<nsSubDocumentFrame
*>(mFrame
.GetFrame())->ShowViewer();
267 nsSubDocumentFrame::Init(nsIContent
* aContent
,
269 nsIFrame
* aPrevInFlow
)
271 // determine if we are a <frame> or <iframe>
273 nsCOMPtr
<nsIDOMHTMLFrameElement
> frameElem
= do_QueryInterface(aContent
);
274 mIsInline
= frameElem
? PR_FALSE
: PR_TRUE
;
277 nsresult rv
= nsLeafFrame::Init(aContent
, aParent
, aPrevInFlow
);
281 // We are going to create an inner view. If we need a view for the
282 // OuterFrame but we wait for the normal view creation path in
283 // nsCSSFrameConstructor, then we will lose because the inner view's
284 // parent will already have been set to some outer view (e.g., the
285 // canvas) when it really needs to have this frame's view as its
286 // parent. So, create this frame's view right away, whether we
287 // really need it or not, and the inner view will get it as the
290 rv
= nsHTMLContainerFrame::CreateViewForFrame(this, PR_TRUE
);
291 NS_ENSURE_SUCCESS(rv
, rv
);
293 nsIView
* view
= GetView();
295 // Set the primary frame now so that
296 // DocumentViewerImpl::FindContainerView called by ShowViewer below
297 // can find it if necessary.
298 aContent
->SetPrimaryFrame(this);
300 nsContentUtils::AddScriptRunner(new AsyncFrameInit(this));
304 inline PRInt32
ConvertOverflow(PRUint8 aOverflow
)
307 case NS_STYLE_OVERFLOW_VISIBLE
:
308 case NS_STYLE_OVERFLOW_AUTO
:
309 return nsIScrollable::Scrollbar_Auto
;
310 case NS_STYLE_OVERFLOW_HIDDEN
:
311 case NS_STYLE_OVERFLOW_CLIP
:
312 return nsIScrollable::Scrollbar_Never
;
313 case NS_STYLE_OVERFLOW_SCROLL
:
314 return nsIScrollable::Scrollbar_Always
;
316 NS_NOTREACHED("invalid overflow value passed to ConvertOverflow");
317 return nsIScrollable::Scrollbar_Auto
;
321 nsSubDocumentFrame::ShowViewer()
327 if (!PresContext()->IsDynamic()) {
328 // We let the printing code take care of loading the document; just
329 // create a widget for it to use
330 (void) CreateViewAndWidget(eContentTypeContent
);
332 nsRefPtr
<nsFrameLoader
> frameloader
= FrameLoader();
334 nsIntSize margin
= GetMarginAttributes();
335 const nsStyleDisplay
* disp
= GetStyleDisplay();
336 nsWeakFrame
weakThis(this);
337 mCallingShow
= PR_TRUE
;
338 PRBool didCreateDoc
=
339 frameloader
->Show(margin
.width
, margin
.height
,
340 ConvertOverflow(disp
->mOverflowX
),
341 ConvertOverflow(disp
->mOverflowY
),
343 if (!weakThis
.IsAlive()) {
346 mCallingShow
= PR_FALSE
;
347 mDidCreateDoc
= didCreateDoc
;
353 nsSubDocumentFrame::GetSkipSides() const
359 nsSubDocumentFrame::BuildDisplayList(nsDisplayListBuilder
* aBuilder
,
360 const nsRect
& aDirtyRect
,
361 const nsDisplayListSet
& aLists
)
363 if (!IsVisibleForPainting(aBuilder
))
366 if (aBuilder
->IsForEventDelivery() &&
367 GetStyleVisibility()->mPointerEvents
== NS_STYLE_POINTER_EVENTS_NONE
)
370 nsresult rv
= DisplayBorderBackgroundOutline(aBuilder
, aLists
);
371 NS_ENSURE_SUCCESS(rv
, rv
);
375 nsIView
* subdocView
= mInnerView
->GetFirstChild();
379 nsCOMPtr
<nsIPresShell
> presShell
;
381 nsIFrame
* subdocRootFrame
=
382 static_cast<nsIFrame
*>(subdocView
->GetClientData());
384 if (subdocRootFrame
) {
385 presShell
= subdocRootFrame
->PresContext()->PresShell();
387 // During page transition mInnerView will sometimes have two children, the
388 // first being the new page that may not have any frame, and the second
389 // being the old page that will probably have a frame.
390 nsIView
* nextView
= subdocView
->GetNextSibling();
392 subdocRootFrame
= static_cast<nsIFrame
*>(nextView
->GetClientData());
394 if (subdocRootFrame
) {
395 subdocView
= nextView
;
396 presShell
= subdocRootFrame
->PresContext()->PresShell();
398 // If we don't have a frame we use this roundabout way to get the pres shell.
401 nsCOMPtr
<nsIDocShell
> docShell
;
402 mFrameLoader
->GetDocShell(getter_AddRefs(docShell
));
405 docShell
->GetPresShell(getter_AddRefs(presShell
));
411 nsPresContext
* presContext
= presShell
->GetPresContext();
413 nsDisplayList childItems
;
415 PRInt32 parentAPD
= PresContext()->AppUnitsPerDevPixel();
416 PRInt32 subdocAPD
= presContext
->AppUnitsPerDevPixel();
419 if (subdocRootFrame
) {
420 // get the dirty rect relative to the root frame of the subdoc
421 dirty
= aDirtyRect
+ GetOffsetToCrossDoc(subdocRootFrame
);
422 // and convert into the appunits of the subdoc
423 dirty
= dirty
.ConvertAppUnitsRoundOut(parentAPD
, subdocAPD
);
425 aBuilder
->EnterPresShell(subdocRootFrame
, dirty
);
428 // The subdocView's bounds are in appunits of the subdocument, so adjust
430 nsRect subdocBoundsInParentUnits
=
431 subdocView
->GetBounds().ConvertAppUnitsRoundOut(subdocAPD
, parentAPD
);
433 // Get the bounds of subdocView relative to the reference frame.
434 subdocBoundsInParentUnits
= subdocBoundsInParentUnits
+
435 mInnerView
->GetPosition() +
436 GetOffsetToCrossDoc(aBuilder
->ReferenceFrame());
438 if (subdocRootFrame
&& NS_SUCCEEDED(rv
)) {
439 rv
= subdocRootFrame
->
440 BuildDisplayListForStackingContext(aBuilder
, dirty
, &childItems
);
443 if (!aBuilder
->IsForEventDelivery()) {
444 // If we are going to use a displayzoom below then any items we put under
445 // it need to have underlying frames from the subdocument. So we need to
446 // calculate the bounds based on which frame will be the underlying frame
447 // for the canvas background color item.
449 if (subdocRootFrame
) {
450 nsPoint offset
= mInnerView
->GetPosition() +
451 GetOffsetToCrossDoc(aBuilder
->ReferenceFrame());
452 offset
= offset
.ConvertAppUnits(parentAPD
, subdocAPD
);
453 bounds
= subdocView
->GetBounds() + offset
;
455 bounds
= subdocBoundsInParentUnits
;
458 // If we are in print preview/page layout we want to paint the grey
459 // background behind the page, not the canvas color. The canvas color gets
460 // painted on the page itself.
461 if (nsLayoutUtils::NeedsPrintPreviewBackground(presContext
)) {
462 rv
= presShell
->AddPrintPreviewBackgroundItem(
463 *aBuilder
, childItems
, subdocRootFrame
? subdocRootFrame
: this,
466 // Add the canvas background color to the bottom of the list. This
467 // happens after we've built the list so that AddCanvasBackgroundColorItem
468 // can monkey with the contents if necessary.
469 rv
= presShell
->AddCanvasBackgroundColorItem(
470 *aBuilder
, childItems
, subdocRootFrame
? subdocRootFrame
: this,
471 bounds
, NS_RGBA(0,0,0,0), PR_TRUE
);
475 if (NS_SUCCEEDED(rv
)) {
476 if (subdocRootFrame
&& parentAPD
!= subdocAPD
) {
477 nsDisplayZoom
* zoomItem
=
478 new (aBuilder
) nsDisplayZoom(aBuilder
, subdocRootFrame
, &childItems
,
479 subdocAPD
, parentAPD
);
480 childItems
.AppendToTop(zoomItem
);
481 } else if (!nsContentUtils::IsChildOfSameType(presShell
->GetDocument())) {
482 // We always want top level content documents to be in their own layer.
483 // If we need a zoom item then we are good because it creates a layer. If
484 // not then create our own layer.
485 nsDisplayOwnLayer
* layerItem
= new (aBuilder
) nsDisplayOwnLayer(
486 aBuilder
, subdocRootFrame
? subdocRootFrame
: this, &childItems
);
487 childItems
.AppendToTop(layerItem
);
490 // Clip children to the child root frame's rectangle
491 rv
= aLists
.Content()->AppendNewToTop(
492 new (aBuilder
) nsDisplayClip(aBuilder
, this, this, &childItems
,
493 subdocBoundsInParentUnits
));
495 // delete childItems in case of OOM
496 childItems
.DeleteAll();
498 if (subdocRootFrame
) {
499 aBuilder
->LeavePresShell(subdocRootFrame
, dirty
);
506 nsSubDocumentFrame::GetIntrinsicWidth()
509 return 0; // HTML <frame> has no useful intrinsic width
512 if (mContent
->IsXUL()) {
513 return 0; // XUL <iframe> and <browser> have no useful intrinsic width
516 NS_ASSERTION(ObtainIntrinsicSizeFrame() == nsnull
,
517 "Intrinsic width should come from the embedded document.");
519 // We must be an HTML <iframe>. Default to a width of 300, for IE
520 // compat (and per CSS2.1 draft).
521 return nsPresContext::CSSPixelsToAppUnits(300);
525 nsSubDocumentFrame::GetIntrinsicHeight()
527 // <frame> processing does not use this routine, only <iframe>
528 NS_ASSERTION(IsInline(), "Shouldn't have been called");
530 if (mContent
->IsXUL()) {
534 NS_ASSERTION(ObtainIntrinsicSizeFrame() == nsnull
,
535 "Intrinsic height should come from the embedded document.");
537 // Use 150px, for compatibility with IE, and per CSS2.1 draft.
538 return nsPresContext::CSSPixelsToAppUnits(150);
542 NS_IMETHODIMP
nsSubDocumentFrame::GetFrameName(nsAString
& aResult
) const
544 return MakeFrameName(NS_LITERAL_STRING("FrameOuter"), aResult
);
549 nsSubDocumentFrame::GetType() const
551 return nsGkAtoms::subDocumentFrame
;
554 /* virtual */ nscoord
555 nsSubDocumentFrame::GetMinWidth(nsIRenderingContext
*aRenderingContext
)
558 DISPLAY_MIN_WIDTH(this, result
);
560 nsIFrame
* subDocRoot
= ObtainIntrinsicSizeFrame();
562 result
= subDocRoot
->GetMinWidth(aRenderingContext
);
564 result
= GetIntrinsicWidth();
570 /* virtual */ nscoord
571 nsSubDocumentFrame::GetPrefWidth(nsIRenderingContext
*aRenderingContext
)
574 DISPLAY_PREF_WIDTH(this, result
);
576 nsIFrame
* subDocRoot
= ObtainIntrinsicSizeFrame();
578 result
= subDocRoot
->GetPrefWidth(aRenderingContext
);
580 result
= GetIntrinsicWidth();
586 /* virtual */ nsIFrame::IntrinsicSize
587 nsSubDocumentFrame::GetIntrinsicSize()
589 nsIFrame
* subDocRoot
= ObtainIntrinsicSizeFrame();
591 return subDocRoot
->GetIntrinsicSize();
593 return nsLeafFrame::GetIntrinsicSize();
597 nsSubDocumentFrame::GetIntrinsicRatio()
599 nsIFrame
* subDocRoot
= ObtainIntrinsicSizeFrame();
601 return subDocRoot
->GetIntrinsicRatio();
603 return nsLeafFrame::GetIntrinsicRatio();
607 nsSubDocumentFrame::ComputeAutoSize(nsIRenderingContext
*aRenderingContext
,
608 nsSize aCBSize
, nscoord aAvailableWidth
,
609 nsSize aMargin
, nsSize aBorder
,
610 nsSize aPadding
, PRBool aShrinkWrap
)
613 return nsFrame::ComputeAutoSize(aRenderingContext
, aCBSize
,
614 aAvailableWidth
, aMargin
, aBorder
,
615 aPadding
, aShrinkWrap
);
618 return nsLeafFrame::ComputeAutoSize(aRenderingContext
, aCBSize
,
619 aAvailableWidth
, aMargin
, aBorder
,
620 aPadding
, aShrinkWrap
);
625 nsSubDocumentFrame::ComputeSize(nsIRenderingContext
*aRenderingContext
,
626 nsSize aCBSize
, nscoord aAvailableWidth
,
627 nsSize aMargin
, nsSize aBorder
, nsSize aPadding
,
630 nsIFrame
* subDocRoot
= ObtainIntrinsicSizeFrame();
632 return nsLayoutUtils::ComputeSizeWithIntrinsicDimensions(
633 aRenderingContext
, this,
634 subDocRoot
->GetIntrinsicSize(),
635 subDocRoot
->GetIntrinsicRatio(),
636 aCBSize
, aMargin
, aBorder
, aPadding
);
638 return nsLeafFrame::ComputeSize(aRenderingContext
, aCBSize
, aAvailableWidth
,
639 aMargin
, aBorder
, aPadding
, aShrinkWrap
);
643 nsSubDocumentFrame::Reflow(nsPresContext
* aPresContext
,
644 nsHTMLReflowMetrics
& aDesiredSize
,
645 const nsHTMLReflowState
& aReflowState
,
646 nsReflowStatus
& aStatus
)
648 DO_GLOBAL_REFLOW_COUNT("nsSubDocumentFrame");
649 DISPLAY_REFLOW(aPresContext
, this, aReflowState
, aDesiredSize
, aStatus
);
650 // printf("OuterFrame::Reflow %X (%d,%d) \n", this, aReflowState.availableWidth, aReflowState.availableHeight);
651 NS_FRAME_TRACE(NS_FRAME_TRACE_CALLS
,
652 ("enter nsSubDocumentFrame::Reflow: maxSize=%d,%d",
653 aReflowState
.availableWidth
, aReflowState
.availableHeight
));
655 aStatus
= NS_FRAME_COMPLETE
;
657 NS_ASSERTION(mContent
->GetPrimaryFrame() == this,
660 // "offset" is the offset of our content area from our frame's
662 nsPoint
offset(0, 0);
665 // XUL <iframe> or <browser>, or HTML <iframe>, <object> or <embed>
666 nsresult rv
= nsLeafFrame::DoReflow(aPresContext
, aDesiredSize
, aReflowState
,
668 NS_ENSURE_SUCCESS(rv
, rv
);
670 offset
= nsPoint(aReflowState
.mComputedBorderPadding
.left
,
671 aReflowState
.mComputedBorderPadding
.top
);
674 SizeToAvailSize(aReflowState
, aDesiredSize
);
677 nsSize
innerSize(aDesiredSize
.width
, aDesiredSize
.height
);
679 innerSize
.width
-= aReflowState
.mComputedBorderPadding
.LeftRight();
680 innerSize
.height
-= aReflowState
.mComputedBorderPadding
.TopBottom();
684 nsIViewManager
* vm
= mInnerView
->GetViewManager();
685 vm
->MoveViewTo(mInnerView
, offset
.x
, offset
.y
);
686 vm
->ResizeView(mInnerView
, nsRect(nsPoint(0, 0), innerSize
), PR_TRUE
);
689 // Determine if we need to repaint our border, background or outline
690 CheckInvalidateSizeChange(aDesiredSize
);
692 FinishAndStoreOverflow(&aDesiredSize
);
694 // Invalidate the frame contents
695 // XXX is this really needed?
696 nsRect
rect(nsPoint(0, 0), GetSize());
699 if (!aPresContext
->IsPaginated() && !mPostedReflowCallback
) {
700 PresContext()->PresShell()->PostReflowCallback(this);
701 mPostedReflowCallback
= PR_TRUE
;
704 // printf("OuterFrame::Reflow DONE %X (%d,%d)\n", this,
705 // aDesiredSize.width, aDesiredSize.height);
707 NS_FRAME_TRACE(NS_FRAME_TRACE_CALLS
,
708 ("exit nsSubDocumentFrame::Reflow: size=%d,%d status=%x",
709 aDesiredSize
.width
, aDesiredSize
.height
, aStatus
));
711 NS_FRAME_SET_TRUNCATION(aStatus
, aReflowState
, aDesiredSize
);
716 nsSubDocumentFrame::ReflowFinished()
719 nsWeakFrame
weakFrame(this);
721 mFrameLoader
->UpdatePositionAndSize(this);
723 if (weakFrame
.IsAlive()) {
724 // Make sure that we can post a reflow callback in the future.
725 mPostedReflowCallback
= PR_FALSE
;
732 nsSubDocumentFrame::ReflowCallbackCanceled()
734 mPostedReflowCallback
= PR_FALSE
;
738 nsSubDocumentFrame::AttributeChanged(PRInt32 aNameSpaceID
,
742 if (aNameSpaceID
!= kNameSpaceID_None
) {
746 // If the noResize attribute changes, dis/allow frame to be resized
747 if (aAttribute
== nsGkAtoms::noresize
) {
748 // Note that we're not doing content type checks, but that's ok -- if
749 // they'd fail we will just end up with a null framesetFrame.
750 if (mContent
->GetParent()->Tag() == nsGkAtoms::frameset
) {
751 nsIFrame
* parentFrame
= GetParent();
754 // There is no interface for nsHTMLFramesetFrame so QI'ing to
755 // concrete class, yay!
756 nsHTMLFramesetFrame
* framesetFrame
= do_QueryFrame(parentFrame
);
758 framesetFrame
->RecalculateBorderResize();
763 else if (aAttribute
== nsGkAtoms::type
) {
767 if (!mContent
->IsXUL()) {
771 // Note: This logic duplicates a lot of logic in
772 // nsFrameLoader::EnsureDocShell. We should fix that.
774 // Notify our enclosing chrome that our type has changed. We only do this
775 // if our parent is chrome, since in all other cases we're random content
776 // subframes and the treeowner shouldn't worry about us.
778 nsCOMPtr
<nsIDocShell
> docShell
;
779 mFrameLoader
->GetDocShell(getter_AddRefs(docShell
));
780 nsCOMPtr
<nsIDocShellTreeItem
> docShellAsItem(do_QueryInterface(docShell
));
781 if (!docShellAsItem
) {
785 nsCOMPtr
<nsIDocShellTreeItem
> parentItem
;
786 docShellAsItem
->GetParent(getter_AddRefs(parentItem
));
789 parentItem
->GetItemType(&parentType
);
791 if (parentType
!= nsIDocShellTreeItem::typeChrome
) {
795 nsCOMPtr
<nsIDocShellTreeOwner
> parentTreeOwner
;
796 parentItem
->GetTreeOwner(getter_AddRefs(parentTreeOwner
));
797 if (parentTreeOwner
) {
799 mContent
->GetAttr(kNameSpaceID_None
, nsGkAtoms::type
, value
);
801 PRBool is_primary
= value
.LowerCaseEqualsLiteral("content-primary");
804 // when a content panel is no longer primary, hide any open popups it may have
806 nsXULPopupManager
* pm
= nsXULPopupManager::GetInstance();
808 pm
->HidePopupsInDocShell(docShellAsItem
);
812 parentTreeOwner
->ContentShellRemoved(docShellAsItem
);
814 if (value
.LowerCaseEqualsLiteral("content") ||
815 StringBeginsWith(value
, NS_LITERAL_STRING("content-"),
816 nsCaseInsensitiveStringComparator())) {
817 PRBool is_targetable
= is_primary
||
818 value
.LowerCaseEqualsLiteral("content-targetable");
820 parentTreeOwner
->ContentShellAdded(docShellAsItem
, is_primary
,
821 is_targetable
, value
);
830 NS_NewSubDocumentFrame(nsIPresShell
* aPresShell
, nsStyleContext
* aContext
)
832 return new (aPresShell
) nsSubDocumentFrame(aContext
);
835 NS_IMPL_FRAMEARENA_HELPERS(nsSubDocumentFrame
)
838 nsSubDocumentFrame::DestroyFrom(nsIFrame
* aDestructRoot
)
840 if (mPostedReflowCallback
) {
841 PresContext()->PresShell()->CancelReflowCallback(this);
842 mPostedReflowCallback
= PR_FALSE
;
847 nsLeafFrame::DestroyFrom(aDestructRoot
);
851 nsSubDocumentFrame::HideViewer()
853 if (mFrameLoader
&& (mDidCreateDoc
|| mCallingShow
))
854 mFrameLoader
->Hide();
858 nsSubDocumentFrame::GetMarginAttributes()
860 nsIntSize
result(-1, -1);
861 nsGenericHTMLElement
*content
= nsGenericHTMLElement::FromContent(mContent
);
863 const nsAttrValue
* attr
= content
->GetParsedAttr(nsGkAtoms::marginwidth
);
864 if (attr
&& attr
->Type() == nsAttrValue::eInteger
)
865 result
.width
= attr
->GetIntegerValue();
866 attr
= content
->GetParsedAttr(nsGkAtoms::marginheight
);
867 if (attr
&& attr
->Type() == nsAttrValue::eInteger
)
868 result
.height
= attr
->GetIntegerValue();
874 nsSubDocumentFrame::FrameLoader()
876 nsIContent
* content
= GetContent();
881 nsCOMPtr
<nsIFrameLoaderOwner
> loaderOwner
= do_QueryInterface(content
);
883 nsCOMPtr
<nsIFrameLoader
> loader
;
884 loaderOwner
->GetFrameLoader(getter_AddRefs(loader
));
885 mFrameLoader
= static_cast<nsFrameLoader
*>(loader
.get());
891 // XXX this should be called ObtainDocShell or something like that,
892 // to indicate that it could have side effects
894 nsSubDocumentFrame::GetDocShell(nsIDocShell
**aDocShell
)
898 NS_ENSURE_STATE(FrameLoader());
899 return mFrameLoader
->GetDocShell(aDocShell
);
903 nsSubDocumentFrame::BeginSwapDocShells(nsIFrame
* aOther
)
905 if (!aOther
|| aOther
->GetType() != nsGkAtoms::subDocumentFrame
) {
906 return NS_ERROR_NOT_IMPLEMENTED
;
909 nsSubDocumentFrame
* other
= static_cast<nsSubDocumentFrame
*>(aOther
);
910 if (!mFrameLoader
|| !mDidCreateDoc
|| mCallingShow
||
911 !other
->mFrameLoader
|| !other
->mDidCreateDoc
) {
912 return NS_ERROR_NOT_IMPLEMENTED
;
918 mFrameLoader
.swap(other
->mFrameLoader
);
923 nsSubDocumentFrame::EndSwapDocShells(nsIFrame
* aOther
)
925 nsSubDocumentFrame
* other
= static_cast<nsSubDocumentFrame
*>(aOther
);
926 nsWeakFrame
weakThis(this);
927 nsWeakFrame
weakOther(aOther
);
931 // Now make sure we reflow both frames, in case their contents
932 // determine their size.
933 // And repaint them, for good measure, in case there's nothing
934 // interesting that happens during reflow.
935 if (weakThis
.IsAlive()) {
936 PresContext()->PresShell()->
937 FrameNeedsReflow(this, nsIPresShell::eTreeChange
, NS_FRAME_IS_DIRTY
);
938 InvalidateOverflowRect();
940 if (weakOther
.IsAlive()) {
941 other
->PresContext()->PresShell()->
942 FrameNeedsReflow(other
, nsIPresShell::eTreeChange
, NS_FRAME_IS_DIRTY
);
943 other
->InvalidateOverflowRect();
948 nsSubDocumentFrame::CreateViewAndWidget(nsContentType aContentType
)
951 // Nothing to do here
955 // create, init, set the parent of the view
956 nsIView
* outerView
= GetView();
957 NS_ASSERTION(outerView
, "Must have an outer view already");
958 nsRect
viewBounds(0, 0, 0, 0); // size will be fixed during reflow
960 nsIViewManager
* viewMan
= outerView
->GetViewManager();
961 nsIView
* innerView
= viewMan
->CreateView(viewBounds
, outerView
);
963 NS_ERROR("Could not create inner view");
966 mInnerView
= innerView
;
967 viewMan
->InsertChild(outerView
, innerView
, nsnull
, PR_TRUE
);
969 if (aContentType
== eContentTypeContent
) {
971 nsresult rv
= innerView
->CreateWidget(nsnull
,
972 PR_TRUE
, PR_TRUE
, aContentType
);
974 NS_WARNING("Couldn't create widget for frame.");
982 nsSubDocumentFrame::ObtainIntrinsicSizeFrame()
984 nsCOMPtr
<nsIObjectLoadingContent
> olc
= do_QueryInterface(GetContent());
986 // We are an HTML <object>, <embed> or <applet> (a replaced element).
988 // Try to get an nsIFrame for our sub-document's document element
989 nsIFrame
* subDocRoot
= nsnull
;
991 nsCOMPtr
<nsIDocShell
> docShell
;
992 GetDocShell(getter_AddRefs(docShell
));
994 nsCOMPtr
<nsIPresShell
> presShell
;
995 docShell
->GetPresShell(getter_AddRefs(presShell
));
997 nsIScrollableFrame
* scrollable
= presShell
->GetRootScrollFrameAsScrollable();
999 nsIFrame
* scrolled
= scrollable
->GetScrolledFrame();
1001 subDocRoot
= scrolled
->GetFirstChild(nsnull
);
1008 if (subDocRoot
&& subDocRoot
->GetContent() &&
1009 subDocRoot
->GetContent()->NodeInfo()->Equals(nsGkAtoms::svg
, kNameSpaceID_SVG
)) {
1010 return subDocRoot
; // SVG documents have an intrinsic size