mirror of
https://github.com/roytam1/basilisk55.git
synced 2026-05-26 15:02:46 +00:00
import from UXP: Bug 1413619 - Fix insertion point computation when display: contents pseudos are involved. (5b1452e1)
This commit is contained in:
@@ -192,17 +192,17 @@ FlattenedChildIterator::Init(bool aIgnoreXBL)
|
||||
}
|
||||
|
||||
bool
|
||||
ExplicitChildIterator::Seek(nsIContent* aChildToFind)
|
||||
ExplicitChildIterator::Seek(const nsIContent* aChildToFind)
|
||||
{
|
||||
if (aChildToFind->GetParent() == mParent &&
|
||||
!aChildToFind->IsRootOfAnonymousSubtree()) {
|
||||
// Fast path: just point ourselves to aChildToFind, which is a
|
||||
// normal DOM child of ours.
|
||||
MOZ_ASSERT(!nsContentUtils::IsContentInsertionPoint(aChildToFind));
|
||||
mChild = aChildToFind;
|
||||
mChild = const_cast<nsIContent*>(aChildToFind);
|
||||
mIndexInInserted = 0;
|
||||
mDefaultChild = nullptr;
|
||||
mIsFirst = false;
|
||||
MOZ_ASSERT(!nsContentUtils::IsContentInsertionPoint(mChild));
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -348,7 +348,7 @@ AllChildrenIterator::Get() const
|
||||
|
||||
|
||||
bool
|
||||
AllChildrenIterator::Seek(nsIContent* aChildToFind)
|
||||
AllChildrenIterator::Seek(const nsIContent* aChildToFind)
|
||||
{
|
||||
if (mPhase == eAtBegin || mPhase == eAtBeforeKid) {
|
||||
mPhase = eAtExplicitKids;
|
||||
|
||||
+22
-12
@@ -58,13 +58,13 @@ public:
|
||||
// found. This version can take shortcuts that the two-argument version
|
||||
// can't, so can be faster (and in fact can be O(1) instead of O(N) in many
|
||||
// cases).
|
||||
bool Seek(nsIContent* aChildToFind);
|
||||
bool Seek(const nsIContent* aChildToFind);
|
||||
|
||||
// Looks for aChildToFind respecting insertion points until aChildToFind is found.
|
||||
// or aBound is found. If aBound is nullptr then the seek is unbounded. Returns
|
||||
// whether aChildToFind was found as an explicit child prior to encountering
|
||||
// aBound.
|
||||
bool Seek(nsIContent* aChildToFind, nsIContent* aBound)
|
||||
bool Seek(const nsIContent* aChildToFind, nsIContent* aBound)
|
||||
{
|
||||
// It would be nice to assert that we find aChildToFind, but bz thinks that
|
||||
// we might not find aChildToFind when called from ContentInserted
|
||||
@@ -131,19 +131,29 @@ class FlattenedChildIterator : public ExplicitChildIterator
|
||||
public:
|
||||
explicit FlattenedChildIterator(const nsIContent* aParent,
|
||||
bool aStartAtBeginning = true)
|
||||
: ExplicitChildIterator(aParent, aStartAtBeginning), mXBLInvolved(false)
|
||||
: ExplicitChildIterator(aParent, aStartAtBeginning)
|
||||
, mXBLInvolved(false)
|
||||
, mOriginalContent(aParent)
|
||||
{
|
||||
Init(false);
|
||||
}
|
||||
|
||||
FlattenedChildIterator(FlattenedChildIterator&& aOther)
|
||||
: ExplicitChildIterator(Move(aOther)), mXBLInvolved(aOther.mXBLInvolved) {}
|
||||
: ExplicitChildIterator(Move(aOther))
|
||||
, mXBLInvolved(aOther.mXBLInvolved)
|
||||
, mOriginalContent(aOther.mOriginalContent)
|
||||
{}
|
||||
|
||||
FlattenedChildIterator(const FlattenedChildIterator& aOther)
|
||||
: ExplicitChildIterator(aOther), mXBLInvolved(aOther.mXBLInvolved) {}
|
||||
: ExplicitChildIterator(aOther)
|
||||
, mXBLInvolved(aOther.mXBLInvolved)
|
||||
, mOriginalContent(aOther.mOriginalContent)
|
||||
{}
|
||||
|
||||
bool XBLInvolved() { return mXBLInvolved; }
|
||||
|
||||
const nsIContent* Parent() const { return mOriginalContent; }
|
||||
|
||||
protected:
|
||||
/**
|
||||
* This constructor is a hack to help AllChildrenIterator which sometimes
|
||||
@@ -151,7 +161,9 @@ protected:
|
||||
*/
|
||||
FlattenedChildIterator(const nsIContent* aParent, uint32_t aFlags,
|
||||
bool aStartAtBeginning = true)
|
||||
: ExplicitChildIterator(aParent, aStartAtBeginning), mXBLInvolved(false)
|
||||
: ExplicitChildIterator(aParent, aStartAtBeginning)
|
||||
, mXBLInvolved(false)
|
||||
, mOriginalContent(aParent)
|
||||
{
|
||||
bool ignoreXBL = aFlags & nsIContent::eAllButXBL;
|
||||
Init(ignoreXBL);
|
||||
@@ -162,6 +174,8 @@ protected:
|
||||
// For certain optimizations, nsCSSFrameConstructor needs to know if the
|
||||
// child list of the element that we're iterating matches its .childNodes.
|
||||
bool mXBLInvolved;
|
||||
|
||||
const nsIContent* mOriginalContent;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -179,12 +193,11 @@ public:
|
||||
AllChildrenIterator(const nsIContent* aNode, uint32_t aFlags,
|
||||
bool aStartAtBeginning = true) :
|
||||
FlattenedChildIterator(aNode, aFlags, aStartAtBeginning),
|
||||
mOriginalContent(aNode), mAnonKidsIdx(aStartAtBeginning ? UINT32_MAX : 0),
|
||||
mAnonKidsIdx(aStartAtBeginning ? UINT32_MAX : 0),
|
||||
mFlags(aFlags), mPhase(aStartAtBeginning ? eAtBegin : eAtEnd) { }
|
||||
|
||||
AllChildrenIterator(AllChildrenIterator&& aOther)
|
||||
: FlattenedChildIterator(Move(aOther)),
|
||||
mOriginalContent(aOther.mOriginalContent),
|
||||
mAnonKids(Move(aOther.mAnonKids)), mAnonKidsIdx(aOther.mAnonKidsIdx),
|
||||
mFlags(aOther.mFlags), mPhase(aOther.mPhase)
|
||||
#ifdef DEBUG
|
||||
@@ -203,11 +216,10 @@ public:
|
||||
// Seeks the given node in children of a parent element, starting from
|
||||
// the current iterator's position, and sets the iterator at the given child
|
||||
// node if it was found.
|
||||
bool Seek(nsIContent* aChildToFind);
|
||||
bool Seek(const nsIContent* aChildToFind);
|
||||
|
||||
nsIContent* GetNextChild();
|
||||
nsIContent* GetPreviousChild();
|
||||
const nsIContent* Parent() const { return mOriginalContent; }
|
||||
|
||||
enum IteratorPhase
|
||||
{
|
||||
@@ -225,8 +237,6 @@ private:
|
||||
void AppendNativeAnonymousChildren();
|
||||
void AppendNativeAnonymousChildrenFromFrame(nsIFrame* aFrame);
|
||||
|
||||
const nsIContent* mOriginalContent;
|
||||
|
||||
// mAnonKids is an array of native anonymous children, mAnonKidsIdx is index
|
||||
// in the array. If mAnonKidsIdx < mAnonKids.Length() and mPhase is
|
||||
// eAtAnonKids then the iterator points at a child at mAnonKidsIdx index. If
|
||||
|
||||
@@ -6677,115 +6677,147 @@ nsCSSFrameConstructor::IsValidSibling(nsIFrame* aSibling,
|
||||
return true;
|
||||
}
|
||||
|
||||
// FIXME(emilio): If we ever kill IsValidSibling() we can simplify this quite a
|
||||
// bit (no need to pass aTargetContent or aTargetContentDisplay, and the
|
||||
// adjust() calls can be responsibility of the caller).
|
||||
template<nsCSSFrameConstructor::SiblingDirection aDirection>
|
||||
nsIFrame*
|
||||
nsCSSFrameConstructor::FindFrameForContentSibling(nsIContent* aContent,
|
||||
nsIContent* aTargetContent,
|
||||
StyleDisplay& aTargetContentDisplay,
|
||||
nsContainerFrame* aParentFrame,
|
||||
bool aPrevSibling)
|
||||
nsCSSFrameConstructor::FindSiblingInternal(
|
||||
FlattenedChildIterator aIter,
|
||||
nsIContent* aTargetContent,
|
||||
StyleDisplay& aTargetContentDisplay)
|
||||
{
|
||||
nsIFrame* sibling = aContent->GetPrimaryFrame();
|
||||
if (!sibling && GetDisplayContentsStyleFor(aContent)) {
|
||||
// A display:contents node - check if it has a ::before / ::after frame...
|
||||
sibling = aPrevSibling ? nsLayoutUtils::GetAfterFrame(aContent)
|
||||
: nsLayoutUtils::GetBeforeFrame(aContent);
|
||||
if (!sibling) {
|
||||
// ... then recurse into children ...
|
||||
const bool forward = !aPrevSibling;
|
||||
FlattenedChildIterator iter(aContent, forward);
|
||||
sibling = aPrevSibling ?
|
||||
FindPreviousSibling(iter, aTargetContent, aTargetContentDisplay, aParentFrame) :
|
||||
FindNextSibling(iter, aTargetContent, aTargetContentDisplay, aParentFrame);
|
||||
auto adjust = [&](nsIFrame* aPotentialSiblingFrame) -> nsIFrame* {
|
||||
return AdjustSiblingFrame(
|
||||
aPotentialSiblingFrame, aTargetContent, aTargetContentDisplay,
|
||||
aDirection);
|
||||
};
|
||||
|
||||
// The recursion above has already done all the placeholder and
|
||||
// continuation fixups.
|
||||
auto nextDomSibling = [](FlattenedChildIterator& aIter) -> nsIContent* {
|
||||
return aDirection == SiblingDirection::Forward
|
||||
? aIter.GetNextChild() : aIter.GetPreviousChild();
|
||||
};
|
||||
|
||||
auto getNearPseudo = [](const nsIContent* aContent) -> nsIFrame* {
|
||||
return aDirection == SiblingDirection::Forward
|
||||
? nsLayoutUtils::GetBeforeFrame(aContent)
|
||||
: nsLayoutUtils::GetAfterFrame(aContent);
|
||||
};
|
||||
|
||||
auto getFarPseudo = [](const nsIContent* aContent) -> nsIFrame* {
|
||||
return aDirection == SiblingDirection::Forward
|
||||
? nsLayoutUtils::GetAfterFrame(aContent)
|
||||
: nsLayoutUtils::GetBeforeFrame(aContent);
|
||||
};
|
||||
|
||||
while (nsIContent* sibling = nextDomSibling(aIter)) {
|
||||
if (nsIFrame* primaryFrame = sibling->GetPrimaryFrame()) {
|
||||
// XXX the GetContent() == sibling check is needed due to bug 135040.
|
||||
// Remove it once that's fixed.
|
||||
if (primaryFrame->GetContent() == sibling) {
|
||||
if (nsIFrame* frame = adjust(primaryFrame)) {
|
||||
return frame;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (GetDisplayContentsStyleFor(sibling)) {
|
||||
if (nsIFrame* frame = adjust(getNearPseudo(sibling))) {
|
||||
return frame;
|
||||
}
|
||||
|
||||
const bool startFromBeginning = aDirection == SiblingDirection::Forward;
|
||||
FlattenedChildIterator iter(sibling, startFromBeginning);
|
||||
nsIFrame* sibling = FindSiblingInternal<aDirection>(
|
||||
iter, aTargetContent, aTargetContentDisplay);
|
||||
if (sibling) {
|
||||
return sibling;
|
||||
}
|
||||
}
|
||||
if (!sibling) {
|
||||
// ... then ::after / ::before on the opposite end.
|
||||
sibling = aPrevSibling ? nsLayoutUtils::GetAfterFrame(aContent)
|
||||
: nsLayoutUtils::GetBeforeFrame(aContent);
|
||||
}
|
||||
if (!sibling) {
|
||||
return nullptr;
|
||||
}
|
||||
} else if (!sibling || sibling->GetContent() != aContent) {
|
||||
// XXX the GetContent() != aContent check is needed due to bug 135040.
|
||||
// Remove it once that's fixed.
|
||||
}
|
||||
|
||||
return adjust(getFarPseudo(aIter.Parent()));
|
||||
}
|
||||
|
||||
nsIFrame*
|
||||
nsCSSFrameConstructor::AdjustSiblingFrame(
|
||||
nsIFrame* aSibling,
|
||||
nsIContent* aTargetContent,
|
||||
mozilla::StyleDisplay& aTargetContentDisplay,
|
||||
SiblingDirection aDirection)
|
||||
{
|
||||
if (!aSibling) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// If the frame is out-of-flow, GetPrimaryFrame() will have returned the
|
||||
// out-of-flow frame; we want the placeholder.
|
||||
if (sibling->GetStateBits() & NS_FRAME_OUT_OF_FLOW) {
|
||||
nsIFrame* placeholderFrame = sibling->GetPlaceholderFrame();
|
||||
NS_ASSERTION(placeholderFrame, "no placeholder for out-of-flow frame");
|
||||
sibling = placeholderFrame;
|
||||
if (aSibling->GetStateBits() & NS_FRAME_OUT_OF_FLOW) {
|
||||
aSibling = aSibling->GetPlaceholderFrame();
|
||||
MOZ_ASSERT(aSibling);
|
||||
}
|
||||
|
||||
// The frame we have now should never be a continuation.
|
||||
NS_ASSERTION(!sibling->GetPrevContinuation(), "How did that happen?");
|
||||
|
||||
if (aPrevSibling) {
|
||||
// The frame may be a ib-split frame (a split inline frame that
|
||||
// contains a block). Get the last part of that split.
|
||||
if (IsFramePartOfIBSplit(sibling)) {
|
||||
sibling = GetLastIBSplitSibling(sibling, true);
|
||||
MOZ_ASSERT(!aSibling->GetPrevContinuation(), "How?");
|
||||
if (aDirection == SiblingDirection::Backward) {
|
||||
// The frame may be a ib-split frame (a split inline frame that contains a
|
||||
// block). Get the last part of that split.
|
||||
if (IsFramePartOfIBSplit(aSibling)) {
|
||||
aSibling = GetLastIBSplitSibling(aSibling, true);
|
||||
}
|
||||
|
||||
// The frame may have a continuation. If so, we want the last
|
||||
// non-overflow-container continuation as our previous sibling.
|
||||
sibling = sibling->GetTailContinuation();
|
||||
aSibling = aSibling->GetTailContinuation();
|
||||
}
|
||||
|
||||
if (aTargetContent &&
|
||||
!IsValidSibling(sibling, aTargetContent, aTargetContentDisplay)) {
|
||||
sibling = nullptr;
|
||||
if (!IsValidSibling(aSibling, aTargetContent, aTargetContentDisplay)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return sibling;
|
||||
return aSibling;
|
||||
}
|
||||
|
||||
nsIFrame*
|
||||
nsCSSFrameConstructor::FindPreviousSibling(FlattenedChildIterator aIter,
|
||||
nsIContent* aTargetContent,
|
||||
StyleDisplay& aTargetContentDisplay,
|
||||
nsContainerFrame* aParentFrame)
|
||||
nsCSSFrameConstructor::FindPreviousSibling(const FlattenedChildIterator& aIter,
|
||||
StyleDisplay& aTargetContentDisplay)
|
||||
{
|
||||
// Note: not all content objects are associated with a frame (e.g., if it's
|
||||
// `display: none') so keep looking until we find a previous frame.
|
||||
while (nsIContent* sibling = aIter.GetPreviousChild()) {
|
||||
MOZ_ASSERT(sibling != aTargetContent);
|
||||
nsIFrame* prevSibling =
|
||||
FindFrameForContentSibling(sibling, aTargetContent, aTargetContentDisplay,
|
||||
aParentFrame, true);
|
||||
if (prevSibling) {
|
||||
// Found a previous sibling, we're done!
|
||||
return prevSibling;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
return FindSibling<SiblingDirection::Backward>(aIter, aTargetContentDisplay);
|
||||
}
|
||||
|
||||
nsIFrame*
|
||||
nsCSSFrameConstructor::FindNextSibling(FlattenedChildIterator aIter,
|
||||
nsIContent* aTargetContent,
|
||||
StyleDisplay& aTargetContentDisplay,
|
||||
nsContainerFrame* aParentFrame)
|
||||
nsCSSFrameConstructor::FindNextSibling(const FlattenedChildIterator& aIter,
|
||||
StyleDisplay& aTargetContentDisplay)
|
||||
{
|
||||
while (nsIContent* sibling = aIter.GetNextChild()) {
|
||||
MOZ_ASSERT(sibling != aTargetContent);
|
||||
nsIFrame* nextSibling =
|
||||
FindFrameForContentSibling(sibling, aTargetContent, aTargetContentDisplay,
|
||||
aParentFrame, false);
|
||||
return FindSibling<SiblingDirection::Forward>(aIter, aTargetContentDisplay);
|
||||
}
|
||||
|
||||
if (nextSibling) {
|
||||
// We found a next sibling, we're done!
|
||||
return nextSibling;
|
||||
template<nsCSSFrameConstructor::SiblingDirection aDirection>
|
||||
nsIFrame*
|
||||
nsCSSFrameConstructor::FindSibling(const FlattenedChildIterator& aIter,
|
||||
StyleDisplay& aTargetContentDisplay)
|
||||
{
|
||||
nsIContent* targetContent = aIter.Get();
|
||||
nsIFrame* sibling =
|
||||
FindSiblingInternal<aDirection>(aIter, targetContent, aTargetContentDisplay);
|
||||
if (sibling) {
|
||||
return sibling;
|
||||
}
|
||||
|
||||
// Our siblings (if any) do not have a frame to guide us. The frame for the
|
||||
// target content should be inserted whereever a frame for the container would
|
||||
// be inserted. This is needed when inserting into display: contents nodes.
|
||||
const nsIContent* current = aIter.Parent();
|
||||
while (GetDisplayContentsStyleFor(current)) {
|
||||
const nsIContent* parent = current->GetFlattenedTreeParent();
|
||||
MOZ_ASSERT(parent, "No display: contents on the root");
|
||||
|
||||
FlattenedChildIterator iter(parent);
|
||||
iter.Seek(current);
|
||||
sibling = FindSiblingInternal<aDirection>(
|
||||
iter, targetContent, aTargetContentDisplay);
|
||||
if (sibling) {
|
||||
return sibling;
|
||||
}
|
||||
|
||||
current = parent;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
@@ -6851,8 +6883,7 @@ nsCSSFrameConstructor::GetInsertionPrevSibling(InsertionPoint* aInsertion,
|
||||
// Note that FindPreviousSibling is passed the iterator by value, so that
|
||||
// the later usage of the iterator starts from the same place.
|
||||
StyleDisplay childDisplay = UNSET_DISPLAY;
|
||||
nsIFrame* prevSibling =
|
||||
FindPreviousSibling(iter, iter.Get(), childDisplay, aInsertion->mParentFrame);
|
||||
nsIFrame* prevSibling = FindPreviousSibling(iter, childDisplay);
|
||||
|
||||
// Now, find the geometric parent so that we can handle
|
||||
// continuations properly. Use the prev sibling if we have it;
|
||||
@@ -6865,34 +6896,7 @@ nsCSSFrameConstructor::GetInsertionPrevSibling(InsertionPoint* aInsertion,
|
||||
iter.Seek(aEndSkipChild);
|
||||
iter.GetPreviousChild();
|
||||
}
|
||||
nsIFrame* nextSibling =
|
||||
FindNextSibling(iter, iter.Get(), childDisplay, aInsertion->mParentFrame);
|
||||
if (GetDisplayContentsStyleFor(aInsertion->mContainer)) {
|
||||
if (!nextSibling) {
|
||||
// Our siblings (if any) does not have a frame to guide us.
|
||||
// The frame for aChild should be inserted whereever a frame for
|
||||
// the container would be inserted. This is needed when inserting
|
||||
// into nested display:contents nodes.
|
||||
nsIContent* child = aInsertion->mContainer;
|
||||
nsIContent* parent = child->GetParent();
|
||||
aInsertion->mParentFrame =
|
||||
::GetAdjustedParentFrame(aInsertion->mParentFrame,
|
||||
aInsertion->mParentFrame->GetType(),
|
||||
parent);
|
||||
InsertionPoint fakeInsertion(aInsertion->mParentFrame, parent);
|
||||
nsIFrame* result = GetInsertionPrevSibling(&fakeInsertion, child, aIsAppend,
|
||||
aIsRangeInsertSafe, nullptr, nullptr);
|
||||
MOZ_ASSERT(aInsertion->mParentFrame->GetContent() ==
|
||||
fakeInsertion.mParentFrame->GetContent());
|
||||
// fakeInsertion.mParentFrame may now be a continuation of the frame
|
||||
// we started with in the ctor above.
|
||||
aInsertion->mParentFrame = fakeInsertion.mParentFrame;
|
||||
return result;
|
||||
}
|
||||
|
||||
prevSibling = nextSibling->GetPrevSibling();
|
||||
}
|
||||
|
||||
nsIFrame* nextSibling = FindNextSibling(iter, childDisplay);
|
||||
if (nextSibling) {
|
||||
aInsertion->mParentFrame = nextSibling->GetParent()->GetContentInsertionFrame();
|
||||
} else {
|
||||
@@ -8082,22 +8086,6 @@ nsCSSFrameConstructor::ContentRangeInserted(nsIContent* aContainer,
|
||||
}
|
||||
}
|
||||
|
||||
if (!prevSibling) {
|
||||
// We're inserting the new frames as the first child. See if the
|
||||
// parent has a :before pseudo-element
|
||||
nsIFrame* firstChild = insertion.mParentFrame->PrincipalChildList().FirstChild();
|
||||
|
||||
if (firstChild &&
|
||||
nsLayoutUtils::IsGeneratedContentFor(container, firstChild,
|
||||
nsCSSPseudoElements::before)) {
|
||||
// Insert the new frames after the last continuation of the :before
|
||||
prevSibling = firstChild->GetTailContinuation();
|
||||
insertion.mParentFrame = prevSibling->GetParent()->GetContentInsertionFrame();
|
||||
// Don't change isAppend here; we'll can call AppendFrames as needed, and
|
||||
// the change to our prevSibling doesn't affect that.
|
||||
}
|
||||
}
|
||||
|
||||
FrameConstructionItemList items;
|
||||
ParentType parentType = GetParentType(frameType);
|
||||
FlattenedChildIterator iter(aContainer);
|
||||
|
||||
@@ -1962,64 +1962,53 @@ private:
|
||||
nsIFrame* aPrevSibling,
|
||||
nsFrameItems& aFrameItems);
|
||||
|
||||
/**
|
||||
* Find the right frame to use for aContent when looking for sibling
|
||||
* frames for aTargetContent. If aPrevSibling is true, this
|
||||
* will look for last continuations, etc, as necessary. This calls
|
||||
* IsValidSibling as needed; if that returns false it returns null.
|
||||
*
|
||||
* @param aContent the content to search for frames
|
||||
* @param aTargetContent the content we're finding a sibling frame for
|
||||
* @param aTargetContentDisplay the CSS display enum for aTargetContent if
|
||||
* already known, UNSET_DISPLAY otherwise. It will be filled in
|
||||
* if needed.
|
||||
* @param aParentFrame the nearest ancestor frame, used internally for
|
||||
* finding ::after / ::before frames
|
||||
* @param aPrevSibling true if we're searching in reverse DOM order
|
||||
*/
|
||||
nsIFrame* FindFrameForContentSibling(nsIContent* aContent,
|
||||
nsIContent* aTargetContent,
|
||||
mozilla::StyleDisplay& aTargetContentDisplay,
|
||||
nsContainerFrame* aParentFrame,
|
||||
bool aPrevSibling);
|
||||
// The direction in which we should look for siblings.
|
||||
enum class SiblingDirection
|
||||
{
|
||||
Forward,
|
||||
Backward,
|
||||
};
|
||||
|
||||
/**
|
||||
* Find the frame for the content immediately preceding the one aIter
|
||||
* points to, following continuations if necessary. aIter is passed by
|
||||
* value on purpose, so as not to modify the caller's iterator.
|
||||
* Find the frame for the content immediately next to the one aIter points to,
|
||||
* in the direction SiblingDirection indicates, following continuations if
|
||||
* necessary.
|
||||
*
|
||||
* aIter is passed by const reference on purpose, so as not to modify the
|
||||
* caller's iterator.
|
||||
*
|
||||
* @param aIter should be positioned such that aIter.GetPreviousChild()
|
||||
* is the first content to search for frames
|
||||
* @param aTargetContent the content we're finding a sibling frame for
|
||||
* @param aTargetContentDisplay the CSS display enum for aTargetContent if
|
||||
* already known, UNSET_DISPLAY otherwise. It will be filled in
|
||||
* if needed.
|
||||
* @param aParentFrame the nearest ancestor frame, used inernally for
|
||||
* finding ::after / ::before frames
|
||||
* @param aTargetContentDisplay the CSS display enum for the content aIter
|
||||
* points to if already known, UNSET_DISPLAY otherwise. It will be
|
||||
* filled in if needed.
|
||||
*/
|
||||
nsIFrame* FindPreviousSibling(mozilla::dom::FlattenedChildIterator aIter,
|
||||
nsIContent* aTargetContent,
|
||||
mozilla::StyleDisplay& aTargetContentDisplay,
|
||||
nsContainerFrame* aParentFrame);
|
||||
template<SiblingDirection>
|
||||
nsIFrame* FindSibling(const mozilla::dom::FlattenedChildIterator& aIter,
|
||||
mozilla::StyleDisplay& aTargetContentDisplay);
|
||||
|
||||
/**
|
||||
* Find the frame for the content node immediately following the one aIter
|
||||
* points to, following continuations if necessary. aIter is passed by value
|
||||
* on purpose, so as not to modify the caller's iterator.
|
||||
*
|
||||
* @param aIter should be positioned such that aIter.GetNextChild()
|
||||
* is the first content to search for frames
|
||||
* @param aTargetContent the content we're finding a sibling frame for
|
||||
* @param aTargetContentDisplay the CSS display enum for aTargetContent if
|
||||
* already known, UNSET_DISPLAY otherwise. It will be filled in
|
||||
* if needed.
|
||||
* @param aParentFrame the nearest ancestor frame, used inernally for
|
||||
* finding ::after / ::before frames
|
||||
*/
|
||||
nsIFrame* FindNextSibling(mozilla::dom::FlattenedChildIterator aIter,
|
||||
nsIContent* aTargetContent,
|
||||
mozilla::StyleDisplay& aTargetContentDisplay,
|
||||
nsContainerFrame* aParentFrame);
|
||||
// Helper for the implementation of FindSibling.
|
||||
template<SiblingDirection>
|
||||
nsIFrame* FindSiblingInternal(
|
||||
mozilla::dom::FlattenedChildIterator,
|
||||
nsIContent* aTargetContent,
|
||||
mozilla::StyleDisplay& aTargetContentDisplay);
|
||||
|
||||
// An alias of FindSibling<SiblingDirection::Forward>.
|
||||
nsIFrame* FindNextSibling(const mozilla::dom::FlattenedChildIterator& aIter,
|
||||
mozilla::StyleDisplay& aTargetContentDisplay);
|
||||
// An alias of FindSibling<SiblingDirection::Backwards>.
|
||||
nsIFrame* FindPreviousSibling(const mozilla::dom::FlattenedChildIterator& aIter,
|
||||
mozilla::StyleDisplay& aTargetContentDisplay);
|
||||
|
||||
// Given a potential first-continuation sibling frame for aTargetContent,
|
||||
// verify that it is an actual valid sibling for it, and return the
|
||||
// appropriate continuation the new frame for aTargetContent should be
|
||||
// inserted next to.
|
||||
nsIFrame* AdjustSiblingFrame(nsIFrame* aSibling,
|
||||
nsIContent* aTargetContent,
|
||||
mozilla::StyleDisplay& aTargetContentDisplay,
|
||||
SiblingDirection aDirection);
|
||||
|
||||
// Find the right previous sibling for an insertion. This also updates the
|
||||
// parent frame to point to the correct continuation of the parent frame to
|
||||
|
||||
@@ -132,7 +132,8 @@ nsFrameManager::Destroy()
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
/* static */ nsStyleContext*
|
||||
nsFrameManager::GetStyleContextInMap(UndisplayedMap* aMap, nsIContent* aContent)
|
||||
nsFrameManager::GetStyleContextInMap(UndisplayedMap* aMap,
|
||||
const nsIContent* aContent)
|
||||
{
|
||||
if (!aContent) {
|
||||
return nullptr;
|
||||
|
||||
@@ -80,7 +80,7 @@ public:
|
||||
void Destroy();
|
||||
|
||||
// Mapping undisplayed content
|
||||
nsStyleContext* GetUndisplayedContent(nsIContent* aContent)
|
||||
nsStyleContext* GetUndisplayedContent(const nsIContent* aContent)
|
||||
{
|
||||
if (!mUndisplayedMap) {
|
||||
return nullptr;
|
||||
@@ -105,7 +105,7 @@ public:
|
||||
/**
|
||||
* Return the registered display:contents style context for aContent, if any.
|
||||
*/
|
||||
nsStyleContext* GetDisplayContentsStyleFor(nsIContent* aContent)
|
||||
nsStyleContext* GetDisplayContentsStyleFor(const nsIContent* aContent)
|
||||
{
|
||||
if (!mDisplayContentsMap) {
|
||||
return nullptr;
|
||||
@@ -185,7 +185,7 @@ public:
|
||||
nsILayoutHistoryState* aState);
|
||||
protected:
|
||||
static nsStyleContext* GetStyleContextInMap(UndisplayedMap* aMap,
|
||||
nsIContent* aContent);
|
||||
const nsIContent* aContent);
|
||||
static mozilla::UndisplayedNode*
|
||||
GetAllUndisplayedNodesInMapFor(UndisplayedMap* aMap,
|
||||
nsIContent* aParentContent);
|
||||
|
||||
@@ -1608,33 +1608,6 @@ nsLayoutUtils::GetFloatFromPlaceholder(nsIFrame* aFrame) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// static
|
||||
bool
|
||||
nsLayoutUtils::IsGeneratedContentFor(nsIContent* aContent,
|
||||
nsIFrame* aFrame,
|
||||
nsIAtom* aPseudoElement)
|
||||
{
|
||||
NS_PRECONDITION(aFrame, "Must have a frame");
|
||||
NS_PRECONDITION(aPseudoElement, "Must have a pseudo name");
|
||||
|
||||
if (!aFrame->IsGeneratedContentFrame()) {
|
||||
return false;
|
||||
}
|
||||
nsIFrame* parent = aFrame->GetParent();
|
||||
NS_ASSERTION(parent, "Generated content can't be root frame");
|
||||
if (parent->IsGeneratedContentFrame()) {
|
||||
// Not the root of the generated content
|
||||
return false;
|
||||
}
|
||||
|
||||
if (aContent && parent->GetContent() != aContent) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return (aFrame->GetContent()->NodeInfo()->NameAtom() == nsGkAtoms::mozgeneratedcontentbefore) ==
|
||||
(aPseudoElement == nsCSSPseudoElements::before);
|
||||
}
|
||||
|
||||
// static
|
||||
nsIFrame*
|
||||
nsLayoutUtils::GetCrossDocParentFrame(const nsIFrame* aFrame,
|
||||
|
||||
@@ -352,23 +352,6 @@ public:
|
||||
*/
|
||||
static nsIFrame* GetRealPrimaryFrameFor(const nsIContent* aContent);
|
||||
|
||||
/**
|
||||
* IsGeneratedContentFor returns true if aFrame is the outermost
|
||||
* frame for generated content of type aPseudoElement for aContent.
|
||||
* aFrame *might not* have the aPseudoElement pseudo-style! For example
|
||||
* it might be a table wrapper frame and the inner table frame might
|
||||
* have the pseudo-style.
|
||||
*
|
||||
* @param aContent the content node we're looking at. If this is
|
||||
* null, then we just assume that aFrame has the right content
|
||||
* pointer.
|
||||
* @param aFrame the frame we're looking at
|
||||
* @param aPseudoElement the pseudo type we're interested in
|
||||
* @return whether aFrame is the generated aPseudoElement frame for aContent
|
||||
*/
|
||||
static bool IsGeneratedContentFor(nsIContent* aContent, nsIFrame* aFrame,
|
||||
nsIAtom* aPseudoElement);
|
||||
|
||||
#ifdef DEBUG
|
||||
// TODO: remove, see bug 598468.
|
||||
static bool gPreventAssertInCompareTreePosition;
|
||||
|
||||
@@ -249,7 +249,7 @@ asserts(0-10) == grid-fragmentation-015.html grid-fragmentation-015-ref.html # b
|
||||
== grid-fragmentation-dyn5-019.html grid-fragmentation-019-ref.html
|
||||
== grid-fragmentation-dyn1-020.html grid-fragmentation-020-ref.html
|
||||
== grid-fragmentation-dyn2-020.html grid-fragmentation-020-ref.html
|
||||
!= grid-fragmentation-dyn1-021.html grid-fragmentation-021-ref.html # bug 1251799
|
||||
== grid-fragmentation-dyn1-021.html grid-fragmentation-021-ref.html
|
||||
== grid-fragmentation-dyn2-021.html grid-fragmentation-021-ref.html
|
||||
== grid-fragmentation-dyn3-021.html grid-fragmentation-021-ref.html
|
||||
== grid-fragmentation-dyn4-021.html grid-fragmentation-021-ref.html
|
||||
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
<!doctype html>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS Test Reference</title>
|
||||
<link rel="author" title="Emilio Cobos Álvarez" href="mailto:emilio@crisal.io">
|
||||
PASS
|
||||
Reference in New Issue
Block a user