|
|
|
|
| 34 |
#include "ChildIterator.h" |
34 |
#include "ChildIterator.h" |
| 35 |
|
35 |
|
| 36 |
#include "nsFrameManager.h" |
36 |
#include "nsFrameManager.h" |
| 37 |
#include "GeckoProfiler.h" |
37 |
#include "GeckoProfiler.h" |
| 38 |
#include "nsIStatefulFrame.h" |
38 |
#include "nsIStatefulFrame.h" |
| 39 |
|
39 |
|
| 40 |
#ifdef DEBUG |
40 |
#ifdef DEBUG |
| 41 |
//#define DEBUG_UNDISPLAYED_MAP |
41 |
//#define DEBUG_UNDISPLAYED_MAP |
|
|
42 |
//#define DEBUG_DISPLAYCONTENTS_MAP |
| 42 |
#else |
43 |
#else |
| 43 |
#undef DEBUG_UNDISPLAYED_MAP |
44 |
#undef DEBUG_UNDISPLAYED_MAP |
|
|
45 |
#undef DEBUG_DISPLAYCONTENTS_MAP |
| 44 |
#endif |
46 |
#endif |
| 45 |
|
47 |
|
| 46 |
using namespace mozilla; |
48 |
using namespace mozilla; |
| 47 |
using namespace mozilla::dom; |
49 |
using namespace mozilla::dom; |
| 48 |
|
50 |
|
| 49 |
//---------------------------------------------------------------------- |
51 |
//---------------------------------------------------------------------- |
| 50 |
|
52 |
|
| 51 |
struct PlaceholderMapEntry : public PLDHashEntryHdr { |
53 |
struct PlaceholderMapEntry : public PLDHashEntryHdr { |
|
|
| 90 |
|
92 |
|
| 91 |
NS_HIDDEN_(nsresult) AddNodeFor(nsIContent* aParentContent, |
93 |
NS_HIDDEN_(nsresult) AddNodeFor(nsIContent* aParentContent, |
| 92 |
nsIContent* aChild, nsStyleContext* aStyle); |
94 |
nsIContent* aChild, nsStyleContext* aStyle); |
| 93 |
|
95 |
|
| 94 |
NS_HIDDEN_(void) RemoveNodeFor(nsIContent* aParentContent, |
96 |
NS_HIDDEN_(void) RemoveNodeFor(nsIContent* aParentContent, |
| 95 |
UndisplayedNode* aNode); |
97 |
UndisplayedNode* aNode); |
| 96 |
|
98 |
|
| 97 |
NS_HIDDEN_(void) RemoveNodesFor(nsIContent* aParentContent); |
99 |
NS_HIDDEN_(void) RemoveNodesFor(nsIContent* aParentContent); |
|
|
100 |
NS_HIDDEN_(UndisplayedNode*) UnlinkNodesFor(nsIContent* aParentContent); |
| 98 |
|
101 |
|
| 99 |
// Removes all entries from the hash table |
102 |
// Removes all entries from the hash table |
| 100 |
NS_HIDDEN_(void) Clear(void); |
103 |
NS_HIDDEN_(void) Clear(void); |
| 101 |
|
104 |
|
| 102 |
protected: |
105 |
protected: |
| 103 |
/** |
106 |
/** |
| 104 |
* Gets the entry for the provided parent content. If the content |
107 |
* Gets the entry for the provided parent content. If the content |
| 105 |
* is a <xbl:children> element, |**aParentContent| is set to |
108 |
* is a <xbl:children> element, |**aParentContent| is set to |
|
Lines 133-148
nsFrameManager::Destroy()
|
Link Here
|
|---|
|
| 133 |
|
136 |
|
| 134 |
if (mRootFrame) { |
137 |
if (mRootFrame) { |
| 135 |
mRootFrame->Destroy(); |
138 |
mRootFrame->Destroy(); |
| 136 |
mRootFrame = nullptr; |
139 |
mRootFrame = nullptr; |
| 137 |
} |
140 |
} |
| 138 |
|
141 |
|
| 139 |
delete mUndisplayedMap; |
142 |
delete mUndisplayedMap; |
| 140 |
mUndisplayedMap = nullptr; |
143 |
mUndisplayedMap = nullptr; |
|
|
144 |
delete mDisplayContentsMap; |
| 145 |
mDisplayContentsMap = nullptr; |
| 141 |
|
146 |
|
| 142 |
mPresShell = nullptr; |
147 |
mPresShell = nullptr; |
| 143 |
} |
148 |
} |
| 144 |
|
149 |
|
| 145 |
//---------------------------------------------------------------------- |
150 |
//---------------------------------------------------------------------- |
| 146 |
|
151 |
|
| 147 |
// Placeholder frame functions |
152 |
// Placeholder frame functions |
| 148 |
nsPlaceholderFrame* |
153 |
nsPlaceholderFrame* |
|
Lines 318-333
nsFrameManager::ClearUndisplayedContentI
|
Link Here
|
|---|
|
| 318 |
nsStyleContext *context = GetUndisplayedContent(aContent); |
323 |
nsStyleContext *context = GetUndisplayedContent(aContent); |
| 319 |
NS_ASSERTION(context == nullptr, "Found more undisplayed content data after removal"); |
324 |
NS_ASSERTION(context == nullptr, "Found more undisplayed content data after removal"); |
| 320 |
#endif |
325 |
#endif |
| 321 |
return; |
326 |
return; |
| 322 |
} |
327 |
} |
| 323 |
node = node->mNext; |
328 |
node = node->mNext; |
| 324 |
} |
329 |
} |
| 325 |
} |
330 |
} |
|
|
331 |
#ifdef DEBUG_UNDISPLAYED_MAP |
| 332 |
printf( "not found.\n"); |
| 333 |
#endif |
| 326 |
} |
334 |
} |
| 327 |
|
335 |
|
| 328 |
void |
336 |
void |
| 329 |
nsFrameManager::ClearAllUndisplayedContentIn(nsIContent* aParentContent) |
337 |
nsFrameManager::ClearAllUndisplayedContentIn(nsIContent* aParentContent) |
| 330 |
{ |
338 |
{ |
| 331 |
#ifdef DEBUG_UNDISPLAYED_MAP |
339 |
#ifdef DEBUG_UNDISPLAYED_MAP |
| 332 |
static int i = 0; |
340 |
static int i = 0; |
| 333 |
printf("ClearAllUndisplayedContentIn(%d): parent=%p \n", i++, (void*)aParentContent); |
341 |
printf("ClearAllUndisplayedContentIn(%d): parent=%p \n", i++, (void*)aParentContent); |
|
Lines 345-360
nsFrameManager::ClearAllUndisplayedConte
|
Link Here
|
|---|
|
| 345 |
for (nsIContent* child = iter.GetNextChild(); child; child = iter.GetNextChild()) { |
353 |
for (nsIContent* child = iter.GetNextChild(); child; child = iter.GetNextChild()) { |
| 346 |
if (child->GetParent() != aParentContent) { |
354 |
if (child->GetParent() != aParentContent) { |
| 347 |
ClearUndisplayedContentIn(child, child->GetParent()); |
355 |
ClearUndisplayedContentIn(child, child->GetParent()); |
| 348 |
} |
356 |
} |
| 349 |
} |
357 |
} |
| 350 |
} |
358 |
} |
| 351 |
|
359 |
|
| 352 |
//---------------------------------------------------------------------- |
360 |
//---------------------------------------------------------------------- |
|
|
361 |
|
| 362 |
nsStyleContext* |
| 363 |
nsFrameManager::GetDisplayContents(nsIContent* aContent) |
| 364 |
{ |
| 365 |
if (!aContent || !mDisplayContentsMap) { |
| 366 |
return nullptr; |
| 367 |
} |
| 368 |
nsIContent* parent = aContent->GetParent(); |
| 369 |
for (UndisplayedNode* node = mDisplayContentsMap->GetFirstNode(parent); |
| 370 |
node; node = node->mNext) { |
| 371 |
if (node->mContent == aContent) { |
| 372 |
return node->mStyle; |
| 373 |
} |
| 374 |
} |
| 375 |
return nullptr; |
| 376 |
} |
| 377 |
|
| 378 |
UndisplayedNode* |
| 379 |
nsFrameManager::GetAllDisplayContentsIn(nsIContent* aParentContent) |
| 380 |
{ |
| 381 |
return mDisplayContentsMap ? mDisplayContentsMap->GetFirstNode(aParentContent) |
| 382 |
: nullptr; |
| 383 |
} |
| 384 |
|
| 385 |
void |
| 386 |
nsFrameManager::SetDisplayContents(nsIContent* aContent, |
| 387 |
nsStyleContext* aStyleContext) |
| 388 |
{ |
| 389 |
NS_PRECONDITION(!aStyleContext->GetPseudo(), |
| 390 |
"Should only have actual elements here"); |
| 391 |
|
| 392 |
#ifdef DEBUG_DISPLAYCONTENTS_MAP |
| 393 |
static int i = 0; |
| 394 |
printf("SetDisplayContents(%d): aContent=%p \n", i++, (void *)aContent); |
| 395 |
#endif |
| 396 |
|
| 397 |
NS_ASSERTION(!GetDisplayContents(aContent), |
| 398 |
"Already have an undisplayed context entry for aContent"); |
| 399 |
|
| 400 |
if (!mDisplayContentsMap) { |
| 401 |
mDisplayContentsMap = new UndisplayedMap; |
| 402 |
} |
| 403 |
nsIContent* parent = aContent->GetParent(); |
| 404 |
NS_ASSERTION(parent || (mPresShell && mPresShell->GetDocument() && |
| 405 |
mPresShell->GetDocument()->GetRootElement() == aContent), |
| 406 |
"undisplayed content must have a parent, unless it's the root " |
| 407 |
"element"); |
| 408 |
mDisplayContentsMap->AddNodeFor(parent, aContent, aStyleContext); |
| 409 |
} |
| 410 |
|
| 411 |
void |
| 412 |
nsFrameManager::ChangeDisplayContents(nsIContent* aContent, |
| 413 |
nsStyleContext* aStyleContext) |
| 414 |
{ |
| 415 |
NS_ASSERTION(mDisplayContentsMap, "no existing display:contents content"); |
| 416 |
|
| 417 |
#ifdef DEBUG_DISPLAYCONTENTS_MAP |
| 418 |
static int i = 0; |
| 419 |
printf("ChangeDisplayContents(%d): aContent=%p \n", i++, (void *)aContent); |
| 420 |
#endif |
| 421 |
|
| 422 |
for (UndisplayedNode* node = mDisplayContentsMap->GetFirstNode(aContent->GetParent()); |
| 423 |
node; node = node->mNext) { |
| 424 |
if (node->mContent == aContent) { |
| 425 |
node->mStyle = aStyleContext; |
| 426 |
return; |
| 427 |
} |
| 428 |
} |
| 429 |
|
| 430 |
NS_NOTREACHED("no existing display:contents content"); |
| 431 |
} |
| 432 |
|
| 433 |
void |
| 434 |
nsFrameManager::ClearDisplayContentsIn(nsIContent* aContent, |
| 435 |
nsIContent* aParentContent) |
| 436 |
{ |
| 437 |
#ifdef DEBUG_DISPLAYCONTENTS_MAP |
| 438 |
static int i = 0; |
| 439 |
printf("ClearDisplayContents(%d): content=%p parent=%p --> ", i++, (void *)aContent, (void*)aParentContent); |
| 440 |
#endif |
| 441 |
|
| 442 |
if (mDisplayContentsMap) { |
| 443 |
UndisplayedNode* node = mDisplayContentsMap->GetFirstNode(aParentContent); |
| 444 |
while (node) { |
| 445 |
if (node->mContent == aContent) { |
| 446 |
mDisplayContentsMap->RemoveNodeFor(aParentContent, node); |
| 447 |
|
| 448 |
#ifdef DEBUG_DISPLAYCONTENTS_MAP |
| 449 |
printf( "REMOVED!\n"); |
| 450 |
#endif |
| 451 |
#ifdef DEBUG |
| 452 |
// make sure that there are no more entries for the same content |
| 453 |
nsStyleContext* context = GetDisplayContents(aContent); |
| 454 |
NS_ASSERTION(context == nullptr, "Found more entries for aContent after removal"); |
| 455 |
#endif |
| 456 |
ClearAllDisplayContentsIn(aContent); |
| 457 |
ClearAllUndisplayedContentIn(aContent); |
| 458 |
return; |
| 459 |
} |
| 460 |
node = node->mNext; |
| 461 |
} |
| 462 |
} |
| 463 |
#ifdef DEBUG_DISPLAYCONTENTS_MAP |
| 464 |
printf( "not found.\n"); |
| 465 |
#endif |
| 466 |
} |
| 467 |
|
| 468 |
void |
| 469 |
nsFrameManager::ClearAllDisplayContentsIn(nsIContent* aParentContent) |
| 470 |
{ |
| 471 |
#ifdef DEBUG_DISPLAYCONTENTS_MAP |
| 472 |
static int i = 0; |
| 473 |
printf("ClearAllDisplayContentsIn(%d): parent=%p \n", i++, (void*)aParentContent); |
| 474 |
#endif |
| 475 |
|
| 476 |
if (mDisplayContentsMap) { |
| 477 |
UndisplayedNode* cur = mDisplayContentsMap->UnlinkNodesFor(aParentContent); |
| 478 |
while (cur) { |
| 479 |
UndisplayedNode* next = cur->mNext; |
| 480 |
cur->mNext = nullptr; |
| 481 |
ClearAllDisplayContentsIn(cur->mContent); |
| 482 |
ClearAllUndisplayedContentIn(cur->mContent); |
| 483 |
delete cur; |
| 484 |
cur = next; |
| 485 |
} |
| 486 |
} |
| 487 |
|
| 488 |
// Need to look at aParentContent's content list due to XBL insertions. |
| 489 |
// Nodes in aParentContent's content list do not have aParentContent as a |
| 490 |
// parent, but are treated as children of aParentContent. We iterate over |
| 491 |
// the flattened content list and just ignore any nodes we don't care about. |
| 492 |
FlattenedChildIterator iter(aParentContent); |
| 493 |
for (nsIContent* child = iter.GetNextChild(); child; child = iter.GetNextChild()) { |
| 494 |
if (child->GetParent() != aParentContent) { |
| 495 |
ClearDisplayContentsIn(child, child->GetParent()); |
| 496 |
ClearUndisplayedContentIn(child, child->GetParent()); |
| 497 |
} |
| 498 |
} |
| 499 |
} |
| 500 |
|
| 501 |
//---------------------------------------------------------------------- |
| 353 |
nsresult |
502 |
nsresult |
| 354 |
nsFrameManager::AppendFrames(nsIFrame* aParentFrame, |
503 |
nsFrameManager::AppendFrames(nsIFrame* aParentFrame, |
| 355 |
ChildListID aListID, |
504 |
ChildListID aListID, |
| 356 |
nsFrameList& aFrameList) |
505 |
nsFrameList& aFrameList) |
| 357 |
{ |
506 |
{ |
| 358 |
if (aParentFrame->IsAbsoluteContainer() && |
507 |
if (aParentFrame->IsAbsoluteContainer() && |
| 359 |
aListID == aParentFrame->GetAbsoluteListID()) { |
508 |
aListID == aParentFrame->GetAbsoluteListID()) { |
| 360 |
return aParentFrame->GetAbsoluteContainingBlock()-> |
509 |
return aParentFrame->GetAbsoluteContainingBlock()-> |
|
Lines 424-439
nsFrameManager::RemoveFrame(ChildListID
|
Link Here
|
|---|
|
| 424 |
//---------------------------------------------------------------------- |
573 |
//---------------------------------------------------------------------- |
| 425 |
|
574 |
|
| 426 |
void |
575 |
void |
| 427 |
nsFrameManager::NotifyDestroyingFrame(nsIFrame* aFrame) |
576 |
nsFrameManager::NotifyDestroyingFrame(nsIFrame* aFrame) |
| 428 |
{ |
577 |
{ |
| 429 |
nsIContent* content = aFrame->GetContent(); |
578 |
nsIContent* content = aFrame->GetContent(); |
| 430 |
if (content && content->GetPrimaryFrame() == aFrame) { |
579 |
if (content && content->GetPrimaryFrame() == aFrame) { |
| 431 |
ClearAllUndisplayedContentIn(content); |
580 |
ClearAllUndisplayedContentIn(content); |
|
|
581 |
ClearAllDisplayContentsIn(content); |
| 432 |
} |
582 |
} |
| 433 |
} |
583 |
} |
| 434 |
|
584 |
|
| 435 |
// Capture state for a given frame. |
585 |
// Capture state for a given frame. |
| 436 |
// Accept a content id here, in some cases we may not have content (scroll position) |
586 |
// Accept a content id here, in some cases we may not have content (scroll position) |
| 437 |
void |
587 |
void |
| 438 |
nsFrameManager::CaptureFrameStateFor(nsIFrame* aFrame, |
588 |
nsFrameManager::CaptureFrameStateFor(nsIFrame* aFrame, |
| 439 |
nsILayoutHistoryState* aState) |
589 |
nsILayoutHistoryState* aState) |
|
Lines 700-727
nsFrameManagerBase::UndisplayedMap::Remo
|
Link Here
|
|---|
|
| 700 |
} |
850 |
} |
| 701 |
node = node->mNext; |
851 |
node = node->mNext; |
| 702 |
} |
852 |
} |
| 703 |
} |
853 |
} |
| 704 |
} |
854 |
} |
| 705 |
delete aNode; |
855 |
delete aNode; |
| 706 |
} |
856 |
} |
| 707 |
|
857 |
|
| 708 |
void |
858 |
|
| 709 |
nsFrameManagerBase::UndisplayedMap::RemoveNodesFor(nsIContent* aParentContent) |
859 |
UndisplayedNode* |
|
|
860 |
nsFrameManagerBase::UndisplayedMap::UnlinkNodesFor(nsIContent* aParentContent) |
| 710 |
{ |
861 |
{ |
| 711 |
PLHashEntry** entry = GetEntryFor(&aParentContent); |
862 |
PLHashEntry** entry = GetEntryFor(&aParentContent); |
| 712 |
NS_ASSERTION(entry, "content not in map"); |
863 |
NS_ASSERTION(entry, "content not in map"); |
| 713 |
if (*entry) { |
864 |
if (*entry) { |
| 714 |
UndisplayedNode* node = (UndisplayedNode*)((*entry)->value); |
865 |
UndisplayedNode* node = (UndisplayedNode*)((*entry)->value); |
| 715 |
NS_ASSERTION(node, "null node for non-null entry in UndisplayedMap"); |
866 |
NS_ASSERTION(node, "null node for non-null entry in UndisplayedMap"); |
| 716 |
delete node; |
|
|
| 717 |
PL_HashTableRawRemove(mTable, entry, *entry); |
867 |
PL_HashTableRawRemove(mTable, entry, *entry); |
| 718 |
mLastLookup = nullptr; // hashtable may have shifted bucket out from under us |
868 |
mLastLookup = nullptr; // hashtable may have shifted bucket out from under us |
|
|
869 |
return node; |
| 719 |
} |
870 |
} |
|
|
871 |
return nullptr; |
| 872 |
} |
| 873 |
|
| 874 |
void |
| 875 |
nsFrameManagerBase::UndisplayedMap::RemoveNodesFor(nsIContent* aParentContent) |
| 876 |
{ |
| 877 |
delete UnlinkNodesFor(aParentContent); |
| 720 |
} |
878 |
} |
| 721 |
|
879 |
|
| 722 |
static int |
880 |
static int |
| 723 |
RemoveUndisplayedEntry(PLHashEntry* he, int i, void* arg) |
881 |
RemoveUndisplayedEntry(PLHashEntry* he, int i, void* arg) |
| 724 |
{ |
882 |
{ |
| 725 |
UndisplayedNode* node = (UndisplayedNode*)(he->value); |
883 |
UndisplayedNode* node = (UndisplayedNode*)(he->value); |
| 726 |
delete node; |
884 |
delete node; |
| 727 |
// Remove and free this entry and continue enumerating |
885 |
// Remove and free this entry and continue enumerating |