Implement the proposed Web Apps 1.0 API for changing the selected style sheet

set, querying the available sets, etc.  Bug 200930, r=sicking, sr=dbaron
This commit is contained in:
bzbarsky%mit.edu 2007-01-11 19:32:31 +00:00
Родитель 5e27ebc57f
Коммит 867068ef8a
12 изменённых файлов: 389 добавлений и 175 удалений

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

@ -4881,7 +4881,7 @@ function stylesheetFillPopup(menuPopup)
noStyle.setAttribute("checked", styleDisabled);
persistentOnly.setAttribute("checked", !altStyleSelected && !styleDisabled);
persistentOnly.hidden = (window.content.document.preferredStylesheetSet) ? haveAltSheets : false;
persistentOnly.hidden = (window.content.document.preferredStyleSheetSet) ? haveAltSheets : false;
sep.hidden = (noStyle.hidden && persistentOnly.hidden) || !haveAltSheets;
return true;
}

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

@ -66,6 +66,7 @@
#include "nsIDOMStyleSheet.h"
#include "nsDOMAttribute.h"
#include "nsIDOMDOMStringList.h"
#include "nsIDOMDOMImplementation.h"
#include "nsIDOMDocumentView.h"
#include "nsIDOMAbstractView.h"
@ -486,6 +487,117 @@ nsOnloadBlocker::SetLoadFlags(nsLoadFlags aLoadFlags)
return NS_OK;
}
// ==================================================================
// =
// ==================================================================
// If we ever have an nsIDocumentObserver notification for stylesheet title
// changes, we could make this inherit from nsDOMStringList instead of
// reimplementing nsIDOMDOMStringList.
class nsDOMStyleSheetSetList : public nsIDOMDOMStringList
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIDOMDOMSTRINGLIST
nsDOMStyleSheetSetList(nsIDocument* aDocument);
void Disconnect()
{
mDocument = nsnull;
}
protected:
// Rebuild our list of style sets
nsresult GetSets(nsStringArray& aStyleSets);
nsIDocument* mDocument; // Our document; weak ref. It'll let us know if it
// dies.
};
NS_IMPL_ADDREF(nsDOMStyleSheetSetList)
NS_IMPL_RELEASE(nsDOMStyleSheetSetList)
NS_INTERFACE_MAP_BEGIN(nsDOMStyleSheetSetList)
NS_INTERFACE_MAP_ENTRY(nsIDOMDOMStringList)
NS_INTERFACE_MAP_ENTRY(nsISupports)
NS_INTERFACE_MAP_ENTRY_CONTENT_CLASSINFO(DOMStringList)
NS_INTERFACE_MAP_END
nsDOMStyleSheetSetList::nsDOMStyleSheetSetList(nsIDocument* aDocument)
: mDocument(aDocument)
{
NS_ASSERTION(mDocument, "Must have document!");
}
NS_IMETHODIMP
nsDOMStyleSheetSetList::Item(PRUint32 aIndex, nsAString& aResult)
{
nsStringArray styleSets;
nsresult rv = GetSets(styleSets);
NS_ENSURE_SUCCESS(rv, rv);
if (aIndex >= (PRUint32)styleSets.Count()) {
SetDOMStringToNull(aResult);
} else {
styleSets.StringAt(aIndex, aResult);
}
return NS_OK;
}
NS_IMETHODIMP
nsDOMStyleSheetSetList::GetLength(PRUint32 *aLength)
{
nsStringArray styleSets;
nsresult rv = GetSets(styleSets);
NS_ENSURE_SUCCESS(rv, rv);
*aLength = (PRUint32)styleSets.Count();
return NS_OK;
}
NS_IMETHODIMP
nsDOMStyleSheetSetList::Contains(const nsAString& aString, PRBool *aResult)
{
nsStringArray styleSets;
nsresult rv = GetSets(styleSets);
NS_ENSURE_SUCCESS(rv, rv);
*aResult = styleSets.IndexOf(aString) != -1;
return NS_OK;
}
nsresult
nsDOMStyleSheetSetList::GetSets(nsStringArray& aStyleSets)
{
if (!mDocument) {
return NS_OK; // Spec says "no exceptions", and we have no style sets if we
// have no document, for sure
}
PRInt32 count = mDocument->GetNumberOfStyleSheets();
nsAutoString title;
nsAutoString temp;
for (PRInt32 index = 0; index < count; index++) {
nsIStyleSheet* sheet = mDocument->GetStyleSheetAt(index);
NS_ASSERTION(sheet, "Null sheet in sheet list!");
sheet->GetTitle(title);
if (!title.IsEmpty() && aStyleSets.IndexOf(title) == -1 &&
!aStyleSets.AppendString(title)) {
return NS_ERROR_OUT_OF_MEMORY;
}
}
return NS_OK;
}
// ==================================================================
// =
// ==================================================================
class nsDOMImplementation : public nsIDOMDOMImplementation,
public nsIPrivateDOMImplementation
@ -656,6 +768,9 @@ nsDocument::nsDocument(const char* aContentType)
PR_LOG(gDocumentLeakPRLog, PR_LOG_DEBUG,
("DOCUMENT %p created", this));
#endif
// Start out mLastStyleSheetSet as null, per spec
SetDOMStringToNull(mLastStyleSheetSet);
}
nsDocument::~nsDocument()
@ -671,6 +786,10 @@ nsDocument::~nsDocument()
// Clear mObservers to keep it in sync with the mutationobserver list
mObservers.Clear();
if (mStyleSheetSetList) {
mStyleSheetSetList->Disconnect();
}
mParentDocument = nsnull;
// Kill the subdocument map, doing this will release its strong
@ -1585,29 +1704,15 @@ nsDocument::SetHeaderData(nsIAtom* aHeaderField, const nsAString& aData)
}
if (aHeaderField == nsGkAtoms::headerDefaultStyle) {
// switch alternate style sheets based on default
// XXXldb What if we don't have all the sheets yet? Should this use
// the DOM API for preferred stylesheet set that's "coming soon"?
nsAutoString type;
nsAutoString title;
PRInt32 index;
CSSLoader()->SetPreferredSheet(aData);
PRInt32 count = mStyleSheets.Count();
for (index = 0; index < count; index++) {
nsIStyleSheet* sheet = mStyleSheets[index];
sheet->GetType(type);
if (!type.EqualsLiteral("text/html")) {
sheet->GetTitle(title);
if (!title.IsEmpty()) { // if sheet has title
PRBool enabled =
(!aData.IsEmpty() &&
title.Equals(aData, nsCaseInsensitiveStringComparator()));
sheet->SetEnabled(enabled);
}
}
// Only mess with our stylesheets if we don't have a lastStyleSheetSet, per
// spec.
if (DOMStringIsNull(mLastStyleSheetSet)) {
// Calling EnableStyleSheetsForSetInternal, not SetSelectedStyleSheetSet,
// per spec. The idea here is that we're changing our preferred set and
// that shouldn't change the value of lastStyleSheetSet. Also, we're
// using the Internal version so we can update the CSSLoader and not have
// to worry about null strings.
EnableStyleSheetsForSetInternal(aData, PR_TRUE);
}
}
@ -2073,7 +2178,7 @@ void
nsDocument::UpdateStyleSheets(nsCOMArray<nsIStyleSheet>& aOldSheets,
nsCOMArray<nsIStyleSheet>& aNewSheets)
{
NS_DOCUMENT_NOTIFY_OBSERVERS(BeginUpdate, (this, UPDATE_STYLE));
BeginUpdate(UPDATE_STYLE);
// XXX Need to set the sheet on the ownernode, if any
NS_PRECONDITION(aOldSheets.Count() == aNewSheets.Count(),
@ -2105,7 +2210,7 @@ nsDocument::UpdateStyleSheets(nsCOMArray<nsIStyleSheet>& aOldSheets,
}
}
NS_DOCUMENT_NOTIFY_OBSERVERS(EndUpdate, (this, UPDATE_STYLE));
EndUpdate(UPDATE_STYLE);
}
void
@ -2942,12 +3047,118 @@ nsDocument::GetStyleSheets(nsIDOMStyleSheetList** aStyleSheets)
}
NS_IMETHODIMP
nsDocument::GetPreferredStylesheetSet(nsAString& aStyleTitle)
nsDocument::GetSelectedStyleSheetSet(nsAString& aSheetSet)
{
CSSLoader()->GetPreferredSheet(aStyleTitle);
aSheetSet.Truncate();
// Look through our sheets, find the selected set title
PRInt32 count = GetNumberOfStyleSheets();
nsAutoString title;
for (PRInt32 index = 0; index < count; index++) {
nsIStyleSheet* sheet = GetStyleSheetAt(index);
NS_ASSERTION(sheet, "Null sheet in sheet list!");
nsCOMPtr<nsIDOMStyleSheet> domSheet = do_QueryInterface(sheet);
NS_ASSERTION(domSheet, "Sheet must QI to nsIDOMStyleSheet");
PRBool disabled;
domSheet->GetDisabled(&disabled);
if (disabled) {
// Disabled sheets don't affect the currently selected set
continue;
}
sheet->GetTitle(title);
if (aSheetSet.IsEmpty()) {
aSheetSet = title;
} else if (!title.IsEmpty() && !aSheetSet.Equals(title)) {
// Sheets from multiple sets enabled; return null string, per spec.
SetDOMStringToNull(aSheetSet);
break;
}
}
return NS_OK;
}
NS_IMETHODIMP
nsDocument::SetSelectedStyleSheetSet(const nsAString& aSheetSet)
{
if (DOMStringIsNull(aSheetSet)) {
return NS_OK;
}
// Must update mLastStyleSheetSet before doing anything else with stylesheets
// or CSSLoaders.
mLastStyleSheetSet = aSheetSet;
EnableStyleSheetsForSetInternal(aSheetSet, PR_TRUE);
return NS_OK;
}
NS_IMETHODIMP
nsDocument::GetLastStyleSheetSet(nsAString& aSheetSet)
{
aSheetSet = mLastStyleSheetSet;
return NS_OK;
}
NS_IMETHODIMP
nsDocument::GetPreferredStyleSheetSet(nsAString& aSheetSet)
{
GetHeaderData(nsGkAtoms::headerDefaultStyle, aSheetSet);
return NS_OK;
}
NS_IMETHODIMP
nsDocument::GetStyleSheetSets(nsIDOMDOMStringList** aList)
{
if (!mStyleSheetSetList) {
mStyleSheetSetList = new nsDOMStyleSheetSetList(this);
if (!mStyleSheetSetList) {
return NS_ERROR_OUT_OF_MEMORY;
}
}
NS_ADDREF(*aList = mStyleSheetSetList);
return NS_OK;
}
NS_IMETHODIMP
nsDocument::EnableStyleSheetsForSet(const nsAString& aSheetSet)
{
// Per spec, passing in null is a no-op.
if (!DOMStringIsNull(aSheetSet)) {
// Note: must make sure to not change the CSSLoader's preferred sheet --
// that value should be equal to either our lastStyleSheetSet (if that's
// non-null) or to our preferredStyleSheetSet. And this method doesn't
// change either of those.
EnableStyleSheetsForSetInternal(aSheetSet, PR_FALSE);
}
return NS_OK;
}
void
nsDocument::EnableStyleSheetsForSetInternal(const nsAString& aSheetSet,
PRBool aUpdateCSSLoader)
{
BeginUpdate(UPDATE_STYLE);
PRInt32 count = GetNumberOfStyleSheets();
nsAutoString title;
for (PRInt32 index = 0; index < count; index++) {
nsIStyleSheet* sheet = GetStyleSheetAt(index);
NS_ASSERTION(sheet, "Null sheet in sheet list!");
sheet->GetTitle(title);
if (!title.IsEmpty()) {
sheet->SetEnabled(title.Equals(aSheetSet));
}
}
if (aUpdateCSSLoader) {
CSSLoader()->SetPreferredSheet(aSheetSet);
}
EndUpdate(UPDATE_STYLE);
}
NS_IMETHODIMP
nsDocument::GetCharacterSet(nsAString& aCharacterSet)
{

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

@ -111,6 +111,7 @@
class nsIEventListenerManager;
class nsDOMStyleSheetList;
class nsDOMStyleSheetSetList;
class nsIOutputStream;
class nsDocument;
class nsIDTD;
@ -732,6 +733,7 @@ protected:
nsCOMPtr<nsIEventListenerManager> mListenerManager;
nsCOMPtr<nsIDOMStyleSheetList> mDOMStyleSheets;
nsRefPtr<nsDOMStyleSheetSetList> mStyleSheetSetList;
nsRefPtr<nsScriptLoader> mScriptLoader;
nsDocHeaderData* mHeaderData;
@ -776,6 +778,12 @@ private:
already_AddRefed<nsIDOMElement>
CheckAncestryAndGetFrame(nsIDocument* aDocument) const;
// Just like EnableStyleSheetsForSet, but doesn't check whether
// aSheetSet is null and allows the caller to control whether to set
// aSheetSet as the preferred set in the CSSLoader.
void EnableStyleSheetsForSetInternal(const nsAString& aSheetSet,
PRBool aUpdateCSSLoader);
// These are not implemented and not supported.
nsDocument(const nsDocument& aOther);
nsDocument& operator=(const nsDocument& aOther);
@ -797,6 +805,9 @@ private:
nsTHashtable<nsUint32ToContentHashEntry> mLinkMap;
// URIs whose visitedness has changed while we were hidden
nsCOMArray<nsIURI> mVisitednessChangedURIs;
// Member to store out last-selected stylesheet set.
nsString mLastStyleSheetSet;
};

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

