зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1169514 - Part 3: Use a shared preference style sheet across all pres contexts. r=jwatt
This commit is contained in:
Родитель
4c1cfc10bd
Коммит
426f0f8f78
|
@ -139,10 +139,10 @@ typedef struct CapturingContentInfo {
|
|||
mozilla::StaticRefPtr<nsIContent> mContent;
|
||||
} CapturingContentInfo;
|
||||
|
||||
// a7ef8bb3-d628-4965-80f3-a326e089fb7f
|
||||
// 7f0ae6b1-5fa1-4ba7-885e-a93e17d72cd2
|
||||
#define NS_IPRESSHELL_IID \
|
||||
{ 0xa7ef8bb3, 0xd628, 0x4965, \
|
||||
{ 0x80, 0xf3, 0xa3, 0x26, 0xe0, 0x89, 0xfb, 0x7f } }
|
||||
{ 0x7f0ae6b1, 0x5fa1, 0x4ba7, \
|
||||
{ 0x88, 0x5e, 0xa9, 0x3e, 0x17, 0xd7, 0x2c, 0xd2 } }
|
||||
|
||||
// debug VerifyReflow flags
|
||||
#define VERIFY_REFLOW_ON 0x01
|
||||
|
@ -355,15 +355,11 @@ public:
|
|||
void ReconstructStyleData() { ReconstructStyleDataExternal(); }
|
||||
#endif
|
||||
|
||||
/** 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
|
||||
* - aForceReflow argument is used to force a full reframe to make the rules show
|
||||
* (only used when the current page needs to reflect changed pref rules)
|
||||
*
|
||||
* - initially created for bugs 31816, 20760, 22963
|
||||
/**
|
||||
* Update the style set somehow to take into account changed prefs which
|
||||
* affect document styling.
|
||||
*/
|
||||
virtual nsresult SetPreferenceStyleRules(bool aForceReflow) = 0;
|
||||
virtual void UpdatePreferenceStyles() = 0;
|
||||
|
||||
/**
|
||||
* FrameSelection will return the Frame based selection API.
|
||||
|
|
|
@ -67,6 +67,7 @@
|
|||
#include "mozilla/Preferences.h"
|
||||
#include "gfxTextRun.h"
|
||||
#include "nsFontFaceUtils.h"
|
||||
#include "nsLayoutStylesheetCache.h"
|
||||
|
||||
#if defined(MOZ_WIDGET_GTK)
|
||||
#include "gfxPlatformGtk.h" // xxx - for UseFcFontList
|
||||
|
@ -929,6 +930,12 @@ nsPresContext::PreferenceChanged(const char* aPrefName)
|
|||
mPrefChangedTimer = do_CreateInstance("@mozilla.org/timer;1");
|
||||
if (!mPrefChangedTimer)
|
||||
return;
|
||||
// We will end up calling InvalidatePreferenceSheets one from each pres
|
||||
// context, but all it's doing is clearing its cached sheet pointers,
|
||||
// so it won't be wastefully recreating the sheet multiple times.
|
||||
// The first pres context that has its mPrefChangedTimer called will
|
||||
// be the one to cause the reconstruction of the pref style sheet.
|
||||
nsLayoutStylesheetCache::InvalidatePreferenceSheets();
|
||||
mPrefChangedTimer->InitWithFuncCallback(nsPresContext::PrefChangedUpdateTimerCallback, (void*)this, 0, nsITimer::TYPE_ONE_SHOT);
|
||||
}
|
||||
if (prefName.EqualsLiteral("nglayout.debug.paint_flashing") ||
|
||||
|
@ -953,7 +960,7 @@ nsPresContext::UpdateAfterPreferencesChanged()
|
|||
|
||||
// update the presShell: tell it to set the preference style rules up
|
||||
if (mShell) {
|
||||
mShell->SetPreferenceStyleRules(true);
|
||||
mShell->UpdatePreferenceStyles();
|
||||
}
|
||||
|
||||
InvalidatePaintedLayers();
|
||||
|
|
|
@ -179,6 +179,7 @@
|
|||
#include "mozilla/gfx/2D.h"
|
||||
#include "nsSubDocumentFrame.h"
|
||||
#include "nsQueryObject.h"
|
||||
#include "nsLayoutStylesheetCache.h"
|
||||
|
||||
#ifdef ANDROID
|
||||
#include "nsIDocShellTreeOwner.h"
|
||||
|
@ -207,10 +208,6 @@ nsIContent* nsIPresShell::gKeyDownTarget;
|
|||
nsClassHashtable<nsUint32HashKey, nsIPresShell::PointerCaptureInfo>* nsIPresShell::gPointerCaptureList;
|
||||
nsClassHashtable<nsUint32HashKey, nsIPresShell::PointerInfo>* nsIPresShell::gActivePointersIds;
|
||||
|
||||
// convert a color value to a string, in the CSS format #RRGGBB
|
||||
// * - initially created for bugs 31816, 20760, 22963
|
||||
static void ColorToString(nscolor aColor, nsAutoString &aString);
|
||||
|
||||
// RangePaintInfo is used to paint ranges to offscreen buffers
|
||||
struct RangePaintInfo {
|
||||
nsRefPtr<nsRange> mRange;
|
||||
|
@ -893,9 +890,8 @@ PresShell::Init(nsIDocument* aDocument,
|
|||
// frames.
|
||||
mPresContext->CompatibilityModeChanged();
|
||||
|
||||
// setup the preference style rules (no forced reflow), and do it
|
||||
// before creating any frames.
|
||||
SetPreferenceStyleRules(false);
|
||||
// Add the preference style sheet.
|
||||
UpdatePreferenceStyles();
|
||||
|
||||
if (TouchCaretPrefEnabled() && !AccessibleCaretEnabled()) {
|
||||
// Create touch caret handle
|
||||
|
@ -1188,7 +1184,7 @@ PresShell::Destroy()
|
|||
}
|
||||
|
||||
// release our pref style sheet, if we have one still
|
||||
ClearPreferenceStyleRules();
|
||||
RemovePreferenceStyles();
|
||||
|
||||
mIsDestroying = true;
|
||||
|
||||
|
@ -1323,280 +1319,60 @@ nsIPresShell::GetAuthorStyleDisabled() const
|
|||
return mStyleSet->GetAuthorStyleDisabled();
|
||||
}
|
||||
|
||||
nsresult
|
||||
PresShell::SetPreferenceStyleRules(bool aForceReflow)
|
||||
void
|
||||
PresShell::UpdatePreferenceStyles()
|
||||
{
|
||||
if (!mDocument) {
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
return;
|
||||
}
|
||||
|
||||
nsPIDOMWindow *window = mDocument->GetWindow();
|
||||
|
||||
// If the document doesn't have a window there's no need to notify
|
||||
// its presshell about changes to preferences since the document is
|
||||
// in a state where it doesn't matter any more (see
|
||||
// nsDocumentViewer::Close()).
|
||||
|
||||
if (!window) {
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
if (!mDocument->GetWindow()) {
|
||||
return;
|
||||
}
|
||||
|
||||
NS_PRECONDITION(mPresContext, "presContext cannot be null");
|
||||
if (mPresContext) {
|
||||
// first, make sure this is not a chrome shell
|
||||
if (nsContentUtils::IsInChromeDocshell(mDocument)) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_attinasi
|
||||
printf("Setting Preference Style Rules:\n");
|
||||
#endif
|
||||
// if here, we need to create rules for the prefs
|
||||
// - this includes the background-color, the text-color,
|
||||
// the link color, the visited link color and the link-underlining
|
||||
|
||||
// first clear any exising rules
|
||||
nsresult result = ClearPreferenceStyleRules();
|
||||
|
||||
// now the link rules (must come after the color rules, or links will not be correct color!)
|
||||
// XXX - when there is both an override and agent pref stylesheet this won't matter,
|
||||
// as the color rules will be overrides and the links rules will be agent
|
||||
if (NS_SUCCEEDED(result)) {
|
||||
result = SetPrefLinkRules();
|
||||
}
|
||||
if (NS_SUCCEEDED(result)) {
|
||||
result = SetPrefFocusRules();
|
||||
}
|
||||
#ifdef DEBUG_attinasi
|
||||
printf( "Preference Style Rules set: error=%ld\n", (long)result);
|
||||
#endif
|
||||
|
||||
// Note that this method never needs to force any calculation; the caller
|
||||
// will recalculate style if needed
|
||||
|
||||
return result;
|
||||
// Documents in chrome shells do not have any preference style rules applied.
|
||||
if (nsContentUtils::IsInChromeDocshell(mDocument)) {
|
||||
return;
|
||||
}
|
||||
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
// We need to pass in mPresContext so that if the nsLayoutStylesheetCache
|
||||
// needs to recreate the pref style sheet, it has somewhere to get the
|
||||
// pref styling information from. All pres contexts for
|
||||
// IsChromeOriginImage() == false will have the same pref styling information,
|
||||
// and similarly for IsChromeOriginImage() == true, so it doesn't really
|
||||
// matter which pres context we pass in when it does need to be recreated.
|
||||
// (See nsPresContext::GetDocumentColorPreferences for how whether we
|
||||
// are a chrome origin image affects some pref styling information.)
|
||||
nsRefPtr<CSSStyleSheet> newPrefSheet =
|
||||
mPresContext->IsChromeOriginImage() ?
|
||||
nsLayoutStylesheetCache::ChromePreferenceSheet(mPresContext) :
|
||||
nsLayoutStylesheetCache::ContentPreferenceSheet(mPresContext);
|
||||
|
||||
if (mPrefStyleSheet == newPrefSheet) {
|
||||
return;
|
||||
}
|
||||
|
||||
mStyleSet->BeginUpdate();
|
||||
|
||||
RemovePreferenceStyles();
|
||||
|
||||
mStyleSet->AppendStyleSheet(nsStyleSet::eUserSheet, newPrefSheet);
|
||||
mPrefStyleSheet = newPrefSheet;
|
||||
|
||||
mStyleSet->EndUpdate();
|
||||
}
|
||||
|
||||
nsresult PresShell::ClearPreferenceStyleRules(void)
|
||||
void
|
||||
PresShell::RemovePreferenceStyles()
|
||||
{
|
||||
nsresult result = NS_OK;
|
||||
if (mPrefStyleSheet) {
|
||||
NS_ASSERTION(mStyleSet, "null styleset entirely unexpected!");
|
||||
if (mStyleSet) {
|
||||
// remove the sheet from the styleset:
|
||||
// - note that we have to check for success by comparing the count before and after...
|
||||
#ifdef DEBUG
|
||||
int32_t numBefore = mStyleSet->SheetCount(nsStyleSet::eUserSheet);
|
||||
NS_ASSERTION(numBefore > 0, "no user stylesheets in styleset, but we have one!");
|
||||
#endif
|
||||
mStyleSet->RemoveStyleSheet(nsStyleSet::eUserSheet, mPrefStyleSheet);
|
||||
|
||||
#ifdef DEBUG_attinasi
|
||||
NS_ASSERTION((numBefore - 1) == mStyleSet->GetNumberOfUserStyleSheets(),
|
||||
"Pref stylesheet was not removed");
|
||||
printf("PrefStyleSheet removed\n");
|
||||
#endif
|
||||
// clear the sheet pointer: it is strictly historical now
|
||||
mPrefStyleSheet = nullptr;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
nsresult
|
||||
PresShell::CreatePreferenceStyleSheet()
|
||||
{
|
||||
NS_ASSERTION(!mPrefStyleSheet, "prefStyleSheet already exists");
|
||||
mPrefStyleSheet = new CSSStyleSheet(CORS_NONE, mozilla::net::RP_Default);
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
nsresult rv = NS_NewURI(getter_AddRefs(uri), "about:PreferenceStyleSheet", nullptr);
|
||||
if (NS_FAILED(rv)) {
|
||||
mStyleSet->RemoveStyleSheet(nsStyleSet::eUserSheet, mPrefStyleSheet);
|
||||
mPrefStyleSheet = nullptr;
|
||||
return rv;
|
||||
}
|
||||
NS_ASSERTION(uri, "null but no error");
|
||||
mPrefStyleSheet->SetURIs(uri, uri, uri);
|
||||
mPrefStyleSheet->SetComplete();
|
||||
uint32_t index;
|
||||
rv =
|
||||
mPrefStyleSheet->InsertRuleInternal(NS_LITERAL_STRING("@namespace svg url(http://www.w3.org/2000/svg);"),
|
||||
0, &index);
|
||||
if (NS_FAILED(rv)) {
|
||||
mPrefStyleSheet = nullptr;
|
||||
return rv;
|
||||
}
|
||||
rv =
|
||||
mPrefStyleSheet->InsertRuleInternal(NS_LITERAL_STRING("@namespace url(http://www.w3.org/1999/xhtml);"),
|
||||
0, &index);
|
||||
if (NS_FAILED(rv)) {
|
||||
mPrefStyleSheet = nullptr;
|
||||
return rv;
|
||||
}
|
||||
|
||||
mStyleSet->AppendStyleSheet(nsStyleSet::eUserSheet, mPrefStyleSheet);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// XXX We want these after the @namespace rules. Does order matter
|
||||
// for these rules, or can we call StyleRule::StyleRuleCount()
|
||||
// and just "append"?
|
||||
static uint32_t sInsertPrefSheetRulesAt = 2;
|
||||
|
||||
nsresult PresShell::SetPrefLinkRules(void)
|
||||
{
|
||||
NS_ASSERTION(mPresContext,"null prescontext not allowed");
|
||||
if (!mPresContext) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
if (!mPrefStyleSheet) {
|
||||
rv = CreatePreferenceStyleSheet();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
NS_ASSERTION(mPrefStyleSheet, "prefstylesheet should not be null");
|
||||
|
||||
// support default link colors:
|
||||
// this means the link colors need to be overridable,
|
||||
// which they are if we put them in the agent stylesheet,
|
||||
// though if using an override sheet this will cause authors grief still
|
||||
// In the agent stylesheet, they are !important when we are ignoring document colors
|
||||
|
||||
nscolor linkColor(mPresContext->DefaultLinkColor());
|
||||
nscolor activeColor(mPresContext->DefaultActiveLinkColor());
|
||||
nscolor visitedColor(mPresContext->DefaultVisitedLinkColor());
|
||||
|
||||
NS_NAMED_LITERAL_STRING(ruleClose, "}");
|
||||
uint32_t index = 0;
|
||||
nsAutoString strColor;
|
||||
|
||||
// insert a rule to color links: '*|*:link {color: #RRGGBB [!important];}'
|
||||
ColorToString(linkColor, strColor);
|
||||
rv = mPrefStyleSheet->
|
||||
InsertRuleInternal(NS_LITERAL_STRING("*|*:link{color:") +
|
||||
strColor + ruleClose,
|
||||
sInsertPrefSheetRulesAt, &index);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// - visited links: '*|*:visited {color: #RRGGBB [!important];}'
|
||||
ColorToString(visitedColor, strColor);
|
||||
rv = mPrefStyleSheet->
|
||||
InsertRuleInternal(NS_LITERAL_STRING("*|*:visited{color:") +
|
||||
strColor + ruleClose,
|
||||
sInsertPrefSheetRulesAt, &index);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// - active links: '*|*:-moz-any-link:active {color: #RRGGBB [!important];}'
|
||||
ColorToString(activeColor, strColor);
|
||||
rv = mPrefStyleSheet->
|
||||
InsertRuleInternal(NS_LITERAL_STRING("*|*:-moz-any-link:active{color:") +
|
||||
strColor + ruleClose,
|
||||
sInsertPrefSheetRulesAt, &index);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
bool underlineLinks =
|
||||
mPresContext->GetCachedBoolPref(kPresContext_UnderlineLinks);
|
||||
|
||||
if (underlineLinks) {
|
||||
// create a rule to make underlining happen
|
||||
// '*|*:-moz-any-link {text-decoration:[underline|none];}'
|
||||
// no need for important, we want these to be overridable
|
||||
// NOTE: these must go in the agent stylesheet or they cannot be
|
||||
// overridden by authors
|
||||
rv = mPrefStyleSheet->
|
||||
InsertRuleInternal(NS_LITERAL_STRING("*|*:-moz-any-link:not(svg|a){text-decoration:underline}"),
|
||||
sInsertPrefSheetRulesAt, &index);
|
||||
} else {
|
||||
rv = mPrefStyleSheet->
|
||||
InsertRuleInternal(NS_LITERAL_STRING("*|*:-moz-any-link{text-decoration:none}"),
|
||||
sInsertPrefSheetRulesAt, &index);
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult PresShell::SetPrefFocusRules(void)
|
||||
{
|
||||
NS_ASSERTION(mPresContext,"null prescontext not allowed");
|
||||
nsresult result = NS_OK;
|
||||
|
||||
if (!mPresContext)
|
||||
result = NS_ERROR_FAILURE;
|
||||
|
||||
if (NS_SUCCEEDED(result) && !mPrefStyleSheet)
|
||||
result = CreatePreferenceStyleSheet();
|
||||
|
||||
if (NS_SUCCEEDED(result)) {
|
||||
NS_ASSERTION(mPrefStyleSheet, "prefstylesheet should not be null");
|
||||
|
||||
if (mPresContext->GetUseFocusColors()) {
|
||||
nscolor focusBackground(mPresContext->FocusBackgroundColor());
|
||||
nscolor focusText(mPresContext->FocusTextColor());
|
||||
|
||||
// insert a rule to make focus the preferred color
|
||||
uint32_t index = 0;
|
||||
nsAutoString strRule, strColor;
|
||||
|
||||
///////////////////////////////////////////////////////////////
|
||||
// - focus: '*:focus
|
||||
ColorToString(focusText,strColor);
|
||||
strRule.AppendLiteral("*:focus,*:focus>font {color: ");
|
||||
strRule.Append(strColor);
|
||||
strRule.AppendLiteral(" !important; background-color: ");
|
||||
ColorToString(focusBackground,strColor);
|
||||
strRule.Append(strColor);
|
||||
strRule.AppendLiteral(" !important; } ");
|
||||
// insert the rules
|
||||
result = mPrefStyleSheet->
|
||||
InsertRuleInternal(strRule, sInsertPrefSheetRulesAt, &index);
|
||||
}
|
||||
uint8_t focusRingWidth = mPresContext->FocusRingWidth();
|
||||
bool focusRingOnAnything = mPresContext->GetFocusRingOnAnything();
|
||||
uint8_t focusRingStyle = mPresContext->GetFocusRingStyle();
|
||||
|
||||
if ((NS_SUCCEEDED(result) && focusRingWidth != 1 && focusRingWidth <= 4 ) || focusRingOnAnything) {
|
||||
uint32_t index = 0;
|
||||
nsAutoString strRule;
|
||||
if (!focusRingOnAnything)
|
||||
strRule.AppendLiteral("*|*:link:focus, *|*:visited"); // If we only want focus rings on the normal things like links
|
||||
strRule.AppendLiteral(":focus {outline: "); // For example 3px dotted WindowText (maximum 4)
|
||||
strRule.AppendInt(focusRingWidth);
|
||||
if (focusRingStyle == 0) // solid
|
||||
strRule.AppendLiteral("px solid -moz-mac-focusring !important; -moz-outline-radius: 3px; outline-offset: 1px; } ");
|
||||
else // dotted
|
||||
strRule.AppendLiteral("px dotted WindowText !important; } ");
|
||||
// insert the rules
|
||||
result = mPrefStyleSheet->
|
||||
InsertRuleInternal(strRule, sInsertPrefSheetRulesAt, &index);
|
||||
NS_ENSURE_SUCCESS(result, result);
|
||||
if (focusRingWidth != 1) {
|
||||
// If the focus ring width is different from the default, fix buttons with rings
|
||||
strRule.AssignLiteral("button::-moz-focus-inner, input[type=\"reset\"]::-moz-focus-inner,");
|
||||
strRule.AppendLiteral("input[type=\"button\"]::-moz-focus-inner, ");
|
||||
strRule.AppendLiteral("input[type=\"submit\"]::-moz-focus-inner { padding: 1px 2px 1px 2px; border: ");
|
||||
strRule.AppendInt(focusRingWidth);
|
||||
if (focusRingStyle == 0) // solid
|
||||
strRule.AppendLiteral("px solid transparent !important; } ");
|
||||
else
|
||||
strRule.AppendLiteral("px dotted transparent !important; } ");
|
||||
result = mPrefStyleSheet->
|
||||
InsertRuleInternal(strRule, sInsertPrefSheetRulesAt, &index);
|
||||
NS_ENSURE_SUCCESS(result, result);
|
||||
|
||||
strRule.AssignLiteral("button:focus::-moz-focus-inner, input[type=\"reset\"]:focus::-moz-focus-inner,");
|
||||
strRule.AppendLiteral("input[type=\"button\"]:focus::-moz-focus-inner, input[type=\"submit\"]:focus::-moz-focus-inner {");
|
||||
strRule.AppendLiteral("border-color: ButtonText !important; }");
|
||||
result = mPrefStyleSheet->
|
||||
InsertRuleInternal(strRule, sInsertPrefSheetRulesAt, &index);
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -10679,16 +10455,6 @@ void ReflowCountMgr::DisplayDiffsInTotals(const char * aStr)
|
|||
|
||||
#endif // MOZ_REFLOW_PERF
|
||||
|
||||
// make a color string like #RRGGBB
|
||||
void ColorToString(nscolor aColor, nsAutoString &aString)
|
||||
{
|
||||
char buf[8];
|
||||
|
||||
PR_snprintf(buf, sizeof(buf), "#%02x%02x%02x",
|
||||
NS_GET_R(aColor), NS_GET_G(aColor), NS_GET_B(aColor));
|
||||
CopyASCIItoUTF16(buf, aString);
|
||||
}
|
||||
|
||||
nsIFrame* nsIPresShell::GetAbsoluteContainingBlock(nsIFrame *aFrame)
|
||||
{
|
||||
return FrameConstructor()->GetAbsoluteContainingBlock(aFrame,
|
||||
|
|
|
@ -88,7 +88,7 @@ public:
|
|||
virtual void Destroy() override;
|
||||
virtual void MakeZombie() override;
|
||||
|
||||
virtual nsresult SetPreferenceStyleRules(bool aForceReflow) override;
|
||||
virtual void UpdatePreferenceStyles() override;
|
||||
|
||||
NS_IMETHOD GetSelection(SelectionType aType, nsISelection** aSelection) override;
|
||||
virtual mozilla::dom::Selection* GetCurrentSelection(SelectionType aType) override;
|
||||
|
@ -514,14 +514,7 @@ protected:
|
|||
|
||||
void RecordStyleSheetChange(nsIStyleSheet* aStyleSheet);
|
||||
|
||||
/**
|
||||
* methods that manage rules that are used to implement the associated preferences
|
||||
* - initially created for bugs 31816, 20760, 22963
|
||||
*/
|
||||
nsresult ClearPreferenceStyleRules(void);
|
||||
nsresult CreatePreferenceStyleSheet(void);
|
||||
nsresult SetPrefLinkRules(void);
|
||||
nsresult SetPrefFocusRules(void);
|
||||
void RemovePreferenceStyles();
|
||||
|
||||
// methods for painting a range to an offscreen buffer
|
||||
|
||||
|
|
|
@ -218,6 +218,32 @@ nsLayoutStylesheetCache::NoFramesSheet()
|
|||
return gStyleCache->mNoFramesSheet;
|
||||
}
|
||||
|
||||
/* static */ CSSStyleSheet*
|
||||
nsLayoutStylesheetCache::ChromePreferenceSheet(nsPresContext* aPresContext)
|
||||
{
|
||||
EnsureGlobal();
|
||||
|
||||
if (!gStyleCache->mChromePreferenceSheet) {
|
||||
gStyleCache->BuildPreferenceSheet(gStyleCache->mChromePreferenceSheet,
|
||||
aPresContext);
|
||||
}
|
||||
|
||||
return gStyleCache->mChromePreferenceSheet;
|
||||
}
|
||||
|
||||
/* static */ CSSStyleSheet*
|
||||
nsLayoutStylesheetCache::ContentPreferenceSheet(nsPresContext* aPresContext)
|
||||
{
|
||||
EnsureGlobal();
|
||||
|
||||
if (!gStyleCache->mContentPreferenceSheet) {
|
||||
gStyleCache->BuildPreferenceSheet(gStyleCache->mContentPreferenceSheet,
|
||||
aPresContext);
|
||||
}
|
||||
|
||||
return gStyleCache->mContentPreferenceSheet;
|
||||
}
|
||||
|
||||
void
|
||||
nsLayoutStylesheetCache::Shutdown()
|
||||
{
|
||||
|
@ -245,6 +271,8 @@ nsLayoutStylesheetCache::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf
|
|||
|
||||
#define MEASURE(s) n += s ? s->SizeOfIncludingThis(aMallocSizeOf) : 0;
|
||||
|
||||
MEASURE(mChromePreferenceSheet);
|
||||
MEASURE(mContentPreferenceSheet);
|
||||
MEASURE(mCounterStylesSheet);
|
||||
MEASURE(mFormsSheet);
|
||||
MEASURE(mFullScreenOverrideSheet);
|
||||
|
@ -460,6 +488,133 @@ nsLayoutStylesheetCache::DependentPrefChanged(const char* aPref, void* aData)
|
|||
InvalidateSheet(gStyleCache->mHTMLSheet);
|
||||
}
|
||||
|
||||
/* static */ void
|
||||
nsLayoutStylesheetCache::InvalidatePreferenceSheets()
|
||||
{
|
||||
if (!gStyleCache) {
|
||||
return;
|
||||
}
|
||||
|
||||
gStyleCache->mContentPreferenceSheet = nullptr;
|
||||
gStyleCache->mChromePreferenceSheet = nullptr;
|
||||
}
|
||||
|
||||
/* static */ void
|
||||
nsLayoutStylesheetCache::AppendPreferenceRule(CSSStyleSheet* aSheet,
|
||||
const nsAString& aString)
|
||||
{
|
||||
uint32_t result;
|
||||
aSheet->InsertRuleInternal(aString, aSheet->StyleRuleCount(), &result);
|
||||
}
|
||||
|
||||
/* static */ void
|
||||
nsLayoutStylesheetCache::AppendPreferenceColorRule(CSSStyleSheet* aSheet,
|
||||
const char* aString,
|
||||
nscolor aColor)
|
||||
{
|
||||
nsAutoString rule;
|
||||
rule.AppendPrintf(
|
||||
aString, NS_GET_R(aColor), NS_GET_G(aColor), NS_GET_B(aColor));
|
||||
AppendPreferenceRule(aSheet, rule);
|
||||
}
|
||||
|
||||
void
|
||||
nsLayoutStylesheetCache::BuildPreferenceSheet(nsRefPtr<CSSStyleSheet>& aSheet,
|
||||
nsPresContext* aPresContext)
|
||||
{
|
||||
aSheet = new CSSStyleSheet(CORS_NONE, mozilla::net::RP_Default);
|
||||
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
NS_NewURI(getter_AddRefs(uri), "about:PreferenceStyleSheet", nullptr);
|
||||
MOZ_ASSERT(uri, "URI creation shouldn't fail");
|
||||
|
||||
aSheet->SetURIs(uri, uri, uri);
|
||||
aSheet->SetComplete();
|
||||
|
||||
AppendPreferenceRule(aSheet,
|
||||
NS_LITERAL_STRING("@namespace url(http://www.w3.org/1999/xhtml);"));
|
||||
AppendPreferenceRule(aSheet,
|
||||
NS_LITERAL_STRING("@namespace svg url(http://www.w3.org/2000/svg);"));
|
||||
|
||||
// Rules for link styling.
|
||||
|
||||
AppendPreferenceColorRule(aSheet,
|
||||
"*|*:link { color: #%02x%02x%02x; }",
|
||||
aPresContext->DefaultLinkColor());
|
||||
AppendPreferenceColorRule(aSheet,
|
||||
"*|*:-moz-any-link:active { color: #%02x%02x%02x; }",
|
||||
aPresContext->DefaultActiveLinkColor());
|
||||
AppendPreferenceColorRule(aSheet,
|
||||
"*|*:visited { color: #%02x%02x%02x; }",
|
||||
aPresContext->DefaultVisitedLinkColor());
|
||||
|
||||
AppendPreferenceRule(aSheet,
|
||||
aPresContext->GetCachedBoolPref(kPresContext_UnderlineLinks) ?
|
||||
NS_LITERAL_STRING(
|
||||
"*|*:-moz-any-link:not(svg|a) { text-decoration: underline; }") :
|
||||
NS_LITERAL_STRING(
|
||||
"*|*:-moz-any-link{ text-decoration: none; }"));
|
||||
|
||||
// Rules for focus styling.
|
||||
|
||||
bool focusRingOnAnything = aPresContext->GetFocusRingOnAnything();
|
||||
uint8_t focusRingWidth = aPresContext->FocusRingWidth();
|
||||
uint8_t focusRingStyle = aPresContext->GetFocusRingStyle();
|
||||
|
||||
if ((focusRingWidth != 1 && focusRingWidth <= 4) || focusRingOnAnything) {
|
||||
if (focusRingWidth != 1) {
|
||||
// If the focus ring width is different from the default, fix buttons
|
||||
// with rings.
|
||||
nsString rule;
|
||||
rule.AppendPrintf(
|
||||
"button::-moz-focus-inner, input[type=\"reset\"]::-moz-focus-inner, "
|
||||
"input[type=\"button\"]::-moz-focus-inner, "
|
||||
"input[type=\"submit\"]::-moz-focus-inner { "
|
||||
"padding: 1px 2px 1px 2px; "
|
||||
"border: %d %s transparent !important; }",
|
||||
focusRingWidth,
|
||||
focusRingWidth == 0 ? (const char*) "solid" : (const char*) "dotted");
|
||||
AppendPreferenceRule(aSheet, rule);
|
||||
|
||||
// NS_LITERAL_STRING doesn't work with concatenated string literals, hence
|
||||
// the newline escaping.
|
||||
AppendPreferenceRule(aSheet, NS_LITERAL_STRING("\
|
||||
button:focus::-moz-focus-inner, \
|
||||
input[type=\"reset\"]:focus::-moz-focus-inner, \
|
||||
input[type=\"button\"]:focus::-moz-focus-inner, \
|
||||
input[type=\"submit\"]:focus::-moz-focus-inner { \
|
||||
border-color: ButtonText !important; }"));
|
||||
}
|
||||
|
||||
nsString rule;
|
||||
if (focusRingOnAnything) {
|
||||
rule.AppendLiteral(":focus");
|
||||
} else {
|
||||
rule.AppendLiteral("*|*:link:focus, *|*:visited:focus");
|
||||
}
|
||||
rule.AppendPrintf(" { outline: %dpx ", focusRingWidth);
|
||||
if (focusRingStyle == 0) { // solid
|
||||
rule.AppendLiteral("solid -moz-mac-focusring !important; "
|
||||
"-moz-outline-radius: 3px; outline-offset: 1px; }");
|
||||
} else {
|
||||
rule.AppendLiteral("dotted WindowText !important; }");
|
||||
}
|
||||
AppendPreferenceRule(aSheet, rule);
|
||||
}
|
||||
|
||||
if (aPresContext->GetUseFocusColors()) {
|
||||
nsString rule;
|
||||
nscolor focusText = aPresContext->FocusTextColor();
|
||||
nscolor focusBG = aPresContext->FocusBackgroundColor();
|
||||
rule.AppendPrintf(
|
||||
"*:focus, *:focus > font { color: #%02x%02x%02x !important; "
|
||||
"background-color: #%02x%02x%02x !important; }",
|
||||
NS_GET_R(focusText), NS_GET_G(focusText), NS_GET_B(focusText),
|
||||
NS_GET_R(focusBG), NS_GET_G(focusBG), NS_GET_B(focusBG));
|
||||
AppendPreferenceRule(aSheet, rule);
|
||||
}
|
||||
}
|
||||
|
||||
mozilla::StaticRefPtr<nsLayoutStylesheetCache>
|
||||
nsLayoutStylesheetCache::gStyleCache;
|
||||
|
||||
|
|
|
@ -50,6 +50,10 @@ class nsLayoutStylesheetCache final
|
|||
static mozilla::CSSStyleSheet* CounterStylesSheet();
|
||||
static mozilla::CSSStyleSheet* NoScriptSheet();
|
||||
static mozilla::CSSStyleSheet* NoFramesSheet();
|
||||
static mozilla::CSSStyleSheet* ChromePreferenceSheet(nsPresContext* aPresContext);
|
||||
static mozilla::CSSStyleSheet* ContentPreferenceSheet(nsPresContext* aPresContext);
|
||||
|
||||
static void InvalidatePreferenceSheets();
|
||||
|
||||
static void Shutdown();
|
||||
|
||||
|
@ -71,9 +75,17 @@ private:
|
|||
bool aEnableUnsafeRules);
|
||||
static void InvalidateSheet(nsRefPtr<mozilla::CSSStyleSheet>& aSheet);
|
||||
static void DependentPrefChanged(const char* aPref, void* aData);
|
||||
void BuildPreferenceSheet(nsRefPtr<mozilla::CSSStyleSheet>& aSheet,
|
||||
nsPresContext* aPresContext);
|
||||
static void AppendPreferenceRule(mozilla::CSSStyleSheet* aSheet,
|
||||
const nsAString& aRule);
|
||||
static void AppendPreferenceColorRule(mozilla::CSSStyleSheet* aSheet,
|
||||
const char* aString, nscolor aColor);
|
||||
|
||||
static mozilla::StaticRefPtr<nsLayoutStylesheetCache> gStyleCache;
|
||||
static mozilla::css::Loader* gCSSLoader;
|
||||
nsRefPtr<mozilla::CSSStyleSheet> mChromePreferenceSheet;
|
||||
nsRefPtr<mozilla::CSSStyleSheet> mContentPreferenceSheet;
|
||||
nsRefPtr<mozilla::CSSStyleSheet> mCounterStylesSheet;
|
||||
nsRefPtr<mozilla::CSSStyleSheet> mFormsSheet;
|
||||
nsRefPtr<mozilla::CSSStyleSheet> mFullScreenOverrideSheet;
|
||||
|
|
Загрузка…
Ссылка в новой задаче