Fix for 112980, nsITheme API and dynamic skin switching re-enabling. r=ben, sr=waterson

This commit is contained in:
hyatt%netscape.com 2001-12-17 22:51:39 +00:00
Родитель 6c39aa2280
Коммит d4065d8e54
110 изменённых файлов: 3460 добавлений и 2260 удалений

Просмотреть файл

@ -47,7 +47,6 @@
#include "nsChromeProtocolHandler.h"
#include "nsChromeRegistry.h"
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsChromeRegistry, Init)
// The list of components we register
@ -63,7 +62,7 @@ static nsModuleComponentInfo components[] =
NS_CHROMEPROTOCOLHANDLER_CID,
NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "chrome",
nsChromeProtocolHandler::Create
},
}
};
NS_IMPL_NSGETMODULE(nsChromeModule, components);

Просмотреть файл

@ -105,6 +105,7 @@
#include "nsIDOMElement.h"
#include "nsIChromeEventHandler.h"
#include "nsIContent.h"
#include "nsIDOMWindowCollection.h"
#include "imgICache.h"
static char kChromePrefix[] = "chrome://";
@ -1106,41 +1107,62 @@ nsChromeRegistry::UpdateArc(nsIRDFDataSource *aDataSource, nsIRDFResource* aSour
// theme stuff
static void FlushSkinBindingsForWindow(nsIDOMWindowInternal* aWindow)
{
// Get the DOM document.
nsCOMPtr<nsIDOMDocument> domDocument;
aWindow->GetDocument(getter_AddRefs(domDocument));
if (!domDocument)
return;
nsCOMPtr<nsIDocument> document = do_QueryInterface(domDocument);
if (!document)
return;
// Annihilate all XBL bindings.
nsCOMPtr<nsIBindingManager> bindingManager;
document->GetBindingManager(getter_AddRefs(bindingManager));
bindingManager->FlushSkinBindings();
}
NS_IMETHODIMP nsChromeRegistry::RefreshSkins()
{
nsresult rv;
nsCOMPtr<nsIWindowMediator> windowMediator(do_GetService(kWindowMediatorCID));
if (!windowMediator)
return NS_OK;
rv = FlushCaches();
if (NS_FAILED(rv)) return rv;
// Get the window mediator
nsCOMPtr<nsIWindowMediator> windowMediator =
do_GetService(kWindowMediatorCID, &rv);
if (NS_SUCCEEDED(rv)) {
nsCOMPtr<nsISimpleEnumerator> windowEnumerator;
if (NS_SUCCEEDED(windowMediator->GetEnumerator(nsnull, getter_AddRefs(windowEnumerator)))) {
// Get each dom window
windowMediator->GetEnumerator(nsnull, getter_AddRefs(windowEnumerator));
PRBool more;
rv = windowEnumerator->HasMoreElements(&more);
if (NS_FAILED(rv)) return rv;
windowEnumerator->HasMoreElements(&more);
while (more) {
nsCOMPtr<nsISupports> protoWindow;
rv = windowEnumerator->GetNext(getter_AddRefs(protoWindow));
if (NS_SUCCEEDED(rv) && protoWindow) {
windowEnumerator->GetNext(getter_AddRefs(protoWindow));
if (protoWindow) {
nsCOMPtr<nsIDOMWindowInternal> domWindow = do_QueryInterface(protoWindow);
if (domWindow) {
rv = RefreshWindow(domWindow);
if (NS_FAILED(rv)) return rv;
}
}
rv = windowEnumerator->HasMoreElements(&more);
if (NS_FAILED(rv)) return rv;
}
if (domWindow)
FlushSkinBindingsForWindow(domWindow);
}
windowEnumerator->HasMoreElements(&more);
}
return rv;
FlushCaches();
windowMediator->GetEnumerator(nsnull, getter_AddRefs(windowEnumerator));
windowEnumerator->HasMoreElements(&more);
while (more) {
nsCOMPtr<nsISupports> protoWindow;
windowEnumerator->GetNext(getter_AddRefs(protoWindow));
if (protoWindow) {
nsCOMPtr<nsIDOMWindowInternal> domWindow = do_QueryInterface(protoWindow);
if (domWindow)
RefreshWindow(domWindow);
}
windowEnumerator->HasMoreElements(&more);
}
return NS_OK;
}
@ -1149,12 +1171,10 @@ nsresult nsChromeRegistry::FlushCaches()
nsresult rv;
// Flush the style sheet cache completely.
// XXX For now flush everything. need a better call that only flushes style sheets.
nsCOMPtr<nsIXULPrototypeCache> xulCache =
do_GetService("@mozilla.org/xul/xul-prototype-cache;1", &rv);
if (NS_SUCCEEDED(rv) && xulCache) {
xulCache->Flush();
}
if (NS_SUCCEEDED(rv) && xulCache)
xulCache->FlushSkinFiles();
// Flush the new imagelib image chrome cache.
nsCOMPtr<imgICache> imageCache(do_GetService("@mozilla.org/image/cache;1", &rv));
@ -1175,6 +1195,18 @@ static PRBool IsChromeURI(nsIURI* aURI)
NS_IMETHODIMP nsChromeRegistry::RefreshWindow(nsIDOMWindowInternal* aWindow)
{
// Deal with our subframes first.
nsCOMPtr<nsIDOMWindowCollection> frames;
aWindow->GetFrames(getter_AddRefs(frames));
PRUint32 length;
frames->GetLength(&length);
for (PRUint32 i = 0; i < length; i++) {
nsCOMPtr<nsIDOMWindow> childWin;
frames->Item(i, getter_AddRefs(childWin));
nsCOMPtr<nsIDOMWindowInternal> childInt(do_QueryInterface(childWin));
RefreshWindow(childInt);
}
nsresult rv;
// Get the DOM document.
nsCOMPtr<nsIDOMDocument> domDocument;
@ -1186,13 +1218,6 @@ NS_IMETHODIMP nsChromeRegistry::RefreshWindow(nsIDOMWindowInternal* aWindow)
if (!document)
return NS_OK;
// Annihilate all XBL bindings.
nsCOMPtr<nsIBindingManager> bindingManager;
document->GetBindingManager(getter_AddRefs(bindingManager));
bindingManager->FlushChromeBindings();
nsCOMPtr<nsIXULDocument> xulDoc = do_QueryInterface(domDocument);
if (xulDoc) {
// Deal with the agent sheets first.
PRInt32 shellCount = document->GetNumberOfShells();
for (PRInt32 k = 0; k < shellCount; k++) {
@ -1238,7 +1263,6 @@ NS_IMETHODIMP nsChromeRegistry::RefreshWindow(nsIDOMWindowInternal* aWindow)
styleSet->ReplaceAgentStyleSheets(newAgentSheets);
}
}
}
nsCOMPtr<nsIHTMLContentContainer> container = do_QueryInterface(document);
nsCOMPtr<nsICSSLoader> cssLoader;
@ -1246,10 +1270,6 @@ NS_IMETHODIMP nsChromeRegistry::RefreshWindow(nsIDOMWindowInternal* aWindow)
if (NS_FAILED(rv)) return rv;
// Build an array of nsIURIs of style sheets we need to load.
nsCOMPtr<nsISupportsArray> urls;
rv = NS_NewISupportsArray(getter_AddRefs(urls));
if (NS_FAILED(rv)) return rv;
nsCOMPtr<nsISupportsArray> oldSheets;
rv = NS_NewISupportsArray(getter_AddRefs(oldSheets));
if (NS_FAILED(rv)) return rv;
@ -1270,7 +1290,8 @@ NS_IMETHODIMP nsChromeRegistry::RefreshWindow(nsIDOMWindowInternal* aWindow)
document->GetNumberOfStyleSheets(&count);
// Iterate over the style sheets.
for (PRInt32 i = 0; i < count; i++) {
PRUint32 i;
for (i = 0; i < (PRUint32)count; i++) {
// Get the style sheet
nsCOMPtr<nsIStyleSheet> styleSheet;
document->GetStyleSheetAt(i, getter_AddRefs(styleSheet));
@ -1281,40 +1302,35 @@ NS_IMETHODIMP nsChromeRegistry::RefreshWindow(nsIDOMWindowInternal* aWindow)
nsCOMPtr<nsIStyleSheet> attr = do_QueryInterface(attrSheet);
nsCOMPtr<nsIStyleSheet> inl = do_QueryInterface(inlineSheet);
if ((attr.get() != styleSheet.get()) &&
(inl.get() != styleSheet.get())) {
// Get the URI and add it to our array.
(inl.get() != styleSheet.get()))
// Add this sheet to the list of old style sheets.
oldSheets->AppendElement(styleSheet);
}
// Iterate over our old sheets and kick off a sync load of the new
// sheet if and only if it's a chrome URL.
PRUint32 oldCount;
oldSheets->Count(&oldCount);
for (i = 0; i < oldCount; i++) {
nsCOMPtr<nsISupports> supp = getter_AddRefs(oldSheets->ElementAt(i));
nsCOMPtr<nsIStyleSheet> sheet(do_QueryInterface(supp));
nsCOMPtr<nsIURI> uri;
rv = styleSheet->GetURL(*getter_AddRefs(uri));
if (NS_FAILED(rv)) return rv;
rv = urls->AppendElement(uri) ? NS_OK : NS_ERROR_FAILURE;
rv = sheet->GetURL(*getter_AddRefs(uri));
if (NS_FAILED(rv)) return rv;
// Remove the sheet.
rv = oldSheets->AppendElement(styleSheet) ? NS_OK : NS_ERROR_FAILURE;
if (NS_FAILED(rv)) return rv;
}
}
// Iterate over the URL array and kick off an asynchronous load of the
// sheets for our doc.
PRUint32 urlCount;
rv = urls->Count(&urlCount);
if (NS_FAILED(rv)) return rv;
for (PRUint32 j = 0; j < urlCount; j++) {
nsCOMPtr<nsISupports> supports = getter_AddRefs(urls->ElementAt(j));
nsCOMPtr<nsIURL> url = do_QueryInterface(supports);
if (IsChromeURI(uri)) {
// Reload the sheet.
nsCOMPtr<nsICSSStyleSheet> newSheet;
rv = LoadStyleSheetWithURL(url, getter_AddRefs(newSheet));
if (NS_FAILED(rv)) return rv;
if (newSheet) {
rv = newSheets->AppendElement(newSheet) ? NS_OK : NS_ERROR_FAILURE;
if (NS_FAILED(rv)) return rv;
LoadStyleSheetWithURL(uri, getter_AddRefs(newSheet));
if (newSheet)
newSheets->AppendElement(newSheet);
}
else // Just use the same sheet.
newSheets->AppendElement(sheet);
}
// Now notify the document that multiple sheets have been added and removed.
rv = document->UpdateStyleSheets(oldSheets, newSheets);
if (NS_FAILED(rv)) return rv;
document->UpdateStyleSheets(oldSheets, newSheets);
}
return NS_OK;

Просмотреть файл

@ -48,6 +48,8 @@
#include "nsIDocShellTreeItem.h"
#include "nsStyleUtil.h"
#include "nsCSSAtoms.h"
#include "nsThemeConstants.h"
#include "nsITheme.h"
// Temporary - Test of full time Standard mode for forms
#include "nsIPref.h"
@ -352,6 +354,8 @@ static PRBool SetColor(const nsCSSValue& aValue, const nscolor aParentColor,
nsILookAndFeel* look = nsnull;
if (NS_SUCCEEDED(aPresContext->GetLookAndFeel(&look)) && look) {
nsILookAndFeel::nsColorID colorID = (nsILookAndFeel::nsColorID)aValue.GetIntValue();
if (colorID == nsILookAndFeel::eColor_theme)
return PR_FALSE;
if (NS_SUCCEEDED(look->GetColor(colorID, aResult))) {
result = PR_TRUE;
}
@ -758,7 +762,8 @@ CheckFontCallback(const nsCSSStruct& aData)
(family == NS_STYLE_FONT_BUTTON) ||
(family == NS_STYLE_FONT_PULL_DOWN_MENU) ||
(family == NS_STYLE_FONT_LIST) ||
(family == NS_STYLE_FONT_FIELD))
(family == NS_STYLE_FONT_FIELD) ||
(family == NS_STYLE_FONT_THEME))
return nsRuleNode::eRuleFullMixed;
}
return nsRuleNode::eRuleUnknown;
@ -774,6 +779,7 @@ static const PropertyCheckData FontCheckProperties[] = {
};
static const PropertyCheckData DisplayCheckProperties[] = {
CHECKDATA_PROP(nsCSSDisplay, mAppearance, CHECKDATA_VALUE, PR_FALSE),
CHECKDATA_PROP(nsCSSDisplay, mClip, CHECKDATA_RECT, PR_FALSE),
CHECKDATA_PROP(nsCSSDisplay, mDisplay, CHECKDATA_VALUE, PR_FALSE),
CHECKDATA_PROP(nsCSSDisplay, mBinding, CHECKDATA_VALUE, PR_FALSE),
@ -1803,6 +1809,7 @@ SetFont(nsIPresContext* aPresContext, nsIStyleContext* aContext,
case NS_STYLE_FONT_PULL_DOWN_MENU:sysID = eSystemFont_PullDownMenu; break;
case NS_STYLE_FONT_LIST: sysID = eSystemFont_List; break;
case NS_STYLE_FONT_FIELD: sysID = eSystemFont_Field; break;
case NS_STYLE_FONT_THEME: sysID = eSystemFont_Theme; break;
}
nsCompatibility mode = eCompatibility_Standard;
@ -1826,7 +1833,24 @@ SetFont(nsIPresContext* aPresContext, nsIStyleContext* aContext,
if (dc) {
// GetSystemFont sets the font face but not necessarily the size
aFont->mFont.size = defaultVariableFont.size;
if (NS_FAILED(dc->GetSystemFont(sysID, &aFont->mFont))) {
// If our font type is theme, then check for appearance data and
// obtain our font based off our widget type.
if (sysID == eSystemFont_Theme) {
const nsStyleDisplay* display = (const nsStyleDisplay*)
aContext->GetStyleData(eStyleStruct_Display);
if (display->mAppearance) {
// Get our theme.
nsCOMPtr<nsITheme> theme;
aPresContext->GetTheme(getter_AddRefs(theme));
if (theme) {
nsCOMPtr<nsIDeviceContext> deviceContext;
aPresContext->GetDeviceContext(getter_AddRefs(deviceContext));
theme->GetWidgetFont(deviceContext, display->mAppearance, &aFont->mFont);
}
}
}
else if (NS_FAILED(dc->GetSystemFont(sysID, &aFont->mFont))) {
aFont->mFont.name = defaultVariableFont.name;
}
aFont->mSize = aFont->mFont.size; // this becomes our cascading size
@ -2697,6 +2721,18 @@ nsRuleNode::ComputeDisplayData(nsStyleStruct* aStartStruct, const nsCSSStruct& a
display->mDisplay = parentDisplay->mDisplay;
}
// appearance: enum, none, inherit
if (eCSSUnit_Enumerated == displayData.mAppearance.GetUnit()) {
display->mAppearance = displayData.mAppearance.GetIntValue();
}
else if (eCSSUnit_None == displayData.mAppearance.GetUnit()) {
display->mAppearance = NS_THEME_NONE;
}
else if (eCSSUnit_Inherit == displayData.mAppearance.GetUnit()) {
inherited = PR_TRUE;
display->mAppearance = parentDisplay->mAppearance;
}
// binding: url, none, inherit
if (eCSSUnit_URL == displayData.mBinding.GetUnit()) {
displayData.mBinding.GetStringValue(display->mBinding);
@ -3026,7 +3062,18 @@ nsRuleNode::ComputeColorData(nsStyleStruct* aStartStruct, const nsCSSStruct& aDa
parentColor = color;
// color: color, string, inherit
SetColor(colorData.mColor, parentColor->mColor, mPresContext, color->mColor, inherited);
if (!SetColor(colorData.mColor, parentColor->mColor, mPresContext, color->mColor,
inherited) && colorData.mColor.GetUnit() == eCSSUnit_Integer) {
// See if this is a special theme color. Theme colors must always be resolved
// dynamically at paint time.
nsCOMPtr<nsILookAndFeel> look;
mPresContext->GetLookAndFeel(getter_AddRefs(look));
if (look) {
nsILookAndFeel::nsColorID colorID = (nsILookAndFeel::nsColorID)colorData.mColor.GetIntValue();
if (colorID == nsILookAndFeel::eColor_theme)
color->mColorFlags = NS_COLORFLAGS_THEME;
}
}
if (inherited)
// We inherited, and therefore can't be cached in the rule node. We have to be put right on the

Просмотреть файл

@ -148,11 +148,31 @@ public:
NS_IMETHOD Shutdown();
// The following two methods can be used to tear down and reconstruct a rule tree. The idea
// is to first call BeginRuleTreeReconstruct, which will set aside the old rule
// tree. The entire frame tree should then have ReResolveStyleContext
// called on it. With the old rule tree hidden from view, the newly resolved style contexts will
// resolve to rule nodes in a fresh rule tree, and the re-resolve system will properly compute
// the visual impact of the changes.
//
// After re-resolution, call EndRuleTreeReconstruct() to finally discard the old rule tree.
// This trick can be used in lieu of a full frame reconstruction when drastic style changes
// happen (e.g., stylesheets being added/removed in the DOM, theme switching in the Mozilla app,
// etc.
virtual nsresult BeginRuleTreeReconstruct();
virtual nsresult EndRuleTreeReconstruct();
virtual nsresult GetRuleTree(nsRuleNode** aResult);
virtual nsresult ClearCachedDataInRuleTree(nsIStyleRule* aRule);
virtual nsresult ClearStyleData(nsIPresContext* aPresContext, nsIStyleRule* aRule, nsIStyleContext* aContext);
virtual nsresult GetStyleFrameConstruction(nsIStyleFrameConstruction** aResult) {
*aResult = mFrameConstructor;
NS_IF_ADDREF(*aResult);
return NS_OK;
}
virtual nsresult RemoveBodyFixupRule(nsIDocument *aDocument);
NS_IMETHOD ReParentStyleContext(nsIPresContext* aPresContext,
@ -318,6 +338,7 @@ protected:
nsRuleNode* mRuleTree; // This is the root of our rule tree. It is a lexicographic tree of
// matched rules that style contexts use to look up properties.
nsRuleNode* mOldRuleTree; // Used during rule tree reconstruction.
nsRuleWalker* mRuleWalker; // This is an instance of a rule walker that can be used
// to navigate through our tree.
@ -336,6 +357,7 @@ StyleSetImpl::StyleSetImpl()
: mFrameConstructor(nsnull),
mQuirkStyleSheet(nsnull),
mRuleTree(nsnull),
mOldRuleTree(nsnull),
mRuleWalker(nsnull)
#ifdef MOZ_PERF_METRICS
,mTimerEnabled(PR_FALSE)
@ -1224,6 +1246,26 @@ StyleSetImpl::GetRuleTree(nsRuleNode** aResult)
return NS_OK;
}
nsresult
StyleSetImpl::BeginRuleTreeReconstruct()
{
delete mRuleWalker;
mRuleWalker = nsnull;
mOldRuleTree = mRuleTree;
mRuleTree = nsnull;
return NS_OK;
}
nsresult
StyleSetImpl::EndRuleTreeReconstruct()
{
if (mOldRuleTree) {
mOldRuleTree->Destroy();
mOldRuleTree = nsnull;
}
return NS_OK;
}
nsresult
StyleSetImpl::ClearCachedDataInRuleTree(nsIStyleRule* aInlineStyleRule)
{

Просмотреть файл

@ -402,6 +402,7 @@ void nsCSSDisplay::List(FILE* out, PRInt32 aIndent) const
nsAutoString buffer;
mAppearance.AppendToString(buffer, eCSSProperty_appearance);
mDirection.AppendToString(buffer, eCSSProperty_direction);
mDisplay.AppendToString(buffer, eCSSProperty_display);
mBinding.AppendToString(buffer, eCSSProperty_binding);
@ -1554,6 +1555,7 @@ CSSDeclarationImpl::AppendValue(nsCSSProperty aProperty, const nsCSSValue& aValu
break;
// nsCSSDisplay
case eCSSProperty_appearance:
case eCSSProperty_float:
case eCSSProperty_clear:
case eCSSProperty_display:
@ -1565,6 +1567,7 @@ CSSDeclarationImpl::AppendValue(nsCSSProperty aProperty, const nsCSSValue& aValu
case eCSSProperty_overflow:
CSS_ENSURE(Display) {
switch (aProperty) {
case eCSSProperty_appearance: mDisplay->mAppearance = aValue; break;
case eCSSProperty_float: mDisplay->mFloat = aValue; break;
case eCSSProperty_clear: mDisplay->mClear = aValue; break;
case eCSSProperty_display: mDisplay->mDisplay = aValue; break;
@ -2326,6 +2329,7 @@ CSSDeclarationImpl::SetValueImportant(nsCSSProperty aProperty)
break;
// nsCSSDisplay
case eCSSProperty_appearance:
case eCSSProperty_direction:
case eCSSProperty_display:
case eCSSProperty_binding:
@ -2338,6 +2342,7 @@ CSSDeclarationImpl::SetValueImportant(nsCSSProperty aProperty)
if (nsnull != mDisplay) {
CSS_ENSURE_IMPORTANT(Display) {
switch (aProperty) {
CSS_CASE_IMPORTANT(eCSSProperty_appearance, mDisplay->mAppearance);
CSS_CASE_IMPORTANT(eCSSProperty_direction, mDisplay->mDirection);
CSS_CASE_IMPORTANT(eCSSProperty_display, mDisplay->mDisplay);
CSS_CASE_IMPORTANT(eCSSProperty_binding, mDisplay->mBinding);
@ -3204,6 +3209,7 @@ CSSDeclarationImpl::RemoveProperty(nsCSSProperty aProperty)
break;
// nsCSSDisplay
case eCSSProperty_appearance:
case eCSSProperty_float:
case eCSSProperty_clear:
case eCSSProperty_display:
@ -3215,6 +3221,7 @@ CSSDeclarationImpl::RemoveProperty(nsCSSProperty aProperty)
case eCSSProperty_overflow:
CSS_CHECK(Display) {
switch (aProperty) {
case eCSSProperty_appearance: mDisplay->mAppearance.Reset(); break;
case eCSSProperty_float: mDisplay->mFloat.Reset(); break;
case eCSSProperty_clear: mDisplay->mClear.Reset(); break;
case eCSSProperty_display: mDisplay->mDisplay.Reset(); break;
@ -3995,6 +4002,7 @@ CSSDeclarationImpl::GetValue(nsCSSProperty aProperty, nsCSSValue& aValue)
break;
// nsCSSDisplay
case eCSSProperty_appearance:
case eCSSProperty_float:
case eCSSProperty_clear:
case eCSSProperty_display:
@ -4006,6 +4014,7 @@ CSSDeclarationImpl::GetValue(nsCSSProperty aProperty, nsCSSValue& aValue)
case eCSSProperty_overflow:
if (nsnull != mDisplay) {
switch (aProperty) {
case eCSSProperty_appearance: aValue = mDisplay->mAppearance; break;
case eCSSProperty_float: aValue = mDisplay->mFloat; break;
case eCSSProperty_clear: aValue = mDisplay->mClear; break;
case eCSSProperty_display: aValue = mDisplay->mDisplay; break;

Просмотреть файл

@ -67,6 +67,7 @@
#include "nsCSSAtoms.h"
#include "nsINameSpaceManager.h"
#include "nsINameSpace.h"
#include "nsThemeConstants.h"
// XXX TODO:
// - rework aErrorCode stuff: switch over to nsresult
@ -257,6 +258,7 @@ protected:
#endif
// Property specific parsing routines
PRBool ParseAppearance(PRInt32& aErrorCode, nsICSSDeclaration* aDeclaration, PRInt32& aChangeHint);
PRBool ParseAzimuth(PRInt32& aErrorCode, nsCSSValue& aValue);
PRBool ParseBackground(PRInt32& aErrorCode, nsICSSDeclaration* aDeclaration, PRInt32& aChangeHint);
PRBool ParseBackgroundPosition(PRInt32& aErrorCode, nsICSSDeclaration* aDeclaration, PRInt32& aChangeHint);
@ -3400,6 +3402,8 @@ PRBool CSSParserImpl::ParseProperty(PRInt32& aErrorCode,
PRInt32& aChangeHint)
{
switch (aPropID) { // handle shorthand or multiple properties
case eCSSProperty_appearance:
return ParseAppearance(aErrorCode, aDeclaration, aChangeHint);
case eCSSProperty_background:
return ParseBackground(aErrorCode, aDeclaration, aChangeHint);
case eCSSProperty_background_position:
@ -3616,6 +3620,8 @@ PRBool CSSParserImpl::ParseSingleValueProperty(PRInt32& aErrorCode,
case eCSSProperty_background_y_position:
return ParseVariant(aErrorCode, aValue, VARIANT_HKLP,
kBackgroundXYPositionKTable);
case eCSSProperty_appearance:
return ParseVariant(aErrorCode, aValue, VARIANT_HOK, nsCSSProps::kAppearanceKTable);
case eCSSProperty_binding:
return ParseVariant(aErrorCode, aValue, VARIANT_HUO, nsnull);
case eCSSProperty_border_collapse:
@ -3947,6 +3953,52 @@ PRBool CSSParserImpl::ParseAzimuth(PRInt32& aErrorCode, nsCSSValue& aValue)
return PR_FALSE;
}
static PRBool HasForegroundContent(PRUint8 aAppearance)
{
return ((aAppearance == NS_THEME_BUTTON) ||
(aAppearance == NS_THEME_TOOLBAR_BUTTON) ||
(aAppearance == NS_THEME_TOOLBAR_DUAL_BUTTON) ||
(aAppearance == NS_THEME_LISTBOX_LISTITEM) ||
(aAppearance == NS_THEME_TREEVIEW_TREEITEM) ||
(aAppearance == NS_THEME_TREEVIEW_HEADER_CELL) ||
(aAppearance == NS_THEME_TAB) ||
(aAppearance == NS_THEME_TOOLTIP) ||
(aAppearance == NS_THEME_TEXTFIELD));
}
PRBool CSSParserImpl::ParseAppearance(PRInt32& aErrorCode, nsICSSDeclaration* aDeclaration,
PRInt32& aChangeHint)
{
nsCSSValue appearance;
if (!ParseVariant(aErrorCode, appearance, VARIANT_HK, nsCSSProps::kAppearanceKTable))
return PR_FALSE;
if (ExpectEndProperty(aErrorCode, PR_TRUE))
aErrorCode = AppendValue(aDeclaration, eCSSProperty_appearance, appearance, aChangeHint);
else
return PR_FALSE;
if (appearance.GetIntValue() && HasForegroundContent(appearance.GetIntValue())) {
// When an appearance is specified, it can act as a shorthand that
// specifies color and font information as well.
// Add in font information.
PRInt32 index = SearchKeywordTable(eCSSKeyword_theme, nsCSSProps::kFontKTable);
if (index > 0) {
nsCSSValue val(nsCSSProps::kFontKTable[index], eCSSUnit_Enumerated);
AppendValue(aDeclaration, eCSSProperty_font_family, val, aChangeHint);
}
// Add in color information.
index = SearchKeywordTable(eCSSKeyword_theme, nsCSSProps::kColorKTable);
if (index > 0) {
nsCSSValue val(nsCSSProps::kColorKTable[index], eCSSUnit_Integer);
AppendValue(aDeclaration, eCSSProperty_color, val, aChangeHint);
}
}
return PR_TRUE;
}
PRBool CSSParserImpl::ParseBackground(PRInt32& aErrorCode, nsICSSDeclaration* aDeclaration,
PRInt32& aChangeHint)
{

Просмотреть файл

@ -402,6 +402,7 @@ void nsCSSDisplay::List(FILE* out, PRInt32 aIndent) const
nsAutoString buffer;
mAppearance.AppendToString(buffer, eCSSProperty_appearance);
mDirection.AppendToString(buffer, eCSSProperty_direction);
mDisplay.AppendToString(buffer, eCSSProperty_display);
mBinding.AppendToString(buffer, eCSSProperty_binding);
@ -1554,6 +1555,7 @@ CSSDeclarationImpl::AppendValue(nsCSSProperty aProperty, const nsCSSValue& aValu
break;
// nsCSSDisplay
case eCSSProperty_appearance:
case eCSSProperty_float:
case eCSSProperty_clear:
case eCSSProperty_display:
@ -1565,6 +1567,7 @@ CSSDeclarationImpl::AppendValue(nsCSSProperty aProperty, const nsCSSValue& aValu
case eCSSProperty_overflow:
CSS_ENSURE(Display) {
switch (aProperty) {
case eCSSProperty_appearance: mDisplay->mAppearance = aValue; break;
case eCSSProperty_float: mDisplay->mFloat = aValue; break;
case eCSSProperty_clear: mDisplay->mClear = aValue; break;
case eCSSProperty_display: mDisplay->mDisplay = aValue; break;
@ -2326,6 +2329,7 @@ CSSDeclarationImpl::SetValueImportant(nsCSSProperty aProperty)
break;
// nsCSSDisplay
case eCSSProperty_appearance:
case eCSSProperty_direction:
case eCSSProperty_display:
case eCSSProperty_binding:
@ -2338,6 +2342,7 @@ CSSDeclarationImpl::SetValueImportant(nsCSSProperty aProperty)
if (nsnull != mDisplay) {
CSS_ENSURE_IMPORTANT(Display) {
switch (aProperty) {
CSS_CASE_IMPORTANT(eCSSProperty_appearance, mDisplay->mAppearance);
CSS_CASE_IMPORTANT(eCSSProperty_direction, mDisplay->mDirection);
CSS_CASE_IMPORTANT(eCSSProperty_display, mDisplay->mDisplay);
CSS_CASE_IMPORTANT(eCSSProperty_binding, mDisplay->mBinding);
@ -3204,6 +3209,7 @@ CSSDeclarationImpl::RemoveProperty(nsCSSProperty aProperty)
break;
// nsCSSDisplay
case eCSSProperty_appearance:
case eCSSProperty_float:
case eCSSProperty_clear:
case eCSSProperty_display:
@ -3215,6 +3221,7 @@ CSSDeclarationImpl::RemoveProperty(nsCSSProperty aProperty)
case eCSSProperty_overflow:
CSS_CHECK(Display) {
switch (aProperty) {
case eCSSProperty_appearance: mDisplay->mAppearance.Reset(); break;
case eCSSProperty_float: mDisplay->mFloat.Reset(); break;
case eCSSProperty_clear: mDisplay->mClear.Reset(); break;
case eCSSProperty_display: mDisplay->mDisplay.Reset(); break;
@ -3995,6 +4002,7 @@ CSSDeclarationImpl::GetValue(nsCSSProperty aProperty, nsCSSValue& aValue)
break;
// nsCSSDisplay
case eCSSProperty_appearance:
case eCSSProperty_float:
case eCSSProperty_clear:
case eCSSProperty_display:
@ -4006,6 +4014,7 @@ CSSDeclarationImpl::GetValue(nsCSSProperty aProperty, nsCSSValue& aValue)
case eCSSProperty_overflow:
if (nsnull != mDisplay) {
switch (aProperty) {
case eCSSProperty_appearance: aValue = mDisplay->mAppearance; break;
case eCSSProperty_float: aValue = mDisplay->mFloat; break;
case eCSSProperty_clear: aValue = mDisplay->mClear; break;
case eCSSProperty_display: aValue = mDisplay->mDisplay; break;

Просмотреть файл

@ -2285,6 +2285,11 @@ MapDisplayForDeclaration(nsICSSDeclaration* aDecl, const nsStyleStructID& aID, n
return NS_OK; // We don't have any rules for display.
if (aID == eStyleStruct_Display) {
// appearance: enum, none, inherit
if (aDisplay.mAppearance.GetUnit() == eCSSUnit_Null &&
ourDisplay->mAppearance.GetUnit() != eCSSUnit_Null)
aDisplay.mAppearance = ourDisplay->mAppearance;
// display: enum, none, inherit
if (aDisplay.mDisplay.GetUnit() == eCSSUnit_Null && ourDisplay->mDisplay.GetUnit() != eCSSUnit_Null)
aDisplay.mDisplay = ourDisplay->mDisplay;

Просмотреть файл

@ -1,515 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Netscape Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the NPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the NPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef nsICSSDeclaration_h___
#define nsICSSDeclaration_h___
#include "nsISupports.h"
#include "nsColor.h"
#include <stdio.h>
#include "nsString.h"
#include "nsCoord.h"
#include "nsCSSValue.h"
#include "nsCSSProps.h"
class nsISizeOfHandler;
struct nsCSSStruct {
virtual const nsID& GetID(void) = 0;
virtual ~nsCSSStruct();
};
// SID for the nsCSSFont struct {f645dbf8-b48a-11d1-9ca5-0060088f9ff7}
#define NS_CSS_FONT_SID \
{0xf645dbf8, 0xb48a, 0x11d1, {0x9c, 0xa5, 0x00, 0x60, 0x08, 0x8f, 0x9f, 0xf7}}
// SID for the nsCSSColor struct {fd825f22-b48a-11d1-9ca5-0060088f9ff7}
#define NS_CSS_COLOR_SID \
{0xfd825f22, 0xb48a, 0x11d1, {0x9c, 0xa5, 0x00, 0x60, 0x08, 0x8f, 0x9f, 0xf7}}
// SID for the nsCSSText struct {fe13ce94-b48a-11d1-9ca5-0060088f9ff7}
#define NS_CSS_TEXT_SID \
{0xfe13ce94, 0xb48a, 0x11d1, {0x9c, 0xa5, 0x00, 0x60, 0x08, 0x8f, 0x9f, 0xf7}}
// SID for the nsCSSDisplay struct {fe13ce95-b48a-11d1-9ca5-0060088f9ff7}
#define NS_CSS_DISPLAY_SID \
{0xfe13ce95, 0xb48a, 0x11d1, {0x9c, 0xa5, 0x00, 0x60, 0x08, 0x8f, 0x9f, 0xf7}}
// SID for the nsCSSMargin struct {fe6019d4-b48a-11d1-9ca5-0060088f9ff7}
#define NS_CSS_MARGIN_SID \
{0xfe6019d4, 0xb48a, 0x11d1, {0x9c, 0xa5, 0x00, 0x60, 0x08, 0x8f, 0x9f, 0xf7}}
// SID for the nsCSSPosition struct {fee33b2a-b48a-11d1-9ca5-0060088f9ff7}
#define NS_CSS_POSITION_SID \
{0xfee33b2a, 0xb48a, 0x11d1, {0x9c, 0xa5, 0x00, 0x60, 0x08, 0x8f, 0x9f, 0xf7}}
// SID for the nsCSSList struct {603f8266-b48b-11d1-9ca5-0060088f9ff7}
#define NS_CSS_LIST_SID \
{0x603f8266, 0xb48b, 0x11d1, {0x9c, 0xa5, 0x00, 0x60, 0x08, 0x8f, 0x9f, 0xf7}}
// SID for the nsCSSTable struct {16aa4b30-5a3b-11d2-803b-006008159b5a}
#define NS_CSS_TABLE_SID \
{0x16aa4b30, 0x5a3b, 0x11d2, {0x80, 0x3b, 0x00, 0x60, 0x08, 0x15, 0x9b, 0x5a}}
// SID for the nsCSSBreaks struct {15124c20-5a3b-11d2-803b-006008159b5a}
#define NS_CSS_BREAKS_SID \
{0x15124c20, 0x5a3b, 0x11d2, {0x80, 0x3b, 0x00, 0x60, 0x08, 0x15, 0x9b, 0x5a}}
// SID for the nsCSSPage struct {15dd8810-5a3b-11d2-803b-006008159b5a}
#define NS_CSS_PAGE_SID \
{0x15dd8810, 0x5a3b, 0x11d2, {0x80, 0x3b, 0x00, 0x60, 0x08, 0x15, 0x9b, 0x5a}}
// SID for the nsCSSContent struct {1629ef70-5a3b-11d2-803b-006008159b5a}
#define NS_CSS_CONTENT_SID \
{0x1629ef70, 0x5a3b, 0x11d2, {0x80, 0x3b, 0x00, 0x60, 0x08, 0x15, 0x9b, 0x5a}}
// SID for the nsCSSUserInterface struct {4397c3a0-3efe-11d3-8060-006008159b5a}
#define NS_CSS_USER_INTERFACE_SID \
{0x4397c3a0, 0x3efe, 0x11d3, {0x80, 0x60, 0x00, 0x60, 0x08, 0x15, 0x9b, 0x5a}}
// SID for the nsCSSAural struct {166d2bb0-5a3b-11d2-803b-006008159b5a}
#define NS_CSS_AURAL_SID \
{0x166d2bb0, 0x5a3b, 0x11d2, {0x80, 0x3b, 0x00, 0x60, 0x08, 0x15, 0x9b, 0x5a}}
#ifdef INCLUDE_XUL
// {FC075D62-B1CF-47a1-AF4E-CB40E11A4314}
#define NS_CSS_XUL_SID \
{ 0xfc075d62, 0xb1cf, 0x47a1, { 0xaf, 0x4e, 0xcb, 0x40, 0xe1, 0x1a, 0x43, 0x14 } }
#endif
#ifdef MOZ_SVG
// {9A41A036-027B-45ef-89C9-6E32797839E7}
#define NS_CSS_SVG_SID \
{ 0x9a41a036, 0x27b, 0x45ef, { 0x89, 0xc9, 0x6e, 0x32, 0x79, 0x78, 0x39, 0xe7 } }
#endif
// IID for the nsICSSDeclaration interface {7b36b9ac-b48d-11d1-9ca5-0060088f9ff7}
#define NS_ICSS_DECLARATION_IID \
{0x7b36b9ac, 0xb48d, 0x11d1, {0x9c, 0xa5, 0x00, 0x60, 0x08, 0x8f, 0x9f, 0xf7}}
struct nsCSSFont : public nsCSSStruct {
nsCSSFont(void);
nsCSSFont(const nsCSSFont& aCopy);
virtual ~nsCSSFont(void);
const nsID& GetID(void);
void List(FILE* out = stdout, PRInt32 aIndent = 0) const;
nsCSSValue mFamily;
nsCSSValue mStyle;
nsCSSValue mVariant;
nsCSSValue mWeight;
nsCSSValue mSize;
nsCSSValue mSizeAdjust; // NEW
nsCSSValue mStretch; // NEW
};
struct nsCSSValueList {
nsCSSValueList(void);
nsCSSValueList(const nsCSSValueList& aCopy);
~nsCSSValueList(void);
nsCSSValue mValue;
nsCSSValueList* mNext;
};
struct nsCSSColor : public nsCSSStruct {
nsCSSColor(void);
nsCSSColor(const nsCSSColor& aCopy);
virtual ~nsCSSColor(void);
const nsID& GetID(void);
void List(FILE* out = stdout, PRInt32 aIndent = 0) const;
nsCSSValue mColor;
nsCSSValue mBackColor;
nsCSSValue mBackImage;
nsCSSValue mBackRepeat;
nsCSSValue mBackAttachment;
nsCSSValue mBackPositionX;
nsCSSValue mBackPositionY;
};
struct nsCSSShadow {
nsCSSShadow(void);
nsCSSShadow(const nsCSSShadow& aCopy);
~nsCSSShadow(void);
nsCSSValue mColor;
nsCSSValue mXOffset;
nsCSSValue mYOffset;
nsCSSValue mRadius;
nsCSSShadow* mNext;
};
struct nsCSSText : public nsCSSStruct {
nsCSSText(void);
nsCSSText(const nsCSSText& aCopy);
virtual ~nsCSSText(void);
const nsID& GetID(void);
void List(FILE* out = stdout, PRInt32 aIndent = 0) const;
nsCSSValue mWordSpacing;
nsCSSValue mLetterSpacing;
nsCSSValue mVerticalAlign;
nsCSSValue mTextTransform;
nsCSSValue mTextAlign;
nsCSSValue mTextIndent;
nsCSSValue mDecoration;
nsCSSShadow* mTextShadow; // NEW
nsCSSValue mUnicodeBidi; // NEW
nsCSSValue mLineHeight;
nsCSSValue mWhiteSpace;
};
struct nsCSSRect {
nsCSSRect(void);
nsCSSRect(const nsCSSRect& aCopy);
~nsCSSRect();
void List(FILE* out = 0, nsCSSProperty aPropID = eCSSProperty_UNKNOWN, PRInt32 aIndent = 0) const;
void List(FILE* out, PRInt32 aIndent, const nsCSSProperty aTRBL[]) const;
nsCSSValue mTop;
nsCSSValue mRight;
nsCSSValue mBottom;
nsCSSValue mLeft;
};
struct nsCSSDisplay : public nsCSSStruct {
nsCSSDisplay(void);
nsCSSDisplay(const nsCSSDisplay& aCopy);
virtual ~nsCSSDisplay(void);
const nsID& GetID(void);
void List(FILE* out = stdout, PRInt32 aIndent = 0) const;
nsCSSValue mDirection;
nsCSSValue mDisplay;
nsCSSValue mBinding;
nsCSSValue mPosition;
nsCSSValue mFloat;
nsCSSValue mClear;
nsCSSRect* mClip;
nsCSSValue mOverflow;
nsCSSValue mVisibility;
nsCSSValue mOpacity;
// mLang member variable is here not because in needs to be stored
// in nsCSSDeclaration objects but because it's needed on the
// stack when the struct is used in WalkRuleTree.
nsCSSValue mLang;
};
struct nsCSSMargin : public nsCSSStruct {
nsCSSMargin(void);
nsCSSMargin(const nsCSSMargin& aCopy);
virtual ~nsCSSMargin(void);
const nsID& GetID(void);
void List(FILE* out = stdout, PRInt32 aIndent = 0) const;
void EnsureBorderColors();
nsCSSRect* mMargin;
nsCSSRect* mPadding;
nsCSSRect* mBorderWidth;
nsCSSRect* mBorderColor;
nsCSSValueList** mBorderColors;
nsCSSRect* mBorderStyle;
nsCSSRect* mBorderRadius; // (extension)
nsCSSValue mOutlineWidth;
nsCSSValue mOutlineColor;
nsCSSValue mOutlineStyle;
nsCSSRect* mOutlineRadius; // (extension)
nsCSSValue mFloatEdge; // NEW
};
struct nsCSSPosition : public nsCSSStruct {
nsCSSPosition(void);
nsCSSPosition(const nsCSSPosition& aCopy);
virtual ~nsCSSPosition(void);
const nsID& GetID(void);
void List(FILE* out = stdout, PRInt32 aIndent = 0) const;
nsCSSValue mWidth;
nsCSSValue mMinWidth;
nsCSSValue mMaxWidth;
nsCSSValue mHeight;
nsCSSValue mMinHeight;
nsCSSValue mMaxHeight;
nsCSSValue mBoxSizing; // NEW
nsCSSRect* mOffset;
nsCSSValue mZIndex;
};
struct nsCSSList : public nsCSSStruct {
nsCSSList(void);
nsCSSList(const nsCSSList& aCopy);
virtual ~nsCSSList(void);
const nsID& GetID(void);
void List(FILE* out = stdout, PRInt32 aIndent = 0) const;
nsCSSValue mType;
nsCSSValue mImage;
nsCSSValue mPosition;
nsCSSRect* mImageRegion;
};
struct nsCSSTable : public nsCSSStruct { // NEW
nsCSSTable(void);
nsCSSTable(const nsCSSTable& aCopy);
virtual ~nsCSSTable(void);
const nsID& GetID(void);
void List(FILE* out = stdout, PRInt32 aIndent = 0) const;
nsCSSValue mBorderCollapse;
nsCSSValue mBorderSpacingX;
nsCSSValue mBorderSpacingY;
nsCSSValue mCaptionSide;
nsCSSValue mEmptyCells;
nsCSSValue mLayout;
nsCSSValue mFrame; // Not mappable via CSS, only using HTML4 table attrs.
nsCSSValue mRules; // Not mappable via CSS, only using HTML4 table attrs.
nsCSSValue mSpan; // Not mappable via CSS, only using HTML4 table attrs.
nsCSSValue mCols; // Not mappable via CSS, only using HTML4 table attrs.
};
struct nsCSSBreaks : public nsCSSStruct { // NEW
nsCSSBreaks(void);
nsCSSBreaks(const nsCSSBreaks& aCopy);
virtual ~nsCSSBreaks(void);
const nsID& GetID(void);
void List(FILE* out = stdout, PRInt32 aIndent = 0) const;
nsCSSValue mOrphans;
nsCSSValue mWidows;
nsCSSValue mPage;
nsCSSValue mPageBreakAfter;
nsCSSValue mPageBreakBefore;
nsCSSValue mPageBreakInside;
};
struct nsCSSPage : public nsCSSStruct { // NEW
nsCSSPage(void);
nsCSSPage(const nsCSSPage& aCopy);
virtual ~nsCSSPage(void);
const nsID& GetID(void);
void List(FILE* out = stdout, PRInt32 aIndent = 0) const;
nsCSSValue mMarks;
nsCSSValue mSizeWidth;
nsCSSValue mSizeHeight;
};
struct nsCSSCounterData {
nsCSSCounterData(void);
nsCSSCounterData(const nsCSSCounterData& aCopy);
~nsCSSCounterData(void);
nsCSSValue mCounter;
nsCSSValue mValue;
nsCSSCounterData* mNext;
};
struct nsCSSQuotes {
nsCSSQuotes(void);
nsCSSQuotes(const nsCSSQuotes& aCopy);
~nsCSSQuotes(void);
nsCSSValue mOpen;
nsCSSValue mClose;
nsCSSQuotes* mNext;
};
struct nsCSSContent : public nsCSSStruct {
nsCSSContent(void);
nsCSSContent(const nsCSSContent& aCopy);
virtual ~nsCSSContent(void);
const nsID& GetID(void);
void List(FILE* out = stdout, PRInt32 aIndent = 0) const;
nsCSSValueList* mContent;
nsCSSCounterData* mCounterIncrement;
nsCSSCounterData* mCounterReset;
nsCSSValue mMarkerOffset;
nsCSSQuotes* mQuotes;
};
struct nsCSSUserInterface : public nsCSSStruct { // NEW
nsCSSUserInterface(void);
nsCSSUserInterface(const nsCSSUserInterface& aCopy);
virtual ~nsCSSUserInterface(void);
const nsID& GetID(void);
void List(FILE* out = stdout, PRInt32 aIndent = 0) const;
nsCSSValue mUserInput;
nsCSSValue mUserModify;
nsCSSValue mUserSelect;
nsCSSValueList* mKeyEquivalent;
nsCSSValue mUserFocus;
nsCSSValue mResizer;
nsCSSValueList* mCursor;
};
struct nsCSSAural : public nsCSSStruct { // NEW
nsCSSAural(void);
nsCSSAural(const nsCSSAural& aCopy);
virtual ~nsCSSAural(void);
const nsID& GetID(void);
void List(FILE* out = stdout, PRInt32 aIndent = 0) const;
nsCSSValue mAzimuth;
nsCSSValue mElevation;
nsCSSValue mCueAfter;
nsCSSValue mCueBefore;
nsCSSValue mPauseAfter;
nsCSSValue mPauseBefore;
nsCSSValue mPitch;
nsCSSValue mPitchRange;
nsCSSValue mPlayDuring;
nsCSSValue mPlayDuringFlags;
nsCSSValue mRichness;
nsCSSValue mSpeak;
nsCSSValue mSpeakHeader;
nsCSSValue mSpeakNumeral;
nsCSSValue mSpeakPunctuation;
nsCSSValue mSpeechRate;
nsCSSValue mStress;
nsCSSValue mVoiceFamily;
nsCSSValue mVolume;
};
#ifdef INCLUDE_XUL
struct nsCSSXUL : public nsCSSStruct {
nsCSSXUL(void);
nsCSSXUL(const nsCSSXUL& aCopy);
virtual ~nsCSSXUL(void);
const nsID& GetID(void);
void List(FILE* out = stdout, PRInt32 aIndent = 0) const;
nsCSSValue mBoxAlign;
nsCSSValue mBoxDirection;
nsCSSValue mBoxFlex;
nsCSSValue mBoxOrient;
nsCSSValue mBoxPack;
nsCSSValue mBoxOrdinal;
};
#endif
#ifdef MOZ_SVG
struct nsCSSSVG : public nsCSSStruct {
nsCSSSVG(void);
nsCSSSVG(const nsCSSSVG& aCopy);
virtual ~nsCSSSVG(void);
const nsID& GetID(void);
void List(FILE* out = stdout, PRInt32 aIndent = 0) const;
nsCSSValue mFill;
nsCSSValue mFillOpacity;
nsCSSValue mFillRule;
nsCSSValue mStroke;
nsCSSValue mStrokeDasharray;
nsCSSValue mStrokeDashoffset;
nsCSSValue mStrokeLinecap;
nsCSSValue mStrokeLinejoin;
nsCSSValue mStrokeMiterlimit;
nsCSSValue mStrokeOpacity;
nsCSSValue mStrokeWidth;
};
#endif
class nsICSSDeclaration : public nsISupports {
public:
NS_DEFINE_STATIC_IID_ACCESSOR(NS_ICSS_DECLARATION_IID);
NS_IMETHOD GetData(const nsID& aIID, nsCSSStruct** aData) = 0;
NS_IMETHOD EnsureData(const nsID& aSID, nsCSSStruct** aData) = 0;
NS_IMETHOD AppendValue(nsCSSProperty aProperty,
const nsCSSValue& aValue) = 0;
NS_IMETHOD AppendStructValue(nsCSSProperty aProperty, void* aStruct) = 0;
NS_IMETHOD SetValueImportant(nsCSSProperty aProperty) = 0;
NS_IMETHOD AppendComment(const nsAReadableString& aComment) = 0;
NS_IMETHOD RemoveProperty(nsCSSProperty aProperty, nsCSSValue& aValue) = 0;
// XXX make nscolor a struct to avoid type conflicts
NS_IMETHOD GetValue(nsCSSProperty aProperty, nsCSSValue& aValue) = 0;
NS_IMETHOD GetValue(nsCSSProperty aProperty, nsAWritableString& aValue) = 0;
NS_IMETHOD GetValue(const nsAReadableString& aProperty,
nsAWritableString& aValue) = 0;
NS_IMETHOD GetImportantValues(nsICSSDeclaration*& aResult) = 0;
NS_IMETHOD GetValueIsImportant(nsCSSProperty aProperty,
PRBool& aIsImportant) = 0;
NS_IMETHOD GetValueIsImportant(const nsAReadableString& aProperty,
PRBool& aIsImportant) = 0;
NS_IMETHOD Count(PRUint32* aCount) = 0;
NS_IMETHOD GetNthProperty(PRUint32 aIndex, nsAWritableString& aReturn) = 0;
NS_IMETHOD GetStyleImpact(PRInt32* aHint) const = 0;
NS_IMETHOD ToString(nsAWritableString& aString) = 0;
NS_IMETHOD Clone(nsICSSDeclaration*& aClone) const = 0;
#ifdef DEBUG
virtual void List(FILE* out = stdout, PRInt32 aIndent = 0) const = 0;
virtual void SizeOf(nsISizeOfHandler *aSizeOfHandler, PRUint32 &aSize) = 0;
#endif
};
extern NS_EXPORT nsresult
NS_NewCSSDeclaration(nsICSSDeclaration** aInstancePtrResult);
#endif /* nsICSSDeclaration_h___ */

Просмотреть файл

@ -408,6 +408,55 @@ CSS_KEY(x-small, x_small)
CSS_KEY(x-soft, x_soft)
CSS_KEY(xx-large, xx_large)
CSS_KEY(xx-small, xx_small)
// Appearance keywords for widget styles
CSS_KEY(theme, theme)
CSS_KEY(radio, radio)
CSS_KEY(checkbox, checkbox)
CSS_KEY(toolbox, toolbox)
CSS_KEY(toolbar, toolbar)
CSS_KEY(toolbarbutton, toolbarbutton)
CSS_KEY(toolbargripper, toolbargripper)
CSS_KEY(dualbutton, dualbutton)
CSS_KEY(dualbutton-dropdown, dualbutton_dropdown)
CSS_KEY(separator, separator)
CSS_KEY(statusbar, statusbar)
CSS_KEY(statusbarpane, statusbar_pane)
CSS_KEY(resizerpane, resizer_pane)
CSS_KEY(resizer, resizer)
CSS_KEY(listbox, listbox)
CSS_KEY(listitem, listitem)
CSS_KEY(treeview, treeview)
CSS_KEY(treeitem, treeitem)
CSS_KEY(treetwisty, treetwisty)
CSS_KEY(treeline, treeline)
CSS_KEY(treeheader, treeheader)
CSS_KEY(treeheadercell, treeheadercell)
CSS_KEY(treeheadersortarrow, treeheadersortarrow)
CSS_KEY(progressbar, progressbar)
CSS_KEY(progresschunk, progresschunk)
CSS_KEY(tab, tab)
CSS_KEY(tabpanel, tabpanel)
CSS_KEY(tooltip, tooltip)
CSS_KEY(spinner, spinner)
CSS_KEY(spinner-upbutton, spinner_upbutton)
CSS_KEY(spinner-downbutton, spinner_downbutton)
CSS_KEY(scrollbarbutton, scrollbarbutton)
CSS_KEY(scrollbartrack, scrollbartrack)
CSS_KEY(scrollbartrackstart, scrollbartrackstart)
CSS_KEY(scrollbartrackend, scrollbartrackend)
CSS_KEY(scrollbarthumb, scrollbarthumb)
CSS_KEY(scrollbargripper, scrollbargripper)
CSS_KEY(textfield, textfield)
CSS_KEY(caret, caret)
CSS_KEY(menulist, menulist)
CSS_KEY(menulistbutton, menulistbutton)
CSS_KEY(slider, slider)
CSS_KEY(sliderthumb, sliderthumb)
CSS_KEY(sliderthumbstart, sliderthumbstart)
CSS_KEY(sliderthumbend, sliderthumbend)
CSS_KEY(sliderthumbtick, sliderthumbtick)
#ifdef MOZ_SVG
CSS_KEY(bevel, bevel)
CSS_KEY(butt, butt)

Просмотреть файл

@ -76,6 +76,7 @@
// support them correctly the old constants need to be renamed and
// new ones should be entered.
CSS_PROP(-moz-appearance, appearance, REFLOW)
CSS_PROP(-moz-border-radius, _moz_border_radius, VISUAL)
CSS_PROP(-moz-border-radius-topleft, _moz_border_radius_topLeft, VISUAL)
CSS_PROP(-moz-border-radius-topright, _moz_border_radius_topRight, VISUAL)

Просмотреть файл

@ -83,6 +83,7 @@ public:
static const PRInt32 kHintTable[];
// Keyword/Enum value tables
static const PRInt32 kAppearanceKTable[];
static const PRInt32 kAzimuthKTable[];
static const PRInt32 kBackgroundAttachmentKTable[];
static const PRInt32 kBackgroundColorKTable[];

Просмотреть файл

@ -157,6 +157,9 @@ struct nsStyleFont : public nsStyleStruct {
nsStyleFont(nsIPresContext* aPresContext);
};
#define NS_COLORFLAGS_NONE 0x00
#define NS_COLORFLAGS_THEME 0x01
struct nsStyleColor : public nsStyleStruct {
nsStyleColor(nsIPresContext* aPresContext);
nsStyleColor(const nsStyleColor& aOther);
@ -179,6 +182,8 @@ struct nsStyleColor : public nsStyleStruct {
// Don't add ANY members to this struct! We can achieve caching in the rule
// tree (rather than the style tree) by letting color stay by itself! -dwh
nscolor mColor; // [inherited]
PRPackedBool mColorFlags; // Used to indicate theme colors. Theme colors
// must be resolved dynamically.
};
struct nsStyleBackground : public nsStyleStruct {
@ -740,6 +745,7 @@ struct nsStyleDisplay : public nsStyleStruct {
PRInt32 CalcDifference(const nsStyleDisplay& aOther) const;
PRUint8 mDisplay; // [reset] see nsStyleConsts.h NS_STYLE_DISPLAY_*
PRUint8 mAppearance; // [reset]
nsString mBinding; // [reset] absolute url string
PRUint8 mPosition; // [reset] see nsStyleConsts.h
PRUint8 mFloats; // [reset] see nsStyleConsts.h NS_STYLE_FLOAT_*

Просмотреть файл

@ -39,6 +39,7 @@
#include "nsCSSProps.h"
#include "nsCSSKeywords.h"
#include "nsStyleConsts.h"
#include "nsThemeConstants.h" // For system widget appearance types
#include "nsILookAndFeel.h" // for system colors
@ -123,6 +124,58 @@ nsCSSProps::GetStringValue(nsCSSProperty aProperty)
/***************************************************************************/
const PRInt32 nsCSSProps::kAppearanceKTable[] = {
eCSSKeyword_none, NS_THEME_NONE,
eCSSKeyword_button, NS_THEME_BUTTON,
eCSSKeyword_radio, NS_THEME_RADIO,
eCSSKeyword_checkbox, NS_THEME_CHECKBOX,
eCSSKeyword_toolbox, NS_THEME_TOOLBOX,
eCSSKeyword_toolbar, NS_THEME_TOOLBAR,
eCSSKeyword_toolbarbutton, NS_THEME_TOOLBAR_BUTTON,
eCSSKeyword_toolbargripper, NS_THEME_TOOLBAR_GRIPPER,
eCSSKeyword_dualbutton, NS_THEME_TOOLBAR_DUAL_BUTTON,
eCSSKeyword_dualbutton_dropdown, NS_THEME_TOOLBAR_DUAL_BUTTON_DROPDOWN,
eCSSKeyword_separator, NS_THEME_TOOLBAR_SEPARATOR,
eCSSKeyword_statusbar, NS_THEME_STATUSBAR,
eCSSKeyword_statusbar_pane, NS_THEME_STATUSBAR_PANE,
eCSSKeyword_resizer_pane, NS_THEME_STATUSBAR_RESIZER_PANE,
eCSSKeyword_resizer, NS_THEME_RESIZER,
eCSSKeyword_listbox, NS_THEME_LISTBOX,
eCSSKeyword_listitem, NS_THEME_LISTBOX_LISTITEM,
eCSSKeyword_treeview, NS_THEME_TREEVIEW,
eCSSKeyword_treeitem, NS_THEME_TREEVIEW_TREEITEM,
eCSSKeyword_treetwisty, NS_THEME_TREEVIEW_TWISTY,
eCSSKeyword_treeline, NS_THEME_TREEVIEW_LINE,
eCSSKeyword_treeheader, NS_THEME_TREEVIEW_HEADER,
eCSSKeyword_treeheadercell, NS_THEME_TREEVIEW_HEADER_CELL,
eCSSKeyword_treeheadersortarrow, NS_THEME_TREEVIEW_HEADER_SORTARROW,
eCSSKeyword_progressbar, NS_THEME_PROGRESSBAR,
eCSSKeyword_progresschunk, NS_THEME_PROGRESSBAR_CHUNK,
eCSSKeyword_tab, NS_THEME_TAB,
eCSSKeyword_tabpanel, NS_THEME_TAB_PANEL,
eCSSKeyword_tooltip, NS_THEME_TOOLTIP,
eCSSKeyword_spinner, NS_THEME_SPINNER,
eCSSKeyword_spinner_upbutton, NS_THEME_SPINNER_UP_BUTTON,
eCSSKeyword_spinner_downbutton, NS_THEME_SPINNER_DOWN_BUTTON,
eCSSKeyword_scrollbar, NS_THEME_SCROLLBAR,
eCSSKeyword_scrollbarbutton, NS_THEME_SCROLLBAR_BUTTON,
eCSSKeyword_scrollbartrack, NS_THEME_SCROLLBAR_TRACK,
eCSSKeyword_scrollbartrackstart, NS_THEME_SCROLLBAR_TRACK_START,
eCSSKeyword_scrollbartrackend, NS_THEME_SCROLLBAR_TRACK_END,
eCSSKeyword_scrollbarthumb, NS_THEME_SCROLLBAR_THUMB,
eCSSKeyword_scrollbargripper, NS_THEME_SCROLLBAR_GRIPPER,
eCSSKeyword_textfield, NS_THEME_TEXTFIELD,
eCSSKeyword_caret, NS_THEME_TEXTFIELD_CARET,
eCSSKeyword_menulist, NS_THEME_DROPDOWN,
eCSSKeyword_menulistbutton, NS_THEME_DROPDOWN_BUTTON,
eCSSKeyword_slider, NS_THEME_SLIDER,
eCSSKeyword_sliderthumb, NS_THEME_SLIDER_THUMB,
eCSSKeyword_sliderthumbstart, NS_THEME_SLIDER_THUMB_START,
eCSSKeyword_sliderthumbend, NS_THEME_SLIDER_THUMB_END,
eCSSKeyword_sliderthumbtick, NS_THEME_SLIDER_TICK,
-1,-1
};
// Keyword id tables for variant/enum parsing
const PRInt32 nsCSSProps::kAzimuthKTable[] = {
eCSSKeyword_left_side, NS_STYLE_AZIMUTH_LEFT_SIDE,
@ -244,6 +297,7 @@ const PRInt32 nsCSSProps::kColorKTable[] = {
eCSSKeyword_window, nsILookAndFeel::eColor_window,
eCSSKeyword_windowframe, nsILookAndFeel::eColor_windowframe,
eCSSKeyword_windowtext, nsILookAndFeel::eColor_windowtext,
eCSSKeyword_theme, nsILookAndFeel::eColor_theme,
eCSSKeyword__moz_field, nsILookAndFeel::eColor__moz_field,
eCSSKeyword__moz_fieldtext, nsILookAndFeel::eColor__moz_fieldtext,
eCSSKeyword__moz_dialog, nsILookAndFeel::eColor__moz_dialog,
@ -387,6 +441,7 @@ const PRInt32 nsCSSProps::kFontKTable[] = {
eCSSKeyword_pull_down_menu, NS_STYLE_FONT_PULL_DOWN_MENU,
eCSSKeyword_list, NS_STYLE_FONT_LIST,
eCSSKeyword_field, NS_STYLE_FONT_FIELD,
eCSSKeyword_theme, NS_STYLE_FONT_THEME,
-1,-1
};

Просмотреть файл

@ -914,6 +914,7 @@ PRInt32 nsStyleTableBorder::CalcDifference(const nsStyleTableBorder& aOther) con
//
nsStyleColor::nsStyleColor(nsIPresContext* aPresContext)
:mColorFlags(NS_COLORFLAGS_NONE)
{
aPresContext->GetDefaultColor(&mColor);
}
@ -921,6 +922,7 @@ nsStyleColor::nsStyleColor(nsIPresContext* aPresContext)
nsStyleColor::nsStyleColor(const nsStyleColor& aSource)
{
mColor = aSource.mColor;
mColorFlags = aSource.mColorFlags;
}
PRInt32 nsStyleColor::CalcDifference(const nsStyleColor& aOther) const
@ -975,6 +977,7 @@ PRInt32 nsStyleBackground::CalcDifference(const nsStyleBackground& aOther) const
nsStyleDisplay::nsStyleDisplay()
{
mAppearance = 0;
mDisplay = NS_STYLE_DISPLAY_INLINE;
mPosition = NS_STYLE_POSITION_NORMAL;
mFloats = NS_STYLE_FLOAT_NONE;
@ -988,6 +991,7 @@ nsStyleDisplay::nsStyleDisplay()
nsStyleDisplay::nsStyleDisplay(const nsStyleDisplay& aSource)
{
mAppearance = aSource.mAppearance;
mDisplay = aSource.mDisplay;
mBinding = aSource.mBinding;
mPosition = aSource.mPosition;
@ -1007,7 +1011,8 @@ PRInt32 nsStyleDisplay::CalcDifference(const nsStyleDisplay& aOther) const
if ((mDisplay == aOther.mDisplay) &&
(mFloats == aOther.mFloats) &&
(mOverflow == aOther.mOverflow)) {
(mOverflow == aOther.mOverflow) &&
(mAppearance == aOther.mAppearance)) {
if ((mBreakType == aOther.mBreakType) &&
(mBreakBefore == aOther.mBreakBefore) &&
(mBreakAfter == aOther.mBreakAfter) &&

Просмотреть файл

@ -170,7 +170,7 @@ public:
NS_IMETHOD RemoveLoadingDocListener(const nsCString& aURL)=0;
NS_IMETHOD InheritsStyle(nsIContent* aContent, PRBool* aResult) = 0;
NS_IMETHOD FlushChromeBindings() = 0;
NS_IMETHOD FlushSkinBindings() = 0;
NS_IMETHOD GetBindingImplementation(nsIContent* aContent, REFNSIID aIID, void** aResult)=0;

Просмотреть файл

@ -74,6 +74,8 @@ public:
NS_IMETHOD GetPrototypeBinding(const nsAReadableCString& aRef, nsIXBLPrototypeBinding** aResult)=0;
NS_IMETHOD SetPrototypeBinding(const nsAReadableCString& aRef, nsIXBLPrototypeBinding* aBinding)=0;
NS_IMETHOD FlushSkinStylesheets()=0;
};
extern nsresult

Просмотреть файл

@ -112,7 +112,9 @@ public:
NS_IMETHOD GetStyleSheets(nsISupportsArray** aResult)=0;
NS_IMETHOD HasInsertionPoints(PRBool* aResult)=0;
NS_IMETHOD HasStyleSheets(PRBool* aResult)=0;
NS_IMETHOD FlushSkinSheets()=0;
NS_IMETHOD InstantiateInsertionPoints(nsIXBLBinding* aBinding)=0;

Просмотреть файл

@ -280,7 +280,7 @@ public:
NS_IMETHOD RemoveLoadingDocListener(const nsCString& aURL);
NS_IMETHOD InheritsStyle(nsIContent* aContent, PRBool* aResult);
NS_IMETHOD FlushChromeBindings();
NS_IMETHOD FlushSkinBindings();
NS_IMETHOD GetBindingImplementation(nsIContent* aContent, REFNSIID aIID, void** aResult);
@ -1031,18 +1031,29 @@ nsBindingManager::RemoveLoadingDocListener(const nsCString& aURL)
PRBool PR_CALLBACK MarkForDeath(nsHashKey* aKey, void* aData, void* aClosure)
{
PRBool marked = PR_FALSE;
nsIXBLBinding* binding = (nsIXBLBinding*)aData;
binding->MarkedForDeath(&marked);
if (marked)
return PR_TRUE; // Already marked for death.
nsCAutoString uriStr;
binding->GetDocURI(uriStr);
nsCOMPtr<nsIURI> uri;
NS_NewURI(getter_AddRefs(uri), uriStr.get());
if (uri) {
nsXPIDLCString path;
uri->GetPath(getter_Copies(path));
if (!PL_strncmp(path.get(), "/skin", 5))
binding->MarkForDeath();
}
return PR_TRUE;
}
NS_IMETHODIMP
nsBindingManager::FlushChromeBindings()
nsBindingManager::FlushSkinBindings()
{
mBindingTable->Enumerate(MarkForDeath);
mDocumentTable = nsnull;
return NS_OK;
}

Просмотреть файл

@ -345,6 +345,22 @@ nsXBLDocumentInfo::SetPrototypeBinding(const nsAReadableCString& aRef, nsIXBLPro
return NS_OK;
}
PRBool PR_CALLBACK FlushScopedSkinSheets(nsHashKey* aKey, void* aData, void* aClosure)
{
nsIXBLPrototypeBinding* proto = (nsIXBLPrototypeBinding*)aData;
proto->FlushSkinSheets();
return PR_TRUE;
}
NS_IMETHODIMP
nsXBLDocumentInfo::FlushSkinStylesheets()
{
if (mBindingTable)
mBindingTable->Enumerate(FlushScopedSkinSheets);
return NS_OK;
}
//----------------------------------------------------------------------
//
// nsIScriptGlobalObjectOwner methods

Просмотреть файл

@ -25,6 +25,8 @@ public:
NS_IMETHOD GetPrototypeBinding(const nsAReadableCString& aRef, nsIXBLPrototypeBinding** aResult);
NS_IMETHOD SetPrototypeBinding(const nsAReadableCString& aRef, nsIXBLPrototypeBinding* aBinding);
NS_IMETHOD FlushSkinStylesheets();
// nsIScriptGlobalObjectOwner methods
NS_DECL_NSISCRIPTGLOBALOBJECTOWNER

Просмотреть файл

@ -424,6 +424,14 @@ nsXBLPrototypeBinding::AddResource(nsIAtom* aResourceType, const nsAReadableStri
return NS_OK;
}
NS_IMETHODIMP
nsXBLPrototypeBinding::FlushSkinSheets()
{
if (mResources)
return mResources->FlushSkinSheets();
return NS_OK;
}
NS_IMETHODIMP
nsXBLPrototypeBinding::BindingAttached(nsIDOMEventReceiver* aReceiver)
{

Просмотреть файл

@ -111,9 +111,12 @@ class nsXBLPrototypeBinding: public nsIXBLPrototypeBinding, public nsSupportsWea
NS_IMETHOD GetStyleSheets(nsISupportsArray** aResult);
NS_IMETHOD HasInsertionPoints(PRBool* aResult) { *aResult = (mInsertionPointTable != nsnull); return NS_OK; };
NS_IMETHOD HasStyleSheets(PRBool* aResult)
{ *aResult = (mResources && mResources->mStyleSheetList); return NS_OK; };
NS_IMETHOD FlushSkinSheets();
NS_IMETHOD InstantiateInsertionPoints(nsIXBLBinding* aBinding);
NS_IMETHOD GetInsertionPoint(nsIContent* aBoundElement, nsIContent* aCopyRoot,

Просмотреть файл

@ -47,6 +47,11 @@
#include "nsXBLResourceLoader.h"
#include "nsXBLPrototypeResources.h"
#include "nsIDocumentObserver.h"
#include "nsICSSLoader.h"
#include "nsIURI.h"
#include "nsLayoutCID.h"
static NS_DEFINE_CID(kCSSLoaderCID, NS_CSS_LOADER_CID);
MOZ_DECL_CTOR_COUNTER(nsXBLPrototypeResources);
@ -87,3 +92,67 @@ nsXBLPrototypeResources::AddResourceListener(nsIContent* aBoundElement)
if (mLoader)
mLoader->AddResourceListener(aBoundElement);
}
static PRBool IsChromeURI(nsIURI* aURI)
{
PRBool isChrome=PR_FALSE;
if (NS_SUCCEEDED(aURI->SchemeIs("chrome", &isChrome)) && isChrome)
return PR_TRUE;
return PR_FALSE;
}
nsresult
nsXBLPrototypeResources::FlushSkinSheets()
{
if (!mStyleSheetList)
return NS_OK;
// We have scoped stylesheets. Reload any chrome stylesheets we
// encounter. (If they aren't skin sheets, it doesn't matter, since
// they'll still be in the chrome cache.
mRuleProcessors->Clear();
nsCOMPtr<nsICSSLoader> loader;
nsresult rv = nsComponentManager::CreateInstance(kCSSLoaderCID,
nsnull,
NS_GET_IID(nsICSSLoader),
getter_AddRefs(loader));
if (NS_FAILED(rv) || !loader) return rv;
nsCOMPtr<nsISupportsArray> newSheets;
rv = NS_NewISupportsArray(getter_AddRefs(newSheets));
if (NS_FAILED(rv)) return rv;
nsCOMPtr<nsIStyleRuleProcessor> prevProcessor;
PRUint32 count;
mStyleSheetList->Count(&count);
PRUint32 i;
for (i = 0; i < count; i++) {
nsCOMPtr<nsISupports> supp = getter_AddRefs(mStyleSheetList->ElementAt(i));
nsCOMPtr<nsICSSStyleSheet> oldSheet(do_QueryInterface(supp));
nsCOMPtr<nsICSSStyleSheet> newSheet;
nsCOMPtr<nsIURI> uri;
oldSheet->GetURL(*getter_AddRefs(uri));
if (IsChromeURI(uri)) {
PRBool complete;
loader->LoadAgentSheet(uri, *getter_AddRefs(newSheet), complete, nsnull);
}
else
newSheet = oldSheet;
newSheets->AppendElement(newSheet);
nsCOMPtr<nsIStyleRuleProcessor> processor;
newSheet->GetStyleRuleProcessor(*getter_AddRefs(processor), prevProcessor);
if (processor != prevProcessor) {
mRuleProcessors->AppendElement(processor);
prevProcessor = processor;
}
}
mStyleSheetList = newSheets;
return NS_OK;
}

Просмотреть файл

@ -58,6 +58,7 @@ public:
void LoadResources(PRBool* aResult);
void AddResource(nsIAtom* aResourceType, const nsAReadableString& aSrc);
void AddResourceListener(nsIContent* aElement);
nsresult FlushSkinSheets();
nsXBLPrototypeResources(nsIXBLPrototypeBinding* aBinding);
~nsXBLPrototypeResources();

Просмотреть файл

@ -84,6 +84,12 @@ public:
NS_IMETHOD FlushXBLInformation() = 0;
/*
* Flush only the skin files from the cache while retaining all other
* files.
*/
NS_IMETHOD FlushSkinFiles() = 0;
/**
* Flush the cache; remove all XUL prototype documents, style
* sheets, and scripts.

Просмотреть файл

@ -79,6 +79,7 @@ public:
NS_IMETHOD GetXBLDocumentInfo(const nsCString& aString, nsIXBLDocumentInfo** _result);
NS_IMETHOD PutXBLDocumentInfo(nsIXBLDocumentInfo* aDocumentInfo);
NS_IMETHOD FlushXBLInformation();
NS_IMETHOD FlushSkinFiles();
NS_IMETHOD Flush();
@ -329,6 +330,98 @@ nsXULPrototypeCache::FlushXBLInformation()
return NS_OK;
}
struct nsHashKeyEntry {
nsHashKey* mKey;
nsHashKeyEntry* mNext;
nsHashKeyEntry(nsHashKey* aKey, nsHashKeyEntry* aNext = nsnull) {
mKey = aKey;
mNext = aNext;
}
~nsHashKeyEntry() {
delete mNext;
}
};
struct nsHashKeys {
nsHashKeyEntry* mFirst;
nsHashKeys() { mFirst = nsnull; };
~nsHashKeys() { Clear(); };
void AppendKey(nsHashKey* aKey) {
mFirst = new nsHashKeyEntry(aKey, mFirst);
}
void Clear() {
delete mFirst;
mFirst = nsnull;
}
};
PRBool PR_CALLBACK FlushSkinXBL(nsHashKey* aKey, void* aData, void* aClosure)
{
nsIXBLDocumentInfo* docInfo = (nsIXBLDocumentInfo*)aData;
nsCOMPtr<nsIDocument> doc;
docInfo->GetDocument(getter_AddRefs(doc));
nsCOMPtr<nsIURI> uri;
doc->GetDocumentURL(getter_AddRefs(uri));
nsXPIDLCString str;
uri->GetPath(getter_Copies(str));
if (!PL_strncmp(str.get(), "/skin", 5)) {
// This is a skin binding. Add the key to the list.
nsHashKeys* list = (nsHashKeys*)aClosure;
list->AppendKey(aKey);
}
return PR_TRUE;
}
PRBool PR_CALLBACK FlushSkinSheets(nsHashKey* aKey, void* aData, void* aClosure)
{
nsICSSStyleSheet* sheet = (nsICSSStyleSheet*)aData;
nsCOMPtr<nsIURI> uri;
sheet->GetURL(*getter_AddRefs(uri));
nsXPIDLCString str;
uri->GetPath(getter_Copies(str));
if (!PL_strncmp(str.get(), "/skin", 5)) {
// This is a skin binding. Add the key to the list.
nsHashKeys* list = (nsHashKeys*)aClosure;
list->AppendKey(aKey);
}
return PR_TRUE;
}
PRBool PR_CALLBACK FlushScopedSkinStylesheets(nsHashKey* aKey, void* aData, void* aClosure)
{
nsIXBLDocumentInfo* docInfo = (nsIXBLDocumentInfo*)aData;
docInfo->FlushSkinStylesheets();
return PR_TRUE;
}
NS_IMETHODIMP
nsXULPrototypeCache::FlushSkinFiles()
{
// Flush out skin XBL files from the cache.
nsHashKeys keysToRemove;
nsHashKeyEntry* curr;
mXBLDocTable.Enumerate(FlushSkinXBL, &keysToRemove);
for (curr = keysToRemove.mFirst; curr; curr = curr->mNext)
mXBLDocTable.Remove(curr->mKey);
// Now flush out our skin stylesheets from the cache.
keysToRemove.Clear();
mStyleSheetTable.Enumerate(FlushSkinSheets, &keysToRemove);
for (curr = keysToRemove.mFirst; curr; curr = curr->mNext)
mStyleSheetTable.Remove(curr->mKey);
// Iterate over all the remaining XBL and make sure cached
// scoped skin stylesheets are flushed and refetched by the
// prototype bindings.
mXBLDocTable.Enumerate(FlushScopedSkinStylesheets);
return NS_OK;
}
NS_IMETHODIMP
nsXULPrototypeCache::Flush()

Просмотреть файл

@ -25,3 +25,6 @@ nsIDeviceContextSpec.h
nsIDeviceContextSpecFactory.h
nsIDrawingSurface.h
nsRepeater.h
nsThemeConstants.h
nsITheme.h

Просмотреть файл

@ -54,6 +54,8 @@ EXPORTS = \
nsIDeviceContextSpec.h \
nsIDeviceContextSpecFactory.h \
nsIDrawingSurface.h \
nsITheme.h \
nsThemeConstants.h \
$(NULL)
ifeq ($(MOZ_WIDGET_TOOLKIT),mac)

Просмотреть файл

@ -1,54 +0,0 @@
#!nmake
#
# The contents of this file are subject to the Netscape Public
# License Version 1.1 (the "License"); you may not use this file
# except in compliance with the License. You may obtain a copy of
# the License at http://www.mozilla.org/NPL/
#
# Software distributed under the License is distributed on an "AS
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
# implied. See the License for the specific language governing
# rights and limitations under the License.
#
# The Original Code is mozilla.org code.
#
# The Initial Developer of the Original Code is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All
# Rights Reserved.
#
# Contributor(s):
DEPTH=..\..
EXPORTS = \
nsColor.h \
nsColorNames.h \
nsColorNameList.h \
nsCoord.h \
nsFont.h \
nsRect.h \
nsPoint.h \
nsSize.h \
nsMargin.h \
nsTransform2D.h \
nsIRenderingContext.h \
nsRenderingContextImpl.h \
nsIFontMetrics.h \
nsIDeviceContext.h \
nsIImage.h \
nsIBlender.h \
nsGfxCIID.h \
nsIRegion.h \
nsDeviceContext.h \
nsIDeviceContextSpec.h \
nsIDeviceContextSpecFactory.h \
nsIDrawingSurface.h \
nsCompressedCharMap.h \
$(NULL)
MODULE=gfx
include <$(DEPTH)\config\rules.mak>

Просмотреть файл

@ -139,7 +139,8 @@ typedef void * nsPalette;
eSystemFont_Field,
eSystemFont_Tooltips, // moz
eSystemFont_Widget
eSystemFont_Widget,
eSystemFont_Theme
} nsSystemFontID;
class nsIDeviceContext : public nsISupports

87
gfx/public/nsITheme.h Normal file
Просмотреть файл

@ -0,0 +1,87 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is the Mozilla browser.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1999 Netscape Communications Corporation. All
* Rights Reserved.
*
* Original Author: David W. Hyatt (hyatt@netscape.com)
*
* Contributors:
*/
#include "nsISupports.h"
#include "nsCOMPtr.h"
#include "nsColor.h"
struct nsRect;
struct nsSize;
struct nsFont;
struct nsMargin;
class nsIPresContext;
class nsIRenderingContext;
class nsIDeviceContext;
class nsIFrame;
class nsIAtom;
// IID for the nsITheme interface
// {F791038C-F97E-4068-A542-0343AE440664}
#define NS_ITHEME_IID \
{ 0xf791038c, 0xf97e, 0x4068, { 0xa5, 0x42, 0x3, 0x43, 0xae, 0x44, 0x6, 0x64 } }
// {D930E29B-6909-44e5-AB4B-AF10D6923705}
#define NS_THEMERENDERER_CID \
{ 0xd930e29b, 0x6909, 0x44e5, { 0xab, 0x4b, 0xaf, 0x10, 0xd6, 0x92, 0x37, 0x5 } }
class nsITheme: public nsISupports {
public:
static const nsIID& GetIID() { static nsIID iid = NS_ITHEME_IID; return iid; }
NS_IMETHOD DrawWidgetBackground(nsIRenderingContext* aContext,
nsIFrame* aFrame,
PRUint8 aWidgetType,
const nsRect& aRect,
const nsRect& aClipRect)=0;
NS_IMETHOD GetWidgetPadding(nsIDeviceContext* aContext,
nsIFrame* aFrame,
PRUint8 aWidgetType,
nsMargin* aResult)=0;
NS_IMETHOD GetWidgetFont(nsIDeviceContext* aContext,
PRUint8 aWidgetType,
nsFont* aFont)=0;
NS_IMETHOD GetWidgetColor(nsIPresContext* aPresContext,
nsIRenderingContext* aContext,
nsIFrame* aFrame,
PRUint8 aWidgetType,
nscolor* aFont)=0;
NS_IMETHOD GetMinimumWidgetSize(nsIRenderingContext* aContext, nsIFrame* aFrame,
PRUint8 aWidgetType,
nsSize* aResult)=0;
NS_IMETHOD WidgetStateChanged(nsIFrame* aFrame, PRUint8 aWidgetType,
nsIAtom* aAttribute, PRBool* aShouldRepaint)=0;
NS_IMETHOD ThemeChanged()=0;
virtual PRBool ThemeSupportsWidget(nsIPresContext* aPresContext,
PRUint8 aWidgetType)=0;
};
// Creator function
extern NS_METHOD NS_NewNativeTheme(nsISupports *aOuter, REFNSIID aIID, void **aResult);

Просмотреть файл

@ -0,0 +1,143 @@
// No appearance at all.
#define NS_THEME_NONE 0
// A typical dialog button.
#define NS_THEME_BUTTON 1
// A radio element within a radio group.
#define NS_THEME_RADIO 2
// A checkbox element.
#define NS_THEME_CHECKBOX 3
// The toolbox that contains the toolbars.
#define NS_THEME_TOOLBOX 11
// A toolbar in an application window.
#define NS_THEME_TOOLBAR 12
// A single toolbar button (with no associated dropdown)
#define NS_THEME_TOOLBAR_BUTTON 13
// A dual toolbar button (e.g., a Back button with a dropdown)
#define NS_THEME_TOOLBAR_DUAL_BUTTON 14
// The dropdown portion of a dual toolbar button
#define NS_THEME_TOOLBAR_DUAL_BUTTON_DROPDOWN 15
// A separator. Can be horizontal or vertical.
#define NS_THEME_TOOLBAR_SEPARATOR 16
// The gripper for a toolbar.
#define NS_THEME_TOOLBAR_GRIPPER 17
// A status bar in a main application window.
#define NS_THEME_STATUSBAR 21
// A single pane of a status bar.
#define NS_THEME_STATUSBAR_PANE 21
// The resizer background area in a status bar
// for the resizer widget in the corner of a window.
#define NS_THEME_STATUSBAR_RESIZER_PANE 23
// The resizer itself.
#define NS_THEME_RESIZER 24
// List boxes
#define NS_THEME_LISTBOX 31
// A listbox item
#define NS_THEME_LISTBOX_LISTITEM 32
// A tree widget
#define NS_THEME_TREEVIEW 41
// A tree item
#define NS_THEME_TREEVIEW_TREEITEM 42
// A tree widget twisty
#define NS_THEME_TREEVIEW_TWISTY 43
// A tree widget branch line
#define NS_THEME_TREEVIEW_LINE 44
// A listbox or tree widget header
#define NS_THEME_TREEVIEW_HEADER 45
// An individual header cell
#define NS_THEME_TREEVIEW_HEADER_CELL 46
// The sort arrow for a header.
#define NS_THEME_TREEVIEW_HEADER_SORTARROW 47
// A progress bar.
#define NS_THEME_PROGRESSBAR 51
// The progress bar's progress indicator
#define NS_THEME_PROGRESSBAR_CHUNK 52
// A single tab in a tab widget.
#define NS_THEME_TAB 61
// The tab panel
#define NS_THEME_TAB_PANEL 62
// A tooltip
#define NS_THEME_TOOLTIP 71
// A spin control (up/down control for time/date pickers)
#define NS_THEME_SPINNER 72
// The up button of a spin control
#define NS_THEME_SPINNER_UP_BUTTON 73
// The down button of a spin control
#define NS_THEME_SPINNER_DOWN_BUTTON 74
// A scrollbar.
#define NS_THEME_SCROLLBAR 81
// A scrollbar button (up/down/left/right)
#define NS_THEME_SCROLLBAR_BUTTON 82
// The scrollbar track
#define NS_THEME_SCROLLBAR_TRACK 83
// The start of a scrollbar track
#define NS_THEME_SCROLLBAR_TRACK_START 84
// The end of a scrollbar track
#define NS_THEME_SCROLLBAR_TRACK_END 85
// The scrollbar thumb
#define NS_THEME_SCROLLBAR_THUMB 86
// The gripper that goes on the thumb
#define NS_THEME_SCROLLBAR_GRIPPER 87
// A textfield or text area
#define NS_THEME_TEXTFIELD 91
// The caret of a text area
#define NS_THEME_TEXTFIELD_CARET 92
// A dropdown list.
#define NS_THEME_DROPDOWN 101
// The dropdown button(s) that open up a dropdown list.
#define NS_THEME_DROPDOWN_BUTTON 102
// A slider
#define NS_THEME_SLIDER 111
// A slider's thumb
#define NS_THEME_SLIDER_THUMB 112
// If the platform supports it, the left/right chunks
// of the slider thumb
#define NS_THEME_SLIDER_THUMB_START 113
#define NS_THEME_SLIDER_THUMB_END 114
// The ticks for a slider.
#define NS_THEME_SLIDER_TICK 115

Просмотреть файл

@ -35,6 +35,8 @@ REQUIRES = xpcom \
unicharutil \
locale \
necko \
content \
layout \
$(NULL)
DEFINES=-DWIN32_LEAN_AND_MEAN -DSTRICT
@ -57,6 +59,7 @@ OBJS = \
.\$(OBJDIR)\nsPrintOptionsWin.obj \
.\$(OBJDIR)\nsGfxFactoryWin.obj \
.\$(OBJDIR)\nsCompressedCharMap.obj \
.\$(OBJDIR)\nsNativeThemeWin.obj \
$(NULL)
EXPORTS= nsIRenderingContextWin.h \

Просмотреть файл

@ -355,6 +355,58 @@ NS_IMETHODIMP nsDeviceContextWin :: GetScrollBarDimensions(float &aWidth, float
return NS_OK;
}
nsresult nsDeviceContextWin::CopyLogFontToNSFont(HDC* aHDC, const LOGFONT* ptrLogFont,
nsFont* aFont) const
{
PRUnichar name[LF_FACESIZE];
name[0] = 0;
MultiByteToWideChar(CP_ACP, 0, ptrLogFont->lfFaceName,
strlen(ptrLogFont->lfFaceName) + 1, name, sizeof(name)/sizeof(name[0]));
aFont->name = name;
// Do Style
aFont->style = NS_FONT_STYLE_NORMAL;
if (ptrLogFont->lfItalic)
{
aFont->style = NS_FONT_STYLE_ITALIC;
}
// XXX What about oblique?
aFont->variant = NS_FONT_VARIANT_NORMAL;
// Do Weight
aFont->weight = (ptrLogFont->lfWeight == FW_BOLD ?
NS_FONT_WEIGHT_BOLD : NS_FONT_WEIGHT_NORMAL);
// Do decorations
aFont->decorations = NS_FONT_DECORATION_NONE;
if (ptrLogFont->lfUnderline)
{
aFont->decorations |= NS_FONT_DECORATION_UNDERLINE;
}
if (ptrLogFont->lfStrikeOut)
{
aFont->decorations |= NS_FONT_DECORATION_LINE_THROUGH;
}
// Do Point Size
//
// The lfHeight is in pixel and it needs to be adjusted for the
// device it will be "displayed" on
// Screens and Printers will differe in DPI
//
// So this accounts for the difference in the DeviceContexts
// The mPixelScale will be a "1" for the screen and could be
// any value when going to a printer, for example mPixleScale is
// 6.25 when going to a 600dpi printer.
// round, but take into account whether it is negative
LONG logHeight = LONG((float(ptrLogFont->lfHeight) * mPixelScale) + (ptrLogFont->lfHeight < 0 ? -0.5 : 0.5)); // round up
int pointSize = -MulDiv(logHeight, 72, ::GetDeviceCaps(*aHDC, LOGPIXELSY));
aFont->size = NSIntPointsToTwips(pointSize);
return NS_OK;
}
nsresult nsDeviceContextWin :: GetSysFontInfo(HDC aHDC, nsSystemFontID anID, nsFont* aFont) const
{
NONCLIENTMETRICS ncm;
@ -442,54 +494,7 @@ nsresult nsDeviceContextWin :: GetSysFontInfo(HDC aHDC, nsSystemFontID anID, nsF
return NS_ERROR_FAILURE;
}
PRUnichar name[LF_FACESIZE];
name[0] = 0;
MultiByteToWideChar(CP_ACP, 0, ptrLogFont->lfFaceName,
strlen(ptrLogFont->lfFaceName) + 1, name, sizeof(name)/sizeof(name[0]));
aFont->name = name;
// Do Style
aFont->style = NS_FONT_STYLE_NORMAL;
if (ptrLogFont->lfItalic)
{
aFont->style = NS_FONT_STYLE_ITALIC;
}
// XXX What about oblique?
aFont->variant = NS_FONT_VARIANT_NORMAL;
// Do Weight
aFont->weight = (ptrLogFont->lfWeight == FW_BOLD ?
NS_FONT_WEIGHT_BOLD : NS_FONT_WEIGHT_NORMAL);
// Do decorations
aFont->decorations = NS_FONT_DECORATION_NONE;
if (ptrLogFont->lfUnderline)
{
aFont->decorations |= NS_FONT_DECORATION_UNDERLINE;
}
if (ptrLogFont->lfStrikeOut)
{
aFont->decorations |= NS_FONT_DECORATION_LINE_THROUGH;
}
// Do Point Size
//
// The lfHeight is in pixel and it needs to be adjusted for the
// device it will be "displayed" on
// Screens and Printers will differe in DPI
//
// So this accounts for the difference in the DeviceContexts
// The mPixelScale will be a "1" for the screen and could be
// any value when going to a printer, for example mPixleScale is
// 6.25 when going to a 600dpi printer.
// round, but take into account whether it is negative
LONG logHeight = LONG((float(ptrLogFont->lfHeight) * mPixelScale) + (ptrLogFont->lfHeight < 0 ? -0.5 : 0.5)); // round up
int pointSize = -MulDiv(logHeight, 72, ::GetDeviceCaps(aHDC, LOGPIXELSY));
aFont->size = NSIntPointsToTwips(pointSize);
return NS_OK;
return CopyLogFontToNSFont(&aHDC, ptrLogFont, aFont);
}
NS_IMETHODIMP nsDeviceContextWin :: GetSystemFont(nsSystemFontID anID, nsFont *aFont) const
@ -927,8 +932,6 @@ BOOL CALLBACK abortproc( HDC hdc, int iError )
return TRUE;
}
NS_IMETHODIMP nsDeviceContextWin :: GetDeviceContextFor(nsIDeviceContextSpec *aDevice,
nsIDeviceContext *&aContext)
{

Просмотреть файл

@ -93,6 +93,7 @@ public:
// Static Helper Methods
static char* GetACPString(const nsAString& aStr);
friend class nsNativeThemeWin;
protected:
virtual ~nsDeviceContextWin();
@ -103,6 +104,8 @@ protected:
void ComputeFullAreaUsingScreen ( nsRect* outRect ) ;
nsresult GetSysFontInfo(HDC aHDC, nsSystemFontID anID, nsFont* aFont) const;
nsresult CopyLogFontToNSFont(HDC* aHDC, const LOGFONT* ptrLogFont, nsFont* aFont) const;
PRBool mCachedClientRect;
PRBool mCachedFullRect;

Просмотреть файл

@ -53,6 +53,7 @@
#include "nsPrintOptionsWin.h"
#include "nsFontList.h"
#include "nsIGenericFactory.h"
#include "nsNativeThemeWin.h"
//NS_GENERIC_FACTORY_CONSTRUCTOR(nsFontMetricsWin)
NS_GENERIC_FACTORY_CONSTRUCTOR(nsDeviceContextWin)
@ -68,7 +69,7 @@ NS_GENERIC_FACTORY_CONSTRUCTOR(nsPrintOptionsWin)
NS_GENERIC_FACTORY_CONSTRUCTOR(nsFontEnumeratorWin)
NS_GENERIC_FACTORY_CONSTRUCTOR(nsFontList)
NS_GENERIC_FACTORY_CONSTRUCTOR(nsScreenManagerWin)
NS_GENERIC_FACTORY_CONSTRUCTOR(nsNativeThemeWin)
PRBool
UseAFunctions()
@ -212,6 +213,12 @@ static nsModuleComponentInfo components[] =
NS_SCREENMANAGER_CID,
"@mozilla.org/gfx/screenmanager;1",
nsScreenManagerWinConstructor },
{ "Native Theme Renderer",
NS_THEMERENDERER_CID,
"@mozilla.org/chrome/chrome-native-theme;1",
NS_NewNativeTheme
}
};
NS_IMPL_NSGETMODULE(nsGfxModule, components)

Просмотреть файл

@ -0,0 +1,839 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Netscape Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* David Hyatt (hyatt@netscape.com)
*
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the NPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the NPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include <windows.h>
#include "nsNativeThemeWin.h"
#include "nsRenderingContextWin.h"
#include "nsDeviceContextWin.h"
#include "nsRect.h"
#include "nsSize.h"
#include "nsTransform2D.h"
#include "nsThemeConstants.h"
#include "nsIPresShell.h"
#include "nsIPresContext.h"
#include "nsIContent.h"
#include "nsIDocument.h"
#include "nsIFrame.h"
#include "nsIEventStateManager.h"
#include "nsINameSpaceManager.h"
#include "nsIPresContext.h"
#include "nsILookAndFeel.h"
#define THEME_COLOR 204
#define THEME_FONT 210
// Button constants
#define TP_BUTTON 1
#define TP_RADIO 2
#define TP_CHECKBOX 3
#define BP_NORMAL 1
#define BP_HOVER 2
#define BP_ACTIVE 3
#define BP_DISABLED 4
#define BP_DEFAULT 5
// Scrollbar constants
#define SP_BUTTON 1
#define SP_THUMBHOR 2
#define SP_THUMBVERT 3
#define SP_TRACKSTARTHOR 4
#define SP_TRACKENDHOR 5
#define SP_TRACKSTARTVERT 6
#define SP_TRACKENDVERT 7
#define SP_GRIPPERHOR 8
#define SP_GRIPPERVERT 9
// Tab constants
#define TABP_TAB_SELAFTER 2
#define TABP_TAB_SELBEFORE 3
#define TABP_TAB 4
#define TABP_TAB_SELECTED 5
#define TABP_TAB_PANE 9
NS_IMPL_ISUPPORTS1(nsNativeThemeWin, nsITheme)
typedef HANDLE (WINAPI*OpenThemeDataPtr)(HWND hwnd, LPCWSTR pszClassList);
typedef HRESULT (WINAPI*CloseThemeDataPtr)(HANDLE hTheme);
typedef HRESULT (WINAPI*DrawThemeBackgroundPtr)(HANDLE hTheme, HDC hdc, int iPartId,
int iStateId, const RECT *pRect,
const RECT* pClipRect);
typedef HRESULT (WINAPI*GetThemeContentRectPtr)(HANDLE hTheme, HDC hdc, int iPartId,
int iStateId, const RECT* pRect,
RECT* pContentRect);
typedef HRESULT (WINAPI*GetThemePartSizePtr)(HANDLE hTheme, HDC hdc, int iPartId,
int iStateId, RECT* prc, int ts,
SIZE* psz);
typedef HRESULT (WINAPI*GetThemeFontPtr)(HANDLE hTheme, HDC hdc, int iPartId,
int iStateId, int iPropId, OUT LOGFONT* pFont);
typedef HRESULT (WINAPI*GetThemeSysFontPtr)(HANDLE hTheme, int iFontId, OUT LOGFONT* pFont);
typedef HRESULT (WINAPI*GetThemeColorPtr)(HANDLE hTheme, HDC hdc, int iPartId,
int iStateId, int iPropId, OUT COLORREF* pFont);
typedef HRESULT (WINAPI*GetThemeTextMetricsPtr)(HANDLE hTheme, OPTIONAL HDC hdc, int iPartId,
int iStateId, OUT TEXTMETRIC* ptm);
static OpenThemeDataPtr openTheme = NULL;
static CloseThemeDataPtr closeTheme = NULL;
static DrawThemeBackgroundPtr drawThemeBG = NULL;
static GetThemeContentRectPtr getThemeContentRect = NULL;
static GetThemePartSizePtr getThemePartSize = NULL;
static GetThemeFontPtr getThemeFont = NULL;
static GetThemeSysFontPtr getThemeSysFont = NULL;
static GetThemeColorPtr getThemeColor = NULL;
static GetThemeTextMetricsPtr getThemeTextMetrics = NULL;
static const char kThemeLibraryName[] = "uxtheme.dll";
nsNativeThemeWin::nsNativeThemeWin() {
NS_INIT_ISUPPORTS();
mThemeDLL = NULL;
mButtonTheme = NULL;
mToolbarTheme = NULL;
mRebarTheme = NULL;
mScrollbarTheme = NULL;
mStatusbarTheme = NULL;
mTabTheme = NULL;
mTreeViewTheme = NULL;
mThemeDLL = ::LoadLibrary(kThemeLibraryName);
if (mThemeDLL) {
openTheme = (OpenThemeDataPtr)GetProcAddress(mThemeDLL, "OpenThemeData");
closeTheme = (CloseThemeDataPtr)GetProcAddress(mThemeDLL, "CloseThemeData");
drawThemeBG = (DrawThemeBackgroundPtr)GetProcAddress(mThemeDLL, "DrawThemeBackground");
getThemeContentRect = (GetThemeContentRectPtr)GetProcAddress(mThemeDLL, "GetThemeBackgroundContentRect");
getThemePartSize = (GetThemePartSizePtr)GetProcAddress(mThemeDLL, "GetThemePartSize");
getThemeFont = (GetThemeFontPtr)GetProcAddress(mThemeDLL, "GetThemeFont");
getThemeSysFont = (GetThemeSysFontPtr)GetProcAddress(mThemeDLL, "GetThemeSysFont");
getThemeTextMetrics = (GetThemeTextMetricsPtr)GetProcAddress(mThemeDLL, "GetThemeTextMetrics");
getThemeColor = (GetThemeColorPtr)GetProcAddress(mThemeDLL, "GetThemeColor");
mCheckedAtom = getter_AddRefs(NS_NewAtom("checked"));
mDisabledAtom = getter_AddRefs(NS_NewAtom("disabled"));
mSBOrientAtom = getter_AddRefs(NS_NewAtom("sborient"));
mSelectedAtom = getter_AddRefs(NS_NewAtom("selected"));
mTypeAtom = getter_AddRefs(NS_NewAtom("type"));
}
}
nsNativeThemeWin::~nsNativeThemeWin() {
if (!mThemeDLL)
return;
CloseData();
if (mThemeDLL)
::FreeLibrary(mThemeDLL);
}
static void GetNativeRect(const nsRect& aSrc, RECT& aDst)
{
aDst.top = aSrc.y;
aDst.bottom = aSrc.y + aSrc.height;
aDst.left = aSrc.x;
aDst.right = aSrc.x + aSrc.width;
}
HANDLE
nsNativeThemeWin::GetTheme(PRUint8 aWidgetType)
{
switch (aWidgetType) {
case NS_THEME_BUTTON:
case NS_THEME_RADIO:
case NS_THEME_CHECKBOX: {
if (!mButtonTheme)
mButtonTheme = openTheme(NULL, L"Button");
return mButtonTheme;
}
case NS_THEME_TOOLBOX: {
if (!mRebarTheme)
mRebarTheme = openTheme(NULL, L"Rebar");
return mRebarTheme;
}
case NS_THEME_TOOLBAR:
case NS_THEME_TOOLBAR_BUTTON: {
if (!mToolbarTheme)
mToolbarTheme = openTheme(NULL, L"Toolbar");
return mToolbarTheme;
}
case NS_THEME_TAB:
case NS_THEME_TAB_PANEL: {
if (!mTabTheme)
mTabTheme = openTheme(NULL, L"Tab");
return mTabTheme;
}
case NS_THEME_SCROLLBAR:
case NS_THEME_SCROLLBAR_TRACK:
case NS_THEME_SCROLLBAR_BUTTON:
case NS_THEME_SCROLLBAR_THUMB:
case NS_THEME_SCROLLBAR_GRIPPER: {
if (!mScrollbarTheme)
mScrollbarTheme = openTheme(NULL, L"Scrollbar");
return mScrollbarTheme;
}
case NS_THEME_STATUSBAR: {
if (!mStatusbarTheme)
mStatusbarTheme = openTheme(NULL, L"Status");
return mStatusbarTheme;
}
}
return NULL;
}
static void GetPrimaryPresShell(nsIFrame* aFrame, nsIPresShell** aResult)
{
*aResult = nsnull;
if (!aFrame)
return;
nsCOMPtr<nsIDocument> doc;
nsCOMPtr<nsIContent> content;
aFrame->GetContent(getter_AddRefs(content));
content->GetDocument(*getter_AddRefs(doc));
if (doc)
doc->GetShellAt(0, aResult); // Addref happens here.
}
static PRInt32 GetContentState(nsIFrame* aFrame)
{
if (!aFrame)
return 0;
nsCOMPtr<nsIPresShell> shell;
GetPrimaryPresShell(aFrame, getter_AddRefs(shell));
if (!shell)
return 0;
nsCOMPtr<nsIPresContext> context;
shell->GetPresContext(getter_AddRefs(context));
nsCOMPtr<nsIEventStateManager> esm;
context->GetEventStateManager(getter_AddRefs(esm));
PRInt32 flags = 0;
nsCOMPtr<nsIContent> content;
aFrame->GetContent(getter_AddRefs(content));
esm->GetContentState(content, flags);
return flags;
}
static PRBool HasAttrValue(nsIContent* aContent, nsIAtom* aAtom, const char* aStr)
{
nsAutoString attr;
aContent->GetAttr(kNameSpaceID_None, aAtom, attr);
return attr.EqualsIgnoreCase(aStr);
}
static PRBool CheckBooleanAttr(nsIFrame* aFrame, nsIAtom* aAtom)
{
if (!aFrame)
return PR_FALSE;
nsCOMPtr<nsIContent> content;
aFrame->GetContent(getter_AddRefs(content));
nsAutoString attr;
nsresult res = content->GetAttr(kNameSpaceID_None, aAtom, attr);
if (res == NS_CONTENT_ATTR_NO_VALUE)
return PR_TRUE; // This handles the HTML case (an attr with no value is like a true val)
return attr.EqualsIgnoreCase("true"); // This handles the XUL case.
}
PRBool nsNativeThemeWin::IsDisabled(nsIFrame* aFrame)
{
return CheckBooleanAttr(aFrame, mDisabledAtom);
}
PRBool nsNativeThemeWin::IsChecked(nsIFrame* aFrame)
{
if (!aFrame)
return NS_OK;
nsCOMPtr<nsIContent> content;
aFrame->GetContent(getter_AddRefs(content));
nsAutoString checked;
nsresult res = content->GetAttr(kNameSpaceID_None, mCheckedAtom, checked);
if (res == NS_CONTENT_ATTR_NO_VALUE)
return PR_TRUE; // XXXdwh Can the HTML form control's checked property differ
// from the checked attribute? If so, will need an IsContentofType
// HTML followed by a QI to nsIDOMHTMLInputElement to grab the prop.
return checked.EqualsIgnoreCase("true"); // This handles the XUL case.
}
PRBool nsNativeThemeWin::IsSelected(nsIFrame* aFrame)
{
return CheckBooleanAttr(aFrame, mSelectedAtom);
}
nsresult
nsNativeThemeWin::GetThemePartAndState(nsIFrame* aFrame, PRUint8 aWidgetType,
PRInt32& aPart, PRInt32& aState)
{
switch (aWidgetType) {
case NS_THEME_BUTTON: {
aPart = TP_BUTTON;
if (!aFrame) {
aState = BP_NORMAL;
return NS_OK;
}
if (IsDisabled(aFrame)) {
aState = BP_DISABLED;
return NS_OK;
}
PRInt32 eventState = GetContentState(aFrame);
if (eventState & NS_EVENT_STATE_HOVER && eventState & NS_EVENT_STATE_ACTIVE)
aState = BP_ACTIVE;
else if (eventState & NS_EVENT_STATE_FOCUS)
aState = BP_DEFAULT;
else if (eventState & NS_EVENT_STATE_HOVER)
aState = BP_HOVER;
else
aState = BP_NORMAL;
return NS_OK;
}
case NS_THEME_CHECKBOX:
case NS_THEME_RADIO: {
aPart = (aWidgetType == NS_THEME_CHECKBOX) ? TP_CHECKBOX : TP_RADIO;
if (!aFrame)
aState = BP_NORMAL;
else if (IsDisabled(aFrame))
aState = BP_DISABLED;
else {
PRInt32 eventState = GetContentState(aFrame);
if (eventState & NS_EVENT_STATE_HOVER && eventState & NS_EVENT_STATE_ACTIVE)
aState = BP_ACTIVE;
else if (eventState & NS_EVENT_STATE_HOVER)
aState = BP_HOVER;
else
aState = BP_NORMAL;
}
// XXXdwh This check will need to be more complicated, since HTML radio groups
// use checked, but XUL radio groups use selected. There will need to be an
// IsContentOfType test for HTML vs. XUL here.
nsIAtom* atom = (aWidgetType == NS_THEME_CHECKBOX) ? mCheckedAtom : mSelectedAtom;
if (CheckBooleanAttr(aFrame, atom))
aState += 4; // 4 unchecked states, 4 checked states.
return NS_OK;
}
case NS_THEME_TOOLBAR_BUTTON: {
aPart = TP_BUTTON;
if (!aFrame) {
aState = BP_NORMAL;
return NS_OK;
}
if (IsDisabled(aFrame)) {
aState = BP_DISABLED;
return NS_OK;
}
PRInt32 eventState = GetContentState(aFrame);
if (eventState & NS_EVENT_STATE_HOVER && eventState & NS_EVENT_STATE_ACTIVE)
aState = BP_ACTIVE;
else if (eventState & NS_EVENT_STATE_HOVER)
aState = BP_HOVER;
else
aState = BP_NORMAL;
return NS_OK;
}
case NS_THEME_SCROLLBAR_BUTTON: {
aPart = SP_BUTTON;
aState = 8; // Assume horizontal by default.
// States are 4 vert up, 4 vert down, 4 horz left, 4 horz right
if (!aFrame)
aState += BP_NORMAL;
else if (IsDisabled(aFrame))
aState += BP_DISABLED;
else {
PRInt32 eventState = GetContentState(aFrame);
if (eventState & NS_EVENT_STATE_HOVER && eventState & NS_EVENT_STATE_ACTIVE)
aState += BP_ACTIVE;
else if (eventState & NS_EVENT_STATE_HOVER)
aState += BP_HOVER;
else
aState += BP_NORMAL;
}
if (aFrame) {
nsCOMPtr<nsIContent> content;
aFrame->GetContent(getter_AddRefs(content));
// Get our parent frame's orientation. If we are a horizontal scrollbar,
// then subtract 8 from the result to get the correct offset.
if (HasAttrValue(content, mSBOrientAtom, "vertical"))
aState -= 8; // We're vertical instead.
// Are we the start button or end button? If we are the end button, add 4
// to the result to get the correct offset.
if (HasAttrValue(content, mTypeAtom, "increment"))
aState += 4;
}
return NS_OK;
}
case NS_THEME_SCROLLBAR_TRACK: {
aPart = SP_TRACKSTARTHOR;
aState = BP_NORMAL;
if (aFrame) {
nsCOMPtr<nsIContent> content;
aFrame->GetContent(getter_AddRefs(content));
// Get our scrollbar frame's orientation. If we are a vertical scrollbar,
// then add 2 to get the correct val
if (HasAttrValue(content, mSBOrientAtom, "vertical"))
aPart += 2; // We're vertical instead.
}
return NS_OK;
}
case NS_THEME_SCROLLBAR_THUMB: {
aPart = SP_THUMBHOR;
if (!aFrame)
aState = BP_NORMAL;
else if (IsDisabled(aFrame))
aState = BP_DISABLED;
else {
PRInt32 eventState = GetContentState(aFrame);
if (eventState & NS_EVENT_STATE_ACTIVE) // Hover is not also a requirement for
// the thumb, since the drag is not canceled
// when you move outside the thumb.
aState = BP_ACTIVE;
else if (eventState & NS_EVENT_STATE_HOVER)
aState = BP_HOVER;
else
aState = BP_NORMAL;
}
if (aFrame) {
nsCOMPtr<nsIContent> content;
aFrame->GetContent(getter_AddRefs(content));
// Get our parent frame's orientation. If we are a horizontal scrollbar,
// then subtract 8 from the result to get the correct offset.
if (HasAttrValue(content, mSBOrientAtom, "vertical"))
aPart = SP_THUMBVERT; // We're vertical instead.
}
return NS_OK;
}
case NS_THEME_SCROLLBAR_GRIPPER: {
aPart = SP_GRIPPERHOR;
if (!aFrame)
aState = BP_NORMAL;
else if (IsDisabled(aFrame))
aState = BP_DISABLED;
else {
PRInt32 eventState = GetContentState(aFrame);
if (eventState & NS_EVENT_STATE_ACTIVE) // Hover is not also a requirement for
// the gripper, since the drag is not canceled
// when you move outside the gripper.
aState = BP_ACTIVE;
else if (eventState & NS_EVENT_STATE_HOVER)
aState = BP_HOVER;
else
aState = BP_NORMAL;
}
if (aFrame) {
nsCOMPtr<nsIContent> content;
aFrame->GetContent(getter_AddRefs(content));
if (HasAttrValue(content, mSBOrientAtom, "vertical"))
aPart = SP_GRIPPERVERT; // We're vertical instead.
}
return NS_OK;
}
case NS_THEME_TOOLBOX:
case NS_THEME_STATUSBAR: {
aPart = aState = 0;
return NS_OK; // These have no part or state.
}
case NS_THEME_TAB: {
aPart = TABP_TAB;
if (!aFrame) {
aState = BP_NORMAL;
return NS_OK;
}
if (IsDisabled(aFrame)) {
aState = BP_DISABLED;
return NS_OK;
}
if (IsSelected(aFrame)) {
aPart = TABP_TAB_SELECTED;
aState = BP_ACTIVE; // The selected tab is always "pressed".
}
else {
PRInt32 eventState = GetContentState(aFrame);
if (eventState & NS_EVENT_STATE_HOVER && eventState & NS_EVENT_STATE_ACTIVE)
aState = BP_ACTIVE;
else if (eventState & NS_EVENT_STATE_FOCUS)
aState = BP_DEFAULT;
else if (eventState & NS_EVENT_STATE_HOVER)
aState = BP_HOVER;
else
aState = BP_NORMAL;
}
return NS_OK;
}
}
aPart = 0;
aState = 0;
return NS_ERROR_FAILURE;
}
nsresult
GetSystemColor(PRUint8 aWidgetType, nsILookAndFeel::nsColorID& aColorID)
{
switch (aWidgetType) {
case NS_THEME_BUTTON:
case NS_THEME_TOOLBAR_BUTTON:
case NS_THEME_TAB: {
aColorID = nsILookAndFeel::eColor_buttontext;
return NS_OK;
}
}
return NS_ERROR_FAILURE;
}
nsresult
GetSystemFont(PRUint8 aWidgetType, nsSystemFontID& aFont)
{
switch (aWidgetType) {
case NS_THEME_BUTTON:
case NS_THEME_TOOLBAR_BUTTON:
case NS_THEME_TAB: {
aFont = eSystemFont_Button;
return NS_OK;
}
}
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP
nsNativeThemeWin::DrawWidgetBackground(nsIRenderingContext* aContext,
nsIFrame* aFrame,
PRUint8 aWidgetType,
const nsRect& aRect,
const nsRect& aClipRect)
{
if (!drawThemeBG)
return NS_ERROR_FAILURE;
HANDLE theme = GetTheme(aWidgetType);
if (!theme)
return NS_ERROR_FAILURE;
PRInt32 part, state;
nsresult rv = GetThemePartAndState(aFrame, aWidgetType, part, state);
if (NS_FAILED(rv))
return rv;
nsTransform2D* transformMatrix;
aContext->GetCurrentTransform(transformMatrix);
RECT widgetRect;
RECT clipRect;
nsRect tr(aRect);
nsRect cr(aClipRect);
transformMatrix->TransformCoord(&tr.x,&tr.y,&tr.width,&tr.height);
GetNativeRect(tr, widgetRect);
transformMatrix->TransformCoord(&cr.x,&cr.y,&cr.width,&cr.height);
GetNativeRect(cr, clipRect);
HDC hdc = ((nsRenderingContextWin*)aContext)->mDC;
if (!hdc)
return NS_ERROR_FAILURE;
drawThemeBG(theme, hdc, part, state, &widgetRect, &clipRect);
return NS_OK;
}
NS_IMETHODIMP
nsNativeThemeWin::GetWidgetPadding(nsIDeviceContext* aContext,
nsIFrame* aFrame,
PRUint8 aWidgetType,
nsMargin* aResult)
{
if (!getThemeContentRect)
return NS_ERROR_FAILURE;
if (aWidgetType == NS_THEME_TOOLBOX || aWidgetType == NS_THEME_TOOLBAR || aWidgetType == NS_THEME_STATUSBAR)
return NS_OK; // Don't worry about it.
HANDLE theme = GetTheme(aWidgetType);
if (!theme)
return NS_ERROR_FAILURE;
PRInt32 part, state;
nsresult rv = GetThemePartAndState(aFrame, aWidgetType, part, state);
if (NS_FAILED(rv))
return rv;
// Get our info.
RECT outerRect; // Create a fake outer rect.
outerRect.top = outerRect.left = 100;
outerRect.right = outerRect.bottom = 200;
RECT contentRect(outerRect);
HRESULT res = getThemeContentRect(theme, NULL, part, state, &outerRect, &contentRect);
if (FAILED(res))
return NS_ERROR_FAILURE;
// Now compute the delta in each direction and place it in our
// nsMargin struct.
aResult->top = contentRect.top - outerRect.top;
aResult->bottom = outerRect.bottom - contentRect.bottom;
aResult->left = contentRect.left - outerRect.left;
aResult->right = outerRect.right - contentRect.right;
return NS_OK;
}
NS_IMETHODIMP
nsNativeThemeWin::GetWidgetFont(nsIDeviceContext* aContext,
PRUint8 aWidgetType,
nsFont* aFont)
{
if (!getThemeFont)
return NS_ERROR_FAILURE;
HANDLE theme = GetTheme(aWidgetType);
if (!theme)
return NS_ERROR_FAILURE;
PRInt32 part, state;
nsresult rv = GetThemePartAndState(nsnull, aWidgetType, part, state);
if (NS_FAILED(rv))
return rv;
nsDeviceContextWin* dcWin = (nsDeviceContextWin*)aContext;
HWND hwnd;
HDC tdc;
if (!dcWin->mDC) {
hwnd = (HWND)dcWin->mWidget;
tdc = ::GetDC(hwnd);
}
else
tdc = dcWin->mDC;
// Get our info.
// LOGFONT logFont;
// HRESULT res = getThemeFont(theme, tdc, part, state, THEME_FONT, &logFont);
// if (FAILED(res)) {
// Part didn't define a font. Get the font from the system metrics
// instead.
nsSystemFontID sysID;
rv = GetSystemFont(aWidgetType, sysID);
if (NS_FAILED(rv))
return rv;
dcWin->GetSysFontInfo(tdc, sysID, aFont);
// }
// else
// dcWin->CopyLogFontToNSFont(&tdc, &logFont, aFont);
// Release the dc
if (!dcWin->mDC)
::ReleaseDC(hwnd, tdc);
return NS_OK;
}
NS_IMETHODIMP
nsNativeThemeWin::GetWidgetColor(nsIPresContext* aPresContext,
nsIRenderingContext* aContext,
nsIFrame* aFrame,
PRUint8 aWidgetType,
nscolor* aColor)
{
HANDLE theme = GetTheme(aWidgetType);
PRInt32 part, state;
nsresult rv = GetThemePartAndState(aFrame, aWidgetType, part, state);
HDC hdc = ((nsRenderingContextWin*)aContext)->mDC;
if (!hdc)
return NS_ERROR_FAILURE;
//COLORREF color;
//HRESULT res = getThemeColor(theme, hdc, part, state, THEME_COLOR, &color);
//if (FAILED(res)) {
// Try to get a system color based off the widget type.
nsCOMPtr<nsILookAndFeel> lf;
aPresContext->GetLookAndFeel(getter_AddRefs(lf));
nsILookAndFeel::nsColorID colorID;
rv = GetSystemColor(aWidgetType, colorID);
if (NS_FAILED(rv))
return rv;
lf->GetColor(colorID, *aColor);
// }
// Copy the colorref into an nscolor.
// *aColor = color;
return NS_OK;
}
NS_IMETHODIMP
nsNativeThemeWin::GetMinimumWidgetSize(nsIRenderingContext* aContext, nsIFrame* aFrame,
PRUint8 aWidgetType,
nsSize* aResult)
{
if (!getThemePartSize)
return NS_ERROR_FAILURE;
if (aWidgetType == NS_THEME_TOOLBOX || aWidgetType == NS_THEME_TOOLBAR || aWidgetType == NS_THEME_STATUSBAR)
return NS_OK; // Don't worry about it.
HANDLE theme = GetTheme(aWidgetType);
if (!theme)
return NS_ERROR_FAILURE;
PRInt32 part, state;
nsresult rv = GetThemePartAndState(aFrame, aWidgetType, part, state);
if (NS_FAILED(rv))
return rv;
HDC hdc = ((nsRenderingContextWin*)aContext)->mDC;
if (!hdc)
return NS_ERROR_FAILURE;
PRInt32 sizeReq = 1; // Best-fit size.
if (aWidgetType == NS_THEME_SCROLLBAR_THUMB)
sizeReq = 0; // Best-fit size for scrollbar thumbs is too large for most themes.
// In our app, we want the thumb to be able to really shrink down,
// so use the min-size request value (of 0).
SIZE sz;
getThemePartSize(theme, hdc, part, state, NULL, sizeReq, &sz);
aResult->width = sz.cx;
aResult->height = sz.cy;
return NS_OK;
}
NS_IMETHODIMP
nsNativeThemeWin::WidgetStateChanged(nsIFrame* aFrame, PRUint8 aWidgetType,
nsIAtom* aAttribute, PRBool* aShouldRepaint)
{
// Some widget types just never change state.
if (aWidgetType == NS_THEME_TOOLBOX || aWidgetType == NS_THEME_TOOLBAR ||
aWidgetType == NS_THEME_SCROLLBAR_TRACK || aWidgetType == NS_THEME_STATUSBAR) {
*aShouldRepaint = PR_FALSE;
return NS_OK;
}
// XXXdwh Not sure what can really be done here. Can at least guess for
// specific widgets that they're highly unlikely to have certain states.
// For example, a toolbar doesn't care about any states.
if (!aAttribute) {
// Hover/focus/active changed. Always repaint.
*aShouldRepaint = PR_TRUE;
}
else {
// Check the attribute to see if it's relevant.
// disabled, checked, dlgtype, default, etc.
*aShouldRepaint = PR_FALSE;
if (aAttribute == mDisabledAtom || aAttribute == mCheckedAtom ||
aAttribute == mSelectedAtom)
*aShouldRepaint = PR_TRUE;
}
return NS_OK;
}
void
nsNativeThemeWin::CloseData()
{
// XXXdwh Calling closeTheme trashes the this ptr and causes horrible things
// to happen. For now, just drop the stale handles without closing them.
// Is this a bug in the API, or is there something I'm doing wrong?
if (mToolbarTheme) {
closeTheme(mToolbarTheme);
mToolbarTheme = NULL;
}
if (mScrollbarTheme) {
closeTheme(mScrollbarTheme);
mScrollbarTheme = NULL;
}
if (mRebarTheme) {
closeTheme(mRebarTheme);
mRebarTheme = NULL;
}
if (mButtonTheme) {
closeTheme(mButtonTheme);
mButtonTheme = NULL;
}
if (mStatusbarTheme) {
closeTheme(mStatusbarTheme);
mStatusbarTheme = NULL;
}
if (mTabTheme) {
closeTheme(mTabTheme);
mTabTheme = NULL;
}
if (mTreeViewTheme) {
closeTheme(mTreeViewTheme);
mTreeViewTheme = NULL;
}
}
NS_IMETHODIMP
nsNativeThemeWin::ThemeChanged()
{
CloseData();
return NS_OK;
}
PRBool
nsNativeThemeWin::ThemeSupportsWidget(nsIPresContext* aPresContext,
PRUint8 aWidgetType)
{
// XXXdwh We can go even further and call the API to ask if support exists.
HANDLE theme = GetTheme(aWidgetType);
return theme != NULL;
}
///////////////////////////////////////////
// Creation Routine
///////////////////////////////////////////
NS_METHOD NS_NewNativeTheme(nsISupports *aOuter, REFNSIID aIID, void **aResult)
{
if (aOuter)
return NS_ERROR_NO_AGGREGATION;
nsNativeThemeWin* theme = new nsNativeThemeWin();
if (!theme)
return NS_ERROR_OUT_OF_MEMORY;
return theme->QueryInterface(aIID, aResult);
}

Просмотреть файл

@ -0,0 +1,98 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is the Mozilla browser.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1999 Netscape Communications Corporation. All
* Rights Reserved.
*
* Original Author: David W. Hyatt (hyatt@netscape.com)
*
* Contributors:
*/
#include "nsITheme.h"
#include "nsCOMPtr.h"
#include "nsIAtom.h"
#include <windows.h>
class nsNativeThemeWin: public nsITheme {
public:
NS_DECL_ISUPPORTS
// The nsITheme interface.
NS_IMETHOD DrawWidgetBackground(nsIRenderingContext* aContext,
nsIFrame* aFrame,
PRUint8 aWidgetType,
const nsRect& aRect,
const nsRect& aClipRect);
NS_IMETHOD GetWidgetPadding(nsIDeviceContext* aContext,
nsIFrame* aFrame,
PRUint8 aWidgetType,
nsMargin* aResult);
NS_IMETHOD GetWidgetFont(nsIDeviceContext* aContext,
PRUint8 aWidgetType,
nsFont* aFont);
NS_IMETHOD GetWidgetColor(nsIPresContext* aPresContext,
nsIRenderingContext* aContext,
nsIFrame* aFrame,
PRUint8 aWidgetType,
nscolor* aFont);
NS_IMETHOD GetMinimumWidgetSize(nsIRenderingContext* aContext, nsIFrame* aFrame,
PRUint8 aWidgetType,
nsSize* aResult);
NS_IMETHOD WidgetStateChanged(nsIFrame* aFrame, PRUint8 aWidgetType,
nsIAtom* aAttribute, PRBool* aShouldRepaint);
NS_IMETHOD ThemeChanged();
PRBool ThemeSupportsWidget(nsIPresContext* aPresContext,
PRUint8 aWidgetType);
nsNativeThemeWin();
virtual ~nsNativeThemeWin();
protected:
void CloseData();
HANDLE GetTheme(PRUint8 aWidgetType);
nsresult GetThemePartAndState(nsIFrame* aFrame, PRUint8 aWidgetType,
PRInt32& aPart, PRInt32& aState);
PRBool IsDisabled(nsIFrame* aFrame);
PRBool IsChecked(nsIFrame* aFrame);
PRBool IsSelected(nsIFrame* aFrame);
private:
HMODULE mThemeDLL;
HANDLE mButtonTheme;
HANDLE mToolbarTheme;
HANDLE mRebarTheme;
HANDLE mScrollbarTheme;
HANDLE mStatusbarTheme;
HANDLE mTabTheme;
HANDLE mTreeViewTheme;
nsCOMPtr<nsIAtom> mCheckedAtom;
nsCOMPtr<nsIAtom> mDisabledAtom;
nsCOMPtr<nsIAtom> mSBOrientAtom;
nsCOMPtr<nsIAtom> mSelectedAtom;
nsCOMPtr<nsIAtom> mTypeAtom;
};
// Creator function
extern NS_METHOD NS_NewNativeThemeWin(nsISupports *aOuter, REFNSIID aIID, void **aResult);

Просмотреть файл

@ -242,6 +242,8 @@ private:
void InitBidiInfo(void);
#endif // IBMBIDI
friend class nsNativeThemeWin;
protected:
nscolor mCurrentColor;
nsIFontMetrics *mFontMetrics;

Просмотреть файл

@ -96,6 +96,7 @@
#include "nsIBindingManager.h"
#include "nsIXBLBinding.h"
#include "nsIElementFactory.h"
#include "nsITheme.h"
#include "nsContentCID.h"
#include "nsIDocShell.h"
#include "nsFormControlHelper.h"
@ -7795,7 +7796,13 @@ FindPreviousSibling(nsIPresShell* aPresShell,
prevSibling->GetStyleData(eStyleStruct_Display,
(const nsStyleStruct*&)display);
if (display->IsFloating() || display->IsPositioned()) {
if (display->mDisplay == NS_STYLE_DISPLAY_POPUP) {
nsIFrame* placeholderFrame;
aPresShell->GetPlaceholderFrameFor(prevSibling, &placeholderFrame);
if (prevSibling)
prevSibling = placeholderFrame;
}
else if (display->IsFloating() || display->IsPositioned()) {
nsIFrame* placeholderFrame;
aPresShell->GetPlaceholderFrameFor(prevSibling, &placeholderFrame);
NS_ASSERTION(placeholderFrame, "no placeholder for out-of-flow frame");
@ -8510,6 +8517,9 @@ nsCSSFrameConstructor::ContentInserted(nsIPresContext* aPresContext,
nsXULTreeOuterGroupFrame* treeRowGroup;
tree->GetTreeBody(&treeRowGroup);
if (treeRowGroup) {
// Don't bother with the odd XBL case of anonymous content.
if (aIndexInContainer == -1)
return NS_OK;
// Get the primary frame for the parent of the child that's being added.
nsIFrame* innerFrame = GetFrameFor(shell, aPresContext, aContainer);
@ -10052,28 +10062,43 @@ nsCSSFrameConstructor::ContentStatesChanged(nsIPresContext* aPresContext,
NS_ASSERTION(shell, "couldn't get pres shell");
if (shell) {
nsIStyleSet* styleSet;
shell->GetStyleSet(&styleSet);
nsCOMPtr<nsIStyleSet> styleSet;
shell->GetStyleSet(getter_AddRefs(styleSet));
NS_ASSERTION(styleSet, "couldn't get style set");
if (styleSet) { // test if any style rules exist which are dependent on content state
nsIFrame* primaryFrame1 = nsnull;
nsIFrame* primaryFrame2 = nsnull;
if (aContent1 && (NS_OK == styleSet->HasStateDependentStyle(aPresContext, aContent1))) {
PRUint8 app1 = 0;
PRUint8 app2 = 0;
shell->GetPrimaryFrameFor(aContent1, &primaryFrame1);
if (primaryFrame1) {
const nsStyleDisplay* disp;
primaryFrame1->GetStyleData(eStyleStruct_Display, (const nsStyleStruct*&)disp);
app1 = disp->mAppearance;
}
else {
if (!app1 && (NS_OK != styleSet->HasStateDependentStyle(aPresContext, aContent1))) {
primaryFrame1 = nsnull;
aContent1 = nsnull;
}
if (aContent2 && (aContent2 != aContent1) &&
(NS_OK == styleSet->HasStateDependentStyle(aPresContext, aContent2))) {
if (aContent2 == aContent1)
aContent2 = nsnull;
else if (aContent2) {
shell->GetPrimaryFrameFor(aContent2, &primaryFrame2);
if (primaryFrame2) {
const nsStyleDisplay* disp2;
primaryFrame2->GetStyleData(eStyleStruct_Display, (const nsStyleStruct*&)disp2);
app2 = disp2->mAppearance;
}
else {
if (!app2 && (NS_OK != styleSet->HasStateDependentStyle(aPresContext, aContent2))) {
primaryFrame2 = nsnull;
aContent2 = nsnull;
}
NS_RELEASE(styleSet);
}
if (primaryFrame1 && primaryFrame2) { // detect if one is parent of other, skip child
nsIFrame* parent;
@ -10109,10 +10134,29 @@ nsCSSFrameConstructor::ContentStatesChanged(nsIPresContext* aPresContext,
kNameSpaceID_Unknown, nsnull,
changeList1, NS_STYLE_HINT_NONE, frameChange1);
if (app1) {
nsCOMPtr<nsITheme> theme;
aPresContext->GetTheme(getter_AddRefs(theme));
PRBool repaint = PR_FALSE;
if (theme)
theme->WidgetStateChanged(primaryFrame1, app1, nsnull, &repaint);
if (repaint)
ApplyRenderingChangeToTree(aPresContext, primaryFrame1, nsnull);
}
if ((frameChange1 != NS_STYLE_HINT_RECONSTRUCT_ALL) && (primaryFrame2)) {
frameManager->ComputeStyleChangeFor(aPresContext, primaryFrame2,
kNameSpaceID_Unknown, nsnull,
changeList2, NS_STYLE_HINT_NONE, frameChange2);
if (app2) {
nsCOMPtr<nsITheme> theme;
aPresContext->GetTheme(getter_AddRefs(theme));
PRBool repaint = PR_FALSE;
if (theme)
theme->WidgetStateChanged(primaryFrame1, app2, nsnull, &repaint);
if (repaint)
ApplyRenderingChangeToTree(aPresContext, primaryFrame2, nsnull);
}
}
if ((frameChange1 == NS_STYLE_HINT_RECONSTRUCT_ALL) ||
@ -10157,6 +10201,15 @@ nsCSSFrameConstructor::ContentStatesChanged(nsIPresContext* aPresContext,
frameManager->ComputeStyleChangeFor(aPresContext, primaryFrame2,
kNameSpaceID_Unknown, nsnull,
changeList, NS_STYLE_HINT_NONE, frameChange);
if (app2) {
nsCOMPtr<nsITheme> theme;
aPresContext->GetTheme(getter_AddRefs(theme));
PRBool repaint = PR_FALSE;
if (theme)
theme->WidgetStateChanged(primaryFrame2, app2, nsnull, &repaint);
if (repaint)
ApplyRenderingChangeToTree(aPresContext, primaryFrame2, nsnull);
}
switch (frameChange) { // max change needed for top level frames
case NS_STYLE_HINT_RECONSTRUCT_ALL:
@ -10392,6 +10445,23 @@ nsCSSFrameConstructor::AttributeChanged(nsIPresContext* aPresContext,
set->ClearStyleData(aPresContext, rule, styleContext);
}
// See if we have appearance information for a theme.
if (primaryFrame) {
const nsStyleDisplay* disp;
primaryFrame->GetStyleData(eStyleStruct_Display,
(nsStyleStruct*&)disp);
if (disp && disp->mAppearance) {
nsCOMPtr<nsITheme> theme;
aPresContext->GetTheme(getter_AddRefs(theme));
if (theme && theme->ThemeSupportsWidget(aPresContext, disp->mAppearance)) {
PRBool repaint = PR_FALSE;
theme->WidgetStateChanged(primaryFrame, disp->mAppearance, aAttribute, &repaint);
if (repaint)
ApplyRenderingChangeToTree(aPresContext, primaryFrame, nsnull);
}
}
}
// apply changes
if (primaryFrame && aHint == NS_STYLE_HINT_ATTRCHANGE)
result = primaryFrame->AttributeChanged(aPresContext, aContent, aNameSpaceID, aAttribute, aModType, aHint);

Просмотреть файл

@ -57,6 +57,9 @@
#include "imgIContainer.h"
#include "nsCSSRendering.h"
#include "nsIPrintContext.h"
#include "nsITheme.h"
#include "nsThemeConstants.h"
#include "nsIServiceManager.h"
#define BORDER_FULL 0 //entire side
#define BORDER_INSIDE 1 //inside half
@ -1594,6 +1597,16 @@ void nsCSSRendering::PaintBorder(nsIPresContext* aPresContext,
nsCompatibility compatMode;
aPresContext->GetCompatibilityMode(&compatMode);
// Check to see if we have an appearance defined. If so, we let the theme
// renderer draw the border.
const nsStyleDisplay* displayData;
aForFrame->GetStyleData(eStyleStruct_Display, ((const nsStyleStruct*&)displayData));
if (displayData->mAppearance) {
nsCOMPtr<nsITheme> theme;
aPresContext->GetTheme(getter_AddRefs(theme));
if (theme && theme->ThemeSupportsWidget(aPresContext, displayData->mAppearance))
return; // Let the theme handle it.
}
// Get our style context's color struct.
const nsStyleColor* ourColor = (const nsStyleColor*)aStyleContext->GetStyleData(eStyleStruct_Color);
@ -2419,6 +2432,20 @@ nsCSSRendering::PaintBackground(nsIPresContext* aPresContext,
return;
}
// Check to see if we have an appearance defined. If so, we let the theme
// renderer draw the background.
const nsStyleDisplay* displayData;
aForFrame->GetStyleData(eStyleStruct_Display, ((const nsStyleStruct*&)displayData));
if (displayData->mAppearance) {
nsCOMPtr<nsITheme> theme;
aPresContext->GetTheme(getter_AddRefs(theme));
if (theme && theme->ThemeSupportsWidget(aPresContext, displayData->mAppearance)) {
theme->DrawWidgetBackground(&aRenderingContext, aForFrame,
displayData->mAppearance, aBorderArea, aDirtyRect);
return;
}
}
// if there is no background image, try a color.
if (aColor.mBackgroundImage.IsEmpty()) {
// See if there's a background color specified. The background color

Просмотреть файл

@ -55,6 +55,7 @@
#include "nsIContent.h"
#include "nsINameSpaceManager.h"
#include "nsIXMLContent.h"
#include "nsIXBLBinding.h"
#include "nsIDocument.h"
#include "nsIBindingManager.h"
#include "nsIScrollableFrame.h"
@ -1721,7 +1722,6 @@ FrameManager::ReResolveStyleContext(nsIPresContext* aPresContext,
NS_ADDREF(aParentContext);
NOISY_TRACE_FRAME("non-null parent context provided: using it and assuming already resolved",aFrame);
}
NS_ASSERTION(aParentContext, "Failed to resolve parent context");
// do primary context
nsIStyleContext* newContext = nsnull;
@ -1859,6 +1859,12 @@ FrameManager::ReResolveStyleContext(nsIPresContext* aPresContext,
aResultChange = aMinChange;
if (aMinChange < NS_STYLE_HINT_FRAMECHANGE) {
// There is no need to waste time crawling into a frame's children on a frame change.
// The act of reconstructing frames will force new style contexts to be resolved on all
// of this frame's descendants anyway, so we want to avoid wasting time processing
// style contexts that we're just going to throw away anyway. - dwh
// now do children
PRInt32 listIndex = 0;
nsIAtom* childList = nsnull;
@ -1913,6 +1919,7 @@ FrameManager::ReResolveStyleContext(nsIPresContext* aPresContext,
aFrame->GetAdditionalChildListName(listIndex++, &childList);
} while (childList);
// XXX need to do overflow frames???
}
NS_RELEASE(newContext);
NS_IF_RELEASE(localContent);

Просмотреть файл

@ -158,6 +158,13 @@ public:
NS_IMETHOD SelectAlternateStyleSheet(const nsString& aSheetTitle) = 0;
/*
* Called when stylesheets are added/removed/enabled/disabled to rebuild
* all style data for a given pres shell without necessarily reconstructing
* all of the frames.
*/
NS_IMETHOD ReconstructStyleData() = 0;
/** Setup all style rules required to implement preferences
* - used for background/text/link colors and link underlining
* may be extended for any prefs that are implemented via style rules

Просмотреть файл

@ -65,6 +65,7 @@
#include "nsIDOMWindow.h"
#include "nsNetUtil.h"
#include "nsXPIDLString.h"
#include "prprf.h"
#ifdef IBMBIDI
#include "nsBidiPresUtils.h"
@ -143,7 +144,8 @@ nsPresContext::nsPresContext()
mDefaultCursiveFont("cursive", NS_FONT_STYLE_NORMAL, NS_FONT_VARIANT_NORMAL,
NS_FONT_WEIGHT_NORMAL, 0, NSIntPointsToTwips(12)),
mDefaultFantasyFont("fantasy", NS_FONT_STYLE_NORMAL, NS_FONT_VARIANT_NORMAL,
NS_FONT_WEIGHT_NORMAL, 0, NSIntPointsToTwips(12))
NS_FONT_WEIGHT_NORMAL, 0, NSIntPointsToTwips(12)),
mNoTheme(PR_FALSE)
{
NS_INIT_REFCNT();
mCompatibilityMode = eCompatibility_Standard;
@ -1748,6 +1750,39 @@ nsPresContext::IsRenderingOnlySelection(PRBool* aResult)
return NS_OK;
}
NS_IMETHODIMP
nsPresContext::GetTheme(nsITheme** aResult)
{
if (!mNoTheme && !mTheme) {
mTheme = do_GetService("@mozilla.org/chrome/chrome-native-theme;1");
if (!mTheme)
mNoTheme = PR_TRUE;
}
*aResult = mTheme;
NS_IF_ADDREF(*aResult);
return mTheme ? NS_OK : NS_ERROR_FAILURE;
}
NS_IMETHODIMP
nsPresContext::ThemeChanged()
{
// Tell the theme that it changed, so it can flush any handles to stale theme
// data.
if (mTheme)
mTheme->ThemeChanged();
// Clear all cached nsILookAndFeel colors.
if (mLookAndFeel)
mLookAndFeel->LookAndFeelChanged();
if (!mShell)
return NS_OK;
return mShell->ReconstructStyleData();
}
#ifdef MOZ_REFLOW_PERF
NS_IMETHODIMP
nsPresContext::CountReflows(const char * aName, PRUint32 aType, nsIFrame * aFrame)

Просмотреть файл

@ -68,6 +68,7 @@ class nsIURI;
class nsILookAndFeel;
class nsICSSPseudoComparator;
class nsILanguageAtom;
class nsITheme;
#ifdef MOZ_REFLOW_PERF
class nsIRenderingContext;
@ -524,6 +525,19 @@ public:
NS_IMETHOD SetIsRenderingOnlySelection(PRBool aResult) = 0;
NS_IMETHOD IsRenderingOnlySelection(PRBool* aResult) = 0;
/*
* Obtain a native them for rendering our widgets (both form controls and html)
*/
NS_IMETHOD GetTheme(nsITheme** aResult) = 0;
/*
* Notify the pres context that the theme has changed. An internal switch
* means it's one of our Mozilla themes that changed (e.g., Modern to Classic).
* Otherwise, the OS is telling us that the native theme for the platform
* has changed.
*/
NS_IMETHOD ThemeChanged() = 0;
#ifdef MOZ_REFLOW_PERF
NS_IMETHOD CountReflows(const char * aName, PRUint32 aType, nsIFrame * aFrame) = 0;
NS_IMETHOD PaintCount(const char * aName, nsIRenderingContext* aRendingContext, nsIFrame * aFrame, PRUint32 aColor) = 0;

Просмотреть файл

@ -146,6 +146,17 @@
#include "nsIDOMHTMLImageElement.h"
#include "nsITimer.h"
// For style data reconstruction
#include "nsStyleChangeList.h"
#include "nsIStyleFrameConstruction.h"
#include "nsINameSpaceManager.h"
#include "nsIBindingManager.h"
#include "nsIMenuFrame.h"
#include "nsITreeFrame.h"
#include "nsIOutlinerBoxObject.h"
#include "nsIXBLBinding.h"
#include "nsPlaceholderFrame.h"
// Dummy layout request
#include "nsIChannel.h"
#include "nsILoadGroup.h"
@ -844,6 +855,7 @@ public:
NS_IMETHOD GetActiveAlternateStyleSheet(nsString& aSheetTitle);
NS_IMETHOD SelectAlternateStyleSheet(const nsString& aSheetTitle);
NS_IMETHOD ListAlternateStyleSheets(nsStringArray& aTitleList);
NS_IMETHOD ReconstructStyleData();
NS_IMETHOD SetPreferenceStyleRules(PRBool aForceReflow);
NS_IMETHOD EnablePrefStyleRules(PRBool aEnable, PRUint8 aPrefType=0xFF);
NS_IMETHOD ArePrefStyleRulesEnabled(PRBool& aEnabled);
@ -1891,7 +1903,7 @@ PresShell::SelectAlternateStyleSheet(const nsString& aSheetTitle)
}
}
}
ReconstructFrames();
ReconstructStyleData();
}
return NS_OK;
}
@ -2059,7 +2071,7 @@ PresShell::SetPreferenceStyleRules(PRBool aForceReflow)
// this is harsh, but without it the new colors don't appear on the current page
// Fortunately, it only happens when the prefs change, a rare event.
// XXX - determine why the normal PresContext::RemapStyleAndReflow doesn't cut it
ReconstructFrames();
ReconstructStyleData();
}
return result;
@ -5225,18 +5237,152 @@ PresShell::ReconstructFrames(void)
return rv;
}
static nsresult
FlushMiscWidgetInfo(nsStyleChangeList& aChangeList, nsIPresContext* aPresContext, nsIFrame* aFrame)
{
// Ok, get our binding information.
const nsStyleDisplay* oldDisplay;
aFrame->GetStyleData(eStyleStruct_Display, (const nsStyleStruct*&)oldDisplay);
if (!oldDisplay->mBinding.IsEmpty()) {
// We had a binding.
nsCOMPtr<nsIContent> content;
aFrame->GetContent(getter_AddRefs(content));
nsCOMPtr<nsIDocument> doc;
content->GetDocument(*getter_AddRefs(doc));
if (doc) {
nsCOMPtr<nsIBindingManager> bm;
doc->GetBindingManager(getter_AddRefs(bm));
nsCOMPtr<nsIXBLBinding> binding;
bm->GetBinding(content, getter_AddRefs(binding));
PRBool marked = PR_FALSE;
binding->MarkedForDeath(&marked);
if (marked) {
// Add in a change to process, thus ensuring this binding gets rebuilt.
aChangeList.AppendChange(aFrame, content, NS_STYLE_HINT_FRAMECHANGE);
return NS_OK;
}
}
}
nsCOMPtr<nsITreeFrame> treeFrame(do_QueryInterface(aFrame));
if (treeFrame) {
// Trees are problematic. Always flush them out on a skin switch.
nsCOMPtr<nsIContent> content;
aFrame->GetContent(getter_AddRefs(content));
aChangeList.AppendChange(aFrame, content, NS_STYLE_HINT_FRAMECHANGE);
return NS_OK;
}
// Outliners have a special style cache that needs to be flushed when
// the theme changes.
nsCOMPtr<nsIOutlinerBoxObject> outlinerBox(do_QueryInterface(aFrame));
if (outlinerBox)
outlinerBox->ClearStyleAndImageCaches();
nsCOMPtr<nsIMenuFrame> menuFrame(do_QueryInterface(aFrame));
if (menuFrame) {
menuFrame->UngenerateMenu(); // We deliberately don't re-resolve style on
menuFrame->OpenMenu(PR_FALSE); // a menu's popup sub-content, since doing so
// slows menus to a crawl. That means we have to
// special-case them on a skin switch, and ensure that
// the popup frames just get destroyed completely.
}
// Now walk our children.
PRInt32 listIndex = 0;
nsCOMPtr<nsIAtom> childList;
nsIFrame* child;
do {
child = nsnull;
aFrame->FirstChild(aPresContext, childList, &child);
while (child) {
nsFrameState state;
child->GetFrameState(&state);
if (NS_FRAME_OUT_OF_FLOW != (state & NS_FRAME_OUT_OF_FLOW)) {
// only do frames that are in flow
nsCOMPtr<nsIAtom> frameType;
child->GetFrameType(getter_AddRefs(frameType));
if (nsLayoutAtoms::placeholderFrame == frameType.get()) { // placeholder
// get out of flow frame and recurse there
nsIFrame* outOfFlowFrame = ((nsPlaceholderFrame*)child)->GetOutOfFlowFrame();
NS_ASSERTION(outOfFlowFrame, "no out-of-flow frame");
FlushMiscWidgetInfo(aChangeList, aPresContext, outOfFlowFrame);
}
else
FlushMiscWidgetInfo(aChangeList, aPresContext, child);
}
child->GetNextSibling(&child);
}
aFrame->GetAdditionalChildListName(listIndex++, getter_AddRefs(childList));
} while (childList);
return NS_OK;
}
NS_IMETHODIMP
PresShell::ReconstructStyleData()
{
nsIFrame* rootFrame;
GetRootFrame(&rootFrame);
if (!rootFrame)
return NS_OK;
nsCOMPtr<nsIStyleSet> set;
GetStyleSet(getter_AddRefs(set));
if (!set)
return NS_OK;
nsCOMPtr<nsIStyleFrameConstruction> cssFrameConstructor;
set->GetStyleFrameConstruction(getter_AddRefs(cssFrameConstructor));
if (!cssFrameConstructor)
return NS_OK;
nsCOMPtr<nsIFrameManager> frameManager;
GetFrameManager(getter_AddRefs(frameManager));
// Now handle some of our more problematic widgets (and also deal with
// skin XBL changing).
nsStyleChangeList changeList;
FlushMiscWidgetInfo(changeList, mPresContext, rootFrame);
cssFrameConstructor->ProcessRestyledFrames(changeList, mPresContext);
changeList.Clear();
// Clear all undisplayed content in the undisplayed content map.
// These cached style contexts will no longer be valid following
// a full rule tree reconstruct.
frameManager->ClearUndisplayedContentMap();
// Now do a complete re-resolve of our style tree.
set->BeginRuleTreeReconstruct();
PRInt32 frameChange = NS_STYLE_HINT_NONE;
frameManager->ComputeStyleChangeFor(mPresContext, rootFrame,
kNameSpaceID_Unknown, nsnull,
changeList, NS_STYLE_HINT_NONE, frameChange);
if (frameChange == NS_STYLE_HINT_RECONSTRUCT_ALL)
set->ReconstructDocElementHierarchy(mPresContext);
else
cssFrameConstructor->ProcessRestyledFrames(changeList, mPresContext);
set->EndRuleTreeReconstruct();
return NS_OK;
}
NS_IMETHODIMP
PresShell::StyleSheetAdded(nsIDocument *aDocument,
nsIStyleSheet* aStyleSheet)
{
return ReconstructFrames();
return ReconstructStyleData();
}
NS_IMETHODIMP
PresShell::StyleSheetRemoved(nsIDocument *aDocument,
nsIStyleSheet* aStyleSheet)
{
return ReconstructFrames();
return ReconstructStyleData();
}
NS_IMETHODIMP
@ -5290,7 +5436,7 @@ PresShell::StyleRuleAdded(nsIDocument *aDocument,
return rv;
}
// XXX For now reconstruct everything
return ReconstructFrames();
return ReconstructStyleData();
}
NS_IMETHODIMP
@ -5307,7 +5453,7 @@ PresShell::StyleRuleRemoved(nsIDocument *aDocument,
return rv;
}
// XXX For now reconstruct everything
return ReconstructFrames();
return ReconstructStyleData();
}
NS_IMETHODIMP
@ -5496,14 +5642,7 @@ NS_IMETHODIMP
PresShell::BidiStyleChangeReflow()
{
// Have the root frame's style context remap its style
nsIFrame* rootFrame;
mFrameManager->GetRootFrame(&rootFrame);
if (rootFrame) {
mStyleSet->ClearStyleData(mPresContext, nsnull, nsnull);
ReconstructFrames();
}
return NS_OK;
return ReconstructStyleData();
}
#endif // IBMBIDI
@ -5683,6 +5822,9 @@ PresShell::HandleEvent(nsIView *aView,
return HandleEventInternal(aEvent, aView, NS_EVENT_FLAG_INIT, aEventStatus);
#endif
// Check for a theme change up front, since the frame type is irrelevant
if (aEvent->message == NS_THEMECHANGED && mPresContext)
return mPresContext->ThemeChanged();
aView->GetClientData(clientData);
frame = (nsIFrame *)clientData;

Просмотреть файл

@ -402,6 +402,7 @@
#define NS_STYLE_FONT_PULL_DOWN_MENU 14
#define NS_STYLE_FONT_LIST 15
#define NS_STYLE_FONT_FIELD 16
#define NS_STYLE_FONT_THEME 17
// See nsStylePosition.mPosition
#define NS_STYLE_POSITION_NORMAL 0

Просмотреть файл

@ -68,6 +68,7 @@ class nsIURI;
class nsILookAndFeel;
class nsICSSPseudoComparator;
class nsILanguageAtom;
class nsITheme;
#ifdef MOZ_REFLOW_PERF
class nsIRenderingContext;
@ -524,6 +525,19 @@ public:
NS_IMETHOD SetIsRenderingOnlySelection(PRBool aResult) = 0;
NS_IMETHOD IsRenderingOnlySelection(PRBool* aResult) = 0;
/*
* Obtain a native them for rendering our widgets (both form controls and html)
*/
NS_IMETHOD GetTheme(nsITheme** aResult) = 0;
/*
* Notify the pres context that the theme has changed. An internal switch
* means it's one of our Mozilla themes that changed (e.g., Modern to Classic).
* Otherwise, the OS is telling us that the native theme for the platform
* has changed.
*/
NS_IMETHOD ThemeChanged() = 0;
#ifdef MOZ_REFLOW_PERF
NS_IMETHOD CountReflows(const char * aName, PRUint32 aType, nsIFrame * aFrame) = 0;
NS_IMETHOD PaintCount(const char * aName, nsIRenderingContext* aRendingContext, nsIFrame * aFrame, PRUint32 aColor) = 0;

Просмотреть файл

@ -158,6 +158,13 @@ public:
NS_IMETHOD SelectAlternateStyleSheet(const nsString& aSheetTitle) = 0;
/*
* Called when stylesheets are added/removed/enabled/disabled to rebuild
* all style data for a given pres shell without necessarily reconstructing
* all of the frames.
*/
NS_IMETHOD ReconstructStyleData() = 0;
/** Setup all style rules required to implement preferences
* - used for background/text/link colors and link underlining
* may be extended for any prefs that are implemented via style rules

Просмотреть файл

@ -46,6 +46,7 @@ class nsIStyleRule;
class nsIStyleSheet;
class nsIStyleContext;
class nsIStyleRuleSupplier;
class nsIStyleFrameConstruction;
class nsIPresContext;
class nsIPresShell;
class nsIContent;
@ -109,8 +110,24 @@ public:
virtual nsresult GetRuleTree(nsRuleNode** aResult) = 0;
virtual nsresult ClearCachedDataInRuleTree(nsIStyleRule* aRule) = 0;
// The following two methods can be used to tear down and reconstruct a rule tree. The idea
// is to first call BeginRuleTreeReconstruct, which will set aside the old rule
// tree. The entire frame tree should then have ReResolveStyleContext
// called on it. With the old rule tree hidden from view, the newly resolved style contexts will
// resolve to rule nodes in a fresh rule tree, and the re-resolve system will properly compute
// the visual impact of the changes.
//
// After re-resolution, call EndRuleTreeReconstruct() to finally discard the old rule tree.
// This trick can be used in lieu of a full frame reconstruction when drastic style changes
// happen (e.g., stylesheets being added/removed in the DOM, theme switching in the Mozilla app,
// etc.
virtual nsresult BeginRuleTreeReconstruct()=0;
virtual nsresult EndRuleTreeReconstruct()=0;
virtual nsresult RemoveBodyFixupRule(nsIDocument *aDocument) = 0;
virtual nsresult GetStyleFrameConstruction(nsIStyleFrameConstruction** aResult) = 0;
// ClearCachedStyleData is used to invalidate portions of both the style context tree
// and rule tree without destroying the actual nodes in the two trees. |aRule| provides
// a hint as to which rule has changed, and all subtree data pruning will occur rooted

Просмотреть файл

@ -68,6 +68,7 @@ class nsIURI;
class nsILookAndFeel;
class nsICSSPseudoComparator;
class nsILanguageAtom;
class nsITheme;
#ifdef MOZ_REFLOW_PERF
class nsIRenderingContext;
@ -524,6 +525,19 @@ public:
NS_IMETHOD SetIsRenderingOnlySelection(PRBool aResult) = 0;
NS_IMETHOD IsRenderingOnlySelection(PRBool* aResult) = 0;
/*
* Obtain a native them for rendering our widgets (both form controls and html)
*/
NS_IMETHOD GetTheme(nsITheme** aResult) = 0;
/*
* Notify the pres context that the theme has changed. An internal switch
* means it's one of our Mozilla themes that changed (e.g., Modern to Classic).
* Otherwise, the OS is telling us that the native theme for the platform
* has changed.
*/
NS_IMETHOD ThemeChanged() = 0;
#ifdef MOZ_REFLOW_PERF
NS_IMETHOD CountReflows(const char * aName, PRUint32 aType, nsIFrame * aFrame) = 0;
NS_IMETHOD PaintCount(const char * aName, nsIRenderingContext* aRendingContext, nsIFrame * aFrame, PRUint32 aColor) = 0;

Просмотреть файл

@ -402,6 +402,7 @@
#define NS_STYLE_FONT_PULL_DOWN_MENU 14
#define NS_STYLE_FONT_LIST 15
#define NS_STYLE_FONT_FIELD 16
#define NS_STYLE_FONT_THEME 17
// See nsStylePosition.mPosition
#define NS_STYLE_POSITION_NORMAL 0

Просмотреть файл

@ -65,6 +65,7 @@
#include "nsIDOMWindow.h"
#include "nsNetUtil.h"
#include "nsXPIDLString.h"
#include "prprf.h"
#ifdef IBMBIDI
#include "nsBidiPresUtils.h"
@ -143,7 +144,8 @@ nsPresContext::nsPresContext()
mDefaultCursiveFont("cursive", NS_FONT_STYLE_NORMAL, NS_FONT_VARIANT_NORMAL,
NS_FONT_WEIGHT_NORMAL, 0, NSIntPointsToTwips(12)),
mDefaultFantasyFont("fantasy", NS_FONT_STYLE_NORMAL, NS_FONT_VARIANT_NORMAL,
NS_FONT_WEIGHT_NORMAL, 0, NSIntPointsToTwips(12))
NS_FONT_WEIGHT_NORMAL, 0, NSIntPointsToTwips(12)),
mNoTheme(PR_FALSE)
{
NS_INIT_REFCNT();
mCompatibilityMode = eCompatibility_Standard;
@ -1748,6 +1750,39 @@ nsPresContext::IsRenderingOnlySelection(PRBool* aResult)
return NS_OK;
}
NS_IMETHODIMP
nsPresContext::GetTheme(nsITheme** aResult)
{
if (!mNoTheme && !mTheme) {
mTheme = do_GetService("@mozilla.org/chrome/chrome-native-theme;1");
if (!mTheme)
mNoTheme = PR_TRUE;
}
*aResult = mTheme;
NS_IF_ADDREF(*aResult);
return mTheme ? NS_OK : NS_ERROR_FAILURE;
}
NS_IMETHODIMP
nsPresContext::ThemeChanged()
{
// Tell the theme that it changed, so it can flush any handles to stale theme
// data.
if (mTheme)
mTheme->ThemeChanged();
// Clear all cached nsILookAndFeel colors.
if (mLookAndFeel)
mLookAndFeel->LookAndFeelChanged();
if (!mShell)
return NS_OK;
return mShell->ReconstructStyleData();
}
#ifdef MOZ_REFLOW_PERF
NS_IMETHODIMP
nsPresContext::CountReflows(const char * aName, PRUint32 aType, nsIFrame * aFrame)

Просмотреть файл

@ -56,6 +56,7 @@
#include "nsHashtable.h"
#include "nsIContent.h"
#include "nsITheme.h"
// Base class for concrete presentation context classes
class nsPresContext : public nsIPresContext, public nsIObserver {
@ -199,6 +200,9 @@ public:
//Mohamed End
#endif // IBMBIDI
NS_IMETHOD GetTheme(nsITheme** aResult);
NS_IMETHOD ThemeChanged();
protected:
nsPresContext();
virtual ~nsPresContext();
@ -286,6 +290,9 @@ protected:
PRUint16 mImageAnimationModePref;
nsCOMPtr<nsITheme> mTheme;
PRBool mNoTheme;
protected:
void GetUserPreferences();
void GetFontPreferences();

Просмотреть файл

@ -364,13 +364,17 @@ nsGfxScrollFrame::GetScrollbarSizes(nsIPresContext* aPresContext,
{
nsBoxLayoutState state(aPresContext);
if (mInner->mHScrollbarBox) {
nsSize hs;
mInner->mHScrollbarBox->GetPrefSize(state, hs);
*aHbarHeight = hs.height;
}
if (mInner->mVScrollbarBox) {
nsSize vs;
mInner->mVScrollbarBox->GetPrefSize(state, vs);
*aVbarWidth = vs.width;
}
return NS_OK;
}
@ -536,6 +540,22 @@ nsGfxScrollFrame::RemoveFrame(nsIPresContext* aPresContext,
nsIAtom* aListName,
nsIFrame* aOldFrame)
{
nsIFrame* vscroll = nsnull;
if (mInner->mVScrollbarBox)
mInner->mVScrollbarBox->GetFrame(&vscroll);
nsIFrame* hscroll = nsnull;
if (mInner->mHScrollbarBox)
mInner->mHScrollbarBox->GetFrame(&hscroll);
if (aOldFrame == vscroll) {
mInner->mVScrollbarBox = nsnull;
return nsBoxFrame::RemoveFrame(aPresContext, aPresShell, aListName, aOldFrame);
}
else if (aOldFrame == hscroll) {
mInner->mHScrollbarBox = nsnull;
return nsBoxFrame::RemoveFrame(aPresContext, aPresShell, aListName, aOldFrame);
}
else {
nsIFrame* frame;
mInner->mScrollAreaBox->GetFrame(&frame);
@ -544,6 +564,7 @@ nsGfxScrollFrame::RemoveFrame(nsIPresContext* aPresContext,
aListName,
aOldFrame);
}
}
NS_IMETHODIMP
@ -915,8 +936,10 @@ nsGfxScrollFrameInner::GetScrollableView(nsIPresContext* aPresContext)
PRBool
nsGfxScrollFrameInner::AddHorizontalScrollbar(nsBoxLayoutState& aState, nsRect& aScrollAreaSize, PRBool aOnTop)
{
if (!mHScrollbarBox)
return PR_TRUE;
#ifdef IBMBIDI
if (mHScrollbarBox) {
PRInt32 dir = GetIntegerAttribute(mHScrollbarBox, nsXULAtoms::dir, -1);
const nsStyleVisibility* vis;
mOuter->GetStyleData(eStyleStruct_Visibility, (const nsStyleStruct*&)vis);
@ -928,14 +951,17 @@ nsGfxScrollFrameInner::AddHorizontalScrollbar(nsBoxLayoutState& aState, nsRect&
(NS_STYLE_DIRECTION_LTR == vis->mDirection) ? 0 : 0x7FFFFFFF);
SetAttribute(mHScrollbarBox, nsXULAtoms::dir, vis->mDirection * mOnePixel);
}
}
#endif // IBMBIDI
return AddRemoveScrollbar(aState, aScrollAreaSize, aOnTop, PR_TRUE, PR_TRUE);
}
PRBool
nsGfxScrollFrameInner::AddVerticalScrollbar(nsBoxLayoutState& aState, nsRect& aScrollAreaSize, PRBool aOnRight)
{
if (!mVScrollbarBox)
return PR_TRUE;
return AddRemoveScrollbar(aState, aScrollAreaSize, aOnRight, PR_FALSE, PR_TRUE);
}
@ -1283,7 +1309,7 @@ nsGfxScrollFrameInner::Layout(nsBoxLayoutState& aState)
if (scrollBarRight)
vRect.x += clientRect.width - vSize.width;
if (mHasVerticalScrollbar) {
if (mHasVerticalScrollbar && mVScrollbarBox) {
SetAttribute(mVScrollbarBox, nsXULAtoms::maxpos, maxY);
SetAttribute(mVScrollbarBox, nsXULAtoms::pageincrement, nscoord(scrollAreaRect.height - fontHeight));
SetAttribute(mVScrollbarBox, nsXULAtoms::increment, fontHeight, PR_FALSE);
@ -1295,7 +1321,7 @@ nsGfxScrollFrameInner::Layout(nsBoxLayoutState& aState)
mVScrollbarBox->GetMinSize(aState, vMinSize);
}
if (mHasVerticalScrollbar && (vMinSize.width > vRect.width || vMinSize.height > vRect.height)) {
if (mHasVerticalScrollbar && mVScrollbarBox && (vMinSize.width > vRect.width || vMinSize.height > vRect.height)) {
if (RemoveVerticalScrollbar(aState, scrollAreaRect, scrollBarRight)) {
needsLayout = PR_TRUE;
SetAttribute(mVScrollbarBox, nsXULAtoms::curpos, 0);
@ -1322,7 +1348,7 @@ nsGfxScrollFrameInner::Layout(nsBoxLayoutState& aState)
if (scrollBarBottom)
hRect.y += clientRect.height - hSize.height;
if (mHasHorizontalScrollbar) {
if (mHasHorizontalScrollbar && mHScrollbarBox) {
SetAttribute(mHScrollbarBox, nsXULAtoms::maxpos, maxX);
SetAttribute(mHScrollbarBox, nsXULAtoms::pageincrement, nscoord(float(scrollAreaRect.width)*0.8));
SetAttribute(mHScrollbarBox, nsXULAtoms::increment, 10*mOnePixel, PR_FALSE);
@ -1333,7 +1359,7 @@ nsGfxScrollFrameInner::Layout(nsBoxLayoutState& aState)
mHScrollbarBox->GetMinSize(aState, hMinSize);
}
if (mHasHorizontalScrollbar && (hMinSize.width > hRect.width || hMinSize.height > hRect.height)) {
if (mHasHorizontalScrollbar && mHScrollbarBox && (hMinSize.width > hRect.width || hMinSize.height > hRect.height)) {
if (RemoveHorizontalScrollbar(aState, scrollAreaRect, scrollBarBottom)) {
needsLayout = PR_TRUE;
SetAttribute(mHScrollbarBox, nsXULAtoms::curpos, 0);

Просмотреть файл

@ -34,6 +34,7 @@ REQUIRES = xpcom \
content \
gfx \
widget \
layout_xul \
locale \
view \
necko \

Просмотреть файл

@ -49,6 +49,7 @@ REQUIRES = xpcom \
java \
exthandler \
content \
layout_xul \
$(NULL)
include <$(DEPTH)\config\config.mak>

Просмотреть файл

@ -55,6 +55,7 @@
#include "nsIContent.h"
#include "nsINameSpaceManager.h"
#include "nsIXMLContent.h"
#include "nsIXBLBinding.h"
#include "nsIDocument.h"
#include "nsIBindingManager.h"
#include "nsIScrollableFrame.h"
@ -1721,7 +1722,6 @@ FrameManager::ReResolveStyleContext(nsIPresContext* aPresContext,
NS_ADDREF(aParentContext);
NOISY_TRACE_FRAME("non-null parent context provided: using it and assuming already resolved",aFrame);
}
NS_ASSERTION(aParentContext, "Failed to resolve parent context");
// do primary context
nsIStyleContext* newContext = nsnull;
@ -1859,6 +1859,12 @@ FrameManager::ReResolveStyleContext(nsIPresContext* aPresContext,
aResultChange = aMinChange;
if (aMinChange < NS_STYLE_HINT_FRAMECHANGE) {
// There is no need to waste time crawling into a frame's children on a frame change.
// The act of reconstructing frames will force new style contexts to be resolved on all
// of this frame's descendants anyway, so we want to avoid wasting time processing
// style contexts that we're just going to throw away anyway. - dwh
// now do children
PRInt32 listIndex = 0;
nsIAtom* childList = nsnull;
@ -1913,6 +1919,7 @@ FrameManager::ReResolveStyleContext(nsIPresContext* aPresContext,
aFrame->GetAdditionalChildListName(listIndex++, &childList);
} while (childList);
// XXX need to do overflow frames???
}
NS_RELEASE(newContext);
NS_IF_RELEASE(localContent);

Просмотреть файл

@ -364,13 +364,17 @@ nsGfxScrollFrame::GetScrollbarSizes(nsIPresContext* aPresContext,
{
nsBoxLayoutState state(aPresContext);
if (mInner->mHScrollbarBox) {
nsSize hs;
mInner->mHScrollbarBox->GetPrefSize(state, hs);
*aHbarHeight = hs.height;
}
if (mInner->mVScrollbarBox) {
nsSize vs;
mInner->mVScrollbarBox->GetPrefSize(state, vs);
*aVbarWidth = vs.width;
}
return NS_OK;
}
@ -536,6 +540,22 @@ nsGfxScrollFrame::RemoveFrame(nsIPresContext* aPresContext,
nsIAtom* aListName,
nsIFrame* aOldFrame)
{
nsIFrame* vscroll = nsnull;
if (mInner->mVScrollbarBox)
mInner->mVScrollbarBox->GetFrame(&vscroll);
nsIFrame* hscroll = nsnull;
if (mInner->mHScrollbarBox)
mInner->mHScrollbarBox->GetFrame(&hscroll);
if (aOldFrame == vscroll) {
mInner->mVScrollbarBox = nsnull;
return nsBoxFrame::RemoveFrame(aPresContext, aPresShell, aListName, aOldFrame);
}
else if (aOldFrame == hscroll) {
mInner->mHScrollbarBox = nsnull;
return nsBoxFrame::RemoveFrame(aPresContext, aPresShell, aListName, aOldFrame);
}
else {
nsIFrame* frame;
mInner->mScrollAreaBox->GetFrame(&frame);
@ -544,6 +564,7 @@ nsGfxScrollFrame::RemoveFrame(nsIPresContext* aPresContext,
aListName,
aOldFrame);
}
}
NS_IMETHODIMP
@ -915,8 +936,10 @@ nsGfxScrollFrameInner::GetScrollableView(nsIPresContext* aPresContext)
PRBool
nsGfxScrollFrameInner::AddHorizontalScrollbar(nsBoxLayoutState& aState, nsRect& aScrollAreaSize, PRBool aOnTop)
{
if (!mHScrollbarBox)
return PR_TRUE;
#ifdef IBMBIDI
if (mHScrollbarBox) {
PRInt32 dir = GetIntegerAttribute(mHScrollbarBox, nsXULAtoms::dir, -1);
const nsStyleVisibility* vis;
mOuter->GetStyleData(eStyleStruct_Visibility, (const nsStyleStruct*&)vis);
@ -928,14 +951,17 @@ nsGfxScrollFrameInner::AddHorizontalScrollbar(nsBoxLayoutState& aState, nsRect&
(NS_STYLE_DIRECTION_LTR == vis->mDirection) ? 0 : 0x7FFFFFFF);
SetAttribute(mHScrollbarBox, nsXULAtoms::dir, vis->mDirection * mOnePixel);
}
}
#endif // IBMBIDI
return AddRemoveScrollbar(aState, aScrollAreaSize, aOnTop, PR_TRUE, PR_TRUE);
}
PRBool
nsGfxScrollFrameInner::AddVerticalScrollbar(nsBoxLayoutState& aState, nsRect& aScrollAreaSize, PRBool aOnRight)
{
if (!mVScrollbarBox)
return PR_TRUE;
return AddRemoveScrollbar(aState, aScrollAreaSize, aOnRight, PR_FALSE, PR_TRUE);
}
@ -1283,7 +1309,7 @@ nsGfxScrollFrameInner::Layout(nsBoxLayoutState& aState)
if (scrollBarRight)
vRect.x += clientRect.width - vSize.width;
if (mHasVerticalScrollbar) {
if (mHasVerticalScrollbar && mVScrollbarBox) {
SetAttribute(mVScrollbarBox, nsXULAtoms::maxpos, maxY);
SetAttribute(mVScrollbarBox, nsXULAtoms::pageincrement, nscoord(scrollAreaRect.height - fontHeight));
SetAttribute(mVScrollbarBox, nsXULAtoms::increment, fontHeight, PR_FALSE);
@ -1295,7 +1321,7 @@ nsGfxScrollFrameInner::Layout(nsBoxLayoutState& aState)
mVScrollbarBox->GetMinSize(aState, vMinSize);
}
if (mHasVerticalScrollbar && (vMinSize.width > vRect.width || vMinSize.height > vRect.height)) {
if (mHasVerticalScrollbar && mVScrollbarBox && (vMinSize.width > vRect.width || vMinSize.height > vRect.height)) {
if (RemoveVerticalScrollbar(aState, scrollAreaRect, scrollBarRight)) {
needsLayout = PR_TRUE;
SetAttribute(mVScrollbarBox, nsXULAtoms::curpos, 0);
@ -1322,7 +1348,7 @@ nsGfxScrollFrameInner::Layout(nsBoxLayoutState& aState)
if (scrollBarBottom)
hRect.y += clientRect.height - hSize.height;
if (mHasHorizontalScrollbar) {
if (mHasHorizontalScrollbar && mHScrollbarBox) {
SetAttribute(mHScrollbarBox, nsXULAtoms::maxpos, maxX);
SetAttribute(mHScrollbarBox, nsXULAtoms::pageincrement, nscoord(float(scrollAreaRect.width)*0.8));
SetAttribute(mHScrollbarBox, nsXULAtoms::increment, 10*mOnePixel, PR_FALSE);
@ -1333,7 +1359,7 @@ nsGfxScrollFrameInner::Layout(nsBoxLayoutState& aState)
mHScrollbarBox->GetMinSize(aState, hMinSize);
}
if (mHasHorizontalScrollbar && (hMinSize.width > hRect.width || hMinSize.height > hRect.height)) {
if (mHasHorizontalScrollbar && mHScrollbarBox && (hMinSize.width > hRect.width || hMinSize.height > hRect.height)) {
if (RemoveHorizontalScrollbar(aState, scrollAreaRect, scrollBarBottom)) {
needsLayout = PR_TRUE;
SetAttribute(mHScrollbarBox, nsXULAtoms::curpos, 0);

Просмотреть файл

@ -146,6 +146,17 @@
#include "nsIDOMHTMLImageElement.h"
#include "nsITimer.h"
// For style data reconstruction
#include "nsStyleChangeList.h"
#include "nsIStyleFrameConstruction.h"
#include "nsINameSpaceManager.h"
#include "nsIBindingManager.h"
#include "nsIMenuFrame.h"
#include "nsITreeFrame.h"
#include "nsIOutlinerBoxObject.h"
#include "nsIXBLBinding.h"
#include "nsPlaceholderFrame.h"
// Dummy layout request
#include "nsIChannel.h"
#include "nsILoadGroup.h"
@ -844,6 +855,7 @@ public:
NS_IMETHOD GetActiveAlternateStyleSheet(nsString& aSheetTitle);
NS_IMETHOD SelectAlternateStyleSheet(const nsString& aSheetTitle);
NS_IMETHOD ListAlternateStyleSheets(nsStringArray& aTitleList);
NS_IMETHOD ReconstructStyleData();
NS_IMETHOD SetPreferenceStyleRules(PRBool aForceReflow);
NS_IMETHOD EnablePrefStyleRules(PRBool aEnable, PRUint8 aPrefType=0xFF);
NS_IMETHOD ArePrefStyleRulesEnabled(PRBool& aEnabled);
@ -1891,7 +1903,7 @@ PresShell::SelectAlternateStyleSheet(const nsString& aSheetTitle)
}
}
}
ReconstructFrames();
ReconstructStyleData();
}
return NS_OK;
}
@ -2059,7 +2071,7 @@ PresShell::SetPreferenceStyleRules(PRBool aForceReflow)
// this is harsh, but without it the new colors don't appear on the current page
// Fortunately, it only happens when the prefs change, a rare event.
// XXX - determine why the normal PresContext::RemapStyleAndReflow doesn't cut it
ReconstructFrames();
ReconstructStyleData();
}
return result;
@ -5225,18 +5237,152 @@ PresShell::ReconstructFrames(void)
return rv;
}
static nsresult
FlushMiscWidgetInfo(nsStyleChangeList& aChangeList, nsIPresContext* aPresContext, nsIFrame* aFrame)
{
// Ok, get our binding information.
const nsStyleDisplay* oldDisplay;
aFrame->GetStyleData(eStyleStruct_Display, (const nsStyleStruct*&)oldDisplay);
if (!oldDisplay->mBinding.IsEmpty()) {
// We had a binding.
nsCOMPtr<nsIContent> content;
aFrame->GetContent(getter_AddRefs(content));
nsCOMPtr<nsIDocument> doc;
content->GetDocument(*getter_AddRefs(doc));
if (doc) {
nsCOMPtr<nsIBindingManager> bm;
doc->GetBindingManager(getter_AddRefs(bm));
nsCOMPtr<nsIXBLBinding> binding;
bm->GetBinding(content, getter_AddRefs(binding));
PRBool marked = PR_FALSE;
binding->MarkedForDeath(&marked);
if (marked) {
// Add in a change to process, thus ensuring this binding gets rebuilt.
aChangeList.AppendChange(aFrame, content, NS_STYLE_HINT_FRAMECHANGE);
return NS_OK;
}
}
}
nsCOMPtr<nsITreeFrame> treeFrame(do_QueryInterface(aFrame));
if (treeFrame) {
// Trees are problematic. Always flush them out on a skin switch.
nsCOMPtr<nsIContent> content;
aFrame->GetContent(getter_AddRefs(content));
aChangeList.AppendChange(aFrame, content, NS_STYLE_HINT_FRAMECHANGE);
return NS_OK;
}
// Outliners have a special style cache that needs to be flushed when
// the theme changes.
nsCOMPtr<nsIOutlinerBoxObject> outlinerBox(do_QueryInterface(aFrame));
if (outlinerBox)
outlinerBox->ClearStyleAndImageCaches();
nsCOMPtr<nsIMenuFrame> menuFrame(do_QueryInterface(aFrame));
if (menuFrame) {
menuFrame->UngenerateMenu(); // We deliberately don't re-resolve style on
menuFrame->OpenMenu(PR_FALSE); // a menu's popup sub-content, since doing so
// slows menus to a crawl. That means we have to
// special-case them on a skin switch, and ensure that
// the popup frames just get destroyed completely.
}
// Now walk our children.
PRInt32 listIndex = 0;
nsCOMPtr<nsIAtom> childList;
nsIFrame* child;
do {
child = nsnull;
aFrame->FirstChild(aPresContext, childList, &child);
while (child) {
nsFrameState state;
child->GetFrameState(&state);
if (NS_FRAME_OUT_OF_FLOW != (state & NS_FRAME_OUT_OF_FLOW)) {
// only do frames that are in flow
nsCOMPtr<nsIAtom> frameType;
child->GetFrameType(getter_AddRefs(frameType));
if (nsLayoutAtoms::placeholderFrame == frameType.get()) { // placeholder
// get out of flow frame and recurse there
nsIFrame* outOfFlowFrame = ((nsPlaceholderFrame*)child)->GetOutOfFlowFrame();
NS_ASSERTION(outOfFlowFrame, "no out-of-flow frame");
FlushMiscWidgetInfo(aChangeList, aPresContext, outOfFlowFrame);
}
else
FlushMiscWidgetInfo(aChangeList, aPresContext, child);
}
child->GetNextSibling(&child);
}
aFrame->GetAdditionalChildListName(listIndex++, getter_AddRefs(childList));
} while (childList);
return NS_OK;
}
NS_IMETHODIMP
PresShell::ReconstructStyleData()
{
nsIFrame* rootFrame;
GetRootFrame(&rootFrame);
if (!rootFrame)
return NS_OK;
nsCOMPtr<nsIStyleSet> set;
GetStyleSet(getter_AddRefs(set));
if (!set)
return NS_OK;
nsCOMPtr<nsIStyleFrameConstruction> cssFrameConstructor;
set->GetStyleFrameConstruction(getter_AddRefs(cssFrameConstructor));
if (!cssFrameConstructor)
return NS_OK;
nsCOMPtr<nsIFrameManager> frameManager;
GetFrameManager(getter_AddRefs(frameManager));
// Now handle some of our more problematic widgets (and also deal with
// skin XBL changing).
nsStyleChangeList changeList;
FlushMiscWidgetInfo(changeList, mPresContext, rootFrame);
cssFrameConstructor->ProcessRestyledFrames(changeList, mPresContext);
changeList.Clear();
// Clear all undisplayed content in the undisplayed content map.
// These cached style contexts will no longer be valid following
// a full rule tree reconstruct.
frameManager->ClearUndisplayedContentMap();
// Now do a complete re-resolve of our style tree.
set->BeginRuleTreeReconstruct();
PRInt32 frameChange = NS_STYLE_HINT_NONE;
frameManager->ComputeStyleChangeFor(mPresContext, rootFrame,
kNameSpaceID_Unknown, nsnull,
changeList, NS_STYLE_HINT_NONE, frameChange);
if (frameChange == NS_STYLE_HINT_RECONSTRUCT_ALL)
set->ReconstructDocElementHierarchy(mPresContext);
else
cssFrameConstructor->ProcessRestyledFrames(changeList, mPresContext);
set->EndRuleTreeReconstruct();
return NS_OK;
}
NS_IMETHODIMP
PresShell::StyleSheetAdded(nsIDocument *aDocument,
nsIStyleSheet* aStyleSheet)
{
return ReconstructFrames();
return ReconstructStyleData();
}
NS_IMETHODIMP
PresShell::StyleSheetRemoved(nsIDocument *aDocument,
nsIStyleSheet* aStyleSheet)
{
return ReconstructFrames();
return ReconstructStyleData();
}
NS_IMETHODIMP
@ -5290,7 +5436,7 @@ PresShell::StyleRuleAdded(nsIDocument *aDocument,
return rv;
}
// XXX For now reconstruct everything
return ReconstructFrames();
return ReconstructStyleData();
}
NS_IMETHODIMP
@ -5307,7 +5453,7 @@ PresShell::StyleRuleRemoved(nsIDocument *aDocument,
return rv;
}
// XXX For now reconstruct everything
return ReconstructFrames();
return ReconstructStyleData();
}
NS_IMETHODIMP
@ -5496,14 +5642,7 @@ NS_IMETHODIMP
PresShell::BidiStyleChangeReflow()
{
// Have the root frame's style context remap its style
nsIFrame* rootFrame;
mFrameManager->GetRootFrame(&rootFrame);
if (rootFrame) {
mStyleSet->ClearStyleData(mPresContext, nsnull, nsnull);
ReconstructFrames();
}
return NS_OK;
return ReconstructStyleData();
}
#endif // IBMBIDI
@ -5683,6 +5822,9 @@ PresShell::HandleEvent(nsIView *aView,
return HandleEventInternal(aEvent, aView, NS_EVENT_FLAG_INIT, aEventStatus);
#endif
// Check for a theme change up front, since the frame type is irrelevant
if (aEvent->message == NS_THEMECHANGED && mPresContext)
return mPresContext->ThemeChanged();
aView->GetClientData(clientData);
frame = (nsIFrame *)clientData;

Просмотреть файл

@ -96,6 +96,7 @@
#include "nsIBindingManager.h"
#include "nsIXBLBinding.h"
#include "nsIElementFactory.h"
#include "nsITheme.h"
#include "nsContentCID.h"
#include "nsIDocShell.h"
#include "nsFormControlHelper.h"
@ -7795,7 +7796,13 @@ FindPreviousSibling(nsIPresShell* aPresShell,
prevSibling->GetStyleData(eStyleStruct_Display,
(const nsStyleStruct*&)display);
if (display->IsFloating() || display->IsPositioned()) {
if (display->mDisplay == NS_STYLE_DISPLAY_POPUP) {
nsIFrame* placeholderFrame;
aPresShell->GetPlaceholderFrameFor(prevSibling, &placeholderFrame);
if (prevSibling)
prevSibling = placeholderFrame;
}
else if (display->IsFloating() || display->IsPositioned()) {
nsIFrame* placeholderFrame;
aPresShell->GetPlaceholderFrameFor(prevSibling, &placeholderFrame);
NS_ASSERTION(placeholderFrame, "no placeholder for out-of-flow frame");
@ -8510,6 +8517,9 @@ nsCSSFrameConstructor::ContentInserted(nsIPresContext* aPresContext,
nsXULTreeOuterGroupFrame* treeRowGroup;
tree->GetTreeBody(&treeRowGroup);
if (treeRowGroup) {
// Don't bother with the odd XBL case of anonymous content.
if (aIndexInContainer == -1)
return NS_OK;
// Get the primary frame for the parent of the child that's being added.
nsIFrame* innerFrame = GetFrameFor(shell, aPresContext, aContainer);
@ -10052,28 +10062,43 @@ nsCSSFrameConstructor::ContentStatesChanged(nsIPresContext* aPresContext,
NS_ASSERTION(shell, "couldn't get pres shell");
if (shell) {
nsIStyleSet* styleSet;
shell->GetStyleSet(&styleSet);
nsCOMPtr<nsIStyleSet> styleSet;
shell->GetStyleSet(getter_AddRefs(styleSet));
NS_ASSERTION(styleSet, "couldn't get style set");
if (styleSet) { // test if any style rules exist which are dependent on content state
nsIFrame* primaryFrame1 = nsnull;
nsIFrame* primaryFrame2 = nsnull;
if (aContent1 && (NS_OK == styleSet->HasStateDependentStyle(aPresContext, aContent1))) {
PRUint8 app1 = 0;
PRUint8 app2 = 0;
shell->GetPrimaryFrameFor(aContent1, &primaryFrame1);
if (primaryFrame1) {
const nsStyleDisplay* disp;
primaryFrame1->GetStyleData(eStyleStruct_Display, (const nsStyleStruct*&)disp);
app1 = disp->mAppearance;
}
else {
if (!app1 && (NS_OK != styleSet->HasStateDependentStyle(aPresContext, aContent1))) {
primaryFrame1 = nsnull;
aContent1 = nsnull;
}
if (aContent2 && (aContent2 != aContent1) &&
(NS_OK == styleSet->HasStateDependentStyle(aPresContext, aContent2))) {
if (aContent2 == aContent1)
aContent2 = nsnull;
else if (aContent2) {
shell->GetPrimaryFrameFor(aContent2, &primaryFrame2);
if (primaryFrame2) {
const nsStyleDisplay* disp2;
primaryFrame2->GetStyleData(eStyleStruct_Display, (const nsStyleStruct*&)disp2);
app2 = disp2->mAppearance;
}
else {
if (!app2 && (NS_OK != styleSet->HasStateDependentStyle(aPresContext, aContent2))) {
primaryFrame2 = nsnull;
aContent2 = nsnull;
}
NS_RELEASE(styleSet);
}
if (primaryFrame1 && primaryFrame2) { // detect if one is parent of other, skip child
nsIFrame* parent;
@ -10109,10 +10134,29 @@ nsCSSFrameConstructor::ContentStatesChanged(nsIPresContext* aPresContext,
kNameSpaceID_Unknown, nsnull,
changeList1, NS_STYLE_HINT_NONE, frameChange1);
if (app1) {
nsCOMPtr<nsITheme> theme;
aPresContext->GetTheme(getter_AddRefs(theme));
PRBool repaint = PR_FALSE;
if (theme)
theme->WidgetStateChanged(primaryFrame1, app1, nsnull, &repaint);
if (repaint)
ApplyRenderingChangeToTree(aPresContext, primaryFrame1, nsnull);
}
if ((frameChange1 != NS_STYLE_HINT_RECONSTRUCT_ALL) && (primaryFrame2)) {
frameManager->ComputeStyleChangeFor(aPresContext, primaryFrame2,
kNameSpaceID_Unknown, nsnull,
changeList2, NS_STYLE_HINT_NONE, frameChange2);
if (app2) {
nsCOMPtr<nsITheme> theme;
aPresContext->GetTheme(getter_AddRefs(theme));
PRBool repaint = PR_FALSE;
if (theme)
theme->WidgetStateChanged(primaryFrame1, app2, nsnull, &repaint);
if (repaint)
ApplyRenderingChangeToTree(aPresContext, primaryFrame2, nsnull);
}
}
if ((frameChange1 == NS_STYLE_HINT_RECONSTRUCT_ALL) ||
@ -10157,6 +10201,15 @@ nsCSSFrameConstructor::ContentStatesChanged(nsIPresContext* aPresContext,
frameManager->ComputeStyleChangeFor(aPresContext, primaryFrame2,
kNameSpaceID_Unknown, nsnull,
changeList, NS_STYLE_HINT_NONE, frameChange);
if (app2) {
nsCOMPtr<nsITheme> theme;
aPresContext->GetTheme(getter_AddRefs(theme));
PRBool repaint = PR_FALSE;
if (theme)
theme->WidgetStateChanged(primaryFrame2, app2, nsnull, &repaint);
if (repaint)
ApplyRenderingChangeToTree(aPresContext, primaryFrame2, nsnull);
}
switch (frameChange) { // max change needed for top level frames
case NS_STYLE_HINT_RECONSTRUCT_ALL:
@ -10392,6 +10445,23 @@ nsCSSFrameConstructor::AttributeChanged(nsIPresContext* aPresContext,
set->ClearStyleData(aPresContext, rule, styleContext);
}
// See if we have appearance information for a theme.
if (primaryFrame) {
const nsStyleDisplay* disp;
primaryFrame->GetStyleData(eStyleStruct_Display,
(nsStyleStruct*&)disp);
if (disp && disp->mAppearance) {
nsCOMPtr<nsITheme> theme;
aPresContext->GetTheme(getter_AddRefs(theme));
if (theme && theme->ThemeSupportsWidget(aPresContext, disp->mAppearance)) {
PRBool repaint = PR_FALSE;
theme->WidgetStateChanged(primaryFrame, disp->mAppearance, aAttribute, &repaint);
if (repaint)
ApplyRenderingChangeToTree(aPresContext, primaryFrame, nsnull);
}
}
}
// apply changes
if (primaryFrame && aHint == NS_STYLE_HINT_ATTRCHANGE)
result = primaryFrame->AttributeChanged(aPresContext, aContent, aNameSpaceID, aAttribute, aModType, aHint);

Просмотреть файл

@ -57,6 +57,9 @@
#include "imgIContainer.h"
#include "nsCSSRendering.h"
#include "nsIPrintContext.h"
#include "nsITheme.h"
#include "nsThemeConstants.h"
#include "nsIServiceManager.h"
#define BORDER_FULL 0 //entire side
#define BORDER_INSIDE 1 //inside half
@ -1594,6 +1597,16 @@ void nsCSSRendering::PaintBorder(nsIPresContext* aPresContext,
nsCompatibility compatMode;
aPresContext->GetCompatibilityMode(&compatMode);
// Check to see if we have an appearance defined. If so, we let the theme
// renderer draw the border.
const nsStyleDisplay* displayData;
aForFrame->GetStyleData(eStyleStruct_Display, ((const nsStyleStruct*&)displayData));
if (displayData->mAppearance) {
nsCOMPtr<nsITheme> theme;
aPresContext->GetTheme(getter_AddRefs(theme));
if (theme && theme->ThemeSupportsWidget(aPresContext, displayData->mAppearance))
return; // Let the theme handle it.
}
// Get our style context's color struct.
const nsStyleColor* ourColor = (const nsStyleColor*)aStyleContext->GetStyleData(eStyleStruct_Color);
@ -2419,6 +2432,20 @@ nsCSSRendering::PaintBackground(nsIPresContext* aPresContext,
return;
}
// Check to see if we have an appearance defined. If so, we let the theme
// renderer draw the background.
const nsStyleDisplay* displayData;
aForFrame->GetStyleData(eStyleStruct_Display, ((const nsStyleStruct*&)displayData));
if (displayData->mAppearance) {
nsCOMPtr<nsITheme> theme;
aPresContext->GetTheme(getter_AddRefs(theme));
if (theme && theme->ThemeSupportsWidget(aPresContext, displayData->mAppearance)) {
theme->DrawWidgetBackground(&aRenderingContext, aForFrame,
displayData->mAppearance, aBorderArea, aDirtyRect);
return;
}
}
// if there is no background image, try a color.
if (aColor.mBackgroundImage.IsEmpty()) {
// See if there's a background color specified. The background color

Просмотреть файл

@ -402,6 +402,7 @@ void nsCSSDisplay::List(FILE* out, PRInt32 aIndent) const
nsAutoString buffer;
mAppearance.AppendToString(buffer, eCSSProperty_appearance);
mDirection.AppendToString(buffer, eCSSProperty_direction);
mDisplay.AppendToString(buffer, eCSSProperty_display);
mBinding.AppendToString(buffer, eCSSProperty_binding);
@ -1554,6 +1555,7 @@ CSSDeclarationImpl::AppendValue(nsCSSProperty aProperty, const nsCSSValue& aValu
break;
// nsCSSDisplay
case eCSSProperty_appearance:
case eCSSProperty_float:
case eCSSProperty_clear:
case eCSSProperty_display:
@ -1565,6 +1567,7 @@ CSSDeclarationImpl::AppendValue(nsCSSProperty aProperty, const nsCSSValue& aValu
case eCSSProperty_overflow:
CSS_ENSURE(Display) {
switch (aProperty) {
case eCSSProperty_appearance: mDisplay->mAppearance = aValue; break;
case eCSSProperty_float: mDisplay->mFloat = aValue; break;
case eCSSProperty_clear: mDisplay->mClear = aValue; break;
case eCSSProperty_display: mDisplay->mDisplay = aValue; break;
@ -2326,6 +2329,7 @@ CSSDeclarationImpl::SetValueImportant(nsCSSProperty aProperty)
break;
// nsCSSDisplay
case eCSSProperty_appearance:
case eCSSProperty_direction:
case eCSSProperty_display:
case eCSSProperty_binding:
@ -2338,6 +2342,7 @@ CSSDeclarationImpl::SetValueImportant(nsCSSProperty aProperty)
if (nsnull != mDisplay) {
CSS_ENSURE_IMPORTANT(Display) {
switch (aProperty) {
CSS_CASE_IMPORTANT(eCSSProperty_appearance, mDisplay->mAppearance);
CSS_CASE_IMPORTANT(eCSSProperty_direction, mDisplay->mDirection);
CSS_CASE_IMPORTANT(eCSSProperty_display, mDisplay->mDisplay);
CSS_CASE_IMPORTANT(eCSSProperty_binding, mDisplay->mBinding);
@ -3204,6 +3209,7 @@ CSSDeclarationImpl::RemoveProperty(nsCSSProperty aProperty)
break;
// nsCSSDisplay
case eCSSProperty_appearance:
case eCSSProperty_float:
case eCSSProperty_clear:
case eCSSProperty_display:
@ -3215,6 +3221,7 @@ CSSDeclarationImpl::RemoveProperty(nsCSSProperty aProperty)
case eCSSProperty_overflow:
CSS_CHECK(Display) {
switch (aProperty) {
case eCSSProperty_appearance: mDisplay->mAppearance.Reset(); break;
case eCSSProperty_float: mDisplay->mFloat.Reset(); break;
case eCSSProperty_clear: mDisplay->mClear.Reset(); break;
case eCSSProperty_display: mDisplay->mDisplay.Reset(); break;
@ -3995,6 +4002,7 @@ CSSDeclarationImpl::GetValue(nsCSSProperty aProperty, nsCSSValue& aValue)
break;
// nsCSSDisplay
case eCSSProperty_appearance:
case eCSSProperty_float:
case eCSSProperty_clear:
case eCSSProperty_display:
@ -4006,6 +4014,7 @@ CSSDeclarationImpl::GetValue(nsCSSProperty aProperty, nsCSSValue& aValue)
case eCSSProperty_overflow:
if (nsnull != mDisplay) {
switch (aProperty) {
case eCSSProperty_appearance: aValue = mDisplay->mAppearance; break;
case eCSSProperty_float: aValue = mDisplay->mFloat; break;
case eCSSProperty_clear: aValue = mDisplay->mClear; break;
case eCSSProperty_display: aValue = mDisplay->mDisplay; break;

Просмотреть файл

@ -408,6 +408,55 @@ CSS_KEY(x-small, x_small)
CSS_KEY(x-soft, x_soft)
CSS_KEY(xx-large, xx_large)
CSS_KEY(xx-small, xx_small)
// Appearance keywords for widget styles
CSS_KEY(theme, theme)
CSS_KEY(radio, radio)
CSS_KEY(checkbox, checkbox)
CSS_KEY(toolbox, toolbox)
CSS_KEY(toolbar, toolbar)
CSS_KEY(toolbarbutton, toolbarbutton)
CSS_KEY(toolbargripper, toolbargripper)
CSS_KEY(dualbutton, dualbutton)
CSS_KEY(dualbutton-dropdown, dualbutton_dropdown)
CSS_KEY(separator, separator)
CSS_KEY(statusbar, statusbar)
CSS_KEY(statusbarpane, statusbar_pane)
CSS_KEY(resizerpane, resizer_pane)
CSS_KEY(resizer, resizer)
CSS_KEY(listbox, listbox)
CSS_KEY(listitem, listitem)
CSS_KEY(treeview, treeview)
CSS_KEY(treeitem, treeitem)
CSS_KEY(treetwisty, treetwisty)
CSS_KEY(treeline, treeline)
CSS_KEY(treeheader, treeheader)
CSS_KEY(treeheadercell, treeheadercell)
CSS_KEY(treeheadersortarrow, treeheadersortarrow)
CSS_KEY(progressbar, progressbar)
CSS_KEY(progresschunk, progresschunk)
CSS_KEY(tab, tab)
CSS_KEY(tabpanel, tabpanel)
CSS_KEY(tooltip, tooltip)
CSS_KEY(spinner, spinner)
CSS_KEY(spinner-upbutton, spinner_upbutton)
CSS_KEY(spinner-downbutton, spinner_downbutton)
CSS_KEY(scrollbarbutton, scrollbarbutton)
CSS_KEY(scrollbartrack, scrollbartrack)
CSS_KEY(scrollbartrackstart, scrollbartrackstart)
CSS_KEY(scrollbartrackend, scrollbartrackend)
CSS_KEY(scrollbarthumb, scrollbarthumb)
CSS_KEY(scrollbargripper, scrollbargripper)
CSS_KEY(textfield, textfield)
CSS_KEY(caret, caret)
CSS_KEY(menulist, menulist)
CSS_KEY(menulistbutton, menulistbutton)
CSS_KEY(slider, slider)
CSS_KEY(sliderthumb, sliderthumb)
CSS_KEY(sliderthumbstart, sliderthumbstart)
CSS_KEY(sliderthumbend, sliderthumbend)
CSS_KEY(sliderthumbtick, sliderthumbtick)
#ifdef MOZ_SVG
CSS_KEY(bevel, bevel)
CSS_KEY(butt, butt)

Просмотреть файл

@ -67,6 +67,7 @@
#include "nsCSSAtoms.h"
#include "nsINameSpaceManager.h"
#include "nsINameSpace.h"
#include "nsThemeConstants.h"
// XXX TODO:
// - rework aErrorCode stuff: switch over to nsresult
@ -257,6 +258,7 @@ protected:
#endif
// Property specific parsing routines
PRBool ParseAppearance(PRInt32& aErrorCode, nsICSSDeclaration* aDeclaration, PRInt32& aChangeHint);
PRBool ParseAzimuth(PRInt32& aErrorCode, nsCSSValue& aValue);
PRBool ParseBackground(PRInt32& aErrorCode, nsICSSDeclaration* aDeclaration, PRInt32& aChangeHint);
PRBool ParseBackgroundPosition(PRInt32& aErrorCode, nsICSSDeclaration* aDeclaration, PRInt32& aChangeHint);
@ -3400,6 +3402,8 @@ PRBool CSSParserImpl::ParseProperty(PRInt32& aErrorCode,
PRInt32& aChangeHint)
{
switch (aPropID) { // handle shorthand or multiple properties
case eCSSProperty_appearance:
return ParseAppearance(aErrorCode, aDeclaration, aChangeHint);
case eCSSProperty_background:
return ParseBackground(aErrorCode, aDeclaration, aChangeHint);
case eCSSProperty_background_position:
@ -3616,6 +3620,8 @@ PRBool CSSParserImpl::ParseSingleValueProperty(PRInt32& aErrorCode,
case eCSSProperty_background_y_position:
return ParseVariant(aErrorCode, aValue, VARIANT_HKLP,
kBackgroundXYPositionKTable);
case eCSSProperty_appearance:
return ParseVariant(aErrorCode, aValue, VARIANT_HOK, nsCSSProps::kAppearanceKTable);
case eCSSProperty_binding:
return ParseVariant(aErrorCode, aValue, VARIANT_HUO, nsnull);
case eCSSProperty_border_collapse:
@ -3947,6 +3953,52 @@ PRBool CSSParserImpl::ParseAzimuth(PRInt32& aErrorCode, nsCSSValue& aValue)
return PR_FALSE;
}
static PRBool HasForegroundContent(PRUint8 aAppearance)
{
return ((aAppearance == NS_THEME_BUTTON) ||
(aAppearance == NS_THEME_TOOLBAR_BUTTON) ||
(aAppearance == NS_THEME_TOOLBAR_DUAL_BUTTON) ||
(aAppearance == NS_THEME_LISTBOX_LISTITEM) ||
(aAppearance == NS_THEME_TREEVIEW_TREEITEM) ||
(aAppearance == NS_THEME_TREEVIEW_HEADER_CELL) ||
(aAppearance == NS_THEME_TAB) ||
(aAppearance == NS_THEME_TOOLTIP) ||
(aAppearance == NS_THEME_TEXTFIELD));
}
PRBool CSSParserImpl::ParseAppearance(PRInt32& aErrorCode, nsICSSDeclaration* aDeclaration,
PRInt32& aChangeHint)
{
nsCSSValue appearance;
if (!ParseVariant(aErrorCode, appearance, VARIANT_HK, nsCSSProps::kAppearanceKTable))
return PR_FALSE;
if (ExpectEndProperty(aErrorCode, PR_TRUE))
aErrorCode = AppendValue(aDeclaration, eCSSProperty_appearance, appearance, aChangeHint);
else
return PR_FALSE;
if (appearance.GetIntValue() && HasForegroundContent(appearance.GetIntValue())) {
// When an appearance is specified, it can act as a shorthand that
// specifies color and font information as well.
// Add in font information.
PRInt32 index = SearchKeywordTable(eCSSKeyword_theme, nsCSSProps::kFontKTable);
if (index > 0) {
nsCSSValue val(nsCSSProps::kFontKTable[index], eCSSUnit_Enumerated);
AppendValue(aDeclaration, eCSSProperty_font_family, val, aChangeHint);
}
// Add in color information.
index = SearchKeywordTable(eCSSKeyword_theme, nsCSSProps::kColorKTable);
if (index > 0) {
nsCSSValue val(nsCSSProps::kColorKTable[index], eCSSUnit_Integer);
AppendValue(aDeclaration, eCSSProperty_color, val, aChangeHint);
}
}
return PR_TRUE;
}
PRBool CSSParserImpl::ParseBackground(PRInt32& aErrorCode, nsICSSDeclaration* aDeclaration,
PRInt32& aChangeHint)
{

Просмотреть файл

@ -76,6 +76,7 @@
// support them correctly the old constants need to be renamed and
// new ones should be entered.
CSS_PROP(-moz-appearance, appearance, REFLOW)
CSS_PROP(-moz-border-radius, _moz_border_radius, VISUAL)
CSS_PROP(-moz-border-radius-topleft, _moz_border_radius_topLeft, VISUAL)
CSS_PROP(-moz-border-radius-topright, _moz_border_radius_topRight, VISUAL)

Просмотреть файл

@ -39,6 +39,7 @@
#include "nsCSSProps.h"
#include "nsCSSKeywords.h"
#include "nsStyleConsts.h"
#include "nsThemeConstants.h" // For system widget appearance types
#include "nsILookAndFeel.h" // for system colors
@ -123,6 +124,58 @@ nsCSSProps::GetStringValue(nsCSSProperty aProperty)
/***************************************************************************/
const PRInt32 nsCSSProps::kAppearanceKTable[] = {
eCSSKeyword_none, NS_THEME_NONE,
eCSSKeyword_button, NS_THEME_BUTTON,
eCSSKeyword_radio, NS_THEME_RADIO,
eCSSKeyword_checkbox, NS_THEME_CHECKBOX,
eCSSKeyword_toolbox, NS_THEME_TOOLBOX,
eCSSKeyword_toolbar, NS_THEME_TOOLBAR,
eCSSKeyword_toolbarbutton, NS_THEME_TOOLBAR_BUTTON,
eCSSKeyword_toolbargripper, NS_THEME_TOOLBAR_GRIPPER,
eCSSKeyword_dualbutton, NS_THEME_TOOLBAR_DUAL_BUTTON,
eCSSKeyword_dualbutton_dropdown, NS_THEME_TOOLBAR_DUAL_BUTTON_DROPDOWN,
eCSSKeyword_separator, NS_THEME_TOOLBAR_SEPARATOR,
eCSSKeyword_statusbar, NS_THEME_STATUSBAR,
eCSSKeyword_statusbar_pane, NS_THEME_STATUSBAR_PANE,
eCSSKeyword_resizer_pane, NS_THEME_STATUSBAR_RESIZER_PANE,
eCSSKeyword_resizer, NS_THEME_RESIZER,
eCSSKeyword_listbox, NS_THEME_LISTBOX,
eCSSKeyword_listitem, NS_THEME_LISTBOX_LISTITEM,
eCSSKeyword_treeview, NS_THEME_TREEVIEW,
eCSSKeyword_treeitem, NS_THEME_TREEVIEW_TREEITEM,
eCSSKeyword_treetwisty, NS_THEME_TREEVIEW_TWISTY,
eCSSKeyword_treeline, NS_THEME_TREEVIEW_LINE,
eCSSKeyword_treeheader, NS_THEME_TREEVIEW_HEADER,
eCSSKeyword_treeheadercell, NS_THEME_TREEVIEW_HEADER_CELL,
eCSSKeyword_treeheadersortarrow, NS_THEME_TREEVIEW_HEADER_SORTARROW,
eCSSKeyword_progressbar, NS_THEME_PROGRESSBAR,
eCSSKeyword_progresschunk, NS_THEME_PROGRESSBAR_CHUNK,
eCSSKeyword_tab, NS_THEME_TAB,
eCSSKeyword_tabpanel, NS_THEME_TAB_PANEL,
eCSSKeyword_tooltip, NS_THEME_TOOLTIP,
eCSSKeyword_spinner, NS_THEME_SPINNER,
eCSSKeyword_spinner_upbutton, NS_THEME_SPINNER_UP_BUTTON,
eCSSKeyword_spinner_downbutton, NS_THEME_SPINNER_DOWN_BUTTON,
eCSSKeyword_scrollbar, NS_THEME_SCROLLBAR,
eCSSKeyword_scrollbarbutton, NS_THEME_SCROLLBAR_BUTTON,
eCSSKeyword_scrollbartrack, NS_THEME_SCROLLBAR_TRACK,
eCSSKeyword_scrollbartrackstart, NS_THEME_SCROLLBAR_TRACK_START,
eCSSKeyword_scrollbartrackend, NS_THEME_SCROLLBAR_TRACK_END,
eCSSKeyword_scrollbarthumb, NS_THEME_SCROLLBAR_THUMB,
eCSSKeyword_scrollbargripper, NS_THEME_SCROLLBAR_GRIPPER,
eCSSKeyword_textfield, NS_THEME_TEXTFIELD,
eCSSKeyword_caret, NS_THEME_TEXTFIELD_CARET,
eCSSKeyword_menulist, NS_THEME_DROPDOWN,
eCSSKeyword_menulistbutton, NS_THEME_DROPDOWN_BUTTON,
eCSSKeyword_slider, NS_THEME_SLIDER,
eCSSKeyword_sliderthumb, NS_THEME_SLIDER_THUMB,
eCSSKeyword_sliderthumbstart, NS_THEME_SLIDER_THUMB_START,
eCSSKeyword_sliderthumbend, NS_THEME_SLIDER_THUMB_END,
eCSSKeyword_sliderthumbtick, NS_THEME_SLIDER_TICK,
-1,-1
};
// Keyword id tables for variant/enum parsing
const PRInt32 nsCSSProps::kAzimuthKTable[] = {
eCSSKeyword_left_side, NS_STYLE_AZIMUTH_LEFT_SIDE,
@ -244,6 +297,7 @@ const PRInt32 nsCSSProps::kColorKTable[] = {
eCSSKeyword_window, nsILookAndFeel::eColor_window,
eCSSKeyword_windowframe, nsILookAndFeel::eColor_windowframe,
eCSSKeyword_windowtext, nsILookAndFeel::eColor_windowtext,
eCSSKeyword_theme, nsILookAndFeel::eColor_theme,
eCSSKeyword__moz_field, nsILookAndFeel::eColor__moz_field,
eCSSKeyword__moz_fieldtext, nsILookAndFeel::eColor__moz_fieldtext,
eCSSKeyword__moz_dialog, nsILookAndFeel::eColor__moz_dialog,
@ -387,6 +441,7 @@ const PRInt32 nsCSSProps::kFontKTable[] = {
eCSSKeyword_pull_down_menu, NS_STYLE_FONT_PULL_DOWN_MENU,
eCSSKeyword_list, NS_STYLE_FONT_LIST,
eCSSKeyword_field, NS_STYLE_FONT_FIELD,
eCSSKeyword_theme, NS_STYLE_FONT_THEME,
-1,-1
};

Просмотреть файл

@ -83,6 +83,7 @@ public:
static const PRInt32 kHintTable[];
// Keyword/Enum value tables
static const PRInt32 kAppearanceKTable[];
static const PRInt32 kAzimuthKTable[];
static const PRInt32 kBackgroundAttachmentKTable[];
static const PRInt32 kBackgroundColorKTable[];

Просмотреть файл

@ -402,6 +402,7 @@ void nsCSSDisplay::List(FILE* out, PRInt32 aIndent) const
nsAutoString buffer;
mAppearance.AppendToString(buffer, eCSSProperty_appearance);
mDirection.AppendToString(buffer, eCSSProperty_direction);
mDisplay.AppendToString(buffer, eCSSProperty_display);
mBinding.AppendToString(buffer, eCSSProperty_binding);
@ -1554,6 +1555,7 @@ CSSDeclarationImpl::AppendValue(nsCSSProperty aProperty, const nsCSSValue& aValu
break;
// nsCSSDisplay
case eCSSProperty_appearance:
case eCSSProperty_float:
case eCSSProperty_clear:
case eCSSProperty_display:
@ -1565,6 +1567,7 @@ CSSDeclarationImpl::AppendValue(nsCSSProperty aProperty, const nsCSSValue& aValu
case eCSSProperty_overflow:
CSS_ENSURE(Display) {
switch (aProperty) {
case eCSSProperty_appearance: mDisplay->mAppearance = aValue; break;
case eCSSProperty_float: mDisplay->mFloat = aValue; break;
case eCSSProperty_clear: mDisplay->mClear = aValue; break;
case eCSSProperty_display: mDisplay->mDisplay = aValue; break;
@ -2326,6 +2329,7 @@ CSSDeclarationImpl::SetValueImportant(nsCSSProperty aProperty)
break;
// nsCSSDisplay
case eCSSProperty_appearance:
case eCSSProperty_direction:
case eCSSProperty_display:
case eCSSProperty_binding:
@ -2338,6 +2342,7 @@ CSSDeclarationImpl::SetValueImportant(nsCSSProperty aProperty)
if (nsnull != mDisplay) {
CSS_ENSURE_IMPORTANT(Display) {
switch (aProperty) {
CSS_CASE_IMPORTANT(eCSSProperty_appearance, mDisplay->mAppearance);
CSS_CASE_IMPORTANT(eCSSProperty_direction, mDisplay->mDirection);
CSS_CASE_IMPORTANT(eCSSProperty_display, mDisplay->mDisplay);
CSS_CASE_IMPORTANT(eCSSProperty_binding, mDisplay->mBinding);
@ -3204,6 +3209,7 @@ CSSDeclarationImpl::RemoveProperty(nsCSSProperty aProperty)
break;
// nsCSSDisplay
case eCSSProperty_appearance:
case eCSSProperty_float:
case eCSSProperty_clear:
case eCSSProperty_display:
@ -3215,6 +3221,7 @@ CSSDeclarationImpl::RemoveProperty(nsCSSProperty aProperty)
case eCSSProperty_overflow:
CSS_CHECK(Display) {
switch (aProperty) {
case eCSSProperty_appearance: mDisplay->mAppearance.Reset(); break;
case eCSSProperty_float: mDisplay->mFloat.Reset(); break;
case eCSSProperty_clear: mDisplay->mClear.Reset(); break;
case eCSSProperty_display: mDisplay->mDisplay.Reset(); break;
@ -3995,6 +4002,7 @@ CSSDeclarationImpl::GetValue(nsCSSProperty aProperty, nsCSSValue& aValue)
break;
// nsCSSDisplay
case eCSSProperty_appearance:
case eCSSProperty_float:
case eCSSProperty_clear:
case eCSSProperty_display:
@ -4006,6 +4014,7 @@ CSSDeclarationImpl::GetValue(nsCSSProperty aProperty, nsCSSValue& aValue)
case eCSSProperty_overflow:
if (nsnull != mDisplay) {
switch (aProperty) {
case eCSSProperty_appearance: aValue = mDisplay->mAppearance; break;
case eCSSProperty_float: aValue = mDisplay->mFloat; break;
case eCSSProperty_clear: aValue = mDisplay->mClear; break;
case eCSSProperty_display: aValue = mDisplay->mDisplay; break;

Просмотреть файл

@ -2285,6 +2285,11 @@ MapDisplayForDeclaration(nsICSSDeclaration* aDecl, const nsStyleStructID& aID, n
return NS_OK; // We don't have any rules for display.
if (aID == eStyleStruct_Display) {
// appearance: enum, none, inherit
if (aDisplay.mAppearance.GetUnit() == eCSSUnit_Null &&
ourDisplay->mAppearance.GetUnit() != eCSSUnit_Null)
aDisplay.mAppearance = ourDisplay->mAppearance;
// display: enum, none, inherit
if (aDisplay.mDisplay.GetUnit() == eCSSUnit_Null && ourDisplay->mDisplay.GetUnit() != eCSSUnit_Null)
aDisplay.mDisplay = ourDisplay->mDisplay;

Просмотреть файл

@ -48,6 +48,8 @@
#include "nsIDocShellTreeItem.h"
#include "nsStyleUtil.h"
#include "nsCSSAtoms.h"
#include "nsThemeConstants.h"
#include "nsITheme.h"
// Temporary - Test of full time Standard mode for forms
#include "nsIPref.h"
@ -352,6 +354,8 @@ static PRBool SetColor(const nsCSSValue& aValue, const nscolor aParentColor,
nsILookAndFeel* look = nsnull;
if (NS_SUCCEEDED(aPresContext->GetLookAndFeel(&look)) && look) {
nsILookAndFeel::nsColorID colorID = (nsILookAndFeel::nsColorID)aValue.GetIntValue();
if (colorID == nsILookAndFeel::eColor_theme)
return PR_FALSE;
if (NS_SUCCEEDED(look->GetColor(colorID, aResult))) {
result = PR_TRUE;
}
@ -758,7 +762,8 @@ CheckFontCallback(const nsCSSStruct& aData)
(family == NS_STYLE_FONT_BUTTON) ||
(family == NS_STYLE_FONT_PULL_DOWN_MENU) ||
(family == NS_STYLE_FONT_LIST) ||
(family == NS_STYLE_FONT_FIELD))
(family == NS_STYLE_FONT_FIELD) ||
(family == NS_STYLE_FONT_THEME))
return nsRuleNode::eRuleFullMixed;
}
return nsRuleNode::eRuleUnknown;
@ -774,6 +779,7 @@ static const PropertyCheckData FontCheckProperties[] = {
};
static const PropertyCheckData DisplayCheckProperties[] = {
CHECKDATA_PROP(nsCSSDisplay, mAppearance, CHECKDATA_VALUE, PR_FALSE),
CHECKDATA_PROP(nsCSSDisplay, mClip, CHECKDATA_RECT, PR_FALSE),
CHECKDATA_PROP(nsCSSDisplay, mDisplay, CHECKDATA_VALUE, PR_FALSE),
CHECKDATA_PROP(nsCSSDisplay, mBinding, CHECKDATA_VALUE, PR_FALSE),
@ -1803,6 +1809,7 @@ SetFont(nsIPresContext* aPresContext, nsIStyleContext* aContext,
case NS_STYLE_FONT_PULL_DOWN_MENU:sysID = eSystemFont_PullDownMenu; break;
case NS_STYLE_FONT_LIST: sysID = eSystemFont_List; break;
case NS_STYLE_FONT_FIELD: sysID = eSystemFont_Field; break;
case NS_STYLE_FONT_THEME: sysID = eSystemFont_Theme; break;
}
nsCompatibility mode = eCompatibility_Standard;
@ -1826,7 +1833,24 @@ SetFont(nsIPresContext* aPresContext, nsIStyleContext* aContext,
if (dc) {
// GetSystemFont sets the font face but not necessarily the size
aFont->mFont.size = defaultVariableFont.size;
if (NS_FAILED(dc->GetSystemFont(sysID, &aFont->mFont))) {
// If our font type is theme, then check for appearance data and
// obtain our font based off our widget type.
if (sysID == eSystemFont_Theme) {
const nsStyleDisplay* display = (const nsStyleDisplay*)
aContext->GetStyleData(eStyleStruct_Display);
if (display->mAppearance) {
// Get our theme.
nsCOMPtr<nsITheme> theme;
aPresContext->GetTheme(getter_AddRefs(theme));
if (theme) {
nsCOMPtr<nsIDeviceContext> deviceContext;
aPresContext->GetDeviceContext(getter_AddRefs(deviceContext));
theme->GetWidgetFont(deviceContext, display->mAppearance, &aFont->mFont);
}
}
}
else if (NS_FAILED(dc->GetSystemFont(sysID, &aFont->mFont))) {
aFont->mFont.name = defaultVariableFont.name;
}
aFont->mSize = aFont->mFont.size; // this becomes our cascading size
@ -2697,6 +2721,18 @@ nsRuleNode::ComputeDisplayData(nsStyleStruct* aStartStruct, const nsCSSStruct& a
display->mDisplay = parentDisplay->mDisplay;
}
// appearance: enum, none, inherit
if (eCSSUnit_Enumerated == displayData.mAppearance.GetUnit()) {
display->mAppearance = displayData.mAppearance.GetIntValue();
}
else if (eCSSUnit_None == displayData.mAppearance.GetUnit()) {
display->mAppearance = NS_THEME_NONE;
}
else if (eCSSUnit_Inherit == displayData.mAppearance.GetUnit()) {
inherited = PR_TRUE;
display->mAppearance = parentDisplay->mAppearance;
}
// binding: url, none, inherit
if (eCSSUnit_URL == displayData.mBinding.GetUnit()) {
displayData.mBinding.GetStringValue(display->mBinding);
@ -3026,7 +3062,18 @@ nsRuleNode::ComputeColorData(nsStyleStruct* aStartStruct, const nsCSSStruct& aDa
parentColor = color;
// color: color, string, inherit
SetColor(colorData.mColor, parentColor->mColor, mPresContext, color->mColor, inherited);
if (!SetColor(colorData.mColor, parentColor->mColor, mPresContext, color->mColor,
inherited) && colorData.mColor.GetUnit() == eCSSUnit_Integer) {
// See if this is a special theme color. Theme colors must always be resolved
// dynamically at paint time.
nsCOMPtr<nsILookAndFeel> look;
mPresContext->GetLookAndFeel(getter_AddRefs(look));
if (look) {
nsILookAndFeel::nsColorID colorID = (nsILookAndFeel::nsColorID)colorData.mColor.GetIntValue();
if (colorID == nsILookAndFeel::eColor_theme)
color->mColorFlags = NS_COLORFLAGS_THEME;
}
}
if (inherited)
// We inherited, and therefore can't be cached in the rule node. We have to be put right on the

Просмотреть файл

@ -148,11 +148,31 @@ public:
NS_IMETHOD Shutdown();
// The following two methods can be used to tear down and reconstruct a rule tree. The idea
// is to first call BeginRuleTreeReconstruct, which will set aside the old rule
// tree. The entire frame tree should then have ReResolveStyleContext
// called on it. With the old rule tree hidden from view, the newly resolved style contexts will
// resolve to rule nodes in a fresh rule tree, and the re-resolve system will properly compute
// the visual impact of the changes.
//
// After re-resolution, call EndRuleTreeReconstruct() to finally discard the old rule tree.
// This trick can be used in lieu of a full frame reconstruction when drastic style changes
// happen (e.g., stylesheets being added/removed in the DOM, theme switching in the Mozilla app,
// etc.
virtual nsresult BeginRuleTreeReconstruct();
virtual nsresult EndRuleTreeReconstruct();
virtual nsresult GetRuleTree(nsRuleNode** aResult);
virtual nsresult ClearCachedDataInRuleTree(nsIStyleRule* aRule);
virtual nsresult ClearStyleData(nsIPresContext* aPresContext, nsIStyleRule* aRule, nsIStyleContext* aContext);
virtual nsresult GetStyleFrameConstruction(nsIStyleFrameConstruction** aResult) {
*aResult = mFrameConstructor;
NS_IF_ADDREF(*aResult);
return NS_OK;
}
virtual nsresult RemoveBodyFixupRule(nsIDocument *aDocument);
NS_IMETHOD ReParentStyleContext(nsIPresContext* aPresContext,
@ -318,6 +338,7 @@ protected:
nsRuleNode* mRuleTree; // This is the root of our rule tree. It is a lexicographic tree of
// matched rules that style contexts use to look up properties.
nsRuleNode* mOldRuleTree; // Used during rule tree reconstruction.
nsRuleWalker* mRuleWalker; // This is an instance of a rule walker that can be used
// to navigate through our tree.
@ -336,6 +357,7 @@ StyleSetImpl::StyleSetImpl()
: mFrameConstructor(nsnull),
mQuirkStyleSheet(nsnull),
mRuleTree(nsnull),
mOldRuleTree(nsnull),
mRuleWalker(nsnull)
#ifdef MOZ_PERF_METRICS
,mTimerEnabled(PR_FALSE)
@ -1224,6 +1246,26 @@ StyleSetImpl::GetRuleTree(nsRuleNode** aResult)
return NS_OK;
}
nsresult
StyleSetImpl::BeginRuleTreeReconstruct()
{
delete mRuleWalker;
mRuleWalker = nsnull;
mOldRuleTree = mRuleTree;
mRuleTree = nsnull;
return NS_OK;
}
nsresult
StyleSetImpl::EndRuleTreeReconstruct()
{
if (mOldRuleTree) {
mOldRuleTree->Destroy();
mOldRuleTree = nsnull;
}
return NS_OK;
}
nsresult
StyleSetImpl::ClearCachedDataInRuleTree(nsIStyleRule* aInlineStyleRule)
{

Просмотреть файл

@ -914,6 +914,7 @@ PRInt32 nsStyleTableBorder::CalcDifference(const nsStyleTableBorder& aOther) con
//
nsStyleColor::nsStyleColor(nsIPresContext* aPresContext)
:mColorFlags(NS_COLORFLAGS_NONE)
{
aPresContext->GetDefaultColor(&mColor);
}
@ -921,6 +922,7 @@ nsStyleColor::nsStyleColor(nsIPresContext* aPresContext)
nsStyleColor::nsStyleColor(const nsStyleColor& aSource)
{
mColor = aSource.mColor;
mColorFlags = aSource.mColorFlags;
}
PRInt32 nsStyleColor::CalcDifference(const nsStyleColor& aOther) const
@ -975,6 +977,7 @@ PRInt32 nsStyleBackground::CalcDifference(const nsStyleBackground& aOther) const
nsStyleDisplay::nsStyleDisplay()
{
mAppearance = 0;
mDisplay = NS_STYLE_DISPLAY_INLINE;
mPosition = NS_STYLE_POSITION_NORMAL;
mFloats = NS_STYLE_FLOAT_NONE;
@ -988,6 +991,7 @@ nsStyleDisplay::nsStyleDisplay()
nsStyleDisplay::nsStyleDisplay(const nsStyleDisplay& aSource)
{
mAppearance = aSource.mAppearance;
mDisplay = aSource.mDisplay;
mBinding = aSource.mBinding;
mPosition = aSource.mPosition;
@ -1007,7 +1011,8 @@ PRInt32 nsStyleDisplay::CalcDifference(const nsStyleDisplay& aOther) const
if ((mDisplay == aOther.mDisplay) &&
(mFloats == aOther.mFloats) &&
(mOverflow == aOther.mOverflow)) {
(mOverflow == aOther.mOverflow) &&
(mAppearance == aOther.mAppearance)) {
if ((mBreakType == aOther.mBreakType) &&
(mBreakBefore == aOther.mBreakBefore) &&
(mBreakAfter == aOther.mBreakAfter) &&

Просмотреть файл

@ -157,6 +157,9 @@ struct nsStyleFont : public nsStyleStruct {
nsStyleFont(nsIPresContext* aPresContext);
};
#define NS_COLORFLAGS_NONE 0x00
#define NS_COLORFLAGS_THEME 0x01
struct nsStyleColor : public nsStyleStruct {
nsStyleColor(nsIPresContext* aPresContext);
nsStyleColor(const nsStyleColor& aOther);
@ -179,6 +182,8 @@ struct nsStyleColor : public nsStyleStruct {
// Don't add ANY members to this struct! We can achieve caching in the rule
// tree (rather than the style tree) by letting color stay by itself! -dwh
nscolor mColor; // [inherited]
PRPackedBool mColorFlags; // Used to indicate theme colors. Theme colors
// must be resolved dynamically.
};
struct nsStyleBackground : public nsStyleStruct {
@ -740,6 +745,7 @@ struct nsStyleDisplay : public nsStyleStruct {
PRInt32 CalcDifference(const nsStyleDisplay& aOther) const;
PRUint8 mDisplay; // [reset] see nsStyleConsts.h NS_STYLE_DISPLAY_*
PRUint8 mAppearance; // [reset]
nsString mBinding; // [reset] absolute url string
PRUint8 mPosition; // [reset] see nsStyleConsts.h
PRUint8 mFloats; // [reset] see nsStyleConsts.h NS_STYLE_FLOAT_*

Просмотреть файл

@ -80,6 +80,8 @@ public:
NS_IMETHOD MarkAsGenerated() = 0;
NS_IMETHOD UngenerateMenu() = 0;
NS_IMETHOD GetActiveChild(nsIDOMElement** aResult)=0;
NS_IMETHOD SetActiveChild(nsIDOMElement* aChild)=0;
};

Просмотреть файл

@ -55,7 +55,11 @@
#include "nsIDOMNamedNodeMap.h"
#include "nsIDOMAttr.h"
#include "nsIWidget.h"
#include "nsIRenderingContext.h"
#include "nsIDocument.h"
#include "nsIDeviceContext.h"
#include "nsITheme.h"
#include "nsIServiceManager.h"
//#define DEBUG_LAYOUT
@ -209,6 +213,9 @@ void Coelesced()
#endif
PRUint32 nsBox::gRefCnt = 0;
nsITheme* nsBox::gTheme = nsnull;
nsBox::nsBox(nsIPresShell* aShell):mMouseThrough(unset),
mNextChild(nsnull),
mParentBox(nsnull)
@ -216,6 +223,18 @@ nsBox::nsBox(nsIPresShell* aShell):mMouseThrough(unset),
{
//mX = 0;
//mY = 0;
gRefCnt++;
if (gRefCnt == 1)
nsServiceManager::GetService("@mozilla.org/chrome/chrome-native-theme;1",
NS_GET_IID(nsITheme),
(nsISupports**)&gTheme);
}
nsBox::~nsBox()
{
gRefCnt--;
if (gRefCnt == 0)
nsServiceManager::ReleaseService("@mozilla.org/chrome/chrome-native-theme;1", gTheme);
}
NS_IMETHODIMP
@ -625,6 +644,40 @@ nsBox::GetBorder(nsMargin& aMargin)
nsIFrame* frame = nsnull;
GetFrame(&frame);
aMargin.SizeTo(0,0,0,0);
const nsStyleDisplay* disp;
frame->GetStyleData(eStyleStruct_Display,
(const nsStyleStruct*&) disp);
if (disp->mAppearance && gTheme) {
// Go to the theme for the border.
nsSize size;
nsCOMPtr<nsIDocument> doc;
nsCOMPtr<nsIContent> content;
frame->GetContent(getter_AddRefs(content));
content->GetDocument(*getter_AddRefs(doc));
nsCOMPtr<nsIPresShell> shell;
if (doc) {
doc->GetShellAt(0, getter_AddRefs(shell));
nsCOMPtr<nsIPresContext> context;
shell->GetPresContext(getter_AddRefs(context));
if (gTheme->ThemeSupportsWidget(context, disp->mAppearance)) {
nsCOMPtr<nsIDeviceContext> dc;
context->GetDeviceContext(getter_AddRefs(dc));
nsMargin margin(0,0,0,0);
gTheme->GetWidgetPadding(dc, frame,
disp->mAppearance, &margin);
float p2t;
context->GetScaledPixelsToTwips(&p2t);
aMargin.top = NSIntPixelsToTwips(margin.top, p2t);
aMargin.right = NSIntPixelsToTwips(margin.right, p2t);
aMargin.bottom = NSIntPixelsToTwips(margin.bottom, p2t);
aMargin.left = NSIntPixelsToTwips(margin.left, p2t);
return NS_OK;
}
}
}
const nsStyleBorder* border;
nsresult rv = frame->GetStyleData(eStyleStruct_Border,
(const nsStyleStruct*&) border);
@ -632,7 +685,6 @@ nsBox::GetBorder(nsMargin& aMargin)
if (NS_FAILED(rv))
return rv;
aMargin.SizeTo(0,0,0,0);
border->GetBorder(aMargin);
return rv;
@ -1231,6 +1283,27 @@ nsIBox::AddCSSMinSize(nsBoxLayoutState& aState, nsIBox* aBox, nsSize& aSize)
nsIFrame* frame = nsnull;
aBox->GetFrame(&frame);
// See if a native theme wants to supply a minimum size.
const nsStyleDisplay* display;
frame->GetStyleData(eStyleStruct_Display,
(const nsStyleStruct*&) display);
if (display->mAppearance) {
nsCOMPtr<nsITheme> theme;
aState.GetPresContext()->GetTheme(getter_AddRefs(theme));
if (theme && theme->ThemeSupportsWidget(aState.GetPresContext(), display->mAppearance)) {
nsSize size;
const nsHTMLReflowState* reflowState = aState.GetReflowState();
if (reflowState) {
theme->GetMinimumWidgetSize(reflowState->rendContext, frame,
display->mAppearance, &size);
float p2t;
aState.GetPresContext()->GetScaledPixelsToTwips(&p2t);
aSize.width = NSIntPixelsToTwips(size.width, p2t);
aSize.height = NSIntPixelsToTwips(size.height, p2t);
}
}
}
// add in the css min, max, pref
const nsStylePosition* position;
frame->GetStyleData(eStyleStruct_Position,

Просмотреть файл

@ -40,6 +40,8 @@
#include "nsIBox.h"
class nsITheme;
class nsBox : public nsIBox {
public:
@ -102,6 +104,7 @@ public:
NS_IMETHOD GetIndexOf(nsIBox* aChild, PRInt32* aIndex);
nsBox(nsIPresShell* aShell);
virtual ~nsBox();
virtual nsresult SyncLayout(nsBoxLayoutState& aBoxLayoutState);
@ -145,6 +148,9 @@ protected:
virtual void GetBoxName(nsAutoString& aName);
static PRUint32 gRefCnt;
static nsITheme* gTheme;
enum eMouseThrough {
unset,
never,

Просмотреть файл

@ -1251,7 +1251,9 @@ nsBoxFrame::InsertFrames(nsIPresContext* aPresContext,
nsIBox* prevBox = GetBox(aPrevFrame);
if (prevBox == nsnull && aPrevFrame != nsnull) {
#ifdef DEBUG
printf("Warning prev sibling is not in our list!!!\n");
#endif
aPrevFrame = nsnull;
}

Просмотреть файл

@ -410,6 +410,7 @@ nsContainerBox::SetDebugOnChildList(nsBoxLayoutState& aState, nsIBox* aChild, PR
void
nsContainerBox::SanityCheck(nsFrameList& aFrameList)
{
#ifdef DEBUG
// make sure the length match
PRInt32 length = aFrameList.GetLength();
NS_ASSERTION(length == mChildCount,"nsBox::ERROR!! Box info list count does not match frame count!!");
@ -431,6 +432,7 @@ nsContainerBox::SanityCheck(nsFrameList& aFrameList)
child->GetNextSibling(&child);
count++;
}
#endif
}
void

Просмотреть файл

@ -91,6 +91,7 @@
#include "nsIDOMDocument.h"
#include "nsIEventQueueService.h"
#include "nsTransform2D.h"
#include "nsITheme.h"
#include "nsIServiceManager.h"
#include "nsIURI.h"
@ -286,7 +287,8 @@ nsImageBoxFrame::AttributeChanged(nsIPresContext* aPresContext,
return NS_OK;
}
nsImageBoxFrame::nsImageBoxFrame(nsIPresShell* aShell):nsLeafBoxFrame(aShell), mIntrinsicSize(0,0)
nsImageBoxFrame::nsImageBoxFrame(nsIPresShell* aShell):nsLeafBoxFrame(aShell), mIntrinsicSize(0,0),
mLoadFlags(nsIRequest::LOAD_NORMAL), mSuppressStyleCheck(PR_FALSE)
{
mSizeFrozen = PR_FALSE;
mHasImage = PR_FALSE;
@ -336,7 +338,9 @@ nsImageBoxFrame::Init(nsIPresContext* aPresContext,
NS_RELEASE(listener);
}
mSuppressStyleCheck = PR_TRUE;
nsresult rv = nsLeafBoxFrame::Init(aPresContext, aContent, aParent, aContext, aPrevInFlow);
mSuppressStyleCheck = PR_FALSE;
GetImageSource();
UpdateLoadFlags();
@ -357,6 +361,14 @@ nsImageBoxFrame::GetImageSource()
if (mSrc.IsEmpty()) {
mUseSrcAttr = PR_FALSE;
// Only get the list-style-image if we aren't being drawn
// by a native theme.
const nsStyleDisplay* disp =
(const nsStyleDisplay*)mStyleContext->GetStyleData(eStyleStruct_Display);
if (disp->mAppearance && nsBox::gTheme &&
nsBox::gTheme->ThemeSupportsWidget(nsnull, disp->mAppearance))
return;
// get the list-style-image
const nsStyleList* myList =
(const nsStyleList*)mStyleContext->GetStyleData(eStyleStruct_List);
@ -543,7 +555,7 @@ nsImageBoxFrame::DidSetStyleContext( nsIPresContext* aPresContext )
(const nsStyleList*)mStyleContext->GetStyleData(eStyleStruct_List);
mSubRect = myList->mImageRegion;
if (mUseSrcAttr)
if (mUseSrcAttr || mSuppressStyleCheck)
return NS_OK; // No more work required, since the image isn't specified by style.
// If list-style-image changes, we have a new image.

Просмотреть файл

@ -155,7 +155,7 @@ private:
PRInt32 mLoadFlags;
nsSize mImageSize;
PRBool mSuppressStyleCheck;
}; // class nsImageBoxFrame
#endif /* nsImageBoxFrame_h___ */

Просмотреть файл

@ -327,8 +327,8 @@ nsMenuFrame::GetAdditionalChildListName(PRInt32 aIndex,
return NS_OK;
}
NS_IMETHODIMP
nsMenuFrame::Destroy(nsIPresContext* aPresContext)
nsresult
nsMenuFrame::DestroyPopupFrames(nsIPresContext* aPresContext)
{
// Remove our frame mappings
if (mFrameConstructor) {
@ -341,7 +341,13 @@ nsMenuFrame::Destroy(nsIPresContext* aPresContext)
// Cleanup frames in popup child list
mPopupFrames.DestroyFrames(aPresContext);
return NS_OK;
}
NS_IMETHODIMP
nsMenuFrame::Destroy(nsIPresContext* aPresContext)
{
DestroyPopupFrames(aPresContext);
return nsBoxFrame::Destroy(aPresContext);
}
@ -623,6 +629,22 @@ nsMenuFrame::MarkAsGenerated()
return NS_OK;
}
NS_IMETHODIMP
nsMenuFrame::UngenerateMenu()
{
nsCOMPtr<nsIContent> child;
GetMenuChildrenElement(getter_AddRefs(child));
if (child) {
nsAutoString genVal;
child->GetAttr(kNameSpaceID_None, nsXULAtoms::menugenerated, genVal);
if (!genVal.IsEmpty())
child->UnsetAttr(kNameSpaceID_None, nsXULAtoms::menugenerated, PR_TRUE);
}
return NS_OK;
}
NS_IMETHODIMP
nsMenuFrame::ActivateMenu(PRBool aActivateFlag)
{

Просмотреть файл

@ -148,6 +148,8 @@ public:
NS_IMETHOD GetActiveChild(nsIDOMElement** aResult);
NS_IMETHOD SetActiveChild(nsIDOMElement* aChild);
NS_IMETHOD UngenerateMenu();
NS_IMETHOD SelectFirstItem();
NS_IMETHOD Escape(PRBool& aHandledFlag);
@ -170,6 +172,8 @@ public:
// nsMenuFrame methods
nsresult DestroyPopupFrames(nsIPresContext* aPresContext);
PRBool IsOpen() { return mMenuOpen; };
PRBool IsMenu();
PRBool IsDisabled();

Просмотреть файл

@ -1076,6 +1076,9 @@ nsSliderFrame::RemoveListener()
NS_ASSERTION(mMediator, "No listener was ever added!!");
nsIFrame* thumbFrame = mFrames.FirstChild();
if (!thumbFrame)
return;
nsCOMPtr<nsIContent> content;
thumbFrame->GetContent(getter_AddRefs(content));

Просмотреть файл

@ -60,6 +60,7 @@
#include "nsIPref.h"
#include "nsXPIDLString.h"
#include "nsIServiceManager.h"
#include "nsITheme.h"
#include "nsUnicharUtils.h"
#ifdef IBMBIDI
@ -404,6 +405,32 @@ nsTextBoxFrame::PaintTitle(nsIPresContext* aPresContext,
CalculateUnderline(aRenderingContext);
const nsStyleColor* colorStyle = (const nsStyleColor*)mStyleContext->GetStyleData(eStyleStruct_Color);
PRBool useStyleColor = PR_TRUE;
if (colorStyle->mColorFlags & NS_COLORFLAGS_THEME) {
// Obtain the color dynamically from the theme if possible.
nsCOMPtr<nsITheme> theme;
aPresContext->GetTheme(getter_AddRefs(theme));
if (theme) {
// Find the nearest enclosing style context that defined an appearance.
nsIFrame* curr = this;
while (curr) {
const nsStyleDisplay* disp;
curr->GetStyleData(eStyleStruct_Display, (const nsStyleStruct*&)disp);
if (disp->mAppearance) {
nscolor color;
if (NS_SUCCEEDED(theme->GetWidgetColor(aPresContext, &aRenderingContext, curr,
disp->mAppearance, &color))) {
useStyleColor = PR_FALSE;
aRenderingContext.SetColor(color);
}
break;
}
curr->GetParent(&curr);
}
}
}
if (useStyleColor)
aRenderingContext.SetColor(colorStyle->mColor);
#ifdef IBMBIDI

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -157,6 +157,10 @@ interface nsIOutlinerBoxObject : nsISupports
void onDragOver ( in nsIDOMEvent event) ;
void onDragDrop ( in nsIDOMEvent event ) ;
/**
* Called on a theme switch to flush out the outliner's style and image caches.
*/
void clearStyleAndImageCaches();
};
%{C++

Просмотреть файл

@ -2562,6 +2562,13 @@ nsOutlinerBodyFrame::EnsureColumns()
}
}
NS_IMETHODIMP nsOutlinerBodyFrame::ClearStyleAndImageCaches()
{
mStyleCache.Clear();
mImageCache = nsnull;
mScrollbar = nsnull;
return NS_OK;
}
#ifdef XP_MAC
#pragma mark -

Просмотреть файл

@ -109,7 +109,9 @@ class nsOutlinerStyleCache
{
public:
nsOutlinerStyleCache() :mTransitionTable(nsnull), mCache(nsnull), mNextState(0) {};
virtual ~nsOutlinerStyleCache() { delete mTransitionTable; delete mCache; };
virtual ~nsOutlinerStyleCache() { Clear(); };
void Clear() { delete mTransitionTable; mTransitionTable = nsnull; delete mCache; mCache = nsnull; mNextState = 0; };
nsresult GetStyleContext(nsICSSPseudoComparator* aComparator, nsIPresContext* aPresContext,
nsIContent* aContent,

Просмотреть файл

@ -403,7 +403,13 @@ NS_IMETHODIMP nsOutlinerBoxObject::OnDragDrop(nsIDOMEvent* inEvent)
return NS_OK;
}
NS_IMETHODIMP nsOutlinerBoxObject::ClearStyleAndImageCaches()
{
nsIOutlinerBoxObject* body = GetOutlinerBody();
if (body)
return body->ClearStyleAndImageCaches();
return NS_OK;
}
// Creation Routine ///////////////////////////////////////////////////////////////////////

Просмотреть файл

@ -157,6 +157,10 @@ interface nsIOutlinerBoxObject : nsISupports
void onDragOver ( in nsIDOMEvent event) ;
void onDragDrop ( in nsIDOMEvent event ) ;
/**
* Called on a theme switch to flush out the outliner's style and image caches.
*/
void clearStyleAndImageCaches();
};
%{C++

Просмотреть файл

@ -2562,6 +2562,13 @@ nsOutlinerBodyFrame::EnsureColumns()
}
}
NS_IMETHODIMP nsOutlinerBodyFrame::ClearStyleAndImageCaches()
{
mStyleCache.Clear();
mImageCache = nsnull;
mScrollbar = nsnull;
return NS_OK;
}
#ifdef XP_MAC
#pragma mark -

Просмотреть файл

@ -109,7 +109,9 @@ class nsOutlinerStyleCache
{
public:
nsOutlinerStyleCache() :mTransitionTable(nsnull), mCache(nsnull), mNextState(0) {};
virtual ~nsOutlinerStyleCache() { delete mTransitionTable; delete mCache; };
virtual ~nsOutlinerStyleCache() { Clear(); };
void Clear() { delete mTransitionTable; mTransitionTable = nsnull; delete mCache; mCache = nsnull; mNextState = 0; };
nsresult GetStyleContext(nsICSSPseudoComparator* aComparator, nsIPresContext* aPresContext,
nsIContent* aContent,

Просмотреть файл

@ -403,7 +403,13 @@ NS_IMETHODIMP nsOutlinerBoxObject::OnDragDrop(nsIDOMEvent* inEvent)
return NS_OK;
}
NS_IMETHODIMP nsOutlinerBoxObject::ClearStyleAndImageCaches()
{
nsIOutlinerBoxObject* body = GetOutlinerBody();
if (body)
return body->ClearStyleAndImageCaches();
return NS_OK;
}
// Creation Routine ///////////////////////////////////////////////////////////////////////

Просмотреть файл

@ -35,6 +35,7 @@ MODULE_NAME = nsChromeModule
REQUIRES = xpcom \
string \
rdf \
gfx \
necko \
content \
$(NULL)

Просмотреть файл

@ -1,49 +0,0 @@
#!gmake
#
# The contents of this file are subject to the Netscape Public
# License Version 1.1 (the "License"); you may not use this file
# except in compliance with the License. You may obtain a copy of
# the License at http://www.mozilla.org/NPL/
#
# Software distributed under the License is distributed on an "AS
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
# implied. See the License for the specific language governing
# rights and limitations under the License.
#
# The Original Code is mozilla.org code.
#
# The Initial Developer of the Original Code is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All
# Rights Reserved.
#
# Contributor(s):
DEPTH=..\..\..
MODULE=chrome
MODULE = chrome
LIBRARY_NAME = chrome
MODULE_NAME = nsChromeModule
REQUIRES = xpcom \
string \
rdf \
necko \
content \
$(NULL)
CPP_OBJS=\
.\$(OBJDIR)\nsChromeFactory.obj \
$(NULL)
LINCS = $(LINCS) -I..\src # for implementation headers
SUB_LIBRARIES= \
$(DIST)\lib\chrome_s.lib \
$(NULL)
LLIBS=\
$(DIST)\lib\xpcom.lib \
$(LIBNSPR)
include <$(DEPTH)\config\rules.mak>

Просмотреть файл

@ -47,7 +47,6 @@
#include "nsChromeProtocolHandler.h"
#include "nsChromeRegistry.h"
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsChromeRegistry, Init)
// The list of components we register
@ -63,7 +62,7 @@ static nsModuleComponentInfo components[] =
NS_CHROMEPROTOCOLHANDLER_CID,
NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "chrome",
nsChromeProtocolHandler::Create
},
}
};
NS_IMPL_NSGETMODULE(nsChromeModule, components);

Просмотреть файл

@ -1,2 +0,0 @@
nsIChromeRegistry.idl

Просмотреть файл

@ -105,6 +105,7 @@
#include "nsIDOMElement.h"
#include "nsIChromeEventHandler.h"
#include "nsIContent.h"
#include "nsIDOMWindowCollection.h"
#include "imgICache.h"
static char kChromePrefix[] = "chrome://";
@ -1106,41 +1107,62 @@ nsChromeRegistry::UpdateArc(nsIRDFDataSource *aDataSource, nsIRDFResource* aSour
// theme stuff
static void FlushSkinBindingsForWindow(nsIDOMWindowInternal* aWindow)
{
// Get the DOM document.
nsCOMPtr<nsIDOMDocument> domDocument;
aWindow->GetDocument(getter_AddRefs(domDocument));
if (!domDocument)
return;
nsCOMPtr<nsIDocument> document = do_QueryInterface(domDocument);
if (!document)
return;
// Annihilate all XBL bindings.
nsCOMPtr<nsIBindingManager> bindingManager;
document->GetBindingManager(getter_AddRefs(bindingManager));
bindingManager->FlushSkinBindings();
}
NS_IMETHODIMP nsChromeRegistry::RefreshSkins()
{
nsresult rv;
nsCOMPtr<nsIWindowMediator> windowMediator(do_GetService(kWindowMediatorCID));
if (!windowMediator)
return NS_OK;
rv = FlushCaches();
if (NS_FAILED(rv)) return rv;
// Get the window mediator
nsCOMPtr<nsIWindowMediator> windowMediator =
do_GetService(kWindowMediatorCID, &rv);
if (NS_SUCCEEDED(rv)) {
nsCOMPtr<nsISimpleEnumerator> windowEnumerator;
if (NS_SUCCEEDED(windowMediator->GetEnumerator(nsnull, getter_AddRefs(windowEnumerator)))) {
// Get each dom window
windowMediator->GetEnumerator(nsnull, getter_AddRefs(windowEnumerator));
PRBool more;
rv = windowEnumerator->HasMoreElements(&more);
if (NS_FAILED(rv)) return rv;
windowEnumerator->HasMoreElements(&more);
while (more) {
nsCOMPtr<nsISupports> protoWindow;
rv = windowEnumerator->GetNext(getter_AddRefs(protoWindow));
if (NS_SUCCEEDED(rv) && protoWindow) {
windowEnumerator->GetNext(getter_AddRefs(protoWindow));
if (protoWindow) {
nsCOMPtr<nsIDOMWindowInternal> domWindow = do_QueryInterface(protoWindow);
if (domWindow) {
rv = RefreshWindow(domWindow);
if (NS_FAILED(rv)) return rv;
}
}
rv = windowEnumerator->HasMoreElements(&more);
if (NS_FAILED(rv)) return rv;
}
if (domWindow)
FlushSkinBindingsForWindow(domWindow);
}
windowEnumerator->HasMoreElements(&more);
}
return rv;
FlushCaches();
windowMediator->GetEnumerator(nsnull, getter_AddRefs(windowEnumerator));
windowEnumerator->HasMoreElements(&more);
while (more) {
nsCOMPtr<nsISupports> protoWindow;
windowEnumerator->GetNext(getter_AddRefs(protoWindow));
if (protoWindow) {
nsCOMPtr<nsIDOMWindowInternal> domWindow = do_QueryInterface(protoWindow);
if (domWindow)
RefreshWindow(domWindow);
}
windowEnumerator->HasMoreElements(&more);
}
return NS_OK;
}
@ -1149,12 +1171,10 @@ nsresult nsChromeRegistry::FlushCaches()
nsresult rv;
// Flush the style sheet cache completely.
// XXX For now flush everything. need a better call that only flushes style sheets.
nsCOMPtr<nsIXULPrototypeCache> xulCache =
do_GetService("@mozilla.org/xul/xul-prototype-cache;1", &rv);
if (NS_SUCCEEDED(rv) && xulCache) {
xulCache->Flush();
}
if (NS_SUCCEEDED(rv) && xulCache)
xulCache->FlushSkinFiles();
// Flush the new imagelib image chrome cache.
nsCOMPtr<imgICache> imageCache(do_GetService("@mozilla.org/image/cache;1", &rv));
@ -1175,6 +1195,18 @@ static PRBool IsChromeURI(nsIURI* aURI)
NS_IMETHODIMP nsChromeRegistry::RefreshWindow(nsIDOMWindowInternal* aWindow)
{
// Deal with our subframes first.
nsCOMPtr<nsIDOMWindowCollection> frames;
aWindow->GetFrames(getter_AddRefs(frames));
PRUint32 length;
frames->GetLength(&length);
for (PRUint32 i = 0; i < length; i++) {
nsCOMPtr<nsIDOMWindow> childWin;
frames->Item(i, getter_AddRefs(childWin));
nsCOMPtr<nsIDOMWindowInternal> childInt(do_QueryInterface(childWin));
RefreshWindow(childInt);
}
nsresult rv;
// Get the DOM document.
nsCOMPtr<nsIDOMDocument> domDocument;
@ -1186,13 +1218,6 @@ NS_IMETHODIMP nsChromeRegistry::RefreshWindow(nsIDOMWindowInternal* aWindow)
if (!document)
return NS_OK;
// Annihilate all XBL bindings.
nsCOMPtr<nsIBindingManager> bindingManager;
document->GetBindingManager(getter_AddRefs(bindingManager));
bindingManager->FlushChromeBindings();
nsCOMPtr<nsIXULDocument> xulDoc = do_QueryInterface(domDocument);
if (xulDoc) {
// Deal with the agent sheets first.
PRInt32 shellCount = document->GetNumberOfShells();
for (PRInt32 k = 0; k < shellCount; k++) {
@ -1238,7 +1263,6 @@ NS_IMETHODIMP nsChromeRegistry::RefreshWindow(nsIDOMWindowInternal* aWindow)
styleSet->ReplaceAgentStyleSheets(newAgentSheets);
}
}
}
nsCOMPtr<nsIHTMLContentContainer> container = do_QueryInterface(document);
nsCOMPtr<nsICSSLoader> cssLoader;
@ -1246,10 +1270,6 @@ NS_IMETHODIMP nsChromeRegistry::RefreshWindow(nsIDOMWindowInternal* aWindow)
if (NS_FAILED(rv)) return rv;
// Build an array of nsIURIs of style sheets we need to load.
nsCOMPtr<nsISupportsArray> urls;
rv = NS_NewISupportsArray(getter_AddRefs(urls));
if (NS_FAILED(rv)) return rv;
nsCOMPtr<nsISupportsArray> oldSheets;
rv = NS_NewISupportsArray(getter_AddRefs(oldSheets));
if (NS_FAILED(rv)) return rv;
@ -1270,7 +1290,8 @@ NS_IMETHODIMP nsChromeRegistry::RefreshWindow(nsIDOMWindowInternal* aWindow)
document->GetNumberOfStyleSheets(&count);
// Iterate over the style sheets.
for (PRInt32 i = 0; i < count; i++) {
PRUint32 i;
for (i = 0; i < (PRUint32)count; i++) {
// Get the style sheet
nsCOMPtr<nsIStyleSheet> styleSheet;
document->GetStyleSheetAt(i, getter_AddRefs(styleSheet));
@ -1281,40 +1302,35 @@ NS_IMETHODIMP nsChromeRegistry::RefreshWindow(nsIDOMWindowInternal* aWindow)
nsCOMPtr<nsIStyleSheet> attr = do_QueryInterface(attrSheet);
nsCOMPtr<nsIStyleSheet> inl = do_QueryInterface(inlineSheet);
if ((attr.get() != styleSheet.get()) &&
(inl.get() != styleSheet.get())) {
// Get the URI and add it to our array.
(inl.get() != styleSheet.get()))
// Add this sheet to the list of old style sheets.
oldSheets->AppendElement(styleSheet);
}
// Iterate over our old sheets and kick off a sync load of the new
// sheet if and only if it's a chrome URL.
PRUint32 oldCount;
oldSheets->Count(&oldCount);
for (i = 0; i < oldCount; i++) {
nsCOMPtr<nsISupports> supp = getter_AddRefs(oldSheets->ElementAt(i));
nsCOMPtr<nsIStyleSheet> sheet(do_QueryInterface(supp));
nsCOMPtr<nsIURI> uri;
rv = styleSheet->GetURL(*getter_AddRefs(uri));
if (NS_FAILED(rv)) return rv;
rv = urls->AppendElement(uri) ? NS_OK : NS_ERROR_FAILURE;
rv = sheet->GetURL(*getter_AddRefs(uri));
if (NS_FAILED(rv)) return rv;
// Remove the sheet.
rv = oldSheets->AppendElement(styleSheet) ? NS_OK : NS_ERROR_FAILURE;
if (NS_FAILED(rv)) return rv;
}
}
// Iterate over the URL array and kick off an asynchronous load of the
// sheets for our doc.
PRUint32 urlCount;
rv = urls->Count(&urlCount);
if (NS_FAILED(rv)) return rv;
for (PRUint32 j = 0; j < urlCount; j++) {
nsCOMPtr<nsISupports> supports = getter_AddRefs(urls->ElementAt(j));
nsCOMPtr<nsIURL> url = do_QueryInterface(supports);
if (IsChromeURI(uri)) {
// Reload the sheet.
nsCOMPtr<nsICSSStyleSheet> newSheet;
rv = LoadStyleSheetWithURL(url, getter_AddRefs(newSheet));
if (NS_FAILED(rv)) return rv;
if (newSheet) {
rv = newSheets->AppendElement(newSheet) ? NS_OK : NS_ERROR_FAILURE;
if (NS_FAILED(rv)) return rv;
LoadStyleSheetWithURL(uri, getter_AddRefs(newSheet));
if (newSheet)
newSheets->AppendElement(newSheet);
}
else // Just use the same sheet.
newSheets->AppendElement(sheet);
}
// Now notify the document that multiple sheets have been added and removed.
rv = document->UpdateStyleSheets(oldSheets, newSheets);
if (NS_FAILED(rv)) return rv;
document->UpdateStyleSheets(oldSheets, newSheets);
}
return NS_OK;

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше