зеркало из https://github.com/mozilla/pjs.git
Make ProbePseudoStyleFor return null whenever :before and :after aren't displayed so that we don't try to reframe constantly in certain cases, preventing link clicking from working. b=188525 r+sr=bzbarsky
This commit is contained in:
Родитель
e2875e8fee
Коммит
1d38d9f953
|
@ -50,6 +50,7 @@
|
|||
#include "nsIDocument.h"
|
||||
#include "nsIStyleFrameConstruction.h"
|
||||
#include "nsCSSAnonBoxes.h"
|
||||
#include "nsCSSPseudoElements.h"
|
||||
#include "nsTimer.h"
|
||||
#include "nsICSSStyleSheet.h"
|
||||
#include "nsNetUtil.h"
|
||||
|
@ -1326,6 +1327,24 @@ StyleSetImpl::ProbePseudoStyleFor(nsIPresContext* aPresContext,
|
|||
mRuleWalker->Reset();
|
||||
}
|
||||
}
|
||||
|
||||
// For :before and :after pseudo-elements, having display: none or no
|
||||
// 'content' property is equivalent to not having the pseudo-element
|
||||
// at all.
|
||||
if (result &&
|
||||
(aPseudoTag == nsCSSPseudoElements::before ||
|
||||
aPseudoTag == nsCSSPseudoElements::after)) {
|
||||
const nsStyleDisplay *display;
|
||||
const nsStyleContent *content;
|
||||
::GetStyleData(result, &display);
|
||||
::GetStyleData(result, &content);
|
||||
// XXXldb What is contentCount for |content: ""|?
|
||||
if (display->mDisplay == NS_STYLE_DISPLAY_NONE ||
|
||||
content->ContentCount() == 0) {
|
||||
result->Release();
|
||||
result = nsnull;
|
||||
}
|
||||
}
|
||||
|
||||
MOZ_TIMER_DEBUGLOG(("Stop: StyleSetImpl::ProbePseudoStyleFor(), this=%p\n", this));
|
||||
STYLESET_STOP_TIMER(NS_TIMER_STYLE_RESOLUTION);
|
||||
|
|
|
@ -1586,94 +1586,86 @@ nsCSSFrameConstructor::CreateGeneratedContentFrame(nsIPresShell* aPresShe
|
|||
aStyleContext);
|
||||
|
||||
if (pseudoStyleContext) {
|
||||
const nsStyleDisplay* display;
|
||||
|
||||
// See whether the generated content should be displayed.
|
||||
display = (const nsStyleDisplay*)pseudoStyleContext->GetStyleData(eStyleStruct_Display);
|
||||
|
||||
if (NS_STYLE_DISPLAY_NONE != display->mDisplay) {
|
||||
// See if there was any content specified
|
||||
const nsStyleContent* styleContent =
|
||||
(const nsStyleContent*)pseudoStyleContext->GetStyleData(eStyleStruct_Content);
|
||||
PRUint32 contentCount = styleContent->ContentCount();
|
||||
|
||||
// XXXldb What is contentCount for |content: ""|?
|
||||
if (contentCount > 0) {
|
||||
if (aWrapperFrame) {
|
||||
if (!*aWrapperFrame) {
|
||||
const nsStyleDisplay *display;
|
||||
::GetStyleData(aStyleContext, &display);
|
||||
nsIAtom *wrapperPseudo;
|
||||
if (display->IsBlockLevel()) {
|
||||
NS_NewBlockFrame(aPresShell, aWrapperFrame);
|
||||
wrapperPseudo = nsCSSAnonBoxes::mozGCWrapperBlock;
|
||||
} else {
|
||||
NS_NewInlineFrame(aPresShell, aWrapperFrame);
|
||||
wrapperPseudo = nsCSSAnonBoxes::mozGCWrapperInline;
|
||||
}
|
||||
nsStyleContext* parentSC = aStyleContext->GetParent();
|
||||
nsRefPtr<nsStyleContext> wrapperSC;
|
||||
wrapperSC = aPresContext->ResolvePseudoStyleContextFor(nsnull,
|
||||
wrapperPseudo,
|
||||
parentSC);
|
||||
// |aFrame| is already the correct parent.
|
||||
InitAndRestoreFrame(aPresContext, aState, aContent, aFrame,
|
||||
wrapperSC, nsnull, *aWrapperFrame);
|
||||
}
|
||||
// Use the wrapper as the parent.
|
||||
aFrame = *aWrapperFrame;
|
||||
}
|
||||
// Create a block box or an inline box depending on the value of
|
||||
// the 'display' property
|
||||
nsIFrame* containerFrame;
|
||||
nsFrameItems childFrames;
|
||||
|
||||
if (NS_STYLE_DISPLAY_BLOCK == display->mDisplay) {
|
||||
NS_NewBlockFrame(aPresShell, &containerFrame);
|
||||
// |ProbePseudoStyleContext| checks the 'display' property and the
|
||||
// |ContentCount()| of the 'content' property for us.
|
||||
if (aWrapperFrame) {
|
||||
if (!*aWrapperFrame) {
|
||||
const nsStyleDisplay *display;
|
||||
::GetStyleData(aStyleContext, &display);
|
||||
nsIAtom *wrapperPseudo;
|
||||
if (display->IsBlockLevel()) {
|
||||
NS_NewBlockFrame(aPresShell, aWrapperFrame);
|
||||
wrapperPseudo = nsCSSAnonBoxes::mozGCWrapperBlock;
|
||||
} else {
|
||||
NS_NewInlineFrame(aPresShell, &containerFrame);
|
||||
NS_NewInlineFrame(aPresShell, aWrapperFrame);
|
||||
wrapperPseudo = nsCSSAnonBoxes::mozGCWrapperInline;
|
||||
}
|
||||
InitAndRestoreFrame(aPresContext, aState, aContent,
|
||||
aFrame, pseudoStyleContext, nsnull, containerFrame);
|
||||
nsHTMLContainerFrame::CreateViewForFrame(aPresContext, containerFrame,
|
||||
pseudoStyleContext, nsnull, PR_FALSE);
|
||||
nsStyleContext* parentSC = aStyleContext->GetParent();
|
||||
nsRefPtr<nsStyleContext> wrapperSC;
|
||||
wrapperSC = aPresContext->ResolvePseudoStyleContextFor(nsnull,
|
||||
wrapperPseudo,
|
||||
parentSC);
|
||||
// |aFrame| is already the correct parent.
|
||||
InitAndRestoreFrame(aPresContext, aState, aContent, aFrame,
|
||||
wrapperSC, nsnull, *aWrapperFrame);
|
||||
}
|
||||
// Use the wrapper as the parent.
|
||||
aFrame = *aWrapperFrame;
|
||||
}
|
||||
// Create a block box or an inline box depending on the value of
|
||||
// the 'display' property
|
||||
nsIFrame* containerFrame;
|
||||
nsFrameItems childFrames;
|
||||
|
||||
// Mark the frame as being associated with generated content
|
||||
nsFrameState frameState;
|
||||
containerFrame->GetFrameState(&frameState);
|
||||
frameState |= NS_FRAME_GENERATED_CONTENT;
|
||||
containerFrame->SetFrameState(frameState);
|
||||
const nsStyleDisplay *display;
|
||||
::GetStyleData(pseudoStyleContext.get(), &display);
|
||||
if (NS_STYLE_DISPLAY_BLOCK == display->mDisplay) {
|
||||
NS_NewBlockFrame(aPresShell, &containerFrame);
|
||||
} else {
|
||||
NS_NewInlineFrame(aPresShell, &containerFrame);
|
||||
}
|
||||
InitAndRestoreFrame(aPresContext, aState, aContent,
|
||||
aFrame, pseudoStyleContext, nsnull, containerFrame);
|
||||
nsHTMLContainerFrame::CreateViewForFrame(aPresContext, containerFrame,
|
||||
pseudoStyleContext, nsnull, PR_FALSE);
|
||||
|
||||
// Create another pseudo style context to use for all the generated child
|
||||
// frames
|
||||
nsRefPtr<nsStyleContext> textStyleContext;
|
||||
textStyleContext = aPresContext->ResolveStyleContextForNonElement(pseudoStyleContext);
|
||||
// Mark the frame as being associated with generated content
|
||||
nsFrameState frameState;
|
||||
containerFrame->GetFrameState(&frameState);
|
||||
frameState |= NS_FRAME_GENERATED_CONTENT;
|
||||
containerFrame->SetFrameState(frameState);
|
||||
|
||||
// Now create content objects (and child frames) for each value of the
|
||||
// 'content' property
|
||||
// Create another pseudo style context to use for all the generated child
|
||||
// frames
|
||||
nsRefPtr<nsStyleContext> textStyleContext;
|
||||
textStyleContext = aPresContext->ResolveStyleContextForNonElement(pseudoStyleContext);
|
||||
|
||||
for (PRUint32 contentIndex = 0; contentIndex < contentCount; contentIndex++) {
|
||||
nsIFrame* frame;
|
||||
// Now create content objects (and child frames) for each value of the
|
||||
// 'content' property
|
||||
|
||||
// Create a frame
|
||||
nsresult result;
|
||||
result = CreateGeneratedFrameFor(aPresContext, mDocument, containerFrame,
|
||||
aContent, textStyleContext,
|
||||
styleContent, contentIndex, &frame);
|
||||
// Non-elements can't possibly have a view, so don't bother checking
|
||||
if (NS_SUCCEEDED(result) && frame) {
|
||||
// Add it to the list of child frames
|
||||
childFrames.AddChild(frame);
|
||||
}
|
||||
}
|
||||
|
||||
if (childFrames.childList) {
|
||||
containerFrame->SetInitialChildList(aPresContext, nsnull, childFrames.childList);
|
||||
}
|
||||
*aResult = containerFrame;
|
||||
return PR_TRUE;
|
||||
const nsStyleContent *styleContent;
|
||||
::GetStyleData(pseudoStyleContext.get(), &styleContent);
|
||||
PRUint32 contentCount = styleContent->ContentCount();
|
||||
for (PRUint32 contentIndex = 0; contentIndex < contentCount; contentIndex++) {
|
||||
nsIFrame* frame;
|
||||
|
||||
// Create a frame
|
||||
nsresult result;
|
||||
result = CreateGeneratedFrameFor(aPresContext, mDocument, containerFrame,
|
||||
aContent, textStyleContext,
|
||||
styleContent, contentIndex, &frame);
|
||||
// Non-elements can't possibly have a view, so don't bother checking
|
||||
if (NS_SUCCEEDED(result) && frame) {
|
||||
// Add it to the list of child frames
|
||||
childFrames.AddChild(frame);
|
||||
}
|
||||
}
|
||||
|
||||
if (childFrames.childList) {
|
||||
containerFrame->SetInitialChildList(aPresContext, nsnull, childFrames.childList);
|
||||
}
|
||||
*aResult = containerFrame;
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
return PR_FALSE;
|
||||
|
|
|
@ -1586,94 +1586,86 @@ nsCSSFrameConstructor::CreateGeneratedContentFrame(nsIPresShell* aPresShe
|
|||
aStyleContext);
|
||||
|
||||
if (pseudoStyleContext) {
|
||||
const nsStyleDisplay* display;
|
||||
|
||||
// See whether the generated content should be displayed.
|
||||
display = (const nsStyleDisplay*)pseudoStyleContext->GetStyleData(eStyleStruct_Display);
|
||||
|
||||
if (NS_STYLE_DISPLAY_NONE != display->mDisplay) {
|
||||
// See if there was any content specified
|
||||
const nsStyleContent* styleContent =
|
||||
(const nsStyleContent*)pseudoStyleContext->GetStyleData(eStyleStruct_Content);
|
||||
PRUint32 contentCount = styleContent->ContentCount();
|
||||
|
||||
// XXXldb What is contentCount for |content: ""|?
|
||||
if (contentCount > 0) {
|
||||
if (aWrapperFrame) {
|
||||
if (!*aWrapperFrame) {
|
||||
const nsStyleDisplay *display;
|
||||
::GetStyleData(aStyleContext, &display);
|
||||
nsIAtom *wrapperPseudo;
|
||||
if (display->IsBlockLevel()) {
|
||||
NS_NewBlockFrame(aPresShell, aWrapperFrame);
|
||||
wrapperPseudo = nsCSSAnonBoxes::mozGCWrapperBlock;
|
||||
} else {
|
||||
NS_NewInlineFrame(aPresShell, aWrapperFrame);
|
||||
wrapperPseudo = nsCSSAnonBoxes::mozGCWrapperInline;
|
||||
}
|
||||
nsStyleContext* parentSC = aStyleContext->GetParent();
|
||||
nsRefPtr<nsStyleContext> wrapperSC;
|
||||
wrapperSC = aPresContext->ResolvePseudoStyleContextFor(nsnull,
|
||||
wrapperPseudo,
|
||||
parentSC);
|
||||
// |aFrame| is already the correct parent.
|
||||
InitAndRestoreFrame(aPresContext, aState, aContent, aFrame,
|
||||
wrapperSC, nsnull, *aWrapperFrame);
|
||||
}
|
||||
// Use the wrapper as the parent.
|
||||
aFrame = *aWrapperFrame;
|
||||
}
|
||||
// Create a block box or an inline box depending on the value of
|
||||
// the 'display' property
|
||||
nsIFrame* containerFrame;
|
||||
nsFrameItems childFrames;
|
||||
|
||||
if (NS_STYLE_DISPLAY_BLOCK == display->mDisplay) {
|
||||
NS_NewBlockFrame(aPresShell, &containerFrame);
|
||||
// |ProbePseudoStyleContext| checks the 'display' property and the
|
||||
// |ContentCount()| of the 'content' property for us.
|
||||
if (aWrapperFrame) {
|
||||
if (!*aWrapperFrame) {
|
||||
const nsStyleDisplay *display;
|
||||
::GetStyleData(aStyleContext, &display);
|
||||
nsIAtom *wrapperPseudo;
|
||||
if (display->IsBlockLevel()) {
|
||||
NS_NewBlockFrame(aPresShell, aWrapperFrame);
|
||||
wrapperPseudo = nsCSSAnonBoxes::mozGCWrapperBlock;
|
||||
} else {
|
||||
NS_NewInlineFrame(aPresShell, &containerFrame);
|
||||
NS_NewInlineFrame(aPresShell, aWrapperFrame);
|
||||
wrapperPseudo = nsCSSAnonBoxes::mozGCWrapperInline;
|
||||
}
|
||||
InitAndRestoreFrame(aPresContext, aState, aContent,
|
||||
aFrame, pseudoStyleContext, nsnull, containerFrame);
|
||||
nsHTMLContainerFrame::CreateViewForFrame(aPresContext, containerFrame,
|
||||
pseudoStyleContext, nsnull, PR_FALSE);
|
||||
nsStyleContext* parentSC = aStyleContext->GetParent();
|
||||
nsRefPtr<nsStyleContext> wrapperSC;
|
||||
wrapperSC = aPresContext->ResolvePseudoStyleContextFor(nsnull,
|
||||
wrapperPseudo,
|
||||
parentSC);
|
||||
// |aFrame| is already the correct parent.
|
||||
InitAndRestoreFrame(aPresContext, aState, aContent, aFrame,
|
||||
wrapperSC, nsnull, *aWrapperFrame);
|
||||
}
|
||||
// Use the wrapper as the parent.
|
||||
aFrame = *aWrapperFrame;
|
||||
}
|
||||
// Create a block box or an inline box depending on the value of
|
||||
// the 'display' property
|
||||
nsIFrame* containerFrame;
|
||||
nsFrameItems childFrames;
|
||||
|
||||
// Mark the frame as being associated with generated content
|
||||
nsFrameState frameState;
|
||||
containerFrame->GetFrameState(&frameState);
|
||||
frameState |= NS_FRAME_GENERATED_CONTENT;
|
||||
containerFrame->SetFrameState(frameState);
|
||||
const nsStyleDisplay *display;
|
||||
::GetStyleData(pseudoStyleContext.get(), &display);
|
||||
if (NS_STYLE_DISPLAY_BLOCK == display->mDisplay) {
|
||||
NS_NewBlockFrame(aPresShell, &containerFrame);
|
||||
} else {
|
||||
NS_NewInlineFrame(aPresShell, &containerFrame);
|
||||
}
|
||||
InitAndRestoreFrame(aPresContext, aState, aContent,
|
||||
aFrame, pseudoStyleContext, nsnull, containerFrame);
|
||||
nsHTMLContainerFrame::CreateViewForFrame(aPresContext, containerFrame,
|
||||
pseudoStyleContext, nsnull, PR_FALSE);
|
||||
|
||||
// Create another pseudo style context to use for all the generated child
|
||||
// frames
|
||||
nsRefPtr<nsStyleContext> textStyleContext;
|
||||
textStyleContext = aPresContext->ResolveStyleContextForNonElement(pseudoStyleContext);
|
||||
// Mark the frame as being associated with generated content
|
||||
nsFrameState frameState;
|
||||
containerFrame->GetFrameState(&frameState);
|
||||
frameState |= NS_FRAME_GENERATED_CONTENT;
|
||||
containerFrame->SetFrameState(frameState);
|
||||
|
||||
// Now create content objects (and child frames) for each value of the
|
||||
// 'content' property
|
||||
// Create another pseudo style context to use for all the generated child
|
||||
// frames
|
||||
nsRefPtr<nsStyleContext> textStyleContext;
|
||||
textStyleContext = aPresContext->ResolveStyleContextForNonElement(pseudoStyleContext);
|
||||
|
||||
for (PRUint32 contentIndex = 0; contentIndex < contentCount; contentIndex++) {
|
||||
nsIFrame* frame;
|
||||
// Now create content objects (and child frames) for each value of the
|
||||
// 'content' property
|
||||
|
||||
// Create a frame
|
||||
nsresult result;
|
||||
result = CreateGeneratedFrameFor(aPresContext, mDocument, containerFrame,
|
||||
aContent, textStyleContext,
|
||||
styleContent, contentIndex, &frame);
|
||||
// Non-elements can't possibly have a view, so don't bother checking
|
||||
if (NS_SUCCEEDED(result) && frame) {
|
||||
// Add it to the list of child frames
|
||||
childFrames.AddChild(frame);
|
||||
}
|
||||
}
|
||||
|
||||
if (childFrames.childList) {
|
||||
containerFrame->SetInitialChildList(aPresContext, nsnull, childFrames.childList);
|
||||
}
|
||||
*aResult = containerFrame;
|
||||
return PR_TRUE;
|
||||
const nsStyleContent *styleContent;
|
||||
::GetStyleData(pseudoStyleContext.get(), &styleContent);
|
||||
PRUint32 contentCount = styleContent->ContentCount();
|
||||
for (PRUint32 contentIndex = 0; contentIndex < contentCount; contentIndex++) {
|
||||
nsIFrame* frame;
|
||||
|
||||
// Create a frame
|
||||
nsresult result;
|
||||
result = CreateGeneratedFrameFor(aPresContext, mDocument, containerFrame,
|
||||
aContent, textStyleContext,
|
||||
styleContent, contentIndex, &frame);
|
||||
// Non-elements can't possibly have a view, so don't bother checking
|
||||
if (NS_SUCCEEDED(result) && frame) {
|
||||
// Add it to the list of child frames
|
||||
childFrames.AddChild(frame);
|
||||
}
|
||||
}
|
||||
|
||||
if (childFrames.childList) {
|
||||
containerFrame->SetInitialChildList(aPresContext, nsnull, childFrames.childList);
|
||||
}
|
||||
*aResult = containerFrame;
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
return PR_FALSE;
|
||||
|
|
|
@ -50,6 +50,7 @@
|
|||
#include "nsIDocument.h"
|
||||
#include "nsIStyleFrameConstruction.h"
|
||||
#include "nsCSSAnonBoxes.h"
|
||||
#include "nsCSSPseudoElements.h"
|
||||
#include "nsTimer.h"
|
||||
#include "nsICSSStyleSheet.h"
|
||||
#include "nsNetUtil.h"
|
||||
|
@ -1326,6 +1327,24 @@ StyleSetImpl::ProbePseudoStyleFor(nsIPresContext* aPresContext,
|
|||
mRuleWalker->Reset();
|
||||
}
|
||||
}
|
||||
|
||||
// For :before and :after pseudo-elements, having display: none or no
|
||||
// 'content' property is equivalent to not having the pseudo-element
|
||||
// at all.
|
||||
if (result &&
|
||||
(aPseudoTag == nsCSSPseudoElements::before ||
|
||||
aPseudoTag == nsCSSPseudoElements::after)) {
|
||||
const nsStyleDisplay *display;
|
||||
const nsStyleContent *content;
|
||||
::GetStyleData(result, &display);
|
||||
::GetStyleData(result, &content);
|
||||
// XXXldb What is contentCount for |content: ""|?
|
||||
if (display->mDisplay == NS_STYLE_DISPLAY_NONE ||
|
||||
content->ContentCount() == 0) {
|
||||
result->Release();
|
||||
result = nsnull;
|
||||
}
|
||||
}
|
||||
|
||||
MOZ_TIMER_DEBUGLOG(("Stop: StyleSetImpl::ProbePseudoStyleFor(), this=%p\n", this));
|
||||
STYLESET_STOP_TIMER(NS_TIMER_STYLE_RESOLUTION);
|
||||
|
|
Загрузка…
Ссылка в новой задаче