зеркало из https://github.com/mozilla/pjs.git
Make IsWidgetStyled use style system to really check whether author styled borders or backgrounds, rather than depending on default values in forms.css. b=240117 r+sr=bzbarsky a=roc
This commit is contained in:
Родитель
82f36a3c3f
Коммит
041b414fb6
|
@ -79,6 +79,7 @@
|
|||
#include "nsIViewManager.h"
|
||||
#include "nsCSSFrameConstructor.h"
|
||||
#include "nsStyleChangeList.h"
|
||||
#include "nsRuleNode.h"
|
||||
|
||||
#ifdef IBMBIDI
|
||||
#include "nsBidiPresUtils.h"
|
||||
|
@ -1480,3 +1481,9 @@ nsPresContext::IsChrome()
|
|||
return isChrome;
|
||||
}
|
||||
|
||||
/* virtual */ PRBool
|
||||
nsPresContext::HasAuthorSpecifiedBorderOrBackground(nsIFrame *aFrame) const
|
||||
{
|
||||
return nsRuleNode::
|
||||
HasAuthorSpecifiedBorderOrBackground(aFrame->GetStyleContext());
|
||||
}
|
||||
|
|
|
@ -729,6 +729,9 @@ public:
|
|||
// Is this presentation in a chrome docshell?
|
||||
PRBool IsChrome();
|
||||
|
||||
// Public API for native theme code to get style internals.
|
||||
virtual PRBool HasAuthorSpecifiedBorderOrBackground(nsIFrame *aFrame) const;
|
||||
|
||||
protected:
|
||||
friend class nsRunnableMethod<nsPresContext>;
|
||||
NS_HIDDEN_(void) ThemeChangedInternal();
|
||||
|
|
|
@ -367,6 +367,12 @@ void nsCSSValue::SetSystemFontValue()
|
|||
mUnit = eCSSUnit_System_Font;
|
||||
}
|
||||
|
||||
void nsCSSValue::SetDummyValue()
|
||||
{
|
||||
Reset();
|
||||
mUnit = eCSSUnit_Dummy;
|
||||
}
|
||||
|
||||
void nsCSSValue::StartImageLoad(nsIDocument* aDocument) const
|
||||
{
|
||||
NS_PRECONDITION(eCSSUnit_URL == mUnit, "Not a URL value!");
|
||||
|
|
|
@ -63,6 +63,8 @@ enum nsCSSUnit {
|
|||
eCSSUnit_None = 4, // (n/a) value is none
|
||||
eCSSUnit_Normal = 5, // (n/a) value is normal (algorithmic, different than auto)
|
||||
eCSSUnit_System_Font = 6, // (n/a) value is -moz-use-system-font
|
||||
eCSSUnit_Dummy = 7, // (n/a) a fake but specified value, used
|
||||
// only in temporary values
|
||||
eCSSUnit_String = 10, // (PRUnichar*) a string value
|
||||
eCSSUnit_Attr = 11, // (PRUnichar*) a attr(string) value
|
||||
eCSSUnit_Array = 20, // (nsCSSValue::Array*) a list of values
|
||||
|
@ -275,6 +277,7 @@ public:
|
|||
NS_HIDDEN_(void) SetNoneValue();
|
||||
NS_HIDDEN_(void) SetNormalValue();
|
||||
NS_HIDDEN_(void) SetSystemFontValue();
|
||||
NS_HIDDEN_(void) SetDummyValue();
|
||||
NS_HIDDEN_(void) StartImageLoad(nsIDocument* aDocument)
|
||||
const; // Not really const, but pretending
|
||||
|
||||
|
|
|
@ -4917,3 +4917,63 @@ nsRuleNode::Sweep()
|
|||
}
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
/* static */ PRBool
|
||||
nsRuleNode::HasAuthorSpecifiedBorderOrBackground(nsStyleContext* aStyleContext)
|
||||
{
|
||||
nsRuleDataColor colorData;
|
||||
nsRuleDataMargin marginData;
|
||||
/* We're relying on the use of |aStyleContext| not mutating it! */
|
||||
nsRuleData ruleData(NS_STYLE_INHERIT_BIT(Background) |
|
||||
NS_STYLE_INHERIT_BIT(Border),
|
||||
aStyleContext->PresContext(), aStyleContext);
|
||||
ruleData.mColorData = &colorData;
|
||||
ruleData.mMarginData = &marginData;
|
||||
|
||||
nsCSSValue* values[] = {
|
||||
&colorData.mBackColor,
|
||||
&colorData.mBackImage,
|
||||
&marginData.mBorderColor.mTop,
|
||||
&marginData.mBorderStyle.mTop,
|
||||
&marginData.mBorderWidth.mTop,
|
||||
&marginData.mBorderColor.mRight,
|
||||
&marginData.mBorderStyle.mRight,
|
||||
&marginData.mBorderWidth.mRight,
|
||||
&marginData.mBorderColor.mBottom,
|
||||
&marginData.mBorderStyle.mBottom,
|
||||
&marginData.mBorderWidth.mBottom,
|
||||
&marginData.mBorderColor.mLeft,
|
||||
&marginData.mBorderStyle.mLeft,
|
||||
&marginData.mBorderWidth.mLeft
|
||||
};
|
||||
|
||||
// We need to be careful not to count styles covered up by
|
||||
// user-important or UA-important declarations.
|
||||
for (nsRuleNode* ruleNode = aStyleContext->GetRuleNode(); ruleNode;
|
||||
ruleNode = ruleNode->GetParent()) {
|
||||
nsIStyleRule *rule = ruleNode->GetRule();
|
||||
if (rule) {
|
||||
ruleData.mLevel = ruleNode->GetLevel();
|
||||
ruleData.mIsImportantRule = ruleNode->IsImportantRule();
|
||||
rule->MapRuleInfoInto(&ruleData);
|
||||
if (ruleData.mLevel == nsStyleSet::eAgentSheet ||
|
||||
ruleData.mLevel == nsStyleSet::eUserSheet) {
|
||||
// This is a rule whose effect we want to ignore, so if any of
|
||||
// the properties we care about were set, set them to the dummy
|
||||
// value that they'll never otherwise get.
|
||||
for (PRUint32 i = 0; i < NS_ARRAY_LENGTH(values); ++i)
|
||||
if (values[i]->GetUnit() != eCSSUnit_Null)
|
||||
values[i]->SetDummyValue();
|
||||
} else {
|
||||
// If any of the values we care about was set by the above rule,
|
||||
// we have author style.
|
||||
for (PRUint32 i = 0; i < NS_ARRAY_LENGTH(values); ++i)
|
||||
if (values[i]->GetUnit() != eCSSUnit_Null &&
|
||||
values[i]->GetUnit() != eCSSUnit_Dummy) // see above
|
||||
return PR_TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
|
|
@ -710,6 +710,9 @@ public:
|
|||
*/
|
||||
NS_HIDDEN_(void) Mark();
|
||||
NS_HIDDEN_(PRBool) Sweep();
|
||||
|
||||
static PRBool
|
||||
HasAuthorSpecifiedBorderOrBackground(nsStyleContext* aStyleContext);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -50,34 +50,6 @@
|
|||
#include "nsThemeConstants.h"
|
||||
#include "nsIComponentManager.h"
|
||||
|
||||
nsMargin nsNativeTheme::sButtonBorderSize(2, 2, 2, 2);
|
||||
PRUint8 nsNativeTheme::sButtonActiveBorderStyle = NS_STYLE_BORDER_STYLE_INSET;
|
||||
PRUint8 nsNativeTheme::sButtonInactiveBorderStyle = NS_STYLE_BORDER_STYLE_OUTSET;
|
||||
nsILookAndFeel::nsColorID nsNativeTheme::sButtonBorderColorID = nsILookAndFeel::eColor_buttonface;
|
||||
nsILookAndFeel::nsColorID nsNativeTheme::sButtonDisabledBorderColorID = nsILookAndFeel::eColor_buttonface;
|
||||
nsILookAndFeel::nsColorID nsNativeTheme::sButtonBGColorID = nsILookAndFeel::eColor_buttonface;
|
||||
nsILookAndFeel::nsColorID nsNativeTheme::sButtonDisabledBGColorID = nsILookAndFeel::eColor_buttonface;
|
||||
|
||||
nsMargin nsNativeTheme::sTextfieldBorderSize(2, 2, 2, 2);
|
||||
PRUint8 nsNativeTheme::sTextfieldBorderStyle = NS_STYLE_BORDER_STYLE_INSET;
|
||||
nsILookAndFeel::nsColorID nsNativeTheme::sTextfieldBorderColorID = nsILookAndFeel::eColor_threedface;
|
||||
PRBool nsNativeTheme::sTextfieldBGTransparent = PR_FALSE;
|
||||
nsILookAndFeel::nsColorID nsNativeTheme::sTextfieldBGColorID = nsILookAndFeel::eColor__moz_field;
|
||||
nsILookAndFeel::nsColorID nsNativeTheme::sTextfieldDisabledBGColorID = nsILookAndFeel::eColor_threedface;
|
||||
|
||||
nsMargin nsNativeTheme::sListboxBorderSize(2, 2, 2, 2);
|
||||
PRUint8 nsNativeTheme::sListboxBorderStyle = NS_STYLE_BORDER_STYLE_INSET;
|
||||
nsILookAndFeel::nsColorID nsNativeTheme::sListboxBorderColorID = nsILookAndFeel::eColor_threedface;
|
||||
nsILookAndFeel::nsColorID nsNativeTheme::sListboxBGColorID = nsILookAndFeel::eColor__moz_field;
|
||||
nsILookAndFeel::nsColorID nsNativeTheme::sListboxDisabledBGColorID = nsILookAndFeel::eColor_threedface;
|
||||
|
||||
nsMargin nsNativeTheme::sComboboxBorderSize(2, 2, 2, 2);
|
||||
PRUint8 nsNativeTheme::sComboboxBorderStyle = NS_STYLE_BORDER_STYLE_INSET;
|
||||
nsILookAndFeel::nsColorID nsNativeTheme::sComboboxBorderColorID = nsILookAndFeel::eColor_threedface;
|
||||
PRBool nsNativeTheme::sComboboxBGTransparent = PR_FALSE;
|
||||
nsILookAndFeel::nsColorID nsNativeTheme::sComboboxBGColorID = nsILookAndFeel::eColor__moz_field;
|
||||
nsILookAndFeel::nsColorID nsNativeTheme::sComboboxDisabledBGColorID = nsILookAndFeel::eColor_threedface;
|
||||
|
||||
nsNativeTheme::nsNativeTheme()
|
||||
{
|
||||
}
|
||||
|
@ -182,136 +154,19 @@ nsNativeTheme::GetCheckedOrSelected(nsIFrame* aFrame, PRBool aCheckSelected)
|
|||
: nsWidgetAtoms::checked);
|
||||
}
|
||||
|
||||
static void
|
||||
ConvertBorderToAppUnits(nsPresContext* aPresContext, const nsMargin &aSource, nsMargin &aDest)
|
||||
{
|
||||
PRInt32 cp2a = nsPresContext::AppUnitsPerCSSPixel();
|
||||
PRInt32 dp2a = aPresContext->AppUnitsPerDevPixel();
|
||||
aDest.top = NS_ROUND_BORDER_TO_PIXELS(NSIntPixelsToAppUnits(aSource.top, cp2a), dp2a);
|
||||
aDest.left = NS_ROUND_BORDER_TO_PIXELS(NSIntPixelsToAppUnits(aSource.left, cp2a), dp2a);
|
||||
aDest.bottom = NS_ROUND_BORDER_TO_PIXELS(NSIntPixelsToAppUnits(aSource.bottom, cp2a), dp2a);
|
||||
aDest.right = NS_ROUND_BORDER_TO_PIXELS(NSIntPixelsToAppUnits(aSource.right, cp2a), dp2a);;
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsNativeTheme::IsWidgetStyled(nsPresContext* aPresContext, nsIFrame* aFrame,
|
||||
PRUint8 aWidgetType)
|
||||
{
|
||||
// Check for specific widgets to see if HTML has overridden the style.
|
||||
if (aFrame && (aWidgetType == NS_THEME_BUTTON ||
|
||||
aWidgetType == NS_THEME_TEXTFIELD ||
|
||||
aWidgetType == NS_THEME_TEXTFIELD_MULTILINE ||
|
||||
aWidgetType == NS_THEME_LISTBOX ||
|
||||
aWidgetType == NS_THEME_DROPDOWN)) {
|
||||
if (aFrame->GetContent()->IsNodeOfType(nsINode::eHTML)) {
|
||||
nscolor defaultBGColor;
|
||||
nscolor defaultBorderColor;
|
||||
PRUint8 defaultBorderStyle;
|
||||
nsMargin defaultBorderSize;
|
||||
PRBool defaultBGTransparent = PR_FALSE;
|
||||
|
||||
nsILookAndFeel *lookAndFeel = aPresContext->LookAndFeel();
|
||||
|
||||
switch (aWidgetType) {
|
||||
case NS_THEME_BUTTON:
|
||||
ConvertBorderToAppUnits(aPresContext, sButtonBorderSize,
|
||||
defaultBorderSize);
|
||||
if (IsDisabled(aFrame)) {
|
||||
defaultBorderStyle = sButtonInactiveBorderStyle;
|
||||
lookAndFeel->GetColor(sButtonDisabledBorderColorID,
|
||||
defaultBorderColor);
|
||||
lookAndFeel->GetColor(sButtonDisabledBGColorID,
|
||||
defaultBGColor);
|
||||
} else {
|
||||
PRInt32 contentState = GetContentState(aFrame, aWidgetType);
|
||||
if (contentState & NS_EVENT_STATE_HOVER &&
|
||||
contentState & NS_EVENT_STATE_ACTIVE)
|
||||
defaultBorderStyle = sButtonActiveBorderStyle;
|
||||
else
|
||||
defaultBorderStyle = sButtonInactiveBorderStyle;
|
||||
lookAndFeel->GetColor(sButtonBorderColorID,
|
||||
defaultBorderColor);
|
||||
lookAndFeel->GetColor(sButtonBGColorID,
|
||||
defaultBGColor);
|
||||
}
|
||||
break;
|
||||
|
||||
case NS_THEME_TEXTFIELD:
|
||||
case NS_THEME_TEXTFIELD_MULTILINE:
|
||||
defaultBorderStyle = sTextfieldBorderStyle;
|
||||
ConvertBorderToAppUnits(aPresContext, sTextfieldBorderSize, defaultBorderSize);
|
||||
lookAndFeel->GetColor(sTextfieldBorderColorID, defaultBorderColor);
|
||||
defaultBGTransparent = sTextfieldBGTransparent;
|
||||
if (!defaultBGTransparent) {
|
||||
if (IsDisabled(aFrame))
|
||||
lookAndFeel->GetColor(sTextfieldDisabledBGColorID, defaultBGColor);
|
||||
else
|
||||
lookAndFeel->GetColor(sTextfieldBGColorID, defaultBGColor);
|
||||
}
|
||||
break;
|
||||
|
||||
case NS_THEME_LISTBOX:
|
||||
defaultBorderStyle = sListboxBorderStyle;
|
||||
ConvertBorderToAppUnits(aPresContext, sListboxBorderSize, defaultBorderSize);
|
||||
lookAndFeel->GetColor(sListboxBorderColorID, defaultBorderColor);
|
||||
if (IsDisabled(aFrame))
|
||||
lookAndFeel->GetColor(sListboxDisabledBGColorID, defaultBGColor);
|
||||
else
|
||||
lookAndFeel->GetColor(sListboxBGColorID, defaultBGColor);
|
||||
break;
|
||||
|
||||
case NS_THEME_DROPDOWN:
|
||||
defaultBorderStyle = sComboboxBorderStyle;
|
||||
ConvertBorderToAppUnits(aPresContext, sComboboxBorderSize, defaultBorderSize);
|
||||
lookAndFeel->GetColor(sComboboxBorderColorID, defaultBorderColor);
|
||||
defaultBGTransparent = sComboboxBGTransparent;
|
||||
if (!defaultBGTransparent) {
|
||||
if (IsDisabled(aFrame))
|
||||
lookAndFeel->GetColor(sComboboxDisabledBGColorID, defaultBGColor);
|
||||
else
|
||||
lookAndFeel->GetColor(sComboboxBGColorID, defaultBGColor);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
NS_ERROR("nsNativeTheme::IsWidgetStyled widget type not handled");
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
// Check whether background differs from default
|
||||
const nsStyleBackground* ourBG = aFrame->GetStyleBackground();
|
||||
|
||||
if (defaultBGTransparent) {
|
||||
if (!(ourBG->mBackgroundFlags & NS_STYLE_BG_COLOR_TRANSPARENT))
|
||||
return PR_TRUE;
|
||||
} else if (ourBG->mBackgroundColor != defaultBGColor ||
|
||||
ourBG->mBackgroundFlags & NS_STYLE_BG_COLOR_TRANSPARENT)
|
||||
return PR_TRUE;
|
||||
|
||||
if (!(ourBG->mBackgroundFlags & NS_STYLE_BG_IMAGE_NONE))
|
||||
return PR_TRUE;
|
||||
|
||||
// Check whether border style or color differs from default
|
||||
const nsStyleBorder* ourBorder = aFrame->GetStyleBorder();
|
||||
|
||||
for (PRInt32 i = 0; i < 4; ++i) {
|
||||
if (ourBorder->GetBorderStyle(i) != defaultBorderStyle)
|
||||
return PR_TRUE;
|
||||
|
||||
PRBool borderFG, borderClear;
|
||||
nscolor borderColor;
|
||||
ourBorder->GetBorderColor(i, borderColor, borderFG, borderClear);
|
||||
if (borderColor != defaultBorderColor || borderClear)
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
// Check whether border size differs from default
|
||||
if (ourBorder->GetBorder() != defaultBorderSize)
|
||||
return PR_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return PR_FALSE;
|
||||
return aFrame &&
|
||||
(aWidgetType == NS_THEME_BUTTON ||
|
||||
aWidgetType == NS_THEME_TEXTFIELD ||
|
||||
aWidgetType == NS_THEME_TEXTFIELD_MULTILINE ||
|
||||
aWidgetType == NS_THEME_LISTBOX ||
|
||||
aWidgetType == NS_THEME_DROPDOWN) &&
|
||||
aFrame->GetContent()->IsNodeOfType(nsINode::eHTML) &&
|
||||
aPresContext->HasAuthorSpecifiedBorderOrBackground(aFrame);
|
||||
}
|
||||
|
||||
// treeheadercell:
|
||||
|
|
|
@ -134,36 +134,4 @@ class nsNativeTheme
|
|||
PRBool CheckBooleanAttr(nsIFrame* aFrame, nsIAtom* aAtom);
|
||||
|
||||
PRBool GetCheckedOrSelected(nsIFrame* aFrame, PRBool aCheckSelected);
|
||||
|
||||
// The following should be set to appropriate platform values by the subclass,
|
||||
// to match the values in forms.css. The defaults match forms.css.
|
||||
|
||||
// push buttons
|
||||
static nsMargin sButtonBorderSize;
|
||||
static PRUint8 sButtonActiveBorderStyle;
|
||||
static PRUint8 sButtonInactiveBorderStyle;
|
||||
static nsILookAndFeel::nsColorID sButtonBorderColorID;
|
||||
static nsILookAndFeel::nsColorID sButtonDisabledBorderColorID;
|
||||
static nsILookAndFeel::nsColorID sButtonBGColorID;
|
||||
static nsILookAndFeel::nsColorID sButtonDisabledBGColorID;
|
||||
// text fields
|
||||
static nsMargin sTextfieldBorderSize;
|
||||
static PRUint8 sTextfieldBorderStyle;
|
||||
static nsILookAndFeel::nsColorID sTextfieldBorderColorID;
|
||||
static PRBool sTextfieldBGTransparent;
|
||||
static nsILookAndFeel::nsColorID sTextfieldBGColorID;
|
||||
static nsILookAndFeel::nsColorID sTextfieldDisabledBGColorID;
|
||||
// listboxes
|
||||
static nsMargin sListboxBorderSize;
|
||||
static PRUint8 sListboxBorderStyle;
|
||||
static nsILookAndFeel::nsColorID sListboxBorderColorID;
|
||||
static nsILookAndFeel::nsColorID sListboxBGColorID;
|
||||
static nsILookAndFeel::nsColorID sListboxDisabledBGColorID;
|
||||
// comboboxes
|
||||
static nsMargin sComboboxBorderSize;
|
||||
static PRUint8 sComboboxBorderStyle;
|
||||
static nsILookAndFeel::nsColorID sComboboxBorderColorID;
|
||||
static PRBool sComboboxBGTransparent;
|
||||
static nsILookAndFeel::nsColorID sComboboxBGColorID;
|
||||
static nsILookAndFeel::nsColorID sComboboxDisabledBGColorID;
|
||||
};
|
||||
|
|
Загрузка…
Ссылка в новой задаче