1999-02-05 03:55:18 +00:00
|
|
|
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
|
|
|
*
|
1999-11-06 03:40:37 +00:00
|
|
|
* The contents of this file are subject to the Netscape Public
|
|
|
|
* License Version 1.1 (the "License"); you may not use this file
|
|
|
|
* except in compliance with the License. You may obtain a copy of
|
|
|
|
* the License at http://www.mozilla.org/NPL/
|
1999-02-05 03:55:18 +00:00
|
|
|
*
|
1999-11-06 03:40:37 +00:00
|
|
|
* Software distributed under the License is distributed on an "AS
|
|
|
|
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
|
|
|
* implied. See the License for the specific language governing
|
|
|
|
* rights and limitations under the License.
|
1999-02-05 03:55:18 +00:00
|
|
|
*
|
1999-11-06 03:40:37 +00:00
|
|
|
* The Original Code is mozilla.org code.
|
|
|
|
*
|
|
|
|
* The Initial Developer of the Original Code is Netscape
|
1999-02-05 03:55:18 +00:00
|
|
|
* Communications Corporation. Portions created by Netscape are
|
1999-11-06 03:40:37 +00:00
|
|
|
* Copyright (C) 1998 Netscape Communications Corporation. All
|
|
|
|
* Rights Reserved.
|
|
|
|
*
|
|
|
|
* Contributor(s):
|
2000-02-02 22:24:56 +00:00
|
|
|
* Pierre Phaneuf <pp@ludusdesign.com>
|
1999-02-05 03:55:18 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
#include "nsCSSFrameConstructor.h"
|
|
|
|
#include "nsIArena.h"
|
|
|
|
#include "nsCRT.h"
|
|
|
|
#include "nsIAtom.h"
|
|
|
|
#include "nsIURL.h"
|
|
|
|
#include "nsISupportsArray.h"
|
|
|
|
#include "nsHashtable.h"
|
|
|
|
#include "nsIHTMLContent.h"
|
|
|
|
#include "nsIHTMLAttributes.h"
|
|
|
|
#include "nsIStyleRule.h"
|
|
|
|
#include "nsIFrame.h"
|
|
|
|
#include "nsIStyleContext.h"
|
|
|
|
#include "nsHTMLAtoms.h"
|
|
|
|
#include "nsIPresContext.h"
|
|
|
|
#include "nsILinkHandler.h"
|
|
|
|
#include "nsIDocument.h"
|
|
|
|
#include "nsIHTMLTableCellElement.h"
|
1999-12-13 22:56:31 +00:00
|
|
|
#include "nsTableColGroupFrame.h"
|
1999-02-05 03:55:18 +00:00
|
|
|
#include "nsTableColFrame.h"
|
|
|
|
#include "nsHTMLIIDs.h"
|
|
|
|
#include "nsIStyleFrameConstruction.h"
|
|
|
|
#include "nsHTMLParts.h"
|
|
|
|
#include "nsIPresShell.h"
|
1999-04-20 00:05:14 +00:00
|
|
|
#include "nsIStyleSet.h"
|
1999-02-05 03:55:18 +00:00
|
|
|
#include "nsIViewManager.h"
|
|
|
|
#include "nsStyleConsts.h"
|
|
|
|
#include "nsTableOuterFrame.h"
|
|
|
|
#include "nsIXMLDocument.h"
|
|
|
|
#include "nsIWebShell.h"
|
|
|
|
#include "nsHTMLContainerFrame.h"
|
|
|
|
#include "nsINameSpaceManager.h"
|
|
|
|
#include "nsLayoutAtoms.h"
|
|
|
|
#include "nsIDOMHTMLSelectElement.h"
|
|
|
|
#include "nsIComboboxControlFrame.h"
|
1999-08-25 13:42:59 +00:00
|
|
|
#include "nsIListControlFrame.h"
|
1999-06-21 20:41:56 +00:00
|
|
|
#include "nsIRadioControlFrame.h"
|
2000-03-24 15:48:59 +00:00
|
|
|
#include "nsICheckboxControlFrame.h"
|
1999-02-05 03:55:18 +00:00
|
|
|
#include "nsIListControlFrame.h"
|
|
|
|
#include "nsIDOMCharacterData.h"
|
|
|
|
#include "nsIDOMHTMLImageElement.h"
|
|
|
|
#include "nsITextContent.h"
|
1999-02-26 17:11:54 +00:00
|
|
|
#include "nsPlaceholderFrame.h"
|
1999-03-03 16:33:57 +00:00
|
|
|
#include "nsTableRowGroupFrame.h"
|
1999-03-25 06:41:43 +00:00
|
|
|
#include "nsStyleChangeList.h"
|
1999-03-31 06:47:40 +00:00
|
|
|
#include "nsIFormControl.h"
|
1999-03-30 15:22:54 +00:00
|
|
|
#include "nsCSSAtoms.h"
|
1999-04-11 03:10:20 +00:00
|
|
|
#include "nsIDeviceContext.h"
|
1999-04-27 22:14:54 +00:00
|
|
|
#include "nsTextFragment.h"
|
1999-06-30 22:17:43 +00:00
|
|
|
#include "nsISupportsArray.h"
|
|
|
|
#include "nsIAnonymousContentCreator.h"
|
1999-08-05 03:09:22 +00:00
|
|
|
#include "nsIFrameManager.h"
|
1999-08-19 14:29:55 +00:00
|
|
|
#include "nsIAttributeContent.h"
|
1999-10-12 00:16:06 +00:00
|
|
|
#include "nsIPref.h"
|
2000-01-09 02:04:36 +00:00
|
|
|
#include "nsLegendFrame.h"
|
2000-03-22 05:53:32 +00:00
|
|
|
#include "nsIContentIterator.h"
|
2000-04-25 07:10:48 +00:00
|
|
|
#include "nsBoxLayoutState.h"
|
2000-05-22 08:23:46 +00:00
|
|
|
#include "nsIBindingManager.h"
|
2000-07-28 00:35:30 +00:00
|
|
|
#include "nsIXBLBinding.h"
|
1999-02-05 03:55:18 +00:00
|
|
|
|
2000-02-12 03:10:01 +00:00
|
|
|
#include "nsIDOMWindow.h"
|
|
|
|
#include "nsPIDOMWindow.h"
|
2000-02-14 01:42:09 +00:00
|
|
|
#ifdef INCLUDE_XUL
|
|
|
|
#include "nsIDOMXULCommandDispatcher.h"
|
|
|
|
#include "nsIDOMXULDocument.h"
|
2000-05-26 22:45:26 +00:00
|
|
|
#include "nsIMenuFrame.h"
|
2000-02-14 01:42:09 +00:00
|
|
|
#endif
|
|
|
|
|
2000-03-15 15:45:29 +00:00
|
|
|
// XXX - temporary, this is for GfxList View
|
|
|
|
#include "nsViewsCID.h"
|
|
|
|
#include "nsWidgetsCID.h"
|
|
|
|
// to here
|
2000-02-12 03:10:01 +00:00
|
|
|
|
1999-08-31 03:09:40 +00:00
|
|
|
#include "nsInlineFrame.h"
|
1999-10-29 14:39:48 +00:00
|
|
|
#include "nsBlockFrame.h"
|
1999-12-17 03:28:50 +00:00
|
|
|
|
|
|
|
#include "nsGfxTextControlFrame.h"
|
2000-02-11 01:23:36 +00:00
|
|
|
#include "nsIScrollableFrame.h"
|
1999-12-17 03:28:50 +00:00
|
|
|
|
2000-01-11 08:25:59 +00:00
|
|
|
#include "nsIServiceManager.h"
|
|
|
|
#include "nsIXBLService.h"
|
|
|
|
|
1999-08-31 03:09:40 +00:00
|
|
|
#undef NOISY_FIRST_LETTER
|
|
|
|
|
1999-10-02 10:41:40 +00:00
|
|
|
#ifdef MOZ_MATHML
|
1999-09-21 01:15:30 +00:00
|
|
|
#include "nsMathMLAtoms.h"
|
|
|
|
#include "nsMathMLParts.h"
|
|
|
|
#endif
|
|
|
|
|
2000-04-01 22:26:38 +00:00
|
|
|
#ifdef MOZ_SVG
|
|
|
|
#include "nsSVGAtoms.h"
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef MOZ_SVG
|
|
|
|
#include "nsSVGAtoms.h"
|
|
|
|
#include "nsSVGContainerFrame.h"
|
|
|
|
#include "nsPolygonFrame.h"
|
|
|
|
#include "nsPolylineFrame.h"
|
|
|
|
|
2000-05-16 03:40:02 +00:00
|
|
|
|
|
|
|
|
2000-04-01 22:26:38 +00:00
|
|
|
nsresult
|
|
|
|
NS_NewSVGContainerFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame, PRBool aIsRoot );
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
NS_NewPolygonFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame);
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
NS_NewPolylineFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame);
|
|
|
|
#endif
|
|
|
|
|
1999-02-05 03:55:18 +00:00
|
|
|
#ifdef INCLUDE_XUL
|
|
|
|
#include "nsXULAtoms.h"
|
|
|
|
#include "nsToolboxFrame.h"
|
|
|
|
#include "nsToolbarFrame.h"
|
|
|
|
#include "nsTreeIndentationFrame.h"
|
1999-06-15 04:02:43 +00:00
|
|
|
#include "nsIDOMElement.h"
|
|
|
|
#include "nsIDOMDocument.h"
|
|
|
|
#include "nsDocument.h"
|
1999-07-01 21:11:38 +00:00
|
|
|
#include "nsToolbarItemFrame.h"
|
2000-02-29 06:51:04 +00:00
|
|
|
#include "nsIScrollable.h"
|
1999-07-01 21:11:38 +00:00
|
|
|
|
1999-11-01 15:24:57 +00:00
|
|
|
#ifdef DEBUG
|
|
|
|
static PRBool gNoisyContentUpdates = PR_FALSE;
|
|
|
|
static PRBool gReallyNoisyContentUpdates = PR_FALSE;
|
|
|
|
static PRBool gNoisyInlineConstruction = PR_FALSE;
|
|
|
|
#endif
|
|
|
|
|
2000-05-21 07:00:35 +00:00
|
|
|
#include "nsXULTreeFrame.h"
|
2000-06-06 23:13:49 +00:00
|
|
|
#include "nsXULTreeOuterGroupFrame.h"
|
2000-05-21 07:00:35 +00:00
|
|
|
#include "nsXULTreeSliceFrame.h"
|
|
|
|
#include "nsXULTreeCellFrame.h"
|
2000-08-03 00:22:36 +00:00
|
|
|
#include "nsMenuFrame.h"
|
|
|
|
#include "nsPopupSetFrame.h"
|
2000-05-21 07:00:35 +00:00
|
|
|
|
1) implememted box reflow coelescing.
2) implemented gfx scrollbars for list boxes
3) fixed progess meter to be an animated gif
4) fixed bugs 23521, 24721, 19114, 20546, 24385, 24457, 23156, 20226, 22543
-r hyatt, troy, rod
2000-02-09 22:02:40 +00:00
|
|
|
#define NEWGFX_LIST_SCROLLFRAME
|
2000-03-15 15:45:29 +00:00
|
|
|
//------------------------------------------------------------------
|
1999-11-19 15:41:19 +00:00
|
|
|
|
2000-03-31 07:02:06 +00:00
|
|
|
#ifdef NEWGFX_LIST_SCROLLFRAME
|
1999-11-19 15:41:19 +00:00
|
|
|
nsresult
|
1999-12-04 23:49:50 +00:00
|
|
|
NS_NewGfxListControlFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame );
|
2000-03-31 07:02:06 +00:00
|
|
|
#endif
|
|
|
|
|
|
|
|
|
2000-06-23 05:15:04 +00:00
|
|
|
nsresult
|
|
|
|
NS_NewAutoRepeatBoxFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame);
|
|
|
|
|
2000-03-31 07:02:06 +00:00
|
|
|
nsresult
|
2000-04-05 00:19:00 +00:00
|
|
|
NS_NewRootBoxFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame);
|
1999-11-19 15:41:19 +00:00
|
|
|
|
1999-08-19 22:16:23 +00:00
|
|
|
nsresult
|
1999-12-04 23:49:50 +00:00
|
|
|
NS_NewThumbFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame );
|
1999-08-19 22:16:23 +00:00
|
|
|
|
|
|
|
nsresult
|
1999-12-04 23:49:50 +00:00
|
|
|
NS_NewScrollPortFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame );
|
1999-08-19 22:16:23 +00:00
|
|
|
|
|
|
|
nsresult
|
2000-03-31 07:02:06 +00:00
|
|
|
NS_NewGfxScrollFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame, nsIDocument* aDocument, PRBool aIsRoot);
|
1999-08-19 22:16:23 +00:00
|
|
|
|
1999-04-21 22:46:15 +00:00
|
|
|
nsresult
|
1999-12-04 23:49:50 +00:00
|
|
|
NS_NewTabFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame );
|
1999-04-21 22:46:15 +00:00
|
|
|
|
|
|
|
nsresult
|
2000-04-05 00:19:00 +00:00
|
|
|
NS_NewDeckFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame, nsIBoxLayout* aLayoutManager = nsnull);
|
1999-04-21 22:46:15 +00:00
|
|
|
|
2000-03-02 03:01:30 +00:00
|
|
|
nsresult
|
|
|
|
NS_NewSpringFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame );
|
|
|
|
|
|
|
|
nsresult
|
2000-04-05 00:19:00 +00:00
|
|
|
NS_NewStackFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame, nsIBoxLayout* aLayoutManager = nsnull);
|
2000-03-02 03:01:30 +00:00
|
|
|
|
1999-02-19 18:23:02 +00:00
|
|
|
nsresult
|
1999-12-04 23:49:50 +00:00
|
|
|
NS_NewProgressMeterFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame );
|
1999-02-19 18:23:02 +00:00
|
|
|
|
|
|
|
nsresult
|
1999-12-04 23:49:50 +00:00
|
|
|
NS_NewTitledButtonFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame );
|
1999-02-19 18:23:02 +00:00
|
|
|
|
2000-02-16 23:00:52 +00:00
|
|
|
nsresult
|
2000-03-31 07:02:06 +00:00
|
|
|
NS_NewImageBoxFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame );
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
NS_NewTextBoxFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame );
|
2000-02-16 23:00:52 +00:00
|
|
|
|
2000-02-14 01:42:09 +00:00
|
|
|
nsresult
|
|
|
|
NS_NewTitledBoxFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame );
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
NS_NewTitleFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame );
|
|
|
|
|
2000-03-11 10:38:36 +00:00
|
|
|
nsresult
|
2000-03-31 07:02:06 +00:00
|
|
|
NS_NewButtonBoxFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame);
|
2000-03-11 10:38:36 +00:00
|
|
|
|
1999-06-15 04:02:43 +00:00
|
|
|
nsresult
|
1999-12-04 23:49:50 +00:00
|
|
|
NS_NewSliderFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame );
|
1999-06-15 04:02:43 +00:00
|
|
|
|
|
|
|
nsresult
|
1999-12-04 23:49:50 +00:00
|
|
|
NS_NewScrollbarFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame );
|
1999-06-15 04:02:43 +00:00
|
|
|
|
|
|
|
nsresult
|
1999-12-04 23:49:50 +00:00
|
|
|
NS_NewSpinnerFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame );
|
1999-06-15 04:02:43 +00:00
|
|
|
|
|
|
|
nsresult
|
1999-12-04 23:49:50 +00:00
|
|
|
NS_NewFontPickerFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame );
|
1999-06-15 04:02:43 +00:00
|
|
|
|
|
|
|
nsresult
|
1999-12-04 23:49:50 +00:00
|
|
|
NS_NewScrollbarButtonFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame );
|
1999-06-15 04:02:43 +00:00
|
|
|
|
|
|
|
nsresult
|
1999-12-04 23:49:50 +00:00
|
|
|
NS_NewScrollbarFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame );
|
1999-06-15 04:02:43 +00:00
|
|
|
|
1999-06-30 22:17:43 +00:00
|
|
|
nsresult
|
1999-12-04 23:49:50 +00:00
|
|
|
NS_NewGrippyFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame );
|
1999-06-30 22:17:43 +00:00
|
|
|
|
|
|
|
nsresult
|
1999-12-04 23:49:50 +00:00
|
|
|
NS_NewSplitterFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame );
|
1999-07-18 06:29:43 +00:00
|
|
|
|
|
|
|
nsresult
|
1999-12-04 23:49:50 +00:00
|
|
|
NS_NewMenuPopupFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame );
|
1999-07-18 06:29:43 +00:00
|
|
|
|
1999-08-06 19:20:56 +00:00
|
|
|
nsresult
|
1999-12-04 23:49:50 +00:00
|
|
|
NS_NewPopupSetFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame);
|
1999-08-06 19:20:56 +00:00
|
|
|
|
2000-06-23 05:15:04 +00:00
|
|
|
nsresult
|
|
|
|
NS_NewScrollBoxFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame);
|
|
|
|
|
1999-07-18 06:37:06 +00:00
|
|
|
nsresult
|
1999-12-04 23:49:50 +00:00
|
|
|
NS_NewMenuFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame, PRUint32 aFlags );
|
1999-07-18 07:07:55 +00:00
|
|
|
|
|
|
|
nsresult
|
1999-12-04 23:49:50 +00:00
|
|
|
NS_NewMenuBarFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame );
|
1999-07-18 07:07:55 +00:00
|
|
|
|
2000-04-05 00:19:00 +00:00
|
|
|
// grid
|
|
|
|
nsresult
|
|
|
|
NS_NewGridLayout ( nsIPresShell* aPresShell, nsCOMPtr<nsIBoxLayout>& aNewLayout );
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
NS_NewObeliskLayout ( nsIPresShell* aPresShell, nsCOMPtr<nsIBoxLayout>& aNewLayout );
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
NS_NewTempleLayout ( nsIPresShell* aPresShell, nsCOMPtr<nsIBoxLayout>& aNewLayout );
|
|
|
|
|
2000-06-06 23:13:49 +00:00
|
|
|
nsresult
|
|
|
|
NS_NewTreeLayout ( nsIPresShell* aPresShell, nsCOMPtr<nsIBoxLayout>& aNewLayout );
|
|
|
|
|
2000-07-10 20:10:27 +00:00
|
|
|
nsresult
|
|
|
|
NS_NewBulletinBoardLayout ( nsIPresShell* aPresShell, nsCOMPtr<nsIBoxLayout>& aNewLayout );
|
|
|
|
|
2000-04-05 00:19:00 +00:00
|
|
|
// end grid
|
|
|
|
|
2000-07-11 23:34:44 +00:00
|
|
|
nsresult
|
|
|
|
NS_NewTitleBarFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame);
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
NS_NewResizerFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame);
|
|
|
|
|
|
|
|
|
1999-02-05 03:55:18 +00:00
|
|
|
#endif
|
|
|
|
|
|
|
|
//static NS_DEFINE_IID(kIStyleRuleIID, NS_ISTYLE_RULE_IID);
|
|
|
|
static NS_DEFINE_IID(kIStyleFrameConstructionIID, NS_ISTYLE_FRAME_CONSTRUCTION_IID);
|
|
|
|
static NS_DEFINE_IID(kIHTMLTableCellElementIID, NS_IHTMLTABLECELLELEMENT_IID);
|
|
|
|
static NS_DEFINE_IID(kIXMLDocumentIID, NS_IXMLDOCUMENT_IID);
|
|
|
|
static NS_DEFINE_IID(kIWebShellIID, NS_IWEB_SHELL_IID);
|
|
|
|
|
|
|
|
static NS_DEFINE_IID(kIDOMHTMLSelectElementIID, NS_IDOMHTMLSELECTELEMENT_IID);
|
|
|
|
static NS_DEFINE_IID(kIComboboxControlFrameIID, NS_ICOMBOBOXCONTROLFRAME_IID);
|
1999-06-21 20:41:56 +00:00
|
|
|
static NS_DEFINE_IID(kIRadioControlFrameIID, NS_IRADIOCONTROLFRAME_IID);
|
1999-02-05 03:55:18 +00:00
|
|
|
static NS_DEFINE_IID(kIListControlFrameIID, NS_ILISTCONTROLFRAME_IID);
|
|
|
|
static NS_DEFINE_IID(kIDOMHTMLImageElementIID, NS_IDOMHTMLIMAGEELEMENT_IID);
|
|
|
|
static NS_DEFINE_IID(kIDOMCharacterDataIID, NS_IDOMCHARACTERDATA_IID);
|
1999-02-16 04:41:15 +00:00
|
|
|
static NS_DEFINE_IID(kScrollViewIID, NS_ISCROLLABLEVIEW_IID);
|
1999-03-31 06:47:40 +00:00
|
|
|
static NS_DEFINE_IID(kIFormControlIID, NS_IFORMCONTROL_IID);
|
1999-04-12 22:14:31 +00:00
|
|
|
static NS_DEFINE_IID(kIFrameIID, NS_IFRAME_IID);
|
2000-04-04 01:28:15 +00:00
|
|
|
static NS_DEFINE_IID(kIScrollableFrameIID, NS_ISCROLLABLE_FRAME_IID);
|
1999-04-12 22:14:31 +00:00
|
|
|
|
2000-05-25 19:58:51 +00:00
|
|
|
//----------------------------------------------------------------------
|
|
|
|
//
|
|
|
|
// When inline frames get weird and have block frames in them, we
|
|
|
|
// annotate them to help us respond to incremental content changes
|
|
|
|
// more easily.
|
|
|
|
|
|
|
|
static inline PRBool
|
|
|
|
IsFrameSpecial(nsIFrame* aFrame)
|
|
|
|
{
|
|
|
|
nsFrameState state;
|
|
|
|
aFrame->GetFrameState(&state);
|
|
|
|
return state & NS_FRAME_IS_SPECIAL;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline void
|
|
|
|
GetSpecialSibling(nsIFrameManager* aFrameManager, nsIFrame* aFrame, nsIFrame** aResult)
|
|
|
|
{
|
|
|
|
// We only store the "special sibling" annotation with the first
|
|
|
|
// frame in the flow. Walk back to find that frame now.
|
|
|
|
while (1) {
|
|
|
|
nsIFrame* prev = aFrame;
|
|
|
|
aFrame->GetPrevInFlow(&prev);
|
|
|
|
if (! prev)
|
|
|
|
break;
|
|
|
|
aFrame = prev;
|
|
|
|
}
|
|
|
|
|
|
|
|
void* value;
|
|
|
|
aFrameManager->GetFrameProperty(aFrame, nsLayoutAtoms::inlineFrameAnnotation, 0, &value);
|
|
|
|
*aResult = NS_STATIC_CAST(nsIFrame*, value);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
SetFrameIsSpecial(nsIFrameManager* aFrameManager, nsIFrame* aFrame, nsIFrame* aSpecialSibling)
|
|
|
|
{
|
|
|
|
NS_PRECONDITION(aFrameManager && aFrame, "bad args!");
|
|
|
|
|
|
|
|
// Mark the frame and all of its siblings as "special".
|
|
|
|
for (nsIFrame* frame = aFrame; frame != nsnull; frame->GetNextInFlow(&frame)) {
|
|
|
|
nsFrameState state;
|
|
|
|
frame->GetFrameState(&state);
|
|
|
|
state |= NS_FRAME_IS_SPECIAL;
|
|
|
|
frame->SetFrameState(state);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (aSpecialSibling) {
|
|
|
|
#ifdef DEBUG
|
|
|
|
// We should be the first-in-flow
|
|
|
|
nsIFrame* prev;
|
|
|
|
aFrame->GetPrevInFlow(&prev);
|
|
|
|
NS_ASSERTION(! prev, "assigning special sibling to other than first-in-flow!");
|
|
|
|
#endif
|
|
|
|
|
|
|
|
// Store the "special sibling" (if we were given one) with the
|
|
|
|
// first frame in the flow.
|
|
|
|
aFrameManager->SetFrameProperty(aFrame, nsLayoutAtoms::inlineFrameAnnotation,
|
|
|
|
aSpecialSibling, nsnull);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2000-07-06 04:31:33 +00:00
|
|
|
//----------------------------------------------------------------------
|
|
|
|
|
|
|
|
// XXX this predicate and its cousins need to migrated to a single
|
|
|
|
// place in layout - something in nsStyleDisplay maybe?
|
|
|
|
static PRBool
|
|
|
|
IsInlineFrame(nsIFrame* aFrame)
|
|
|
|
{
|
|
|
|
const nsStyleDisplay* display;
|
|
|
|
aFrame->GetStyleData(eStyleStruct_Display, (const nsStyleStruct*&) display);
|
|
|
|
switch (display->mDisplay) {
|
|
|
|
case NS_STYLE_DISPLAY_INLINE:
|
|
|
|
case NS_STYLE_DISPLAY_INLINE_BLOCK:
|
|
|
|
case NS_STYLE_DISPLAY_INLINE_TABLE:
|
|
|
|
return PR_TRUE;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return PR_FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
|
|
|
|
// Block/inline frame construction logic. We maintain a few invariants here:
|
|
|
|
//
|
|
|
|
// 1. Block frames contain block and inline frames.
|
|
|
|
//
|
|
|
|
// 2. Inline frames only contain inline frames. If an inline parent has a block
|
|
|
|
// child then the block child is migrated upward until it lands in a block
|
|
|
|
// parent (the inline frames containing block is where it will end up).
|
|
|
|
|
|
|
|
// XXX consolidate these things
|
|
|
|
static PRBool
|
|
|
|
IsBlockFrame(nsIPresContext* aPresContext, nsIFrame* aFrame)
|
|
|
|
{
|
|
|
|
const nsStyleDisplay* display;
|
|
|
|
aFrame->GetStyleData(eStyleStruct_Display, (const nsStyleStruct*&) display);
|
|
|
|
if (NS_STYLE_DISPLAY_INLINE == display->mDisplay) {
|
|
|
|
return PR_FALSE;
|
|
|
|
}
|
|
|
|
return PR_TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static nsIFrame*
|
|
|
|
FindFirstBlock(nsIPresContext* aPresContext, nsIFrame* aKid, nsIFrame** aPrevKid)
|
|
|
|
{
|
|
|
|
nsIFrame* prevKid = nsnull;
|
|
|
|
while (aKid) {
|
|
|
|
if (IsBlockFrame(aPresContext, aKid)) {
|
|
|
|
*aPrevKid = prevKid;
|
|
|
|
return aKid;
|
|
|
|
}
|
|
|
|
prevKid = aKid;
|
|
|
|
aKid->GetNextSibling(&aKid);
|
|
|
|
}
|
|
|
|
*aPrevKid = nsnull;
|
|
|
|
return nsnull;
|
|
|
|
}
|
|
|
|
|
|
|
|
static nsIFrame*
|
|
|
|
FindLastBlock(nsIPresContext* aPresContext, nsIFrame* aKid)
|
|
|
|
{
|
|
|
|
nsIFrame* lastBlock = nsnull;
|
|
|
|
while (aKid) {
|
|
|
|
if (IsBlockFrame(aPresContext, aKid)) {
|
|
|
|
lastBlock = aKid;
|
|
|
|
}
|
|
|
|
aKid->GetNextSibling(&aKid);
|
|
|
|
}
|
|
|
|
return lastBlock;
|
|
|
|
}
|
|
|
|
|
|
|
|
static nsresult
|
|
|
|
MoveChildrenTo(nsIPresContext* aPresContext,
|
|
|
|
nsIStyleContext* aNewParentSC,
|
|
|
|
nsIFrame* aNewParent,
|
|
|
|
nsIFrame* aFrameList)
|
|
|
|
{
|
|
|
|
while (aFrameList) {
|
|
|
|
aFrameList->SetParent(aNewParent);
|
|
|
|
aFrameList->GetNextSibling(&aFrameList);
|
|
|
|
}
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2000-05-25 19:58:51 +00:00
|
|
|
|
1999-08-27 21:46:10 +00:00
|
|
|
// -----------------------------------------------------------
|
|
|
|
|
1999-02-05 03:55:18 +00:00
|
|
|
// Structure used when constructing formatting object trees.
|
|
|
|
struct nsFrameItems {
|
|
|
|
nsIFrame* childList;
|
|
|
|
nsIFrame* lastChild;
|
|
|
|
|
1999-04-28 19:08:14 +00:00
|
|
|
nsFrameItems(nsIFrame* aFrame = nsnull);
|
1999-02-05 03:55:18 +00:00
|
|
|
|
|
|
|
// Appends the frame to the end of the list
|
|
|
|
void AddChild(nsIFrame* aChild);
|
|
|
|
};
|
|
|
|
|
|
|
|
nsFrameItems::nsFrameItems(nsIFrame* aFrame)
|
1999-02-26 17:11:54 +00:00
|
|
|
: childList(aFrame), lastChild(aFrame)
|
|
|
|
{
|
|
|
|
}
|
1999-02-05 03:55:18 +00:00
|
|
|
|
|
|
|
void
|
|
|
|
nsFrameItems::AddChild(nsIFrame* aChild)
|
|
|
|
{
|
|
|
|
if (childList == nsnull) {
|
|
|
|
childList = lastChild = aChild;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
lastChild->SetNextSibling(aChild);
|
|
|
|
lastChild = aChild;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// -----------------------------------------------------------
|
|
|
|
|
|
|
|
// Structure used when constructing formatting object trees. Contains
|
|
|
|
// state information needed for absolutely positioned elements
|
|
|
|
struct nsAbsoluteItems : nsFrameItems {
|
1999-02-26 17:11:54 +00:00
|
|
|
// containing block for absolutely positioned elements
|
1999-04-28 19:08:14 +00:00
|
|
|
nsIFrame* containingBlock;
|
1999-02-05 03:55:18 +00:00
|
|
|
|
1999-04-28 19:08:14 +00:00
|
|
|
nsAbsoluteItems(nsIFrame* aContainingBlock = nsnull);
|
1999-04-25 17:20:53 +00:00
|
|
|
|
|
|
|
// Appends the frame to the end of the list
|
|
|
|
void AddChild(nsIFrame* aChild);
|
1999-02-05 03:55:18 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
nsAbsoluteItems::nsAbsoluteItems(nsIFrame* aContainingBlock)
|
|
|
|
: containingBlock(aContainingBlock)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
1999-04-25 17:20:53 +00:00
|
|
|
// Additional behavior is that it sets the frame's NS_FRAME_OUT_OF_FLOW flag
|
|
|
|
void
|
|
|
|
nsAbsoluteItems::AddChild(nsIFrame* aChild)
|
|
|
|
{
|
|
|
|
nsFrameState frameState;
|
|
|
|
|
|
|
|
// Mark the frame as being moved out of the flow
|
|
|
|
aChild->GetFrameState(&frameState);
|
|
|
|
aChild->SetFrameState(frameState | NS_FRAME_OUT_OF_FLOW);
|
|
|
|
nsFrameItems::AddChild(aChild);
|
|
|
|
}
|
1999-02-05 03:55:18 +00:00
|
|
|
|
2000-04-04 01:28:15 +00:00
|
|
|
// Structures used to record the creation of pseudo table frames where
|
|
|
|
// the content belongs to some ancestor.
|
|
|
|
|
|
|
|
struct nsPseudoFrameData {
|
|
|
|
nsIFrame* mFrame;
|
|
|
|
nsFrameItems mChildList;
|
|
|
|
nsFrameItems mChildList2;
|
|
|
|
|
|
|
|
nsPseudoFrameData();
|
|
|
|
nsPseudoFrameData(nsPseudoFrameData& aOther);
|
|
|
|
void Reset();
|
|
|
|
};
|
|
|
|
|
|
|
|
struct nsPseudoFrames {
|
|
|
|
nsPseudoFrameData mTableOuter;
|
|
|
|
nsPseudoFrameData mTableInner;
|
|
|
|
nsPseudoFrameData mRowGroup;
|
|
|
|
nsPseudoFrameData mColGroup;
|
|
|
|
nsPseudoFrameData mRow;
|
|
|
|
nsPseudoFrameData mCellOuter;
|
|
|
|
nsPseudoFrameData mCellInner;
|
|
|
|
|
|
|
|
// the frame type of the most descendant pseudo frame, no AddRef
|
|
|
|
nsIAtom* mLowestType;
|
|
|
|
|
|
|
|
nsPseudoFrames();
|
|
|
|
nsPseudoFrames& operator=(const nsPseudoFrames& aOther);
|
|
|
|
void Reset(nsPseudoFrames* aSave = nsnull);
|
|
|
|
PRBool IsEmpty() { return (!mLowestType && !mColGroup.mFrame); }
|
|
|
|
};
|
|
|
|
|
|
|
|
nsPseudoFrameData::nsPseudoFrameData()
|
|
|
|
: mFrame(nsnull), mChildList(), mChildList2()
|
|
|
|
{}
|
|
|
|
|
|
|
|
nsPseudoFrameData::nsPseudoFrameData(nsPseudoFrameData& aOther)
|
|
|
|
: mFrame(aOther.mFrame), mChildList(aOther.mChildList),
|
|
|
|
mChildList2(aOther.mChildList2)
|
|
|
|
{}
|
|
|
|
|
|
|
|
void
|
|
|
|
nsPseudoFrameData::Reset()
|
|
|
|
{
|
|
|
|
mFrame = nsnull;
|
|
|
|
mChildList.childList = mChildList.lastChild = nsnull;
|
|
|
|
mChildList2.childList = mChildList2.lastChild = nsnull;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsPseudoFrames::nsPseudoFrames()
|
|
|
|
: mTableOuter(), mTableInner(), mRowGroup(), mColGroup(),
|
2000-04-28 21:05:31 +00:00
|
|
|
mRow(), mCellOuter(), mCellInner(), mLowestType(nsnull)
|
2000-04-04 01:28:15 +00:00
|
|
|
{}
|
|
|
|
|
|
|
|
nsPseudoFrames& nsPseudoFrames::operator=(const nsPseudoFrames& aOther)
|
|
|
|
{
|
|
|
|
mTableOuter = aOther.mTableOuter;
|
|
|
|
mTableInner = aOther.mTableInner;
|
|
|
|
mColGroup = aOther.mColGroup;
|
|
|
|
mRowGroup = aOther.mRowGroup;
|
|
|
|
mRow = aOther.mRow;
|
|
|
|
mCellOuter = aOther.mCellOuter;
|
|
|
|
mCellInner = aOther.mCellInner;
|
|
|
|
mLowestType = aOther.mLowestType;
|
|
|
|
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
void
|
|
|
|
nsPseudoFrames::Reset(nsPseudoFrames* aSave)
|
|
|
|
{
|
|
|
|
if (aSave) {
|
|
|
|
*aSave = *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
mTableOuter.Reset();
|
|
|
|
mTableInner.Reset();
|
|
|
|
mColGroup.Reset();
|
|
|
|
mRowGroup.Reset();
|
|
|
|
mRow.Reset();
|
|
|
|
mCellOuter.Reset();
|
|
|
|
mCellInner.Reset();
|
|
|
|
mLowestType = nsnull;
|
|
|
|
}
|
|
|
|
|
1999-02-10 19:50:50 +00:00
|
|
|
// -----------------------------------------------------------
|
|
|
|
|
1999-04-28 19:08:14 +00:00
|
|
|
// Structure for saving the existing state when pushing/poping containing
|
|
|
|
// blocks. The destructor restores the state to its previous state
|
|
|
|
class nsFrameConstructorSaveState {
|
|
|
|
public:
|
|
|
|
nsFrameConstructorSaveState();
|
|
|
|
~nsFrameConstructorSaveState();
|
|
|
|
|
|
|
|
private:
|
|
|
|
nsAbsoluteItems* mItems; // pointer to struct whose data we save/restore
|
1999-08-27 21:46:10 +00:00
|
|
|
PRBool* mFirstLetterStyle;
|
1999-08-31 03:09:40 +00:00
|
|
|
PRBool* mFirstLineStyle;
|
1999-08-27 21:46:10 +00:00
|
|
|
|
1999-04-28 19:08:14 +00:00
|
|
|
nsAbsoluteItems mSavedItems; // copy of original data
|
1999-08-27 21:46:10 +00:00
|
|
|
PRBool mSavedFirstLetterStyle;
|
1999-08-31 03:09:40 +00:00
|
|
|
PRBool mSavedFirstLineStyle;
|
1999-08-27 21:46:10 +00:00
|
|
|
|
1999-04-28 19:08:14 +00:00
|
|
|
friend class nsFrameConstructorState;
|
|
|
|
};
|
|
|
|
|
|
|
|
// Structure used for maintaining state information during the
|
|
|
|
// frame construction process
|
|
|
|
class nsFrameConstructorState {
|
|
|
|
public:
|
1999-08-05 03:09:22 +00:00
|
|
|
nsCOMPtr<nsIPresShell> mPresShell;
|
|
|
|
nsCOMPtr<nsIFrameManager> mFrameManager;
|
|
|
|
|
1999-04-28 19:08:14 +00:00
|
|
|
// Containing block information for out-of-flow frammes
|
1999-08-05 03:09:22 +00:00
|
|
|
nsAbsoluteItems mFixedItems;
|
|
|
|
nsAbsoluteItems mAbsoluteItems;
|
|
|
|
nsAbsoluteItems mFloatedItems;
|
1999-08-27 21:46:10 +00:00
|
|
|
PRBool mFirstLetterStyle;
|
1999-08-31 03:09:40 +00:00
|
|
|
PRBool mFirstLineStyle;
|
1999-12-06 07:44:18 +00:00
|
|
|
nsCOMPtr<nsILayoutHistoryState> mFrameState;
|
2000-04-04 01:28:15 +00:00
|
|
|
nsPseudoFrames mPseudoFrames;
|
1999-04-28 19:08:14 +00:00
|
|
|
|
|
|
|
// Constructor
|
1999-12-06 07:44:18 +00:00
|
|
|
nsFrameConstructorState(nsIPresContext* aPresContext,
|
|
|
|
nsIFrame* aFixedContainingBlock,
|
|
|
|
nsIFrame* aAbsoluteContainingBlock,
|
|
|
|
nsIFrame* aFloaterContainingBlock,
|
|
|
|
nsILayoutHistoryState* aFrameState);
|
1999-04-28 19:08:14 +00:00
|
|
|
|
|
|
|
// Function to push the existing absolute containing block state and
|
|
|
|
// create a new scope
|
|
|
|
void PushAbsoluteContainingBlock(nsIFrame* aNewAbsoluteContainingBlock,
|
|
|
|
nsFrameConstructorSaveState& aSaveState);
|
|
|
|
|
|
|
|
// Function to push the existing floater containing block state and
|
|
|
|
// create a new scope
|
|
|
|
void PushFloaterContainingBlock(nsIFrame* aNewFloaterContainingBlock,
|
1999-08-27 21:46:10 +00:00
|
|
|
nsFrameConstructorSaveState& aSaveState,
|
1999-08-31 03:09:40 +00:00
|
|
|
PRBool aFirstLetterStyle,
|
|
|
|
PRBool aFirstLineStyle);
|
1999-04-28 19:08:14 +00:00
|
|
|
};
|
|
|
|
|
1999-12-06 07:44:18 +00:00
|
|
|
nsFrameConstructorState::nsFrameConstructorState(nsIPresContext* aPresContext,
|
|
|
|
nsIFrame* aFixedContainingBlock,
|
|
|
|
nsIFrame* aAbsoluteContainingBlock,
|
|
|
|
nsIFrame* aFloaterContainingBlock,
|
|
|
|
nsILayoutHistoryState* aFrameState)
|
1999-04-28 19:08:14 +00:00
|
|
|
: mFixedItems(aFixedContainingBlock),
|
|
|
|
mAbsoluteItems(aAbsoluteContainingBlock),
|
1999-08-27 21:46:10 +00:00
|
|
|
mFloatedItems(aFloaterContainingBlock),
|
1999-09-20 03:46:09 +00:00
|
|
|
mFirstLetterStyle(PR_FALSE),
|
1999-12-06 07:44:18 +00:00
|
|
|
mFirstLineStyle(PR_FALSE),
|
2000-04-04 01:28:15 +00:00
|
|
|
mFrameState(aFrameState),
|
|
|
|
mPseudoFrames()
|
1999-04-28 19:08:14 +00:00
|
|
|
{
|
1999-08-05 03:09:22 +00:00
|
|
|
aPresContext->GetShell(getter_AddRefs(mPresShell));
|
|
|
|
mPresShell->GetFrameManager(getter_AddRefs(mFrameManager));
|
1999-04-28 19:08:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
nsFrameConstructorState::PushAbsoluteContainingBlock(nsIFrame* aNewAbsoluteContainingBlock,
|
|
|
|
nsFrameConstructorSaveState& aSaveState)
|
|
|
|
{
|
|
|
|
aSaveState.mItems = &mAbsoluteItems;
|
|
|
|
aSaveState.mSavedItems = mAbsoluteItems;
|
|
|
|
mAbsoluteItems = nsAbsoluteItems(aNewAbsoluteContainingBlock);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
nsFrameConstructorState::PushFloaterContainingBlock(nsIFrame* aNewFloaterContainingBlock,
|
1999-08-27 21:46:10 +00:00
|
|
|
nsFrameConstructorSaveState& aSaveState,
|
1999-08-31 03:09:40 +00:00
|
|
|
PRBool aFirstLetterStyle,
|
|
|
|
PRBool aFirstLineStyle)
|
1999-04-28 19:08:14 +00:00
|
|
|
{
|
|
|
|
aSaveState.mItems = &mFloatedItems;
|
1999-08-27 21:46:10 +00:00
|
|
|
aSaveState.mFirstLetterStyle = &mFirstLetterStyle;
|
1999-09-20 03:46:09 +00:00
|
|
|
aSaveState.mFirstLineStyle = &mFirstLineStyle;
|
1999-04-28 19:08:14 +00:00
|
|
|
aSaveState.mSavedItems = mFloatedItems;
|
1999-08-27 21:46:10 +00:00
|
|
|
aSaveState.mSavedFirstLetterStyle = mFirstLetterStyle;
|
1999-08-31 03:09:40 +00:00
|
|
|
aSaveState.mSavedFirstLineStyle = mFirstLineStyle;
|
1999-04-28 19:08:14 +00:00
|
|
|
mFloatedItems = nsAbsoluteItems(aNewFloaterContainingBlock);
|
1999-08-27 21:46:10 +00:00
|
|
|
mFirstLetterStyle = aFirstLetterStyle;
|
1999-08-31 03:09:40 +00:00
|
|
|
mFirstLineStyle = aFirstLineStyle;
|
1999-04-28 19:08:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
nsFrameConstructorSaveState::nsFrameConstructorSaveState()
|
1999-09-26 10:07:16 +00:00
|
|
|
: mItems(nsnull), mFirstLetterStyle(nsnull), mFirstLineStyle(nsnull),
|
|
|
|
mSavedFirstLetterStyle(PR_FALSE), mSavedFirstLineStyle(PR_FALSE)
|
1999-04-28 19:08:14 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
nsFrameConstructorSaveState::~nsFrameConstructorSaveState()
|
|
|
|
{
|
|
|
|
// Restore the state
|
|
|
|
if (mItems) {
|
|
|
|
*mItems = mSavedItems;
|
|
|
|
}
|
1999-08-27 21:46:10 +00:00
|
|
|
if (mFirstLetterStyle) {
|
|
|
|
*mFirstLetterStyle = mSavedFirstLetterStyle;
|
|
|
|
}
|
1999-08-31 03:09:40 +00:00
|
|
|
if (mFirstLineStyle) {
|
|
|
|
*mFirstLineStyle = mSavedFirstLineStyle;
|
|
|
|
}
|
1999-04-28 19:08:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// -----------------------------------------------------------
|
|
|
|
|
1999-02-10 19:50:50 +00:00
|
|
|
// Structure used when creating table frames.
|
|
|
|
struct nsTableCreator {
|
1999-08-24 00:44:21 +00:00
|
|
|
virtual nsresult CreateTableOuterFrame(nsIFrame** aNewFrame);
|
1999-05-11 22:03:29 +00:00
|
|
|
virtual nsresult CreateTableFrame(nsIFrame** aNewFrame);
|
2000-04-04 01:28:15 +00:00
|
|
|
virtual nsresult CreateTableCaptionFrame(nsIFrame** aNewFrame);
|
1999-05-11 22:03:29 +00:00
|
|
|
virtual nsresult CreateTableRowGroupFrame(nsIFrame** aNewFrame);
|
|
|
|
virtual nsresult CreateTableColFrame(nsIFrame** aNewFrame);
|
|
|
|
virtual nsresult CreateTableColGroupFrame(nsIFrame** aNewFrame);
|
|
|
|
virtual nsresult CreateTableRowFrame(nsIFrame** aNewFrame);
|
|
|
|
virtual nsresult CreateTableCellFrame(nsIFrame** aNewFrame);
|
1999-09-21 01:15:30 +00:00
|
|
|
virtual nsresult CreateTableCellInnerFrame(nsIFrame** aNewFrame);
|
1999-12-01 10:37:20 +00:00
|
|
|
|
1999-12-04 23:49:50 +00:00
|
|
|
nsTableCreator(nsIPresShell* aPresShell)
|
|
|
|
{
|
|
|
|
mPresShell = aPresShell;
|
|
|
|
}
|
|
|
|
|
1999-12-05 04:57:13 +00:00
|
|
|
virtual ~nsTableCreator() {};
|
|
|
|
|
1999-12-04 23:49:50 +00:00
|
|
|
nsCOMPtr<nsIPresShell> mPresShell;
|
1999-02-10 19:50:50 +00:00
|
|
|
};
|
|
|
|
|
1999-08-24 00:44:21 +00:00
|
|
|
nsresult
|
|
|
|
nsTableCreator::CreateTableOuterFrame(nsIFrame** aNewFrame) {
|
1999-12-04 23:49:50 +00:00
|
|
|
return NS_NewTableOuterFrame(mPresShell, aNewFrame);
|
1999-08-24 00:44:21 +00:00
|
|
|
}
|
|
|
|
|
1999-02-10 19:50:50 +00:00
|
|
|
nsresult
|
1999-05-11 22:03:29 +00:00
|
|
|
nsTableCreator::CreateTableFrame(nsIFrame** aNewFrame) {
|
1999-12-04 23:49:50 +00:00
|
|
|
return NS_NewTableFrame(mPresShell, aNewFrame);
|
1999-02-10 19:50:50 +00:00
|
|
|
}
|
|
|
|
|
2000-04-04 01:28:15 +00:00
|
|
|
nsresult
|
|
|
|
nsTableCreator::CreateTableCaptionFrame(nsIFrame** aNewFrame) {
|
|
|
|
return NS_NewTableCaptionFrame(mPresShell, aNewFrame);
|
|
|
|
}
|
|
|
|
|
1999-02-10 19:50:50 +00:00
|
|
|
nsresult
|
1999-05-11 22:03:29 +00:00
|
|
|
nsTableCreator::CreateTableRowGroupFrame(nsIFrame** aNewFrame) {
|
1999-12-04 23:49:50 +00:00
|
|
|
return NS_NewTableRowGroupFrame(mPresShell, aNewFrame);
|
1999-02-10 19:50:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
1999-05-11 22:03:29 +00:00
|
|
|
nsTableCreator::CreateTableColFrame(nsIFrame** aNewFrame) {
|
1999-12-04 23:49:50 +00:00
|
|
|
return NS_NewTableColFrame(mPresShell, aNewFrame);
|
1999-02-10 19:50:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
1999-05-11 22:03:29 +00:00
|
|
|
nsTableCreator::CreateTableColGroupFrame(nsIFrame** aNewFrame) {
|
1999-12-04 23:49:50 +00:00
|
|
|
return NS_NewTableColGroupFrame(mPresShell, aNewFrame);
|
1999-02-10 19:50:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
1999-05-11 22:03:29 +00:00
|
|
|
nsTableCreator::CreateTableRowFrame(nsIFrame** aNewFrame) {
|
1999-12-04 23:49:50 +00:00
|
|
|
return NS_NewTableRowFrame(mPresShell, aNewFrame);
|
1999-02-10 19:50:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
1999-05-11 22:03:29 +00:00
|
|
|
nsTableCreator::CreateTableCellFrame(nsIFrame** aNewFrame) {
|
1999-12-04 23:49:50 +00:00
|
|
|
return NS_NewTableCellFrame(mPresShell, aNewFrame);
|
1999-02-10 19:50:50 +00:00
|
|
|
}
|
|
|
|
|
1999-12-01 10:37:20 +00:00
|
|
|
nsresult
|
|
|
|
nsTableCreator::CreateTableCellInnerFrame(nsIFrame** aNewFrame) {
|
1999-12-04 23:49:50 +00:00
|
|
|
return NS_NewTableCellInnerFrame(mPresShell, aNewFrame);
|
1999-12-01 10:37:20 +00:00
|
|
|
}
|
|
|
|
|
1999-09-21 01:15:30 +00:00
|
|
|
//MathML Mod - RBS
|
1999-10-02 10:41:40 +00:00
|
|
|
#ifdef MOZ_MATHML
|
1999-09-21 01:15:30 +00:00
|
|
|
|
|
|
|
// Structure used when creating MathML mtable frames
|
|
|
|
struct nsMathMLmtableCreator: public nsTableCreator {
|
2000-03-28 09:32:54 +00:00
|
|
|
virtual nsresult CreateTableOuterFrame(nsIFrame** aNewFrame);
|
|
|
|
virtual nsresult CreateTableCellInnerFrame(nsIFrame** aNewFrame);
|
1999-12-10 13:07:59 +00:00
|
|
|
|
|
|
|
nsMathMLmtableCreator(nsIPresShell* aPresShell)
|
|
|
|
:nsTableCreator(aPresShell) {};
|
1999-09-21 01:15:30 +00:00
|
|
|
};
|
|
|
|
|
2000-03-28 09:32:54 +00:00
|
|
|
nsresult
|
|
|
|
nsMathMLmtableCreator::CreateTableOuterFrame(nsIFrame** aNewFrame)
|
|
|
|
{
|
|
|
|
return NS_NewMathMLmtableOuterFrame(mPresShell, aNewFrame);
|
|
|
|
}
|
|
|
|
|
1999-09-21 01:15:30 +00:00
|
|
|
nsresult
|
|
|
|
nsMathMLmtableCreator::CreateTableCellInnerFrame(nsIFrame** aNewFrame)
|
|
|
|
{
|
|
|
|
// only works if aNewFrame is an AreaFrame (to take care of the lineLayout logic)
|
1999-12-10 13:07:59 +00:00
|
|
|
return NS_NewMathMLmtdFrame(mPresShell, aNewFrame);
|
1999-09-21 01:15:30 +00:00
|
|
|
}
|
1999-10-02 10:41:40 +00:00
|
|
|
#endif // MOZ_MATHML
|
1999-09-21 01:15:30 +00:00
|
|
|
|
1999-02-05 03:55:18 +00:00
|
|
|
// -----------------------------------------------------------
|
|
|
|
|
2000-01-28 02:19:45 +00:00
|
|
|
// return the child list that aFrame belongs on. does not ADDREF
|
2000-04-28 21:05:31 +00:00
|
|
|
PRBool GetCaptionAdjustedParent(nsIFrame* aParentFrame,
|
|
|
|
const nsIFrame* aChildFrame,
|
|
|
|
nsIFrame** aAdjParentFrame)
|
2000-01-28 02:19:45 +00:00
|
|
|
{
|
2000-04-28 21:05:31 +00:00
|
|
|
*aAdjParentFrame = aParentFrame;
|
|
|
|
PRBool haveCaption = PR_FALSE;
|
|
|
|
nsCOMPtr<nsIAtom> childFrameType;
|
|
|
|
aChildFrame->GetFrameType(getter_AddRefs(childFrameType));
|
|
|
|
|
|
|
|
if (nsLayoutAtoms::tableCaptionFrame == childFrameType.get()) {
|
|
|
|
haveCaption = PR_TRUE;
|
|
|
|
nsCOMPtr<nsIAtom> parentFrameType;
|
|
|
|
aParentFrame->GetFrameType(getter_AddRefs(parentFrameType));
|
|
|
|
if (nsLayoutAtoms::tableFrame == parentFrameType.get()) {
|
|
|
|
aParentFrame->GetParent(aAdjParentFrame);
|
|
|
|
}
|
2000-01-28 02:19:45 +00:00
|
|
|
}
|
2000-04-28 21:05:31 +00:00
|
|
|
return haveCaption;
|
2000-01-28 02:19:45 +00:00
|
|
|
}
|
|
|
|
|
1999-02-05 03:55:18 +00:00
|
|
|
nsCSSFrameConstructor::nsCSSFrameConstructor(void)
|
|
|
|
: nsIStyleFrameConstruction(),
|
|
|
|
mDocument(nsnull),
|
|
|
|
mInitialContainingBlock(nsnull),
|
|
|
|
mFixedContainingBlock(nsnull),
|
1999-08-27 06:06:39 +00:00
|
|
|
mDocElementContainingBlock(nsnull),
|
|
|
|
mGfxScrollFrame(nsnull)
|
1999-02-05 03:55:18 +00:00
|
|
|
{
|
|
|
|
NS_INIT_REFCNT();
|
|
|
|
}
|
|
|
|
|
|
|
|
nsCSSFrameConstructor::~nsCSSFrameConstructor(void)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMPL_ISUPPORTS(nsCSSFrameConstructor, kIStyleFrameConstructionIID);
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsCSSFrameConstructor::Init(nsIDocument* aDocument)
|
|
|
|
{
|
|
|
|
NS_PRECONDITION(aDocument, "null ptr");
|
|
|
|
if (! aDocument)
|
|
|
|
return NS_ERROR_NULL_POINTER;
|
|
|
|
|
|
|
|
if (mDocument)
|
|
|
|
return NS_ERROR_ALREADY_INITIALIZED;
|
|
|
|
|
|
|
|
mDocument = aDocument; // not refcounted!
|
2000-03-27 22:12:42 +00:00
|
|
|
|
|
|
|
// This initializes the Gfx Scrollbar Prefs booleans
|
|
|
|
mGotGfxPrefs = PR_FALSE;
|
|
|
|
mHasGfxScrollbars = PR_FALSE;
|
|
|
|
mDoGfxListbox = PR_FALSE;
|
|
|
|
mDoGfxCombobox = PR_FALSE;
|
|
|
|
|
|
|
|
HasGfxScrollbars();
|
|
|
|
|
1999-02-05 03:55:18 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
1999-04-27 03:58:46 +00:00
|
|
|
// Helper function that determines the child list name that aChildFrame
|
|
|
|
// is contained in
|
|
|
|
static void
|
2000-01-22 01:16:50 +00:00
|
|
|
GetChildListNameFor(nsIPresContext* aPresContext,
|
|
|
|
nsIFrame* aParentFrame,
|
|
|
|
nsIFrame* aChildFrame,
|
|
|
|
nsIAtom** aListName)
|
1999-04-27 03:58:46 +00:00
|
|
|
{
|
|
|
|
nsFrameState frameState;
|
|
|
|
nsIAtom* listName;
|
|
|
|
|
|
|
|
// See if the frame is moved out of the flow
|
|
|
|
aChildFrame->GetFrameState(&frameState);
|
|
|
|
if (frameState & NS_FRAME_OUT_OF_FLOW) {
|
|
|
|
// Look at the style information to tell
|
|
|
|
const nsStylePosition* position;
|
|
|
|
aChildFrame->GetStyleData(eStyleStruct_Position, (const nsStyleStruct*&)position);
|
|
|
|
|
|
|
|
if (NS_STYLE_POSITION_ABSOLUTE == position->mPosition) {
|
|
|
|
listName = nsLayoutAtoms::absoluteList;
|
|
|
|
} else if (NS_STYLE_POSITION_FIXED == position->mPosition) {
|
|
|
|
listName = nsLayoutAtoms::fixedList;
|
|
|
|
} else {
|
|
|
|
#ifdef NS_DEBUG
|
|
|
|
const nsStyleDisplay* display;
|
|
|
|
aChildFrame->GetStyleData(eStyleStruct_Display, (const nsStyleStruct*&)display);
|
|
|
|
NS_ASSERTION(display->IsFloating(), "not a floated frame");
|
|
|
|
#endif
|
|
|
|
listName = nsLayoutAtoms::floaterList;
|
|
|
|
}
|
|
|
|
|
|
|
|
} else {
|
|
|
|
listName = nsnull;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Verify that the frame is actually in that child list
|
|
|
|
#ifdef NS_DEBUG
|
|
|
|
nsIFrame* firstChild;
|
2000-01-22 01:16:50 +00:00
|
|
|
aParentFrame->FirstChild(aPresContext, listName, &firstChild);
|
1999-04-27 03:58:46 +00:00
|
|
|
|
|
|
|
nsFrameList frameList(firstChild);
|
|
|
|
NS_ASSERTION(frameList.ContainsFrame(aChildFrame), "not in child list");
|
|
|
|
#endif
|
|
|
|
|
|
|
|
NS_IF_ADDREF(listName);
|
|
|
|
*aListName = listName;
|
|
|
|
}
|
|
|
|
|
2000-03-23 21:05:23 +00:00
|
|
|
class GeneratedContentIterator : public nsIContentIterator
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
GeneratedContentIterator(nsIPresContext* aPresContext, nsIFrame* aFrame);
|
|
|
|
virtual ~GeneratedContentIterator();
|
|
|
|
|
|
|
|
// nsISupports
|
|
|
|
NS_DECL_ISUPPORTS
|
|
|
|
|
|
|
|
// nsIContentIterator
|
|
|
|
NS_IMETHOD Init(nsIContent* aRoot);
|
|
|
|
NS_IMETHOD Init(nsIDOMRange* aRange);
|
|
|
|
|
|
|
|
NS_IMETHOD First();
|
|
|
|
NS_IMETHOD Last();
|
|
|
|
NS_IMETHOD Next();
|
|
|
|
NS_IMETHOD Prev();
|
|
|
|
|
|
|
|
NS_IMETHOD CurrentNode(nsIContent **aNode);
|
|
|
|
NS_IMETHOD IsDone();
|
|
|
|
NS_IMETHOD PositionAt(nsIContent* aCurNode);
|
|
|
|
|
|
|
|
NS_IMETHOD MakePre();
|
|
|
|
NS_IMETHOD MakePost();
|
|
|
|
|
|
|
|
private:
|
|
|
|
nsCOMPtr<nsIPresContext> mPresContext;
|
|
|
|
nsIFrame* mParentFrame;
|
|
|
|
nsIFrame* mCurrentChild;
|
|
|
|
PRBool mIsDone;
|
|
|
|
};
|
|
|
|
|
|
|
|
GeneratedContentIterator::GeneratedContentIterator(nsIPresContext* aPresContext,
|
|
|
|
nsIFrame* aFrame)
|
|
|
|
: mPresContext(aPresContext), mParentFrame(aFrame), mIsDone(PR_FALSE)
|
|
|
|
{
|
|
|
|
NS_INIT_REFCNT();
|
|
|
|
First();
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMPL_ISUPPORTS(GeneratedContentIterator, NS_GET_IID(nsIContentIterator));
|
|
|
|
|
|
|
|
GeneratedContentIterator::~GeneratedContentIterator()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
GeneratedContentIterator::Init(nsIContent* aRoot)
|
|
|
|
{
|
|
|
|
return NS_ERROR_ALREADY_INITIALIZED;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
GeneratedContentIterator::Init(nsIDOMRange* aRange)
|
|
|
|
{
|
|
|
|
return NS_ERROR_ALREADY_INITIALIZED;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
GeneratedContentIterator::First()
|
|
|
|
{
|
|
|
|
// Get the first child frame and make it the current node
|
|
|
|
mParentFrame->FirstChild(mPresContext, nsnull, &mCurrentChild);
|
|
|
|
if (!mCurrentChild) {
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
mIsDone = PR_FALSE;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
static nsIFrame*
|
|
|
|
GetNextChildFrame(nsIPresContext* aPresContext, nsIFrame* aFrame)
|
|
|
|
{
|
|
|
|
NS_PRECONDITION(aFrame, "null pointer");
|
|
|
|
|
|
|
|
// Get the last-in-flow
|
|
|
|
while (PR_TRUE) {
|
|
|
|
nsIFrame* nextInFlow;
|
|
|
|
aFrame->GetNextInFlow(&nextInFlow);
|
|
|
|
if (nextInFlow) {
|
|
|
|
aFrame = nextInFlow;
|
|
|
|
} else {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Get its next sibling
|
|
|
|
nsIFrame* nextSibling;
|
|
|
|
aFrame->GetNextSibling(&nextSibling);
|
|
|
|
|
|
|
|
// If there's no next sibling, then check if the parent frame
|
|
|
|
// has a next-in-flow and look there
|
|
|
|
if (!nextSibling) {
|
|
|
|
nsIFrame* parent;
|
|
|
|
aFrame->GetParent(&parent);
|
|
|
|
parent->GetNextInFlow(&parent);
|
|
|
|
|
|
|
|
if (parent) {
|
|
|
|
parent->FirstChild(aPresContext, nsnull, &nextSibling);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return nextSibling;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
GeneratedContentIterator::Last()
|
|
|
|
{
|
|
|
|
nsIFrame* nextChild;
|
|
|
|
|
|
|
|
// Starting with the first child walk and find the last child
|
|
|
|
mCurrentChild = nsnull;
|
|
|
|
mParentFrame->FirstChild(mPresContext, nsnull, &nextChild);
|
|
|
|
while (nextChild) {
|
|
|
|
mCurrentChild = nextChild;
|
|
|
|
nextChild = ::GetNextChildFrame(mPresContext, nextChild);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!mCurrentChild) {
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
mIsDone = PR_FALSE;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
GeneratedContentIterator::Next()
|
|
|
|
{
|
|
|
|
nsIFrame* nextChild = ::GetNextChildFrame(mPresContext, mCurrentChild);
|
|
|
|
|
|
|
|
if (nextChild) {
|
|
|
|
// Advance to the next child
|
|
|
|
mCurrentChild = nextChild;
|
|
|
|
|
|
|
|
// If we're at the end then the collection is at the end
|
|
|
|
mIsDone = (nsnull == ::GetNextChildFrame(mPresContext, mCurrentChild));
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static nsIFrame*
|
|
|
|
GetPrevChildFrame(nsIPresContext* aPresContext, nsIFrame* aFrame)
|
|
|
|
{
|
|
|
|
NS_PRECONDITION(aFrame, "null pointer");
|
|
|
|
|
|
|
|
// Get its previous sibling. Because we have a singly linked list we
|
|
|
|
// need to search from the first child
|
|
|
|
nsIFrame* parent;
|
|
|
|
nsIFrame* firstChild;
|
|
|
|
nsIFrame* prevSibling;
|
|
|
|
|
|
|
|
aFrame->GetParent(&parent);
|
|
|
|
parent->FirstChild(aPresContext, nsnull, &firstChild);
|
|
|
|
|
|
|
|
NS_ASSERTION(firstChild, "parent has no first child");
|
|
|
|
nsFrameList frameList(firstChild);
|
|
|
|
prevSibling = frameList.GetPrevSiblingFor(aFrame);
|
|
|
|
|
|
|
|
// If there's no previous sibling, then check if the parent frame
|
|
|
|
// has a prev-in-flow and look there
|
|
|
|
if (!prevSibling) {
|
|
|
|
parent->GetPrevInFlow(&parent);
|
|
|
|
|
|
|
|
if (parent) {
|
|
|
|
parent->FirstChild(aPresContext, nsnull, &firstChild);
|
|
|
|
frameList.SetFrames(firstChild);
|
|
|
|
prevSibling = frameList.LastChild();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Get the first-in-flow
|
|
|
|
while (PR_TRUE) {
|
|
|
|
nsIFrame* prevInFlow;
|
|
|
|
prevSibling->GetPrevInFlow(&prevInFlow);
|
|
|
|
if (prevInFlow) {
|
|
|
|
prevSibling = prevInFlow;
|
|
|
|
} else {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return prevSibling;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
GeneratedContentIterator::Prev()
|
|
|
|
{
|
|
|
|
nsIFrame* prevChild = ::GetPrevChildFrame(mPresContext, mCurrentChild);
|
|
|
|
|
|
|
|
if (prevChild) {
|
|
|
|
// Make the previous child the current child
|
|
|
|
mCurrentChild = prevChild;
|
|
|
|
|
|
|
|
// If we're at the beginning then the collection is at the end
|
|
|
|
mIsDone = (nsnull == ::GetPrevChildFrame(mPresContext, mCurrentChild));
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
GeneratedContentIterator::CurrentNode(nsIContent **aNode)
|
|
|
|
{
|
|
|
|
if (mCurrentChild) {
|
|
|
|
mCurrentChild->GetContent(aNode);
|
|
|
|
return NS_OK;
|
|
|
|
|
|
|
|
} else {
|
|
|
|
*aNode = nsnull;
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
GeneratedContentIterator::IsDone()
|
|
|
|
{
|
|
|
|
return mIsDone ? NS_OK : NS_ENUMERATOR_FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
GeneratedContentIterator::PositionAt(nsIContent* aCurNode)
|
|
|
|
{
|
|
|
|
nsIFrame* child;
|
|
|
|
|
|
|
|
// Starting with the first child frame search for the child frame
|
|
|
|
// with the matching content object
|
|
|
|
mParentFrame->FirstChild(mPresContext, nsnull, &child);
|
|
|
|
while (child) {
|
|
|
|
nsCOMPtr<nsIContent> content;
|
|
|
|
|
|
|
|
child->GetContent(getter_AddRefs(content));
|
|
|
|
if (content.get() == aCurNode) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
child = ::GetNextChildFrame(mPresContext, child);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (child) {
|
|
|
|
// Make it the current child
|
|
|
|
mCurrentChild = child;
|
|
|
|
mIsDone = PR_FALSE;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
GeneratedContentIterator::MakePre()
|
|
|
|
{
|
|
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
GeneratedContentIterator::MakePost()
|
|
|
|
{
|
|
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
|
|
|
}
|
|
|
|
|
2000-03-22 05:53:32 +00:00
|
|
|
nsresult
|
|
|
|
NS_NewGeneratedContentIterator(nsIPresContext* aPresContext,
|
|
|
|
nsIFrame* aFrame,
|
|
|
|
nsIContentIterator** aIterator)
|
|
|
|
{
|
2000-03-23 21:05:23 +00:00
|
|
|
NS_ENSURE_ARG_POINTER(aIterator);
|
|
|
|
if (!aIterator) {
|
|
|
|
return NS_ERROR_NULL_POINTER;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Make sure the frame corresponds to generated content
|
|
|
|
#ifdef DEBUG
|
|
|
|
nsFrameState frameState;
|
|
|
|
aFrame->GetFrameState(&frameState);
|
|
|
|
NS_ASSERTION(frameState & NS_FRAME_GENERATED_CONTENT, "unexpected frame");
|
|
|
|
#endif
|
|
|
|
|
|
|
|
GeneratedContentIterator* it = new GeneratedContentIterator(aPresContext, aFrame);
|
|
|
|
if (!it) {
|
|
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
|
|
}
|
|
|
|
return it->QueryInterface(NS_GET_IID(nsIContentIterator), (void **)aIterator);
|
2000-03-22 05:53:32 +00:00
|
|
|
}
|
|
|
|
|
1999-04-05 02:53:07 +00:00
|
|
|
nsresult
|
|
|
|
nsCSSFrameConstructor::CreateGeneratedFrameFor(nsIPresContext* aPresContext,
|
1999-09-07 03:09:33 +00:00
|
|
|
nsIDocument* aDocument,
|
1999-04-05 02:53:07 +00:00
|
|
|
nsIFrame* aParentFrame,
|
|
|
|
nsIContent* aContent,
|
|
|
|
nsIStyleContext* aStyleContext,
|
|
|
|
const nsStyleContent* aStyleContent,
|
|
|
|
PRUint32 aContentIndex,
|
|
|
|
nsIFrame** aFrame)
|
|
|
|
{
|
|
|
|
*aFrame = nsnull; // initialize OUT parameter
|
|
|
|
|
|
|
|
// Get the content value
|
|
|
|
nsStyleContentType type;
|
|
|
|
nsAutoString contentString;
|
|
|
|
aStyleContent->GetContentAt(aContentIndex, type, contentString);
|
|
|
|
|
1999-12-04 23:49:50 +00:00
|
|
|
nsCOMPtr<nsIPresShell> shell;
|
|
|
|
aPresContext->GetShell(getter_AddRefs(shell));
|
|
|
|
|
1999-04-05 02:53:07 +00:00
|
|
|
if (eStyleContentType_URL == type) {
|
|
|
|
nsIHTMLContent* imageContent;
|
|
|
|
|
|
|
|
// Create an HTML image content object, and set the SRC.
|
|
|
|
// XXX Check if it's an image type we can handle...
|
2000-05-10 13:13:39 +00:00
|
|
|
|
|
|
|
nsCOMPtr<nsINodeInfoManager> nimgr;
|
|
|
|
nsresult rv = aDocument->GetNodeInfoManager(*getter_AddRefs(nimgr));
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
|
|
|
|
nsCOMPtr<nsINodeInfo> nodeInfo;
|
|
|
|
nimgr->GetNodeInfo(nsHTMLAtoms::img, nsnull, kNameSpaceID_None,
|
|
|
|
*getter_AddRefs(nodeInfo));
|
|
|
|
|
|
|
|
NS_NewHTMLImageElement(&imageContent, nodeInfo);
|
1999-04-05 02:53:07 +00:00
|
|
|
imageContent->SetHTMLAttribute(nsHTMLAtoms::src, contentString, PR_FALSE);
|
1999-09-07 03:09:33 +00:00
|
|
|
|
|
|
|
// Set aContent as the parent content and set the document object. This
|
|
|
|
// way event handling works
|
|
|
|
imageContent->SetParent(aContent);
|
2000-05-19 04:48:43 +00:00
|
|
|
imageContent->SetDocument(aDocument, PR_TRUE, PR_TRUE);
|
1999-04-05 02:53:07 +00:00
|
|
|
|
|
|
|
// Create an image frame and initialize it
|
|
|
|
nsIFrame* imageFrame;
|
1999-12-04 23:49:50 +00:00
|
|
|
NS_NewImageFrame(shell, &imageFrame);
|
1999-11-24 06:03:41 +00:00
|
|
|
imageFrame->Init(aPresContext, imageContent, aParentFrame, aStyleContext, nsnull);
|
1999-04-05 02:53:07 +00:00
|
|
|
NS_RELEASE(imageContent);
|
|
|
|
|
|
|
|
// Return the image frame
|
|
|
|
*aFrame = imageFrame;
|
|
|
|
|
|
|
|
} else {
|
1999-08-19 14:29:55 +00:00
|
|
|
|
1999-04-05 02:53:07 +00:00
|
|
|
switch (type) {
|
|
|
|
case eStyleContentType_String:
|
|
|
|
break;
|
|
|
|
|
|
|
|
case eStyleContentType_Attr:
|
1999-08-19 14:29:55 +00:00
|
|
|
{
|
1999-06-10 05:24:00 +00:00
|
|
|
nsIAtom* attrName = nsnull;
|
|
|
|
PRInt32 attrNameSpace = kNameSpaceID_None;
|
1999-07-26 00:37:24 +00:00
|
|
|
PRInt32 barIndex = contentString.FindChar('|'); // CSS namespace delimiter
|
1999-06-10 05:24:00 +00:00
|
|
|
if (-1 != barIndex) {
|
|
|
|
nsAutoString nameSpaceVal;
|
|
|
|
contentString.Left(nameSpaceVal, barIndex);
|
|
|
|
PRInt32 error;
|
|
|
|
attrNameSpace = nameSpaceVal.ToInteger(&error, 10);
|
|
|
|
contentString.Cut(0, barIndex + 1);
|
|
|
|
if (contentString.Length()) {
|
|
|
|
attrName = NS_NewAtom(contentString);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
attrName = NS_NewAtom(contentString);
|
|
|
|
}
|
1999-08-19 14:29:55 +00:00
|
|
|
|
|
|
|
// Creates the content and frame and return if successful
|
|
|
|
nsresult rv = NS_ERROR_FAILURE;
|
|
|
|
if (nsnull != attrName) {
|
2000-02-08 13:17:50 +00:00
|
|
|
nsCOMPtr<nsIContent> content;
|
1999-08-19 14:29:55 +00:00
|
|
|
nsIFrame* textFrame = nsnull;
|
2000-02-08 13:17:50 +00:00
|
|
|
NS_NewAttributeContent(getter_AddRefs(content));
|
1999-08-19 14:29:55 +00:00
|
|
|
if (nsnull != content) {
|
|
|
|
nsCOMPtr<nsIAttributeContent> attrContent(do_QueryInterface(content));
|
|
|
|
if (attrContent) {
|
|
|
|
attrContent->Init(aContent, attrNameSpace, attrName);
|
|
|
|
}
|
|
|
|
|
1999-09-07 03:09:33 +00:00
|
|
|
// Set aContent as the parent content and set the document object. This
|
|
|
|
// way event handling works
|
|
|
|
content->SetParent(aContent);
|
2000-05-19 04:48:43 +00:00
|
|
|
content->SetDocument(aDocument, PR_TRUE, PR_TRUE);
|
1999-09-07 03:09:33 +00:00
|
|
|
|
1999-08-19 14:29:55 +00:00
|
|
|
// Create a text frame and initialize it
|
1999-12-04 23:49:50 +00:00
|
|
|
NS_NewTextFrame(shell, &textFrame);
|
1999-11-24 06:03:41 +00:00
|
|
|
textFrame->Init(aPresContext, content, aParentFrame, aStyleContext, nsnull);
|
1999-08-19 14:29:55 +00:00
|
|
|
|
|
|
|
// Return the text frame
|
|
|
|
*aFrame = textFrame;
|
|
|
|
rv = NS_OK;
|
|
|
|
}
|
1999-06-10 05:24:00 +00:00
|
|
|
NS_RELEASE(attrName);
|
|
|
|
}
|
1999-08-19 14:29:55 +00:00
|
|
|
return rv;
|
1999-04-05 02:53:07 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case eStyleContentType_Counter:
|
|
|
|
case eStyleContentType_Counters:
|
1999-04-27 22:14:54 +00:00
|
|
|
case eStyleContentType_URL:
|
1999-04-05 02:53:07 +00:00
|
|
|
return NS_ERROR_NOT_IMPLEMENTED; // XXX not supported yet...
|
|
|
|
|
|
|
|
case eStyleContentType_OpenQuote:
|
|
|
|
case eStyleContentType_CloseQuote:
|
|
|
|
{
|
|
|
|
PRUint32 quotesCount = aStyleContent->QuotesCount();
|
|
|
|
if (quotesCount > 0) {
|
|
|
|
nsAutoString openQuote, closeQuote;
|
|
|
|
|
|
|
|
// If the depth is greater than the number of pairs, the last pair
|
|
|
|
// is repeated
|
|
|
|
PRUint32 quoteDepth = 0; // XXX really track the nested quotes...
|
|
|
|
if (quoteDepth > quotesCount) {
|
|
|
|
quoteDepth = quotesCount - 1;
|
|
|
|
}
|
|
|
|
aStyleContent->GetQuotesAt(quoteDepth, openQuote, closeQuote);
|
|
|
|
if (eStyleContentType_OpenQuote == type) {
|
|
|
|
contentString = openQuote;
|
|
|
|
} else {
|
|
|
|
contentString = closeQuote;
|
|
|
|
}
|
|
|
|
|
|
|
|
} else {
|
2000-05-09 05:11:12 +00:00
|
|
|
// XXX Don't assume default. Only use what is in 'quotes' property
|
2000-05-12 07:53:02 +00:00
|
|
|
contentString.AssignWithConversion('\"');
|
1999-04-05 02:53:07 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case eStyleContentType_NoOpenQuote:
|
|
|
|
case eStyleContentType_NoCloseQuote:
|
|
|
|
// XXX Adjust quote depth...
|
|
|
|
return NS_OK;
|
1999-08-19 14:29:55 +00:00
|
|
|
} // switch
|
1999-04-05 02:53:07 +00:00
|
|
|
|
1999-08-19 14:29:55 +00:00
|
|
|
|
1999-04-05 02:53:07 +00:00
|
|
|
// Create a text content node
|
1999-08-19 14:29:55 +00:00
|
|
|
nsIContent* textContent = nsnull;
|
1999-04-05 02:53:07 +00:00
|
|
|
nsIDOMCharacterData* domData;
|
1999-08-19 14:29:55 +00:00
|
|
|
nsIFrame* textFrame = nsnull;
|
1999-04-05 02:53:07 +00:00
|
|
|
|
|
|
|
NS_NewTextNode(&textContent);
|
1999-09-07 03:09:33 +00:00
|
|
|
if (textContent) {
|
|
|
|
// Set the text
|
1999-08-19 14:29:55 +00:00
|
|
|
textContent->QueryInterface(kIDOMCharacterDataIID, (void**)&domData);
|
|
|
|
domData->SetData(contentString);
|
|
|
|
NS_RELEASE(domData);
|
1999-04-05 02:53:07 +00:00
|
|
|
|
1999-11-11 21:43:15 +00:00
|
|
|
// Set aContent as the parent content and set the document object. This
|
|
|
|
// way event handling works
|
|
|
|
textContent->SetParent(aContent);
|
2000-05-19 04:48:43 +00:00
|
|
|
textContent->SetDocument(aDocument, PR_TRUE, PR_TRUE);
|
1999-11-11 21:43:15 +00:00
|
|
|
|
1999-08-19 14:29:55 +00:00
|
|
|
// Create a text frame and initialize it
|
1999-12-04 23:49:50 +00:00
|
|
|
NS_NewTextFrame(shell, &textFrame);
|
1999-11-24 06:03:41 +00:00
|
|
|
textFrame->Init(aPresContext, textContent, aParentFrame, aStyleContext, nsnull);
|
1999-04-05 02:53:07 +00:00
|
|
|
|
1999-08-19 14:29:55 +00:00
|
|
|
NS_RELEASE(textContent);
|
|
|
|
}
|
1999-04-05 02:53:07 +00:00
|
|
|
|
|
|
|
// Return the text frame
|
|
|
|
*aFrame = textFrame;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
1999-03-30 15:22:54 +00:00
|
|
|
PRBool
|
1999-12-04 23:49:50 +00:00
|
|
|
nsCSSFrameConstructor::CreateGeneratedContentFrame(nsIPresShell* aPresShell,
|
|
|
|
nsIPresContext* aPresContext,
|
1999-07-05 18:46:09 +00:00
|
|
|
nsFrameConstructorState& aState,
|
1999-03-30 15:22:54 +00:00
|
|
|
nsIFrame* aFrame,
|
|
|
|
nsIContent* aContent,
|
|
|
|
nsIStyleContext* aStyleContext,
|
|
|
|
nsIAtom* aPseudoElement,
|
1999-07-05 18:46:09 +00:00
|
|
|
PRBool aForBlock,
|
1999-03-30 15:22:54 +00:00
|
|
|
nsIFrame** aResult)
|
|
|
|
{
|
|
|
|
*aResult = nsnull; // initialize OUT parameter
|
|
|
|
|
|
|
|
// Probe for the existence of the pseudo-element
|
2000-02-23 21:24:07 +00:00
|
|
|
nsCOMPtr<nsIStyleContext> pseudoStyleContext;
|
1999-03-30 15:22:54 +00:00
|
|
|
aPresContext->ProbePseudoStyleContextFor(aContent, aPseudoElement, aStyleContext,
|
2000-02-23 21:24:07 +00:00
|
|
|
PR_FALSE, getter_AddRefs(pseudoStyleContext));
|
1999-03-30 15:22:54 +00:00
|
|
|
|
|
|
|
if (pseudoStyleContext) {
|
|
|
|
const nsStyleDisplay* display;
|
|
|
|
|
|
|
|
// See whether the generated content should be displayed.
|
|
|
|
display = (const nsStyleDisplay*)pseudoStyleContext->GetStyleData(eStyleStruct_Display);
|
|
|
|
|
1999-10-02 04:27:40 +00:00
|
|
|
if (NS_STYLE_DISPLAY_NONE == display->mDisplay) {
|
|
|
|
aState.mFrameManager->SetUndisplayedPseudoIn(pseudoStyleContext, aContent);
|
|
|
|
}
|
|
|
|
else { // has valid display type
|
1999-04-05 02:53:07 +00:00
|
|
|
// See if there was any content specified
|
1999-04-10 04:21:33 +00:00
|
|
|
const nsStyleContent* styleContent =
|
|
|
|
(const nsStyleContent*)pseudoStyleContext->GetStyleData(eStyleStruct_Content);
|
1999-04-02 18:50:45 +00:00
|
|
|
PRUint32 contentCount = styleContent->ContentCount();
|
|
|
|
|
1999-04-05 02:53:07 +00:00
|
|
|
if (contentCount > 0) {
|
|
|
|
PRUint8 displayValue = display->mDisplay;
|
|
|
|
|
|
|
|
// Make sure the 'display' property value is allowable
|
|
|
|
const nsStyleDisplay* subjectDisplay = (const nsStyleDisplay*)
|
|
|
|
aStyleContext->GetStyleData(eStyleStruct_Display);
|
|
|
|
|
|
|
|
if (subjectDisplay->IsBlockLevel()) {
|
|
|
|
// For block-level elements the only allowed 'display' values are:
|
|
|
|
// 'none', 'inline', 'block', and 'marker'
|
|
|
|
if ((NS_STYLE_DISPLAY_INLINE != displayValue) &&
|
|
|
|
(NS_STYLE_DISPLAY_BLOCK != displayValue) &&
|
|
|
|
(NS_STYLE_DISPLAY_MARKER != displayValue)) {
|
|
|
|
// Pseudo-element behaves as if the value were 'block'
|
|
|
|
displayValue = NS_STYLE_DISPLAY_BLOCK;
|
|
|
|
}
|
|
|
|
|
|
|
|
} else {
|
|
|
|
// For inline-level elements the only allowed 'display' values are
|
|
|
|
// 'none' and 'inline'
|
|
|
|
displayValue = NS_STYLE_DISPLAY_INLINE;
|
1999-04-02 18:50:45 +00:00
|
|
|
}
|
1999-03-30 15:22:54 +00:00
|
|
|
|
1999-04-05 02:53:07 +00:00
|
|
|
if (display->mDisplay != displayValue) {
|
|
|
|
// Reset the value
|
|
|
|
nsStyleDisplay* mutableDisplay = (nsStyleDisplay*)
|
|
|
|
pseudoStyleContext->GetMutableStyleData(eStyleStruct_Display);
|
|
|
|
|
|
|
|
mutableDisplay->mDisplay = displayValue;
|
|
|
|
}
|
|
|
|
|
1999-04-10 04:21:33 +00:00
|
|
|
// Also make sure the 'position' property is 'static'. :before and :after
|
|
|
|
// pseudo-elements can not be floated or positioned
|
|
|
|
const nsStylePosition * stylePosition =
|
|
|
|
(const nsStylePosition*)pseudoStyleContext->GetStyleData(eStyleStruct_Position);
|
|
|
|
if (NS_STYLE_POSITION_NORMAL != stylePosition->mPosition) {
|
|
|
|
// Reset the value
|
|
|
|
nsStylePosition* mutablePosition = (nsStylePosition*)
|
|
|
|
pseudoStyleContext->GetMutableStyleData(eStyleStruct_Position);
|
|
|
|
|
|
|
|
mutablePosition->mPosition = NS_STYLE_POSITION_NORMAL;
|
|
|
|
}
|
|
|
|
|
1999-04-05 02:53:07 +00:00
|
|
|
// Create a block box or an inline box depending on the value of
|
|
|
|
// the 'display' property
|
|
|
|
nsIFrame* containerFrame;
|
|
|
|
nsFrameItems childFrames;
|
2000-02-10 04:35:51 +00:00
|
|
|
|
|
|
|
nsCOMPtr<nsIDOMElement>containerElement;
|
|
|
|
nsCOMPtr<nsIContent> containerContent;
|
|
|
|
nsCOMPtr<nsIDocument> document;
|
|
|
|
|
|
|
|
aContent->GetDocument(*getter_AddRefs(document));
|
|
|
|
|
|
|
|
nsCOMPtr<nsIDOMDocument> domdoc(do_QueryInterface(document));
|
|
|
|
nsresult result;
|
2000-04-16 11:19:26 +00:00
|
|
|
result = domdoc->CreateElement(NS_ConvertASCIItoUCS2("SPAN"),getter_AddRefs(containerElement));//is the literal the correct way?
|
2000-02-10 04:35:51 +00:00
|
|
|
if (NS_SUCCEEDED(result) && containerElement)
|
|
|
|
{
|
|
|
|
containerContent = do_QueryInterface(containerElement);
|
2000-02-10 05:20:55 +00:00
|
|
|
}//do NOT use YET set this up for later checkin. this will be the content of the new frame.
|
2000-02-10 04:35:51 +00:00
|
|
|
|
1999-04-05 02:53:07 +00:00
|
|
|
if (NS_STYLE_DISPLAY_BLOCK == displayValue) {
|
1999-12-04 23:49:50 +00:00
|
|
|
NS_NewBlockFrame(aPresShell, &containerFrame);
|
1999-04-05 02:53:07 +00:00
|
|
|
} else {
|
1999-12-04 23:49:50 +00:00
|
|
|
NS_NewInlineFrame(aPresShell, &containerFrame);
|
1999-12-06 07:44:18 +00:00
|
|
|
}
|
2000-02-10 05:20:55 +00:00
|
|
|
InitAndRestoreFrame(aPresContext, aState, aContent,
|
1999-12-06 07:44:18 +00:00
|
|
|
aFrame, pseudoStyleContext, nsnull, containerFrame);
|
1999-04-05 02:53:07 +00:00
|
|
|
|
1999-04-06 04:58:05 +00:00
|
|
|
// Mark the frame as being associated with generated content
|
|
|
|
nsFrameState frameState;
|
|
|
|
containerFrame->GetFrameState(&frameState);
|
|
|
|
frameState |= NS_FRAME_GENERATED_CONTENT;
|
|
|
|
containerFrame->SetFrameState(frameState);
|
|
|
|
|
1999-04-05 02:53:07 +00:00
|
|
|
// Create another pseudo style context to use for all the generated child
|
|
|
|
// frames
|
|
|
|
nsIStyleContext* textStyleContext;
|
|
|
|
aPresContext->ResolvePseudoStyleContextFor(aContent, nsHTMLAtoms::textPseudo,
|
|
|
|
pseudoStyleContext, PR_FALSE,
|
|
|
|
&textStyleContext);
|
|
|
|
|
|
|
|
// Now create content objects (and child frames) for each value of the
|
|
|
|
// 'content' property
|
1999-09-07 03:09:33 +00:00
|
|
|
|
1999-04-05 02:53:07 +00:00
|
|
|
for (PRUint32 contentIndex = 0; contentIndex < contentCount; contentIndex++) {
|
|
|
|
nsIFrame* frame;
|
|
|
|
|
|
|
|
// Create a frame
|
1999-09-07 03:09:33 +00:00
|
|
|
result = CreateGeneratedFrameFor(aPresContext, document, containerFrame,
|
1999-07-05 18:46:09 +00:00
|
|
|
aContent, textStyleContext,
|
|
|
|
styleContent, contentIndex, &frame);
|
1999-04-05 02:53:07 +00:00
|
|
|
if (NS_SUCCEEDED(result) && frame) {
|
|
|
|
// Add it to the list of child frames
|
|
|
|
childFrames.AddChild(frame);
|
|
|
|
}
|
|
|
|
}
|
1999-03-30 15:22:54 +00:00
|
|
|
|
1999-04-05 02:53:07 +00:00
|
|
|
NS_RELEASE(textStyleContext);
|
|
|
|
if (childFrames.childList) {
|
1999-11-24 06:03:41 +00:00
|
|
|
containerFrame->SetInitialChildList(aPresContext, nsnull, childFrames.childList);
|
1999-04-05 02:53:07 +00:00
|
|
|
}
|
|
|
|
*aResult = containerFrame;
|
1999-04-02 18:50:45 +00:00
|
|
|
return PR_TRUE;
|
|
|
|
}
|
1999-03-30 15:22:54 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return PR_FALSE;
|
|
|
|
}
|
1999-02-05 03:55:18 +00:00
|
|
|
|
1999-09-16 19:55:08 +00:00
|
|
|
#if 0
|
1999-08-27 21:46:10 +00:00
|
|
|
static PRBool
|
|
|
|
IsEmptyTextContent(nsIContent* aContent)
|
1999-02-05 03:55:18 +00:00
|
|
|
{
|
1999-08-27 21:46:10 +00:00
|
|
|
PRBool result = PR_FALSE;
|
|
|
|
nsCOMPtr<nsITextContent> tc(do_QueryInterface(aContent));
|
|
|
|
if (tc) {
|
|
|
|
tc->IsOnlyWhitespace(&result);
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
1999-03-30 15:22:54 +00:00
|
|
|
|
1999-08-27 21:46:10 +00:00
|
|
|
#include "nsIDOMHTMLParagraphElement.h"
|
1999-03-30 15:22:54 +00:00
|
|
|
|
1999-08-27 21:46:10 +00:00
|
|
|
static PRBool
|
|
|
|
IsHTMLParagraph(nsIContent* aContent)
|
|
|
|
{
|
|
|
|
nsCOMPtr<nsIDOMHTMLParagraphElement> p(do_QueryInterface(aContent));
|
|
|
|
PRBool status = PR_FALSE;
|
|
|
|
if (p) {
|
|
|
|
status = PR_TRUE;
|
1999-03-30 15:22:54 +00:00
|
|
|
}
|
1999-08-27 21:46:10 +00:00
|
|
|
return status;
|
|
|
|
}
|
1999-03-30 15:22:54 +00:00
|
|
|
|
1999-08-27 21:46:10 +00:00
|
|
|
static PRBool
|
1999-08-31 03:09:40 +00:00
|
|
|
IsEmptyContainer(nsIContent* aContainer)
|
1999-08-27 21:46:10 +00:00
|
|
|
{
|
|
|
|
// Check each kid and if each kid is empty text content (or there
|
|
|
|
// are no kids) then return true.
|
|
|
|
PRInt32 i, numKids;
|
|
|
|
aContainer->ChildCount(numKids);
|
|
|
|
for (i = 0; i < numKids; i++) {
|
|
|
|
nsCOMPtr<nsIContent> kid;
|
|
|
|
aContainer->ChildAt(i, *getter_AddRefs(kid));
|
|
|
|
if (kid.get()) {
|
|
|
|
if (!IsEmptyTextContent(kid)) {
|
|
|
|
return PR_FALSE;
|
|
|
|
}
|
1999-02-05 03:55:18 +00:00
|
|
|
}
|
|
|
|
}
|
1999-08-27 21:46:10 +00:00
|
|
|
return PR_TRUE;
|
|
|
|
}
|
1999-02-05 03:55:18 +00:00
|
|
|
|
1999-08-27 21:46:10 +00:00
|
|
|
static PRBool
|
|
|
|
IsEmptyHTMLParagraph(nsIContent* aContent)
|
|
|
|
{
|
|
|
|
if (!IsHTMLParagraph(aContent)) {
|
|
|
|
// It's not an HTML paragraph so return false
|
|
|
|
return PR_FALSE;
|
1999-03-30 15:22:54 +00:00
|
|
|
}
|
1999-08-31 03:09:40 +00:00
|
|
|
return IsEmptyContainer(aContent);
|
1999-02-05 03:55:18 +00:00
|
|
|
}
|
1999-08-31 03:09:40 +00:00
|
|
|
#endif
|
1999-02-05 03:55:18 +00:00
|
|
|
|
|
|
|
nsresult
|
1999-12-04 23:49:50 +00:00
|
|
|
nsCSSFrameConstructor::CreateInputFrame(nsIPresShell *aPresShell,
|
|
|
|
nsIPresContext *aPresContext,
|
1999-08-03 14:41:48 +00:00
|
|
|
nsIContent *aContent,
|
|
|
|
nsIFrame *&aFrame,
|
2000-02-23 21:36:29 +00:00
|
|
|
nsIStyleContext *aStyleContext)
|
1999-02-05 03:55:18 +00:00
|
|
|
{
|
|
|
|
nsresult rv;
|
|
|
|
|
|
|
|
// Figure out which type of input frame to create
|
|
|
|
nsAutoString val;
|
|
|
|
if (NS_OK == aContent->GetAttribute(kNameSpaceID_HTML, nsHTMLAtoms::type, val)) {
|
|
|
|
if (val.EqualsIgnoreCase("submit")) {
|
1999-12-04 23:49:50 +00:00
|
|
|
rv = ConstructButtonControlFrame(aPresShell, aPresContext, aFrame);
|
1999-02-05 03:55:18 +00:00
|
|
|
}
|
|
|
|
else if (val.EqualsIgnoreCase("reset")) {
|
1999-12-04 23:49:50 +00:00
|
|
|
rv = ConstructButtonControlFrame(aPresShell, aPresContext, aFrame);
|
1999-02-05 03:55:18 +00:00
|
|
|
}
|
|
|
|
else if (val.EqualsIgnoreCase("button")) {
|
1999-12-04 23:49:50 +00:00
|
|
|
rv = ConstructButtonControlFrame(aPresShell, aPresContext, aFrame);
|
1999-02-05 03:55:18 +00:00
|
|
|
}
|
|
|
|
else if (val.EqualsIgnoreCase("checkbox")) {
|
2000-03-24 15:48:59 +00:00
|
|
|
rv = ConstructCheckboxControlFrame(aPresShell, aPresContext, aFrame, aContent, aStyleContext);
|
1999-02-05 03:55:18 +00:00
|
|
|
}
|
|
|
|
else if (val.EqualsIgnoreCase("file")) {
|
1999-12-04 23:49:50 +00:00
|
|
|
rv = NS_NewFileControlFrame(aPresShell, &aFrame);
|
1999-02-05 03:55:18 +00:00
|
|
|
}
|
|
|
|
else if (val.EqualsIgnoreCase("hidden")) {
|
1999-12-04 23:49:50 +00:00
|
|
|
rv = ConstructButtonControlFrame(aPresShell, aPresContext, aFrame);
|
1999-02-05 03:55:18 +00:00
|
|
|
}
|
|
|
|
else if (val.EqualsIgnoreCase("image")) {
|
1999-12-04 23:49:50 +00:00
|
|
|
rv = NS_NewImageControlFrame(aPresShell, &aFrame);
|
1999-02-05 03:55:18 +00:00
|
|
|
}
|
|
|
|
else if (val.EqualsIgnoreCase("password")) {
|
1999-12-04 23:49:50 +00:00
|
|
|
rv = ConstructTextControlFrame(aPresShell, aPresContext, aFrame, aContent);
|
1999-02-05 03:55:18 +00:00
|
|
|
}
|
|
|
|
else if (val.EqualsIgnoreCase("radio")) {
|
1999-12-04 23:49:50 +00:00
|
|
|
rv = ConstructRadioControlFrame(aPresShell, aPresContext, aFrame, aContent, aStyleContext);
|
1999-02-05 03:55:18 +00:00
|
|
|
}
|
|
|
|
else if (val.EqualsIgnoreCase("text")) {
|
1999-12-04 23:49:50 +00:00
|
|
|
rv = ConstructTextControlFrame(aPresShell, aPresContext, aFrame, aContent);
|
1999-02-05 03:55:18 +00:00
|
|
|
}
|
|
|
|
else {
|
1999-12-04 23:49:50 +00:00
|
|
|
rv = ConstructTextControlFrame(aPresShell, aPresContext, aFrame, aContent);
|
1999-02-05 03:55:18 +00:00
|
|
|
}
|
|
|
|
} else {
|
1999-12-04 23:49:50 +00:00
|
|
|
rv = ConstructTextControlFrame(aPresShell, aPresContext, aFrame, aContent);
|
1999-02-05 03:55:18 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
2000-04-04 01:28:15 +00:00
|
|
|
PRBool IsOnlyWhiteSpace(nsIContent* aContent)
|
|
|
|
{
|
|
|
|
PRBool onlyWhiteSpace = PR_FALSE;
|
|
|
|
nsCOMPtr<nsITextContent> textContent = do_QueryInterface(aContent);
|
|
|
|
if (textContent) {
|
|
|
|
textContent->IsOnlyWhitespace(&onlyWhiteSpace);
|
|
|
|
}
|
|
|
|
return onlyWhiteSpace;
|
|
|
|
}
|
|
|
|
|
1999-02-05 03:55:18 +00:00
|
|
|
/****************************************************
|
|
|
|
** BEGIN TABLE SECTION
|
|
|
|
****************************************************/
|
|
|
|
|
2000-04-04 01:28:15 +00:00
|
|
|
// The term pseudo frame is being used instead of anonymous frame, since anonymous
|
|
|
|
// frame has been used elsewhere to refer to frames that have generated content
|
1999-02-05 03:55:18 +00:00
|
|
|
|
2000-04-04 01:28:15 +00:00
|
|
|
PRBool
|
|
|
|
IsTableRelated(PRUint8 aDisplay)
|
1999-02-05 03:55:18 +00:00
|
|
|
{
|
2000-04-04 01:28:15 +00:00
|
|
|
return (aDisplay == NS_STYLE_DISPLAY_TABLE) ||
|
|
|
|
(aDisplay == NS_STYLE_DISPLAY_TABLE_HEADER_GROUP) ||
|
|
|
|
(aDisplay == NS_STYLE_DISPLAY_TABLE_ROW_GROUP) ||
|
|
|
|
(aDisplay == NS_STYLE_DISPLAY_TABLE_FOOTER_GROUP) ||
|
|
|
|
(aDisplay == NS_STYLE_DISPLAY_TABLE_ROW) ||
|
|
|
|
(aDisplay == NS_STYLE_DISPLAY_TABLE_COLUMN) ||
|
|
|
|
(aDisplay == NS_STYLE_DISPLAY_TABLE_CELL);
|
|
|
|
}
|
1999-02-05 03:55:18 +00:00
|
|
|
|
2000-04-04 01:28:15 +00:00
|
|
|
PRBool
|
|
|
|
IsTableRelated(nsIAtom* aParentType)
|
|
|
|
{
|
|
|
|
return (nsLayoutAtoms::tableFrame == aParentType) ||
|
|
|
|
(nsLayoutAtoms::tableCaptionFrame == aParentType) ||
|
|
|
|
(nsLayoutAtoms::tableRowGroupFrame == aParentType) ||
|
|
|
|
(nsLayoutAtoms::tableColGroupFrame == aParentType) ||
|
|
|
|
(nsLayoutAtoms::tableColFrame == aParentType) ||
|
|
|
|
(nsLayoutAtoms::tableRowFrame == aParentType) ||
|
|
|
|
(nsLayoutAtoms::tableCellFrame == aParentType);
|
|
|
|
}
|
|
|
|
|
|
|
|
PRBool
|
|
|
|
IsParentOf(nsIAtom* aParentFrameType,
|
|
|
|
PRUint8 aChildDisplay)
|
|
|
|
{
|
|
|
|
switch (aChildDisplay) {
|
|
|
|
case NS_STYLE_DISPLAY_TABLE:
|
|
|
|
return (!IsTableRelated(aParentFrameType));
|
|
|
|
case NS_STYLE_DISPLAY_TABLE_CAPTION:
|
|
|
|
case NS_STYLE_DISPLAY_TABLE_HEADER_GROUP:
|
|
|
|
case NS_STYLE_DISPLAY_TABLE_ROW_GROUP:
|
|
|
|
case NS_STYLE_DISPLAY_TABLE_FOOTER_GROUP:
|
|
|
|
case NS_STYLE_DISPLAY_TABLE_COLUMN_GROUP:
|
|
|
|
return (nsLayoutAtoms::tableFrame == aParentFrameType);
|
|
|
|
case NS_STYLE_DISPLAY_TABLE_ROW:
|
|
|
|
return (nsLayoutAtoms::tableRowGroupFrame == aParentFrameType);
|
|
|
|
case NS_STYLE_DISPLAY_TABLE_COLUMN:
|
|
|
|
return (nsLayoutAtoms::tableColGroupFrame == aParentFrameType);
|
|
|
|
case NS_STYLE_DISPLAY_TABLE_CELL:
|
|
|
|
return (nsLayoutAtoms::tableRowFrame == aParentFrameType);
|
|
|
|
default:
|
|
|
|
return (!IsTableRelated(aParentFrameType));
|
|
|
|
}
|
|
|
|
}
|
1999-02-05 03:55:18 +00:00
|
|
|
|
2000-04-04 01:28:15 +00:00
|
|
|
nsIFrame*
|
|
|
|
GetOuterTableFrame(nsIFrame* aParentFrame)
|
|
|
|
{
|
|
|
|
nsIFrame* parent;
|
|
|
|
nsCOMPtr<nsIAtom> frameType;
|
|
|
|
aParentFrame->GetFrameType(getter_AddRefs(frameType));
|
|
|
|
if (nsLayoutAtoms::tableOuterFrame == frameType.get()) {
|
|
|
|
parent = aParentFrame;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
aParentFrame->GetParent(&parent);
|
|
|
|
}
|
|
|
|
return parent;
|
|
|
|
}
|
1999-02-11 15:54:13 +00:00
|
|
|
|
2000-04-04 01:28:15 +00:00
|
|
|
void
|
|
|
|
GetNonScrollFrame(nsIFrame& aFrameIn,
|
|
|
|
nsIFrame*& aNonScrollFrame,
|
|
|
|
nsIAtom*& aNonScrollFrameType)
|
|
|
|
{
|
|
|
|
nsIAtom* frameType;
|
|
|
|
aFrameIn.GetFrameType(&frameType);
|
1999-02-05 03:55:18 +00:00
|
|
|
|
2000-04-04 01:28:15 +00:00
|
|
|
if (nsLayoutAtoms::scrollFrame == frameType) {
|
|
|
|
// get the scrolled frame if there is a scroll frame
|
|
|
|
nsIScrollableFrame* scrollable = nsnull;
|
|
|
|
nsresult rv = aFrameIn.QueryInterface(kIScrollableFrameIID, (void **)&scrollable);
|
|
|
|
if (NS_SUCCEEDED(rv) && (scrollable)) {
|
|
|
|
scrollable->GetScrolledFrame(nsnull, aNonScrollFrame);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
aNonScrollFrame = &aFrameIn;
|
|
|
|
}
|
|
|
|
aNonScrollFrameType = nsnull;
|
|
|
|
if (aNonScrollFrame) {
|
|
|
|
aNonScrollFrame->GetFrameType(&aNonScrollFrameType);
|
|
|
|
}
|
|
|
|
}
|
1999-02-05 03:55:18 +00:00
|
|
|
|
2000-04-04 01:28:15 +00:00
|
|
|
nsresult
|
|
|
|
ProcessPseudoFrame(nsIPresContext* aPresContext,
|
|
|
|
nsPseudoFrameData& aPseudoData,
|
|
|
|
nsIFrame*& aParent)
|
|
|
|
{
|
|
|
|
nsresult rv = NS_OK;
|
|
|
|
if (!aPresContext) return rv;
|
1999-02-05 03:55:18 +00:00
|
|
|
|
2000-04-04 01:28:15 +00:00
|
|
|
aParent = aPseudoData.mFrame;
|
|
|
|
nsFrameItems* items = &aPseudoData.mChildList;
|
|
|
|
if (items && items->childList) {
|
|
|
|
rv = aParent->SetInitialChildList(aPresContext, nsnull, items->childList);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
}
|
|
|
|
aPseudoData.Reset();
|
|
|
|
return rv;
|
|
|
|
}
|
1999-02-05 03:55:18 +00:00
|
|
|
|
2000-04-04 01:28:15 +00:00
|
|
|
nsresult
|
|
|
|
ProcessPseudoTableFrame(nsIPresContext* aPresContext,
|
|
|
|
nsPseudoFrames& aPseudoFrames,
|
|
|
|
nsIFrame*& aParent)
|
|
|
|
{
|
|
|
|
nsresult rv = NS_OK;
|
|
|
|
if (!aPresContext) return rv;
|
1999-02-05 03:55:18 +00:00
|
|
|
|
2000-04-04 01:28:15 +00:00
|
|
|
// process the col group frame, if it exists
|
|
|
|
if (aPseudoFrames.mColGroup.mFrame) {
|
|
|
|
rv = ProcessPseudoFrame(aPresContext, aPseudoFrames.mColGroup, aParent);
|
1999-02-05 03:55:18 +00:00
|
|
|
}
|
|
|
|
|
2000-04-04 01:28:15 +00:00
|
|
|
// process the inner table frame
|
|
|
|
rv = ProcessPseudoFrame(aPresContext, aPseudoFrames.mTableInner, aParent);
|
1999-02-05 03:55:18 +00:00
|
|
|
|
2000-04-04 01:28:15 +00:00
|
|
|
// process the outer table frame
|
|
|
|
aParent = aPseudoFrames.mTableOuter.mFrame;
|
|
|
|
nsFrameItems* items = &aPseudoFrames.mTableOuter.mChildList;
|
|
|
|
if (items && items->childList) {
|
|
|
|
rv = aParent->SetInitialChildList(aPresContext, nsnull, items->childList);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
2000-01-28 02:19:45 +00:00
|
|
|
}
|
2000-04-04 01:28:15 +00:00
|
|
|
nsFrameItems* captions = &aPseudoFrames.mTableOuter.mChildList2;
|
|
|
|
if (captions && captions->childList) {
|
|
|
|
rv = aParent->SetInitialChildList(aPresContext, nsLayoutAtoms::captionList, captions->childList);
|
|
|
|
}
|
|
|
|
aPseudoFrames.mTableOuter.Reset();
|
1999-02-05 03:55:18 +00:00
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
2000-04-04 01:28:15 +00:00
|
|
|
nsresult
|
|
|
|
ProcessPseudoCellFrame(nsIPresContext* aPresContext,
|
|
|
|
nsPseudoFrames& aPseudoFrames,
|
|
|
|
nsIFrame*& aParent)
|
1999-02-05 03:55:18 +00:00
|
|
|
{
|
1999-02-26 09:15:03 +00:00
|
|
|
nsresult rv = NS_OK;
|
2000-04-04 01:28:15 +00:00
|
|
|
if (!aPresContext) return rv;
|
1999-02-26 09:15:03 +00:00
|
|
|
|
2000-04-04 01:28:15 +00:00
|
|
|
rv = ProcessPseudoFrame(aPresContext, aPseudoFrames.mCellInner, aParent);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
rv = ProcessPseudoFrame(aPresContext, aPseudoFrames.mCellOuter, aParent);
|
|
|
|
return rv;
|
|
|
|
}
|
1999-02-26 09:15:03 +00:00
|
|
|
|
2000-04-04 01:28:15 +00:00
|
|
|
|
|
|
|
nsresult
|
|
|
|
ProcessPseudoFrames(nsIPresContext* aPresContext,
|
|
|
|
nsPseudoFrames& aPseudoFrames,
|
|
|
|
nsIAtom* aHighestType,
|
|
|
|
nsIFrame*& aHighestFrame)
|
|
|
|
{
|
|
|
|
nsresult rv = NS_OK;
|
|
|
|
if (!aPresContext) return rv;
|
|
|
|
|
|
|
|
aHighestFrame = nsnull;
|
|
|
|
|
|
|
|
if (nsLayoutAtoms::tableFrame == aPseudoFrames.mLowestType) {
|
|
|
|
rv = ProcessPseudoTableFrame(aPresContext, aPseudoFrames, aHighestFrame);
|
|
|
|
if (nsLayoutAtoms::tableOuterFrame == aHighestType) return rv;
|
|
|
|
|
|
|
|
if (aPseudoFrames.mCellOuter.mFrame) {
|
|
|
|
rv = ProcessPseudoCellFrame(aPresContext, aPseudoFrames, aHighestFrame);
|
|
|
|
if (nsLayoutAtoms::tableCellFrame == aHighestType) return rv;
|
1999-02-05 03:55:18 +00:00
|
|
|
}
|
2000-04-04 01:28:15 +00:00
|
|
|
if (aPseudoFrames.mRow.mFrame) {
|
|
|
|
rv = ProcessPseudoFrame(aPresContext, aPseudoFrames.mRow, aHighestFrame);
|
|
|
|
if (nsLayoutAtoms::tableRowFrame == aHighestType) return rv;
|
|
|
|
}
|
|
|
|
if (aPseudoFrames.mRowGroup.mFrame) {
|
|
|
|
rv = ProcessPseudoFrame(aPresContext, aPseudoFrames.mRowGroup, aHighestFrame);
|
|
|
|
if (nsLayoutAtoms::tableRowGroupFrame == aHighestType) return rv;
|
1999-02-26 09:15:03 +00:00
|
|
|
}
|
1999-02-05 03:55:18 +00:00
|
|
|
}
|
2000-04-04 01:28:15 +00:00
|
|
|
else if (nsLayoutAtoms::tableRowGroupFrame == aPseudoFrames.mLowestType) {
|
|
|
|
rv = ProcessPseudoFrame(aPresContext, aPseudoFrames.mRowGroup, aHighestFrame);
|
|
|
|
if (nsLayoutAtoms::tableRowGroupFrame == aHighestType) return rv;
|
1999-02-05 03:55:18 +00:00
|
|
|
|
2000-04-04 01:28:15 +00:00
|
|
|
if (aPseudoFrames.mTableOuter.mFrame) {
|
|
|
|
rv = ProcessPseudoTableFrame(aPresContext, aPseudoFrames, aHighestFrame);
|
|
|
|
if (nsLayoutAtoms::tableOuterFrame == aHighestType) return rv;
|
|
|
|
}
|
|
|
|
if (aPseudoFrames.mCellOuter.mFrame) {
|
|
|
|
rv = ProcessPseudoCellFrame(aPresContext, aPseudoFrames, aHighestFrame);
|
|
|
|
if (nsLayoutAtoms::tableCellFrame == aHighestType) return rv;
|
|
|
|
}
|
|
|
|
if (aPseudoFrames.mRow.mFrame) {
|
|
|
|
rv = ProcessPseudoFrame(aPresContext, aPseudoFrames.mRow, aHighestFrame);
|
|
|
|
if (nsLayoutAtoms::tableRowFrame == aHighestType) return rv;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (nsLayoutAtoms::tableRowFrame == aPseudoFrames.mLowestType) {
|
|
|
|
rv = ProcessPseudoFrame(aPresContext, aPseudoFrames.mRow, aHighestFrame);
|
|
|
|
if (nsLayoutAtoms::tableRowFrame == aHighestType) return rv;
|
1999-12-06 07:44:18 +00:00
|
|
|
|
2000-04-04 01:28:15 +00:00
|
|
|
if (aPseudoFrames.mRowGroup.mFrame) {
|
|
|
|
rv = ProcessPseudoFrame(aPresContext, aPseudoFrames.mRowGroup, aHighestFrame);
|
|
|
|
if (nsLayoutAtoms::tableRowGroupFrame == aHighestType) return rv;
|
|
|
|
}
|
|
|
|
if (aPseudoFrames.mTableOuter.mFrame) {
|
|
|
|
rv = ProcessPseudoTableFrame(aPresContext, aPseudoFrames, aHighestFrame);
|
|
|
|
if (nsLayoutAtoms::tableOuterFrame == aHighestType) return rv;
|
|
|
|
}
|
|
|
|
if (aPseudoFrames.mCellOuter.mFrame) {
|
|
|
|
rv = ProcessPseudoCellFrame(aPresContext, aPseudoFrames, aHighestFrame);
|
|
|
|
if (nsLayoutAtoms::tableCellFrame == aHighestType) return rv;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (nsLayoutAtoms::tableCellFrame == aPseudoFrames.mLowestType) {
|
|
|
|
rv = ProcessPseudoCellFrame(aPresContext, aPseudoFrames, aHighestFrame);
|
|
|
|
if (nsLayoutAtoms::tableCellFrame == aHighestType) return rv;
|
1999-02-26 09:15:03 +00:00
|
|
|
|
2000-04-04 01:28:15 +00:00
|
|
|
if (aPseudoFrames.mRow.mFrame) {
|
|
|
|
rv = ProcessPseudoFrame(aPresContext, aPseudoFrames.mRow, aHighestFrame);
|
|
|
|
if (nsLayoutAtoms::tableRowFrame == aHighestType) return rv;
|
|
|
|
}
|
|
|
|
if (aPseudoFrames.mRowGroup.mFrame) {
|
|
|
|
rv = ProcessPseudoFrame(aPresContext, aPseudoFrames.mRowGroup, aHighestFrame);
|
|
|
|
if (nsLayoutAtoms::tableRowGroupFrame == aHighestType) return rv;
|
1999-02-26 09:15:03 +00:00
|
|
|
}
|
2000-04-04 01:28:15 +00:00
|
|
|
if (aPseudoFrames.mTableOuter.mFrame) {
|
|
|
|
rv = ProcessPseudoTableFrame(aPresContext, aPseudoFrames, aHighestFrame);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (aPseudoFrames.mColGroup.mFrame) {
|
|
|
|
// process the col group frame
|
|
|
|
rv = ProcessPseudoFrame(aPresContext, aPseudoFrames.mColGroup, aHighestFrame);
|
1999-02-26 09:15:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return rv;
|
1999-02-05 03:55:18 +00:00
|
|
|
}
|
|
|
|
|
2000-04-04 01:28:15 +00:00
|
|
|
nsresult
|
|
|
|
ProcessPseudoFrames(nsIPresContext* aPresContext,
|
|
|
|
nsPseudoFrames& aPseudoFrames,
|
|
|
|
nsFrameItems& aItems)
|
1999-02-05 03:55:18 +00:00
|
|
|
{
|
2000-04-04 01:28:15 +00:00
|
|
|
nsIFrame* highestFrame;
|
|
|
|
nsresult rv = ProcessPseudoFrames(aPresContext, aPseudoFrames, nsnull, highestFrame);
|
|
|
|
if (highestFrame) {
|
|
|
|
aItems.AddChild(highestFrame);
|
1999-02-05 03:55:18 +00:00
|
|
|
}
|
2000-04-04 01:28:15 +00:00
|
|
|
aPseudoFrames.Reset();
|
|
|
|
return rv;
|
|
|
|
}
|
1999-02-26 17:11:54 +00:00
|
|
|
|
2000-04-04 01:28:15 +00:00
|
|
|
nsresult
|
|
|
|
ProcessPseudoFrames(nsIPresContext* aPresContext,
|
|
|
|
nsPseudoFrames& aPseudoFrames,
|
|
|
|
nsIAtom* aHighestType)
|
|
|
|
{
|
|
|
|
nsIFrame* highestFrame;
|
|
|
|
nsresult rv = ProcessPseudoFrames(aPresContext, aPseudoFrames, aHighestType, highestFrame);
|
1999-02-05 03:55:18 +00:00
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
2000-04-04 01:28:15 +00:00
|
|
|
nsCSSFrameConstructor::CreatePseudoTableFrame(nsIPresShell* aPresShell,
|
|
|
|
nsIPresContext* aPresContext,
|
|
|
|
nsTableCreator& aTableCreator,
|
|
|
|
nsFrameConstructorState& aState,
|
|
|
|
nsIFrame* aParentFrameIn)
|
1999-02-05 03:55:18 +00:00
|
|
|
{
|
|
|
|
nsresult rv = NS_OK;
|
1999-02-26 09:15:03 +00:00
|
|
|
|
2000-04-04 01:28:15 +00:00
|
|
|
nsIFrame* parentFrame = (aState.mPseudoFrames.mCellInner.mFrame)
|
|
|
|
? aState.mPseudoFrames.mCellInner.mFrame : aParentFrameIn;
|
|
|
|
if (!parentFrame) return rv;
|
1999-02-05 03:55:18 +00:00
|
|
|
|
2000-04-04 01:28:15 +00:00
|
|
|
nsCOMPtr<nsIStyleContext> parentStyle;
|
|
|
|
nsCOMPtr<nsIContent> parentContent;
|
|
|
|
nsCOMPtr<nsIStyleContext> childStyle;
|
|
|
|
|
|
|
|
parentFrame->GetStyleContext(getter_AddRefs(parentStyle));
|
|
|
|
parentFrame->GetContent(getter_AddRefs(parentContent));
|
|
|
|
|
2000-04-28 21:05:31 +00:00
|
|
|
// create the SC for the inner table which will be the parent of the outer table's SC
|
|
|
|
aPresContext->ResolvePseudoStyleContextFor(parentContent, nsHTMLAtoms::tablePseudo,
|
2000-04-04 01:28:15 +00:00
|
|
|
parentStyle, PR_FALSE,
|
|
|
|
getter_AddRefs(childStyle));
|
|
|
|
|
|
|
|
nsPseudoFrameData& pseudoOuter = aState.mPseudoFrames.mTableOuter;
|
|
|
|
nsPseudoFrameData& pseudoInner = aState.mPseudoFrames.mTableInner;
|
|
|
|
|
|
|
|
// construct the pseudo outer and inner as part of the pseudo frames
|
|
|
|
PRBool pseudoParent;
|
|
|
|
nsFrameItems items;
|
|
|
|
rv = ConstructTableFrame(aPresShell, aPresContext, aState, parentContent,
|
|
|
|
parentFrame, childStyle.get(), aTableCreator,
|
|
|
|
PR_TRUE, items, pseudoOuter.mFrame,
|
|
|
|
pseudoInner.mFrame, pseudoParent);
|
|
|
|
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
// set pseudo data for the newly created frames
|
|
|
|
pseudoOuter.mChildList.AddChild(pseudoInner.mFrame);
|
|
|
|
aState.mPseudoFrames.mLowestType = nsLayoutAtoms::tableFrame;
|
|
|
|
|
|
|
|
// set pseudo data for the parent
|
|
|
|
if (aState.mPseudoFrames.mCellInner.mFrame) {
|
|
|
|
aState.mPseudoFrames.mCellInner.mChildList.AddChild(pseudoOuter.mFrame);
|
1999-02-05 03:55:18 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
2000-04-04 01:28:15 +00:00
|
|
|
nsCSSFrameConstructor::CreatePseudoRowGroupFrame(nsIPresShell* aPresShell,
|
|
|
|
nsIPresContext* aPresContext,
|
|
|
|
nsTableCreator& aTableCreator,
|
|
|
|
nsFrameConstructorState& aState,
|
|
|
|
nsIFrame* aParentFrameIn)
|
1999-02-05 03:55:18 +00:00
|
|
|
{
|
|
|
|
nsresult rv = NS_OK;
|
|
|
|
|
2000-04-04 01:28:15 +00:00
|
|
|
nsIFrame* parentFrame = (aState.mPseudoFrames.mTableInner.mFrame)
|
|
|
|
? aState.mPseudoFrames.mTableInner.mFrame : aParentFrameIn;
|
|
|
|
if (!parentFrame) return rv;
|
1999-10-12 00:16:06 +00:00
|
|
|
|
2000-04-04 01:28:15 +00:00
|
|
|
nsCOMPtr<nsIStyleContext> parentStyle;
|
|
|
|
nsCOMPtr<nsIContent> parentContent;
|
|
|
|
nsCOMPtr<nsIStyleContext> childStyle;
|
1999-02-05 03:55:18 +00:00
|
|
|
|
2000-04-04 01:28:15 +00:00
|
|
|
parentFrame->GetStyleContext(getter_AddRefs(parentStyle));
|
|
|
|
parentFrame->GetContent(getter_AddRefs(parentContent));
|
1999-08-19 22:16:23 +00:00
|
|
|
|
2000-04-04 01:28:15 +00:00
|
|
|
aPresContext->ResolvePseudoStyleContextFor(parentContent, nsHTMLAtoms::tableRowGroupPseudo,
|
|
|
|
parentStyle, PR_FALSE,
|
|
|
|
getter_AddRefs(childStyle));
|
1999-08-19 22:16:23 +00:00
|
|
|
|
2000-04-04 01:28:15 +00:00
|
|
|
nsPseudoFrameData& pseudo = aState.mPseudoFrames.mRowGroup;
|
1999-02-05 03:55:18 +00:00
|
|
|
|
2000-04-04 01:28:15 +00:00
|
|
|
// construct the pseudo row group as part of the pseudo frames
|
|
|
|
PRBool pseudoParent;
|
|
|
|
nsFrameItems items;
|
|
|
|
rv = ConstructTableRowGroupFrame(aPresShell, aPresContext, aState, parentContent,
|
|
|
|
parentFrame, childStyle.get(), aTableCreator,
|
|
|
|
PR_TRUE, items, pseudo.mFrame, pseudoParent);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
1999-08-27 06:06:39 +00:00
|
|
|
|
2000-04-04 01:28:15 +00:00
|
|
|
// set pseudo data for the newly created frames
|
|
|
|
aState.mPseudoFrames.mLowestType = nsLayoutAtoms::tableRowGroupFrame;
|
|
|
|
|
|
|
|
// set pseudo data for the parent
|
|
|
|
if (aState.mPseudoFrames.mTableInner.mFrame) {
|
|
|
|
aState.mPseudoFrames.mTableInner.mChildList.AddChild(pseudo.mFrame);
|
|
|
|
}
|
1999-06-23 03:02:21 +00:00
|
|
|
|
1999-02-05 03:55:18 +00:00
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
2000-04-04 01:28:15 +00:00
|
|
|
nsresult
|
|
|
|
nsCSSFrameConstructor::CreatePseudoColGroupFrame(nsIPresShell* aPresShell,
|
|
|
|
nsIPresContext* aPresContext,
|
|
|
|
nsTableCreator& aTableCreator,
|
|
|
|
nsFrameConstructorState& aState,
|
|
|
|
nsIFrame* aParentFrameIn)
|
1999-02-05 03:55:18 +00:00
|
|
|
{
|
|
|
|
nsresult rv = NS_OK;
|
1999-02-26 09:15:03 +00:00
|
|
|
|
2000-04-04 01:28:15 +00:00
|
|
|
nsIFrame* parentFrame = (aState.mPseudoFrames.mTableInner.mFrame)
|
|
|
|
? aState.mPseudoFrames.mTableInner.mFrame : aParentFrameIn;
|
|
|
|
if (!parentFrame) return rv;
|
|
|
|
|
|
|
|
nsCOMPtr<nsIStyleContext> parentStyle;
|
|
|
|
nsCOMPtr<nsIContent> parentContent;
|
|
|
|
nsCOMPtr<nsIStyleContext> childStyle;
|
|
|
|
|
|
|
|
parentFrame->GetStyleContext(getter_AddRefs(parentStyle));
|
|
|
|
parentFrame->GetContent(getter_AddRefs(parentContent));
|
|
|
|
|
|
|
|
aPresContext->ResolvePseudoStyleContextFor(parentContent, nsHTMLAtoms::tableColGroupPseudo,
|
|
|
|
parentStyle, PR_FALSE,
|
|
|
|
getter_AddRefs(childStyle));
|
|
|
|
|
|
|
|
nsPseudoFrameData& pseudo = aState.mPseudoFrames.mColGroup;
|
|
|
|
|
|
|
|
// construct the pseudo col group as part of the pseudo frames
|
|
|
|
PRBool pseudoParent;
|
|
|
|
nsFrameItems items;
|
|
|
|
rv = ConstructTableColGroupFrame(aPresShell, aPresContext, aState, parentContent,
|
|
|
|
parentFrame, childStyle.get(), aTableCreator,
|
|
|
|
PR_TRUE, items, pseudo.mFrame, pseudoParent);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
2000-04-28 21:05:31 +00:00
|
|
|
((nsTableColGroupFrame*)pseudo.mFrame)->SetType(eColGroupAnonymousCol);
|
2000-04-04 01:28:15 +00:00
|
|
|
|
|
|
|
// set pseudo data for the parent
|
|
|
|
if (aState.mPseudoFrames.mTableInner.mFrame) {
|
|
|
|
aState.mPseudoFrames.mTableInner.mChildList.AddChild(pseudo.mFrame);
|
|
|
|
}
|
|
|
|
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
nsCSSFrameConstructor::CreatePseudoRowFrame(nsIPresShell* aPresShell,
|
|
|
|
nsIPresContext* aPresContext,
|
|
|
|
nsTableCreator& aTableCreator,
|
|
|
|
nsFrameConstructorState& aState,
|
|
|
|
nsIFrame* aParentFrameIn)
|
|
|
|
{
|
|
|
|
nsresult rv = NS_OK;
|
|
|
|
|
|
|
|
nsIFrame* parentFrame = (aState.mPseudoFrames.mRowGroup.mFrame)
|
|
|
|
? aState.mPseudoFrames.mRowGroup.mFrame : aParentFrameIn;
|
|
|
|
if (!parentFrame) return rv;
|
|
|
|
|
|
|
|
nsCOMPtr<nsIStyleContext> parentStyle;
|
|
|
|
nsCOMPtr<nsIContent> parentContent;
|
|
|
|
nsCOMPtr<nsIStyleContext> childStyle;
|
|
|
|
|
|
|
|
parentFrame->GetStyleContext(getter_AddRefs(parentStyle));
|
|
|
|
parentFrame->GetContent(getter_AddRefs(parentContent));
|
|
|
|
|
|
|
|
aPresContext->ResolvePseudoStyleContextFor(parentContent, nsHTMLAtoms::tableRowPseudo,
|
|
|
|
parentStyle, PR_FALSE,
|
|
|
|
getter_AddRefs(childStyle));
|
|
|
|
|
|
|
|
nsPseudoFrameData& pseudo = aState.mPseudoFrames.mRow;
|
|
|
|
|
|
|
|
// construct the pseudo row as part of the pseudo frames
|
|
|
|
PRBool pseudoParent;
|
|
|
|
nsFrameItems items;
|
|
|
|
rv = ConstructTableRowFrame(aPresShell, aPresContext, aState, parentContent,
|
|
|
|
parentFrame, childStyle.get(), aTableCreator,
|
|
|
|
PR_TRUE, items, pseudo.mFrame, pseudoParent);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
aState.mPseudoFrames.mLowestType = nsLayoutAtoms::tableRowFrame;
|
|
|
|
|
|
|
|
// set pseudo data for the parent
|
|
|
|
if (aState.mPseudoFrames.mRowGroup.mFrame) {
|
|
|
|
aState.mPseudoFrames.mRowGroup.mChildList.AddChild(pseudo.mFrame);
|
|
|
|
}
|
|
|
|
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
nsCSSFrameConstructor::CreatePseudoCellFrame(nsIPresShell* aPresShell,
|
|
|
|
nsIPresContext* aPresContext,
|
|
|
|
nsTableCreator& aTableCreator,
|
|
|
|
nsFrameConstructorState& aState,
|
|
|
|
nsIFrame* aParentFrameIn)
|
|
|
|
{
|
|
|
|
nsresult rv = NS_OK;
|
|
|
|
|
|
|
|
nsIFrame* parentFrame = (aState.mPseudoFrames.mRow.mFrame)
|
|
|
|
? aState.mPseudoFrames.mRow.mFrame : aParentFrameIn;
|
|
|
|
if (!parentFrame) return rv;
|
|
|
|
|
|
|
|
nsCOMPtr<nsIStyleContext> parentStyle;
|
|
|
|
nsCOMPtr<nsIContent> parentContent;
|
|
|
|
nsCOMPtr<nsIStyleContext> childStyle;
|
|
|
|
|
|
|
|
parentFrame->GetStyleContext(getter_AddRefs(parentStyle));
|
|
|
|
parentFrame->GetContent(getter_AddRefs(parentContent));
|
|
|
|
|
|
|
|
aPresContext->ResolvePseudoStyleContextFor(parentContent, nsHTMLAtoms::tableCellPseudo,
|
|
|
|
parentStyle, PR_FALSE,
|
|
|
|
getter_AddRefs(childStyle));
|
|
|
|
|
|
|
|
nsPseudoFrameData& pseudoOuter = aState.mPseudoFrames.mCellOuter;
|
|
|
|
nsPseudoFrameData& pseudoInner = aState.mPseudoFrames.mCellInner;
|
|
|
|
|
|
|
|
// construct the pseudo outer and inner as part of the pseudo frames
|
|
|
|
PRBool pseudoParent;
|
|
|
|
nsFrameItems items;
|
|
|
|
rv = ConstructTableCellFrame(aPresShell, aPresContext, aState, parentContent,
|
|
|
|
parentFrame, childStyle.get(), aTableCreator,
|
|
|
|
PR_TRUE, items, pseudoOuter.mFrame,
|
|
|
|
pseudoInner.mFrame, pseudoParent);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
// set pseudo data for the newly created frames
|
|
|
|
pseudoOuter.mChildList.AddChild(pseudoInner.mFrame);
|
|
|
|
aState.mPseudoFrames.mLowestType = nsLayoutAtoms::tableCellFrame;
|
|
|
|
|
|
|
|
// set pseudo data for the parent
|
|
|
|
if (aState.mPseudoFrames.mRow.mFrame) {
|
|
|
|
aState.mPseudoFrames.mRow.mChildList.AddChild(pseudoOuter.mFrame);
|
|
|
|
}
|
|
|
|
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
// called if the parent is not a table
|
|
|
|
nsresult
|
|
|
|
nsCSSFrameConstructor::GetPseudoTableFrame(nsIPresShell* aPresShell,
|
|
|
|
nsIPresContext* aPresContext,
|
|
|
|
nsTableCreator& aTableCreator,
|
|
|
|
nsFrameConstructorState& aState,
|
|
|
|
nsIFrame& aParentFrameIn)
|
|
|
|
{
|
|
|
|
nsresult rv = NS_OK;
|
|
|
|
if (!aPresShell || !aPresContext) return rv;
|
|
|
|
|
|
|
|
nsPseudoFrames& pseudoFrames = aState.mPseudoFrames;
|
|
|
|
nsCOMPtr<nsIAtom> parentFrameType;
|
|
|
|
aParentFrameIn.GetFrameType(getter_AddRefs(parentFrameType));
|
|
|
|
|
|
|
|
if (pseudoFrames.IsEmpty()) {
|
|
|
|
PRBool created = PR_FALSE;
|
|
|
|
if (nsLayoutAtoms::tableRowGroupFrame == parentFrameType.get()) { // row group parent
|
|
|
|
rv = CreatePseudoRowFrame(aPresShell, aPresContext, aTableCreator, aState, &aParentFrameIn);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
created = PR_TRUE;
|
1999-02-26 09:15:03 +00:00
|
|
|
}
|
2000-04-04 01:28:15 +00:00
|
|
|
if (created || (nsLayoutAtoms::tableRowFrame == parentFrameType.get())) { // row parent
|
|
|
|
rv = CreatePseudoCellFrame(aPresShell, aPresContext, aTableCreator, aState, &aParentFrameIn);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
}
|
|
|
|
rv = CreatePseudoTableFrame(aPresShell, aPresContext, aTableCreator, aState, &aParentFrameIn);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
if (!pseudoFrames.mTableInner.mFrame) {
|
|
|
|
if (pseudoFrames.mRowGroup.mFrame && !(pseudoFrames.mRow.mFrame)) {
|
|
|
|
rv = CreatePseudoRowFrame(aPresShell, aPresContext, aTableCreator, aState);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
}
|
|
|
|
if (pseudoFrames.mRow.mFrame && !(pseudoFrames.mCellOuter.mFrame)) {
|
|
|
|
rv = CreatePseudoCellFrame(aPresShell, aPresContext, aTableCreator, aState);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
}
|
|
|
|
CreatePseudoTableFrame(aPresShell, aPresContext, aTableCreator, aState);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
// called if the parent is not a col group
|
|
|
|
nsresult
|
|
|
|
nsCSSFrameConstructor::GetPseudoColGroupFrame(nsIPresShell* aPresShell,
|
|
|
|
nsIPresContext* aPresContext,
|
|
|
|
nsTableCreator& aTableCreator,
|
|
|
|
nsFrameConstructorState& aState,
|
|
|
|
nsIFrame& aParentFrameIn)
|
|
|
|
{
|
|
|
|
nsresult rv = NS_OK;
|
|
|
|
if (!aPresShell || !aPresContext) return rv;
|
|
|
|
|
|
|
|
nsPseudoFrames& pseudoFrames = aState.mPseudoFrames;
|
|
|
|
nsCOMPtr<nsIAtom> parentFrameType;
|
|
|
|
aParentFrameIn.GetFrameType(getter_AddRefs(parentFrameType));
|
1999-10-17 03:15:13 +00:00
|
|
|
|
2000-04-04 01:28:15 +00:00
|
|
|
if (pseudoFrames.IsEmpty()) {
|
|
|
|
PRBool created = PR_FALSE;
|
|
|
|
if (nsLayoutAtoms::tableRowGroupFrame == parentFrameType.get()) { // row group parent
|
|
|
|
rv = CreatePseudoRowFrame(aPresShell, aPresContext, aTableCreator, aState, &aParentFrameIn);
|
|
|
|
created = PR_TRUE;
|
|
|
|
}
|
|
|
|
if (created || (nsLayoutAtoms::tableRowFrame == parentFrameType.get())) { // row parent
|
|
|
|
rv = CreatePseudoCellFrame(aPresShell, aPresContext, aTableCreator, aState, &aParentFrameIn);
|
|
|
|
created = PR_TRUE;
|
|
|
|
}
|
|
|
|
if (created || (nsLayoutAtoms::tableCellFrame == parentFrameType.get()) || // cell parent
|
|
|
|
!IsTableRelated(parentFrameType.get())) { // block parent
|
|
|
|
rv = CreatePseudoTableFrame(aPresShell, aPresContext, aTableCreator, aState, &aParentFrameIn);
|
|
|
|
}
|
|
|
|
rv = CreatePseudoColGroupFrame(aPresShell, aPresContext, aTableCreator, aState, &aParentFrameIn);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
if (!pseudoFrames.mColGroup.mFrame) {
|
|
|
|
if (pseudoFrames.mRowGroup.mFrame && !(pseudoFrames.mRow.mFrame)) {
|
|
|
|
rv = CreatePseudoRowFrame(aPresShell, aPresContext, aTableCreator, aState);
|
|
|
|
}
|
|
|
|
if (pseudoFrames.mRow.mFrame && !(pseudoFrames.mCellOuter.mFrame)) {
|
|
|
|
rv = CreatePseudoCellFrame(aPresShell, aPresContext, aTableCreator, aState);
|
|
|
|
}
|
|
|
|
if (pseudoFrames.mCellOuter.mFrame && !(pseudoFrames.mTableOuter.mFrame)) {
|
|
|
|
rv = CreatePseudoTableFrame(aPresShell, aPresContext, aTableCreator, aState);
|
|
|
|
}
|
|
|
|
rv = CreatePseudoColGroupFrame(aPresShell, aPresContext, aTableCreator, aState);
|
1999-11-24 06:03:41 +00:00
|
|
|
}
|
2000-04-04 01:28:15 +00:00
|
|
|
}
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
// called if the parent is not a row group
|
|
|
|
nsresult
|
|
|
|
nsCSSFrameConstructor::GetPseudoRowGroupFrame(nsIPresShell* aPresShell,
|
|
|
|
nsIPresContext* aPresContext,
|
|
|
|
nsTableCreator& aTableCreator,
|
|
|
|
nsFrameConstructorState& aState,
|
|
|
|
nsIFrame& aParentFrameIn)
|
|
|
|
{
|
|
|
|
nsresult rv = NS_OK;
|
|
|
|
if (!aPresShell || !aPresContext) return rv;
|
1999-11-24 06:03:41 +00:00
|
|
|
|
2000-04-04 01:28:15 +00:00
|
|
|
nsPseudoFrames& pseudoFrames = aState.mPseudoFrames;
|
|
|
|
nsCOMPtr<nsIAtom> parentFrameType;
|
|
|
|
aParentFrameIn.GetFrameType(getter_AddRefs(parentFrameType));
|
|
|
|
|
|
|
|
if (pseudoFrames.IsEmpty()) {
|
|
|
|
PRBool created = PR_FALSE;
|
|
|
|
if (nsLayoutAtoms::tableRowFrame == parentFrameType.get()) { // row parent
|
|
|
|
rv = CreatePseudoCellFrame(aPresShell, aPresContext, aTableCreator, aState, &aParentFrameIn);
|
|
|
|
created = PR_TRUE;
|
|
|
|
}
|
|
|
|
if (created || (nsLayoutAtoms::tableCellFrame == parentFrameType.get()) || // cell parent
|
|
|
|
!IsTableRelated(parentFrameType)) { // block parent
|
|
|
|
rv = CreatePseudoTableFrame(aPresShell, aPresContext, aTableCreator, aState, &aParentFrameIn);
|
1999-02-05 03:55:18 +00:00
|
|
|
}
|
2000-04-04 01:28:15 +00:00
|
|
|
rv = CreatePseudoRowGroupFrame(aPresShell, aPresContext, aTableCreator, aState, &aParentFrameIn);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
if (!pseudoFrames.mRowGroup.mFrame) {
|
|
|
|
if (pseudoFrames.mRow.mFrame && !(pseudoFrames.mCellOuter.mFrame)) {
|
|
|
|
rv = CreatePseudoCellFrame(aPresShell, aPresContext, aTableCreator, aState);
|
|
|
|
}
|
|
|
|
if (pseudoFrames.mCellOuter.mFrame && !(pseudoFrames.mTableOuter.mFrame)) {
|
|
|
|
rv = CreatePseudoTableFrame(aPresShell, aPresContext, aTableCreator, aState);
|
|
|
|
}
|
|
|
|
rv = CreatePseudoRowGroupFrame(aPresShell, aPresContext, aTableCreator, aState);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
// called if the parent is not a row
|
|
|
|
nsresult
|
|
|
|
nsCSSFrameConstructor::GetPseudoRowFrame(nsIPresShell* aPresShell,
|
|
|
|
nsIPresContext* aPresContext,
|
|
|
|
nsTableCreator& aTableCreator,
|
|
|
|
nsFrameConstructorState& aState,
|
|
|
|
nsIFrame& aParentFrameIn)
|
|
|
|
{
|
|
|
|
nsresult rv = NS_OK;
|
|
|
|
if (!aPresShell || !aPresContext) return rv;
|
|
|
|
|
|
|
|
nsPseudoFrames& pseudoFrames = aState.mPseudoFrames;
|
|
|
|
nsCOMPtr<nsIAtom> parentFrameType;
|
|
|
|
aParentFrameIn.GetFrameType(getter_AddRefs(parentFrameType));
|
|
|
|
|
|
|
|
if (pseudoFrames.IsEmpty()) {
|
|
|
|
PRBool created = PR_FALSE;
|
|
|
|
if ((nsLayoutAtoms::tableCellFrame == parentFrameType.get()) || // cell parent
|
|
|
|
!IsTableRelated(parentFrameType)) { // block parent
|
|
|
|
rv = CreatePseudoTableFrame(aPresShell, aPresContext, aTableCreator, aState, &aParentFrameIn);
|
|
|
|
created = PR_TRUE;
|
|
|
|
}
|
|
|
|
if (created || (nsLayoutAtoms::tableFrame == parentFrameType.get())) { // table parent
|
|
|
|
rv = CreatePseudoRowGroupFrame(aPresShell, aPresContext, aTableCreator, aState, &aParentFrameIn);
|
|
|
|
}
|
|
|
|
rv = CreatePseudoRowFrame(aPresShell, aPresContext, aTableCreator, aState, &aParentFrameIn);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
if (!pseudoFrames.mRow.mFrame) {
|
|
|
|
if (pseudoFrames.mCellOuter.mFrame && !pseudoFrames.mTableOuter.mFrame) {
|
|
|
|
rv = CreatePseudoTableFrame(aPresShell, aPresContext, aTableCreator, aState);
|
|
|
|
}
|
|
|
|
if (pseudoFrames.mTableInner.mFrame && !(pseudoFrames.mRowGroup.mFrame)) {
|
|
|
|
rv = CreatePseudoRowGroupFrame(aPresShell, aPresContext, aTableCreator, aState);
|
|
|
|
}
|
|
|
|
rv = CreatePseudoRowFrame(aPresShell, aPresContext, aTableCreator, aState);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
// called if the parent is not a cell or block
|
|
|
|
nsresult
|
|
|
|
nsCSSFrameConstructor::GetPseudoCellFrame(nsIPresShell* aPresShell,
|
|
|
|
nsIPresContext* aPresContext,
|
|
|
|
nsTableCreator& aTableCreator,
|
|
|
|
nsFrameConstructorState& aState,
|
|
|
|
nsIFrame& aParentFrameIn)
|
|
|
|
{
|
|
|
|
nsresult rv = NS_OK;
|
|
|
|
if (!aPresShell || !aPresContext) return rv;
|
|
|
|
|
|
|
|
nsPseudoFrames& pseudoFrames = aState.mPseudoFrames;
|
|
|
|
nsCOMPtr<nsIAtom> parentFrameType;
|
|
|
|
aParentFrameIn.GetFrameType(getter_AddRefs(parentFrameType));
|
|
|
|
|
|
|
|
if (pseudoFrames.IsEmpty()) {
|
|
|
|
PRBool created = PR_FALSE;
|
|
|
|
if (nsLayoutAtoms::tableFrame == parentFrameType.get()) { // table parent
|
|
|
|
rv = CreatePseudoRowGroupFrame(aPresShell, aPresContext, aTableCreator, aState, &aParentFrameIn);
|
|
|
|
created = PR_TRUE;
|
|
|
|
}
|
|
|
|
if (created || (nsLayoutAtoms::tableRowGroupFrame == parentFrameType.get())) { // row group parent
|
|
|
|
rv = CreatePseudoRowFrame(aPresShell, aPresContext, aTableCreator, aState, &aParentFrameIn);
|
|
|
|
created = PR_TRUE;
|
|
|
|
}
|
|
|
|
rv = CreatePseudoCellFrame(aPresShell, aPresContext, aTableCreator, aState, &aParentFrameIn);
|
|
|
|
}
|
|
|
|
else if (!pseudoFrames.mCellOuter.mFrame) {
|
|
|
|
if (pseudoFrames.mTableInner.mFrame && !(pseudoFrames.mRowGroup.mFrame)) {
|
|
|
|
rv = CreatePseudoRowGroupFrame(aPresShell, aPresContext, aTableCreator, aState);
|
|
|
|
}
|
|
|
|
if (pseudoFrames.mRowGroup.mFrame && !(pseudoFrames.mRow.mFrame)) {
|
|
|
|
rv = CreatePseudoRowFrame(aPresShell, aPresContext, aTableCreator, aState);
|
|
|
|
}
|
|
|
|
rv = CreatePseudoCellFrame(aPresShell, aPresContext, aTableCreator, aState);
|
|
|
|
}
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
nsCSSFrameConstructor::GetParentFrame(nsIPresShell* aPresShell,
|
|
|
|
nsIPresContext* aPresContext,
|
|
|
|
nsTableCreator& aTableCreator,
|
|
|
|
nsIFrame& aParentFrameIn,
|
|
|
|
nsIAtom* aChildFrameType,
|
|
|
|
nsFrameConstructorState& aState,
|
|
|
|
nsIFrame*& aParentFrame,
|
|
|
|
PRBool& aIsPseudoParent)
|
|
|
|
{
|
|
|
|
nsresult rv = NS_OK;
|
|
|
|
if (!aPresShell || !aPresContext) return rv;
|
|
|
|
|
|
|
|
nsCOMPtr<nsIAtom> parentFrameType;
|
|
|
|
aParentFrameIn.GetFrameType(getter_AddRefs(parentFrameType));
|
|
|
|
nsIFrame* pseudoParentFrame = nsnull;
|
|
|
|
nsPseudoFrames& pseudoFrames = aState.mPseudoFrames;
|
|
|
|
aParentFrame = &aParentFrameIn;
|
|
|
|
aIsPseudoParent = PR_FALSE;
|
|
|
|
|
|
|
|
if (nsLayoutAtoms::tableOuterFrame == aChildFrameType) { // table child
|
|
|
|
if (IsTableRelated(parentFrameType)) { // need pseudo cell parent
|
|
|
|
rv = GetPseudoCellFrame(aPresShell, aPresContext, aTableCreator, aState, aParentFrameIn);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
pseudoParentFrame = pseudoFrames.mCellInner.mFrame;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (nsLayoutAtoms::tableCaptionFrame == aChildFrameType) { // caption child
|
|
|
|
if (nsLayoutAtoms::tableOuterFrame != parentFrameType.get()) { // need pseudo table parent
|
|
|
|
rv = GetPseudoTableFrame(aPresShell, aPresContext, aTableCreator, aState, aParentFrameIn);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
pseudoParentFrame = pseudoFrames.mTableOuter.mFrame;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (nsLayoutAtoms::tableColGroupFrame == aChildFrameType) { // col group child
|
|
|
|
if (nsLayoutAtoms::tableFrame != parentFrameType.get()) { // need pseudo table parent
|
|
|
|
rv = GetPseudoTableFrame(aPresShell, aPresContext, aTableCreator, aState, aParentFrameIn);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
pseudoParentFrame = pseudoFrames.mTableInner.mFrame;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (nsLayoutAtoms::tableColFrame == aChildFrameType) { // col child
|
|
|
|
if (nsLayoutAtoms::tableColGroupFrame != parentFrameType.get()) { // need pseudo col group parent
|
|
|
|
rv = GetPseudoColGroupFrame(aPresShell, aPresContext, aTableCreator, aState, aParentFrameIn);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
pseudoParentFrame = pseudoFrames.mColGroup.mFrame;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (nsLayoutAtoms::tableRowGroupFrame == aChildFrameType) { // row group child
|
2000-08-03 00:22:36 +00:00
|
|
|
// XXX can this go away?
|
2000-04-04 01:28:15 +00:00
|
|
|
if (nsLayoutAtoms::tableFrame != parentFrameType.get()) {
|
|
|
|
// trees allow row groups to contain row groups, so don't create pseudo frames
|
2000-08-03 00:22:36 +00:00
|
|
|
if (nsLayoutAtoms::tableRowGroupFrame == parentFrameType.get()) { // need pseudo table parent
|
2000-04-04 01:28:15 +00:00
|
|
|
rv = GetPseudoTableFrame(aPresShell, aPresContext, aTableCreator, aState, aParentFrameIn);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
pseudoParentFrame = pseudoFrames.mTableInner.mFrame;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (nsLayoutAtoms::tableRowFrame == aChildFrameType) { // row child
|
|
|
|
if (nsLayoutAtoms::tableRowGroupFrame != parentFrameType.get()) { // need pseudo row group parent
|
|
|
|
rv = GetPseudoRowGroupFrame(aPresShell, aPresContext, aTableCreator, aState, aParentFrameIn);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
pseudoParentFrame = pseudoFrames.mRowGroup.mFrame;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (nsLayoutAtoms::tableCellFrame == aChildFrameType) { // cell child
|
|
|
|
if (nsLayoutAtoms::tableRowFrame != parentFrameType.get()) { // need pseudo row parent
|
|
|
|
rv = GetPseudoRowFrame(aPresShell, aPresContext, aTableCreator, aState, aParentFrameIn);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
pseudoParentFrame = pseudoFrames.mRow.mFrame;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (nsLayoutAtoms::tableFrame == aChildFrameType) { // invalid
|
|
|
|
NS_ASSERTION(PR_FALSE, "GetParentFrame called on nsLayoutAtoms::tableFrame child");
|
|
|
|
}
|
|
|
|
else { // foreign frame
|
2000-08-03 00:22:36 +00:00
|
|
|
if (IsTableRelated(parentFrameType) &&
|
2000-04-04 01:28:15 +00:00
|
|
|
(nsLayoutAtoms::tableCaptionFrame != parentFrameType.get())) { // need pseudo cell parent
|
|
|
|
rv = GetPseudoCellFrame(aPresShell, aPresContext, aTableCreator, aState, aParentFrameIn);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
pseudoParentFrame = pseudoFrames.mCellInner.mFrame;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (pseudoParentFrame) {
|
|
|
|
aParentFrame = pseudoParentFrame;
|
|
|
|
aIsPseudoParent = PR_TRUE;
|
1999-02-05 03:55:18 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2000-04-28 21:05:31 +00:00
|
|
|
void
|
|
|
|
FixUpOuterTableFloat(nsIStyleContext* aOuterSC,
|
|
|
|
nsIStyleContext* aInnerSC)
|
|
|
|
{
|
|
|
|
nsStyleDisplay* outerStyleDisplay = (nsStyleDisplay*)aOuterSC->GetMutableStyleData(eStyleStruct_Display);
|
|
|
|
nsStyleDisplay* innerStyleDisplay = (nsStyleDisplay*)aInnerSC->GetStyleData(eStyleStruct_Display);
|
|
|
|
if (outerStyleDisplay->mFloats != innerStyleDisplay->mFloats) {
|
|
|
|
outerStyleDisplay->mFloats = innerStyleDisplay->mFloats;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2000-04-04 01:28:15 +00:00
|
|
|
// Construct the outer, inner table frames and the children frames for the table.
|
|
|
|
nsresult
|
|
|
|
nsCSSFrameConstructor::ConstructTableFrame(nsIPresShell* aPresShell,
|
|
|
|
nsIPresContext* aPresContext,
|
|
|
|
nsFrameConstructorState& aState,
|
|
|
|
nsIContent* aContent,
|
|
|
|
nsIFrame* aParentFrameIn,
|
|
|
|
nsIStyleContext* aStyleContext,
|
|
|
|
nsTableCreator& aTableCreator,
|
|
|
|
PRBool aIsPseudo,
|
|
|
|
nsFrameItems& aChildItems,
|
|
|
|
nsIFrame*& aNewOuterFrame,
|
|
|
|
nsIFrame*& aNewInnerFrame,
|
|
|
|
PRBool& aIsPseudoParent)
|
|
|
|
{
|
|
|
|
nsresult rv = NS_OK;
|
|
|
|
if (!aPresShell || !aPresContext || !aParentFrameIn) return rv;
|
|
|
|
|
|
|
|
// Create the outer table frame which holds the caption and inner table frame
|
|
|
|
aTableCreator.CreateTableOuterFrame(&aNewOuterFrame);
|
|
|
|
|
|
|
|
nsIFrame* parentFrame = aParentFrameIn;
|
|
|
|
aIsPseudoParent = PR_FALSE;
|
|
|
|
if (!aIsPseudo) {
|
|
|
|
// this frame may have a pseudo parent
|
|
|
|
GetParentFrame(aPresShell, aPresContext, aTableCreator, *aParentFrameIn,
|
|
|
|
nsLayoutAtoms::tableOuterFrame, aState, parentFrame, aIsPseudoParent);
|
|
|
|
if (!aIsPseudoParent && !aState.mPseudoFrames.IsEmpty()) {
|
|
|
|
ProcessPseudoFrames(aPresContext, aState.mPseudoFrames, aChildItems);
|
|
|
|
}
|
|
|
|
if (!aIsPseudo && aIsPseudoParent && aState.mPseudoFrames.mTableOuter.mFrame) {
|
|
|
|
ProcessPseudoFrames(aPresContext, aState.mPseudoFrames, nsLayoutAtoms::tableOuterFrame);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2000-04-28 21:05:31 +00:00
|
|
|
// create the pseudo SC for the outer table as a child of the inner SC
|
|
|
|
nsCOMPtr<nsIStyleContext> outerStyleContext;
|
|
|
|
aPresContext->ResolvePseudoStyleContextFor(aContent, nsHTMLAtoms::tableOuterPseudo,
|
|
|
|
aStyleContext, PR_FALSE,
|
|
|
|
getter_AddRefs(outerStyleContext));
|
|
|
|
FixUpOuterTableFloat(outerStyleContext, aStyleContext);
|
|
|
|
|
2000-04-04 01:28:15 +00:00
|
|
|
// Init the table outer frame and see if we need to create a view, e.g.
|
|
|
|
// the frame is absolutely positioned
|
|
|
|
InitAndRestoreFrame(aPresContext, aState, aContent,
|
2000-04-28 21:05:31 +00:00
|
|
|
parentFrame, outerStyleContext, nsnull, aNewOuterFrame);
|
2000-04-04 01:28:15 +00:00
|
|
|
nsHTMLContainerFrame::CreateViewForFrame(aPresContext, aNewOuterFrame,
|
2000-04-28 21:05:31 +00:00
|
|
|
outerStyleContext, PR_FALSE);
|
2000-04-04 01:28:15 +00:00
|
|
|
|
|
|
|
// Create the inner table frame
|
|
|
|
aTableCreator.CreateTableFrame(&aNewInnerFrame);
|
|
|
|
|
|
|
|
InitAndRestoreFrame(aPresContext, aState, aContent,
|
|
|
|
aNewOuterFrame, aStyleContext, nsnull, aNewInnerFrame);
|
|
|
|
|
|
|
|
if (!aIsPseudo) {
|
|
|
|
nsFrameItems childItems;
|
|
|
|
nsIFrame* captionFrame;
|
|
|
|
|
|
|
|
rv = TableProcessChildren(aPresShell, aPresContext, aState, aContent, aNewInnerFrame,
|
|
|
|
aTableCreator, childItems, captionFrame);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
2000-05-31 08:32:45 +00:00
|
|
|
// if there are any anonymous children for the table, create frames for them
|
|
|
|
CreateAnonymousFrames(aPresShell, aPresContext, nsnull, aState, aContent, aNewInnerFrame,
|
|
|
|
childItems);
|
|
|
|
|
2000-04-04 01:28:15 +00:00
|
|
|
// Set the inner table frame's initial primary list
|
|
|
|
aNewInnerFrame->SetInitialChildList(aPresContext, nsnull, childItems.childList);
|
|
|
|
|
|
|
|
// Set the outer table frame's primary and option lists
|
|
|
|
aNewOuterFrame->SetInitialChildList(aPresContext, nsnull, aNewInnerFrame);
|
|
|
|
if (captionFrame) {
|
|
|
|
aNewOuterFrame->SetInitialChildList(aPresContext, nsLayoutAtoms::captionList, captionFrame);
|
|
|
|
}
|
|
|
|
if (aIsPseudoParent) {
|
|
|
|
aState.mPseudoFrames.mCellInner.mChildList.AddChild(aNewOuterFrame);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
1999-02-05 03:55:18 +00:00
|
|
|
nsresult
|
2000-04-04 01:28:15 +00:00
|
|
|
nsCSSFrameConstructor::ConstructTableCaptionFrame(nsIPresShell* aPresShell,
|
1999-12-04 23:49:50 +00:00
|
|
|
nsIPresContext* aPresContext,
|
1999-04-28 19:08:14 +00:00
|
|
|
nsFrameConstructorState& aState,
|
|
|
|
nsIContent* aContent,
|
2000-04-04 01:28:15 +00:00
|
|
|
nsIFrame* aParentFrameIn,
|
1999-04-28 19:08:14 +00:00
|
|
|
nsIStyleContext* aStyleContext,
|
2000-04-04 01:28:15 +00:00
|
|
|
nsTableCreator& aTableCreator,
|
|
|
|
nsFrameItems& aChildItems,
|
|
|
|
nsIFrame*& aNewFrame,
|
|
|
|
PRBool& aIsPseudoParent)
|
|
|
|
|
|
|
|
{
|
|
|
|
nsresult rv = NS_OK;
|
|
|
|
if (!aPresShell || !aPresContext || !aParentFrameIn) return rv;
|
|
|
|
|
|
|
|
nsIFrame* parentFrame = aParentFrameIn;
|
|
|
|
aIsPseudoParent = PR_FALSE;
|
|
|
|
// this frame may have a pseudo parent
|
|
|
|
GetParentFrame(aPresShell, aPresContext, aTableCreator, *aParentFrameIn,
|
|
|
|
nsLayoutAtoms::tableCaptionFrame, aState, parentFrame, aIsPseudoParent);
|
|
|
|
if (!aIsPseudoParent && !aState.mPseudoFrames.IsEmpty()) {
|
|
|
|
ProcessPseudoFrames(aPresContext, aState.mPseudoFrames, aChildItems);
|
|
|
|
}
|
|
|
|
|
|
|
|
rv = aTableCreator.CreateTableCaptionFrame(&aNewFrame);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
InitAndRestoreFrame(aPresContext, aState, aContent,
|
|
|
|
parentFrame, aStyleContext, nsnull, aNewFrame);
|
|
|
|
|
|
|
|
nsFrameItems childItems;
|
|
|
|
// pass in aTableCreator so ProcessChildren will call TableProcessChildren
|
|
|
|
rv = ProcessChildren(aPresShell, aPresContext, aState, aContent, aNewFrame,
|
|
|
|
PR_TRUE, childItems, PR_TRUE, &aTableCreator);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
aNewFrame->SetInitialChildList(aPresContext, nsnull, childItems.childList);
|
|
|
|
if (aIsPseudoParent) {
|
|
|
|
aState.mPseudoFrames.mTableOuter.mChildList2.AddChild(aNewFrame);
|
|
|
|
}
|
|
|
|
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
nsCSSFrameConstructor::ConstructTableRowGroupFrame(nsIPresShell* aPresShell,
|
|
|
|
nsIPresContext* aPresContext,
|
|
|
|
nsFrameConstructorState& aState,
|
|
|
|
nsIContent* aContent,
|
|
|
|
nsIFrame* aParentFrameIn,
|
|
|
|
nsIStyleContext* aStyleContext,
|
|
|
|
nsTableCreator& aTableCreator,
|
|
|
|
PRBool aIsPseudo,
|
|
|
|
nsFrameItems& aChildItems,
|
|
|
|
nsIFrame*& aNewFrame,
|
|
|
|
PRBool& aIsPseudoParent)
|
|
|
|
{
|
|
|
|
nsresult rv = NS_OK;
|
|
|
|
if (!aPresShell || !aPresContext || !aParentFrameIn) return rv;
|
|
|
|
|
|
|
|
nsIFrame* parentFrame = aParentFrameIn;
|
|
|
|
aIsPseudoParent = PR_FALSE;
|
|
|
|
if (!aIsPseudo) {
|
|
|
|
// this frame may have a pseudo parent
|
|
|
|
GetParentFrame(aPresShell, aPresContext, aTableCreator, *aParentFrameIn,
|
|
|
|
nsLayoutAtoms::tableRowGroupFrame, aState, parentFrame, aIsPseudoParent);
|
|
|
|
if (!aIsPseudoParent && !aState.mPseudoFrames.IsEmpty()) {
|
|
|
|
ProcessPseudoFrames(aPresContext, aState.mPseudoFrames, aChildItems);
|
|
|
|
}
|
|
|
|
if (!aIsPseudo && aIsPseudoParent && aState.mPseudoFrames.mRowGroup.mFrame) {
|
|
|
|
ProcessPseudoFrames(aPresContext, aState.mPseudoFrames, nsLayoutAtoms::tableRowGroupFrame);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
const nsStyleDisplay* styleDisplay =
|
|
|
|
(const nsStyleDisplay*) aStyleContext->GetStyleData(eStyleStruct_Display);
|
|
|
|
|
|
|
|
rv = aTableCreator.CreateTableRowGroupFrame(&aNewFrame);
|
|
|
|
|
|
|
|
nsIFrame* scrollFrame = nsnull;
|
|
|
|
if (IsScrollable(aPresContext, styleDisplay)) {
|
|
|
|
// Create an area container for the frame
|
|
|
|
BuildScrollFrame(aPresShell, aPresContext, aState, aContent, aStyleContext,
|
|
|
|
aNewFrame, parentFrame, scrollFrame, aStyleContext);
|
|
|
|
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
InitAndRestoreFrame(aPresContext, aState, aContent, parentFrame,
|
|
|
|
aStyleContext, nsnull, aNewFrame);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!aIsPseudo) {
|
|
|
|
nsFrameItems childItems;
|
2000-08-03 00:22:36 +00:00
|
|
|
nsIFrame* captionFrame;
|
|
|
|
rv = TableProcessChildren(aPresShell, aPresContext, aState, aContent,
|
|
|
|
aNewFrame, aTableCreator, childItems, captionFrame);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
// if there are any anonymous children for the table, create frames for them
|
|
|
|
CreateAnonymousFrames(aPresShell, aPresContext, nsnull, aState, aContent, aNewFrame,
|
|
|
|
childItems);
|
2000-04-04 01:28:15 +00:00
|
|
|
|
2000-08-03 00:22:36 +00:00
|
|
|
aNewFrame->SetInitialChildList(aPresContext, nsnull, childItems.childList);
|
2000-04-04 01:28:15 +00:00
|
|
|
if (aIsPseudoParent) {
|
2000-05-04 14:53:59 +00:00
|
|
|
nsIFrame* child = (scrollFrame) ? scrollFrame : aNewFrame;
|
|
|
|
aState.mPseudoFrames.mTableInner.mChildList.AddChild(child);
|
2000-04-04 01:28:15 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// if there is a scroll frame, use it as the one constructed
|
|
|
|
if (scrollFrame) {
|
|
|
|
aNewFrame = scrollFrame;
|
|
|
|
}
|
|
|
|
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
nsCSSFrameConstructor::ConstructTableColGroupFrame(nsIPresShell* aPresShell,
|
|
|
|
nsIPresContext* aPresContext,
|
|
|
|
nsFrameConstructorState& aState,
|
|
|
|
nsIContent* aContent,
|
|
|
|
nsIFrame* aParentFrameIn,
|
|
|
|
nsIStyleContext* aStyleContext,
|
|
|
|
nsTableCreator& aTableCreator,
|
|
|
|
PRBool aIsPseudo,
|
|
|
|
nsFrameItems& aChildItems,
|
|
|
|
nsIFrame*& aNewFrame,
|
|
|
|
PRBool& aIsPseudoParent)
|
1999-02-05 03:55:18 +00:00
|
|
|
{
|
2000-04-04 01:28:15 +00:00
|
|
|
nsresult rv = NS_OK;
|
|
|
|
if (!aPresShell || !aPresContext || !aParentFrameIn) return rv;
|
|
|
|
|
|
|
|
nsIFrame* parentFrame = aParentFrameIn;
|
|
|
|
aIsPseudoParent = PR_FALSE;
|
|
|
|
if (!aIsPseudo) {
|
|
|
|
// this frame may have a pseudo parent
|
|
|
|
GetParentFrame(aPresShell, aPresContext, aTableCreator, *aParentFrameIn,
|
|
|
|
nsLayoutAtoms::tableColGroupFrame, aState, parentFrame, aIsPseudoParent);
|
|
|
|
if (!aIsPseudoParent && !aState.mPseudoFrames.IsEmpty()) {
|
|
|
|
ProcessPseudoFrames(aPresContext, aState.mPseudoFrames, aChildItems);
|
|
|
|
}
|
|
|
|
if (!aIsPseudo && aIsPseudoParent && aState.mPseudoFrames.mColGroup.mFrame) {
|
|
|
|
ProcessPseudoFrames(aPresContext, aState.mPseudoFrames, nsLayoutAtoms::tableColGroupFrame);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
rv = aTableCreator.CreateTableColGroupFrame(&aNewFrame);
|
1999-02-26 09:15:03 +00:00
|
|
|
if (NS_FAILED(rv)) return rv;
|
1999-12-06 07:44:18 +00:00
|
|
|
InitAndRestoreFrame(aPresContext, aState, aContent,
|
2000-04-04 01:28:15 +00:00
|
|
|
parentFrame, aStyleContext, nsnull, aNewFrame);
|
|
|
|
|
|
|
|
if (!aIsPseudo) {
|
1999-02-26 09:15:03 +00:00
|
|
|
nsFrameItems childItems;
|
2000-04-04 01:28:15 +00:00
|
|
|
nsIFrame* captionFrame;
|
|
|
|
rv = TableProcessChildren(aPresShell, aPresContext, aState, aContent, aNewFrame,
|
|
|
|
aTableCreator, childItems, captionFrame);
|
1999-02-26 09:15:03 +00:00
|
|
|
if (NS_FAILED(rv)) return rv;
|
2000-04-04 01:28:15 +00:00
|
|
|
aNewFrame->SetInitialChildList(aPresContext, nsnull, childItems.childList);
|
|
|
|
if (aIsPseudoParent) {
|
|
|
|
aState.mPseudoFrames.mTableInner.mChildList.AddChild(aNewFrame);
|
|
|
|
}
|
1999-02-05 03:55:18 +00:00
|
|
|
}
|
1999-02-26 09:15:03 +00:00
|
|
|
|
1999-02-05 03:55:18 +00:00
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
2000-04-04 01:28:15 +00:00
|
|
|
nsCSSFrameConstructor::ConstructTableRowFrame(nsIPresShell* aPresShell,
|
1999-12-04 23:49:50 +00:00
|
|
|
nsIPresContext* aPresContext,
|
1999-04-28 19:08:14 +00:00
|
|
|
nsFrameConstructorState& aState,
|
|
|
|
nsIContent* aContent,
|
2000-04-04 01:28:15 +00:00
|
|
|
nsIFrame* aParentFrameIn,
|
1999-04-28 19:08:14 +00:00
|
|
|
nsIStyleContext* aStyleContext,
|
2000-04-04 01:28:15 +00:00
|
|
|
nsTableCreator& aTableCreator,
|
|
|
|
PRBool aIsPseudo,
|
|
|
|
nsFrameItems& aChildItems,
|
|
|
|
nsIFrame*& aNewFrame,
|
|
|
|
PRBool& aIsPseudoParent)
|
1999-02-05 03:55:18 +00:00
|
|
|
{
|
|
|
|
nsresult rv = NS_OK;
|
2000-04-04 01:28:15 +00:00
|
|
|
if (!aPresShell || !aPresContext || !aParentFrameIn) return rv;
|
|
|
|
|
|
|
|
nsIFrame* parentFrame = aParentFrameIn;
|
|
|
|
aIsPseudoParent = PR_FALSE;
|
|
|
|
if (!aIsPseudo) {
|
|
|
|
// this frame may have a pseudo parent
|
|
|
|
GetParentFrame(aPresShell, aPresContext, aTableCreator, *aParentFrameIn,
|
|
|
|
nsLayoutAtoms::tableRowFrame, aState, parentFrame, aIsPseudoParent);
|
|
|
|
if (!aIsPseudoParent && !aState.mPseudoFrames.IsEmpty()) {
|
|
|
|
ProcessPseudoFrames(aPresContext, aState.mPseudoFrames, aChildItems);
|
|
|
|
}
|
|
|
|
if (!aIsPseudo && aIsPseudoParent && aState.mPseudoFrames.mRow.mFrame) {
|
|
|
|
ProcessPseudoFrames(aPresContext, aState.mPseudoFrames, nsLayoutAtoms::tableRowFrame);
|
|
|
|
}
|
|
|
|
}
|
1999-02-05 03:55:18 +00:00
|
|
|
|
2000-04-04 01:28:15 +00:00
|
|
|
rv = aTableCreator.CreateTableRowFrame(&aNewFrame);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
InitAndRestoreFrame(aPresContext, aState, aContent,
|
|
|
|
parentFrame, aStyleContext, nsnull, aNewFrame);
|
|
|
|
if (!aIsPseudo) {
|
|
|
|
nsFrameItems childItems;
|
|
|
|
nsIFrame* captionFrame;
|
|
|
|
rv = TableProcessChildren(aPresShell, aPresContext, aState, aContent, aNewFrame,
|
|
|
|
aTableCreator, childItems, captionFrame);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
2000-05-31 08:32:45 +00:00
|
|
|
// if there are any anonymous children for the table, create frames for them
|
|
|
|
CreateAnonymousFrames(aPresShell, aPresContext, nsnull, aState, aContent, aNewFrame,
|
|
|
|
childItems);
|
|
|
|
|
2000-04-04 01:28:15 +00:00
|
|
|
aNewFrame->SetInitialChildList(aPresContext, nsnull, childItems.childList);
|
|
|
|
if (aIsPseudoParent) {
|
|
|
|
aState.mPseudoFrames.mRowGroup.mChildList.AddChild(aNewFrame);
|
|
|
|
}
|
1999-02-05 03:55:18 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
1999-02-27 19:02:48 +00:00
|
|
|
nsresult
|
2000-04-04 01:28:15 +00:00
|
|
|
nsCSSFrameConstructor::ConstructTableColFrame(nsIPresShell* aPresShell,
|
|
|
|
nsIPresContext* aPresContext,
|
|
|
|
nsFrameConstructorState& aState,
|
|
|
|
nsIContent* aContent,
|
|
|
|
nsIFrame* aParentFrameIn,
|
|
|
|
nsIStyleContext* aStyleContext,
|
|
|
|
nsTableCreator& aTableCreator,
|
|
|
|
PRBool aIsPseudo,
|
|
|
|
nsFrameItems& aChildItems,
|
|
|
|
nsIFrame*& aNewFrame,
|
|
|
|
PRBool& aIsPseudoParent)
|
1999-02-27 19:02:48 +00:00
|
|
|
{
|
2000-04-04 01:28:15 +00:00
|
|
|
nsresult rv = NS_OK;
|
|
|
|
if (!aPresShell || !aPresContext || !aParentFrameIn) return rv;
|
|
|
|
|
|
|
|
nsIFrame* parentFrame = aParentFrameIn;
|
|
|
|
aIsPseudoParent = PR_FALSE;
|
|
|
|
if (!aIsPseudo) {
|
|
|
|
// this frame may have a pseudo parent
|
|
|
|
GetParentFrame(aPresShell, aPresContext, aTableCreator, *aParentFrameIn,
|
|
|
|
nsLayoutAtoms::tableColFrame, aState, parentFrame, aIsPseudoParent);
|
|
|
|
if (!aIsPseudoParent && !aState.mPseudoFrames.IsEmpty()) {
|
|
|
|
ProcessPseudoFrames(aPresContext, aState.mPseudoFrames, aChildItems);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
rv = aTableCreator.CreateTableColFrame(&aNewFrame);
|
1999-02-27 19:02:48 +00:00
|
|
|
if (NS_FAILED(rv)) return rv;
|
1999-12-06 07:44:18 +00:00
|
|
|
InitAndRestoreFrame(aPresContext, aState, aContent,
|
2000-04-04 01:28:15 +00:00
|
|
|
parentFrame, aStyleContext, nsnull, aNewFrame);
|
|
|
|
if (!aIsPseudo) {
|
|
|
|
nsFrameItems childItems;
|
|
|
|
nsIFrame* captionFrame;
|
|
|
|
rv = TableProcessChildren(aPresShell, aPresContext, aState, aContent, aNewFrame,
|
|
|
|
aTableCreator, childItems, captionFrame);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
aNewFrame->SetInitialChildList(aPresContext, nsnull, childItems.childList);
|
|
|
|
if (aIsPseudoParent) {
|
|
|
|
aState.mPseudoFrames.mColGroup.mChildList.AddChild(aNewFrame);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1999-02-27 19:02:48 +00:00
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
1999-02-05 03:55:18 +00:00
|
|
|
nsresult
|
2000-04-04 01:28:15 +00:00
|
|
|
nsCSSFrameConstructor::ConstructTableCellFrame(nsIPresShell* aPresShell,
|
1999-12-04 23:49:50 +00:00
|
|
|
nsIPresContext* aPresContext,
|
1999-04-28 19:08:14 +00:00
|
|
|
nsFrameConstructorState& aState,
|
|
|
|
nsIContent* aContent,
|
2000-04-04 01:28:15 +00:00
|
|
|
nsIFrame* aParentFrameIn,
|
1999-04-28 19:08:14 +00:00
|
|
|
nsIStyleContext* aStyleContext,
|
|
|
|
nsTableCreator& aTableCreator,
|
2000-04-04 01:28:15 +00:00
|
|
|
PRBool aIsPseudo,
|
|
|
|
nsFrameItems& aChildItems,
|
|
|
|
nsIFrame*& aNewCellOuterFrame,
|
|
|
|
nsIFrame*& aNewCellInnerFrame,
|
|
|
|
PRBool& aIsPseudoParent)
|
1999-02-05 03:55:18 +00:00
|
|
|
{
|
|
|
|
nsresult rv = NS_OK;
|
2000-04-04 01:28:15 +00:00
|
|
|
if (!aPresShell || !aPresContext || !aParentFrameIn) return rv;
|
|
|
|
|
|
|
|
nsIFrame* parentFrame = aParentFrameIn;
|
|
|
|
aIsPseudoParent = PR_FALSE;
|
|
|
|
if (!aIsPseudo) {
|
|
|
|
// this frame may have a pseudo parent
|
|
|
|
GetParentFrame(aPresShell, aPresContext, aTableCreator, *aParentFrameIn,
|
|
|
|
nsLayoutAtoms::tableCellFrame, aState, parentFrame, aIsPseudoParent);
|
|
|
|
if (!aIsPseudoParent && !aState.mPseudoFrames.IsEmpty()) {
|
|
|
|
ProcessPseudoFrames(aPresContext, aState.mPseudoFrames, aChildItems);
|
|
|
|
}
|
|
|
|
if (!aIsPseudo && aIsPseudoParent && aState.mPseudoFrames.mCellOuter.mFrame) {
|
|
|
|
ProcessPseudoFrames(aPresContext, aState.mPseudoFrames, nsLayoutAtoms::tableCellFrame);
|
1999-02-05 03:55:18 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2000-04-04 01:28:15 +00:00
|
|
|
rv = aTableCreator.CreateTableCellFrame(&aNewCellOuterFrame);
|
1999-02-26 09:15:03 +00:00
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
// Initialize the table cell frame
|
1999-12-06 07:44:18 +00:00
|
|
|
InitAndRestoreFrame(aPresContext, aState, aContent,
|
2000-04-04 01:28:15 +00:00
|
|
|
parentFrame, aStyleContext, nsnull, aNewCellOuterFrame);
|
|
|
|
// Create a block frame that will format the cell's content
|
|
|
|
rv = aTableCreator.CreateTableCellInnerFrame(&aNewCellInnerFrame);
|
1999-12-01 10:37:20 +00:00
|
|
|
|
1999-02-26 09:15:03 +00:00
|
|
|
if (NS_FAILED(rv)) {
|
2000-04-04 01:28:15 +00:00
|
|
|
aNewCellOuterFrame->Destroy(aPresContext);
|
|
|
|
aNewCellOuterFrame = nsnull;
|
1999-02-26 09:15:03 +00:00
|
|
|
return rv;
|
|
|
|
}
|
1999-02-05 03:55:18 +00:00
|
|
|
|
1999-02-26 09:15:03 +00:00
|
|
|
// Resolve pseudo style and initialize the body cell frame
|
2000-04-04 01:28:15 +00:00
|
|
|
nsCOMPtr<nsIStyleContext> innerPseudoStyle;
|
|
|
|
aPresContext->ResolvePseudoStyleContextFor(aContent, nsHTMLAtoms::cellContentPseudo,
|
1999-02-26 09:15:03 +00:00
|
|
|
aStyleContext, PR_FALSE,
|
2000-04-04 01:28:15 +00:00
|
|
|
getter_AddRefs(innerPseudoStyle));
|
1999-12-06 07:44:18 +00:00
|
|
|
InitAndRestoreFrame(aPresContext, aState, aContent,
|
2000-04-04 01:28:15 +00:00
|
|
|
aNewCellOuterFrame, innerPseudoStyle, nsnull, aNewCellInnerFrame);
|
1999-02-26 09:15:03 +00:00
|
|
|
|
2000-04-04 01:28:15 +00:00
|
|
|
if (!aIsPseudo) {
|
1999-08-31 03:09:40 +00:00
|
|
|
PRBool haveFirstLetterStyle, haveFirstLineStyle;
|
|
|
|
HaveSpecialBlockStyle(aPresContext, aContent, aStyleContext,
|
|
|
|
&haveFirstLetterStyle, &haveFirstLineStyle);
|
1999-08-27 21:46:10 +00:00
|
|
|
|
2000-04-04 01:28:15 +00:00
|
|
|
// The block frame is a floater container
|
1999-07-16 23:04:27 +00:00
|
|
|
nsFrameConstructorSaveState floaterSaveState;
|
2000-04-04 01:28:15 +00:00
|
|
|
aState.PushFloaterContainingBlock(aNewCellInnerFrame, floaterSaveState,
|
|
|
|
haveFirstLetterStyle, haveFirstLineStyle);
|
1999-07-16 23:04:27 +00:00
|
|
|
|
|
|
|
// Process the child content
|
1999-02-05 03:55:18 +00:00
|
|
|
nsFrameItems childItems;
|
2000-04-04 01:28:15 +00:00
|
|
|
// pass in null tableCreator so ProcessChildren will not call TableProcessChildren
|
|
|
|
rv = ProcessChildren(aPresShell, aPresContext, aState, aContent, aNewCellInnerFrame,
|
|
|
|
PR_TRUE, childItems, PR_TRUE, nsnull);
|
1999-02-26 09:15:03 +00:00
|
|
|
if (NS_FAILED(rv)) return rv;
|
1999-08-25 05:52:10 +00:00
|
|
|
|
2000-04-04 01:28:15 +00:00
|
|
|
// if there are any tree anonymous children create frames for them
|
1999-08-25 05:52:10 +00:00
|
|
|
nsCOMPtr<nsIAtom> tagName;
|
|
|
|
aContent->GetTag(*getter_AddRefs(tagName));
|
2000-08-03 00:22:36 +00:00
|
|
|
CreateAnonymousTableCellFrames(aPresShell, aPresContext, tagName, aState, aContent,
|
|
|
|
aNewCellInnerFrame, aNewCellOuterFrame, childItems);
|
1999-08-25 05:52:10 +00:00
|
|
|
|
2000-04-04 01:28:15 +00:00
|
|
|
aNewCellInnerFrame->SetInitialChildList(aPresContext, nsnull, childItems.childList);
|
1999-07-16 23:04:27 +00:00
|
|
|
if (aState.mFloatedItems.childList) {
|
2000-04-04 01:28:15 +00:00
|
|
|
aNewCellInnerFrame->SetInitialChildList(aPresContext, nsLayoutAtoms::floaterList,
|
1999-07-16 23:04:27 +00:00
|
|
|
aState.mFloatedItems.childList);
|
1999-02-26 17:11:54 +00:00
|
|
|
}
|
2000-04-04 01:28:15 +00:00
|
|
|
|
|
|
|
aNewCellOuterFrame->SetInitialChildList(aPresContext, nsnull, aNewCellInnerFrame);
|
|
|
|
if (aIsPseudoParent) {
|
|
|
|
aState.mPseudoFrames.mRow.mChildList.AddChild(aNewCellOuterFrame);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
PRBool
|
|
|
|
nsCSSFrameConstructor::MustGeneratePseudoParent(nsIPresContext* aPresContext,
|
|
|
|
nsIFrame* aParentFrame,
|
|
|
|
nsIAtom* aTag,
|
|
|
|
nsIContent* aContent)
|
|
|
|
{
|
|
|
|
nsCOMPtr<nsIStyleContext> styleContext;
|
|
|
|
|
|
|
|
nsresult rv = ResolveStyleContext(aPresContext, aParentFrame, aContent, aTag, getter_AddRefs(styleContext));
|
|
|
|
if (NS_FAILED(rv)) return PR_FALSE;
|
|
|
|
|
|
|
|
const nsStyleDisplay* display = (const nsStyleDisplay*)
|
|
|
|
styleContext->GetStyleData(eStyleStruct_Display);
|
|
|
|
|
|
|
|
if (NS_STYLE_DISPLAY_NONE == display->mDisplay) return PR_FALSE;
|
|
|
|
|
|
|
|
// check tags first
|
|
|
|
|
|
|
|
if ((nsLayoutAtoms::textTagName == aTag)) {
|
|
|
|
return !IsOnlyWhiteSpace(aContent);
|
|
|
|
}
|
|
|
|
|
2000-04-28 21:05:31 +00:00
|
|
|
// exclude tags
|
|
|
|
if ( (nsLayoutAtoms::commentTagName == aTag) ||
|
|
|
|
(nsHTMLAtoms::form == aTag) ) {
|
|
|
|
return PR_FALSE;
|
2000-04-04 01:28:15 +00:00
|
|
|
}
|
|
|
|
|
2000-04-28 21:05:31 +00:00
|
|
|
// XXX DJF - when should pseudo frames be constructed for MathML?
|
2000-04-04 04:57:08 +00:00
|
|
|
#ifdef MOZ_MATHML
|
2000-04-28 21:05:31 +00:00
|
|
|
if ( (nsMathMLAtoms::math == aTag) ) {
|
2000-04-04 01:28:15 +00:00
|
|
|
return PR_TRUE;
|
|
|
|
}
|
2000-04-28 21:05:31 +00:00
|
|
|
else {
|
|
|
|
return PR_FALSE;
|
|
|
|
}
|
2000-04-04 01:28:15 +00:00
|
|
|
#endif
|
2000-04-28 21:05:31 +00:00
|
|
|
|
2000-05-04 14:53:59 +00:00
|
|
|
return PR_TRUE;
|
2000-04-04 01:28:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// this is called when a non table related element is a child of a table, row group,
|
|
|
|
// or row, but not a cell.
|
|
|
|
nsresult
|
|
|
|
nsCSSFrameConstructor::ConstructTableForeignFrame(nsIPresShell* aPresShell,
|
|
|
|
nsIPresContext* aPresContext,
|
|
|
|
nsFrameConstructorState& aState,
|
|
|
|
nsIContent* aContent,
|
|
|
|
nsIFrame* aParentFrameIn,
|
|
|
|
nsIStyleContext* aStyleContext,
|
|
|
|
nsTableCreator& aTableCreator,
|
|
|
|
nsFrameItems& aChildItems,
|
|
|
|
nsIFrame*& aNewFrame,
|
|
|
|
PRBool& aIsPseudoParent)
|
|
|
|
{
|
|
|
|
nsresult rv = NS_OK;
|
|
|
|
aNewFrame = nsnull;
|
|
|
|
if (!aPresShell || !aPresContext || !aParentFrameIn) return rv;
|
|
|
|
|
|
|
|
nsIFrame* parentFrame = nsnull;
|
|
|
|
aIsPseudoParent = PR_FALSE;
|
|
|
|
|
|
|
|
// XXX form code needs to be fixed so that the forms can work without a frame.
|
|
|
|
nsCOMPtr<nsIAtom> tag;
|
|
|
|
aContent->GetTag(*getter_AddRefs(tag));
|
|
|
|
|
|
|
|
if (nsHTMLAtoms::form == tag.get()) {
|
2000-04-10 04:00:37 +00:00
|
|
|
// A form doesn't get a psuedo frame parent, but it needs a frame.
|
2000-04-04 01:28:15 +00:00
|
|
|
// if the parent is a table, put the form in the outer table frame
|
2000-04-10 04:00:37 +00:00
|
|
|
// otherwise use aParentFrameIn as the parent
|
2000-04-04 01:28:15 +00:00
|
|
|
nsCOMPtr<nsIAtom> frameType;
|
|
|
|
aParentFrameIn->GetFrameType(getter_AddRefs(frameType));
|
|
|
|
if (nsLayoutAtoms::tableFrame == frameType.get()) {
|
|
|
|
aParentFrameIn->GetParent(&parentFrame);
|
|
|
|
}
|
2000-04-10 04:00:37 +00:00
|
|
|
else {
|
|
|
|
parentFrame = aParentFrameIn;
|
|
|
|
}
|
2000-04-04 01:28:15 +00:00
|
|
|
}
|
2000-04-04 04:57:08 +00:00
|
|
|
// Do not construct pseudo frames for trees
|
2000-08-03 00:22:36 +00:00
|
|
|
else if (MustGeneratePseudoParent(aPresContext, aParentFrameIn, tag.get(), aContent)) {
|
2000-04-04 01:28:15 +00:00
|
|
|
// this frame may have a pseudo parent, use block frame type to trigger foreign
|
|
|
|
GetParentFrame(aPresShell, aPresContext, aTableCreator, *aParentFrameIn,
|
|
|
|
nsLayoutAtoms::blockFrame, aState, parentFrame, aIsPseudoParent);
|
|
|
|
if (!aIsPseudoParent && !aState.mPseudoFrames.IsEmpty()) {
|
|
|
|
ProcessPseudoFrames(aPresContext, aState.mPseudoFrames, aChildItems);
|
|
|
|
}
|
|
|
|
//char buf[256];
|
|
|
|
//sprintf(buf, "anonymous frame constructed for %s", tag.get());
|
|
|
|
//NS_WARN_IF_FALSE(PR_FALSE, buf);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!parentFrame) return rv; // if pseudo frame wasn't created
|
|
|
|
|
2000-04-10 04:00:37 +00:00
|
|
|
// save the pseudo frame state XXX - why
|
2000-04-04 01:28:15 +00:00
|
|
|
nsPseudoFrames prevPseudoFrames;
|
|
|
|
aState.mPseudoFrames.Reset(&prevPseudoFrames);
|
|
|
|
|
|
|
|
nsFrameItems items;
|
|
|
|
rv = ConstructFrame(aPresShell, aPresContext, aState, aContent, parentFrame, items);
|
|
|
|
aNewFrame = items.childList;
|
|
|
|
|
2000-04-10 04:00:37 +00:00
|
|
|
// restore the pseudo frame state XXX - why
|
2000-04-04 01:28:15 +00:00
|
|
|
aState.mPseudoFrames = prevPseudoFrames;
|
|
|
|
|
|
|
|
if (aIsPseudoParent) {
|
|
|
|
aState.mPseudoFrames.mCellInner.mChildList.AddChild(aNewFrame);
|
1999-02-05 03:55:18 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
2000-04-04 01:28:15 +00:00
|
|
|
nsCSSFrameConstructor::TableProcessChildren(nsIPresShell* aPresShell,
|
1999-12-04 23:49:50 +00:00
|
|
|
nsIPresContext* aPresContext,
|
1999-04-28 19:08:14 +00:00
|
|
|
nsFrameConstructorState& aState,
|
|
|
|
nsIContent* aContent,
|
|
|
|
nsIFrame* aParentFrame,
|
2000-04-04 01:28:15 +00:00
|
|
|
nsTableCreator& aTableCreator,
|
1999-04-28 19:08:14 +00:00
|
|
|
nsFrameItems& aChildItems,
|
2000-04-04 01:28:15 +00:00
|
|
|
nsIFrame*& aCaption)
|
1999-02-05 03:55:18 +00:00
|
|
|
{
|
|
|
|
nsresult rv = NS_OK;
|
2000-04-04 01:28:15 +00:00
|
|
|
if (!aPresShell || !aPresContext || !aContent || !aParentFrame) return rv;
|
|
|
|
|
|
|
|
aCaption = nsnull;
|
|
|
|
|
|
|
|
// save the incoming pseudo frame state
|
|
|
|
nsPseudoFrames priorPseudoFrames;
|
|
|
|
aState.mPseudoFrames.Reset(&priorPseudoFrames);
|
1999-02-05 03:55:18 +00:00
|
|
|
|
2000-04-04 01:28:15 +00:00
|
|
|
nsCOMPtr<nsIAtom> parentFrameType;
|
|
|
|
aParentFrame->GetFrameType(getter_AddRefs(parentFrameType));
|
1999-02-11 15:54:13 +00:00
|
|
|
nsCOMPtr<nsIStyleContext> parentStyleContext;
|
|
|
|
aParentFrame->GetStyleContext(getter_AddRefs(parentStyleContext));
|
1999-02-05 03:55:18 +00:00
|
|
|
|
2000-04-04 01:28:15 +00:00
|
|
|
PRInt32 count;
|
1999-02-05 03:55:18 +00:00
|
|
|
aContent->ChildCount(count);
|
2000-04-04 01:28:15 +00:00
|
|
|
|
|
|
|
for (PRInt32 childX = 0; childX < count; childX++) { // iterate the child content
|
1999-02-11 15:54:13 +00:00
|
|
|
nsCOMPtr<nsIContent> childContent;
|
2000-04-04 01:28:15 +00:00
|
|
|
rv = aContent->ChildAt(childX, *getter_AddRefs(childContent));
|
|
|
|
if (childContent.get() && NS_SUCCEEDED(rv)) {
|
|
|
|
rv = TableProcessChild(aPresShell, aPresContext, aState, *childContent.get(), aParentFrame,
|
|
|
|
parentFrameType.get(), parentStyleContext.get(),
|
|
|
|
aTableCreator, aChildItems, aCaption);
|
|
|
|
}
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
}
|
|
|
|
// process the current pseudo frame state
|
|
|
|
if (!aState.mPseudoFrames.IsEmpty()) {
|
|
|
|
ProcessPseudoFrames(aPresContext, aState.mPseudoFrames, aChildItems);
|
1999-02-05 03:55:18 +00:00
|
|
|
}
|
|
|
|
|
2000-04-04 01:28:15 +00:00
|
|
|
// restore the incoming pseudo frame state
|
|
|
|
aState.mPseudoFrames = priorPseudoFrames;
|
1999-02-05 03:55:18 +00:00
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
2000-04-04 01:28:15 +00:00
|
|
|
nsCSSFrameConstructor::TableProcessChild(nsIPresShell* aPresShell,
|
1999-12-04 23:49:50 +00:00
|
|
|
nsIPresContext* aPresContext,
|
1999-04-28 19:08:14 +00:00
|
|
|
nsFrameConstructorState& aState,
|
2000-04-04 01:28:15 +00:00
|
|
|
nsIContent& aChildContent,
|
1999-04-28 19:08:14 +00:00
|
|
|
nsIFrame* aParentFrame,
|
2000-04-04 01:28:15 +00:00
|
|
|
nsIAtom* aParentFrameType,
|
1999-04-28 19:08:14 +00:00
|
|
|
nsIStyleContext* aParentStyleContext,
|
2000-04-04 01:28:15 +00:00
|
|
|
nsTableCreator& aTableCreator,
|
1999-04-28 19:08:14 +00:00
|
|
|
nsFrameItems& aChildItems,
|
2000-04-04 01:28:15 +00:00
|
|
|
nsIFrame*& aCaption)
|
1999-02-05 03:55:18 +00:00
|
|
|
{
|
|
|
|
nsresult rv = NS_OK;
|
1999-02-12 01:35:37 +00:00
|
|
|
|
2000-04-04 01:28:15 +00:00
|
|
|
PRBool childIsCaption = PR_FALSE;
|
|
|
|
PRBool isPseudoParent = PR_FALSE;
|
|
|
|
|
|
|
|
nsIFrame* childFrame = nsnull;
|
|
|
|
nsCOMPtr<nsIStyleContext> childStyleContext;
|
1999-02-05 03:55:18 +00:00
|
|
|
|
2000-04-04 01:28:15 +00:00
|
|
|
// Resolve the style context and get its display
|
|
|
|
aPresContext->ResolveStyleContextFor(&aChildContent, aParentStyleContext, PR_FALSE,
|
|
|
|
getter_AddRefs(childStyleContext));
|
|
|
|
const nsStyleDisplay* styleDisplay = (const nsStyleDisplay*)
|
|
|
|
childStyleContext->GetStyleData(eStyleStruct_Display);
|
|
|
|
|
|
|
|
switch (styleDisplay->mDisplay) {
|
|
|
|
case NS_STYLE_DISPLAY_TABLE:
|
|
|
|
nsIFrame* innerTableFrame;
|
|
|
|
rv = ConstructTableFrame(aPresShell, aPresContext, aState, &aChildContent, aParentFrame,
|
|
|
|
childStyleContext, aTableCreator, PR_FALSE, aChildItems,
|
|
|
|
childFrame, innerTableFrame, isPseudoParent);
|
|
|
|
break;
|
1999-02-11 23:08:28 +00:00
|
|
|
|
2000-04-04 01:28:15 +00:00
|
|
|
case NS_STYLE_DISPLAY_TABLE_CAPTION:
|
|
|
|
if (!aCaption) { // only allow one caption
|
|
|
|
nsIFrame* parentFrame = GetOuterTableFrame(aParentFrame);
|
|
|
|
rv = ConstructTableCaptionFrame(aPresShell, aPresContext, aState, &aChildContent,
|
|
|
|
parentFrame, childStyleContext, aTableCreator,
|
|
|
|
aChildItems, aCaption, isPseudoParent);
|
|
|
|
}
|
|
|
|
childIsCaption = PR_TRUE;
|
|
|
|
break;
|
1999-02-11 23:08:28 +00:00
|
|
|
|
2000-04-04 01:28:15 +00:00
|
|
|
case NS_STYLE_DISPLAY_TABLE_COLUMN_GROUP:
|
|
|
|
rv = ConstructTableColGroupFrame(aPresShell, aPresContext, aState, &aChildContent,
|
|
|
|
aParentFrame, childStyleContext, aTableCreator,
|
|
|
|
PR_FALSE, aChildItems, childFrame, isPseudoParent);
|
|
|
|
break;
|
1999-02-11 23:08:28 +00:00
|
|
|
|
2000-04-04 01:28:15 +00:00
|
|
|
case NS_STYLE_DISPLAY_TABLE_HEADER_GROUP:
|
|
|
|
case NS_STYLE_DISPLAY_TABLE_FOOTER_GROUP:
|
|
|
|
case NS_STYLE_DISPLAY_TABLE_ROW_GROUP:
|
|
|
|
rv = ConstructTableRowGroupFrame(aPresShell, aPresContext, aState, &aChildContent,
|
|
|
|
aParentFrame, childStyleContext, aTableCreator,
|
|
|
|
PR_FALSE, aChildItems, childFrame, isPseudoParent);
|
|
|
|
break;
|
1999-02-11 23:08:28 +00:00
|
|
|
|
2000-04-04 01:28:15 +00:00
|
|
|
case NS_STYLE_DISPLAY_TABLE_ROW:
|
|
|
|
rv = ConstructTableRowFrame(aPresShell, aPresContext, aState, &aChildContent,
|
|
|
|
aParentFrame, childStyleContext, aTableCreator,
|
|
|
|
PR_FALSE, aChildItems, childFrame, isPseudoParent);
|
|
|
|
break;
|
1999-02-11 23:08:28 +00:00
|
|
|
|
2000-04-04 01:28:15 +00:00
|
|
|
case NS_STYLE_DISPLAY_TABLE_COLUMN:
|
|
|
|
rv = ConstructTableColFrame(aPresShell, aPresContext, aState, &aChildContent,
|
|
|
|
aParentFrame, childStyleContext, aTableCreator,
|
|
|
|
PR_FALSE, aChildItems, childFrame, isPseudoParent);
|
|
|
|
break;
|
1999-09-21 01:15:30 +00:00
|
|
|
|
2000-04-01 22:26:38 +00:00
|
|
|
|
2000-04-04 01:28:15 +00:00
|
|
|
case NS_STYLE_DISPLAY_TABLE_CELL:
|
|
|
|
nsIFrame* innerCell;
|
|
|
|
rv = ConstructTableCellFrame(aPresShell, aPresContext, aState, &aChildContent,
|
|
|
|
aParentFrame, childStyleContext, aTableCreator, PR_FALSE,
|
|
|
|
aChildItems, childFrame, innerCell, isPseudoParent);
|
|
|
|
break;
|
1999-02-11 23:08:28 +00:00
|
|
|
|
2000-04-04 01:28:15 +00:00
|
|
|
default:
|
|
|
|
rv = ConstructTableForeignFrame(aPresShell, aPresContext, aState, &aChildContent,
|
|
|
|
aParentFrame, childStyleContext, aTableCreator,
|
|
|
|
aChildItems, childFrame, isPseudoParent);
|
|
|
|
break;
|
1999-02-05 03:55:18 +00:00
|
|
|
}
|
|
|
|
|
2000-04-04 01:28:15 +00:00
|
|
|
// for every table related frame except captions and ones with pseudo parents,
|
|
|
|
// link into the child list
|
|
|
|
if (childFrame && !childIsCaption && !isPseudoParent) {
|
|
|
|
aChildItems.AddChild(childFrame);
|
1999-02-05 03:55:18 +00:00
|
|
|
}
|
2000-04-04 01:28:15 +00:00
|
|
|
return rv;
|
1999-02-05 03:55:18 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
const nsStyleDisplay*
|
|
|
|
nsCSSFrameConstructor:: GetDisplay(nsIFrame* aFrame)
|
|
|
|
{
|
|
|
|
if (nsnull == aFrame) {
|
|
|
|
return nsnull;
|
|
|
|
}
|
1999-02-11 15:54:13 +00:00
|
|
|
nsCOMPtr<nsIStyleContext> styleContext;
|
|
|
|
aFrame->GetStyleContext(getter_AddRefs(styleContext));
|
1999-02-05 03:55:18 +00:00
|
|
|
const nsStyleDisplay* display =
|
|
|
|
(const nsStyleDisplay*)styleContext->GetStyleData(eStyleStruct_Display);
|
|
|
|
return display;
|
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************
|
|
|
|
* END TABLE SECTION
|
|
|
|
***********************************************/
|
|
|
|
|
1999-04-30 19:51:59 +00:00
|
|
|
nsresult
|
1999-12-04 23:49:50 +00:00
|
|
|
nsCSSFrameConstructor::ConstructDocElementTableFrame(nsIPresShell* aPresShell,
|
|
|
|
nsIPresContext* aPresContext,
|
1999-04-30 19:51:59 +00:00
|
|
|
nsIContent* aDocElement,
|
|
|
|
nsIFrame* aParentFrame,
|
1999-12-06 07:44:18 +00:00
|
|
|
nsIFrame*& aNewTableFrame,
|
|
|
|
nsILayoutHistoryState* aFrameState)
|
1999-04-30 19:51:59 +00:00
|
|
|
{
|
1999-12-06 07:44:18 +00:00
|
|
|
nsFrameConstructorState state(aPresContext, nsnull, nsnull, nsnull, aFrameState);
|
1999-04-30 19:51:59 +00:00
|
|
|
nsFrameItems frameItems;
|
|
|
|
|
1999-12-04 23:49:50 +00:00
|
|
|
ConstructFrame(aPresShell, aPresContext, state, aDocElement, aParentFrame, frameItems);
|
1999-04-30 19:51:59 +00:00
|
|
|
aNewTableFrame = frameItems.childList;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2000-04-19 02:13:43 +00:00
|
|
|
static PRBool
|
|
|
|
IsCanvasFrame(nsIFrame* aFrame)
|
|
|
|
{
|
|
|
|
nsCOMPtr<nsIAtom> parentType;
|
|
|
|
|
|
|
|
aFrame->GetFrameType(getter_AddRefs(parentType));
|
|
|
|
return parentType.get() == nsLayoutAtoms::canvasFrame;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
PropagateBackgroundToParent(nsIStyleContext* aStyleContext,
|
|
|
|
const nsStyleColor* aColor,
|
|
|
|
nsIStyleContext* aParentStyleContext)
|
|
|
|
{
|
|
|
|
nsStyleColor* mutableColor;
|
|
|
|
mutableColor = (nsStyleColor*)aParentStyleContext->GetMutableStyleData(eStyleStruct_Color);
|
|
|
|
|
|
|
|
mutableColor->mBackgroundAttachment = aColor->mBackgroundAttachment;
|
|
|
|
mutableColor->mBackgroundFlags = aColor->mBackgroundFlags | NS_STYLE_BG_PROPAGATED_FROM_CHILD;
|
|
|
|
mutableColor->mBackgroundRepeat = aColor->mBackgroundRepeat;
|
|
|
|
mutableColor->mBackgroundColor = aColor->mBackgroundColor;
|
|
|
|
mutableColor->mBackgroundXPosition = aColor->mBackgroundXPosition;
|
|
|
|
mutableColor->mBackgroundYPosition = aColor->mBackgroundYPosition;
|
|
|
|
mutableColor->mBackgroundImage = aColor->mBackgroundImage;
|
|
|
|
|
|
|
|
// Reset the BODY's background to transparent
|
|
|
|
mutableColor = (nsStyleColor*)aStyleContext->GetMutableStyleData(eStyleStruct_Color);
|
|
|
|
mutableColor->mBackgroundFlags = NS_STYLE_BG_COLOR_TRANSPARENT |
|
|
|
|
NS_STYLE_BG_IMAGE_NONE |
|
|
|
|
NS_STYLE_BG_PROPAGATED_TO_PARENT;
|
|
|
|
mutableColor->mBackgroundImage.SetLength(0);
|
|
|
|
mutableColor->mBackgroundAttachment = NS_STYLE_BG_ATTACHMENT_SCROLL;
|
|
|
|
}
|
|
|
|
|
1999-10-12 00:16:06 +00:00
|
|
|
/**
|
|
|
|
* New one
|
|
|
|
*/
|
|
|
|
nsresult
|
1999-12-04 23:49:50 +00:00
|
|
|
nsCSSFrameConstructor::ConstructDocElementFrame(nsIPresShell* aPresShell,
|
|
|
|
nsIPresContext* aPresContext,
|
1999-10-12 00:16:06 +00:00
|
|
|
nsFrameConstructorState& aState,
|
|
|
|
nsIContent* aDocElement,
|
|
|
|
nsIFrame* aParentFrame,
|
|
|
|
nsIStyleContext* aParentStyleContext,
|
|
|
|
nsIFrame*& aNewFrame)
|
|
|
|
{
|
1999-11-10 23:51:44 +00:00
|
|
|
// how the root frame hierarchy should look
|
1999-10-12 00:16:06 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
|
|
|
|
---------------No Scrollbars------
|
|
|
|
|
|
|
|
|
1999-11-10 23:51:44 +00:00
|
|
|
AreaFrame or BoxFrame (InitialContainingBlock)
|
1999-10-12 00:16:06 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
---------------Native Scrollbars------
|
|
|
|
|
|
|
|
|
|
|
|
|
1999-11-10 23:51:44 +00:00
|
|
|
ScrollFrame
|
1999-10-12 00:16:06 +00:00
|
|
|
|
|
|
|
^
|
|
|
|
|
|
1999-11-10 23:51:44 +00:00
|
|
|
AreaFrame or BoxFrame (InitialContainingBlock)
|
1999-10-12 00:16:06 +00:00
|
|
|
|
|
|
|
|
|
|
|
---------------Gfx Scrollbars ------
|
|
|
|
|
|
|
|
|
|
|
|
GfxScrollFrame
|
|
|
|
|
|
|
|
^
|
|
|
|
|
|
1999-11-10 23:51:44 +00:00
|
|
|
ScrollPort
|
1999-10-12 00:16:06 +00:00
|
|
|
|
|
|
|
^
|
|
|
|
|
|
1999-11-10 23:51:44 +00:00
|
|
|
AreaFrame or BoxFrame (InitialContainingBlock)
|
1999-10-12 00:16:06 +00:00
|
|
|
|
|
|
|
*/
|
|
|
|
|
2000-01-14 09:28:54 +00:00
|
|
|
if (!mTempFrameTreeState)
|
2000-03-24 03:37:03 +00:00
|
|
|
aPresShell->CaptureHistoryState(getter_AddRefs(mTempFrameTreeState));
|
2000-01-14 09:28:54 +00:00
|
|
|
|
1999-11-10 23:51:44 +00:00
|
|
|
// ----- reattach gfx scrollbars ------
|
|
|
|
// Gfx scrollframes were created in the root frame but the primary frame map may have been destroyed if a
|
|
|
|
// new style sheet was loaded so lets reattach the frames to their content.
|
|
|
|
if (mGfxScrollFrame)
|
|
|
|
{
|
|
|
|
nsIFrame* scrollPort = nsnull;
|
2000-01-22 01:16:50 +00:00
|
|
|
mGfxScrollFrame->FirstChild(aPresContext, nsnull, &scrollPort);
|
1999-11-10 23:51:44 +00:00
|
|
|
|
|
|
|
nsIFrame* gfxScrollbarFrame1 = nsnull;
|
|
|
|
nsIFrame* gfxScrollbarFrame2 = nsnull;
|
|
|
|
nsresult rv = scrollPort->GetNextSibling(&gfxScrollbarFrame1);
|
|
|
|
rv = gfxScrollbarFrame1->GetNextSibling(&gfxScrollbarFrame2);
|
|
|
|
nsCOMPtr<nsIContent> content;
|
|
|
|
gfxScrollbarFrame1->GetContent(getter_AddRefs(content));
|
|
|
|
aState.mFrameManager->SetPrimaryFrameFor(content, gfxScrollbarFrame1);
|
|
|
|
gfxScrollbarFrame2->GetContent(getter_AddRefs(content));
|
|
|
|
aState.mFrameManager->SetPrimaryFrameFor(content, gfxScrollbarFrame2);
|
|
|
|
}
|
|
|
|
|
1999-10-12 00:16:06 +00:00
|
|
|
// --------- CREATE AREA OR BOX FRAME -------
|
|
|
|
nsCOMPtr<nsIStyleContext> styleContext;
|
|
|
|
aPresContext->ResolveStyleContextFor(aDocElement, aParentStyleContext,
|
|
|
|
PR_FALSE,
|
|
|
|
getter_AddRefs(styleContext));
|
|
|
|
|
|
|
|
const nsStyleDisplay* display =
|
|
|
|
(const nsStyleDisplay*)styleContext->GetStyleData(eStyleStruct_Display);
|
2000-04-19 02:13:43 +00:00
|
|
|
const nsStyleColor* color =
|
|
|
|
(const nsStyleColor*)styleContext->GetStyleData(eStyleStruct_Color);
|
1999-10-12 00:16:06 +00:00
|
|
|
|
|
|
|
PRBool docElemIsTable = IsTableRelated(display->mDisplay);
|
|
|
|
|
|
|
|
|
|
|
|
// --------- IF SCROLLABLE WRAP IN SCROLLFRAME --------
|
|
|
|
|
|
|
|
PRBool isScrollable = IsScrollable(aPresContext, display);
|
|
|
|
PRBool isPaginated = PR_FALSE;
|
|
|
|
aPresContext->IsPaginated(&isPaginated);
|
1999-10-12 20:50:01 +00:00
|
|
|
nsIFrame* scrollFrame = nsnull;
|
1999-10-12 00:16:06 +00:00
|
|
|
|
|
|
|
// build a scrollframe
|
|
|
|
if (!isPaginated && isScrollable) {
|
|
|
|
nsIFrame* newScrollFrame = nsnull;
|
1999-11-02 05:36:08 +00:00
|
|
|
nsCOMPtr<nsIDocument> document;
|
|
|
|
aDocElement->GetDocument(*getter_AddRefs(document));
|
1999-12-08 01:56:28 +00:00
|
|
|
nsCOMPtr<nsIStyleContext> newContext;
|
|
|
|
|
1999-12-04 23:49:50 +00:00
|
|
|
BeginBuildingScrollFrame( aPresShell, aPresContext,
|
1999-10-12 00:16:06 +00:00
|
|
|
aState,
|
|
|
|
aDocElement,
|
|
|
|
styleContext,
|
|
|
|
aParentFrame,
|
|
|
|
nsLayoutAtoms::scrolledContentPseudo,
|
|
|
|
document,
|
2000-03-31 07:02:06 +00:00
|
|
|
PR_FALSE,
|
1999-10-12 20:50:01 +00:00
|
|
|
scrollFrame,
|
1999-12-08 01:56:28 +00:00
|
|
|
newContext,
|
1999-10-12 00:16:06 +00:00
|
|
|
newScrollFrame);
|
|
|
|
|
1999-12-08 01:56:28 +00:00
|
|
|
styleContext = newContext;
|
1999-10-12 00:16:06 +00:00
|
|
|
aParentFrame = newScrollFrame;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsIFrame* contentFrame = nsnull;
|
|
|
|
PRBool isBlockFrame = PR_FALSE;
|
|
|
|
|
|
|
|
if (docElemIsTable) {
|
|
|
|
// if the document is a table then just populate it.
|
1999-12-06 07:44:18 +00:00
|
|
|
ConstructDocElementTableFrame(aPresShell, aPresContext, aDocElement,
|
|
|
|
aParentFrame, contentFrame,
|
|
|
|
aState.mFrameState);
|
1999-10-12 00:16:06 +00:00
|
|
|
contentFrame->GetStyleContext(getter_AddRefs(styleContext));
|
|
|
|
} else {
|
|
|
|
// otherwise build a box or a block
|
|
|
|
PRInt32 nameSpaceID;
|
|
|
|
if (NS_SUCCEEDED(aDocElement->GetNameSpaceID(nameSpaceID)) &&
|
|
|
|
nameSpaceID == nsXULAtoms::nameSpaceID) {
|
2000-03-02 03:01:30 +00:00
|
|
|
NS_NewBoxFrame(aPresShell, &contentFrame, PR_TRUE);
|
1999-10-12 00:16:06 +00:00
|
|
|
}
|
|
|
|
else {
|
1999-12-04 23:49:50 +00:00
|
|
|
NS_NewDocumentElementFrame(aPresShell, &contentFrame);
|
1999-10-12 00:16:06 +00:00
|
|
|
isBlockFrame = PR_TRUE;
|
2000-04-01 00:18:21 +00:00
|
|
|
|
|
|
|
// Since we always create a block frame, we need to make sure that the
|
|
|
|
// style context's display type is block level.
|
|
|
|
nsStyleDisplay* disp = (nsStyleDisplay*)styleContext->GetMutableStyleData(eStyleStruct_Display);
|
|
|
|
disp->mDisplay = NS_STYLE_DISPLAY_BLOCK;
|
1999-10-12 00:16:06 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// initialize the child
|
1999-12-06 07:44:18 +00:00
|
|
|
InitAndRestoreFrame(aPresContext, aState, aDocElement,
|
|
|
|
aParentFrame, styleContext, nsnull, contentFrame);
|
1999-10-12 00:16:06 +00:00
|
|
|
}
|
|
|
|
|
2000-01-27 20:21:28 +00:00
|
|
|
// set the primary frame
|
|
|
|
aState.mFrameManager->SetPrimaryFrameFor(aDocElement, contentFrame);
|
|
|
|
|
1999-10-12 00:16:06 +00:00
|
|
|
// Finish building the scrollframe
|
|
|
|
if (isScrollable) {
|
|
|
|
FinishBuildingScrollFrame(aPresContext,
|
|
|
|
aState,
|
|
|
|
aDocElement,
|
|
|
|
aParentFrame,
|
|
|
|
contentFrame,
|
|
|
|
styleContext);
|
2000-01-31 14:04:41 +00:00
|
|
|
// primary is set above (to the contentFrame)
|
|
|
|
|
|
|
|
aNewFrame = scrollFrame;
|
1999-10-12 20:50:01 +00:00
|
|
|
} else {
|
|
|
|
// if not scrollable the new frame is the content frame.
|
|
|
|
aNewFrame = contentFrame;
|
1999-10-12 00:16:06 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
mInitialContainingBlock = contentFrame;
|
|
|
|
|
|
|
|
// if it was a table then we don't need to process our children.
|
|
|
|
if (!docElemIsTable) {
|
|
|
|
// Process the child content
|
|
|
|
nsFrameConstructorSaveState absoluteSaveState;
|
|
|
|
nsFrameConstructorSaveState floaterSaveState;
|
|
|
|
nsFrameItems childItems;
|
|
|
|
|
|
|
|
// XXX these next lines are wrong for BoxFrame
|
|
|
|
PRBool haveFirstLetterStyle, haveFirstLineStyle;
|
|
|
|
HaveSpecialBlockStyle(aPresContext, aDocElement, styleContext,
|
|
|
|
&haveFirstLetterStyle, &haveFirstLineStyle);
|
|
|
|
aState.PushAbsoluteContainingBlock(contentFrame, absoluteSaveState);
|
|
|
|
aState.PushFloaterContainingBlock(contentFrame, floaterSaveState,
|
|
|
|
haveFirstLetterStyle,
|
|
|
|
haveFirstLineStyle);
|
1999-12-04 23:49:50 +00:00
|
|
|
ProcessChildren(aPresShell, aPresContext, aState, aDocElement, contentFrame,
|
1999-10-12 00:16:06 +00:00
|
|
|
PR_TRUE, childItems, isBlockFrame);
|
|
|
|
|
|
|
|
// See if the document element has a fixed background attachment.
|
|
|
|
// Note: the reason we wait until after processing the document element's
|
|
|
|
// children is because of special treatment of the background for the HTML
|
|
|
|
// element. See BodyFixupRule::MapStyleInto() for details
|
|
|
|
if (NS_STYLE_BG_ATTACHMENT_FIXED == color->mBackgroundAttachment) {
|
|
|
|
// Fixed background attachments are handled by setting the
|
|
|
|
// NS_VIEW_PUBLIC_FLAG_DONT_BITBLT flag bit on the view.
|
|
|
|
//
|
|
|
|
// If the document element's frame is scrollable, then set the bit on its
|
|
|
|
// view; otherwise, set it on the root frame's view. This avoids
|
|
|
|
// unnecessarily creating another view and should be faster
|
|
|
|
nsIView* view;
|
|
|
|
|
|
|
|
if (IsScrollable(aPresContext, display)) {
|
1999-10-26 04:44:41 +00:00
|
|
|
contentFrame->GetView(aPresContext, &view);
|
1999-10-12 00:16:06 +00:00
|
|
|
} else {
|
|
|
|
nsIFrame* parentFrame;
|
|
|
|
|
|
|
|
contentFrame->GetParent(&parentFrame);
|
1999-10-26 04:44:41 +00:00
|
|
|
parentFrame->GetView(aPresContext, &view);
|
1999-10-12 00:16:06 +00:00
|
|
|
}
|
|
|
|
|
2000-03-09 05:54:58 +00:00
|
|
|
// Not all shells have scroll frames, even in scrollable presContext (bug 30317)
|
|
|
|
if (view) {
|
|
|
|
PRUint32 viewFlags;
|
|
|
|
view->GetViewFlags(&viewFlags);
|
|
|
|
view->SetViewFlags(viewFlags | NS_VIEW_PUBLIC_FLAG_DONT_BITBLT);
|
|
|
|
}
|
1999-10-12 00:16:06 +00:00
|
|
|
}
|
2000-02-10 21:36:28 +00:00
|
|
|
|
1999-10-12 00:16:06 +00:00
|
|
|
// Set the initial child lists
|
1999-11-24 06:03:41 +00:00
|
|
|
contentFrame->SetInitialChildList(aPresContext, nsnull,
|
2000-02-10 21:36:28 +00:00
|
|
|
childItems.childList);
|
|
|
|
|
2000-04-04 06:29:20 +00:00
|
|
|
// Create any anonymous frames the doc element frame requires
|
|
|
|
CreateAnonymousFrames(aPresShell, aPresContext, nsnull, aState, aDocElement, contentFrame,
|
|
|
|
childItems);
|
|
|
|
|
2000-02-10 21:36:28 +00:00
|
|
|
// only support absolute positioning if we are a block.
|
|
|
|
// if we are a box don't do it.
|
|
|
|
if (isBlockFrame) {
|
|
|
|
if (aState.mAbsoluteItems.childList) {
|
|
|
|
contentFrame->SetInitialChildList(aPresContext,
|
|
|
|
nsLayoutAtoms::absoluteList,
|
|
|
|
aState.mAbsoluteItems.childList);
|
|
|
|
}
|
|
|
|
if (aState.mFloatedItems.childList) {
|
|
|
|
contentFrame->SetInitialChildList(aPresContext,
|
|
|
|
nsLayoutAtoms::floaterList,
|
|
|
|
aState.mFloatedItems.childList);
|
|
|
|
}
|
1999-10-12 00:16:06 +00:00
|
|
|
}
|
2000-04-19 02:13:43 +00:00
|
|
|
|
2000-05-10 03:31:43 +00:00
|
|
|
// this is not sufficient: if the background gets changed via DOM after
|
|
|
|
// frame construction we need to do this again...
|
2000-05-06 06:04:08 +00:00
|
|
|
|
2000-04-19 02:13:43 +00:00
|
|
|
// Section 14.2 of the CSS2 spec says that the background of the root element
|
|
|
|
// covers the entire canvas. See if a background was specified for the root
|
|
|
|
// element
|
|
|
|
if (!color->BackgroundIsTransparent() && IsCanvasFrame(aParentFrame)) {
|
|
|
|
nsIStyleContext* parentContext;
|
|
|
|
|
|
|
|
// Propagate the document element's background to the canvas so that it
|
|
|
|
// renders the background over the entire canvas
|
|
|
|
aParentFrame->GetStyleContext(&parentContext);
|
|
|
|
PropagateBackgroundToParent(styleContext, color, parentContext);
|
|
|
|
NS_RELEASE(parentContext);
|
|
|
|
}
|
1999-10-12 00:16:06 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
1999-04-30 19:51:59 +00:00
|
|
|
|
1999-10-12 00:16:06 +00:00
|
|
|
|
1999-08-19 22:16:23 +00:00
|
|
|
NS_IMETHODIMP
|
1999-12-04 23:49:50 +00:00
|
|
|
nsCSSFrameConstructor::ConstructRootFrame(nsIPresShell* aPresShell,
|
|
|
|
nsIPresContext* aPresContext,
|
1999-08-19 22:16:23 +00:00
|
|
|
nsIContent* aDocElement,
|
|
|
|
nsIFrame*& aNewFrame)
|
|
|
|
{
|
|
|
|
|
1999-10-12 00:16:06 +00:00
|
|
|
// how the root frame hierarchy should look
|
1999-08-19 22:16:23 +00:00
|
|
|
|
1999-10-12 00:16:06 +00:00
|
|
|
/*
|
1999-08-19 22:16:23 +00:00
|
|
|
|
1999-10-12 00:16:06 +00:00
|
|
|
---------------No Scrollbars------
|
|
|
|
|
|
|
|
|
|
|
|
|
1999-11-10 23:51:44 +00:00
|
|
|
ViewPortFrame (FixedContainingBlock) <---- RootView
|
1999-10-12 00:16:06 +00:00
|
|
|
|
|
|
|
^
|
|
|
|
|
|
|
|
|
RootFrame(DocElementContainingBlock)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
---------------Native Scrollbars------
|
|
|
|
|
|
|
|
|
|
|
|
|
1999-11-10 23:51:44 +00:00
|
|
|
ViewPortFrame (FixedContainingBlock) <---- RootView
|
1999-10-12 00:16:06 +00:00
|
|
|
|
|
|
|
^
|
|
|
|
|
|
1999-11-10 23:51:44 +00:00
|
|
|
ScrollFrame <--- RootScrollableView
|
1999-10-12 00:16:06 +00:00
|
|
|
|
|
|
|
^
|
|
|
|
|
|
|
|
|
RootFrame(DocElementContainingBlock)
|
|
|
|
|
|
|
|
|
|
|
|
---------------Gfx Scrollbars ------
|
|
|
|
|
|
|
|
|
1999-11-10 23:51:44 +00:00
|
|
|
ViewPortFrame (FixedContainingBlock) <---- RootView
|
1999-10-12 00:16:06 +00:00
|
|
|
|
|
|
|
^
|
|
|
|
|
|
|
|
|
GfxScrollFrame
|
|
|
|
|
|
|
|
^
|
|
|
|
|
|
1999-11-10 23:51:44 +00:00
|
|
|
ScrollPort <--- RootScrollableView
|
1999-10-12 00:16:06 +00:00
|
|
|
|
|
|
|
^
|
|
|
|
|
|
|
|
|
RootFrame(DocElementContainingBlock)
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
// --------- BUILD VIEWPORT -----------
|
|
|
|
nsIFrame* viewportFrame = nsnull;
|
|
|
|
nsCOMPtr<nsIStyleContext> viewportPseudoStyle;
|
1999-08-19 22:16:23 +00:00
|
|
|
|
|
|
|
aPresContext->ResolvePseudoStyleContextFor(nsnull, nsLayoutAtoms::viewportPseudo,
|
1999-10-12 00:16:06 +00:00
|
|
|
nsnull, PR_FALSE,
|
|
|
|
getter_AddRefs(viewportPseudoStyle));
|
1999-08-19 22:16:23 +00:00
|
|
|
|
|
|
|
{ // ensure that the viewport thinks it is a block frame, layout goes pootsy if it doesn't
|
|
|
|
nsStyleDisplay* display = (nsStyleDisplay*)viewportPseudoStyle->GetMutableStyleData(eStyleStruct_Display);
|
|
|
|
display->mDisplay = NS_STYLE_DISPLAY_BLOCK;
|
|
|
|
}
|
|
|
|
|
1999-12-04 23:49:50 +00:00
|
|
|
NS_NewViewportFrame(aPresShell, &viewportFrame);
|
1999-10-12 00:16:06 +00:00
|
|
|
|
|
|
|
|
1999-11-24 06:03:41 +00:00
|
|
|
viewportFrame->Init(aPresContext, nsnull, nsnull, viewportPseudoStyle, nsnull);
|
1999-08-19 22:16:23 +00:00
|
|
|
|
|
|
|
// Bind the viewport frame to the root view
|
|
|
|
nsCOMPtr<nsIPresShell> presShell;
|
|
|
|
aPresContext->GetShell(getter_AddRefs(presShell));
|
|
|
|
nsCOMPtr<nsIViewManager> viewManager;
|
|
|
|
presShell->GetViewManager(getter_AddRefs(viewManager));
|
|
|
|
nsIView* rootView;
|
|
|
|
|
|
|
|
viewManager->GetRootView(rootView);
|
1999-10-26 04:44:41 +00:00
|
|
|
viewportFrame->SetView(aPresContext, rootView);
|
1999-08-19 22:16:23 +00:00
|
|
|
|
1999-10-12 00:16:06 +00:00
|
|
|
// The viewport is the containing block for 'fixed' elements
|
|
|
|
mFixedContainingBlock = viewportFrame;
|
|
|
|
|
|
|
|
// --------- CREATE ROOT FRAME -------
|
|
|
|
|
|
|
|
|
|
|
|
// Create the root frame. The document element's frame is a child of the
|
|
|
|
// root frame.
|
|
|
|
//
|
|
|
|
// The root frame serves two purposes:
|
|
|
|
// - reserves space for any margins needed for the document element's frame
|
2000-04-19 02:13:43 +00:00
|
|
|
// - renders the document element's background. This ensures the background covers
|
|
|
|
// the entire canvas as specified by the CSS2 spec
|
1999-10-12 00:16:06 +00:00
|
|
|
|
|
|
|
PRBool isPaginated = PR_FALSE;
|
|
|
|
aPresContext->IsPaginated(&isPaginated);
|
|
|
|
nsIFrame* rootFrame = nsnull;
|
|
|
|
nsIAtom* rootPseudo;
|
|
|
|
|
|
|
|
if (!isPaginated) {
|
2000-03-31 07:02:06 +00:00
|
|
|
PRInt32 nameSpaceID;
|
|
|
|
if (NS_SUCCEEDED(aDocElement->GetNameSpaceID(nameSpaceID)) &&
|
|
|
|
nameSpaceID == nsXULAtoms::nameSpaceID)
|
|
|
|
{
|
|
|
|
NS_NewRootBoxFrame(aPresShell, &rootFrame);
|
|
|
|
} else {
|
2000-04-19 02:13:43 +00:00
|
|
|
NS_NewCanvasFrame(aPresShell, &rootFrame);
|
2000-03-31 07:02:06 +00:00
|
|
|
}
|
|
|
|
|
1999-10-12 00:16:06 +00:00
|
|
|
rootPseudo = nsLayoutAtoms::canvasPseudo;
|
|
|
|
mDocElementContainingBlock = rootFrame;
|
|
|
|
} else {
|
|
|
|
// Create a page sequence frame
|
1999-12-04 23:49:50 +00:00
|
|
|
NS_NewSimplePageSequenceFrame(aPresShell, &rootFrame);
|
1999-10-12 00:16:06 +00:00
|
|
|
rootPseudo = nsLayoutAtoms::pageSequencePseudo;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// --------- IF SCROLLABLE WRAP IN SCROLLFRAME --------
|
|
|
|
|
|
|
|
// If the device supports scrolling (e.g., in galley mode on the screen and
|
1999-08-19 22:16:23 +00:00
|
|
|
// for print-preview, but not when printing), then create a scroll frame that
|
|
|
|
// will act as the scrolling mechanism for the viewport.
|
|
|
|
// XXX Do we even need a viewport when printing to a printer?
|
|
|
|
// XXX It would be nice to have a better way to query for whether the device
|
|
|
|
// is scrollable
|
|
|
|
PRBool isScrollable = PR_TRUE;
|
|
|
|
if (aPresContext) {
|
|
|
|
nsIDeviceContext* dc;
|
|
|
|
aPresContext->GetDeviceContext(&dc);
|
|
|
|
if (dc) {
|
|
|
|
PRBool supportsWidgets;
|
|
|
|
if (NS_SUCCEEDED(dc->SupportsNativeWidgets(supportsWidgets))) {
|
|
|
|
isScrollable = supportsWidgets;
|
|
|
|
}
|
|
|
|
NS_RELEASE(dc);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2000-03-31 07:02:06 +00:00
|
|
|
//isScrollable = PR_FALSE;
|
|
|
|
|
1999-08-19 22:16:23 +00:00
|
|
|
// As long as the webshell doesn't prohibit it, and the device supports
|
|
|
|
// it, create a scroll frame that will act as the scolling mechanism for
|
|
|
|
// the viewport.
|
2000-02-29 06:51:04 +00:00
|
|
|
//
|
|
|
|
// Threre are three possible values stored in the docshell:
|
|
|
|
// 1) NS_STYLE_OVERFLOW_HIDDEN = no scrollbars
|
|
|
|
// 2) NS_STYLE_OVERFLOW_AUTO = scrollbars appear if needed
|
|
|
|
// 3) NS_STYLE_OVERFLOW_SCROLL = scrollbars always
|
|
|
|
// Only need to create a scroll frame/view for cases 2 and 3.
|
|
|
|
// Currently OVERFLOW_SCROLL isn't honored, as
|
|
|
|
// scrollportview::SetScrollPref is not implemented.
|
|
|
|
PRInt32 nameSpaceID; // Never create scrollbars for XUL documents
|
|
|
|
if (NS_SUCCEEDED(aDocElement->GetNameSpaceID(nameSpaceID)) &&
|
|
|
|
nameSpaceID == nsXULAtoms::nameSpaceID) {
|
|
|
|
isScrollable = PR_FALSE;
|
|
|
|
} else {
|
|
|
|
nsresult rv;
|
|
|
|
nsCOMPtr<nsISupports> container;
|
|
|
|
if (nsnull != aPresContext) {
|
|
|
|
aPresContext->GetContainer(getter_AddRefs(container));
|
|
|
|
if (nsnull != container) {
|
|
|
|
nsCOMPtr<nsIScrollable> scrollableContainer = do_QueryInterface(container, &rv);
|
|
|
|
if (NS_SUCCEEDED(rv) && scrollableContainer) {
|
|
|
|
PRInt32 scrolling = -1;
|
|
|
|
// XXX We should get prefs for X and Y and deal with these independently!
|
|
|
|
scrollableContainer->GetCurrentScrollbarPreferences(nsIScrollable::ScrollOrientation_Y,&scrolling);
|
|
|
|
if (NS_STYLE_OVERFLOW_HIDDEN == scrolling) {
|
|
|
|
isScrollable = PR_FALSE;
|
|
|
|
}
|
|
|
|
// XXX NS_STYLE_OVERFLOW_SCROLL should create 'always on' scrollbars
|
1999-08-19 22:16:23 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1999-10-12 00:16:06 +00:00
|
|
|
nsIFrame* newFrame = rootFrame;
|
|
|
|
nsCOMPtr<nsIStyleContext> rootPseudoStyle;
|
|
|
|
// we must create a state because if the scrollbars are GFX it needs the
|
|
|
|
// state to build the scrollbar frames.
|
|
|
|
nsFrameConstructorState state(aPresContext,
|
1999-12-06 07:44:18 +00:00
|
|
|
nsnull,
|
1999-10-12 00:16:06 +00:00
|
|
|
nsnull,
|
|
|
|
nsnull,
|
|
|
|
nsnull);
|
1999-08-19 22:16:23 +00:00
|
|
|
|
1999-10-12 00:16:06 +00:00
|
|
|
nsIFrame* parentFrame = viewportFrame;
|
1999-08-19 22:16:23 +00:00
|
|
|
|
1999-10-12 00:16:06 +00:00
|
|
|
if (isScrollable) {
|
1999-08-19 22:16:23 +00:00
|
|
|
|
1999-10-12 00:16:06 +00:00
|
|
|
// built the frame. We give it the content we are wrapping which is the document,
|
|
|
|
// the root frame, the parent view port frame, and we should get back the new
|
|
|
|
// frame and the scrollable view if one was created.
|
1999-08-19 22:16:23 +00:00
|
|
|
|
1999-10-12 00:16:06 +00:00
|
|
|
// resolve a context for the scrollframe
|
|
|
|
nsCOMPtr<nsIStyleContext> styleContext;
|
|
|
|
aPresContext->ResolvePseudoStyleContextFor(nsnull,
|
1999-12-08 01:56:28 +00:00
|
|
|
nsLayoutAtoms::viewportScrollPseudo,
|
|
|
|
viewportPseudoStyle, PR_FALSE,
|
|
|
|
getter_AddRefs(styleContext));
|
1999-10-12 00:16:06 +00:00
|
|
|
|
|
|
|
|
|
|
|
nsIFrame* newScrollableFrame = nsnull;
|
1999-11-02 06:40:38 +00:00
|
|
|
nsCOMPtr<nsIDocument> document;
|
|
|
|
aDocElement->GetDocument(*getter_AddRefs(document));
|
1999-10-12 00:16:06 +00:00
|
|
|
|
1999-12-04 23:49:50 +00:00
|
|
|
BeginBuildingScrollFrame( aPresShell,
|
|
|
|
aPresContext,
|
1999-10-12 00:16:06 +00:00
|
|
|
state,
|
|
|
|
nsnull,
|
|
|
|
styleContext,
|
|
|
|
viewportFrame,
|
|
|
|
rootPseudo,
|
|
|
|
document,
|
2000-03-31 07:02:06 +00:00
|
|
|
PR_TRUE,
|
1999-10-12 00:16:06 +00:00
|
|
|
newFrame,
|
|
|
|
rootPseudoStyle,
|
|
|
|
newScrollableFrame);
|
|
|
|
|
|
|
|
// Inform the view manager about the root scrollable view
|
|
|
|
// get the scrolling view
|
|
|
|
nsIView* view = nsnull;
|
1999-10-26 04:44:41 +00:00
|
|
|
newScrollableFrame->GetView(aPresContext, &view);
|
1999-10-12 00:16:06 +00:00
|
|
|
nsIScrollableView* scrollableView;
|
|
|
|
view->QueryInterface(kScrollViewIID, (void**)&scrollableView);
|
|
|
|
viewManager->SetRootScrollableView(scrollableView);
|
|
|
|
parentFrame = newScrollableFrame;
|
1999-11-10 23:51:44 +00:00
|
|
|
|
|
|
|
// if gfx scrollbars store them
|
2000-03-27 22:12:42 +00:00
|
|
|
if (HasGfxScrollbars()) {
|
1999-11-10 23:51:44 +00:00
|
|
|
mGfxScrollFrame = newFrame;
|
|
|
|
} else {
|
|
|
|
mGfxScrollFrame = nsnull;
|
|
|
|
}
|
1999-10-12 00:16:06 +00:00
|
|
|
} else {
|
|
|
|
aPresContext->ResolvePseudoStyleContextFor(nsnull, rootPseudo,
|
|
|
|
viewportPseudoStyle,
|
|
|
|
PR_FALSE,
|
|
|
|
getter_AddRefs(rootPseudoStyle));
|
1999-08-19 22:16:23 +00:00
|
|
|
}
|
|
|
|
|
1999-11-24 06:03:41 +00:00
|
|
|
rootFrame->Init(aPresContext, nsnull, parentFrame, rootPseudoStyle, nsnull);
|
1999-10-12 00:16:06 +00:00
|
|
|
|
|
|
|
if (isScrollable) {
|
|
|
|
FinishBuildingScrollFrame(aPresContext,
|
|
|
|
state,
|
|
|
|
aDocElement,
|
|
|
|
parentFrame,
|
|
|
|
rootFrame,
|
|
|
|
rootPseudoStyle);
|
2000-01-31 14:04:41 +00:00
|
|
|
|
|
|
|
// set the primary frame to the root frame
|
|
|
|
state.mFrameManager->SetPrimaryFrameFor(aDocElement, rootFrame);
|
1999-10-12 00:16:06 +00:00
|
|
|
}
|
1999-08-19 22:16:23 +00:00
|
|
|
|
1999-10-12 00:16:06 +00:00
|
|
|
if (isPaginated) {
|
1999-08-19 22:16:23 +00:00
|
|
|
// Create the first page
|
|
|
|
nsIFrame* pageFrame;
|
1999-12-04 23:49:50 +00:00
|
|
|
NS_NewPageFrame(aPresShell, &pageFrame);
|
1999-08-19 22:16:23 +00:00
|
|
|
|
|
|
|
// The page is the containing block for 'fixed' elements. which are repeated
|
|
|
|
// on every page
|
|
|
|
mFixedContainingBlock = pageFrame;
|
|
|
|
|
|
|
|
// Initialize the page and force it to have a view. This makes printing of
|
|
|
|
// the pages easier and faster.
|
|
|
|
nsCOMPtr<nsIStyleContext> pagePseudoStyle;
|
|
|
|
|
|
|
|
aPresContext->ResolvePseudoStyleContextFor(nsnull, nsLayoutAtoms::pagePseudo,
|
1999-10-12 00:16:06 +00:00
|
|
|
rootPseudoStyle, PR_FALSE,
|
1999-08-19 22:16:23 +00:00
|
|
|
getter_AddRefs(pagePseudoStyle));
|
|
|
|
|
1999-11-24 06:03:41 +00:00
|
|
|
pageFrame->Init(aPresContext, nsnull, rootFrame, pagePseudoStyle,
|
1999-08-19 22:16:23 +00:00
|
|
|
nsnull);
|
1999-11-24 06:03:41 +00:00
|
|
|
nsHTMLContainerFrame::CreateViewForFrame(aPresContext, pageFrame,
|
1999-08-19 22:16:23 +00:00
|
|
|
pagePseudoStyle, PR_TRUE);
|
|
|
|
|
|
|
|
// The eventual parent of the document element frame
|
|
|
|
mDocElementContainingBlock = pageFrame;
|
|
|
|
|
|
|
|
|
|
|
|
// Set the initial child lists
|
1999-11-24 06:03:41 +00:00
|
|
|
rootFrame->SetInitialChildList(aPresContext, nsnull, pageFrame);
|
1999-10-12 00:16:06 +00:00
|
|
|
|
|
|
|
}
|
|
|
|
|
1999-11-24 06:03:41 +00:00
|
|
|
viewportFrame->SetInitialChildList(aPresContext, nsnull, newFrame);
|
1999-10-12 00:16:06 +00:00
|
|
|
|
|
|
|
aNewFrame = viewportFrame;
|
1999-11-10 23:51:44 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
1999-10-12 00:16:06 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
1999-02-05 03:55:18 +00:00
|
|
|
nsresult
|
1999-12-04 23:49:50 +00:00
|
|
|
nsCSSFrameConstructor::CreatePlaceholderFrameFor(nsIPresShell* aPresShell,
|
|
|
|
nsIPresContext* aPresContext,
|
1999-08-05 03:09:22 +00:00
|
|
|
nsIFrameManager* aFrameManager,
|
1999-02-05 03:55:18 +00:00
|
|
|
nsIContent* aContent,
|
|
|
|
nsIFrame* aFrame,
|
|
|
|
nsIStyleContext* aStyleContext,
|
|
|
|
nsIFrame* aParentFrame,
|
1999-04-25 16:58:42 +00:00
|
|
|
nsIFrame** aPlaceholderFrame)
|
1999-02-05 03:55:18 +00:00
|
|
|
{
|
1999-04-25 16:58:42 +00:00
|
|
|
nsPlaceholderFrame* placeholderFrame;
|
1999-12-04 23:49:50 +00:00
|
|
|
nsresult rv = NS_NewPlaceholderFrame(aPresShell, (nsIFrame**)&placeholderFrame);
|
1999-02-05 03:55:18 +00:00
|
|
|
|
|
|
|
if (NS_SUCCEEDED(rv)) {
|
|
|
|
// The placeholder frame gets a pseudo style context
|
1999-02-11 15:54:13 +00:00
|
|
|
nsCOMPtr<nsIStyleContext> placeholderPseudoStyle;
|
|
|
|
aPresContext->ResolvePseudoStyleContextFor(aContent, nsHTMLAtoms::placeholderPseudo,
|
|
|
|
aStyleContext,
|
1999-02-12 17:45:58 +00:00
|
|
|
PR_FALSE,
|
1999-02-11 15:54:13 +00:00
|
|
|
getter_AddRefs(placeholderPseudoStyle));
|
1999-11-24 06:03:41 +00:00
|
|
|
placeholderFrame->Init(aPresContext, aContent, aParentFrame,
|
1999-02-25 03:27:57 +00:00
|
|
|
placeholderPseudoStyle, nsnull);
|
1999-02-05 03:55:18 +00:00
|
|
|
|
|
|
|
// Add mapping from absolutely positioned frame to its placeholder frame
|
1999-08-05 03:09:22 +00:00
|
|
|
aFrameManager->SetPlaceholderFrameFor(aFrame, placeholderFrame);
|
1999-02-05 03:55:18 +00:00
|
|
|
|
1999-04-25 16:58:42 +00:00
|
|
|
// The placeholder frame has a pointer back to the out-of-flow frame
|
|
|
|
placeholderFrame->SetOutOfFlowFrame(aFrame);
|
1999-02-26 17:11:54 +00:00
|
|
|
|
1999-04-25 16:58:42 +00:00
|
|
|
*aPlaceholderFrame = NS_STATIC_CAST(nsIFrame*, placeholderFrame);
|
1999-02-26 17:11:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
1999-08-06 05:11:39 +00:00
|
|
|
|
|
|
|
nsWidgetRendering
|
|
|
|
nsCSSFrameConstructor::GetFormElementRenderingMode(nsIPresContext* aPresContext,
|
|
|
|
nsWidgetType aWidgetType)
|
|
|
|
{
|
|
|
|
if (!aPresContext) { return eWidgetRendering_Gfx;}
|
|
|
|
|
|
|
|
nsWidgetRendering mode;
|
|
|
|
aPresContext->GetWidgetRenderingMode(&mode);
|
|
|
|
|
|
|
|
switch (mode)
|
|
|
|
{
|
|
|
|
case eWidgetRendering_Gfx:
|
|
|
|
return eWidgetRendering_Gfx;
|
|
|
|
|
|
|
|
case eWidgetRendering_PartialGfx:
|
|
|
|
switch (aWidgetType)
|
|
|
|
{
|
|
|
|
case eWidgetType_Button:
|
|
|
|
case eWidgetType_Checkbox:
|
|
|
|
case eWidgetType_Radio:
|
|
|
|
case eWidgetType_Text:
|
|
|
|
return eWidgetRendering_Gfx;
|
|
|
|
|
|
|
|
default:
|
|
|
|
return eWidgetRendering_Native;
|
|
|
|
}
|
|
|
|
|
|
|
|
case eWidgetRendering_Native:
|
|
|
|
PRBool useNativeWidgets = PR_FALSE;
|
|
|
|
nsIDeviceContext* dc;
|
|
|
|
aPresContext->GetDeviceContext(&dc);
|
|
|
|
if (dc) {
|
|
|
|
PRBool supportsWidgets;
|
|
|
|
if (NS_SUCCEEDED(dc->SupportsNativeWidgets(supportsWidgets))) {
|
|
|
|
useNativeWidgets = supportsWidgets;
|
|
|
|
}
|
|
|
|
NS_RELEASE(dc);
|
|
|
|
}
|
|
|
|
if (useNativeWidgets)
|
|
|
|
return eWidgetRendering_Native;
|
|
|
|
else
|
|
|
|
return eWidgetRendering_Gfx;
|
|
|
|
}
|
|
|
|
return eWidgetRendering_Gfx;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
1999-06-21 20:41:56 +00:00
|
|
|
nsresult
|
1999-12-04 23:49:50 +00:00
|
|
|
nsCSSFrameConstructor::ConstructRadioControlFrame(nsIPresShell* aPresShell,
|
|
|
|
nsIPresContext* aPresContext,
|
1999-06-21 20:41:56 +00:00
|
|
|
nsIFrame*& aNewFrame,
|
1999-08-03 14:41:48 +00:00
|
|
|
nsIContent* aContent,
|
|
|
|
nsIStyleContext* aStyleContext)
|
1999-06-21 20:41:56 +00:00
|
|
|
{
|
1999-08-06 05:11:39 +00:00
|
|
|
nsresult rv = NS_OK;
|
|
|
|
if (GetFormElementRenderingMode(aPresContext, eWidgetType_Radio) == eWidgetRendering_Gfx)
|
1999-12-04 23:49:50 +00:00
|
|
|
rv = NS_NewGfxRadioControlFrame(aPresShell, &aNewFrame);
|
1999-08-06 05:11:39 +00:00
|
|
|
else
|
2000-01-31 22:46:55 +00:00
|
|
|
NS_ASSERTION(0, "We longer support native widgets");
|
1999-08-06 05:11:39 +00:00
|
|
|
|
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
aNewFrame = nsnull;
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
1999-06-21 20:41:56 +00:00
|
|
|
nsCOMPtr<nsIStyleContext> radioStyle;
|
|
|
|
aPresContext->ResolvePseudoStyleContextFor(aContent, nsHTMLAtoms::radioPseudo,
|
1999-08-03 14:41:48 +00:00
|
|
|
aStyleContext, PR_FALSE, getter_AddRefs(radioStyle));
|
1999-06-21 20:41:56 +00:00
|
|
|
nsIRadioControlFrame* radio = nsnull;
|
2000-01-31 22:46:55 +00:00
|
|
|
if (aNewFrame != nsnull && NS_SUCCEEDED(aNewFrame->QueryInterface(kIRadioControlFrameIID, (void**)&radio))) {
|
1999-06-21 20:41:56 +00:00
|
|
|
radio->SetRadioButtonFaceStyleContext(radioStyle);
|
|
|
|
NS_RELEASE(radio);
|
|
|
|
}
|
2000-03-24 15:48:59 +00:00
|
|
|
return rv;
|
1999-06-21 20:41:56 +00:00
|
|
|
}
|
|
|
|
|
1999-08-06 05:11:39 +00:00
|
|
|
nsresult
|
2000-03-24 15:48:59 +00:00
|
|
|
nsCSSFrameConstructor::ConstructCheckboxControlFrame(nsIPresShell* aPresShell,
|
|
|
|
nsIPresContext* aPresContext,
|
|
|
|
nsIFrame*& aNewFrame,
|
|
|
|
nsIContent* aContent,
|
|
|
|
nsIStyleContext* aStyleContext)
|
1999-08-06 05:11:39 +00:00
|
|
|
{
|
|
|
|
nsresult rv = NS_OK;
|
|
|
|
if (GetFormElementRenderingMode(aPresContext, eWidgetType_Checkbox) == eWidgetRendering_Gfx)
|
1999-12-04 23:49:50 +00:00
|
|
|
rv = NS_NewGfxCheckboxControlFrame(aPresShell, &aNewFrame);
|
1999-08-06 05:11:39 +00:00
|
|
|
else
|
2000-01-31 22:46:55 +00:00
|
|
|
NS_ASSERTION(0, "We longer support native widgets");
|
|
|
|
|
1999-08-06 05:11:39 +00:00
|
|
|
|
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
aNewFrame = nsnull;
|
|
|
|
}
|
2000-03-24 15:48:59 +00:00
|
|
|
|
|
|
|
nsCOMPtr<nsIStyleContext> checkboxStyle;
|
|
|
|
aPresContext->ResolvePseudoStyleContextFor(aContent, nsHTMLAtoms::checkPseudo,
|
|
|
|
aStyleContext, PR_FALSE, getter_AddRefs(checkboxStyle));
|
|
|
|
nsICheckboxControlFrame* checkbox = nsnull;
|
|
|
|
if (aNewFrame != nsnull &&
|
|
|
|
NS_SUCCEEDED(aNewFrame->QueryInterface(NS_GET_IID(nsICheckboxControlFrame), (void**)&checkbox))) {
|
|
|
|
checkbox->SetCheckboxFaceStyleContext(checkboxStyle);
|
|
|
|
NS_RELEASE(checkbox);
|
|
|
|
}
|
1999-08-06 05:11:39 +00:00
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
1999-12-04 23:49:50 +00:00
|
|
|
nsCSSFrameConstructor::ConstructButtonControlFrame(nsIPresShell* aPresShell,
|
|
|
|
nsIPresContext* aPresContext,
|
1999-08-06 05:11:39 +00:00
|
|
|
nsIFrame*& aNewFrame)
|
|
|
|
{
|
|
|
|
nsresult rv = NS_OK;
|
|
|
|
if (GetFormElementRenderingMode(aPresContext, eWidgetType_Button) == eWidgetRendering_Gfx)
|
1999-12-04 23:49:50 +00:00
|
|
|
rv = NS_NewGfxButtonControlFrame(aPresShell, &aNewFrame);
|
1999-08-06 05:11:39 +00:00
|
|
|
else
|
2000-01-31 22:46:55 +00:00
|
|
|
NS_ASSERTION(0, "We longer support native widgets");
|
1999-08-06 05:11:39 +00:00
|
|
|
|
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
aNewFrame = nsnull;
|
|
|
|
}
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
1999-06-12 22:32:41 +00:00
|
|
|
nsresult
|
1999-12-04 23:49:50 +00:00
|
|
|
nsCSSFrameConstructor::ConstructTextControlFrame(nsIPresShell* aPresShell,
|
|
|
|
nsIPresContext* aPresContext,
|
1999-08-19 22:11:03 +00:00
|
|
|
nsIFrame*& aNewFrame,
|
|
|
|
nsIContent* aContent)
|
1999-06-12 22:32:41 +00:00
|
|
|
{
|
|
|
|
if (!aPresContext) { return NS_ERROR_NULL_POINTER;}
|
|
|
|
nsresult rv = NS_OK;
|
1999-08-19 22:11:03 +00:00
|
|
|
|
1999-06-12 22:32:41 +00:00
|
|
|
nsWidgetRendering mode;
|
|
|
|
aPresContext->GetWidgetRenderingMode(&mode);
|
|
|
|
if (eWidgetRendering_Gfx == mode)
|
|
|
|
{
|
1999-12-04 23:49:50 +00:00
|
|
|
rv = NS_NewGfxTextControlFrame(aPresShell, &aNewFrame);
|
1999-06-12 22:32:41 +00:00
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
aNewFrame = nsnull;
|
|
|
|
}
|
1999-12-17 03:28:50 +00:00
|
|
|
if (aNewFrame)
|
2000-05-16 03:40:02 +00:00
|
|
|
{
|
2000-05-17 01:59:47 +00:00
|
|
|
#ifndef ENDER_LITE
|
1999-12-17 03:28:50 +00:00
|
|
|
((nsGfxTextControlFrame*)aNewFrame)->SetFrameConstructor(this);
|
2000-05-16 03:40:02 +00:00
|
|
|
#endif
|
|
|
|
}
|
1999-06-12 22:32:41 +00:00
|
|
|
}
|
|
|
|
if (!aNewFrame)
|
|
|
|
{
|
2000-01-31 22:46:55 +00:00
|
|
|
NS_ASSERTION(0, "We longer support native widgets");
|
1999-06-12 22:32:41 +00:00
|
|
|
}
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
1999-08-19 22:16:23 +00:00
|
|
|
PRBool
|
2000-03-27 22:12:42 +00:00
|
|
|
nsCSSFrameConstructor::HasGfxScrollbars()
|
1999-08-19 22:16:23 +00:00
|
|
|
{
|
2000-03-27 22:12:42 +00:00
|
|
|
// Get the Prefs
|
|
|
|
if (!mGotGfxPrefs) {
|
2000-03-02 07:13:02 +00:00
|
|
|
nsCOMPtr<nsIPref> pref(do_GetService(NS_PREF_PROGID));
|
1999-10-19 03:00:47 +00:00
|
|
|
if (pref) {
|
2000-03-27 22:12:42 +00:00
|
|
|
pref->GetBoolPref("nglayout.widget.gfxscrollbars", &mHasGfxScrollbars);
|
|
|
|
pref->GetBoolPref("nglayout.widget.gfxlistbox", &mDoGfxListbox);
|
|
|
|
pref->GetBoolPref("nglayout.widget.gfxcombobox", &mDoGfxCombobox);
|
|
|
|
mGotGfxPrefs = PR_TRUE;
|
|
|
|
} else {
|
|
|
|
mHasGfxScrollbars = PR_FALSE;
|
|
|
|
mDoGfxListbox = PR_FALSE;
|
|
|
|
mDoGfxCombobox = PR_FALSE;
|
1999-10-19 03:00:47 +00:00
|
|
|
}
|
2000-03-27 22:12:42 +00:00
|
|
|
}
|
1999-10-12 00:16:06 +00:00
|
|
|
|
2000-07-10 20:10:27 +00:00
|
|
|
//return mHasGfxScrollbars;
|
|
|
|
// we no longer support native scrollbars. Except in form elements. So
|
|
|
|
// we always return true
|
|
|
|
return PR_TRUE;
|
1999-08-19 22:16:23 +00:00
|
|
|
}
|
|
|
|
|
1999-02-05 03:55:18 +00:00
|
|
|
nsresult
|
1999-12-04 23:49:50 +00:00
|
|
|
nsCSSFrameConstructor::ConstructSelectFrame(nsIPresShell* aPresShell,
|
|
|
|
nsIPresContext* aPresContext,
|
1999-04-28 19:08:14 +00:00
|
|
|
nsFrameConstructorState& aState,
|
|
|
|
nsIContent* aContent,
|
|
|
|
nsIFrame* aParentFrame,
|
|
|
|
nsIAtom* aTag,
|
|
|
|
nsIStyleContext* aStyleContext,
|
|
|
|
nsIFrame*& aNewFrame,
|
|
|
|
PRBool& aProcessChildren,
|
|
|
|
PRBool aIsAbsolutelyPositioned,
|
|
|
|
PRBool& aFrameHasBeenInitialized,
|
|
|
|
PRBool aIsFixedPositioned,
|
|
|
|
nsFrameItems& aFrameItems)
|
1999-02-05 03:55:18 +00:00
|
|
|
{
|
1999-11-19 15:41:19 +00:00
|
|
|
nsresult rv = NS_OK;
|
1999-03-02 22:43:26 +00:00
|
|
|
nsWidgetRendering mode;
|
|
|
|
aPresContext->GetWidgetRenderingMode(&mode);
|
1999-04-12 22:14:31 +00:00
|
|
|
const PRInt32 kNoSizeSpecified = -1;
|
1999-03-22 21:32:12 +00:00
|
|
|
|
|
|
|
if (eWidgetRendering_Gfx == mode) {
|
1999-08-31 03:09:40 +00:00
|
|
|
// Construct a frame-based listbox or combobox
|
|
|
|
nsCOMPtr<nsIDOMHTMLSelectElement> sel(do_QueryInterface(aContent));
|
1999-04-12 22:14:31 +00:00
|
|
|
PRInt32 size = 1;
|
1999-08-31 03:09:40 +00:00
|
|
|
if (sel) {
|
|
|
|
sel->GetSize(&size);
|
1999-07-20 22:32:41 +00:00
|
|
|
PRBool multipleSelect = PR_FALSE;
|
1999-08-31 03:09:40 +00:00
|
|
|
sel->GetMultiple(&multipleSelect);
|
1999-07-20 22:32:41 +00:00
|
|
|
// Construct a combobox if size=1 or no size is specified and its multiple select
|
2000-03-14 12:03:21 +00:00
|
|
|
if (((1 == size || 0 == size) || (kNoSizeSpecified == size)) && (PR_FALSE == multipleSelect)) {
|
fixed bugs #6303, #6753, #6756, #6759
Re-wrote nsComboboxFrame.
removed the obsolete nsHTMLAtoms: comboText,comoTextSelected,comTextSelectedFocus,dropDownVisible,
dropdownHidden, dropDownBtnOut, dropDownBtnPressed,
Added nsHTMLAtoms::combobox, nsLayoutAtoms::popupList
Renamed dropDownList to dropDownListPseudo
Added "arrow.gif" as to be used the background-image for the combobox button
ua.css - added rules for select to differentiate between comboboxes and listboxes.
Added style rules to more closely match the XPTOOLKIT XPWidgets look.
removed the following :-moz-combobox-text, -moz-combobox-textselected
nsIFormControlFrame.h - Added SetSuggestedSize method.
nsButtonControlFrame - Implemented SetSuggestedSize.
nsCSSFrameConstructor.cpp - Rewrote ConstructSelectFrame.
nsIWidget.h -Added GetAbsoluteBounds method.
nsWindow.cpp - Implemented GetAbsoluteBounds.
1999-07-14 22:00:24 +00:00
|
|
|
// Construct a frame-based combo box.
|
|
|
|
// The frame-based combo box is built out of tree parts. A display area, a button and
|
|
|
|
// a dropdown list. The display area and button are created through anonymous content.
|
|
|
|
// The drop-down list's frame is created explicitly. The combobox frame shares it's content
|
|
|
|
// with the drop-down list.
|
1999-12-05 20:43:26 +00:00
|
|
|
PRUint32 flags = NS_BLOCK_SHRINK_WRAP | (aIsAbsolutelyPositioned?NS_BLOCK_SPACE_MGR:0);
|
fixed bugs #6303, #6753, #6756, #6759
Re-wrote nsComboboxFrame.
removed the obsolete nsHTMLAtoms: comboText,comoTextSelected,comTextSelectedFocus,dropDownVisible,
dropdownHidden, dropDownBtnOut, dropDownBtnPressed,
Added nsHTMLAtoms::combobox, nsLayoutAtoms::popupList
Renamed dropDownList to dropDownListPseudo
Added "arrow.gif" as to be used the background-image for the combobox button
ua.css - added rules for select to differentiate between comboboxes and listboxes.
Added style rules to more closely match the XPTOOLKIT XPWidgets look.
removed the following :-moz-combobox-text, -moz-combobox-textselected
nsIFormControlFrame.h - Added SetSuggestedSize method.
nsButtonControlFrame - Implemented SetSuggestedSize.
nsCSSFrameConstructor.cpp - Rewrote ConstructSelectFrame.
nsIWidget.h -Added GetAbsoluteBounds method.
nsWindow.cpp - Implemented GetAbsoluteBounds.
1999-07-14 22:00:24 +00:00
|
|
|
nsIFrame * comboboxFrame;
|
1999-12-05 20:43:26 +00:00
|
|
|
rv = NS_NewComboboxControlFrame(aPresShell, &comboboxFrame, flags);
|
fixed bugs #6303, #6753, #6756, #6759
Re-wrote nsComboboxFrame.
removed the obsolete nsHTMLAtoms: comboText,comoTextSelected,comTextSelectedFocus,dropDownVisible,
dropdownHidden, dropDownBtnOut, dropDownBtnPressed,
Added nsHTMLAtoms::combobox, nsLayoutAtoms::popupList
Renamed dropDownList to dropDownListPseudo
Added "arrow.gif" as to be used the background-image for the combobox button
ua.css - added rules for select to differentiate between comboboxes and listboxes.
Added style rules to more closely match the XPTOOLKIT XPWidgets look.
removed the following :-moz-combobox-text, -moz-combobox-textselected
nsIFormControlFrame.h - Added SetSuggestedSize method.
nsButtonControlFrame - Implemented SetSuggestedSize.
nsCSSFrameConstructor.cpp - Rewrote ConstructSelectFrame.
nsIWidget.h -Added GetAbsoluteBounds method.
nsWindow.cpp - Implemented GetAbsoluteBounds.
1999-07-14 22:00:24 +00:00
|
|
|
|
1999-12-06 07:44:18 +00:00
|
|
|
// Determine geometric parent for the combobox frame
|
fixed bugs #6303, #6753, #6756, #6759
Re-wrote nsComboboxFrame.
removed the obsolete nsHTMLAtoms: comboText,comoTextSelected,comTextSelectedFocus,dropDownVisible,
dropdownHidden, dropDownBtnOut, dropDownBtnPressed,
Added nsHTMLAtoms::combobox, nsLayoutAtoms::popupList
Renamed dropDownList to dropDownListPseudo
Added "arrow.gif" as to be used the background-image for the combobox button
ua.css - added rules for select to differentiate between comboboxes and listboxes.
Added style rules to more closely match the XPTOOLKIT XPWidgets look.
removed the following :-moz-combobox-text, -moz-combobox-textselected
nsIFormControlFrame.h - Added SetSuggestedSize method.
nsButtonControlFrame - Implemented SetSuggestedSize.
nsCSSFrameConstructor.cpp - Rewrote ConstructSelectFrame.
nsIWidget.h -Added GetAbsoluteBounds method.
nsWindow.cpp - Implemented GetAbsoluteBounds.
1999-07-14 22:00:24 +00:00
|
|
|
nsIFrame* geometricParent = aParentFrame;
|
|
|
|
if (aIsAbsolutelyPositioned) {
|
|
|
|
geometricParent = aState.mAbsoluteItems.containingBlock;
|
|
|
|
} else if (aIsFixedPositioned) {
|
|
|
|
geometricParent = aState.mFixedItems.containingBlock;
|
|
|
|
}
|
1999-12-06 07:44:18 +00:00
|
|
|
// Initialize the combobox frame
|
|
|
|
InitAndRestoreFrame(aPresContext, aState, aContent,
|
|
|
|
geometricParent, aStyleContext, nsnull, comboboxFrame);
|
|
|
|
|
1999-12-07 00:05:23 +00:00
|
|
|
nsHTMLContainerFrame::CreateViewForFrame(aPresContext, comboboxFrame,
|
|
|
|
aStyleContext, PR_FALSE);
|
2000-03-24 15:48:59 +00:00
|
|
|
|
2000-03-27 22:12:42 +00:00
|
|
|
if (HasGfxScrollbars() && mDoGfxCombobox) {
|
2000-03-15 15:45:29 +00:00
|
|
|
///////////////////////////////////////////////////////////////////
|
|
|
|
// Combobox - New GFX Implementation
|
|
|
|
///////////////////////////////////////////////////////////////////
|
|
|
|
// Construct a frame-based list box
|
|
|
|
nsIComboboxControlFrame* comboBox = nsnull;
|
|
|
|
if (NS_SUCCEEDED(comboboxFrame->QueryInterface(kIComboboxControlFrameIID, (void**)&comboBox))) {
|
|
|
|
comboBox->SetFrameConstructor(this);
|
|
|
|
|
|
|
|
nsIFrame * listFrame;
|
|
|
|
rv = NS_NewGfxListControlFrame(aPresShell, &listFrame);
|
|
|
|
|
|
|
|
// Notify the listbox that it is being used as a dropdown list.
|
|
|
|
nsIListControlFrame * listControlFrame;
|
|
|
|
if (NS_SUCCEEDED(listFrame->QueryInterface(kIListControlFrameIID, (void**)&listControlFrame))) {
|
|
|
|
listControlFrame->SetComboboxFrame(comboboxFrame);
|
|
|
|
}
|
|
|
|
// Notify combobox that it should use the listbox as it's popup
|
|
|
|
comboBox->SetDropDown(listFrame);
|
|
|
|
|
|
|
|
nsCOMPtr<nsIStyleContext> gfxListStyle;
|
|
|
|
aPresContext->ResolvePseudoStyleContextFor(aContent,
|
|
|
|
nsHTMLAtoms::dropDownListPseudo,
|
|
|
|
aStyleContext, PR_FALSE,
|
|
|
|
getter_AddRefs(gfxListStyle));
|
|
|
|
|
|
|
|
// initialize the list control
|
|
|
|
InitAndRestoreFrame(aPresContext, aState, aContent,
|
|
|
|
comboboxFrame, gfxListStyle, nsnull, listFrame);
|
2000-03-18 14:25:02 +00:00
|
|
|
|
2000-03-15 15:45:29 +00:00
|
|
|
nsHTMLContainerFrame::CreateViewForFrame(aPresContext, listFrame,
|
|
|
|
gfxListStyle, PR_TRUE);
|
2000-03-18 14:25:02 +00:00
|
|
|
nsIView * view;
|
|
|
|
listFrame->GetView(aPresContext, &view);
|
|
|
|
if (view != nsnull) {
|
|
|
|
nsWidgetInitData widgetData;
|
|
|
|
view->SetFloating(PR_TRUE);
|
|
|
|
widgetData.mWindowType = eWindowType_popup;
|
|
|
|
widgetData.mBorderStyle = eBorderStyle_default;
|
2000-03-15 15:45:29 +00:00
|
|
|
|
|
|
|
#ifdef XP_MAC
|
2000-03-18 14:25:02 +00:00
|
|
|
static NS_DEFINE_IID(kCPopUpCID, NS_POPUP_CID);
|
|
|
|
view->CreateWidget(kCPopUpCID, &widgetData, nsnull);
|
2000-03-15 15:45:29 +00:00
|
|
|
#else
|
2000-03-18 14:25:02 +00:00
|
|
|
static NS_DEFINE_IID(kCChildCID, NS_CHILD_CID);
|
|
|
|
view->CreateWidget(kCChildCID, &widgetData, nsnull);
|
2000-03-15 15:45:29 +00:00
|
|
|
#endif
|
2000-03-18 14:25:02 +00:00
|
|
|
}
|
2000-03-15 15:45:29 +00:00
|
|
|
|
2000-05-26 06:42:29 +00:00
|
|
|
nsCOMPtr<nsIStyleContext> gfxScrolledStyle;
|
|
|
|
aPresContext->ResolvePseudoStyleContextFor(aContent,
|
|
|
|
nsLayoutAtoms::selectScrolledContentPseudo,
|
|
|
|
gfxListStyle, PR_FALSE,
|
|
|
|
getter_AddRefs(gfxScrolledStyle));
|
|
|
|
|
|
|
|
|
2000-03-15 15:45:29 +00:00
|
|
|
// create the area frame we are scrolling
|
2000-03-27 22:12:42 +00:00
|
|
|
flags = NS_BLOCK_SHRINK_WRAP | (aIsAbsolutelyPositioned?NS_BLOCK_SPACE_MGR:0);
|
2000-03-15 15:45:29 +00:00
|
|
|
nsIFrame* scrolledFrame = nsnull;
|
|
|
|
NS_NewSelectsAreaFrame(aPresShell, &scrolledFrame, flags);
|
|
|
|
|
2000-05-26 06:42:29 +00:00
|
|
|
nsIFrame* newScrollFrame = nsnull;
|
|
|
|
|
|
|
|
|
|
|
|
/* scroll frame */
|
|
|
|
#ifdef NEWGFX_LIST_SCROLLFRAME
|
|
|
|
nsIStyleContext* newStyle = nsnull;
|
|
|
|
|
|
|
|
// ok take the style context, the Select area frame to scroll,the listFrame, and its parent
|
|
|
|
// and build the scrollframe.
|
|
|
|
BuildScrollFrame(aPresShell, aPresContext, aState, aContent, gfxScrolledStyle, scrolledFrame,
|
|
|
|
listFrame, newScrollFrame, newStyle);
|
|
|
|
|
|
|
|
gfxScrolledStyle = newStyle;
|
|
|
|
|
|
|
|
#else
|
|
|
|
newScrollFrame = scrolledFrame;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/*
|
2000-03-15 15:45:29 +00:00
|
|
|
// resolve a style for our gfx scrollframe based on the list frames style
|
2000-05-26 06:42:29 +00:00
|
|
|
|
2000-03-15 15:45:29 +00:00
|
|
|
InitAndRestoreFrame(aPresContext, aState, aContent,
|
2000-05-26 06:42:29 +00:00
|
|
|
parentFrame, gfxScrolledStyle, nsnull, scrolledFrame);
|
|
|
|
*/
|
2000-03-15 15:45:29 +00:00
|
|
|
|
|
|
|
// XXX Temporary for Bug 19416
|
|
|
|
{
|
|
|
|
nsIView * lstView;
|
|
|
|
scrolledFrame->GetView(aPresContext, &lstView);
|
|
|
|
if (lstView) {
|
|
|
|
lstView->IgnoreSetPosition(PR_TRUE);
|
|
|
|
}
|
2000-03-14 12:03:21 +00:00
|
|
|
}
|
2000-03-15 15:45:29 +00:00
|
|
|
// this is what is returned when the scrollframe is created.
|
|
|
|
// newScrollFrame - Either a gfx scrollframe or a native scrollframe that was created
|
|
|
|
// scrolledFrameStyleContext - The resolved style context of the scrolledframe you passed in.
|
|
|
|
// this is not the style of the scrollFrame.
|
1999-12-07 00:05:23 +00:00
|
|
|
|
2000-03-15 15:45:29 +00:00
|
|
|
nsFrameItems anonChildItems;
|
|
|
|
// Create display and button frames from the combobox'es anonymous content
|
|
|
|
CreateAnonymousFrames(aPresShell, aPresContext, nsHTMLAtoms::combobox, aState, aContent, comboboxFrame,
|
|
|
|
anonChildItems);
|
2000-03-14 12:03:21 +00:00
|
|
|
|
2000-03-15 15:45:29 +00:00
|
|
|
comboboxFrame->SetInitialChildList(aPresContext, nsnull,
|
|
|
|
anonChildItems.childList);
|
2000-03-14 12:03:21 +00:00
|
|
|
|
|
|
|
|
2000-03-15 15:45:29 +00:00
|
|
|
// The area frame is a floater container
|
|
|
|
PRBool haveFirstLetterStyle, haveFirstLineStyle;
|
|
|
|
HaveSpecialBlockStyle(aPresContext, aContent, aStyleContext,
|
|
|
|
&haveFirstLetterStyle, &haveFirstLineStyle);
|
|
|
|
nsFrameConstructorSaveState floaterSaveState;
|
|
|
|
aState.PushFloaterContainingBlock(scrolledFrame, floaterSaveState,
|
|
|
|
haveFirstLetterStyle,
|
|
|
|
haveFirstLineStyle);
|
|
|
|
|
|
|
|
// Process children
|
|
|
|
nsFrameItems childItems;
|
|
|
|
|
|
|
|
ProcessChildren(aPresShell, aPresContext, aState, aContent, scrolledFrame, PR_FALSE,
|
|
|
|
childItems, PR_TRUE);
|
|
|
|
|
|
|
|
// if a select is being created with zero options we need to create
|
|
|
|
// a special pseudo frame so it can be sized as best it can
|
|
|
|
nsCOMPtr<nsIDOMHTMLSelectElement> selectElement;
|
|
|
|
nsresult result = aContent->QueryInterface(NS_GET_IID(nsIDOMHTMLSelectElement),
|
|
|
|
(void**)getter_AddRefs(selectElement));
|
|
|
|
if (NS_SUCCEEDED(result) && selectElement) {
|
|
|
|
PRUint32 numOptions = 0;
|
|
|
|
result = selectElement->GetLength(&numOptions);
|
|
|
|
if (NS_SUCCEEDED(result) && 0 == numOptions) {
|
|
|
|
nsCOMPtr<nsIStyleContext> styleContext;
|
|
|
|
nsIFrame* generatedFrame = nsnull;
|
|
|
|
scrolledFrame->GetStyleContext(getter_AddRefs(styleContext));
|
|
|
|
if (CreateGeneratedContentFrame(aPresShell, aPresContext, aState, scrolledFrame, aContent,
|
|
|
|
styleContext, nsLayoutAtoms::dummyOptionPseudo,
|
|
|
|
PR_FALSE, &generatedFrame)) {
|
|
|
|
// Add the generated frame to the child list
|
|
|
|
childItems.AddChild(generatedFrame);
|
|
|
|
}
|
2000-03-14 12:03:21 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2000-03-15 15:45:29 +00:00
|
|
|
// Set the scrolled frame's initial child lists
|
|
|
|
scrolledFrame->SetInitialChildList(aPresContext, nsnull, childItems.childList);
|
2000-03-14 12:03:21 +00:00
|
|
|
|
2000-03-15 15:45:29 +00:00
|
|
|
// set the floated list
|
|
|
|
if (aState.mFloatedItems.childList) {
|
|
|
|
scrolledFrame->SetInitialChildList(aPresContext,
|
|
|
|
nsLayoutAtoms::floaterList,
|
|
|
|
aState.mFloatedItems.childList);
|
|
|
|
}
|
2000-03-14 12:03:21 +00:00
|
|
|
|
2000-03-15 15:45:29 +00:00
|
|
|
// now we need to set the initial child list of the listFrame and this of course will be the gfx scrollframe
|
|
|
|
listFrame->SetInitialChildList(aPresContext, nsnull, newScrollFrame);
|
2000-03-14 12:03:21 +00:00
|
|
|
|
2000-03-15 15:45:29 +00:00
|
|
|
// Initialize the additional popup child list which contains the dropdown list frame.
|
|
|
|
nsFrameItems popupItems;
|
|
|
|
popupItems.AddChild(listFrame);
|
|
|
|
comboboxFrame->SetInitialChildList(aPresContext, nsLayoutAtoms::popupList,
|
|
|
|
popupItems.childList);
|
|
|
|
|
|
|
|
// our new frame retured is the top frame which is the list frame.
|
|
|
|
//aNewFrame = listFrame;
|
|
|
|
|
|
|
|
// yes we have already initialized our frame
|
|
|
|
// Don't process, the children, They are already processed by the InitializeScrollFrame
|
|
|
|
// call above.
|
|
|
|
aProcessChildren = PR_FALSE;
|
|
|
|
aNewFrame = comboboxFrame;
|
|
|
|
aFrameHasBeenInitialized = PR_TRUE;
|
1999-04-12 22:14:31 +00:00
|
|
|
}
|
2000-03-15 15:45:29 +00:00
|
|
|
} else {
|
|
|
|
///////////////////////////////////////////////////////////////////
|
|
|
|
// Combobox - Old Native Implementation
|
|
|
|
///////////////////////////////////////////////////////////////////
|
|
|
|
nsIComboboxControlFrame* comboBox = nsnull;
|
|
|
|
if (NS_SUCCEEDED(comboboxFrame->QueryInterface(kIComboboxControlFrameIID, (void**)&comboBox))) {
|
|
|
|
comboBox->SetFrameConstructor(this);
|
|
|
|
|
|
|
|
// Create a listbox
|
|
|
|
nsIFrame * listFrame;
|
|
|
|
rv = NS_NewListControlFrame(aPresShell, &listFrame);
|
|
|
|
|
|
|
|
// Notify the listbox that it is being used as a dropdown list.
|
|
|
|
nsIListControlFrame * listControlFrame;
|
|
|
|
if (NS_SUCCEEDED(listFrame->QueryInterface(kIListControlFrameIID, (void**)&listControlFrame))) {
|
|
|
|
listControlFrame->SetComboboxFrame(comboboxFrame);
|
|
|
|
}
|
|
|
|
// Notify combobox that it should use the listbox as it's popup
|
|
|
|
comboBox->SetDropDown(listFrame);
|
1999-04-12 22:14:31 +00:00
|
|
|
|
2000-03-15 15:45:29 +00:00
|
|
|
// Resolve psuedo element style for the dropdown list
|
|
|
|
nsCOMPtr<nsIStyleContext> listStyle;
|
|
|
|
rv = aPresContext->ResolvePseudoStyleContextFor(aContent,
|
|
|
|
nsHTMLAtoms::dropDownListPseudo,
|
|
|
|
aStyleContext,
|
|
|
|
PR_FALSE,
|
|
|
|
getter_AddRefs(listStyle));
|
|
|
|
|
|
|
|
// Initialize the scroll frame positioned. Note that it is NOT initialized as
|
|
|
|
// absolutely positioned.
|
|
|
|
nsIFrame* newFrame = nsnull;
|
|
|
|
nsIFrame* scrolledFrame = nsnull;
|
|
|
|
NS_NewSelectsAreaFrame(aPresShell, &scrolledFrame, flags);
|
|
|
|
|
|
|
|
InitializeSelectFrame(aPresShell, aPresContext, aState, listFrame, scrolledFrame, aContent, comboboxFrame,
|
|
|
|
listStyle, PR_FALSE, PR_FALSE, PR_TRUE);
|
|
|
|
|
|
|
|
newFrame = listFrame;
|
|
|
|
// XXX Temporary for Bug 19416
|
|
|
|
{
|
|
|
|
nsIView * lstView;
|
|
|
|
scrolledFrame->GetView(aPresContext, &lstView);
|
|
|
|
if (lstView) {
|
|
|
|
lstView->IgnoreSetPosition(PR_TRUE);
|
|
|
|
}
|
1999-12-14 22:21:58 +00:00
|
|
|
}
|
fixed bugs #6303, #6753, #6756, #6759
Re-wrote nsComboboxFrame.
removed the obsolete nsHTMLAtoms: comboText,comoTextSelected,comTextSelectedFocus,dropDownVisible,
dropdownHidden, dropDownBtnOut, dropDownBtnPressed,
Added nsHTMLAtoms::combobox, nsLayoutAtoms::popupList
Renamed dropDownList to dropDownListPseudo
Added "arrow.gif" as to be used the background-image for the combobox button
ua.css - added rules for select to differentiate between comboboxes and listboxes.
Added style rules to more closely match the XPTOOLKIT XPWidgets look.
removed the following :-moz-combobox-text, -moz-combobox-textselected
nsIFormControlFrame.h - Added SetSuggestedSize method.
nsButtonControlFrame - Implemented SetSuggestedSize.
nsCSSFrameConstructor.cpp - Rewrote ConstructSelectFrame.
nsIWidget.h -Added GetAbsoluteBounds method.
nsWindow.cpp - Implemented GetAbsoluteBounds.
1999-07-14 22:00:24 +00:00
|
|
|
|
2000-03-15 15:45:29 +00:00
|
|
|
// Set flag so the events go to the listFrame not child frames.
|
|
|
|
// XXX: We should replace this with a real widget manager similar
|
|
|
|
// to how the nsFormControlFrame works. Re-directing events is a temporary Kludge.
|
|
|
|
nsIView *listView;
|
|
|
|
listFrame->GetView(aPresContext, &listView);
|
|
|
|
NS_ASSERTION(nsnull != listView,"ListFrame's view is nsnull");
|
|
|
|
nsIWidget * viewWidget;
|
|
|
|
listView->GetWidget(viewWidget);
|
|
|
|
//viewWidget->SetOverrideShow(PR_TRUE);
|
|
|
|
NS_RELEASE(viewWidget);
|
|
|
|
//listView->SetViewFlags(NS_VIEW_PUBLIC_FLAG_DONT_CHECK_CHILDREN);
|
|
|
|
|
|
|
|
nsIFrame* frame = nsnull;
|
|
|
|
if (NS_SUCCEEDED(comboboxFrame->QueryInterface(kIFrameIID, (void**)&frame))) {
|
|
|
|
nsFrameItems childItems;
|
1999-04-12 22:14:31 +00:00
|
|
|
|
2000-03-15 15:45:29 +00:00
|
|
|
// Create display and button frames from the combobox'es anonymous content
|
|
|
|
CreateAnonymousFrames(aPresShell, aPresContext, nsHTMLAtoms::combobox, aState, aContent, frame,
|
|
|
|
childItems);
|
fixed bugs #6303, #6753, #6756, #6759
Re-wrote nsComboboxFrame.
removed the obsolete nsHTMLAtoms: comboText,comoTextSelected,comTextSelectedFocus,dropDownVisible,
dropdownHidden, dropDownBtnOut, dropDownBtnPressed,
Added nsHTMLAtoms::combobox, nsLayoutAtoms::popupList
Renamed dropDownList to dropDownListPseudo
Added "arrow.gif" as to be used the background-image for the combobox button
ua.css - added rules for select to differentiate between comboboxes and listboxes.
Added style rules to more closely match the XPTOOLKIT XPWidgets look.
removed the following :-moz-combobox-text, -moz-combobox-textselected
nsIFormControlFrame.h - Added SetSuggestedSize method.
nsButtonControlFrame - Implemented SetSuggestedSize.
nsCSSFrameConstructor.cpp - Rewrote ConstructSelectFrame.
nsIWidget.h -Added GetAbsoluteBounds method.
nsWindow.cpp - Implemented GetAbsoluteBounds.
1999-07-14 22:00:24 +00:00
|
|
|
|
2000-03-15 15:45:29 +00:00
|
|
|
frame->SetInitialChildList(aPresContext, nsnull,
|
|
|
|
childItems.childList);
|
|
|
|
|
|
|
|
// Initialize the additional popup child list which contains the dropdown list frame.
|
|
|
|
nsFrameItems popupItems;
|
|
|
|
popupItems.AddChild(listFrame);
|
|
|
|
frame->SetInitialChildList(aPresContext, nsLayoutAtoms::popupList,
|
|
|
|
popupItems.childList);
|
|
|
|
}
|
|
|
|
// Don't process, the children, They are already processed by the InitializeScrollFrame
|
|
|
|
// call above.
|
|
|
|
aProcessChildren = PR_FALSE;
|
|
|
|
aNewFrame = comboboxFrame;
|
|
|
|
aFrameHasBeenInitialized = PR_TRUE;
|
fixed bugs #6303, #6753, #6756, #6759
Re-wrote nsComboboxFrame.
removed the obsolete nsHTMLAtoms: comboText,comoTextSelected,comTextSelectedFocus,dropDownVisible,
dropdownHidden, dropDownBtnOut, dropDownBtnPressed,
Added nsHTMLAtoms::combobox, nsLayoutAtoms::popupList
Renamed dropDownList to dropDownListPseudo
Added "arrow.gif" as to be used the background-image for the combobox button
ua.css - added rules for select to differentiate between comboboxes and listboxes.
Added style rules to more closely match the XPTOOLKIT XPWidgets look.
removed the following :-moz-combobox-text, -moz-combobox-textselected
nsIFormControlFrame.h - Added SetSuggestedSize method.
nsButtonControlFrame - Implemented SetSuggestedSize.
nsCSSFrameConstructor.cpp - Rewrote ConstructSelectFrame.
nsIWidget.h -Added GetAbsoluteBounds method.
nsWindow.cpp - Implemented GetAbsoluteBounds.
1999-07-14 22:00:24 +00:00
|
|
|
}
|
|
|
|
}
|
2000-03-27 22:12:42 +00:00
|
|
|
} else if (HasGfxScrollbars() && mDoGfxListbox) {
|
2000-03-15 15:45:29 +00:00
|
|
|
|
2000-03-14 12:03:21 +00:00
|
|
|
///////////////////////////////////////////////////////////////////
|
|
|
|
// ListBox - New GFX Implementation
|
|
|
|
///////////////////////////////////////////////////////////////////
|
2000-03-15 15:45:29 +00:00
|
|
|
// Construct a frame-based list box
|
1999-11-19 15:41:19 +00:00
|
|
|
nsIFrame * listFrame;
|
1) implememted box reflow coelescing.
2) implemented gfx scrollbars for list boxes
3) fixed progess meter to be an animated gif
4) fixed bugs 23521, 24721, 19114, 20546, 24385, 24457, 23156, 20226, 22543
-r hyatt, troy, rod
2000-02-09 22:02:40 +00:00
|
|
|
rv = NS_NewGfxListControlFrame(aPresShell, &listFrame);
|
1999-11-19 15:41:19 +00:00
|
|
|
|
|
|
|
// initialize the list control
|
1999-12-06 07:44:18 +00:00
|
|
|
InitAndRestoreFrame(aPresContext, aState, aContent,
|
|
|
|
aParentFrame, aStyleContext, nsnull, listFrame);
|
1999-11-19 15:41:19 +00:00
|
|
|
|
|
|
|
// create the area frame we are scrolling
|
1999-12-05 20:43:26 +00:00
|
|
|
PRUint32 flags = NS_BLOCK_SHRINK_WRAP | (aIsAbsolutelyPositioned?NS_BLOCK_SPACE_MGR:0);
|
1999-11-19 15:41:19 +00:00
|
|
|
nsIFrame* scrolledFrame = nsnull;
|
1) implememted box reflow coelescing.
2) implemented gfx scrollbars for list boxes
3) fixed progess meter to be an animated gif
4) fixed bugs 23521, 24721, 19114, 20546, 24385, 24457, 23156, 20226, 22543
-r hyatt, troy, rod
2000-02-09 22:02:40 +00:00
|
|
|
NS_NewSelectsAreaFrame(aPresShell, &scrolledFrame, flags);
|
1999-11-19 15:41:19 +00:00
|
|
|
|
|
|
|
// resolve a style for our gfx scrollframe based on the list frames style
|
1) implememted box reflow coelescing.
2) implemented gfx scrollbars for list boxes
3) fixed progess meter to be an animated gif
4) fixed bugs 23521, 24721, 19114, 20546, 24385, 24457, 23156, 20226, 22543
-r hyatt, troy, rod
2000-02-09 22:02:40 +00:00
|
|
|
nsCOMPtr<nsIStyleContext> scrollFrameStyle;
|
1999-11-19 15:41:19 +00:00
|
|
|
aPresContext->ResolvePseudoStyleContextFor(aContent,
|
1) implememted box reflow coelescing.
2) implemented gfx scrollbars for list boxes
3) fixed progess meter to be an animated gif
4) fixed bugs 23521, 24721, 19114, 20546, 24385, 24457, 23156, 20226, 22543
-r hyatt, troy, rod
2000-02-09 22:02:40 +00:00
|
|
|
nsLayoutAtoms::selectScrolledContentPseudo,
|
1999-11-19 15:41:19 +00:00
|
|
|
aStyleContext, PR_FALSE,
|
|
|
|
getter_AddRefs(scrollFrameStyle));
|
1) implememted box reflow coelescing.
2) implemented gfx scrollbars for list boxes
3) fixed progess meter to be an animated gif
4) fixed bugs 23521, 24721, 19114, 20546, 24385, 24457, 23156, 20226, 22543
-r hyatt, troy, rod
2000-02-09 22:02:40 +00:00
|
|
|
|
|
|
|
InitAndRestoreFrame(aPresContext, aState, aContent,
|
|
|
|
listFrame, scrollFrameStyle, nsnull, scrolledFrame);
|
|
|
|
|
1999-11-19 15:41:19 +00:00
|
|
|
// this is what is returned when the scrollframe is created.
|
|
|
|
// newScrollFrame - Either a gfx scrollframe or a native scrollframe that was created
|
|
|
|
// scrolledFrameStyleContext - The resolved style context of the scrolledframe you passed in.
|
|
|
|
// this is not the style of the scrollFrame.
|
|
|
|
|
|
|
|
nsIFrame* newScrollFrame = nsnull;
|
1) implememted box reflow coelescing.
2) implemented gfx scrollbars for list boxes
3) fixed progess meter to be an animated gif
4) fixed bugs 23521, 24721, 19114, 20546, 24385, 24457, 23156, 20226, 22543
-r hyatt, troy, rod
2000-02-09 22:02:40 +00:00
|
|
|
|
|
|
|
/* scroll frame */
|
|
|
|
|
|
|
|
#ifdef NEWGFX_LIST_SCROLLFRAME
|
1999-11-19 15:41:19 +00:00
|
|
|
nsIStyleContext * scrolledFrameStyleContext = nsnull;
|
|
|
|
|
|
|
|
// ok take the style context, the Select area frame to scroll,the listFrame, and its parent
|
|
|
|
// and build the scrollframe.
|
1) implememted box reflow coelescing.
2) implemented gfx scrollbars for list boxes
3) fixed progess meter to be an animated gif
4) fixed bugs 23521, 24721, 19114, 20546, 24385, 24457, 23156, 20226, 22543
-r hyatt, troy, rod
2000-02-09 22:02:40 +00:00
|
|
|
BuildScrollFrame(aPresShell, aPresContext, aState, aContent, scrollFrameStyle, scrolledFrame,
|
1999-11-19 15:41:19 +00:00
|
|
|
listFrame, newScrollFrame, scrolledFrameStyleContext);
|
1) implememted box reflow coelescing.
2) implemented gfx scrollbars for list boxes
3) fixed progess meter to be an animated gif
4) fixed bugs 23521, 24721, 19114, 20546, 24385, 24457, 23156, 20226, 22543
-r hyatt, troy, rod
2000-02-09 22:02:40 +00:00
|
|
|
#else
|
|
|
|
newScrollFrame = scrolledFrame;
|
|
|
|
#endif
|
1999-11-19 15:41:19 +00:00
|
|
|
|
|
|
|
// The area frame is a floater container
|
|
|
|
PRBool haveFirstLetterStyle, haveFirstLineStyle;
|
|
|
|
HaveSpecialBlockStyle(aPresContext, aContent, aStyleContext,
|
|
|
|
&haveFirstLetterStyle, &haveFirstLineStyle);
|
|
|
|
nsFrameConstructorSaveState floaterSaveState;
|
|
|
|
aState.PushFloaterContainingBlock(scrolledFrame, floaterSaveState,
|
|
|
|
haveFirstLetterStyle,
|
|
|
|
haveFirstLineStyle);
|
|
|
|
|
|
|
|
// Process children
|
|
|
|
nsFrameItems childItems;
|
|
|
|
|
1999-12-04 23:49:50 +00:00
|
|
|
ProcessChildren(aPresShell, aPresContext, aState, aContent, scrolledFrame, PR_FALSE,
|
1999-11-19 15:41:19 +00:00
|
|
|
childItems, PR_TRUE);
|
|
|
|
|
|
|
|
// if a select is being created with zero options we need to create
|
|
|
|
// a special pseudo frame so it can be sized as best it can
|
|
|
|
nsCOMPtr<nsIDOMHTMLSelectElement> selectElement;
|
2000-02-02 22:24:56 +00:00
|
|
|
nsresult result = aContent->QueryInterface(NS_GET_IID(nsIDOMHTMLSelectElement),
|
1999-11-19 15:41:19 +00:00
|
|
|
(void**)getter_AddRefs(selectElement));
|
|
|
|
if (NS_SUCCEEDED(result) && selectElement) {
|
|
|
|
PRUint32 numOptions = 0;
|
|
|
|
result = selectElement->GetLength(&numOptions);
|
|
|
|
if (NS_SUCCEEDED(result) && 0 == numOptions) {
|
2000-02-23 21:32:23 +00:00
|
|
|
nsCOMPtr<nsIStyleContext> styleContext;
|
1999-11-19 15:41:19 +00:00
|
|
|
nsIFrame* generatedFrame = nsnull;
|
2000-03-14 12:03:21 +00:00
|
|
|
scrolledFrame->GetStyleContext(getter_AddRefs(styleContext));
|
1) implememted box reflow coelescing.
2) implemented gfx scrollbars for list boxes
3) fixed progess meter to be an animated gif
4) fixed bugs 23521, 24721, 19114, 20546, 24385, 24457, 23156, 20226, 22543
-r hyatt, troy, rod
2000-02-09 22:02:40 +00:00
|
|
|
if (CreateGeneratedContentFrame(aPresShell, aPresContext, aState, scrolledFrame, aContent,
|
1999-11-19 15:41:19 +00:00
|
|
|
styleContext, nsLayoutAtoms::dummyOptionPseudo,
|
2000-03-14 12:03:21 +00:00
|
|
|
PR_FALSE, &generatedFrame)) {
|
1999-11-19 15:41:19 +00:00
|
|
|
// Add the generated frame to the child list
|
|
|
|
childItems.AddChild(generatedFrame);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Set the scrolled frame's initial child lists
|
1999-11-24 06:03:41 +00:00
|
|
|
scrolledFrame->SetInitialChildList(aPresContext, nsnull, childItems.childList);
|
1999-11-19 15:41:19 +00:00
|
|
|
|
|
|
|
// set the floated list
|
|
|
|
if (aState.mFloatedItems.childList) {
|
1999-11-24 06:03:41 +00:00
|
|
|
scrolledFrame->SetInitialChildList(aPresContext,
|
1999-11-19 15:41:19 +00:00
|
|
|
nsLayoutAtoms::floaterList,
|
|
|
|
aState.mFloatedItems.childList);
|
|
|
|
}
|
|
|
|
|
|
|
|
// now we need to set the initial child list of the listFrame and this of course will be the gfx scrollframe
|
1999-11-24 06:03:41 +00:00
|
|
|
listFrame->SetInitialChildList(aPresContext, nsnull, newScrollFrame);
|
1999-11-19 15:41:19 +00:00
|
|
|
|
|
|
|
// our new frame retured is the top frame which is the list frame.
|
|
|
|
aNewFrame = listFrame;
|
|
|
|
|
|
|
|
// yes we have already initialized our frame
|
|
|
|
aFrameHasBeenInitialized = PR_TRUE;
|
2000-03-15 15:45:29 +00:00
|
|
|
} else {
|
2000-03-14 12:03:21 +00:00
|
|
|
///////////////////////////////////////////////////////////////////
|
|
|
|
// ListBox - Old Native Implementation
|
|
|
|
///////////////////////////////////////////////////////////////////
|
1999-03-02 22:43:26 +00:00
|
|
|
nsIFrame * listFrame;
|
1999-12-04 23:49:50 +00:00
|
|
|
rv = NS_NewListControlFrame(aPresShell, &listFrame);
|
1999-03-02 22:43:26 +00:00
|
|
|
aNewFrame = listFrame;
|
1999-12-05 20:43:26 +00:00
|
|
|
|
|
|
|
PRUint32 flags = NS_BLOCK_SHRINK_WRAP | (aIsAbsolutelyPositioned?NS_BLOCK_SPACE_MGR:0);
|
1999-08-19 22:16:23 +00:00
|
|
|
nsIFrame* scrolledFrame = nsnull;
|
1999-12-05 20:43:26 +00:00
|
|
|
NS_NewSelectsAreaFrame(aPresShell, &scrolledFrame, flags);
|
|
|
|
|
1999-10-12 00:16:06 +00:00
|
|
|
// ******* this code stolen from Initialze ScrollFrame ********
|
|
|
|
// please adjust this code to use BuildScrollFrame.
|
|
|
|
|
1999-12-04 23:49:50 +00:00
|
|
|
InitializeSelectFrame(aPresShell, aPresContext, aState, listFrame, scrolledFrame, aContent, aParentFrame,
|
1999-10-12 00:16:06 +00:00
|
|
|
aStyleContext, aIsAbsolutelyPositioned, aIsFixedPositioned, PR_FALSE);
|
1999-03-02 22:43:26 +00:00
|
|
|
|
1999-08-19 22:16:23 +00:00
|
|
|
aNewFrame = listFrame;
|
|
|
|
|
1999-04-12 22:14:31 +00:00
|
|
|
// Set flag so the events go to the listFrame not child frames.
|
|
|
|
// XXX: We should replace this with a real widget manager similar
|
|
|
|
// to how the nsFormControlFrame works.
|
|
|
|
// Re-directing events is a temporary Kludge.
|
1999-03-02 22:43:26 +00:00
|
|
|
nsIView *listView;
|
1999-10-26 04:44:41 +00:00
|
|
|
listFrame->GetView(aPresContext, &listView);
|
1999-03-02 22:43:26 +00:00
|
|
|
NS_ASSERTION(nsnull != listView,"ListFrame's view is nsnull");
|
1999-09-03 14:57:47 +00:00
|
|
|
//listView->SetViewFlags(NS_VIEW_PUBLIC_FLAG_DONT_CHECK_CHILDREN);
|
1999-03-02 22:43:26 +00:00
|
|
|
aFrameHasBeenInitialized = PR_TRUE;
|
|
|
|
}
|
1999-02-05 03:55:18 +00:00
|
|
|
} else {
|
2000-01-31 22:46:55 +00:00
|
|
|
NS_ASSERTION(0, "We longer support native widgets");
|
1999-02-05 03:55:18 +00:00
|
|
|
}
|
1999-03-02 22:43:26 +00:00
|
|
|
}
|
|
|
|
else {
|
1999-04-12 22:14:31 +00:00
|
|
|
// Not frame based. Use a SelectFrame which creates a native widget.
|
2000-01-31 22:46:55 +00:00
|
|
|
NS_ASSERTION(0, "We longer support native widgets");
|
1999-02-05 03:55:18 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return rv;
|
|
|
|
|
1999-10-12 00:16:06 +00:00
|
|
|
}
|
1999-03-02 22:43:26 +00:00
|
|
|
|
1999-10-12 00:16:06 +00:00
|
|
|
/**
|
|
|
|
* Used to be InitializeScrollFrame but now its only used for the select tag
|
|
|
|
* But the select tag should really be fixed to use GFX scrollbars that can
|
|
|
|
* be create with BuildScrollFrame.
|
|
|
|
*/
|
1999-02-05 03:55:18 +00:00
|
|
|
nsresult
|
1999-12-04 23:49:50 +00:00
|
|
|
nsCSSFrameConstructor::InitializeSelectFrame(nsIPresShell* aPresShell,
|
|
|
|
nsIPresContext* aPresContext,
|
1999-10-12 00:16:06 +00:00
|
|
|
nsFrameConstructorState& aState,
|
|
|
|
nsIFrame* scrollFrame,
|
|
|
|
nsIFrame* scrolledFrame,
|
|
|
|
nsIContent* aContent,
|
|
|
|
nsIFrame* aParentFrame,
|
|
|
|
nsIStyleContext* aStyleContext,
|
|
|
|
PRBool aIsAbsolutelyPositioned,
|
|
|
|
PRBool aIsFixedPositioned,
|
|
|
|
PRBool aCreateBlock)
|
1999-02-05 03:55:18 +00:00
|
|
|
{
|
1999-10-12 00:16:06 +00:00
|
|
|
// Initialize it
|
|
|
|
nsIFrame* geometricParent = aParentFrame;
|
|
|
|
|
|
|
|
if (aIsAbsolutelyPositioned) {
|
|
|
|
geometricParent = aState.mAbsoluteItems.containingBlock;
|
|
|
|
} else if (aIsFixedPositioned) {
|
|
|
|
geometricParent = aState.mFixedItems.containingBlock;
|
1999-02-05 03:55:18 +00:00
|
|
|
}
|
1999-10-12 00:16:06 +00:00
|
|
|
|
|
|
|
nsCOMPtr<nsIStyleContext> scrollPseudoStyle;
|
|
|
|
nsCOMPtr<nsIStyleContext> scrolledPseudoStyle;
|
1999-02-05 03:55:18 +00:00
|
|
|
|
1999-10-12 00:16:06 +00:00
|
|
|
|
|
|
|
aPresContext->ResolvePseudoStyleContextFor(aContent,
|
|
|
|
nsLayoutAtoms::scrolledContentPseudo,
|
1999-10-14 14:55:08 +00:00
|
|
|
aStyleContext, PR_FALSE,
|
1999-10-12 00:16:06 +00:00
|
|
|
getter_AddRefs(scrolledPseudoStyle));
|
|
|
|
|
1999-12-06 07:44:18 +00:00
|
|
|
InitAndRestoreFrame(aPresContext, aState, aContent,
|
|
|
|
geometricParent, aStyleContext, nsnull, scrollFrame);
|
1999-10-12 00:16:06 +00:00
|
|
|
|
1999-12-06 07:44:18 +00:00
|
|
|
// Initialize the frame and force it to have a view
|
1999-10-12 00:16:06 +00:00
|
|
|
// the scrolled frame is anonymous and does not have a content node
|
1999-12-06 07:44:18 +00:00
|
|
|
InitAndRestoreFrame(aPresContext, aState, aContent,
|
|
|
|
scrollFrame, scrolledPseudoStyle, nsnull, scrolledFrame);
|
1999-10-12 00:16:06 +00:00
|
|
|
|
1999-12-06 07:44:18 +00:00
|
|
|
nsHTMLContainerFrame::CreateViewForFrame(aPresContext, scrolledFrame,
|
1999-10-12 00:16:06 +00:00
|
|
|
scrolledPseudoStyle, PR_TRUE);
|
|
|
|
|
|
|
|
|
|
|
|
// The area frame is a floater container
|
|
|
|
PRBool haveFirstLetterStyle, haveFirstLineStyle;
|
|
|
|
HaveSpecialBlockStyle(aPresContext, aContent, aStyleContext,
|
|
|
|
&haveFirstLetterStyle, &haveFirstLineStyle);
|
|
|
|
nsFrameConstructorSaveState floaterSaveState;
|
|
|
|
aState.PushFloaterContainingBlock(scrolledFrame, floaterSaveState,
|
|
|
|
haveFirstLetterStyle,
|
|
|
|
haveFirstLineStyle);
|
|
|
|
|
|
|
|
// Process children
|
|
|
|
nsFrameConstructorSaveState absoluteSaveState;
|
|
|
|
nsFrameItems childItems;
|
|
|
|
PRBool isPositionedContainingBlock = aIsAbsolutelyPositioned ||
|
|
|
|
aIsFixedPositioned;
|
|
|
|
|
|
|
|
if (isPositionedContainingBlock) {
|
|
|
|
// The area frame becomes a container for child frames that are
|
|
|
|
// absolutely positioned
|
|
|
|
aState.PushAbsoluteContainingBlock(scrolledFrame, absoluteSaveState);
|
|
|
|
}
|
|
|
|
|
1999-12-04 23:49:50 +00:00
|
|
|
ProcessChildren(aPresShell, aPresContext, aState, aContent, scrolledFrame, PR_FALSE,
|
1999-10-12 00:16:06 +00:00
|
|
|
childItems, PR_TRUE);
|
|
|
|
|
|
|
|
// if a select is being created with zero options we need to create
|
|
|
|
// a special pseudo frame so it can be sized as best it can
|
|
|
|
nsCOMPtr<nsIDOMHTMLSelectElement> selectElement;
|
2000-02-02 22:24:56 +00:00
|
|
|
nsresult result = aContent->QueryInterface(NS_GET_IID(nsIDOMHTMLSelectElement),
|
1999-10-12 00:16:06 +00:00
|
|
|
(void**)getter_AddRefs(selectElement));
|
|
|
|
if (NS_SUCCEEDED(result) && selectElement) {
|
|
|
|
PRUint32 numOptions = 0;
|
|
|
|
result = selectElement->GetLength(&numOptions);
|
|
|
|
if (NS_SUCCEEDED(result) && 0 == numOptions) {
|
2000-02-23 21:32:23 +00:00
|
|
|
nsCOMPtr<nsIStyleContext> styleContext;
|
1999-10-12 00:16:06 +00:00
|
|
|
nsIFrame* generatedFrame = nsnull;
|
2000-02-23 21:32:23 +00:00
|
|
|
scrolledFrame->GetStyleContext(getter_AddRefs(styleContext));
|
1999-12-04 23:49:50 +00:00
|
|
|
if (CreateGeneratedContentFrame(aPresShell, aPresContext, aState, scrolledFrame, aContent,
|
1999-10-12 00:16:06 +00:00
|
|
|
styleContext, nsLayoutAtoms::dummyOptionPseudo,
|
1999-10-29 14:39:48 +00:00
|
|
|
PR_FALSE, &generatedFrame)) {
|
1999-10-12 00:16:06 +00:00
|
|
|
// Add the generated frame to the child list
|
|
|
|
childItems.AddChild(generatedFrame);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
//////////////////////////////////////////////////
|
|
|
|
//////////////////////////////////////////////////
|
|
|
|
|
|
|
|
// Set the scrolled frame's initial child lists
|
1999-11-24 06:03:41 +00:00
|
|
|
scrolledFrame->SetInitialChildList(aPresContext, nsnull, childItems.childList);
|
1999-10-12 00:16:06 +00:00
|
|
|
if (isPositionedContainingBlock && aState.mAbsoluteItems.childList) {
|
1999-11-24 06:03:41 +00:00
|
|
|
scrolledFrame->SetInitialChildList(aPresContext,
|
1999-10-12 00:16:06 +00:00
|
|
|
nsLayoutAtoms::absoluteList,
|
|
|
|
aState.mAbsoluteItems.childList);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (aState.mFloatedItems.childList) {
|
1999-11-24 06:03:41 +00:00
|
|
|
scrolledFrame->SetInitialChildList(aPresContext,
|
1999-10-12 00:16:06 +00:00
|
|
|
nsLayoutAtoms::floaterList,
|
|
|
|
aState.mFloatedItems.childList);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Set the scroll frame's initial child list
|
1999-11-24 06:03:41 +00:00
|
|
|
scrollFrame->SetInitialChildList(aPresContext, nsnull, scrolledFrame);
|
1999-10-12 00:16:06 +00:00
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2000-02-14 01:42:09 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Used to be InitializeScrollFrame but now its only used for the select tag
|
|
|
|
* But the select tag should really be fixed to use GFX scrollbars that can
|
|
|
|
* be create with BuildScrollFrame.
|
|
|
|
*/
|
|
|
|
nsresult
|
|
|
|
nsCSSFrameConstructor::ConstructTitledBoxFrame(nsIPresShell* aPresShell,
|
|
|
|
nsIPresContext* aPresContext,
|
|
|
|
nsFrameConstructorState& aState,
|
|
|
|
nsIContent* aContent,
|
|
|
|
nsIFrame* aParentFrame,
|
|
|
|
nsIAtom* aTag,
|
|
|
|
nsIStyleContext* aStyleContext,
|
|
|
|
nsIFrame*& aNewFrame)
|
|
|
|
{
|
2000-06-12 23:23:00 +00:00
|
|
|
/*
|
2000-02-14 01:42:09 +00:00
|
|
|
nsIFrame * newFrame;
|
|
|
|
nsresult rv = NS_NewTitledBoxFrame(aPresShell, &newFrame);
|
|
|
|
if (!NS_SUCCEEDED(rv)) {
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsCOMPtr<nsIPresShell> shell;
|
|
|
|
aPresContext->GetShell(getter_AddRefs(shell));
|
|
|
|
|
|
|
|
// Initialize it
|
|
|
|
nsIFrame* geometricParent = aParentFrame;
|
|
|
|
|
|
|
|
InitAndRestoreFrame(aPresContext, aState, aContent,
|
|
|
|
geometricParent, aStyleContext, nsnull, newFrame);
|
|
|
|
|
|
|
|
// cache our display type
|
|
|
|
const nsStyleDisplay* styleDisplay;
|
|
|
|
newFrame->GetStyleData(eStyleStruct_Display, (const nsStyleStruct*&) styleDisplay);
|
|
|
|
|
|
|
|
nsIFrame * boxFrame;
|
|
|
|
NS_NewTitledBoxInnerFrame(shell, &boxFrame);
|
|
|
|
|
|
|
|
|
|
|
|
// Resolve style and initialize the frame
|
|
|
|
nsIStyleContext* styleContext;
|
|
|
|
aPresContext->ResolvePseudoStyleContextFor(aContent, nsXULAtoms::titledboxContentPseudo,
|
|
|
|
aStyleContext, PR_FALSE, &styleContext);
|
|
|
|
InitAndRestoreFrame(aPresContext, aState, nsnull,
|
|
|
|
newFrame, styleContext, nsnull, boxFrame);
|
|
|
|
|
|
|
|
NS_RELEASE(styleContext);
|
|
|
|
|
|
|
|
nsFrameItems childItems;
|
|
|
|
|
|
|
|
ProcessChildren(aPresShell, aPresContext, aState, aContent, boxFrame, PR_FALSE,
|
|
|
|
childItems, PR_TRUE);
|
|
|
|
|
|
|
|
static NS_DEFINE_IID(kTitleFrameCID, NS_TITLE_FRAME_CID);
|
|
|
|
nsIFrame * child = childItems.childList;
|
|
|
|
nsIFrame * previous = nsnull;
|
|
|
|
nsIFrame* titleFrame = nsnull;
|
|
|
|
while (nsnull != child) {
|
|
|
|
nsresult result = child->QueryInterface(kTitleFrameCID, (void**)&titleFrame);
|
|
|
|
if (NS_SUCCEEDED(result) && titleFrame) {
|
|
|
|
if (nsnull != previous) {
|
|
|
|
nsIFrame * nxt;
|
|
|
|
titleFrame->GetNextSibling(&nxt);
|
|
|
|
previous->SetNextSibling(nxt);
|
|
|
|
titleFrame->SetNextSibling(boxFrame);
|
|
|
|
break;
|
|
|
|
} else {
|
|
|
|
nsIFrame * nxt;
|
|
|
|
titleFrame->GetNextSibling(&nxt);
|
|
|
|
childItems.childList = nxt;
|
|
|
|
titleFrame->SetNextSibling(boxFrame);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
previous = child;
|
|
|
|
child->GetNextSibling(&child);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Set the scrolled frame's initial child lists
|
|
|
|
boxFrame->SetInitialChildList(aPresContext, nsnull, childItems.childList);
|
|
|
|
|
|
|
|
if (titleFrame)
|
|
|
|
newFrame->SetInitialChildList(aPresContext, nsnull, titleFrame);
|
|
|
|
else
|
|
|
|
newFrame->SetInitialChildList(aPresContext, nsnull, boxFrame);
|
|
|
|
|
|
|
|
// our new frame retured is the top frame which is the list frame.
|
|
|
|
aNewFrame = newFrame;
|
2000-06-12 23:23:00 +00:00
|
|
|
*/
|
2000-02-14 01:42:09 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2000-01-09 02:04:36 +00:00
|
|
|
/**
|
|
|
|
* Used to be InitializeScrollFrame but now its only used for the select tag
|
|
|
|
* But the select tag should really be fixed to use GFX scrollbars that can
|
|
|
|
* be create with BuildScrollFrame.
|
|
|
|
*/
|
|
|
|
nsresult
|
|
|
|
nsCSSFrameConstructor::ConstructFieldSetFrame(nsIPresShell* aPresShell,
|
|
|
|
nsIPresContext* aPresContext,
|
|
|
|
nsFrameConstructorState& aState,
|
|
|
|
nsIContent* aContent,
|
|
|
|
nsIFrame* aParentFrame,
|
|
|
|
nsIAtom* aTag,
|
|
|
|
nsIStyleContext* aStyleContext,
|
|
|
|
nsIFrame*& aNewFrame,
|
|
|
|
PRBool& aProcessChildren,
|
|
|
|
PRBool aIsAbsolutelyPositioned,
|
|
|
|
PRBool& aFrameHasBeenInitialized,
|
|
|
|
PRBool aIsFixedPositioned)
|
|
|
|
{
|
|
|
|
nsIFrame * newFrame;
|
2000-01-18 15:40:25 +00:00
|
|
|
PRUint32 flags = aIsAbsolutelyPositioned ? NS_BLOCK_SPACE_MGR : 0;
|
|
|
|
nsresult rv = NS_NewFieldSetFrame(aPresShell, &newFrame, flags);
|
2000-01-31 14:26:25 +00:00
|
|
|
if (!NS_SUCCEEDED(rv)) {
|
2000-01-31 14:04:41 +00:00
|
|
|
return rv;
|
|
|
|
}
|
2000-01-09 02:04:36 +00:00
|
|
|
|
|
|
|
nsCOMPtr<nsIPresShell> shell;
|
|
|
|
aPresContext->GetShell(getter_AddRefs(shell));
|
|
|
|
|
|
|
|
// Initialize it
|
|
|
|
nsIFrame* geometricParent = aParentFrame;
|
|
|
|
|
|
|
|
if (aIsAbsolutelyPositioned) {
|
|
|
|
geometricParent = aState.mAbsoluteItems.containingBlock;
|
|
|
|
} else if (aIsFixedPositioned) {
|
|
|
|
geometricParent = aState.mFixedItems.containingBlock;
|
|
|
|
}
|
|
|
|
|
|
|
|
InitAndRestoreFrame(aPresContext, aState, aContent,
|
|
|
|
geometricParent, aStyleContext, nsnull, newFrame);
|
|
|
|
|
|
|
|
// See if we need to create a view, e.g. the frame is absolutely
|
|
|
|
// positioned
|
|
|
|
nsHTMLContainerFrame::CreateViewForFrame(aPresContext, newFrame,
|
|
|
|
aStyleContext, PR_FALSE);
|
|
|
|
|
|
|
|
// cache our display type
|
|
|
|
const nsStyleDisplay* styleDisplay;
|
|
|
|
newFrame->GetStyleData(eStyleStruct_Display, (const nsStyleStruct*&) styleDisplay);
|
2000-02-10 21:36:28 +00:00
|
|
|
|
2000-05-02 14:34:24 +00:00
|
|
|
nsIFrame * areaFrame;
|
|
|
|
//NS_NewBlockFrame(shell, &areaFrame, flags);
|
|
|
|
NS_NewAreaFrame(shell, &areaFrame, flags | NS_BLOCK_SHRINK_WRAP);// | NS_BLOCK_MARGIN_ROOT);
|
2000-01-09 02:04:36 +00:00
|
|
|
|
|
|
|
// Resolve style and initialize the frame
|
|
|
|
nsIStyleContext* styleContext;
|
|
|
|
aPresContext->ResolvePseudoStyleContextFor(aContent, nsHTMLAtoms::fieldsetContentPseudo,
|
|
|
|
aStyleContext, PR_FALSE, &styleContext);
|
|
|
|
InitAndRestoreFrame(aPresContext, aState, aContent,
|
2000-05-02 14:34:24 +00:00
|
|
|
newFrame, styleContext, nsnull, areaFrame);
|
2000-01-09 02:04:36 +00:00
|
|
|
|
|
|
|
NS_RELEASE(styleContext);
|
|
|
|
|
|
|
|
|
|
|
|
// The area frame is a floater container
|
|
|
|
PRBool haveFirstLetterStyle, haveFirstLineStyle;
|
|
|
|
HaveSpecialBlockStyle(aPresContext, aContent, aStyleContext,
|
|
|
|
&haveFirstLetterStyle, &haveFirstLineStyle);
|
|
|
|
nsFrameConstructorSaveState floaterSaveState;
|
2000-05-02 14:34:24 +00:00
|
|
|
aState.PushFloaterContainingBlock(areaFrame, floaterSaveState,
|
2000-01-09 02:04:36 +00:00
|
|
|
haveFirstLetterStyle,
|
|
|
|
haveFirstLineStyle);
|
|
|
|
|
|
|
|
// Process children
|
|
|
|
nsFrameConstructorSaveState absoluteSaveState;
|
|
|
|
nsFrameItems childItems;
|
|
|
|
PRBool isPositionedContainingBlock = aIsAbsolutelyPositioned ||
|
|
|
|
aIsFixedPositioned;
|
|
|
|
|
|
|
|
if (isPositionedContainingBlock) {
|
|
|
|
// The area frame becomes a container for child frames that are
|
|
|
|
// absolutely positioned
|
2000-05-02 14:34:24 +00:00
|
|
|
aState.PushAbsoluteContainingBlock(areaFrame, absoluteSaveState);
|
2000-01-09 02:04:36 +00:00
|
|
|
}
|
|
|
|
|
2000-05-02 14:34:24 +00:00
|
|
|
ProcessChildren(aPresShell, aPresContext, aState, aContent, areaFrame, PR_FALSE,
|
2000-01-09 02:04:36 +00:00
|
|
|
childItems, PR_TRUE);
|
|
|
|
|
|
|
|
static NS_DEFINE_IID(kLegendFrameCID, NS_LEGEND_FRAME_CID);
|
|
|
|
nsIFrame * child = childItems.childList;
|
|
|
|
nsIFrame * previous = nsnull;
|
|
|
|
nsIFrame* legendFrame = nsnull;
|
|
|
|
while (nsnull != child) {
|
|
|
|
nsresult result = child->QueryInterface(kLegendFrameCID, (void**)&legendFrame);
|
|
|
|
if (NS_SUCCEEDED(result) && legendFrame) {
|
|
|
|
if (nsnull != previous) {
|
|
|
|
nsIFrame * nxt;
|
|
|
|
legendFrame->GetNextSibling(&nxt);
|
|
|
|
previous->SetNextSibling(nxt);
|
2000-05-02 14:34:24 +00:00
|
|
|
areaFrame->SetNextSibling(legendFrame);
|
2000-01-09 02:04:36 +00:00
|
|
|
legendFrame->SetParent(newFrame);
|
|
|
|
legendFrame->SetNextSibling(nsnull);
|
|
|
|
break;
|
|
|
|
} else {
|
|
|
|
nsIFrame * nxt;
|
|
|
|
legendFrame->GetNextSibling(&nxt);
|
|
|
|
childItems.childList = nxt;
|
2000-05-02 14:34:24 +00:00
|
|
|
areaFrame->SetNextSibling(legendFrame);
|
2000-01-09 02:04:36 +00:00
|
|
|
legendFrame->SetParent(newFrame);
|
|
|
|
legendFrame->SetNextSibling(nsnull);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2000-03-21 21:40:23 +00:00
|
|
|
previous = child;
|
2000-01-09 02:04:36 +00:00
|
|
|
child->GetNextSibling(&child);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Set the scrolled frame's initial child lists
|
2000-05-02 14:34:24 +00:00
|
|
|
areaFrame->SetInitialChildList(aPresContext, nsnull, childItems.childList);
|
2000-01-09 02:04:36 +00:00
|
|
|
if (isPositionedContainingBlock && aState.mAbsoluteItems.childList) {
|
2000-05-02 14:34:24 +00:00
|
|
|
areaFrame->SetInitialChildList(aPresContext,
|
2000-01-09 02:04:36 +00:00
|
|
|
nsLayoutAtoms::absoluteList,
|
|
|
|
aState.mAbsoluteItems.childList);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (aState.mFloatedItems.childList) {
|
2000-05-02 14:34:24 +00:00
|
|
|
areaFrame->SetInitialChildList(aPresContext,
|
2000-01-09 02:04:36 +00:00
|
|
|
nsLayoutAtoms::floaterList,
|
|
|
|
aState.mFloatedItems.childList);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Set the scroll frame's initial child list
|
2000-05-02 14:34:24 +00:00
|
|
|
newFrame->SetInitialChildList(aPresContext, nsnull, areaFrame);
|
2000-01-09 02:04:36 +00:00
|
|
|
|
|
|
|
// our new frame retured is the top frame which is the list frame.
|
|
|
|
aNewFrame = newFrame;
|
|
|
|
|
|
|
|
// yes we have already initialized our frame
|
|
|
|
aFrameHasBeenInitialized = PR_TRUE;
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
1999-10-12 00:16:06 +00:00
|
|
|
|
|
|
|
nsresult
|
2000-04-04 01:28:15 +00:00
|
|
|
nsCSSFrameConstructor::ConstructFrameByTag(nsIPresShell* aPresShell,
|
1999-12-04 23:49:50 +00:00
|
|
|
nsIPresContext* aPresContext,
|
1999-10-12 00:16:06 +00:00
|
|
|
nsFrameConstructorState& aState,
|
|
|
|
nsIContent* aContent,
|
|
|
|
nsIFrame* aParentFrame,
|
|
|
|
nsIAtom* aTag,
|
2000-05-24 08:19:10 +00:00
|
|
|
PRInt32 aNameSpaceID,
|
1999-10-12 00:16:06 +00:00
|
|
|
nsIStyleContext* aStyleContext,
|
|
|
|
nsFrameItems& aFrameItems)
|
|
|
|
{
|
|
|
|
PRBool processChildren = PR_FALSE; // whether we should process child content
|
|
|
|
PRBool isAbsolutelyPositioned = PR_FALSE;
|
|
|
|
PRBool isFixedPositioned = PR_FALSE;
|
|
|
|
PRBool isFloating = PR_FALSE;
|
2000-05-09 05:11:12 +00:00
|
|
|
PRBool isRelativePositioned = PR_FALSE;
|
1999-10-12 00:16:06 +00:00
|
|
|
PRBool canBePositioned = PR_TRUE;
|
|
|
|
PRBool frameHasBeenInitialized = PR_FALSE;
|
|
|
|
nsIFrame* newFrame = nsnull; // the frame we construct
|
|
|
|
PRBool isReplaced = PR_FALSE;
|
|
|
|
PRBool addToHashTable = PR_TRUE;
|
2000-04-01 18:47:09 +00:00
|
|
|
PRBool isFloaterContainer = PR_FALSE;
|
2000-05-09 05:11:12 +00:00
|
|
|
PRBool isPositionedContainingBlock = PR_FALSE;
|
1999-10-12 00:16:06 +00:00
|
|
|
nsresult rv = NS_OK;
|
|
|
|
|
|
|
|
if (nsLayoutAtoms::textTagName == aTag) {
|
2000-04-04 01:28:15 +00:00
|
|
|
// process pending pseudo frames. whitespace doesn't have an effect.
|
|
|
|
if (!aState.mPseudoFrames.IsEmpty() && !IsOnlyWhiteSpace(aContent)) {
|
|
|
|
ProcessPseudoFrames(aPresContext, aState.mPseudoFrames, aFrameItems);
|
|
|
|
}
|
1999-12-04 23:49:50 +00:00
|
|
|
rv = NS_NewTextFrame(aPresShell, &newFrame);
|
1999-10-12 00:16:06 +00:00
|
|
|
// Text frames don't go in the content->frame hash table, because
|
|
|
|
// they're anonymous. This keeps the hash table smaller
|
|
|
|
addToHashTable = PR_FALSE;
|
|
|
|
isReplaced = PR_TRUE; // XXX kipp: temporary
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
nsIHTMLContent *htmlContent;
|
|
|
|
|
|
|
|
// Ignore the tag if it's not HTML content
|
|
|
|
if (NS_SUCCEEDED(aContent->QueryInterface(kIHTMLContentIID, (void **)&htmlContent))) {
|
|
|
|
NS_RELEASE(htmlContent);
|
|
|
|
|
|
|
|
// See if the element is absolute or fixed positioned
|
|
|
|
const nsStylePosition* position = (const nsStylePosition*)
|
|
|
|
aStyleContext->GetStyleData(eStyleStruct_Position);
|
|
|
|
const nsStyleDisplay* display = (const nsStyleDisplay*)
|
|
|
|
aStyleContext->GetStyleData(eStyleStruct_Display);
|
|
|
|
if (NS_STYLE_POSITION_ABSOLUTE == position->mPosition) {
|
|
|
|
isAbsolutelyPositioned = PR_TRUE;
|
|
|
|
}
|
|
|
|
else if (NS_STYLE_POSITION_FIXED == position->mPosition) {
|
|
|
|
isFixedPositioned = PR_TRUE;
|
1999-02-05 03:55:18 +00:00
|
|
|
}
|
2000-05-09 05:11:12 +00:00
|
|
|
else {
|
|
|
|
if (NS_STYLE_FLOAT_NONE != display->mFloats) {
|
|
|
|
isFloating = PR_TRUE;
|
|
|
|
}
|
|
|
|
if (NS_STYLE_POSITION_RELATIVE == position->mPosition) {
|
|
|
|
isRelativePositioned = PR_TRUE;
|
|
|
|
}
|
1999-02-26 17:11:54 +00:00
|
|
|
}
|
1999-02-05 03:55:18 +00:00
|
|
|
|
|
|
|
// Create a frame based on the tag
|
|
|
|
if (nsHTMLAtoms::img == aTag) {
|
1999-02-13 05:59:19 +00:00
|
|
|
isReplaced = PR_TRUE;
|
2000-04-04 01:28:15 +00:00
|
|
|
if (!aState.mPseudoFrames.IsEmpty()) { // process pending pseudo frames
|
|
|
|
ProcessPseudoFrames(aPresContext, aState.mPseudoFrames, aFrameItems);
|
|
|
|
}
|
2000-07-19 05:06:55 +00:00
|
|
|
// XXX If image display is turned off, then use ConstructAlternateFrame()
|
1999-02-06 03:45:11 +00:00
|
|
|
// instead...
|
1999-12-04 23:49:50 +00:00
|
|
|
rv = NS_NewImageFrame(aPresShell, &newFrame);
|
1999-02-05 03:55:18 +00:00
|
|
|
}
|
|
|
|
else if (nsHTMLAtoms::hr == aTag) {
|
2000-04-04 01:28:15 +00:00
|
|
|
if (!aState.mPseudoFrames.IsEmpty()) { // process pending pseudo frames
|
|
|
|
ProcessPseudoFrames(aPresContext, aState.mPseudoFrames, aFrameItems);
|
|
|
|
}
|
1999-12-04 23:49:50 +00:00
|
|
|
rv = NS_NewHRFrame(aPresShell, &newFrame);
|
1999-02-05 03:55:18 +00:00
|
|
|
}
|
|
|
|
else if (nsHTMLAtoms::br == aTag) {
|
2000-04-04 01:28:15 +00:00
|
|
|
if (!aState.mPseudoFrames.IsEmpty()) { // process pending pseudo frames
|
|
|
|
ProcessPseudoFrames(aPresContext, aState.mPseudoFrames, aFrameItems);
|
|
|
|
}
|
1999-12-04 23:49:50 +00:00
|
|
|
rv = NS_NewBRFrame(aPresShell, &newFrame);
|
1999-02-26 17:11:54 +00:00
|
|
|
isReplaced = PR_TRUE;
|
1999-07-06 03:52:33 +00:00
|
|
|
// BR frames don't go in the content->frame hash table: typically
|
|
|
|
// there are many BR content objects and this would increase the size
|
|
|
|
// of the hash table, and it's doubtful we need the mapping anyway
|
|
|
|
addToHashTable = PR_FALSE;
|
1999-02-05 03:55:18 +00:00
|
|
|
}
|
|
|
|
else if (nsHTMLAtoms::wbr == aTag) {
|
2000-04-04 01:28:15 +00:00
|
|
|
if (!aState.mPseudoFrames.IsEmpty()) { // process pending pseudo frames
|
|
|
|
ProcessPseudoFrames(aPresContext, aState.mPseudoFrames, aFrameItems);
|
|
|
|
}
|
1999-12-04 23:49:50 +00:00
|
|
|
rv = NS_NewWBRFrame(aPresShell, &newFrame);
|
1999-02-05 03:55:18 +00:00
|
|
|
}
|
|
|
|
else if (nsHTMLAtoms::input == aTag) {
|
2000-04-04 01:28:15 +00:00
|
|
|
if (!aState.mPseudoFrames.IsEmpty()) { // process pending pseudo frames
|
|
|
|
ProcessPseudoFrames(aPresContext, aState.mPseudoFrames, aFrameItems);
|
|
|
|
}
|
1999-02-13 05:59:19 +00:00
|
|
|
isReplaced = PR_TRUE;
|
2000-02-23 21:36:29 +00:00
|
|
|
rv = CreateInputFrame(aPresShell, aPresContext, aContent, newFrame, aStyleContext);
|
1999-02-05 03:55:18 +00:00
|
|
|
}
|
|
|
|
else if (nsHTMLAtoms::textarea == aTag) {
|
2000-04-04 01:28:15 +00:00
|
|
|
if (!aState.mPseudoFrames.IsEmpty()) { // process pending pseudo frames
|
|
|
|
ProcessPseudoFrames(aPresContext, aState.mPseudoFrames, aFrameItems);
|
|
|
|
}
|
1999-02-13 05:59:19 +00:00
|
|
|
isReplaced = PR_TRUE;
|
1999-12-04 23:49:50 +00:00
|
|
|
rv = ConstructTextControlFrame(aPresShell, aPresContext, newFrame, aContent);
|
1999-02-05 03:55:18 +00:00
|
|
|
}
|
|
|
|
else if (nsHTMLAtoms::select == aTag) {
|
2000-04-04 01:28:15 +00:00
|
|
|
if (!aState.mPseudoFrames.IsEmpty()) { // process pending pseudo frames
|
|
|
|
ProcessPseudoFrames(aPresContext, aState.mPseudoFrames, aFrameItems);
|
|
|
|
}
|
1999-02-13 05:59:19 +00:00
|
|
|
isReplaced = PR_TRUE;
|
1999-12-04 23:49:50 +00:00
|
|
|
rv = ConstructSelectFrame(aPresShell, aPresContext, aState, aContent, aParentFrame,
|
1999-04-28 19:08:14 +00:00
|
|
|
aTag, aStyleContext, newFrame, processChildren,
|
|
|
|
isAbsolutelyPositioned, frameHasBeenInitialized,
|
|
|
|
isFixedPositioned, aFrameItems);
|
1999-02-05 03:55:18 +00:00
|
|
|
}
|
2000-07-06 04:31:33 +00:00
|
|
|
else if (nsHTMLAtoms::object == aTag) {
|
|
|
|
if (!aState.mPseudoFrames.IsEmpty()) { // process pending pseudo frames
|
|
|
|
ProcessPseudoFrames(aPresContext, aState.mPseudoFrames, aFrameItems);
|
|
|
|
}
|
|
|
|
isReplaced = PR_TRUE;
|
|
|
|
rv = NS_NewObjectFrame(aPresShell, &newFrame);
|
|
|
|
}
|
1999-02-05 03:55:18 +00:00
|
|
|
else if (nsHTMLAtoms::applet == aTag) {
|
2000-04-04 01:28:15 +00:00
|
|
|
if (!aState.mPseudoFrames.IsEmpty()) { // process pending pseudo frames
|
|
|
|
ProcessPseudoFrames(aPresContext, aState.mPseudoFrames, aFrameItems);
|
|
|
|
}
|
1999-02-13 05:59:19 +00:00
|
|
|
isReplaced = PR_TRUE;
|
1999-12-04 23:49:50 +00:00
|
|
|
rv = NS_NewObjectFrame(aPresShell, &newFrame);
|
1999-02-05 03:55:18 +00:00
|
|
|
}
|
|
|
|
else if (nsHTMLAtoms::embed == aTag) {
|
2000-04-04 01:28:15 +00:00
|
|
|
if (!aState.mPseudoFrames.IsEmpty()) { // process pending pseudo frames
|
|
|
|
ProcessPseudoFrames(aPresContext, aState.mPseudoFrames, aFrameItems);
|
|
|
|
}
|
1999-12-04 23:49:50 +00:00
|
|
|
rv = NS_NewObjectFrame(aPresShell, &newFrame);
|
1999-02-05 03:55:18 +00:00
|
|
|
}
|
|
|
|
else if (nsHTMLAtoms::fieldset == aTag) {
|
2000-04-04 01:28:15 +00:00
|
|
|
if (!aState.mPseudoFrames.IsEmpty()) { // process pending pseudo frames
|
|
|
|
ProcessPseudoFrames(aPresContext, aState.mPseudoFrames, aFrameItems);
|
|
|
|
}
|
2000-01-31 22:46:55 +00:00
|
|
|
#define DO_NEWFIELDSET
|
2000-01-09 02:04:36 +00:00
|
|
|
#ifdef DO_NEWFIELDSET
|
|
|
|
rv = ConstructFieldSetFrame(aPresShell, aPresContext, aState, aContent, aParentFrame,
|
|
|
|
aTag, aStyleContext, newFrame, processChildren,
|
|
|
|
isAbsolutelyPositioned, frameHasBeenInitialized,
|
|
|
|
isFixedPositioned);
|
|
|
|
processChildren = PR_FALSE;
|
|
|
|
#else
|
2000-01-18 15:40:25 +00:00
|
|
|
rv = NS_NewFieldSetFrame(aPresShell, &newFrame, isAbsolutelyPositioned ? NS_BLOCK_SPACE_MGR : 0);
|
1999-02-05 03:55:18 +00:00
|
|
|
processChildren = PR_TRUE;
|
2000-01-09 02:04:36 +00:00
|
|
|
#endif
|
1999-02-05 03:55:18 +00:00
|
|
|
}
|
|
|
|
else if (nsHTMLAtoms::legend == aTag) {
|
2000-04-04 01:28:15 +00:00
|
|
|
if (!aState.mPseudoFrames.IsEmpty()) { // process pending pseudo frames
|
|
|
|
ProcessPseudoFrames(aPresContext, aState.mPseudoFrames, aFrameItems);
|
|
|
|
}
|
1999-12-04 23:49:50 +00:00
|
|
|
rv = NS_NewLegendFrame(aPresShell, &newFrame);
|
1999-02-05 03:55:18 +00:00
|
|
|
processChildren = PR_TRUE;
|
|
|
|
canBePositioned = PR_FALSE;
|
|
|
|
}
|
|
|
|
else if (nsHTMLAtoms::form == aTag) {
|
2000-04-04 01:28:15 +00:00
|
|
|
if (!aState.mPseudoFrames.IsEmpty()) { // process pending pseudo frames
|
|
|
|
ProcessPseudoFrames(aPresContext, aState.mPseudoFrames, aFrameItems);
|
|
|
|
}
|
2000-03-15 04:38:08 +00:00
|
|
|
PRBool isOutOfFlow = isFloating || isAbsolutelyPositioned || isFixedPositioned;
|
|
|
|
|
|
|
|
rv = NS_NewFormFrame(aPresShell, &newFrame,
|
|
|
|
isOutOfFlow ? NS_BLOCK_SPACE_MGR|NS_BLOCK_MARGIN_ROOT : 0);
|
1999-07-22 23:28:16 +00:00
|
|
|
processChildren = PR_TRUE;
|
2000-04-01 18:47:09 +00:00
|
|
|
|
|
|
|
// A form frame is a block frame therefore it can contain floaters
|
|
|
|
isFloaterContainer = PR_TRUE;
|
2000-05-09 05:11:12 +00:00
|
|
|
|
|
|
|
// See if it's a containing block for absolutely positioned elements
|
|
|
|
isPositionedContainingBlock = isAbsolutelyPositioned || isFixedPositioned || isRelativePositioned;
|
1999-02-05 03:55:18 +00:00
|
|
|
}
|
|
|
|
else if (nsHTMLAtoms::frameset == aTag) {
|
2000-04-04 01:28:15 +00:00
|
|
|
if (!aState.mPseudoFrames.IsEmpty()) { // process pending pseudo frames
|
|
|
|
ProcessPseudoFrames(aPresContext, aState.mPseudoFrames, aFrameItems);
|
|
|
|
}
|
1999-12-04 23:49:50 +00:00
|
|
|
rv = NS_NewHTMLFramesetFrame(aPresShell, &newFrame);
|
1999-02-05 03:55:18 +00:00
|
|
|
canBePositioned = PR_FALSE;
|
|
|
|
}
|
|
|
|
else if (nsHTMLAtoms::iframe == aTag) {
|
2000-04-04 01:28:15 +00:00
|
|
|
if (!aState.mPseudoFrames.IsEmpty()) { // process pending pseudo frames
|
|
|
|
ProcessPseudoFrames(aPresContext, aState.mPseudoFrames, aFrameItems);
|
|
|
|
}
|
1999-02-13 05:59:19 +00:00
|
|
|
isReplaced = PR_TRUE;
|
1999-12-04 23:49:50 +00:00
|
|
|
rv = NS_NewHTMLFrameOuterFrame(aPresShell, &newFrame);
|
1999-02-05 03:55:18 +00:00
|
|
|
}
|
|
|
|
else if (nsHTMLAtoms::spacer == aTag) {
|
2000-04-04 01:28:15 +00:00
|
|
|
if (!aState.mPseudoFrames.IsEmpty()) { // process pending pseudo frames
|
|
|
|
ProcessPseudoFrames(aPresContext, aState.mPseudoFrames, aFrameItems);
|
|
|
|
}
|
1999-12-04 23:49:50 +00:00
|
|
|
rv = NS_NewSpacerFrame(aPresShell, &newFrame);
|
1999-02-05 03:55:18 +00:00
|
|
|
canBePositioned = PR_FALSE;
|
|
|
|
}
|
|
|
|
else if (nsHTMLAtoms::button == aTag) {
|
2000-04-04 01:28:15 +00:00
|
|
|
if (!aState.mPseudoFrames.IsEmpty()) { // process pending pseudo frames
|
|
|
|
ProcessPseudoFrames(aPresContext, aState.mPseudoFrames, aFrameItems);
|
|
|
|
}
|
1999-12-04 23:49:50 +00:00
|
|
|
rv = NS_NewHTMLButtonControlFrame(aPresShell, &newFrame);
|
1999-03-06 19:43:13 +00:00
|
|
|
// the html4 button needs to act just like a
|
|
|
|
// regular button except contain html content
|
|
|
|
// so it must be replaced or html outside it will
|
|
|
|
// draw into its borders. -EDV
|
|
|
|
isReplaced = PR_TRUE;
|
1999-02-05 03:55:18 +00:00
|
|
|
processChildren = PR_TRUE;
|
|
|
|
}
|
|
|
|
else if (nsHTMLAtoms::label == aTag) {
|
2000-04-04 01:28:15 +00:00
|
|
|
if (!aState.mPseudoFrames.IsEmpty()) { // process pending pseudo frames
|
|
|
|
ProcessPseudoFrames(aPresContext, aState.mPseudoFrames, aFrameItems);
|
|
|
|
}
|
2000-03-27 22:12:42 +00:00
|
|
|
rv = NS_NewLabelFrame(aPresShell, &newFrame, isAbsolutelyPositioned ? NS_BLOCK_SPACE_MGR : 0);
|
1999-02-05 03:55:18 +00:00
|
|
|
processChildren = PR_TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// If we succeeded in creating a frame then initialize it, process its
|
|
|
|
// children (if requested), and set the initial child list
|
|
|
|
if (NS_SUCCEEDED(rv) && (nsnull != newFrame)) {
|
1999-02-13 05:59:19 +00:00
|
|
|
// If the frame is a replaced element, then set the frame state bit
|
|
|
|
if (isReplaced) {
|
|
|
|
nsFrameState state;
|
|
|
|
newFrame->GetFrameState(&state);
|
|
|
|
newFrame->SetFrameState(state | NS_FRAME_REPLACED_ELEMENT);
|
|
|
|
}
|
|
|
|
|
1999-02-05 03:55:18 +00:00
|
|
|
if (!frameHasBeenInitialized) {
|
|
|
|
nsIFrame* geometricParent = aParentFrame;
|
|
|
|
|
1999-07-16 18:17:14 +00:00
|
|
|
// Makes sure we use the correct parent frame pointer when initializing
|
|
|
|
// the frame
|
|
|
|
if (isFloating) {
|
|
|
|
geometricParent = aState.mFloatedItems.containingBlock;
|
|
|
|
|
|
|
|
} else if (canBePositioned) {
|
|
|
|
if (isAbsolutelyPositioned) {
|
1999-04-28 19:08:14 +00:00
|
|
|
geometricParent = aState.mAbsoluteItems.containingBlock;
|
1999-02-05 03:55:18 +00:00
|
|
|
} else if (isFixedPositioned) {
|
1999-04-28 19:08:14 +00:00
|
|
|
geometricParent = aState.mFixedItems.containingBlock;
|
1999-02-05 03:55:18 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1999-12-06 07:44:18 +00:00
|
|
|
InitAndRestoreFrame(aPresContext, aState, aContent,
|
|
|
|
geometricParent, aStyleContext, nsnull, newFrame);
|
1999-02-05 03:55:18 +00:00
|
|
|
|
1999-02-26 17:11:54 +00:00
|
|
|
// See if we need to create a view, e.g. the frame is absolutely
|
|
|
|
// positioned
|
1999-11-24 06:03:41 +00:00
|
|
|
nsHTMLContainerFrame::CreateViewForFrame(aPresContext, newFrame,
|
1999-02-05 03:55:18 +00:00
|
|
|
aStyleContext, PR_FALSE);
|
|
|
|
|
|
|
|
// Process the child content if requested
|
|
|
|
nsFrameItems childItems;
|
|
|
|
if (processChildren) {
|
2000-05-09 05:11:12 +00:00
|
|
|
if (isPositionedContainingBlock) {
|
|
|
|
// The area frame becomes a container for child frames that are
|
|
|
|
// absolutely positioned
|
|
|
|
nsFrameConstructorSaveState absoluteSaveState;
|
|
|
|
aState.PushAbsoluteContainingBlock(newFrame, absoluteSaveState);
|
|
|
|
|
|
|
|
// Process the child frames
|
|
|
|
rv = ProcessChildren(aPresShell, aPresContext, aState, aContent, newFrame,
|
|
|
|
PR_TRUE, childItems, PR_FALSE);
|
|
|
|
|
|
|
|
// Set the frame's absolute list if there were any absolutely positioned children
|
|
|
|
if (aState.mAbsoluteItems.childList) {
|
|
|
|
newFrame->SetInitialChildList(aPresContext,
|
|
|
|
nsLayoutAtoms::absoluteList,
|
|
|
|
aState.mAbsoluteItems.childList);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (isFloaterContainer) {
|
2000-04-01 18:47:09 +00:00
|
|
|
// If the frame can contain floaters, then push a floater
|
|
|
|
// containing block
|
|
|
|
PRBool haveFirstLetterStyle, haveFirstLineStyle;
|
|
|
|
HaveSpecialBlockStyle(aPresContext, aContent, aStyleContext,
|
|
|
|
&haveFirstLetterStyle, &haveFirstLineStyle);
|
|
|
|
nsFrameConstructorSaveState floaterSaveState;
|
|
|
|
aState.PushFloaterContainingBlock(newFrame, floaterSaveState,
|
|
|
|
PR_FALSE, PR_FALSE);
|
|
|
|
|
|
|
|
// Process the child frames
|
|
|
|
rv = ProcessChildren(aPresShell, aPresContext, aState, aContent, newFrame,
|
|
|
|
PR_TRUE, childItems, PR_FALSE);
|
|
|
|
|
|
|
|
// Set the frame's floater list if there were any floated children
|
|
|
|
if (aState.mFloatedItems.childList) {
|
|
|
|
newFrame->SetInitialChildList(aPresContext,
|
|
|
|
nsLayoutAtoms::floaterList,
|
|
|
|
aState.mFloatedItems.childList);
|
|
|
|
}
|
|
|
|
|
|
|
|
} else {
|
|
|
|
rv = ProcessChildren(aPresShell, aPresContext, aState, aContent, newFrame,
|
|
|
|
PR_TRUE, childItems, PR_FALSE);
|
|
|
|
}
|
1999-02-05 03:55:18 +00:00
|
|
|
}
|
|
|
|
|
1999-06-30 22:17:43 +00:00
|
|
|
// if there are any anonymous children create frames for them
|
1999-12-04 23:49:50 +00:00
|
|
|
CreateAnonymousFrames(aPresShell, aPresContext, aTag, aState, aContent, newFrame,
|
1999-08-27 21:46:10 +00:00
|
|
|
childItems);
|
1999-06-30 22:17:43 +00:00
|
|
|
|
|
|
|
|
1999-02-05 03:55:18 +00:00
|
|
|
// Set the frame's initial child list
|
1999-11-24 06:03:41 +00:00
|
|
|
newFrame->SetInitialChildList(aPresContext, nsnull, childItems.childList);
|
1999-02-05 03:55:18 +00:00
|
|
|
}
|
|
|
|
|
1999-03-30 15:22:54 +00:00
|
|
|
// If the frame is positioned, then create a placeholder frame
|
1999-07-16 18:17:14 +00:00
|
|
|
if (canBePositioned && (isAbsolutelyPositioned || isFixedPositioned)) {
|
1999-02-05 03:55:18 +00:00
|
|
|
nsIFrame* placeholderFrame;
|
|
|
|
|
1999-12-04 23:49:50 +00:00
|
|
|
CreatePlaceholderFrameFor(aPresShell, aPresContext, aState.mFrameManager, aContent,
|
1999-08-05 03:09:22 +00:00
|
|
|
newFrame, aStyleContext, aParentFrame, &placeholderFrame);
|
1999-02-05 03:55:18 +00:00
|
|
|
|
1999-02-26 17:11:54 +00:00
|
|
|
// Add the positioned frame to its containing block's list of
|
|
|
|
// child frames
|
1999-02-05 03:55:18 +00:00
|
|
|
if (isAbsolutelyPositioned) {
|
1999-04-28 19:08:14 +00:00
|
|
|
aState.mAbsoluteItems.AddChild(newFrame);
|
1999-02-05 03:55:18 +00:00
|
|
|
} else {
|
1999-04-28 19:08:14 +00:00
|
|
|
aState.mFixedItems.AddChild(newFrame);
|
1999-02-05 03:55:18 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Add the placeholder frame to the flow
|
|
|
|
aFrameItems.AddChild(placeholderFrame);
|
|
|
|
|
1999-02-26 17:11:54 +00:00
|
|
|
} else if (isFloating) {
|
|
|
|
nsIFrame* placeholderFrame;
|
1999-12-04 23:49:50 +00:00
|
|
|
CreatePlaceholderFrameFor(aPresShell, aPresContext, aState.mFrameManager, aContent, newFrame,
|
1999-04-25 16:58:42 +00:00
|
|
|
aStyleContext, aParentFrame, &placeholderFrame);
|
1999-02-26 17:11:54 +00:00
|
|
|
|
|
|
|
// Add the floating frame to its containing block's list of child frames
|
1999-04-28 19:08:14 +00:00
|
|
|
aState.mFloatedItems.AddChild(newFrame);
|
1999-02-26 17:11:54 +00:00
|
|
|
|
|
|
|
// Add the placeholder frame to the flow
|
|
|
|
aFrameItems.AddChild(placeholderFrame);
|
1999-07-01 14:34:35 +00:00
|
|
|
|
1999-02-05 03:55:18 +00:00
|
|
|
} else {
|
|
|
|
// Add the newly constructed frame to the flow
|
|
|
|
aFrameItems.AddChild(newFrame);
|
|
|
|
}
|
1999-07-01 14:34:35 +00:00
|
|
|
|
|
|
|
if (addToHashTable) {
|
|
|
|
// Add a mapping from content object to primary frame. Note that for
|
|
|
|
// floated and positioned frames this is the out-of-flow frame and not
|
|
|
|
// the placeholder frame
|
1999-08-05 03:09:22 +00:00
|
|
|
aState.mFrameManager->SetPrimaryFrameFor(aContent, newFrame);
|
1999-07-01 14:34:35 +00:00
|
|
|
}
|
1999-02-05 03:55:18 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
1999-06-30 22:17:43 +00:00
|
|
|
// after the node has been constructed and initialized create any
|
|
|
|
// anonymous content a node needs.
|
2000-03-25 02:18:55 +00:00
|
|
|
static void LocateAnonymousFrame(nsIPresContext* aPresContext,
|
|
|
|
nsIFrame* aParentFrame,
|
|
|
|
nsIContent* aTargetContent,
|
|
|
|
nsIFrame** aResult)
|
|
|
|
{
|
|
|
|
// Check ourselves.
|
|
|
|
*aResult = nsnull;
|
|
|
|
nsCOMPtr<nsIContent> content;
|
|
|
|
aParentFrame->GetContent(getter_AddRefs(content));
|
|
|
|
if (content.get() == aTargetContent) {
|
2000-04-13 20:10:06 +00:00
|
|
|
// We must take into account if the parent is a scrollframe. If it is, we
|
|
|
|
// need to bypass the scrolling mechanics and get at the true frame.
|
|
|
|
nsCOMPtr<nsIScrollableFrame> scrollFrame ( do_QueryInterface(aParentFrame) );
|
|
|
|
if ( scrollFrame )
|
|
|
|
scrollFrame->GetScrolledFrame ( aPresContext, *aResult );
|
|
|
|
else
|
|
|
|
*aResult = aParentFrame;
|
2000-03-25 02:18:55 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Check our kids.
|
|
|
|
nsIFrame* currFrame;
|
|
|
|
aParentFrame->FirstChild(aPresContext, nsnull, &currFrame);
|
|
|
|
while (currFrame) {
|
|
|
|
LocateAnonymousFrame(aPresContext, currFrame, aTargetContent, aResult);
|
|
|
|
if (*aResult)
|
|
|
|
return;
|
|
|
|
currFrame->GetNextSibling(&currFrame);
|
|
|
|
}
|
2000-05-26 22:45:26 +00:00
|
|
|
|
|
|
|
nsCOMPtr<nsIMenuFrame> menuFrame(do_QueryInterface(aParentFrame));
|
|
|
|
if (menuFrame) {
|
|
|
|
nsIFrame* popupChild;
|
|
|
|
menuFrame->GetMenuChild(&popupChild);
|
|
|
|
if (popupChild) {
|
|
|
|
LocateAnonymousFrame(aPresContext, popupChild, aTargetContent, aResult);
|
|
|
|
if (*aResult)
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
2000-03-25 02:18:55 +00:00
|
|
|
}
|
|
|
|
|
1999-06-30 22:17:43 +00:00
|
|
|
nsresult
|
1999-12-04 23:49:50 +00:00
|
|
|
nsCSSFrameConstructor::CreateAnonymousFrames(nsIPresShell* aPresShell,
|
|
|
|
nsIPresContext* aPresContext,
|
1999-06-30 22:17:43 +00:00
|
|
|
nsIAtom* aTag,
|
|
|
|
nsFrameConstructorState& aState,
|
1999-08-27 06:06:39 +00:00
|
|
|
nsIContent* aParent,
|
1999-06-30 22:17:43 +00:00
|
|
|
nsIFrame* aNewFrame,
|
|
|
|
nsFrameItems& aChildItems)
|
|
|
|
{
|
2000-01-11 03:40:41 +00:00
|
|
|
nsCOMPtr<nsIStyleContext> styleContext;
|
|
|
|
aNewFrame->GetStyleContext(getter_AddRefs(styleContext));
|
|
|
|
|
|
|
|
const nsStyleUserInterface* ui= (const nsStyleUserInterface*)
|
|
|
|
styleContext->GetStyleData(eStyleStruct_UserInterface);
|
|
|
|
|
2000-03-26 10:06:21 +00:00
|
|
|
if (!ui->mBehavior.IsEmpty()) {
|
2000-01-11 08:25:59 +00:00
|
|
|
// Get the XBL loader.
|
|
|
|
nsresult rv;
|
2000-01-12 10:27:57 +00:00
|
|
|
NS_WITH_SERVICE(nsIXBLService, xblService, "component://netscape/xbl", &rv);
|
2000-01-11 08:25:59 +00:00
|
|
|
if (!xblService)
|
|
|
|
return rv;
|
|
|
|
|
|
|
|
// Load the bindings.
|
2000-07-28 00:35:30 +00:00
|
|
|
nsCOMPtr<nsIXBLBinding> binding;
|
|
|
|
xblService->LoadBindings(aParent, ui->mBehavior, PR_FALSE, getter_AddRefs(binding));
|
2000-01-11 08:25:59 +00:00
|
|
|
|
|
|
|
// Retrieve the anonymous content that we should build.
|
|
|
|
nsCOMPtr<nsISupportsArray> anonymousItems;
|
2000-03-14 11:09:46 +00:00
|
|
|
nsCOMPtr<nsIContent> childElement;
|
2000-05-22 08:23:46 +00:00
|
|
|
PRBool multiple;
|
|
|
|
xblService->GetContentList(aParent, getter_AddRefs(anonymousItems), getter_AddRefs(childElement), &multiple);
|
2000-01-11 08:25:59 +00:00
|
|
|
|
2000-05-03 06:17:49 +00:00
|
|
|
if (anonymousItems)
|
|
|
|
{
|
|
|
|
// See if we have to move our explicit content.
|
|
|
|
nsFrameItems explicitItems;
|
2000-05-22 08:23:46 +00:00
|
|
|
if (childElement || multiple) {
|
2000-05-03 06:17:49 +00:00
|
|
|
// First, remove all of the kids from the frame list and put them
|
|
|
|
// in a new frame list.
|
|
|
|
explicitItems.childList = aChildItems.childList;
|
|
|
|
explicitItems.lastChild = aChildItems.lastChild;
|
|
|
|
aChildItems.childList = aChildItems.lastChild = nsnull;
|
|
|
|
}
|
2000-03-25 02:18:55 +00:00
|
|
|
|
2000-05-03 06:17:49 +00:00
|
|
|
// Build the frames for the anonymous content.
|
|
|
|
PRUint32 count = 0;
|
|
|
|
anonymousItems->Count(&count);
|
2000-01-11 08:25:59 +00:00
|
|
|
|
2000-05-03 06:17:49 +00:00
|
|
|
for (PRUint32 i=0; i < count; i++)
|
|
|
|
{
|
|
|
|
// get our child's content and set its parent to our content
|
|
|
|
nsCOMPtr<nsISupports> node;
|
|
|
|
anonymousItems->GetElementAt(i,getter_AddRefs(node));
|
2000-01-11 08:25:59 +00:00
|
|
|
|
2000-05-03 06:17:49 +00:00
|
|
|
nsCOMPtr<nsIContent> content(do_QueryInterface(node));
|
2000-01-11 08:25:59 +00:00
|
|
|
|
2000-05-03 06:17:49 +00:00
|
|
|
// create the frame and attach it to our frame
|
|
|
|
ConstructFrame(aPresShell, aPresContext, aState, content, aNewFrame, aChildItems);
|
2000-03-25 02:18:55 +00:00
|
|
|
}
|
|
|
|
|
2000-05-03 06:17:49 +00:00
|
|
|
if (childElement) {
|
|
|
|
// Now append the explicit frames
|
|
|
|
// All our explicit content that we built must be reparented.
|
|
|
|
nsIFrame* frame = nsnull;
|
|
|
|
nsIFrame* currFrame = aChildItems.childList;
|
|
|
|
while (currFrame) {
|
|
|
|
LocateAnonymousFrame(aPresContext,
|
|
|
|
currFrame,
|
|
|
|
childElement,
|
|
|
|
&frame);
|
|
|
|
if (frame)
|
|
|
|
break;
|
|
|
|
currFrame->GetNextSibling(&currFrame);
|
|
|
|
}
|
|
|
|
|
|
|
|
nsCOMPtr<nsIFrameManager> frameManager;
|
|
|
|
aPresShell->GetFrameManager(getter_AddRefs(frameManager));
|
2000-03-25 02:18:55 +00:00
|
|
|
|
2000-05-03 06:17:49 +00:00
|
|
|
if (frameManager && frame && explicitItems.childList) {
|
|
|
|
frameManager->AppendFrames(aPresContext, *aPresShell, frame,
|
|
|
|
nsnull, explicitItems.childList);
|
2000-07-27 06:20:13 +00:00
|
|
|
nsCOMPtr<nsIStyleContext> styleContext;
|
|
|
|
frame->GetStyleContext(getter_AddRefs(styleContext));
|
|
|
|
nsIFrame* walkit = explicitItems.childList;
|
|
|
|
while (walkit) {
|
|
|
|
aPresContext->ReParentStyleContext(walkit, styleContext);
|
|
|
|
walkit->GetNextSibling(&walkit);
|
|
|
|
}
|
2000-05-03 06:17:49 +00:00
|
|
|
}
|
2000-04-04 06:29:20 +00:00
|
|
|
}
|
2000-05-22 08:23:46 +00:00
|
|
|
else if (multiple) {
|
|
|
|
nsCOMPtr<nsIDocument> document;
|
|
|
|
nsCOMPtr<nsIBindingManager> bindingManager;
|
|
|
|
aParent->GetDocument(*getter_AddRefs(document));
|
|
|
|
document->GetBindingManager(getter_AddRefs(bindingManager));
|
|
|
|
nsCOMPtr<nsIContent> currContent;
|
|
|
|
nsCOMPtr<nsIContent> insertionElement;
|
|
|
|
nsIFrame* currFrame = explicitItems.childList;
|
|
|
|
explicitItems.childList = explicitItems.lastChild = nsnull;
|
|
|
|
nsCOMPtr<nsIFrameManager> frameManager;
|
|
|
|
aPresShell->GetFrameManager(getter_AddRefs(frameManager));
|
|
|
|
|
|
|
|
while (currFrame) {
|
|
|
|
nsIFrame* nextFrame;
|
|
|
|
currFrame->GetNextSibling(&nextFrame);
|
|
|
|
currFrame->SetNextSibling(nsnull);
|
|
|
|
|
|
|
|
currFrame->GetContent(getter_AddRefs(currContent));
|
|
|
|
bindingManager->GetInsertionPoint(aParent, currContent, getter_AddRefs(insertionElement));
|
|
|
|
|
|
|
|
nsIFrame* frame = nsnull;
|
|
|
|
if (insertionElement) {
|
|
|
|
nsIFrame* childFrame = aChildItems.childList;
|
|
|
|
while (childFrame) {
|
|
|
|
LocateAnonymousFrame(aPresContext,
|
|
|
|
childFrame,
|
|
|
|
insertionElement,
|
|
|
|
&frame);
|
|
|
|
if (frame)
|
|
|
|
break;
|
|
|
|
childFrame->GetNextSibling(&childFrame);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!frame) {
|
|
|
|
if (!explicitItems.childList)
|
|
|
|
explicitItems.childList = explicitItems.lastChild = currFrame;
|
|
|
|
else {
|
|
|
|
explicitItems.lastChild->SetNextSibling(currFrame);
|
|
|
|
explicitItems.lastChild = currFrame;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (frameManager && frame) {
|
|
|
|
frameManager->AppendFrames(aPresContext, *aPresShell, frame,
|
|
|
|
nsnull, currFrame);
|
2000-07-27 06:20:13 +00:00
|
|
|
frame->GetStyleContext(getter_AddRefs(styleContext));
|
|
|
|
aPresContext->ReParentStyleContext(currFrame, styleContext);
|
2000-05-22 08:23:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
currFrame = nextFrame;
|
|
|
|
}
|
|
|
|
if (explicitItems.lastChild) {
|
|
|
|
explicitItems.lastChild->SetNextSibling(aChildItems.childList);
|
|
|
|
aChildItems.childList = explicitItems.childList;
|
|
|
|
}
|
|
|
|
}
|
2000-03-25 02:18:55 +00:00
|
|
|
|
2000-05-03 06:17:49 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
2000-01-11 08:25:59 +00:00
|
|
|
}
|
2000-05-03 06:17:49 +00:00
|
|
|
// if we have no anonymous content from XBL see if we have some from these tags.
|
|
|
|
// only these tags types can have anonymous content. We do this check for performance
|
1999-06-30 22:17:43 +00:00
|
|
|
// reasons. If we did a query interface on every tag it would be very inefficient.
|
|
|
|
if (aTag != nsHTMLAtoms::input &&
|
2000-05-16 03:40:02 +00:00
|
|
|
aTag != nsHTMLAtoms::textarea &&
|
fixed bugs #6303, #6753, #6756, #6759
Re-wrote nsComboboxFrame.
removed the obsolete nsHTMLAtoms: comboText,comoTextSelected,comTextSelectedFocus,dropDownVisible,
dropdownHidden, dropDownBtnOut, dropDownBtnPressed,
Added nsHTMLAtoms::combobox, nsLayoutAtoms::popupList
Renamed dropDownList to dropDownListPseudo
Added "arrow.gif" as to be used the background-image for the combobox button
ua.css - added rules for select to differentiate between comboboxes and listboxes.
Added style rules to more closely match the XPTOOLKIT XPWidgets look.
removed the following :-moz-combobox-text, -moz-combobox-textselected
nsIFormControlFrame.h - Added SetSuggestedSize method.
nsButtonControlFrame - Implemented SetSuggestedSize.
nsCSSFrameConstructor.cpp - Rewrote ConstructSelectFrame.
nsIWidget.h -Added GetAbsoluteBounds method.
nsWindow.cpp - Implemented GetAbsoluteBounds.
1999-07-14 22:00:24 +00:00
|
|
|
aTag != nsHTMLAtoms::combobox &&
|
1999-06-30 22:17:43 +00:00
|
|
|
aTag != nsXULAtoms::splitter &&
|
2000-08-07 02:51:35 +00:00
|
|
|
aTag != nsXULAtoms::scrollbar
|
fixed bugs #6303, #6753, #6756, #6759
Re-wrote nsComboboxFrame.
removed the obsolete nsHTMLAtoms: comboText,comoTextSelected,comTextSelectedFocus,dropDownVisible,
dropdownHidden, dropDownBtnOut, dropDownBtnPressed,
Added nsHTMLAtoms::combobox, nsLayoutAtoms::popupList
Renamed dropDownList to dropDownListPseudo
Added "arrow.gif" as to be used the background-image for the combobox button
ua.css - added rules for select to differentiate between comboboxes and listboxes.
Added style rules to more closely match the XPTOOLKIT XPWidgets look.
removed the following :-moz-combobox-text, -moz-combobox-textselected
nsIFormControlFrame.h - Added SetSuggestedSize method.
nsButtonControlFrame - Implemented SetSuggestedSize.
nsCSSFrameConstructor.cpp - Rewrote ConstructSelectFrame.
nsIWidget.h -Added GetAbsoluteBounds method.
nsWindow.cpp - Implemented GetAbsoluteBounds.
1999-07-14 22:00:24 +00:00
|
|
|
) {
|
1999-06-30 22:17:43 +00:00
|
|
|
return NS_OK;
|
|
|
|
|
|
|
|
}
|
1999-08-27 06:06:39 +00:00
|
|
|
|
fixed bugs #6303, #6753, #6756, #6759
Re-wrote nsComboboxFrame.
removed the obsolete nsHTMLAtoms: comboText,comoTextSelected,comTextSelectedFocus,dropDownVisible,
dropdownHidden, dropDownBtnOut, dropDownBtnPressed,
Added nsHTMLAtoms::combobox, nsLayoutAtoms::popupList
Renamed dropDownList to dropDownListPseudo
Added "arrow.gif" as to be used the background-image for the combobox button
ua.css - added rules for select to differentiate between comboboxes and listboxes.
Added style rules to more closely match the XPTOOLKIT XPWidgets look.
removed the following :-moz-combobox-text, -moz-combobox-textselected
nsIFormControlFrame.h - Added SetSuggestedSize method.
nsButtonControlFrame - Implemented SetSuggestedSize.
nsCSSFrameConstructor.cpp - Rewrote ConstructSelectFrame.
nsIWidget.h -Added GetAbsoluteBounds method.
nsWindow.cpp - Implemented GetAbsoluteBounds.
1999-07-14 22:00:24 +00:00
|
|
|
// get the document
|
1999-09-20 00:02:59 +00:00
|
|
|
nsCOMPtr<nsIDocument> doc;
|
|
|
|
nsresult rv = aParent->GetDocument(*getter_AddRefs(doc));
|
fixed bugs #6303, #6753, #6756, #6759
Re-wrote nsComboboxFrame.
removed the obsolete nsHTMLAtoms: comboText,comoTextSelected,comTextSelectedFocus,dropDownVisible,
dropdownHidden, dropDownBtnOut, dropDownBtnPressed,
Added nsHTMLAtoms::combobox, nsLayoutAtoms::popupList
Renamed dropDownList to dropDownListPseudo
Added "arrow.gif" as to be used the background-image for the combobox button
ua.css - added rules for select to differentiate between comboboxes and listboxes.
Added style rules to more closely match the XPTOOLKIT XPWidgets look.
removed the following :-moz-combobox-text, -moz-combobox-textselected
nsIFormControlFrame.h - Added SetSuggestedSize method.
nsButtonControlFrame - Implemented SetSuggestedSize.
nsCSSFrameConstructor.cpp - Rewrote ConstructSelectFrame.
nsIWidget.h -Added GetAbsoluteBounds method.
nsWindow.cpp - Implemented GetAbsoluteBounds.
1999-07-14 22:00:24 +00:00
|
|
|
if (NS_FAILED(rv) || !doc)
|
|
|
|
return rv;
|
1999-06-30 22:17:43 +00:00
|
|
|
|
1999-12-04 23:49:50 +00:00
|
|
|
return CreateAnonymousFrames(aPresShell, aPresContext, aState, aParent, doc, aNewFrame, aChildItems);
|
1999-08-27 06:06:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// after the node has been constructed and initialized create any
|
|
|
|
// anonymous content a node needs.
|
|
|
|
nsresult
|
1999-12-04 23:49:50 +00:00
|
|
|
nsCSSFrameConstructor::CreateAnonymousFrames(nsIPresShell* aPresShell,
|
|
|
|
nsIPresContext* aPresContext,
|
1999-08-27 06:06:39 +00:00
|
|
|
nsFrameConstructorState& aState,
|
|
|
|
nsIContent* aParent,
|
|
|
|
nsIDocument* aDocument,
|
2000-05-02 14:34:24 +00:00
|
|
|
nsIFrame* aParentFrame,
|
1999-08-27 06:06:39 +00:00
|
|
|
nsFrameItems& aChildItems)
|
|
|
|
{
|
|
|
|
|
2000-05-02 14:34:24 +00:00
|
|
|
nsCOMPtr<nsIAnonymousContentCreator> creator(do_QueryInterface(aParentFrame));
|
1999-08-27 06:06:39 +00:00
|
|
|
|
|
|
|
if (!creator)
|
1999-06-30 22:17:43 +00:00
|
|
|
return NS_OK;
|
|
|
|
|
1999-08-27 06:06:39 +00:00
|
|
|
nsCOMPtr<nsISupportsArray> anonymousItems;
|
|
|
|
NS_NewISupportsArray(getter_AddRefs(anonymousItems));
|
|
|
|
|
|
|
|
|
2000-01-22 01:16:50 +00:00
|
|
|
creator->CreateAnonymousContent(aPresContext, *anonymousItems);
|
1999-08-27 06:06:39 +00:00
|
|
|
|
|
|
|
PRUint32 count = 0;
|
|
|
|
anonymousItems->Count(&count);
|
|
|
|
|
|
|
|
for (PRUint32 i=0; i < count; i++)
|
|
|
|
{
|
|
|
|
// get our child's content and set its parent to our content
|
|
|
|
nsCOMPtr<nsISupports> node;
|
|
|
|
anonymousItems->GetElementAt(i,getter_AddRefs(node));
|
|
|
|
|
|
|
|
nsCOMPtr<nsIContent> content(do_QueryInterface(node));
|
|
|
|
content->SetParent(aParent);
|
2000-05-19 04:48:43 +00:00
|
|
|
content->SetDocument(aDocument, PR_TRUE, PR_TRUE);
|
1999-08-27 06:06:39 +00:00
|
|
|
|
2000-05-02 14:34:24 +00:00
|
|
|
nsIFrame * newFrame = nsnull;
|
|
|
|
nsresult rv = creator->CreateFrameFor(aPresContext, content, &newFrame);
|
|
|
|
if (NS_SUCCEEDED(rv) && newFrame != nsnull) {
|
|
|
|
aChildItems.AddChild(newFrame);
|
|
|
|
} else {
|
|
|
|
// create the frame and attach it to our frame
|
|
|
|
ConstructFrame(aPresShell, aPresContext, aState, content, aParentFrame, aChildItems);
|
|
|
|
}
|
1999-08-27 06:06:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
// after the node has been constructed and initialized create any
|
|
|
|
// anonymous content a node needs.
|
|
|
|
nsresult
|
2000-08-03 00:22:36 +00:00
|
|
|
nsCSSFrameConstructor::CreateAnonymousTableCellFrames(nsIPresShell* aPresShell,
|
1999-12-04 23:49:50 +00:00
|
|
|
nsIPresContext* aPresContext,
|
1999-08-27 06:06:39 +00:00
|
|
|
nsIAtom* aTag,
|
|
|
|
nsFrameConstructorState& aState,
|
|
|
|
nsIContent* aParent,
|
|
|
|
nsIFrame* aNewFrame,
|
1999-09-28 00:57:31 +00:00
|
|
|
nsIFrame* aNewCellFrame,
|
1999-08-27 06:06:39 +00:00
|
|
|
nsFrameItems& aChildItems)
|
|
|
|
{
|
2000-02-15 09:28:28 +00:00
|
|
|
nsCOMPtr<nsIStyleContext> styleContext;
|
|
|
|
aNewCellFrame->GetStyleContext(getter_AddRefs(styleContext));
|
1999-09-28 00:57:31 +00:00
|
|
|
|
2000-02-15 09:28:28 +00:00
|
|
|
const nsStyleUserInterface* ui= (const nsStyleUserInterface*)
|
|
|
|
styleContext->GetStyleData(eStyleStruct_UserInterface);
|
1999-08-27 06:06:39 +00:00
|
|
|
|
2000-03-26 10:06:21 +00:00
|
|
|
if (!ui->mBehavior.IsEmpty()) {
|
2000-02-15 09:28:28 +00:00
|
|
|
// Get the XBL loader.
|
|
|
|
nsresult rv;
|
|
|
|
NS_WITH_SERVICE(nsIXBLService, xblService, "component://netscape/xbl", &rv);
|
|
|
|
if (!xblService)
|
|
|
|
return rv;
|
1999-08-25 05:52:10 +00:00
|
|
|
|
2000-02-15 09:28:28 +00:00
|
|
|
// Load the bindings.
|
2000-07-28 00:35:30 +00:00
|
|
|
nsCOMPtr<nsIXBLBinding> binding;
|
|
|
|
xblService->LoadBindings(aParent, ui->mBehavior, PR_FALSE, getter_AddRefs(binding));
|
|
|
|
|
2000-02-15 09:28:28 +00:00
|
|
|
// Retrieve the anonymous content that we should build.
|
2000-03-14 11:09:46 +00:00
|
|
|
nsCOMPtr<nsIContent> childElement;
|
2000-02-15 09:28:28 +00:00
|
|
|
nsCOMPtr<nsISupportsArray> anonymousItems;
|
2000-05-22 08:23:46 +00:00
|
|
|
PRBool multiple;
|
|
|
|
xblService->GetContentList(aParent, getter_AddRefs(anonymousItems), getter_AddRefs(childElement), &multiple);
|
1999-08-25 05:52:10 +00:00
|
|
|
|
2000-02-15 09:28:28 +00:00
|
|
|
if (!anonymousItems)
|
|
|
|
return NS_OK;
|
1999-08-25 05:52:10 +00:00
|
|
|
|
2000-02-15 09:28:28 +00:00
|
|
|
// Build the frames for the anonymous content.
|
|
|
|
PRUint32 count = 0;
|
|
|
|
anonymousItems->Count(&count);
|
1999-11-30 00:53:41 +00:00
|
|
|
|
2000-02-15 09:28:28 +00:00
|
|
|
for (PRUint32 i=0; i < count; i++)
|
|
|
|
{
|
|
|
|
// get our child's content and set its parent to our content
|
|
|
|
nsCOMPtr<nsISupports> node;
|
|
|
|
anonymousItems->GetElementAt(i,getter_AddRefs(node));
|
1999-08-25 05:52:10 +00:00
|
|
|
|
2000-02-15 09:28:28 +00:00
|
|
|
nsCOMPtr<nsIContent> content(do_QueryInterface(node));
|
|
|
|
|
|
|
|
// create the frame and attach it to our frame
|
|
|
|
ConstructFrame(aPresShell, aPresContext, aState, content, aNewFrame, aChildItems);
|
1999-08-25 05:52:10 +00:00
|
|
|
}
|
1999-06-30 22:17:43 +00:00
|
|
|
|
2000-02-15 09:28:28 +00:00
|
|
|
return NS_OK;
|
1999-09-28 00:57:31 +00:00
|
|
|
}
|
1999-06-30 22:17:43 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
1999-02-05 03:55:18 +00:00
|
|
|
#ifdef INCLUDE_XUL
|
|
|
|
nsresult
|
2000-03-11 10:38:36 +00:00
|
|
|
nsCSSFrameConstructor::ConstructXULFrame(nsIPresShell* aPresShell,
|
1999-12-04 23:49:50 +00:00
|
|
|
nsIPresContext* aPresContext,
|
1999-04-28 19:08:14 +00:00
|
|
|
nsFrameConstructorState& aState,
|
|
|
|
nsIContent* aContent,
|
|
|
|
nsIFrame* aParentFrame,
|
|
|
|
nsIAtom* aTag,
|
2000-05-24 08:19:10 +00:00
|
|
|
PRInt32 aNameSpaceID,
|
1999-04-28 19:08:14 +00:00
|
|
|
nsIStyleContext* aStyleContext,
|
|
|
|
nsFrameItems& aFrameItems,
|
2000-01-10 11:18:12 +00:00
|
|
|
PRBool& aHaltProcessing)
|
2000-03-30 03:21:26 +00:00
|
|
|
{
|
1999-10-12 00:16:06 +00:00
|
|
|
PRBool primaryFrameSet = PR_FALSE;
|
1999-02-05 03:55:18 +00:00
|
|
|
PRBool processChildren = PR_FALSE; // whether we should process child content
|
|
|
|
nsresult rv = NS_OK;
|
|
|
|
PRBool isAbsolutelyPositioned = PR_FALSE;
|
1999-02-10 19:50:50 +00:00
|
|
|
PRBool isFixedPositioned = PR_FALSE;
|
1999-03-04 23:39:06 +00:00
|
|
|
PRBool isReplaced = PR_FALSE;
|
1999-07-20 07:03:16 +00:00
|
|
|
PRBool frameHasBeenInitialized = PR_FALSE;
|
1999-02-05 03:55:18 +00:00
|
|
|
|
1999-10-12 00:16:06 +00:00
|
|
|
// this is the new frame that will be created
|
1999-02-10 19:50:50 +00:00
|
|
|
nsIFrame* newFrame = nsnull;
|
1999-10-12 00:16:06 +00:00
|
|
|
|
|
|
|
// this is the also the new frame that is created. But if a scroll frame is needed
|
|
|
|
// the content will be mapped to the scrollframe and topFrame will point to it.
|
|
|
|
// newFrame will still point to the child that we created like a "div" for example.
|
|
|
|
nsIFrame* topFrame = nsnull;
|
|
|
|
|
1999-02-05 03:55:18 +00:00
|
|
|
NS_ASSERTION(aTag != nsnull, "null XUL tag");
|
|
|
|
if (aTag == nsnull)
|
|
|
|
return NS_OK;
|
|
|
|
|
2000-03-11 10:38:36 +00:00
|
|
|
|
2000-05-24 08:19:10 +00:00
|
|
|
if (aNameSpaceID == nsXULAtoms::nameSpaceID) {
|
2000-03-11 10:38:36 +00:00
|
|
|
|
2000-05-15 20:25:02 +00:00
|
|
|
// was here
|
2000-03-11 10:38:36 +00:00
|
|
|
|
1999-02-05 03:55:18 +00:00
|
|
|
// See if the element is absolutely positioned
|
|
|
|
const nsStylePosition* position = (const nsStylePosition*)
|
|
|
|
aStyleContext->GetStyleData(eStyleStruct_Position);
|
|
|
|
if (NS_STYLE_POSITION_ABSOLUTE == position->mPosition)
|
|
|
|
isAbsolutelyPositioned = PR_TRUE;
|
|
|
|
|
|
|
|
// Create a frame based on the tag
|
2000-03-02 03:01:30 +00:00
|
|
|
// box is first because it is created the most.
|
|
|
|
// BOX CONSTRUCTION
|
2000-06-23 05:15:04 +00:00
|
|
|
if (aTag == nsXULAtoms::box || aTag == nsXULAtoms::vbox || aTag == nsXULAtoms::hbox || aTag == nsXULAtoms::tabbox ||
|
2000-05-30 08:41:39 +00:00
|
|
|
aTag == nsXULAtoms::tabpage || aTag == nsXULAtoms::tabcontrol
|
2000-05-21 07:00:35 +00:00
|
|
|
|| aTag == nsXULAtoms::treecell
|
|
|
|
) {
|
2000-03-02 03:01:30 +00:00
|
|
|
processChildren = PR_TRUE;
|
|
|
|
isReplaced = PR_TRUE;
|
2000-05-21 07:00:35 +00:00
|
|
|
|
|
|
|
if (aTag == nsXULAtoms::treecell)
|
|
|
|
rv = NS_NewXULTreeCellFrame(aPresShell, &newFrame);
|
|
|
|
else
|
2000-06-23 05:15:04 +00:00
|
|
|
|
|
|
|
// create a box. Its not root, its layout manager is default (nsnull) which is "sprocket" and
|
|
|
|
// its default orientation is horizontal for hbox and vertical for vbox
|
|
|
|
rv = NS_NewBoxFrame(aPresShell, &newFrame, PR_FALSE, nsnull, aTag != nsXULAtoms::vbox);
|
2000-03-02 03:01:30 +00:00
|
|
|
|
|
|
|
const nsStyleDisplay* display = (const nsStyleDisplay*)
|
|
|
|
aStyleContext->GetStyleData(eStyleStruct_Display);
|
|
|
|
|
|
|
|
// Boxes can scroll.
|
|
|
|
if (IsScrollable(aPresContext, display)) {
|
|
|
|
|
|
|
|
// set the top to be the newly created scrollframe
|
|
|
|
BuildScrollFrame(aPresShell, aPresContext, aState, aContent, aStyleContext, newFrame, aParentFrame,
|
|
|
|
topFrame, aStyleContext);
|
|
|
|
|
|
|
|
// we have a scrollframe so the parent becomes the scroll frame.
|
|
|
|
newFrame->GetParent(&aParentFrame);
|
|
|
|
|
|
|
|
primaryFrameSet = PR_TRUE;
|
|
|
|
|
|
|
|
frameHasBeenInitialized = PR_TRUE;
|
|
|
|
|
|
|
|
}
|
|
|
|
} // End of BOX CONSTRUCTION logic
|
2000-03-11 10:38:36 +00:00
|
|
|
|
|
|
|
// BUTTON CONSTRUCTION
|
2000-05-30 08:44:40 +00:00
|
|
|
else if (aTag == nsXULAtoms::button || aTag == nsXULAtoms::checkbox || aTag == nsXULAtoms::radio) {
|
2000-03-11 10:38:36 +00:00
|
|
|
processChildren = PR_TRUE;
|
|
|
|
isReplaced = PR_TRUE;
|
2000-03-31 07:02:06 +00:00
|
|
|
rv = NS_NewButtonBoxFrame(aPresShell, &newFrame);
|
2000-03-11 10:38:36 +00:00
|
|
|
|
|
|
|
const nsStyleDisplay* display = (const nsStyleDisplay*)
|
|
|
|
aStyleContext->GetStyleData(eStyleStruct_Display);
|
|
|
|
|
|
|
|
// Boxes can scroll.
|
|
|
|
if (IsScrollable(aPresContext, display)) {
|
|
|
|
|
|
|
|
// set the top to be the newly created scrollframe
|
|
|
|
BuildScrollFrame(aPresShell, aPresContext, aState, aContent, aStyleContext, newFrame, aParentFrame,
|
|
|
|
topFrame, aStyleContext);
|
|
|
|
|
|
|
|
// we have a scrollframe so the parent becomes the scroll frame.
|
|
|
|
newFrame->GetParent(&aParentFrame);
|
|
|
|
|
|
|
|
primaryFrameSet = PR_TRUE;
|
|
|
|
|
|
|
|
frameHasBeenInitialized = PR_TRUE;
|
|
|
|
|
|
|
|
}
|
|
|
|
} // End of BUTTON CONSTRUCTION logic
|
2000-06-23 05:15:04 +00:00
|
|
|
// BUTTON CONSTRUCTION
|
|
|
|
else if (aTag == nsXULAtoms::autorepeatbutton) {
|
|
|
|
processChildren = PR_TRUE;
|
|
|
|
isReplaced = PR_TRUE;
|
|
|
|
rv = NS_NewAutoRepeatBoxFrame(aPresShell, &newFrame);
|
|
|
|
|
|
|
|
const nsStyleDisplay* display = (const nsStyleDisplay*)
|
|
|
|
aStyleContext->GetStyleData(eStyleStruct_Display);
|
|
|
|
|
|
|
|
// Boxes can scroll.
|
|
|
|
if (IsScrollable(aPresContext, display)) {
|
|
|
|
|
|
|
|
// set the top to be the newly created scrollframe
|
|
|
|
BuildScrollFrame(aPresShell, aPresContext, aState, aContent, aStyleContext, newFrame, aParentFrame,
|
|
|
|
topFrame, aStyleContext);
|
|
|
|
|
|
|
|
// we have a scrollframe so the parent becomes the scroll frame.
|
|
|
|
newFrame->GetParent(&aParentFrame);
|
|
|
|
|
|
|
|
primaryFrameSet = PR_TRUE;
|
|
|
|
|
|
|
|
frameHasBeenInitialized = PR_TRUE;
|
|
|
|
|
|
|
|
}
|
|
|
|
} // End of BUTTON CONSTRUCTION logic
|
2000-03-02 03:01:30 +00:00
|
|
|
|
2000-07-11 23:34:44 +00:00
|
|
|
|
|
|
|
// TITLEBAR CONSTRUCTION
|
|
|
|
else if (aTag == nsXULAtoms::titlebar) {
|
|
|
|
processChildren = PR_TRUE;
|
|
|
|
isReplaced = PR_TRUE;
|
|
|
|
rv = NS_NewTitleBarFrame(aPresShell, &newFrame);
|
|
|
|
|
|
|
|
const nsStyleDisplay* display = (const nsStyleDisplay*)
|
|
|
|
aStyleContext->GetStyleData(eStyleStruct_Display);
|
|
|
|
// Boxes can scroll.
|
|
|
|
if (IsScrollable(aPresContext, display)) {
|
|
|
|
|
|
|
|
// set the top to be the newly created scrollframe
|
|
|
|
BuildScrollFrame(aPresShell, aPresContext, aState, aContent, aStyleContext, newFrame, aParentFrame,
|
|
|
|
topFrame, aStyleContext);
|
|
|
|
|
|
|
|
// we have a scrollframe so the parent becomes the scroll frame.
|
|
|
|
newFrame->GetParent(&aParentFrame);
|
|
|
|
|
|
|
|
primaryFrameSet = PR_TRUE;
|
|
|
|
|
|
|
|
frameHasBeenInitialized = PR_TRUE;
|
|
|
|
|
|
|
|
}
|
|
|
|
} // End of TITLEBAR CONSTRUCTION logic
|
|
|
|
|
|
|
|
// RESIZER CONSTRUCTION
|
|
|
|
else if (aTag == nsXULAtoms::resizer) {
|
|
|
|
processChildren = PR_TRUE;
|
|
|
|
isReplaced = PR_TRUE;
|
|
|
|
rv = NS_NewResizerFrame(aPresShell, &newFrame);
|
|
|
|
|
|
|
|
const nsStyleDisplay* display = (const nsStyleDisplay*)
|
|
|
|
aStyleContext->GetStyleData(eStyleStruct_Display);
|
|
|
|
|
|
|
|
// Boxes can scroll.
|
|
|
|
if (IsScrollable(aPresContext, display)) {
|
|
|
|
|
|
|
|
// set the top to be the newly created scrollframe
|
|
|
|
BuildScrollFrame(aPresShell, aPresContext, aState, aContent, aStyleContext, newFrame, aParentFrame,
|
|
|
|
topFrame, aStyleContext);
|
|
|
|
|
|
|
|
// we have a scrollframe so the parent becomes the scroll frame.
|
|
|
|
newFrame->GetParent(&aParentFrame);
|
|
|
|
|
|
|
|
primaryFrameSet = PR_TRUE;
|
|
|
|
|
|
|
|
frameHasBeenInitialized = PR_TRUE;
|
|
|
|
|
|
|
|
}
|
|
|
|
} // End of RESIZER CONSTRUCTION logic
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2000-06-23 05:15:04 +00:00
|
|
|
// TITLED BUTTON CONSTRUCTION
|
2000-03-31 07:02:06 +00:00
|
|
|
else if (aTag == nsXULAtoms::titledbutton) {
|
2000-03-02 03:01:30 +00:00
|
|
|
|
|
|
|
processChildren = PR_TRUE;
|
|
|
|
isReplaced = PR_TRUE;
|
|
|
|
rv = NS_NewTitledButtonFrame(aPresShell, &newFrame);
|
|
|
|
}
|
|
|
|
// End of TITLED BUTTON CONSTRUCTION logic
|
2000-03-31 07:02:06 +00:00
|
|
|
else if (aTag == nsXULAtoms::image) {
|
|
|
|
processChildren = PR_TRUE;
|
|
|
|
isReplaced = PR_TRUE;
|
|
|
|
rv = NS_NewImageBoxFrame(aPresShell, &newFrame);
|
|
|
|
}
|
2000-03-02 03:01:30 +00:00
|
|
|
else if (aTag == nsXULAtoms::spring) {
|
|
|
|
processChildren = PR_TRUE;
|
|
|
|
isReplaced = PR_TRUE;
|
|
|
|
rv = NS_NewSpringFrame(aPresShell, &newFrame);
|
|
|
|
}
|
|
|
|
// End of TITLED BUTTON CONSTRUCTION logic
|
|
|
|
|
|
|
|
// TEXT CONSTRUCTION
|
|
|
|
else if (aTag == nsXULAtoms::text) {
|
|
|
|
processChildren = PR_TRUE;
|
|
|
|
isReplaced = PR_TRUE;
|
2000-03-31 07:02:06 +00:00
|
|
|
rv = NS_NewTextBoxFrame(aPresShell, &newFrame);
|
2000-03-02 03:01:30 +00:00
|
|
|
}
|
|
|
|
// End of TEXT CONSTRUCTION logic
|
|
|
|
|
|
|
|
// Menu Construction
|
|
|
|
else if (aTag == nsXULAtoms::menu ||
|
|
|
|
aTag == nsXULAtoms::menuitem ||
|
|
|
|
aTag == nsXULAtoms::menulist ||
|
|
|
|
aTag == nsXULAtoms::menubutton) {
|
|
|
|
// A derived class box frame
|
|
|
|
// that has custom reflow to prevent menu children
|
|
|
|
// from becoming part of the flow.
|
|
|
|
processChildren = PR_TRUE; // Will need this to be custom.
|
|
|
|
isReplaced = PR_TRUE;
|
|
|
|
rv = NS_NewMenuFrame(aPresShell, &newFrame, (aTag != nsXULAtoms::menuitem));
|
2000-08-03 00:22:36 +00:00
|
|
|
((nsMenuFrame*) newFrame)->SetFrameConstructor(this);
|
2000-03-02 03:01:30 +00:00
|
|
|
}
|
|
|
|
else if (aTag == nsXULAtoms::menubar) {
|
2000-06-20 23:10:06 +00:00
|
|
|
#if (defined(XP_MAC) && !TARGET_CARBON) || defined(RHAPSODY) // The Mac uses its native menu bar.
|
2000-03-02 03:01:30 +00:00
|
|
|
aHaltProcessing = PR_TRUE;
|
|
|
|
return NS_OK;
|
|
|
|
#else
|
|
|
|
processChildren = PR_TRUE;
|
|
|
|
rv = NS_NewMenuBarFrame(aPresShell, &newFrame);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
else if (aTag == nsXULAtoms::popupset) {
|
|
|
|
// This frame contains child popups
|
|
|
|
processChildren = PR_TRUE;
|
|
|
|
isReplaced = PR_TRUE;
|
|
|
|
rv = NS_NewPopupSetFrame(aPresShell, &newFrame);
|
2000-08-03 00:22:36 +00:00
|
|
|
((nsPopupSetFrame*) newFrame)->SetFrameConstructor(this);
|
2000-03-02 03:01:30 +00:00
|
|
|
}
|
|
|
|
else if (aTag == nsXULAtoms::menupopup || aTag == nsXULAtoms::popup) {
|
|
|
|
// This is its own frame that derives from
|
|
|
|
// box.
|
|
|
|
processChildren = PR_TRUE;
|
|
|
|
isReplaced = PR_TRUE;
|
|
|
|
rv = NS_NewMenuPopupFrame(aPresShell, &newFrame);
|
2000-03-31 07:02:06 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// ------- Begin Grid ---------
|
2000-05-21 07:00:35 +00:00
|
|
|
else if (aTag == nsXULAtoms::grid || aTag == nsXULAtoms::tree) {
|
2000-03-31 07:02:06 +00:00
|
|
|
processChildren = PR_TRUE;
|
|
|
|
isReplaced = PR_TRUE;
|
2000-04-05 00:19:00 +00:00
|
|
|
nsCOMPtr<nsIBoxLayout> layout;
|
|
|
|
NS_NewGridLayout(aPresShell, layout);
|
2000-05-21 07:00:35 +00:00
|
|
|
|
|
|
|
if (aTag == nsXULAtoms::tree)
|
|
|
|
rv = NS_NewXULTreeFrame(aPresShell, &newFrame, PR_FALSE, layout);
|
|
|
|
else
|
|
|
|
rv = NS_NewBoxFrame(aPresShell, &newFrame, PR_FALSE, layout);
|
2000-03-31 07:02:06 +00:00
|
|
|
|
|
|
|
const nsStyleDisplay* display = (const nsStyleDisplay*)
|
|
|
|
aStyleContext->GetStyleData(eStyleStruct_Display);
|
|
|
|
|
|
|
|
// Boxes can scroll.
|
|
|
|
if (IsScrollable(aPresContext, display)) {
|
|
|
|
|
|
|
|
// set the top to be the newly created scrollframe
|
|
|
|
BuildScrollFrame(aPresShell, aPresContext, aState, aContent, aStyleContext, newFrame, aParentFrame,
|
|
|
|
topFrame, aStyleContext);
|
|
|
|
|
|
|
|
// we have a scrollframe so the parent becomes the scroll frame.
|
|
|
|
newFrame->GetParent(&aParentFrame);
|
|
|
|
|
|
|
|
primaryFrameSet = PR_TRUE;
|
|
|
|
|
|
|
|
frameHasBeenInitialized = PR_TRUE;
|
|
|
|
|
|
|
|
}
|
|
|
|
} //------- End Grid ------
|
|
|
|
|
|
|
|
// ------- Begin Rows/Columns ---------
|
2000-05-21 07:00:35 +00:00
|
|
|
else if (aTag == nsXULAtoms::rows || aTag == nsXULAtoms::columns
|
|
|
|
|| aTag == nsXULAtoms::treechildren || aTag == nsXULAtoms::treecolgroup ||
|
|
|
|
aTag == nsXULAtoms::treehead || aTag == nsXULAtoms::treerows ||
|
|
|
|
aTag == nsXULAtoms::treecols || aTag == nsXULAtoms::treeitem
|
|
|
|
) {
|
2000-03-31 07:02:06 +00:00
|
|
|
processChildren = PR_TRUE;
|
|
|
|
isReplaced = PR_TRUE;
|
2000-05-21 07:00:35 +00:00
|
|
|
PRBool isHorizontal = (aTag == nsXULAtoms::columns)
|
|
|
|
|| (aTag == nsXULAtoms::treecolgroup) || (aTag == nsXULAtoms::treecols)
|
|
|
|
;
|
2000-04-05 00:19:00 +00:00
|
|
|
nsCOMPtr<nsIBoxLayout> layout;
|
2000-06-06 23:13:49 +00:00
|
|
|
|
|
|
|
if (aTag == nsXULAtoms::treechildren || aTag == nsXULAtoms::treeitem) {
|
|
|
|
NS_NewTreeLayout(aPresShell, layout);
|
|
|
|
nsCOMPtr<nsIContent> parentContent;
|
|
|
|
aParentFrame->GetContent(getter_AddRefs(parentContent));
|
|
|
|
nsCOMPtr<nsIAtom> parentTag;
|
|
|
|
parentContent->GetTag(*getter_AddRefs(parentTag));
|
|
|
|
if (parentTag.get() == nsXULAtoms::tree) {
|
|
|
|
rv = NS_NewXULTreeOuterGroupFrame(aPresShell, &newFrame, PR_FALSE, layout, PR_FALSE);
|
|
|
|
((nsXULTreeGroupFrame*)newFrame)->InitGroup(this, aPresContext, (nsXULTreeOuterGroupFrame*) newFrame);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
rv = NS_NewXULTreeGroupFrame(aPresShell, &newFrame, PR_FALSE, layout, PR_FALSE);
|
|
|
|
((nsXULTreeGroupFrame*)newFrame)->InitGroup(this, aPresContext, ((nsXULTreeGroupFrame*)aParentFrame)->GetOuterFrame());
|
|
|
|
}
|
|
|
|
|
|
|
|
processChildren = PR_FALSE;
|
|
|
|
}
|
2000-05-21 07:00:35 +00:00
|
|
|
else
|
2000-06-06 23:13:49 +00:00
|
|
|
{
|
|
|
|
NS_NewTempleLayout(aPresShell, layout);
|
2000-05-21 07:00:35 +00:00
|
|
|
rv = NS_NewBoxFrame(aPresShell, &newFrame, PR_FALSE, layout, isHorizontal);
|
2000-06-06 23:13:49 +00:00
|
|
|
}
|
2000-03-31 07:02:06 +00:00
|
|
|
|
|
|
|
const nsStyleDisplay* display = (const nsStyleDisplay*)
|
|
|
|
aStyleContext->GetStyleData(eStyleStruct_Display);
|
|
|
|
|
|
|
|
// Boxes can scroll.
|
|
|
|
if (IsScrollable(aPresContext, display)) {
|
|
|
|
|
|
|
|
// set the top to be the newly created scrollframe
|
|
|
|
BuildScrollFrame(aPresShell, aPresContext, aState, aContent, aStyleContext, newFrame, aParentFrame,
|
|
|
|
topFrame, aStyleContext);
|
|
|
|
|
|
|
|
// we have a scrollframe so the parent becomes the scroll frame.
|
|
|
|
newFrame->GetParent(&aParentFrame);
|
|
|
|
|
|
|
|
primaryFrameSet = PR_TRUE;
|
|
|
|
|
|
|
|
frameHasBeenInitialized = PR_TRUE;
|
|
|
|
|
|
|
|
}
|
|
|
|
} //------- End Grid ------
|
|
|
|
|
|
|
|
// ------- Begin Row/Column ---------
|
2000-05-21 07:00:35 +00:00
|
|
|
else if (aTag == nsXULAtoms::row || aTag == nsXULAtoms::column
|
|
|
|
|| aTag == nsXULAtoms::treerow || aTag == nsXULAtoms::treecol
|
|
|
|
) {
|
2000-03-31 07:02:06 +00:00
|
|
|
processChildren = PR_TRUE;
|
|
|
|
isReplaced = PR_TRUE;
|
2000-05-22 08:23:46 +00:00
|
|
|
PRBool isHorizontal = (aTag == nsXULAtoms::row) || (aTag == nsXULAtoms::treerow);
|
2000-04-05 00:19:00 +00:00
|
|
|
nsCOMPtr<nsIBoxLayout> layout;
|
|
|
|
NS_NewObeliskLayout(aPresShell, layout);
|
2000-05-21 07:00:35 +00:00
|
|
|
|
|
|
|
if (aTag == nsXULAtoms::treerow)
|
|
|
|
rv = NS_NewXULTreeSliceFrame(aPresShell, &newFrame, PR_FALSE, layout, isHorizontal);
|
|
|
|
else
|
|
|
|
rv = NS_NewBoxFrame(aPresShell, &newFrame, PR_FALSE, layout, isHorizontal);
|
2000-03-31 07:02:06 +00:00
|
|
|
|
|
|
|
const nsStyleDisplay* display = (const nsStyleDisplay*)
|
|
|
|
aStyleContext->GetStyleData(eStyleStruct_Display);
|
|
|
|
|
|
|
|
// Boxes can scroll.
|
|
|
|
if (IsScrollable(aPresContext, display)) {
|
|
|
|
|
|
|
|
// set the top to be the newly created scrollframe
|
|
|
|
BuildScrollFrame(aPresShell, aPresContext, aState, aContent, aStyleContext, newFrame, aParentFrame,
|
|
|
|
topFrame, aStyleContext);
|
|
|
|
|
|
|
|
// we have a scrollframe so the parent becomes the scroll frame.
|
|
|
|
newFrame->GetParent(&aParentFrame);
|
|
|
|
|
|
|
|
primaryFrameSet = PR_TRUE;
|
|
|
|
|
|
|
|
frameHasBeenInitialized = PR_TRUE;
|
|
|
|
|
|
|
|
}
|
|
|
|
} //------- End Grid ------
|
2000-04-05 00:19:00 +00:00
|
|
|
|
2000-03-02 03:01:30 +00:00
|
|
|
else if (aTag == nsXULAtoms::title) {
|
|
|
|
processChildren = PR_TRUE;
|
|
|
|
isReplaced = PR_TRUE;
|
|
|
|
rv = NS_NewTitleFrame(aPresShell, &newFrame);
|
|
|
|
|
|
|
|
const nsStyleDisplay* display = (const nsStyleDisplay*)
|
|
|
|
aStyleContext->GetStyleData(eStyleStruct_Display);
|
|
|
|
|
|
|
|
// Boxes can scroll.
|
|
|
|
if (IsScrollable(aPresContext, display)) {
|
|
|
|
|
|
|
|
// set the top to be the newly created scrollframe
|
|
|
|
BuildScrollFrame(aPresShell, aPresContext, aState, aContent, aStyleContext, newFrame, aParentFrame,
|
|
|
|
topFrame, aStyleContext);
|
|
|
|
|
|
|
|
// we have a scrollframe so the parent becomes the scroll frame.
|
|
|
|
newFrame->GetParent(&aParentFrame);
|
|
|
|
|
|
|
|
primaryFrameSet = PR_TRUE;
|
|
|
|
|
|
|
|
frameHasBeenInitialized = PR_TRUE;
|
|
|
|
|
|
|
|
}
|
|
|
|
} // End of BOX CONSTRUCTION logic
|
|
|
|
|
|
|
|
else if (aTag == nsXULAtoms::titledbox) {
|
|
|
|
|
2000-06-12 23:23:00 +00:00
|
|
|
rv = NS_NewTitledBoxFrame(aPresShell, &newFrame);
|
|
|
|
|
|
|
|
//ConstructTitledBoxFrame(aPresShell, aPresContext, aState, aContent, aParentFrame, aTag, aStyleContext, newFrame);
|
|
|
|
processChildren = PR_TRUE;
|
2000-03-02 03:01:30 +00:00
|
|
|
isReplaced = PR_TRUE;
|
|
|
|
|
|
|
|
const nsStyleDisplay* display = (const nsStyleDisplay*)
|
|
|
|
aStyleContext->GetStyleData(eStyleStruct_Display);
|
|
|
|
|
|
|
|
// Boxes can scroll.
|
|
|
|
if (IsScrollable(aPresContext, display)) {
|
|
|
|
|
|
|
|
// set the top to be the newly created scrollframe
|
|
|
|
BuildScrollFrame(aPresShell, aPresContext, aState, aContent, aStyleContext, newFrame, aParentFrame,
|
|
|
|
topFrame, aStyleContext);
|
|
|
|
|
|
|
|
// we have a scrollframe so the parent becomes the scroll frame.
|
|
|
|
newFrame->GetParent(&aParentFrame);
|
|
|
|
|
|
|
|
primaryFrameSet = PR_TRUE;
|
|
|
|
|
|
|
|
frameHasBeenInitialized = PR_TRUE;
|
|
|
|
}
|
|
|
|
}
|
2000-06-23 05:15:04 +00:00
|
|
|
else if (aTag == nsXULAtoms::scrollbox) {
|
|
|
|
rv = NS_NewScrollBoxFrame(aPresShell, &newFrame);
|
|
|
|
|
|
|
|
//ConstructTitledBoxFrame(aPresShell, aPresContext, aState, aContent, aParentFrame, aTag, aStyleContext, newFrame);
|
|
|
|
processChildren = PR_TRUE;
|
|
|
|
isReplaced = PR_TRUE;
|
|
|
|
}
|
2000-03-02 03:01:30 +00:00
|
|
|
|
|
|
|
else if (aTag == nsXULAtoms::spinner)
|
1999-12-04 23:49:50 +00:00
|
|
|
rv = NS_NewSpinnerFrame(aPresShell, &newFrame);
|
1999-04-20 21:57:41 +00:00
|
|
|
else if (aTag == nsXULAtoms::fontpicker)
|
1999-12-04 23:49:50 +00:00
|
|
|
rv = NS_NewFontPickerFrame(aPresShell, &newFrame);
|
1999-10-14 10:55:24 +00:00
|
|
|
else if (aTag == nsXULAtoms::iframe) {
|
|
|
|
isReplaced = PR_TRUE;
|
1999-12-04 23:49:50 +00:00
|
|
|
rv = NS_NewHTMLFrameOuterFrame(aPresShell, &newFrame);
|
1999-10-14 10:55:24 +00:00
|
|
|
}
|
|
|
|
else if (aTag == nsXULAtoms::editor) {
|
|
|
|
isReplaced = PR_TRUE;
|
1999-12-04 23:49:50 +00:00
|
|
|
rv = NS_NewHTMLFrameOuterFrame(aPresShell, &newFrame);
|
1999-10-14 10:55:24 +00:00
|
|
|
}
|
|
|
|
else if (aTag == nsXULAtoms::browser) {
|
|
|
|
isReplaced = PR_TRUE;
|
1999-12-04 23:49:50 +00:00
|
|
|
rv = NS_NewHTMLFrameOuterFrame(aPresShell, &newFrame);
|
1999-10-14 10:55:24 +00:00
|
|
|
}
|
1999-06-23 03:02:21 +00:00
|
|
|
else if (aTag == nsXULAtoms::treeindentation)
|
|
|
|
{
|
1999-12-04 23:49:50 +00:00
|
|
|
rv = NS_NewTreeIndentationFrame(aPresShell, &newFrame);
|
1999-06-23 03:02:21 +00:00
|
|
|
}
|
|
|
|
// End of TREE CONSTRUCTION code here (there's more later on in the function)
|
1999-02-05 03:55:18 +00:00
|
|
|
|
1999-02-26 17:11:54 +00:00
|
|
|
// TOOLBAR CONSTRUCTION
|
|
|
|
else if (aTag == nsXULAtoms::toolbox) {
|
|
|
|
processChildren = PR_TRUE;
|
1999-12-04 23:49:50 +00:00
|
|
|
rv = NS_NewToolboxFrame(aPresShell, &newFrame);
|
1999-08-27 06:06:39 +00:00
|
|
|
|
|
|
|
const nsStyleDisplay* display = (const nsStyleDisplay*)
|
|
|
|
aStyleContext->GetStyleData(eStyleStruct_Display);
|
|
|
|
|
|
|
|
if (IsScrollable(aPresContext, display)) {
|
|
|
|
|
1999-10-12 00:16:06 +00:00
|
|
|
// build the scrollframe
|
|
|
|
// set the top to be the newly created scrollframe
|
1999-12-04 23:49:50 +00:00
|
|
|
BuildScrollFrame(aPresShell, aPresContext, aState, aContent, aStyleContext, newFrame, aParentFrame,
|
1999-10-12 00:16:06 +00:00
|
|
|
topFrame, aStyleContext);
|
|
|
|
|
|
|
|
// we have a scrollframe so the parent becomes the scroll frame.
|
|
|
|
newFrame->GetParent(&aParentFrame);
|
|
|
|
primaryFrameSet = PR_TRUE;
|
|
|
|
|
1999-08-27 06:06:39 +00:00
|
|
|
frameHasBeenInitialized = PR_TRUE;
|
|
|
|
|
|
|
|
}
|
1999-02-26 17:11:54 +00:00
|
|
|
}
|
|
|
|
else if (aTag == nsXULAtoms::toolbar) {
|
1999-08-27 06:06:39 +00:00
|
|
|
|
1999-02-26 17:11:54 +00:00
|
|
|
processChildren = PR_TRUE;
|
1999-12-04 23:49:50 +00:00
|
|
|
rv = NS_NewToolbarFrame(aPresShell, &newFrame);
|
1999-08-27 06:06:39 +00:00
|
|
|
|
|
|
|
const nsStyleDisplay* display = (const nsStyleDisplay*)
|
|
|
|
aStyleContext->GetStyleData(eStyleStruct_Display);
|
|
|
|
|
|
|
|
if (IsScrollable(aPresContext, display)) {
|
|
|
|
|
1999-10-12 00:16:06 +00:00
|
|
|
// set the top to be the newly created scrollframe
|
1999-12-04 23:49:50 +00:00
|
|
|
BuildScrollFrame(aPresShell, aPresContext, aState, aContent, aStyleContext, newFrame, aParentFrame,
|
1999-10-12 00:16:06 +00:00
|
|
|
topFrame, aStyleContext);
|
|
|
|
|
|
|
|
// we have a scrollframe so the parent becomes the scroll frame.
|
|
|
|
newFrame->GetParent(&aParentFrame);
|
|
|
|
primaryFrameSet = PR_TRUE;
|
|
|
|
|
1999-08-27 06:06:39 +00:00
|
|
|
frameHasBeenInitialized = PR_TRUE;
|
|
|
|
|
|
|
|
}
|
1999-02-26 17:11:54 +00:00
|
|
|
}
|
1999-07-01 21:11:38 +00:00
|
|
|
else if (aTag == nsXULAtoms::toolbaritem) {
|
|
|
|
processChildren = PR_TRUE;
|
1999-12-04 23:49:50 +00:00
|
|
|
rv = NS_NewToolbarItemFrame(aPresShell, &newFrame);
|
1999-07-01 21:11:38 +00:00
|
|
|
}
|
1999-02-26 17:11:54 +00:00
|
|
|
// End of TOOLBAR CONSTRUCTION logic
|
1999-02-05 03:55:18 +00:00
|
|
|
|
1999-02-26 17:11:54 +00:00
|
|
|
// PROGRESS METER CONSTRUCTION
|
2000-03-15 03:16:43 +00:00
|
|
|
else if (aTag == nsXULAtoms::progressbar) {
|
1999-02-26 17:11:54 +00:00
|
|
|
processChildren = PR_TRUE;
|
1999-03-04 23:39:06 +00:00
|
|
|
isReplaced = PR_TRUE;
|
1999-12-04 23:49:50 +00:00
|
|
|
rv = NS_NewProgressMeterFrame(aPresShell, &newFrame);
|
1999-02-26 17:11:54 +00:00
|
|
|
}
|
|
|
|
// End of PROGRESS METER CONSTRUCTION logic
|
2000-03-02 10:00:09 +00:00
|
|
|
|
2000-03-02 03:01:30 +00:00
|
|
|
// STACK CONSTRUCTION
|
|
|
|
else if (aTag == nsXULAtoms::stack) {
|
|
|
|
processChildren = PR_TRUE;
|
2000-02-16 23:00:52 +00:00
|
|
|
isReplaced = PR_TRUE;
|
2000-03-02 03:01:30 +00:00
|
|
|
rv = NS_NewStackFrame(aPresShell, &newFrame);
|
2000-02-16 23:00:52 +00:00
|
|
|
}
|
2000-03-02 03:01:30 +00:00
|
|
|
// End of STACK CONSTRUCTION logic
|
2000-02-16 23:00:52 +00:00
|
|
|
|
2000-07-10 20:10:27 +00:00
|
|
|
// BULLETINBOARD CONSTRUCTION
|
|
|
|
else if (aTag == nsXULAtoms::bulletinboard) {
|
|
|
|
processChildren = PR_TRUE;
|
|
|
|
isReplaced = PR_TRUE;
|
|
|
|
|
|
|
|
|
|
|
|
nsCOMPtr<nsIBoxLayout> layout;
|
|
|
|
NS_NewBulletinBoardLayout(aPresShell, layout);
|
|
|
|
|
|
|
|
rv = NS_NewBoxFrame(aPresShell, &newFrame, PR_FALSE, layout);
|
|
|
|
|
|
|
|
const nsStyleDisplay* display = (const nsStyleDisplay*)
|
|
|
|
aStyleContext->GetStyleData(eStyleStruct_Display);
|
|
|
|
|
|
|
|
if (IsScrollable(aPresContext, display)) {
|
|
|
|
|
|
|
|
// set the top to be the newly created scrollframe
|
|
|
|
BuildScrollFrame(aPresShell, aPresContext, aState, aContent, aStyleContext, newFrame, aParentFrame,
|
|
|
|
topFrame, aStyleContext);
|
|
|
|
|
|
|
|
// we have a scrollframe so the parent becomes the scroll frame.
|
|
|
|
newFrame->GetParent(&aParentFrame);
|
|
|
|
primaryFrameSet = PR_TRUE;
|
|
|
|
|
|
|
|
frameHasBeenInitialized = PR_TRUE;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// End of STACK CONSTRUCTION logic
|
|
|
|
|
1999-04-21 22:46:15 +00:00
|
|
|
// DECK CONSTRUCTION
|
|
|
|
else if (aTag == nsXULAtoms::deck || aTag == nsXULAtoms::tabpanel) {
|
|
|
|
processChildren = PR_TRUE;
|
|
|
|
isReplaced = PR_TRUE;
|
1999-12-04 23:49:50 +00:00
|
|
|
rv = NS_NewDeckFrame(aPresShell, &newFrame);
|
1999-04-21 22:46:15 +00:00
|
|
|
}
|
|
|
|
// End of DECK CONSTRUCTION logic
|
|
|
|
|
|
|
|
// TAB CONSTRUCTION
|
|
|
|
else if (aTag == nsXULAtoms::tab) {
|
|
|
|
processChildren = PR_TRUE;
|
|
|
|
isReplaced = PR_TRUE;
|
1999-12-04 23:49:50 +00:00
|
|
|
rv = NS_NewTabFrame(aPresShell, &newFrame);
|
1999-04-21 22:46:15 +00:00
|
|
|
}
|
|
|
|
// End of TAB CONSTRUCTION logic
|
|
|
|
|
1999-06-15 04:02:43 +00:00
|
|
|
// SLIDER CONSTRUCTION
|
|
|
|
else if (aTag == nsXULAtoms::slider) {
|
|
|
|
processChildren = PR_TRUE;
|
|
|
|
isReplaced = PR_TRUE;
|
1999-12-04 23:49:50 +00:00
|
|
|
rv = NS_NewSliderFrame(aPresShell, &newFrame);
|
1999-06-15 04:02:43 +00:00
|
|
|
}
|
|
|
|
// End of SLIDER CONSTRUCTION logic
|
|
|
|
|
|
|
|
// SCROLLBAR CONSTRUCTION
|
|
|
|
else if (aTag == nsXULAtoms::scrollbar) {
|
|
|
|
processChildren = PR_TRUE;
|
|
|
|
isReplaced = PR_TRUE;
|
1999-12-04 23:49:50 +00:00
|
|
|
rv = NS_NewScrollbarFrame(aPresShell, &newFrame);
|
1999-06-15 04:02:43 +00:00
|
|
|
|
|
|
|
}
|
|
|
|
// End of SCROLLBAR CONSTRUCTION logic
|
|
|
|
|
|
|
|
// SCROLLBUTTON CONSTRUCTION
|
|
|
|
else if (aTag == nsXULAtoms::scrollbarbutton) {
|
|
|
|
processChildren = PR_TRUE;
|
|
|
|
isReplaced = PR_TRUE;
|
1999-12-04 23:49:50 +00:00
|
|
|
rv = NS_NewScrollbarButtonFrame(aPresShell, &newFrame);
|
1999-06-15 04:02:43 +00:00
|
|
|
}
|
|
|
|
// End of SCROLLBUTTON CONSTRUCTION logic
|
|
|
|
|
1999-06-30 22:17:43 +00:00
|
|
|
// SPLITTER CONSTRUCTION
|
|
|
|
else if (aTag == nsXULAtoms::splitter) {
|
|
|
|
processChildren = PR_TRUE;
|
|
|
|
isReplaced = PR_TRUE;
|
1999-12-04 23:49:50 +00:00
|
|
|
rv = NS_NewSplitterFrame(aPresShell, &newFrame);
|
1999-06-30 22:17:43 +00:00
|
|
|
}
|
|
|
|
// End of SPLITTER CONSTRUCTION logic
|
|
|
|
|
|
|
|
// GRIPPY CONSTRUCTION
|
|
|
|
else if (aTag == nsXULAtoms::grippy) {
|
|
|
|
processChildren = PR_TRUE;
|
|
|
|
isReplaced = PR_TRUE;
|
1999-12-04 23:49:50 +00:00
|
|
|
rv = NS_NewGrippyFrame(aPresShell, &newFrame);
|
1999-06-30 22:17:43 +00:00
|
|
|
}
|
|
|
|
// End of GRIPPY CONSTRUCTION logic
|
2000-07-07 22:24:06 +00:00
|
|
|
#if 1
|
2000-06-22 00:36:19 +00:00
|
|
|
else if (aTag != nsHTMLAtoms::html) {
|
|
|
|
nsCAutoString str("Invalid XUL tag encountered in file. Perhaps you used the wrong namespace?\n\nThe tag name is ");
|
|
|
|
nsAutoString tagName;
|
|
|
|
aTag->ToString(tagName);
|
|
|
|
str.AppendWithConversion(tagName);
|
2000-07-07 22:24:06 +00:00
|
|
|
NS_WARNING(str);
|
2000-06-22 00:36:19 +00:00
|
|
|
}
|
2000-06-22 19:34:29 +00:00
|
|
|
#endif
|
1999-02-05 03:55:18 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// If we succeeded in creating a frame then initialize it, process its
|
|
|
|
// children (if requested), and set the initial child list
|
1999-02-10 19:50:50 +00:00
|
|
|
if (NS_SUCCEEDED(rv) && newFrame != nsnull) {
|
1999-10-12 00:16:06 +00:00
|
|
|
|
|
|
|
// if no top frame was created then the top is the new frame
|
|
|
|
if (topFrame == nsnull)
|
|
|
|
topFrame = newFrame;
|
|
|
|
|
1999-03-04 23:39:06 +00:00
|
|
|
// If the frame is a replaced element, then set the frame state bit
|
|
|
|
if (isReplaced) {
|
|
|
|
nsFrameState state;
|
|
|
|
newFrame->GetFrameState(&state);
|
|
|
|
newFrame->SetFrameState(state | NS_FRAME_REPLACED_ELEMENT);
|
|
|
|
}
|
|
|
|
|
2000-02-10 21:36:28 +00:00
|
|
|
// xul does not support absolute positioning
|
|
|
|
nsIFrame* geometricParent = aParentFrame;
|
|
|
|
|
|
|
|
/*
|
1999-10-12 00:16:06 +00:00
|
|
|
nsIFrame* geometricParent = isAbsolutelyPositioned
|
1999-07-20 07:03:16 +00:00
|
|
|
? aState.mAbsoluteItems.containingBlock
|
|
|
|
: aParentFrame;
|
2000-02-10 21:36:28 +00:00
|
|
|
*/
|
1999-10-12 00:16:06 +00:00
|
|
|
// if the new frame was already initialized to initialize it again.
|
|
|
|
if (!frameHasBeenInitialized) {
|
|
|
|
|
1999-12-06 07:44:18 +00:00
|
|
|
InitAndRestoreFrame(aPresContext, aState, aContent,
|
|
|
|
geometricParent, aStyleContext, nsnull, newFrame);
|
1999-02-05 03:55:18 +00:00
|
|
|
|
2000-07-10 20:10:27 +00:00
|
|
|
|
2000-06-28 22:19:54 +00:00
|
|
|
/*
|
|
|
|
// if our parent is a block frame then do things the way html likes it
|
|
|
|
// if not then we are in a box so do what boxes like. On example is boxes
|
|
|
|
// do not support the absolute positioning of their children. While html blocks
|
|
|
|
// thats why we call different things here.
|
2000-07-10 20:10:27 +00:00
|
|
|
nsCOMPtr<nsIAtom> frameType;
|
|
|
|
geometricParent->GetFrameType(getter_AddRefs(frameType));
|
|
|
|
if ((frameType.get() == nsLayoutAtoms::blockFrame) ||
|
|
|
|
(frameType.get() == nsLayoutAtoms::areaFrame)) {
|
2000-06-28 22:19:54 +00:00
|
|
|
*/
|
|
|
|
// See if we need to create a view, e.g. the frame is absolutely positioned
|
|
|
|
nsHTMLContainerFrame::CreateViewForFrame(aPresContext, newFrame,
|
|
|
|
aStyleContext, PR_FALSE);
|
|
|
|
|
2000-07-10 20:10:27 +00:00
|
|
|
/*
|
2000-06-28 22:19:54 +00:00
|
|
|
} else {
|
|
|
|
// we are in a box so do the box thing.
|
|
|
|
nsBoxFrame::CreateViewForFrame(aPresContext, newFrame,
|
|
|
|
aStyleContext, PR_FALSE);
|
|
|
|
}
|
|
|
|
*/
|
2000-07-10 20:10:27 +00:00
|
|
|
|
1999-10-12 00:16:06 +00:00
|
|
|
}
|
1999-02-05 03:55:18 +00:00
|
|
|
|
1999-07-20 07:03:16 +00:00
|
|
|
// Process the child content if requested
|
|
|
|
nsFrameItems childItems;
|
|
|
|
if (processChildren) {
|
1999-12-04 23:49:50 +00:00
|
|
|
rv = ProcessChildren(aPresShell, aPresContext, aState, aContent, newFrame,
|
1999-08-27 21:46:10 +00:00
|
|
|
PR_FALSE, childItems, PR_FALSE);
|
1999-10-12 00:16:06 +00:00
|
|
|
|
2000-05-15 20:25:02 +00:00
|
|
|
CreateAnonymousFrames(aPresShell, aPresContext, aTag, aState, aContent, newFrame,
|
1999-07-20 07:03:16 +00:00
|
|
|
childItems);
|
|
|
|
|
|
|
|
// Set the frame's initial child list
|
1999-11-24 06:03:41 +00:00
|
|
|
newFrame->SetInitialChildList(aPresContext, nsnull, childItems.childList);
|
1999-02-26 17:11:54 +00:00
|
|
|
}
|
|
|
|
|
1999-07-20 07:03:16 +00:00
|
|
|
// Add the new frame to our list of frame items.
|
1999-10-12 00:16:06 +00:00
|
|
|
aFrameItems.AddChild(topFrame);
|
1999-02-05 03:55:18 +00:00
|
|
|
|
1999-07-01 14:34:35 +00:00
|
|
|
// If the frame is absolutely positioned, then create a placeholder frame
|
1999-02-10 19:50:50 +00:00
|
|
|
if (isAbsolutelyPositioned || isFixedPositioned) {
|
1999-02-05 03:55:18 +00:00
|
|
|
nsIFrame* placeholderFrame;
|
|
|
|
|
1999-12-04 23:49:50 +00:00
|
|
|
CreatePlaceholderFrameFor(aPresShell, aPresContext, aState.mFrameManager, aContent,
|
1999-08-05 03:09:22 +00:00
|
|
|
newFrame, aStyleContext, aParentFrame, &placeholderFrame);
|
1999-02-05 03:55:18 +00:00
|
|
|
|
1999-02-10 19:50:50 +00:00
|
|
|
// Add the positioned frame to its containing block's list of child frames
|
|
|
|
if (isAbsolutelyPositioned) {
|
1999-04-28 19:08:14 +00:00
|
|
|
aState.mAbsoluteItems.AddChild(newFrame);
|
1999-02-26 17:11:54 +00:00
|
|
|
} else {
|
1999-04-28 19:08:14 +00:00
|
|
|
aState.mFixedItems.AddChild(newFrame);
|
1999-02-26 17:11:54 +00:00
|
|
|
}
|
1999-02-05 03:55:18 +00:00
|
|
|
|
|
|
|
// Add the placeholder frame to the flow
|
|
|
|
aFrameItems.AddChild(placeholderFrame);
|
1999-02-26 17:11:54 +00:00
|
|
|
}
|
1999-07-06 03:52:33 +00:00
|
|
|
}
|
1999-07-01 14:34:35 +00:00
|
|
|
|
1999-07-06 03:52:33 +00:00
|
|
|
addToHashTable:
|
1999-10-12 00:16:06 +00:00
|
|
|
|
|
|
|
if (topFrame) {
|
|
|
|
// the top frame is always what we map the content to. This is the frame that contains a pointer
|
|
|
|
// to the content node.
|
|
|
|
|
1999-07-01 14:34:35 +00:00
|
|
|
// Add a mapping from content object to primary frame. Note that for
|
|
|
|
// floated and positioned frames this is the out-of-flow frame and not
|
|
|
|
// the placeholder frame
|
1999-10-12 00:16:06 +00:00
|
|
|
if (!primaryFrameSet)
|
|
|
|
aState.mFrameManager->SetPrimaryFrameFor(aContent, topFrame);
|
1999-02-05 03:55:18 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2000-06-28 22:19:54 +00:00
|
|
|
static NS_DEFINE_IID(kWidgetCID, NS_CHILD_CID);
|
|
|
|
|
|
|
|
|
1999-08-19 22:16:23 +00:00
|
|
|
|
1999-08-27 06:06:39 +00:00
|
|
|
nsresult
|
1999-12-04 23:49:50 +00:00
|
|
|
nsCSSFrameConstructor::BeginBuildingScrollFrame(nsIPresShell* aPresShell,
|
|
|
|
nsIPresContext* aPresContext,
|
1999-08-27 06:06:39 +00:00
|
|
|
nsFrameConstructorState& aState,
|
|
|
|
nsIContent* aContent,
|
1999-10-12 00:16:06 +00:00
|
|
|
nsIStyleContext* aContentStyle,
|
1999-08-27 06:06:39 +00:00
|
|
|
nsIFrame* aParentFrame,
|
1999-10-12 00:16:06 +00:00
|
|
|
nsIAtom* aScrolledPseudo,
|
|
|
|
nsIDocument* aDocument,
|
2000-03-31 07:02:06 +00:00
|
|
|
PRBool aIsRoot,
|
1999-08-27 06:06:39 +00:00
|
|
|
nsIFrame*& aNewFrame,
|
1999-10-12 00:16:06 +00:00
|
|
|
nsCOMPtr<nsIStyleContext>& aScrolledChildStyle,
|
|
|
|
nsIFrame*& aScrollableFrame)
|
1999-08-27 06:06:39 +00:00
|
|
|
{
|
1999-10-12 00:16:06 +00:00
|
|
|
nsIFrame* scrollFrame = nsnull;
|
|
|
|
nsIFrame* parentFrame = nsnull;
|
|
|
|
nsIFrame* gfxScrollFrame = nsnull;
|
1999-08-27 06:06:39 +00:00
|
|
|
|
1999-10-12 00:16:06 +00:00
|
|
|
nsFrameItems anonymousItems;
|
1999-08-27 06:06:39 +00:00
|
|
|
|
1999-11-11 21:48:17 +00:00
|
|
|
nsCOMPtr<nsIStyleContext> contentStyle = dont_QueryInterface(aContentStyle);
|
|
|
|
|
2000-03-27 22:12:42 +00:00
|
|
|
PRBool isGfx = HasGfxScrollbars();
|
1999-08-27 06:06:39 +00:00
|
|
|
|
1999-10-12 00:16:06 +00:00
|
|
|
if (isGfx) {
|
|
|
|
|
1999-12-04 23:49:50 +00:00
|
|
|
BuildGfxScrollFrame(aPresShell, aPresContext, aState, aContent, aDocument, aParentFrame,
|
2000-03-31 07:02:06 +00:00
|
|
|
contentStyle, aIsRoot, gfxScrollFrame, anonymousItems);
|
1999-08-27 06:06:39 +00:00
|
|
|
|
1999-10-12 00:16:06 +00:00
|
|
|
scrollFrame = anonymousItems.childList;
|
|
|
|
parentFrame = gfxScrollFrame;
|
1999-08-27 06:06:39 +00:00
|
|
|
aNewFrame = gfxScrollFrame;
|
1999-10-12 00:16:06 +00:00
|
|
|
|
|
|
|
// we used the style that was passed in. So resolve another one.
|
|
|
|
nsCOMPtr<nsIStyleContext> scrollPseudoStyle;
|
|
|
|
aPresContext->ResolvePseudoStyleContextFor(aContent,
|
|
|
|
nsLayoutAtoms::scrolledContentPseudo,
|
1999-11-11 21:48:17 +00:00
|
|
|
contentStyle, PR_FALSE,
|
1999-12-08 01:56:28 +00:00
|
|
|
getter_AddRefs(scrollPseudoStyle));
|
1999-10-12 00:16:06 +00:00
|
|
|
|
1999-12-08 01:56:28 +00:00
|
|
|
contentStyle = scrollPseudoStyle;
|
1999-12-06 07:44:18 +00:00
|
|
|
InitAndRestoreFrame(aPresContext, aState, aContent,
|
|
|
|
parentFrame, contentStyle, nsnull, scrollFrame);
|
2000-06-28 22:19:54 +00:00
|
|
|
|
1999-08-27 06:06:39 +00:00
|
|
|
} else {
|
1999-12-04 23:49:50 +00:00
|
|
|
NS_NewScrollFrame(aPresShell, &scrollFrame);
|
1999-08-27 06:06:39 +00:00
|
|
|
aNewFrame = scrollFrame;
|
1999-10-12 00:16:06 +00:00
|
|
|
parentFrame = aParentFrame;
|
1999-12-06 07:44:18 +00:00
|
|
|
InitAndRestoreFrame(aPresContext, aState, aContent,
|
|
|
|
parentFrame, contentStyle, nsnull, scrollFrame);
|
1999-08-27 06:06:39 +00:00
|
|
|
}
|
|
|
|
|
1999-10-12 00:16:06 +00:00
|
|
|
// initialize the scrolled frame
|
|
|
|
nsCOMPtr<nsIStyleContext> scrolledPseudoStyle;
|
|
|
|
aPresContext->ResolvePseudoStyleContextFor(aContent,
|
|
|
|
aScrolledPseudo,
|
1999-11-11 21:48:17 +00:00
|
|
|
contentStyle, PR_FALSE,
|
1999-10-12 00:16:06 +00:00
|
|
|
getter_AddRefs(scrolledPseudoStyle));
|
|
|
|
|
|
|
|
|
|
|
|
aScrollableFrame = scrollFrame;
|
|
|
|
|
|
|
|
// set the child frame for the gfxscrollbar if the is one. This frames will be the
|
|
|
|
// 2 scrollbars and the scrolled frame.
|
|
|
|
if (gfxScrollFrame) {
|
1999-11-24 06:03:41 +00:00
|
|
|
gfxScrollFrame->SetInitialChildList(aPresContext, nsnull, anonymousItems.childList);
|
1999-10-12 00:16:06 +00:00
|
|
|
}
|
|
|
|
|
1999-11-10 23:51:44 +00:00
|
|
|
|
1999-10-12 00:16:06 +00:00
|
|
|
aScrolledChildStyle = scrolledPseudoStyle;
|
|
|
|
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
nsCSSFrameConstructor::FinishBuildingScrollFrame(nsIPresContext* aPresContext,
|
|
|
|
nsFrameConstructorState& aState,
|
|
|
|
nsIContent* aContent,
|
|
|
|
nsIFrame* aScrollFrame,
|
|
|
|
nsIFrame* aScrolledFrame,
|
|
|
|
nsIStyleContext* aScrolledContentStyle)
|
|
|
|
|
|
|
|
{
|
|
|
|
// create a view
|
1999-11-24 06:03:41 +00:00
|
|
|
nsHTMLContainerFrame::CreateViewForFrame(aPresContext, aScrolledFrame,
|
1999-10-12 00:16:06 +00:00
|
|
|
aScrolledContentStyle, PR_TRUE);
|
|
|
|
|
|
|
|
// the the scroll frames child list
|
1999-11-24 06:03:41 +00:00
|
|
|
aScrollFrame->SetInitialChildList(aPresContext, nsnull, aScrolledFrame);
|
1999-10-12 00:16:06 +00:00
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
1999-08-27 06:06:39 +00:00
|
|
|
|
1999-08-19 22:16:23 +00:00
|
|
|
/**
|
1999-11-10 23:51:44 +00:00
|
|
|
* Called to wrap a scrollframe or gfx scrollframe around a frame. The hierarchy will look like this
|
|
|
|
*
|
|
|
|
* ------ for native scrollbars -----
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* ScrollFrame
|
|
|
|
* ^
|
|
|
|
* |
|
|
|
|
* Frame (scrolled frame you passed in)
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* ------- for gfx scrollbars ------
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* GfxScrollFrame
|
|
|
|
* ^
|
|
|
|
* |
|
|
|
|
* ScrollPort
|
|
|
|
* ^
|
|
|
|
* |
|
|
|
|
* Frame (scrolled frame you passed in)
|
|
|
|
*
|
|
|
|
*
|
|
|
|
*-----------------------------------
|
|
|
|
* LEGEND:
|
|
|
|
*
|
|
|
|
* ScrollFrame: This is a frame that has a view that manages native scrollbars. It implements
|
|
|
|
* nsIScrollableView. It also manages clipping and scrolling of native widgets by
|
|
|
|
* having a native scrolling window.
|
|
|
|
*
|
|
|
|
* GfxScrollFrame: This is a frame that manages gfx cross platform frame based scrollbars.
|
|
|
|
*
|
|
|
|
* ScrollPort: This is similar to the ScrollFrame above in that is clips and scrolls its children
|
|
|
|
* with a native scrolling window. But because it is contained in a GfxScrollFrame
|
|
|
|
* it does not have any code to do scrollbars so it is much simpler. Infact it only has
|
|
|
|
* 1 view attached to it. Where the ScrollFrame above has 5!
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* @param aContent the content node of the child to wrap.
|
|
|
|
* @param aScrolledFrame The frame of the content to wrap. This should not be
|
|
|
|
* Initialized. This method will initialize it with a scrolled pseudo
|
|
|
|
* and no nsIContent. The content will be attached to the scrollframe
|
|
|
|
* returned.
|
|
|
|
* @param aContentStyle the style context that has already been resolved for the content being passed in.
|
|
|
|
*
|
|
|
|
* @param aParentFrame The parent to attach the scroll frame to
|
|
|
|
*
|
|
|
|
* @param aNewFrame The new scrollframe or gfx scrollframe that we create. It will contain the
|
|
|
|
* scrolled frame you passed in. (returned)
|
|
|
|
* @param aScrolledContentStyle the style that was resolved for the scrolled frame. (returned)
|
1999-08-19 22:16:23 +00:00
|
|
|
*/
|
|
|
|
nsresult
|
1999-12-04 23:49:50 +00:00
|
|
|
nsCSSFrameConstructor::BuildScrollFrame (nsIPresShell* aPresShell,
|
|
|
|
nsIPresContext* aPresContext,
|
1999-08-19 22:16:23 +00:00
|
|
|
nsFrameConstructorState& aState,
|
|
|
|
nsIContent* aContent,
|
1999-10-12 00:16:06 +00:00
|
|
|
nsIStyleContext* aContentStyle,
|
1999-08-19 22:16:23 +00:00
|
|
|
nsIFrame* aScrolledFrame,
|
|
|
|
nsIFrame* aParentFrame,
|
1999-10-12 00:16:06 +00:00
|
|
|
nsIFrame*& aNewFrame,
|
|
|
|
nsIStyleContext*& aScrolledContentStyle)
|
1999-08-19 22:16:23 +00:00
|
|
|
{
|
1999-10-12 00:16:06 +00:00
|
|
|
nsIFrame *scrollFrame;
|
1999-11-02 06:40:38 +00:00
|
|
|
nsCOMPtr<nsIDocument> document;
|
|
|
|
aContent->GetDocument(*getter_AddRefs(document));
|
1999-10-12 00:16:06 +00:00
|
|
|
nsCOMPtr<nsIStyleContext> scrolledContentStyle;
|
1999-08-19 22:16:23 +00:00
|
|
|
|
1999-10-12 00:16:06 +00:00
|
|
|
|
1999-12-04 23:49:50 +00:00
|
|
|
BeginBuildingScrollFrame(aPresShell, aPresContext,
|
1999-10-12 00:16:06 +00:00
|
|
|
aState,
|
|
|
|
aContent,
|
|
|
|
aContentStyle,
|
|
|
|
aParentFrame,
|
|
|
|
nsLayoutAtoms::scrolledContentPseudo,
|
|
|
|
document,
|
2000-03-31 07:02:06 +00:00
|
|
|
PR_FALSE,
|
1999-10-12 00:16:06 +00:00
|
|
|
aNewFrame,
|
|
|
|
scrolledContentStyle,
|
|
|
|
scrollFrame);
|
1999-12-06 07:44:18 +00:00
|
|
|
|
|
|
|
InitAndRestoreFrame(aPresContext, aState, aContent,
|
|
|
|
scrollFrame, scrolledContentStyle, nsnull, aScrolledFrame);
|
1999-08-19 22:16:23 +00:00
|
|
|
|
1999-10-12 00:16:06 +00:00
|
|
|
FinishBuildingScrollFrame(aPresContext,
|
|
|
|
aState,
|
|
|
|
aContent,
|
|
|
|
scrollFrame,
|
|
|
|
aScrolledFrame,
|
|
|
|
scrolledContentStyle);
|
1999-08-19 22:16:23 +00:00
|
|
|
|
1999-10-12 00:16:06 +00:00
|
|
|
aScrolledContentStyle = scrolledContentStyle;
|
1999-08-19 22:16:23 +00:00
|
|
|
|
2000-01-31 14:04:41 +00:00
|
|
|
// now set the primary frame to the ScrollFrame
|
|
|
|
aState.mFrameManager->SetPrimaryFrameFor( aContent, aNewFrame );
|
|
|
|
|
1999-10-12 00:16:06 +00:00
|
|
|
return NS_OK;
|
1999-08-19 22:16:23 +00:00
|
|
|
|
|
|
|
}
|
|
|
|
|
1999-10-12 00:16:06 +00:00
|
|
|
/**
|
|
|
|
* If we are building GFX scrollframes this will create one
|
|
|
|
*/
|
1999-08-19 22:16:23 +00:00
|
|
|
nsresult
|
1999-12-04 23:49:50 +00:00
|
|
|
nsCSSFrameConstructor::BuildGfxScrollFrame (nsIPresShell* aPresShell,
|
|
|
|
nsIPresContext* aPresContext,
|
1999-08-19 22:16:23 +00:00
|
|
|
nsFrameConstructorState& aState,
|
|
|
|
nsIContent* aContent,
|
1999-10-12 00:16:06 +00:00
|
|
|
nsIDocument* aDocument,
|
1999-08-19 22:16:23 +00:00
|
|
|
nsIFrame* aParentFrame,
|
|
|
|
nsIStyleContext* aStyleContext,
|
2000-03-31 07:02:06 +00:00
|
|
|
PRBool aIsRoot,
|
1999-08-19 22:16:23 +00:00
|
|
|
nsIFrame*& aNewFrame,
|
|
|
|
nsFrameItems& aAnonymousFrames)
|
|
|
|
{
|
2000-03-31 07:02:06 +00:00
|
|
|
NS_NewGfxScrollFrame(aPresShell, &aNewFrame, aDocument, aIsRoot);
|
1999-08-19 22:16:23 +00:00
|
|
|
|
1999-12-06 07:44:18 +00:00
|
|
|
InitAndRestoreFrame(aPresContext, aState, aContent,
|
|
|
|
aParentFrame, aStyleContext, nsnull, aNewFrame);
|
1999-08-19 22:16:23 +00:00
|
|
|
|
2000-06-28 22:19:54 +00:00
|
|
|
// Create a view
|
|
|
|
nsHTMLContainerFrame::CreateViewForFrame(aPresContext, aNewFrame,
|
|
|
|
aStyleContext, PR_FALSE);
|
|
|
|
|
1999-08-19 22:16:23 +00:00
|
|
|
nsIFrame* scrollbox = nsnull;
|
1999-12-04 23:49:50 +00:00
|
|
|
NS_NewScrollPortFrame(aPresShell, &scrollbox);
|
1999-08-19 22:16:23 +00:00
|
|
|
|
|
|
|
|
|
|
|
aAnonymousFrames.AddChild(scrollbox);
|
|
|
|
|
|
|
|
// if there are any anonymous children for the nsScrollFrame create frames for them.
|
1999-12-04 23:49:50 +00:00
|
|
|
CreateAnonymousFrames(aPresShell, aPresContext, aState, aContent, aDocument, aNewFrame,
|
1999-08-19 22:16:23 +00:00
|
|
|
aAnonymousFrames);
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
1999-02-05 03:55:18 +00:00
|
|
|
nsresult
|
1999-12-04 23:49:50 +00:00
|
|
|
nsCSSFrameConstructor::ConstructFrameByDisplayType(nsIPresShell* aPresShell,
|
|
|
|
nsIPresContext* aPresContext,
|
1999-04-28 19:08:14 +00:00
|
|
|
nsFrameConstructorState& aState,
|
|
|
|
const nsStyleDisplay* aDisplay,
|
|
|
|
nsIContent* aContent,
|
|
|
|
nsIFrame* aParentFrame,
|
|
|
|
nsIStyleContext* aStyleContext,
|
|
|
|
nsFrameItems& aFrameItems)
|
1999-02-05 03:55:18 +00:00
|
|
|
{
|
1999-10-12 00:16:06 +00:00
|
|
|
PRBool primaryFrameSet = PR_FALSE;
|
1999-02-05 03:55:18 +00:00
|
|
|
PRBool isAbsolutelyPositioned = PR_FALSE;
|
|
|
|
PRBool isFixedPositioned = PR_FALSE;
|
1999-02-26 17:11:54 +00:00
|
|
|
PRBool isFloating = PR_FALSE;
|
1999-02-05 03:55:18 +00:00
|
|
|
PRBool isBlock = aDisplay->IsBlockLevel();
|
|
|
|
nsIFrame* newFrame = nsnull; // the frame we construct
|
1999-11-01 15:24:57 +00:00
|
|
|
nsIFrame* newBlock = nsnull;
|
|
|
|
nsIFrame* nextInline = nsnull;
|
1999-12-04 23:49:50 +00:00
|
|
|
nsTableCreator tableCreator(aPresShell); // Used to make table frames.
|
1999-07-06 03:52:33 +00:00
|
|
|
PRBool addToHashTable = PR_TRUE;
|
2000-04-04 01:28:15 +00:00
|
|
|
PRBool pseudoParent = PR_FALSE; // is the new frame's parent anonymous
|
1999-02-05 03:55:18 +00:00
|
|
|
nsresult rv = NS_OK;
|
|
|
|
|
|
|
|
// Get the position syle info
|
|
|
|
const nsStylePosition* position = (const nsStylePosition*)
|
|
|
|
aStyleContext->GetStyleData(eStyleStruct_Position);
|
|
|
|
|
|
|
|
// The frame is also a block if it's an inline frame that's floated or
|
|
|
|
// absolutely positioned
|
1999-02-26 17:11:54 +00:00
|
|
|
if (NS_STYLE_FLOAT_NONE != aDisplay->mFloats) {
|
|
|
|
isFloating = PR_TRUE;
|
|
|
|
}
|
1999-02-05 03:55:18 +00:00
|
|
|
if ((NS_STYLE_DISPLAY_INLINE == aDisplay->mDisplay) &&
|
1999-02-26 17:11:54 +00:00
|
|
|
(isFloating || position->IsAbsolutelyPositioned())) {
|
1999-02-05 03:55:18 +00:00
|
|
|
isBlock = PR_TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
// If the frame is a block-level frame and is scrollable, then wrap it
|
|
|
|
// in a scroll frame.
|
|
|
|
// XXX Ignore tables for the time being
|
|
|
|
if ((isBlock && (aDisplay->mDisplay != NS_STYLE_DISPLAY_TABLE)) &&
|
|
|
|
IsScrollable(aPresContext, aDisplay)) {
|
|
|
|
|
2000-04-04 01:28:15 +00:00
|
|
|
if (!aState.mPseudoFrames.IsEmpty()) { // process pending pseudo frames
|
|
|
|
ProcessPseudoFrames(aPresContext, aState.mPseudoFrames, aFrameItems);
|
|
|
|
}
|
1999-02-05 03:55:18 +00:00
|
|
|
// See if it's absolute positioned or fixed positioned
|
|
|
|
if (NS_STYLE_POSITION_ABSOLUTE == position->mPosition) {
|
|
|
|
isAbsolutelyPositioned = PR_TRUE;
|
|
|
|
} else if (NS_STYLE_POSITION_FIXED == position->mPosition) {
|
|
|
|
isFixedPositioned = PR_TRUE;
|
|
|
|
}
|
|
|
|
|
1999-10-12 00:16:06 +00:00
|
|
|
// Initialize it
|
|
|
|
nsIFrame* geometricParent = aParentFrame;
|
|
|
|
|
|
|
|
if (isAbsolutelyPositioned) {
|
|
|
|
geometricParent = aState.mAbsoluteItems.containingBlock;
|
|
|
|
} else if (isFixedPositioned) {
|
|
|
|
geometricParent = aState.mFixedItems.containingBlock;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsIFrame* scrolledFrame = nsnull;
|
|
|
|
|
1999-12-04 23:49:50 +00:00
|
|
|
NS_NewAreaFrame(aPresShell, &scrolledFrame, NS_BLOCK_SPACE_MGR |
|
1999-10-14 04:47:18 +00:00
|
|
|
NS_BLOCK_SHRINK_WRAP | NS_BLOCK_MARGIN_ROOT);
|
1999-10-12 00:16:06 +00:00
|
|
|
|
|
|
|
|
|
|
|
nsIStyleContext* newStyle = nsnull;
|
1999-08-19 22:16:23 +00:00
|
|
|
// Build the scrollframe it
|
1999-12-04 23:49:50 +00:00
|
|
|
BuildScrollFrame(aPresShell, aPresContext, aState, aContent, aStyleContext, scrolledFrame, geometricParent,
|
1999-10-12 00:16:06 +00:00
|
|
|
newFrame, newStyle);
|
|
|
|
|
|
|
|
// buildscrollframe sets the primary frame.
|
|
|
|
primaryFrameSet = PR_TRUE;
|
|
|
|
|
|
|
|
//-----
|
|
|
|
|
|
|
|
// The area frame is a floater container
|
|
|
|
PRBool haveFirstLetterStyle, haveFirstLineStyle;
|
|
|
|
HaveSpecialBlockStyle(aPresContext, aContent, aStyleContext,
|
|
|
|
&haveFirstLetterStyle, &haveFirstLineStyle);
|
|
|
|
nsFrameConstructorSaveState floaterSaveState;
|
|
|
|
aState.PushFloaterContainingBlock(scrolledFrame, floaterSaveState,
|
|
|
|
haveFirstLetterStyle,
|
|
|
|
haveFirstLineStyle);
|
|
|
|
|
|
|
|
// Process children
|
|
|
|
nsFrameConstructorSaveState absoluteSaveState;
|
|
|
|
nsFrameItems childItems;
|
|
|
|
PRBool isPositionedContainingBlock = isAbsolutelyPositioned ||
|
|
|
|
isFixedPositioned;
|
|
|
|
|
|
|
|
if (isPositionedContainingBlock) {
|
|
|
|
// The area frame becomes a container for child frames that are
|
|
|
|
// absolutely positioned
|
|
|
|
aState.PushAbsoluteContainingBlock(scrolledFrame, absoluteSaveState);
|
|
|
|
}
|
|
|
|
|
1999-12-04 23:49:50 +00:00
|
|
|
ProcessChildren(aPresShell, aPresContext, aState, aContent, scrolledFrame, PR_FALSE,
|
1999-10-12 00:16:06 +00:00
|
|
|
childItems, PR_TRUE);
|
|
|
|
|
2000-05-09 21:42:40 +00:00
|
|
|
nsCOMPtr<nsIAtom> tag;
|
|
|
|
aContent->GetTag(*getter_AddRefs(tag));
|
|
|
|
CreateAnonymousFrames(aPresShell, aPresContext, tag, aState, aContent, newFrame,
|
|
|
|
childItems);
|
|
|
|
|
1999-10-12 00:16:06 +00:00
|
|
|
// Set the scrolled frame's initial child lists
|
1999-11-24 06:03:41 +00:00
|
|
|
scrolledFrame->SetInitialChildList(aPresContext, nsnull, childItems.childList);
|
1999-10-12 00:16:06 +00:00
|
|
|
if (isPositionedContainingBlock && aState.mAbsoluteItems.childList) {
|
1999-11-24 06:03:41 +00:00
|
|
|
scrolledFrame->SetInitialChildList(aPresContext,
|
1999-10-12 00:16:06 +00:00
|
|
|
nsLayoutAtoms::absoluteList,
|
|
|
|
aState.mAbsoluteItems.childList);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (aState.mFloatedItems.childList) {
|
1999-11-24 06:03:41 +00:00
|
|
|
scrolledFrame->SetInitialChildList(aPresContext,
|
1999-10-12 00:16:06 +00:00
|
|
|
nsLayoutAtoms::floaterList,
|
|
|
|
aState.mFloatedItems.childList);
|
|
|
|
}
|
|
|
|
///------
|
1999-02-26 17:11:54 +00:00
|
|
|
}
|
1999-02-05 03:55:18 +00:00
|
|
|
// See if the frame is absolute or fixed positioned
|
1999-02-26 17:11:54 +00:00
|
|
|
else if (position->IsAbsolutelyPositioned() &&
|
|
|
|
((NS_STYLE_DISPLAY_BLOCK == aDisplay->mDisplay) ||
|
|
|
|
(NS_STYLE_DISPLAY_INLINE == aDisplay->mDisplay) ||
|
|
|
|
(NS_STYLE_DISPLAY_LIST_ITEM == aDisplay->mDisplay))) {
|
1999-02-05 03:55:18 +00:00
|
|
|
|
2000-04-04 01:28:15 +00:00
|
|
|
if (!aState.mPseudoFrames.IsEmpty()) { // process pending pseudo frames
|
|
|
|
ProcessPseudoFrames(aPresContext, aState.mPseudoFrames, aFrameItems);
|
|
|
|
}
|
1999-02-05 03:55:18 +00:00
|
|
|
if (NS_STYLE_POSITION_ABSOLUTE == position->mPosition) {
|
|
|
|
isAbsolutelyPositioned = PR_TRUE;
|
|
|
|
} else {
|
|
|
|
isFixedPositioned = PR_TRUE;
|
|
|
|
}
|
|
|
|
|
1999-05-11 22:03:29 +00:00
|
|
|
// Create a frame to wrap up the absolute positioned item
|
1999-12-04 23:49:50 +00:00
|
|
|
NS_NewAbsoluteItemWrapperFrame(aPresShell, &newFrame);
|
1999-12-06 07:44:18 +00:00
|
|
|
InitAndRestoreFrame(aPresContext, aState, aContent,
|
|
|
|
(isAbsolutelyPositioned
|
|
|
|
? aState.mAbsoluteItems.containingBlock
|
|
|
|
: aState.mFixedItems.containingBlock),
|
|
|
|
aStyleContext, nsnull, newFrame);
|
1999-02-05 03:55:18 +00:00
|
|
|
|
|
|
|
// Create a view
|
1999-11-24 06:03:41 +00:00
|
|
|
nsHTMLContainerFrame::CreateViewForFrame(aPresContext, newFrame,
|
1999-02-05 03:55:18 +00:00
|
|
|
aStyleContext, PR_FALSE);
|
|
|
|
|
|
|
|
// Process the child content. The area frame becomes a container for child
|
|
|
|
// frames that are absolutely positioned
|
1999-04-28 19:08:14 +00:00
|
|
|
nsFrameConstructorSaveState absoluteSaveState;
|
|
|
|
nsFrameConstructorSaveState floaterSaveState;
|
|
|
|
nsFrameItems childItems;
|
1999-02-05 03:55:18 +00:00
|
|
|
|
1999-08-31 03:09:40 +00:00
|
|
|
PRBool haveFirstLetterStyle = PR_FALSE, haveFirstLineStyle = PR_FALSE;
|
|
|
|
if (aDisplay->IsBlockLevel()) {
|
|
|
|
HaveSpecialBlockStyle(aPresContext, aContent, aStyleContext,
|
|
|
|
&haveFirstLetterStyle, &haveFirstLineStyle);
|
|
|
|
}
|
1999-04-28 19:08:14 +00:00
|
|
|
aState.PushAbsoluteContainingBlock(newFrame, absoluteSaveState);
|
1999-08-31 03:09:40 +00:00
|
|
|
aState.PushFloaterContainingBlock(newFrame, floaterSaveState,
|
|
|
|
haveFirstLetterStyle,
|
|
|
|
haveFirstLineStyle);
|
1999-12-04 23:49:50 +00:00
|
|
|
ProcessChildren(aPresShell, aPresContext, aState, aContent, newFrame, PR_TRUE,
|
1999-08-27 21:46:10 +00:00
|
|
|
childItems, PR_TRUE);
|
1999-02-05 03:55:18 +00:00
|
|
|
|
2000-05-09 21:42:40 +00:00
|
|
|
nsCOMPtr<nsIAtom> tag;
|
|
|
|
aContent->GetTag(*getter_AddRefs(tag));
|
|
|
|
CreateAnonymousFrames(aPresShell, aPresContext, tag, aState, aContent, newFrame,
|
|
|
|
childItems);
|
|
|
|
|
1999-02-26 17:11:54 +00:00
|
|
|
// Set the frame's initial child list(s)
|
1999-11-24 06:03:41 +00:00
|
|
|
newFrame->SetInitialChildList(aPresContext, nsnull, childItems.childList);
|
1999-04-28 19:08:14 +00:00
|
|
|
if (aState.mAbsoluteItems.childList) {
|
1999-11-24 06:03:41 +00:00
|
|
|
newFrame->SetInitialChildList(aPresContext, nsLayoutAtoms::absoluteList,
|
1999-04-28 19:08:14 +00:00
|
|
|
aState.mAbsoluteItems.childList);
|
1999-02-05 03:55:18 +00:00
|
|
|
}
|
1999-04-28 19:08:14 +00:00
|
|
|
if (aState.mFloatedItems.childList) {
|
1999-11-24 06:03:41 +00:00
|
|
|
newFrame->SetInitialChildList(aPresContext,
|
1999-02-26 17:11:54 +00:00
|
|
|
nsLayoutAtoms::floaterList,
|
1999-04-28 19:08:14 +00:00
|
|
|
aState.mFloatedItems.childList);
|
1999-02-26 17:11:54 +00:00
|
|
|
}
|
|
|
|
}
|
1999-02-05 03:55:18 +00:00
|
|
|
// See if the frame is floated, and it's a block or inline frame
|
1999-02-26 17:11:54 +00:00
|
|
|
else if (isFloating &&
|
|
|
|
((NS_STYLE_DISPLAY_BLOCK == aDisplay->mDisplay) ||
|
|
|
|
(NS_STYLE_DISPLAY_INLINE == aDisplay->mDisplay) ||
|
|
|
|
(NS_STYLE_DISPLAY_LIST_ITEM == aDisplay->mDisplay))) {
|
2000-04-04 01:28:15 +00:00
|
|
|
if (!aState.mPseudoFrames.IsEmpty()) { // process pending pseudo frames
|
|
|
|
ProcessPseudoFrames(aPresContext, aState.mPseudoFrames, aFrameItems);
|
|
|
|
}
|
1999-02-05 03:55:18 +00:00
|
|
|
// Create an area frame
|
1999-12-04 23:49:50 +00:00
|
|
|
NS_NewFloatingItemWrapperFrame(aPresShell, &newFrame);
|
1999-02-05 03:55:18 +00:00
|
|
|
|
|
|
|
// Initialize the frame
|
1999-12-06 07:44:18 +00:00
|
|
|
InitAndRestoreFrame(aPresContext, aState, aContent,
|
|
|
|
aState.mFloatedItems.containingBlock,
|
|
|
|
aStyleContext, nsnull, newFrame);
|
1999-02-05 03:55:18 +00:00
|
|
|
|
|
|
|
// See if we need to create a view
|
1999-11-24 06:03:41 +00:00
|
|
|
nsHTMLContainerFrame::CreateViewForFrame(aPresContext, newFrame,
|
1999-02-05 03:55:18 +00:00
|
|
|
aStyleContext, PR_FALSE);
|
|
|
|
|
|
|
|
// Process the child content
|
1999-04-28 19:08:14 +00:00
|
|
|
nsFrameConstructorSaveState floaterSaveState;
|
|
|
|
nsFrameItems childItems;
|
|
|
|
|
1999-08-31 03:09:40 +00:00
|
|
|
PRBool haveFirstLetterStyle = PR_FALSE, haveFirstLineStyle = PR_FALSE;
|
|
|
|
if (aDisplay->IsBlockLevel()) {
|
|
|
|
HaveSpecialBlockStyle(aPresContext, aContent, aStyleContext,
|
|
|
|
&haveFirstLetterStyle, &haveFirstLineStyle);
|
|
|
|
}
|
|
|
|
aState.PushFloaterContainingBlock(newFrame, floaterSaveState,
|
|
|
|
haveFirstLetterStyle,
|
|
|
|
haveFirstLineStyle);
|
1999-12-04 23:49:50 +00:00
|
|
|
ProcessChildren(aPresShell, aPresContext, aState, aContent, newFrame,
|
1999-08-27 21:46:10 +00:00
|
|
|
PR_TRUE, childItems, PR_TRUE);
|
1999-02-05 03:55:18 +00:00
|
|
|
|
2000-05-09 21:42:40 +00:00
|
|
|
nsCOMPtr<nsIAtom> tag;
|
|
|
|
aContent->GetTag(*getter_AddRefs(tag));
|
|
|
|
CreateAnonymousFrames(aPresShell, aPresContext, tag, aState, aContent, newFrame,
|
|
|
|
childItems);
|
|
|
|
|
1999-02-26 17:11:54 +00:00
|
|
|
// Set the frame's initial child list(s)
|
1999-11-24 06:03:41 +00:00
|
|
|
newFrame->SetInitialChildList(aPresContext, nsnull, childItems.childList);
|
1999-04-28 19:08:14 +00:00
|
|
|
if (aState.mFloatedItems.childList) {
|
1999-11-24 06:03:41 +00:00
|
|
|
newFrame->SetInitialChildList(aPresContext,
|
1999-02-26 17:11:54 +00:00
|
|
|
nsLayoutAtoms::floaterList,
|
1999-04-28 19:08:14 +00:00
|
|
|
aState.mFloatedItems.childList);
|
1999-02-26 17:11:54 +00:00
|
|
|
}
|
|
|
|
}
|
1999-04-19 19:10:15 +00:00
|
|
|
// See if it's relatively positioned
|
1999-07-20 04:16:56 +00:00
|
|
|
else if ((NS_STYLE_POSITION_RELATIVE == position->mPosition) &&
|
|
|
|
((NS_STYLE_DISPLAY_BLOCK == aDisplay->mDisplay) ||
|
|
|
|
(NS_STYLE_DISPLAY_INLINE == aDisplay->mDisplay) ||
|
|
|
|
(NS_STYLE_DISPLAY_LIST_ITEM == aDisplay->mDisplay))) {
|
2000-04-04 01:28:15 +00:00
|
|
|
if (!aState.mPseudoFrames.IsEmpty()) { // process pending pseudo frames
|
|
|
|
ProcessPseudoFrames(aPresContext, aState.mPseudoFrames, aFrameItems);
|
|
|
|
}
|
1999-04-19 19:10:15 +00:00
|
|
|
// Is it block-level or inline-level?
|
1999-08-27 21:46:10 +00:00
|
|
|
PRBool isBlockFrame = PR_FALSE;
|
1999-07-24 23:08:34 +00:00
|
|
|
if ((NS_STYLE_DISPLAY_BLOCK == aDisplay->mDisplay) ||
|
1999-07-20 04:16:56 +00:00
|
|
|
(NS_STYLE_DISPLAY_LIST_ITEM == aDisplay->mDisplay)) {
|
1999-05-11 22:03:29 +00:00
|
|
|
// Create a wrapper frame. No space manager, though
|
1999-12-04 23:49:50 +00:00
|
|
|
NS_NewRelativeItemWrapperFrame(aPresShell, &newFrame);
|
1999-08-27 21:46:10 +00:00
|
|
|
isBlockFrame = PR_TRUE;
|
1999-02-05 03:55:18 +00:00
|
|
|
|
2000-06-07 06:58:45 +00:00
|
|
|
// Initialize the frame
|
|
|
|
InitAndRestoreFrame(aPresContext, aState, aContent,
|
|
|
|
aParentFrame, aStyleContext, nsnull, newFrame);
|
1999-02-05 03:55:18 +00:00
|
|
|
|
2000-06-07 06:58:45 +00:00
|
|
|
// Create a view
|
|
|
|
nsHTMLContainerFrame::CreateViewForFrame(aPresContext, newFrame,
|
|
|
|
aStyleContext, PR_FALSE);
|
1999-04-28 19:08:14 +00:00
|
|
|
|
2000-06-07 06:58:45 +00:00
|
|
|
// Process the child content. Relatively positioned frames becomes a
|
|
|
|
// container for child frames that are positioned
|
|
|
|
nsFrameConstructorSaveState absoluteSaveState;
|
|
|
|
nsFrameConstructorSaveState floaterSaveState;
|
|
|
|
nsFrameItems childItems;
|
|
|
|
|
|
|
|
aState.PushAbsoluteContainingBlock(newFrame, absoluteSaveState);
|
1999-04-19 19:10:15 +00:00
|
|
|
|
1999-08-31 03:09:40 +00:00
|
|
|
PRBool haveFirstLetterStyle, haveFirstLineStyle;
|
|
|
|
HaveSpecialBlockStyle(aPresContext, aContent, aStyleContext,
|
|
|
|
&haveFirstLetterStyle, &haveFirstLineStyle);
|
|
|
|
aState.PushFloaterContainingBlock(newFrame, floaterSaveState,
|
|
|
|
haveFirstLetterStyle,
|
|
|
|
haveFirstLineStyle);
|
1999-02-05 03:55:18 +00:00
|
|
|
|
2000-06-07 06:58:45 +00:00
|
|
|
ProcessChildren(aPresShell, aPresContext, aState, aContent, newFrame, PR_TRUE,
|
|
|
|
childItems, isBlockFrame);
|
2000-05-09 21:42:40 +00:00
|
|
|
|
2000-06-07 06:58:45 +00:00
|
|
|
nsCOMPtr<nsIAtom> tag;
|
|
|
|
aContent->GetTag(*getter_AddRefs(tag));
|
|
|
|
CreateAnonymousFrames(aPresShell, aPresContext, tag, aState, aContent, newFrame,
|
|
|
|
childItems);
|
|
|
|
|
|
|
|
// Set the frame's initial child list
|
|
|
|
newFrame->SetInitialChildList(aPresContext, nsnull, childItems.childList);
|
|
|
|
if (aState.mAbsoluteItems.childList) {
|
|
|
|
newFrame->SetInitialChildList(aPresContext, nsLayoutAtoms::absoluteList,
|
|
|
|
aState.mAbsoluteItems.childList);
|
|
|
|
}
|
|
|
|
if (aState.mFloatedItems.childList) {
|
|
|
|
newFrame->SetInitialChildList(aPresContext,
|
|
|
|
nsLayoutAtoms::floaterList,
|
|
|
|
aState.mFloatedItems.childList);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
// Create a positioned inline frame
|
|
|
|
NS_NewPositionedInlineFrame(aPresShell, &newFrame);
|
|
|
|
ConstructInline(aPresShell, aPresContext, aState, aDisplay, aContent,
|
|
|
|
aParentFrame, aStyleContext, PR_TRUE, newFrame,
|
|
|
|
&newBlock, &nextInline);
|
1999-02-26 17:11:54 +00:00
|
|
|
}
|
|
|
|
}
|
1999-08-27 21:46:10 +00:00
|
|
|
// See if it's a block frame of some sort
|
|
|
|
else if ((NS_STYLE_DISPLAY_BLOCK == aDisplay->mDisplay) ||
|
|
|
|
(NS_STYLE_DISPLAY_LIST_ITEM == aDisplay->mDisplay) ||
|
|
|
|
(NS_STYLE_DISPLAY_RUN_IN == aDisplay->mDisplay) ||
|
|
|
|
(NS_STYLE_DISPLAY_COMPACT == aDisplay->mDisplay) ||
|
|
|
|
(NS_STYLE_DISPLAY_INLINE_BLOCK == aDisplay->mDisplay)) {
|
2000-04-04 01:28:15 +00:00
|
|
|
if (!aState.mPseudoFrames.IsEmpty()) { // process pending pseudo frames
|
|
|
|
ProcessPseudoFrames(aPresContext, aState.mPseudoFrames, aFrameItems);
|
|
|
|
}
|
1999-08-27 21:46:10 +00:00
|
|
|
// Create the block frame
|
1999-12-04 23:49:50 +00:00
|
|
|
rv = NS_NewBlockFrame(aPresShell, &newFrame);
|
1999-08-27 21:46:10 +00:00
|
|
|
if (NS_SUCCEEDED(rv)) {
|
|
|
|
// That worked so construct the block and its children
|
1999-12-04 23:49:50 +00:00
|
|
|
rv = ConstructBlock(aPresShell, aPresContext, aState, aDisplay, aContent,
|
1999-08-27 21:46:10 +00:00
|
|
|
aParentFrame, aStyleContext, newFrame);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// See if it's an inline frame of some sort
|
|
|
|
else if ((NS_STYLE_DISPLAY_INLINE == aDisplay->mDisplay) ||
|
|
|
|
(NS_STYLE_DISPLAY_MARKER == aDisplay->mDisplay)) {
|
2000-04-04 01:28:15 +00:00
|
|
|
if (!aState.mPseudoFrames.IsEmpty()) { // process pending pseudo frames
|
|
|
|
ProcessPseudoFrames(aPresContext, aState.mPseudoFrames, aFrameItems);
|
|
|
|
}
|
1999-08-27 21:46:10 +00:00
|
|
|
// Create the inline frame
|
1999-12-04 23:49:50 +00:00
|
|
|
rv = NS_NewInlineFrame(aPresShell, &newFrame);
|
1999-08-27 21:46:10 +00:00
|
|
|
if (NS_SUCCEEDED(rv)) {
|
|
|
|
// That worked so construct the inline and its children
|
1999-12-04 23:49:50 +00:00
|
|
|
rv = ConstructInline(aPresShell, aPresContext, aState, aDisplay, aContent,
|
2000-06-07 06:58:45 +00:00
|
|
|
aParentFrame, aStyleContext, PR_FALSE, newFrame,
|
1999-11-01 15:24:57 +00:00
|
|
|
&newBlock, &nextInline);
|
1999-08-27 21:46:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// To keep the hash table small don't add inline frames (they're
|
|
|
|
// typically things like FONT and B), because we can quickly
|
|
|
|
// find them if we need to
|
|
|
|
addToHashTable = PR_FALSE;
|
|
|
|
}
|
1999-03-30 15:22:54 +00:00
|
|
|
// otherwise let the display property influence the frame type to create
|
1999-02-26 17:11:54 +00:00
|
|
|
else {
|
1999-08-27 21:46:10 +00:00
|
|
|
// XXX This section now only handles table frames; should be
|
|
|
|
// factored out probably
|
|
|
|
|
1999-03-30 15:22:54 +00:00
|
|
|
// Use the 'display' property to choose a frame type
|
1999-02-05 03:55:18 +00:00
|
|
|
switch (aDisplay->mDisplay) {
|
|
|
|
case NS_STYLE_DISPLAY_TABLE:
|
|
|
|
{
|
2000-04-04 01:28:15 +00:00
|
|
|
if (!aState.mPseudoFrames.IsEmpty()) { // process pending pseudo frames
|
|
|
|
ProcessPseudoFrames(aPresContext, aState.mPseudoFrames, aFrameItems);
|
|
|
|
}
|
1999-02-05 03:55:18 +00:00
|
|
|
nsIFrame* geometricParent = aParentFrame;
|
|
|
|
if (NS_STYLE_POSITION_ABSOLUTE == position->mPosition) {
|
|
|
|
isAbsolutelyPositioned = PR_TRUE;
|
1999-09-29 05:06:17 +00:00
|
|
|
geometricParent = aState.mAbsoluteItems.containingBlock;
|
2000-04-19 04:44:16 +00:00
|
|
|
} else if (NS_STYLE_POSITION_FIXED == position->mPosition) {
|
1999-02-05 03:55:18 +00:00
|
|
|
isFixedPositioned = PR_TRUE;
|
1999-09-29 05:06:17 +00:00
|
|
|
geometricParent = aState.mFixedItems.containingBlock;
|
2000-04-19 04:44:16 +00:00
|
|
|
} else if (isFloating) {
|
|
|
|
geometricParent = aState.mFloatedItems.containingBlock;
|
1999-02-05 03:55:18 +00:00
|
|
|
}
|
2000-04-04 01:28:15 +00:00
|
|
|
nsIFrame* innerTable;
|
|
|
|
rv = ConstructTableFrame(aPresShell, aPresContext, aState, aContent,
|
|
|
|
geometricParent, aStyleContext, tableCreator,
|
|
|
|
PR_FALSE, aFrameItems, newFrame, innerTable, pseudoParent);
|
1999-03-17 18:17:24 +00:00
|
|
|
// Note: table construction function takes care of initializing
|
|
|
|
// the frame, processing children, and setting the initial child
|
|
|
|
// list
|
|
|
|
goto nearly_done;
|
1999-02-05 03:55:18 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// the next 5 cases are only relevant if the parent is not a table, ConstructTableFrame handles children
|
|
|
|
case NS_STYLE_DISPLAY_TABLE_CAPTION:
|
|
|
|
{
|
2000-03-02 06:09:37 +00:00
|
|
|
// aParentFrame may be an inner table frame rather than an outer frame
|
|
|
|
// In this case we need to get the outer frame.
|
|
|
|
nsIFrame* parentFrame = aParentFrame;
|
|
|
|
nsIFrame* outerFrame = nsnull;
|
|
|
|
aParentFrame->GetParent(&outerFrame);
|
|
|
|
nsCOMPtr<nsIAtom> frameType;
|
|
|
|
if (outerFrame) {
|
|
|
|
outerFrame->GetFrameType(getter_AddRefs(frameType));
|
|
|
|
if (nsLayoutAtoms::tableOuterFrame == frameType.get()) {
|
|
|
|
parentFrame = outerFrame;
|
|
|
|
}
|
|
|
|
}
|
2000-04-04 01:28:15 +00:00
|
|
|
rv = ConstructTableCaptionFrame(aPresShell, aPresContext, aState, aContent,
|
|
|
|
parentFrame, aStyleContext, tableCreator,
|
|
|
|
aFrameItems, newFrame, pseudoParent);
|
|
|
|
if (!pseudoParent) {
|
|
|
|
aFrameItems.AddChild(newFrame);
|
|
|
|
}
|
1999-02-05 03:55:18 +00:00
|
|
|
return rv;
|
|
|
|
}
|
2000-04-04 01:28:15 +00:00
|
|
|
|
1999-02-05 03:55:18 +00:00
|
|
|
case NS_STYLE_DISPLAY_TABLE_ROW_GROUP:
|
|
|
|
case NS_STYLE_DISPLAY_TABLE_HEADER_GROUP:
|
|
|
|
case NS_STYLE_DISPLAY_TABLE_FOOTER_GROUP:
|
2000-04-04 01:28:15 +00:00
|
|
|
rv = ConstructTableRowGroupFrame(aPresShell, aPresContext, aState, aContent,
|
|
|
|
aParentFrame, aStyleContext, tableCreator,
|
|
|
|
PR_FALSE, aFrameItems, newFrame, pseudoParent);
|
|
|
|
if (!pseudoParent) {
|
|
|
|
aFrameItems.AddChild(newFrame);
|
|
|
|
}
|
|
|
|
return rv;
|
|
|
|
|
1999-02-05 03:55:18 +00:00
|
|
|
case NS_STYLE_DISPLAY_TABLE_COLUMN_GROUP:
|
2000-04-04 01:28:15 +00:00
|
|
|
rv = ConstructTableColGroupFrame(aPresShell, aPresContext, aState, aContent,
|
|
|
|
aParentFrame, aStyleContext, tableCreator,
|
|
|
|
PR_FALSE, aFrameItems, newFrame, pseudoParent);
|
|
|
|
if (!pseudoParent) {
|
|
|
|
aFrameItems.AddChild(newFrame);
|
|
|
|
}
|
1999-02-05 03:55:18 +00:00
|
|
|
return rv;
|
|
|
|
|
|
|
|
case NS_STYLE_DISPLAY_TABLE_COLUMN:
|
2000-04-04 01:28:15 +00:00
|
|
|
rv = ConstructTableColFrame(aPresShell, aPresContext, aState, aContent,
|
|
|
|
aParentFrame, aStyleContext, tableCreator,
|
|
|
|
PR_FALSE, aFrameItems, newFrame, pseudoParent);
|
|
|
|
if (!pseudoParent) {
|
|
|
|
aFrameItems.AddChild(newFrame);
|
|
|
|
}
|
1999-02-05 03:55:18 +00:00
|
|
|
return rv;
|
|
|
|
|
|
|
|
case NS_STYLE_DISPLAY_TABLE_ROW:
|
2000-04-04 01:28:15 +00:00
|
|
|
rv = ConstructTableRowFrame(aPresShell, aPresContext, aState, aContent,
|
|
|
|
aParentFrame, aStyleContext, tableCreator,
|
|
|
|
PR_FALSE, aFrameItems, newFrame, pseudoParent);
|
|
|
|
if (!pseudoParent) {
|
|
|
|
aFrameItems.AddChild(newFrame);
|
|
|
|
}
|
1999-02-05 03:55:18 +00:00
|
|
|
return rv;
|
|
|
|
|
|
|
|
case NS_STYLE_DISPLAY_TABLE_CELL:
|
1999-02-26 09:15:03 +00:00
|
|
|
{
|
2000-04-04 01:28:15 +00:00
|
|
|
nsIFrame* innerTable;
|
|
|
|
rv = ConstructTableCellFrame(aPresShell, aPresContext, aState, aContent,
|
|
|
|
aParentFrame, aStyleContext, tableCreator,
|
|
|
|
PR_FALSE, aFrameItems, newFrame, innerTable, pseudoParent);
|
|
|
|
if (!pseudoParent) {
|
1999-02-26 09:15:03 +00:00
|
|
|
aFrameItems.AddChild(newFrame);
|
2000-04-04 01:28:15 +00:00
|
|
|
}
|
1999-02-26 09:15:03 +00:00
|
|
|
return rv;
|
|
|
|
}
|
1999-02-05 03:55:18 +00:00
|
|
|
|
|
|
|
default:
|
|
|
|
// Don't create any frame for content that's not displayed...
|
2000-04-04 01:28:15 +00:00
|
|
|
if (!aState.mPseudoFrames.IsEmpty()) { // process pending pseudo frames
|
|
|
|
ProcessPseudoFrames(aPresContext, aState.mPseudoFrames, aFrameItems);
|
|
|
|
}
|
1999-02-05 03:55:18 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1999-02-17 17:02:27 +00:00
|
|
|
// If the frame is absolutely positioned, then create a placeholder frame
|
1999-03-17 18:17:24 +00:00
|
|
|
nearly_done:
|
1999-02-05 03:55:18 +00:00
|
|
|
if (isAbsolutelyPositioned || isFixedPositioned) {
|
|
|
|
nsIFrame* placeholderFrame;
|
|
|
|
|
1999-12-04 23:49:50 +00:00
|
|
|
CreatePlaceholderFrameFor(aPresShell, aPresContext, aState.mFrameManager, aContent,
|
1999-08-05 03:09:22 +00:00
|
|
|
newFrame, aStyleContext, aParentFrame, &placeholderFrame);
|
1999-02-05 03:55:18 +00:00
|
|
|
|
|
|
|
// Add the positioned frame to its containing block's list of child frames
|
|
|
|
if (isAbsolutelyPositioned) {
|
1999-04-28 19:08:14 +00:00
|
|
|
aState.mAbsoluteItems.AddChild(newFrame);
|
1999-02-05 03:55:18 +00:00
|
|
|
} else {
|
1999-04-28 19:08:14 +00:00
|
|
|
aState.mFixedItems.AddChild(newFrame);
|
1999-02-05 03:55:18 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Add the placeholder frame to the flow
|
|
|
|
aFrameItems.AddChild(placeholderFrame);
|
|
|
|
|
1999-02-26 17:11:54 +00:00
|
|
|
} else if (isFloating) {
|
|
|
|
nsIFrame* placeholderFrame;
|
1999-12-04 23:49:50 +00:00
|
|
|
CreatePlaceholderFrameFor(aPresShell, aPresContext, aState.mFrameManager, aContent, newFrame,
|
1999-04-25 16:58:42 +00:00
|
|
|
aStyleContext, aParentFrame, &placeholderFrame);
|
1999-02-26 17:11:54 +00:00
|
|
|
|
|
|
|
// Add the floating frame to its containing block's list of child frames
|
1999-04-28 19:08:14 +00:00
|
|
|
aState.mFloatedItems.AddChild(newFrame);
|
1999-02-26 17:11:54 +00:00
|
|
|
|
|
|
|
// Add the placeholder frame to the flow
|
|
|
|
aFrameItems.AddChild(placeholderFrame);
|
2000-04-04 01:28:15 +00:00
|
|
|
} else if ((nsnull != newFrame) && !pseudoParent) {
|
1999-02-05 03:55:18 +00:00
|
|
|
// Add the frame we just created to the flowed list
|
|
|
|
aFrameItems.AddChild(newFrame);
|
1999-11-01 15:24:57 +00:00
|
|
|
if (newBlock) {
|
|
|
|
aFrameItems.AddChild(newBlock);
|
|
|
|
if (nextInline) {
|
|
|
|
aFrameItems.AddChild(nextInline);
|
|
|
|
}
|
|
|
|
}
|
1999-02-05 03:55:18 +00:00
|
|
|
}
|
|
|
|
|
1999-07-06 03:52:33 +00:00
|
|
|
if (newFrame && addToHashTable) {
|
1999-07-01 14:34:35 +00:00
|
|
|
// Add a mapping from content object to primary frame. Note that for
|
|
|
|
// floated and positioned frames this is the out-of-flow frame and not
|
|
|
|
// the placeholder frame
|
1999-10-12 00:16:06 +00:00
|
|
|
if (!primaryFrameSet)
|
|
|
|
aState.mFrameManager->SetPrimaryFrameFor(aContent, newFrame);
|
1999-07-01 14:34:35 +00:00
|
|
|
}
|
|
|
|
|
1999-02-05 03:55:18 +00:00
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
2000-01-22 01:16:50 +00:00
|
|
|
nsCSSFrameConstructor::GetAdjustedParentFrame(nsIPresContext* aPresContext,
|
|
|
|
nsIFrame* aCurrentParentFrame,
|
|
|
|
PRUint8 aChildDisplayType,
|
|
|
|
nsIFrame*& aNewParentFrame)
|
1999-02-05 03:55:18 +00:00
|
|
|
{
|
|
|
|
NS_PRECONDITION(nsnull!=aCurrentParentFrame, "bad arg aCurrentParentFrame");
|
|
|
|
|
|
|
|
nsresult rv = NS_OK;
|
|
|
|
// by default, the new parent frame is the given current parent frame
|
|
|
|
aNewParentFrame = aCurrentParentFrame;
|
|
|
|
if (nsnull != aCurrentParentFrame) {
|
|
|
|
const nsStyleDisplay* currentParentDisplay;
|
|
|
|
aCurrentParentFrame->GetStyleData(eStyleStruct_Display, (const nsStyleStruct *&)currentParentDisplay);
|
|
|
|
if (NS_STYLE_DISPLAY_TABLE == currentParentDisplay->mDisplay) {
|
|
|
|
if (NS_STYLE_DISPLAY_TABLE_CAPTION != aChildDisplayType) {
|
|
|
|
nsIFrame *innerTableFrame = nsnull;
|
2000-01-22 01:16:50 +00:00
|
|
|
aCurrentParentFrame->FirstChild(aPresContext, nsnull, &innerTableFrame);
|
1999-02-05 03:55:18 +00:00
|
|
|
if (nsnull != innerTableFrame) {
|
|
|
|
const nsStyleDisplay* innerTableDisplay;
|
|
|
|
innerTableFrame->GetStyleData(eStyleStruct_Display, (const nsStyleStruct *&)innerTableDisplay);
|
|
|
|
if (NS_STYLE_DISPLAY_TABLE == innerTableDisplay->mDisplay) {
|
|
|
|
// we were given the outer table frame, use the inner table frame
|
|
|
|
aNewParentFrame=innerTableFrame;
|
|
|
|
} // else we were already given the inner table frame
|
|
|
|
} // else the current parent has no children and cannot be an outer table frame
|
1999-03-23 14:16:52 +00:00
|
|
|
} else { // else the child is a caption and really belongs to the outer table frame
|
|
|
|
nsIFrame* parFrame = nsnull;
|
|
|
|
aCurrentParentFrame->GetParent(&parFrame);
|
|
|
|
const nsStyleDisplay* parDisplay;
|
|
|
|
aCurrentParentFrame->GetStyleData(eStyleStruct_Display, (const nsStyleStruct *&)parDisplay);
|
|
|
|
if (NS_STYLE_DISPLAY_TABLE == parDisplay->mDisplay) {
|
|
|
|
aNewParentFrame = parFrame; // aNewParentFrame was an inner frame
|
|
|
|
}
|
|
|
|
}
|
1999-02-05 03:55:18 +00:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
rv = NS_ERROR_NULL_POINTER;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_POSTCONDITION(nsnull!=aNewParentFrame, "bad result null aNewParentFrame");
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
PRBool
|
|
|
|
nsCSSFrameConstructor::IsScrollable(nsIPresContext* aPresContext,
|
|
|
|
const nsStyleDisplay* aDisplay)
|
|
|
|
{
|
|
|
|
// For the time being it's scrollable if the overflow property is auto or
|
|
|
|
// scroll, regardless of whether the width or height is fixed in size
|
2000-01-10 03:23:44 +00:00
|
|
|
switch (aDisplay->mOverflow) {
|
|
|
|
case NS_STYLE_OVERFLOW_SCROLL:
|
|
|
|
case NS_STYLE_OVERFLOW_AUTO:
|
|
|
|
case NS_STYLE_OVERFLOW_SCROLLBARS_NONE:
|
|
|
|
case NS_STYLE_OVERFLOW_SCROLLBARS_HORIZONTAL:
|
|
|
|
case NS_STYLE_OVERFLOW_SCROLLBARS_VERTICAL:
|
|
|
|
return PR_TRUE;
|
1999-02-05 03:55:18 +00:00
|
|
|
}
|
|
|
|
return PR_FALSE;
|
|
|
|
}
|
|
|
|
|
1999-02-11 23:08:28 +00:00
|
|
|
|
1999-12-06 07:44:18 +00:00
|
|
|
nsresult
|
|
|
|
nsCSSFrameConstructor::InitAndRestoreFrame(nsIPresContext* aPresContext,
|
|
|
|
nsFrameConstructorState& aState,
|
|
|
|
nsIContent* aContent,
|
|
|
|
nsIFrame* aParentFrame,
|
|
|
|
nsIStyleContext* aStyleContext,
|
|
|
|
nsIFrame* aPrevInFlow,
|
|
|
|
nsIFrame* aNewFrame)
|
|
|
|
{
|
|
|
|
nsresult rv = NS_OK;
|
|
|
|
|
|
|
|
NS_ASSERTION(aNewFrame, "Null frame cannot be initialized");
|
|
|
|
|
|
|
|
// Initialize the frame
|
|
|
|
rv = aNewFrame->Init(aPresContext, aContent, aParentFrame,
|
|
|
|
aStyleContext, aPrevInFlow);
|
|
|
|
|
|
|
|
if (aState.mFrameState && aState.mFrameManager) {
|
1999-12-06 09:03:16 +00:00
|
|
|
aState.mFrameManager->RestoreFrameState(aPresContext, aNewFrame, aState.mFrameState);
|
1999-12-06 07:44:18 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
1999-02-11 23:08:28 +00:00
|
|
|
nsresult
|
|
|
|
nsCSSFrameConstructor::ResolveStyleContext(nsIPresContext* aPresContext,
|
|
|
|
nsIFrame* aParentFrame,
|
|
|
|
nsIContent* aContent,
|
|
|
|
nsIAtom* aTag,
|
|
|
|
nsIStyleContext** aStyleContext)
|
|
|
|
{
|
|
|
|
nsresult rv = NS_OK;
|
|
|
|
// Resolve the style context based on the content object and the parent
|
|
|
|
// style context
|
|
|
|
nsCOMPtr<nsIStyleContext> parentStyleContext;
|
|
|
|
|
|
|
|
aParentFrame->GetStyleContext(getter_AddRefs(parentStyleContext));
|
|
|
|
if (nsLayoutAtoms::textTagName == aTag) {
|
|
|
|
// Use a special pseudo element style context for text
|
|
|
|
nsCOMPtr<nsIContent> parentContent;
|
|
|
|
if (nsnull != aParentFrame) {
|
|
|
|
aParentFrame->GetContent(getter_AddRefs(parentContent));
|
|
|
|
}
|
|
|
|
rv = aPresContext->ResolvePseudoStyleContextFor(parentContent,
|
|
|
|
nsHTMLAtoms::textPseudo,
|
|
|
|
parentStyleContext,
|
1999-02-12 17:45:58 +00:00
|
|
|
PR_FALSE,
|
1999-02-11 23:08:28 +00:00
|
|
|
aStyleContext);
|
|
|
|
} else if (nsLayoutAtoms::commentTagName == aTag) {
|
|
|
|
// Use a special pseudo element style context for comments
|
|
|
|
nsCOMPtr<nsIContent> parentContent;
|
|
|
|
if (nsnull != aParentFrame) {
|
|
|
|
aParentFrame->GetContent(getter_AddRefs(parentContent));
|
|
|
|
}
|
|
|
|
rv = aPresContext->ResolvePseudoStyleContextFor(parentContent,
|
|
|
|
nsHTMLAtoms::commentPseudo,
|
|
|
|
parentStyleContext,
|
1999-02-12 17:45:58 +00:00
|
|
|
PR_FALSE,
|
1999-02-11 23:08:28 +00:00
|
|
|
aStyleContext);
|
1999-03-31 20:49:25 +00:00
|
|
|
} else if (nsLayoutAtoms::processingInstructionTagName == aTag) {
|
|
|
|
// Use a special pseudo element style context for comments
|
|
|
|
nsCOMPtr<nsIContent> parentContent;
|
|
|
|
if (nsnull != aParentFrame) {
|
|
|
|
aParentFrame->GetContent(getter_AddRefs(parentContent));
|
|
|
|
}
|
|
|
|
rv = aPresContext->ResolvePseudoStyleContextFor(parentContent,
|
|
|
|
nsHTMLAtoms::processingInstructionPseudo,
|
|
|
|
parentStyleContext,
|
|
|
|
PR_FALSE,
|
|
|
|
aStyleContext);
|
1999-02-11 23:08:28 +00:00
|
|
|
} else {
|
|
|
|
rv = aPresContext->ResolveStyleContextFor(aContent, parentStyleContext,
|
1999-02-12 17:45:58 +00:00
|
|
|
PR_FALSE,
|
1999-02-11 23:08:28 +00:00
|
|
|
aStyleContext);
|
|
|
|
}
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
1999-09-21 01:15:30 +00:00
|
|
|
// MathML Mod - RBS
|
1999-10-02 10:41:40 +00:00
|
|
|
#ifdef MOZ_MATHML
|
1999-09-21 01:15:30 +00:00
|
|
|
nsresult
|
1999-12-10 13:07:59 +00:00
|
|
|
nsCSSFrameConstructor::ConstructMathMLFrame(nsIPresShell* aPresShell,
|
|
|
|
nsIPresContext* aPresContext,
|
1999-09-21 01:15:30 +00:00
|
|
|
nsFrameConstructorState& aState,
|
|
|
|
nsIContent* aContent,
|
|
|
|
nsIFrame* aParentFrame,
|
|
|
|
nsIAtom* aTag,
|
2000-05-24 08:19:10 +00:00
|
|
|
PRInt32 aNameSpaceID,
|
1999-09-21 01:15:30 +00:00
|
|
|
nsIStyleContext* aStyleContext,
|
|
|
|
nsFrameItems& aFrameItems)
|
|
|
|
{
|
|
|
|
PRBool processChildren = PR_TRUE; // Whether we should process child content.
|
|
|
|
// MathML frames are inline frames.
|
|
|
|
// processChildren = PR_TRUE for inline frames.
|
|
|
|
// see case NS_STYLE_DISPLAY_INLINE in
|
|
|
|
// ConstructFrameByDisplayType()
|
|
|
|
|
|
|
|
nsresult rv = NS_OK;
|
|
|
|
PRBool isAbsolutelyPositioned = PR_FALSE;
|
|
|
|
PRBool isFixedPositioned = PR_FALSE;
|
|
|
|
PRBool isReplaced = PR_FALSE;
|
|
|
|
|
|
|
|
NS_ASSERTION(aTag != nsnull, "null MathML tag");
|
|
|
|
if (aTag == nsnull)
|
|
|
|
return NS_OK;
|
|
|
|
|
|
|
|
// Make sure that we remain confined in the MathML world
|
2000-05-24 08:19:10 +00:00
|
|
|
if (aNameSpaceID != nsMathMLAtoms::nameSpaceID)
|
1999-09-21 01:15:30 +00:00
|
|
|
return NS_OK;
|
1999-10-02 10:41:40 +00:00
|
|
|
|
1999-09-21 01:15:30 +00:00
|
|
|
// Initialize the new frame
|
|
|
|
nsIFrame* newFrame = nsnull;
|
1999-12-10 13:07:59 +00:00
|
|
|
nsMathMLmtableCreator mathTableCreator(aPresShell); // Used to make table views.
|
1999-09-21 01:15:30 +00:00
|
|
|
|
|
|
|
// See if the element is absolute or fixed positioned
|
|
|
|
const nsStylePosition* position = (const nsStylePosition*)
|
|
|
|
aStyleContext->GetStyleData(eStyleStruct_Position);
|
|
|
|
if (NS_STYLE_POSITION_ABSOLUTE == position->mPosition) {
|
|
|
|
isAbsolutelyPositioned = PR_TRUE;
|
|
|
|
}
|
|
|
|
else if (NS_STYLE_POSITION_FIXED == position->mPosition) {
|
|
|
|
isFixedPositioned = PR_TRUE;
|
|
|
|
}
|
|
|
|
|
2000-01-07 15:25:15 +00:00
|
|
|
if (aTag == nsMathMLAtoms::mi_)
|
1999-12-10 13:07:59 +00:00
|
|
|
rv = NS_NewMathMLmiFrame(aPresShell, &newFrame);
|
2000-03-28 09:32:54 +00:00
|
|
|
else if (aTag == nsMathMLAtoms::mtext_ ||
|
|
|
|
aTag == nsMathMLAtoms::mn_)
|
|
|
|
rv = NS_NewMathMLmtextFrame(aPresShell, &newFrame);
|
1999-12-10 13:07:59 +00:00
|
|
|
else if (aTag == nsMathMLAtoms::mo_)
|
|
|
|
rv = NS_NewMathMLmoFrame(aPresShell, &newFrame);
|
|
|
|
else if (aTag == nsMathMLAtoms::mfrac_)
|
|
|
|
rv = NS_NewMathMLmfracFrame(aPresShell, &newFrame);
|
|
|
|
else if (aTag == nsMathMLAtoms::msup_)
|
|
|
|
rv = NS_NewMathMLmsupFrame(aPresShell, &newFrame);
|
|
|
|
else if (aTag == nsMathMLAtoms::msub_)
|
|
|
|
rv = NS_NewMathMLmsubFrame(aPresShell, &newFrame);
|
|
|
|
else if (aTag == nsMathMLAtoms::msubsup_)
|
|
|
|
rv = NS_NewMathMLmsubsupFrame(aPresShell, &newFrame);
|
|
|
|
else if (aTag == nsMathMLAtoms::munder_)
|
|
|
|
rv = NS_NewMathMLmunderFrame(aPresShell, &newFrame);
|
|
|
|
else if (aTag == nsMathMLAtoms::mover_)
|
|
|
|
rv = NS_NewMathMLmoverFrame(aPresShell, &newFrame);
|
|
|
|
else if (aTag == nsMathMLAtoms::munderover_)
|
|
|
|
rv = NS_NewMathMLmunderoverFrame(aPresShell, &newFrame);
|
|
|
|
else if (aTag == nsMathMLAtoms::mphantom_)
|
|
|
|
rv = NS_NewMathMLmphantomFrame(aPresShell, &newFrame);
|
|
|
|
else if (aTag == nsMathMLAtoms::mpadded_)
|
|
|
|
rv = NS_NewMathMLmpaddedFrame(aPresShell, &newFrame);
|
2000-01-27 12:28:41 +00:00
|
|
|
else if (aTag == nsMathMLAtoms::mspace_)
|
|
|
|
rv = NS_NewMathMLmspaceFrame(aPresShell, &newFrame);
|
2000-01-30 23:33:38 +00:00
|
|
|
else if (aTag == nsMathMLAtoms::ms_)
|
|
|
|
rv = NS_NewMathMLmsFrame(aPresShell, &newFrame);
|
1999-12-10 13:07:59 +00:00
|
|
|
else if (aTag == nsMathMLAtoms::mfenced_)
|
|
|
|
rv = NS_NewMathMLmfencedFrame(aPresShell, &newFrame);
|
|
|
|
else if (aTag == nsMathMLAtoms::mmultiscripts_)
|
|
|
|
rv = NS_NewMathMLmmultiscriptsFrame(aPresShell, &newFrame);
|
|
|
|
else if (aTag == nsMathMLAtoms::mstyle_)
|
|
|
|
rv = NS_NewMathMLmstyleFrame(aPresShell, &newFrame);
|
|
|
|
else if (aTag == nsMathMLAtoms::msqrt_)
|
|
|
|
rv = NS_NewMathMLmsqrtFrame(aPresShell, &newFrame);
|
|
|
|
else if (aTag == nsMathMLAtoms::mroot_)
|
|
|
|
rv = NS_NewMathMLmrootFrame(aPresShell, &newFrame);
|
2000-02-07 08:55:51 +00:00
|
|
|
else if (aTag == nsMathMLAtoms::maction_)
|
|
|
|
rv = NS_NewMathMLmactionFrame(aPresShell, &newFrame);
|
1999-12-10 13:07:59 +00:00
|
|
|
else if (aTag == nsMathMLAtoms::mrow_ ||
|
|
|
|
aTag == nsMathMLAtoms::merror_ ||
|
|
|
|
aTag == nsMathMLAtoms::none_ ||
|
|
|
|
aTag == nsMathMLAtoms::mprescripts_ )
|
|
|
|
rv = NS_NewMathMLmrowFrame(aPresShell, &newFrame);
|
1999-09-21 01:15:30 +00:00
|
|
|
// CONSTRUCTION of MTABLE elements
|
1999-12-10 13:07:59 +00:00
|
|
|
else if (aTag == nsMathMLAtoms::mtable_) {
|
1999-09-21 01:15:30 +00:00
|
|
|
// <mtable> is an inline-table, for the moment, we just do what
|
|
|
|
// <table> does, and wait until nsLineLayout::TreatFrameAsBlock
|
|
|
|
// can handle NS_STYLE_DISPLAY_INLINE_TABLE.
|
|
|
|
nsIFrame* geometricParent = aParentFrame;
|
|
|
|
if (isAbsolutelyPositioned) {
|
|
|
|
aParentFrame = aState.mAbsoluteItems.containingBlock;
|
|
|
|
}
|
|
|
|
else if (isFixedPositioned) {
|
|
|
|
aParentFrame = aState.mFixedItems.containingBlock;
|
2000-04-04 01:28:15 +00:00
|
|
|
}
|
|
|
|
nsIFrame* innerTable;
|
|
|
|
PRBool pseudoParent;
|
|
|
|
rv = ConstructTableFrame(aPresShell, aPresContext, aState, aContent,
|
|
|
|
geometricParent, aStyleContext, mathTableCreator,
|
|
|
|
PR_FALSE, aFrameItems, newFrame, innerTable, pseudoParent);
|
1999-09-21 01:15:30 +00:00
|
|
|
// Note: table construction function takes care of initializing the frame,
|
|
|
|
// processing children, and setting the initial child list
|
|
|
|
if (isAbsolutelyPositioned || isFixedPositioned) {
|
|
|
|
nsIFrame* placeholderFrame;
|
1999-12-10 13:07:59 +00:00
|
|
|
CreatePlaceholderFrameFor(aPresShell, aPresContext, aState.mFrameManager, aContent, newFrame,
|
1999-09-21 01:15:30 +00:00
|
|
|
aStyleContext, aParentFrame, &placeholderFrame);
|
|
|
|
// Add the positioned frame to its containing block's list of child frames
|
|
|
|
if (isAbsolutelyPositioned) {
|
|
|
|
aState.mAbsoluteItems.AddChild(newFrame);
|
|
|
|
} else {
|
|
|
|
aState.mFixedItems.AddChild(newFrame);
|
|
|
|
}
|
|
|
|
// Add the placeholder frame to the flow
|
|
|
|
aFrameItems.AddChild(placeholderFrame);
|
2000-04-04 01:28:15 +00:00
|
|
|
} else if (!pseudoParent) {
|
1999-09-21 01:15:30 +00:00
|
|
|
// Add the table frame to the flow
|
|
|
|
aFrameItems.AddChild(newFrame);
|
|
|
|
}
|
|
|
|
return rv;
|
|
|
|
}
|
1999-12-10 13:07:59 +00:00
|
|
|
else if (aTag == nsMathMLAtoms::mtd_) {
|
2000-04-04 01:28:15 +00:00
|
|
|
nsIFrame* innerCell;
|
|
|
|
PRBool pseudoParent;
|
|
|
|
rv = ConstructTableCellFrame(aPresShell, aPresContext, aState, aContent,
|
|
|
|
aParentFrame, aStyleContext, mathTableCreator,
|
|
|
|
PR_FALSE, aFrameItems, newFrame, innerCell, pseudoParent);
|
|
|
|
if (!pseudoParent) {
|
|
|
|
aFrameItems.AddChild(newFrame);
|
|
|
|
}
|
1999-09-21 01:15:30 +00:00
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
// End CONSTRUCTION of MTABLE elements
|
|
|
|
|
|
|
|
else {
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
// If we succeeded in creating a frame then initialize it, process its
|
|
|
|
// children (if requested), and set the initial child list
|
|
|
|
if (NS_SUCCEEDED(rv) && newFrame != nsnull) {
|
|
|
|
// If the frame is a replaced element, then set the frame state bit
|
|
|
|
if (isReplaced) {
|
|
|
|
nsFrameState state;
|
|
|
|
newFrame->GetFrameState(&state);
|
|
|
|
newFrame->SetFrameState(state | NS_FRAME_REPLACED_ELEMENT);
|
|
|
|
}
|
|
|
|
|
|
|
|
nsIFrame* geometricParent = isAbsolutelyPositioned
|
|
|
|
? aState.mAbsoluteItems.containingBlock
|
|
|
|
: aParentFrame;
|
1999-12-06 07:44:18 +00:00
|
|
|
InitAndRestoreFrame(aPresContext, aState, aContent,
|
|
|
|
geometricParent, aStyleContext, nsnull, newFrame);
|
1999-09-21 01:15:30 +00:00
|
|
|
|
|
|
|
// See if we need to create a view, e.g. the frame is absolutely positioned
|
1999-11-24 06:03:41 +00:00
|
|
|
nsHTMLContainerFrame::CreateViewForFrame(aPresContext, newFrame,
|
1999-09-21 01:15:30 +00:00
|
|
|
aStyleContext, PR_FALSE);
|
|
|
|
|
|
|
|
// Add the new frame to our list of frame items.
|
|
|
|
aFrameItems.AddChild(newFrame);
|
|
|
|
|
|
|
|
// Process the child content if requested
|
|
|
|
nsFrameItems childItems;
|
|
|
|
if (processChildren) {
|
1999-12-04 23:49:50 +00:00
|
|
|
rv = ProcessChildren(aPresShell, aPresContext, aState, aContent, newFrame, PR_TRUE,
|
1999-09-21 01:15:30 +00:00
|
|
|
childItems, PR_FALSE);
|
2000-05-09 21:42:40 +00:00
|
|
|
|
|
|
|
CreateAnonymousFrames(aPresShell, aPresContext, aTag, aState, aContent, newFrame,
|
|
|
|
childItems);
|
1999-09-21 01:15:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Set the frame's initial child list
|
1999-11-24 06:03:41 +00:00
|
|
|
newFrame->SetInitialChildList(aPresContext, nsnull, childItems.childList);
|
1999-09-21 01:15:30 +00:00
|
|
|
|
|
|
|
// If the frame is absolutely positioned then create a placeholder frame
|
|
|
|
if (isAbsolutelyPositioned || isFixedPositioned) {
|
|
|
|
nsIFrame* placeholderFrame;
|
|
|
|
|
1999-12-10 13:07:59 +00:00
|
|
|
CreatePlaceholderFrameFor(aPresShell, aPresContext, aState.mFrameManager, aContent, newFrame,
|
1999-09-21 01:15:30 +00:00
|
|
|
aStyleContext, aParentFrame, &placeholderFrame);
|
|
|
|
|
|
|
|
// Add the positioned frame to its containing block's list of child frames
|
|
|
|
if (isAbsolutelyPositioned) {
|
|
|
|
aState.mAbsoluteItems.AddChild(newFrame);
|
|
|
|
} else {
|
|
|
|
aState.mFixedItems.AddChild(newFrame);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Add the placeholder frame to the flow
|
|
|
|
aFrameItems.AddChild(placeholderFrame);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return rv;
|
|
|
|
}
|
1999-10-02 10:41:40 +00:00
|
|
|
#endif // MOZ_MATHML
|
1999-09-21 01:15:30 +00:00
|
|
|
|
2000-04-01 22:26:38 +00:00
|
|
|
// SVG
|
|
|
|
#ifdef MOZ_SVG
|
|
|
|
nsresult
|
|
|
|
nsCSSFrameConstructor::ConstructSVGFrame(nsIPresShell* aPresShell,
|
|
|
|
nsIPresContext* aPresContext,
|
|
|
|
nsFrameConstructorState& aState,
|
|
|
|
nsIContent* aContent,
|
|
|
|
nsIFrame* aParentFrame,
|
|
|
|
nsIAtom* aTag,
|
2000-05-24 08:19:10 +00:00
|
|
|
PRInt32 aNameSpaceID,
|
2000-04-01 22:26:38 +00:00
|
|
|
nsIStyleContext* aStyleContext,
|
|
|
|
nsFrameItems& aFrameItems)
|
|
|
|
{
|
|
|
|
PRBool processChildren = PR_TRUE; // Whether we should process child content.
|
|
|
|
// MathML frames are inline frames.
|
|
|
|
// processChildren = PR_TRUE for inline frames.
|
|
|
|
// see case NS_STYLE_DISPLAY_INLINE in
|
|
|
|
// ConstructFrameByDisplayType()
|
|
|
|
|
|
|
|
nsresult rv = NS_OK;
|
|
|
|
PRBool isAbsolutelyPositioned = PR_FALSE;
|
|
|
|
PRBool isFixedPositioned = PR_FALSE;
|
|
|
|
PRBool isReplaced = PR_FALSE;
|
|
|
|
|
|
|
|
NS_ASSERTION(aTag != nsnull, "null SVG tag");
|
|
|
|
if (aTag == nsnull)
|
|
|
|
return NS_OK;
|
|
|
|
|
2000-05-24 08:19:10 +00:00
|
|
|
// Make sure that we remain confined in the SVG world
|
|
|
|
if (aNameSpaceID != nsSVGAtoms::nameSpaceID)
|
2000-04-01 22:26:38 +00:00
|
|
|
return NS_OK;
|
|
|
|
|
|
|
|
// Initialize the new frame
|
|
|
|
nsIFrame* newFrame = nsnull;
|
|
|
|
nsIFrame* ignore = nsnull;
|
|
|
|
//nsSVGTableCreator svgTableCreator(aPresShell); // Used to make table views.
|
|
|
|
|
|
|
|
// See if the element is absolute or fixed positioned
|
|
|
|
const nsStylePosition* position = (const nsStylePosition*)
|
|
|
|
aStyleContext->GetStyleData(eStyleStruct_Position);
|
|
|
|
if (NS_STYLE_POSITION_ABSOLUTE == position->mPosition) {
|
|
|
|
isAbsolutelyPositioned = PR_TRUE;
|
|
|
|
}
|
|
|
|
else if (NS_STYLE_POSITION_FIXED == position->mPosition) {
|
|
|
|
isFixedPositioned = PR_TRUE;
|
|
|
|
}
|
|
|
|
if (aTag == nsSVGAtoms::g)
|
|
|
|
rv = NS_NewSVGContainerFrame(aPresShell, &newFrame);
|
|
|
|
else if (aTag == nsSVGAtoms::polygon)
|
|
|
|
rv = NS_NewPolygonFrame(aPresShell, &newFrame);
|
|
|
|
else if (aTag == nsSVGAtoms::polyline)
|
|
|
|
rv = NS_NewPolylineFrame(aPresShell, &newFrame);
|
|
|
|
|
|
|
|
// If we succeeded in creating a frame then initialize it, process its
|
|
|
|
// children (if requested), and set the initial child list
|
|
|
|
if (NS_SUCCEEDED(rv) && newFrame != nsnull) {
|
|
|
|
// If the frame is a replaced element, then set the frame state bit
|
|
|
|
if (isReplaced) {
|
|
|
|
nsFrameState state;
|
|
|
|
newFrame->GetFrameState(&state);
|
|
|
|
newFrame->SetFrameState(state | NS_FRAME_REPLACED_ELEMENT);
|
|
|
|
}
|
|
|
|
|
|
|
|
nsIFrame* geometricParent = isAbsolutelyPositioned
|
|
|
|
? aState.mAbsoluteItems.containingBlock
|
|
|
|
: aParentFrame;
|
|
|
|
InitAndRestoreFrame(aPresContext, aState, aContent,
|
|
|
|
geometricParent, aStyleContext, nsnull, newFrame);
|
|
|
|
|
|
|
|
// See if we need to create a view, e.g. the frame is absolutely positioned
|
|
|
|
nsHTMLContainerFrame::CreateViewForFrame(aPresContext, newFrame,
|
|
|
|
aStyleContext, PR_FALSE);
|
|
|
|
|
|
|
|
// Add the new frame to our list of frame items.
|
|
|
|
aFrameItems.AddChild(newFrame);
|
|
|
|
|
|
|
|
// Process the child content if requested
|
|
|
|
nsFrameItems childItems;
|
|
|
|
if (processChildren) {
|
|
|
|
rv = ProcessChildren(aPresShell, aPresContext, aState, aContent, newFrame, PR_TRUE,
|
|
|
|
childItems, PR_FALSE);
|
2000-05-09 21:42:40 +00:00
|
|
|
|
|
|
|
CreateAnonymousFrames(aPresShell, aPresContext, aTag, aState, aContent, newFrame,
|
|
|
|
childItems);
|
2000-04-01 22:26:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Set the frame's initial child list
|
|
|
|
newFrame->SetInitialChildList(aPresContext, nsnull, childItems.childList);
|
|
|
|
|
|
|
|
// If the frame is absolutely positioned then create a placeholder frame
|
|
|
|
if (isAbsolutelyPositioned || isFixedPositioned) {
|
|
|
|
nsIFrame* placeholderFrame;
|
|
|
|
|
|
|
|
CreatePlaceholderFrameFor(aPresShell, aPresContext, aState.mFrameManager, aContent, newFrame,
|
|
|
|
aStyleContext, aParentFrame, &placeholderFrame);
|
|
|
|
|
|
|
|
// Add the positioned frame to its containing block's list of child frames
|
|
|
|
if (isAbsolutelyPositioned) {
|
|
|
|
aState.mAbsoluteItems.AddChild(newFrame);
|
|
|
|
} else {
|
|
|
|
aState.mFixedItems.AddChild(newFrame);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Add the placeholder frame to the flow
|
|
|
|
aFrameItems.AddChild(placeholderFrame);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
#endif // MOZ_SVG
|
|
|
|
|
1999-02-05 03:55:18 +00:00
|
|
|
nsresult
|
1999-12-04 23:49:50 +00:00
|
|
|
nsCSSFrameConstructor::ConstructFrame(nsIPresShell* aPresShell,
|
|
|
|
nsIPresContext* aPresContext,
|
1999-04-28 19:08:14 +00:00
|
|
|
nsFrameConstructorState& aState,
|
|
|
|
nsIContent* aContent,
|
|
|
|
nsIFrame* aParentFrame,
|
|
|
|
nsFrameItems& aFrameItems)
|
|
|
|
|
1999-02-05 03:55:18 +00:00
|
|
|
{
|
|
|
|
NS_PRECONDITION(nsnull != aParentFrame, "no parent frame");
|
|
|
|
|
|
|
|
nsresult rv;
|
|
|
|
|
|
|
|
// Get the element's tag
|
1999-02-11 15:54:13 +00:00
|
|
|
nsCOMPtr<nsIAtom> tag;
|
|
|
|
aContent->GetTag(*getter_AddRefs(tag));
|
1999-02-05 03:55:18 +00:00
|
|
|
|
1999-02-11 23:08:28 +00:00
|
|
|
nsCOMPtr<nsIStyleContext> styleContext;
|
|
|
|
rv = ResolveStyleContext(aPresContext, aParentFrame, aContent, tag, getter_AddRefs(styleContext));
|
|
|
|
|
1999-02-05 03:55:18 +00:00
|
|
|
if (NS_SUCCEEDED(rv)) {
|
|
|
|
// Pre-check for display "none" - if we find that, don't create
|
|
|
|
// any frame at all
|
|
|
|
const nsStyleDisplay* display = (const nsStyleDisplay*)
|
|
|
|
styleContext->GetStyleData(eStyleStruct_Display);
|
|
|
|
|
1999-10-02 04:27:40 +00:00
|
|
|
if (NS_STYLE_DISPLAY_NONE == display->mDisplay) {
|
|
|
|
aState.mFrameManager->SetUndisplayedContent(aContent, styleContext);
|
|
|
|
}
|
2000-05-15 20:25:02 +00:00
|
|
|
else
|
|
|
|
{
|
2000-05-24 08:19:10 +00:00
|
|
|
PRInt32 nameSpaceID;
|
|
|
|
aContent->GetNameSpaceID(nameSpaceID);
|
2000-05-15 20:25:02 +00:00
|
|
|
rv = ConstructFrameInternal(aPresShell,
|
|
|
|
aPresContext,
|
|
|
|
aState,
|
|
|
|
aContent,
|
|
|
|
aParentFrame,
|
|
|
|
tag,
|
2000-05-24 08:19:10 +00:00
|
|
|
nameSpaceID,
|
2000-05-15 20:25:02 +00:00
|
|
|
styleContext,
|
|
|
|
aFrameItems,
|
|
|
|
PR_FALSE);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return rv;
|
|
|
|
}
|
1999-02-05 03:55:18 +00:00
|
|
|
|
2000-05-15 20:25:02 +00:00
|
|
|
|
|
|
|
nsresult
|
|
|
|
nsCSSFrameConstructor::ConstructFrameInternal( nsIPresShell* aPresShell,
|
|
|
|
nsIPresContext* aPresContext,
|
|
|
|
nsFrameConstructorState& aState,
|
|
|
|
nsIContent* aContent,
|
|
|
|
nsIFrame* aParentFrame,
|
|
|
|
nsIAtom* aTag,
|
2000-05-24 08:19:10 +00:00
|
|
|
PRInt32 aNameSpaceID,
|
2000-05-15 20:25:02 +00:00
|
|
|
nsIStyleContext* aStyleContext,
|
|
|
|
nsFrameItems& aFrameItems,
|
|
|
|
PRBool aXBLBaseTag)
|
|
|
|
{
|
|
|
|
// The following code allows the user to specify the base tag
|
|
|
|
// of a XUL object using XBL. XUL objects (like boxes, menus, etc.)
|
|
|
|
// can then be extended arbitrarily.
|
2000-07-28 00:35:30 +00:00
|
|
|
nsCOMPtr<nsIXBLBinding> binding;
|
2000-05-15 20:25:02 +00:00
|
|
|
if (!aXBLBaseTag)
|
|
|
|
{
|
|
|
|
const nsStyleUserInterface* ui= (const nsStyleUserInterface*)
|
|
|
|
aStyleContext->GetStyleData(eStyleStruct_UserInterface);
|
|
|
|
|
|
|
|
// Ensure that our XBL bindings are installed.
|
|
|
|
if (!ui->mBehavior.IsEmpty()) {
|
|
|
|
// Get the XBL loader.
|
|
|
|
nsresult rv;
|
|
|
|
NS_WITH_SERVICE(nsIXBLService, xblService, "component://netscape/xbl", &rv);
|
|
|
|
if (!xblService)
|
|
|
|
return rv;
|
|
|
|
|
|
|
|
// Load the bindings.
|
2000-08-04 08:45:29 +00:00
|
|
|
rv = xblService->LoadBindings(aContent, ui->mBehavior, PR_FALSE, getter_AddRefs(binding));
|
|
|
|
if (NS_FAILED(rv))
|
|
|
|
return NS_OK;
|
2000-05-15 20:25:02 +00:00
|
|
|
|
|
|
|
nsCOMPtr<nsIAtom> baseTag;
|
2000-05-24 08:19:10 +00:00
|
|
|
PRInt32 nameSpaceID;
|
|
|
|
xblService->ResolveTag(aContent, &nameSpaceID, getter_AddRefs(baseTag));
|
2000-05-15 20:25:02 +00:00
|
|
|
|
|
|
|
if (baseTag.get() != aTag) {
|
|
|
|
// Construct the frame using the XBL base tag.
|
2000-07-28 00:35:30 +00:00
|
|
|
nsresult rv = ConstructFrameInternal( aPresShell,
|
2000-05-15 20:25:02 +00:00
|
|
|
aPresContext,
|
|
|
|
aState,
|
|
|
|
aContent,
|
|
|
|
aParentFrame,
|
|
|
|
baseTag,
|
2000-05-24 08:19:10 +00:00
|
|
|
nameSpaceID,
|
2000-05-15 20:25:02 +00:00
|
|
|
aStyleContext,
|
|
|
|
aFrameItems,
|
|
|
|
PR_TRUE);
|
2000-07-28 00:35:30 +00:00
|
|
|
if (binding) {
|
|
|
|
nsCOMPtr<nsIBindingManager> bm;
|
|
|
|
mDocument->GetBindingManager(getter_AddRefs(bm));
|
|
|
|
if (bm)
|
|
|
|
bm->AddToAttachedQueue(binding);
|
|
|
|
}
|
|
|
|
return rv;
|
2000-05-15 20:25:02 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
nsIFrame* lastChild = aFrameItems.lastChild;
|
|
|
|
|
|
|
|
// Handle specific frame types
|
|
|
|
nsresult rv = ConstructFrameByTag(aPresShell, aPresContext, aState, aContent, aParentFrame,
|
2000-05-24 08:19:10 +00:00
|
|
|
aTag, aNameSpaceID, aStyleContext, aFrameItems);
|
1999-02-05 03:55:18 +00:00
|
|
|
|
|
|
|
#ifdef INCLUDE_XUL
|
2000-05-15 20:25:02 +00:00
|
|
|
// Failing to find a matching HTML frame, try creating a specialized
|
|
|
|
// XUL frame. This is temporary, pending planned factoring of this
|
|
|
|
// whole process into separate, pluggable steps.
|
|
|
|
if (NS_SUCCEEDED(rv) && ((nsnull == aFrameItems.childList) ||
|
|
|
|
(lastChild == aFrameItems.lastChild))) {
|
|
|
|
PRBool haltProcessing = PR_FALSE;
|
|
|
|
rv = ConstructXULFrame(aPresShell, aPresContext, aState, aContent, aParentFrame,
|
2000-05-24 08:19:10 +00:00
|
|
|
aTag, aNameSpaceID, aStyleContext, aFrameItems, haltProcessing);
|
2000-05-15 20:25:02 +00:00
|
|
|
if (haltProcessing) {
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
}
|
1999-02-05 03:55:18 +00:00
|
|
|
#endif
|
|
|
|
|
1999-09-21 01:15:30 +00:00
|
|
|
// MathML Mod - RBS
|
1999-10-02 10:41:40 +00:00
|
|
|
#ifdef MOZ_MATHML
|
2000-05-15 20:25:02 +00:00
|
|
|
if (NS_SUCCEEDED(rv) && ((nsnull == aFrameItems.childList) ||
|
|
|
|
(lastChild == aFrameItems.lastChild))) {
|
|
|
|
rv = ConstructMathMLFrame(aPresShell, aPresContext, aState, aContent, aParentFrame,
|
2000-05-24 08:19:10 +00:00
|
|
|
aTag, aNameSpaceID, aStyleContext, aFrameItems);
|
2000-05-15 20:25:02 +00:00
|
|
|
}
|
1999-09-21 01:15:30 +00:00
|
|
|
#endif
|
|
|
|
|
2000-04-01 22:26:38 +00:00
|
|
|
// SVG
|
|
|
|
#ifdef MOZ_SVG
|
2000-05-15 20:25:02 +00:00
|
|
|
if (NS_SUCCEEDED(rv) && ((nsnull == aFrameItems.childList) ||
|
|
|
|
(lastChild == aFrameItems.lastChild))) {
|
|
|
|
rv = ConstructSVGFrame(aPresShell, aPresContext, aState, aContent, aParentFrame,
|
2000-05-24 08:19:10 +00:00
|
|
|
aTag, aNameSpaceID, aStyleContext, aFrameItems);
|
2000-05-15 20:25:02 +00:00
|
|
|
}
|
2000-04-01 22:26:38 +00:00
|
|
|
#endif
|
|
|
|
|
2000-05-15 20:25:02 +00:00
|
|
|
if (NS_SUCCEEDED(rv) && ((nsnull == aFrameItems.childList) ||
|
|
|
|
(lastChild == aFrameItems.lastChild))) {
|
|
|
|
// When there is no explicit frame to create, assume it's a
|
|
|
|
// container and let display style dictate the rest
|
|
|
|
const nsStyleDisplay* display = (const nsStyleDisplay*)
|
|
|
|
aStyleContext->GetStyleData(eStyleStruct_Display);
|
|
|
|
|
|
|
|
rv = ConstructFrameByDisplayType(aPresShell, aPresContext, aState, display, aContent,
|
|
|
|
aParentFrame, aStyleContext, aFrameItems);
|
1999-02-05 03:55:18 +00:00
|
|
|
}
|
2000-05-15 20:25:02 +00:00
|
|
|
|
2000-07-28 00:35:30 +00:00
|
|
|
if (binding) {
|
|
|
|
nsCOMPtr<nsIBindingManager> bm;
|
|
|
|
mDocument->GetBindingManager(getter_AddRefs(bm));
|
|
|
|
if (bm)
|
|
|
|
bm->AddToAttachedQueue(binding);
|
|
|
|
}
|
|
|
|
|
1999-02-05 03:55:18 +00:00
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
2000-05-15 20:25:02 +00:00
|
|
|
|
|
|
|
|
1999-03-01 16:57:35 +00:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsCSSFrameConstructor::ReconstructDocElementHierarchy(nsIPresContext* aPresContext)
|
1999-02-05 03:55:18 +00:00
|
|
|
{
|
|
|
|
nsresult rv = NS_OK;
|
1999-12-04 23:49:50 +00:00
|
|
|
nsCOMPtr<nsIPresShell> shell;
|
|
|
|
aPresContext->GetShell(getter_AddRefs(shell));
|
|
|
|
|
1999-03-01 16:57:35 +00:00
|
|
|
if (nsnull != mDocument) {
|
|
|
|
nsCOMPtr<nsIContent> rootContent(dont_AddRef(mDocument->GetRootContent()));
|
1999-12-06 07:44:18 +00:00
|
|
|
|
1999-03-01 16:57:35 +00:00
|
|
|
if (rootContent) {
|
1999-12-06 07:44:18 +00:00
|
|
|
// Before removing the frames associated with the content object, ask them to save their
|
|
|
|
// state onto a temporary state object.
|
|
|
|
CaptureStateForFramesOf(aPresContext, rootContent, mTempFrameTreeState);
|
|
|
|
|
1999-08-05 03:09:22 +00:00
|
|
|
nsFrameConstructorState state(aPresContext, mFixedContainingBlock,
|
1999-12-06 07:44:18 +00:00
|
|
|
nsnull, nsnull, mTempFrameTreeState);
|
1999-08-05 03:09:22 +00:00
|
|
|
nsIFrame* docElementFrame;
|
1999-03-01 16:57:35 +00:00
|
|
|
|
1999-08-05 03:09:22 +00:00
|
|
|
// Get the frame that corresponds to the document element
|
|
|
|
state.mFrameManager->GetPrimaryFrameFor(rootContent, &docElementFrame);
|
|
|
|
|
|
|
|
// Clear the hash tables that map from content to frame and out-of-flow
|
|
|
|
// frame to placeholder frame
|
|
|
|
state.mFrameManager->ClearPrimaryFrameMap();
|
|
|
|
state.mFrameManager->ClearPlaceholderFrameMap();
|
1999-10-02 04:27:40 +00:00
|
|
|
state.mFrameManager->ClearUndisplayedContentMap();
|
1999-08-05 03:09:22 +00:00
|
|
|
|
|
|
|
if (docElementFrame) {
|
|
|
|
nsIFrame* docParentFrame;
|
|
|
|
docElementFrame->GetParent(&docParentFrame);
|
|
|
|
|
|
|
|
if (docParentFrame) {
|
|
|
|
// Remove the old document element hieararchy
|
1999-11-24 06:03:41 +00:00
|
|
|
rv = state.mFrameManager->RemoveFrame(aPresContext, *shell,
|
1999-08-05 03:09:22 +00:00
|
|
|
docParentFrame, nsnull,
|
|
|
|
docElementFrame);
|
1999-12-06 07:44:18 +00:00
|
|
|
// XXX Remove any existing fixed items...
|
1999-08-05 03:09:22 +00:00
|
|
|
if (NS_SUCCEEDED(rv)) {
|
1999-12-06 07:44:18 +00:00
|
|
|
// Create the new document element hierarchy
|
1999-08-05 03:09:22 +00:00
|
|
|
nsIFrame* newChild;
|
|
|
|
nsCOMPtr<nsIStyleContext> rootPseudoStyle;
|
1999-03-01 16:57:35 +00:00
|
|
|
|
1999-08-05 03:09:22 +00:00
|
|
|
docParentFrame->GetStyleContext(getter_AddRefs(rootPseudoStyle));
|
1999-12-04 23:49:50 +00:00
|
|
|
rv = ConstructDocElementFrame(shell, aPresContext, state, rootContent,
|
1999-08-05 03:09:22 +00:00
|
|
|
docParentFrame, rootPseudoStyle,
|
|
|
|
newChild);
|
|
|
|
|
|
|
|
if (NS_SUCCEEDED(rv)) {
|
1999-11-24 06:03:41 +00:00
|
|
|
rv = state.mFrameManager->InsertFrames(aPresContext, *shell,
|
1999-08-05 03:09:22 +00:00
|
|
|
docParentFrame, nsnull,
|
|
|
|
nsnull, newChild);
|
|
|
|
|
|
|
|
// Tell the fixed containing block about its 'fixed' frames
|
|
|
|
if (state.mFixedItems.childList) {
|
1999-11-24 06:03:41 +00:00
|
|
|
state.mFrameManager->InsertFrames(aPresContext, *shell,
|
1999-08-05 03:09:22 +00:00
|
|
|
mFixedContainingBlock, nsLayoutAtoms::fixedList,
|
|
|
|
nsnull, state.mFixedItems.childList);
|
1999-03-01 16:57:35 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
1999-02-05 03:55:18 +00:00
|
|
|
}
|
|
|
|
}
|
1999-03-01 16:57:35 +00:00
|
|
|
}
|
1999-02-05 03:55:18 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
1999-03-01 16:57:35 +00:00
|
|
|
|
1999-02-05 03:55:18 +00:00
|
|
|
nsIFrame*
|
1999-08-05 03:09:22 +00:00
|
|
|
nsCSSFrameConstructor::GetFrameFor(nsIPresShell* aPresShell,
|
|
|
|
nsIPresContext* aPresContext,
|
|
|
|
nsIContent* aContent)
|
1999-02-05 03:55:18 +00:00
|
|
|
{
|
|
|
|
// Get the primary frame associated with the content
|
|
|
|
nsIFrame* frame;
|
1999-02-12 17:45:58 +00:00
|
|
|
aPresShell->GetPrimaryFrameFor(aContent, &frame);
|
1999-02-05 03:55:18 +00:00
|
|
|
|
|
|
|
if (nsnull != frame) {
|
1999-08-23 14:05:39 +00:00
|
|
|
// Check to see if the content is a select and
|
|
|
|
// then if it has a drop down (thus making it a combobox)
|
|
|
|
// The drop down is a ListControlFrame derived from a
|
1999-08-25 13:42:59 +00:00
|
|
|
// nsScrollFrame then get the area frame and that will be the parent
|
|
|
|
// What is unclear here, is if any of this fails, should it return
|
|
|
|
// the nsComboboxControlFrame or null?
|
1999-08-23 14:05:39 +00:00
|
|
|
nsCOMPtr<nsIDOMHTMLSelectElement> selectElement;
|
2000-02-02 22:24:56 +00:00
|
|
|
nsresult res = aContent->QueryInterface(NS_GET_IID(nsIDOMHTMLSelectElement),
|
1999-08-23 14:05:39 +00:00
|
|
|
(void**)getter_AddRefs(selectElement));
|
|
|
|
if (NS_SUCCEEDED(res) && selectElement) {
|
|
|
|
nsIComboboxControlFrame * comboboxFrame;
|
2000-02-02 22:24:56 +00:00
|
|
|
res = frame->QueryInterface(NS_GET_IID(nsIComboboxControlFrame),
|
1999-08-23 14:05:39 +00:00
|
|
|
(void**)&comboboxFrame);
|
1999-08-25 13:42:59 +00:00
|
|
|
nsIFrame * listFrame;
|
1999-08-23 20:59:08 +00:00
|
|
|
if (NS_SUCCEEDED(res) && comboboxFrame) {
|
1999-08-23 14:05:39 +00:00
|
|
|
comboboxFrame->GetDropDown(&listFrame);
|
1999-08-25 13:42:59 +00:00
|
|
|
} else {
|
2000-03-18 14:25:02 +00:00
|
|
|
listFrame = frame;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (listFrame != nsnull) {
|
|
|
|
nsIListControlFrame * list;
|
|
|
|
res = listFrame->QueryInterface(NS_GET_IID(nsIListControlFrame),
|
|
|
|
(void**)&list);
|
|
|
|
if (NS_SUCCEEDED(res) && list) {
|
|
|
|
list->GetOptionsContainer(aPresContext, &frame);
|
1999-08-25 13:42:59 +00:00
|
|
|
}
|
1999-08-23 14:05:39 +00:00
|
|
|
}
|
|
|
|
} else {
|
2000-01-27 02:19:12 +00:00
|
|
|
// If the primary frame is a scroll frame, then get the scrolled frame.
|
|
|
|
// That's the frame that gets the reflow command
|
2000-01-27 20:21:28 +00:00
|
|
|
const nsStyleDisplay* display;
|
|
|
|
frame->GetStyleData(eStyleStruct_Display, (const nsStyleStruct*&)display);
|
|
|
|
|
2000-02-11 01:23:36 +00:00
|
|
|
// If the primary frame supports IScrollableFrame, then get the scrolled frame.
|
|
|
|
// That's the frame that gets the reflow command
|
|
|
|
nsIScrollableFrame *pScrollableFrame = nsnull;
|
|
|
|
if (NS_SUCCEEDED( frame->QueryInterface(nsIScrollableFrame::GetIID(),
|
|
|
|
(void **)&pScrollableFrame) ))
|
|
|
|
{
|
|
|
|
pScrollableFrame->GetScrolledFrame( aPresContext, frame );
|
2000-01-27 20:21:28 +00:00
|
|
|
}
|
2000-02-11 01:23:36 +00:00
|
|
|
|
1999-08-23 14:05:39 +00:00
|
|
|
// if we get an outer table frame use its 1st child which is a table inner frame
|
|
|
|
// if we get a table cell frame use its 1st child which is an area frame
|
|
|
|
else if ((NS_STYLE_DISPLAY_TABLE == display->mDisplay) ||
|
|
|
|
(NS_STYLE_DISPLAY_TABLE_CELL == display->mDisplay)) {
|
2000-01-22 01:16:50 +00:00
|
|
|
frame->FirstChild(aPresContext, nsnull, &frame);
|
1999-08-23 14:05:39 +00:00
|
|
|
}
|
1999-05-06 22:29:28 +00:00
|
|
|
}
|
1999-02-05 03:55:18 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return frame;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsIFrame*
|
|
|
|
nsCSSFrameConstructor::GetAbsoluteContainingBlock(nsIPresContext* aPresContext,
|
|
|
|
nsIFrame* aFrame)
|
|
|
|
{
|
|
|
|
NS_PRECONDITION(nsnull != mInitialContainingBlock, "no initial containing block");
|
|
|
|
|
1999-04-20 22:08:33 +00:00
|
|
|
// Starting with aFrame, look for a frame that is absolutely positioned or
|
|
|
|
// relatively positioned
|
1999-04-20 21:51:55 +00:00
|
|
|
nsIFrame* containingBlock = nsnull;
|
|
|
|
for (nsIFrame* frame = aFrame; frame; frame->GetParent(&frame)) {
|
1999-02-05 03:55:18 +00:00
|
|
|
const nsStylePosition* position;
|
|
|
|
|
1999-04-20 22:08:33 +00:00
|
|
|
// Is it positioned?
|
1999-04-20 21:51:55 +00:00
|
|
|
frame->GetStyleData(eStyleStruct_Position, (const nsStyleStruct*&)position);
|
1999-04-20 22:08:33 +00:00
|
|
|
if ((position->mPosition == NS_STYLE_POSITION_ABSOLUTE) ||
|
|
|
|
(position->mPosition == NS_STYLE_POSITION_RELATIVE)) {
|
1999-02-05 03:55:18 +00:00
|
|
|
const nsStyleDisplay* display;
|
|
|
|
|
|
|
|
// If it's a table then ignore it, because for the time being tables
|
|
|
|
// are not containers for absolutely positioned child frames
|
1999-04-20 21:51:55 +00:00
|
|
|
frame->GetStyleData(eStyleStruct_Display, (const nsStyleStruct*&)display);
|
1999-02-05 03:55:18 +00:00
|
|
|
if (display->mDisplay != NS_STYLE_DISPLAY_TABLE) {
|
1999-04-20 21:51:55 +00:00
|
|
|
nsIAtom* frameType;
|
|
|
|
frame->GetFrameType(&frameType);
|
|
|
|
|
|
|
|
if (nsLayoutAtoms::scrollFrame == frameType) {
|
|
|
|
// We want the scrolled frame, not the scroll frame
|
|
|
|
nsIFrame* scrolledFrame;
|
2000-01-22 01:16:50 +00:00
|
|
|
frame->FirstChild(aPresContext, nsnull, &scrolledFrame);
|
1999-04-20 21:51:55 +00:00
|
|
|
NS_RELEASE(frameType);
|
|
|
|
if (scrolledFrame) {
|
|
|
|
scrolledFrame->GetFrameType(&frameType);
|
|
|
|
if (nsLayoutAtoms::areaFrame == frameType) {
|
|
|
|
containingBlock = scrolledFrame;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1999-04-20 22:08:33 +00:00
|
|
|
} else if ((nsLayoutAtoms::areaFrame == frameType) ||
|
|
|
|
(nsLayoutAtoms::positionedInlineFrame == frameType)) {
|
1999-04-20 21:51:55 +00:00
|
|
|
containingBlock = frame;
|
|
|
|
}
|
|
|
|
NS_RELEASE(frameType);
|
1999-02-05 03:55:18 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1999-04-20 21:51:55 +00:00
|
|
|
// See if we found a containing block
|
|
|
|
if (containingBlock) {
|
|
|
|
break;
|
|
|
|
}
|
1999-02-05 03:55:18 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// If we didn't find an absolutely positioned containing block, then use the
|
|
|
|
// initial containing block
|
1999-04-20 21:51:55 +00:00
|
|
|
if (!containingBlock) {
|
1999-02-05 03:55:18 +00:00
|
|
|
containingBlock = mInitialContainingBlock;
|
|
|
|
}
|
|
|
|
|
|
|
|
return containingBlock;
|
|
|
|
}
|
|
|
|
|
1999-02-26 17:11:54 +00:00
|
|
|
nsIFrame*
|
|
|
|
nsCSSFrameConstructor::GetFloaterContainingBlock(nsIPresContext* aPresContext,
|
|
|
|
nsIFrame* aFrame)
|
|
|
|
{
|
|
|
|
NS_PRECONDITION(mInitialContainingBlock, "no initial containing block");
|
|
|
|
|
1999-09-24 17:14:19 +00:00
|
|
|
// Starting with aFrame, look for a frame that is a real block frame,
|
|
|
|
// or a floated inline or absolutely positioned inline frame
|
1999-02-26 17:11:54 +00:00
|
|
|
nsIFrame* containingBlock = aFrame;
|
|
|
|
while (nsnull != containingBlock) {
|
|
|
|
const nsStyleDisplay* display;
|
|
|
|
containingBlock->GetStyleData(eStyleStruct_Display,
|
|
|
|
(const nsStyleStruct*&)display);
|
|
|
|
if ((NS_STYLE_DISPLAY_BLOCK == display->mDisplay) ||
|
|
|
|
(NS_STYLE_DISPLAY_LIST_ITEM == display->mDisplay)) {
|
|
|
|
break;
|
|
|
|
}
|
1999-09-24 17:14:19 +00:00
|
|
|
else if (NS_STYLE_DISPLAY_INLINE == display->mDisplay) {
|
|
|
|
const nsStylePosition* position;
|
|
|
|
containingBlock->GetStyleData(eStyleStruct_Position,
|
|
|
|
(const nsStyleStruct*&)position);
|
|
|
|
|
1999-10-29 14:39:48 +00:00
|
|
|
if ((NS_STYLE_FLOAT_NONE != display->mFloats) ||
|
1999-09-24 17:14:19 +00:00
|
|
|
(position->IsAbsolutelyPositioned())) {
|
1999-10-29 14:39:48 +00:00
|
|
|
if (NS_STYLE_FLOAT_NONE != display->mFloats) {
|
|
|
|
nsCOMPtr<nsIAtom> frameType;
|
|
|
|
containingBlock->GetFrameType(getter_AddRefs(frameType));
|
|
|
|
if (nsLayoutAtoms::letterFrame != frameType.get()) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
break;
|
|
|
|
}
|
1999-09-24 17:14:19 +00:00
|
|
|
}
|
|
|
|
}
|
1999-02-26 17:11:54 +00:00
|
|
|
|
|
|
|
// Continue walking up the hierarchy
|
|
|
|
containingBlock->GetParent(&containingBlock);
|
|
|
|
}
|
|
|
|
|
|
|
|
// If we didn't find a containing block, then use the initial
|
|
|
|
// containing block
|
|
|
|
if (nsnull == containingBlock) {
|
|
|
|
containingBlock = mInitialContainingBlock;
|
|
|
|
}
|
|
|
|
return containingBlock;
|
|
|
|
}
|
|
|
|
|
1999-04-07 03:10:59 +00:00
|
|
|
// Helper function to determine whether a given frame is generated content
|
|
|
|
// for the specified content object. Returns PR_TRUE if the frame is associated
|
|
|
|
// with generated content and PR_FALSE otherwise
|
|
|
|
static inline PRBool
|
1999-09-02 05:21:39 +00:00
|
|
|
IsGeneratedContentFor(nsIContent* aContent, nsIFrame* aFrame, nsIAtom* aPseudoElement)
|
1999-04-07 03:10:59 +00:00
|
|
|
{
|
1999-07-16 02:14:26 +00:00
|
|
|
NS_PRECONDITION(aFrame, "null frame pointer");
|
1999-04-07 03:10:59 +00:00
|
|
|
nsFrameState state;
|
|
|
|
PRBool result = PR_FALSE;
|
|
|
|
|
|
|
|
// First check the frame state bit
|
|
|
|
aFrame->GetFrameState(&state);
|
|
|
|
if (state & NS_FRAME_GENERATED_CONTENT) {
|
|
|
|
nsIContent* content;
|
|
|
|
|
|
|
|
// Check that it has the same content pointer
|
|
|
|
aFrame->GetContent(&content);
|
1999-09-02 05:21:39 +00:00
|
|
|
if (content == aContent) {
|
|
|
|
nsIStyleContext* styleContext;
|
|
|
|
nsIAtom* pseudoType;
|
|
|
|
|
|
|
|
// See if the pseudo element type matches
|
|
|
|
aFrame->GetStyleContext(&styleContext);
|
|
|
|
styleContext->GetPseudoType(pseudoType);
|
|
|
|
result = (pseudoType == aPseudoElement);
|
|
|
|
NS_RELEASE(styleContext);
|
|
|
|
NS_IF_RELEASE(pseudoType);
|
|
|
|
}
|
1999-04-07 03:10:59 +00:00
|
|
|
NS_IF_RELEASE(content);
|
|
|
|
}
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
1999-04-06 04:58:05 +00:00
|
|
|
// This function is called by ContentAppended() and ContentInserted() when
|
|
|
|
// appending flowed frames to a parent's principal child list. It handles the
|
|
|
|
// case where the parent frame has :after pseudo-element generated content
|
|
|
|
nsresult
|
1999-08-05 03:09:22 +00:00
|
|
|
nsCSSFrameConstructor::AppendFrames(nsIPresContext* aPresContext,
|
|
|
|
nsIPresShell* aPresShell,
|
|
|
|
nsIFrameManager* aFrameManager,
|
|
|
|
nsIContent* aContainer,
|
|
|
|
nsIFrame* aParentFrame,
|
|
|
|
nsIFrame* aFrameList)
|
1999-04-06 04:58:05 +00:00
|
|
|
{
|
|
|
|
nsIFrame* firstChild;
|
2000-01-22 01:16:50 +00:00
|
|
|
aParentFrame->FirstChild(aPresContext, nsnull, &firstChild);
|
1999-04-06 04:58:05 +00:00
|
|
|
nsFrameList frames(firstChild);
|
|
|
|
nsIFrame* lastChild = frames.LastChild();
|
|
|
|
|
|
|
|
// See if the parent has an :after pseudo-element
|
1999-09-02 05:21:39 +00:00
|
|
|
if (lastChild && IsGeneratedContentFor(aContainer, lastChild, nsCSSAtoms::afterPseudo)) {
|
1999-04-07 03:10:59 +00:00
|
|
|
// Insert the frames before the :after pseudo-element
|
1999-11-24 06:03:41 +00:00
|
|
|
return aFrameManager->InsertFrames(aPresContext, *aPresShell, aParentFrame,
|
1999-08-05 03:09:22 +00:00
|
|
|
nsnull, frames.GetPrevSiblingFor(lastChild),
|
|
|
|
aFrameList);
|
1999-04-06 04:58:05 +00:00
|
|
|
}
|
|
|
|
|
2000-01-28 02:19:45 +00:00
|
|
|
nsresult rv = NS_OK;
|
|
|
|
|
1999-12-13 22:56:31 +00:00
|
|
|
// a col group or col appended to a table may result in an insert rather than an append
|
|
|
|
nsIAtom* parentType;
|
|
|
|
aParentFrame->GetFrameType(&parentType);
|
|
|
|
if (nsLayoutAtoms::tableFrame == parentType) {
|
|
|
|
nsTableFrame* tableFrame = (nsTableFrame *)aParentFrame;
|
|
|
|
nsIAtom* childType;
|
|
|
|
aFrameList->GetFrameType(&childType);
|
|
|
|
if (nsLayoutAtoms::tableColFrame == childType) {
|
2000-01-28 02:19:45 +00:00
|
|
|
// table column
|
1999-12-13 22:56:31 +00:00
|
|
|
nsIFrame* parentFrame = aParentFrame;
|
|
|
|
aFrameList->GetParent(&parentFrame);
|
2000-01-28 02:19:45 +00:00
|
|
|
NS_RELEASE(childType);
|
|
|
|
rv = aFrameManager->AppendFrames(aPresContext, *aPresShell, parentFrame,
|
|
|
|
nsLayoutAtoms::colGroupList, aFrameList);
|
1999-12-13 22:56:31 +00:00
|
|
|
}
|
|
|
|
else if (nsLayoutAtoms::tableColGroupFrame == childType) {
|
2000-01-28 02:19:45 +00:00
|
|
|
// table col group
|
1999-12-13 22:56:31 +00:00
|
|
|
nsIFrame* prevSibling;
|
|
|
|
PRBool doAppend = nsTableColGroupFrame::GetLastRealColGroup(tableFrame, &prevSibling);
|
|
|
|
if (doAppend) {
|
2000-01-28 02:19:45 +00:00
|
|
|
rv = aFrameManager->AppendFrames(aPresContext, *aPresShell, aParentFrame,
|
|
|
|
nsLayoutAtoms::colGroupList, aFrameList);
|
1999-12-13 22:56:31 +00:00
|
|
|
}
|
|
|
|
else {
|
2000-01-28 02:19:45 +00:00
|
|
|
rv = aFrameManager->InsertFrames(aPresContext, *aPresShell, aParentFrame,
|
|
|
|
nsLayoutAtoms::colGroupList, prevSibling, aFrameList);
|
1999-12-13 22:56:31 +00:00
|
|
|
}
|
|
|
|
}
|
2000-01-28 02:19:45 +00:00
|
|
|
else if (nsLayoutAtoms::tableCaptionFrame == childType) {
|
|
|
|
// table caption
|
|
|
|
rv = aFrameManager->AppendFrames(aPresContext, *aPresShell, aParentFrame,
|
|
|
|
nsLayoutAtoms::captionList, aFrameList);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
rv = aFrameManager->AppendFrames(aPresContext, *aPresShell, aParentFrame,
|
|
|
|
nsnull, aFrameList);
|
|
|
|
}
|
1999-12-13 22:56:31 +00:00
|
|
|
NS_IF_RELEASE(childType);
|
|
|
|
}
|
2000-01-28 02:19:45 +00:00
|
|
|
else {
|
|
|
|
// Append the frames to the end of the parent's child list
|
2000-04-28 21:05:31 +00:00
|
|
|
// check for a table caption which goes on an additional child list with a different parent
|
|
|
|
nsIFrame* outerTableFrame;
|
|
|
|
if (GetCaptionAdjustedParent(aParentFrame, aFrameList, &outerTableFrame)) {
|
|
|
|
rv = aFrameManager->AppendFrames(aPresContext, *aPresShell, outerTableFrame,
|
|
|
|
nsLayoutAtoms::captionList, aFrameList);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
rv = aFrameManager->AppendFrames(aPresContext, *aPresShell, aParentFrame,
|
|
|
|
nsnull, aFrameList);
|
|
|
|
}
|
2000-01-28 02:19:45 +00:00
|
|
|
}
|
1999-12-13 22:56:31 +00:00
|
|
|
NS_IF_RELEASE(parentType);
|
|
|
|
|
2000-01-28 02:19:45 +00:00
|
|
|
return rv;
|
1999-04-06 04:58:05 +00:00
|
|
|
}
|
|
|
|
|
2000-01-06 08:58:05 +00:00
|
|
|
static nsIFrame*
|
|
|
|
FindPreviousSibling(nsIPresShell* aPresShell,
|
|
|
|
nsIContent* aContainer,
|
|
|
|
PRInt32 aIndexInContainer)
|
|
|
|
{
|
|
|
|
nsIFrame* prevSibling = nsnull;
|
|
|
|
|
|
|
|
// Note: not all content objects are associated with a frame (e.g., if their
|
|
|
|
// 'display' type is 'hidden') so keep looking until we find a previous frame
|
|
|
|
for (PRInt32 i = aIndexInContainer - 1; i >= 0; i--) {
|
|
|
|
nsCOMPtr<nsIContent> precedingContent;
|
|
|
|
|
|
|
|
aContainer->ChildAt(i, *getter_AddRefs(precedingContent));
|
|
|
|
aPresShell->GetPrimaryFrameFor(precedingContent, &prevSibling);
|
|
|
|
|
|
|
|
if (nsnull != prevSibling) {
|
|
|
|
// The frame may have a next-in-flow. Get the last-in-flow
|
|
|
|
nsIFrame* nextInFlow;
|
|
|
|
do {
|
|
|
|
prevSibling->GetNextInFlow(&nextInFlow);
|
|
|
|
if (nsnull != nextInFlow) {
|
|
|
|
prevSibling = nextInFlow;
|
|
|
|
}
|
|
|
|
} while (nsnull != nextInFlow);
|
|
|
|
|
|
|
|
// Did we really get the *right* frame?
|
|
|
|
const nsStyleDisplay* display;
|
|
|
|
prevSibling->GetStyleData(eStyleStruct_Display,
|
|
|
|
(const nsStyleStruct*&)display);
|
2000-05-24 23:28:20 +00:00
|
|
|
const nsStylePosition* position;
|
|
|
|
prevSibling->GetStyleData(eStyleStruct_Position,
|
|
|
|
(const nsStyleStruct*&)position);
|
|
|
|
if (display->IsFloating() || position->IsPositioned()) {
|
2000-01-06 08:58:05 +00:00
|
|
|
// Nope. Get the place-holder instead
|
|
|
|
nsIFrame* placeholderFrame;
|
|
|
|
aPresShell->GetPlaceholderFrameFor(prevSibling, &placeholderFrame);
|
|
|
|
NS_ASSERTION(nsnull != placeholderFrame, "yikes");
|
|
|
|
prevSibling = placeholderFrame;
|
|
|
|
}
|
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return prevSibling;
|
|
|
|
}
|
|
|
|
|
|
|
|
static nsIFrame*
|
|
|
|
FindNextSibling(nsIPresShell* aPresShell,
|
|
|
|
nsIContent* aContainer,
|
|
|
|
PRInt32 aIndexInContainer)
|
|
|
|
{
|
|
|
|
nsIFrame* nextSibling = nsnull;
|
|
|
|
|
|
|
|
// Note: not all content objects are associated with a frame (e.g., if their
|
|
|
|
// 'display' type is 'hidden') so keep looking until we find a previous frame
|
|
|
|
PRInt32 count;
|
|
|
|
aContainer->ChildCount(count);
|
|
|
|
for (PRInt32 i = aIndexInContainer + 1; i < count; i++) {
|
|
|
|
nsCOMPtr<nsIContent> nextContent;
|
|
|
|
|
|
|
|
aContainer->ChildAt(i, *getter_AddRefs(nextContent));
|
|
|
|
aPresShell->GetPrimaryFrameFor(nextContent, &nextSibling);
|
|
|
|
|
|
|
|
if (nsnull != nextSibling) {
|
|
|
|
// The frame may have a next-in-flow. Get the first-in-flow
|
|
|
|
nsIFrame* prevInFlow;
|
|
|
|
do {
|
|
|
|
nextSibling->GetPrevInFlow(&prevInFlow);
|
|
|
|
if (nsnull != prevInFlow) {
|
|
|
|
nextSibling = prevInFlow;
|
|
|
|
}
|
|
|
|
} while (nsnull != prevInFlow);
|
|
|
|
|
|
|
|
// Did we really get the *right* frame?
|
|
|
|
const nsStyleDisplay* display;
|
|
|
|
nextSibling->GetStyleData(eStyleStruct_Display,
|
|
|
|
(const nsStyleStruct*&)display);
|
2000-05-24 23:28:20 +00:00
|
|
|
const nsStylePosition* position;
|
|
|
|
nextSibling->GetStyleData(eStyleStruct_Position,
|
|
|
|
(const nsStyleStruct*&)position);
|
|
|
|
if (display->IsFloating() || position->IsPositioned()) {
|
2000-01-06 08:58:05 +00:00
|
|
|
// Nope. Get the place-holder instead
|
|
|
|
nsIFrame* placeholderFrame;
|
|
|
|
aPresShell->GetPlaceholderFrameFor(nextSibling, &placeholderFrame);
|
|
|
|
NS_ASSERTION(nsnull != placeholderFrame, "yikes");
|
|
|
|
nextSibling = placeholderFrame;
|
|
|
|
}
|
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return nextSibling;
|
|
|
|
}
|
|
|
|
|
1999-02-05 03:55:18 +00:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsCSSFrameConstructor::ContentAppended(nsIPresContext* aPresContext,
|
|
|
|
nsIContent* aContainer,
|
|
|
|
PRInt32 aNewIndexInContainer)
|
|
|
|
{
|
1999-11-01 15:24:57 +00:00
|
|
|
#ifdef DEBUG
|
|
|
|
if (gNoisyContentUpdates) {
|
|
|
|
printf("nsCSSFrameConstructor::ContentAppended container=%p index=%d\n",
|
|
|
|
aContainer, aNewIndexInContainer);
|
|
|
|
if (gReallyNoisyContentUpdates && aContainer) {
|
|
|
|
aContainer->List(stdout, 0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
1999-08-05 03:09:22 +00:00
|
|
|
nsCOMPtr<nsIPresShell> shell;
|
|
|
|
aPresContext->GetShell(getter_AddRefs(shell));
|
|
|
|
|
1999-07-20 23:24:10 +00:00
|
|
|
#ifdef INCLUDE_XUL
|
|
|
|
if (aContainer) {
|
|
|
|
nsCOMPtr<nsIAtom> tag;
|
|
|
|
aContainer->GetTag(*getter_AddRefs(tag));
|
|
|
|
if (tag && (tag.get() == nsXULAtoms::treechildren ||
|
|
|
|
tag.get() == nsXULAtoms::treeitem)) {
|
|
|
|
// Walk up to the outermost tree row group frame and tell it that
|
|
|
|
// content was added.
|
1999-07-22 10:06:38 +00:00
|
|
|
nsCOMPtr<nsIContent> parent;
|
1999-07-20 23:24:10 +00:00
|
|
|
nsCOMPtr<nsIContent> child = dont_QueryInterface(aContainer);
|
1999-07-22 10:06:38 +00:00
|
|
|
child->GetParent(*getter_AddRefs(parent));
|
1999-07-20 23:24:10 +00:00
|
|
|
while (parent) {
|
|
|
|
parent->GetTag(*getter_AddRefs(tag));
|
|
|
|
if (tag.get() == nsXULAtoms::tree)
|
|
|
|
break;
|
|
|
|
child = parent;
|
1999-07-22 10:06:38 +00:00
|
|
|
child->GetParent(*getter_AddRefs(parent));
|
1999-07-20 23:24:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (parent) {
|
|
|
|
// We found it. Get the primary frame.
|
2000-01-06 08:58:05 +00:00
|
|
|
nsIFrame* outerFrame = GetFrameFor(shell, aPresContext, child);
|
1999-07-20 23:24:10 +00:00
|
|
|
|
|
|
|
// Convert to a tree row group frame.
|
2000-06-06 23:13:49 +00:00
|
|
|
nsXULTreeOuterGroupFrame* treeRowGroup = (nsXULTreeOuterGroupFrame*)outerFrame;
|
2000-01-13 19:20:25 +00:00
|
|
|
if (treeRowGroup) {
|
2000-01-06 08:58:05 +00:00
|
|
|
|
|
|
|
// Get the primary frame for the parent of the child that's being added.
|
|
|
|
nsIFrame* innerFrame = GetFrameFor(shell, aPresContext, aContainer);
|
|
|
|
|
2000-06-06 23:13:49 +00:00
|
|
|
nsXULTreeGroupFrame* innerGroup = (nsXULTreeGroupFrame*) innerFrame;
|
|
|
|
if (innerGroup) {
|
|
|
|
nsBoxLayoutState state(aPresContext);
|
|
|
|
innerGroup->MarkDirtyChildren(state);
|
|
|
|
}
|
|
|
|
treeRowGroup->ClearRowGroupInfo();
|
2000-06-29 23:34:46 +00:00
|
|
|
shell->FlushPendingNotifications();
|
2000-01-06 08:58:05 +00:00
|
|
|
|
1999-07-20 23:24:10 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif // INCLUDE_XUL
|
|
|
|
|
1999-09-13 21:25:43 +00:00
|
|
|
// Get the frame associated with the content
|
1999-08-06 21:14:45 +00:00
|
|
|
nsIFrame* parentFrame = GetFrameFor(shell, aPresContext, aContainer);
|
1999-02-05 03:55:18 +00:00
|
|
|
if (nsnull != parentFrame) {
|
1999-11-01 15:24:57 +00:00
|
|
|
|
|
|
|
// If the frame we are manipulating is a special frame then do
|
|
|
|
// something different instead of just appending newly created
|
|
|
|
// frames. Note that only the first-in-flow is marked so we check
|
|
|
|
// before getting to the last-in-flow.
|
2000-05-25 19:58:51 +00:00
|
|
|
if (IsFrameSpecial(parentFrame)) {
|
1999-11-01 15:24:57 +00:00
|
|
|
// We are pretty harsh here (and definitely not optimal) -- we
|
|
|
|
// wipe out the entire containing block and recreate it from
|
|
|
|
// scratch. The reason is that because we know that a special
|
|
|
|
// inline frame has propogated some of its children upward to be
|
|
|
|
// children of the block and that those frames may need to move
|
|
|
|
// around. This logic guarantees a correct answer.
|
|
|
|
#ifdef DEBUG
|
|
|
|
if (gNoisyContentUpdates) {
|
|
|
|
printf("nsCSSFrameConstructor::ContentAppended: parentFrame=");
|
|
|
|
nsFrame::ListTag(stdout, parentFrame);
|
|
|
|
printf(" is special\n");
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
return ReframeContainingBlock(aPresContext, parentFrame);
|
|
|
|
}
|
|
|
|
|
1999-02-05 03:55:18 +00:00
|
|
|
// Get the parent frame's last-in-flow
|
|
|
|
nsIFrame* nextInFlow = parentFrame;
|
|
|
|
while (nsnull != nextInFlow) {
|
1999-02-24 04:48:08 +00:00
|
|
|
parentFrame->GetNextInFlow(&nextInFlow);
|
1999-02-05 03:55:18 +00:00
|
|
|
if (nsnull != nextInFlow) {
|
|
|
|
parentFrame = nextInFlow;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1999-09-13 21:25:43 +00:00
|
|
|
// If we didn't process children when we originally created the frame,
|
|
|
|
// then don't do any processing now
|
|
|
|
nsCOMPtr<nsIAtom> frameType;
|
|
|
|
parentFrame->GetFrameType(getter_AddRefs(frameType));
|
|
|
|
if (frameType.get() == nsLayoutAtoms::objectFrame) {
|
|
|
|
// This handles APPLET, EMBED, and OBJECT
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
1999-02-05 03:55:18 +00:00
|
|
|
// Create some new frames
|
1999-04-28 19:08:14 +00:00
|
|
|
PRInt32 count;
|
|
|
|
nsIFrame* firstAppendedFrame = nsnull;
|
|
|
|
nsFrameItems frameItems;
|
1999-08-05 03:09:22 +00:00
|
|
|
nsFrameConstructorState state(aPresContext, mFixedContainingBlock,
|
1999-04-28 19:08:14 +00:00
|
|
|
GetAbsoluteContainingBlock(aPresContext, parentFrame),
|
1999-12-06 07:44:18 +00:00
|
|
|
GetFloaterContainingBlock(aPresContext, parentFrame),
|
|
|
|
nsnull);
|
1999-02-05 03:55:18 +00:00
|
|
|
|
1999-08-27 21:46:10 +00:00
|
|
|
// See if the containing block has :first-letter style applied.
|
1999-10-29 14:39:48 +00:00
|
|
|
PRBool haveFirstLetterStyle, haveFirstLineStyle;
|
1999-08-27 21:46:10 +00:00
|
|
|
nsIFrame* containingBlock = state.mFloatedItems.containingBlock;
|
1999-10-29 14:39:48 +00:00
|
|
|
nsCOMPtr<nsIContent> blockContent;
|
1999-08-27 21:46:10 +00:00
|
|
|
nsCOMPtr<nsIStyleContext> blockSC;
|
|
|
|
containingBlock->GetStyleContext(getter_AddRefs(blockSC));
|
|
|
|
containingBlock->GetContent(getter_AddRefs(blockContent));
|
1999-10-29 14:39:48 +00:00
|
|
|
HaveSpecialBlockStyle(aPresContext, blockContent, blockSC,
|
|
|
|
&haveFirstLetterStyle,
|
|
|
|
&haveFirstLineStyle);
|
|
|
|
|
|
|
|
if (haveFirstLetterStyle) {
|
|
|
|
// Before we get going, remove the current letter frames
|
|
|
|
RemoveLetterFrames(aPresContext, state.mPresShell,
|
|
|
|
state.mFrameManager, containingBlock);
|
1999-08-27 21:46:10 +00:00
|
|
|
}
|
1999-02-05 03:55:18 +00:00
|
|
|
|
1999-08-27 21:46:10 +00:00
|
|
|
PRInt32 i;
|
|
|
|
aContainer->ChildCount(count);
|
1999-08-06 21:43:33 +00:00
|
|
|
for (i = aNewIndexInContainer; i < count; i++) {
|
1999-08-27 21:46:10 +00:00
|
|
|
nsCOMPtr<nsIContent> childContent;
|
|
|
|
aContainer->ChildAt(i, *getter_AddRefs(childContent));
|
1999-08-31 03:09:40 +00:00
|
|
|
|
1999-08-27 21:46:10 +00:00
|
|
|
// Construct a child frame
|
1999-12-04 23:49:50 +00:00
|
|
|
ConstructFrame(shell, aPresContext, state, childContent, parentFrame, frameItems);
|
1999-02-05 03:55:18 +00:00
|
|
|
}
|
2000-07-28 00:35:30 +00:00
|
|
|
|
|
|
|
// We built some new frames. Initialize any newly-constructed bindings.
|
|
|
|
nsCOMPtr<nsIBindingManager> bm;
|
|
|
|
mDocument->GetBindingManager(getter_AddRefs(bm));
|
|
|
|
bm->ProcessAttachedQueue();
|
|
|
|
|
2000-04-04 01:28:15 +00:00
|
|
|
// process the current pseudo frame state
|
|
|
|
if (!state.mPseudoFrames.IsEmpty()) {
|
|
|
|
ProcessPseudoFrames(aPresContext, state.mPseudoFrames, frameItems);
|
|
|
|
}
|
1999-02-05 03:55:18 +00:00
|
|
|
|
1999-08-31 03:09:40 +00:00
|
|
|
if (haveFirstLineStyle) {
|
|
|
|
// It's possible that some of the new frames go into a
|
|
|
|
// first-line frame. Look at them and see...
|
1999-12-04 23:49:50 +00:00
|
|
|
AppendFirstLineFrames(shell, aPresContext, state, aContainer, parentFrame,
|
1999-08-31 03:09:40 +00:00
|
|
|
frameItems);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Adjust parent frame for table inner/outer frame. We need to do
|
|
|
|
// this here because we need both the parent frame and the
|
|
|
|
// constructed frame
|
1999-02-05 03:55:18 +00:00
|
|
|
nsresult result = NS_OK;
|
1999-08-31 03:09:40 +00:00
|
|
|
nsIFrame* adjustedParentFrame = parentFrame;
|
1999-02-05 03:55:18 +00:00
|
|
|
firstAppendedFrame = frameItems.childList;
|
|
|
|
if (nsnull != firstAppendedFrame) {
|
|
|
|
const nsStyleDisplay* firstAppendedFrameDisplay;
|
1999-02-26 17:11:54 +00:00
|
|
|
firstAppendedFrame->GetStyleData(eStyleStruct_Display,
|
|
|
|
(const nsStyleStruct *&)firstAppendedFrameDisplay);
|
2000-01-22 01:16:50 +00:00
|
|
|
result = GetAdjustedParentFrame(aPresContext, parentFrame,
|
1999-02-26 17:11:54 +00:00
|
|
|
firstAppendedFrameDisplay->mDisplay,
|
|
|
|
adjustedParentFrame);
|
1999-02-05 03:55:18 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Notify the parent frame passing it the list of new frames
|
1999-08-31 03:09:40 +00:00
|
|
|
if (NS_SUCCEEDED(result) && firstAppendedFrame) {
|
1999-11-01 15:24:57 +00:00
|
|
|
// Perform special check for diddling around with the frames in
|
|
|
|
// a special inline frame.
|
1999-11-09 22:36:05 +00:00
|
|
|
|
|
|
|
// XXX Bug 18366
|
|
|
|
// Although select frame are inline we do not want to call
|
|
|
|
// WipeContainingBlock because it will throw away the entire selct frame and
|
|
|
|
// start over which is something we do not want to do
|
|
|
|
//
|
1999-11-09 23:49:37 +00:00
|
|
|
nsCOMPtr<nsIDOMHTMLSelectElement> selectContent(do_QueryInterface(aContainer));
|
|
|
|
if (!selectContent) {
|
1999-11-09 22:36:05 +00:00
|
|
|
if (WipeContainingBlock(aPresContext, state, blockContent, adjustedParentFrame,
|
|
|
|
frameItems.childList)) {
|
|
|
|
return NS_OK;
|
|
|
|
}
|
1999-11-01 15:24:57 +00:00
|
|
|
}
|
|
|
|
|
1999-04-06 04:58:05 +00:00
|
|
|
// Append the flowed frames to the principal child list
|
1999-08-05 03:09:22 +00:00
|
|
|
AppendFrames(aPresContext, shell, state.mFrameManager, aContainer,
|
|
|
|
adjustedParentFrame, firstAppendedFrame);
|
1999-02-05 03:55:18 +00:00
|
|
|
|
|
|
|
// If there are new absolutely positioned child frames, then notify
|
|
|
|
// the parent
|
|
|
|
// XXX We can't just assume these frames are being appended, we need to
|
|
|
|
// determine where in the list they should be inserted...
|
1999-04-28 19:08:14 +00:00
|
|
|
if (state.mAbsoluteItems.childList) {
|
1999-11-24 06:03:41 +00:00
|
|
|
state.mAbsoluteItems.containingBlock->AppendFrames(aPresContext, *shell,
|
1999-11-01 15:24:57 +00:00
|
|
|
nsLayoutAtoms::absoluteList,
|
|
|
|
state.mAbsoluteItems.childList);
|
1999-02-05 03:55:18 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// If there are new fixed positioned child frames, then notify
|
|
|
|
// the parent
|
|
|
|
// XXX We can't just assume these frames are being appended, we need to
|
|
|
|
// determine where in the list they should be inserted...
|
1999-04-28 19:08:14 +00:00
|
|
|
if (state.mFixedItems.childList) {
|
1999-11-24 06:03:41 +00:00
|
|
|
state.mFixedItems.containingBlock->AppendFrames(aPresContext, *shell,
|
1999-11-01 15:24:57 +00:00
|
|
|
nsLayoutAtoms::fixedList,
|
|
|
|
state.mFixedItems.childList);
|
1999-02-05 03:55:18 +00:00
|
|
|
}
|
1999-02-26 17:11:54 +00:00
|
|
|
|
|
|
|
// If there are new floating child frames, then notify
|
|
|
|
// the parent
|
|
|
|
// XXX We can't just assume these frames are being appended, we need to
|
|
|
|
// determine where in the list they should be inserted...
|
1999-04-28 19:08:14 +00:00
|
|
|
if (state.mFloatedItems.childList) {
|
1999-11-24 06:03:41 +00:00
|
|
|
state.mFloatedItems.containingBlock->AppendFrames(aPresContext, *shell,
|
1999-11-01 15:24:57 +00:00
|
|
|
nsLayoutAtoms::floaterList,
|
|
|
|
state.mFloatedItems.childList);
|
1999-02-26 17:11:54 +00:00
|
|
|
}
|
1999-10-29 14:39:48 +00:00
|
|
|
|
|
|
|
// Recover first-letter frames
|
|
|
|
if (haveFirstLetterStyle) {
|
1999-12-04 23:49:50 +00:00
|
|
|
RecoverLetterFrames(shell, aPresContext, state, containingBlock);
|
1999-10-29 14:39:48 +00:00
|
|
|
}
|
1999-02-05 03:55:18 +00:00
|
|
|
}
|
1999-08-06 21:14:45 +00:00
|
|
|
|
1999-08-31 03:09:40 +00:00
|
|
|
// Here we have been notified that content has been appended so if
|
|
|
|
// the select now has a single item we need to go in and removed
|
|
|
|
// the dummy frame.
|
|
|
|
nsCOMPtr<nsIDOMHTMLSelectElement> sel(do_QueryInterface(aContainer));
|
|
|
|
if (sel) {
|
1999-08-06 21:14:45 +00:00
|
|
|
nsCOMPtr<nsIContent> childContent;
|
1999-08-06 21:45:14 +00:00
|
|
|
aContainer->ChildAt(aNewIndexInContainer, *getter_AddRefs(childContent));
|
1999-08-06 21:14:45 +00:00
|
|
|
if (childContent) {
|
1999-08-31 03:09:40 +00:00
|
|
|
RemoveDummyFrameFromSelect(aPresContext, shell, aContainer,
|
|
|
|
childContent, sel);
|
1999-08-06 21:14:45 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1999-02-05 03:55:18 +00:00
|
|
|
}
|
1999-08-27 21:46:10 +00:00
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
1999-02-05 03:55:18 +00:00
|
|
|
|
1999-08-06 21:14:45 +00:00
|
|
|
nsresult
|
|
|
|
nsCSSFrameConstructor::RemoveDummyFrameFromSelect(nsIPresContext* aPresContext,
|
|
|
|
nsIPresShell * aPresShell,
|
|
|
|
nsIContent* aContainer,
|
|
|
|
nsIContent* aChild,
|
|
|
|
nsIDOMHTMLSelectElement * aSelectElement)
|
|
|
|
{
|
|
|
|
//check to see if there is one item,
|
|
|
|
// meaning we need to remove the dummy frame
|
|
|
|
PRUint32 numOptions = 0;
|
|
|
|
nsresult result = aSelectElement->GetLength(&numOptions);
|
1999-08-19 14:29:55 +00:00
|
|
|
if (NS_SUCCEEDED(result)) {
|
2000-08-02 21:53:23 +00:00
|
|
|
if (0 == numOptions) {
|
1999-08-19 14:29:55 +00:00
|
|
|
nsIFrame* parentFrame;
|
|
|
|
nsIFrame* childFrame;
|
|
|
|
// Get the childFrame for the added child (option)
|
|
|
|
// then get the child's parent frame which should be an area frame
|
|
|
|
aPresShell->GetPrimaryFrameFor(aChild, &childFrame);
|
1999-10-20 23:35:38 +00:00
|
|
|
if (nsnull != childFrame) {
|
|
|
|
childFrame->GetParent(&parentFrame);
|
|
|
|
|
|
|
|
// Now loop through all the child looking fr the frame whose content
|
|
|
|
// is equal to the select element's content
|
|
|
|
// this is because when gernated content is created it stuff the parent content
|
|
|
|
// pointer into the generated frame, so in this case it has the select content
|
2000-01-22 01:16:50 +00:00
|
|
|
parentFrame->FirstChild(aPresContext, nsnull, &childFrame);
|
1999-10-20 23:35:38 +00:00
|
|
|
nsCOMPtr<nsIContent> selectContent = do_QueryInterface(aSelectElement);
|
|
|
|
while (nsnull != childFrame) {
|
|
|
|
nsIContent * content;
|
|
|
|
childFrame->GetContent(&content);
|
1999-08-06 21:14:45 +00:00
|
|
|
|
1999-10-20 23:35:38 +00:00
|
|
|
// Found the dummy frame so get the FrameManager and
|
|
|
|
// delete/remove the dummy frame
|
|
|
|
if (selectContent.get() == content) {
|
|
|
|
nsCOMPtr<nsIFrameManager> frameManager;
|
|
|
|
aPresShell->GetFrameManager(getter_AddRefs(frameManager));
|
1999-11-24 06:03:41 +00:00
|
|
|
frameManager->RemoveFrame(aPresContext, *aPresShell, parentFrame, nsnull, childFrame);
|
1999-10-20 23:35:38 +00:00
|
|
|
NS_IF_RELEASE(content);
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
1999-08-19 14:29:55 +00:00
|
|
|
NS_IF_RELEASE(content);
|
1999-10-20 23:35:38 +00:00
|
|
|
childFrame->GetNextSibling(&childFrame);
|
1999-08-19 14:29:55 +00:00
|
|
|
}
|
1999-08-06 21:14:45 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
|
1999-02-05 03:55:18 +00:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsCSSFrameConstructor::ContentInserted(nsIPresContext* aPresContext,
|
|
|
|
nsIContent* aContainer,
|
|
|
|
nsIContent* aChild,
|
1999-12-06 07:44:18 +00:00
|
|
|
PRInt32 aIndexInContainer,
|
|
|
|
nsILayoutHistoryState* aFrameState)
|
1999-02-05 03:55:18 +00:00
|
|
|
{
|
1999-11-01 15:24:57 +00:00
|
|
|
#ifdef DEBUG
|
|
|
|
if (gNoisyContentUpdates) {
|
|
|
|
printf("nsCSSFrameConstructor::ContentInserted container=%p child=%p index=%d\n",
|
|
|
|
aContainer, aChild, aIndexInContainer);
|
|
|
|
if (gReallyNoisyContentUpdates) {
|
|
|
|
(aContainer ? aContainer : aChild)->List(stdout, 0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2000-06-29 23:34:46 +00:00
|
|
|
nsCOMPtr<nsIPresShell> shell;
|
|
|
|
aPresContext->GetShell(getter_AddRefs(shell));
|
|
|
|
nsresult rv = NS_OK;
|
|
|
|
|
1999-07-20 23:24:10 +00:00
|
|
|
#ifdef INCLUDE_XUL
|
|
|
|
if (aContainer) {
|
|
|
|
nsCOMPtr<nsIAtom> tag;
|
|
|
|
aContainer->GetTag(*getter_AddRefs(tag));
|
|
|
|
if (tag && (tag.get() == nsXULAtoms::treechildren ||
|
1999-11-01 15:24:57 +00:00
|
|
|
tag.get() == nsXULAtoms::treeitem)) {
|
1999-07-20 23:24:10 +00:00
|
|
|
// Walk up to the outermost tree row group frame and tell it that
|
|
|
|
// content was added.
|
1999-07-22 10:06:38 +00:00
|
|
|
nsCOMPtr<nsIContent> parent;
|
1999-07-20 23:24:10 +00:00
|
|
|
nsCOMPtr<nsIContent> child = dont_QueryInterface(aContainer);
|
1999-07-22 10:06:38 +00:00
|
|
|
child->GetParent(*getter_AddRefs(parent));
|
1999-07-20 23:24:10 +00:00
|
|
|
while (parent) {
|
|
|
|
parent->GetTag(*getter_AddRefs(tag));
|
|
|
|
if (tag.get() == nsXULAtoms::tree)
|
|
|
|
break;
|
|
|
|
child = parent;
|
1999-07-22 10:06:38 +00:00
|
|
|
child->GetParent(*getter_AddRefs(parent));
|
1999-07-20 23:24:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (parent) {
|
|
|
|
// We found it. Get the primary frame.
|
|
|
|
nsCOMPtr<nsIPresShell> shell;
|
|
|
|
aPresContext->GetShell(getter_AddRefs(shell));
|
2000-01-06 08:58:05 +00:00
|
|
|
nsIFrame* outerFrame = GetFrameFor(shell, aPresContext, child);
|
1999-07-20 23:24:10 +00:00
|
|
|
|
|
|
|
// Convert to a tree row group frame.
|
2000-06-06 23:13:49 +00:00
|
|
|
nsXULTreeOuterGroupFrame* treeRowGroup = (nsXULTreeOuterGroupFrame*)outerFrame;
|
2000-06-29 23:34:46 +00:00
|
|
|
|
2000-01-13 19:20:25 +00:00
|
|
|
if (treeRowGroup) {
|
2000-01-06 08:58:05 +00:00
|
|
|
|
|
|
|
// Get the primary frame for the parent of the child that's being added.
|
|
|
|
nsIFrame* innerFrame = GetFrameFor(shell, aPresContext, aContainer);
|
|
|
|
|
2000-06-06 23:13:49 +00:00
|
|
|
nsXULTreeGroupFrame* innerGroup = (nsXULTreeGroupFrame*) innerFrame;
|
|
|
|
treeRowGroup->ClearRowGroupInfo();
|
2000-06-29 23:34:46 +00:00
|
|
|
nsBoxLayoutState state(aPresContext);
|
|
|
|
treeRowGroup->MarkDirtyChildren(state);
|
|
|
|
|
2000-01-06 08:58:05 +00:00
|
|
|
// See if there's a previous sibling.
|
|
|
|
nsIFrame* prevSibling = FindPreviousSibling(shell,
|
|
|
|
aContainer,
|
|
|
|
aIndexInContainer);
|
|
|
|
if (prevSibling || innerFrame) {
|
2000-01-06 09:36:36 +00:00
|
|
|
// We're onscreen, but because of the fact that we can be called to
|
|
|
|
// "kill" a displayed frame (e.g., when you close a tree node), we
|
|
|
|
// have to see if this slaying is taking place. If so, then we don't
|
|
|
|
// really want to do anything. Instead we need to add our node to
|
|
|
|
// the undisplayed content list so that the style system will know
|
|
|
|
// to check it for subsequent display changes (e.g., when you next
|
|
|
|
// reopen).
|
|
|
|
nsCOMPtr<nsIStyleContext> styleContext;
|
|
|
|
nsCOMPtr<nsIAtom> tagName;
|
|
|
|
aChild->GetTag(*getter_AddRefs(tagName));
|
|
|
|
ResolveStyleContext(aPresContext, innerFrame, aChild, tagName, getter_AddRefs(styleContext));
|
|
|
|
|
|
|
|
// Pre-check for display "none" - if we find that, don't reflow at all.
|
|
|
|
const nsStyleDisplay* display = (const nsStyleDisplay*)
|
|
|
|
styleContext->GetStyleData(eStyleStruct_Display);
|
|
|
|
|
|
|
|
if (NS_STYLE_DISPLAY_NONE == display->mDisplay) {
|
|
|
|
|
|
|
|
nsFrameConstructorState state(aPresContext, mFixedContainingBlock,
|
|
|
|
GetAbsoluteContainingBlock(aPresContext, innerFrame),
|
|
|
|
GetFloaterContainingBlock(aPresContext, innerFrame),
|
|
|
|
aFrameState);
|
|
|
|
state.mFrameManager->SetUndisplayedContent(aChild, styleContext);
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2000-06-29 23:34:46 +00:00
|
|
|
if (innerGroup) {
|
|
|
|
//nsBoxLayoutState state(aPresContext);
|
|
|
|
//innerGroup->MarkDirtyChildren(state);
|
|
|
|
|
|
|
|
// Good call. Make sure a full reflow happens.
|
|
|
|
nsIFrame* nextSibling = FindNextSibling(shell, aContainer, aIndexInContainer);
|
|
|
|
if (nextSibling)
|
2000-06-06 23:13:49 +00:00
|
|
|
innerGroup->OnContentInserted(aPresContext, nextSibling, aIndexInContainer);
|
2000-01-06 08:58:05 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2000-06-29 23:34:46 +00:00
|
|
|
shell->FlushPendingNotifications();
|
1999-07-20 23:24:10 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif // INCLUDE_XUL
|
2000-05-21 07:00:35 +00:00
|
|
|
|
1999-02-05 03:55:18 +00:00
|
|
|
// If we have a null parent, then this must be the document element
|
|
|
|
// being inserted
|
|
|
|
if (nsnull == aContainer) {
|
2000-08-07 02:51:35 +00:00
|
|
|
nsCOMPtr<nsIContent> docElement( dont_AddRef( mDocument->GetRootContent() ) );
|
1999-02-05 03:55:18 +00:00
|
|
|
|
2000-08-07 02:51:35 +00:00
|
|
|
if (aChild == docElement.get()) {
|
|
|
|
NS_PRECONDITION(nsnull == mInitialContainingBlock, "initial containing block already created");
|
|
|
|
|
|
|
|
// Get the style context of the containing block frame
|
|
|
|
nsCOMPtr<nsIStyleContext> containerStyle;
|
|
|
|
mDocElementContainingBlock->GetStyleContext(getter_AddRefs(containerStyle));
|
1999-02-05 03:55:18 +00:00
|
|
|
|
2000-08-07 02:51:35 +00:00
|
|
|
// Create frames for the document element and its child elements
|
|
|
|
nsIFrame* docElementFrame;
|
|
|
|
nsFrameConstructorState state(aPresContext, mFixedContainingBlock, nsnull, nsnull, aFrameState);
|
|
|
|
ConstructDocElementFrame(shell, aPresContext,
|
|
|
|
state,
|
|
|
|
docElement,
|
|
|
|
mDocElementContainingBlock,
|
|
|
|
containerStyle,
|
|
|
|
docElementFrame);
|
1999-02-05 03:55:18 +00:00
|
|
|
|
2000-08-07 02:51:35 +00:00
|
|
|
// Set the initial child list for the parent
|
|
|
|
mDocElementContainingBlock->SetInitialChildList(aPresContext,
|
|
|
|
nsnull,
|
|
|
|
docElementFrame);
|
1999-02-05 03:55:18 +00:00
|
|
|
|
2000-08-07 02:51:35 +00:00
|
|
|
// Tell the fixed containing block about its 'fixed' frames
|
|
|
|
if (state.mFixedItems.childList) {
|
|
|
|
mFixedContainingBlock->SetInitialChildList(aPresContext,
|
|
|
|
nsLayoutAtoms::fixedList,
|
|
|
|
state.mFixedItems.childList);
|
|
|
|
}
|
1999-02-05 03:55:18 +00:00
|
|
|
}
|
2000-08-07 07:55:10 +00:00
|
|
|
|
|
|
|
nsCOMPtr<nsIBindingManager> bm;
|
|
|
|
mDocument->GetBindingManager(getter_AddRefs(bm));
|
|
|
|
bm->ProcessAttachedQueue();
|
|
|
|
|
2000-08-07 02:51:35 +00:00
|
|
|
// otherwise this is not a child of the root element, and we
|
|
|
|
// won't let it have a frame.
|
1999-08-06 14:11:14 +00:00
|
|
|
|
1999-09-13 21:25:43 +00:00
|
|
|
} else {
|
1999-02-05 03:55:18 +00:00
|
|
|
// Find the frame that precedes the insertion point.
|
|
|
|
nsIFrame* prevSibling = FindPreviousSibling(shell, aContainer, aIndexInContainer);
|
2000-03-31 07:02:06 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
if (prevSibling) {
|
|
|
|
nsIFrame* parent;
|
|
|
|
prevSibling->GetParent(&parent);
|
|
|
|
nsIFrame* first;
|
|
|
|
parent->FirstChild(aPresContext, nsnull, &first);
|
|
|
|
PRBool found = PR_FALSE;
|
|
|
|
while(first)
|
|
|
|
{
|
|
|
|
if (first == prevSibling) {
|
|
|
|
found = PR_TRUE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
first->GetNextSibling(&first);
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_ASSERTION(found,"Error sibling not in parent!!!!!");
|
|
|
|
}
|
|
|
|
*/
|
|
|
|
|
1999-02-05 03:55:18 +00:00
|
|
|
nsIFrame* nextSibling = nsnull;
|
|
|
|
PRBool isAppend = PR_FALSE;
|
|
|
|
|
|
|
|
// If there is no previous sibling, then find the frame that follows
|
|
|
|
if (nsnull == prevSibling) {
|
|
|
|
nextSibling = FindNextSibling(shell, aContainer, aIndexInContainer);
|
|
|
|
}
|
|
|
|
|
1999-08-31 03:09:40 +00:00
|
|
|
// Get the geometric parent. Use the prev sibling if we have it;
|
|
|
|
// otherwise use the next sibling
|
1999-02-05 03:55:18 +00:00
|
|
|
nsIFrame* parentFrame;
|
1999-08-31 03:09:40 +00:00
|
|
|
if (nsnull != prevSibling) {
|
|
|
|
prevSibling->GetParent(&parentFrame);
|
|
|
|
}
|
|
|
|
else if (nextSibling) {
|
|
|
|
nextSibling->GetParent(&parentFrame);
|
|
|
|
}
|
|
|
|
else {
|
1999-02-05 03:55:18 +00:00
|
|
|
// No previous or next sibling so treat this like an appended frame.
|
|
|
|
isAppend = PR_TRUE;
|
1999-10-06 23:17:28 +00:00
|
|
|
parentFrame = GetFrameFor(shell, aPresContext, aContainer);
|
1999-09-13 21:25:43 +00:00
|
|
|
|
1999-09-13 22:07:15 +00:00
|
|
|
if (parentFrame) {
|
|
|
|
// If we didn't process children when we originally created the frame,
|
|
|
|
// then don't do any processing now
|
|
|
|
nsCOMPtr<nsIAtom> frameType;
|
|
|
|
parentFrame->GetFrameType(getter_AddRefs(frameType));
|
|
|
|
if (frameType.get() == nsLayoutAtoms::objectFrame) {
|
|
|
|
// This handles APPLET, EMBED, and OBJECT
|
|
|
|
return NS_OK;
|
|
|
|
}
|
1999-09-13 21:25:43 +00:00
|
|
|
}
|
1999-02-05 03:55:18 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Construct a new frame
|
|
|
|
if (nsnull != parentFrame) {
|
1999-11-01 15:24:57 +00:00
|
|
|
// If the frame we are manipulating is a special frame then do
|
|
|
|
// something different instead of just inserting newly created
|
|
|
|
// frames.
|
2000-05-25 19:58:51 +00:00
|
|
|
if (IsFrameSpecial(parentFrame)) {
|
1999-11-01 15:24:57 +00:00
|
|
|
// We are pretty harsh here (and definitely not optimal) -- we
|
|
|
|
// wipe out the entire containing block and recreate it from
|
|
|
|
// scratch. The reason is that because we know that a special
|
|
|
|
// inline frame has propogated some of its children upward to be
|
|
|
|
// children of the block and that those frames may need to move
|
|
|
|
// around. This logic guarantees a correct answer.
|
|
|
|
#ifdef DEBUG
|
|
|
|
if (gNoisyContentUpdates) {
|
|
|
|
printf("nsCSSFrameConstructor::ContentInserted: parentFrame=");
|
|
|
|
nsFrame::ListTag(stdout, parentFrame);
|
|
|
|
printf(" is special\n");
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
return ReframeContainingBlock(aPresContext, parentFrame);
|
|
|
|
}
|
|
|
|
|
1999-04-28 19:08:14 +00:00
|
|
|
nsFrameItems frameItems;
|
1999-08-05 03:09:22 +00:00
|
|
|
nsFrameConstructorState state(aPresContext, mFixedContainingBlock,
|
1999-04-28 19:08:14 +00:00
|
|
|
GetAbsoluteContainingBlock(aPresContext, parentFrame),
|
1999-12-06 07:44:18 +00:00
|
|
|
GetFloaterContainingBlock(aPresContext, parentFrame),
|
|
|
|
aFrameState);
|
1999-08-27 21:46:10 +00:00
|
|
|
|
1999-10-29 14:39:48 +00:00
|
|
|
// Recover state for the containing block - we need to know if
|
|
|
|
// it has :first-letter or :first-line style applied to it. The
|
|
|
|
// reason we care is that the internal structure in these cases
|
|
|
|
// is not the normal structure and requires custom updating
|
|
|
|
// logic.
|
1999-08-27 21:46:10 +00:00
|
|
|
nsIFrame* containingBlock = state.mFloatedItems.containingBlock;
|
|
|
|
nsCOMPtr<nsIStyleContext> blockSC;
|
|
|
|
nsCOMPtr<nsIContent> blockContent;
|
1999-08-31 03:09:40 +00:00
|
|
|
PRBool haveFirstLetterStyle = PR_FALSE;
|
|
|
|
PRBool haveFirstLineStyle = PR_FALSE;
|
1999-10-29 14:39:48 +00:00
|
|
|
|
|
|
|
// In order to shave off some cycles, we only dig up the
|
|
|
|
// containing block haveFirst* flags if the parent frame where
|
|
|
|
// the insertion/append is occuring is an inline or block
|
|
|
|
// container. For other types of containers this isn't relevant.
|
1999-08-31 03:09:40 +00:00
|
|
|
const nsStyleDisplay* parentDisplay;
|
|
|
|
parentFrame->GetStyleData(eStyleStruct_Display,
|
|
|
|
(const nsStyleStruct*&)parentDisplay);
|
|
|
|
|
|
|
|
// Examine the parentFrame where the insertion is taking
|
|
|
|
// place. If its a certain kind of container then some special
|
|
|
|
// processing is done.
|
|
|
|
if ((NS_STYLE_DISPLAY_BLOCK == parentDisplay->mDisplay) ||
|
1999-10-29 14:39:48 +00:00
|
|
|
(NS_STYLE_DISPLAY_LIST_ITEM == parentDisplay->mDisplay) ||
|
1999-08-31 03:09:40 +00:00
|
|
|
(NS_STYLE_DISPLAY_INLINE == parentDisplay->mDisplay) ||
|
|
|
|
(NS_STYLE_DISPLAY_INLINE_BLOCK == parentDisplay->mDisplay)) {
|
1999-10-29 14:39:48 +00:00
|
|
|
// Recover the special style flags for the containing block
|
1999-08-31 03:09:40 +00:00
|
|
|
containingBlock->GetStyleContext(getter_AddRefs(blockSC));
|
|
|
|
containingBlock->GetContent(getter_AddRefs(blockContent));
|
|
|
|
HaveSpecialBlockStyle(aPresContext, blockContent, blockSC,
|
|
|
|
&haveFirstLetterStyle,
|
|
|
|
&haveFirstLineStyle);
|
|
|
|
|
|
|
|
if (haveFirstLetterStyle) {
|
|
|
|
// Get the correct parentFrame and prevSibling - if a
|
|
|
|
// letter-frame is present, use its parent.
|
|
|
|
nsCOMPtr<nsIAtom> parentFrameType;
|
|
|
|
parentFrame->GetFrameType(getter_AddRefs(parentFrameType));
|
1999-08-31 07:14:54 +00:00
|
|
|
if (parentFrameType.get() == nsLayoutAtoms::letterFrame) {
|
1999-08-31 03:09:40 +00:00
|
|
|
if (prevSibling) {
|
|
|
|
prevSibling = parentFrame;
|
|
|
|
}
|
|
|
|
parentFrame->GetParent(&parentFrame);
|
1999-08-27 21:46:10 +00:00
|
|
|
}
|
|
|
|
|
1999-10-29 14:39:48 +00:00
|
|
|
// Remove the old letter frames before doing the insertion
|
|
|
|
RemoveLetterFrames(aPresContext, state.mPresShell,
|
|
|
|
state.mFrameManager,
|
|
|
|
state.mFloatedItems.containingBlock);
|
|
|
|
|
1999-08-27 21:46:10 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1999-11-01 15:24:57 +00:00
|
|
|
// If the frame we are manipulating is a special inline frame
|
|
|
|
// then do something different instead of just inserting newly
|
|
|
|
// created frames.
|
2000-05-25 19:58:51 +00:00
|
|
|
if (IsFrameSpecial(parentFrame)) {
|
1999-11-01 15:24:57 +00:00
|
|
|
// We are pretty harsh here (and definitely not optimal) -- we
|
|
|
|
// wipe out the entire containing block and recreate it from
|
|
|
|
// scratch. The reason is that because we know that a special
|
|
|
|
// inline frame has propogated some of its children upward to be
|
|
|
|
// children of the block and that those frames may need to move
|
|
|
|
// around. This logic guarantees a correct answer.
|
|
|
|
nsCOMPtr<nsIContent> parentContainer;
|
|
|
|
blockContent->GetParent(*getter_AddRefs(parentContainer));
|
|
|
|
#ifdef DEBUG
|
|
|
|
if (gNoisyContentUpdates) {
|
|
|
|
printf("nsCSSFrameConstructor::ContentInserted: parentFrame=");
|
|
|
|
nsFrame::ListTag(stdout, parentFrame);
|
|
|
|
printf(" is special inline\n");
|
|
|
|
printf(" ==> blockContent=%p, parentContainer=%p\n",
|
|
|
|
blockContent.get(), parentContainer.get());
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
if (parentContainer) {
|
|
|
|
PRInt32 ix;
|
|
|
|
parentContainer->IndexOf(blockContent, ix);
|
|
|
|
ContentReplaced(aPresContext, parentContainer, blockContent, blockContent, ix);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
// XXX uh oh. the block that needs reworking has no parent...
|
|
|
|
}
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2000-03-10 01:10:44 +00:00
|
|
|
rv = ConstructFrame(shell, aPresContext, state, aChild, parentFrame, frameItems);
|
2000-07-28 00:35:30 +00:00
|
|
|
nsCOMPtr<nsIBindingManager> bm;
|
|
|
|
mDocument->GetBindingManager(getter_AddRefs(bm));
|
|
|
|
bm->ProcessAttachedQueue();
|
|
|
|
|
2000-04-04 01:28:15 +00:00
|
|
|
// process the current pseudo frame state
|
|
|
|
if (!state.mPseudoFrames.IsEmpty()) {
|
|
|
|
ProcessPseudoFrames(aPresContext, state.mPseudoFrames, frameItems);
|
|
|
|
}
|
1999-11-01 15:24:57 +00:00
|
|
|
|
1999-11-24 21:10:49 +00:00
|
|
|
// XXX Bug 19949
|
|
|
|
// Although select frame are inline we do not want to call
|
|
|
|
// WipeContainingBlock because it will throw away the entire select frame and
|
|
|
|
// start over which is something we do not want to do
|
|
|
|
//
|
|
|
|
nsCOMPtr<nsIDOMHTMLSelectElement> selectContent(do_QueryInterface(aContainer));
|
|
|
|
if (!selectContent) {
|
|
|
|
// Perform special check for diddling around with the frames in
|
|
|
|
// a special inline frame.
|
|
|
|
if (WipeContainingBlock(aPresContext, state, blockContent, parentFrame, frameItems.childList)) {
|
|
|
|
return NS_OK;
|
|
|
|
}
|
1999-11-01 15:24:57 +00:00
|
|
|
}
|
1999-08-27 21:46:10 +00:00
|
|
|
|
1999-08-31 03:09:40 +00:00
|
|
|
if (haveFirstLineStyle) {
|
|
|
|
// It's possible that the new frame goes into a first-line
|
|
|
|
// frame. Look at it and see...
|
|
|
|
if (isAppend) {
|
|
|
|
// Use append logic when appending
|
1999-12-04 23:49:50 +00:00
|
|
|
AppendFirstLineFrames(shell, aPresContext, state, aContainer, parentFrame,
|
1999-08-31 03:09:40 +00:00
|
|
|
frameItems);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
// Use more complicated insert logic when inserting
|
|
|
|
InsertFirstLineFrames(aPresContext, state, aContainer,
|
|
|
|
containingBlock, &parentFrame,
|
|
|
|
prevSibling, frameItems);
|
|
|
|
}
|
|
|
|
}
|
1999-02-05 03:55:18 +00:00
|
|
|
|
|
|
|
nsIFrame* newFrame = frameItems.childList;
|
|
|
|
if (NS_SUCCEEDED(rv) && (nsnull != newFrame)) {
|
1999-11-01 15:24:57 +00:00
|
|
|
|
1999-02-05 03:55:18 +00:00
|
|
|
// Notify the parent frame
|
|
|
|
if (isAppend) {
|
1999-08-31 03:09:40 +00:00
|
|
|
rv = AppendFrames(aPresContext, shell, state.mFrameManager,
|
|
|
|
aContainer, parentFrame, newFrame);
|
1999-02-05 03:55:18 +00:00
|
|
|
} else {
|
1999-04-06 04:58:05 +00:00
|
|
|
if (!prevSibling) {
|
|
|
|
// We're inserting the new frame as the first child. See if the
|
|
|
|
// parent has a :before pseudo-element
|
|
|
|
nsIFrame* firstChild;
|
2000-01-22 01:16:50 +00:00
|
|
|
parentFrame->FirstChild(aPresContext, nsnull, &firstChild);
|
1999-04-06 04:58:05 +00:00
|
|
|
|
1999-09-02 05:21:39 +00:00
|
|
|
if (firstChild && IsGeneratedContentFor(aContainer, firstChild, nsCSSAtoms::beforePseudo)) {
|
1999-04-07 03:10:59 +00:00
|
|
|
// Insert the new frames after the :before pseudo-element
|
|
|
|
prevSibling = firstChild;
|
1999-04-06 04:58:05 +00:00
|
|
|
}
|
|
|
|
}
|
2000-01-28 02:19:45 +00:00
|
|
|
// check for a table caption which goes on an additional child list
|
2000-04-28 21:05:31 +00:00
|
|
|
nsIFrame* outerTableFrame;
|
|
|
|
if (GetCaptionAdjustedParent(parentFrame, newFrame, &outerTableFrame)) {
|
|
|
|
rv = state.mFrameManager->AppendFrames(aPresContext, *shell, outerTableFrame,
|
|
|
|
nsLayoutAtoms::captionList, newFrame);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
rv = state.mFrameManager->InsertFrames(aPresContext, *shell, parentFrame,
|
|
|
|
nsnull, prevSibling, newFrame);
|
|
|
|
}
|
1999-02-05 03:55:18 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// If there are new absolutely positioned child frames, then notify
|
|
|
|
// the parent
|
|
|
|
// XXX We can't just assume these frames are being appended, we need to
|
|
|
|
// determine where in the list they should be inserted...
|
1999-04-28 19:08:14 +00:00
|
|
|
if (state.mAbsoluteItems.childList) {
|
1999-11-24 06:03:41 +00:00
|
|
|
rv = state.mAbsoluteItems.containingBlock->AppendFrames(aPresContext, *shell,
|
1999-02-05 03:55:18 +00:00
|
|
|
nsLayoutAtoms::absoluteList,
|
1999-04-28 19:08:14 +00:00
|
|
|
state.mAbsoluteItems.childList);
|
1999-02-05 03:55:18 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// If there are new fixed positioned child frames, then notify
|
|
|
|
// the parent
|
|
|
|
// XXX We can't just assume these frames are being appended, we need to
|
|
|
|
// determine where in the list they should be inserted...
|
1999-04-28 19:08:14 +00:00
|
|
|
if (state.mFixedItems.childList) {
|
1999-11-24 06:03:41 +00:00
|
|
|
rv = state.mFixedItems.containingBlock->AppendFrames(aPresContext, *shell,
|
1999-02-05 03:55:18 +00:00
|
|
|
nsLayoutAtoms::fixedList,
|
1999-04-28 19:08:14 +00:00
|
|
|
state.mFixedItems.childList);
|
1999-02-05 03:55:18 +00:00
|
|
|
}
|
1999-02-26 17:11:54 +00:00
|
|
|
|
|
|
|
// If there are new floating child frames, then notify
|
|
|
|
// the parent
|
|
|
|
// XXX We can't just assume these frames are being appended, we need to
|
|
|
|
// determine where in the list they should be inserted...
|
1999-04-28 19:08:14 +00:00
|
|
|
if (state.mFloatedItems.childList) {
|
1999-11-24 06:03:41 +00:00
|
|
|
rv = state.mFloatedItems.containingBlock->AppendFrames(aPresContext, *shell,
|
1999-04-28 19:08:14 +00:00
|
|
|
nsLayoutAtoms::floaterList,
|
|
|
|
state.mFloatedItems.childList);
|
1999-02-26 17:11:54 +00:00
|
|
|
}
|
1999-08-27 21:46:10 +00:00
|
|
|
|
1999-10-29 14:39:48 +00:00
|
|
|
if (haveFirstLetterStyle) {
|
|
|
|
// Recover the letter frames for the containing block when
|
|
|
|
// it has first-letter style.
|
1999-12-04 23:49:50 +00:00
|
|
|
RecoverLetterFrames(shell, aPresContext, state,
|
1999-10-29 14:39:48 +00:00
|
|
|
state.mFloatedItems.containingBlock);
|
1999-08-27 21:46:10 +00:00
|
|
|
}
|
1999-10-29 14:39:48 +00:00
|
|
|
|
1999-02-05 03:55:18 +00:00
|
|
|
}
|
|
|
|
}
|
1999-08-27 21:46:10 +00:00
|
|
|
|
1999-08-06 21:14:45 +00:00
|
|
|
// Here we have been notified that content has been insert
|
|
|
|
// so if the select now has a single item
|
|
|
|
// we need to go in and removed the dummy frame
|
|
|
|
nsCOMPtr<nsIDOMHTMLSelectElement> selectElement;
|
2000-02-02 22:24:56 +00:00
|
|
|
nsresult result = aContainer->QueryInterface(NS_GET_IID(nsIDOMHTMLSelectElement),
|
1999-08-06 21:14:45 +00:00
|
|
|
(void**)getter_AddRefs(selectElement));
|
|
|
|
if (NS_SUCCEEDED(result) && selectElement) {
|
|
|
|
RemoveDummyFrameFromSelect(aPresContext, shell, aContainer, aChild, selectElement);
|
|
|
|
}
|
|
|
|
|
1999-02-05 03:55:18 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsCSSFrameConstructor::ContentReplaced(nsIPresContext* aPresContext,
|
|
|
|
nsIContent* aContainer,
|
|
|
|
nsIContent* aOldChild,
|
|
|
|
nsIContent* aNewChild,
|
|
|
|
PRInt32 aIndexInContainer)
|
|
|
|
{
|
|
|
|
// XXX For now, do a brute force remove and insert.
|
|
|
|
nsresult res = ContentRemoved(aPresContext, aContainer,
|
|
|
|
aOldChild, aIndexInContainer);
|
|
|
|
if (NS_OK == res) {
|
|
|
|
res = ContentInserted(aPresContext, aContainer,
|
1999-12-06 07:44:18 +00:00
|
|
|
aNewChild, aIndexInContainer, nsnull);
|
1999-02-05 03:55:18 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
1999-04-27 03:10:45 +00:00
|
|
|
// Returns PR_TRUE if aAncestorFrame is an ancestor frame of aFrame
|
|
|
|
static PRBool
|
|
|
|
IsAncestorFrame(nsIFrame* aFrame, nsIFrame* aAncestorFrame)
|
|
|
|
{
|
|
|
|
nsIFrame* parentFrame;
|
|
|
|
aFrame->GetParent(&parentFrame);
|
|
|
|
|
|
|
|
while (parentFrame) {
|
|
|
|
if (parentFrame == aAncestorFrame) {
|
|
|
|
return PR_TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
parentFrame->GetParent(&parentFrame);
|
|
|
|
}
|
|
|
|
|
|
|
|
return PR_FALSE;
|
|
|
|
}
|
|
|
|
|
1999-07-07 20:33:07 +00:00
|
|
|
/**
|
|
|
|
* Called to delete a frame subtree. Two important things happen:
|
|
|
|
* 1. for each frame in the subtree we remove the mapping from the
|
|
|
|
* content object to its frame
|
|
|
|
* 2. for child frames that have been moved out of the flow we delete
|
|
|
|
* the out-of-flow frame as well
|
|
|
|
*
|
1999-11-21 04:06:44 +00:00
|
|
|
* Note: this function should only be called by DeletingFrameSubtree()
|
|
|
|
*
|
1999-07-07 20:33:07 +00:00
|
|
|
* @param aRemovedFrame this is the frame that was removed from the
|
|
|
|
* content model. As we recurse we need to remember this so we
|
|
|
|
* can check if out-of-flow frames are a descendent of the frame
|
|
|
|
* being removed
|
|
|
|
* @param aFrame the local subtree that is being deleted. This is initially
|
|
|
|
* the same as aRemovedFrame, but as we recurse down the tree
|
|
|
|
* this changes
|
|
|
|
*/
|
1999-04-27 03:10:45 +00:00
|
|
|
static nsresult
|
1999-11-21 04:06:44 +00:00
|
|
|
DoDeletingFrameSubtree(nsIPresContext* aPresContext,
|
|
|
|
nsIPresShell* aPresShell,
|
|
|
|
nsIFrameManager* aFrameManager,
|
|
|
|
nsIFrame* aRemovedFrame,
|
|
|
|
nsIFrame* aFrame)
|
|
|
|
{
|
|
|
|
NS_PRECONDITION(aFrameManager, "no frame manager");
|
|
|
|
|
|
|
|
// Remove the mapping from the content object to its frame
|
|
|
|
nsCOMPtr<nsIContent> content;
|
|
|
|
aFrame->GetContent(getter_AddRefs(content));
|
2000-04-18 05:38:05 +00:00
|
|
|
if ( content ) {
|
|
|
|
aFrameManager->SetPrimaryFrameFor(content, nsnull);
|
|
|
|
aFrameManager->ClearAllUndisplayedContentIn(content);
|
|
|
|
}
|
1999-11-21 04:06:44 +00:00
|
|
|
|
|
|
|
// Walk aFrame's child frames
|
|
|
|
nsIAtom* childListName = nsnull;
|
|
|
|
PRInt32 childListIndex = 0;
|
|
|
|
|
|
|
|
do {
|
|
|
|
// Recursively walk aFrame's child frames looking for placeholder frames
|
|
|
|
nsIFrame* childFrame;
|
2000-01-22 01:16:50 +00:00
|
|
|
aFrame->FirstChild(aPresContext, childListName, &childFrame);
|
1999-11-21 04:06:44 +00:00
|
|
|
while (childFrame) {
|
|
|
|
nsIAtom* frameType;
|
|
|
|
PRBool isPlaceholder;
|
|
|
|
|
|
|
|
// See if it's a placeholder frame
|
|
|
|
childFrame->GetFrameType(&frameType);
|
|
|
|
isPlaceholder = (nsLayoutAtoms::placeholderFrame == frameType);
|
|
|
|
NS_IF_RELEASE(frameType);
|
|
|
|
|
|
|
|
if (isPlaceholder) {
|
|
|
|
// Get the out-of-flow frame
|
|
|
|
nsIFrame* outOfFlowFrame = ((nsPlaceholderFrame*)childFrame)->GetOutOfFlowFrame();
|
|
|
|
NS_ASSERTION(outOfFlowFrame, "no out-of-flow frame");
|
|
|
|
|
|
|
|
// Remove the mapping from the out-of-flow frame to its placeholder
|
|
|
|
aFrameManager->SetPlaceholderFrameFor(outOfFlowFrame, nsnull);
|
|
|
|
|
|
|
|
// Recursively find and delete any of its out-of-flow frames, and remove
|
|
|
|
// the mapping from content objects to frames
|
|
|
|
DoDeletingFrameSubtree(aPresContext, aPresShell, aFrameManager, aRemovedFrame,
|
|
|
|
outOfFlowFrame);
|
|
|
|
|
|
|
|
// Don't delete the out-of-flow frame if aRemovedFrame is one of its
|
|
|
|
// ancestor frames, because when aRemovedFrame is deleted it will delete
|
|
|
|
// its child frames including this out-of-flow frame
|
|
|
|
if (!IsAncestorFrame(outOfFlowFrame, aRemovedFrame)) {
|
|
|
|
// Get the out-of-flow frame's parent
|
|
|
|
nsIFrame* parentFrame;
|
|
|
|
outOfFlowFrame->GetParent(&parentFrame);
|
|
|
|
|
|
|
|
// Get the child list name for the out-of-flow frame
|
|
|
|
nsIAtom* listName;
|
2000-01-22 01:16:50 +00:00
|
|
|
GetChildListNameFor(aPresContext, parentFrame, outOfFlowFrame, &listName);
|
1999-11-21 04:06:44 +00:00
|
|
|
|
|
|
|
// Ask the parent to delete the out-of-flow frame
|
1999-11-24 06:03:41 +00:00
|
|
|
aFrameManager->RemoveFrame(aPresContext, *aPresShell, parentFrame,
|
1999-11-21 04:06:44 +00:00
|
|
|
listName, outOfFlowFrame);
|
|
|
|
NS_IF_RELEASE(listName);
|
|
|
|
}
|
|
|
|
|
|
|
|
} else {
|
|
|
|
// Recursively find and delete any of its out-of-flow frames, and remove
|
|
|
|
// the mapping from content objects to frames
|
|
|
|
DoDeletingFrameSubtree(aPresContext, aPresShell, aFrameManager, aRemovedFrame,
|
|
|
|
childFrame);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Get the next sibling child frame
|
|
|
|
childFrame->GetNextSibling(&childFrame);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Look for any additional named child lists
|
|
|
|
NS_IF_RELEASE(childListName);
|
|
|
|
aFrame->GetAdditionalChildListName(childListIndex++, &childListName);
|
|
|
|
} while (childListName);
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Called to delete a frame subtree. Calls DoDeletingFrameSubtree()
|
|
|
|
* for aFrame and each of its continuing frames
|
|
|
|
*/
|
|
|
|
static nsresult
|
1999-08-05 03:09:22 +00:00
|
|
|
DeletingFrameSubtree(nsIPresContext* aPresContext,
|
|
|
|
nsIPresShell* aPresShell,
|
|
|
|
nsIFrameManager* aFrameManager,
|
|
|
|
nsIFrame* aFrame)
|
1999-04-27 03:10:45 +00:00
|
|
|
{
|
1999-08-05 03:30:09 +00:00
|
|
|
// If there's no frame manager it's probably because the pres shell is
|
|
|
|
// being destroyed
|
|
|
|
if (aFrameManager) {
|
1999-11-04 05:23:11 +00:00
|
|
|
while (aFrame) {
|
2000-06-07 06:58:45 +00:00
|
|
|
// If it's a "special" block-in-inline frame, then we need to
|
|
|
|
// remember to delete our special siblings, too.
|
|
|
|
if (IsFrameSpecial(aFrame)) {
|
|
|
|
nsIFrame* specialSibling;
|
|
|
|
GetSpecialSibling(aFrameManager, aFrame, &specialSibling);
|
|
|
|
DeletingFrameSubtree(aPresContext, aPresShell, aFrameManager, specialSibling);
|
|
|
|
}
|
|
|
|
|
1999-11-21 04:06:44 +00:00
|
|
|
DoDeletingFrameSubtree(aPresContext, aPresShell, aFrameManager,
|
|
|
|
aFrame, aFrame);
|
|
|
|
|
|
|
|
// If it's split, then get the continuing frame. Note that we only do
|
|
|
|
// this for the top-most frame being deleted. Don't do it if we're
|
|
|
|
// recursing over a subtree, because those continuing frames should be
|
|
|
|
// found as part of the walk over the top-most frame's continuing frames.
|
|
|
|
// Walking them again will make this an N^2/2 algorithm
|
1999-11-04 05:23:11 +00:00
|
|
|
aFrame->GetNextInFlow(&aFrame);
|
|
|
|
}
|
1999-04-27 03:10:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
1999-07-09 20:58:16 +00:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsCSSFrameConstructor::RemoveMappingsForFrameSubtree(nsIPresContext* aPresContext,
|
1999-12-06 07:44:18 +00:00
|
|
|
nsIFrame* aRemovedFrame,
|
|
|
|
nsILayoutHistoryState* aFrameState)
|
1999-07-09 20:58:16 +00:00
|
|
|
{
|
|
|
|
nsCOMPtr<nsIPresShell> presShell;
|
|
|
|
aPresContext->GetShell(getter_AddRefs(presShell));
|
1999-08-05 03:09:22 +00:00
|
|
|
nsCOMPtr<nsIFrameManager> frameManager;
|
|
|
|
presShell->GetFrameManager(getter_AddRefs(frameManager));
|
1999-12-06 07:44:18 +00:00
|
|
|
|
|
|
|
// Save the frame tree's state before deleting it
|
2000-01-14 09:28:54 +00:00
|
|
|
CaptureStateFor(aPresContext, aRemovedFrame, mTempFrameTreeState);
|
1999-12-06 07:44:18 +00:00
|
|
|
|
1999-11-21 04:06:44 +00:00
|
|
|
return DeletingFrameSubtree(aPresContext, presShell, frameManager, aRemovedFrame);
|
1999-07-09 20:58:16 +00:00
|
|
|
}
|
|
|
|
|
1999-02-05 03:55:18 +00:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsCSSFrameConstructor::ContentRemoved(nsIPresContext* aPresContext,
|
|
|
|
nsIContent* aContainer,
|
|
|
|
nsIContent* aChild,
|
|
|
|
PRInt32 aIndexInContainer)
|
|
|
|
{
|
1999-11-01 15:24:57 +00:00
|
|
|
#ifdef DEBUG
|
|
|
|
if (gNoisyContentUpdates) {
|
|
|
|
printf("nsCSSFrameConstructor::ContentRemoved container=%p child=%p index=%d\n",
|
|
|
|
aContainer, aChild, aIndexInContainer);
|
|
|
|
if (gReallyNoisyContentUpdates) {
|
|
|
|
aContainer->List(stdout, 0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
1999-08-05 03:09:22 +00:00
|
|
|
nsCOMPtr<nsIPresShell> shell;
|
1999-02-12 17:45:58 +00:00
|
|
|
aPresContext->GetShell(getter_AddRefs(shell));
|
1999-08-05 03:09:22 +00:00
|
|
|
nsCOMPtr<nsIFrameManager> frameManager;
|
|
|
|
shell->GetFrameManager(getter_AddRefs(frameManager));
|
|
|
|
nsresult rv = NS_OK;
|
1999-02-05 03:55:18 +00:00
|
|
|
|
1999-07-02 04:47:05 +00:00
|
|
|
// Find the child frame that maps the content
|
1999-02-05 03:55:18 +00:00
|
|
|
nsIFrame* childFrame;
|
1999-08-06 14:11:14 +00:00
|
|
|
shell->GetPrimaryFrameFor(aChild, &childFrame);
|
|
|
|
|
1999-10-02 04:27:40 +00:00
|
|
|
if (! childFrame) {
|
|
|
|
frameManager->ClearUndisplayedContentIn(aChild, aContainer);
|
|
|
|
}
|
1999-10-29 14:39:48 +00:00
|
|
|
|
1999-08-06 14:11:14 +00:00
|
|
|
// When the last item is removed from a select,
|
|
|
|
// we need to add a pseudo frame so select gets sized as the best it can
|
|
|
|
// so here we see if it is a select and then we get the number of options
|
1999-08-08 19:16:09 +00:00
|
|
|
nsresult result = NS_ERROR_FAILURE;
|
1999-08-31 03:09:40 +00:00
|
|
|
if (aContainer && childFrame) {
|
1999-08-10 21:28:06 +00:00
|
|
|
nsCOMPtr<nsIDOMHTMLSelectElement> selectElement;
|
2000-02-02 22:24:56 +00:00
|
|
|
result = aContainer->QueryInterface(NS_GET_IID(nsIDOMHTMLSelectElement),
|
1999-08-06 14:11:14 +00:00
|
|
|
(void**)getter_AddRefs(selectElement));
|
1999-08-10 21:28:06 +00:00
|
|
|
if (NS_SUCCEEDED(result) && selectElement) {
|
|
|
|
PRUint32 numOptions = 0;
|
|
|
|
result = selectElement->GetLength(&numOptions);
|
1999-08-25 13:42:59 +00:00
|
|
|
nsIFrame * selectFrame; // XXX temp needed only native controls
|
|
|
|
shell->GetPrimaryFrameFor(aContainer, &selectFrame);// XXX temp needed only native controls
|
|
|
|
|
1999-08-10 21:28:06 +00:00
|
|
|
// For "select" add the pseudo frame after the last item is deleted
|
|
|
|
nsIFrame* parentFrame = nsnull;
|
|
|
|
childFrame->GetParent(&parentFrame);
|
1999-08-25 13:42:59 +00:00
|
|
|
if (parentFrame == selectFrame) { // XXX temp needed only native controls
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
1999-08-10 21:28:06 +00:00
|
|
|
if (NS_SUCCEEDED(result) && shell && parentFrame && 1 == numOptions) {
|
1999-08-06 14:11:14 +00:00
|
|
|
|
1999-08-10 21:28:06 +00:00
|
|
|
nsIStyleContext* styleContext = nsnull;
|
|
|
|
nsIFrame* generatedFrame = nsnull;
|
1999-12-06 07:44:18 +00:00
|
|
|
nsFrameConstructorState state(aPresContext, nsnull, nsnull, nsnull, nsnull);
|
1999-08-10 21:28:06 +00:00
|
|
|
|
|
|
|
//shell->GetPrimaryFrameFor(aContainer, &contentFrame);
|
|
|
|
parentFrame->GetStyleContext(&styleContext);
|
1999-12-04 23:49:50 +00:00
|
|
|
if (CreateGeneratedContentFrame(shell, aPresContext, state, parentFrame, aContainer,
|
1999-08-10 21:28:06 +00:00
|
|
|
styleContext, nsLayoutAtoms::dummyOptionPseudo,
|
1999-10-29 14:39:48 +00:00
|
|
|
PR_FALSE, &generatedFrame)) {
|
1999-08-10 21:28:06 +00:00
|
|
|
// Add the generated frame to the child list
|
1999-11-24 06:03:41 +00:00
|
|
|
frameManager->AppendFrames(aPresContext, *shell, parentFrame, nsnull, generatedFrame);
|
1999-08-10 21:28:06 +00:00
|
|
|
}
|
2000-03-22 02:54:26 +00:00
|
|
|
NS_IF_RELEASE(styleContext);
|
1999-08-10 21:28:06 +00:00
|
|
|
}
|
1999-08-06 14:11:14 +00:00
|
|
|
}
|
1999-08-10 21:28:06 +00:00
|
|
|
}
|
1999-02-05 03:55:18 +00:00
|
|
|
|
1999-07-10 00:51:35 +00:00
|
|
|
#ifdef INCLUDE_XUL
|
1999-07-20 23:24:10 +00:00
|
|
|
if (aContainer) {
|
|
|
|
nsCOMPtr<nsIAtom> tag;
|
|
|
|
aContainer->GetTag(*getter_AddRefs(tag));
|
|
|
|
if (tag.get() == nsXULAtoms::treechildren ||
|
|
|
|
tag.get() == nsXULAtoms::treeitem) {
|
|
|
|
if (childFrame) {
|
1999-07-14 19:21:27 +00:00
|
|
|
// Convert to a tree row group frame.
|
|
|
|
nsIFrame* parentFrame;
|
|
|
|
childFrame->GetParent(&parentFrame);
|
2000-06-06 23:13:49 +00:00
|
|
|
nsXULTreeGroupFrame* treeRowGroup = (nsXULTreeGroupFrame*)parentFrame;
|
|
|
|
if (treeRowGroup) {
|
|
|
|
treeRowGroup->OnContentRemoved(aPresContext, childFrame, aIndexInContainer);
|
|
|
|
}
|
1999-07-10 00:51:35 +00:00
|
|
|
}
|
2000-06-06 23:13:49 +00:00
|
|
|
{
|
1999-07-20 23:24:10 +00:00
|
|
|
// Ensure that we notify the outermost row group that the item
|
|
|
|
// has been removed (so that we can update the scrollbar state).
|
|
|
|
// Walk up to the outermost tree row group frame and tell it that
|
2000-01-06 08:58:05 +00:00
|
|
|
// the scrollbar thumb should be updated.
|
1999-07-22 10:06:38 +00:00
|
|
|
nsCOMPtr<nsIContent> parent;
|
1999-07-20 23:24:10 +00:00
|
|
|
nsCOMPtr<nsIContent> child = dont_QueryInterface(aContainer);
|
1999-07-22 10:06:38 +00:00
|
|
|
child->GetParent(*getter_AddRefs(parent));
|
1999-07-20 23:24:10 +00:00
|
|
|
while (parent) {
|
|
|
|
parent->GetTag(*getter_AddRefs(tag));
|
|
|
|
if (tag.get() == nsXULAtoms::tree)
|
|
|
|
break;
|
|
|
|
child = parent;
|
1999-07-22 10:06:38 +00:00
|
|
|
child->GetParent(*getter_AddRefs(parent));
|
1999-07-20 23:24:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (parent) {
|
|
|
|
// We found it. Get the primary frame.
|
|
|
|
nsIFrame* parentFrame = GetFrameFor(shell, aPresContext, child);
|
|
|
|
|
|
|
|
// Convert to a tree row group frame.
|
2000-06-06 23:13:49 +00:00
|
|
|
nsXULTreeOuterGroupFrame* treeRowGroup = (nsXULTreeOuterGroupFrame*)parentFrame;
|
|
|
|
if (treeRowGroup) {
|
|
|
|
nsBoxLayoutState state(aPresContext);
|
|
|
|
treeRowGroup->MarkDirtyChildren(state);
|
|
|
|
treeRowGroup->ClearRowGroupInfo();
|
2000-06-29 23:34:46 +00:00
|
|
|
shell->FlushPendingNotifications();
|
2000-06-06 23:13:49 +00:00
|
|
|
}
|
2000-06-19 22:57:39 +00:00
|
|
|
return NS_OK;
|
1999-07-20 23:24:10 +00:00
|
|
|
}
|
|
|
|
}
|
1999-07-10 00:51:35 +00:00
|
|
|
}
|
1999-07-20 23:24:10 +00:00
|
|
|
}
|
1999-07-10 00:51:35 +00:00
|
|
|
#endif // INCLUDE_XUL
|
|
|
|
|
1999-07-20 23:24:10 +00:00
|
|
|
if (childFrame) {
|
1999-11-01 15:24:57 +00:00
|
|
|
// If the frame we are manipulating is a special frame then do
|
|
|
|
// something different instead of just inserting newly created
|
|
|
|
// frames.
|
2000-06-21 02:35:28 +00:00
|
|
|
if (IsFrameSpecial(childFrame)) {
|
1999-11-01 15:24:57 +00:00
|
|
|
// We are pretty harsh here (and definitely not optimal) -- we
|
|
|
|
// wipe out the entire containing block and recreate it from
|
|
|
|
// scratch. The reason is that because we know that a special
|
|
|
|
// inline frame has propogated some of its children upward to be
|
|
|
|
// children of the block and that those frames may need to move
|
|
|
|
// around. This logic guarantees a correct answer.
|
|
|
|
#ifdef DEBUG
|
|
|
|
if (gNoisyContentUpdates) {
|
2000-06-21 02:35:28 +00:00
|
|
|
printf("nsCSSFrameConstructor::ContentRemoved: childFrame=");
|
|
|
|
nsFrame::ListTag(stdout, childFrame);
|
1999-11-01 15:24:57 +00:00
|
|
|
printf(" is special\n");
|
|
|
|
}
|
|
|
|
#endif
|
2000-06-21 02:35:28 +00:00
|
|
|
return ReframeContainingBlock(aPresContext, childFrame);
|
1999-11-01 15:24:57 +00:00
|
|
|
}
|
|
|
|
|
2000-06-21 02:35:28 +00:00
|
|
|
// Get the childFrame's parent frame
|
|
|
|
nsIFrame* parentFrame;
|
|
|
|
childFrame->GetParent(&parentFrame);
|
|
|
|
|
1999-08-27 21:46:10 +00:00
|
|
|
// Examine the containing-block for the removed content and see if
|
|
|
|
// :first-letter style applies.
|
|
|
|
nsIFrame* containingBlock =
|
|
|
|
GetFloaterContainingBlock(aPresContext, parentFrame);
|
|
|
|
nsCOMPtr<nsIStyleContext> blockSC;
|
|
|
|
containingBlock->GetStyleContext(getter_AddRefs(blockSC));
|
|
|
|
nsCOMPtr<nsIContent> blockContent;
|
|
|
|
containingBlock->GetContent(getter_AddRefs(blockContent));
|
|
|
|
PRBool haveFLS = HaveFirstLetterStyle(aPresContext, blockContent, blockSC);
|
|
|
|
if (haveFLS) {
|
|
|
|
// Trap out to special routine that handles adjusting a blocks
|
|
|
|
// frame tree when first-letter style is present.
|
|
|
|
#ifdef NOISY_FIRST_LETTER
|
|
|
|
printf("ContentRemoved: containingBlock=");
|
|
|
|
nsFrame::ListTag(stdout, containingBlock);
|
|
|
|
printf(" parentFrame=");
|
|
|
|
nsFrame::ListTag(stdout, parentFrame);
|
|
|
|
printf(" childFrame=");
|
|
|
|
nsFrame::ListTag(stdout, childFrame);
|
|
|
|
printf("\n");
|
|
|
|
#endif
|
|
|
|
|
1999-10-29 14:39:48 +00:00
|
|
|
// First update the containing blocks structure by removing the
|
|
|
|
// existing letter frames. This makes the subsequent logic
|
|
|
|
// simpler.
|
|
|
|
RemoveLetterFrames(aPresContext, shell, frameManager, containingBlock);
|
|
|
|
|
|
|
|
// Recover childFrame and parentFrame
|
|
|
|
shell->GetPrimaryFrameFor(aChild, &childFrame);
|
|
|
|
if (!childFrame) {
|
|
|
|
frameManager->ClearUndisplayedContentIn(aChild, aContainer);
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
childFrame->GetParent(&parentFrame);
|
|
|
|
|
1999-08-27 21:46:10 +00:00
|
|
|
#ifdef NOISY_FIRST_LETTER
|
1999-10-29 14:39:48 +00:00
|
|
|
printf(" ==> revised parentFrame=");
|
|
|
|
nsFrame::ListTag(stdout, parentFrame);
|
|
|
|
printf(" childFrame=");
|
|
|
|
nsFrame::ListTag(stdout, childFrame);
|
|
|
|
printf("\n");
|
1999-08-27 21:46:10 +00:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
1999-07-07 20:33:07 +00:00
|
|
|
// Walk the frame subtree deleting any out-of-flow frames, and
|
|
|
|
// remove the mapping from content objects to frames
|
1999-11-21 04:06:44 +00:00
|
|
|
DeletingFrameSubtree(aPresContext, shell, frameManager, childFrame);
|
1999-04-27 03:10:45 +00:00
|
|
|
|
2000-05-25 19:26:27 +00:00
|
|
|
// See if the child frame is a floating frame
|
|
|
|
// (positioned frames are handled below in the "else" clause)
|
1999-02-26 17:11:54 +00:00
|
|
|
const nsStyleDisplay* display;
|
|
|
|
childFrame->GetStyleData(eStyleStruct_Display,
|
|
|
|
(const nsStyleStruct*&)display);
|
2000-05-25 19:26:27 +00:00
|
|
|
if (display->IsFloating()) {
|
1999-10-29 14:39:48 +00:00
|
|
|
#ifdef NOISY_FIRST_LETTER
|
|
|
|
printf(" ==> child display is still floating!\n");
|
|
|
|
#endif
|
1999-02-06 17:10:42 +00:00
|
|
|
// Get the placeholder frame
|
|
|
|
nsIFrame* placeholderFrame;
|
1999-08-05 03:09:22 +00:00
|
|
|
frameManager->GetPlaceholderFrameFor(childFrame, &placeholderFrame);
|
1999-02-06 17:10:42 +00:00
|
|
|
|
|
|
|
// Remove the mapping from the frame to its placeholder
|
1999-08-05 03:09:22 +00:00
|
|
|
frameManager->SetPlaceholderFrameFor(childFrame, nsnull);
|
1999-02-06 17:10:42 +00:00
|
|
|
|
1999-02-26 17:11:54 +00:00
|
|
|
// Now we remove the floating frame
|
|
|
|
|
|
|
|
// XXX has to be done first for now: the blocks line list
|
|
|
|
// contains an array of pointers to the placeholder - we have to
|
|
|
|
// remove the floater first (which gets rid of the lines
|
|
|
|
// reference to the placeholder and floater) and then remove the
|
|
|
|
// placeholder
|
1999-11-24 06:03:41 +00:00
|
|
|
rv = frameManager->RemoveFrame(aPresContext, *shell, parentFrame,
|
1999-08-05 03:09:22 +00:00
|
|
|
nsLayoutAtoms::floaterList, childFrame);
|
1999-02-05 03:55:18 +00:00
|
|
|
|
1999-02-26 17:11:54 +00:00
|
|
|
// Remove the placeholder frame first (XXX second for now) (so
|
|
|
|
// that it doesn't retain a dangling pointer to memory)
|
1999-02-05 03:55:18 +00:00
|
|
|
if (nsnull != placeholderFrame) {
|
1999-02-10 01:36:30 +00:00
|
|
|
placeholderFrame->GetParent(&parentFrame);
|
1999-11-21 04:06:44 +00:00
|
|
|
DeletingFrameSubtree(aPresContext, shell, frameManager, placeholderFrame);
|
1999-11-24 06:03:41 +00:00
|
|
|
rv = frameManager->RemoveFrame(aPresContext, *shell, parentFrame,
|
1999-08-27 21:46:10 +00:00
|
|
|
nsnull, placeholderFrame);
|
1999-02-05 03:55:18 +00:00
|
|
|
}
|
1999-02-26 17:11:54 +00:00
|
|
|
}
|
|
|
|
else {
|
1999-07-07 20:33:07 +00:00
|
|
|
// See if it's absolutely or fixed positioned
|
1999-02-26 17:11:54 +00:00
|
|
|
const nsStylePosition* position;
|
|
|
|
childFrame->GetStyleData(eStyleStruct_Position, (const nsStyleStruct*&)position);
|
|
|
|
if (position->IsAbsolutelyPositioned()) {
|
|
|
|
// Get the placeholder frame
|
|
|
|
nsIFrame* placeholderFrame;
|
1999-08-05 03:09:22 +00:00
|
|
|
frameManager->GetPlaceholderFrameFor(childFrame, &placeholderFrame);
|
1999-02-26 17:11:54 +00:00
|
|
|
|
|
|
|
// Remove the mapping from the frame to its placeholder
|
1999-08-05 03:09:22 +00:00
|
|
|
frameManager->SetPlaceholderFrameFor(childFrame, nsnull);
|
1999-02-26 17:11:54 +00:00
|
|
|
|
|
|
|
// Generate two notifications. First for the absolutely positioned
|
|
|
|
// frame
|
1999-11-24 06:03:41 +00:00
|
|
|
rv = frameManager->RemoveFrame(aPresContext, *shell, parentFrame,
|
1999-07-24 03:58:35 +00:00
|
|
|
(NS_STYLE_POSITION_FIXED == position->mPosition) ?
|
|
|
|
nsLayoutAtoms::fixedList : nsLayoutAtoms::absoluteList, childFrame);
|
1999-02-26 17:11:54 +00:00
|
|
|
|
|
|
|
// Now the placeholder frame
|
|
|
|
if (nsnull != placeholderFrame) {
|
|
|
|
placeholderFrame->GetParent(&parentFrame);
|
1999-11-24 06:03:41 +00:00
|
|
|
rv = frameManager->RemoveFrame(aPresContext, *shell, parentFrame, nsnull,
|
1999-08-05 03:09:22 +00:00
|
|
|
placeholderFrame);
|
1999-02-26 17:11:54 +00:00
|
|
|
}
|
1999-02-05 03:55:18 +00:00
|
|
|
|
1999-02-26 17:11:54 +00:00
|
|
|
} else {
|
|
|
|
// Notify the parent frame that it should delete the frame
|
2000-04-28 21:05:31 +00:00
|
|
|
// check for a table caption which goes on an additional child list with a different parent
|
|
|
|
nsIFrame* outerTableFrame;
|
|
|
|
if (GetCaptionAdjustedParent(parentFrame, childFrame, &outerTableFrame)) {
|
|
|
|
rv = frameManager->RemoveFrame(aPresContext, *shell, outerTableFrame,
|
|
|
|
nsLayoutAtoms::captionList, childFrame);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
rv = frameManager->RemoveFrame(aPresContext, *shell, parentFrame,
|
|
|
|
nsnull, childFrame);
|
|
|
|
}
|
1999-02-26 17:11:54 +00:00
|
|
|
}
|
1999-02-05 03:55:18 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (mInitialContainingBlock == childFrame) {
|
|
|
|
mInitialContainingBlock = nsnull;
|
|
|
|
}
|
1999-08-06 14:11:14 +00:00
|
|
|
|
1999-10-29 14:39:48 +00:00
|
|
|
if (haveFLS && mInitialContainingBlock) {
|
|
|
|
nsFrameConstructorState state(aPresContext, mFixedContainingBlock,
|
|
|
|
GetAbsoluteContainingBlock(aPresContext,
|
|
|
|
parentFrame),
|
|
|
|
GetFloaterContainingBlock(aPresContext,
|
1999-12-06 07:44:18 +00:00
|
|
|
parentFrame),
|
|
|
|
nsnull);
|
1999-12-04 23:49:50 +00:00
|
|
|
RecoverLetterFrames(shell, aPresContext, state, containingBlock);
|
1999-08-27 21:46:10 +00:00
|
|
|
}
|
1999-02-05 03:55:18 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
1999-04-02 22:57:25 +00:00
|
|
|
static void
|
1999-11-24 06:03:41 +00:00
|
|
|
ApplyRenderingChangeToTree(nsIPresContext* aPresContext,
|
1999-09-25 05:02:52 +00:00
|
|
|
nsIFrame* aFrame,
|
|
|
|
nsIViewManager* aViewManager);
|
|
|
|
|
|
|
|
static void
|
2000-01-22 01:16:50 +00:00
|
|
|
SyncAndInvalidateView(nsIPresContext* aPresContext,
|
|
|
|
nsIView* aView,
|
|
|
|
nsIFrame* aFrame,
|
1999-09-25 05:02:52 +00:00
|
|
|
nsIViewManager* aViewManager)
|
|
|
|
{
|
|
|
|
const nsStyleColor* color;
|
|
|
|
const nsStyleDisplay* disp;
|
|
|
|
aFrame->GetStyleData(eStyleStruct_Color, (const nsStyleStruct*&) color);
|
|
|
|
aFrame->GetStyleData(eStyleStruct_Display, (const nsStyleStruct*&) disp);
|
|
|
|
|
|
|
|
aViewManager->SetViewOpacity(aView, color->mOpacity);
|
1999-09-29 03:37:02 +00:00
|
|
|
|
|
|
|
// See if the view should be hidden or visible
|
|
|
|
PRBool viewIsVisible = PR_TRUE;
|
|
|
|
PRBool viewHasTransparentContent = (color->mBackgroundFlags &
|
|
|
|
NS_STYLE_BG_COLOR_TRANSPARENT) == NS_STYLE_BG_COLOR_TRANSPARENT;
|
|
|
|
|
|
|
|
if (NS_STYLE_VISIBILITY_COLLAPSE == disp->mVisible) {
|
|
|
|
viewIsVisible = PR_FALSE;
|
|
|
|
}
|
|
|
|
else if (NS_STYLE_VISIBILITY_HIDDEN == disp->mVisible) {
|
|
|
|
// If it has a widget, hide the view because the widget can't deal with it
|
|
|
|
nsIWidget* widget = nsnull;
|
|
|
|
aView->GetWidget(widget);
|
|
|
|
if (widget) {
|
|
|
|
viewIsVisible = PR_FALSE;
|
|
|
|
NS_RELEASE(widget);
|
1999-09-27 07:28:06 +00:00
|
|
|
}
|
|
|
|
else {
|
1999-09-29 03:37:02 +00:00
|
|
|
// If it's a scroll frame, then hide the view. This means that
|
|
|
|
// child elements can't override their parent's visibility, but
|
|
|
|
// it's not practical to leave it visible in all cases because
|
|
|
|
// the scrollbars will be showing
|
|
|
|
nsIAtom* frameType;
|
|
|
|
aFrame->GetFrameType(&frameType);
|
|
|
|
|
|
|
|
if (frameType == nsLayoutAtoms::scrollFrame) {
|
|
|
|
viewIsVisible = PR_FALSE;
|
|
|
|
} else {
|
|
|
|
// If it's a container element, then leave the view visible, but
|
|
|
|
// mark it as having transparent content. The reason we need to
|
|
|
|
// do this is that child elements can override their parent's
|
|
|
|
// hidden visibility and be visible anyway
|
|
|
|
nsIFrame* firstChild;
|
|
|
|
|
2000-01-22 01:16:50 +00:00
|
|
|
aFrame->FirstChild(aPresContext, nsnull, &firstChild);
|
1999-09-29 03:37:02 +00:00
|
|
|
if (firstChild) {
|
|
|
|
// It's not a left frame, so the view needs to be visible, but
|
|
|
|
// marked as having transparent content
|
|
|
|
viewHasTransparentContent = PR_TRUE;
|
|
|
|
} else {
|
|
|
|
// It's a leaf frame so go ahead and hide the view
|
|
|
|
viewIsVisible = PR_FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
NS_IF_RELEASE(frameType);
|
1999-09-25 05:02:52 +00:00
|
|
|
}
|
1999-09-29 03:37:02 +00:00
|
|
|
}
|
|
|
|
|
1999-10-13 01:02:53 +00:00
|
|
|
// If the frame has visible content that overflows the content area, then we
|
|
|
|
// need the view marked as having transparent content
|
|
|
|
if (NS_STYLE_OVERFLOW_VISIBLE == disp->mOverflow) {
|
|
|
|
nsFrameState frameState;
|
|
|
|
|
|
|
|
aFrame->GetFrameState(&frameState);
|
|
|
|
if (frameState & NS_FRAME_OUTSIDE_CHILDREN) {
|
|
|
|
viewHasTransparentContent = PR_TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1999-09-29 03:37:02 +00:00
|
|
|
if (viewIsVisible) {
|
|
|
|
aViewManager->SetViewContentTransparency(aView, viewHasTransparentContent);
|
|
|
|
aViewManager->SetViewVisibility(aView, nsViewVisibility_kShow);
|
1999-11-14 02:51:25 +00:00
|
|
|
aViewManager->UpdateView(aView, NS_VMREFRESH_NO_SYNC);
|
1999-09-25 05:02:52 +00:00
|
|
|
}
|
1999-09-27 07:28:06 +00:00
|
|
|
else {
|
1999-09-29 03:37:02 +00:00
|
|
|
aViewManager->SetViewVisibility(aView, nsViewVisibility_kHide);
|
1999-09-25 05:02:52 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
1999-11-24 06:03:41 +00:00
|
|
|
UpdateViewsForTree(nsIPresContext* aPresContext, nsIFrame* aFrame,
|
1999-09-25 05:02:52 +00:00
|
|
|
nsIViewManager* aViewManager, nsRect& aBoundsRect)
|
1999-04-02 22:57:25 +00:00
|
|
|
{
|
|
|
|
nsIView* view;
|
1999-11-24 06:03:41 +00:00
|
|
|
aFrame->GetView(aPresContext, &view);
|
1999-04-02 22:57:25 +00:00
|
|
|
|
|
|
|
if (view) {
|
2000-01-22 01:16:50 +00:00
|
|
|
SyncAndInvalidateView(aPresContext, view, aFrame, aViewManager);
|
1999-04-02 22:57:25 +00:00
|
|
|
}
|
|
|
|
|
1999-09-25 05:02:52 +00:00
|
|
|
nsRect bounds;
|
|
|
|
aFrame->GetRect(bounds);
|
|
|
|
nsPoint parentOffset(bounds.x, bounds.y);
|
|
|
|
bounds.x = 0;
|
|
|
|
bounds.y = 0;
|
|
|
|
|
|
|
|
// now do children of frame
|
1999-04-02 22:57:25 +00:00
|
|
|
PRInt32 listIndex = 0;
|
|
|
|
nsIAtom* childList = nsnull;
|
1999-09-25 05:02:52 +00:00
|
|
|
nsIAtom* frameType = nsnull;
|
1999-04-02 22:57:25 +00:00
|
|
|
|
|
|
|
do {
|
|
|
|
nsIFrame* child = nsnull;
|
2000-01-22 01:16:50 +00:00
|
|
|
aFrame->FirstChild(aPresContext, childList, &child);
|
1999-04-02 22:57:25 +00:00
|
|
|
while (child) {
|
1999-09-25 05:02:52 +00:00
|
|
|
nsFrameState childState;
|
|
|
|
child->GetFrameState(&childState);
|
|
|
|
if (NS_FRAME_OUT_OF_FLOW != (childState & NS_FRAME_OUT_OF_FLOW)) {
|
|
|
|
// only do frames that are in flow
|
|
|
|
child->GetFrameType(&frameType);
|
|
|
|
if (nsLayoutAtoms::placeholderFrame == frameType) { // placeholder
|
|
|
|
// get out of flow frame and start over there
|
|
|
|
nsIFrame* outOfFlowFrame = ((nsPlaceholderFrame*)child)->GetOutOfFlowFrame();
|
|
|
|
NS_ASSERTION(outOfFlowFrame, "no out-of-flow frame");
|
|
|
|
|
|
|
|
ApplyRenderingChangeToTree(aPresContext, outOfFlowFrame, aViewManager);
|
|
|
|
}
|
|
|
|
else { // regular frame
|
|
|
|
nsRect childBounds;
|
|
|
|
UpdateViewsForTree(aPresContext, child, aViewManager, childBounds);
|
|
|
|
bounds.UnionRect(bounds, childBounds);
|
|
|
|
}
|
|
|
|
NS_IF_RELEASE(frameType);
|
1999-06-10 05:24:00 +00:00
|
|
|
}
|
1999-04-02 22:57:25 +00:00
|
|
|
child->GetNextSibling(&child);
|
|
|
|
}
|
|
|
|
NS_IF_RELEASE(childList);
|
|
|
|
aFrame->GetAdditionalChildListName(listIndex++, &childList);
|
|
|
|
} while (childList);
|
|
|
|
NS_IF_RELEASE(childList);
|
1999-09-25 05:02:52 +00:00
|
|
|
aBoundsRect = bounds;
|
|
|
|
aBoundsRect += parentOffset;
|
1999-04-02 22:57:25 +00:00
|
|
|
}
|
1999-02-05 03:55:18 +00:00
|
|
|
|
|
|
|
static void
|
1999-11-24 06:03:41 +00:00
|
|
|
ApplyRenderingChangeToTree(nsIPresContext* aPresContext,
|
1999-09-25 05:02:52 +00:00
|
|
|
nsIFrame* aFrame,
|
|
|
|
nsIViewManager* aViewManager)
|
1999-02-05 03:55:18 +00:00
|
|
|
{
|
1999-09-25 05:02:52 +00:00
|
|
|
nsIViewManager* viewManager = aViewManager;
|
1999-02-05 03:55:18 +00:00
|
|
|
|
|
|
|
// Trigger rendering updates by damaging this frame and any
|
|
|
|
// continuations of this frame.
|
1999-02-27 07:15:09 +00:00
|
|
|
|
|
|
|
// XXX this needs to detect the need for a view due to an opacity change and deal with it...
|
|
|
|
|
1999-09-25 05:02:52 +00:00
|
|
|
if (viewManager) {
|
|
|
|
NS_ADDREF(viewManager); // add local ref
|
|
|
|
viewManager->BeginUpdateViewBatch();
|
|
|
|
}
|
1999-02-05 03:55:18 +00:00
|
|
|
while (nsnull != aFrame) {
|
|
|
|
// Get the frame's bounding rect
|
1999-09-25 05:02:52 +00:00
|
|
|
nsRect invalidRect;
|
|
|
|
nsPoint viewOffset;
|
1999-02-05 03:55:18 +00:00
|
|
|
|
|
|
|
// Get view if this frame has one and trigger an update. If the
|
|
|
|
// frame doesn't have a view, find the nearest containing view
|
|
|
|
// (adjusting r's coordinate system to reflect the nesting) and
|
|
|
|
// update there.
|
1999-09-25 05:02:52 +00:00
|
|
|
nsIView* view = nsnull;
|
1999-11-24 06:03:41 +00:00
|
|
|
aFrame->GetView(aPresContext, &view);
|
1999-09-25 05:02:52 +00:00
|
|
|
nsIView* parentView;
|
|
|
|
if (! view) { // XXX can view have children outside it?
|
1999-11-24 06:03:41 +00:00
|
|
|
aFrame->GetOffsetFromView(aPresContext, viewOffset, &parentView);
|
1999-09-25 05:02:52 +00:00
|
|
|
NS_ASSERTION(nsnull != parentView, "no view");
|
|
|
|
if (! viewManager) {
|
|
|
|
parentView->GetViewManager(viewManager);
|
|
|
|
viewManager->BeginUpdateViewBatch();
|
|
|
|
}
|
1999-02-05 03:55:18 +00:00
|
|
|
}
|
1999-09-25 05:02:52 +00:00
|
|
|
else {
|
|
|
|
if (! viewManager) {
|
|
|
|
view->GetViewManager(viewManager);
|
|
|
|
viewManager->BeginUpdateViewBatch();
|
|
|
|
}
|
1999-02-05 03:55:18 +00:00
|
|
|
}
|
1999-09-25 05:02:52 +00:00
|
|
|
UpdateViewsForTree(aPresContext, aFrame, viewManager, invalidRect);
|
|
|
|
|
|
|
|
if (! view) { // if frame has view, will already be invalidated
|
|
|
|
// XXX Instead of calling this we should really be calling
|
|
|
|
// Invalidate on on the nsFrame (which does this)
|
|
|
|
const nsStyleSpacing* spacing;
|
|
|
|
aFrame->GetStyleData(eStyleStruct_Spacing, (const nsStyleStruct*&)spacing);
|
|
|
|
nscoord width;
|
|
|
|
spacing->GetOutlineWidth(width);
|
|
|
|
if (width > 0) {
|
|
|
|
invalidRect.Inflate(width, width);
|
|
|
|
}
|
|
|
|
nsPoint frameOrigin;
|
|
|
|
aFrame->GetOrigin(frameOrigin);
|
|
|
|
invalidRect -= frameOrigin;
|
|
|
|
invalidRect += viewOffset;
|
|
|
|
viewManager->UpdateView(parentView, invalidRect, NS_VMREFRESH_NO_SYNC);
|
1999-08-19 14:29:55 +00:00
|
|
|
}
|
|
|
|
|
1999-02-24 04:48:08 +00:00
|
|
|
aFrame->GetNextInFlow(&aFrame);
|
1999-02-05 03:55:18 +00:00
|
|
|
}
|
|
|
|
|
1999-09-25 05:02:52 +00:00
|
|
|
if (viewManager) {
|
2000-07-28 21:54:49 +00:00
|
|
|
viewManager->EndUpdateViewBatch(NS_VMREFRESH_NO_SYNC);
|
1999-02-05 03:55:18 +00:00
|
|
|
NS_RELEASE(viewManager);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2000-06-07 06:58:45 +00:00
|
|
|
nsresult
|
|
|
|
nsCSSFrameConstructor::StyleChangeReflow(nsIPresContext* aPresContext,
|
|
|
|
nsIFrame* aFrame,
|
|
|
|
nsIAtom* aAttribute)
|
1999-02-05 03:55:18 +00:00
|
|
|
{
|
2000-04-25 07:10:48 +00:00
|
|
|
|
|
|
|
// Is it a box? If so we can coelesce.
|
|
|
|
nsresult rv;
|
|
|
|
nsCOMPtr<nsIBox> box = do_QueryInterface(aFrame, &rv);
|
|
|
|
if (NS_SUCCEEDED(rv) && box) {
|
|
|
|
nsBoxLayoutState state(aPresContext);
|
|
|
|
box->MarkStyleChange(state);
|
2000-06-07 06:58:45 +00:00
|
|
|
}
|
|
|
|
else if (IsFrameSpecial(aFrame)) {
|
|
|
|
// We are pretty harsh here (and definitely not optimal) -- we
|
|
|
|
// wipe out the entire containing block and recreate it from
|
|
|
|
// scratch. The reason is that because we know that a special
|
|
|
|
// inline frame has propogated some of its children upward to be
|
|
|
|
// children of the block and that those frames may need to move
|
|
|
|
// around. This logic guarantees a correct answer.
|
|
|
|
#ifdef DEBUG
|
|
|
|
if (gNoisyContentUpdates) {
|
|
|
|
printf("nsCSSFrameConstructor::StyleChangeReflow: aFrame=");
|
|
|
|
nsFrame::ListTag(stdout, aFrame);
|
|
|
|
printf(" is special\n");
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
ReframeContainingBlock(aPresContext, aFrame);
|
|
|
|
}
|
|
|
|
else {
|
2000-04-25 07:10:48 +00:00
|
|
|
nsCOMPtr<nsIPresShell> shell;
|
|
|
|
aPresContext->GetShell(getter_AddRefs(shell));
|
1) implememted box reflow coelescing.
2) implemented gfx scrollbars for list boxes
3) fixed progess meter to be an animated gif
4) fixed bugs 23521, 24721, 19114, 20546, 24385, 24457, 23156, 20226, 22543
-r hyatt, troy, rod
2000-02-09 22:02:40 +00:00
|
|
|
|
|
|
|
|
2000-04-25 07:10:48 +00:00
|
|
|
nsIReflowCommand* reflowCmd;
|
2000-06-07 06:58:45 +00:00
|
|
|
rv = NS_NewHTMLReflowCommand(&reflowCmd, aFrame,
|
|
|
|
nsIReflowCommand::StyleChanged,
|
|
|
|
nsnull,
|
|
|
|
aAttribute);
|
1) implememted box reflow coelescing.
2) implemented gfx scrollbars for list boxes
3) fixed progess meter to be an animated gif
4) fixed bugs 23521, 24721, 19114, 20546, 24385, 24457, 23156, 20226, 22543
-r hyatt, troy, rod
2000-02-09 22:02:40 +00:00
|
|
|
|
2000-04-25 07:10:48 +00:00
|
|
|
if (NS_SUCCEEDED(rv)) {
|
|
|
|
shell->AppendReflowCommand(reflowCmd);
|
|
|
|
NS_RELEASE(reflowCmd);
|
|
|
|
}
|
1999-02-05 03:55:18 +00:00
|
|
|
}
|
2000-06-07 06:58:45 +00:00
|
|
|
|
|
|
|
return NS_OK;
|
1999-02-05 03:55:18 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsCSSFrameConstructor::ContentChanged(nsIPresContext* aPresContext,
|
|
|
|
nsIContent* aContent,
|
|
|
|
nsISupports* aSubContent)
|
|
|
|
{
|
1999-02-12 17:45:58 +00:00
|
|
|
nsCOMPtr<nsIPresShell> shell;
|
|
|
|
aPresContext->GetShell(getter_AddRefs(shell));
|
1999-02-05 03:55:18 +00:00
|
|
|
nsresult rv = NS_OK;
|
|
|
|
|
|
|
|
// Find the child frame
|
|
|
|
nsIFrame* frame;
|
1999-02-12 17:45:58 +00:00
|
|
|
shell->GetPrimaryFrameFor(aContent, &frame);
|
1999-02-05 03:55:18 +00:00
|
|
|
|
|
|
|
// Notify the first frame that maps the content. It will generate a reflow
|
|
|
|
// command
|
|
|
|
|
|
|
|
// It's possible the frame whose content changed isn't inserted into the
|
|
|
|
// frame hierarchy yet, or that there is no frame that maps the content
|
|
|
|
if (nsnull != frame) {
|
|
|
|
#if 0
|
|
|
|
NS_FRAME_LOG(NS_FRAME_TRACE_CALLS,
|
|
|
|
("nsHTMLStyleSheet::ContentChanged: content=%p[%s] subcontent=%p frame=%p",
|
|
|
|
aContent, ContentTag(aContent, 0),
|
|
|
|
aSubContent, frame));
|
|
|
|
#endif
|
1999-10-29 14:39:48 +00:00
|
|
|
|
|
|
|
// Special check for text content that is a child of a letter
|
|
|
|
// frame. There are two interesting cases that we have to handle
|
|
|
|
// carefully: text content that is going empty (which means we
|
|
|
|
// should select a new text node as the first-letter text) or text
|
|
|
|
// content that empty but is no longer empty (it might be the
|
|
|
|
// first-letter text but isn't currently).
|
|
|
|
//
|
|
|
|
// To deal with both of these we make a simple change: map a
|
|
|
|
// ContentChanged into a ContentReplaced when we are changing text
|
|
|
|
// that is part of a first-letter situation.
|
|
|
|
PRBool doContentChanged = PR_TRUE;
|
|
|
|
nsCOMPtr<nsITextContent> textContent(do_QueryInterface(aContent));
|
|
|
|
if (textContent) {
|
|
|
|
// Ok, it's text content. Now do some real work...
|
|
|
|
nsIFrame* block = GetFloaterContainingBlock(aPresContext, frame);
|
|
|
|
if (block) {
|
|
|
|
// See if the block has first-letter style applied to it.
|
|
|
|
nsCOMPtr<nsIContent> blockContent;
|
|
|
|
block->GetContent(getter_AddRefs(blockContent));
|
|
|
|
nsCOMPtr<nsIStyleContext> blockSC;
|
|
|
|
block->GetStyleContext(getter_AddRefs(blockSC));
|
|
|
|
PRBool haveFirstLetterStyle =
|
|
|
|
HaveFirstLetterStyle(aPresContext, blockContent, blockSC);
|
|
|
|
if (haveFirstLetterStyle) {
|
|
|
|
// The block has first-letter style. Use content-replaced to
|
|
|
|
// repair the blocks frame structure properly.
|
|
|
|
nsCOMPtr<nsIContent> container;
|
|
|
|
aContent->GetParent(*getter_AddRefs(container));
|
|
|
|
if (container) {
|
|
|
|
PRInt32 ix;
|
|
|
|
container->IndexOf(aContent, ix);
|
|
|
|
doContentChanged = PR_FALSE;
|
|
|
|
rv = ContentReplaced(aPresContext, container,
|
|
|
|
aContent, aContent, ix);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (doContentChanged) {
|
|
|
|
frame->ContentChanged(aPresContext, aContent, aSubContent);
|
|
|
|
}
|
1999-02-05 03:55:18 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return rv;
|
|
|
|
}
|
1999-02-27 07:15:09 +00:00
|
|
|
|
1999-03-25 06:41:43 +00:00
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsCSSFrameConstructor::ProcessRestyledFrames(nsStyleChangeList& aChangeList,
|
|
|
|
nsIPresContext* aPresContext)
|
|
|
|
{
|
|
|
|
PRInt32 count = aChangeList.Count();
|
|
|
|
while (0 < count--) {
|
|
|
|
nsIFrame* frame;
|
1999-10-02 04:27:40 +00:00
|
|
|
nsIContent* content;
|
1999-03-25 06:41:43 +00:00
|
|
|
PRInt32 hint;
|
1999-10-02 04:27:40 +00:00
|
|
|
aChangeList.ChangeAt(count, frame, content, hint);
|
1999-03-25 06:41:43 +00:00
|
|
|
switch (hint) {
|
|
|
|
case NS_STYLE_HINT_RECONSTRUCT_ALL:
|
|
|
|
NS_ERROR("This shouldn't happen");
|
|
|
|
break;
|
|
|
|
case NS_STYLE_HINT_FRAMECHANGE:
|
|
|
|
RecreateFramesForContent(aPresContext, content);
|
|
|
|
break;
|
|
|
|
case NS_STYLE_HINT_REFLOW:
|
|
|
|
StyleChangeReflow(aPresContext, frame, nsnull);
|
|
|
|
break;
|
|
|
|
case NS_STYLE_HINT_VISUAL:
|
1999-11-24 06:03:41 +00:00
|
|
|
ApplyRenderingChangeToTree(aPresContext, frame, nsnull);
|
1999-03-25 06:41:43 +00:00
|
|
|
break;
|
|
|
|
case NS_STYLE_HINT_CONTENT:
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
aChangeList.Clear();
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
1999-02-27 07:15:09 +00:00
|
|
|
NS_IMETHODIMP
|
1999-04-20 00:05:14 +00:00
|
|
|
nsCSSFrameConstructor::ContentStatesChanged(nsIPresContext* aPresContext,
|
|
|
|
nsIContent* aContent1,
|
|
|
|
nsIContent* aContent2)
|
1999-02-27 07:15:09 +00:00
|
|
|
{
|
|
|
|
nsresult result = NS_OK;
|
|
|
|
|
|
|
|
nsCOMPtr<nsIPresShell> shell;
|
|
|
|
aPresContext->GetShell(getter_AddRefs(shell));
|
|
|
|
|
1999-04-20 00:05:14 +00:00
|
|
|
NS_ASSERTION(shell, "couldn't get pres shell");
|
|
|
|
if (shell) {
|
|
|
|
nsIStyleSet* styleSet;
|
|
|
|
shell->GetStyleSet(&styleSet);
|
|
|
|
|
|
|
|
NS_ASSERTION(styleSet, "couldn't get style set");
|
|
|
|
if (styleSet) { // test if any style rules exist which are dependent on content state
|
|
|
|
nsIFrame* primaryFrame1 = nsnull;
|
|
|
|
nsIFrame* primaryFrame2 = nsnull;
|
|
|
|
if (aContent1 && (NS_OK == styleSet->HasStateDependentStyle(aPresContext, aContent1))) {
|
|
|
|
shell->GetPrimaryFrameFor(aContent1, &primaryFrame1);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
aContent1 = nsnull;
|
|
|
|
}
|
1999-02-27 07:15:09 +00:00
|
|
|
|
1999-04-20 00:05:14 +00:00
|
|
|
if (aContent2 && (aContent2 != aContent1) &&
|
|
|
|
(NS_OK == styleSet->HasStateDependentStyle(aPresContext, aContent2))) {
|
|
|
|
shell->GetPrimaryFrameFor(aContent2, &primaryFrame2);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
aContent2 = nsnull;
|
|
|
|
}
|
|
|
|
NS_RELEASE(styleSet);
|
|
|
|
|
|
|
|
if (primaryFrame1 && primaryFrame2) { // detect if one is parent of other, skip child
|
|
|
|
nsIFrame* parent;
|
|
|
|
primaryFrame1->GetParent(&parent);
|
|
|
|
while (parent) {
|
|
|
|
if (parent == primaryFrame2) { // frame2 is frame1's parent, skip frame1
|
|
|
|
primaryFrame1 = nsnull;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
parent->GetParent(&parent);
|
|
|
|
}
|
|
|
|
if (primaryFrame1) {
|
|
|
|
primaryFrame2->GetParent(&parent);
|
|
|
|
while (parent) {
|
|
|
|
if (parent == primaryFrame1) { // frame1 is frame2's parent, skip frame2
|
|
|
|
primaryFrame2 = nsnull;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
parent->GetParent(&parent);
|
1999-03-25 06:41:43 +00:00
|
|
|
}
|
1999-02-27 07:15:09 +00:00
|
|
|
}
|
1999-04-20 00:05:14 +00:00
|
|
|
}
|
|
|
|
|
1999-09-21 07:55:37 +00:00
|
|
|
nsCOMPtr<nsIFrameManager> frameManager;
|
|
|
|
shell->GetFrameManager(getter_AddRefs(frameManager));
|
1999-04-20 00:05:14 +00:00
|
|
|
|
|
|
|
if (primaryFrame1) {
|
|
|
|
nsStyleChangeList changeList1;
|
|
|
|
nsStyleChangeList changeList2;
|
|
|
|
PRInt32 frameChange1 = NS_STYLE_HINT_NONE;
|
|
|
|
PRInt32 frameChange2 = NS_STYLE_HINT_NONE;
|
1999-11-24 06:03:41 +00:00
|
|
|
frameManager->ComputeStyleChangeFor(aPresContext, primaryFrame1,
|
1999-10-15 23:14:44 +00:00
|
|
|
kNameSpaceID_Unknown, nsnull,
|
|
|
|
changeList1, NS_STYLE_HINT_NONE, frameChange1);
|
1999-04-20 00:05:14 +00:00
|
|
|
|
|
|
|
if ((frameChange1 != NS_STYLE_HINT_RECONSTRUCT_ALL) && (primaryFrame2)) {
|
1999-11-24 06:03:41 +00:00
|
|
|
frameManager->ComputeStyleChangeFor(aPresContext, primaryFrame2,
|
1999-10-15 23:14:44 +00:00
|
|
|
kNameSpaceID_Unknown, nsnull,
|
|
|
|
changeList2, NS_STYLE_HINT_NONE, frameChange2);
|
1999-04-20 00:05:14 +00:00
|
|
|
}
|
1999-02-27 07:15:09 +00:00
|
|
|
|
1999-04-20 00:05:14 +00:00
|
|
|
if ((frameChange1 == NS_STYLE_HINT_RECONSTRUCT_ALL) ||
|
|
|
|
(frameChange2 == NS_STYLE_HINT_RECONSTRUCT_ALL)) {
|
|
|
|
result = ReconstructDocElementHierarchy(aPresContext);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
switch (frameChange1) {
|
|
|
|
case NS_STYLE_HINT_FRAMECHANGE:
|
|
|
|
result = RecreateFramesForContent(aPresContext, aContent1);
|
1999-04-20 14:23:18 +00:00
|
|
|
changeList1.Clear();
|
|
|
|
break;
|
1999-04-20 00:05:14 +00:00
|
|
|
case NS_STYLE_HINT_REFLOW:
|
|
|
|
case NS_STYLE_HINT_VISUAL:
|
|
|
|
case NS_STYLE_HINT_CONTENT:
|
|
|
|
// let primary frame deal with it
|
1999-09-10 05:54:00 +00:00
|
|
|
result = primaryFrame1->ContentStateChanged(aPresContext, aContent1, frameChange1);
|
1999-04-20 00:05:14 +00:00
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
switch (frameChange2) {
|
|
|
|
case NS_STYLE_HINT_FRAMECHANGE:
|
|
|
|
result = RecreateFramesForContent(aPresContext, aContent2);
|
1999-04-20 14:23:18 +00:00
|
|
|
changeList2.Clear();
|
|
|
|
break;
|
1999-04-20 00:05:14 +00:00
|
|
|
case NS_STYLE_HINT_REFLOW:
|
|
|
|
case NS_STYLE_HINT_VISUAL:
|
|
|
|
case NS_STYLE_HINT_CONTENT:
|
|
|
|
// let primary frame deal with it
|
1999-09-10 05:54:00 +00:00
|
|
|
result = primaryFrame2->ContentStateChanged(aPresContext, aContent2, frameChange2);
|
1999-04-20 00:05:14 +00:00
|
|
|
// then process any children that need it
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
1999-04-20 14:23:18 +00:00
|
|
|
ProcessRestyledFrames(changeList1, aPresContext);
|
|
|
|
ProcessRestyledFrames(changeList2, aPresContext);
|
1999-04-20 00:05:14 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (primaryFrame2) {
|
|
|
|
nsStyleChangeList changeList;
|
|
|
|
PRInt32 frameChange = NS_STYLE_HINT_NONE;
|
1999-11-24 06:03:41 +00:00
|
|
|
frameManager->ComputeStyleChangeFor(aPresContext, primaryFrame2,
|
1999-10-15 23:14:44 +00:00
|
|
|
kNameSpaceID_Unknown, nsnull,
|
|
|
|
changeList, NS_STYLE_HINT_NONE, frameChange);
|
1999-04-20 00:05:14 +00:00
|
|
|
|
|
|
|
switch (frameChange) { // max change needed for top level frames
|
|
|
|
case NS_STYLE_HINT_RECONSTRUCT_ALL:
|
|
|
|
result = ReconstructDocElementHierarchy(aPresContext);
|
1999-04-20 14:23:18 +00:00
|
|
|
changeList.Clear();
|
|
|
|
break;
|
1999-04-20 00:05:14 +00:00
|
|
|
case NS_STYLE_HINT_FRAMECHANGE:
|
|
|
|
result = RecreateFramesForContent(aPresContext, aContent2);
|
1999-04-20 14:23:18 +00:00
|
|
|
changeList.Clear();
|
|
|
|
break;
|
1999-04-20 00:05:14 +00:00
|
|
|
case NS_STYLE_HINT_REFLOW:
|
|
|
|
case NS_STYLE_HINT_VISUAL:
|
|
|
|
case NS_STYLE_HINT_CONTENT:
|
|
|
|
// let primary frame deal with it
|
1999-09-10 05:54:00 +00:00
|
|
|
result = primaryFrame2->ContentStateChanged(aPresContext, aContent2, frameChange);
|
1999-04-20 00:05:14 +00:00
|
|
|
// then process any children that need it
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
1999-04-20 14:23:18 +00:00
|
|
|
ProcessRestyledFrames(changeList, aPresContext);
|
1999-04-20 00:05:14 +00:00
|
|
|
}
|
|
|
|
else { // no frames, reconstruct for content
|
|
|
|
if (aContent1) {
|
|
|
|
result = RecreateFramesForContent(aPresContext, aContent1);
|
|
|
|
}
|
|
|
|
if (aContent2) {
|
|
|
|
result = RecreateFramesForContent(aPresContext, aContent2);
|
|
|
|
}
|
|
|
|
}
|
1999-02-27 07:15:09 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
1999-02-05 03:55:18 +00:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsCSSFrameConstructor::AttributeChanged(nsIPresContext* aPresContext,
|
|
|
|
nsIContent* aContent,
|
1999-10-15 23:14:44 +00:00
|
|
|
PRInt32 aNameSpaceID,
|
1999-02-05 03:55:18 +00:00
|
|
|
nsIAtom* aAttribute,
|
|
|
|
PRInt32 aHint)
|
|
|
|
{
|
|
|
|
nsresult result = NS_OK;
|
|
|
|
|
1999-02-12 17:45:58 +00:00
|
|
|
nsCOMPtr<nsIPresShell> shell;
|
|
|
|
aPresContext->GetShell(getter_AddRefs(shell));
|
1999-03-25 06:41:43 +00:00
|
|
|
nsIFrame* primaryFrame;
|
1999-02-05 03:55:18 +00:00
|
|
|
|
1999-03-25 06:41:43 +00:00
|
|
|
shell->GetPrimaryFrameFor(aContent, &primaryFrame);
|
1999-03-01 16:57:35 +00:00
|
|
|
|
|
|
|
PRBool reconstruct = PR_FALSE;
|
1999-02-05 03:55:18 +00:00
|
|
|
PRBool restyle = PR_FALSE;
|
|
|
|
PRBool reframe = PR_FALSE;
|
|
|
|
|
|
|
|
#if 0
|
|
|
|
NS_FRAME_LOG(NS_FRAME_TRACE_CALLS,
|
|
|
|
("HTMLStyleSheet::AttributeChanged: content=%p[%s] frame=%p",
|
|
|
|
aContent, ContentTag(aContent, 0), frame));
|
|
|
|
#endif
|
|
|
|
|
|
|
|
// the style tag has its own interpretation based on aHint
|
1999-02-27 01:34:32 +00:00
|
|
|
if (NS_STYLE_HINT_UNKNOWN == aHint) {
|
|
|
|
nsIStyledContent* styledContent;
|
2000-02-02 22:24:56 +00:00
|
|
|
result = aContent->QueryInterface(NS_GET_IID(nsIStyledContent), (void**)&styledContent);
|
1999-02-05 03:55:18 +00:00
|
|
|
|
|
|
|
if (NS_OK == result) {
|
|
|
|
// Get style hint from HTML content object.
|
1999-07-07 01:28:43 +00:00
|
|
|
styledContent->GetMappedAttributeImpact(aAttribute, aHint);
|
1999-02-27 01:34:32 +00:00
|
|
|
NS_RELEASE(styledContent);
|
1999-02-05 03:55:18 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
switch (aHint) {
|
|
|
|
default:
|
1999-03-01 16:57:35 +00:00
|
|
|
case NS_STYLE_HINT_RECONSTRUCT_ALL:
|
|
|
|
reconstruct = PR_TRUE;
|
1999-02-05 03:55:18 +00:00
|
|
|
case NS_STYLE_HINT_FRAMECHANGE:
|
|
|
|
reframe = PR_TRUE;
|
|
|
|
case NS_STYLE_HINT_REFLOW:
|
|
|
|
case NS_STYLE_HINT_VISUAL:
|
1999-03-25 06:41:43 +00:00
|
|
|
case NS_STYLE_HINT_UNKNOWN:
|
1999-02-05 03:55:18 +00:00
|
|
|
case NS_STYLE_HINT_CONTENT:
|
|
|
|
case NS_STYLE_HINT_AURAL:
|
|
|
|
restyle = PR_TRUE;
|
|
|
|
break;
|
|
|
|
case NS_STYLE_HINT_NONE:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2000-06-06 23:13:49 +00:00
|
|
|
#ifdef INCLUDE_XUL
|
|
|
|
// The following tree widget trap prevents offscreen tree widget
|
|
|
|
// content from being removed and re-inserted (which is what would
|
|
|
|
// happen otherwise).
|
|
|
|
if (!primaryFrame) {
|
|
|
|
nsCOMPtr<nsIAtom> tag;
|
|
|
|
aContent->GetTag(*getter_AddRefs(tag));
|
|
|
|
if (reframe == PR_FALSE && tag && (tag.get() == nsXULAtoms::treechildren ||
|
2000-08-03 23:21:23 +00:00
|
|
|
tag.get() == nsXULAtoms::treeitem || tag.get() == nsXULAtoms::treerow ||
|
|
|
|
tag.get() == nsXULAtoms::treecell))
|
2000-06-06 23:13:49 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
#endif // INCLUDE_XUL
|
|
|
|
|
1999-02-05 03:55:18 +00:00
|
|
|
// apply changes
|
1999-03-01 16:57:35 +00:00
|
|
|
if (PR_TRUE == reconstruct) {
|
1999-03-25 06:41:43 +00:00
|
|
|
result = ReconstructDocElementHierarchy(aPresContext);
|
1999-03-01 16:57:35 +00:00
|
|
|
}
|
|
|
|
else if (PR_TRUE == reframe) {
|
1999-03-25 06:41:43 +00:00
|
|
|
result = RecreateFramesForContent(aPresContext, aContent);
|
1999-02-05 03:55:18 +00:00
|
|
|
}
|
|
|
|
else if (PR_TRUE == restyle) {
|
|
|
|
// If there is no frame then there is no point in re-styling it,
|
|
|
|
// is there?
|
1999-03-25 06:41:43 +00:00
|
|
|
if (primaryFrame) {
|
|
|
|
PRInt32 maxHint = aHint;
|
|
|
|
nsStyleChangeList changeList;
|
|
|
|
// put primary frame on list to deal with, re-resolve may update or add next in flows
|
1999-10-02 04:27:40 +00:00
|
|
|
changeList.AppendChange(primaryFrame, aContent, maxHint);
|
1999-09-21 07:55:37 +00:00
|
|
|
nsCOMPtr<nsIFrameManager> frameManager;
|
|
|
|
shell->GetFrameManager(getter_AddRefs(frameManager));
|
2000-05-16 02:43:33 +00:00
|
|
|
|
|
|
|
PRBool affects;
|
|
|
|
frameManager->AttributeAffectsStyle(aAttribute, aContent, affects);
|
|
|
|
if (affects) {
|
|
|
|
#ifdef DEBUG_shaver
|
|
|
|
fputc('+', stderr);
|
|
|
|
#endif
|
|
|
|
// there is an effect, so compute it
|
|
|
|
frameManager->ComputeStyleChangeFor(aPresContext, primaryFrame,
|
|
|
|
aNameSpaceID, aAttribute,
|
|
|
|
changeList, aHint, maxHint);
|
|
|
|
} else {
|
|
|
|
#ifdef DEBUG_shaver
|
|
|
|
fputc('-', stderr);
|
|
|
|
#endif
|
|
|
|
// let this frame update itself, but don't walk the whole frame tree
|
|
|
|
maxHint = NS_STYLE_HINT_VISUAL;
|
|
|
|
}
|
1999-03-25 06:41:43 +00:00
|
|
|
|
1999-04-20 14:23:18 +00:00
|
|
|
switch (maxHint) { // maxHint is hint for primary only
|
1999-03-25 06:41:43 +00:00
|
|
|
case NS_STYLE_HINT_RECONSTRUCT_ALL:
|
|
|
|
result = ReconstructDocElementHierarchy(aPresContext);
|
1999-04-20 14:23:18 +00:00
|
|
|
changeList.Clear();
|
1999-03-25 06:41:43 +00:00
|
|
|
break;
|
|
|
|
case NS_STYLE_HINT_FRAMECHANGE:
|
|
|
|
result = RecreateFramesForContent(aPresContext, aContent);
|
1999-04-20 14:23:18 +00:00
|
|
|
changeList.Clear();
|
1999-03-25 06:41:43 +00:00
|
|
|
break;
|
|
|
|
case NS_STYLE_HINT_REFLOW:
|
|
|
|
case NS_STYLE_HINT_VISUAL:
|
|
|
|
case NS_STYLE_HINT_CONTENT:
|
2000-05-06 06:04:08 +00:00
|
|
|
// first check if it is a background change:
|
|
|
|
// - if it is then we may need to notify the canvas frame
|
|
|
|
// so it can take care of invalidating the whole canvas
|
|
|
|
if (aAttribute == nsHTMLAtoms::bgcolor || aAttribute == nsHTMLAtoms::background) {
|
|
|
|
// see if the content element is the root (HTML) or BODY element
|
|
|
|
// NOTE: the assumption here is that the background color or image on
|
|
|
|
// the BODY or HTML element need to have the canvas frame invalidate
|
|
|
|
// so the entire visible regions gets painted
|
|
|
|
nsCOMPtr<nsIContent> rootContent;
|
|
|
|
nsCOMPtr<nsIContent> parentContent;
|
|
|
|
rootContent = getter_AddRefs(mDocument->GetRootContent());
|
|
|
|
aContent->GetParent(*getter_AddRefs(parentContent));
|
|
|
|
if (aContent == rootContent.get() || // content is the root (HTML)
|
|
|
|
parentContent == rootContent ) { // content's parent is root (BODY)
|
|
|
|
// Walk the frame tree up and find the canvas frame
|
|
|
|
nsIFrame *pCanvasFrameCandidate = nsnull;
|
|
|
|
primaryFrame->GetParent(&pCanvasFrameCandidate);
|
|
|
|
while (pCanvasFrameCandidate) {
|
|
|
|
if (IsCanvasFrame(pCanvasFrameCandidate)) {
|
|
|
|
pCanvasFrameCandidate->AttributeChanged(aPresContext,aContent,aNameSpaceID,aAttribute,maxHint);
|
|
|
|
break;
|
|
|
|
} else {
|
|
|
|
pCanvasFrameCandidate->GetParent(&pCanvasFrameCandidate);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
1999-03-25 06:41:43 +00:00
|
|
|
// let the frame deal with it, since we don't know how to
|
1999-10-15 23:14:44 +00:00
|
|
|
result = primaryFrame->AttributeChanged(aPresContext, aContent, aNameSpaceID, aAttribute, maxHint);
|
1999-03-25 06:41:43 +00:00
|
|
|
default:
|
|
|
|
break;
|
1999-02-05 03:55:18 +00:00
|
|
|
}
|
1999-04-20 14:23:18 +00:00
|
|
|
// handle any children (primary may be on list too)
|
|
|
|
ProcessRestyledFrames(changeList, aPresContext);
|
1999-02-05 03:55:18 +00:00
|
|
|
}
|
1999-03-25 06:41:43 +00:00
|
|
|
else { // no frame now, possibly genetate one with new style data
|
|
|
|
result = RecreateFramesForContent(aPresContext, aContent);
|
|
|
|
}
|
1999-02-05 03:55:18 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Style change notifications
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsCSSFrameConstructor::StyleRuleChanged(nsIPresContext* aPresContext,
|
|
|
|
nsIStyleSheet* aStyleSheet,
|
|
|
|
nsIStyleRule* aStyleRule,
|
|
|
|
PRInt32 aHint)
|
|
|
|
{
|
1999-03-25 06:41:43 +00:00
|
|
|
nsresult result = NS_OK;
|
1999-02-12 17:45:58 +00:00
|
|
|
nsCOMPtr<nsIPresShell> shell;
|
|
|
|
aPresContext->GetShell(getter_AddRefs(shell));
|
1999-02-05 03:55:18 +00:00
|
|
|
nsIFrame* frame;
|
1999-02-12 17:45:58 +00:00
|
|
|
shell->GetRootFrame(&frame);
|
1999-02-05 03:55:18 +00:00
|
|
|
|
2000-04-26 23:22:06 +00:00
|
|
|
if (!frame) {
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
1999-02-05 03:55:18 +00:00
|
|
|
PRBool reframe = PR_FALSE;
|
|
|
|
PRBool reflow = PR_FALSE;
|
|
|
|
PRBool render = PR_FALSE;
|
|
|
|
PRBool restyle = PR_FALSE;
|
|
|
|
switch (aHint) {
|
|
|
|
default:
|
|
|
|
case NS_STYLE_HINT_UNKNOWN:
|
|
|
|
case NS_STYLE_HINT_FRAMECHANGE:
|
|
|
|
reframe = PR_TRUE;
|
|
|
|
case NS_STYLE_HINT_REFLOW:
|
|
|
|
reflow = PR_TRUE;
|
|
|
|
case NS_STYLE_HINT_VISUAL:
|
|
|
|
render = PR_TRUE;
|
|
|
|
case NS_STYLE_HINT_CONTENT:
|
|
|
|
case NS_STYLE_HINT_AURAL:
|
|
|
|
restyle = PR_TRUE;
|
|
|
|
break;
|
|
|
|
case NS_STYLE_HINT_NONE:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
1999-09-22 01:18:45 +00:00
|
|
|
if (restyle) {
|
1999-02-05 03:55:18 +00:00
|
|
|
nsIStyleContext* sc;
|
1999-02-10 00:42:56 +00:00
|
|
|
frame->GetStyleContext(&sc);
|
1999-02-05 03:55:18 +00:00
|
|
|
sc->RemapStyle(aPresContext);
|
|
|
|
NS_RELEASE(sc);
|
1999-09-22 01:18:45 +00:00
|
|
|
}
|
1999-02-05 03:55:18 +00:00
|
|
|
|
1999-09-22 01:18:45 +00:00
|
|
|
if (reframe) {
|
|
|
|
result = ReconstructDocElementHierarchy(aPresContext);
|
|
|
|
}
|
|
|
|
else {
|
1999-02-05 03:55:18 +00:00
|
|
|
// XXX hack, skip the root and scrolling frames
|
2000-01-22 01:16:50 +00:00
|
|
|
frame->FirstChild(aPresContext, nsnull, &frame);
|
|
|
|
frame->FirstChild(aPresContext, nsnull, &frame);
|
1999-03-25 06:41:43 +00:00
|
|
|
if (reflow) {
|
1999-02-05 03:55:18 +00:00
|
|
|
StyleChangeReflow(aPresContext, frame, nsnull);
|
|
|
|
}
|
|
|
|
else if (render) {
|
1999-11-24 06:03:41 +00:00
|
|
|
ApplyRenderingChangeToTree(aPresContext, frame, nsnull);
|
1999-02-05 03:55:18 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1999-03-25 06:41:43 +00:00
|
|
|
return result;
|
1999-02-05 03:55:18 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsCSSFrameConstructor::StyleRuleAdded(nsIPresContext* aPresContext,
|
|
|
|
nsIStyleSheet* aStyleSheet,
|
|
|
|
nsIStyleRule* aStyleRule)
|
|
|
|
{
|
1999-03-25 06:41:43 +00:00
|
|
|
// XXX TBI: should query rule for impact and do minimal work
|
|
|
|
ReconstructDocElementHierarchy(aPresContext);
|
1999-02-05 03:55:18 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsCSSFrameConstructor::StyleRuleRemoved(nsIPresContext* aPresContext,
|
|
|
|
nsIStyleSheet* aStyleSheet,
|
|
|
|
nsIStyleRule* aStyleRule)
|
|
|
|
{
|
1999-03-25 06:41:43 +00:00
|
|
|
// XXX TBI: should query rule for impact and do minimal work
|
|
|
|
ReconstructDocElementHierarchy(aPresContext);
|
1999-02-05 03:55:18 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2000-03-14 05:30:00 +00:00
|
|
|
static void
|
|
|
|
GetAlternateTextFor(nsIContent* aContent,
|
|
|
|
nsIAtom* aTag, // content object's tag
|
|
|
|
nsString& aAltText)
|
1999-02-06 03:45:11 +00:00
|
|
|
{
|
2000-03-14 05:30:00 +00:00
|
|
|
nsresult rv;
|
1999-02-06 03:45:11 +00:00
|
|
|
|
1999-12-22 21:26:14 +00:00
|
|
|
// The "alt" attribute specifies alternate text that is rendered
|
|
|
|
// when the image can not be displayed
|
2000-03-14 05:30:00 +00:00
|
|
|
rv = aContent->GetAttribute(kNameSpaceID_HTML, nsHTMLAtoms::alt, aAltText);
|
1999-12-22 21:26:14 +00:00
|
|
|
if (NS_CONTENT_ATTR_NOT_THERE == rv) {
|
|
|
|
// If there's no "alt" attribute, then use the value of the "title"
|
|
|
|
// attribute. Note that this is not the same as a value of ""
|
2000-03-14 05:30:00 +00:00
|
|
|
rv = aContent->GetAttribute(kNameSpaceID_HTML, nsHTMLAtoms::title, aAltText);
|
1999-12-22 21:26:14 +00:00
|
|
|
}
|
|
|
|
if (NS_CONTENT_ATTR_NOT_THERE == rv) {
|
2000-03-14 05:30:00 +00:00
|
|
|
// If there's no "title" attribute, then what we do depends on the type
|
|
|
|
// of element
|
|
|
|
if (nsHTMLAtoms::img == aTag) {
|
|
|
|
// Use the filename minus the extension
|
|
|
|
aContent->GetAttribute(kNameSpaceID_HTML, nsHTMLAtoms::src, aAltText);
|
|
|
|
if (aAltText.Length() > 0) {
|
|
|
|
// The path is a hierarchical structure of segments. Get the last substring
|
|
|
|
// in the path
|
|
|
|
PRInt32 offset = aAltText.RFindChar('/');
|
|
|
|
if (offset >= 0) {
|
|
|
|
aAltText.Cut(0, offset + 1);
|
|
|
|
}
|
1999-02-06 03:45:11 +00:00
|
|
|
|
2000-03-14 05:30:00 +00:00
|
|
|
// Ignore fragment identifiers ('#' delimiter), query strings ('?'
|
|
|
|
// delimiter), and anything beginning with ';'
|
|
|
|
offset = aAltText.FindCharInSet("#?;");
|
|
|
|
if (offset >= 0) {
|
|
|
|
aAltText.Truncate(offset);
|
|
|
|
}
|
2000-02-11 01:00:17 +00:00
|
|
|
|
2000-03-14 05:30:00 +00:00
|
|
|
// Trim off any extension (including the '.')
|
|
|
|
offset = aAltText.RFindChar('.');
|
|
|
|
if (offset >= 0) {
|
|
|
|
aAltText.Truncate(offset);
|
|
|
|
}
|
1999-02-06 03:45:11 +00:00
|
|
|
}
|
2000-03-14 05:30:00 +00:00
|
|
|
|
|
|
|
} else if (nsHTMLAtoms::input == aTag) {
|
|
|
|
// Use the valuf of the "name" attribute
|
|
|
|
aContent->GetAttribute(kNameSpaceID_HTML, nsHTMLAtoms::name, aAltText);
|
1999-02-06 03:45:11 +00:00
|
|
|
}
|
1999-12-22 21:26:14 +00:00
|
|
|
}
|
2000-03-14 05:30:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Construct an alternate frame to use when the image can't be rendered
|
|
|
|
nsresult
|
2000-07-19 05:06:55 +00:00
|
|
|
nsCSSFrameConstructor::ConstructAlternateFrame(nsIPresShell* aPresShell,
|
|
|
|
nsIPresContext* aPresContext,
|
|
|
|
nsIContent* aContent,
|
|
|
|
nsIStyleContext* aStyleContext,
|
|
|
|
nsIFrame* aParentFrame,
|
|
|
|
nsIFrame*& aFrame)
|
2000-03-14 05:30:00 +00:00
|
|
|
{
|
|
|
|
nsAutoString altText;
|
|
|
|
|
|
|
|
// Initialize OUT parameter
|
|
|
|
aFrame = nsnull;
|
|
|
|
|
|
|
|
// Get the alternate text to use
|
2000-07-19 05:06:55 +00:00
|
|
|
nsCOMPtr<nsIAtom> tag;
|
|
|
|
aContent->GetTag(*getter_AddRefs(tag));
|
|
|
|
GetAlternateTextFor(aContent, tag, altText);
|
1999-04-14 04:00:16 +00:00
|
|
|
|
1999-12-22 21:26:14 +00:00
|
|
|
// Create a text content element for the alternate text
|
|
|
|
nsCOMPtr<nsIContent> altTextContent;
|
|
|
|
NS_NewTextNode(getter_AddRefs(altTextContent));
|
1999-02-06 03:45:11 +00:00
|
|
|
|
1999-12-22 21:26:14 +00:00
|
|
|
// Set the content's text
|
|
|
|
nsIDOMCharacterData* domData;
|
|
|
|
altTextContent->QueryInterface(kIDOMCharacterDataIID, (void**)&domData);
|
|
|
|
domData->SetData(altText);
|
|
|
|
NS_RELEASE(domData);
|
|
|
|
|
|
|
|
// Set aContent as the parent content and set the document object
|
|
|
|
nsCOMPtr<nsIDocument> document;
|
|
|
|
aContent->GetDocument(*getter_AddRefs(document));
|
|
|
|
altTextContent->SetParent(aContent);
|
2000-05-19 04:48:43 +00:00
|
|
|
altTextContent->SetDocument(document, PR_TRUE, PR_TRUE);
|
1999-12-22 21:26:14 +00:00
|
|
|
|
|
|
|
// Create either an inline frame, block frame, or area frame
|
|
|
|
nsIFrame* containerFrame;
|
2000-01-22 01:16:50 +00:00
|
|
|
PRBool isOutOfFlow = PR_FALSE;
|
1999-12-22 21:26:14 +00:00
|
|
|
const nsStyleDisplay* display = (const nsStyleDisplay*)
|
|
|
|
aStyleContext->GetStyleData(eStyleStruct_Display);
|
|
|
|
const nsStylePosition* position = (const nsStylePosition*)
|
|
|
|
aStyleContext->GetStyleData(eStyleStruct_Position);
|
1999-04-20 03:57:01 +00:00
|
|
|
|
1999-12-22 21:26:14 +00:00
|
|
|
if (position->IsAbsolutelyPositioned()) {
|
|
|
|
NS_NewAbsoluteItemWrapperFrame(aPresShell, &containerFrame);
|
2000-01-22 01:16:50 +00:00
|
|
|
isOutOfFlow = PR_TRUE;
|
|
|
|
} else if (display->IsFloating()) {
|
|
|
|
NS_NewFloatingItemWrapperFrame(aPresShell, &containerFrame);
|
|
|
|
isOutOfFlow = PR_TRUE;
|
|
|
|
} else if (NS_STYLE_DISPLAY_BLOCK == display->mDisplay) {
|
1999-12-22 21:26:14 +00:00
|
|
|
NS_NewBlockFrame(aPresShell, &containerFrame);
|
|
|
|
} else {
|
|
|
|
NS_NewInlineFrame(aPresShell, &containerFrame);
|
|
|
|
}
|
|
|
|
containerFrame->Init(aPresContext, aContent, aParentFrame, aStyleContext, nsnull);
|
|
|
|
nsHTMLContainerFrame::CreateViewForFrame(aPresContext, containerFrame,
|
|
|
|
aStyleContext, PR_FALSE);
|
1999-04-20 03:57:01 +00:00
|
|
|
|
2000-01-22 01:16:50 +00:00
|
|
|
// If the frame is out-of-flow, then mark it as such
|
2000-03-17 05:10:37 +00:00
|
|
|
if (isOutOfFlow) {
|
|
|
|
nsFrameState frameState;
|
|
|
|
containerFrame->GetFrameState(&frameState);
|
|
|
|
containerFrame->SetFrameState(frameState | NS_FRAME_OUT_OF_FLOW);
|
|
|
|
}
|
2000-01-22 01:16:50 +00:00
|
|
|
|
1999-12-22 21:26:14 +00:00
|
|
|
// Create a text frame to display the alt-text. It gets a pseudo-element
|
|
|
|
// style context
|
|
|
|
nsIFrame* textFrame;
|
|
|
|
nsIStyleContext* textStyleContext;
|
1999-04-20 03:57:01 +00:00
|
|
|
|
1999-12-22 21:26:14 +00:00
|
|
|
NS_NewTextFrame(aPresShell, &textFrame);
|
|
|
|
aPresContext->ResolvePseudoStyleContextFor(aContent, nsHTMLAtoms::textPseudo,
|
|
|
|
aStyleContext, PR_FALSE,
|
|
|
|
&textStyleContext);
|
1999-04-20 03:57:01 +00:00
|
|
|
|
1999-12-22 21:26:14 +00:00
|
|
|
textFrame->Init(aPresContext, altTextContent, containerFrame,
|
|
|
|
textStyleContext, nsnull);
|
|
|
|
NS_RELEASE(textStyleContext);
|
|
|
|
containerFrame->SetInitialChildList(aPresContext, nsnull, textFrame);
|
|
|
|
|
|
|
|
// Return the container frame
|
|
|
|
aFrame = containerFrame;
|
1999-02-06 03:45:11 +00:00
|
|
|
|
2000-03-14 05:30:00 +00:00
|
|
|
return NS_OK;
|
1999-02-06 03:45:11 +00:00
|
|
|
}
|
|
|
|
|
1999-09-15 04:03:08 +00:00
|
|
|
#ifdef NS_DEBUG
|
|
|
|
static PRBool
|
|
|
|
IsPlaceholderFrame(nsIFrame* aFrame)
|
1999-09-07 02:42:00 +00:00
|
|
|
{
|
1999-09-15 04:03:08 +00:00
|
|
|
nsIAtom* frameType;
|
|
|
|
PRBool result;
|
1999-09-07 02:42:00 +00:00
|
|
|
|
1999-09-15 04:03:08 +00:00
|
|
|
aFrame->GetFrameType(&frameType);
|
|
|
|
result = frameType == nsLayoutAtoms::placeholderFrame;
|
|
|
|
NS_IF_RELEASE(frameType);
|
|
|
|
return result;
|
1999-09-07 02:42:00 +00:00
|
|
|
}
|
1999-09-15 04:03:08 +00:00
|
|
|
#endif
|
1999-02-06 03:45:11 +00:00
|
|
|
|
2000-07-19 05:06:55 +00:00
|
|
|
|
|
|
|
static PRBool
|
|
|
|
HasDisplayableChildren(nsIPresContext* aPresContext, nsIFrame* aContainerFrame)
|
|
|
|
{
|
|
|
|
// Returns 'true' if there are frames within aContainerFrame that
|
|
|
|
// could be displayed in the frame list.
|
|
|
|
NS_PRECONDITION(aContainerFrame != nsnull, "null ptr");
|
|
|
|
if (! aContainerFrame)
|
|
|
|
return PR_FALSE;
|
|
|
|
|
|
|
|
nsIFrame* frame;
|
|
|
|
aContainerFrame->FirstChild(aPresContext, nsnull, &frame);
|
|
|
|
|
|
|
|
while (frame) {
|
|
|
|
// If it's not a text frame, then assume that it's displayable.
|
|
|
|
nsCOMPtr<nsIAtom> frameType;
|
|
|
|
frame->GetFrameType(getter_AddRefs(frameType));
|
2000-07-19 05:23:09 +00:00
|
|
|
if (frameType.get() != nsLayoutAtoms::textFrame)
|
2000-07-19 05:06:55 +00:00
|
|
|
return PR_TRUE;
|
|
|
|
|
|
|
|
// Get the text content...
|
|
|
|
nsCOMPtr<nsIContent> content;
|
|
|
|
frame->GetContent(getter_AddRefs(content));
|
|
|
|
|
|
|
|
nsCOMPtr<nsITextContent> text = do_QueryInterface(content);
|
|
|
|
NS_ASSERTION(text != nsnull, "oops, not an nsITextContent");
|
|
|
|
if (! text)
|
|
|
|
return PR_TRUE;
|
|
|
|
|
|
|
|
// Is it only whitespace?
|
|
|
|
PRBool onlyWhitespace;
|
|
|
|
text->IsOnlyWhitespace(&onlyWhitespace);
|
|
|
|
|
|
|
|
// If not, then we have displayable content here.
|
|
|
|
if (! onlyWhitespace)
|
|
|
|
return PR_TRUE;
|
|
|
|
|
|
|
|
// Otherwise, on to the next frame...
|
|
|
|
frame->GetNextSibling(&frame);
|
|
|
|
}
|
|
|
|
|
|
|
|
// If we get here, then we've iterated through all the child frames,
|
|
|
|
// and every one is a text frame containing whitespace. (Or, there
|
|
|
|
// weren't any frames at all!) There is nothing to diplay.
|
|
|
|
return PR_FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
1999-02-05 03:55:18 +00:00
|
|
|
NS_IMETHODIMP
|
1999-12-04 23:49:50 +00:00
|
|
|
nsCSSFrameConstructor::CantRenderReplacedElement(nsIPresShell* aPresShell,
|
|
|
|
nsIPresContext* aPresContext,
|
1999-02-05 03:55:18 +00:00
|
|
|
nsIFrame* aFrame)
|
|
|
|
{
|
1999-04-27 03:58:46 +00:00
|
|
|
nsIFrame* parentFrame;
|
|
|
|
nsCOMPtr<nsIStyleContext> styleContext;
|
|
|
|
nsCOMPtr<nsIContent> content;
|
|
|
|
nsCOMPtr<nsIAtom> tag;
|
|
|
|
nsresult rv = NS_OK;
|
1999-02-05 03:55:18 +00:00
|
|
|
|
1999-02-10 01:36:30 +00:00
|
|
|
aFrame->GetParent(&parentFrame);
|
1999-04-27 03:58:46 +00:00
|
|
|
aFrame->GetStyleContext(getter_AddRefs(styleContext));
|
1999-02-05 03:55:18 +00:00
|
|
|
|
1999-04-27 03:58:46 +00:00
|
|
|
// Get aFrame's content object and the tag name
|
1999-02-11 15:54:13 +00:00
|
|
|
aFrame->GetContent(getter_AddRefs(content));
|
|
|
|
NS_ASSERTION(content, "null content object");
|
|
|
|
content->GetTag(*getter_AddRefs(tag));
|
1999-04-27 03:58:46 +00:00
|
|
|
|
|
|
|
// Get the child list name that the frame is contained in
|
|
|
|
nsCOMPtr<nsIAtom> listName;
|
2000-01-22 01:16:50 +00:00
|
|
|
GetChildListNameFor(aPresContext, parentFrame, aFrame, getter_AddRefs(listName));
|
1999-04-14 04:00:16 +00:00
|
|
|
|
|
|
|
// If the frame is out of the flow, then it has a placeholder frame.
|
|
|
|
nsIFrame* placeholderFrame = nsnull;
|
|
|
|
nsCOMPtr<nsIPresShell> presShell;
|
|
|
|
aPresContext->GetShell(getter_AddRefs(presShell));
|
|
|
|
if (listName) {
|
|
|
|
presShell->GetPlaceholderFrameFor(aFrame, &placeholderFrame);
|
|
|
|
}
|
1999-02-05 18:24:48 +00:00
|
|
|
|
1999-02-17 17:02:27 +00:00
|
|
|
// Get the previous sibling frame
|
|
|
|
nsIFrame* firstChild;
|
2000-01-22 01:16:50 +00:00
|
|
|
parentFrame->FirstChild(aPresContext, listName, &firstChild);
|
1999-02-17 17:02:27 +00:00
|
|
|
nsFrameList frameList(firstChild);
|
|
|
|
|
2000-06-16 12:57:44 +00:00
|
|
|
// See whether it's an IMG or an INPUT element (for image buttons)
|
|
|
|
if (nsHTMLAtoms::img == tag.get() || nsHTMLAtoms::input == tag.get()) {
|
1999-02-06 03:45:11 +00:00
|
|
|
// It's an IMG element. Try and construct an alternate frame to use when the
|
|
|
|
// image can't be rendered
|
|
|
|
nsIFrame* newFrame;
|
2000-07-19 05:06:55 +00:00
|
|
|
rv = ConstructAlternateFrame(aPresShell, aPresContext, content, styleContext,
|
|
|
|
parentFrame, newFrame);
|
1999-02-06 03:45:11 +00:00
|
|
|
|
|
|
|
if (NS_SUCCEEDED(rv)) {
|
1999-08-05 03:09:22 +00:00
|
|
|
nsCOMPtr<nsIFrameManager> frameManager;
|
|
|
|
presShell->GetFrameManager(getter_AddRefs(frameManager));
|
1999-04-14 04:00:16 +00:00
|
|
|
|
1999-09-07 02:42:00 +00:00
|
|
|
// Replace the old frame with the new frame
|
1999-09-15 04:03:08 +00:00
|
|
|
// Reset the primary frame mapping
|
|
|
|
frameManager->SetPrimaryFrameFor(content, newFrame);
|
|
|
|
|
|
|
|
if (placeholderFrame) {
|
|
|
|
// Reuse the existing placeholder frame, and add an association to the
|
|
|
|
// new frame
|
|
|
|
frameManager->SetPlaceholderFrameFor(newFrame, placeholderFrame);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Replace the old frame with the new frame
|
1999-11-24 06:03:41 +00:00
|
|
|
frameManager->ReplaceFrame(aPresContext, *presShell, parentFrame,
|
1999-09-15 04:03:08 +00:00
|
|
|
listName, aFrame, newFrame);
|
1999-09-21 05:20:11 +00:00
|
|
|
|
|
|
|
// Now that we've replaced the primary frame, if there's a placeholder
|
|
|
|
// frame then complete the transition from image frame to new frame
|
|
|
|
if (placeholderFrame) {
|
|
|
|
// Remove the association between the old frame and its placeholder
|
|
|
|
frameManager->SetPlaceholderFrameFor(aFrame, nsnull);
|
|
|
|
|
|
|
|
// Placeholder frames have a pointer back to the out-of-flow frame.
|
|
|
|
// Make sure that's correct, too.
|
|
|
|
((nsPlaceholderFrame*)placeholderFrame)->SetOutOfFlowFrame(newFrame);
|
2000-01-22 01:16:50 +00:00
|
|
|
|
|
|
|
// XXX Work around a bug in the block code where the floater won't get
|
|
|
|
// reflowed unless the line containing the placeholder frame is reflowed...
|
|
|
|
nsIFrame* placeholderParentFrame;
|
|
|
|
placeholderFrame->GetParent(&placeholderParentFrame);
|
|
|
|
placeholderParentFrame->ReflowDirtyChild(aPresShell, placeholderFrame);
|
1999-09-21 05:20:11 +00:00
|
|
|
}
|
1999-02-05 03:55:18 +00:00
|
|
|
}
|
|
|
|
|
1999-03-24 01:13:59 +00:00
|
|
|
} else if ((nsHTMLAtoms::object == tag.get()) ||
|
1999-04-07 05:16:47 +00:00
|
|
|
(nsHTMLAtoms::embed == tag.get()) ||
|
1999-03-24 01:13:59 +00:00
|
|
|
(nsHTMLAtoms::applet == tag.get())) {
|
1999-09-15 04:03:08 +00:00
|
|
|
|
|
|
|
// It's an OBJECT, EMBED, or APPLET, so we should display the contents
|
1999-09-07 02:42:00 +00:00
|
|
|
// instead
|
1999-09-15 04:03:08 +00:00
|
|
|
nsIFrame* absoluteContainingBlock;
|
|
|
|
nsIFrame* floaterContainingBlock;
|
|
|
|
nsIFrame* inFlowParent = parentFrame;
|
|
|
|
|
|
|
|
// If the OBJECT frame is out-of-flow, then get the placeholder frame's
|
|
|
|
// parent and use that when determining the absolute containing block and
|
|
|
|
// floater containing block
|
|
|
|
if (placeholderFrame) {
|
|
|
|
placeholderFrame->GetParent(&inFlowParent);
|
|
|
|
}
|
|
|
|
|
|
|
|
absoluteContainingBlock = GetAbsoluteContainingBlock(aPresContext, inFlowParent),
|
|
|
|
floaterContainingBlock = GetFloaterContainingBlock(aPresContext, inFlowParent);
|
|
|
|
|
|
|
|
#ifdef NS_DEBUG
|
|
|
|
// Verify that we calculated the same containing block
|
|
|
|
if (listName.get() == nsLayoutAtoms::absoluteList) {
|
|
|
|
NS_ASSERTION(absoluteContainingBlock == parentFrame,
|
|
|
|
"wrong absolute containing block");
|
|
|
|
} else if (listName.get() == nsLayoutAtoms::floaterList) {
|
|
|
|
NS_ASSERTION(floaterContainingBlock == parentFrame,
|
|
|
|
"wrong floater containing block");
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
// Now initialize the frame construction state
|
1999-08-05 03:09:22 +00:00
|
|
|
nsFrameConstructorState state(aPresContext, mFixedContainingBlock,
|
1999-12-06 07:44:18 +00:00
|
|
|
absoluteContainingBlock, floaterContainingBlock, nsnull);
|
1999-04-28 19:08:14 +00:00
|
|
|
nsFrameItems frameItems;
|
2000-07-06 04:31:33 +00:00
|
|
|
const nsStyleDisplay* display =
|
|
|
|
NS_STATIC_CAST(const nsStyleDisplay*, styleContext->GetStyleData(eStyleStruct_Display));
|
1999-02-17 17:02:27 +00:00
|
|
|
|
1999-09-15 04:03:08 +00:00
|
|
|
// Create a new frame based on the display type.
|
|
|
|
// Note: if the old frame was out-of-flow, then so will the new frame
|
|
|
|
// and we'll get a new placeholder frame
|
1999-12-04 23:49:50 +00:00
|
|
|
rv = ConstructFrameByDisplayType(aPresShell, aPresContext, state, display, content,
|
1999-11-01 15:24:57 +00:00
|
|
|
inFlowParent, styleContext, frameItems);
|
1999-02-17 17:02:27 +00:00
|
|
|
|
2000-07-19 05:06:55 +00:00
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
nsIFrame* newFrame = frameItems.childList;
|
1999-09-07 02:42:00 +00:00
|
|
|
|
2000-07-19 05:06:55 +00:00
|
|
|
if (nsHTMLAtoms::applet == tag.get()
|
2000-07-19 05:23:09 +00:00
|
|
|
&& !HasDisplayableChildren(aPresContext, newFrame)) {
|
2000-07-19 05:06:55 +00:00
|
|
|
// If it's an <applet> tag without any displayable content, then
|
|
|
|
// it may have "alt" text specified that we could use to render
|
|
|
|
// text. Nuke the frames we just created, and use
|
|
|
|
// ConstructAlternateFrame() to fix stuff up.
|
|
|
|
nsFrameList list(newFrame);
|
|
|
|
list.DestroyFrames(aPresContext);
|
|
|
|
|
|
|
|
rv = ConstructAlternateFrame(aPresShell, aPresContext, content, styleContext,
|
|
|
|
parentFrame, newFrame);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (NS_SUCCEEDED(rv)) {
|
1999-09-15 04:03:08 +00:00
|
|
|
if (placeholderFrame) {
|
|
|
|
// Remove the association between the old frame and its placeholder
|
|
|
|
// Note: ConstructFrameByDisplayType() will already have added an
|
|
|
|
// association for the new placeholder frame
|
|
|
|
state.mFrameManager->SetPlaceholderFrameFor(aFrame, nsnull);
|
|
|
|
|
|
|
|
// Verify that the new frame is also a placeholder frame
|
|
|
|
NS_ASSERTION(IsPlaceholderFrame(newFrame), "unexpected frame type");
|
|
|
|
|
|
|
|
// Replace the old placeholder frame with the new placeholder frame
|
1999-11-24 06:03:41 +00:00
|
|
|
state.mFrameManager->ReplaceFrame(aPresContext, *presShell, inFlowParent,
|
1999-09-15 04:03:08 +00:00
|
|
|
nsnull, placeholderFrame, newFrame);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Replace the primary frame
|
2000-07-06 04:31:33 +00:00
|
|
|
if (listName == nsnull) {
|
|
|
|
if (IsInlineFrame(aFrame) && !AreAllKidsInline(newFrame)) {
|
|
|
|
// We're in the uncomfortable position of being an inline
|
|
|
|
// that now contains a block. As in ConstructInline(), break
|
|
|
|
// the newly constructed frames into three lists: the inline
|
|
|
|
// frames before the first block frame (list1), the inline
|
|
|
|
// frames after the last block frame (list3), and all the
|
|
|
|
// frames between the first and last block frames (list2).
|
|
|
|
nsIFrame* list1 = newFrame;
|
|
|
|
nsIFrame* prevToFirstBlock;
|
|
|
|
nsIFrame* list2 = FindFirstBlock(aPresContext, list1, &prevToFirstBlock);
|
|
|
|
|
|
|
|
if (prevToFirstBlock) {
|
|
|
|
prevToFirstBlock->SetNextSibling(nsnull);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
list1 = nsnull;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsIFrame* afterFirstBlock;
|
|
|
|
list2->GetNextSibling(&afterFirstBlock);
|
|
|
|
nsIFrame* list3 = nsnull;
|
|
|
|
nsIFrame* lastBlock = FindLastBlock(aPresContext, afterFirstBlock);
|
|
|
|
if (! lastBlock) {
|
|
|
|
lastBlock = list2;
|
|
|
|
}
|
|
|
|
lastBlock->GetNextSibling(&list3);
|
|
|
|
lastBlock->SetNextSibling(nsnull);
|
|
|
|
|
|
|
|
// Create "special" inline-block linkage between the frames
|
|
|
|
SetFrameIsSpecial(state.mFrameManager, list1, list2);
|
|
|
|
SetFrameIsSpecial(state.mFrameManager, list2, list3);
|
|
|
|
SetFrameIsSpecial(state.mFrameManager, list3, nsnull);
|
|
|
|
|
|
|
|
// Recursively split inlines back up to the first containing
|
|
|
|
// block frame.
|
|
|
|
SplitToContainingBlock(aPresContext, state, aFrame, list1, list2, list3, PR_FALSE);
|
|
|
|
}
|
|
|
|
} else if (listName.get() == nsLayoutAtoms::absoluteList) {
|
1999-09-15 04:03:08 +00:00
|
|
|
newFrame = state.mAbsoluteItems.childList;
|
|
|
|
state.mAbsoluteItems.childList = nsnull;
|
|
|
|
} else if (listName.get() == nsLayoutAtoms::fixedList) {
|
|
|
|
newFrame = state.mFixedItems.childList;
|
|
|
|
state.mFixedItems.childList = nsnull;
|
|
|
|
} else if (listName.get() == nsLayoutAtoms::floaterList) {
|
|
|
|
newFrame = state.mFloatedItems.childList;
|
|
|
|
state.mFloatedItems.childList = nsnull;
|
|
|
|
}
|
1999-11-24 06:03:41 +00:00
|
|
|
state.mFrameManager->ReplaceFrame(aPresContext, *presShell, parentFrame,
|
1999-09-15 04:03:08 +00:00
|
|
|
listName, aFrame, newFrame);
|
|
|
|
|
|
|
|
// Reset the primary frame mapping. Don't assume that
|
|
|
|
// ConstructFrameByDisplayType() has done this
|
|
|
|
state.mFrameManager->SetPrimaryFrameFor(content, newFrame);
|
|
|
|
|
1999-02-17 17:02:27 +00:00
|
|
|
// If there are new absolutely positioned child frames, then notify
|
|
|
|
// the parent
|
|
|
|
// XXX We can't just assume these frames are being appended, we need to
|
|
|
|
// determine where in the list they should be inserted...
|
1999-04-28 19:08:14 +00:00
|
|
|
if (state.mAbsoluteItems.childList) {
|
1999-11-24 06:03:41 +00:00
|
|
|
rv = state.mAbsoluteItems.containingBlock->AppendFrames(aPresContext, *presShell,
|
1999-09-15 04:03:08 +00:00
|
|
|
nsLayoutAtoms::absoluteList,
|
|
|
|
state.mAbsoluteItems.childList);
|
1999-02-17 17:02:27 +00:00
|
|
|
}
|
1999-09-07 02:42:00 +00:00
|
|
|
|
1999-02-17 17:02:27 +00:00
|
|
|
// If there are new fixed positioned child frames, then notify
|
|
|
|
// the parent
|
|
|
|
// XXX We can't just assume these frames are being appended, we need to
|
|
|
|
// determine where in the list they should be inserted...
|
1999-04-28 19:08:14 +00:00
|
|
|
if (state.mFixedItems.childList) {
|
1999-11-24 06:03:41 +00:00
|
|
|
rv = state.mFixedItems.containingBlock->AppendFrames(aPresContext, *presShell,
|
1999-09-15 04:03:08 +00:00
|
|
|
nsLayoutAtoms::fixedList,
|
|
|
|
state.mFixedItems.childList);
|
1999-02-17 17:02:27 +00:00
|
|
|
}
|
1999-09-07 02:42:00 +00:00
|
|
|
|
1999-09-15 04:03:08 +00:00
|
|
|
// If there are new floating child frames, then notify the parent
|
1999-02-26 17:11:54 +00:00
|
|
|
// XXX We can't just assume these frames are being appended, we need to
|
|
|
|
// determine where in the list they should be inserted...
|
1999-04-28 19:08:14 +00:00
|
|
|
if (state.mFloatedItems.childList) {
|
1999-11-24 06:03:41 +00:00
|
|
|
rv = state.mFloatedItems.containingBlock->AppendFrames(aPresContext,
|
1999-04-28 19:08:14 +00:00
|
|
|
*presShell,
|
1999-02-26 17:11:54 +00:00
|
|
|
nsLayoutAtoms::floaterList,
|
1999-04-28 19:08:14 +00:00
|
|
|
state.mFloatedItems.childList);
|
1999-02-26 17:11:54 +00:00
|
|
|
}
|
1999-02-17 17:02:27 +00:00
|
|
|
}
|
|
|
|
|
1999-04-20 03:57:01 +00:00
|
|
|
} else if (nsHTMLAtoms::input == tag.get()) {
|
|
|
|
// XXX image INPUT elements are also image frames, but don't throw away the
|
|
|
|
// image frame, because the frame class has extra logic that is specific to
|
|
|
|
// INPUT elements
|
|
|
|
|
1999-02-05 03:55:18 +00:00
|
|
|
} else {
|
|
|
|
NS_ASSERTION(PR_FALSE, "unexpected tag");
|
|
|
|
}
|
|
|
|
|
1999-02-06 03:45:11 +00:00
|
|
|
return rv;
|
1999-02-05 03:55:18 +00:00
|
|
|
}
|
|
|
|
|
1999-02-26 03:35:22 +00:00
|
|
|
nsresult
|
1999-12-04 23:49:50 +00:00
|
|
|
nsCSSFrameConstructor::CreateContinuingOuterTableFrame(nsIPresShell* aPresShell,
|
|
|
|
nsIPresContext* aPresContext,
|
1999-02-26 03:35:22 +00:00
|
|
|
nsIFrame* aFrame,
|
|
|
|
nsIFrame* aParentFrame,
|
|
|
|
nsIContent* aContent,
|
|
|
|
nsIStyleContext* aStyleContext,
|
|
|
|
nsIFrame** aContinuingFrame)
|
|
|
|
{
|
|
|
|
nsIFrame* newFrame;
|
|
|
|
nsresult rv;
|
|
|
|
|
1999-12-04 23:49:50 +00:00
|
|
|
rv = NS_NewTableOuterFrame(aPresShell, &newFrame);
|
1999-02-26 03:35:22 +00:00
|
|
|
if (NS_SUCCEEDED(rv)) {
|
1999-11-24 06:03:41 +00:00
|
|
|
newFrame->Init(aPresContext, aContent, aParentFrame, aStyleContext, aFrame);
|
|
|
|
nsHTMLContainerFrame::CreateViewForFrame(aPresContext, newFrame,
|
1999-02-26 03:35:22 +00:00
|
|
|
aStyleContext, PR_FALSE);
|
|
|
|
|
|
|
|
// Create a continuing inner table frame, and if there's a caption then
|
|
|
|
// replicate the caption
|
|
|
|
nsIFrame* childFrame;
|
|
|
|
nsFrameItems newChildFrames;
|
|
|
|
|
2000-01-22 01:16:50 +00:00
|
|
|
aFrame->FirstChild(aPresContext, nsnull, &childFrame);
|
1999-02-26 03:35:22 +00:00
|
|
|
while (childFrame) {
|
|
|
|
nsIAtom* tableType;
|
|
|
|
|
|
|
|
// See if it's the inner table frame
|
|
|
|
childFrame->GetFrameType(&tableType);
|
|
|
|
if (nsLayoutAtoms::tableFrame == tableType) {
|
|
|
|
nsIFrame* continuingTableFrame;
|
|
|
|
|
|
|
|
// It's the inner table frame, so create a continuing frame
|
1999-12-04 23:49:50 +00:00
|
|
|
CreateContinuingFrame(aPresShell, aPresContext, childFrame, newFrame, &continuingTableFrame);
|
1999-02-26 03:35:22 +00:00
|
|
|
newChildFrames.AddChild(continuingTableFrame);
|
|
|
|
} else {
|
|
|
|
nsIContent* caption;
|
|
|
|
nsIStyleContext* captionStyle;
|
|
|
|
const nsStyleDisplay* display;
|
|
|
|
|
|
|
|
childFrame->GetContent(&caption);
|
|
|
|
childFrame->GetStyleContext(&captionStyle);
|
|
|
|
display = (const nsStyleDisplay*)captionStyle->GetStyleData(eStyleStruct_Display);
|
|
|
|
NS_ASSERTION(NS_STYLE_DISPLAY_TABLE_CAPTION == display->mDisplay, "expected caption");
|
|
|
|
|
|
|
|
// Replicate the caption frame
|
|
|
|
// XXX We have to do it this way instead of calling ConstructFrameByDisplayType(),
|
|
|
|
// because of a bug in the way ConstructTableFrame() handles the initial child
|
|
|
|
// list...
|
1999-04-28 19:08:14 +00:00
|
|
|
nsIFrame* captionFrame;
|
|
|
|
nsFrameItems childItems;
|
1999-12-04 23:49:50 +00:00
|
|
|
NS_NewTableCaptionFrame(aPresShell, &captionFrame);
|
1999-08-05 03:09:22 +00:00
|
|
|
nsFrameConstructorState state(aPresContext, mFixedContainingBlock,
|
1999-04-28 19:08:14 +00:00
|
|
|
GetAbsoluteContainingBlock(aPresContext, newFrame),
|
1999-12-06 07:44:18 +00:00
|
|
|
captionFrame, nsnull);
|
1999-11-24 06:03:41 +00:00
|
|
|
captionFrame->Init(aPresContext, caption, newFrame, captionStyle, nsnull);
|
1999-12-04 23:49:50 +00:00
|
|
|
ProcessChildren(aPresShell, aPresContext, state, caption, captionFrame,
|
1999-08-27 21:46:10 +00:00
|
|
|
PR_TRUE, childItems, PR_TRUE);
|
1999-11-24 06:03:41 +00:00
|
|
|
captionFrame->SetInitialChildList(aPresContext, nsnull, childItems.childList);
|
1999-03-03 16:33:57 +00:00
|
|
|
// XXX Deal with absolute and fixed frames...
|
1999-04-28 19:08:14 +00:00
|
|
|
if (state.mFloatedItems.childList) {
|
1999-11-24 06:03:41 +00:00
|
|
|
captionFrame->SetInitialChildList(aPresContext,
|
1999-02-26 17:11:54 +00:00
|
|
|
nsLayoutAtoms::floaterList,
|
1999-04-28 19:08:14 +00:00
|
|
|
state.mFloatedItems.childList);
|
1999-02-26 17:11:54 +00:00
|
|
|
}
|
1999-02-26 03:35:22 +00:00
|
|
|
newChildFrames.AddChild(captionFrame);
|
|
|
|
NS_RELEASE(caption);
|
|
|
|
NS_RELEASE(captionStyle);
|
|
|
|
}
|
|
|
|
NS_IF_RELEASE(tableType);
|
|
|
|
childFrame->GetNextSibling(&childFrame);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Set the outer table's initial child list
|
1999-11-24 06:03:41 +00:00
|
|
|
newFrame->SetInitialChildList(aPresContext, nsnull, newChildFrames.childList);
|
1999-02-26 03:35:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
*aContinuingFrame = newFrame;
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
1999-03-03 16:33:57 +00:00
|
|
|
nsresult
|
1999-12-04 23:49:50 +00:00
|
|
|
nsCSSFrameConstructor::CreateContinuingTableFrame(nsIPresShell* aPresShell,
|
|
|
|
nsIPresContext* aPresContext,
|
1999-03-03 16:33:57 +00:00
|
|
|
nsIFrame* aFrame,
|
|
|
|
nsIFrame* aParentFrame,
|
|
|
|
nsIContent* aContent,
|
|
|
|
nsIStyleContext* aStyleContext,
|
|
|
|
nsIFrame** aContinuingFrame)
|
|
|
|
{
|
|
|
|
nsIFrame* newFrame;
|
|
|
|
nsresult rv;
|
|
|
|
|
1999-12-04 23:49:50 +00:00
|
|
|
rv = NS_NewTableFrame(aPresShell, &newFrame);
|
1999-03-03 16:33:57 +00:00
|
|
|
if (NS_SUCCEEDED(rv)) {
|
1999-11-24 06:03:41 +00:00
|
|
|
newFrame->Init(aPresContext, aContent, aParentFrame, aStyleContext, aFrame);
|
|
|
|
nsHTMLContainerFrame::CreateViewForFrame(aPresContext, newFrame,
|
1999-03-03 16:33:57 +00:00
|
|
|
aStyleContext, PR_FALSE);
|
|
|
|
|
|
|
|
// Replicate any header/footer frames
|
|
|
|
nsIFrame* rowGroupFrame;
|
|
|
|
nsFrameItems childFrames;
|
|
|
|
|
2000-01-22 01:16:50 +00:00
|
|
|
aFrame->FirstChild(aPresContext, nsnull, &rowGroupFrame);
|
1999-03-03 16:33:57 +00:00
|
|
|
while (rowGroupFrame) {
|
|
|
|
// See if it's a header/footer
|
|
|
|
nsIStyleContext* rowGroupStyle;
|
|
|
|
const nsStyleDisplay* display;
|
|
|
|
|
|
|
|
rowGroupFrame->GetStyleContext(&rowGroupStyle);
|
|
|
|
display = (const nsStyleDisplay*)rowGroupStyle->GetStyleData(eStyleStruct_Display);
|
|
|
|
|
|
|
|
if ((NS_STYLE_DISPLAY_TABLE_HEADER_GROUP == display->mDisplay) ||
|
|
|
|
(NS_STYLE_DISPLAY_TABLE_FOOTER_GROUP == display->mDisplay)) {
|
|
|
|
|
|
|
|
// Replicate the header/footer frame
|
1999-04-28 19:08:14 +00:00
|
|
|
nsIFrame* headerFooterFrame;
|
|
|
|
nsFrameItems childItems;
|
|
|
|
nsIContent* headerFooter;
|
1999-08-05 03:09:22 +00:00
|
|
|
nsFrameConstructorState state(aPresContext, mFixedContainingBlock,
|
1999-04-28 19:08:14 +00:00
|
|
|
GetAbsoluteContainingBlock(aPresContext, newFrame),
|
1999-12-06 07:44:18 +00:00
|
|
|
nsnull, nsnull);
|
1999-03-03 16:33:57 +00:00
|
|
|
|
1999-12-04 23:49:50 +00:00
|
|
|
NS_NewTableRowGroupFrame(aPresShell, &headerFooterFrame);
|
1999-03-03 16:33:57 +00:00
|
|
|
rowGroupFrame->GetContent(&headerFooter);
|
1999-11-24 06:03:41 +00:00
|
|
|
headerFooterFrame->Init(aPresContext, headerFooter, newFrame,
|
1999-03-03 16:33:57 +00:00
|
|
|
rowGroupStyle, nsnull);
|
1999-12-04 23:49:50 +00:00
|
|
|
ProcessChildren(aPresShell, aPresContext, state, headerFooter, headerFooterFrame,
|
1999-08-27 21:46:10 +00:00
|
|
|
PR_FALSE, childItems, PR_FALSE);
|
1999-04-28 19:08:14 +00:00
|
|
|
NS_ASSERTION(!state.mFloatedItems.childList, "unexpected floated element");
|
1999-03-03 16:33:57 +00:00
|
|
|
NS_RELEASE(headerFooter);
|
1999-11-24 06:03:41 +00:00
|
|
|
headerFooterFrame->SetInitialChildList(aPresContext, nsnull, childItems.childList);
|
1999-03-03 16:33:57 +00:00
|
|
|
|
|
|
|
// Table specific initialization
|
|
|
|
((nsTableRowGroupFrame*)headerFooterFrame)->InitRepeatedFrame
|
2000-01-22 01:16:50 +00:00
|
|
|
(aPresContext, (nsTableRowGroupFrame*)rowGroupFrame);
|
1999-03-03 16:33:57 +00:00
|
|
|
|
|
|
|
// XXX Deal with absolute and fixed frames...
|
|
|
|
childFrames.AddChild(headerFooterFrame);
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_RELEASE(rowGroupStyle);
|
1999-03-05 06:00:40 +00:00
|
|
|
|
|
|
|
// Header and footer must be first, and then the body row groups.
|
|
|
|
// So if we found a body row group, then stop looking for header and
|
|
|
|
// footer elements
|
|
|
|
if (NS_STYLE_DISPLAY_TABLE_ROW_GROUP == display->mDisplay) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Get the next row group frame
|
1999-03-03 16:33:57 +00:00
|
|
|
rowGroupFrame->GetNextSibling(&rowGroupFrame);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Set the table frame's initial child list
|
1999-11-24 06:03:41 +00:00
|
|
|
newFrame->SetInitialChildList(aPresContext, nsnull, childFrames.childList);
|
1999-03-03 16:33:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
*aContinuingFrame = newFrame;
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
1999-02-24 04:03:50 +00:00
|
|
|
NS_IMETHODIMP
|
1999-12-04 23:49:50 +00:00
|
|
|
nsCSSFrameConstructor::CreateContinuingFrame(nsIPresShell* aPresShell,
|
|
|
|
nsIPresContext* aPresContext,
|
1999-02-24 04:03:50 +00:00
|
|
|
nsIFrame* aFrame,
|
|
|
|
nsIFrame* aParentFrame,
|
|
|
|
nsIFrame** aContinuingFrame)
|
|
|
|
{
|
1999-02-25 05:31:15 +00:00
|
|
|
nsIAtom* frameType;
|
|
|
|
nsIContent* content;
|
|
|
|
nsIStyleContext* styleContext;
|
|
|
|
nsIFrame* newFrame = nsnull;
|
|
|
|
nsresult rv;
|
1999-02-24 17:16:04 +00:00
|
|
|
|
1999-02-25 05:31:15 +00:00
|
|
|
// Use the frame type to determine what type of frame to create
|
1999-02-24 17:16:04 +00:00
|
|
|
aFrame->GetFrameType(&frameType);
|
1999-02-25 05:31:15 +00:00
|
|
|
aFrame->GetContent(&content);
|
|
|
|
aFrame->GetStyleContext(&styleContext);
|
1999-02-24 17:16:04 +00:00
|
|
|
|
|
|
|
if (nsLayoutAtoms::textFrame == frameType) {
|
1999-12-04 23:49:50 +00:00
|
|
|
rv = NS_NewContinuingTextFrame(aPresShell, &newFrame);
|
1999-02-25 05:31:15 +00:00
|
|
|
if (NS_SUCCEEDED(rv)) {
|
1999-11-24 06:03:41 +00:00
|
|
|
newFrame->Init(aPresContext, content, aParentFrame, styleContext, aFrame);
|
|
|
|
nsHTMLContainerFrame::CreateViewForFrame(aPresContext, newFrame,
|
1999-02-25 05:31:15 +00:00
|
|
|
styleContext, PR_FALSE);
|
|
|
|
}
|
1999-02-24 17:16:04 +00:00
|
|
|
|
1999-04-20 18:23:13 +00:00
|
|
|
} else if (nsLayoutAtoms::inlineFrame == frameType) {
|
1999-12-04 23:49:50 +00:00
|
|
|
rv = NS_NewInlineFrame(aPresShell, &newFrame);
|
1999-02-25 05:31:15 +00:00
|
|
|
if (NS_SUCCEEDED(rv)) {
|
1999-11-24 06:03:41 +00:00
|
|
|
newFrame->Init(aPresContext, content, aParentFrame, styleContext, aFrame);
|
|
|
|
nsHTMLContainerFrame::CreateViewForFrame(aPresContext, newFrame,
|
1999-02-25 05:31:15 +00:00
|
|
|
styleContext, PR_FALSE);
|
|
|
|
}
|
1999-02-24 17:16:04 +00:00
|
|
|
|
1999-04-20 18:23:13 +00:00
|
|
|
} else if (nsLayoutAtoms::blockFrame == frameType) {
|
1999-12-04 23:49:50 +00:00
|
|
|
rv = NS_NewBlockFrame(aPresShell, &newFrame);
|
1999-02-25 05:31:15 +00:00
|
|
|
if (NS_SUCCEEDED(rv)) {
|
1999-11-24 06:03:41 +00:00
|
|
|
newFrame->Init(aPresContext, content, aParentFrame, styleContext, aFrame);
|
|
|
|
nsHTMLContainerFrame::CreateViewForFrame(aPresContext, newFrame,
|
1999-02-25 05:31:15 +00:00
|
|
|
styleContext, PR_FALSE);
|
|
|
|
}
|
1999-02-24 17:16:04 +00:00
|
|
|
|
|
|
|
} else if (nsLayoutAtoms::areaFrame == frameType) {
|
1999-12-04 23:49:50 +00:00
|
|
|
rv = NS_NewAreaFrame(aPresShell, &newFrame);
|
1999-02-25 05:31:15 +00:00
|
|
|
if (NS_SUCCEEDED(rv)) {
|
1999-11-24 06:03:41 +00:00
|
|
|
newFrame->Init(aPresContext, content, aParentFrame, styleContext,
|
1999-05-11 22:03:29 +00:00
|
|
|
aFrame);
|
1999-11-24 06:03:41 +00:00
|
|
|
nsHTMLContainerFrame::CreateViewForFrame(aPresContext, newFrame,
|
1999-02-25 05:31:15 +00:00
|
|
|
styleContext, PR_FALSE);
|
|
|
|
}
|
1999-02-24 17:16:04 +00:00
|
|
|
|
1999-04-20 20:00:52 +00:00
|
|
|
} else if (nsLayoutAtoms::positionedInlineFrame == frameType) {
|
1999-12-04 23:49:50 +00:00
|
|
|
rv = NS_NewPositionedInlineFrame(aPresShell, &newFrame);
|
1999-04-20 20:00:52 +00:00
|
|
|
if (NS_SUCCEEDED(rv)) {
|
1999-11-24 06:03:41 +00:00
|
|
|
newFrame->Init(aPresContext, content, aParentFrame, styleContext, aFrame);
|
|
|
|
nsHTMLContainerFrame::CreateViewForFrame(aPresContext, newFrame,
|
1999-04-20 20:00:52 +00:00
|
|
|
styleContext, PR_FALSE);
|
|
|
|
}
|
|
|
|
|
1999-02-24 17:16:04 +00:00
|
|
|
} else if (nsLayoutAtoms::pageFrame == frameType) {
|
1999-12-04 23:49:50 +00:00
|
|
|
rv = NS_NewPageFrame(aPresShell, &newFrame);
|
1999-02-25 05:31:15 +00:00
|
|
|
if (NS_SUCCEEDED(rv)) {
|
1999-11-24 06:03:41 +00:00
|
|
|
newFrame->Init(aPresContext, content, aParentFrame, styleContext, aFrame);
|
|
|
|
nsHTMLContainerFrame::CreateViewForFrame(aPresContext, newFrame,
|
1999-02-25 05:31:15 +00:00
|
|
|
styleContext, PR_TRUE);
|
|
|
|
}
|
1999-02-24 17:16:04 +00:00
|
|
|
|
|
|
|
} else if (nsLayoutAtoms::tableOuterFrame == frameType) {
|
1999-12-04 23:49:50 +00:00
|
|
|
rv = CreateContinuingOuterTableFrame(aPresShell, aPresContext, aFrame, aParentFrame,
|
1999-02-26 03:35:22 +00:00
|
|
|
content, styleContext, &newFrame);
|
1999-02-24 17:16:04 +00:00
|
|
|
|
|
|
|
} else if (nsLayoutAtoms::tableFrame == frameType) {
|
1999-12-04 23:49:50 +00:00
|
|
|
rv = CreateContinuingTableFrame(aPresShell, aPresContext, aFrame, aParentFrame,
|
1999-03-03 16:33:57 +00:00
|
|
|
content, styleContext, &newFrame);
|
1999-02-24 17:16:04 +00:00
|
|
|
|
|
|
|
} else if (nsLayoutAtoms::tableRowGroupFrame == frameType) {
|
1999-12-04 23:49:50 +00:00
|
|
|
rv = NS_NewTableRowGroupFrame(aPresShell, &newFrame);
|
1999-02-25 05:31:15 +00:00
|
|
|
if (NS_SUCCEEDED(rv)) {
|
1999-11-24 06:03:41 +00:00
|
|
|
newFrame->Init(aPresContext, content, aParentFrame, styleContext, aFrame);
|
|
|
|
nsHTMLContainerFrame::CreateViewForFrame(aPresContext, newFrame,
|
1999-02-25 05:31:15 +00:00
|
|
|
styleContext, PR_FALSE);
|
|
|
|
}
|
1999-02-24 17:16:04 +00:00
|
|
|
|
|
|
|
} else if (nsLayoutAtoms::tableRowFrame == frameType) {
|
1999-12-04 23:49:50 +00:00
|
|
|
rv = NS_NewTableRowFrame(aPresShell, &newFrame);
|
1999-02-25 05:31:15 +00:00
|
|
|
if (NS_SUCCEEDED(rv)) {
|
1999-11-24 06:03:41 +00:00
|
|
|
newFrame->Init(aPresContext, content, aParentFrame, styleContext, aFrame);
|
|
|
|
nsHTMLContainerFrame::CreateViewForFrame(aPresContext, newFrame,
|
1999-02-25 05:31:15 +00:00
|
|
|
styleContext, PR_FALSE);
|
1999-02-24 17:16:04 +00:00
|
|
|
|
1999-02-25 05:31:15 +00:00
|
|
|
// Create a continuing frame for each table cell frame
|
|
|
|
nsIFrame* cellFrame;
|
|
|
|
nsFrameItems newChildList;
|
1999-02-24 17:16:04 +00:00
|
|
|
|
2000-01-22 01:16:50 +00:00
|
|
|
aFrame->FirstChild(aPresContext, nsnull, &cellFrame);
|
1999-02-25 05:31:15 +00:00
|
|
|
while (cellFrame) {
|
|
|
|
nsIAtom* tableType;
|
|
|
|
|
|
|
|
// See if it's a table cell frame
|
|
|
|
cellFrame->GetFrameType(&tableType);
|
|
|
|
if (nsLayoutAtoms::tableCellFrame == tableType) {
|
|
|
|
nsIFrame* continuingCellFrame;
|
1999-02-24 17:16:04 +00:00
|
|
|
|
1999-12-04 23:49:50 +00:00
|
|
|
CreateContinuingFrame(aPresShell, aPresContext, cellFrame, newFrame, &continuingCellFrame);
|
1999-02-25 05:31:15 +00:00
|
|
|
newChildList.AddChild(continuingCellFrame);
|
|
|
|
}
|
1999-02-24 17:16:04 +00:00
|
|
|
|
1999-02-25 05:31:15 +00:00
|
|
|
NS_IF_RELEASE(tableType);
|
|
|
|
cellFrame->GetNextSibling(&cellFrame);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Set the table cell's initial child list
|
1999-11-24 06:03:41 +00:00
|
|
|
newFrame->SetInitialChildList(aPresContext, nsnull, newChildList.childList);
|
1999-02-25 05:31:15 +00:00
|
|
|
}
|
1999-02-24 17:16:04 +00:00
|
|
|
|
1999-02-25 05:31:15 +00:00
|
|
|
} else if (nsLayoutAtoms::tableCellFrame == frameType) {
|
1999-12-04 23:49:50 +00:00
|
|
|
rv = NS_NewTableCellFrame(aPresShell, &newFrame);
|
1999-02-25 05:31:15 +00:00
|
|
|
if (NS_SUCCEEDED(rv)) {
|
1999-11-24 06:03:41 +00:00
|
|
|
newFrame->Init(aPresContext, content, aParentFrame, styleContext, aFrame);
|
|
|
|
nsHTMLContainerFrame::CreateViewForFrame(aPresContext, newFrame,
|
1999-02-25 05:31:15 +00:00
|
|
|
styleContext, PR_FALSE);
|
1999-02-24 17:16:04 +00:00
|
|
|
|
1999-02-25 05:31:15 +00:00
|
|
|
// Create a continuing area frame
|
|
|
|
nsIFrame* areaFrame;
|
|
|
|
nsIFrame* continuingAreaFrame;
|
2000-01-22 01:16:50 +00:00
|
|
|
aFrame->FirstChild(aPresContext, nsnull, &areaFrame);
|
1999-12-04 23:49:50 +00:00
|
|
|
CreateContinuingFrame(aPresShell, aPresContext, areaFrame, newFrame, &continuingAreaFrame);
|
1999-02-24 17:16:04 +00:00
|
|
|
|
1999-02-25 05:31:15 +00:00
|
|
|
// Set the table cell's initial child list
|
1999-11-24 06:03:41 +00:00
|
|
|
newFrame->SetInitialChildList(aPresContext, nsnull, continuingAreaFrame);
|
1999-02-24 17:16:04 +00:00
|
|
|
}
|
1999-04-27 22:14:54 +00:00
|
|
|
|
|
|
|
} else if (nsLayoutAtoms::lineFrame == frameType) {
|
1999-12-04 23:49:50 +00:00
|
|
|
rv = NS_NewFirstLineFrame(aPresShell, &newFrame);
|
1999-04-27 22:14:54 +00:00
|
|
|
if (NS_SUCCEEDED(rv)) {
|
1999-11-24 06:03:41 +00:00
|
|
|
newFrame->Init(aPresContext, content, aParentFrame, styleContext, aFrame);
|
|
|
|
nsHTMLContainerFrame::CreateViewForFrame(aPresContext, newFrame,
|
1999-04-27 22:14:54 +00:00
|
|
|
styleContext, PR_FALSE);
|
|
|
|
}
|
|
|
|
|
|
|
|
} else if (nsLayoutAtoms::letterFrame == frameType) {
|
1999-12-04 23:49:50 +00:00
|
|
|
rv = NS_NewFirstLetterFrame(aPresShell, &newFrame);
|
1999-04-27 22:14:54 +00:00
|
|
|
if (NS_SUCCEEDED(rv)) {
|
1999-11-24 06:03:41 +00:00
|
|
|
newFrame->Init(aPresContext, content, aParentFrame, styleContext, aFrame);
|
|
|
|
nsHTMLContainerFrame::CreateViewForFrame(aPresContext, newFrame,
|
1999-04-27 22:14:54 +00:00
|
|
|
styleContext, PR_FALSE);
|
|
|
|
}
|
1999-02-25 05:31:15 +00:00
|
|
|
|
|
|
|
} else {
|
|
|
|
NS_ASSERTION(PR_FALSE, "unexpected frame type");
|
|
|
|
rv = NS_ERROR_UNEXPECTED;
|
1999-02-24 17:16:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
*aContinuingFrame = newFrame;
|
1999-02-25 05:31:15 +00:00
|
|
|
NS_RELEASE(styleContext);
|
|
|
|
NS_IF_RELEASE(content);
|
|
|
|
NS_IF_RELEASE(frameType);
|
1999-02-24 17:16:04 +00:00
|
|
|
return rv;
|
1999-02-24 04:03:50 +00:00
|
|
|
}
|
|
|
|
|
2000-03-23 23:18:56 +00:00
|
|
|
// Helper function that searches the immediate child frames
|
|
|
|
// (and their children if the frames are "special")
|
|
|
|
// for a frame that maps the specified content object
|
|
|
|
nsIFrame*
|
|
|
|
nsCSSFrameConstructor::FindFrameWithContent(nsIPresContext* aPresContext,
|
|
|
|
nsIFrame* aParentFrame,
|
|
|
|
nsIContent* aParentContent,
|
|
|
|
nsIContent* aContent)
|
1999-07-02 04:47:05 +00:00
|
|
|
{
|
1999-07-06 03:52:33 +00:00
|
|
|
NS_PRECONDITION(aParentFrame, "No frame to search!");
|
|
|
|
if (!aParentFrame) {
|
|
|
|
return nsnull;
|
1999-07-02 04:47:05 +00:00
|
|
|
}
|
|
|
|
|
1999-07-06 03:52:33 +00:00
|
|
|
keepLooking:
|
|
|
|
// Search for the frame in each child list that aParentFrame supports
|
|
|
|
nsIAtom* listName = nsnull;
|
|
|
|
PRInt32 listIndex = 0;
|
|
|
|
do {
|
|
|
|
nsIFrame* kidFrame;
|
2000-01-22 01:16:50 +00:00
|
|
|
aParentFrame->FirstChild(aPresContext, listName, &kidFrame);
|
1999-07-06 03:52:33 +00:00
|
|
|
while (kidFrame) {
|
|
|
|
nsCOMPtr<nsIContent> kidContent;
|
|
|
|
|
|
|
|
// See if the child frame points to the content object we're
|
|
|
|
// looking for
|
|
|
|
kidFrame->GetContent(getter_AddRefs(kidContent));
|
|
|
|
if (kidContent.get() == aContent) {
|
|
|
|
nsCOMPtr<nsIAtom> frameType;
|
|
|
|
|
|
|
|
// We found a match. See if it's a placeholder frame
|
|
|
|
kidFrame->GetFrameType(getter_AddRefs(frameType));
|
|
|
|
if (nsLayoutAtoms::placeholderFrame == frameType.get()) {
|
|
|
|
// Ignore the placeholder and return the out-of-flow frame instead
|
|
|
|
return ((nsPlaceholderFrame*)kidFrame)->GetOutOfFlowFrame();
|
|
|
|
} else {
|
|
|
|
// Return the matching child frame
|
|
|
|
return kidFrame;
|
|
|
|
}
|
|
|
|
}
|
1999-07-02 04:47:05 +00:00
|
|
|
|
1999-07-06 03:52:33 +00:00
|
|
|
// We search the immediate children only, but if the child frame has
|
|
|
|
// the same content pointer as its parent then we need to search its
|
2000-05-25 19:58:51 +00:00
|
|
|
// child frames, too.
|
|
|
|
// We also need to search the child frame's children if the child frame
|
2000-03-23 23:18:56 +00:00
|
|
|
// is a "special" frame
|
2000-05-25 19:58:51 +00:00
|
|
|
if (kidContent.get() == aParentContent || IsFrameSpecial(kidFrame)) {
|
2000-01-22 01:16:50 +00:00
|
|
|
nsIFrame* matchingFrame = FindFrameWithContent(aPresContext, kidFrame, aParentContent,
|
1999-07-06 03:52:33 +00:00
|
|
|
aContent);
|
1999-07-02 04:47:05 +00:00
|
|
|
|
1999-07-06 03:52:33 +00:00
|
|
|
if (matchingFrame) {
|
|
|
|
return matchingFrame;
|
|
|
|
}
|
1999-07-02 04:47:05 +00:00
|
|
|
}
|
1999-07-06 03:52:33 +00:00
|
|
|
|
|
|
|
// Get the next sibling frame
|
|
|
|
kidFrame->GetNextSibling(&kidFrame);
|
1999-07-02 04:47:05 +00:00
|
|
|
}
|
|
|
|
|
1999-07-06 03:52:33 +00:00
|
|
|
NS_IF_RELEASE(listName);
|
|
|
|
aParentFrame->GetAdditionalChildListName(listIndex++, &listName);
|
|
|
|
} while(listName);
|
|
|
|
|
|
|
|
// We didn't find a matching frame. If aFrame has a next-in-flow,
|
|
|
|
// then continue looking there
|
|
|
|
aParentFrame->GetNextInFlow(&aParentFrame);
|
|
|
|
if (aParentFrame) {
|
|
|
|
goto keepLooking;
|
1999-07-02 04:47:05 +00:00
|
|
|
}
|
|
|
|
|
1999-07-06 03:52:33 +00:00
|
|
|
// No matching frame
|
1999-07-02 04:47:05 +00:00
|
|
|
return nsnull;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Request to find the primary frame associated with a given content object.
|
|
|
|
// This is typically called by the pres shell when there is no mapping in
|
|
|
|
// the pres shell hash table
|
|
|
|
NS_IMETHODIMP
|
1999-08-05 03:09:22 +00:00
|
|
|
nsCSSFrameConstructor::FindPrimaryFrameFor(nsIPresContext* aPresContext,
|
|
|
|
nsIFrameManager* aFrameManager,
|
|
|
|
nsIContent* aContent,
|
|
|
|
nsIFrame** aFrame)
|
1999-07-02 04:47:05 +00:00
|
|
|
{
|
1999-07-06 03:52:33 +00:00
|
|
|
*aFrame = nsnull; // initialize OUT parameter
|
1999-07-02 04:47:05 +00:00
|
|
|
|
1999-07-06 03:52:33 +00:00
|
|
|
// Get the pres shell
|
|
|
|
nsCOMPtr<nsIPresShell> presShell;
|
|
|
|
aPresContext->GetShell(getter_AddRefs(presShell));
|
1999-07-02 04:47:05 +00:00
|
|
|
|
1999-07-06 03:52:33 +00:00
|
|
|
// We want to be able to quickly map from a content object to its frame,
|
|
|
|
// but we also want to keep the hash table small. Therefore, many frames
|
|
|
|
// are not added to the hash table when they're first created:
|
|
|
|
// - text frames
|
|
|
|
// - inline frames (often things like FONT and B)
|
|
|
|
// - BR frames
|
|
|
|
// - internal table frames (row-group, row, cell, col-group, col)
|
|
|
|
//
|
|
|
|
// That means we need to need to search for the frame
|
2000-03-10 01:10:44 +00:00
|
|
|
nsCOMPtr<nsIContent> parentContent; // we get this one time
|
|
|
|
nsIFrame* parentFrame; // this pointer is used to iterate across all frames that map to parentContent
|
1999-07-06 03:52:33 +00:00
|
|
|
|
|
|
|
// Get the frame that corresponds to the parent content object.
|
|
|
|
// Note that this may recurse indirectly, because the pres shell will
|
|
|
|
// call us back if there is no mapping in the hash table
|
|
|
|
aContent->GetParent(*getter_AddRefs(parentContent));
|
|
|
|
if (parentContent.get()) {
|
1999-08-05 03:09:22 +00:00
|
|
|
aFrameManager->GetPrimaryFrameFor(parentContent, &parentFrame);
|
2000-03-10 01:10:44 +00:00
|
|
|
while (parentFrame) {
|
1999-07-06 03:52:33 +00:00
|
|
|
// Search the child frames for a match
|
2000-01-22 01:16:50 +00:00
|
|
|
*aFrame = FindFrameWithContent(aPresContext, parentFrame, parentContent.get(), aContent);
|
1999-07-02 04:47:05 +00:00
|
|
|
|
1999-07-06 03:52:33 +00:00
|
|
|
// If we found a match, then add a mapping to the hash table so
|
|
|
|
// next time this will be quick
|
|
|
|
if (*aFrame) {
|
1999-08-05 03:09:22 +00:00
|
|
|
aFrameManager->SetPrimaryFrameFor(aContent, *aFrame);
|
2000-03-10 01:10:44 +00:00
|
|
|
break;
|
|
|
|
}
|
2000-05-25 19:58:51 +00:00
|
|
|
else if (IsFrameSpecial(parentFrame)) {
|
|
|
|
// If it's a "special" frame (that is, part of an inline
|
|
|
|
// that's been split because it contained a block), we need to
|
|
|
|
// follow the out-of-flow "special sibling" link, and search
|
|
|
|
// *that* subtree as well.
|
|
|
|
nsIFrame* specialSibling = nsnull;
|
|
|
|
GetSpecialSibling(aFrameManager, parentFrame, &specialSibling);
|
|
|
|
parentFrame = specialSibling;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
break;
|
1999-07-06 03:52:33 +00:00
|
|
|
}
|
|
|
|
}
|
1999-07-02 04:47:05 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
1999-12-06 07:44:18 +00:00
|
|
|
// Capture state for the frame tree rooted at the frame associated with the
|
|
|
|
// content object, aContent
|
|
|
|
nsresult
|
|
|
|
nsCSSFrameConstructor::CaptureStateForFramesOf(nsIPresContext* aPresContext,
|
|
|
|
nsIContent* aContent,
|
|
|
|
nsILayoutHistoryState* aHistoryState)
|
|
|
|
{
|
|
|
|
nsCOMPtr<nsIPresShell> presShell;
|
|
|
|
nsresult rv = NS_OK;
|
|
|
|
|
|
|
|
rv = aPresContext->GetShell(getter_AddRefs(presShell));
|
|
|
|
if (NS_SUCCEEDED(rv) && presShell) {
|
|
|
|
nsIFrame* frame;
|
|
|
|
rv = presShell->GetPrimaryFrameFor(aContent, &frame);
|
|
|
|
if (NS_SUCCEEDED(rv) && frame) {
|
|
|
|
CaptureStateFor(aPresContext, frame, aHistoryState);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Capture state for the frame tree rooted at aFrame.
|
|
|
|
nsresult
|
|
|
|
nsCSSFrameConstructor::CaptureStateFor(nsIPresContext* aPresContext,
|
|
|
|
nsIFrame* aFrame,
|
|
|
|
nsILayoutHistoryState* aHistoryState)
|
|
|
|
{
|
|
|
|
nsresult rv = NS_OK;
|
|
|
|
|
|
|
|
if (aFrame && aPresContext && aHistoryState) {
|
|
|
|
nsCOMPtr<nsIPresShell> presShell;
|
|
|
|
rv = aPresContext->GetShell(getter_AddRefs(presShell));
|
|
|
|
if (NS_SUCCEEDED(rv) && presShell) {
|
|
|
|
nsCOMPtr<nsIFrameManager> frameManager;
|
|
|
|
rv = presShell->GetFrameManager(getter_AddRefs(frameManager));
|
|
|
|
if (NS_SUCCEEDED(rv) && frameManager) {
|
1999-12-06 09:03:16 +00:00
|
|
|
rv = frameManager->CaptureFrameState(aPresContext, aFrame, aHistoryState);
|
1999-12-06 07:44:18 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
1999-02-05 03:55:18 +00:00
|
|
|
nsresult
|
1999-02-27 07:15:09 +00:00
|
|
|
nsCSSFrameConstructor::RecreateFramesForContent(nsIPresContext* aPresContext,
|
|
|
|
nsIContent* aContent)
|
1999-02-05 03:55:18 +00:00
|
|
|
{
|
|
|
|
nsresult rv = NS_OK;
|
1999-12-06 07:44:18 +00:00
|
|
|
nsIContent* container;
|
1999-03-25 19:27:11 +00:00
|
|
|
rv = aContent->GetParent(container);
|
1999-12-06 07:44:18 +00:00
|
|
|
if (NS_SUCCEEDED(rv) && container) {
|
|
|
|
PRInt32 indexInContainer;
|
1999-03-25 19:27:11 +00:00
|
|
|
rv = container->IndexOf(aContent, indexInContainer);
|
1999-10-12 00:32:13 +00:00
|
|
|
if (NS_SUCCEEDED(rv)) {
|
1999-12-06 07:44:18 +00:00
|
|
|
// Before removing the frames associated with the content object, ask them to save their
|
|
|
|
// state onto a temporary state object.
|
|
|
|
CaptureStateForFramesOf(aPresContext, aContent, mTempFrameTreeState);
|
|
|
|
|
|
|
|
// Remove the frames associated with the content object on which the
|
1999-03-25 19:27:11 +00:00
|
|
|
// attribute change occurred.
|
|
|
|
rv = ContentRemoved(aPresContext, container, aContent, indexInContainer);
|
|
|
|
|
1999-10-12 00:32:13 +00:00
|
|
|
if (NS_SUCCEEDED(rv)) {
|
1999-03-25 19:27:11 +00:00
|
|
|
// Now, recreate the frames associated with this content object.
|
1999-12-06 07:44:18 +00:00
|
|
|
rv = ContentInserted(aPresContext, container, aContent, indexInContainer, mTempFrameTreeState);
|
|
|
|
}
|
1999-03-25 19:27:11 +00:00
|
|
|
}
|
1999-12-06 07:44:18 +00:00
|
|
|
NS_RELEASE(container);
|
1999-02-05 03:55:18 +00:00
|
|
|
}
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
1999-04-27 22:14:54 +00:00
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
// Block frame construction code
|
|
|
|
|
|
|
|
nsIStyleContext*
|
|
|
|
nsCSSFrameConstructor::GetFirstLetterStyle(nsIPresContext* aPresContext,
|
|
|
|
nsIContent* aContent,
|
|
|
|
nsIStyleContext* aStyleContext)
|
|
|
|
{
|
|
|
|
nsIStyleContext* fls = nsnull;
|
2000-06-17 01:46:58 +00:00
|
|
|
if (aContent) {
|
|
|
|
aPresContext->ResolvePseudoStyleContextFor(aContent,
|
|
|
|
nsHTMLAtoms::firstLetterPseudo,
|
|
|
|
aStyleContext, PR_FALSE, &fls);
|
|
|
|
}
|
1999-04-27 22:14:54 +00:00
|
|
|
return fls;
|
|
|
|
}
|
|
|
|
|
1999-08-31 03:09:40 +00:00
|
|
|
nsIStyleContext*
|
|
|
|
nsCSSFrameConstructor::GetFirstLineStyle(nsIPresContext* aPresContext,
|
|
|
|
nsIContent* aContent,
|
|
|
|
nsIStyleContext* aStyleContext)
|
|
|
|
{
|
|
|
|
nsIStyleContext* fls = nsnull;
|
2000-06-17 01:46:58 +00:00
|
|
|
if (aContent) {
|
|
|
|
aPresContext->ResolvePseudoStyleContextFor(aContent,
|
|
|
|
nsHTMLAtoms::firstLinePseudo,
|
|
|
|
aStyleContext, PR_FALSE, &fls);
|
|
|
|
}
|
1999-08-31 03:09:40 +00:00
|
|
|
return fls;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Predicate to see if a given content (block element) has
|
|
|
|
// first-letter style applied to it.
|
|
|
|
PRBool
|
|
|
|
nsCSSFrameConstructor::HaveFirstLetterStyle(nsIPresContext* aPresContext,
|
|
|
|
nsIContent* aContent,
|
|
|
|
nsIStyleContext* aStyleContext)
|
|
|
|
{
|
|
|
|
nsCOMPtr<nsIStyleContext> fls;
|
2000-06-17 01:46:58 +00:00
|
|
|
if (aContent) {
|
|
|
|
aPresContext->ProbePseudoStyleContextFor(aContent,
|
|
|
|
nsHTMLAtoms::firstLetterPseudo,
|
|
|
|
aStyleContext, PR_FALSE,
|
|
|
|
getter_AddRefs(fls));
|
|
|
|
}
|
1999-08-31 03:09:40 +00:00
|
|
|
PRBool result = PR_FALSE;
|
|
|
|
if (fls) {
|
|
|
|
result = PR_TRUE;
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
PRBool
|
|
|
|
nsCSSFrameConstructor::HaveFirstLineStyle(nsIPresContext* aPresContext,
|
|
|
|
nsIContent* aContent,
|
|
|
|
nsIStyleContext* aStyleContext)
|
|
|
|
{
|
|
|
|
nsCOMPtr<nsIStyleContext> fls;
|
2000-06-17 01:46:58 +00:00
|
|
|
if (aContent) {
|
|
|
|
aPresContext->ProbePseudoStyleContextFor(aContent,
|
|
|
|
nsHTMLAtoms::firstLinePseudo,
|
|
|
|
aStyleContext, PR_FALSE,
|
|
|
|
getter_AddRefs(fls));
|
|
|
|
}
|
1999-08-31 03:09:40 +00:00
|
|
|
PRBool result = PR_FALSE;
|
|
|
|
if (fls) {
|
|
|
|
result = PR_TRUE;
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
nsCSSFrameConstructor::HaveSpecialBlockStyle(nsIPresContext* aPresContext,
|
|
|
|
nsIContent* aContent,
|
|
|
|
nsIStyleContext* aStyleContext,
|
|
|
|
PRBool* aHaveFirstLetterStyle,
|
|
|
|
PRBool* aHaveFirstLineStyle)
|
|
|
|
{
|
|
|
|
*aHaveFirstLetterStyle =
|
|
|
|
HaveFirstLetterStyle(aPresContext, aContent, aStyleContext);
|
|
|
|
*aHaveFirstLineStyle =
|
|
|
|
HaveFirstLineStyle(aPresContext, aContent, aStyleContext);
|
|
|
|
}
|
|
|
|
|
1999-08-27 21:46:10 +00:00
|
|
|
/**
|
|
|
|
* Request to process the child content elements and create frames.
|
|
|
|
*
|
|
|
|
* @param aContent the content object whose child elements to process
|
|
|
|
* @param aFrame the the associated with aContent. This will be the
|
|
|
|
* parent frame (both content and geometric) for the flowed
|
|
|
|
* child frames
|
|
|
|
*/
|
1999-04-27 22:14:54 +00:00
|
|
|
nsresult
|
2000-04-04 01:28:15 +00:00
|
|
|
nsCSSFrameConstructor::ProcessChildren(nsIPresShell* aPresShell,
|
1999-12-04 23:49:50 +00:00
|
|
|
nsIPresContext* aPresContext,
|
1999-08-27 21:46:10 +00:00
|
|
|
nsFrameConstructorState& aState,
|
|
|
|
nsIContent* aContent,
|
|
|
|
nsIFrame* aFrame,
|
|
|
|
PRBool aCanHaveGeneratedContent,
|
|
|
|
nsFrameItems& aFrameItems,
|
2000-04-04 01:28:15 +00:00
|
|
|
PRBool aParentIsBlock,
|
|
|
|
nsTableCreator* aTableCreator)
|
1999-04-27 22:14:54 +00:00
|
|
|
{
|
|
|
|
nsresult rv = NS_OK;
|
1999-08-27 21:46:10 +00:00
|
|
|
nsCOMPtr<nsIStyleContext> styleContext;
|
1999-04-27 22:14:54 +00:00
|
|
|
|
|
|
|
if (aCanHaveGeneratedContent) {
|
|
|
|
// Probe for generated content before
|
|
|
|
nsIFrame* generatedFrame;
|
1999-08-27 21:46:10 +00:00
|
|
|
aFrame->GetStyleContext(getter_AddRefs(styleContext));
|
1999-12-04 23:49:50 +00:00
|
|
|
if (CreateGeneratedContentFrame(aPresShell, aPresContext, aState, aFrame, aContent,
|
1999-04-27 22:14:54 +00:00
|
|
|
styleContext, nsCSSAtoms::beforePseudo,
|
1999-08-27 21:46:10 +00:00
|
|
|
aParentIsBlock, &generatedFrame)) {
|
1999-04-27 22:14:54 +00:00
|
|
|
// Add the generated frame to the child list
|
|
|
|
aFrameItems.AddChild(generatedFrame);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2000-04-04 01:28:15 +00:00
|
|
|
if (aTableCreator) { // do special table child processing
|
|
|
|
// if there is a caption child here, it gets recorded in aState.mPseudoFrames.
|
|
|
|
nsIFrame* captionFrame;
|
|
|
|
TableProcessChildren(aPresShell, aPresContext, aState, aContent, aFrame,
|
|
|
|
*aTableCreator, aFrameItems, captionFrame);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
// save the incoming pseudo frame state
|
|
|
|
nsPseudoFrames priorPseudoFrames;
|
|
|
|
aState.mPseudoFrames.Reset(&priorPseudoFrames);
|
|
|
|
|
|
|
|
// Iterate the child content objects and construct frames
|
|
|
|
PRInt32 count;
|
|
|
|
aContent->ChildCount(count);
|
|
|
|
for (PRInt32 i = 0; i < count; i++) {
|
|
|
|
nsCOMPtr<nsIContent> childContent;
|
|
|
|
if (NS_SUCCEEDED(aContent->ChildAt(i, *getter_AddRefs(childContent)))) {
|
|
|
|
// Construct a child frame
|
|
|
|
rv = ConstructFrame(aPresShell, aPresContext, aState, childContent, aFrame, aFrameItems);
|
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
return rv;
|
|
|
|
}
|
1999-04-27 22:14:54 +00:00
|
|
|
}
|
|
|
|
}
|
2000-04-04 01:28:15 +00:00
|
|
|
// process the current pseudo frame state
|
|
|
|
if (!aState.mPseudoFrames.IsEmpty()) {
|
|
|
|
ProcessPseudoFrames(aPresContext, aState.mPseudoFrames, aFrameItems);
|
|
|
|
}
|
|
|
|
|
|
|
|
// restore the incoming pseudo frame state
|
|
|
|
aState.mPseudoFrames = priorPseudoFrames;
|
1999-04-27 22:14:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (aCanHaveGeneratedContent) {
|
|
|
|
// Probe for generated content after
|
|
|
|
nsIFrame* generatedFrame;
|
1999-12-04 23:49:50 +00:00
|
|
|
if (CreateGeneratedContentFrame(aPresShell, aPresContext, aState, aFrame, aContent,
|
1999-04-27 22:14:54 +00:00
|
|
|
styleContext, nsCSSAtoms::afterPseudo,
|
1999-08-27 21:46:10 +00:00
|
|
|
aParentIsBlock, &generatedFrame)) {
|
1999-04-27 22:14:54 +00:00
|
|
|
// Add the generated frame to the child list
|
|
|
|
aFrameItems.AddChild(generatedFrame);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1999-11-01 15:24:57 +00:00
|
|
|
if (aParentIsBlock) {
|
|
|
|
if (aState.mFirstLetterStyle) {
|
1999-12-04 23:49:50 +00:00
|
|
|
rv = WrapFramesInFirstLetterFrame(aPresShell, aPresContext, aState, aContent, aFrame, aFrameItems);
|
1999-11-01 15:24:57 +00:00
|
|
|
}
|
|
|
|
if (aState.mFirstLineStyle) {
|
1999-12-04 23:49:50 +00:00
|
|
|
rv = WrapFramesInFirstLineFrame(aPresShell, aPresContext, aState, aContent, aFrame, aFrameItems);
|
1999-11-01 15:24:57 +00:00
|
|
|
}
|
1999-08-31 03:09:40 +00:00
|
|
|
}
|
|
|
|
|
1999-04-27 22:14:54 +00:00
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
1999-08-31 03:09:40 +00:00
|
|
|
//----------------------------------------------------------------------
|
|
|
|
|
|
|
|
// Support for :first-line style
|
|
|
|
|
|
|
|
static void
|
|
|
|
ReparentFrame(nsIPresContext* aPresContext,
|
|
|
|
nsIFrame* aNewParentFrame,
|
|
|
|
nsIStyleContext* aParentStyleContext,
|
|
|
|
nsIFrame* aFrame)
|
|
|
|
{
|
1999-09-03 23:37:37 +00:00
|
|
|
aPresContext->ReParentStyleContext(aFrame, aParentStyleContext);
|
1999-08-31 03:09:40 +00:00
|
|
|
aFrame->SetParent(aNewParentFrame);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Special routine to handle placing a list of frames into a block
|
|
|
|
// frame that has first-line style. The routine ensures that the first
|
|
|
|
// collection of inline frames end up in a first-line frame.
|
|
|
|
nsresult
|
|
|
|
nsCSSFrameConstructor::WrapFramesInFirstLineFrame(
|
1999-12-04 23:49:50 +00:00
|
|
|
nsIPresShell* aPresShell,
|
1999-08-31 03:09:40 +00:00
|
|
|
nsIPresContext* aPresContext,
|
|
|
|
nsFrameConstructorState& aState,
|
|
|
|
nsIContent* aContent,
|
|
|
|
nsIFrame* aFrame,
|
|
|
|
nsFrameItems& aFrameItems)
|
|
|
|
{
|
|
|
|
nsresult rv = NS_OK;
|
|
|
|
|
|
|
|
// Find the first and last inline frame in aFrameItems
|
|
|
|
nsIFrame* kid = aFrameItems.childList;
|
|
|
|
nsIFrame* firstInlineFrame = nsnull;
|
|
|
|
nsIFrame* lastInlineFrame = nsnull;
|
|
|
|
while (kid) {
|
|
|
|
if (IsInlineFrame(kid)) {
|
|
|
|
if (!firstInlineFrame) firstInlineFrame = kid;
|
|
|
|
lastInlineFrame = kid;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
kid->GetNextSibling(&kid);
|
|
|
|
}
|
|
|
|
|
|
|
|
// If we don't find any inline frames, then there is nothing to do
|
|
|
|
if (!firstInlineFrame) {
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Create line frame
|
|
|
|
nsCOMPtr<nsIStyleContext> parentStyle;
|
|
|
|
aFrame->GetStyleContext(getter_AddRefs(parentStyle));
|
|
|
|
nsCOMPtr<nsIStyleContext> firstLineStyle(
|
|
|
|
getter_AddRefs(GetFirstLineStyle(aPresContext, aContent, parentStyle))
|
|
|
|
);
|
|
|
|
nsIFrame* lineFrame;
|
1999-12-04 23:49:50 +00:00
|
|
|
rv = NS_NewFirstLineFrame(aPresShell, &lineFrame);
|
1999-08-31 03:09:40 +00:00
|
|
|
if (NS_SUCCEEDED(rv)) {
|
|
|
|
// Initialize the line frame
|
1999-12-06 07:44:18 +00:00
|
|
|
rv = InitAndRestoreFrame(aPresContext, aState, aContent,
|
|
|
|
aFrame, firstLineStyle, nsnull, lineFrame);
|
1999-08-31 03:09:40 +00:00
|
|
|
|
|
|
|
// Mangle the list of frames we are giving to the block: first
|
|
|
|
// chop the list in two after lastInlineFrame
|
|
|
|
nsIFrame* secondBlockFrame;
|
|
|
|
lastInlineFrame->GetNextSibling(&secondBlockFrame);
|
|
|
|
lastInlineFrame->SetNextSibling(nsnull);
|
|
|
|
|
|
|
|
// The lineFrame will be the block's first child; the rest of the
|
|
|
|
// frame list (after lastInlineFrame) will be the second and
|
|
|
|
// subsequent children; join the list together and reset
|
|
|
|
// aFrameItems appropriately.
|
|
|
|
if (secondBlockFrame) {
|
|
|
|
lineFrame->SetNextSibling(secondBlockFrame);
|
|
|
|
}
|
|
|
|
if (aFrameItems.childList == lastInlineFrame) {
|
|
|
|
// Just in case the block had exactly one inline child
|
|
|
|
aFrameItems.lastChild = lineFrame;
|
|
|
|
}
|
|
|
|
aFrameItems.childList = lineFrame;
|
|
|
|
|
|
|
|
// Give the inline frames to the lineFrame <b>after</b> reparenting them
|
|
|
|
kid = firstInlineFrame;
|
|
|
|
while (kid) {
|
|
|
|
ReparentFrame(aPresContext, lineFrame, firstLineStyle, kid);
|
|
|
|
kid->GetNextSibling(&kid);
|
|
|
|
}
|
1999-11-24 06:03:41 +00:00
|
|
|
lineFrame->SetInitialChildList(aPresContext, nsnull, firstInlineFrame);
|
1999-08-31 03:09:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Special routine to handle appending a new frame to a block frame's
|
|
|
|
// child list. Takes care of placing the new frame into the right
|
|
|
|
// place when first-line style is present.
|
|
|
|
nsresult
|
|
|
|
nsCSSFrameConstructor::AppendFirstLineFrames(
|
1999-12-04 23:49:50 +00:00
|
|
|
nsIPresShell* aPresShell,
|
1999-08-31 03:09:40 +00:00
|
|
|
nsIPresContext* aPresContext,
|
|
|
|
nsFrameConstructorState& aState,
|
|
|
|
nsIContent* aContent,
|
|
|
|
nsIFrame* aBlockFrame,
|
|
|
|
nsFrameItems& aFrameItems)
|
|
|
|
{
|
|
|
|
// It's possible that aBlockFrame needs to have a first-line frame
|
|
|
|
// created because it doesn't currently have any children.
|
|
|
|
nsIFrame* blockKid;
|
2000-01-22 01:16:50 +00:00
|
|
|
aBlockFrame->FirstChild(aPresContext, nsnull, &blockKid);
|
1999-08-31 03:09:40 +00:00
|
|
|
if (!blockKid) {
|
1999-12-04 23:49:50 +00:00
|
|
|
return WrapFramesInFirstLineFrame(aPresShell, aPresContext, aState, aContent,
|
1999-08-31 03:09:40 +00:00
|
|
|
aBlockFrame, aFrameItems);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Examine the last block child - if it's a first-line frame then
|
|
|
|
// appended frames need special treatment.
|
|
|
|
nsresult rv = NS_OK;
|
|
|
|
nsFrameList blockFrames(blockKid);
|
|
|
|
nsIFrame* lastBlockKid = blockFrames.LastChild();
|
|
|
|
nsCOMPtr<nsIAtom> frameType;
|
|
|
|
lastBlockKid->GetFrameType(getter_AddRefs(frameType));
|
1999-08-31 07:14:54 +00:00
|
|
|
if (frameType.get() != nsLayoutAtoms::lineFrame) {
|
1999-08-31 03:09:40 +00:00
|
|
|
// No first-line frame at the end of the list, therefore there is
|
|
|
|
// an interveening block between any first-line frame the frames
|
|
|
|
// we are appending. Therefore, we don't need any special
|
|
|
|
// treatment of the appended frames.
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
nsIFrame* lineFrame = lastBlockKid;
|
|
|
|
nsCOMPtr<nsIStyleContext> firstLineStyle;
|
|
|
|
lineFrame->GetStyleContext(getter_AddRefs(firstLineStyle));
|
|
|
|
|
|
|
|
// Find the first and last inline frame in aFrameItems
|
|
|
|
nsIFrame* kid = aFrameItems.childList;
|
|
|
|
nsIFrame* firstInlineFrame = nsnull;
|
|
|
|
nsIFrame* lastInlineFrame = nsnull;
|
|
|
|
while (kid) {
|
|
|
|
if (IsInlineFrame(kid)) {
|
|
|
|
if (!firstInlineFrame) firstInlineFrame = kid;
|
|
|
|
lastInlineFrame = kid;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
kid->GetNextSibling(&kid);
|
|
|
|
}
|
|
|
|
|
|
|
|
// If we don't find any inline frames, then there is nothing to do
|
|
|
|
if (!firstInlineFrame) {
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
// The inline frames get appended to the lineFrame. Make sure they
|
|
|
|
// are reparented properly.
|
|
|
|
nsIFrame* remainingFrames;
|
|
|
|
lastInlineFrame->GetNextSibling(&remainingFrames);
|
|
|
|
lastInlineFrame->SetNextSibling(nsnull);
|
|
|
|
kid = firstInlineFrame;
|
|
|
|
while (kid) {
|
|
|
|
ReparentFrame(aPresContext, lineFrame, firstLineStyle, kid);
|
|
|
|
kid->GetNextSibling(&kid);
|
|
|
|
}
|
1999-11-24 06:03:41 +00:00
|
|
|
aState.mFrameManager->AppendFrames(aPresContext, *aState.mPresShell,
|
1999-08-31 03:09:40 +00:00
|
|
|
lineFrame, nsnull, firstInlineFrame);
|
|
|
|
|
|
|
|
// The remaining frames get appended to the block frame
|
|
|
|
if (remainingFrames) {
|
|
|
|
aFrameItems.childList = remainingFrames;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
aFrameItems.childList = nsnull;
|
|
|
|
aFrameItems.lastChild = nsnull;
|
|
|
|
}
|
|
|
|
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Special routine to handle inserting a new frame into a block
|
|
|
|
// frame's child list. Takes care of placing the new frame into the
|
|
|
|
// right place when first-line style is present.
|
|
|
|
nsresult
|
|
|
|
nsCSSFrameConstructor::InsertFirstLineFrames(
|
|
|
|
nsIPresContext* aPresContext,
|
|
|
|
nsFrameConstructorState& aState,
|
|
|
|
nsIContent* aContent,
|
|
|
|
nsIFrame* aBlockFrame,
|
|
|
|
nsIFrame** aParentFrame,
|
|
|
|
nsIFrame* aPrevSibling,
|
|
|
|
nsFrameItems& aFrameItems)
|
|
|
|
{
|
|
|
|
nsresult rv = NS_OK;
|
|
|
|
#if 0
|
|
|
|
nsIFrame* parentFrame = *aParentFrame;
|
|
|
|
nsIFrame* newFrame = aFrameItems.childList;
|
|
|
|
PRBool isInline = IsInlineFrame(newFrame);
|
|
|
|
|
|
|
|
if (!aPrevSibling) {
|
|
|
|
// Insertion will become the first frame. Two cases: we either
|
|
|
|
// already have a first-line frame or we don't.
|
|
|
|
nsIFrame* firstBlockKid;
|
|
|
|
aBlockFrame->FirstChild(nsnull, &firstBlockKid);
|
|
|
|
nsCOMPtr<nsIAtom> frameType;
|
|
|
|
firstBlockKid->GetFrameType(getter_AddRefs(frameType));
|
1999-09-01 01:00:25 +00:00
|
|
|
if (frameType.get() == nsLayoutAtoms::lineFrame) {
|
1999-08-31 03:09:40 +00:00
|
|
|
// We already have a first-line frame
|
|
|
|
nsIFrame* lineFrame = firstBlockKid;
|
|
|
|
nsCOMPtr<nsIStyleContext> firstLineStyle;
|
|
|
|
lineFrame->GetStyleContext(getter_AddRefs(firstLineStyle));
|
|
|
|
|
|
|
|
if (isInline) {
|
|
|
|
// Easy case: the new inline frame will go into the lineFrame.
|
|
|
|
ReparentFrame(aPresContext, lineFrame, firstLineStyle, newFrame);
|
1999-11-24 06:03:41 +00:00
|
|
|
aState.mFrameManager->InsertFrames(aPresContext, *aState.mPresShell,
|
1999-08-31 03:09:40 +00:00
|
|
|
lineFrame, nsnull, nsnull,
|
|
|
|
newFrame);
|
|
|
|
|
|
|
|
// Since the frame is going into the lineFrame, don't let it
|
|
|
|
// go into the block too.
|
|
|
|
aFrameItems.childList = nsnull;
|
|
|
|
aFrameItems.lastChild = nsnull;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
// Harder case: We are about to insert a block level element
|
|
|
|
// before the first-line frame.
|
|
|
|
// XXX need a method to steal away frames from the line-frame
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
// We do not have a first-line frame
|
|
|
|
if (isInline) {
|
|
|
|
// We now need a first-line frame to contain the inline frame.
|
|
|
|
nsIFrame* lineFrame;
|
|
|
|
rv = NS_NewFirstLineFrame(&lineFrame);
|
|
|
|
if (NS_SUCCEEDED(rv)) {
|
|
|
|
// Lookup first-line style context
|
|
|
|
nsCOMPtr<nsIStyleContext> parentStyle;
|
|
|
|
aBlockFrame->GetStyleContext(getter_AddRefs(parentStyle));
|
|
|
|
nsCOMPtr<nsIStyleContext> firstLineStyle(
|
|
|
|
getter_AddRefs(GetFirstLineStyle(aPresContext, aContent,
|
|
|
|
parentStyle))
|
|
|
|
);
|
|
|
|
|
|
|
|
// Initialize the line frame
|
1999-12-06 07:44:18 +00:00
|
|
|
rv = InitAndRestoreFrame(aPresContext, aState, aContent,
|
|
|
|
aBlockFrame, firstLineStyle, nsnull, lineFrame);
|
1999-08-31 03:09:40 +00:00
|
|
|
|
|
|
|
// Make sure the caller inserts the lineFrame into the
|
|
|
|
// blocks list of children.
|
|
|
|
aFrameItems.childList = lineFrame;
|
|
|
|
aFrameItems.lastChild = lineFrame;
|
|
|
|
|
|
|
|
// Give the inline frames to the lineFrame <b>after</b>
|
|
|
|
// reparenting them
|
|
|
|
ReparentFrame(aPresContext, lineFrame, firstLineStyle, newFrame);
|
1999-11-24 06:03:41 +00:00
|
|
|
lineFrame->SetInitialChildList(aPresContext, nsnull, newFrame);
|
1999-08-31 03:09:40 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
// Easy case: the regular insertion logic can insert the new
|
|
|
|
// frame because its a block frame.
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
// Insertion will not be the first frame.
|
|
|
|
nsIFrame* prevSiblingParent;
|
|
|
|
aPrevSibling->GetParent(&prevSiblingParent);
|
|
|
|
if (prevSiblingParent == aBlockFrame) {
|
|
|
|
// Easy case: The prev-siblings parent is the block
|
|
|
|
// frame. Therefore the prev-sibling is not currently in a
|
|
|
|
// line-frame. Therefore the new frame which is going after it,
|
|
|
|
// regardless of type, is not going into a line-frame.
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
// If the prevSiblingParent is not the block-frame then it must
|
|
|
|
// be a line-frame (if it were a letter-frame, that logic would
|
|
|
|
// already have adjusted the prev-sibling to be the
|
|
|
|
// letter-frame).
|
|
|
|
if (isInline) {
|
|
|
|
// Easy case: the insertion can go where the caller thinks it
|
|
|
|
// should go (which is into prevSiblingParent).
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
// Block elements don't end up in line-frames, therefore
|
|
|
|
// change the insertion point to aBlockFrame. However, there
|
|
|
|
// might be more inline elements following aPrevSibling that
|
|
|
|
// need to be pulled out of the line-frame and become children
|
|
|
|
// of the block.
|
|
|
|
nsIFrame* nextSibling;
|
|
|
|
aPrevSibling->GetNextSibling(&nextSibling);
|
|
|
|
nsIFrame* nextLineFrame;
|
|
|
|
prevSiblingParent->GetNextInFlow(&nextLineFrame);
|
|
|
|
if (nextSibling || nextLineFrame) {
|
|
|
|
// Oy. We have work to do. Create a list of the new frames
|
|
|
|
// that are going into the block by stripping them away from
|
|
|
|
// the line-frame(s).
|
|
|
|
nsFrameList list(nextSibling);
|
|
|
|
if (nextSibling) {
|
|
|
|
nsLineFrame* lineFrame = (nsLineFrame*) prevSiblingParent;
|
|
|
|
lineFrame->StealFramesFrom(nextSibling);
|
|
|
|
}
|
|
|
|
|
|
|
|
nsLineFrame* nextLineFrame = (nsLineFrame*) lineFrame;
|
|
|
|
for (;;) {
|
|
|
|
nextLineFrame->GetNextInFlow(&nextLineFrame);
|
|
|
|
if (!nextLineFrame) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
nsIFrame* kids;
|
|
|
|
nextLineFrame->FirstChild(nsnull, &kids);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
// We got lucky: aPrevSibling was the last inline frame in
|
|
|
|
// the line-frame.
|
|
|
|
ReparentFrame(aPresContext, aBlockFrame, firstLineStyle, newFrame);
|
1999-11-24 06:03:41 +00:00
|
|
|
aState.mFrameManager->InsertFrames(aPresContext, *aState.mPresShell,
|
1999-08-31 03:09:40 +00:00
|
|
|
aBlockFrame, nsnull,
|
|
|
|
prevSiblingParent, newFrame);
|
|
|
|
aFrameItems.childList = nsnull;
|
|
|
|
aFrameItems.lastChild = nsnull;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
|
1999-10-29 14:39:48 +00:00
|
|
|
// First-letter support
|
|
|
|
|
1999-08-27 21:46:10 +00:00
|
|
|
// Determine how many characters in the text fragment apply to the
|
|
|
|
// first letter
|
1999-04-27 22:14:54 +00:00
|
|
|
static PRInt32
|
1999-10-15 23:36:07 +00:00
|
|
|
FirstLetterCount(const nsTextFragment* aFragment)
|
1999-04-27 22:14:54 +00:00
|
|
|
{
|
|
|
|
PRInt32 count = 0;
|
|
|
|
PRInt32 firstLetterLength = 0;
|
|
|
|
PRBool done = PR_FALSE;
|
1999-10-15 23:36:07 +00:00
|
|
|
|
|
|
|
PRInt32 i, n = aFragment->GetLength();
|
|
|
|
for (i = 0; i < n; i++) {
|
|
|
|
PRUnichar ch = aFragment->CharAt(i);
|
|
|
|
if (XP_IS_SPACE(ch)) {
|
|
|
|
if (firstLetterLength) {
|
|
|
|
done = PR_TRUE;
|
|
|
|
break;
|
1999-04-27 22:14:54 +00:00
|
|
|
}
|
1999-10-15 23:36:07 +00:00
|
|
|
count++;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
// XXX I18n
|
|
|
|
if ((ch == '\'') || (ch == '\"')) {
|
|
|
|
if (firstLetterLength) {
|
1999-04-27 22:14:54 +00:00
|
|
|
done = PR_TRUE;
|
|
|
|
break;
|
|
|
|
}
|
1999-10-15 23:36:07 +00:00
|
|
|
// keep looping
|
|
|
|
firstLetterLength = 1;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
count++;
|
|
|
|
done = PR_TRUE;
|
|
|
|
break;
|
1999-04-27 22:14:54 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1999-10-15 23:36:07 +00:00
|
|
|
return count;
|
1999-04-27 22:14:54 +00:00
|
|
|
}
|
|
|
|
|
1999-08-31 03:09:40 +00:00
|
|
|
static PRBool
|
|
|
|
NeedFirstLetterContinuation(nsIContent* aContent)
|
1999-04-27 22:14:54 +00:00
|
|
|
{
|
|
|
|
NS_PRECONDITION(aContent, "null ptr");
|
|
|
|
|
|
|
|
PRBool result = PR_FALSE;
|
|
|
|
if (aContent) {
|
1999-08-31 03:09:40 +00:00
|
|
|
nsCOMPtr<nsITextContent> tc(do_QueryInterface(aContent));
|
|
|
|
if (tc) {
|
1999-10-15 23:36:07 +00:00
|
|
|
const nsTextFragment* frag = nsnull;
|
|
|
|
tc->GetText(&frag);
|
|
|
|
PRInt32 flc = FirstLetterCount(frag);
|
|
|
|
PRInt32 tl = frag->GetLength();
|
1999-04-27 22:14:54 +00:00
|
|
|
if (flc < tl) {
|
|
|
|
result = PR_TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
1999-10-29 14:39:48 +00:00
|
|
|
static PRBool IsFirstLetterContent(nsIContent* aContent)
|
|
|
|
{
|
|
|
|
PRBool result = PR_FALSE;
|
|
|
|
|
|
|
|
nsCOMPtr<nsITextContent> textContent = do_QueryInterface(aContent);
|
|
|
|
if (textContent) {
|
|
|
|
PRInt32 textLength;
|
|
|
|
textContent->GetTextLength(&textLength);
|
|
|
|
if (textLength) {
|
|
|
|
PRBool onlyWhiteSpace;
|
|
|
|
textContent->IsOnlyWhitespace(&onlyWhiteSpace);
|
|
|
|
result = !onlyWhiteSpace;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Create a letter frame, only make it a floating frame.
|
|
|
|
*/
|
1999-04-27 22:14:54 +00:00
|
|
|
void
|
1999-10-29 14:39:48 +00:00
|
|
|
nsCSSFrameConstructor::CreateFloatingLetterFrame(
|
1999-12-04 23:49:50 +00:00
|
|
|
nsIPresShell* aPresShell,
|
1999-04-27 22:14:54 +00:00
|
|
|
nsIPresContext* aPresContext,
|
1999-10-29 14:39:48 +00:00
|
|
|
nsFrameConstructorState& aState,
|
|
|
|
nsIContent* aTextContent,
|
1999-04-27 22:14:54 +00:00
|
|
|
nsIFrame* aTextFrame,
|
1999-10-29 14:39:48 +00:00
|
|
|
nsIContent* aBlockContent,
|
1999-04-27 22:14:54 +00:00
|
|
|
nsIFrame* aParentFrame,
|
1999-10-29 14:39:48 +00:00
|
|
|
nsIStyleContext* aStyleContext,
|
|
|
|
nsFrameItems& aResult)
|
1999-04-27 22:14:54 +00:00
|
|
|
{
|
1999-10-29 14:39:48 +00:00
|
|
|
// Create the first-letter-frame
|
|
|
|
nsIFrame* letterFrame;
|
1999-12-06 07:44:18 +00:00
|
|
|
|
|
|
|
NS_NewFirstLetterFrame(aPresShell, &letterFrame);
|
|
|
|
InitAndRestoreFrame(aPresContext, aState, aTextContent,
|
|
|
|
aParentFrame, aStyleContext, nsnull, letterFrame);
|
1999-10-29 14:39:48 +00:00
|
|
|
|
|
|
|
// Init the text frame to refer to the letter frame. Make sure we
|
|
|
|
// get a proper style context for it (the one passed in is for the
|
|
|
|
// letter frame and will have the float property set on it; the text
|
|
|
|
// frame shouldn't have that set).
|
|
|
|
nsCOMPtr<nsIStyleContext> textSC;
|
|
|
|
aPresContext->ResolveStyleContextFor(aTextContent, aStyleContext, PR_FALSE,
|
1999-12-06 07:44:18 +00:00
|
|
|
getter_AddRefs(textSC));
|
|
|
|
InitAndRestoreFrame(aPresContext, aState, aTextContent,
|
|
|
|
letterFrame, textSC, nsnull, aTextFrame);
|
1999-10-29 14:39:48 +00:00
|
|
|
|
|
|
|
// And then give the text frame to the letter frame
|
1999-11-24 06:03:41 +00:00
|
|
|
letterFrame->SetInitialChildList(aPresContext, nsnull, aTextFrame);
|
1999-10-29 14:39:48 +00:00
|
|
|
|
|
|
|
// Now make the placeholder
|
|
|
|
nsIFrame* placeholderFrame;
|
1999-12-04 23:49:50 +00:00
|
|
|
CreatePlaceholderFrameFor(aPresShell, aPresContext, aState.mFrameManager, aTextContent,
|
1999-10-29 14:39:48 +00:00
|
|
|
letterFrame, aStyleContext, aParentFrame,
|
|
|
|
&placeholderFrame);
|
|
|
|
|
1999-04-27 22:14:54 +00:00
|
|
|
// See if we will need to continue the text frame (does it contain
|
|
|
|
// more than just the first-letter text or not?) If it does, then we
|
|
|
|
// create (in advance) a continuation frame for it.
|
|
|
|
nsIFrame* nextTextFrame = nsnull;
|
1999-10-29 14:39:48 +00:00
|
|
|
if (NeedFirstLetterContinuation(aTextContent)) {
|
1999-04-27 22:14:54 +00:00
|
|
|
// Create continuation
|
1999-12-04 23:49:50 +00:00
|
|
|
CreateContinuingFrame(aPresShell, aPresContext, aTextFrame, aParentFrame,
|
1999-04-27 22:14:54 +00:00
|
|
|
&nextTextFrame);
|
|
|
|
|
1999-10-29 14:39:48 +00:00
|
|
|
// Repair the continuations style context
|
|
|
|
nsCOMPtr<nsIStyleContext> parentStyleContext;
|
|
|
|
parentStyleContext = getter_AddRefs(aStyleContext->GetParent());
|
|
|
|
if (parentStyleContext) {
|
|
|
|
nsCOMPtr<nsIStyleContext> newSC;
|
|
|
|
aPresContext->ResolveStyleContextFor(aTextContent, parentStyleContext,
|
|
|
|
PR_FALSE, getter_AddRefs(newSC));
|
|
|
|
if (newSC) {
|
|
|
|
nextTextFrame->SetStyleContext(aPresContext, newSC);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
1999-04-27 22:14:54 +00:00
|
|
|
|
|
|
|
// Update the child lists for the frame containing the floating first
|
|
|
|
// letter frame.
|
1999-10-29 14:39:48 +00:00
|
|
|
aState.mFloatedItems.AddChild(letterFrame);
|
|
|
|
aResult.childList = aResult.lastChild = placeholderFrame;
|
1999-04-27 22:14:54 +00:00
|
|
|
if (nextTextFrame) {
|
1999-10-29 14:39:48 +00:00
|
|
|
aResult.AddChild(nextTextFrame);
|
1999-04-27 22:14:54 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1999-10-29 14:39:48 +00:00
|
|
|
/**
|
|
|
|
* Create a new letter frame for aTextFrame. The letter frame will be
|
|
|
|
* a child of aParentFrame.
|
|
|
|
*/
|
1999-04-27 22:14:54 +00:00
|
|
|
nsresult
|
1999-12-04 23:49:50 +00:00
|
|
|
nsCSSFrameConstructor::CreateLetterFrame(nsIPresShell* aPresShell, nsIPresContext* aPresContext,
|
1999-10-29 14:39:48 +00:00
|
|
|
nsFrameConstructorState& aState,
|
|
|
|
nsIContent* aTextContent,
|
|
|
|
nsIFrame* aParentFrame,
|
|
|
|
nsFrameItems& aResult)
|
1999-04-27 22:14:54 +00:00
|
|
|
{
|
1999-10-29 14:39:48 +00:00
|
|
|
nsCOMPtr<nsIContent> parentContent;
|
|
|
|
aParentFrame->GetContent(getter_AddRefs(parentContent));
|
|
|
|
|
1999-04-27 22:14:54 +00:00
|
|
|
// Get style context for the first-letter-frame
|
1999-10-29 14:39:48 +00:00
|
|
|
nsCOMPtr<nsIStyleContext> parentStyleContext;
|
|
|
|
aParentFrame->GetStyleContext(getter_AddRefs(parentStyleContext));
|
|
|
|
if (parentStyleContext) {
|
|
|
|
// Use content from containing block so that we can actually
|
|
|
|
// find a matching style rule.
|
|
|
|
nsCOMPtr<nsIContent> blockContent;
|
|
|
|
aState.mFloatedItems.containingBlock->GetContent(
|
|
|
|
getter_AddRefs(blockContent));
|
|
|
|
|
|
|
|
// Create first-letter style rule
|
|
|
|
nsCOMPtr<nsIStyleContext> sc = getter_AddRefs(
|
|
|
|
GetFirstLetterStyle(aPresContext, blockContent, parentStyleContext));
|
1999-04-27 22:14:54 +00:00
|
|
|
if (sc) {
|
1999-10-29 14:39:48 +00:00
|
|
|
// Create a new text frame (the original one will be discarded)
|
|
|
|
nsIFrame* textFrame;
|
1999-12-04 23:49:50 +00:00
|
|
|
NS_NewTextFrame(aPresShell, &textFrame);
|
1999-10-29 14:39:48 +00:00
|
|
|
|
|
|
|
// Create the right type of first-letter frame
|
1999-04-27 22:14:54 +00:00
|
|
|
const nsStyleDisplay* display = (const nsStyleDisplay*)
|
|
|
|
sc->GetStyleData(eStyleStruct_Display);
|
|
|
|
if (display->IsFloating()) {
|
1999-10-29 14:39:48 +00:00
|
|
|
// Make a floating first-letter frame
|
1999-12-04 23:49:50 +00:00
|
|
|
CreateFloatingLetterFrame(aPresShell, aPresContext, aState,
|
1999-10-29 14:39:48 +00:00
|
|
|
aTextContent, textFrame,
|
|
|
|
blockContent, aParentFrame,
|
|
|
|
sc, aResult);
|
1999-04-27 22:14:54 +00:00
|
|
|
}
|
|
|
|
else {
|
1999-10-29 14:39:48 +00:00
|
|
|
// Make an inflow first-letter frame
|
|
|
|
nsIFrame* letterFrame;
|
1999-12-04 23:49:50 +00:00
|
|
|
nsresult rv = NS_NewFirstLetterFrame(aPresShell, &letterFrame);
|
1999-04-27 22:14:54 +00:00
|
|
|
if (NS_SUCCEEDED(rv)) {
|
|
|
|
// Initialize the first-letter-frame.
|
1999-11-24 06:03:41 +00:00
|
|
|
letterFrame->Init(aPresContext, aTextContent, aParentFrame,
|
1999-10-29 14:39:48 +00:00
|
|
|
sc, nsnull);
|
|
|
|
nsCOMPtr<nsIStyleContext> textSC;
|
|
|
|
aPresContext->ResolveStyleContextFor(aTextContent, sc, PR_FALSE,
|
|
|
|
getter_AddRefs(textSC));
|
1999-12-06 07:44:18 +00:00
|
|
|
InitAndRestoreFrame(aPresContext, aState, aTextContent,
|
|
|
|
letterFrame, textSC, nsnull, textFrame);
|
1999-11-24 06:03:41 +00:00
|
|
|
letterFrame->SetInitialChildList(aPresContext, nsnull, textFrame);
|
1999-10-29 14:39:48 +00:00
|
|
|
aResult.childList = aResult.lastChild = letterFrame;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
nsCSSFrameConstructor::WrapFramesInFirstLetterFrame(
|
1999-12-04 23:49:50 +00:00
|
|
|
nsIPresShell* aPresShell,
|
1999-10-29 14:39:48 +00:00
|
|
|
nsIPresContext* aPresContext,
|
|
|
|
nsFrameConstructorState& aState,
|
|
|
|
nsIContent* aBlockContent,
|
|
|
|
nsIFrame* aBlockFrame,
|
|
|
|
nsFrameItems& aBlockFrames)
|
|
|
|
{
|
|
|
|
nsresult rv = NS_OK;
|
|
|
|
|
|
|
|
nsIFrame* parentFrame = nsnull;
|
|
|
|
nsIFrame* textFrame = nsnull;
|
|
|
|
nsIFrame* prevFrame = nsnull;
|
|
|
|
nsFrameItems letterFrames;
|
|
|
|
PRBool stopLooking = PR_FALSE;
|
1999-12-04 23:49:50 +00:00
|
|
|
rv = WrapFramesInFirstLetterFrame(aPresShell, aPresContext, aState,
|
1999-10-29 14:39:48 +00:00
|
|
|
aBlockFrame, aBlockFrames.childList,
|
|
|
|
&parentFrame, &textFrame, &prevFrame,
|
|
|
|
letterFrames, &stopLooking);
|
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
if (parentFrame) {
|
|
|
|
if (parentFrame == aBlockFrame) {
|
|
|
|
// Text textFrame out of the blocks frame list and substitute the
|
|
|
|
// letter frame(s) instead.
|
|
|
|
nsIFrame* nextSibling;
|
|
|
|
textFrame->GetNextSibling(&nextSibling);
|
|
|
|
textFrame->SetNextSibling(nsnull);
|
|
|
|
if (prevFrame) {
|
|
|
|
prevFrame->SetNextSibling(letterFrames.childList);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
aBlockFrames.childList = letterFrames.childList;
|
|
|
|
}
|
|
|
|
letterFrames.lastChild->SetNextSibling(nextSibling);
|
|
|
|
|
|
|
|
// Destroy the old textFrame
|
1999-11-24 06:03:41 +00:00
|
|
|
textFrame->Destroy(aPresContext);
|
1999-10-29 14:39:48 +00:00
|
|
|
|
|
|
|
// Repair lastChild; the only time this needs to happen is when
|
|
|
|
// the block had one child (the text frame).
|
|
|
|
if (!nextSibling) {
|
|
|
|
aBlockFrames.lastChild = letterFrames.lastChild;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
// Take the old textFrame out of the inline parents child list
|
1999-11-24 06:03:41 +00:00
|
|
|
parentFrame->RemoveFrame(aPresContext, *aState.mPresShell.get(),
|
1999-10-29 14:39:48 +00:00
|
|
|
nsnull, textFrame);
|
|
|
|
|
|
|
|
// Insert in the letter frame(s)
|
1999-11-24 06:03:41 +00:00
|
|
|
parentFrame->InsertFrames(aPresContext, *aState.mPresShell.get(),
|
1999-10-29 14:39:48 +00:00
|
|
|
nsnull, prevFrame, letterFrames.childList);
|
|
|
|
}
|
|
|
|
}
|
1999-04-27 22:14:54 +00:00
|
|
|
|
1999-10-29 14:39:48 +00:00
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
nsCSSFrameConstructor::WrapFramesInFirstLetterFrame(
|
1999-12-04 23:49:50 +00:00
|
|
|
nsIPresShell* aPresShell,
|
1999-10-29 14:39:48 +00:00
|
|
|
nsIPresContext* aPresContext,
|
|
|
|
nsFrameConstructorState& aState,
|
|
|
|
nsIFrame* aParentFrame,
|
|
|
|
nsIFrame* aParentFrameList,
|
|
|
|
nsIFrame** aModifiedParent,
|
|
|
|
nsIFrame** aTextFrame,
|
|
|
|
nsIFrame** aPrevFrame,
|
|
|
|
nsFrameItems& aLetterFrames,
|
|
|
|
PRBool* aStopLooking)
|
|
|
|
{
|
|
|
|
nsresult rv = NS_OK;
|
|
|
|
|
|
|
|
nsIFrame* prevFrame = nsnull;
|
|
|
|
nsIFrame* frame = aParentFrameList;
|
|
|
|
|
|
|
|
while (frame) {
|
|
|
|
nsIFrame* nextFrame;
|
|
|
|
frame->GetNextSibling(&nextFrame);
|
|
|
|
|
|
|
|
nsCOMPtr<nsIAtom> frameType;
|
|
|
|
frame->GetFrameType(getter_AddRefs(frameType));
|
1999-10-29 15:20:20 +00:00
|
|
|
if (nsLayoutAtoms::textFrame == frameType.get()) {
|
1999-10-29 14:39:48 +00:00
|
|
|
// Wrap up first-letter content in a letter frame
|
|
|
|
nsCOMPtr<nsIContent> textContent;
|
|
|
|
frame->GetContent(getter_AddRefs(textContent));
|
|
|
|
if (IsFirstLetterContent(textContent)) {
|
|
|
|
// Create letter frame to wrap up the text
|
1999-12-04 23:49:50 +00:00
|
|
|
rv = CreateLetterFrame(aPresShell, aPresContext, aState, textContent,
|
1999-10-29 14:39:48 +00:00
|
|
|
aParentFrame, aLetterFrames);
|
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
return rv;
|
1999-04-27 22:14:54 +00:00
|
|
|
}
|
1999-10-29 14:39:48 +00:00
|
|
|
|
|
|
|
// Provide adjustment information for parent
|
|
|
|
*aModifiedParent = aParentFrame;
|
|
|
|
*aTextFrame = frame;
|
|
|
|
*aPrevFrame = prevFrame;
|
|
|
|
*aStopLooking = PR_TRUE;
|
|
|
|
return NS_OK;
|
1999-04-27 22:14:54 +00:00
|
|
|
}
|
1999-10-29 14:39:48 +00:00
|
|
|
}
|
1999-10-29 15:20:20 +00:00
|
|
|
else if ((nsLayoutAtoms::inlineFrame == frameType.get()) ||
|
|
|
|
(nsLayoutAtoms::lineFrame == frameType.get())) {
|
1999-10-29 14:39:48 +00:00
|
|
|
nsIFrame* kids;
|
2000-01-22 01:16:50 +00:00
|
|
|
frame->FirstChild(aPresContext, nsnull, &kids);
|
1999-12-04 23:49:50 +00:00
|
|
|
WrapFramesInFirstLetterFrame(aPresShell, aPresContext, aState, frame, kids,
|
1999-10-29 14:39:48 +00:00
|
|
|
aModifiedParent, aTextFrame,
|
|
|
|
aPrevFrame, aLetterFrames, aStopLooking);
|
|
|
|
if (*aStopLooking) {
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
// This will stop us looking to create more letter frames. For
|
|
|
|
// example, maybe the frame-type is "letterFrame" or
|
|
|
|
// "placeholderFrame". This keeps us from creating extra letter
|
|
|
|
// frames, and also prevents us from creating letter frames when
|
|
|
|
// the first real content child of a block is not text (e.g. an
|
|
|
|
// image, hr, etc.)
|
|
|
|
*aStopLooking = PR_TRUE;
|
|
|
|
break;
|
|
|
|
}
|
1999-08-27 21:46:10 +00:00
|
|
|
|
1999-10-29 14:39:48 +00:00
|
|
|
prevFrame = frame;
|
|
|
|
frame = nextFrame;
|
|
|
|
}
|
1999-08-27 21:46:10 +00:00
|
|
|
|
1999-10-29 14:39:48 +00:00
|
|
|
return rv;
|
|
|
|
}
|
1999-08-27 21:46:10 +00:00
|
|
|
|
1999-10-29 14:39:48 +00:00
|
|
|
nsresult
|
|
|
|
nsCSSFrameConstructor::RemoveFloatingFirstLetterFrames(
|
|
|
|
nsIPresContext* aPresContext,
|
|
|
|
nsIPresShell* aPresShell,
|
|
|
|
nsIFrameManager* aFrameManager,
|
|
|
|
nsIFrame* aBlockFrame,
|
|
|
|
PRBool* aStopLooking)
|
|
|
|
{
|
|
|
|
// First look for the floater frame that is a letter frame
|
|
|
|
nsIFrame* floater;
|
2000-01-22 01:16:50 +00:00
|
|
|
aBlockFrame->FirstChild(aPresContext, nsLayoutAtoms::floaterList, &floater);
|
1999-10-29 14:39:48 +00:00
|
|
|
while (floater) {
|
|
|
|
// See if we found a floating letter frame
|
|
|
|
nsCOMPtr<nsIAtom> frameType;
|
|
|
|
floater->GetFrameType(getter_AddRefs(frameType));
|
|
|
|
if (nsLayoutAtoms::letterFrame == frameType.get()) {
|
|
|
|
break;
|
1999-04-27 22:14:54 +00:00
|
|
|
}
|
1999-10-29 14:39:48 +00:00
|
|
|
floater->GetNextSibling(&floater);
|
|
|
|
}
|
|
|
|
if (!floater) {
|
|
|
|
// No such frame
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Take the text frame away from the letter frame (so it isn't
|
|
|
|
// destroyed when we destroy the letter frame).
|
|
|
|
nsIFrame* textFrame;
|
2000-01-22 01:16:50 +00:00
|
|
|
floater->FirstChild(aPresContext, nsnull, &textFrame);
|
1999-10-29 14:39:48 +00:00
|
|
|
if (!textFrame) {
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Discover the placeholder frame for the letter frame
|
|
|
|
nsIFrame* parentFrame;
|
|
|
|
nsIFrame* placeholderFrame;
|
|
|
|
aFrameManager->GetPlaceholderFrameFor(floater, &placeholderFrame);
|
|
|
|
if (!placeholderFrame) {
|
|
|
|
// Somethings really wrong
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
placeholderFrame->GetParent(&parentFrame);
|
|
|
|
if (!parentFrame) {
|
|
|
|
// Somethings really wrong
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Create a new text frame with the right style context that maps
|
|
|
|
// all of the content that was previously part of the letter frame
|
|
|
|
// (and probably continued elsewhere).
|
|
|
|
nsCOMPtr<nsIStyleContext> parentSC;
|
|
|
|
parentFrame->GetStyleContext(getter_AddRefs(parentSC));
|
|
|
|
if (!parentSC) {
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
nsCOMPtr<nsIContent> textContent;
|
|
|
|
textFrame->GetContent(getter_AddRefs(textContent));
|
|
|
|
if (!textContent) {
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
nsCOMPtr<nsIStyleContext> newSC;
|
|
|
|
aPresContext->ResolveStyleContextFor(textContent, parentSC,
|
|
|
|
PR_FALSE,
|
|
|
|
getter_AddRefs(newSC));
|
|
|
|
if (!newSC) {
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
nsIFrame* newTextFrame;
|
1999-12-04 23:49:50 +00:00
|
|
|
nsresult rv = NS_NewTextFrame(aPresShell, &newTextFrame);
|
1999-10-29 14:39:48 +00:00
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
return rv;
|
|
|
|
}
|
1999-11-24 06:03:41 +00:00
|
|
|
newTextFrame->Init(aPresContext, textContent, parentFrame, newSC, nsnull);
|
1999-10-29 14:39:48 +00:00
|
|
|
|
|
|
|
// Destroy the old text frame's continuations (the old text frame
|
|
|
|
// will be destroyed when its letter frame is destroyed).
|
|
|
|
nsIFrame* nextTextFrame;
|
|
|
|
textFrame->GetNextInFlow(&nextTextFrame);
|
|
|
|
if (nextTextFrame) {
|
|
|
|
nsIFrame* nextTextParent;
|
|
|
|
nextTextFrame->GetParent(&nextTextParent);
|
|
|
|
if (nextTextParent) {
|
|
|
|
nsSplittableFrame::BreakFromPrevFlow(nextTextFrame);
|
1999-11-24 06:03:41 +00:00
|
|
|
aFrameManager->RemoveFrame(aPresContext, *aPresShell, nextTextParent,
|
1999-10-29 14:39:48 +00:00
|
|
|
nsnull, nextTextFrame);
|
1999-04-28 00:55:11 +00:00
|
|
|
}
|
1999-04-27 22:14:54 +00:00
|
|
|
}
|
1999-10-29 14:39:48 +00:00
|
|
|
|
|
|
|
// First find out where (in the content) the placeholder frames
|
|
|
|
// text is and its previous sibling frame, if any.
|
|
|
|
nsIFrame* prevSibling = nsnull;
|
|
|
|
|
|
|
|
nsCOMPtr<nsIContent> container;
|
|
|
|
parentFrame->GetContent(getter_AddRefs(container));
|
|
|
|
if (container.get() && textContent.get()) {
|
|
|
|
PRInt32 ix = 0;
|
|
|
|
container->IndexOf(textContent, ix);
|
|
|
|
prevSibling = FindPreviousSibling(aPresShell, container, ix);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Now that everything is set...
|
|
|
|
#ifdef NOISY_FIRST_LETTER
|
|
|
|
printf("RemoveFloatingFirstLetterFrames: textContent=%p oldTextFrame=%p newTextFrame=%p\n",
|
|
|
|
textContent.get(), textFrame, newTextFrame);
|
|
|
|
#endif
|
|
|
|
aFrameManager->SetPlaceholderFrameFor(floater, nsnull);
|
|
|
|
aFrameManager->SetPrimaryFrameFor(textContent, nsnull);
|
|
|
|
|
|
|
|
// Remove the floater frame
|
1999-11-24 06:03:41 +00:00
|
|
|
aFrameManager->RemoveFrame(aPresContext, *aPresShell,
|
1999-10-29 14:39:48 +00:00
|
|
|
aBlockFrame, nsLayoutAtoms::floaterList,
|
|
|
|
floater);
|
|
|
|
|
|
|
|
// Remove placeholder frame
|
1999-11-24 06:03:41 +00:00
|
|
|
aFrameManager->RemoveFrame(aPresContext, *aPresShell,
|
1999-10-29 14:39:48 +00:00
|
|
|
parentFrame, nsnull, placeholderFrame);
|
|
|
|
|
|
|
|
// Insert text frame in its place
|
1999-11-24 06:03:41 +00:00
|
|
|
aFrameManager->InsertFrames(aPresContext, *aPresShell, parentFrame, nsnull,
|
1999-10-29 14:39:48 +00:00
|
|
|
prevSibling, newTextFrame);
|
|
|
|
|
1999-04-27 22:14:54 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
1999-04-28 19:08:14 +00:00
|
|
|
|
1999-10-29 14:39:48 +00:00
|
|
|
nsresult
|
|
|
|
nsCSSFrameConstructor::RemoveFirstLetterFrames(nsIPresContext* aPresContext,
|
|
|
|
nsIPresShell* aPresShell,
|
|
|
|
nsIFrameManager* aFrameManager,
|
|
|
|
nsIFrame* aFrame,
|
|
|
|
PRBool* aStopLooking)
|
|
|
|
{
|
|
|
|
nsIFrame* kid;
|
|
|
|
nsIFrame* prevSibling = nsnull;
|
2000-01-22 01:16:50 +00:00
|
|
|
aFrame->FirstChild(aPresContext, nsnull, &kid);
|
1999-10-29 14:39:48 +00:00
|
|
|
|
|
|
|
while (kid) {
|
|
|
|
nsCOMPtr<nsIAtom> frameType;
|
|
|
|
kid->GetFrameType(getter_AddRefs(frameType));
|
1999-10-29 15:20:20 +00:00
|
|
|
if (nsLayoutAtoms::letterFrame == frameType.get()) {
|
1999-10-29 14:39:48 +00:00
|
|
|
// Bingo. Found it. First steal away the text frame.
|
|
|
|
nsIFrame* textFrame;
|
2000-01-22 01:16:50 +00:00
|
|
|
kid->FirstChild(aPresContext, nsnull, &textFrame);
|
1999-10-29 14:39:48 +00:00
|
|
|
if (!textFrame) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Create a new textframe
|
|
|
|
nsCOMPtr<nsIStyleContext> parentSC;
|
|
|
|
aFrame->GetStyleContext(getter_AddRefs(parentSC));
|
|
|
|
if (!parentSC) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
nsCOMPtr<nsIContent> textContent;
|
|
|
|
textFrame->GetContent(getter_AddRefs(textContent));
|
|
|
|
if (!textContent) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
nsCOMPtr<nsIStyleContext> newSC;
|
|
|
|
aPresContext->ResolveStyleContextFor(textContent, parentSC,
|
|
|
|
PR_FALSE,
|
|
|
|
getter_AddRefs(newSC));
|
|
|
|
if (!newSC) {
|
|
|
|
break;
|
|
|
|
}
|
1999-12-04 23:49:50 +00:00
|
|
|
NS_NewTextFrame(aPresShell, &textFrame);
|
1999-11-24 06:03:41 +00:00
|
|
|
textFrame->Init(aPresContext, textContent, aFrame, newSC, nsnull);
|
1999-10-29 14:39:48 +00:00
|
|
|
|
|
|
|
// Next rip out the kid and replace it with the text frame
|
|
|
|
nsIFrameManager* frameManager = aFrameManager;
|
|
|
|
frameManager->SetPrimaryFrameFor(textContent, nsnull);
|
1999-11-24 06:03:41 +00:00
|
|
|
frameManager->RemoveFrame(aPresContext, *aPresShell,
|
1999-10-29 14:39:48 +00:00
|
|
|
aFrame, nsnull, kid);
|
|
|
|
|
|
|
|
// Insert text frame in its place
|
1999-11-24 06:03:41 +00:00
|
|
|
frameManager->InsertFrames(aPresContext, *aPresShell, aFrame, nsnull,
|
1999-10-29 14:39:48 +00:00
|
|
|
prevSibling, textFrame);
|
|
|
|
|
|
|
|
*aStopLooking = PR_TRUE;
|
|
|
|
break;
|
|
|
|
}
|
1999-10-29 15:20:20 +00:00
|
|
|
else if ((nsLayoutAtoms::inlineFrame == frameType.get()) ||
|
|
|
|
(nsLayoutAtoms::lineFrame == frameType.get())) {
|
1999-10-29 14:39:48 +00:00
|
|
|
// Look inside child inline frame for the letter frame
|
|
|
|
RemoveFirstLetterFrames(aPresContext, aPresShell, aFrameManager, kid,
|
|
|
|
aStopLooking);
|
|
|
|
if (*aStopLooking) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
prevSibling = kid;
|
|
|
|
kid->GetNextSibling(&kid);
|
|
|
|
}
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
nsCSSFrameConstructor::RemoveLetterFrames(nsIPresContext* aPresContext,
|
|
|
|
nsIPresShell* aPresShell,
|
|
|
|
nsIFrameManager* aFrameManager,
|
|
|
|
nsIFrame* aBlockFrame)
|
|
|
|
{
|
|
|
|
PRBool stopLooking = PR_FALSE;
|
|
|
|
nsresult rv = RemoveFloatingFirstLetterFrames(aPresContext, aPresShell,
|
|
|
|
aFrameManager,
|
|
|
|
aBlockFrame, &stopLooking);
|
|
|
|
if (NS_SUCCEEDED(rv) && !stopLooking) {
|
|
|
|
rv = RemoveFirstLetterFrames(aPresContext, aPresShell, aFrameManager,
|
|
|
|
aBlockFrame, &stopLooking);
|
|
|
|
}
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Fixup the letter frame situation for the given block
|
|
|
|
nsresult
|
1999-12-04 23:49:50 +00:00
|
|
|
nsCSSFrameConstructor::RecoverLetterFrames(nsIPresShell* aPresShell, nsIPresContext* aPresContext,
|
1999-10-29 14:39:48 +00:00
|
|
|
nsFrameConstructorState& aState,
|
|
|
|
nsIFrame* aBlockFrame)
|
|
|
|
{
|
|
|
|
nsresult rv = NS_OK;
|
|
|
|
|
|
|
|
nsIFrame* blockKids;
|
2000-01-22 01:16:50 +00:00
|
|
|
aBlockFrame->FirstChild(aPresContext, nsnull, &blockKids);
|
1999-10-29 14:39:48 +00:00
|
|
|
nsIFrame* parentFrame = nsnull;
|
|
|
|
nsIFrame* textFrame = nsnull;
|
|
|
|
nsIFrame* prevFrame = nsnull;
|
|
|
|
nsFrameItems letterFrames;
|
|
|
|
PRBool stopLooking = PR_FALSE;
|
1999-12-04 23:49:50 +00:00
|
|
|
rv = WrapFramesInFirstLetterFrame(aPresShell, aPresContext, aState,
|
1999-10-29 14:39:48 +00:00
|
|
|
aBlockFrame, blockKids,
|
|
|
|
&parentFrame, &textFrame, &prevFrame,
|
|
|
|
letterFrames, &stopLooking);
|
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
if (parentFrame) {
|
|
|
|
// Take the old textFrame out of the parents child list
|
1999-11-24 06:03:41 +00:00
|
|
|
parentFrame->RemoveFrame(aPresContext, *aState.mPresShell.get(),
|
1999-10-29 14:39:48 +00:00
|
|
|
nsnull, textFrame);
|
|
|
|
|
|
|
|
// Insert in the letter frame(s)
|
1999-11-24 06:03:41 +00:00
|
|
|
parentFrame->InsertFrames(aPresContext, *aState.mPresShell.get(),
|
1999-10-29 14:39:48 +00:00
|
|
|
nsnull, prevFrame, letterFrames.childList);
|
|
|
|
|
|
|
|
// Insert in floaters too if needed
|
|
|
|
if (aState.mFloatedItems.childList) {
|
1999-11-24 06:03:41 +00:00
|
|
|
aBlockFrame->AppendFrames(aPresContext, *aState.mPresShell.get(),
|
1999-10-29 14:39:48 +00:00
|
|
|
nsLayoutAtoms::floaterList,
|
|
|
|
aState.mFloatedItems.childList);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
|
1999-06-23 03:02:21 +00:00
|
|
|
// Tree Widget Routines
|
1999-10-29 14:39:48 +00:00
|
|
|
|
1999-06-23 03:02:21 +00:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsCSSFrameConstructor::CreateTreeWidgetContent(nsIPresContext* aPresContext,
|
|
|
|
nsIFrame* aParentFrame,
|
1999-06-28 08:35:10 +00:00
|
|
|
nsIFrame* aPrevFrame,
|
1999-06-23 03:02:21 +00:00
|
|
|
nsIContent* aChild,
|
1999-06-28 08:35:10 +00:00
|
|
|
nsIFrame** aNewFrame,
|
1999-06-29 20:20:40 +00:00
|
|
|
PRBool aIsAppend,
|
1999-12-06 07:44:18 +00:00
|
|
|
PRBool aIsScrollbar,
|
|
|
|
nsILayoutHistoryState* aFrameState)
|
1999-06-23 03:02:21 +00:00
|
|
|
{
|
|
|
|
nsCOMPtr<nsIPresShell> shell;
|
|
|
|
aPresContext->GetShell(getter_AddRefs(shell));
|
|
|
|
nsresult rv = NS_OK;
|
|
|
|
|
|
|
|
// Construct a new frame
|
|
|
|
if (nsnull != aParentFrame) {
|
|
|
|
nsFrameItems frameItems;
|
1999-08-05 03:09:22 +00:00
|
|
|
nsFrameConstructorState state(aPresContext, mFixedContainingBlock,
|
1999-06-23 03:02:21 +00:00
|
|
|
GetAbsoluteContainingBlock(aPresContext, aParentFrame),
|
1999-12-06 07:44:18 +00:00
|
|
|
GetFloaterContainingBlock(aPresContext, aParentFrame),
|
2000-01-14 09:28:54 +00:00
|
|
|
mTempFrameTreeState);
|
1999-12-01 11:13:06 +00:00
|
|
|
|
|
|
|
// Get the element's tag
|
|
|
|
nsCOMPtr<nsIAtom> tag;
|
|
|
|
aChild->GetTag(*getter_AddRefs(tag));
|
|
|
|
|
2000-07-27 09:10:52 +00:00
|
|
|
PRInt32 namespaceID;
|
|
|
|
aChild->GetNameSpaceID(namespaceID);
|
|
|
|
|
1999-12-01 11:13:06 +00:00
|
|
|
nsCOMPtr<nsIStyleContext> styleContext;
|
|
|
|
rv = ResolveStyleContext(aPresContext, aParentFrame, aChild, tag, getter_AddRefs(styleContext));
|
|
|
|
|
|
|
|
if (NS_SUCCEEDED(rv)) {
|
|
|
|
// Pre-check for display "none" - only if we find that, do we create
|
|
|
|
// any frame at all
|
|
|
|
const nsStyleDisplay* display = (const nsStyleDisplay*)
|
|
|
|
styleContext->GetStyleData(eStyleStruct_Display);
|
|
|
|
|
|
|
|
if (NS_STYLE_DISPLAY_NONE == display->mDisplay) {
|
|
|
|
*aNewFrame = nsnull;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2000-07-27 09:10:52 +00:00
|
|
|
rv = ConstructFrameInternal(shell, aPresContext, state, aChild, aParentFrame, tag, namespaceID,
|
|
|
|
styleContext, frameItems, PR_FALSE);
|
1999-06-23 03:02:21 +00:00
|
|
|
|
|
|
|
nsIFrame* newFrame = frameItems.childList;
|
|
|
|
*aNewFrame = newFrame;
|
|
|
|
|
|
|
|
if (NS_SUCCEEDED(rv) && (nsnull != newFrame)) {
|
2000-07-28 00:35:30 +00:00
|
|
|
nsCOMPtr<nsIBindingManager> bm;
|
|
|
|
mDocument->GetBindingManager(getter_AddRefs(bm));
|
|
|
|
bm->ProcessAttachedQueue();
|
|
|
|
|
1999-06-23 03:02:21 +00:00
|
|
|
// Notify the parent frame
|
2000-06-06 23:13:49 +00:00
|
|
|
if (aIsAppend)
|
|
|
|
rv = ((nsXULTreeGroupFrame*)aParentFrame)->TreeAppendFrames(newFrame);
|
|
|
|
else
|
|
|
|
rv = ((nsXULTreeGroupFrame*)aParentFrame)->TreeInsertFrames(aPrevFrame, newFrame);
|
1999-06-23 03:02:21 +00:00
|
|
|
// If there are new absolutely positioned child frames, then notify
|
|
|
|
// the parent
|
|
|
|
// XXX We can't just assume these frames are being appended, we need to
|
|
|
|
// determine where in the list they should be inserted...
|
|
|
|
if (state.mAbsoluteItems.childList) {
|
1999-11-24 06:03:41 +00:00
|
|
|
rv = state.mAbsoluteItems.containingBlock->AppendFrames(aPresContext, *shell,
|
1999-06-23 03:02:21 +00:00
|
|
|
nsLayoutAtoms::absoluteList,
|
|
|
|
state.mAbsoluteItems.childList);
|
|
|
|
}
|
|
|
|
|
|
|
|
// If there are new fixed positioned child frames, then notify
|
|
|
|
// the parent
|
|
|
|
// XXX We can't just assume these frames are being appended, we need to
|
|
|
|
// determine where in the list they should be inserted...
|
|
|
|
if (state.mFixedItems.childList) {
|
1999-11-24 06:03:41 +00:00
|
|
|
rv = state.mFixedItems.containingBlock->AppendFrames(aPresContext, *shell,
|
1999-06-23 03:02:21 +00:00
|
|
|
nsLayoutAtoms::fixedList,
|
|
|
|
state.mFixedItems.childList);
|
|
|
|
}
|
|
|
|
|
|
|
|
// If there are new floating child frames, then notify
|
|
|
|
// the parent
|
|
|
|
// XXX We can't just assume these frames are being appended, we need to
|
|
|
|
// determine where in the list they should be inserted...
|
|
|
|
if (state.mFloatedItems.childList) {
|
1999-11-24 06:03:41 +00:00
|
|
|
rv = state.mFloatedItems.containingBlock->AppendFrames(aPresContext, *shell,
|
1999-06-23 03:02:21 +00:00
|
|
|
nsLayoutAtoms::floaterList,
|
|
|
|
state.mFloatedItems.childList);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
1999-11-01 15:24:57 +00:00
|
|
|
//----------------------------------------
|
|
|
|
|
|
|
|
nsresult
|
1999-12-04 23:49:50 +00:00
|
|
|
nsCSSFrameConstructor::ConstructBlock(nsIPresShell* aPresShell,
|
|
|
|
nsIPresContext* aPresContext,
|
1999-11-01 15:24:57 +00:00
|
|
|
nsFrameConstructorState& aState,
|
|
|
|
const nsStyleDisplay* aDisplay,
|
|
|
|
nsIContent* aContent,
|
|
|
|
nsIFrame* aParentFrame,
|
|
|
|
nsIStyleContext* aStyleContext,
|
|
|
|
nsIFrame* aNewFrame)
|
|
|
|
{
|
1999-12-06 07:44:18 +00:00
|
|
|
InitAndRestoreFrame(aPresContext, aState, aContent,
|
|
|
|
aParentFrame, aStyleContext, nsnull, aNewFrame);
|
1999-11-01 15:24:57 +00:00
|
|
|
|
|
|
|
// See if we need to create a view, e.g. the frame is absolutely positioned
|
1999-11-24 06:03:41 +00:00
|
|
|
nsHTMLContainerFrame::CreateViewForFrame(aPresContext, aNewFrame,
|
1999-11-01 15:24:57 +00:00
|
|
|
aStyleContext, PR_FALSE);
|
|
|
|
|
|
|
|
// See if the block has first-letter style applied to it...
|
|
|
|
PRBool haveFirstLetterStyle, haveFirstLineStyle;
|
|
|
|
HaveSpecialBlockStyle(aPresContext, aContent, aStyleContext,
|
|
|
|
&haveFirstLetterStyle, &haveFirstLineStyle);
|
|
|
|
|
|
|
|
// Process the child content
|
|
|
|
nsFrameItems childItems;
|
|
|
|
nsFrameConstructorSaveState floaterSaveState;
|
|
|
|
aState.PushFloaterContainingBlock(aNewFrame, floaterSaveState,
|
|
|
|
haveFirstLetterStyle,
|
|
|
|
haveFirstLineStyle);
|
1999-12-04 23:49:50 +00:00
|
|
|
nsresult rv = ProcessBlockChildren(aPresShell, aPresContext, aState, aContent, aNewFrame,
|
1999-11-01 15:24:57 +00:00
|
|
|
PR_TRUE, childItems, PR_TRUE);
|
|
|
|
|
2000-05-09 21:42:40 +00:00
|
|
|
nsCOMPtr<nsIAtom> tag;
|
|
|
|
aContent->GetTag(*getter_AddRefs(tag));
|
|
|
|
CreateAnonymousFrames(aPresShell, aPresContext, tag, aState, aContent, aNewFrame,
|
|
|
|
childItems);
|
|
|
|
|
1999-11-01 15:24:57 +00:00
|
|
|
// Set the frame's initial child list
|
1999-11-24 06:03:41 +00:00
|
|
|
aNewFrame->SetInitialChildList(aPresContext, nsnull, childItems.childList);
|
1999-11-01 15:24:57 +00:00
|
|
|
|
|
|
|
// Set the frame's floater list if there were any floated children
|
|
|
|
if (aState.mFloatedItems.childList) {
|
1999-11-24 06:03:41 +00:00
|
|
|
aNewFrame->SetInitialChildList(aPresContext,
|
1999-11-01 15:24:57 +00:00
|
|
|
nsLayoutAtoms::floaterList,
|
|
|
|
aState.mFloatedItems.childList);
|
|
|
|
}
|
|
|
|
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
1999-12-04 23:49:50 +00:00
|
|
|
nsCSSFrameConstructor::ProcessBlockChildren(nsIPresShell* aPresShell,
|
|
|
|
nsIPresContext* aPresContext,
|
1999-11-01 15:24:57 +00:00
|
|
|
nsFrameConstructorState& aState,
|
|
|
|
nsIContent* aContent,
|
|
|
|
nsIFrame* aFrame,
|
|
|
|
PRBool aCanHaveGeneratedContent,
|
|
|
|
nsFrameItems& aFrameItems,
|
|
|
|
PRBool aParentIsBlock)
|
|
|
|
{
|
|
|
|
nsresult rv = NS_OK;
|
|
|
|
nsCOMPtr<nsIStyleContext> styleContext;
|
|
|
|
|
|
|
|
if (aCanHaveGeneratedContent) {
|
|
|
|
// Probe for generated content before
|
|
|
|
nsIFrame* generatedFrame;
|
|
|
|
aFrame->GetStyleContext(getter_AddRefs(styleContext));
|
1999-12-04 23:49:50 +00:00
|
|
|
if (CreateGeneratedContentFrame(aPresShell, aPresContext, aState, aFrame, aContent,
|
1999-11-01 15:24:57 +00:00
|
|
|
styleContext, nsCSSAtoms::beforePseudo,
|
|
|
|
aParentIsBlock, &generatedFrame)) {
|
|
|
|
// Add the generated frame to the child list
|
|
|
|
aFrameItems.AddChild(generatedFrame);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Iterate the child content objects and construct frames
|
|
|
|
PRInt32 count;
|
|
|
|
aContent->ChildCount(count);
|
|
|
|
for (PRInt32 i = 0; i < count; i++) {
|
|
|
|
nsCOMPtr<nsIContent> childContent;
|
|
|
|
if (NS_SUCCEEDED(aContent->ChildAt(i, *getter_AddRefs(childContent)))) {
|
|
|
|
// Construct a child frame
|
1999-12-04 23:49:50 +00:00
|
|
|
rv = ConstructFrame(aPresShell, aPresContext, aState, childContent, aFrame, aFrameItems);
|
1999-11-01 15:24:57 +00:00
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2000-04-04 01:28:15 +00:00
|
|
|
// process pseudo frames if necessary
|
|
|
|
if (!aState.mPseudoFrames.IsEmpty()) {
|
|
|
|
ProcessPseudoFrames(aPresContext, aState.mPseudoFrames, aFrameItems);
|
|
|
|
}
|
|
|
|
|
1999-11-01 15:24:57 +00:00
|
|
|
if (aCanHaveGeneratedContent) {
|
|
|
|
// Probe for generated content after
|
|
|
|
nsIFrame* generatedFrame;
|
1999-12-04 23:49:50 +00:00
|
|
|
if (CreateGeneratedContentFrame(aPresShell, aPresContext, aState, aFrame, aContent,
|
1999-11-01 15:24:57 +00:00
|
|
|
styleContext, nsCSSAtoms::afterPseudo,
|
|
|
|
aParentIsBlock, &generatedFrame)) {
|
|
|
|
// Add the generated frame to the child list
|
|
|
|
aFrameItems.AddChild(generatedFrame);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (aParentIsBlock) {
|
|
|
|
if (aState.mFirstLetterStyle) {
|
1999-12-04 23:49:50 +00:00
|
|
|
rv = WrapFramesInFirstLetterFrame(aPresShell, aPresContext, aState, aContent, aFrame, aFrameItems);
|
1999-11-01 15:24:57 +00:00
|
|
|
}
|
|
|
|
if (aState.mFirstLineStyle) {
|
1999-12-04 23:49:50 +00:00
|
|
|
rv = WrapFramesInFirstLineFrame(aPresShell, aPresContext, aState, aContent, aFrame, aFrameItems);
|
1999-11-01 15:24:57 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
PRBool
|
|
|
|
nsCSSFrameConstructor::AreAllKidsInline(nsIFrame* aFrameList)
|
|
|
|
{
|
|
|
|
nsIFrame* kid = aFrameList;
|
|
|
|
while (kid) {
|
|
|
|
if (!IsInlineFrame(kid)) {
|
|
|
|
return PR_FALSE;
|
|
|
|
}
|
|
|
|
kid->GetNextSibling(&kid);
|
|
|
|
}
|
|
|
|
return PR_TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
1999-12-04 23:49:50 +00:00
|
|
|
nsCSSFrameConstructor::ConstructInline(nsIPresShell* aPresShell,
|
|
|
|
nsIPresContext* aPresContext,
|
1999-11-01 15:24:57 +00:00
|
|
|
nsFrameConstructorState& aState,
|
|
|
|
const nsStyleDisplay* aDisplay,
|
|
|
|
nsIContent* aContent,
|
|
|
|
nsIFrame* aParentFrame,
|
|
|
|
nsIStyleContext* aStyleContext,
|
2000-06-07 06:58:45 +00:00
|
|
|
PRBool aIsPositioned,
|
1999-11-01 15:24:57 +00:00
|
|
|
nsIFrame* aNewFrame,
|
|
|
|
nsIFrame** aNewBlockFrame,
|
|
|
|
nsIFrame** aNextInlineFrame)
|
|
|
|
{
|
|
|
|
// Initialize the frame
|
1999-12-06 07:44:18 +00:00
|
|
|
InitAndRestoreFrame(aPresContext, aState, aContent,
|
|
|
|
aParentFrame, aStyleContext, nsnull, aNewFrame);
|
1999-11-01 15:24:57 +00:00
|
|
|
|
2000-06-07 06:58:45 +00:00
|
|
|
if (aIsPositioned) {
|
|
|
|
// Relatively positioned frames need a view
|
|
|
|
nsHTMLContainerFrame::CreateViewForFrame(aPresContext, aNewFrame,
|
|
|
|
aStyleContext, PR_FALSE);
|
|
|
|
|
|
|
|
// Relatively positioned frames becomes a container for child
|
|
|
|
// frames that are positioned
|
|
|
|
nsFrameConstructorSaveState absoluteSaveState;
|
|
|
|
aState.PushAbsoluteContainingBlock(aNewFrame, absoluteSaveState);
|
|
|
|
}
|
|
|
|
|
1999-11-01 15:24:57 +00:00
|
|
|
// Process the child content
|
|
|
|
nsFrameItems childItems;
|
|
|
|
PRBool kidsAllInline;
|
1999-12-04 23:49:50 +00:00
|
|
|
nsresult rv = ProcessInlineChildren(aPresShell, aPresContext, aState, aContent,
|
1999-11-01 15:24:57 +00:00
|
|
|
aNewFrame, PR_TRUE, childItems, &kidsAllInline);
|
|
|
|
if (kidsAllInline) {
|
|
|
|
// Set the inline frame's initial child list
|
2000-05-09 21:42:40 +00:00
|
|
|
nsCOMPtr<nsIAtom> tag;
|
|
|
|
aContent->GetTag(*getter_AddRefs(tag));
|
|
|
|
CreateAnonymousFrames(aPresShell, aPresContext, tag, aState, aContent, aNewFrame,
|
|
|
|
childItems);
|
|
|
|
|
1999-11-24 06:03:41 +00:00
|
|
|
aNewFrame->SetInitialChildList(aPresContext, nsnull, childItems.childList);
|
2000-06-07 06:58:45 +00:00
|
|
|
|
|
|
|
if (aIsPositioned) {
|
|
|
|
if (aState.mAbsoluteItems.childList) {
|
|
|
|
aNewFrame->SetInitialChildList(aPresContext, nsLayoutAtoms::absoluteList,
|
|
|
|
aState.mAbsoluteItems.childList);
|
|
|
|
}
|
|
|
|
if (aState.mFloatedItems.childList) {
|
|
|
|
aNewFrame->SetInitialChildList(aPresContext,
|
|
|
|
nsLayoutAtoms::floaterList,
|
|
|
|
aState.mFloatedItems.childList);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1999-11-01 15:24:57 +00:00
|
|
|
*aNewBlockFrame = nsnull;
|
|
|
|
*aNextInlineFrame = nsnull;
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
// This inline frame contains several types of children. Therefore
|
|
|
|
// this frame has to be chopped into several pieces. We will produce
|
|
|
|
// as a result of this 3 lists of children. The first list contains
|
|
|
|
// all of the inline children that preceed the first block child
|
|
|
|
// (and may be empty). The second list contains all of the block
|
|
|
|
// children and any inlines that are between them (and must not be
|
|
|
|
// empty, otherwise - why are we here?). The final list contains all
|
|
|
|
// of the inline children that follow the final block child.
|
|
|
|
|
|
|
|
// Find the first block child which defines list1 and list2
|
|
|
|
nsIFrame* list1 = childItems.childList;
|
|
|
|
nsIFrame* prevToFirstBlock;
|
|
|
|
nsIFrame* list2 = FindFirstBlock(aPresContext, list1, &prevToFirstBlock);
|
|
|
|
if (prevToFirstBlock) {
|
|
|
|
prevToFirstBlock->SetNextSibling(nsnull);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
list1 = nsnull;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Find the last block child which defines the end of list2 and the
|
|
|
|
// start of list3
|
|
|
|
nsIFrame* afterFirstBlock;
|
|
|
|
list2->GetNextSibling(&afterFirstBlock);
|
|
|
|
nsIFrame* list3 = nsnull;
|
|
|
|
nsIFrame* lastBlock = FindLastBlock(aPresContext, afterFirstBlock);
|
|
|
|
if (!lastBlock) {
|
|
|
|
lastBlock = list2;
|
|
|
|
}
|
|
|
|
lastBlock->GetNextSibling(&list3);
|
|
|
|
lastBlock->SetNextSibling(nsnull);
|
|
|
|
|
|
|
|
// list1's frames belong to this inline frame so go ahead and take them
|
1999-11-24 06:03:41 +00:00
|
|
|
aNewFrame->SetInitialChildList(aPresContext, nsnull, list1);
|
1999-11-01 15:24:57 +00:00
|
|
|
|
2000-06-07 06:58:45 +00:00
|
|
|
if (aIsPositioned) {
|
|
|
|
// XXXwaterson just for shits n' giggles, we'll give you the
|
|
|
|
// absolute and floated items, too.
|
|
|
|
if (aState.mAbsoluteItems.childList) {
|
|
|
|
aNewFrame->SetInitialChildList(aPresContext, nsLayoutAtoms::absoluteList,
|
|
|
|
aState.mAbsoluteItems.childList);
|
|
|
|
}
|
|
|
|
if (aState.mFloatedItems.childList) {
|
|
|
|
aNewFrame->SetInitialChildList(aPresContext,
|
|
|
|
nsLayoutAtoms::floaterList,
|
|
|
|
aState.mFloatedItems.childList);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1999-11-01 15:24:57 +00:00
|
|
|
// list2's frames belong to an anonymous block that we create right
|
|
|
|
// now. The anonymous block will be the parent of the block children
|
|
|
|
// of the inline.
|
|
|
|
nsIFrame* blockFrame;
|
2000-06-07 06:58:45 +00:00
|
|
|
nsIAtom* blockStyle;
|
|
|
|
if (aIsPositioned) {
|
|
|
|
NS_NewRelativeItemWrapperFrame(aPresShell, &blockFrame);
|
|
|
|
blockStyle = nsHTMLAtoms::mozAnonymousPositionedBlock;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
NS_NewBlockFrame(aPresShell, &blockFrame);
|
|
|
|
blockStyle = nsHTMLAtoms::mozAnonymousBlock;
|
|
|
|
}
|
|
|
|
|
1999-11-01 15:24:57 +00:00
|
|
|
nsCOMPtr<nsIStyleContext> blockSC;
|
2000-06-07 06:58:45 +00:00
|
|
|
aPresContext->ResolvePseudoStyleContextFor(aContent, blockStyle,
|
1999-11-01 15:24:57 +00:00
|
|
|
aStyleContext, PR_FALSE,
|
|
|
|
getter_AddRefs(blockSC));
|
1999-12-06 07:44:18 +00:00
|
|
|
|
|
|
|
InitAndRestoreFrame(aPresContext, aState, aContent,
|
|
|
|
aParentFrame, blockSC, nsnull, blockFrame);
|
|
|
|
|
2000-06-07 06:58:45 +00:00
|
|
|
if (aIsPositioned) {
|
|
|
|
// Relatively positioned frames need a view
|
|
|
|
nsHTMLContainerFrame::CreateViewForFrame(aPresContext, blockFrame,
|
|
|
|
aStyleContext, PR_FALSE);
|
|
|
|
}
|
|
|
|
|
1999-11-01 15:24:57 +00:00
|
|
|
MoveChildrenTo(aPresContext, blockSC, blockFrame, list2);
|
1999-11-24 06:03:41 +00:00
|
|
|
blockFrame->SetInitialChildList(aPresContext, nsnull, list2);
|
1999-11-01 15:24:57 +00:00
|
|
|
|
|
|
|
// list3's frames belong to another inline frame
|
|
|
|
nsIFrame* inlineFrame = nsnull;
|
2000-06-07 06:58:45 +00:00
|
|
|
|
|
|
|
if (aIsPositioned) {
|
|
|
|
NS_NewPositionedInlineFrame(aPresShell, &inlineFrame);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
NS_NewInlineFrame(aPresShell, &inlineFrame);
|
|
|
|
}
|
|
|
|
|
1999-12-06 07:44:18 +00:00
|
|
|
InitAndRestoreFrame(aPresContext, aState, aContent,
|
2000-06-07 06:58:45 +00:00
|
|
|
aParentFrame, aStyleContext, nsnull, inlineFrame);
|
|
|
|
|
|
|
|
if (aIsPositioned) {
|
|
|
|
// Relatively positioned frames need a view
|
|
|
|
nsHTMLContainerFrame::CreateViewForFrame(aPresContext, inlineFrame,
|
|
|
|
aStyleContext, PR_FALSE);
|
|
|
|
}
|
|
|
|
|
1999-11-01 15:24:57 +00:00
|
|
|
if (list3) {
|
|
|
|
// Reparent (cheaply) the frames in list3 - we don't have to futz
|
|
|
|
// with their style context because they already have the right one.
|
|
|
|
nsFrameList list;
|
|
|
|
list.AppendFrames(inlineFrame, list3);
|
|
|
|
}
|
1999-11-24 06:03:41 +00:00
|
|
|
inlineFrame->SetInitialChildList(aPresContext, nsnull, list3);
|
1999-11-01 15:24:57 +00:00
|
|
|
|
|
|
|
// Mark the 3 frames as special. That way if any of the
|
|
|
|
// append/insert/remove methods try to fiddle with the children, the
|
|
|
|
// containing block will be reframed instead.
|
2000-05-25 19:58:51 +00:00
|
|
|
SetFrameIsSpecial(aState.mFrameManager, aNewFrame, blockFrame);
|
|
|
|
SetFrameIsSpecial(aState.mFrameManager, blockFrame, inlineFrame);
|
|
|
|
SetFrameIsSpecial(aState.mFrameManager, inlineFrame, nsnull);
|
1999-11-01 15:24:57 +00:00
|
|
|
|
|
|
|
#ifdef DEBUG
|
|
|
|
if (gNoisyInlineConstruction) {
|
1999-11-02 06:06:46 +00:00
|
|
|
nsIFrameDebug* frameDebug;
|
|
|
|
|
1999-11-01 15:24:57 +00:00
|
|
|
printf("nsCSSFrameConstructor::ConstructInline:\n");
|
2000-02-02 22:24:56 +00:00
|
|
|
if (NS_SUCCEEDED(aNewFrame->QueryInterface(NS_GET_IID(nsIFrameDebug), (void**)&frameDebug))) {
|
1999-11-02 06:06:46 +00:00
|
|
|
printf(" ==> leading inline frame:\n");
|
|
|
|
frameDebug->List(aPresContext, stdout, 2);
|
|
|
|
}
|
2000-02-02 22:24:56 +00:00
|
|
|
if (NS_SUCCEEDED(blockFrame->QueryInterface(NS_GET_IID(nsIFrameDebug), (void**)&frameDebug))) {
|
1999-11-02 06:06:46 +00:00
|
|
|
printf(" ==> block frame:\n");
|
|
|
|
frameDebug->List(aPresContext, stdout, 2);
|
|
|
|
}
|
2000-02-02 22:24:56 +00:00
|
|
|
if (NS_SUCCEEDED(inlineFrame->QueryInterface(NS_GET_IID(nsIFrameDebug), (void**)&frameDebug))) {
|
1999-11-02 06:06:46 +00:00
|
|
|
printf(" ==> trailing inline frame:\n");
|
|
|
|
frameDebug->List(aPresContext, stdout, 2);
|
|
|
|
}
|
1999-11-01 15:24:57 +00:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
*aNewBlockFrame = blockFrame;
|
|
|
|
*aNextInlineFrame = inlineFrame;
|
|
|
|
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
1999-12-04 23:49:50 +00:00
|
|
|
nsCSSFrameConstructor::ProcessInlineChildren(nsIPresShell* aPresShell,
|
|
|
|
nsIPresContext* aPresContext,
|
1999-11-01 15:24:57 +00:00
|
|
|
nsFrameConstructorState& aState,
|
|
|
|
nsIContent* aContent,
|
|
|
|
nsIFrame* aFrame,
|
|
|
|
PRBool aCanHaveGeneratedContent,
|
|
|
|
nsFrameItems& aFrameItems,
|
|
|
|
PRBool* aKidsAllInline)
|
|
|
|
{
|
|
|
|
nsresult rv = NS_OK;
|
|
|
|
nsCOMPtr<nsIStyleContext> styleContext;
|
|
|
|
|
|
|
|
if (aCanHaveGeneratedContent) {
|
|
|
|
// Probe for generated content before
|
|
|
|
nsIFrame* generatedFrame;
|
|
|
|
aFrame->GetStyleContext(getter_AddRefs(styleContext));
|
1999-12-04 23:49:50 +00:00
|
|
|
if (CreateGeneratedContentFrame(aPresShell, aPresContext, aState, aFrame, aContent,
|
1999-11-01 15:24:57 +00:00
|
|
|
styleContext, nsCSSAtoms::beforePseudo,
|
|
|
|
PR_FALSE, &generatedFrame)) {
|
|
|
|
// Add the generated frame to the child list
|
|
|
|
aFrameItems.AddChild(generatedFrame);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Iterate the child content objects and construct frames
|
|
|
|
PRBool allKidsInline = PR_TRUE;
|
|
|
|
PRInt32 count;
|
|
|
|
aContent->ChildCount(count);
|
|
|
|
for (PRInt32 i = 0; i < count; i++) {
|
|
|
|
nsCOMPtr<nsIContent> childContent;
|
|
|
|
if (NS_SUCCEEDED(aContent->ChildAt(i, *getter_AddRefs(childContent)))) {
|
|
|
|
// Construct a child frame
|
|
|
|
nsIFrame* oldLastChild = aFrameItems.lastChild;
|
1999-12-04 23:49:50 +00:00
|
|
|
rv = ConstructFrame(aPresShell, aPresContext, aState, childContent, aFrame, aFrameItems);
|
1999-11-01 15:24:57 +00:00
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Examine newly added children (we may have added more than one
|
|
|
|
// child if the child was another inline frame that ends up
|
|
|
|
// being carved in 3 pieces) to maintain the allKidsInline flag.
|
|
|
|
if (allKidsInline) {
|
|
|
|
nsIFrame* kid;
|
|
|
|
if (oldLastChild) {
|
|
|
|
oldLastChild->GetNextSibling(&kid);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
kid = aFrameItems.childList;
|
|
|
|
}
|
|
|
|
while (kid) {
|
|
|
|
if (!IsInlineFrame(kid)) {
|
|
|
|
allKidsInline = PR_FALSE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
kid->GetNextSibling(&kid);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (aCanHaveGeneratedContent) {
|
|
|
|
// Probe for generated content after
|
|
|
|
nsIFrame* generatedFrame;
|
1999-12-04 23:49:50 +00:00
|
|
|
if (CreateGeneratedContentFrame(aPresShell, aPresContext, aState, aFrame, aContent,
|
1999-11-01 15:24:57 +00:00
|
|
|
styleContext, nsCSSAtoms::afterPseudo,
|
|
|
|
PR_FALSE, &generatedFrame)) {
|
|
|
|
// Add the generated frame to the child list
|
|
|
|
aFrameItems.AddChild(generatedFrame);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
*aKidsAllInline = allKidsInline;
|
|
|
|
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
1999-11-30 23:23:50 +00:00
|
|
|
// Helper function that recursively removes content to frame mappings and
|
|
|
|
// undisplayed content mappings.
|
|
|
|
// This differs from DeletingFrameSubtree() because the frames have not yet been
|
1999-11-11 21:08:32 +00:00
|
|
|
// added to the frame hierarchy
|
|
|
|
static void
|
2000-01-22 01:16:50 +00:00
|
|
|
DoCleanupFrameReferences(nsIPresContext* aPresContext,
|
|
|
|
nsIFrameManager* aFrameManager,
|
1999-11-30 23:23:50 +00:00
|
|
|
nsIFrame* aFrame)
|
|
|
|
{
|
|
|
|
nsCOMPtr<nsIContent> content;
|
|
|
|
aFrame->GetContent(getter_AddRefs(content));
|
|
|
|
|
|
|
|
// Remove the mapping from the content object to its frame
|
|
|
|
aFrameManager->SetPrimaryFrameFor(content, nsnull);
|
|
|
|
aFrameManager->ClearAllUndisplayedContentIn(content);
|
|
|
|
|
|
|
|
// Recursively walk the child frames.
|
|
|
|
// Note: we only need to look at the principal child list
|
|
|
|
nsIFrame* childFrame;
|
2000-01-22 01:16:50 +00:00
|
|
|
aFrame->FirstChild(aPresContext, nsnull, &childFrame);
|
1999-11-30 23:23:50 +00:00
|
|
|
while (childFrame) {
|
2000-01-22 01:16:50 +00:00
|
|
|
DoCleanupFrameReferences(aPresContext, aFrameManager, childFrame);
|
1999-11-30 23:23:50 +00:00
|
|
|
|
|
|
|
// Get the next sibling child frame
|
|
|
|
childFrame->GetNextSibling(&childFrame);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Helper function that walks a frame list and calls DoCleanupFrameReference()
|
|
|
|
static void
|
2000-01-22 01:16:50 +00:00
|
|
|
CleanupFrameReferences(nsIPresContext* aPresContext,
|
|
|
|
nsIFrameManager* aFrameManager,
|
1999-11-11 21:08:32 +00:00
|
|
|
nsIFrame* aFrameList)
|
|
|
|
{
|
|
|
|
while (aFrameList) {
|
2000-01-22 01:16:50 +00:00
|
|
|
DoCleanupFrameReferences(aPresContext, aFrameManager, aFrameList);
|
1999-11-11 21:08:32 +00:00
|
|
|
|
|
|
|
// Get the sibling frame
|
|
|
|
aFrameList->GetNextSibling(&aFrameList);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1999-11-01 15:24:57 +00:00
|
|
|
PRBool
|
|
|
|
nsCSSFrameConstructor::WipeContainingBlock(nsIPresContext* aPresContext,
|
|
|
|
nsFrameConstructorState& aState,
|
|
|
|
nsIContent* aBlockContent,
|
|
|
|
nsIFrame* aFrame,
|
|
|
|
nsIFrame* aFrameList)
|
|
|
|
{
|
|
|
|
// Before we go and append the frames, check for a special
|
|
|
|
// situation: an inline frame that will now contain block
|
|
|
|
// frames. This is a no-no and the frame construction logic knows
|
|
|
|
// how to fix this.
|
|
|
|
const nsStyleDisplay* parentDisplay;
|
|
|
|
aFrame->GetStyleData(eStyleStruct_Display, (const nsStyleStruct *&) parentDisplay);
|
|
|
|
if (NS_STYLE_DISPLAY_INLINE == parentDisplay->mDisplay) {
|
|
|
|
if (!AreAllKidsInline(aFrameList)) {
|
|
|
|
// Ok, reverse tracks: wipe out the frames we just created
|
1999-11-11 21:08:32 +00:00
|
|
|
nsCOMPtr<nsIPresShell> presShell;
|
|
|
|
nsCOMPtr<nsIFrameManager> frameManager;
|
|
|
|
|
|
|
|
aPresContext->GetShell(getter_AddRefs(presShell));
|
|
|
|
presShell->GetFrameManager(getter_AddRefs(frameManager));
|
|
|
|
|
|
|
|
// Destroy the frames. As we do make sure any content to frame mappings
|
|
|
|
// or entries in the undisplayed content map are removed
|
2000-01-22 01:16:50 +00:00
|
|
|
CleanupFrameReferences(aPresContext, frameManager, aFrameList);
|
1999-11-01 15:24:57 +00:00
|
|
|
nsFrameList tmp(aFrameList);
|
1999-11-24 06:03:41 +00:00
|
|
|
tmp.DestroyFrames(aPresContext);
|
1999-11-01 15:24:57 +00:00
|
|
|
if (aState.mAbsoluteItems.childList) {
|
2000-01-22 01:16:50 +00:00
|
|
|
CleanupFrameReferences(aPresContext, frameManager, aState.mAbsoluteItems.childList);
|
1999-11-01 15:24:57 +00:00
|
|
|
tmp.SetFrames(aState.mAbsoluteItems.childList);
|
1999-11-24 06:03:41 +00:00
|
|
|
tmp.DestroyFrames(aPresContext);
|
1999-11-01 15:24:57 +00:00
|
|
|
}
|
|
|
|
if (aState.mFixedItems.childList) {
|
2000-01-22 01:16:50 +00:00
|
|
|
CleanupFrameReferences(aPresContext, frameManager, aState.mFixedItems.childList);
|
1999-11-01 15:24:57 +00:00
|
|
|
tmp.SetFrames(aState.mFixedItems.childList);
|
1999-11-24 06:03:41 +00:00
|
|
|
tmp.DestroyFrames(aPresContext);
|
1999-11-01 15:24:57 +00:00
|
|
|
}
|
|
|
|
if (aState.mFloatedItems.childList) {
|
2000-01-22 01:16:50 +00:00
|
|
|
CleanupFrameReferences(aPresContext, frameManager, aState.mFloatedItems.childList);
|
1999-11-01 15:24:57 +00:00
|
|
|
tmp.SetFrames(aState.mFloatedItems.childList);
|
1999-11-24 06:03:41 +00:00
|
|
|
tmp.DestroyFrames(aPresContext);
|
1999-11-01 15:24:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Tell parent of the containing block to reformulate the
|
|
|
|
// entire block. This is painful and definitely not optimal
|
|
|
|
// but it will *always* get the right answer.
|
|
|
|
nsCOMPtr<nsIContent> parentContainer;
|
|
|
|
aBlockContent->GetParent(*getter_AddRefs(parentContainer));
|
|
|
|
#ifdef DEBUG
|
|
|
|
if (gNoisyContentUpdates) {
|
|
|
|
printf("nsCSSFrameConstructor::WipeContainingBlock: aBlockContent=%p parentContainer=%p\n",
|
|
|
|
aBlockContent, parentContainer.get());
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
if (parentContainer) {
|
|
|
|
PRInt32 ix;
|
|
|
|
parentContainer->IndexOf(aBlockContent, ix);
|
|
|
|
ContentReplaced(aPresContext, parentContainer, aBlockContent, aBlockContent, ix);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
// XXX uh oh. the block we need to reframe has no parent!
|
|
|
|
}
|
|
|
|
return PR_TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return PR_FALSE;
|
|
|
|
}
|
|
|
|
|
2000-07-06 04:31:33 +00:00
|
|
|
|
|
|
|
nsresult
|
|
|
|
nsCSSFrameConstructor::SplitToContainingBlock(nsIPresContext* aPresContext,
|
|
|
|
nsFrameConstructorState& aState,
|
|
|
|
nsIFrame* aFrame,
|
|
|
|
nsIFrame* aLeftInlineChildFrame,
|
|
|
|
nsIFrame* aBlockChildFrame,
|
|
|
|
nsIFrame* aRightInlineChildFrame,
|
|
|
|
PRBool aTransfer)
|
|
|
|
{
|
|
|
|
// If aFrame is an inline frame, then recursively "split" it until
|
|
|
|
// we reach a block frame. aLeftInlineChildFrame is the original
|
|
|
|
// inline child of aFrame; aBlockChildFrame and
|
|
|
|
// aRightInlineChildFrame are the newly created frames that were
|
|
|
|
// constructed as a result of the previous recursion's "split".
|
|
|
|
//
|
|
|
|
// aBlockChildFrame and aRightInlineChildFrame will be "orphaned" frames upon
|
|
|
|
// entry to this routine; that is, they won't be parented. We'll
|
|
|
|
// assign them proper parents.
|
|
|
|
nsCOMPtr<nsIPresShell> shell;
|
|
|
|
aPresContext->GetShell(getter_AddRefs(shell));
|
|
|
|
|
|
|
|
if (IsBlockFrame(aPresContext, aFrame)) {
|
|
|
|
// If aFrame is a block frame, then we're done: make
|
|
|
|
// aBlockChildFrame and aRightInlineChildFrame children of aFrame,
|
|
|
|
// and insert aBlockChildFrame and aRightInlineChildFrame after
|
|
|
|
// aLeftInlineChildFrame
|
|
|
|
aBlockChildFrame->SetParent(aFrame);
|
|
|
|
aRightInlineChildFrame->SetParent(aFrame);
|
|
|
|
aBlockChildFrame->SetNextSibling(aRightInlineChildFrame);
|
|
|
|
aFrame->InsertFrames(aPresContext, *shell, nsnull, aLeftInlineChildFrame, aBlockChildFrame);
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Otherwise, aFrame is inline. Split it, and recurse to find the
|
|
|
|
// containing block frame.
|
|
|
|
nsCOMPtr<nsIContent> content;
|
|
|
|
aFrame->GetContent(getter_AddRefs(content));
|
|
|
|
|
|
|
|
// Create an "anonymous block" frame that will parent
|
|
|
|
// aBlockChildFrame. The new frame won't have a parent yet: the recursion
|
|
|
|
// will parent it.
|
|
|
|
nsIFrame* blockFrame;
|
|
|
|
NS_NewBlockFrame(shell, &blockFrame);
|
|
|
|
|
|
|
|
nsCOMPtr<nsIStyleContext> styleContext;
|
|
|
|
aFrame->GetStyleContext(getter_AddRefs(styleContext));
|
|
|
|
|
|
|
|
nsCOMPtr<nsIStyleContext> blockSC;
|
|
|
|
aPresContext->ResolvePseudoStyleContextFor(content,
|
|
|
|
nsHTMLAtoms::mozAnonymousBlock,
|
|
|
|
styleContext,
|
|
|
|
PR_FALSE,
|
|
|
|
getter_AddRefs(blockSC));
|
|
|
|
|
|
|
|
InitAndRestoreFrame(aPresContext, aState, content,
|
|
|
|
nsnull, blockSC, nsnull, blockFrame);
|
|
|
|
|
|
|
|
blockFrame->SetInitialChildList(aPresContext, nsnull, aBlockChildFrame);
|
|
|
|
MoveChildrenTo(aPresContext, blockSC, blockFrame, aBlockChildFrame);
|
|
|
|
|
|
|
|
// Create an anonymous inline frame that will parent
|
|
|
|
// aRightInlineChildFrame. The new frame won't have a parent yet:
|
|
|
|
// the recursion will parent it.
|
|
|
|
nsIFrame* inlineFrame;
|
|
|
|
NS_NewInlineFrame(shell, &inlineFrame);
|
|
|
|
|
|
|
|
InitAndRestoreFrame(aPresContext, aState, content,
|
|
|
|
nsnull, styleContext, nsnull, inlineFrame);
|
|
|
|
|
|
|
|
inlineFrame->SetInitialChildList(aPresContext, nsnull, aRightInlineChildFrame);
|
|
|
|
MoveChildrenTo(aPresContext, styleContext, inlineFrame, aRightInlineChildFrame);
|
|
|
|
|
|
|
|
// Make the "special" inline-block linkage between aFrame and the
|
|
|
|
// newly created anonymous frames. We need to create the linkage
|
|
|
|
// between the first in flow, so if we're a continuation frame, walk
|
|
|
|
// back to find it.
|
|
|
|
nsIFrame* firstInFlow = aFrame;
|
|
|
|
while (1) {
|
|
|
|
nsIFrame* prevInFlow;
|
|
|
|
firstInFlow->GetPrevInFlow(&prevInFlow);
|
|
|
|
if (! prevInFlow) break;
|
|
|
|
firstInFlow = prevInFlow;
|
|
|
|
}
|
|
|
|
|
|
|
|
SetFrameIsSpecial(aState.mFrameManager, firstInFlow, blockFrame);
|
|
|
|
SetFrameIsSpecial(aState.mFrameManager, blockFrame, inlineFrame);
|
|
|
|
SetFrameIsSpecial(aState.mFrameManager, inlineFrame, nsnull);
|
|
|
|
|
|
|
|
// If we have a continuation frame, then we need to break the
|
|
|
|
// continuation.
|
|
|
|
nsIFrame* nextInFlow;
|
|
|
|
aFrame->GetNextInFlow(&nextInFlow);
|
|
|
|
if (nextInFlow) {
|
|
|
|
aFrame->SetNextInFlow(nsnull);
|
|
|
|
nextInFlow->SetPrevInFlow(nsnull);
|
|
|
|
}
|
|
|
|
|
|
|
|
// This is where the mothership lands and we start to get a bit
|
|
|
|
// funky. We're going to do a bit of work to ensure that the frames
|
|
|
|
// from the *last* recursion are properly hooked up.
|
|
|
|
//
|
|
|
|
// aTransfer will be set once the recursion begins to nest. (It's
|
|
|
|
// not set at the first level of recursion, because
|
|
|
|
// aLeftInlineChildFrame, aBlockChildFrame, and
|
|
|
|
// aRightInlineChildFrame already have their sibling and parent
|
|
|
|
// pointers properly initialized.)
|
|
|
|
//
|
|
|
|
// Once we begin to nest recursion, aLeftInlineChildFrame
|
|
|
|
// corresponds to the original inline that we're trying to split,
|
|
|
|
// and aBlockChildFrame and aRightInlineChildFrame are the anonymous
|
|
|
|
// frames we created to protect the inline-block invariant.
|
|
|
|
if (aTransfer) {
|
|
|
|
// We need to move any successors of the original inline
|
|
|
|
// (aLeftInlineChildFrame) to aRightInlineChildFrame.
|
|
|
|
nsIFrame* nextInlineFrame;
|
|
|
|
aLeftInlineChildFrame->GetNextSibling(&nextInlineFrame);
|
|
|
|
aLeftInlineChildFrame->SetNextSibling(nsnull);
|
|
|
|
aRightInlineChildFrame->SetNextSibling(nextInlineFrame);
|
|
|
|
|
|
|
|
// Any frame that was moved will need its parent pointer fixed,
|
|
|
|
// and will need to be marked as dirty.
|
|
|
|
while (nextInlineFrame) {
|
|
|
|
nextInlineFrame->SetParent(inlineFrame);
|
|
|
|
|
|
|
|
nsFrameState state;
|
|
|
|
nextInlineFrame->GetFrameState(&state);
|
|
|
|
state |= NS_FRAME_IS_DIRTY;
|
|
|
|
nextInlineFrame->SetFrameState(state);
|
|
|
|
|
|
|
|
nextInlineFrame->GetNextSibling(&nextInlineFrame);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Recurse to the parent frame. This will assign a parent frame to
|
|
|
|
// each new frame we've just created.
|
|
|
|
nsIFrame* parent;
|
|
|
|
aFrame->GetParent(&parent);
|
|
|
|
|
|
|
|
NS_ASSERTION(parent != nsnull, "frame has no geometric parent");
|
|
|
|
if (! parent)
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
|
|
|
|
// When we recur, we'll make the "left inline child frame" be the
|
|
|
|
// inline frame we've just begun to "split", and we'll pass the
|
|
|
|
// newly created anonymous frames as aBlockChildFrame and
|
|
|
|
// aRightInlineChildFrame.
|
|
|
|
return SplitToContainingBlock(aPresContext, aState, parent, aFrame, blockFrame, inlineFrame, PR_TRUE);
|
|
|
|
}
|
|
|
|
|
1999-11-01 15:24:57 +00:00
|
|
|
nsresult
|
|
|
|
nsCSSFrameConstructor::ReframeContainingBlock(nsIPresContext* aPresContext, nsIFrame* aFrame)
|
|
|
|
{
|
2000-06-07 06:58:45 +00:00
|
|
|
// Get the first "normal" parent of the target frame. From there we
|
|
|
|
// look for the containing block in case the target frame is already
|
|
|
|
// a block (which can happen when an inline frame wraps some of its
|
|
|
|
// content in an anonymous block; see ConstructInline)
|
1999-11-01 15:24:57 +00:00
|
|
|
nsIFrame* parentFrame;
|
2000-06-07 06:58:45 +00:00
|
|
|
do {
|
|
|
|
aFrame->GetParent(&parentFrame);
|
|
|
|
if (!parentFrame || !IsFrameSpecial(parentFrame))
|
|
|
|
break;
|
|
|
|
|
|
|
|
aFrame = parentFrame;
|
|
|
|
} while (1);
|
|
|
|
|
|
|
|
|
1999-11-01 15:24:57 +00:00
|
|
|
if (!parentFrame) {
|
|
|
|
return RecreateEntireFrameTree(aPresContext);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Now find the containing block
|
|
|
|
nsIFrame* containingBlock = GetFloaterContainingBlock(aPresContext, parentFrame);
|
|
|
|
if (!containingBlock) {
|
|
|
|
return RecreateEntireFrameTree(aPresContext);
|
|
|
|
}
|
|
|
|
|
|
|
|
// And get the containingBlock's content
|
|
|
|
nsCOMPtr<nsIContent> blockContent;
|
|
|
|
containingBlock->GetContent(getter_AddRefs(blockContent));
|
|
|
|
if (!blockContent) {
|
|
|
|
return RecreateEntireFrameTree(aPresContext);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Now find the containingBlock's content's parent
|
|
|
|
nsCOMPtr<nsIContent> parentContainer;
|
|
|
|
blockContent->GetParent(*getter_AddRefs(parentContainer));
|
|
|
|
if (!parentContainer) {
|
|
|
|
return RecreateEntireFrameTree(aPresContext);
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef DEBUG
|
|
|
|
if (gNoisyContentUpdates) {
|
|
|
|
printf(" ==> blockContent=%p, parentContainer=%p\n",
|
|
|
|
blockContent.get(), parentContainer.get());
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
PRInt32 ix;
|
|
|
|
parentContainer->IndexOf(blockContent, ix);
|
|
|
|
nsresult rv = ContentReplaced(aPresContext, parentContainer, blockContent, blockContent, ix);
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
nsCSSFrameConstructor::RecreateEntireFrameTree(nsIPresContext* aPresContext)
|
|
|
|
{
|
|
|
|
// XXX write me some day
|
|
|
|
return NS_OK;
|
|
|
|
}
|