Handle state and attribute changes on elements without frames more efficiently, and keep the undisplayed map up to date. b=209733 r+sr=bzbarsky

This commit is contained in:
dbaron%dbaron.org 2003-06-18 21:54:51 +00:00
Родитель cf35fe243a
Коммит 2b59f901f7
7 изменённых файлов: 116 добавлений и 6 удалений

Просмотреть файл

@ -10377,10 +10377,10 @@ nsCSSFrameConstructor::ContentStatesChanged(nsIPresContext* aPresContext,
// no frames, reconstruct for content
if (!primaryFrame1 && aContent1) {
result = RecreateFramesForContent(aPresContext, aContent1);
result = MaybeRecreateFramesForContent(aPresContext, aContent1);
}
if (!primaryFrame2 && aContent2) {
result = RecreateFramesForContent(aPresContext, aContent2);
result = MaybeRecreateFramesForContent(aPresContext, aContent2);
}
}
}
@ -10546,7 +10546,7 @@ nsCSSFrameConstructor::AttributeChanged(nsIPresContext* aPresContext,
ProcessRestyledFrames(changeList, aPresContext);
}
else { // no frame now, possibly genetate one with new style data
result = RecreateFramesForContent(aPresContext, aContent);
result = MaybeRecreateFramesForContent(aPresContext, aContent);
}
}
@ -11784,6 +11784,30 @@ nsCSSFrameConstructor::CaptureStateFor(nsIPresContext* aPresContext,
return rv;
}
nsresult
nsCSSFrameConstructor::MaybeRecreateFramesForContent(nsIPresContext* aPresContext,
nsIContent* aContent)
{
nsresult result = NS_OK;
nsCOMPtr<nsIPresShell> shell;
aPresContext->GetShell(getter_AddRefs(shell));
nsCOMPtr<nsIFrameManager> frameManager;
shell->GetFrameManager(getter_AddRefs(frameManager));
nsStyleContext *oldContext = frameManager->GetUndisplayedContent(aContent);
if (oldContext) {
// The parent has a frame, so try resolving a new context.
nsRefPtr<nsStyleContext> newContext =
aPresContext->ResolveStyleContextFor(aContent,
oldContext->GetParent());
frameManager->ChangeUndisplayedContent(aContent, newContext);
if (newContext->GetStyleDisplay()->mDisplay != NS_STYLE_DISPLAY_NONE) {
result = RecreateFramesForContent(aPresContext, aContent);
}
}
return result;
}
nsresult
nsCSSFrameConstructor::RecreateFramesForContent(nsIPresContext* aPresContext,
nsIContent* aContent)

Просмотреть файл

@ -741,6 +741,9 @@ protected:
// cache the "nglayout.debug.enable_xbl_forms" pref
PRBool UseXBLForms();
nsresult MaybeRecreateFramesForContent(nsIPresContext* aPresContext,
nsIContent* aContent);
nsresult RecreateFramesForContent(nsIPresContext* aPresContext,
nsIContent* aContent);

Просмотреть файл

