LCOV - code coverage report
Current view: directory - layout/generic - nsSubDocumentFrame.cpp (source / functions) Found Hit Coverage
Test: app.info Lines: 473 0 0.0 %
Date: 2012-06-02 Functions: 46 0 0.0 %

       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
       4                 :  *
       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/
       9                 :  *
      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.
      14                 :  *
      15                 :  * The Original Code is mozilla.org code.
      16                 :  *
      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.
      21                 :  *
      22                 :  * Contributor(s):
      23                 :  *   Travis Bogard <travis@netscape.com>
      24                 :  *   HÂkan Waara <hwaara@chello.se>
      25                 :  *   Mats Palmgren <matspal@gmail.com>
      26                 :  *
      27                 :  * Alternatively, the contents of this file may be used under the terms of
      28                 :  * either of the GNU General Public License Version 2 or later (the "GPL"),
      29                 :  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
      30                 :  * in which case the provisions of the GPL or the LGPL are applicable instead
      31                 :  * of those above. If you wish to allow use of your version of this file only
      32                 :  * under the terms of either the GPL or the LGPL, and not to allow others to
      33                 :  * use your version of this file under the terms of the MPL, indicate your
      34                 :  * decision by deleting the provisions above and replace them with the notice
      35                 :  * and other provisions required by the GPL or the LGPL. If you do not delete
      36                 :  * the provisions above, a recipient may use your version of this file under
      37                 :  * the terms of any one of the MPL, the GPL or the LGPL.
      38                 :  *
      39                 :  * ***** END LICENSE BLOCK ***** */
      40                 : 
      41                 : /*
      42                 :  * rendering object for replaced elements that contain a document, such
      43                 :  * as <frame>, <iframe>, and some <object>s
      44                 :  */
      45                 : 
      46                 : #include "mozilla/layout/RenderFrameParent.h"
      47                 : 
      48                 : #include "nsSubDocumentFrame.h"
      49                 : #include "nsCOMPtr.h"
      50                 : #include "nsGenericHTMLElement.h"
      51                 : #include "nsIDocShell.h"
      52                 : #include "nsIDocShellLoadInfo.h"
      53                 : #include "nsIDocShellTreeItem.h"
      54                 : #include "nsIDocShellTreeNode.h"
      55                 : #include "nsIDocShellTreeOwner.h"
      56                 : #include "nsIBaseWindow.h"
      57                 : #include "nsIContentViewer.h"
      58                 : #include "nsPresContext.h"
      59                 : #include "nsIPresShell.h"
      60                 : #include "nsIComponentManager.h"
      61                 : #include "nsFrameManager.h"
      62                 : #include "nsIStreamListener.h"
      63                 : #include "nsIURL.h"
      64                 : #include "nsNetUtil.h"
      65                 : #include "nsIDocument.h"
      66                 : #include "nsIView.h"
      67                 : #include "nsIViewManager.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 "nsIScriptSecurityManager.h"
      77                 : #include "nsXPIDLString.h"
      78                 : #include "nsIScrollable.h"
      79                 : #include "nsINameSpaceManager.h"
      80                 : #include "nsWeakReference.h"
      81                 : #include "nsIDOMWindow.h"
      82                 : #include "nsIDOMDocument.h"
      83                 : #include "nsDisplayList.h"
      84                 : #include "nsUnicharUtils.h"
      85                 : #include "nsIScrollableFrame.h"
      86                 : #include "nsIObjectLoadingContent.h"
      87                 : #include "nsLayoutUtils.h"
      88                 : #include "FrameLayerBuilder.h"
      89                 : #include "nsObjectFrame.h"
      90                 : #include "nsIServiceManager.h"
      91                 : #include "nsContentUtils.h"
      92                 : 
      93                 : #ifdef MOZ_XUL
      94                 : #include "nsXULPopupManager.h"
      95                 : #endif
      96                 : 
      97                 : // For Accessibility
      98                 : #ifdef ACCESSIBILITY
      99                 : #include "nsAccessibilityService.h"
     100                 : #endif
     101                 : 
     102                 : using namespace mozilla;
     103                 : using mozilla::layout::RenderFrameParent;
     104                 : 
     105                 : static nsIDocument*
     106               0 : GetDocumentFromView(nsIView* aView)
     107                 : {
     108               0 :   NS_PRECONDITION(aView, "");
     109                 : 
     110               0 :   nsIFrame* f = aView->GetFrame();
     111               0 :   nsIPresShell* ps =  f ? f->PresContext()->PresShell() : nsnull;
     112               0 :   return ps ? ps->GetDocument() : nsnull;
     113                 : }
     114                 : 
     115                 : class AsyncFrameInit;
     116                 : 
     117               0 : nsSubDocumentFrame::nsSubDocumentFrame(nsStyleContext* aContext)
     118                 :   : nsLeafFrame(aContext)
     119                 :   , mIsInline(false)
     120                 :   , mPostedReflowCallback(false)
     121                 :   , mDidCreateDoc(false)
     122               0 :   , mCallingShow(false)
     123                 : {
     124               0 : }
     125                 : 
     126                 : #ifdef ACCESSIBILITY
     127                 : already_AddRefed<nsAccessible>
     128               0 : nsSubDocumentFrame::CreateAccessible()
     129                 : {
     130               0 :   nsAccessibilityService* accService = nsIPresShell::AccService();
     131                 :   return accService ?
     132               0 :     accService->CreateOuterDocAccessible(mContent, PresContext()->PresShell()) :
     133               0 :     nsnull;
     134                 : }
     135                 : #endif
     136                 : 
     137               0 : NS_QUERYFRAME_HEAD(nsSubDocumentFrame)
     138               0 :   NS_QUERYFRAME_ENTRY(nsSubDocumentFrame)
     139               0 : NS_QUERYFRAME_TAIL_INHERITING(nsLeafFrame)
     140                 : 
     141                 : class AsyncFrameInit : public nsRunnable
     142               0 : {
     143                 : public:
     144               0 :   AsyncFrameInit(nsIFrame* aFrame) : mFrame(aFrame) {}
     145               0 :   NS_IMETHOD Run()
     146                 :   {
     147               0 :     if (mFrame.IsAlive()) {
     148               0 :       static_cast<nsSubDocumentFrame*>(mFrame.GetFrame())->ShowViewer();
     149                 :     }
     150               0 :     return NS_OK;
     151                 :   }
     152                 : private:
     153                 :   nsWeakFrame mFrame;
     154                 : };
     155                 : 
     156                 : NS_IMETHODIMP
     157               0 : nsSubDocumentFrame::Init(nsIContent*     aContent,
     158                 :                          nsIFrame*       aParent,
     159                 :                          nsIFrame*       aPrevInFlow)
     160                 : {
     161                 :   // determine if we are a <frame> or <iframe>
     162               0 :   if (aContent) {
     163               0 :     nsCOMPtr<nsIDOMHTMLFrameElement> frameElem = do_QueryInterface(aContent);
     164               0 :     mIsInline = frameElem ? false : true;
     165                 :   }
     166                 : 
     167               0 :   nsresult rv =  nsLeafFrame::Init(aContent, aParent, aPrevInFlow);
     168               0 :   if (NS_FAILED(rv))
     169               0 :     return rv;
     170                 : 
     171                 :   // We are going to create an inner view.  If we need a view for the
     172                 :   // OuterFrame but we wait for the normal view creation path in
     173                 :   // nsCSSFrameConstructor, then we will lose because the inner view's
     174                 :   // parent will already have been set to some outer view (e.g., the
     175                 :   // canvas) when it really needs to have this frame's view as its
     176                 :   // parent. So, create this frame's view right away, whether we
     177                 :   // really need it or not, and the inner view will get it as the
     178                 :   // parent.
     179               0 :   if (!HasView()) {
     180               0 :     rv = nsContainerFrame::CreateViewForFrame(this, true);
     181               0 :     NS_ENSURE_SUCCESS(rv, rv);
     182                 :   }
     183               0 :   EnsureInnerView();
     184                 : 
     185                 :   // Set the primary frame now so that
     186                 :   // DocumentViewerImpl::FindContainerView called by ShowViewer below
     187                 :   // can find it if necessary.
     188               0 :   aContent->SetPrimaryFrame(this);
     189                 : 
     190               0 :   nsContentUtils::AddScriptRunner(new AsyncFrameInit(this));
     191               0 :   return NS_OK;
     192                 : }
     193                 : 
     194               0 : inline PRInt32 ConvertOverflow(PRUint8 aOverflow)
     195                 : {
     196               0 :   switch (aOverflow) {
     197                 :     case NS_STYLE_OVERFLOW_VISIBLE:
     198                 :     case NS_STYLE_OVERFLOW_AUTO:
     199               0 :       return nsIScrollable::Scrollbar_Auto;
     200                 :     case NS_STYLE_OVERFLOW_HIDDEN:
     201                 :     case NS_STYLE_OVERFLOW_CLIP:
     202               0 :       return nsIScrollable::Scrollbar_Never;
     203                 :     case NS_STYLE_OVERFLOW_SCROLL:
     204               0 :       return nsIScrollable::Scrollbar_Always;
     205                 :   }
     206               0 :   NS_NOTREACHED("invalid overflow value passed to ConvertOverflow");
     207               0 :   return nsIScrollable::Scrollbar_Auto;
     208                 : }
     209                 : 
     210                 : void
     211               0 : nsSubDocumentFrame::ShowViewer()
     212                 : {
     213               0 :   if (mCallingShow) {
     214               0 :     return;
     215                 :   }
     216                 : 
     217               0 :   if (!PresContext()->IsDynamic()) {
     218                 :     // We let the printing code take care of loading the document; just
     219                 :     // create the inner view for it to use.
     220               0 :     (void) EnsureInnerView();
     221                 :   } else {
     222               0 :     nsRefPtr<nsFrameLoader> frameloader = FrameLoader();
     223               0 :     if (frameloader) {
     224               0 :       nsIntSize margin = GetMarginAttributes();
     225               0 :       const nsStyleDisplay* disp = GetStyleDisplay();
     226               0 :       nsWeakFrame weakThis(this);
     227               0 :       mCallingShow = true;
     228                 :       bool didCreateDoc =
     229                 :         frameloader->Show(margin.width, margin.height,
     230                 :                           ConvertOverflow(disp->mOverflowX),
     231                 :                           ConvertOverflow(disp->mOverflowY),
     232               0 :                           this);
     233               0 :       if (!weakThis.IsAlive()) {
     234                 :         return;
     235                 :       }
     236               0 :       mCallingShow = false;
     237               0 :       mDidCreateDoc = didCreateDoc;
     238                 :     }
     239                 :   }
     240                 : }
     241                 : 
     242                 : PRIntn
     243               0 : nsSubDocumentFrame::GetSkipSides() const
     244                 : {
     245               0 :   return 0;
     246                 : }
     247                 : 
     248                 : nsIFrame*
     249               0 : nsSubDocumentFrame::GetSubdocumentRootFrame()
     250                 : {
     251               0 :   if (!mInnerView)
     252               0 :     return nsnull;
     253               0 :   nsIView* subdocView = mInnerView->GetFirstChild();
     254               0 :   return subdocView ? subdocView->GetFrame() : nsnull;
     255                 : }
     256                 : 
     257                 : NS_IMETHODIMP
     258               0 : nsSubDocumentFrame::BuildDisplayList(nsDisplayListBuilder*   aBuilder,
     259                 :                                      const nsRect&           aDirtyRect,
     260                 :                                      const nsDisplayListSet& aLists)
     261                 : {
     262               0 :   if (!IsVisibleForPainting(aBuilder))
     263               0 :     return NS_OK;
     264                 : 
     265               0 :   if (aBuilder->IsForEventDelivery() &&
     266               0 :       GetStyleVisibility()->mPointerEvents == NS_STYLE_POINTER_EVENTS_NONE)
     267               0 :     return NS_OK;
     268                 : 
     269               0 :   nsresult rv = DisplayBorderBackgroundOutline(aBuilder, aLists);
     270               0 :   NS_ENSURE_SUCCESS(rv, rv);
     271                 : 
     272               0 :   if (!mInnerView)
     273               0 :     return NS_OK;
     274                 : 
     275               0 :   nsFrameLoader* frameLoader = FrameLoader();
     276               0 :   if (frameLoader) {
     277               0 :     RenderFrameParent* rfp = frameLoader->GetCurrentRemoteFrame();
     278               0 :     if (rfp) {
     279               0 :       return rfp->BuildDisplayList(aBuilder, this, aDirtyRect, aLists);
     280                 :     }
     281                 :   }
     282                 : 
     283               0 :   nsIView* subdocView = mInnerView->GetFirstChild();
     284               0 :   if (!subdocView)
     285               0 :     return NS_OK;
     286                 : 
     287               0 :   nsCOMPtr<nsIPresShell> presShell = nsnull;
     288                 : 
     289               0 :   nsIFrame* subdocRootFrame = subdocView->GetFrame();
     290               0 :   if (subdocRootFrame) {
     291               0 :     presShell = subdocRootFrame->PresContext()->PresShell();
     292                 :   }
     293                 :   // If painting is suppressed in the presshell, we try to look for a better
     294                 :   // presshell to use.
     295               0 :   if (!presShell || (presShell->IsPaintingSuppressed() &&
     296               0 :                      !aBuilder->IsIgnoringPaintSuppression())) {
     297                 :     // During page transition mInnerView will sometimes have two children, the
     298                 :     // first being the new page that may not have any frame, and the second
     299                 :     // being the old page that will probably have a frame.
     300               0 :     nsIView* nextView = subdocView->GetNextSibling();
     301               0 :     nsIFrame* frame = nsnull;
     302               0 :     if (nextView) {
     303               0 :       frame = nextView->GetFrame();
     304                 :     }
     305               0 :     if (frame) {
     306               0 :       nsIPresShell* ps = frame->PresContext()->PresShell();
     307               0 :       if (!presShell || (ps && !ps->IsPaintingSuppressed())) {
     308               0 :         subdocView = nextView;
     309               0 :         subdocRootFrame = frame;
     310               0 :         presShell = ps;
     311                 :       }
     312                 :     }
     313               0 :     if (!presShell) {
     314                 :       // If we don't have a frame we use this roundabout way to get the pres shell.
     315               0 :       if (!mFrameLoader)
     316               0 :         return NS_OK;
     317               0 :       nsCOMPtr<nsIDocShell> docShell;
     318               0 :       mFrameLoader->GetDocShell(getter_AddRefs(docShell));
     319               0 :       if (!docShell)
     320               0 :         return NS_OK;
     321               0 :       docShell->GetPresShell(getter_AddRefs(presShell));
     322               0 :       if (!presShell)
     323               0 :         return NS_OK;
     324                 :     }
     325                 :   }
     326                 : 
     327               0 :   nsPresContext* presContext = presShell->GetPresContext();
     328                 : 
     329               0 :   nsDisplayList childItems;
     330                 : 
     331               0 :   PRInt32 parentAPD = PresContext()->AppUnitsPerDevPixel();
     332               0 :   PRInt32 subdocAPD = presContext->AppUnitsPerDevPixel();
     333                 : 
     334               0 :   nsRect dirty;
     335               0 :   if (subdocRootFrame) {
     336                 :     // get the dirty rect relative to the root frame of the subdoc
     337               0 :     dirty = aDirtyRect + GetOffsetToCrossDoc(subdocRootFrame);
     338                 :     // and convert into the appunits of the subdoc
     339               0 :     dirty = dirty.ConvertAppUnitsRoundOut(parentAPD, subdocAPD);
     340                 : 
     341               0 :     aBuilder->EnterPresShell(subdocRootFrame, dirty);
     342                 :   }
     343                 : 
     344                 :   nsRect subdocBoundsInParentUnits =
     345               0 :     mInnerView->GetBounds() + GetOffsetToCrossDoc(aBuilder->ReferenceFrame());
     346                 : 
     347               0 :   if (subdocRootFrame) {
     348                 :     rv = subdocRootFrame->
     349               0 :            BuildDisplayListForStackingContext(aBuilder, dirty, &childItems);
     350                 :   }
     351                 : 
     352               0 :   if (!aBuilder->IsForEventDelivery()) {
     353                 :     // If we are going to use a displayzoom below then any items we put under
     354                 :     // it need to have underlying frames from the subdocument. So we need to
     355                 :     // calculate the bounds based on which frame will be the underlying frame
     356                 :     // for the canvas background color item.
     357               0 :     nsRect bounds;
     358               0 :     if (subdocRootFrame) {
     359               0 :       bounds = subdocBoundsInParentUnits.ConvertAppUnitsRoundOut(parentAPD, subdocAPD);
     360                 :     } else {
     361               0 :       bounds = subdocBoundsInParentUnits;
     362                 :     }
     363                 : 
     364                 :     // If we are in print preview/page layout we want to paint the grey
     365                 :     // background behind the page, not the canvas color. The canvas color gets
     366                 :     // painted on the page itself.
     367               0 :     if (nsLayoutUtils::NeedsPrintPreviewBackground(presContext)) {
     368               0 :       rv = presShell->AddPrintPreviewBackgroundItem(
     369                 :              *aBuilder, childItems, subdocRootFrame ? subdocRootFrame : this,
     370               0 :              bounds);
     371                 :     } else {
     372                 :       // Add the canvas background color to the bottom of the list. This
     373                 :       // happens after we've built the list so that AddCanvasBackgroundColorItem
     374                 :       // can monkey with the contents if necessary.
     375               0 :       PRUint32 flags = nsIPresShell::FORCE_DRAW;
     376               0 :       rv = presShell->AddCanvasBackgroundColorItem(
     377                 :              *aBuilder, childItems, subdocRootFrame ? subdocRootFrame : this,
     378               0 :              bounds, NS_RGBA(0,0,0,0), flags);
     379                 :     }
     380                 :   }
     381                 : 
     382               0 :   bool addedLayer = false;
     383                 : 
     384               0 :   if (subdocRootFrame && parentAPD != subdocAPD) {
     385               0 :     NS_WARN_IF_FALSE(!addedLayer,
     386                 :                      "Two container layers have been added. "
     387                 :                       "Performance may suffer.");
     388               0 :     addedLayer = true;
     389                 : 
     390                 :     nsDisplayZoom* zoomItem =
     391                 :       new (aBuilder) nsDisplayZoom(aBuilder, subdocRootFrame, &childItems,
     392               0 :                                    subdocAPD, parentAPD);
     393               0 :     childItems.AppendToTop(zoomItem);
     394                 :   }
     395                 : 
     396               0 :   if (!addedLayer && presContext->IsRootContentDocument()) {
     397                 :     // We always want top level content documents to be in their own layer.
     398                 :     nsDisplayOwnLayer* layerItem = new (aBuilder) nsDisplayOwnLayer(
     399               0 :       aBuilder, subdocRootFrame ? subdocRootFrame : this, &childItems);
     400               0 :     childItems.AppendToTop(layerItem);
     401                 :   }
     402                 : 
     403               0 :   if (subdocRootFrame) {
     404               0 :     aBuilder->LeavePresShell(subdocRootFrame, dirty);
     405                 :   }
     406                 : 
     407               0 :   if (ShouldClipSubdocument()) {
     408                 :     nsDisplayClip* item =
     409                 :       new (aBuilder) nsDisplayClip(aBuilder, this, &childItems,
     410               0 :                                    subdocBoundsInParentUnits);
     411                 :     // Clip children to the child root frame's rectangle
     412               0 :     childItems.AppendToTop(item);
     413                 :   }
     414                 : 
     415               0 :   if (mIsInline) {
     416               0 :     WrapReplacedContentForBorderRadius(aBuilder, &childItems, aLists);
     417                 :   } else {
     418               0 :     aLists.Content()->AppendToTop(&childItems);
     419                 :   }
     420                 : 
     421                 :   // delete childItems in case of OOM
     422               0 :   childItems.DeleteAll();
     423                 : 
     424               0 :   return rv;
     425                 : }
     426                 : 
     427                 : nscoord
     428               0 : nsSubDocumentFrame::GetIntrinsicWidth()
     429                 : {
     430               0 :   if (!IsInline()) {
     431               0 :     return 0;  // HTML <frame> has no useful intrinsic width
     432                 :   }
     433                 : 
     434               0 :   if (mContent->IsXUL()) {
     435               0 :     return 0;  // XUL <iframe> and <browser> have no useful intrinsic width
     436                 :   }
     437                 : 
     438               0 :   NS_ASSERTION(ObtainIntrinsicSizeFrame() == nsnull,
     439                 :                "Intrinsic width should come from the embedded document.");
     440                 : 
     441                 :   // We must be an HTML <iframe>.  Default to a width of 300, for IE
     442                 :   // compat (and per CSS2.1 draft).
     443               0 :   return nsPresContext::CSSPixelsToAppUnits(300);
     444                 : }
     445                 : 
     446                 : nscoord
     447               0 : nsSubDocumentFrame::GetIntrinsicHeight()
     448                 : {
     449                 :   // <frame> processing does not use this routine, only <iframe>
     450               0 :   NS_ASSERTION(IsInline(), "Shouldn't have been called");
     451                 : 
     452               0 :   if (mContent->IsXUL()) {
     453               0 :     return 0;
     454                 :   }
     455                 : 
     456               0 :   NS_ASSERTION(ObtainIntrinsicSizeFrame() == nsnull,
     457                 :                "Intrinsic height should come from the embedded document.");
     458                 : 
     459                 :   // Use 150px, for compatibility with IE, and per CSS2.1 draft.
     460               0 :   return nsPresContext::CSSPixelsToAppUnits(150);
     461                 : }
     462                 : 
     463                 : #ifdef DEBUG
     464               0 : NS_IMETHODIMP nsSubDocumentFrame::GetFrameName(nsAString& aResult) const
     465                 : {
     466               0 :   return MakeFrameName(NS_LITERAL_STRING("FrameOuter"), aResult);
     467                 : }
     468                 : #endif
     469                 : 
     470                 : nsIAtom*
     471               0 : nsSubDocumentFrame::GetType() const
     472                 : {
     473               0 :   return nsGkAtoms::subDocumentFrame;
     474                 : }
     475                 : 
     476                 : /* virtual */ nscoord
     477               0 : nsSubDocumentFrame::GetMinWidth(nsRenderingContext *aRenderingContext)
     478                 : {
     479                 :   nscoord result;
     480               0 :   DISPLAY_MIN_WIDTH(this, result);
     481                 : 
     482               0 :   nsIFrame* subDocRoot = ObtainIntrinsicSizeFrame();
     483               0 :   if (subDocRoot) {
     484               0 :     result = subDocRoot->GetMinWidth(aRenderingContext);
     485                 :   } else {
     486               0 :     result = GetIntrinsicWidth();
     487                 :   }
     488                 : 
     489               0 :   return result;
     490                 : }
     491                 : 
     492                 : /* virtual */ nscoord
     493               0 : nsSubDocumentFrame::GetPrefWidth(nsRenderingContext *aRenderingContext)
     494                 : {
     495                 :   nscoord result;
     496               0 :   DISPLAY_PREF_WIDTH(this, result);
     497                 : 
     498               0 :   nsIFrame* subDocRoot = ObtainIntrinsicSizeFrame();
     499               0 :   if (subDocRoot) {
     500               0 :     result = subDocRoot->GetPrefWidth(aRenderingContext);
     501                 :   } else {
     502               0 :     result = GetIntrinsicWidth();
     503                 :   }
     504                 : 
     505               0 :   return result;
     506                 : }
     507                 : 
     508                 : /* virtual */ nsIFrame::IntrinsicSize
     509               0 : nsSubDocumentFrame::GetIntrinsicSize()
     510                 : {
     511               0 :   nsIFrame* subDocRoot = ObtainIntrinsicSizeFrame();
     512               0 :   if (subDocRoot) {
     513               0 :     return subDocRoot->GetIntrinsicSize();
     514                 :   }
     515               0 :   return nsLeafFrame::GetIntrinsicSize();
     516                 : }
     517                 : 
     518                 : /* virtual */ nsSize
     519               0 : nsSubDocumentFrame::GetIntrinsicRatio()
     520                 : {
     521               0 :   nsIFrame* subDocRoot = ObtainIntrinsicSizeFrame();
     522               0 :   if (subDocRoot) {
     523               0 :     return subDocRoot->GetIntrinsicRatio();
     524                 :   }
     525               0 :   return nsLeafFrame::GetIntrinsicRatio();
     526                 : }
     527                 : 
     528                 : /* virtual */ nsSize
     529               0 : nsSubDocumentFrame::ComputeAutoSize(nsRenderingContext *aRenderingContext,
     530                 :                                     nsSize aCBSize, nscoord aAvailableWidth,
     531                 :                                     nsSize aMargin, nsSize aBorder,
     532                 :                                     nsSize aPadding, bool aShrinkWrap)
     533                 : {
     534               0 :   if (!IsInline()) {
     535                 :     return nsFrame::ComputeAutoSize(aRenderingContext, aCBSize,
     536                 :                                     aAvailableWidth, aMargin, aBorder,
     537               0 :                                     aPadding, aShrinkWrap);
     538                 :   }
     539                 : 
     540                 :   return nsLeafFrame::ComputeAutoSize(aRenderingContext, aCBSize,
     541                 :                                       aAvailableWidth, aMargin, aBorder,
     542               0 :                                       aPadding, aShrinkWrap);  
     543                 : }
     544                 : 
     545                 : 
     546                 : /* virtual */ nsSize
     547               0 : nsSubDocumentFrame::ComputeSize(nsRenderingContext *aRenderingContext,
     548                 :                                 nsSize aCBSize, nscoord aAvailableWidth,
     549                 :                                 nsSize aMargin, nsSize aBorder, nsSize aPadding,
     550                 :                                 bool aShrinkWrap)
     551                 : {
     552               0 :   nsIFrame* subDocRoot = ObtainIntrinsicSizeFrame();
     553               0 :   if (subDocRoot) {
     554                 :     return nsLayoutUtils::ComputeSizeWithIntrinsicDimensions(
     555                 :                             aRenderingContext, this,
     556               0 :                             subDocRoot->GetIntrinsicSize(),
     557               0 :                             subDocRoot->GetIntrinsicRatio(),
     558               0 :                             aCBSize, aMargin, aBorder, aPadding);
     559                 :   }
     560                 :   return nsLeafFrame::ComputeSize(aRenderingContext, aCBSize, aAvailableWidth,
     561               0 :                                   aMargin, aBorder, aPadding, aShrinkWrap);
     562                 : }
     563                 : 
     564                 : NS_IMETHODIMP
     565               0 : nsSubDocumentFrame::Reflow(nsPresContext*           aPresContext,
     566                 :                            nsHTMLReflowMetrics&     aDesiredSize,
     567                 :                            const nsHTMLReflowState& aReflowState,
     568                 :                            nsReflowStatus&          aStatus)
     569                 : {
     570               0 :   DO_GLOBAL_REFLOW_COUNT("nsSubDocumentFrame");
     571               0 :   DISPLAY_REFLOW(aPresContext, this, aReflowState, aDesiredSize, aStatus);
     572                 :   // printf("OuterFrame::Reflow %X (%d,%d) \n", this, aReflowState.availableWidth, aReflowState.availableHeight);
     573               0 :   NS_FRAME_TRACE(NS_FRAME_TRACE_CALLS,
     574                 :      ("enter nsSubDocumentFrame::Reflow: maxSize=%d,%d",
     575                 :       aReflowState.availableWidth, aReflowState.availableHeight));
     576                 : 
     577               0 :   aStatus = NS_FRAME_COMPLETE;
     578                 : 
     579               0 :   NS_ASSERTION(mContent->GetPrimaryFrame() == this,
     580                 :                "Shouldn't happen");
     581                 : 
     582                 :   // "offset" is the offset of our content area from our frame's
     583                 :   // top-left corner.
     584               0 :   nsPoint offset(0, 0);
     585                 :   
     586               0 :   if (IsInline()) {
     587                 :     // XUL <iframe> or <browser>, or HTML <iframe>, <object> or <embed>
     588                 :     nsresult rv = nsLeafFrame::DoReflow(aPresContext, aDesiredSize, aReflowState,
     589               0 :                                         aStatus);
     590               0 :     NS_ENSURE_SUCCESS(rv, rv);
     591                 : 
     592                 :     offset = nsPoint(aReflowState.mComputedBorderPadding.left,
     593               0 :                      aReflowState.mComputedBorderPadding.top);
     594                 :   } else {
     595                 :     // HTML <frame>
     596               0 :     SizeToAvailSize(aReflowState, aDesiredSize);
     597                 :   }
     598                 : 
     599               0 :   nsSize innerSize(aDesiredSize.width, aDesiredSize.height);
     600               0 :   if (IsInline()) {
     601               0 :     innerSize.width  -= aReflowState.mComputedBorderPadding.LeftRight();
     602               0 :     innerSize.height -= aReflowState.mComputedBorderPadding.TopBottom();
     603                 :   }
     604                 : 
     605               0 :   if (mInnerView) {
     606               0 :     nsIViewManager* vm = mInnerView->GetViewManager();
     607               0 :     vm->MoveViewTo(mInnerView, offset.x, offset.y);
     608               0 :     vm->ResizeView(mInnerView, nsRect(nsPoint(0, 0), innerSize), true);
     609                 :   }
     610                 : 
     611               0 :   aDesiredSize.SetOverflowAreasToDesiredBounds();
     612               0 :   if (!ShouldClipSubdocument()) {
     613               0 :     nsIFrame* subdocRootFrame = GetSubdocumentRootFrame();
     614               0 :     if (subdocRootFrame) {
     615               0 :       aDesiredSize.mOverflowAreas.UnionWith(subdocRootFrame->GetOverflowAreas() + offset);
     616                 :     }
     617                 :   }
     618                 : 
     619                 :   // Determine if we need to repaint our border, background or outline
     620               0 :   CheckInvalidateSizeChange(aDesiredSize);
     621                 : 
     622               0 :   FinishAndStoreOverflow(&aDesiredSize);
     623                 : 
     624               0 :   if (!aPresContext->IsPaginated() && !mPostedReflowCallback) {
     625               0 :     PresContext()->PresShell()->PostReflowCallback(this);
     626               0 :     mPostedReflowCallback = true;
     627                 :   }
     628                 : 
     629                 :   // printf("OuterFrame::Reflow DONE %X (%d,%d)\n", this,
     630                 :   //        aDesiredSize.width, aDesiredSize.height);
     631                 : 
     632               0 :   NS_FRAME_TRACE(NS_FRAME_TRACE_CALLS,
     633                 :      ("exit nsSubDocumentFrame::Reflow: size=%d,%d status=%x",
     634                 :       aDesiredSize.width, aDesiredSize.height, aStatus));
     635                 : 
     636               0 :   NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize);
     637               0 :   return NS_OK;
     638                 : }
     639                 : 
     640                 : bool
     641               0 : nsSubDocumentFrame::ReflowFinished()
     642                 : {
     643               0 :   if (mFrameLoader) {
     644               0 :     nsWeakFrame weakFrame(this);
     645                 : 
     646               0 :     mFrameLoader->UpdatePositionAndSize(this);
     647                 : 
     648               0 :     if (weakFrame.IsAlive()) {
     649                 :       // Make sure that we can post a reflow callback in the future.
     650               0 :       mPostedReflowCallback = false;
     651                 :     }
     652                 :   } else {
     653               0 :     mPostedReflowCallback = false;
     654                 :   }
     655               0 :   return false;
     656                 : }
     657                 : 
     658                 : void
     659               0 : nsSubDocumentFrame::ReflowCallbackCanceled()
     660                 : {
     661               0 :   mPostedReflowCallback = false;
     662               0 : }
     663                 : 
     664                 : NS_IMETHODIMP
     665               0 : nsSubDocumentFrame::AttributeChanged(PRInt32 aNameSpaceID,
     666                 :                                      nsIAtom* aAttribute,
     667                 :                                      PRInt32 aModType)
     668                 : {
     669               0 :   if (aNameSpaceID != kNameSpaceID_None) {
     670               0 :     return NS_OK;
     671                 :   }
     672                 :   
     673                 :   // If the noResize attribute changes, dis/allow frame to be resized
     674               0 :   if (aAttribute == nsGkAtoms::noresize) {
     675                 :     // Note that we're not doing content type checks, but that's ok -- if
     676                 :     // they'd fail we will just end up with a null framesetFrame.
     677               0 :     if (mContent->GetParent()->Tag() == nsGkAtoms::frameset) {
     678               0 :       nsIFrame* parentFrame = GetParent();
     679                 : 
     680               0 :       if (parentFrame) {
     681                 :         // There is no interface for nsHTMLFramesetFrame so QI'ing to
     682                 :         // concrete class, yay!
     683               0 :         nsHTMLFramesetFrame* framesetFrame = do_QueryFrame(parentFrame);
     684               0 :         if (framesetFrame) {
     685               0 :           framesetFrame->RecalculateBorderResize();
     686                 :         }
     687                 :       }
     688                 :     }
     689                 :   }
     690               0 :   else if (aAttribute == nsGkAtoms::showresizer) {
     691               0 :     nsIFrame* rootFrame = GetSubdocumentRootFrame();
     692               0 :     if (rootFrame) {
     693               0 :       rootFrame->PresContext()->PresShell()->
     694               0 :         FrameNeedsReflow(rootFrame, nsIPresShell::eResize, NS_FRAME_IS_DIRTY);
     695                 :     }
     696                 :   }
     697               0 :   else if (aAttribute == nsGkAtoms::marginwidth ||
     698                 :            aAttribute == nsGkAtoms::marginheight) {
     699                 : 
     700                 :     // Retrieve the attributes
     701               0 :     nsIntSize margins = GetMarginAttributes();
     702                 : 
     703                 :     // Notify the frameloader
     704               0 :     nsRefPtr<nsFrameLoader> frameloader = FrameLoader();
     705               0 :     if (frameloader)
     706               0 :       frameloader->MarginsChanged(margins.width, margins.height);
     707                 :   }
     708               0 :   else if (aAttribute == nsGkAtoms::type) {
     709               0 :     if (!mFrameLoader) 
     710               0 :       return NS_OK;
     711                 : 
     712               0 :     if (!mContent->IsXUL()) {
     713               0 :       return NS_OK;
     714                 :     }
     715                 : 
     716               0 :     if (mFrameLoader->GetRemoteBrowser()) {
     717                 :       // TODO: Implement ContentShellAdded for remote browsers (bug 658304)
     718               0 :       return NS_OK;
     719                 :     }
     720                 : 
     721                 :     // Note: This logic duplicates a lot of logic in
     722                 :     // nsFrameLoader::EnsureDocShell.  We should fix that.
     723                 : 
     724                 :     // Notify our enclosing chrome that our type has changed.  We only do this
     725                 :     // if our parent is chrome, since in all other cases we're random content
     726                 :     // subframes and the treeowner shouldn't worry about us.
     727                 : 
     728               0 :     nsCOMPtr<nsIDocShell> docShell;
     729               0 :     mFrameLoader->GetDocShell(getter_AddRefs(docShell));
     730               0 :     nsCOMPtr<nsIDocShellTreeItem> docShellAsItem(do_QueryInterface(docShell));
     731               0 :     if (!docShellAsItem) {
     732               0 :       return NS_OK;
     733                 :     }
     734                 : 
     735               0 :     nsCOMPtr<nsIDocShellTreeItem> parentItem;
     736               0 :     docShellAsItem->GetParent(getter_AddRefs(parentItem));
     737               0 :     if (!parentItem) {
     738               0 :       return NS_OK;
     739                 :     }
     740                 : 
     741                 :     PRInt32 parentType;
     742               0 :     parentItem->GetItemType(&parentType);
     743                 : 
     744               0 :     if (parentType != nsIDocShellTreeItem::typeChrome) {
     745               0 :       return NS_OK;
     746                 :     }
     747                 : 
     748               0 :     nsCOMPtr<nsIDocShellTreeOwner> parentTreeOwner;
     749               0 :     parentItem->GetTreeOwner(getter_AddRefs(parentTreeOwner));
     750               0 :     if (parentTreeOwner) {
     751               0 :       nsAutoString value;
     752               0 :       mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::type, value);
     753                 : 
     754               0 :       bool is_primary = value.LowerCaseEqualsLiteral("content-primary");
     755                 : 
     756                 : #ifdef MOZ_XUL
     757                 :       // when a content panel is no longer primary, hide any open popups it may have
     758               0 :       if (!is_primary) {
     759               0 :         nsXULPopupManager* pm = nsXULPopupManager::GetInstance();
     760               0 :         if (pm)
     761               0 :           pm->HidePopupsInDocShell(docShellAsItem);
     762                 :       }
     763                 : #endif
     764                 : 
     765               0 :       parentTreeOwner->ContentShellRemoved(docShellAsItem);
     766                 : 
     767               0 :       if (value.LowerCaseEqualsLiteral("content") ||
     768               0 :           StringBeginsWith(value, NS_LITERAL_STRING("content-"),
     769               0 :                            nsCaseInsensitiveStringComparator())) {
     770                 :         bool is_targetable = is_primary ||
     771               0 :           value.LowerCaseEqualsLiteral("content-targetable");
     772                 : 
     773               0 :         parentTreeOwner->ContentShellAdded(docShellAsItem, is_primary,
     774               0 :                                            is_targetable, value);
     775                 :       }
     776                 :     }
     777                 :   }
     778                 : 
     779               0 :   return NS_OK;
     780                 : }
     781                 : 
     782                 : nsIFrame*
     783               0 : NS_NewSubDocumentFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
     784                 : {
     785               0 :   return new (aPresShell) nsSubDocumentFrame(aContext);
     786                 : }
     787                 : 
     788               0 : NS_IMPL_FRAMEARENA_HELPERS(nsSubDocumentFrame)
     789                 : 
     790                 : void
     791               0 : nsSubDocumentFrame::DestroyFrom(nsIFrame* aDestructRoot)
     792                 : {
     793               0 :   if (mPostedReflowCallback) {
     794               0 :     PresContext()->PresShell()->CancelReflowCallback(this);
     795               0 :     mPostedReflowCallback = false;
     796                 :   }
     797                 :   
     798               0 :   HideViewer();
     799                 : 
     800               0 :   nsLeafFrame::DestroyFrom(aDestructRoot);
     801               0 : }
     802                 : 
     803                 : void
     804               0 : nsSubDocumentFrame::HideViewer()
     805                 : {
     806               0 :   if (mFrameLoader && (mDidCreateDoc || mCallingShow))
     807               0 :     mFrameLoader->Hide();
     808               0 : }
     809                 : 
     810                 : nsIntSize
     811               0 : nsSubDocumentFrame::GetMarginAttributes()
     812                 : {
     813               0 :   nsIntSize result(-1, -1);
     814               0 :   nsGenericHTMLElement *content = nsGenericHTMLElement::FromContent(mContent);
     815               0 :   if (content) {
     816               0 :     const nsAttrValue* attr = content->GetParsedAttr(nsGkAtoms::marginwidth);
     817               0 :     if (attr && attr->Type() == nsAttrValue::eInteger)
     818               0 :       result.width = attr->GetIntegerValue();
     819               0 :     attr = content->GetParsedAttr(nsGkAtoms::marginheight);
     820               0 :     if (attr && attr->Type() == nsAttrValue::eInteger)
     821               0 :       result.height = attr->GetIntegerValue();
     822                 :   }
     823                 :   return result;
     824                 : }
     825                 : 
     826                 : nsFrameLoader*
     827               0 : nsSubDocumentFrame::FrameLoader()
     828                 : {
     829               0 :   nsIContent* content = GetContent();
     830               0 :   if (!content)
     831               0 :     return nsnull;
     832                 : 
     833               0 :   if (!mFrameLoader) {
     834               0 :     nsCOMPtr<nsIFrameLoaderOwner> loaderOwner = do_QueryInterface(content);
     835               0 :     if (loaderOwner) {
     836               0 :       nsCOMPtr<nsIFrameLoader> loader;
     837               0 :       loaderOwner->GetFrameLoader(getter_AddRefs(loader));
     838               0 :       mFrameLoader = static_cast<nsFrameLoader*>(loader.get());
     839                 :     }
     840                 :   }
     841               0 :   return mFrameLoader;
     842                 : }
     843                 : 
     844                 : // XXX this should be called ObtainDocShell or something like that,
     845                 : // to indicate that it could have side effects
     846                 : nsresult
     847               0 : nsSubDocumentFrame::GetDocShell(nsIDocShell **aDocShell)
     848                 : {
     849               0 :   *aDocShell = nsnull;
     850                 : 
     851               0 :   NS_ENSURE_STATE(FrameLoader());
     852               0 :   return mFrameLoader->GetDocShell(aDocShell);
     853                 : }
     854                 : 
     855                 : static void
     856               0 : DestroyDisplayItemDataForFrames(nsIFrame* aFrame)
     857                 : {
     858               0 :   FrameLayerBuilder::DestroyDisplayItemDataFor(aFrame);
     859                 : 
     860               0 :   nsIFrame::ChildListIterator lists(aFrame);
     861               0 :   for (; !lists.IsDone(); lists.Next()) {
     862               0 :     nsFrameList::Enumerator childFrames(lists.CurrentList());
     863               0 :     for (; !childFrames.AtEnd(); childFrames.Next()) {
     864               0 :       DestroyDisplayItemDataForFrames(childFrames.get());
     865                 :     }
     866                 :   }
     867               0 : }
     868                 : 
     869                 : static bool
     870               0 : BeginSwapDocShellsForDocument(nsIDocument* aDocument, void*)
     871                 : {
     872               0 :   NS_PRECONDITION(aDocument, "");
     873                 : 
     874               0 :   nsIPresShell* shell = aDocument->GetShell();
     875               0 :   nsIFrame* rootFrame = shell ? shell->GetRootFrame() : nsnull;
     876               0 :   if (rootFrame) {
     877               0 :     ::DestroyDisplayItemDataForFrames(rootFrame);
     878                 :   }
     879                 :   aDocument->EnumerateFreezableElements(
     880               0 :     nsObjectFrame::BeginSwapDocShells, nsnull);
     881               0 :   aDocument->EnumerateSubDocuments(BeginSwapDocShellsForDocument, nsnull);
     882               0 :   return true;
     883                 : }
     884                 : 
     885                 : static nsIView*
     886               0 : BeginSwapDocShellsForViews(nsIView* aSibling)
     887                 : {
     888                 :   // Collect the removed sibling views in reverse order in 'removedViews'.
     889               0 :   nsIView* removedViews = nsnull;
     890               0 :   while (aSibling) {
     891               0 :     nsIDocument* doc = ::GetDocumentFromView(aSibling);
     892               0 :     if (doc) {
     893               0 :       ::BeginSwapDocShellsForDocument(doc, nsnull);
     894                 :     }
     895               0 :     nsIView* next = aSibling->GetNextSibling();
     896               0 :     aSibling->GetViewManager()->RemoveChild(aSibling);
     897               0 :     aSibling->SetNextSibling(removedViews);
     898               0 :     removedViews = aSibling;
     899               0 :     aSibling = next;
     900                 :   }
     901               0 :   return removedViews;
     902                 : }
     903                 : 
     904                 : static void
     905               0 : InsertViewsInReverseOrder(nsIView* aSibling, nsIView* aParent)
     906                 : {
     907               0 :   NS_PRECONDITION(aParent, "");
     908               0 :   NS_PRECONDITION(!aParent->GetFirstChild(), "inserting into non-empty list");
     909                 : 
     910               0 :   nsIViewManager* vm = aParent->GetViewManager();
     911               0 :   while (aSibling) {
     912               0 :     nsIView* next = aSibling->GetNextSibling();
     913               0 :     aSibling->SetNextSibling(nsnull);
     914                 :     // true means 'after' in document order which is 'before' in view order,
     915                 :     // so this call prepends the child, thus reversing the siblings as we go.
     916               0 :     vm->InsertChild(aParent, aSibling, nsnull, true);
     917               0 :     aSibling = next;
     918                 :   }
     919               0 : }
     920                 : 
     921                 : nsresult
     922               0 : nsSubDocumentFrame::BeginSwapDocShells(nsIFrame* aOther)
     923                 : {
     924               0 :   if (!aOther || aOther->GetType() != nsGkAtoms::subDocumentFrame) {
     925               0 :     return NS_ERROR_NOT_IMPLEMENTED;
     926                 :   }
     927                 : 
     928               0 :   nsSubDocumentFrame* other = static_cast<nsSubDocumentFrame*>(aOther);
     929               0 :   if (!mFrameLoader || !mDidCreateDoc || mCallingShow ||
     930               0 :       !other->mFrameLoader || !other->mDidCreateDoc) {
     931               0 :     return NS_ERROR_NOT_IMPLEMENTED;
     932                 :   }
     933                 : 
     934               0 :   if (mInnerView && other->mInnerView) {
     935               0 :     nsIView* ourSubdocViews = mInnerView->GetFirstChild();
     936               0 :     nsIView* ourRemovedViews = ::BeginSwapDocShellsForViews(ourSubdocViews);
     937               0 :     nsIView* otherSubdocViews = other->mInnerView->GetFirstChild();
     938               0 :     nsIView* otherRemovedViews = ::BeginSwapDocShellsForViews(otherSubdocViews);
     939                 : 
     940               0 :     ::InsertViewsInReverseOrder(ourRemovedViews, other->mInnerView);
     941               0 :     ::InsertViewsInReverseOrder(otherRemovedViews, mInnerView);
     942                 :   }
     943               0 :   mFrameLoader.swap(other->mFrameLoader);
     944               0 :   return NS_OK;
     945                 : }
     946                 : 
     947                 : static bool
     948               0 : EndSwapDocShellsForDocument(nsIDocument* aDocument, void*)
     949                 : {
     950               0 :   NS_PRECONDITION(aDocument, "");
     951                 : 
     952                 :   // Our docshell and view trees have been updated for the new hierarchy.
     953                 :   // Now also update all nsDeviceContext::mWidget to that of the
     954                 :   // container view in the new hierarchy.
     955               0 :   nsCOMPtr<nsISupports> container = aDocument->GetContainer();
     956               0 :   nsCOMPtr<nsIDocShell> ds = do_QueryInterface(container);
     957               0 :   if (ds) {
     958               0 :     nsCOMPtr<nsIContentViewer> cv;
     959               0 :     ds->GetContentViewer(getter_AddRefs(cv));
     960               0 :     while (cv) {
     961               0 :       nsCOMPtr<nsPresContext> pc;
     962               0 :       cv->GetPresContext(getter_AddRefs(pc));
     963               0 :       nsDeviceContext* dc = pc ? pc->DeviceContext() : nsnull;
     964               0 :       if (dc) {
     965               0 :         nsIView* v = cv->FindContainerView();
     966               0 :         dc->Init(v ? v->GetNearestWidget(nsnull) : nsnull);
     967                 :       }
     968               0 :       nsCOMPtr<nsIContentViewer> prev;
     969               0 :       cv->GetPreviousViewer(getter_AddRefs(prev));
     970               0 :       cv = prev;
     971                 :     }
     972                 :   }
     973                 : 
     974                 :   aDocument->EnumerateFreezableElements(
     975               0 :     nsObjectFrame::EndSwapDocShells, nsnull);
     976               0 :   aDocument->EnumerateSubDocuments(EndSwapDocShellsForDocument, nsnull);
     977               0 :   return true;
     978                 : }
     979                 : 
     980                 : static void
     981               0 : EndSwapDocShellsForViews(nsIView* aSibling)
     982                 : {
     983               0 :   for ( ; aSibling; aSibling = aSibling->GetNextSibling()) {
     984               0 :     nsIDocument* doc = ::GetDocumentFromView(aSibling);
     985               0 :     if (doc) {
     986               0 :       ::EndSwapDocShellsForDocument(doc, nsnull);
     987                 :     }
     988                 :   }
     989               0 : }
     990                 : 
     991                 : void
     992               0 : nsSubDocumentFrame::EndSwapDocShells(nsIFrame* aOther)
     993                 : {
     994               0 :   nsSubDocumentFrame* other = static_cast<nsSubDocumentFrame*>(aOther);
     995               0 :   nsWeakFrame weakThis(this);
     996               0 :   nsWeakFrame weakOther(aOther);
     997                 : 
     998               0 :   if (mInnerView) {
     999               0 :     ::EndSwapDocShellsForViews(mInnerView->GetFirstChild());
    1000                 :   }
    1001               0 :   if (other->mInnerView) {
    1002               0 :     ::EndSwapDocShellsForViews(other->mInnerView->GetFirstChild());
    1003                 :   }
    1004                 : 
    1005                 :   // Now make sure we reflow both frames, in case their contents
    1006                 :   // determine their size.
    1007                 :   // And repaint them, for good measure, in case there's nothing
    1008                 :   // interesting that happens during reflow.
    1009               0 :   if (weakThis.IsAlive()) {
    1010               0 :     PresContext()->PresShell()->
    1011               0 :       FrameNeedsReflow(this, nsIPresShell::eTreeChange, NS_FRAME_IS_DIRTY);
    1012               0 :     InvalidateFrameSubtree();
    1013                 :   }
    1014               0 :   if (weakOther.IsAlive()) {
    1015               0 :     other->PresContext()->PresShell()->
    1016               0 :       FrameNeedsReflow(other, nsIPresShell::eTreeChange, NS_FRAME_IS_DIRTY);
    1017               0 :     other->InvalidateFrameSubtree();
    1018                 :   }
    1019               0 : }
    1020                 : 
    1021                 : nsIView*
    1022               0 : nsSubDocumentFrame::EnsureInnerView()
    1023                 : {
    1024               0 :   if (mInnerView) {
    1025               0 :     return mInnerView;
    1026                 :   }
    1027                 : 
    1028                 :   // create, init, set the parent of the view
    1029               0 :   nsIView* outerView = GetView();
    1030               0 :   NS_ASSERTION(outerView, "Must have an outer view already");
    1031               0 :   nsRect viewBounds(0, 0, 0, 0); // size will be fixed during reflow
    1032                 : 
    1033               0 :   nsIViewManager* viewMan = outerView->GetViewManager();
    1034               0 :   nsIView* innerView = viewMan->CreateView(viewBounds, outerView);
    1035               0 :   if (!innerView) {
    1036               0 :     NS_ERROR("Could not create inner view");
    1037               0 :     return nsnull;
    1038                 :   }
    1039               0 :   mInnerView = innerView;
    1040               0 :   viewMan->InsertChild(outerView, innerView, nsnull, true);
    1041                 : 
    1042               0 :   return mInnerView;
    1043                 : }
    1044                 : 
    1045                 : nsIFrame*
    1046               0 : nsSubDocumentFrame::ObtainIntrinsicSizeFrame()
    1047                 : {
    1048               0 :   nsCOMPtr<nsIObjectLoadingContent> olc = do_QueryInterface(GetContent());
    1049               0 :   if (olc) {
    1050                 :     // We are an HTML <object>, <embed> or <applet> (a replaced element).
    1051                 : 
    1052                 :     // Try to get an nsIFrame for our sub-document's document element
    1053               0 :     nsIFrame* subDocRoot = nsnull;
    1054                 : 
    1055               0 :     nsCOMPtr<nsIDocShell> docShell;
    1056               0 :     GetDocShell(getter_AddRefs(docShell));
    1057               0 :     if (docShell) {
    1058               0 :       nsCOMPtr<nsIPresShell> presShell;
    1059               0 :       docShell->GetPresShell(getter_AddRefs(presShell));
    1060               0 :       if (presShell) {
    1061               0 :         nsIScrollableFrame* scrollable = presShell->GetRootScrollFrameAsScrollable();
    1062               0 :         if (scrollable) {
    1063               0 :           nsIFrame* scrolled = scrollable->GetScrolledFrame();
    1064               0 :           if (scrolled) {
    1065               0 :             subDocRoot = scrolled->GetFirstPrincipalChild();
    1066                 :           }
    1067                 :         }
    1068                 :       }
    1069                 :     }
    1070                 : 
    1071               0 :     if (subDocRoot && subDocRoot->GetContent() &&
    1072               0 :         subDocRoot->GetContent()->NodeInfo()->Equals(nsGkAtoms::svg, kNameSpaceID_SVG)) {
    1073               0 :       return subDocRoot; // SVG documents have an intrinsic size
    1074                 :     }
    1075                 :   }
    1076               0 :   return nsnull;
    1077                 : }

Generated by: LCOV version 1.7