mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 508725 - Part 5: Record the <style scoped> elements in scope in preparation for selector matching. r=dbaron
This commit is contained in:
parent
ad3f65836e
commit
e4e4c560a0
@ -2294,7 +2294,7 @@ nsCSSFrameConstructor::ConstructDocElementFrame(Element* aDocEle
|
||||
nullptr, aFrameState);
|
||||
// Initialize the ancestor filter with null for now; we'll push
|
||||
// aDocElement once we finish resolving style for it.
|
||||
state.mTreeMatchContext.mAncestorFilter.Init(nullptr);
|
||||
state.mTreeMatchContext.InitAncestors(nullptr);
|
||||
|
||||
// XXXbz why, exactly?
|
||||
if (!mTempFrameTreeState)
|
||||
@ -2361,8 +2361,8 @@ nsCSSFrameConstructor::ConstructDocElementFrame(Element* aDocEle
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
AncestorFilter::AutoAncestorPusher
|
||||
ancestorPusher(true, state.mTreeMatchContext.mAncestorFilter, aDocElement);
|
||||
TreeMatchContext::AutoAncestorPusher
|
||||
ancestorPusher(true, state.mTreeMatchContext, aDocElement);
|
||||
|
||||
// Make sure to start any background image loads for the root element now.
|
||||
styleContext->StartBackgroundImageLoads();
|
||||
@ -3571,9 +3571,9 @@ nsCSSFrameConstructor::ConstructFrameFromItemInternal(FrameConstructionItem& aIt
|
||||
// frames constructed), this is the best place to bottleneck the
|
||||
// pushing of the content instead of having to do it in multiple
|
||||
// places.
|
||||
AncestorFilter::AutoAncestorPusher
|
||||
TreeMatchContext::AutoAncestorPusher
|
||||
ancestorPusher(aState.mTreeMatchContext.mAncestorFilter.HasFilter(),
|
||||
aState.mTreeMatchContext.mAncestorFilter,
|
||||
aState.mTreeMatchContext,
|
||||
content->IsElement() ? content->AsElement() : nullptr);
|
||||
|
||||
nsIFrame* newFrame;
|
||||
@ -3807,9 +3807,9 @@ nsCSSFrameConstructor::CreateAnonymousFrames(nsFrameConstructorState& aState,
|
||||
|
||||
nsFrameConstructorState::PendingBindingAutoPusher pusher(aState,
|
||||
aPendingBinding);
|
||||
AncestorFilter::AutoAncestorPusher
|
||||
TreeMatchContext::AutoAncestorPusher
|
||||
ancestorPusher(aState.mTreeMatchContext.mAncestorFilter.HasFilter(),
|
||||
aState.mTreeMatchContext.mAncestorFilter,
|
||||
aState.mTreeMatchContext,
|
||||
aParent->AsElement());
|
||||
|
||||
nsIAnonymousContentCreator* creator = do_QueryFrame(aParentFrame);
|
||||
@ -6608,7 +6608,7 @@ nsCSSFrameConstructor::ContentAppended(nsIContent* aContainer,
|
||||
nsFrameConstructorState state(mPresShell, mFixedContainingBlock,
|
||||
GetAbsoluteContainingBlock(parentFrame),
|
||||
GetFloatContainingBlock(parentFrame));
|
||||
state.mTreeMatchContext.mAncestorFilter.Init(aContainer->AsElement());
|
||||
state.mTreeMatchContext.InitAncestors(aContainer->AsElement());
|
||||
|
||||
// See if the containing block has :first-letter style applied.
|
||||
bool haveFirstLetterStyle = false, haveFirstLineStyle = false;
|
||||
@ -7044,9 +7044,9 @@ nsCSSFrameConstructor::ContentRangeInserted(nsIContent* aContainer,
|
||||
GetAbsoluteContainingBlock(parentFrame),
|
||||
GetFloatContainingBlock(parentFrame),
|
||||
aFrameState);
|
||||
state.mTreeMatchContext.mAncestorFilter.Init(aContainer ?
|
||||
aContainer->AsElement() :
|
||||
nullptr);
|
||||
state.mTreeMatchContext.InitAncestors(aContainer ?
|
||||
aContainer->AsElement() :
|
||||
nullptr);
|
||||
|
||||
// Recover state for the containing block - we need to know if
|
||||
// it has :first-letter or :first-line style applied to it. The
|
||||
@ -11281,9 +11281,9 @@ nsCSSFrameConstructor::BuildInlineChildItems(nsFrameConstructorState& aState,
|
||||
nsStyleContext* const parentStyleContext = aParentItem.mStyleContext;
|
||||
nsIContent* const parentContent = aParentItem.mContent;
|
||||
|
||||
AncestorFilter::AutoAncestorPusher
|
||||
TreeMatchContext::AutoAncestorPusher
|
||||
ancestorPusher(aState.mTreeMatchContext.mAncestorFilter.HasFilter(),
|
||||
aState.mTreeMatchContext.mAncestorFilter,
|
||||
aState.mTreeMatchContext,
|
||||
parentContent->AsElement());
|
||||
|
||||
CreateGeneratedContentItem(aState, nullptr, parentContent, parentStyleContext,
|
||||
|
@ -1379,8 +1379,8 @@ nsFrameManager::ReResolveStyleContext(nsPresContext *aPresContext,
|
||||
if (checkUndisplayed && mUndisplayedMap) {
|
||||
UndisplayedNode* undisplayed =
|
||||
mUndisplayedMap->GetFirstNode(undisplayedParent);
|
||||
for (AncestorFilter::AutoAncestorPusher
|
||||
pushAncestor(undisplayed, aTreeMatchContext.mAncestorFilter,
|
||||
for (TreeMatchContext::AutoAncestorPusher
|
||||
pushAncestor(undisplayed, aTreeMatchContext,
|
||||
undisplayedParent ? undisplayedParent->AsElement()
|
||||
: nullptr);
|
||||
undisplayed; undisplayed = undisplayed->mNext) {
|
||||
@ -1536,9 +1536,9 @@ nsFrameManager::ReResolveStyleContext(nsPresContext *aPresContext,
|
||||
|
||||
// now do children
|
||||
nsIFrame::ChildListIterator lists(aFrame);
|
||||
for (AncestorFilter::AutoAncestorPusher
|
||||
for (TreeMatchContext::AutoAncestorPusher
|
||||
pushAncestor(!lists.IsDone(),
|
||||
aTreeMatchContext.mAncestorFilter,
|
||||
aTreeMatchContext,
|
||||
content && content->IsElement() ? content->AsElement()
|
||||
: nullptr);
|
||||
!lists.IsDone(); lists.Next()) {
|
||||
@ -1680,7 +1680,7 @@ nsFrameManager::ComputeStyleChangeFor(nsIFrame *aFrame,
|
||||
nsIContent *parent = content ? content->GetParent() : nullptr;
|
||||
Element *parentElement =
|
||||
parent && parent->IsElement() ? parent->AsElement() : nullptr;
|
||||
treeMatchContext.mAncestorFilter.Init(parentElement);
|
||||
treeMatchContext.InitAncestors(parentElement);
|
||||
nsTArray<nsIContent*> visibleKidsOfHiddenElement;
|
||||
do {
|
||||
// Outer loop over special siblings
|
||||
|
@ -3261,14 +3261,14 @@ nsCSSRuleProcessor::SelectorListMatches(Element* aElement,
|
||||
return false;
|
||||
}
|
||||
|
||||
// AncestorFilter out of line methods
|
||||
// TreeMatchContext and AncestorFilter out of line methods
|
||||
void
|
||||
AncestorFilter::Init(Element *aElement)
|
||||
TreeMatchContext::InitAncestors(Element *aElement)
|
||||
{
|
||||
MOZ_ASSERT(!mFilter);
|
||||
MOZ_ASSERT(mHashes.IsEmpty());
|
||||
MOZ_ASSERT(!mAncestorFilter.mFilter);
|
||||
MOZ_ASSERT(mAncestorFilter.mHashes.IsEmpty());
|
||||
|
||||
mFilter = new Filter();
|
||||
mAncestorFilter.mFilter = new AncestorFilter::Filter();
|
||||
|
||||
if (MOZ_LIKELY(aElement)) {
|
||||
MOZ_ASSERT(aElement->IsInDoc(),
|
||||
@ -3289,7 +3289,8 @@ AncestorFilter::Init(Element *aElement)
|
||||
|
||||
// Now push them in reverse order.
|
||||
for (uint32_t i = ancestors.Length(); i-- != 0; ) {
|
||||
PushAncestor(ancestors[i]);
|
||||
mAncestorFilter.PushAncestor(ancestors[i]);
|
||||
PushStyleScope(ancestors[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -26,6 +26,7 @@ class nsIStyleSheet;
|
||||
class nsIAtom;
|
||||
class nsICSSPseudoComparator;
|
||||
class nsAttrValue;
|
||||
struct TreeMatchContext;
|
||||
|
||||
/**
|
||||
* An AncestorFilter is used to keep track of ancestors so that we can
|
||||
@ -33,44 +34,12 @@ class nsAttrValue;
|
||||
* element.
|
||||
*/
|
||||
class NS_STACK_CLASS AncestorFilter {
|
||||
friend struct TreeMatchContext;
|
||||
public:
|
||||
/**
|
||||
* Initialize the filter. If aElement is not null, it and all its
|
||||
* ancestors will be passed to PushAncestor, starting from the root
|
||||
* and going down the tree.
|
||||
*/
|
||||
void Init(mozilla::dom::Element *aElement);
|
||||
|
||||
/* Maintenance of our ancestor state */
|
||||
void PushAncestor(mozilla::dom::Element *aElement);
|
||||
void PopAncestor();
|
||||
|
||||
/* Helper class for maintaining the ancestor state */
|
||||
class NS_STACK_CLASS AutoAncestorPusher {
|
||||
public:
|
||||
AutoAncestorPusher(bool aDoPush,
|
||||
AncestorFilter &aFilter,
|
||||
mozilla::dom::Element *aElement
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
|
||||
: mPushed(aDoPush && aElement), mFilter(aFilter)
|
||||
{
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
|
||||
if (mPushed) {
|
||||
mFilter.PushAncestor(aElement);
|
||||
}
|
||||
}
|
||||
~AutoAncestorPusher() {
|
||||
if (mPushed) {
|
||||
mFilter.PopAncestor();
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
bool mPushed;
|
||||
AncestorFilter &mFilter;
|
||||
MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
|
||||
};
|
||||
|
||||
/* Check whether we might have an ancestor matching one of the given
|
||||
atom hashes. |hashes| must have length hashListLength */
|
||||
template<size_t hashListLength>
|
||||
@ -164,11 +133,66 @@ struct NS_STACK_CLASS TreeMatchContext {
|
||||
return mHaveSpecifiedScope;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the ancestor filter and list of style scopes. If aElement is
|
||||
* not null, it and all its ancestors will be passed to
|
||||
* mAncestorFilter.PushAncestor and PushStyleScope, starting from the root and
|
||||
* going down the tree.
|
||||
*/
|
||||
void InitAncestors(mozilla::dom::Element *aElement);
|
||||
|
||||
void PushStyleScope(mozilla::dom::Element* aElement)
|
||||
{
|
||||
NS_PRECONDITION(aElement, "aElement must not be null");
|
||||
if (aElement->IsScopedStyleRoot()) {
|
||||
mStyleScopes.AppendElement(aElement);
|
||||
}
|
||||
}
|
||||
|
||||
void PopStyleScope(mozilla::dom::Element* aElement)
|
||||
{
|
||||
NS_PRECONDITION(aElement, "aElement must not be null");
|
||||
if (mStyleScopes.SafeLastElement(nullptr) == aElement) {
|
||||
mStyleScopes.TruncateLength(mStyleScopes.Length() - 1);
|
||||
}
|
||||
}
|
||||
|
||||
// Is this matching operation for the creation of a style context?
|
||||
// (If it is, we need to set slow selector bits on nodes indicating
|
||||
// that certain restyling needs to happen.)
|
||||
const bool mForStyling;
|
||||
|
||||
/* Helper class for maintaining the ancestor state */
|
||||
class NS_STACK_CLASS AutoAncestorPusher {
|
||||
public:
|
||||
AutoAncestorPusher(bool aDoPush,
|
||||
TreeMatchContext &aTreeMatchContext,
|
||||
mozilla::dom::Element *aElement
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
|
||||
: mPushed(aDoPush && aElement),
|
||||
mTreeMatchContext(aTreeMatchContext),
|
||||
mElement(aElement)
|
||||
{
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
|
||||
if (mPushed) {
|
||||
mTreeMatchContext.mAncestorFilter.PushAncestor(aElement);
|
||||
mTreeMatchContext.PushStyleScope(aElement);
|
||||
}
|
||||
}
|
||||
~AutoAncestorPusher() {
|
||||
if (mPushed) {
|
||||
mTreeMatchContext.mAncestorFilter.PopAncestor();
|
||||
mTreeMatchContext.PopStyleScope(mElement);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
bool mPushed;
|
||||
TreeMatchContext& mTreeMatchContext;
|
||||
mozilla::dom::Element* mElement;
|
||||
MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
|
||||
};
|
||||
|
||||
private:
|
||||
// When mVisitedHandling is eRelevantLinkUnvisited, this is set to true if a
|
||||
// relevant link (see explanation in definition of VisitedHandling enum) was
|
||||
@ -218,6 +242,10 @@ struct NS_STACK_CLASS TreeMatchContext {
|
||||
eMatchVisitedDefault
|
||||
};
|
||||
|
||||
// List of ancestor elements that define a style scope (due to having a
|
||||
// <style scoped> child).
|
||||
nsAutoTArray<mozilla::dom::Element*, 1> mStyleScopes;
|
||||
|
||||
// Constructor to use when creating a tree match context for styling
|
||||
TreeMatchContext(bool aForStyling,
|
||||
nsRuleWalker::VisitedHandlingType aVisitedHandling,
|
||||
|
Loading…
Reference in New Issue
Block a user