Bug 722853 - Derive private browsing status from docshell when assigning element states. r=dbaron

This commit is contained in:
Josh Matthews 2012-03-30 02:16:22 -04:00
parent 2b7676bb73
commit 50686229de
5 changed files with 23 additions and 70 deletions

View File

@ -88,7 +88,6 @@
#include "nsStyleSet.h"
#include "prlog.h"
#include "nsIObserverService.h"
#include "nsIPrivateBrowsingService.h"
#include "nsNetCID.h"
#include "mozilla/Services.h"
#include "mozilla/dom/Element.h"
@ -1080,63 +1079,6 @@ RuleCascadeData::AttributeListFor(nsIAtom* aAttribute)
return &entry->mSelectors;
}
class nsPrivateBrowsingObserver : nsIObserver,
nsSupportsWeakReference
{
public:
nsPrivateBrowsingObserver();
NS_DECL_ISUPPORTS
NS_DECL_NSIOBSERVER
void Init();
bool InPrivateBrowsing() const { return mInPrivateBrowsing; }
private:
bool mInPrivateBrowsing;
};
NS_IMPL_ISUPPORTS2(nsPrivateBrowsingObserver, nsIObserver, nsISupportsWeakReference)
nsPrivateBrowsingObserver::nsPrivateBrowsingObserver()
: mInPrivateBrowsing(false)
{
}
void
nsPrivateBrowsingObserver::Init()
{
nsCOMPtr<nsIObserverService> observerService =
mozilla::services::GetObserverService();
if (observerService) {
observerService->AddObserver(this, "profile-after-change", true);
observerService->AddObserver(this, NS_PRIVATE_BROWSING_SWITCH_TOPIC, true);
}
}
nsresult
nsPrivateBrowsingObserver::Observe(nsISupports *aSubject,
const char *aTopic,
const PRUnichar *aData)
{
if (!strcmp(aTopic, NS_PRIVATE_BROWSING_SWITCH_TOPIC)) {
if (!nsCRT::strcmp(aData, NS_LITERAL_STRING(NS_PRIVATE_BROWSING_ENTER).get())) {
mInPrivateBrowsing = true;
} else {
mInPrivateBrowsing = false;
}
}
else if (!strcmp(aTopic, "profile-after-change")) {
nsCOMPtr<nsIPrivateBrowsingService> pbService =
do_GetService(NS_PRIVATE_BROWSING_SERVICE_CONTRACTID);
if (pbService)
pbService->GetPrivateBrowsingEnabled(&mInPrivateBrowsing);
}
return NS_OK;
}
static nsPrivateBrowsingObserver *gPrivateBrowsingObserver = nsnull;
// -------------------------------
// CSS Style rule processor implementation
//
@ -1170,11 +1112,6 @@ nsCSSRuleProcessor::Startup()
Preferences::AddBoolVarCache(&gSupportVisitedPseudo, VISITED_PSEUDO_PREF,
true);
gPrivateBrowsingObserver = new nsPrivateBrowsingObserver();
NS_ENSURE_TRUE(gPrivateBrowsingObserver, NS_ERROR_OUT_OF_MEMORY);
NS_ADDREF(gPrivateBrowsingObserver);
gPrivateBrowsingObserver->Init();
return NS_OK;
}
@ -1311,8 +1248,6 @@ nsCSSRuleProcessor::FreeSystemMetrics()
nsCSSRuleProcessor::Shutdown()
{
FreeSystemMetrics();
// Make sure we don't crash if Shutdown is called before Init
NS_IF_RELEASE(gPrivateBrowsingObserver);
}
/* static */ bool
@ -1336,7 +1271,7 @@ nsCSSRuleProcessor::GetWindowsThemeIdentifier()
/* static */
nsEventStates
nsCSSRuleProcessor::GetContentState(Element* aElement)
nsCSSRuleProcessor::GetContentState(Element* aElement, const TreeMatchContext& aTreeMatchContext)
{
nsEventStates state = aElement->StyleState();
@ -1347,7 +1282,7 @@ nsCSSRuleProcessor::GetContentState(Element* aElement)
if (state.HasState(NS_EVENT_STATE_VISITED) &&
(!gSupportVisitedPseudo ||
aElement->OwnerDoc()->IsBeingUsedAsImage() ||
gPrivateBrowsingObserver->InPrivateBrowsing())) {
aTreeMatchContext.mUsingPrivateBrowsing)) {
state &= ~NS_EVENT_STATE_VISITED;
state |= NS_EVENT_STATE_UNVISITED;
}
@ -1366,10 +1301,11 @@ nsCSSRuleProcessor::IsLink(Element* aElement)
nsEventStates
nsCSSRuleProcessor::GetContentStateForVisitedHandling(
Element* aElement,
const TreeMatchContext& aTreeMatchContext,
nsRuleWalker::VisitedHandlingType aVisitedHandling,
bool aIsRelevantLink)
{
nsEventStates contentState = GetContentState(aElement);
nsEventStates contentState = GetContentState(aElement, aTreeMatchContext);
if (contentState.HasAtLeastOneOfStates(NS_EVENT_STATE_VISITED | NS_EVENT_STATE_UNVISITED)) {
NS_ABORT_IF_FALSE(IsLink(aElement), "IsLink() should match state");
contentState &= ~(NS_EVENT_STATE_VISITED | NS_EVENT_STATE_UNVISITED);
@ -2131,6 +2067,7 @@ static bool SelectorMatches(Element* aElement,
nsEventStates contentState =
nsCSSRuleProcessor::GetContentStateForVisitedHandling(
aElement,
aTreeMatchContext,
aTreeMatchContext.VisitedHandling(),
aNodeMatchContext.mIsRelevantLink);
if (!contentState.HasAtLeastOneOfStates(statesToCheck)) {

View File

@ -103,13 +103,15 @@ public:
* Helper to get the content state for a content node. This may be
* slightly adjusted from IntrinsicState().
*/
static nsEventStates GetContentState(mozilla::dom::Element* aElement);
static nsEventStates GetContentState(mozilla::dom::Element* aElement,
const TreeMatchContext& aTreeMatchContext);
/*
* Helper to get the content state for :visited handling for an element
*/
static nsEventStates GetContentStateForVisitedHandling(
mozilla::dom::Element* aElement,
const TreeMatchContext& aTreeMatchContext,
nsRuleWalker::VisitedHandlingType aVisitedHandling,
bool aIsRelevantLink);

View File

@ -212,6 +212,7 @@ nsHTMLStyleSheet::RulesMatching(ElementRuleProcessorData* aData)
if (mLinkRule || mVisitedRule || mActiveRule) {
nsEventStates state = nsCSSRuleProcessor::GetContentStateForVisitedHandling(
aData->mElement,
aData->mTreeMatchContext,
aData->mTreeMatchContext.VisitedHandling(),
// If the node being matched is a link,
// it's the relevant link.

View File

@ -51,6 +51,7 @@
#include "nsCSSPseudoElements.h"
#include "nsRuleWalker.h"
#include "nsNthIndexCache.h"
#include "nsILoadContext.h"
#include "mozilla/BloomFilter.h"
#include "mozilla/GuardObjects.h"
@ -221,6 +222,9 @@ struct NS_STACK_CLASS TreeMatchContext {
// An ancestor filter
AncestorFilter mAncestorFilter;
// Whether this document is using PB mode
bool mUsingPrivateBrowsing;
// Constructor to use when creating a tree match context for styling
TreeMatchContext(bool aForStyling,
nsRuleWalker::VisitedHandlingType aVisitedHandling,
@ -232,7 +236,16 @@ struct NS_STACK_CLASS TreeMatchContext {
, mScopedRoot(nsnull)
, mIsHTMLDocument(aDocument->IsHTML())
, mCompatMode(aDocument->GetCompatibilityMode())
, mUsingPrivateBrowsing(false)
{
nsCOMPtr<nsISupports> container = mDocument->GetContainer();
if (container) {
nsCOMPtr<nsILoadContext> loadContext = do_QueryInterface(container);
NS_ASSERTION(loadContext, "Couldn't get loadContext from container; assuming no private browsing.");
if (loadContext) {
mUsingPrivateBrowsing = loadContext->UsePrivateBrowsing();
}
}
}
};

View File

@ -985,7 +985,7 @@ nsStyleSet::ResolveStyleFor(Element* aElement,
return GetContext(aParentContext, ruleNode, visitedRuleNode,
nsCSSRuleProcessor::IsLink(aElement),
nsCSSRuleProcessor::GetContentState(aElement).
nsCSSRuleProcessor::GetContentState(aElement, aTreeMatchContext).
HasState(NS_EVENT_STATE_VISITED),
nsnull, nsCSSPseudoElements::ePseudo_NotPseudoElement,
true, aElement);