@ -48,7 +48,6 @@ GRE_MODULE = 1
SDK_XPIDLSRCS = \
nsIDOMDocumentStyle.idl \
nsIDOMNSDocumentStyle.idl \
nsIDOMMediaList.idl \
nsIDOMStyleSheet.idl \
nsIDOMStyleSheetList.idl \
@ -56,6 +55,7 @@ SDK_XPIDLSRCS = \
XPIDLSRCS = \
nsIDOMLinkStyle.idl \
nsIDOMNSDocumentStyle.idl \
$(NULL)
include $(topsrcdir)/config/rules.mk

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

@ -43,18 +43,87 @@
* nsIDOMDocumentStyle interface. This interface exposes more ways to interact
* with style sheets in the Document Object Model. This interface is currently
* very much experimental.
*
* NOTE: This interface represents the additions to nsIDOMDocumentStyle defined
* by <http://whatwg.org/specs/web-apps/current-work/#alternate-style-sheets>.
* The comments here describe our implementation; if those comments don't match
* that spec, file bugs.
*/
[scriptable, uuid(4ecdf254-a21e-47b0-8d72-55da8208299f)]
[scriptable, uuid(26311d10-7e24-4c7b-bb3d-17aad86f4d88)]
interface nsIDOMNSDocumentStyle : nsIDOMDocumentStyle
{
/**
* This attribute indicates the preferredStylesheetSet as set by the
* author. It is determined from the order of stylesheet declarations and the
* Default-Style HTTP headers. See [[HTML4]]. If there is no preferred
* stylesheet set, this attribute returns the empty string. The case of this
* attribute must exactly match the case given by the author where the
* preferred stylesheet is specified or implied.
* This attribute must return the preferred style sheet set as set by the
* author. It is determined from the order of style sheet declarations and
* the Default-Style HTTP headers, as eventually defined elsewhere in the Web
* Apps 1.0 specification. If there is no preferred style sheet set, this
* attribute must return the empty string. The case of this attribute must
* exactly match the case given by the author where the preferred style sheet
* is specified or implied. This attribute must never return null.
*/
readonly attribute DOMString preferredStylesheetSet;
readonly attribute DOMString preferredStyleSheetSet;
/**
* This attribute indicates which style sheet set is in use. This attribute
* is live; changing the disabled attribute on style sheets directly will
* change the value of this attribute.
*
* If all the sheets that are enabled and have a title have the same title
* (by case-sensitive comparisons) then the value of this attribute must be
* exactly equal to the title of the first enabled style sheet with a title
* in the styleSheets list. Otherwise, if style sheets from different sets
* are enabled, then the return value must be null (there is no way to
* determine what the currently selected style sheet set is in those
* conditions). Otherwise, either all style sheets that have a title are
* disabled, or there are no alternate style sheets, and
* selectedStyleSheetSet must return the empty string.
*
* Setting this attribute to the null value must have no effect.
*
* Setting this attribute to a non-null value must call
* enableStyleSheetsForSet() with that value as the function's argument, and
* set lastStyleSheetSet to that value.
*
* From the DOM's perspective, all views have the same
* selectedStyleSheetSet. If a UA supports multiple views with different
* selected alternate style sheets, then this attribute (and the StyleSheet
* interface's disabled attribute) must return and set the value for the
* default view.
*/
attribute DOMString selectedStyleSheetSet;
/*
* This property must initially have the value null. Its value changes when
* the selectedStyleSheetSet attribute is set.
*/
readonly attribute DOMString lastStyleSheetSet;
/**
* This must return the live list of the currently available style sheet
* sets. This list is constructed by enumerating all the style sheets for
* this document available to the implementation, in the order they are
* listed in the styleSheets attribute, adding the title of each style sheet
* with a title to the list, avoiding duplicates by dropping titles that
* match (case-sensitively) titles that have already been added to the
* list.
*/
readonly attribute nsIDOMDOMStringList styleSheetSets;
/**
* Calling this method must change the disabled attribute on each StyleSheet
* object with a title attribute with a length greater than 0 in the
* styleSheets attribute, so that all those whose title matches the name
* argument are enabled, and all others are disabled. Title matches must be
* case-sensitive. Calling this method with the empty string disables all
* alternate and preferred style sheets (but does not change the state of
* persistent style sheets, that is those with no title attribute).
*
* Calling this method with a null value must have no effect.
*
* Style sheets that do not have a title are never affected by this
* method. This method does not change the values of the lastStyleSheetSet or
* preferredStyleSheetSet attributes.
*/
void enableStyleSheetsForSet(in DOMString name);
};

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

