mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 598832 part 7. Stop caching the content state of elements; just reget it from the DOM as needed. r=dbaron
This commit is contained in:
parent
06fc5fd9e4
commit
c2d78db208
@ -1121,8 +1121,7 @@ RuleProcessorData::RuleProcessorData(nsPresContext* aPresContext,
|
||||
mElement(aElement),
|
||||
mRuleWalker(aRuleWalker),
|
||||
mPreviousSiblingData(nsnull),
|
||||
mParentData(nsnull),
|
||||
mGotContentState(PR_FALSE)
|
||||
mParentData(nsnull)
|
||||
{
|
||||
MOZ_COUNT_CTOR(RuleProcessorData);
|
||||
|
||||
@ -1147,9 +1146,6 @@ RuleProcessorData::RuleProcessorData(nsPresContext* aPresContext,
|
||||
|
||||
// get the namespace
|
||||
mNameSpaceID = aElement->GetNameSpaceID();
|
||||
|
||||
// No need to initialize mContentState; the ContentState() accessor will handle
|
||||
// that.
|
||||
}
|
||||
|
||||
RuleProcessorData::~RuleProcessorData()
|
||||
@ -1205,27 +1201,30 @@ static void GetLang(nsIContent* aContent, nsString& aLang)
|
||||
}
|
||||
}
|
||||
|
||||
/* static */
|
||||
nsEventStates
|
||||
RuleProcessorData::ContentState()
|
||||
nsCSSRuleProcessor::GetContentState(Element* aElement)
|
||||
{
|
||||
if (!mGotContentState) {
|
||||
mGotContentState = PR_TRUE;
|
||||
mContentState = mPresContext ?
|
||||
mPresContext->EventStateManager()->GetContentState(mElement) :
|
||||
mElement->IntrinsicState();
|
||||
|
||||
// If we are not supposed to mark visited links as such, be sure to
|
||||
// flip the bits appropriately. We want to do this here, rather
|
||||
// than in GetContentStateForVisitedHandling, so that we don't
|
||||
// expose that :visited support is disabled to the Web page.
|
||||
if ((!gSupportVisitedPseudo ||
|
||||
gPrivateBrowsingObserver->InPrivateBrowsing()) &&
|
||||
mContentState.HasState(NS_EVENT_STATE_VISITED)) {
|
||||
mContentState &= ~NS_EVENT_STATE_VISITED;
|
||||
mContentState |= NS_EVENT_STATE_UNVISITED;
|
||||
}
|
||||
nsIPresShell* shell = aElement->GetOwnerDoc()->GetShell();
|
||||
nsPresContext* presContext;
|
||||
nsEventStates state;
|
||||
if (shell && (presContext = shell->GetPresContext())) {
|
||||
state = presContext->EventStateManager()->GetContentState(aElement);
|
||||
} else {
|
||||
state = aElement->IntrinsicState();
|
||||
}
|
||||
return mContentState;
|
||||
|
||||
// If we are not supposed to mark visited links as such, be sure to
|
||||
// flip the bits appropriately. We want to do this here, rather
|
||||
// than in GetContentStateForVisitedHandling, so that we don't
|
||||
// expose that :visited support is disabled to the Web page.
|
||||
if ((!gSupportVisitedPseudo ||
|
||||
gPrivateBrowsingObserver->InPrivateBrowsing()) &&
|
||||
state.HasState(NS_EVENT_STATE_VISITED)) {
|
||||
state &= ~NS_EVENT_STATE_VISITED;
|
||||
state |= NS_EVENT_STATE_UNVISITED;
|
||||
}
|
||||
return state;
|
||||
}
|
||||
|
||||
nsEventStates
|
||||
@ -1234,21 +1233,24 @@ RuleProcessorData::DocumentState()
|
||||
return mElement->GetOwnerDoc()->GetDocumentState();
|
||||
}
|
||||
|
||||
/* static */
|
||||
PRBool
|
||||
RuleProcessorData::IsLink()
|
||||
nsCSSRuleProcessor::IsLink(Element* aElement)
|
||||
{
|
||||
nsEventStates state = ContentState();
|
||||
nsEventStates state = aElement->IntrinsicState();
|
||||
return state.HasAtLeastOneOfStates(NS_EVENT_STATE_VISITED | NS_EVENT_STATE_UNVISITED);
|
||||
}
|
||||
|
||||
/* static */
|
||||
nsEventStates
|
||||
RuleProcessorData::GetContentStateForVisitedHandling(
|
||||
nsCSSRuleProcessor::GetContentStateForVisitedHandling(
|
||||
Element* aElement,
|
||||
nsRuleWalker::VisitedHandlingType aVisitedHandling,
|
||||
PRBool aIsRelevantLink)
|
||||
{
|
||||
nsEventStates contentState = ContentState();
|
||||
nsEventStates contentState = GetContentState(aElement);
|
||||
if (contentState.HasAtLeastOneOfStates(NS_EVENT_STATE_VISITED | NS_EVENT_STATE_UNVISITED)) {
|
||||
NS_ABORT_IF_FALSE(IsLink(), "IsLink() should match state");
|
||||
NS_ABORT_IF_FALSE(IsLink(aElement), "IsLink() should match state");
|
||||
contentState &= ~(NS_EVENT_STATE_VISITED | NS_EVENT_STATE_UNVISITED);
|
||||
if (aIsRelevantLink) {
|
||||
switch (aVisitedHandling) {
|
||||
@ -1342,7 +1344,7 @@ static PRBool ValueIncludes(const nsSubstring& aValueList,
|
||||
|
||||
// Return whether we should apply a "global" (i.e., universal-tag)
|
||||
// selector for event states in quirks mode. Note that
|
||||
// |data.IsLink()| is checked separately by the caller, so we return
|
||||
// |IsLink()| is checked separately by the caller, so we return
|
||||
// false for |nsGkAtoms::a|, which here means a named anchor.
|
||||
inline PRBool IsQuirkEventSensitive(nsIAtom *aContentTag)
|
||||
{
|
||||
@ -1992,7 +1994,7 @@ static PRBool SelectorMatches(Element* aElement,
|
||||
// (unnegated)). This at least makes it closer to the spec.
|
||||
!isNegated &&
|
||||
// important for |IsQuirkEventSensitive|:
|
||||
aElement->IsHTML() && !data.IsLink() &&
|
||||
aElement->IsHTML() && !nsCSSRuleProcessor::IsLink(aElement) &&
|
||||
!IsQuirkEventSensitive(data.mContentTag)) {
|
||||
// In quirks mode, only make certain elements sensitive to
|
||||
// selectors ":hover" and ":active".
|
||||
@ -2002,7 +2004,9 @@ static PRBool SelectorMatches(Element* aElement,
|
||||
if (aDependence)
|
||||
*aDependence = PR_TRUE;
|
||||
} else {
|
||||
nsEventStates contentState = data.GetContentStateForVisitedHandling(
|
||||
nsEventStates contentState =
|
||||
nsCSSRuleProcessor::GetContentStateForVisitedHandling(
|
||||
aElement,
|
||||
aTreeMatchContext.mVisitedHandling,
|
||||
aNodeMatchContext.mIsRelevantLink);
|
||||
if (!contentState.HasAtLeastOneOfStates(statesToCheck)) {
|
||||
@ -2183,8 +2187,9 @@ static PRBool SelectorMatchesTree(Element* aPrevElement,
|
||||
if (! data) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
NodeMatchContext nodeContext(nsEventStates(), aLookForRelevantLink &&
|
||||
data->IsLink());
|
||||
NodeMatchContext nodeContext(nsEventStates(),
|
||||
aLookForRelevantLink &&
|
||||
nsCSSRuleProcessor::IsLink(data->mElement));
|
||||
if (nodeContext.mIsRelevantLink) {
|
||||
// If we find an ancestor of the matched node that is a link
|
||||
// during the matching process, then it's the relevant link (see
|
||||
@ -2240,7 +2245,8 @@ static inline
|
||||
void ContentEnumFunc(css::StyleRule* aRule, nsCSSSelector* aSelector,
|
||||
RuleProcessorData* data)
|
||||
{
|
||||
NodeMatchContext nodeContext(nsEventStates(), data->IsLink());
|
||||
NodeMatchContext nodeContext(nsEventStates(),
|
||||
nsCSSRuleProcessor::IsLink(data->mElement));
|
||||
if (nodeContext.mIsRelevantLink) {
|
||||
data->mHaveRelevantLink = PR_TRUE;
|
||||
}
|
||||
|
@ -50,6 +50,7 @@
|
||||
#include "nsTArray.h"
|
||||
#include "nsAutoPtr.h"
|
||||
#include "nsCSSRules.h"
|
||||
#include "nsRuleWalker.h"
|
||||
|
||||
struct RuleCascadeData;
|
||||
struct nsCSSSelectorList;
|
||||
@ -94,6 +95,25 @@ public:
|
||||
RuleProcessorData& aData,
|
||||
nsCSSSelectorList* aSelectorList);
|
||||
|
||||
/*
|
||||
* Helper to get the content state for a content node. This may be
|
||||
* slightly adjusted from IntrinsicState().
|
||||
*/
|
||||
static nsEventStates GetContentState(mozilla::dom::Element* aElement);
|
||||
|
||||
/*
|
||||
* Helper to get the content state for :visited handling for an element
|
||||
*/
|
||||
static nsEventStates GetContentStateForVisitedHandling(
|
||||
mozilla::dom::Element* aElement,
|
||||
nsRuleWalker::VisitedHandlingType aVisitedHandling,
|
||||
PRBool aIsRelevantLink);
|
||||
|
||||
/*
|
||||
* Helper to test whether a node is a link
|
||||
*/
|
||||
static PRBool IsLink(mozilla::dom::Element* aElement);
|
||||
|
||||
// nsIStyleRuleProcessor
|
||||
virtual void RulesMatching(ElementRuleProcessorData* aData);
|
||||
|
||||
|
@ -70,6 +70,7 @@
|
||||
#include "nsRuleData.h"
|
||||
#include "nsContentErrors.h"
|
||||
#include "nsRuleProcessorData.h"
|
||||
#include "nsCSSRuleProcessor.h"
|
||||
#include "mozilla/dom/Element.h"
|
||||
#include "nsCSSFrameConstructor.h"
|
||||
|
||||
@ -221,11 +222,12 @@ nsHTMLStyleSheet::RulesMatching(ElementRuleProcessorData* aData)
|
||||
// if we have anchor colors, check if this is an anchor with an href
|
||||
if (tag == nsGkAtoms::a) {
|
||||
if (mLinkRule || mVisitedRule || mActiveRule) {
|
||||
nsEventStates state = aData->GetContentStateForVisitedHandling(
|
||||
nsEventStates state = nsCSSRuleProcessor::GetContentStateForVisitedHandling(
|
||||
aData->mElement,
|
||||
ruleWalker->VisitedHandling(),
|
||||
// If the node being matched is a link,
|
||||
// it's the relevant link.
|
||||
aData->IsLink());
|
||||
nsCSSRuleProcessor::IsLink(aData->mElement));
|
||||
if (mLinkRule && state.HasState(NS_EVENT_STATE_UNVISITED)) {
|
||||
ruleWalker->Forward(mLinkRule);
|
||||
ruleWalker->SetHaveRelevantLink();
|
||||
@ -236,7 +238,7 @@ nsHTMLStyleSheet::RulesMatching(ElementRuleProcessorData* aData)
|
||||
}
|
||||
|
||||
// No need to add to the active rule if it's not a link
|
||||
if (mActiveRule && aData->IsLink() &&
|
||||
if (mActiveRule && nsCSSRuleProcessor::IsLink(aData->mElement) &&
|
||||
state.HasState(NS_EVENT_STATE_ACTIVE)) {
|
||||
ruleWalker->Forward(mActiveRule);
|
||||
}
|
||||
@ -275,7 +277,7 @@ nsHTMLStyleSheet::HasStateDependentStyle(StateRuleProcessorData* aData)
|
||||
{
|
||||
if (aData->mElement->IsHTML() &&
|
||||
aData->mContentTag == nsGkAtoms::a &&
|
||||
aData->IsLink() &&
|
||||
nsCSSRuleProcessor::IsLink(aData->mElement) &&
|
||||
((mActiveRule && aData->mStateMask.HasState(NS_EVENT_STATE_ACTIVE)) ||
|
||||
(mLinkRule && aData->mStateMask.HasState(NS_EVENT_STATE_VISITED)) ||
|
||||
(mVisitedRule && aData->mStateMask.HasState(NS_EVENT_STATE_VISITED)))) {
|
||||
|
@ -172,13 +172,7 @@ public:
|
||||
mVisitedHandling = mRuleWalker->VisitedHandling();
|
||||
}
|
||||
|
||||
nsEventStates ContentState();
|
||||
nsEventStates DocumentState();
|
||||
PRBool IsLink();
|
||||
|
||||
nsEventStates GetContentStateForVisitedHandling(
|
||||
nsRuleWalker::VisitedHandlingType aVisitedHandling,
|
||||
PRBool aIsRelevantLink);
|
||||
|
||||
nsPresContext* mPresContext;
|
||||
mozilla::dom::Element* mElement; // weak ref, must not be null
|
||||
@ -195,15 +189,6 @@ public:
|
||||
// selectors require matching of prior siblings or ancestors.
|
||||
RuleProcessorData* mPreviousSiblingData;
|
||||
RuleProcessorData* mParentData;
|
||||
|
||||
private:
|
||||
// mContentState is initialized lazily.
|
||||
nsEventStates mContentState; // eventStateMgr->GetContentState() or
|
||||
// mElement->IntrinsicState() if we have no ESM
|
||||
// adjusted for not supporting :visited (but
|
||||
// with visitedness information when we support
|
||||
// it).
|
||||
PRPackedBool mGotContentState;
|
||||
};
|
||||
|
||||
struct ElementRuleProcessorData : public RuleProcessorData {
|
||||
|
@ -781,8 +781,9 @@ nsStyleSet::ResolveStyleFor(Element* aElement,
|
||||
}
|
||||
|
||||
return GetContext(aParentContext, ruleNode, visitedRuleNode,
|
||||
data.IsLink(),
|
||||
data.ContentState().HasState(NS_EVENT_STATE_VISITED),
|
||||
nsCSSRuleProcessor::IsLink(aElement),
|
||||
nsCSSRuleProcessor::GetContentState(aElement).
|
||||
HasState(NS_EVENT_STATE_VISITED),
|
||||
nsnull, nsCSSPseudoElements::ePseudo_NotPseudoElement);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user