1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 /* storage of the frame tree and information about it */ 8 9 #ifndef _nsFrameManager_h_ 10 #define _nsFrameManager_h_ 11 12 #include "nsDebug.h" 13 #include "mozilla/Attributes.h" 14 #include "nsFrameList.h" 15 16 class nsContainerFrame; 17 class nsIFrame; 18 class nsILayoutHistoryState; 19 class nsIPresShell; 20 class nsPlaceholderFrame; 21 class nsStyleContext; 22 class nsWindowSizes; 23 namespace mozilla { 24 struct UndisplayedNode; 25 } 26 27 /** 28 * Frame manager interface. The frame manager serves one purpose: 29 * <li>handles structural modifications to the frame model. If the frame model 30 * lock can be acquired, then the changes are processed immediately; otherwise, 31 * they're queued and processed later. 32 * 33 * FIXME(emilio): The comment above doesn't make any sense, there's no "frame 34 * model lock" of any sort afaict. 35 */ 36 class nsFrameManager { 37 typedef mozilla::layout::FrameChildListID ChildListID; 38 typedef mozilla::UndisplayedNode UndisplayedNode; 39 40 public: nsFrameManager(nsIPresShell * aPresShell)41 explicit nsFrameManager(nsIPresShell* aPresShell) 42 : mPresShell(aPresShell), 43 mRootFrame(nullptr), 44 mDisplayNoneMap(nullptr), 45 mDisplayContentsMap(nullptr), 46 mIsDestroyingFrames(false) { 47 MOZ_ASSERT(mPresShell, "need a pres shell"); 48 } 49 ~nsFrameManager(); 50 IsDestroyingFrames()51 bool IsDestroyingFrames() const { return mIsDestroyingFrames; } 52 53 /* 54 * Gets and sets the root frame (typically the viewport). The lifetime of the 55 * root frame is controlled by the frame manager. When the frame manager is 56 * destroyed, it destroys the entire frame hierarchy. 57 */ GetRootFrame()58 nsIFrame* GetRootFrame() const { return mRootFrame; } SetRootFrame(nsIFrame * aRootFrame)59 void SetRootFrame(nsIFrame* aRootFrame) { 60 NS_ASSERTION(!mRootFrame, "already have a root frame"); 61 mRootFrame = aRootFrame; 62 } 63 64 /* 65 * After Destroy is called, it is an error to call any FrameManager methods. 66 * Destroy should be called when the frame tree managed by the frame 67 * manager is no longer being displayed. 68 */ 69 void Destroy(); 70 71 // display:none and display:contents content does not get an nsIFrame. To 72 // enable the style context for such content to be obtained we store the 73 // contexts in a couple of hash tables. The following methods provide the 74 // API that's used to set, reset, obtain and clear these style contexts. 75 76 /** 77 * Register the style context for the display:none content, aContent. 78 */ 79 void RegisterDisplayNoneStyleFor(nsIContent* aContent, 80 nsStyleContext* aStyleContext); 81 82 /** 83 * Register the style context for the display:contents content, aContent. 84 */ 85 void RegisterDisplayContentsStyleFor(nsIContent* aContent, 86 nsStyleContext* aStyleContext); 87 88 /** 89 * Change the style context for the display:none content, aContent. 90 */ ChangeRegisteredDisplayNoneStyleFor(nsIContent * aContent,nsStyleContext * aStyleContext)91 void ChangeRegisteredDisplayNoneStyleFor(nsIContent* aContent, 92 nsStyleContext* aStyleContext) { 93 ChangeStyleContextInMap(mDisplayNoneMap, aContent, aStyleContext); 94 } 95 96 /** 97 * Change the style context for the display:contents content, aContent. 98 */ ChangeRegisteredDisplayContentsStyleFor(nsIContent * aContent,nsStyleContext * aStyleContext)99 void ChangeRegisteredDisplayContentsStyleFor(nsIContent* aContent, 100 nsStyleContext* aStyleContext) { 101 ChangeStyleContextInMap(mDisplayContentsMap, aContent, aStyleContext); 102 } 103 104 /** 105 * Get the style context for the display:none content, aContent, if any. 106 */ GetDisplayNoneStyleFor(const nsIContent * aContent)107 nsStyleContext* GetDisplayNoneStyleFor(const nsIContent* aContent) { 108 if (!mDisplayNoneMap) { 109 return nullptr; 110 } 111 return GetStyleContextInMap(mDisplayNoneMap, aContent); 112 } 113 114 /** 115 * Get the style context for the display:contents content, aContent, if any. 116 */ GetDisplayContentsStyleFor(const nsIContent * aContent)117 nsStyleContext* GetDisplayContentsStyleFor(const nsIContent* aContent) { 118 if (!mDisplayContentsMap) { 119 return nullptr; 120 } 121 return GetStyleContextInMap(mDisplayContentsMap, aContent); 122 } 123 124 /** 125 * Return the linked list of UndisplayedNodes that contain the style contexts 126 * that have been registered for the display:none children of 127 * aParentContent. 128 */ 129 UndisplayedNode* GetAllRegisteredDisplayNoneStylesIn( 130 nsIContent* aParentContent); 131 132 /** 133 * Return the linked list of UndisplayedNodes that contain the style contexts 134 * that have been registered for the display:contents children of 135 * aParentContent. 136 */ 137 UndisplayedNode* GetAllRegisteredDisplayContentsStylesIn( 138 nsIContent* aParentContent); 139 140 /** 141 * Unregister the style context for the display:none content, aContent, 142 * if any. If found, then this method also unregisters the style contexts 143 * for any display:contents and display:none descendants of aContent. 144 */ 145 void UnregisterDisplayNoneStyleFor(nsIContent* aContent, 146 nsIContent* aParentContent); 147 148 /** 149 * Unregister the style context for the display:contents content, aContent, 150 * if any. If found, then this method also unregisters the style contexts 151 * for any display:contents and display:none descendants of aContent. 152 */ 153 void UnregisterDisplayContentsStyleFor(nsIContent* aContent, 154 nsIContent* aParentContent); 155 156 // Functions for manipulating the frame model 157 void AppendFrames(nsContainerFrame* aParentFrame, ChildListID aListID, 158 nsFrameList& aFrameList); 159 160 void InsertFrames(nsContainerFrame* aParentFrame, ChildListID aListID, 161 nsIFrame* aPrevFrame, nsFrameList& aFrameList); 162 163 void RemoveFrame(ChildListID aListID, nsIFrame* aOldFrame); 164 165 /* 166 * Notification that a frame is about to be destroyed. This allows any 167 * outstanding references to the frame to be cleaned up. 168 */ 169 void NotifyDestroyingFrame(nsIFrame* aFrame); 170 171 /* 172 * Capture/restore frame state for the frame subtree rooted at aFrame. 173 * aState is the document state storage object onto which each frame 174 * stores its state. Callers of CaptureFrameState are responsible for 175 * traversing next continuations of special siblings of aFrame as 176 * needed; this method will only work with actual frametree descendants 177 * of aFrame. 178 */ 179 180 void CaptureFrameState(nsIFrame* aFrame, nsILayoutHistoryState* aState); 181 182 void RestoreFrameState(nsIFrame* aFrame, nsILayoutHistoryState* aState); 183 184 /* 185 * Add/restore state for one frame 186 */ 187 void CaptureFrameStateFor(nsIFrame* aFrame, nsILayoutHistoryState* aState); 188 189 void RestoreFrameStateFor(nsIFrame* aFrame, nsILayoutHistoryState* aState); 190 191 void DestroyAnonymousContent(already_AddRefed<nsIContent> aContent); 192 193 void AddSizeOfIncludingThis(nsWindowSizes& aSizes) const; 194 195 protected: 196 class UndisplayedMap; 197 198 static nsIContent* ParentForUndisplayedMap(const nsIContent* aContent); 199 200 void ClearAllMapsFor(nsIContent* aParentContent); 201 202 static nsStyleContext* GetStyleContextInMap(UndisplayedMap* aMap, 203 const nsIContent* aContent); 204 static UndisplayedNode* GetUndisplayedNodeInMapFor( 205 UndisplayedMap* aMap, const nsIContent* aContent); 206 static UndisplayedNode* GetAllUndisplayedNodesInMapFor( 207 UndisplayedMap* aMap, nsIContent* aParentContent); 208 static void SetStyleContextInMap(UndisplayedMap* aMap, nsIContent* aContent, 209 nsStyleContext* aStyleContext); 210 static void ChangeStyleContextInMap(UndisplayedMap* aMap, 211 nsIContent* aContent, 212 nsStyleContext* aStyleContext); 213 214 // weak link, because the pres shell owns us 215 nsIPresShell* MOZ_NON_OWNING_REF mPresShell; 216 nsIFrame* mRootFrame; 217 UndisplayedMap* mDisplayNoneMap; 218 UndisplayedMap* mDisplayContentsMap; 219 bool mIsDestroyingFrames; // The frame manager is destroying some frame(s). 220 }; 221 222 #endif 223