@ -77,6 +77,7 @@
#include "nsICSSLoader.h"
#include "nsICSSStyleSheet.h"
#include "nsIDOMStyleSheet.h"
#include "nsIDocumentObserver.h"
#include "nsIDocumentStateListener.h"
@ -3686,8 +3687,10 @@ nsHTMLEditor::EnableStyleSheet(const nsAString &aURL, PRBool aEnable)
if (!sheet)
return NS_OK; // Don't fail if sheet not found
nsCOMPtr<nsIStyleSheet> nsISheet = do_QueryInterface(sheet);
return nsISheet->SetEnabled(aEnable);
nsCOMPtr<nsIDOMStyleSheet> domSheet(do_QueryInterface(sheet));
NS_ASSERTION(domSheet, "Sheet not implementing nsIDOMStyleSheet!");
return domSheet->SetDisabled(!aEnable);
}
@ -3701,8 +3704,10 @@ nsHTMLEditor::EnableExistingStyleSheet(const nsAString &aURL)
// Enable sheet if already loaded.
if (sheet)
{
nsCOMPtr<nsIStyleSheet> nsISheet = do_QueryInterface(sheet);
nsISheet->SetEnabled(PR_TRUE);
nsCOMPtr<nsIDOMStyleSheet> domSheet(do_QueryInterface(sheet));
NS_ASSERTION(domSheet, "Sheet not implementing nsIDOMStyleSheet!");
domSheet->SetDisabled(PR_FALSE);
return PR_TRUE;
}
return PR_FALSE;

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

