Wed, 31 Dec 2014 06:09:35 +0100
Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.
michael@0 | 1 | /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
michael@0 | 2 | /* This Source Code Form is subject to the terms of the Mozilla Public |
michael@0 | 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this |
michael@0 | 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
michael@0 | 5 | #include "nsCOMPtr.h" |
michael@0 | 6 | #include "nsGkAtoms.h" |
michael@0 | 7 | |
michael@0 | 8 | #include "nsFrameTraversal.h" |
michael@0 | 9 | #include "nsFrameList.h" |
michael@0 | 10 | #include "nsPlaceholderFrame.h" |
michael@0 | 11 | |
michael@0 | 12 | |
michael@0 | 13 | class nsFrameIterator : public nsIFrameEnumerator |
michael@0 | 14 | { |
michael@0 | 15 | public: |
michael@0 | 16 | typedef nsIFrame::ChildListID ChildListID; |
michael@0 | 17 | |
michael@0 | 18 | NS_DECL_ISUPPORTS |
michael@0 | 19 | |
michael@0 | 20 | virtual ~nsFrameIterator() {} |
michael@0 | 21 | |
michael@0 | 22 | virtual void First() MOZ_OVERRIDE; |
michael@0 | 23 | virtual void Next() MOZ_OVERRIDE; |
michael@0 | 24 | virtual nsIFrame* CurrentItem() MOZ_OVERRIDE; |
michael@0 | 25 | virtual bool IsDone() MOZ_OVERRIDE; |
michael@0 | 26 | |
michael@0 | 27 | virtual void Last() MOZ_OVERRIDE; |
michael@0 | 28 | virtual void Prev() MOZ_OVERRIDE; |
michael@0 | 29 | |
michael@0 | 30 | nsFrameIterator(nsPresContext* aPresContext, nsIFrame *aStart, |
michael@0 | 31 | nsIteratorType aType, bool aLockScroll, bool aFollowOOFs); |
michael@0 | 32 | |
michael@0 | 33 | protected: |
michael@0 | 34 | void setCurrent(nsIFrame *aFrame){mCurrent = aFrame;} |
michael@0 | 35 | nsIFrame *getCurrent(){return mCurrent;} |
michael@0 | 36 | nsIFrame *getStart(){return mStart;} |
michael@0 | 37 | nsIFrame *getLast(){return mLast;} |
michael@0 | 38 | void setLast(nsIFrame *aFrame){mLast = aFrame;} |
michael@0 | 39 | int8_t getOffEdge(){return mOffEdge;} |
michael@0 | 40 | void setOffEdge(int8_t aOffEdge){mOffEdge = aOffEdge;} |
michael@0 | 41 | |
michael@0 | 42 | /* |
michael@0 | 43 | Our own versions of the standard frame tree navigation |
michael@0 | 44 | methods, which, if the iterator is following out-of-flows, |
michael@0 | 45 | apply the following rules for placeholder frames: |
michael@0 | 46 | |
michael@0 | 47 | - If a frame HAS a placeholder frame, getting its parent |
michael@0 | 48 | gets the placeholder's parent. |
michael@0 | 49 | |
michael@0 | 50 | - If a frame's first child or next/prev sibling IS a |
michael@0 | 51 | placeholder frame, then we instead return the real frame. |
michael@0 | 52 | |
michael@0 | 53 | - If a frame HAS a placeholder frame, getting its next/prev |
michael@0 | 54 | sibling gets the placeholder frame's next/prev sibling. |
michael@0 | 55 | |
michael@0 | 56 | These are all applied recursively to support multiple levels of |
michael@0 | 57 | placeholders. |
michael@0 | 58 | */ |
michael@0 | 59 | |
michael@0 | 60 | nsIFrame* GetParentFrame(nsIFrame* aFrame); |
michael@0 | 61 | // like GetParentFrame but returns null once a popup frame is reached |
michael@0 | 62 | nsIFrame* GetParentFrameNotPopup(nsIFrame* aFrame); |
michael@0 | 63 | |
michael@0 | 64 | nsIFrame* GetFirstChild(nsIFrame* aFrame); |
michael@0 | 65 | nsIFrame* GetLastChild(nsIFrame* aFrame); |
michael@0 | 66 | |
michael@0 | 67 | nsIFrame* GetNextSibling(nsIFrame* aFrame); |
michael@0 | 68 | nsIFrame* GetPrevSibling(nsIFrame* aFrame); |
michael@0 | 69 | |
michael@0 | 70 | /* |
michael@0 | 71 | These methods are overridden by the bidi visual iterator to have the |
michael@0 | 72 | semantics of "get first child in visual order", "get last child in visual |
michael@0 | 73 | order", "get next sibling in visual order" and "get previous sibling in visual |
michael@0 | 74 | order". |
michael@0 | 75 | */ |
michael@0 | 76 | |
michael@0 | 77 | virtual nsIFrame* GetFirstChildInner(nsIFrame* aFrame); |
michael@0 | 78 | virtual nsIFrame* GetLastChildInner(nsIFrame* aFrame); |
michael@0 | 79 | |
michael@0 | 80 | virtual nsIFrame* GetNextSiblingInner(nsIFrame* aFrame); |
michael@0 | 81 | virtual nsIFrame* GetPrevSiblingInner(nsIFrame* aFrame); |
michael@0 | 82 | |
michael@0 | 83 | nsIFrame* GetPlaceholderFrame(nsIFrame* aFrame); |
michael@0 | 84 | bool IsPopupFrame(nsIFrame* aFrame); |
michael@0 | 85 | |
michael@0 | 86 | nsPresContext* const mPresContext; |
michael@0 | 87 | const bool mLockScroll; |
michael@0 | 88 | const bool mFollowOOFs; |
michael@0 | 89 | const nsIteratorType mType; |
michael@0 | 90 | |
michael@0 | 91 | private: |
michael@0 | 92 | nsIFrame* const mStart; |
michael@0 | 93 | nsIFrame* mCurrent; |
michael@0 | 94 | nsIFrame* mLast; //the last one that was in current; |
michael@0 | 95 | int8_t mOffEdge; //0= no -1 to far prev, 1 to far next; |
michael@0 | 96 | }; |
michael@0 | 97 | |
michael@0 | 98 | |
michael@0 | 99 | |
michael@0 | 100 | // Bidi visual iterator |
michael@0 | 101 | class nsVisualIterator: public nsFrameIterator |
michael@0 | 102 | { |
michael@0 | 103 | public: |
michael@0 | 104 | nsVisualIterator(nsPresContext* aPresContext, nsIFrame *aStart, |
michael@0 | 105 | nsIteratorType aType, bool aLockScroll, bool aFollowOOFs) : |
michael@0 | 106 | nsFrameIterator(aPresContext, aStart, aType, aLockScroll, aFollowOOFs) {} |
michael@0 | 107 | |
michael@0 | 108 | protected: |
michael@0 | 109 | nsIFrame* GetFirstChildInner(nsIFrame* aFrame) MOZ_OVERRIDE; |
michael@0 | 110 | nsIFrame* GetLastChildInner(nsIFrame* aFrame) MOZ_OVERRIDE; |
michael@0 | 111 | |
michael@0 | 112 | nsIFrame* GetNextSiblingInner(nsIFrame* aFrame) MOZ_OVERRIDE; |
michael@0 | 113 | nsIFrame* GetPrevSiblingInner(nsIFrame* aFrame) MOZ_OVERRIDE; |
michael@0 | 114 | }; |
michael@0 | 115 | |
michael@0 | 116 | /************IMPLEMENTATIONS**************/ |
michael@0 | 117 | |
michael@0 | 118 | nsresult NS_CreateFrameTraversal(nsIFrameTraversal** aResult) |
michael@0 | 119 | { |
michael@0 | 120 | NS_ENSURE_ARG_POINTER(aResult); |
michael@0 | 121 | *aResult = nullptr; |
michael@0 | 122 | |
michael@0 | 123 | nsCOMPtr<nsIFrameTraversal> t(new nsFrameTraversal()); |
michael@0 | 124 | |
michael@0 | 125 | *aResult = t; |
michael@0 | 126 | NS_ADDREF(*aResult); |
michael@0 | 127 | |
michael@0 | 128 | return NS_OK; |
michael@0 | 129 | } |
michael@0 | 130 | |
michael@0 | 131 | nsresult |
michael@0 | 132 | NS_NewFrameTraversal(nsIFrameEnumerator **aEnumerator, |
michael@0 | 133 | nsPresContext* aPresContext, |
michael@0 | 134 | nsIFrame *aStart, |
michael@0 | 135 | nsIteratorType aType, |
michael@0 | 136 | bool aVisual, |
michael@0 | 137 | bool aLockInScrollView, |
michael@0 | 138 | bool aFollowOOFs) |
michael@0 | 139 | { |
michael@0 | 140 | if (!aEnumerator || !aStart) |
michael@0 | 141 | return NS_ERROR_NULL_POINTER; |
michael@0 | 142 | |
michael@0 | 143 | if (aFollowOOFs) { |
michael@0 | 144 | aStart = nsPlaceholderFrame::GetRealFrameFor(aStart); |
michael@0 | 145 | } |
michael@0 | 146 | |
michael@0 | 147 | nsCOMPtr<nsIFrameEnumerator> trav; |
michael@0 | 148 | if (aVisual) { |
michael@0 | 149 | trav = new nsVisualIterator(aPresContext, aStart, aType, |
michael@0 | 150 | aLockInScrollView, aFollowOOFs); |
michael@0 | 151 | } else { |
michael@0 | 152 | trav = new nsFrameIterator(aPresContext, aStart, aType, |
michael@0 | 153 | aLockInScrollView, aFollowOOFs); |
michael@0 | 154 | } |
michael@0 | 155 | trav.forget(aEnumerator); |
michael@0 | 156 | return NS_OK; |
michael@0 | 157 | } |
michael@0 | 158 | |
michael@0 | 159 | |
michael@0 | 160 | nsFrameTraversal::nsFrameTraversal() |
michael@0 | 161 | { |
michael@0 | 162 | } |
michael@0 | 163 | |
michael@0 | 164 | nsFrameTraversal::~nsFrameTraversal() |
michael@0 | 165 | { |
michael@0 | 166 | } |
michael@0 | 167 | |
michael@0 | 168 | NS_IMPL_ISUPPORTS(nsFrameTraversal,nsIFrameTraversal) |
michael@0 | 169 | |
michael@0 | 170 | NS_IMETHODIMP |
michael@0 | 171 | nsFrameTraversal::NewFrameTraversal(nsIFrameEnumerator **aEnumerator, |
michael@0 | 172 | nsPresContext* aPresContext, |
michael@0 | 173 | nsIFrame *aStart, |
michael@0 | 174 | int32_t aType, |
michael@0 | 175 | bool aVisual, |
michael@0 | 176 | bool aLockInScrollView, |
michael@0 | 177 | bool aFollowOOFs) |
michael@0 | 178 | { |
michael@0 | 179 | return NS_NewFrameTraversal(aEnumerator, aPresContext, aStart, |
michael@0 | 180 | static_cast<nsIteratorType>(aType), |
michael@0 | 181 | aVisual, aLockInScrollView, aFollowOOFs); |
michael@0 | 182 | } |
michael@0 | 183 | |
michael@0 | 184 | // nsFrameIterator implementation |
michael@0 | 185 | |
michael@0 | 186 | NS_IMPL_ISUPPORTS(nsFrameIterator, nsIFrameEnumerator) |
michael@0 | 187 | |
michael@0 | 188 | nsFrameIterator::nsFrameIterator(nsPresContext* aPresContext, nsIFrame *aStart, |
michael@0 | 189 | nsIteratorType aType, bool aLockInScrollView, |
michael@0 | 190 | bool aFollowOOFs) |
michael@0 | 191 | : mPresContext(aPresContext), |
michael@0 | 192 | mLockScroll(aLockInScrollView), |
michael@0 | 193 | mFollowOOFs(aFollowOOFs), |
michael@0 | 194 | mType(aType), |
michael@0 | 195 | mStart(aStart), |
michael@0 | 196 | mCurrent(aStart), |
michael@0 | 197 | mLast(aStart), |
michael@0 | 198 | mOffEdge(0) |
michael@0 | 199 | { |
michael@0 | 200 | MOZ_ASSERT(!aFollowOOFs || aStart->GetType() != nsGkAtoms::placeholderFrame, |
michael@0 | 201 | "Caller should have resolved placeholder frame"); |
michael@0 | 202 | } |
michael@0 | 203 | |
michael@0 | 204 | |
michael@0 | 205 | |
michael@0 | 206 | nsIFrame* |
michael@0 | 207 | nsFrameIterator::CurrentItem() |
michael@0 | 208 | { |
michael@0 | 209 | if (mOffEdge) |
michael@0 | 210 | return nullptr; |
michael@0 | 211 | |
michael@0 | 212 | return mCurrent; |
michael@0 | 213 | } |
michael@0 | 214 | |
michael@0 | 215 | |
michael@0 | 216 | |
michael@0 | 217 | bool |
michael@0 | 218 | nsFrameIterator::IsDone() |
michael@0 | 219 | { |
michael@0 | 220 | return mOffEdge != 0; |
michael@0 | 221 | } |
michael@0 | 222 | |
michael@0 | 223 | void |
michael@0 | 224 | nsFrameIterator::First() |
michael@0 | 225 | { |
michael@0 | 226 | mCurrent = mStart; |
michael@0 | 227 | } |
michael@0 | 228 | |
michael@0 | 229 | static bool |
michael@0 | 230 | IsRootFrame(nsIFrame* aFrame) |
michael@0 | 231 | { |
michael@0 | 232 | nsIAtom* atom = aFrame->GetType(); |
michael@0 | 233 | return (atom == nsGkAtoms::canvasFrame) || |
michael@0 | 234 | (atom == nsGkAtoms::rootFrame); |
michael@0 | 235 | } |
michael@0 | 236 | |
michael@0 | 237 | void |
michael@0 | 238 | nsFrameIterator::Last() |
michael@0 | 239 | { |
michael@0 | 240 | nsIFrame* result; |
michael@0 | 241 | nsIFrame* parent = getCurrent(); |
michael@0 | 242 | // If the current frame is a popup, don't move farther up the tree. |
michael@0 | 243 | // Otherwise, get the nearest root frame or popup. |
michael@0 | 244 | if (parent->GetType() != nsGkAtoms::menuPopupFrame) { |
michael@0 | 245 | while (!IsRootFrame(parent) && (result = GetParentFrameNotPopup(parent))) |
michael@0 | 246 | parent = result; |
michael@0 | 247 | } |
michael@0 | 248 | |
michael@0 | 249 | while ((result = GetLastChild(parent))) { |
michael@0 | 250 | parent = result; |
michael@0 | 251 | } |
michael@0 | 252 | |
michael@0 | 253 | setCurrent(parent); |
michael@0 | 254 | if (!parent) |
michael@0 | 255 | setOffEdge(1); |
michael@0 | 256 | } |
michael@0 | 257 | |
michael@0 | 258 | void |
michael@0 | 259 | nsFrameIterator::Next() |
michael@0 | 260 | { |
michael@0 | 261 | // recursive-oid method to get next frame |
michael@0 | 262 | nsIFrame *result = nullptr; |
michael@0 | 263 | nsIFrame *parent = getCurrent(); |
michael@0 | 264 | if (!parent) |
michael@0 | 265 | parent = getLast(); |
michael@0 | 266 | |
michael@0 | 267 | if (mType == eLeaf) { |
michael@0 | 268 | // Drill down to first leaf |
michael@0 | 269 | while ((result = GetFirstChild(parent))) { |
michael@0 | 270 | parent = result; |
michael@0 | 271 | } |
michael@0 | 272 | } else if (mType == ePreOrder) { |
michael@0 | 273 | result = GetFirstChild(parent); |
michael@0 | 274 | if (result) |
michael@0 | 275 | parent = result; |
michael@0 | 276 | } |
michael@0 | 277 | |
michael@0 | 278 | if (parent != getCurrent()) { |
michael@0 | 279 | result = parent; |
michael@0 | 280 | } else { |
michael@0 | 281 | while (parent) { |
michael@0 | 282 | result = GetNextSibling(parent); |
michael@0 | 283 | if (result) { |
michael@0 | 284 | if (mType != ePreOrder) { |
michael@0 | 285 | parent = result; |
michael@0 | 286 | while ((result = GetFirstChild(parent))) { |
michael@0 | 287 | parent = result; |
michael@0 | 288 | } |
michael@0 | 289 | result = parent; |
michael@0 | 290 | } |
michael@0 | 291 | break; |
michael@0 | 292 | } |
michael@0 | 293 | else { |
michael@0 | 294 | result = GetParentFrameNotPopup(parent); |
michael@0 | 295 | if (!result || IsRootFrame(result) || |
michael@0 | 296 | (mLockScroll && result->GetType() == nsGkAtoms::scrollFrame)) { |
michael@0 | 297 | result = nullptr; |
michael@0 | 298 | break; |
michael@0 | 299 | } |
michael@0 | 300 | if (mType == ePostOrder) |
michael@0 | 301 | break; |
michael@0 | 302 | parent = result; |
michael@0 | 303 | } |
michael@0 | 304 | } |
michael@0 | 305 | } |
michael@0 | 306 | |
michael@0 | 307 | setCurrent(result); |
michael@0 | 308 | if (!result) { |
michael@0 | 309 | setOffEdge(1); |
michael@0 | 310 | setLast(parent); |
michael@0 | 311 | } |
michael@0 | 312 | } |
michael@0 | 313 | |
michael@0 | 314 | void |
michael@0 | 315 | nsFrameIterator::Prev() |
michael@0 | 316 | { |
michael@0 | 317 | // recursive-oid method to get prev frame |
michael@0 | 318 | nsIFrame *result = nullptr; |
michael@0 | 319 | nsIFrame *parent = getCurrent(); |
michael@0 | 320 | if (!parent) |
michael@0 | 321 | parent = getLast(); |
michael@0 | 322 | |
michael@0 | 323 | if (mType == eLeaf) { |
michael@0 | 324 | // Drill down to last leaf |
michael@0 | 325 | while ((result = GetLastChild(parent))) { |
michael@0 | 326 | parent = result; |
michael@0 | 327 | } |
michael@0 | 328 | } else if (mType == ePostOrder) { |
michael@0 | 329 | result = GetLastChild(parent); |
michael@0 | 330 | if (result) |
michael@0 | 331 | parent = result; |
michael@0 | 332 | } |
michael@0 | 333 | |
michael@0 | 334 | if (parent != getCurrent()) { |
michael@0 | 335 | result = parent; |
michael@0 | 336 | } else { |
michael@0 | 337 | while (parent) { |
michael@0 | 338 | result = GetPrevSibling(parent); |
michael@0 | 339 | if (result) { |
michael@0 | 340 | if (mType != ePostOrder) { |
michael@0 | 341 | parent = result; |
michael@0 | 342 | while ((result = GetLastChild(parent))) { |
michael@0 | 343 | parent = result; |
michael@0 | 344 | } |
michael@0 | 345 | result = parent; |
michael@0 | 346 | } |
michael@0 | 347 | break; |
michael@0 | 348 | } else { |
michael@0 | 349 | result = GetParentFrameNotPopup(parent); |
michael@0 | 350 | if (!result || IsRootFrame(result) || |
michael@0 | 351 | (mLockScroll && result->GetType() == nsGkAtoms::scrollFrame)) { |
michael@0 | 352 | result = nullptr; |
michael@0 | 353 | break; |
michael@0 | 354 | } |
michael@0 | 355 | if (mType == ePreOrder) |
michael@0 | 356 | break; |
michael@0 | 357 | parent = result; |
michael@0 | 358 | } |
michael@0 | 359 | } |
michael@0 | 360 | } |
michael@0 | 361 | |
michael@0 | 362 | setCurrent(result); |
michael@0 | 363 | if (!result) { |
michael@0 | 364 | setOffEdge(-1); |
michael@0 | 365 | setLast(parent); |
michael@0 | 366 | } |
michael@0 | 367 | } |
michael@0 | 368 | |
michael@0 | 369 | nsIFrame* |
michael@0 | 370 | nsFrameIterator::GetParentFrame(nsIFrame* aFrame) |
michael@0 | 371 | { |
michael@0 | 372 | if (mFollowOOFs) |
michael@0 | 373 | aFrame = GetPlaceholderFrame(aFrame); |
michael@0 | 374 | if (aFrame) |
michael@0 | 375 | return aFrame->GetParent(); |
michael@0 | 376 | |
michael@0 | 377 | return nullptr; |
michael@0 | 378 | } |
michael@0 | 379 | |
michael@0 | 380 | nsIFrame* |
michael@0 | 381 | nsFrameIterator::GetParentFrameNotPopup(nsIFrame* aFrame) |
michael@0 | 382 | { |
michael@0 | 383 | if (mFollowOOFs) |
michael@0 | 384 | aFrame = GetPlaceholderFrame(aFrame); |
michael@0 | 385 | if (aFrame) { |
michael@0 | 386 | nsIFrame* parent = aFrame->GetParent(); |
michael@0 | 387 | if (!IsPopupFrame(parent)) |
michael@0 | 388 | return parent; |
michael@0 | 389 | } |
michael@0 | 390 | |
michael@0 | 391 | return nullptr; |
michael@0 | 392 | } |
michael@0 | 393 | |
michael@0 | 394 | nsIFrame* |
michael@0 | 395 | nsFrameIterator::GetFirstChild(nsIFrame* aFrame) |
michael@0 | 396 | { |
michael@0 | 397 | nsIFrame* result = GetFirstChildInner(aFrame); |
michael@0 | 398 | if (mLockScroll && result && result->GetType() == nsGkAtoms::scrollFrame) |
michael@0 | 399 | return nullptr; |
michael@0 | 400 | if (result && mFollowOOFs) { |
michael@0 | 401 | result = nsPlaceholderFrame::GetRealFrameFor(result); |
michael@0 | 402 | |
michael@0 | 403 | if (IsPopupFrame(result)) |
michael@0 | 404 | result = GetNextSibling(result); |
michael@0 | 405 | } |
michael@0 | 406 | return result; |
michael@0 | 407 | } |
michael@0 | 408 | |
michael@0 | 409 | nsIFrame* |
michael@0 | 410 | nsFrameIterator::GetLastChild(nsIFrame* aFrame) |
michael@0 | 411 | { |
michael@0 | 412 | nsIFrame* result = GetLastChildInner(aFrame); |
michael@0 | 413 | if (mLockScroll && result && result->GetType() == nsGkAtoms::scrollFrame) |
michael@0 | 414 | return nullptr; |
michael@0 | 415 | if (result && mFollowOOFs) { |
michael@0 | 416 | result = nsPlaceholderFrame::GetRealFrameFor(result); |
michael@0 | 417 | |
michael@0 | 418 | if (IsPopupFrame(result)) |
michael@0 | 419 | result = GetPrevSibling(result); |
michael@0 | 420 | } |
michael@0 | 421 | return result; |
michael@0 | 422 | } |
michael@0 | 423 | |
michael@0 | 424 | nsIFrame* |
michael@0 | 425 | nsFrameIterator::GetNextSibling(nsIFrame* aFrame) |
michael@0 | 426 | { |
michael@0 | 427 | nsIFrame* result = nullptr; |
michael@0 | 428 | if (mFollowOOFs) |
michael@0 | 429 | aFrame = GetPlaceholderFrame(aFrame); |
michael@0 | 430 | if (aFrame) { |
michael@0 | 431 | result = GetNextSiblingInner(aFrame); |
michael@0 | 432 | if (result && mFollowOOFs) |
michael@0 | 433 | result = nsPlaceholderFrame::GetRealFrameFor(result); |
michael@0 | 434 | } |
michael@0 | 435 | |
michael@0 | 436 | if (mFollowOOFs && IsPopupFrame(result)) |
michael@0 | 437 | result = GetNextSibling(result); |
michael@0 | 438 | |
michael@0 | 439 | return result; |
michael@0 | 440 | } |
michael@0 | 441 | |
michael@0 | 442 | nsIFrame* |
michael@0 | 443 | nsFrameIterator::GetPrevSibling(nsIFrame* aFrame) |
michael@0 | 444 | { |
michael@0 | 445 | nsIFrame* result = nullptr; |
michael@0 | 446 | if (mFollowOOFs) |
michael@0 | 447 | aFrame = GetPlaceholderFrame(aFrame); |
michael@0 | 448 | if (aFrame) { |
michael@0 | 449 | result = GetPrevSiblingInner(aFrame); |
michael@0 | 450 | if (result && mFollowOOFs) |
michael@0 | 451 | result = nsPlaceholderFrame::GetRealFrameFor(result); |
michael@0 | 452 | } |
michael@0 | 453 | |
michael@0 | 454 | if (mFollowOOFs && IsPopupFrame(result)) |
michael@0 | 455 | result = GetPrevSibling(result); |
michael@0 | 456 | |
michael@0 | 457 | return result; |
michael@0 | 458 | } |
michael@0 | 459 | |
michael@0 | 460 | nsIFrame* |
michael@0 | 461 | nsFrameIterator::GetFirstChildInner(nsIFrame* aFrame) { |
michael@0 | 462 | return aFrame->GetFirstPrincipalChild(); |
michael@0 | 463 | } |
michael@0 | 464 | |
michael@0 | 465 | nsIFrame* |
michael@0 | 466 | nsFrameIterator::GetLastChildInner(nsIFrame* aFrame) { |
michael@0 | 467 | return aFrame->PrincipalChildList().LastChild(); |
michael@0 | 468 | } |
michael@0 | 469 | |
michael@0 | 470 | nsIFrame* |
michael@0 | 471 | nsFrameIterator::GetNextSiblingInner(nsIFrame* aFrame) { |
michael@0 | 472 | return aFrame->GetNextSibling(); |
michael@0 | 473 | } |
michael@0 | 474 | |
michael@0 | 475 | nsIFrame* |
michael@0 | 476 | nsFrameIterator::GetPrevSiblingInner(nsIFrame* aFrame) { |
michael@0 | 477 | return aFrame->GetPrevSibling(); |
michael@0 | 478 | } |
michael@0 | 479 | |
michael@0 | 480 | |
michael@0 | 481 | nsIFrame* |
michael@0 | 482 | nsFrameIterator::GetPlaceholderFrame(nsIFrame* aFrame) |
michael@0 | 483 | { |
michael@0 | 484 | nsIFrame* result = aFrame; |
michael@0 | 485 | nsIPresShell *presShell = mPresContext->GetPresShell(); |
michael@0 | 486 | if (presShell) { |
michael@0 | 487 | nsIFrame* placeholder = presShell->GetPlaceholderFrameFor(aFrame); |
michael@0 | 488 | if (placeholder) |
michael@0 | 489 | result = placeholder; |
michael@0 | 490 | } |
michael@0 | 491 | |
michael@0 | 492 | if (result != aFrame) |
michael@0 | 493 | result = GetPlaceholderFrame(result); |
michael@0 | 494 | |
michael@0 | 495 | return result; |
michael@0 | 496 | } |
michael@0 | 497 | |
michael@0 | 498 | bool |
michael@0 | 499 | nsFrameIterator::IsPopupFrame(nsIFrame* aFrame) |
michael@0 | 500 | { |
michael@0 | 501 | return (aFrame && |
michael@0 | 502 | aFrame->StyleDisplay()->mDisplay == NS_STYLE_DISPLAY_POPUP); |
michael@0 | 503 | } |
michael@0 | 504 | |
michael@0 | 505 | // nsVisualIterator implementation |
michael@0 | 506 | |
michael@0 | 507 | nsIFrame* |
michael@0 | 508 | nsVisualIterator::GetFirstChildInner(nsIFrame* aFrame) { |
michael@0 | 509 | return aFrame->PrincipalChildList().GetNextVisualFor(nullptr); |
michael@0 | 510 | } |
michael@0 | 511 | |
michael@0 | 512 | nsIFrame* |
michael@0 | 513 | nsVisualIterator::GetLastChildInner(nsIFrame* aFrame) { |
michael@0 | 514 | return aFrame->PrincipalChildList().GetPrevVisualFor(nullptr); |
michael@0 | 515 | } |
michael@0 | 516 | |
michael@0 | 517 | nsIFrame* |
michael@0 | 518 | nsVisualIterator::GetNextSiblingInner(nsIFrame* aFrame) { |
michael@0 | 519 | nsIFrame* parent = GetParentFrame(aFrame); |
michael@0 | 520 | if (!parent) |
michael@0 | 521 | return nullptr; |
michael@0 | 522 | return parent->PrincipalChildList().GetNextVisualFor(aFrame); |
michael@0 | 523 | } |
michael@0 | 524 | |
michael@0 | 525 | nsIFrame* |
michael@0 | 526 | nsVisualIterator::GetPrevSiblingInner(nsIFrame* aFrame) { |
michael@0 | 527 | nsIFrame* parent = GetParentFrame(aFrame); |
michael@0 | 528 | if (!parent) |
michael@0 | 529 | return nullptr; |
michael@0 | 530 | return parent->PrincipalChildList().GetPrevVisualFor(aFrame); |
michael@0 | 531 | } |