diff --git a/mozilla/layout/base/nsIPresShell.h b/mozilla/layout/base/nsIPresShell.h index 5a9f186f464..460d98a1e64 100644 --- a/mozilla/layout/base/nsIPresShell.h +++ b/mozilla/layout/base/nsIPresShell.h @@ -87,6 +87,11 @@ public: */ NS_IMETHOD ResizeReflow(nscoord aWidth, nscoord aHeight) = 0; + /** + * Reflow the frame model with a reflow reason of eReflowReason_StyleChange + */ + NS_IMETHOD StyleChangeReflow() = 0; + virtual nsIFrame* GetRootFrame() = 0; virtual nsIFrame* FindFrameWithContent(nsIContent* aContent) = 0; diff --git a/mozilla/layout/base/nsPresContext.cpp b/mozilla/layout/base/nsPresContext.cpp index b0f6c9c7005..b455c60009a 100644 --- a/mozilla/layout/base/nsPresContext.cpp +++ b/mozilla/layout/base/nsPresContext.cpp @@ -28,9 +28,26 @@ #include "nsIURL.h" #include "nsIURLGroup.h" #include "nsIDocument.h" +#include "nsIFrame.h" +#include "nsIStyleContext.h" +#ifdef _WIN32 +#include +#endif #define NOISY_IMAGES +static int +PrefChangedCallback(const char* aPrefName, void* instance_data) +{ + nsPresContext* presContext = (nsPresContext*)instance_data; + + NS_ASSERTION(nsnull != presContext, "bad instance data"); + if (nsnull != presContext) { + presContext->PreferenceChanged(aPrefName); + } + return 0; // PREF_OK +} + static NS_DEFINE_IID(kIPresContextIID, NS_IPRESCONTEXT_IID); nsPresContext::nsPresContext() @@ -60,8 +77,14 @@ nsPresContext::nsPresContext() mCompatibilityMode = eCompatibility_NavQuirks; mBaseURL = nsnull; +#ifdef _WIN32 + // XXX This needs to be elsewhere, e.g., part of nsIDeviceContext + mDefaultColor = ::GetSysColor(COLOR_WINDOWTEXT); + mDefaultBackgroundColor = ::GetSysColor(COLOR_WINDOW); +#else mDefaultColor = NS_RGB(0x00, 0x00, 0x00); mDefaultBackgroundColor = NS_RGB(0xFF, 0xFF, 0xFF); +#endif #ifdef DEBUG mInitialized = PR_FALSE; @@ -95,6 +118,9 @@ nsPresContext::~nsPresContext() NS_IF_RELEASE(mContainer); NS_IF_RELEASE(mEventManager); NS_IF_RELEASE(mDeviceContext); + // Unregister preference callbacks + mPrefs->UnregisterCallback("browser.", PrefChangedCallback, (void*)this); + mPrefs->UnregisterCallback("intl.font2.", PrefChangedCallback, (void*)this); NS_IF_RELEASE(mPrefs); NS_IF_RELEASE(mBaseURL); } @@ -118,6 +144,75 @@ nsPresContext::Release(void) NS_IMPL_QUERY_INTERFACE(nsPresContext, kIPresContextIID); +void +nsPresContext::GetUserPreferences() +{ + int32 prefInt; + char prefChar[512]; + int charSize = sizeof(prefChar); + + if (NS_OK == mPrefs->GetIntPref("browser.base_font_scaler", &prefInt)) { + mFontScaler = prefInt; + } + + // XXX these font prefs strings don't take font encoding into account + if (NS_OK == mPrefs->GetCharPref("intl.font2.win.prop_font", &(prefChar[0]), &charSize)) { + mDefaultFont.name = prefChar; + } + if (NS_OK == mPrefs->GetIntPref("intl.font2.win.prop_size", &prefInt)) { + mDefaultFont.size = NSIntPointsToTwips(prefInt); + } + if (NS_OK == mPrefs->GetCharPref("intl.font2.win.fixed_font", &(prefChar[0]), &charSize)) { + mDefaultFixedFont.name = prefChar; + } + if (NS_OK == mPrefs->GetIntPref("intl.font2.win.fixed_size", &prefInt)) { + mDefaultFixedFont.size = NSIntPointsToTwips(prefInt); + } + if (NS_OK == mPrefs->GetIntPref("nglayout.compatibility.mode", &prefInt)) { + mCompatibilityMode = (enum nsCompatibility)prefInt; // bad cast + } + + PRBool usePrefColors = PR_TRUE; +#ifdef _WIN32 + XP_Bool boolPref; + // XXX Is Windows the only platform that uses this? + if (NS_OK == mPrefs->GetBoolPref("browser.wfe.use_windows_colors", &boolPref)) { + usePrefColors = !PRBool(boolPref); + } +#endif + if (usePrefColors) { + uint32 colorPref; + if (NS_OK == mPrefs->GetColorPrefDWord("browser.foreground_color", &colorPref)) { + mDefaultColor = (nscolor)colorPref; + } + if (NS_OK == mPrefs->GetColorPrefDWord("browser.background_color", &colorPref)) { + mDefaultBackgroundColor = (nscolor)colorPref; + } + } +} + +void +nsPresContext::PreferenceChanged(const char* aPrefName) +{ + // Initialize our state from the user preferences + GetUserPreferences(); + + // Have the root frame's style context remap its style based on the + // user preferences + nsIFrame* rootFrame; + nsIStyleContext* rootStyleContext; + + rootFrame = mShell->GetRootFrame(); + if (nsnull != rootFrame) { + rootFrame->GetStyleContext(rootStyleContext); + rootStyleContext->RemapStyle(this); + NS_RELEASE(rootStyleContext); + + // Force a reflow of the root frame + mShell->StyleChangeReflow(); + } +} + nsresult nsPresContext::Init(nsIDeviceContext* aDeviceContext, nsIPref* aPrefs) { @@ -129,31 +224,13 @@ nsPresContext::Init(nsIDeviceContext* aDeviceContext, nsIPref* aPrefs) mPrefs = aPrefs; NS_IF_ADDREF(mPrefs); - if (nsnull != mPrefs) { // initialize pres context state from preferences - int32 prefInt; - char prefChar[512]; - int charSize = sizeof(prefChar); + if (nsnull != mPrefs) { + // Register callbacks so we're notified when the preferences change + mPrefs->RegisterCallback("browser.", PrefChangedCallback, (void*)this); + mPrefs->RegisterCallback("intl.font2.", PrefChangedCallback, (void*)this); - if (NS_OK == mPrefs->GetIntPref("browser.base_font_scaler", &prefInt)) { - mFontScaler = prefInt; - } - - // XXX these font prefs strings don't take font encoding into account - if (NS_OK == mPrefs->GetCharPref("intl.font2.win.prop_font", &(prefChar[0]), &charSize)) { - mDefaultFont.name = prefChar; - } - if (NS_OK == mPrefs->GetIntPref("intl.font2.win.prop_size", &prefInt)) { - mDefaultFont.size = NSIntPointsToTwips(prefInt); - } - if (NS_OK == mPrefs->GetCharPref("intl.font2.win.fixed_font", &(prefChar[0]), &charSize)) { - mDefaultFixedFont.name = prefChar; - } - if (NS_OK == mPrefs->GetIntPref("intl.font2.win.fixed_size", &prefInt)) { - mDefaultFixedFont.size = NSIntPointsToTwips(prefInt); - } - if (NS_OK == mPrefs->GetIntPref("nglayout.compatibility.mode", &prefInt)) { - mCompatibilityMode = (enum nsCompatibility)prefInt; // bad cast - } + // Initialize our state from the user preferences + GetUserPreferences(); } #ifdef DEBUG diff --git a/mozilla/layout/base/nsPresShell.cpp b/mozilla/layout/base/nsPresShell.cpp index b259e2d2d20..806e2ef8ce5 100644 --- a/mozilla/layout/base/nsPresShell.cpp +++ b/mozilla/layout/base/nsPresShell.cpp @@ -204,6 +204,7 @@ public: virtual void EndObservingDocument(); NS_IMETHOD InitialReflow(nscoord aWidth, nscoord aHeight); NS_IMETHOD ResizeReflow(nscoord aWidth, nscoord aHeight); + NS_IMETHOD StyleChangeReflow(); virtual nsIFrame* GetRootFrame(); virtual nsIFrame* FindFrameWithContent(nsIContent* aContent); virtual void AppendReflowCommand(nsIReflowCommand* aReflowCommand); @@ -585,6 +586,52 @@ PresShell::ResizeReflow(nscoord aWidth, nscoord aHeight) return NS_OK; //XXX this needs to be real. MMP } +NS_IMETHODIMP +PresShell::StyleChangeReflow() +{ + EnterReflowLock(); + + if (nsnull != mRootFrame) { + // Kick off a top-down reflow + NS_FRAME_LOG(NS_FRAME_TRACE_CALLS, + ("enter nsPresShell::StyleChangeReflow")); +#ifdef NS_DEBUG + if (nsIFrame::GetVerifyTreeEnable()) { + mRootFrame->VerifyTree(); + } +#endif + nsRect bounds; + mPresContext->GetVisibleArea(bounds); + nsSize maxSize(bounds.width, bounds.height); + nsHTMLReflowMetrics desiredSize(nsnull); + nsReflowStatus status; + nsIHTMLReflow* htmlReflow; + nsIRenderingContext* rcx = nsnull; + + CreateRenderingContext(mRootFrame, rcx); + + // XXX We should be using eReflowReason_StyleChange + nsHTMLReflowState reflowState(*mPresContext, mRootFrame, + eReflowReason_Resize, maxSize, rcx); + + if (NS_OK == mRootFrame->QueryInterface(kIHTMLReflowIID, (void**)&htmlReflow)) { + htmlReflow->Reflow(*mPresContext, desiredSize, reflowState, status); + mRootFrame->SizeTo(desiredSize.width, desiredSize.height); +#ifdef NS_DEBUG + if (nsIFrame::GetVerifyTreeEnable()) { + mRootFrame->VerifyTree(); + } +#endif + } + NS_IF_RELEASE(rcx); + NS_FRAME_LOG(NS_FRAME_TRACE_CALLS, ("exit nsPresShell::StyleChangeReflow")); + } + + ExitReflowLock(); + + return NS_OK; //XXX this needs to be real. MMP +} + nsIFrame* PresShell::GetRootFrame() { diff --git a/mozilla/layout/base/public/nsIFrameReflow.h b/mozilla/layout/base/public/nsIFrameReflow.h index 83cee5705f2..b7adb19c956 100644 --- a/mozilla/layout/base/public/nsIFrameReflow.h +++ b/mozilla/layout/base/public/nsIFrameReflow.h @@ -76,7 +76,9 @@ struct nsReflowMetrics { enum nsReflowReason { eReflowReason_Initial = 0, // initial reflow of a newly created frame eReflowReason_Incremental = 1, // an incremental change has occured. see the reflow command for details - eReflowReason_Resize = 2 // general request to determine a desired size + eReflowReason_Resize = 2, // general request to determine a desired size + eReflowReason_StyleChange = 3 // request to reflow because of a style change. Note: you must reflow + // all your child frames }; //---------------------------------------------------------------------- diff --git a/mozilla/layout/base/public/nsIPresShell.h b/mozilla/layout/base/public/nsIPresShell.h index 5a9f186f464..460d98a1e64 100644 --- a/mozilla/layout/base/public/nsIPresShell.h +++ b/mozilla/layout/base/public/nsIPresShell.h @@ -87,6 +87,11 @@ public: */ NS_IMETHOD ResizeReflow(nscoord aWidth, nscoord aHeight) = 0; + /** + * Reflow the frame model with a reflow reason of eReflowReason_StyleChange + */ + NS_IMETHOD StyleChangeReflow() = 0; + virtual nsIFrame* GetRootFrame() = 0; virtual nsIFrame* FindFrameWithContent(nsIContent* aContent) = 0; diff --git a/mozilla/layout/base/src/nsPresContext.cpp b/mozilla/layout/base/src/nsPresContext.cpp index b0f6c9c7005..b455c60009a 100644 --- a/mozilla/layout/base/src/nsPresContext.cpp +++ b/mozilla/layout/base/src/nsPresContext.cpp @@ -28,9 +28,26 @@ #include "nsIURL.h" #include "nsIURLGroup.h" #include "nsIDocument.h" +#include "nsIFrame.h" +#include "nsIStyleContext.h" +#ifdef _WIN32 +#include +#endif #define NOISY_IMAGES +static int +PrefChangedCallback(const char* aPrefName, void* instance_data) +{ + nsPresContext* presContext = (nsPresContext*)instance_data; + + NS_ASSERTION(nsnull != presContext, "bad instance data"); + if (nsnull != presContext) { + presContext->PreferenceChanged(aPrefName); + } + return 0; // PREF_OK +} + static NS_DEFINE_IID(kIPresContextIID, NS_IPRESCONTEXT_IID); nsPresContext::nsPresContext() @@ -60,8 +77,14 @@ nsPresContext::nsPresContext() mCompatibilityMode = eCompatibility_NavQuirks; mBaseURL = nsnull; +#ifdef _WIN32 + // XXX This needs to be elsewhere, e.g., part of nsIDeviceContext + mDefaultColor = ::GetSysColor(COLOR_WINDOWTEXT); + mDefaultBackgroundColor = ::GetSysColor(COLOR_WINDOW); +#else mDefaultColor = NS_RGB(0x00, 0x00, 0x00); mDefaultBackgroundColor = NS_RGB(0xFF, 0xFF, 0xFF); +#endif #ifdef DEBUG mInitialized = PR_FALSE; @@ -95,6 +118,9 @@ nsPresContext::~nsPresContext() NS_IF_RELEASE(mContainer); NS_IF_RELEASE(mEventManager); NS_IF_RELEASE(mDeviceContext); + // Unregister preference callbacks + mPrefs->UnregisterCallback("browser.", PrefChangedCallback, (void*)this); + mPrefs->UnregisterCallback("intl.font2.", PrefChangedCallback, (void*)this); NS_IF_RELEASE(mPrefs); NS_IF_RELEASE(mBaseURL); } @@ -118,6 +144,75 @@ nsPresContext::Release(void) NS_IMPL_QUERY_INTERFACE(nsPresContext, kIPresContextIID); +void +nsPresContext::GetUserPreferences() +{ + int32 prefInt; + char prefChar[512]; + int charSize = sizeof(prefChar); + + if (NS_OK == mPrefs->GetIntPref("browser.base_font_scaler", &prefInt)) { + mFontScaler = prefInt; + } + + // XXX these font prefs strings don't take font encoding into account + if (NS_OK == mPrefs->GetCharPref("intl.font2.win.prop_font", &(prefChar[0]), &charSize)) { + mDefaultFont.name = prefChar; + } + if (NS_OK == mPrefs->GetIntPref("intl.font2.win.prop_size", &prefInt)) { + mDefaultFont.size = NSIntPointsToTwips(prefInt); + } + if (NS_OK == mPrefs->GetCharPref("intl.font2.win.fixed_font", &(prefChar[0]), &charSize)) { + mDefaultFixedFont.name = prefChar; + } + if (NS_OK == mPrefs->GetIntPref("intl.font2.win.fixed_size", &prefInt)) { + mDefaultFixedFont.size = NSIntPointsToTwips(prefInt); + } + if (NS_OK == mPrefs->GetIntPref("nglayout.compatibility.mode", &prefInt)) { + mCompatibilityMode = (enum nsCompatibility)prefInt; // bad cast + } + + PRBool usePrefColors = PR_TRUE; +#ifdef _WIN32 + XP_Bool boolPref; + // XXX Is Windows the only platform that uses this? + if (NS_OK == mPrefs->GetBoolPref("browser.wfe.use_windows_colors", &boolPref)) { + usePrefColors = !PRBool(boolPref); + } +#endif + if (usePrefColors) { + uint32 colorPref; + if (NS_OK == mPrefs->GetColorPrefDWord("browser.foreground_color", &colorPref)) { + mDefaultColor = (nscolor)colorPref; + } + if (NS_OK == mPrefs->GetColorPrefDWord("browser.background_color", &colorPref)) { + mDefaultBackgroundColor = (nscolor)colorPref; + } + } +} + +void +nsPresContext::PreferenceChanged(const char* aPrefName) +{ + // Initialize our state from the user preferences + GetUserPreferences(); + + // Have the root frame's style context remap its style based on the + // user preferences + nsIFrame* rootFrame; + nsIStyleContext* rootStyleContext; + + rootFrame = mShell->GetRootFrame(); + if (nsnull != rootFrame) { + rootFrame->GetStyleContext(rootStyleContext); + rootStyleContext->RemapStyle(this); + NS_RELEASE(rootStyleContext); + + // Force a reflow of the root frame + mShell->StyleChangeReflow(); + } +} + nsresult nsPresContext::Init(nsIDeviceContext* aDeviceContext, nsIPref* aPrefs) { @@ -129,31 +224,13 @@ nsPresContext::Init(nsIDeviceContext* aDeviceContext, nsIPref* aPrefs) mPrefs = aPrefs; NS_IF_ADDREF(mPrefs); - if (nsnull != mPrefs) { // initialize pres context state from preferences - int32 prefInt; - char prefChar[512]; - int charSize = sizeof(prefChar); + if (nsnull != mPrefs) { + // Register callbacks so we're notified when the preferences change + mPrefs->RegisterCallback("browser.", PrefChangedCallback, (void*)this); + mPrefs->RegisterCallback("intl.font2.", PrefChangedCallback, (void*)this); - if (NS_OK == mPrefs->GetIntPref("browser.base_font_scaler", &prefInt)) { - mFontScaler = prefInt; - } - - // XXX these font prefs strings don't take font encoding into account - if (NS_OK == mPrefs->GetCharPref("intl.font2.win.prop_font", &(prefChar[0]), &charSize)) { - mDefaultFont.name = prefChar; - } - if (NS_OK == mPrefs->GetIntPref("intl.font2.win.prop_size", &prefInt)) { - mDefaultFont.size = NSIntPointsToTwips(prefInt); - } - if (NS_OK == mPrefs->GetCharPref("intl.font2.win.fixed_font", &(prefChar[0]), &charSize)) { - mDefaultFixedFont.name = prefChar; - } - if (NS_OK == mPrefs->GetIntPref("intl.font2.win.fixed_size", &prefInt)) { - mDefaultFixedFont.size = NSIntPointsToTwips(prefInt); - } - if (NS_OK == mPrefs->GetIntPref("nglayout.compatibility.mode", &prefInt)) { - mCompatibilityMode = (enum nsCompatibility)prefInt; // bad cast - } + // Initialize our state from the user preferences + GetUserPreferences(); } #ifdef DEBUG diff --git a/mozilla/layout/base/src/nsPresContext.h b/mozilla/layout/base/src/nsPresContext.h index 07cd9f79fe5..23a7c231946 100644 --- a/mozilla/layout/base/src/nsPresContext.h +++ b/mozilla/layout/base/src/nsPresContext.h @@ -101,6 +101,13 @@ protected: #ifdef DEBUG PRBool mInitialized; #endif + +protected: + void GetUserPreferences(); + +private: + friend PrefChangedCallback(const char*, void*); + void PreferenceChanged(const char* aPrefName); }; #endif /* nsPresContext_h___ */ diff --git a/mozilla/layout/html/base/src/nsPresShell.cpp b/mozilla/layout/html/base/src/nsPresShell.cpp index b259e2d2d20..806e2ef8ce5 100644 --- a/mozilla/layout/html/base/src/nsPresShell.cpp +++ b/mozilla/layout/html/base/src/nsPresShell.cpp @@ -204,6 +204,7 @@ public: virtual void EndObservingDocument(); NS_IMETHOD InitialReflow(nscoord aWidth, nscoord aHeight); NS_IMETHOD ResizeReflow(nscoord aWidth, nscoord aHeight); + NS_IMETHOD StyleChangeReflow(); virtual nsIFrame* GetRootFrame(); virtual nsIFrame* FindFrameWithContent(nsIContent* aContent); virtual void AppendReflowCommand(nsIReflowCommand* aReflowCommand); @@ -585,6 +586,52 @@ PresShell::ResizeReflow(nscoord aWidth, nscoord aHeight) return NS_OK; //XXX this needs to be real. MMP } +NS_IMETHODIMP +PresShell::StyleChangeReflow() +{ + EnterReflowLock(); + + if (nsnull != mRootFrame) { + // Kick off a top-down reflow + NS_FRAME_LOG(NS_FRAME_TRACE_CALLS, + ("enter nsPresShell::StyleChangeReflow")); +#ifdef NS_DEBUG + if (nsIFrame::GetVerifyTreeEnable()) { + mRootFrame->VerifyTree(); + } +#endif + nsRect bounds; + mPresContext->GetVisibleArea(bounds); + nsSize maxSize(bounds.width, bounds.height); + nsHTMLReflowMetrics desiredSize(nsnull); + nsReflowStatus status; + nsIHTMLReflow* htmlReflow; + nsIRenderingContext* rcx = nsnull; + + CreateRenderingContext(mRootFrame, rcx); + + // XXX We should be using eReflowReason_StyleChange + nsHTMLReflowState reflowState(*mPresContext, mRootFrame, + eReflowReason_Resize, maxSize, rcx); + + if (NS_OK == mRootFrame->QueryInterface(kIHTMLReflowIID, (void**)&htmlReflow)) { + htmlReflow->Reflow(*mPresContext, desiredSize, reflowState, status); + mRootFrame->SizeTo(desiredSize.width, desiredSize.height); +#ifdef NS_DEBUG + if (nsIFrame::GetVerifyTreeEnable()) { + mRootFrame->VerifyTree(); + } +#endif + } + NS_IF_RELEASE(rcx); + NS_FRAME_LOG(NS_FRAME_TRACE_CALLS, ("exit nsPresShell::StyleChangeReflow")); + } + + ExitReflowLock(); + + return NS_OK; //XXX this needs to be real. MMP +} + nsIFrame* PresShell::GetRootFrame() { diff --git a/mozilla/layout/html/document/src/ua.css b/mozilla/layout/html/document/src/ua.css index 617732cb6a3..940cd99a413 100644 --- a/mozilla/layout/html/document/src/ua.css +++ b/mozilla/layout/html/document/src/ua.css @@ -16,12 +16,12 @@ */ HTML { - background: none; + background: inherit; background-image: none; } BODY { - background: white; + background: inherit; cursor: default; display: block; line-height: normal; diff --git a/mozilla/layout/style/ua.css b/mozilla/layout/style/ua.css index 617732cb6a3..940cd99a413 100644 --- a/mozilla/layout/style/ua.css +++ b/mozilla/layout/style/ua.css @@ -16,12 +16,12 @@ */ HTML { - background: none; + background: inherit; background-image: none; } BODY { - background: white; + background: inherit; cursor: default; display: block; line-height: normal;