@ -304,6 +304,7 @@ public:
// Undisplayed content functions
virtual nsStyleContext* GetUndisplayedContent(nsIContent* aContent);
virtual void SetUndisplayedContent(nsIContent* aContent, nsStyleContext* aStyleContext);
virtual void ChangeUndisplayedContent(nsIContent* aContent, nsStyleContext* aStyleContext);
NS_IMETHOD ClearUndisplayedContentIn(nsIContent* aContent, nsIContent* aParentContent);
NS_IMETHOD ClearAllUndisplayedContentIn(nsIContent* aParentContent);
NS_IMETHOD ClearUndisplayedContentMap();
@ -861,6 +862,32 @@ FrameManager::SetUndisplayedContent(nsIContent* aContent,
}
}
void
FrameManager::ChangeUndisplayedContent(nsIContent* aContent,
nsStyleContext* aStyleContext)
{
if (!mPresShell)
return;
NS_ASSERTION(mUndisplayedMap, "no existing undisplayed content");
#ifdef DEBUG_UNDISPLAYED_MAP
static int i = 0;
printf("ChangeUndisplayedContent(%d): p=%p \n", i++, (void *)aContent);
#endif
nsCOMPtr<nsIContent> parent;
aContent->GetParent(getter_AddRefs(parent));
for (UndisplayedNode* node = mUndisplayedMap->GetFirstNode(parent);
node; node = node->mNext) {
if (node->mContent == aContent) {
node->mStyle = aStyleContext;
return;
}
}
NS_NOTREACHED("no existing undisplayed content");
}
NS_IMETHODIMP
FrameManager::ClearUndisplayedContentIn(nsIContent* aContent, nsIContent* aParentContent)
{

Просмотреть файл

@ -110,6 +110,8 @@ public:
virtual nsStyleContext* GetUndisplayedContent(nsIContent* aContent) = 0;
virtual void SetUndisplayedContent(nsIContent* aContent,
nsStyleContext* aStyleContext) = 0;
virtual void ChangeUndisplayedContent(nsIContent* aContent,
nsStyleContext* aStyleContext) = 0;
NS_IMETHOD ClearUndisplayedContentIn(nsIContent* aContent, nsIContent* aParentContent) = 0;
NS_IMETHOD ClearAllUndisplayedContentIn(nsIContent* aParentContent) = 0;
NS_IMETHOD ClearUndisplayedContentMap() = 0;

Просмотреть файл

@ -304,6 +304,7 @@ public:
// Undisplayed content functions
virtual nsStyleContext* GetUndisplayedContent(nsIContent* aContent);
virtual void SetUndisplayedContent(nsIContent* aContent, nsStyleContext* aStyleContext);
virtual void ChangeUndisplayedContent(nsIContent* aContent, nsStyleContext* aStyleContext);
NS_IMETHOD ClearUndisplayedContentIn(nsIContent* aContent, nsIContent* aParentContent);
NS_IMETHOD ClearAllUndisplayedContentIn(nsIContent* aParentContent);
NS_IMETHOD ClearUndisplayedContentMap();
@ -861,6 +862,32 @@ FrameManager::SetUndisplayedContent(nsIContent* aContent,
}
}
void
FrameManager::ChangeUndisplayedContent(nsIContent* aContent,
nsStyleContext* aStyleContext)
{
if (!mPresShell)
return;
NS_ASSERTION(mUndisplayedMap, "no existing undisplayed content");
#ifdef DEBUG_UNDISPLAYED_MAP
static int i = 0;
printf("ChangeUndisplayedContent(%d): p=%p \n", i++, (void *)aContent);
#endif
nsCOMPtr<nsIContent> parent;
aContent->GetParent(getter_AddRefs(parent));
for (UndisplayedNode* node = mUndisplayedMap->GetFirstNode(parent);
node; node = node->mNext) {
if (node->mContent == aContent) {
node->mStyle = aStyleContext;
return;
}
}
NS_NOTREACHED("no existing undisplayed content");
}
NS_IMETHODIMP
FrameManager::ClearUndisplayedContentIn(nsIContent* aContent, nsIContent* aParentContent)
{

Просмотреть файл

@ -10377,10 +10377,10 @@ nsCSSFrameConstructor::ContentStatesChanged(nsIPresContext* aPresContext,
// no frames, reconstruct for content
if (!primaryFrame1 && aContent1) {
result = RecreateFramesForContent(aPresContext, aContent1);
result = MaybeRecreateFramesForContent(aPresContext, aContent1);
}
if (!primaryFrame2 && aContent2) {
result = RecreateFramesForContent(aPresContext, aContent2);
result = MaybeRecreateFramesForContent(aPresContext, aContent2);
}
}
}
@ -10546,7 +10546,7 @@ nsCSSFrameConstructor::AttributeChanged(nsIPresContext* aPresContext,
ProcessRestyledFrames(changeList, aPresContext);
}
else { // no frame now, possibly genetate one with new style data
result = RecreateFramesForContent(aPresContext, aContent);
result = MaybeRecreateFramesForContent(aPresContext, aContent);
}
}
@ -11784,6 +11784,30 @@ nsCSSFrameConstructor::CaptureStateFor(nsIPresContext* aPresContext,
return rv;
}
nsresult
nsCSSFrameConstructor::MaybeRecreateFramesForContent(nsIPresContext* aPresContext,
nsIContent* aContent)
{
nsresult result = NS_OK;
nsCOMPtr<nsIPresShell> shell;
aPresContext->GetShell(getter_AddRefs(shell));
nsCOMPtr<nsIFrameManager> frameManager;
shell->GetFrameManager(getter_AddRefs(frameManager));
nsStyleContext *oldContext = frameManager->GetUndisplayedContent(aContent);
if (oldContext) {
// The parent has a frame, so try resolving a new context.
nsRefPtr<nsStyleContext> newContext =
aPresContext->ResolveStyleContextFor(aContent,
oldContext->GetParent());
frameManager->ChangeUndisplayedContent(aContent, newContext);
if (newContext->GetStyleDisplay()->mDisplay != NS_STYLE_DISPLAY_NONE) {
result = RecreateFramesForContent(aPresContext, aContent);
}
}
return result;
}
nsresult
nsCSSFrameConstructor::RecreateFramesForContent(nsIPresContext* aPresContext,
nsIContent* aContent)

Просмотреть файл

@ -741,6 +741,9 @@ protected:
// cache the "nglayout.debug.enable_xbl_forms" pref
PRBool UseXBLForms();
nsresult MaybeRecreateFramesForContent(nsIPresContext* aPresContext,
nsIContent* aContent);
nsresult RecreateFramesForContent(nsIPresContext* aPresContext,
nsIContent* aContent);