зеркало из https://github.com/mozilla/gecko-dev.git
Bug 804120 - Offer a way to apply author stylesheet on a given document. r=bz
This commit is contained in:
Родитель
2f66678f37
Коммит
11266e6b35
|
@ -606,11 +606,13 @@ public:
|
|||
enum additionalSheetType {
|
||||
eAgentSheet,
|
||||
eUserSheet,
|
||||
eAuthorSheet,
|
||||
SheetTypeCount
|
||||
};
|
||||
|
||||
virtual nsresult LoadAdditionalStyleSheet(additionalSheetType aType, nsIURI* aSheetURI) = 0;
|
||||
virtual void RemoveAdditionalStyleSheet(additionalSheetType aType, nsIURI* sheetURI) = 0;
|
||||
virtual nsIStyleSheet* FirstAdditionalAuthorSheet() = 0;
|
||||
|
||||
/**
|
||||
* Get this document's CSSLoader. This is guaranteed to not return null.
|
||||
|
|
|
@ -1311,9 +1311,6 @@ nsDocument::nsDocument(const char* aContentType)
|
|||
, mAnimatingImages(true)
|
||||
, mVisibilityState(eHidden)
|
||||
{
|
||||
MOZ_STATIC_ASSERT(NS_ARRAY_LENGTH(mAdditionalSheets) == SheetTypeCount,
|
||||
"mAdditionalSheets array count is not correct");
|
||||
|
||||
SetContentTypeInternal(nsDependentCString(aContentType));
|
||||
|
||||
#ifdef PR_LOGGING
|
||||
|
@ -2054,11 +2051,13 @@ nsDocument::ResetStylesheetsToURI(nsIURI* aURI)
|
|||
RemoveStyleSheetsFromStyleSets(mCatalogSheets, nsStyleSet::eAgentSheet);
|
||||
RemoveStyleSheetsFromStyleSets(mAdditionalSheets[eAgentSheet], nsStyleSet::eAgentSheet);
|
||||
RemoveStyleSheetsFromStyleSets(mAdditionalSheets[eUserSheet], nsStyleSet::eUserSheet);
|
||||
RemoveStyleSheetsFromStyleSets(mAdditionalSheets[eAuthorSheet], nsStyleSet::eDocSheet);
|
||||
|
||||
// Release all the sheets
|
||||
mStyleSheets.Clear();
|
||||
mAdditionalSheets[eAgentSheet].Clear();
|
||||
mAdditionalSheets[eUserSheet].Clear();
|
||||
for (uint32_t i = 0; i < SheetTypeCount; ++i)
|
||||
mAdditionalSheets[i].Clear();
|
||||
|
||||
// NOTE: We don't release the catalog sheets. It doesn't really matter
|
||||
// now, but it could in the future -- in which case not releasing them
|
||||
// is probably the right thing to do.
|
||||
|
@ -2115,6 +2114,17 @@ AppendAuthorSheet(nsIStyleSheet *aSheet, void *aData)
|
|||
return true;
|
||||
}
|
||||
|
||||
static void
|
||||
AppendSheetsToStyleSet(nsStyleSet* aStyleSet,
|
||||
const nsCOMArray<nsIStyleSheet>& aSheets,
|
||||
nsStyleSet::sheetType aType)
|
||||
{
|
||||
for (int32_t i = aSheets.Count() - 1; i >= 0; --i) {
|
||||
aStyleSet->AppendStyleSheet(aType, aSheets[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
nsDocument::FillStyleSet(nsStyleSet* aStyleSet)
|
||||
{
|
||||
|
@ -2154,15 +2164,12 @@ nsDocument::FillStyleSet(nsStyleSet* aStyleSet)
|
|||
}
|
||||
}
|
||||
|
||||
for (int32_t i = mAdditionalSheets[eAgentSheet].Count() - 1; i >= 0; --i) {
|
||||
nsIStyleSheet* sheet = mAdditionalSheets[eAgentSheet][i];
|
||||
aStyleSet->AppendStyleSheet(nsStyleSet::eAgentSheet, sheet);
|
||||
}
|
||||
|
||||
for (int32_t i = mAdditionalSheets[eUserSheet].Count() - 1; i >= 0; --i) {
|
||||
nsIStyleSheet* sheet = mAdditionalSheets[eUserSheet][i];
|
||||
aStyleSet->AppendStyleSheet(nsStyleSet::eUserSheet, sheet);
|
||||
}
|
||||
AppendSheetsToStyleSet(aStyleSet, mAdditionalSheets[eAgentSheet],
|
||||
nsStyleSet::eAgentSheet);
|
||||
AppendSheetsToStyleSet(aStyleSet, mAdditionalSheets[eUserSheet],
|
||||
nsStyleSet::eUserSheet);
|
||||
AppendSheetsToStyleSet(aStyleSet, mAdditionalSheets[eAuthorSheet],
|
||||
nsStyleSet::eDocSheet);
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
@ -3600,6 +3607,23 @@ nsDocument::EnsureCatalogStyleSheet(const char *aStyleSheetURI)
|
|||
}
|
||||
}
|
||||
|
||||
static nsStyleSet::sheetType
|
||||
ConvertAdditionalSheetType(nsIDocument::additionalSheetType aType)
|
||||
{
|
||||
switch(aType) {
|
||||
case nsIDocument::eAgentSheet:
|
||||
return nsStyleSet::eAgentSheet;
|
||||
case nsIDocument::eUserSheet:
|
||||
return nsStyleSet::eUserSheet;
|
||||
case nsIDocument::eAuthorSheet:
|
||||
return nsStyleSet::eDocSheet;
|
||||
default:
|
||||
NS_ASSERTION(false, "wrong type");
|
||||
// we must return something although this should never happen
|
||||
return nsStyleSet::eSheetTypeCount;
|
||||
}
|
||||
}
|
||||
|
||||
static int32_t
|
||||
FindSheet(const nsCOMArray<nsIStyleSheet>& aSheets, nsIURI* aSheetURI)
|
||||
{
|
||||
|
@ -3638,8 +3662,7 @@ nsDocument::LoadAdditionalStyleSheet(additionalSheetType aType, nsIURI* aSheetUR
|
|||
BeginUpdate(UPDATE_STYLE);
|
||||
nsCOMPtr<nsIPresShell> shell = GetShell();
|
||||
if (shell) {
|
||||
nsStyleSet::sheetType type = aType == eAgentSheet ? nsStyleSet::eAgentSheet :
|
||||
nsStyleSet::eUserSheet;
|
||||
nsStyleSet::sheetType type = ConvertAdditionalSheetType(aType);
|
||||
shell->StyleSet()->AppendStyleSheet(type, sheet);
|
||||
}
|
||||
|
||||
|
@ -3668,8 +3691,7 @@ nsDocument::RemoveAdditionalStyleSheet(additionalSheetType aType, nsIURI* aSheet
|
|||
MOZ_ASSERT(sheetRef->IsApplicable());
|
||||
nsCOMPtr<nsIPresShell> shell = GetShell();
|
||||
if (shell) {
|
||||
nsStyleSet::sheetType type = aType == eAgentSheet ? nsStyleSet::eAgentSheet :
|
||||
nsStyleSet::eUserSheet;
|
||||
nsStyleSet::sheetType type = ConvertAdditionalSheetType(aType);
|
||||
shell->StyleSet()->RemoveStyleSheet(type, sheetRef);
|
||||
}
|
||||
}
|
||||
|
@ -3683,6 +3705,12 @@ nsDocument::RemoveAdditionalStyleSheet(additionalSheetType aType, nsIURI* aSheet
|
|||
}
|
||||
}
|
||||
|
||||
nsIStyleSheet*
|
||||
nsDocument::FirstAdditionalAuthorSheet()
|
||||
{
|
||||
return mAdditionalSheets[eAuthorSheet].SafeObjectAt(0);
|
||||
}
|
||||
|
||||
nsIScriptGlobalObject*
|
||||
nsDocument::GetScriptGlobalObject() const
|
||||
{
|
||||
|
@ -9609,6 +9637,10 @@ nsDocument::DocSizeOfExcludingThis(nsWindowSizes* aWindowSizes) const
|
|||
mAdditionalSheets[eUserSheet].
|
||||
SizeOfExcludingThis(SizeOfStyleSheetsElementIncludingThis,
|
||||
aWindowSizes->mMallocSizeOf);
|
||||
aWindowSizes->mStyleSheets +=
|
||||
mAdditionalSheets[eAuthorSheet].
|
||||
SizeOfExcludingThis(SizeOfStyleSheetsElementIncludingThis,
|
||||
aWindowSizes->mMallocSizeOf);
|
||||
// Lumping in the loader with the style-sheets size is not ideal,
|
||||
// but most of the things in there are in fact stylesheets, so it
|
||||
// doesn't seem worthwhile to separate it out.
|
||||
|
|
|
@ -601,6 +601,7 @@ public:
|
|||
|
||||
virtual nsresult LoadAdditionalStyleSheet(additionalSheetType aType, nsIURI* aSheetURI);
|
||||
virtual void RemoveAdditionalStyleSheet(additionalSheetType aType, nsIURI* sheetURI);
|
||||
virtual nsIStyleSheet* FirstAdditionalAuthorSheet();
|
||||
|
||||
virtual nsIChannel* GetChannel() const {
|
||||
return mChannel;
|
||||
|
@ -1124,7 +1125,7 @@ protected:
|
|||
|
||||
nsCOMArray<nsIStyleSheet> mStyleSheets;
|
||||
nsCOMArray<nsIStyleSheet> mCatalogSheets;
|
||||
nsCOMArray<nsIStyleSheet> mAdditionalSheets[2];
|
||||
nsCOMArray<nsIStyleSheet> mAdditionalSheets[SheetTypeCount];
|
||||
|
||||
// Array of observers
|
||||
nsTObserverArray<nsIDocumentObserver*> mObservers;
|
||||
|
|
|
@ -2937,6 +2937,23 @@ nsDOMWindowUtils::SelectAtPoint(float aX, float aY, uint32_t aSelectBehavior,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
static nsIDocument::additionalSheetType
|
||||
convertSheetType(uint32_t aSheetType)
|
||||
{
|
||||
switch(aSheetType) {
|
||||
case nsDOMWindowUtils::AGENT_SHEET:
|
||||
return nsIDocument::eAgentSheet;
|
||||
case nsDOMWindowUtils::USER_SHEET:
|
||||
return nsIDocument::eUserSheet;
|
||||
case nsDOMWindowUtils::AUTHOR_SHEET:
|
||||
return nsIDocument::eAuthorSheet;
|
||||
default:
|
||||
NS_ASSERTION(false, "wrong type");
|
||||
// we must return something although this should never happen
|
||||
return nsIDocument::SheetTypeCount;
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMWindowUtils::LoadSheet(nsIURI *aSheetURI, uint32_t aSheetType)
|
||||
{
|
||||
|
@ -2945,7 +2962,9 @@ nsDOMWindowUtils::LoadSheet(nsIURI *aSheetURI, uint32_t aSheetType)
|
|||
}
|
||||
|
||||
NS_ENSURE_ARG_POINTER(aSheetURI);
|
||||
NS_ENSURE_ARG(aSheetType == AGENT_SHEET || aSheetType == USER_SHEET);
|
||||
NS_ENSURE_ARG(aSheetType == AGENT_SHEET ||
|
||||
aSheetType == USER_SHEET ||
|
||||
aSheetType == AUTHOR_SHEET);
|
||||
|
||||
nsCOMPtr<nsIDOMWindow> window = do_QueryReferent(mWindow);
|
||||
NS_ENSURE_TRUE(window, NS_ERROR_INVALID_ARG);
|
||||
|
@ -2958,9 +2977,7 @@ nsDOMWindowUtils::LoadSheet(nsIURI *aSheetURI, uint32_t aSheetType)
|
|||
nsCOMPtr<nsIDocument> doc = do_QueryInterface(ddoc);
|
||||
NS_ENSURE_TRUE(doc, NS_ERROR_INVALID_ARG);
|
||||
|
||||
nsIDocument::additionalSheetType type =
|
||||
aSheetType == AGENT_SHEET ? nsIDocument::eAgentSheet :
|
||||
nsIDocument::eUserSheet;
|
||||
nsIDocument::additionalSheetType type = convertSheetType(aSheetType);
|
||||
|
||||
rv = doc->LoadAdditionalStyleSheet(type, aSheetURI);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
@ -2976,7 +2993,9 @@ nsDOMWindowUtils::RemoveSheet(nsIURI *aSheetURI, uint32_t aSheetType)
|
|||
}
|
||||
|
||||
NS_ENSURE_ARG_POINTER(aSheetURI);
|
||||
NS_ENSURE_ARG(aSheetType == AGENT_SHEET || aSheetType == USER_SHEET);
|
||||
NS_ENSURE_ARG(aSheetType == AGENT_SHEET ||
|
||||
aSheetType == USER_SHEET ||
|
||||
aSheetType == AUTHOR_SHEET);
|
||||
|
||||
nsCOMPtr<nsIDOMWindow> window = do_QueryReferent(mWindow);
|
||||
NS_ENSURE_TRUE(window, NS_ERROR_INVALID_ARG);
|
||||
|
@ -2989,9 +3008,7 @@ nsDOMWindowUtils::RemoveSheet(nsIURI *aSheetURI, uint32_t aSheetType)
|
|||
nsCOMPtr<nsIDocument> doc = do_QueryInterface(ddoc);
|
||||
NS_ENSURE_TRUE(doc, NS_ERROR_INVALID_ARG);
|
||||
|
||||
nsIDocument::additionalSheetType type =
|
||||
aSheetType == AGENT_SHEET ? nsIDocument::eAgentSheet :
|
||||
nsIDocument::eUserSheet;
|
||||
nsIDocument::additionalSheetType type = convertSheetType(aSheetType);
|
||||
|
||||
doc->RemoveAdditionalStyleSheet(type, aSheetURI);
|
||||
return NS_OK;
|
||||
|
|
|
@ -1262,6 +1262,7 @@ interface nsIDOMWindowUtils : nsISupports {
|
|||
|
||||
const unsigned long AGENT_SHEET = 0;
|
||||
const unsigned long USER_SHEET = 1;
|
||||
const unsigned long AUTHOR_SHEET = 2;
|
||||
/**
|
||||
* Synchronously loads a style sheet from |sheetURI| and adds it to the list
|
||||
* of additional style sheets of the document.
|
||||
|
|
|
@ -1523,7 +1523,15 @@ PresShell::AddAuthorSheet(nsISupports* aSheet)
|
|||
return;
|
||||
}
|
||||
|
||||
mStyleSet->AppendStyleSheet(nsStyleSet::eDocSheet, sheet);
|
||||
// Document specific "additional" Author sheets should be stronger than the ones
|
||||
// added with the StyleSheetService.
|
||||
nsIStyleSheet* firstAuthorSheet = mDocument->FirstAdditionalAuthorSheet();
|
||||
if (firstAuthorSheet) {
|
||||
mStyleSet->InsertStyleSheetBefore(nsStyleSet::eDocSheet, sheet, firstAuthorSheet);
|
||||
} else {
|
||||
mStyleSet->AppendStyleSheet(nsStyleSet::eDocSheet, sheet);
|
||||
}
|
||||
|
||||
ReconstructStyleData();
|
||||
}
|
||||
|
||||
|
|
|
@ -331,6 +331,29 @@ nsStyleSet::ReplaceSheets(sheetType aType,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsStyleSet::InsertStyleSheetBefore(sheetType aType, nsIStyleSheet *aNewSheet,
|
||||
nsIStyleSheet *aReferenceSheet)
|
||||
{
|
||||
NS_PRECONDITION(aNewSheet && aReferenceSheet, "null arg");
|
||||
NS_ASSERTION(aNewSheet->IsApplicable(),
|
||||
"Inapplicable sheet being placed in style set");
|
||||
|
||||
mSheets[aType].RemoveObject(aNewSheet);
|
||||
int32_t idx = mSheets[aType].IndexOf(aReferenceSheet);
|
||||
if (idx < 0)
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
|
||||
if (!mSheets[aType].InsertObjectAt(aNewSheet, idx))
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
if (!mBatching)
|
||||
return GatherRuleProcessors(aType);
|
||||
|
||||
mDirty |= 1 << aType;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
bool
|
||||
nsStyleSet::GetAuthorStyleDisabled()
|
||||
{
|
||||
|
@ -377,11 +400,13 @@ nsStyleSet::AddDocStyleSheet(nsIStyleSheet* aSheet, nsIDocument* aDocument)
|
|||
break;
|
||||
|
||||
// If the sheet is not owned by the document it can be an author
|
||||
// sheet registered at nsStyleSheetService, which means the new
|
||||
// sheet registered at nsStyleSheetService or an additional author
|
||||
// sheet on the document, which means the new
|
||||
// doc sheet should end up before it.
|
||||
if (sheetDocIndex < 0 &&
|
||||
sheetService &&
|
||||
sheetService->AuthorStyleSheets()->IndexOf(sheet) >= 0)
|
||||
((sheetService &&
|
||||
sheetService->AuthorStyleSheets()->IndexOf(sheet) >= 0) ||
|
||||
sheet == aDocument->FirstAdditionalAuthorSheet()))
|
||||
break;
|
||||
}
|
||||
if (!docSheets.InsertObjectAt(aSheet, index))
|
||||
|
|
|
@ -233,6 +233,8 @@ class nsStyleSet
|
|||
nsresult RemoveStyleSheet(sheetType aType, nsIStyleSheet *aSheet);
|
||||
nsresult ReplaceSheets(sheetType aType,
|
||||
const nsCOMArray<nsIStyleSheet> &aNewSheets);
|
||||
nsresult InsertStyleSheetBefore(sheetType aType, nsIStyleSheet *aNewSheet,
|
||||
nsIStyleSheet *aReferenceSheet);
|
||||
|
||||
// Enable/Disable entire author style level (Doc & PresHint levels)
|
||||
bool GetAuthorStyleDisabled();
|
||||
|
|
|
@ -38,6 +38,11 @@ function loadAgentSheet(win, style)
|
|||
loadSheet(win, style, "AGENT_SHEET");
|
||||
}
|
||||
|
||||
function loadAuthorSheet(win, style)
|
||||
{
|
||||
loadSheet(win, style, "AUTHOR_SHEET");
|
||||
}
|
||||
|
||||
function removeUserSheet(win, style)
|
||||
{
|
||||
removeSheet(win, style, "USER_SHEET");
|
||||
|
@ -48,6 +53,11 @@ function removeAgentSheet(win, style)
|
|||
removeSheet(win, style, "AGENT_SHEET");
|
||||
}
|
||||
|
||||
function removeAuthorSheet(win, style)
|
||||
{
|
||||
removeSheet(win, style, "AUTHOR_SHEET");
|
||||
}
|
||||
|
||||
function loadSheet(win, style, type)
|
||||
{
|
||||
var uri = gIOService.newURI(getUri(style), null, null);
|
||||
|
@ -162,15 +172,22 @@ var additionalUser = {
|
|||
removeRules: removeUserSheet
|
||||
};
|
||||
|
||||
var author = {
|
||||
type: 'author',
|
||||
var additionalAuthor = {
|
||||
type: 'additionalAuthor',
|
||||
color: 'rgb(255, 255, 0)',
|
||||
addRules: loadAuthorSheet,
|
||||
removeRules: removeAuthorSheet
|
||||
};
|
||||
|
||||
var doc = {
|
||||
type: 'doc',
|
||||
color: 'rgb(0, 255, 255)',
|
||||
addRules: setDocSheet,
|
||||
removeRules: removeDocSheet
|
||||
};
|
||||
|
||||
var authorFromManager = {
|
||||
type: 'authorFromManager',
|
||||
var author = {
|
||||
type: 'author',
|
||||
color: 'rgb(255, 0, 255)',
|
||||
addRules: loadAndRegisterAuthorSheet,
|
||||
removeRules: unregisterAuthorSheet
|
||||
|
@ -237,35 +254,52 @@ function run()
|
|||
testStyleVsStyle(win, agent, user,
|
||||
{AB:{rr:1, ii:0, ri:1, ir:0}, BA:{rr:1, ii:0, ri:1, ir:0}});
|
||||
|
||||
testStyleVsStyle(win, agent, author,
|
||||
testStyleVsStyle(win, agent, doc,
|
||||
{AB:{rr:1, ii:0, ri:1, ir:0}, BA:{rr:1, ii:0, ri:1, ir:0}});
|
||||
|
||||
|
||||
testStyleVsStyle(win, additionalUser, agent,
|
||||
{AB:{rr:0, ii:1, ri:1, ir:0}, BA:{rr:0, ii:1, ri:1, ir:0}});
|
||||
|
||||
testStyleVsStyle(win, additionalUser, author,
|
||||
testStyleVsStyle(win, additionalUser, doc,
|
||||
{AB:{rr:1, ii:0, ri:1, ir:0}, BA:{rr:1, ii:0, ri:1, ir:0}});
|
||||
|
||||
testStyleVsStyle(win, additionalAgent, user,
|
||||
{AB:{rr:1, ii:0, ri:1, ir:0}, BA:{rr:1, ii:0, ri:1, ir:0}});
|
||||
|
||||
testStyleVsStyle(win, additionalAgent, author,
|
||||
testStyleVsStyle(win, additionalAgent, doc,
|
||||
{AB:{rr:1, ii:0, ri:1, ir:0}, BA:{rr:1, ii:0, ri:1, ir:0}});
|
||||
|
||||
|
||||
testStyleVsStyle(win, additionalAgent, additionalUser,
|
||||
{AB:{rr:1, ii:0, ri:1, ir:0}, BA:{rr:1, ii:0, ri:1, ir:0}});
|
||||
|
||||
testStyleVsStyle(win, authorFromManager, author,
|
||||
testStyleVsStyle(win, author, doc,
|
||||
{AB:{rr:0, ii:0, ri:1, ir:0}, BA:{rr:0, ii:0, ri:1, ir:0}});
|
||||
|
||||
testStyleVsStyle(win, authorFromManager, user,
|
||||
testStyleVsStyle(win, author, user,
|
||||
{AB:{rr:0, ii:1, ri:1, ir:0}, BA:{rr:0, ii:1, ri:1, ir:0}});
|
||||
|
||||
testStyleVsStyle(win, authorFromManager, additionalUser,
|
||||
testStyleVsStyle(win, author, agent,
|
||||
{AB:{rr:0, ii:1, ri:1, ir:0}, BA:{rr:0, ii:1, ri:1, ir:0}});
|
||||
|
||||
testStyleVsStyle(win, author, additionalUser,
|
||||
{AB:{rr:0, ii:1, ri:1, ir:0}, BA:{rr:0, ii:1, ri:1, ir:0}});
|
||||
|
||||
testStyleVsStyle(win, additionalAuthor, doc,
|
||||
{AB:{rr:0, ii:0, ri:1, ir:0}, BA:{rr:0, ii:0, ri:1, ir:0}});
|
||||
|
||||
testStyleVsStyle(win, additionalAuthor, author,
|
||||
{AB:{rr:0, ii:0, ri:1, ir:0}, BA:{rr:0, ii:0, ri:1, ir:0}});
|
||||
|
||||
testStyleVsStyle(win, additionalAuthor, user,
|
||||
{AB:{rr:0, ii:1, ri:1, ir:0}, BA:{rr:0, ii:1, ri:1, ir:0}});
|
||||
|
||||
testStyleVsStyle(win, additionalAuthor, agent,
|
||||
{AB:{rr:0, ii:1, ri:1, ir:0}, BA:{rr:0, ii:1, ri:1, ir:0}});
|
||||
|
||||
testStyleVsStyle(win, additionalAuthor, additionalUser,
|
||||
{AB:{rr:0, ii:1, ri:1, ir:0}, BA:{rr:0, ii:1, ri:1, ir:0}});
|
||||
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче