Rewrite the pref for forbidding pages from setting colors and backgrounds so that it changes transparency less often and interferes less with user and user-agent styles. b=58048, 255829, 255411 r+sr=bzbarsky

This commit is contained in:
dbaron@dbaron.org 2007-05-16 14:10:31 -07:00
parent 5d44540384
commit 8d20e3f29b
7 changed files with 99 additions and 116 deletions

View File

@ -1368,3 +1368,23 @@ nsPresContext::CountReflows(const char * aName, nsIFrame * aFrame)
}
}
#endif
PRBool
nsPresContext::IsChrome()
{
PRBool isChrome = PR_FALSE;
nsCOMPtr<nsISupports> container = GetContainer();
if (container) {
nsresult result;
nsCOMPtr<nsIDocShellTreeItem> docShell(do_QueryInterface(container, &result));
if (NS_SUCCEEDED(result) && docShell) {
PRInt32 docShellType;
result = docShell->GetItemType(&docShellType);
if (NS_SUCCEEDED(result)) {
isChrome = nsIDocShellTreeItem::typeChrome == docShellType;
}
}
}
return isChrome;
}

View File

@ -700,6 +700,9 @@ public:
mType == eContext_PageLayout ||
mType == eContext_PrintPreview); }
// Is this presentation in a chrome docshell?
PRBool IsChrome();
const nsTArray<nsIFrame*>& GetActivePopups() {
NS_ASSERTION(this == RootPresContext(), "Only on root prescontext");
return mActivePopups;

View File

@ -1055,7 +1055,6 @@ protected:
*/
nsresult ClearPreferenceStyleRules(void);
nsresult CreatePreferenceStyleSheet(void);
nsresult SetPrefColorRules(void);
nsresult SetPrefLinkRules(void);
nsresult SetPrefFocusRules(void);
nsresult SetPrefNoScriptRule();
@ -1783,11 +1782,6 @@ PresShell::SetPreferenceStyleRules(PRBool aForceReflow)
// first clear any exising rules
result = ClearPreferenceStyleRules();
// now do the color rules
if (NS_SUCCEEDED(result)) {
result = SetPrefColorRules();
}
// now the link rules (must come after the color rules, or links will not be correct color!)
// XXX - when there is both an override and agent pref stylesheet this won't matter,
// as the color rules will be overrides and the links rules will be agent
@ -1883,73 +1877,6 @@ nsresult PresShell::CreatePreferenceStyleSheet(void)
// and just "append"?
static PRUint32 sInsertPrefSheetRulesAt = 1;
nsresult PresShell::SetPrefColorRules(void)
{
NS_ASSERTION(mPresContext,"null prescontext not allowed");
if (mPresContext) {
nsresult result = NS_OK;
// see if we need to create the rules first
PRBool useDocColors =
mPresContext->GetCachedBoolPref(kPresContext_UseDocumentColors);
if (!useDocColors) {
#ifdef DEBUG_attinasi
printf(" - Creating rules for document colors\n");
#endif
// OK, not using document colors, so we have to force the user's colors via style rules
if (!mPrefStyleSheet) {
result = CreatePreferenceStyleSheet();
}
if (NS_SUCCEEDED(result)) {
NS_ASSERTION(mPrefStyleSheet, "prefstylesheet should not be null");
nscolor bgColor = mPresContext->DefaultBackgroundColor();
nscolor textColor = mPresContext->DefaultColor();
// get the DOM interface to the stylesheet
nsCOMPtr<nsIDOMCSSStyleSheet> sheet(do_QueryInterface(mPrefStyleSheet,&result));
if (NS_SUCCEEDED(result)) {
PRUint32 index = 0;
nsAutoString strColor, strBackgroundColor;
// create a rule for background and foreground color and
// add it to the style sheet
// - the rule is !important so it overrides all but author
// important rules (when put into an agent stylesheet) and
// all (even author important) when put into an override stylesheet
///////////////////////////////////////////////////////////////
// - default colors: ':root {color:#RRGGBB !important;
// background: #RRGGBB !important;}'
ColorToString(textColor,strColor);
ColorToString(bgColor,strBackgroundColor);
result = sheet->InsertRule(NS_LITERAL_STRING("*|*:root {color:") +
strColor +
NS_LITERAL_STRING(" !important; ") +
NS_LITERAL_STRING("border-color: -moz-use-text-color !important; ") +
NS_LITERAL_STRING("background:") +
strBackgroundColor +
NS_LITERAL_STRING(" !important; }"),
sInsertPrefSheetRulesAt, &index);
NS_ENSURE_SUCCESS(result, result);
///////////////////////////////////////////////////////////////
// - everything else inherits the color
// (the background color will be handled in
// nsRuleNode::ComputeBackgroundData)
result = sheet->InsertRule(NS_LITERAL_STRING("*|* {color: inherit !important; border-color: -moz-use-text-color !important; background-image: none !important; } "),
sInsertPrefSheetRulesAt, &index);
}
}
}
return result;
} else {
return NS_ERROR_FAILURE;
}
}
nsresult
PresShell::SetPrefNoScriptRule()
{
@ -2046,11 +1973,7 @@ nsresult PresShell::SetPrefLinkRules(void)
nscolor activeColor(mPresContext->DefaultActiveLinkColor());
nscolor visitedColor(mPresContext->DefaultVisitedLinkColor());
PRBool useDocColors =
mPresContext->GetCachedBoolPref(kPresContext_UseDocumentColors);
NS_NAMED_LITERAL_STRING(notImportantStr, "}");
NS_NAMED_LITERAL_STRING(importantStr, "!important}");
const nsAString& ruleClose = useDocColors ? notImportantStr : importantStr;
NS_NAMED_LITERAL_STRING(ruleClose, "}");
PRUint32 index = 0;
nsAutoString strColor;

View File

@ -44,6 +44,7 @@
#include "nsCSSProps.h"
#include "nsRuleData.h"
#include "nsRuleNode.h"
#include "nsStyleSet.h"
/*
* nsCSSCompressedDataBlock holds property-value pairs corresponding to
@ -171,6 +172,16 @@ inline nsCSSQuotes* QuotesAtCursor(const char *aCursor) {
NS_REINTERPRET_CAST(const CDBPointerStorage*, aCursor)->value);
}
static PRBool
ShouldIgnoreColors(nsRuleData *aRuleData)
{
nsPresContext *presContext = aRuleData->mPresContext;
return aRuleData->mLevel != nsStyleSet::eAgentSheet &&
aRuleData->mLevel != nsStyleSet::eUserSheet &&
!presContext->GetCachedBoolPref(kPresContext_UseDocumentColors) &&
!presContext->IsChrome();
}
nsresult
nsCSSCompressedDataBlock::MapRuleInfoInto(nsRuleData *aRuleData) const
{
@ -207,6 +218,32 @@ nsCSSCompressedDataBlock::MapRuleInfoInto(nsRuleData *aRuleData) const
// XXX Are there other things like this?
aRuleData->mFontData->mFamilyFromHTML = PR_FALSE;
}
else if (iProp == eCSSProperty_color ||
iProp == eCSSProperty_background_color ||
iProp == eCSSProperty_background_image ||
iProp == eCSSProperty_border_top_color ||
iProp == eCSSProperty_border_right_color ||
iProp == eCSSProperty_border_bottom_color ||
iProp == eCSSProperty_border_left_color) {
if (ShouldIgnoreColors(aRuleData)) {
if (iProp == eCSSProperty_background_color) {
// Force non-'transparent' background
// colors to the user's default.
nsCSSUnit u = target->GetUnit();
if (u != eCSSUnit_Enumerated &&
u != eCSSUnit_Inherit &&
u != eCSSUnit_Initial) {
target->SetColorValue(aRuleData->
mPresContext->
DefaultBackgroundColor());
}
} else {
// Ignore 'color', 'border-*-color', and
// 'background-image'
*target = nsCSSValue();
}
}
}
}
cursor += CDBValueStorage_advance;
} break;
@ -266,6 +303,15 @@ nsCSSCompressedDataBlock::MapRuleInfoInto(nsRuleData *aRuleData) const
void* val = PointerAtCursor(cursor);
NS_ASSERTION(val, "oops");
*target = val;
if (iProp == eCSSProperty_border_top_colors ||
iProp == eCSSProperty_border_right_colors ||
iProp == eCSSProperty_border_bottom_colors ||
iProp == eCSSProperty_border_left_colors) {
if (ShouldIgnoreColors(aRuleData)) {
*target = nsnull;
}
}
}
cursor += CDBPointerStorage_advance;
} break;

View File

@ -56,6 +56,8 @@ struct nsRuleData
{
nsStyleStructID mSID;
PRPackedBool mCanStoreInRuleTree;
PRPackedBool mIsImportantRule;
PRUint8 mLevel; // an nsStyleSet::sheetType
nsPresContext* mPresContext;
nsStyleContext* mStyleContext;
nsPostResolveFunc mPostResolveCallback;

View File

@ -51,7 +51,6 @@
#include "nsILookAndFeel.h"
#include "nsIPresShell.h"
#include "nsIFontMetrics.h"
#include "nsIDocShellTreeItem.h"
#include "nsStyleUtil.h"
#include "nsCSSPseudoElements.h"
#include "nsThemeConstants.h"
@ -1393,8 +1392,11 @@ nsRuleNode::WalkRuleTree(const nsStyleStructID aSID,
// Ask the rule to fill in the properties that it specifies.
nsIStyleRule *rule = ruleNode->mRule;
if (rule)
if (rule) {
aRuleData->mLevel = ruleNode->GetLevel();
aRuleData->mIsImportantRule = ruleNode->IsImportantRule();
rule->MapRuleInfoInto(aRuleData);
}
// Now we check to see how many properties have been specified by
// the rules we've examined so far.
@ -1485,25 +1487,6 @@ nsRuleNode::WalkRuleTree(const nsStyleStructID aSID,
return res;
}
static PRBool
IsChrome(nsPresContext* aPresContext)
{
PRBool isChrome = PR_FALSE;
nsCOMPtr<nsISupports> container = aPresContext->GetContainer();
if (container) {
nsresult result;
nsCOMPtr<nsIDocShellTreeItem> docShell(do_QueryInterface(container, &result));
if (NS_SUCCEEDED(result) && docShell) {
PRInt32 docShellType;
result = docShell->GetItemType(&docShellType);
if (NS_SUCCEEDED(result)) {
isChrome = nsIDocShellTreeItem::typeChrome == docShellType;
}
}
}
return isChrome;
}
const nsStyleStruct*
nsRuleNode::SetDefaultOnRoot(const nsStyleStructID aSID, nsStyleContext* aContext)
{
@ -1515,7 +1498,7 @@ nsRuleNode::SetDefaultOnRoot(const nsStyleStructID aSID, nsStyleContext* aContex
nscoord minimumFontSize =
mPresContext->GetCachedIntPref(kPresContext_MinimumFontSize);
if (minimumFontSize > 0 && !IsChrome(mPresContext)) {
if (minimumFontSize > 0 && !mPresContext->IsChrome()) {
fontData->mFont.size = PR_MAX(fontData->mSize, minimumFontSize);
}
else {
@ -2220,8 +2203,11 @@ nsRuleNode::SetGenericFont(nsPresContext* aPresContext,
break;
nsIStyleRule *rule = ruleNode->GetRule();
if (rule)
if (rule) {
ruleData.mLevel = ruleNode->GetLevel();
ruleData.mIsImportantRule = ruleNode->IsImportantRule();
rule->MapRuleInfoInto(&ruleData);
}
}
// Compute the delta from the information that the rules specified
@ -2285,7 +2271,7 @@ nsRuleNode::ComputeFontData(nsStyleStruct* aStartStruct,
// We only need to know this to determine if we have to use the
// document fonts (overriding the useDocumentFonts flag), or to
// determine if we have to override the minimum font-size constraint.
if ((!useDocumentFonts || minimumFontSize > 0) && IsChrome(mPresContext)) {
if ((!useDocumentFonts || minimumFontSize > 0) && mPresContext->IsChrome()) {
// if we are not using document fonts, but this is a XUL document,
// then we use the document fonts anyway
useDocumentFonts = PR_TRUE;
@ -2383,7 +2369,7 @@ nsRuleNode::ComputeTextData(nsStyleStruct* aStartStruct,
nscoord minimumFontSize =
mPresContext->GetCachedIntPref(kPresContext_MinimumFontSize);
if (minimumFontSize > 0 && !IsChrome(mPresContext)) {
if (minimumFontSize > 0 && !mPresContext->IsChrome()) {
// If we applied a minimum font size, scale the line height by
// the same ratio. (If we *might* have applied a minimum font
// size, we can't cache in the rule tree.)
@ -3064,15 +3050,9 @@ nsRuleNode::ComputeBackgroundData(nsStyleStruct* aStartStruct,
else if (SetColor(colorData.mBackColor, parentBG->mBackgroundColor,
mPresContext, aContext, bg->mBackgroundColor, inherited)) {
bg->mBackgroundFlags &= ~NS_STYLE_BG_COLOR_TRANSPARENT;
// if not using document colors, we have to use the user's background color
// instead of any background color other than transparent
if (!mPresContext->GetCachedBoolPref(kPresContext_UseDocumentColors) &&
!IsChrome(mPresContext)) {
bg->mBackgroundColor = mPresContext->DefaultBackgroundColor();
}
}
else if (eCSSUnit_Enumerated == colorData.mBackColor.GetUnit()) {
//bg->mBackgroundColor = parentBG->mBackgroundColor; XXXwdh crap crap crap!
else if (eCSSUnit_Enumerated == colorData.mBackColor.GetUnit() ||
eCSSUnit_Initial == colorData.mBackColor.GetUnit()) {
bg->mBackgroundFlags |= NS_STYLE_BG_COLOR_TRANSPARENT;
}
@ -3080,7 +3060,8 @@ nsRuleNode::ComputeBackgroundData(nsStyleStruct* aStartStruct,
if (eCSSUnit_Image == colorData.mBackImage.GetUnit()) {
bg->mBackgroundImage = colorData.mBackImage.GetImageValue();
}
else if (eCSSUnit_None == colorData.mBackImage.GetUnit()) {
else if (eCSSUnit_None == colorData.mBackImage.GetUnit() ||
eCSSUnit_Initial == colorData.mBackImage.GetUnit()) {
bg->mBackgroundImage = nsnull;
}
else if (eCSSUnit_Inherit == colorData.mBackImage.GetUnit()) {
@ -3102,6 +3083,9 @@ nsRuleNode::ComputeBackgroundData(nsStyleStruct* aStartStruct,
inherited = PR_TRUE;
bg->mBackgroundRepeat = parentBG->mBackgroundRepeat;
}
else if (eCSSUnit_Initial == colorData.mBackRepeat.GetUnit()) {
bg->mBackgroundRepeat = NS_STYLE_BG_REPEAT_XY;
}
// background-attachment: enum, inherit
if (eCSSUnit_Enumerated == colorData.mBackAttachment.GetUnit()) {
@ -3111,6 +3095,9 @@ nsRuleNode::ComputeBackgroundData(nsStyleStruct* aStartStruct,
inherited = PR_TRUE;
bg->mBackgroundAttachment = parentBG->mBackgroundAttachment;
}
else if (eCSSUnit_Initial == colorData.mBackAttachment.GetUnit()) {
bg->mBackgroundAttachment = NS_STYLE_BG_ATTACHMENT_SCROLL;
}
// background-clip: enum, inherit, initial
if (eCSSUnit_Enumerated == colorData.mBackClip.GetUnit()) {
@ -3181,6 +3168,9 @@ nsRuleNode::ComputeBackgroundData(nsStyleStruct* aStartStruct,
bg->mBackgroundFlags &= ~(NS_STYLE_BG_X_POSITION_LENGTH | NS_STYLE_BG_X_POSITION_PERCENT);
bg->mBackgroundFlags |= (parentFlags & (NS_STYLE_BG_X_POSITION_LENGTH | NS_STYLE_BG_X_POSITION_PERCENT));
}
else if (eCSSUnit_Initial == colorData.mBackPosition.mXValue.GetUnit()) {
bg->mBackgroundFlags &= ~(NS_STYLE_BG_X_POSITION_LENGTH | NS_STYLE_BG_X_POSITION_PERCENT);
}
if (eCSSUnit_Percent == colorData.mBackPosition.mYValue.GetUnit()) {
bg->mBackgroundYPosition.mFloat = colorData.mBackPosition.mYValue.GetPercentValue();
@ -3217,6 +3207,9 @@ nsRuleNode::ComputeBackgroundData(nsStyleStruct* aStartStruct,
bg->mBackgroundFlags &= ~(NS_STYLE_BG_Y_POSITION_LENGTH | NS_STYLE_BG_Y_POSITION_PERCENT);
bg->mBackgroundFlags |= (parentFlags & (NS_STYLE_BG_Y_POSITION_LENGTH | NS_STYLE_BG_Y_POSITION_PERCENT));
}
else if (eCSSUnit_Initial == colorData.mBackPosition.mYValue.GetUnit()) {
bg->mBackgroundFlags &= ~(NS_STYLE_BG_Y_POSITION_LENGTH | NS_STYLE_BG_Y_POSITION_PERCENT);
}
COMPUTE_END_RESET(Background, bg)
}

View File

@ -111,10 +111,6 @@ var gBrokenInitial = {
"-moz-user-input": true,
"-moz-user-modify": true,
"-moz-user-select": true,
"background-attachment": true,
"background-color": true,
"background-image": true,
"background-repeat": true,
"border-bottom-color": true,
"border-collapse": true,
"border-color": true,