@ -97,10 +97,10 @@ class nsWeakFrame;
typedef short SelectionType;
// 56719ada-52e9-4d81-b23d-acba10c5c1e2
// 5A76F236-B93A-4C70-BC22-250F71C90518
#define NS_IPRESSHELL_IID \
{ 0x56719ada, 0x52e9, 0x4d81, \
{ 0xb2, 0x3d, 0xac, 0xba, 0x10, 0xc5, 0xc1, 0xe2 } }
{ 0x5a76f236, 0xb93a, 0x4c70, \
{ 0xbc, 0x22, 0x25, 0x0f, 0x71, 0xc9, 0x05, 0x18 } }
// Constants uses for ScrollFrameIntoView() function
#define NS_PRESSHELL_SCROLL_TOP 0
@ -198,12 +198,6 @@ public:
#endif
// These two methods are used only by viewer
NS_IMETHOD GetActiveAlternateStyleSheet(nsString& aSheetTitle) = 0;
NS_IMETHOD SelectAlternateStyleSheet(const nsString& aSheetTitle) = 0;
/* Enable/disable author style level. Disabling author style disables the entire
* author level of the cascade, including the HTML preshint level.
*/
@ -240,12 +234,6 @@ public:
*/
NS_IMETHOD SetPreferenceStyleRules(PRBool aForceReflow) = 0;
/**
* Gather titles of all selectable (alternate and preferred) style sheets
* fills void array with nsString* caller must free strings
*/
NS_IMETHOD ListAlternateStyleSheets(nsStringArray& aTitleList) = 0;
/**
* FrameSelection will return the Frame based selection API.
* You cannot go back and forth anymore with QI between nsIDOM sel and

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

@ -807,9 +807,6 @@ public:
NS_IMETHOD PopStackMemory();
NS_IMETHOD AllocateStackMemory(size_t aSize, void** aResult);
NS_IMETHOD GetActiveAlternateStyleSheet(nsString& aSheetTitle);
NS_IMETHOD SelectAlternateStyleSheet(const nsString& aSheetTitle);
NS_IMETHOD ListAlternateStyleSheets(nsStringArray& aTitleList);
NS_IMETHOD SetPreferenceStyleRules(PRBool aForceReflow);
NS_IMETHOD GetSelection(SelectionType aType, nsISelection** aSelection);
@ -1764,97 +1761,6 @@ PresShell::AllocateFrame(size_t aSize)
return mFrameArena.AllocateFrame(aSize);
}
NS_IMETHODIMP
PresShell::GetActiveAlternateStyleSheet(nsString& aSheetTitle)
{ // first non-html sheet in style set that has title
if (mStyleSet) {
PRInt32 count = mStyleSet->SheetCount(nsStyleSet::eDocSheet);
PRInt32 index;
NS_NAMED_LITERAL_STRING(textHtml, "text/html");
for (index = 0; index < count; index++) {
nsIStyleSheet* sheet = mStyleSet->StyleSheetAt(nsStyleSet::eDocSheet,
index);
if (nsnull != sheet) {
nsAutoString type;
sheet->GetType(type);
if (PR_FALSE == type.Equals(textHtml)) {
nsAutoString title;
sheet->GetTitle(title);
if (!title.IsEmpty()) {
aSheetTitle = title;
index = count; // stop looking
}
}
}
}
}
return NS_OK;
}
NS_IMETHODIMP
PresShell::SelectAlternateStyleSheet(const nsString& aSheetTitle)
{
if (mDocument && mStyleSet) {
mStyleSet->BeginUpdate();
PRInt32 count = mDocument->GetNumberOfStyleSheets();
PRInt32 index;
NS_NAMED_LITERAL_STRING(textHtml,"text/html");
for (index = 0; index < count; index++) {
nsIStyleSheet *sheet = mDocument->GetStyleSheetAt(index);
PRBool complete;
sheet->GetComplete(complete);
if (complete) {
nsAutoString type;
sheet->GetType(type);
if (!type.Equals(textHtml)) {
nsAutoString title;
sheet->GetTitle(title);
if (!title.IsEmpty()) {
if (title.Equals(aSheetTitle)) {
mStyleSet->AddDocStyleSheet(sheet, mDocument);
}
else {
mStyleSet->RemoveStyleSheet(nsStyleSet::eDocSheet, sheet);
}
}
}
}
}
mStyleSet->EndUpdate();
ReconstructStyleData();
}
return NS_OK;
}
NS_IMETHODIMP
PresShell::ListAlternateStyleSheets(nsStringArray& aTitleList)
{
// XXX should this be returning incomplete sheets? Probably.
if (mDocument) {
PRInt32 count = mDocument->GetNumberOfStyleSheets();
PRInt32 index;
NS_NAMED_LITERAL_STRING(textHtml,"text/html");
for (index = 0; index < count; index++) {
nsIStyleSheet *sheet = mDocument->GetStyleSheetAt(index);
if (sheet) {
nsAutoString type;
sheet->GetType(type);
if (PR_FALSE == type.Equals(textHtml)) {
nsAutoString title;
sheet->GetTitle(title);
if (!title.IsEmpty()) {
if (-1 == aTitleList.IndexOf(title)) {
aTitleList.AppendString(title);
}
}
}
}
}
}
return NS_OK;
}
void
nsIPresShell::SetAuthorStyleDisabled(PRBool aStyleDisabled)
{

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

@ -52,6 +52,7 @@
#include "nsIDOMNode.h"
#include "nsIDOMWindow.h"
#include "nsIDocument.h"
#include "nsIDOMNSDocumentStyle.h"
#include "nsIUnicharInputStream.h"
#include "nsIConverterInputStream.h"
#include "nsICharsetAlias.h"
@ -292,11 +293,16 @@ CSSLoaderImpl::Init(nsIDocument* aDocument)
{
NS_ASSERTION(! mDocument, "already initialized");
if (! mDocument) {
mDocument = aDocument;
return NS_OK;
mDocument = aDocument;
// We can just use the preferred set, since there are no sheets in the
// document yet (if there are, how did they get there? _we_ load the sheets!)
// and hence the selected set makes no sense at this time.
nsCOMPtr<nsIDOMNSDocumentStyle> domDoc(do_QueryInterface(mDocument));
if (domDoc) {
domDoc->GetPreferredStyleSheetSet(mPreferredSheet);
}
return NS_ERROR_ALREADY_INITIALIZED;
return NS_OK;
}
PR_STATIC_CALLBACK(PLDHashOperator)
@ -353,6 +359,19 @@ StartNonAlternates(nsIURI *aKey, SheetLoadData* &aData, void* aClosure)
NS_IMETHODIMP
CSSLoaderImpl::SetPreferredSheet(const nsAString& aTitle)
{
#ifdef DEBUG
nsCOMPtr<nsIDOMNSDocumentStyle> doc(do_QueryInterface(mDocument));
if (doc) {
nsAutoString currentPreferred;
doc->GetLastStyleSheetSet(currentPreferred);
if (DOMStringIsNull(currentPreferred)) {
doc->GetPreferredStyleSheetSet(currentPreferred);
}
NS_ASSERTION(currentPreferred.Equals(aTitle),
"Unexpected argument to SetPreferredSheet");
}
#endif
mPreferredSheet = aTitle;
// start any pending alternates that aren't alternates anymore
@ -865,15 +884,12 @@ CSSLoaderImpl::IsAlternate(const nsAString& aTitle, PRBool aHasAlternateRel)
if (!aHasAlternateRel && mDocument && mPreferredSheet.IsEmpty()) {
// There's no preferred set yet, and we now have a sheet with a title.
// Make that be the preferred set.
// XXXbz maybe this should be checking IsVoid(), actually, since the
// preferred set can be explicitly set to the empty string. Look into
// this.
mDocument->SetHeaderData(nsGkAtoms::headerDefaultStyle, aTitle);
// We're definitely not an alternate
return PR_FALSE;
}
return !aTitle.Equals(mPreferredSheet, nsCaseInsensitiveStringComparator());
return !aTitle.Equals(mPreferredSheet);
}
/**

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

@ -841,7 +841,17 @@ nsCSSStyleSheet::GetApplicable(PRBool& aApplicable) const
NS_IMETHODIMP
nsCSSStyleSheet::SetEnabled(PRBool aEnabled)
{
return nsCSSStyleSheet::SetDisabled(!aEnabled);
// Internal method, so callers must handle BeginUpdate/EndUpdate
PRBool oldDisabled = mDisabled;
mDisabled = !aEnabled;
if (mDocument && mInner && mInner->mComplete && oldDisabled != mDisabled) {
ClearRuleCascades();
mDocument->SetStyleSheetApplicableState(this, !mDisabled);
}
return NS_OK;
}
NS_IMETHODIMP
@ -1341,18 +1351,10 @@ nsCSSStyleSheet::GetDisabled(PRBool* aDisabled)
NS_IMETHODIMP
nsCSSStyleSheet::SetDisabled(PRBool aDisabled)
{
PRBool oldDisabled = mDisabled;
mDisabled = aDisabled;
if (mDocument && mInner && mInner->mComplete && oldDisabled != mDisabled) {
ClearRuleCascades();
mDocument->BeginUpdate(UPDATE_STYLE);
mDocument->SetStyleSheetApplicableState(this, !mDisabled);
mDocument->EndUpdate(UPDATE_STYLE);
}
return NS_OK;
// DOM method, so handle BeginUpdate/EndUpdate
MOZ_AUTO_DOC_UPDATE(mDocument, UPDATE_STYLE, PR_TRUE);
nsresult rv = nsCSSStyleSheet::SetEnabled(!aDisabled);
return rv;
}
NS_IMETHODIMP

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

@ -56,9 +56,10 @@ class nsIDocument;
class nsIStyleRuleProcessor;
// IID for the nsIStyleSheet interface
// 93eea32f-681b-4405-b908-3933cf1d5091
// 7b2d31da-c3fb-4537-bd97-337272b83568
#define NS_ISTYLE_SHEET_IID \
{0x93eea32f, 0x681b, 0x4405, {0xb9, 0x08, 0x39, 0x33, 0xcf, 0x1d, 0x50, 0x91}}
{ 0x7b2d31da, 0xc3fb, 0x4537, \
{ 0xbd, 0x97, 0x33, 0x72, 0x72, 0xb8, 0x35, 0x68 } }
/**
* A style sheet is a thing associated with a document that has style
@ -91,7 +92,12 @@ public:
/**
* Set the stylesheet to be enabled. This may or may not make it
* applicable.
* applicable. Note that this WILL inform the sheet's document of
* its new applicable state if the state changes but WILL NOT call
* BeginUpdate() or EndUpdate() on the document -- calling those is
* the caller's responsibility. This allows use of SetEnabled when
* batched updates are desired. If you want updates handled for
* you, see nsIDOMStyleSheet::SetDisabled().
*/
NS_IMETHOD SetEnabled(PRBool aEnabled) = 0;

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

@ -1987,7 +1987,7 @@ function stylesheetFillPopup(menuPopup)
}
menuPopup.firstChild.setAttribute("checked", styleDisabled);
itemPersistentOnly.setAttribute("checked", !altStyleSelected && !styleDisabled);
itemPersistentOnly.hidden = (window.content.document.preferredStylesheetSet) ? true : false;
itemPersistentOnly.hidden = (window.content.document.preferredStyleSheetSet) ? true : false;
}
function stylesheetInFrame(frame, title) {