Bug 1479528: Move all the data-finding related stuff into a single function. r=dholbert

To make it hopefully a bit easier to follow.

Differential Revision: https://phabricator.services.mozilla.com/D2564

MozReview-Commit-ID: 2LMf7IXM1kr
This commit is contained in:
Emilio Cobos Álvarez 2018-07-31 14:44:45 +02:00
parent 3af717e9ff
commit f7180dd264
3 changed files with 136 additions and 101 deletions

View File

@ -16,6 +16,8 @@ namespace dom {
class Text : public CharacterData
{
public:
NS_IMPL_FROMNODE_HELPER(Text, IsText())
explicit Text(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
: CharacterData(aNodeInfo)
{}

View File

@ -3405,10 +3405,9 @@ FindAncestorWithGeneratedContentPseudo(nsIFrame* aFrame)
/* static */
const nsCSSFrameConstructor::FrameConstructionData*
nsCSSFrameConstructor::FindTextData(nsIFrame* aParentFrame,
nsIContent* aTextContent)
nsCSSFrameConstructor::FindTextData(const Text& aTextContent,
nsIFrame* aParentFrame)
{
MOZ_ASSERT(aTextContent, "How?");
if (aParentFrame && IsFrameForSVG(aParentFrame)) {
nsIFrame* ancestorFrame =
nsSVGUtils::GetFirstNonAAncestorFrame(aParentFrame);
@ -3419,7 +3418,7 @@ nsCSSFrameConstructor::FindTextData(nsIFrame* aParentFrame,
// Don't render stuff in display: contents / Shadow DOM subtrees, because
// TextCorrespondenceRecorder in the SVG text code doesn't really know how
// to deal with it. This kinda sucks. :(
if (aParentFrame->GetContent() != aTextContent->GetParent()) {
if (aParentFrame->GetContent() != aTextContent.GetParent()) {
return nullptr;
}
@ -3553,12 +3552,7 @@ nsCSSFrameConstructor::FindHTMLData(const Element& aElement,
nsIFrame* aParentFrame,
ComputedStyle& aStyle)
{
// Ignore the tag if it's not HTML content and if it doesn't extend (via XBL)
// a valid HTML namespace. This check must match the one in
// ShouldHaveFirstLineStyle.
if (!aElement.IsHTMLElement()) {
return nullptr;
}
MOZ_ASSERT(aElement.IsHTMLElement());
nsAtom* tag = aElement.NodeInfo()->NameAtom();
NS_ASSERTION(!aParentFrame ||
@ -4195,12 +4189,9 @@ nsIFrame* NS_NewGridBoxFrame(nsIPresShell* aPresShell,
const nsCSSFrameConstructor::FrameConstructionData*
nsCSSFrameConstructor::FindXULTagData(const Element& aElement,
nsAtom* aTag,
int32_t aNameSpaceID,
ComputedStyle& aStyle)
{
if (aNameSpaceID != kNameSpaceID_XUL) {
return nullptr;
}
MOZ_ASSERT(aElement.IsXULElement());
static const FrameConstructionDataByTag sXULTagData[] = {
#ifdef MOZ_XUL
@ -4928,10 +4919,7 @@ const nsCSSFrameConstructor::FrameConstructionData*
nsCSSFrameConstructor::FindMathMLData(const Element& aElement,
ComputedStyle& aStyle)
{
// Make sure that we remain confined in the MathML world
if (!aElement.IsMathMLElement()) {
return nullptr;
}
MOZ_ASSERT(aElement.IsMathMLElement());
nsAtom* tag = aElement.NodeInfo()->NameAtom();
@ -5116,9 +5104,7 @@ nsCSSFrameConstructor::FindSVGData(const Element& aElement,
bool aAllowsTextPathChild,
ComputedStyle& aStyle)
{
if (!aElement.IsSVGElement()) {
return nullptr;
}
MOZ_ASSERT(aElement.IsSVGElement());
static const FrameConstructionData sSuppressData = SUPPRESS_FCDATA();
static const FrameConstructionData sContainerData =
@ -5493,6 +5479,91 @@ ShouldSuppressFrameInNonOpenDetails(const HTMLDetailsElement* aDetails,
return true;
}
const nsCSSFrameConstructor::FrameConstructionData*
nsCSSFrameConstructor::FindDataForContent(nsIContent& aContent,
ComputedStyle& aStyle,
nsIFrame* aParentFrame,
nsAtom* aTag,
uint32_t aFlags)
{
MOZ_ASSERT(aStyle.StyleDisplay()->mDisplay != StyleDisplay::None &&
aStyle.StyleDisplay()->mDisplay != StyleDisplay::Contents,
"These two special display values should be handled earlier");
if (auto* text = Text::FromNode(aContent)) {
return FindTextData(*text, aParentFrame);
}
return FindElementData(*aContent.AsElement(),
aStyle,
aParentFrame,
aTag,
aFlags);
}
const nsCSSFrameConstructor::FrameConstructionData*
nsCSSFrameConstructor::FindElementData(const Element& aElement,
ComputedStyle& aStyle,
nsIFrame* aParentFrame,
nsAtom* aTag,
uint32_t aFlags)
{
// Don't create frames for non-SVG element children of SVG elements.
if (!aElement.IsSVGElement()) {
if (aParentFrame && IsFrameForSVG(aParentFrame) &&
!aParentFrame->IsFrameOfType(nsIFrame::eSVGForeignObject)) {
return nullptr;
}
if (aFlags & ITEM_IS_WITHIN_SVG_TEXT) {
return nullptr;
}
}
if (auto* data = FindElementTagData(aElement, aStyle, aParentFrame, aTag, aFlags)) {
return data;
}
// Check for 'content: <image-url>' on the element (which makes us ignore
// 'display' values other than 'none' or 'contents').
if (ShouldCreateImageFrameForContent(aElement, aStyle)) {
static const FrameConstructionData sImgData =
SIMPLE_FCDATA(NS_NewImageFrameForContentProperty);
return &sImgData;
}
const auto& display = *aStyle.StyleDisplay();
if (auto* data = FindXULDisplayData(display, aElement)) {
return data;
}
return FindDisplayData(display, aElement);
}
const nsCSSFrameConstructor::FrameConstructionData*
nsCSSFrameConstructor::FindElementTagData(const Element& aElement,
ComputedStyle& aStyle,
nsIFrame* aParentFrame,
nsAtom* aTag,
uint32_t aFlags)
{
switch (aElement.GetNameSpaceID()) {
case kNameSpaceID_XHTML:
return FindHTMLData(aElement, aParentFrame, aStyle);
case kNameSpaceID_MathML:
return FindMathMLData(aElement, aStyle);
case kNameSpaceID_SVG:
return FindSVGData(aElement,
aParentFrame,
aFlags & ITEM_IS_WITHIN_SVG_TEXT,
aFlags & ITEM_ALLOWS_TEXT_PATH_CHILD,
aStyle);
case kNameSpaceID_XUL:
return FindXULTagData(aElement, aTag, aStyle);
default:
return nullptr;
}
}
nsCSSFrameConstructor::XBLBindingLoadInfo::XBLBindingLoadInfo(
already_AddRefed<ComputedStyle> aStyle,
mozilla::UniquePtr<PendingBinding> aPendingBinding,
@ -5661,80 +5732,26 @@ nsCSSFrameConstructor::AddFrameConstructionItemsInternal(nsFrameConstructorState
return;
}
const FrameConstructionData* data =
FindDataForContent(*aContent, *style, aParentFrame, tag, aFlags);
if (!data || data->mBits & FCDATA_SUPPRESS_FRAME) {
return;
}
bool isPopup = false;
const bool isText = !aContent->IsElement();
// Try to find frame construction data for this content
const FrameConstructionData* data;
if (isText) {
data = FindTextData(aParentFrame, aContent);
if (!data) {
// Nothing to do here; suppressed text inside SVG
return;
}
} else {
Element& element = *aContent->AsElement();
// Don't create frames for non-SVG element children of SVG elements.
if (namespaceId != kNameSpaceID_SVG &&
((aParentFrame &&
IsFrameForSVG(aParentFrame) &&
!aParentFrame->IsFrameOfType(nsIFrame::eSVGForeignObject)) ||
(aFlags & ITEM_IS_WITHIN_SVG_TEXT))) {
return;
}
data = FindHTMLData(element, aParentFrame, *style);
if (!data) {
data = FindXULTagData(element, tag, namespaceId, *style);
}
if (!data) {
data = FindMathMLData(element, *style);
}
if (!data) {
data = FindSVGData(element,
aParentFrame,
aFlags & ITEM_IS_WITHIN_SVG_TEXT,
aFlags & ITEM_ALLOWS_TEXT_PATH_CHILD,
*style);
}
// Check for 'content: <image-url>' on the element (which makes us ignore
// 'display' values other than 'none' or 'contents').
if (!data && ShouldCreateImageFrameForContent(element, *style)) {
static const FrameConstructionData sImgData =
SIMPLE_FCDATA(NS_NewImageFrameForContentProperty);
data = &sImgData;
}
// Now check for XUL display types
if (!data) {
data = FindXULDisplayData(display, element);
}
// And general display types
if (!data) {
data = FindDisplayData(display, element);
}
MOZ_ASSERT(data, "Should have frame construction data now");
if (data->mBits & FCDATA_SUPPRESS_FRAME) {
return;
}
#ifdef MOZ_XUL
if ((data->mBits & FCDATA_IS_POPUP) &&
(!aParentFrame || // Parent is inline
!aParentFrame->IsMenuFrame())) {
if (!aState.mPopupItems.containingBlock &&
!aState.mHavePendingPopupgroup) {
return;
}
isPopup = true;
if ((data->mBits & FCDATA_IS_POPUP) &&
(!aParentFrame || // Parent is inline
!aParentFrame->IsMenuFrame())) {
if (!aState.mPopupItems.containingBlock &&
!aState.mHavePendingPopupgroup) {
return;
}
#endif /* MOZ_XUL */
isPopup = true;
}
#endif /* MOZ_XUL */
uint32_t bits = data->mBits;
@ -5771,7 +5788,7 @@ nsCSSFrameConstructor::AddFrameConstructionItemsInternal(nsFrameConstructorState
style.forget(),
aSuppressWhiteSpaceOptimizations);
}
item->mIsText = isText;
item->mIsText = !aContent->IsElement();
item->mIsGeneratedContent = isGeneratedContent;
item->mIsAnonymousContentCreatorContent =
aFlags & ITEM_IS_ANONYMOUSCONTENTCREATOR_CONTENT;
@ -5781,14 +5798,14 @@ nsCSSFrameConstructor::AddFrameConstructionItemsInternal(nsFrameConstructorState
item->mContent->AddRef();
}
item->mIsRootPopupgroup =
namespaceId == kNameSpaceID_XUL && tag == nsGkAtoms::popupgroup &&
aContent->IsRootOfNativeAnonymousSubtree();
aContent->IsRootOfNativeAnonymousSubtree() &&
aContent->IsXULElement() &&
tag == nsGkAtoms::popupgroup;
if (item->mIsRootPopupgroup) {
aState.mHavePendingPopupgroup = true;
}
item->mIsPopup = isPopup;
item->mIsForSVGAElement = namespaceId == kNameSpaceID_SVG &&
tag == nsGkAtoms::a;
item->mIsForSVGAElement = aContent->IsSVGElement(nsGkAtoms::a);
if (canHavePageBreak && display.mBreakAfter) {
AddPageBreakItem(aContent, aItems);

View File

@ -46,6 +46,7 @@ class ComputedStyle;
namespace dom {
class CharacterData;
class Text;
class FlattenedChildIterator;
} // namespace dom
@ -57,6 +58,7 @@ public:
typedef mozilla::ComputedStyle ComputedStyle;
typedef mozilla::CSSPseudoElementType CSSPseudoElementType;
typedef mozilla::dom::Element Element;
typedef mozilla::dom::Text Text;
// FIXME(emilio): Is this really needed?
friend class mozilla::RestyleManager;
@ -808,6 +810,26 @@ private:
ComputedStyle&,
uint32_t aFlags);
const FrameConstructionData* FindDataForContent(nsIContent&,
ComputedStyle&,
nsIFrame* aParentFrame,
nsAtom* aTag,
uint32_t aFlags);
// aParentFrame might be null. If it is, that means it was an inline frame.
static const FrameConstructionData* FindTextData(const Text&,
nsIFrame* aParentFrame);
const FrameConstructionData* FindElementData(const Element&,
ComputedStyle&,
nsIFrame* aParentFrame,
nsAtom* aTag,
uint32_t aFlags);
const FrameConstructionData* FindElementTagData(const Element&,
ComputedStyle&,
nsIFrame* aParentFrame,
nsAtom* aTag,
uint32_t aFlags);
/* A function that takes an integer, content, style, and array of
FrameConstructionDataByInts and finds the appropriate frame construction
data to use and returns it. This can return null if none of the integers
@ -1413,11 +1435,6 @@ private:
const nsStyleDisplay* aStyleDisplay,
nsFrameItems& aFrameItems);
// aParentFrame might be null. If it is, that means it was an
// inline frame.
static const FrameConstructionData* FindTextData(nsIFrame* aParentFrame,
nsIContent* aTextContent);
void ConstructTextFrame(const FrameConstructionData* aData,
nsFrameConstructorState& aState,
nsIContent* aContent,
@ -1537,7 +1554,6 @@ private:
// be overriden by extends="" in XBL.
static const FrameConstructionData* FindXULTagData(const Element&,
nsAtom* aTag,
int32_t aNameSpaceID,
ComputedStyle&);
// XUL data-finding helper functions and structures
#ifdef MOZ_XUL