Fix for bug 7515 (load stylesheets inserted dynamically through the DOM). r=heikki, harishd. sr=jst.

git-svn-id: svn://10.0.0.236/trunk@95505 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
peterv%netscape.com 2001-05-19 02:59:15 +00:00
parent 58b9b2c478
commit f74c7ea12a
23 changed files with 886 additions and 547 deletions

View File

@ -25,6 +25,9 @@
#include "nsISupports.h"
class nsIParser;
class nsIDocument;
#define NS_ISTYLESHEETLINKINGELEMENT_IID \
{0xa6cf90e9, 0x15b3, 0x11d2, \
{0x93, 0x2e, 0x00, 0x80, 0x5f, 0x8a, 0xdd, 0x32}}
@ -51,6 +54,36 @@ public:
* sheet associated with this element.
*/
NS_IMETHOD GetStyleSheet(nsIStyleSheet*& aStyleSheet) = 0;
/**
* Initialize the stylesheet linking element. This method passes
* in a parser that the element blocks if the stylesheet is
* a stylesheet that should be loaded with the parser blocked.
* If aDontLoadStyle is true the element will ignore the first
* modification to the element that would cause a stylesheet to
* be loaded. Subsequent modifications to the element will not
* be ignored.
*/
NS_IMETHOD InitStyleLinkElement(nsIParser *aParser, PRBool aDontLoadStyle) = 0;
/**
* Tells this element to update the stylesheet.
*
* @param aNotify .
* @param aOldDocument .
* @param aDocIndex .
*/
NS_IMETHOD UpdateStyleSheet(PRBool aNotify,
nsIDocument *aOldDocument,
PRInt32 aDocIndex) = 0;
/**
* Tells this element wether to update the stylesheet when the
* element's properties change.
*
* @param aEnableUpdates update on changes or not.
*/
NS_IMETHOD SetEnableUpdates(PRBool aEnableUpdates) = 0;
};
#endif // nsILinkingElement_h__

View File

@ -61,6 +61,7 @@ CPPSRCS = \
nsParserUtils.cpp \
nsPlainTextSerializer.cpp \
nsScriptLoader.cpp \
nsStyleLinkElement.cpp \
$(NULL)
# we don't want the shared lib, but we want to force the creation of a static lib.

View File

@ -55,10 +55,11 @@ CPPSRCS = \
nsTextNode.cpp \
nsXMLContentSerializer.cpp \
nsHTMLContentSerializer.cpp \
nsParserUtils.cpp \
nsParserUtils.cpp \
nsPlainTextSerializer.cpp \
nsContentUtils.cpp \
nsScriptLoader.cpp \
nsStyleLinkElement.cpp \
$(NULL)
MODULE=raptor
@ -94,6 +95,7 @@ CPP_OBJS= \
.\$(OBJDIR)\nsPlainTextSerializer.obj \
.\$(OBJDIR)\nsContentUtils.obj \
.\$(OBJDIR)\nsScriptLoader.obj \
.\$(OBJDIR)\nsStyleLinkElement.obj \
$(NULL)
LINCS=-I$(PUBLIC)\xpcom -I$(PUBLIC)\raptor \

View File

@ -117,6 +117,7 @@ static NS_DEFINE_CID(kCParserCID, NS_PARSER_CID);
#include "nsLWBrkCIID.h"
#include "nsIHTMLDocument.h"
#include "nsHTMLAtoms.h"
nsDOMStyleSheetList::nsDOMStyleSheetList(nsIDocument *aDocument)
@ -430,7 +431,8 @@ nsDocumentChildNodes::DropReference()
// =
// ==================================================================
nsDocument::nsDocument()
nsDocument::nsDocument() : mIsGoingAway(PR_FALSE),
mCSSLoader(nsnull)
{
NS_INIT_REFCNT();
@ -923,7 +925,7 @@ nsDocument::SetHeaderData(nsIAtom* aHeaderField, const nsAReadableString& aData)
{
if (nsnull != aHeaderField) {
if (nsnull == mHeaderData) {
if (0 < aData.Length()) { // don't bother storing empty string
if (!aData.IsEmpty()) { // don't bother storing empty string
mHeaderData = new nsDocHeaderData(aHeaderField, aData);
}
}
@ -932,7 +934,7 @@ nsDocument::SetHeaderData(nsIAtom* aHeaderField, const nsAReadableString& aData)
nsDocHeaderData** lastPtr = &mHeaderData;
do { // look for existing and replace
if (data->mField == aHeaderField) {
if (0 < aData.Length()) {
if (!aData.IsEmpty()) {
data->mData.Assign(aData);
}
else { // don't store empty string
@ -946,10 +948,35 @@ nsDocument::SetHeaderData(nsIAtom* aHeaderField, const nsAReadableString& aData)
data = data->mNext;
} while (nsnull != data);
// didn't find, append
if (0 < aData.Length()) {
if (!aData.IsEmpty()) {
*lastPtr = new nsDocHeaderData(aHeaderField, aData);
}
}
if (aHeaderField == nsHTMLAtoms::headerDefaultStyle) {
// switch alternate style sheets based on default
nsAutoString type;
nsAutoString title;
nsAutoString textHtml;
textHtml.Assign(NS_LITERAL_STRING("text/html"));
PRInt32 index;
mCSSLoader->SetPreferredSheet(nsAutoString(aData));
PRInt32 count = mStyleSheets.Count();
for (index = 0; index < count; index++) {
nsIStyleSheet* sheet = (nsIStyleSheet*)mStyleSheets.ElementAt(index);
sheet->GetType(type);
if (!type.Equals(textHtml)) {
sheet->GetTitle(title);
if (!title.IsEmpty()) { // if sheet has title
nsAutoString data(aData);
PRBool disabled = (aData.IsEmpty() ||
!title.EqualsIgnoreCase(data));
SetStyleSheetDisabledState(sheet, disabled);
}
}
}
}
return NS_OK;
}
return NS_ERROR_NULL_POINTER;
@ -1174,7 +1201,7 @@ void nsDocument::RemoveStyleSheet(nsIStyleSheet* aSheet)
PRBool enabled = PR_TRUE;
aSheet->GetEnabled(enabled);
if (enabled) {
if (enabled && !mIsGoingAway) {
RemoveStyleSheetFromStyleSets(aSheet);
// XXX should observers be notified for disabled sheets??? I think not, but I could be wrong
@ -1347,7 +1374,11 @@ nsDocument::SetScriptGlobalObject(nsIScriptGlobalObject *aScriptGlobalObject)
// content elements can remove references to their script objects.
if (!aScriptGlobalObject) {
PRUint32 ucount, indx;
mChildren->Count(&ucount);
mIsGoingAway = PR_TRUE;
for (indx = 0; indx < ucount; indx++) {
nsCOMPtr<nsIContent> content(dont_AddRef(NS_STATIC_CAST(nsIContent*,mChildren->ElementAt(indx))));
content->SetDocument(nsnull, PR_TRUE, PR_TRUE);

View File

@ -51,6 +51,7 @@
#include "nsIScriptObjectPrincipal.h"
#include "nsIURI.h"
#include "nsScriptLoader.h"
#include "nsICSSLoader.h"
class nsIEventListenerManager;
class nsDOMStyleSheetList;
@ -450,8 +451,6 @@ public:
NS_IMETHOD AddReference(void *aKey, nsISupports *aReference);
NS_IMETHOD RemoveReference(void *aKey, nsISupports **aOldReference);
public:
// nsIDOMNode
NS_DECL_NSIDOMNODE
@ -514,8 +513,6 @@ public:
protected:
NS_IMETHOD GetDTD(nsIDTD** aDTD) const;
protected:
virtual void InternalAddStyleSheet(nsIStyleSheet* aSheet); // subclass hooks for sheet ordering
virtual void InternalInsertStyleSheetAt(nsIStyleSheet* aSheet,
PRInt32 aIndex);
@ -566,11 +563,16 @@ protected:
nsCOMPtr<nsIBindingManager> mBindingManager;
nsCOMPtr<nsINodeInfoManager> mNodeInfoManager; // OWNER
PRBool mIsGoingAway; // True if the document is being destroyed.
nsSupportsHashtable* mBoxObjectTable;
PRInt32 mNumCapturers; //Number of capturing event handlers in doc. Used to optimize event delivery.
nsSupportsHashtable mContentWrapperHash;
nsCOMPtr<nsICSSLoader> mCSSLoader;
private:
// These are not implemented and not supported.
nsDocument(const nsDocument& aOther);

View File

@ -30,7 +30,6 @@
#include "nsIDOMStyleSheet.h"
#include "nsIHTMLContentContainer.h"
#include "nsINameSpaceManager.h"
#include "nsIParser.h"
#include "nsNetUtil.h"
#include "nsVoidArray.h"

View File

@ -28,8 +28,8 @@
#include "nsIStyleSheetLinkingElement.h"
#include "nsICSSStyleSheet.h"
#include "nsICSSLoaderObserver.h"
#include "nsIParser.h"
class nsIParser;
class nsIDocument;
class nsStringArray;

View File

@ -34,15 +34,17 @@
#include "nsIDOMStyleSheet.h"
#include "nsIStyleSheet.h"
#include "nsIStyleSheetLinkingElement.h"
#include "nsStyleLinkElement.h"
#include "nsHTMLUtils.h"
#include "nsIURL.h"
#include "nsNetUtil.h"
#include "nsIDocument.h"
class nsHTMLLinkElement : public nsGenericHTMLLeafElement,
public nsIDOMHTMLLinkElement,
public nsILink,
public nsIStyleSheetLinkingElement,
public nsIDOMLinkStyle
public nsStyleLinkElement
{
public:
nsHTMLLinkElement();
@ -68,12 +70,37 @@ public:
NS_IMETHOD SetLinkState(nsLinkState aState);
NS_IMETHOD GetHrefCString(char* &aBuf);
// nsIStyleSheetLinkingElement
NS_IMETHOD SetStyleSheet(nsIStyleSheet* aStyleSheet);
NS_IMETHOD GetStyleSheet(nsIStyleSheet*& aStyleSheet);
// nsIDOMLinkStyle
NS_DECL_NSIDOMLINKSTYLE
NS_IMETHOD SetDocument(nsIDocument* aDocument, PRBool aDeep,
PRBool aCompileEventHandlers) {
nsIDocument *oldDoc = mDocument;
nsresult rv = nsGenericHTMLLeafElement::SetDocument(aDocument, aDeep,
aCompileEventHandlers);
UpdateStyleSheet(PR_TRUE, oldDoc);
return rv;
}
NS_IMETHOD SetAttribute(PRInt32 aNameSpaceID, nsIAtom* aName,
const nsAReadableString& aValue, PRBool aNotify) {
nsresult rv = nsGenericHTMLLeafElement::SetAttribute(aNameSpaceID, aName,
aValue, aNotify);
UpdateStyleSheet(aNotify);
return rv;
}
NS_IMETHOD SetAttribute(nsINodeInfo* aNodeInfo,
const nsAReadableString& aValue, PRBool aNotify) {
nsresult rv = nsGenericHTMLLeafElement::SetAttribute(aNodeInfo, aValue,
aNotify);
UpdateStyleSheet(aNotify);
return rv;
}
NS_IMETHOD UnsetAttribute(PRInt32 aNameSpaceID, nsIAtom* aAttribute,
PRBool aNotify) {
nsresult rv = nsGenericHTMLLeafElement::UnsetAttribute(aNameSpaceID,
aAttribute,
aNotify);
UpdateStyleSheet(aNotify);
return rv;
}
NS_IMETHOD HandleDOMEvent(nsIPresContext* aPresContext, nsEvent* aEvent,
nsIDOMEvent** aDOMEvent, PRUint32 aFlags,
@ -81,8 +108,12 @@ public:
NS_IMETHOD SizeOf(nsISizeOfHandler* aSizer, PRUint32* aResult) const;
protected:
nsIStyleSheet* mStyleSheet;
virtual void GetStyleSheetInfo(nsAWritableString& aUrl,
nsAWritableString& aTitle,
nsAWritableString& aType,
nsAWritableString& aMedia,
PRBool* aDoBlock);
// The cached visited state
nsLinkState mLinkState;
};
@ -117,13 +148,11 @@ NS_NewHTMLLinkElement(nsIHTMLContent** aInstancePtrResult,
nsHTMLLinkElement::nsHTMLLinkElement()
: mLinkState(eLinkState_Unknown)
{
mStyleSheet = nsnull;
nsHTMLUtils::AddRef(); // for GetHrefCString
}
nsHTMLLinkElement::~nsHTMLLinkElement()
{
NS_IF_RELEASE(mStyleSheet);
nsHTMLUtils::Release(); // for GetHrefCString
}
@ -146,6 +175,7 @@ NS_HTML_CONTENT_INTERFACE_MAP_BEGIN(nsHTMLLinkElement,
NS_INTERFACE_MAP_ENTRY(nsIDOMHTMLLinkElement)
NS_INTERFACE_MAP_ENTRY(nsIDOMLinkStyle)
NS_INTERFACE_MAP_ENTRY(nsIStyleSheetLinkingElement)
NS_INTERFACE_MAP_ENTRY(nsICSSLoaderObserver)
NS_INTERFACE_MAP_ENTRY_CONTENT_CLASSINFO(HTMLLinkElement)
NS_HTML_CONTENT_INTERFACE_MAP_END
@ -245,26 +275,6 @@ nsHTMLLinkElement::SetHref(const nsAReadableString& aValue)
PR_TRUE);
}
NS_IMETHODIMP
nsHTMLLinkElement::SetStyleSheet(nsIStyleSheet* aStyleSheet)
{
NS_IF_RELEASE(mStyleSheet);
mStyleSheet = aStyleSheet;
NS_IF_ADDREF(mStyleSheet);
return NS_OK;
}
NS_IMETHODIMP
nsHTMLLinkElement::GetStyleSheet(nsIStyleSheet*& aStyleSheet)
{
aStyleSheet = mStyleSheet;
NS_IF_ADDREF(aStyleSheet);
return NS_OK;
}
NS_IMETHODIMP
nsHTMLLinkElement::HandleDOMEvent(nsIPresContext* aPresContext,
nsEvent* aEvent,
@ -333,17 +343,87 @@ nsHTMLLinkElement::GetHrefCString(char* &aBuf)
return NS_OK;
}
NS_IMETHODIMP
nsHTMLLinkElement::GetSheet(nsIDOMStyleSheet** aSheet)
void
nsHTMLLinkElement::GetStyleSheetInfo(nsAWritableString& aUrl,
nsAWritableString& aTitle,
nsAWritableString& aType,
nsAWritableString& aMedia,
PRBool* aIsAlternate)
{
NS_ENSURE_ARG_POINTER(aSheet);
*aSheet = 0;
nsresult rv = NS_OK;
if (mStyleSheet)
mStyleSheet->QueryInterface(NS_GET_IID(nsIDOMStyleSheet), (void **)aSheet);
aUrl.Truncate();
aTitle.Truncate();
aType.Truncate();
aMedia.Truncate();
*aIsAlternate = PR_FALSE;
// Always return NS_OK to avoid throwing JS exceptions if mStyleSheet
// is not a nsIDOMStyleSheet
return NS_OK;
nsAutoString href, rel, title, type;
GetHref(href);
if (href.IsEmpty()) {
// if href is empty then just bail
return;
}
GetAttribute(NS_LITERAL_STRING("rel"), rel);
rel.CompressWhitespace();
nsStringArray linkTypes;
nsStyleLinkElement::ParseLinkTypes(rel, linkTypes);
// is it a stylesheet link?
if (linkTypes.IndexOf(NS_LITERAL_STRING("stylesheet")) < 0)
return;
GetAttribute(NS_LITERAL_STRING("title"), title);
title.CompressWhitespace();
aTitle.Assign(title);
// if alternate, does it have title?
if (-1 != linkTypes.IndexOf(NS_LITERAL_STRING("alternate"))) {
if (aTitle.IsEmpty()) { // alternates must have title
return;
} else {
*aIsAlternate = PR_TRUE;
}
}
GetAttribute(NS_LITERAL_STRING("media"), aMedia);
ToLowerCase(aMedia); // HTML4.0 spec is inconsistent, make it case INSENSITIVE
GetAttribute(NS_LITERAL_STRING("type"), type);
aType.Assign(type);
nsAutoString mimeType;
nsAutoString notUsed;
nsStyleLinkElement::SplitMimeType(type, mimeType, notUsed);
if (!mimeType.IsEmpty() && !mimeType.EqualsIgnoreCase("text/css")) {
return;
}
// If we get here we assume that we're loading a css file, so set the
// type to 'text/css'
aType.Assign(NS_LITERAL_STRING("text/css"));
nsCOMPtr<nsIURI> url, base;
nsCOMPtr<nsIURI> baseURL;
GetBaseURL(*getter_AddRefs(baseURL));
rv = NS_MakeAbsoluteURI(aUrl, href, baseURL);
if (!*aIsAlternate) {
if (!aTitle.IsEmpty()) { // possibly preferred sheet
nsAutoString prefStyle;
mDocument->GetHeaderData(nsHTMLAtoms::headerDefaultStyle,
prefStyle);
if (prefStyle.IsEmpty()) {
mDocument->SetHeaderData(nsHTMLAtoms::headerDefaultStyle,
title);
}
}
}
return;
}

View File

@ -33,14 +33,17 @@
#include "nsIDOMStyleSheet.h"
#include "nsIStyleSheet.h"
#include "nsIStyleSheetLinkingElement.h"
#include "nsStyleLinkElement.h"
#include "nsNetUtil.h"
#include "nsIDocument.h"
#include "nsHTMLUtils.h"
// XXX no SRC attribute
class nsHTMLStyleElement : public nsGenericHTMLContainerElement,
public nsIDOMHTMLStyleElement,
public nsIDOMLinkStyle,
public nsIStyleSheetLinkingElement
public nsStyleLinkElement
{
public:
nsHTMLStyleElement();
@ -61,17 +64,48 @@ public:
// nsIDOMHTMLStyleElement
NS_DECL_NSIDOMHTMLSTYLEELEMENT
// nsIDOMLinkStyle
NS_DECL_NSIDOMLINKSTYLE
// nsIStyleSheetLinkingElement
NS_IMETHOD SetStyleSheet(nsIStyleSheet* aStyleSheet);
NS_IMETHOD GetStyleSheet(nsIStyleSheet*& aStyleSheet);
NS_IMETHOD SetDocument(nsIDocument* aDocument, PRBool aDeep,
PRBool aCompileEventHandlers) {
nsIDocument *oldDoc = mDocument;
nsresult rv = nsGenericHTMLContainerElement::SetDocument(aDocument, aDeep,
aCompileEventHandlers);
UpdateStyleSheet(PR_TRUE, oldDoc);
return rv;
}
NS_IMETHOD SetAttribute(PRInt32 aNameSpaceID, nsIAtom* aName,
const nsAReadableString& aValue, PRBool aNotify) {
nsresult rv = nsGenericHTMLContainerElement::SetAttribute(aNameSpaceID, aName,
aValue, aNotify);
UpdateStyleSheet(aNotify);
return rv;
}
NS_IMETHOD SetAttribute(nsINodeInfo* aNodeInfo,
const nsAReadableString& aValue, PRBool aNotify) {
nsresult rv = nsGenericHTMLContainerElement::SetAttribute(aNodeInfo, aValue,
aNotify);
UpdateStyleSheet(aNotify);
return rv;
}
NS_IMETHOD UnsetAttribute(PRInt32 aNameSpaceID, nsIAtom* aAttribute,
PRBool aNotify) {
nsresult rv = nsGenericHTMLContainerElement::UnsetAttribute(aNameSpaceID,
aAttribute,
aNotify);
UpdateStyleSheet(aNotify);
return rv;
}
NS_IMETHOD SizeOf(nsISizeOfHandler* aSizer, PRUint32* aResult) const;
protected:
nsIStyleSheet* mStyleSheet;
virtual void GetStyleSheetInfo(nsAWritableString& aUrl,
nsAWritableString& aTitle,
nsAWritableString& aType,
nsAWritableString& aMedia,
PRBool* aDoBlock);
nsresult GetHrefCString(char* &aBuf);
};
nsresult
@ -103,12 +137,12 @@ NS_NewHTMLStyleElement(nsIHTMLContent** aInstancePtrResult,
nsHTMLStyleElement::nsHTMLStyleElement()
{
mStyleSheet = nsnull;
nsHTMLUtils::AddRef(); // for GetHrefCString
}
nsHTMLStyleElement::~nsHTMLStyleElement()
{
NS_IF_RELEASE(mStyleSheet);
nsHTMLUtils::Release(); // for GetHrefCString
}
@ -130,6 +164,7 @@ NS_HTML_CONTENT_INTERFACE_MAP_BEGIN(nsHTMLStyleElement,
NS_INTERFACE_MAP_ENTRY(nsIDOMHTMLStyleElement)
NS_INTERFACE_MAP_ENTRY(nsIDOMLinkStyle)
NS_INTERFACE_MAP_ENTRY(nsIStyleSheetLinkingElement)
NS_INTERFACE_MAP_ENTRY(nsICSSLoaderObserver)
NS_INTERFACE_MAP_ENTRY_CONTENT_CLASSINFO(HTMLStyleElement)
NS_HTML_CONTENT_INTERFACE_MAP_END
@ -200,26 +235,6 @@ nsHTMLStyleElement::SetDisabled(PRBool aDisabled)
NS_IMPL_STRING_ATTR(nsHTMLStyleElement, Media, media)
NS_IMPL_STRING_ATTR(nsHTMLStyleElement, Type, type)
NS_IMETHODIMP
nsHTMLStyleElement::SetStyleSheet(nsIStyleSheet* aStyleSheet)
{
NS_IF_RELEASE(mStyleSheet);
mStyleSheet = aStyleSheet;
NS_IF_ADDREF(mStyleSheet);
return NS_OK;
}
NS_IMETHODIMP
nsHTMLStyleElement::GetStyleSheet(nsIStyleSheet*& aStyleSheet)
{
aStyleSheet = mStyleSheet;
NS_IF_ADDREF(aStyleSheet);
return NS_OK;
}
NS_IMETHODIMP
nsHTMLStyleElement::SizeOf(nsISizeOfHandler* aSizer, PRUint32* aResult) const
{
@ -228,18 +243,107 @@ nsHTMLStyleElement::SizeOf(nsISizeOfHandler* aSizer, PRUint32* aResult) const
return NS_OK;
}
NS_IMETHODIMP
nsHTMLStyleElement::GetSheet(nsIDOMStyleSheet** aSheet)
nsresult
nsHTMLStyleElement::GetHrefCString(char* &aBuf)
{
NS_ENSURE_ARG_POINTER(aSheet);
*aSheet = 0;
// Get src= attribute (relative URL).
nsAutoString relURLSpec;
if (mStyleSheet) {
mStyleSheet->QueryInterface(NS_GET_IID(nsIDOMStyleSheet), (void **)aSheet);
if (NS_CONTENT_ATTR_HAS_VALUE ==
nsGenericHTMLContainerElement::GetAttribute(kNameSpaceID_HTML,
nsHTMLAtoms::src, relURLSpec)) {
// Clean up any leading or trailing whitespace
relURLSpec.Trim(" \t\n\r");
// Get base URL.
nsCOMPtr<nsIURI> baseURL;
GetBaseURL(*getter_AddRefs(baseURL));
if (baseURL) {
// Get absolute URL.
NS_MakeAbsoluteURIWithCharset(&aBuf, relURLSpec, mDocument, baseURL,
nsHTMLUtils::IOService,
nsHTMLUtils::CharsetMgr);
}
else {
// Absolute URL is same as relative URL.
aBuf = relURLSpec.ToNewUTF8String();
}
}
else {
// Absolute URL is empty because we have no HREF.
aBuf = nsnull;
}
// Always return NS_OK to avoid throwing JS exceptions if mStyleSheet
// is not a nsIDOMStyleSheet
return NS_OK;
}
void
nsHTMLStyleElement::GetStyleSheetInfo(nsAWritableString& aUrl,
nsAWritableString& aTitle,
nsAWritableString& aType,
nsAWritableString& aMedia,
PRBool* aIsAlternate)
{
nsresult rv = NS_OK;
aUrl.Truncate();
aTitle.Truncate();
aType.Truncate();
aMedia.Truncate();
*aIsAlternate = PR_FALSE;
nsAutoString href, rel, title, type;
char *buf;
GetHrefCString(buf);
if (buf) {
href.Assign(NS_ConvertASCIItoUCS2(buf));
nsCRT::free(buf);
}
if (href.IsEmpty()) {
// if href is empty then just bail
return;
}
GetAttribute(NS_LITERAL_STRING("title"), title);
title.CompressWhitespace();
aTitle.Assign(title);
GetAttribute(NS_LITERAL_STRING("media"), aMedia);
ToLowerCase(aMedia); // HTML4.0 spec is inconsistent, make it case INSENSITIVE
GetAttribute(NS_LITERAL_STRING("type"), type);
aType.Assign(aType);
nsAutoString mimeType;
nsAutoString notUsed;
nsStyleLinkElement::SplitMimeType(type, mimeType, notUsed);
if (!mimeType.IsEmpty() && !mimeType.EqualsIgnoreCase("text/css")) {
return;
}
// If we get here we assume that we're loading a css file, so set the
// type to 'text/css'
aType.Assign(NS_LITERAL_STRING("text/css"));
nsCOMPtr<nsIURI> url, base;
nsCOMPtr<nsIURI> baseURL;
GetBaseURL(*getter_AddRefs(baseURL));
rv = NS_MakeAbsoluteURI(aUrl, href, baseURL);
if (!aTitle.IsEmpty()) {
*aIsAlternate = PR_FALSE;
nsAutoString prefStyle;
mDocument->GetHeaderData(nsHTMLAtoms::headerDefaultStyle,
prefStyle);
if (prefStyle.IsEmpty()) { // Set as preferred
mDocument->SetHeaderData(nsHTMLAtoms::headerDefaultStyle,
title);
}
}
return;
}

View File

@ -117,6 +117,7 @@
#include "nsDOMError.h"
#include "nsIScrollable.h"
#include "nsContentPolicyUtils.h"
#include "nsStyleLinkElement.h"
#include "nsReadableUtils.h"
#include "nsWeakReference.h"//nshtmlelementfactory supports weak references
@ -358,7 +359,6 @@ public:
nsString mBaseHREF;
nsString mBaseTarget;
nsString mPreferredStyle;
PRInt32 mStyleSheetCount;
nsICSSLoader* mCSSLoader;
PRInt32 mInsideNoXXXTag;
@ -2312,8 +2312,6 @@ HTMLContentSink::Init(nsIDocument* aDoc,
ProcessHTTPHeaders(aChannel);
mDocument->GetHeaderData(nsHTMLAtoms::headerDefaultStyle, mPreferredStyle);
nsCOMPtr<nsINodeInfo> nodeInfo;
rv = mNodeInfoManager->GetNodeInfo(nsHTMLAtoms::html, nsnull,
kNameSpaceID_None,
@ -3839,7 +3837,7 @@ HTMLContentSink::ProcessLink(nsIHTMLContent* aElement, const nsAReadableString&
if (start < end) {
if ((kLessThanCh == *start) && (kGreaterThanCh == *last)) {
*last = kNullCh;
if (0 == href.Length()) { // first one wins
if (href.IsEmpty()) { // first one wins
href = (start + 1);
href.StripWhitespace();
}
@ -3865,19 +3863,19 @@ HTMLContentSink::ProcessLink(nsIHTMLContent* aElement, const nsAReadableString&
}
if (attr.EqualsIgnoreCase("rel")) {
if (0 == rel.Length()) {
if (rel.IsEmpty()) {
rel = value;
rel.CompressWhitespace();
}
}
else if (attr.EqualsIgnoreCase("title")) {
if (0 == title.Length()) {
if (title.IsEmpty()) {
title = value;
title.CompressWhitespace();
}
}
else if (attr.EqualsIgnoreCase("type")) {
if (0 == type.Length()) {
if (type.IsEmpty()) {
type = value;
type.StripWhitespace();
}
@ -3892,7 +3890,7 @@ HTMLContentSink::ProcessLink(nsIHTMLContent* aElement, const nsAReadableString&
}
}
if (kCommaCh == endCh) { // hit a comma, process what we've got so far
if (0 < href.Length()) {
if (!href.IsEmpty()) {
result = ProcessStyleLink(aElement, href, rel, title, type, media);
if (NS_ERROR_HTMLPARSER_BLOCK == result) {
didBlock = PR_TRUE;
@ -3908,7 +3906,7 @@ HTMLContentSink::ProcessLink(nsIHTMLContent* aElement, const nsAReadableString&
start = ++end;
}
if (0 < href.Length()) {
if (!href.IsEmpty()) {
result = ProcessStyleLink(aElement, href, rel, title, type, media);
if (NS_SUCCEEDED(result) && didBlock) {
result = NS_ERROR_HTMLPARSER_BLOCK;
@ -3917,55 +3915,6 @@ HTMLContentSink::ProcessLink(nsIHTMLContent* aElement, const nsAReadableString&
return result;
}
static void ParseLinkTypes(const nsString& aTypes, nsStringArray& aResult)
{
nsAutoString stringList(aTypes); // copy to work buffer
nsAutoString subStr;
stringList.ToLowerCase();
stringList.Append(kNullCh); // put an extra null at the end
PRUnichar* start = (PRUnichar*)(const PRUnichar*)stringList.GetUnicode();
PRUnichar* end = start;
while (kNullCh != *start) {
while ((kNullCh != *start) && nsCRT::IsAsciiSpace(*start)) { // skip leading space
start++;
}
end = start;
while ((kNullCh != *end) && (! nsCRT::IsAsciiSpace(*end))) { // look for space
end++;
}
*end = kNullCh; // end string here
subStr = start;
if (0 < subStr.Length()) {
aResult.AppendString(subStr);
}
start = ++end;
}
}
static void SplitMimeType(const nsString& aValue, nsString& aType, nsString& aParams)
{
aType.Truncate();
aParams.Truncate();
PRInt32 semiIndex = aValue.FindChar(PRUnichar(';'));
if (-1 != semiIndex) {
aValue.Left(aType, semiIndex);
aValue.Right(aParams, (aValue.Length() - semiIndex) - 1);
aParams.StripWhitespace();
}
else {
aType = aValue;
}
aType.StripWhitespace();
}
NS_IMETHODIMP
HTMLContentSink::StyleSheetLoaded(nsICSSStyleSheet* aSheet,
PRBool aDidNotify)
@ -3996,7 +3945,7 @@ HTMLContentSink::ProcessStyleLink(nsIHTMLContent* aElement,
}
nsStringArray linkTypes;
ParseLinkTypes(aRel, linkTypes);
nsStyleLinkElement::ParseLinkTypes(aRel, linkTypes);
PRBool isAlternate = PR_FALSE;
if (-1 != linkTypes.IndexOf(NS_LITERAL_STRING("stylesheet"))) { // is it a stylesheet link?
@ -4011,32 +3960,32 @@ HTMLContentSink::ProcessStyleLink(nsIHTMLContent* aElement,
nsAutoString mimeType;
nsAutoString params;
SplitMimeType(aType, mimeType, params);
nsStyleLinkElement::SplitMimeType(aType, mimeType, params);
nsDTDMode mode;
mHTMLDocument->GetDTDMode(mode);
nsDTDMode mode;
mHTMLDocument->GetDTDMode(mode);
PRBool isStyleSheet = PR_FALSE; // see bug 18817
if (eDTDMode_strict== mode) {
if (mimeType.EqualsIgnoreCase("text/css")) {
isStyleSheet = PR_TRUE; // strict mode + good mime type
}
else {
if (mimeType.IsEmpty()) {
nsString extension;
aHref.Right(extension, 4);
if (extension.Equals(NS_LITERAL_STRING(".css"))) {
isStyleSheet = PR_TRUE; // strict mode + no mime type + '.css' extension
}
}
}
}
else {
if (mimeType.IsEmpty() || mimeType.EqualsIgnoreCase("text/css")) {
isStyleSheet = PR_TRUE; // quirks mode + good mime type or no mime type at all
}
}
PRBool isStyleSheet = PR_FALSE; // see bug 18817
if (eDTDMode_strict== mode) {
if (mimeType.EqualsIgnoreCase("text/css")) {
isStyleSheet = PR_TRUE; // strict mode + good mime type
}
else {
if (0 == mimeType.Length()) {
nsString extension;
aHref.Right(extension, 4);
if (extension.EqualsWithConversion(".css")) {
isStyleSheet = PR_TRUE; // strict mode + no mime type + '.css' extension
}
}
}
}
else {
if (0 == mimeType.Length() || mimeType.EqualsIgnoreCase("text/css")) {
isStyleSheet = PR_TRUE; // quirks mode + good mime type or no mime type at all
}
}
if (isStyleSheet) {
nsIURI* url = nsnull;
{
@ -4047,10 +3996,10 @@ HTMLContentSink::ProcessStyleLink(nsIHTMLContent* aElement,
}
if (-1 == linkTypes.IndexOf(NS_LITERAL_STRING("alternate"))) {
if (0 < aTitle.Length()) { // possibly preferred sheet
if (0 == mPreferredStyle.Length()) {
mPreferredStyle = aTitle;
mCSSLoader->SetPreferredSheet(aTitle);
if (!aTitle.IsEmpty()) { // possibly preferred sheet
nsAutoString preferredStyle;
mDocument->GetHeaderData(nsHTMLAtoms::headerDefaultStyle, preferredStyle);
if (preferredStyle.IsEmpty()) {
mDocument->SetHeaderData(nsHTMLAtoms::headerDefaultStyle, aTitle);
}
}
@ -4096,70 +4045,45 @@ HTMLContentSink::ProcessLINKTag(const nsIParserNode& aNode)
if(parent!=nsnull) {
// Create content object
nsIHTMLContent* element = nsnull;
nsCOMPtr<nsIHTMLContent> element;
nsCOMPtr<nsINodeInfo> nodeInfo;
mNodeInfoManager->GetNodeInfo(nsHTMLAtoms::link, nsnull, kNameSpaceID_HTML,
*getter_AddRefs(nodeInfo));
result = NS_CreateHTMLElement(&element, nodeInfo, PR_FALSE);
result = NS_CreateHTMLElement(getter_AddRefs(element), nodeInfo, PR_FALSE);
if (NS_SUCCEEDED(result)) {
PRInt32 id;
mDocument->GetAndIncrementContentID(&id);
element->SetContentID(id);
nsCOMPtr<nsIStyleSheetLinkingElement> ssle(do_QueryInterface(element));
if (ssle) {
// XXX need prefs. check here.
if(!mInsideNoXXXTag) {
ssle->InitStyleLinkElement(mParser, PR_FALSE);
}
else {
ssle->InitStyleLinkElement(mParser, PR_TRUE);
}
ssle->SetEnableUpdates(PR_FALSE);
}
// Add in the attributes and add the style content object to the
// head container.
element->SetDocument(mDocument, PR_FALSE, PR_TRUE);
result = AddAttributes(aNode, element);
if (NS_FAILED(result)) {
NS_RELEASE(element);
return result;
}
parent->AppendChildTo(element, PR_FALSE, PR_FALSE);
}
else {
return result;
}
// XXX need prefs. check here.
if(!mInsideNoXXXTag) {
PRInt32 i;
PRInt32 count = aNode.GetAttributeCount();
nsAutoString href;
nsAutoString rel;
nsAutoString title;
nsAutoString type;
nsAutoString media;
for (i = 0; i < count; i++) {
nsAutoString key(aNode.GetKeyAt(i));
if (key.EqualsIgnoreCase("href")) {
GetAttributeValueAt(aNode, i, href);
href.StripWhitespace();
}
else if (key.EqualsIgnoreCase("rel")) {
GetAttributeValueAt(aNode, i, rel);
rel.CompressWhitespace();
}
else if (key.EqualsIgnoreCase("title")) {
GetAttributeValueAt(aNode, i, title);
title.CompressWhitespace();
}
else if (key.EqualsIgnoreCase("type")) {
GetAttributeValueAt(aNode, i, type);
type.StripWhitespace();
}
else if (key.EqualsIgnoreCase("media")) {
GetAttributeValueAt(aNode, i, media);
media.ToLowerCase(); // HTML4.0 spec is inconsistent, make it case INSENSITIVE
}
}
if (0 < href.Length()) {
result = ProcessStyleLink(element, href, rel, title, type, media);
if (ssle) {
ssle->SetEnableUpdates(PR_TRUE);
result = ssle->UpdateStyleSheet(PR_TRUE, mDocument, mStyleSheetCount);
if (NS_SUCCEEDED(result) || (result == NS_ERROR_HTMLPARSER_BLOCK))
mStyleSheetCount++;
}
}
NS_RELEASE(element);
}
return result;
}
@ -4331,11 +4255,7 @@ HTMLContentSink::ProcessHeaderData(nsIAtom* aHeader,const nsAReadableString& aVa
mDocument->SetHeaderData(aHeader, aValue);
if (aHeader == nsHTMLAtoms::headerDefaultStyle) {
mPreferredStyle = aValue;
mCSSLoader->SetPreferredSheet(mPreferredStyle);
}
else if (aHeader == nsHTMLAtoms::link) {
if (aHeader == nsHTMLAtoms::link) {
rv = ProcessLink(aContent, aValue);
}
else if (aHeader == nsHTMLAtoms::headerContentBase) {
@ -4733,16 +4653,15 @@ HTMLContentSink::ProcessSTYLETag(const nsIParserNode& aNode)
nsAutoString mimeType;
nsAutoString params;
SplitMimeType(type, mimeType, params);
nsStyleLinkElement::SplitMimeType(type, mimeType, params);
PRBool blockParser = kBlockByDefault;
if ((0 == mimeType.Length()) || mimeType.EqualsIgnoreCase("text/css")) {
if (0 < title.Length()) { // possibly preferred sheet
if (0 == mPreferredStyle.Length()) {
mPreferredStyle = title;
mCSSLoader->SetPreferredSheet(title);
if (mimeType.IsEmpty() || mimeType.Equals(NS_LITERAL_STRING("text/css"))) {
if (!title.IsEmpty()) { // possibly preferred sheet
nsAutoString preferredStyle;
mDocument->GetHeaderData(nsHTMLAtoms::headerDefaultStyle, preferredStyle);
if (preferredStyle.IsEmpty()) {
mDocument->SetHeaderData(nsHTMLAtoms::headerDefaultStyle, title);
}
}
@ -4752,7 +4671,7 @@ HTMLContentSink::ProcessSTYLETag(const nsIParserNode& aNode)
PRBool doneLoading = PR_FALSE;
nsIUnicharInputStream* uin = nsnull;
if (0 == src.Length()) {
if (src.IsEmpty()) {
// Create a text node holding the content
nsIContent* text;
@ -4805,7 +4724,7 @@ HTMLContentSink::ProcessSTYLETag(const nsIParserNode& aNode)
if (NS_SUCCEEDED(rv) && blockParser && (! doneLoading)) {
rv = NS_ERROR_HTMLPARSER_BLOCK;
}
}//if ((0 == mimeType.Length()) || mimeType.EqualsIgnoreCase("text/css"))
}//if (mimeType.IsEmpty() || mimeType.Equals(NS_LITERAL_STRING("text/css")))
}//if(!mInsideNoXXXTag && NS_SUCCEEDED(rv))
NS_RELEASE(element);
}//if(parent!=nsnull)

View File

@ -275,7 +275,6 @@ nsHTMLDocument::~nsHTMLDocument()
NS_IF_RELEASE(mForms);
if (mCSSLoader) {
mCSSLoader->DropDocumentReference(); // release weak ref
NS_RELEASE(mCSSLoader);
}
NS_IF_RELEASE(mBodyContent);
@ -1115,7 +1114,7 @@ nsHTMLDocument::GetCSSLoader(nsICSSLoader*& aLoader)
{
nsresult result = NS_OK;
if (! mCSSLoader) {
result = NS_NewCSSLoader(this, &mCSSLoader);
result = NS_NewCSSLoader(this, getter_AddRefs(mCSSLoader));
}
if (mCSSLoader) {
mCSSLoader->SetCaseSensitive(PR_FALSE);
@ -1156,38 +1155,6 @@ nsHTMLDocument::SetDTDMode(nsDTDMode aMode)
return NS_OK;
}
NS_IMETHODIMP
nsHTMLDocument::SetHeaderData(nsIAtom* aHeaderField,
const nsAReadableString& aData)
{
nsresult result = nsMarkupDocument::SetHeaderData(aHeaderField, aData);
if (NS_SUCCEEDED(result)) {
if (aHeaderField == nsHTMLAtoms::headerDefaultStyle) {
// switch alternate style sheets based on default
nsAutoString type;
nsAutoString title;
nsAutoString textHtml; textHtml.AssignWithConversion("text/html");
PRInt32 index;
PRInt32 count = mStyleSheets.Count();
for (index = 0; index < count; index++) {
nsIStyleSheet* sheet = (nsIStyleSheet*)mStyleSheets.ElementAt(index);
sheet->GetType(type);
if (PR_FALSE == type.Equals(textHtml)) {
sheet->GetTitle(title);
if (0 < title.Length()) { // if sheet has title
nsAutoString data(aData);
PRBool disabled = ((0 == aData.Length()) ||
(PR_FALSE == title.EqualsIgnoreCase(data)));
SetStyleSheetDisabledState(sheet, disabled);
}
}
}
}
}
return result;
}
NS_IMETHODIMP
nsHTMLDocument::ContentAppended(nsIContent* aContainer,
PRInt32 aNewIndexInContainer)

View File

@ -99,9 +99,6 @@ public:
NS_IMETHOD GetDTDMode(nsDTDMode& aMode);
NS_IMETHOD SetDTDMode(nsDTDMode aMode);
NS_IMETHOD SetHeaderData(nsIAtom* aHeaderField,
const nsAReadableString& aData);
NS_IMETHOD ContentAppended(nsIContent* aContainer,
PRInt32 aNewIndexInContainer);
NS_IMETHOD ContentInserted(nsIContent* aContainer,
@ -198,7 +195,6 @@ protected:
nsString* mReferrer;
nsDTDMode mDTDMode;
nsVoidArray mImageMaps;
nsICSSLoader* mCSSLoader;
nsContentList *mImages;
nsContentList *mApplets;

View File

@ -23,7 +23,6 @@
#include "nsMarkupDocument.h"
#include "nsIURL.h"
#include "nsLayoutCID.h"
#include "nsIPresShell.h"

View File

@ -23,10 +23,6 @@
#define nsMarkupDocument_h___
#include "nsDocument.h"
#include "nsIHTMLDocument.h"
class nsICSSDeclaration;
class nsICSSStyleRule;
/**
* MODULE NOTES:

View File

@ -113,6 +113,11 @@ public:
// if an empty string, then it is set to the default charset
NS_IMETHOD SetCharset(/*in*/ const nsString &aCharsetSrc) = 0;
// stop loading all sheets
NS_IMETHOD Stop(void) = 0;
// stop loading one sheet
NS_IMETHOD StopLoadingSheet(nsIURI* aURL) = 0;
};
extern NS_HTML nsresult

View File

@ -318,6 +318,12 @@ public:
// then use that
// - othersise set the default charset
// stop loading all sheets
NS_IMETHOD Stop(void);
// stop loading one sheet
NS_IMETHOD StopLoadingSheet(nsIURI* aURL);
#ifdef NS_DEBUG
PRBool mSyncCallback;
#endif
@ -468,7 +474,9 @@ static PRBool PR_CALLBACK DeleteSheetMap(nsHashKey* aKey, void* aData, void* aCl
CSSLoaderImpl::~CSSLoaderImpl(void)
{
NS_ASSERTION(0 == mLoadingSheets.Count(), "destructing loader while sheets loading");
if (mLoadingSheets.Count() > 0) {
Stop();
}
NS_IF_RELEASE(mParsers);
mLoadedSheets.Enumerate(ReleaseSheet);
mLoadingSheets.Enumerate(DeleteHashLoadData);
@ -1651,3 +1659,39 @@ nsresult CSSLoaderImpl::SetCharset(/*in*/ const nsString &aHTTPHeader,
}
return rv;
}
static PRBool PR_CALLBACK StopLoadingSheetCallback(nsHashKey* aKey, void* aData, void* aClosure)
{
NS_ENSURE_TRUE(aData, NS_ERROR_NULL_POINTER);
SheetLoadData* data = (SheetLoadData*)aData;
NS_ENSURE_TRUE(data->mLoader, NS_ERROR_NULL_POINTER);
NS_ENSURE_TRUE(data->mURL, NS_ERROR_NULL_POINTER);
data->mLoader->StopLoadingSheet(data->mURL);
return PR_TRUE;
}
NS_IMETHODIMP
CSSLoaderImpl::Stop()
{
if (mLoadingSheets.Count() > 0) {
mLoadingSheets.Enumerate(StopLoadingSheetCallback);
}
return NS_OK;
}
NS_IMETHODIMP
CSSLoaderImpl::StopLoadingSheet(nsIURI* aURL)
{
NS_ENSURE_TRUE(aURL, NS_ERROR_NULL_POINTER);
if (mLoadingSheets.Count() > 0) {
URLKey key(aURL);
SheetLoadData* loadData = (SheetLoadData*)mLoadingSheets.Get(&key);
if (loadData) {
Cleanup(key, loadData);
}
}
return NS_OK;
}

Binary file not shown.

View File

@ -32,16 +32,18 @@
#include "nsGenericDOMDataNode.h"
#include "nsGenericElement.h"
#include "nsLayoutAtoms.h"
#include "nsHTMLAtoms.h"
#include "nsString.h"
#include "nsXPIDLString.h"
#include "nsIXMLContent.h"
#include "nsStyleLinkElement.h"
#include "nsNetUtil.h"
class nsXMLProcessingInstruction : public nsIDOMProcessingInstruction,
public nsIDOMLinkStyle,
public nsIContent
public nsIContent,
public nsStyleLinkElement
{
public:
nsXMLProcessingInstruction(const nsAReadableString& aTarget, const nsAReadableString& aData);
@ -51,19 +53,212 @@ public:
NS_DECL_ISUPPORTS
// nsIDOMNode
NS_IMPL_NSIDOMNODE_USING_GENERIC_DOM_DATA(mInner)
NS_IMETHOD GetNodeName(nsAWritableString& aNodeName);
NS_IMETHOD GetLocalName(nsAWritableString& aLocalName) {
return mInner.GetLocalName(aLocalName);
}
NS_IMETHOD GetNodeValue(nsAWritableString& aNodeValue) {
return mInner.GetNodeValue(aNodeValue);
}
NS_IMETHOD SetNodeValue(const nsAReadableString& aNodeValue) {
nsresult rv = mInner.SetNodeValue(this, aNodeValue);
UpdateStyleSheet(PR_TRUE);
return rv;
}
NS_IMETHOD GetNodeType(PRUint16* aNodeType);
NS_IMETHOD GetParentNode(nsIDOMNode** aParentNode) {
return mInner.GetParentNode(aParentNode);
}
NS_IMETHOD GetChildNodes(nsIDOMNodeList** aChildNodes) {
return mInner.GetChildNodes(aChildNodes);
}
NS_IMETHOD HasChildNodes(PRBool* aHasChildNodes) {
return mInner.HasChildNodes(aHasChildNodes);
}
NS_IMETHOD HasAttributes(PRBool* aHasAttributes) {
return mInner.HasAttributes(aHasAttributes);
}
NS_IMETHOD GetFirstChild(nsIDOMNode** aFirstChild) {
return mInner.GetFirstChild(aFirstChild);
}
NS_IMETHOD GetLastChild(nsIDOMNode** aLastChild) {
return mInner.GetLastChild(aLastChild);
}
NS_IMETHOD GetPreviousSibling(nsIDOMNode** aPreviousSibling) {
return mInner.GetPreviousSibling(this, aPreviousSibling);
}
NS_IMETHOD GetNextSibling(nsIDOMNode** aNextSibling) {
return mInner.GetNextSibling(this, aNextSibling);
}
NS_IMETHOD GetAttributes(nsIDOMNamedNodeMap** aAttributes) {
return mInner.GetAttributes(aAttributes);
}
NS_IMETHOD InsertBefore(nsIDOMNode* aNewChild, nsIDOMNode* aRefChild,
nsIDOMNode** aReturn) {
return mInner.InsertBefore(aNewChild, aRefChild, aReturn);
}
NS_IMETHOD AppendChild(nsIDOMNode* aOldChild, nsIDOMNode** aReturn) {
return mInner.AppendChild(aOldChild, aReturn);
}
NS_IMETHOD ReplaceChild(nsIDOMNode* aNewChild, nsIDOMNode* aOldChild,
nsIDOMNode** aReturn) {
return mInner.ReplaceChild(aNewChild, aOldChild, aReturn);
}
NS_IMETHOD RemoveChild(nsIDOMNode* aOldChild, nsIDOMNode** aReturn) {
return mInner.RemoveChild(aOldChild, aReturn);
}
NS_IMETHOD GetOwnerDocument(nsIDOMDocument** aOwnerDocument) {
return mInner.GetOwnerDocument(aOwnerDocument);
}
NS_IMETHOD GetNamespaceURI(nsAWritableString& aNamespaceURI) {
return mInner.GetNamespaceURI(aNamespaceURI);
}
NS_IMETHOD GetPrefix(nsAWritableString& aPrefix) {
return mInner.GetPrefix(aPrefix);
}
NS_IMETHOD SetPrefix(const nsAReadableString& aPrefix) {
return mInner.SetPrefix(aPrefix);
}
NS_IMETHOD Normalize() {
return NS_OK;
}
NS_IMETHOD IsSupported(const nsAReadableString& aFeature,
const nsAReadableString& aVersion,
PRBool* aReturn) {
return mInner.IsSupported(aFeature, aVersion, aReturn);
}
NS_IMETHOD GetBaseURI(nsAWritableString& aURI) {
return mInner.GetBaseURI(aURI);
}
NS_IMETHOD CloneNode(PRBool aDeep, nsIDOMNode** aReturn);
// nsIDOMProcessingInstruction
NS_DECL_NSIDOMPROCESSINGINSTRUCTION
// nsIDOMLinkStyle
NS_DECL_NSIDOMLINKSTYLE
// nsIContent
NS_IMPL_ICONTENT_USING_GENERIC_DOM_DATA(mInner)
NS_IMETHOD GetDocument(nsIDocument*& aResult) const {
return mInner.GetDocument(aResult);
}
NS_IMETHOD SetDocument(nsIDocument* aDocument, PRBool aDeep,
PRBool aCompileEventHandlers) {
nsIDocument *oldDoc = mInner.mDocument;
nsresult rv = mInner.SetDocument(aDocument, aDeep, aCompileEventHandlers);
UpdateStyleSheet(PR_TRUE, oldDoc);
return rv;
}
NS_IMETHOD GetParent(nsIContent*& aResult) const {
return mInner.GetParent(aResult);
}
NS_IMETHOD SetParent(nsIContent* aParent) {
return mInner.SetParent(aParent);
}
NS_IMETHOD CanContainChildren(PRBool& aResult) const {
return mInner.CanContainChildren(aResult);
}
NS_IMETHOD ChildCount(PRInt32& aResult) const {
return mInner.ChildCount(aResult);
}
NS_IMETHOD ChildAt(PRInt32 aIndex, nsIContent*& aResult) const {
return mInner.ChildAt(aIndex, aResult);
}
NS_IMETHOD IndexOf(nsIContent* aPossibleChild, PRInt32& aResult) const {
return mInner.IndexOf(aPossibleChild, aResult);
}
NS_IMETHOD InsertChildAt(nsIContent* aKid, PRInt32 aIndex,
PRBool aNotify, PRBool aDeepSetDocument) {
return mInner.InsertChildAt(aKid, aIndex, aNotify, aDeepSetDocument);
}
NS_IMETHOD ReplaceChildAt(nsIContent* aKid, PRInt32 aIndex,
PRBool aNotify, PRBool aDeepSetDocument) {
return mInner.ReplaceChildAt(aKid, aIndex, aNotify, aDeepSetDocument);
}
NS_IMETHOD AppendChildTo(nsIContent* aKid, PRBool aNotify,
PRBool aDeepSetDocument) {
return mInner.AppendChildTo(aKid, aNotify, aDeepSetDocument);
}
NS_IMETHOD RemoveChildAt(PRInt32 aIndex, PRBool aNotify) {
return mInner.RemoveChildAt(aIndex, aNotify);
}
NS_IMETHOD GetNameSpaceID(PRInt32& aID) const {
return mInner.GetNameSpaceID(aID);
}
NS_IMETHOD GetTag(nsIAtom*& aResult) const;
NS_IMETHOD GetNodeInfo(nsINodeInfo*& aResult) const;
NS_IMETHOD NormalizeAttributeString(const nsAReadableString& aStr,
nsINodeInfo*& aNodeInfo) {
return mInner.NormalizeAttributeString(aStr, aNodeInfo);
}
NS_IMETHOD GetAttribute(PRInt32 aNameSpaceID, nsIAtom *aAttribute,
nsAWritableString& aResult) const {
return mInner.GetAttribute(aNameSpaceID, aAttribute, aResult);
}
NS_IMETHOD GetAttribute(PRInt32 aNameSpaceID, nsIAtom *aAttribute,
nsIAtom*& aPrefix, nsAWritableString& aResult) const {
return mInner.GetAttribute(aNameSpaceID, aAttribute, aPrefix, aResult);
}
NS_IMETHOD SetAttribute(PRInt32 aNameSpaceID, nsIAtom* aAttribute,
const nsAReadableString& aValue, PRBool aNotify) {
return mInner.SetAttribute(aNameSpaceID, aAttribute, aValue, aNotify);
}
NS_IMETHOD SetAttribute(nsINodeInfo* aNodeInfo,
const nsAReadableString& aValue, PRBool aNotify) {
return mInner.SetAttribute(aNodeInfo, aValue, aNotify);
}
NS_IMETHOD UnsetAttribute(PRInt32 aNameSpaceID, nsIAtom* aAttribute,
PRBool aNotify) {
return mInner.UnsetAttribute(aNameSpaceID, aAttribute, aNotify);
}
NS_IMETHOD GetAttributeNameAt(PRInt32 aIndex,
PRInt32& aNameSpaceID,
nsIAtom*& aName,
nsIAtom*& aPrefix) const {
return mInner.GetAttributeNameAt(aIndex, aNameSpaceID, aName, aPrefix);
}
NS_IMETHOD GetAttributeCount(PRInt32& aResult) const {
return mInner.GetAttributeCount(aResult);
}
NS_IMETHOD List(FILE* out, PRInt32 aIndent) const;
NS_IMETHOD DumpContent(FILE* out,
PRInt32 aIndent,
PRBool aDumpAll) const;
NS_IMETHOD HandleDOMEvent(nsIPresContext* aPresContext,
nsEvent* aEvent,
nsIDOMEvent** aDOMEvent,
PRUint32 aFlags,
nsEventStatus* aEventStatus);
NS_IMETHOD GetContentID(PRUint32* aID);
NS_IMETHOD SetContentID(PRUint32 aID);
NS_IMETHOD RangeAdd(nsIDOMRange& aRange){
return mInner.RangeAdd(aRange);
}
NS_IMETHOD RangeRemove(nsIDOMRange& aRange){
return mInner.RangeRemove(aRange);
}
NS_IMETHOD GetRangeList(nsVoidArray*& aResult) const {
return mInner.GetRangeList(aResult);
}
NS_IMETHOD SetFocus(nsIPresContext* aPresContext) {
return mInner.SetFocus(aPresContext);
}
NS_IMETHOD RemoveFocus(nsIPresContext* aPresContext) {
return mInner.RemoveFocus(aPresContext);
}
NS_IMETHOD GetBindingParent(nsIContent** aContent) {
return mInner.GetBindingParent(aContent);
}
NS_IMETHOD SetBindingParent(nsIContent* aParent) {
return mInner.SetBindingParent(aParent);
}
NS_IMETHOD_(PRBool) IsContentOfType(PRUint32 aFlags);
NS_IMETHOD SizeOf(nsISizeOfHandler* aSizer, PRUint32* aResult) const;
void GetStyleSheetInfo(nsAWritableString& aUrl,
nsAWritableString& aTitle,
nsAWritableString& aType,
nsAWritableString& aMedia,
PRBool* aIsAlternate);
protected:
PRBool GetAttrValue(const char *aAttr, nsString& aValue);
@ -117,6 +312,8 @@ NS_INTERFACE_MAP_BEGIN(nsXMLProcessingInstruction)
NS_INTERFACE_MAP_ENTRY_DOM_DATA()
NS_INTERFACE_MAP_ENTRY(nsIDOMProcessingInstruction)
NS_INTERFACE_MAP_ENTRY(nsIDOMLinkStyle)
NS_INTERFACE_MAP_ENTRY(nsIStyleSheetLinkingElement)
NS_INTERFACE_MAP_ENTRY(nsICSSLoaderObserver)
NS_INTERFACE_MAP_ENTRY_CONTENT_CLASSINFO(ProcessingInstruction)
NS_INTERFACE_MAP_END
@ -142,9 +339,9 @@ nsXMLProcessingInstruction::GetData(nsAWritableString& aData)
NS_IMETHODIMP
nsXMLProcessingInstruction::SetData(const nsAReadableString& aData)
{
// XXX Check if this is a stylesheet PI. If so, we may need
// to parse the contents and see if anything has changed.
return mInner.SetData(this, aData);
nsresult rv = mInner.SetData(this, aData);
UpdateStyleSheet(PR_TRUE);
return rv;
}
PRBool
@ -194,64 +391,6 @@ nsXMLProcessingInstruction::GetAttrValue(const char *aAttr, nsString& aValue)
return PR_FALSE;
}
NS_IMETHODIMP
nsXMLProcessingInstruction::GetSheet(nsIDOMStyleSheet** aSheet)
{
NS_ENSURE_ARG_POINTER(aSheet);
*aSheet = nsnull;
if (!mInner.mDocument)
return NS_OK;
nsAutoString data;
GetData(data);
if (!mTarget.EqualsWithConversion("xml-stylesheet")) {
return NS_OK;
}
if (!GetAttrValue("href", data))
return NS_OK;
nsCOMPtr<nsIURI> baseURI;
mInner.mDocument->GetBaseURL(*getter_AddRefs(baseURI));
nsString href;
NS_MakeAbsoluteURI(href, data, baseURI);
PRInt32 i, count;
count = mInner.mDocument->GetNumberOfStyleSheets();
for (i = 0; i < count; i++) {
nsCOMPtr<nsIStyleSheet> sheet;
sheet = dont_AddRef(mInner.mDocument->GetStyleSheetAt(i));
if (!sheet)
continue;
nsCOMPtr<nsIURI> url;
sheet->GetURL(*getter_AddRefs(url));
if (!url)
continue;
nsXPIDLCString urlspec;
url->GetSpec(getter_Copies(urlspec));
if (href.EqualsWithConversion(urlspec)) {
return sheet->QueryInterface(NS_GET_IID(nsIDOMStyleSheet),
(void **)aSheet);
}
}
return NS_OK;
}
NS_IMETHODIMP
nsXMLProcessingInstruction::GetTag(nsIAtom*& aResult) const
{
@ -366,3 +505,85 @@ nsXMLProcessingInstruction::IsContentOfType(PRUint32 aFlags)
{
return PR_FALSE;
}
void
nsXMLProcessingInstruction::GetStyleSheetInfo(nsAWritableString& aUrl,
nsAWritableString& aTitle,
nsAWritableString& aType,
nsAWritableString& aMedia,
PRBool* aIsAlternate)
{
nsresult rv = NS_OK;
aUrl.Truncate();
aTitle.Truncate();
aType.Truncate();
aMedia.Truncate();
*aIsAlternate = PR_FALSE;
if (!mTarget.Equals(NS_LITERAL_STRING("xml-stylesheet"))) {
return;
}
nsAutoString href, title, type, media, alternate;
GetAttrValue("href", href);
if (href.IsEmpty()) {
// if href is empty then just bail
return;
}
GetAttrValue("title", title);
title.CompressWhitespace();
aTitle.Assign(title);
GetAttrValue("alternate", alternate);
// if alternate, does it have title?
if (alternate.Equals(NS_LITERAL_STRING("yes"))) {
if (aTitle.IsEmpty()) { // alternates must have title
return;
} else {
*aIsAlternate = PR_TRUE;
}
}
GetAttrValue("media", media);
aMedia.Assign(media);
ToLowerCase(aMedia); // case sensitivity?
GetAttrValue("type", type);
nsAutoString mimeType;
nsAutoString notUsed;
SplitMimeType(type, mimeType, notUsed);
if (!mimeType.EqualsIgnoreCase("text/css")) {
aType.Assign(type);
return;
}
// If we get here we assume that we're loading a css file, so set the
// type to 'text/css'
aType.Assign(NS_LITERAL_STRING("text/css"));
nsCOMPtr<nsIURI> url, baseURL;
if (mInner.mDocument) {
mInner.mDocument->GetBaseURL(*getter_AddRefs(baseURL));
}
rv = NS_MakeAbsoluteURI(aUrl, href, baseURL);
if (*aIsAlternate) {
if (!aTitle.IsEmpty()) { // possibly preferred sheet
nsAutoString prefStyle;
mInner.mDocument->GetHeaderData(nsHTMLAtoms::headerDefaultStyle,
prefStyle);
if (prefStyle.IsEmpty()) {
mInner.mDocument->SetHeaderData(nsHTMLAtoms::headerDefaultStyle,
title);
}
}
}
return;
}

View File

@ -40,6 +40,7 @@
#include "nsIDocShellTreeItem.h"
#include "nsIContent.h"
#include "nsITextContent.h"
#include "nsIStyleSheetLinkingElement.h"
#include "nsIPresContext.h"
#include "nsIPresShell.h"
#include "nsIViewManager.h"
@ -73,8 +74,10 @@
#include "nsParserUtils.h"
#include "nsIDocumentViewer.h"
#include "nsIScrollable.h"
#include "nsGenericElement.h"
#include "nsIWebNavigation.h"
#include "nsIScriptElement.h"
#include "nsStyleLinkElement.h"
// XXX misnamed header file, but oh well
#include "nsHTMLTokens.h"
@ -213,10 +216,6 @@ nsXMLContentSink::Init(nsIDocument* aDoc,
mDocElement = nsnull;
mRootElement = nsnull;
// XXX this presumes HTTP header info is alread set in document
// XXX if it isn't we need to set it here...
mDocument->GetHeaderData(nsHTMLAtoms::headerDefaultStyle, mPreferredStyle);
nsIHTMLContentContainer* htmlContainer = nsnull;
if (NS_SUCCEEDED(aDoc->QueryInterface(NS_GET_IID(nsIHTMLContentContainer), (void**)&htmlContainer))) {
htmlContainer->GetCSSLoader(mCSSLoader);
@ -638,10 +637,6 @@ nsXMLContentSink::OpenContainer(const nsIParserNode& aNode)
if (!mMetaElement) {
mMetaElement = htmlContent;
}
} else if (tagAtom.get() == nsHTMLAtoms::link) {
if (!mLinkElement) {
mLinkElement = htmlContent;
}
}
}
else {
@ -669,10 +664,19 @@ nsXMLContentSink::OpenContainer(const nsIParserNode& aNode)
PRInt32 id;
mDocument->GetAndIncrementContentID(&id);
content->SetContentID(id);
nsCOMPtr<nsIStyleSheetLinkingElement> ssle(do_QueryInterface(content));
if (ssle) {
ssle->InitStyleLinkElement(mParser, PR_FALSE);
ssle->SetEnableUpdates(PR_FALSE);
}
content->SetDocument(mDocument, PR_FALSE, PR_TRUE);
// Set the attributes on the new content element
result = AddAttributes(aNode, content, isHTML);
if (NS_OK == result) {
// If this is the document element
if (nsnull == mDocElement) {
@ -700,6 +704,15 @@ nsXMLContentSink::OpenContainer(const nsIParserNode& aNode)
result = aNode.GetIDAttributeAtom(getter_AddRefs(IDAttr));
if (IDAttr && NS_SUCCEEDED(result))
result = nodeInfo->SetIDAttributeAtom(IDAttr);
// We stopped supporting <style src="..."> for XHTML as it is
// non-standard.
if (ssle && !(isHTML && (tagAtom.get() == nsHTMLAtoms::style))) {
ssle->SetEnableUpdates(PR_TRUE);
result = ssle->UpdateStyleSheet(PR_TRUE, mDocument, mStyleSheetCount);
if (NS_SUCCEEDED(result) || (result == NS_ERROR_HTMLPARSER_BLOCK))
mStyleSheetCount++;
}
}
return result;
@ -764,11 +777,6 @@ nsXMLContentSink::CloseContainer(const nsIParserNode& aNode)
result = ProcessMETATag();
mMetaElement = nsnull; // HTML can have more than one meta so clear this now
}
} else if (tagAtom.get() == nsHTMLAtoms::link) {
if (mLinkElement) {
result = ProcessLINKTag();
mLinkElement = nsnull; // HTML can have more than one link so clear this now
}
}
}
@ -952,22 +960,6 @@ ParseProcessingInstruction(const nsString& aText,
}
}
static void SplitMimeType(const nsString& aValue, nsString& aType, nsString& aParams)
{
aType.Truncate();
aParams.Truncate();
PRInt32 semiIndex = aValue.FindChar(PRUnichar(';'));
if (-1 != semiIndex) {
aValue.Left(aType, semiIndex);
aValue.Right(aParams, (aValue.Length() - semiIndex) - 1);
aParams.StripWhitespace();
}
else {
aType = aValue;
}
aType.StripWhitespace();
}
nsresult
nsXMLContentSink::CreateStyleSheetURL(nsIURI** aUrl,
const nsAReadableString& aHref)
@ -1055,8 +1047,6 @@ nsXMLContentSink::ProcessStyleLink(nsIContent* aElement,
if (aType.EqualsIgnoreCase(kXSLType))
rv = ProcessXSLStyleLink(aElement, aHref, aAlternate, aTitle, aType, aMedia);
else
rv = ProcessCSSStyleLink(aElement, aHref, aAlternate, aTitle, aType, aMedia);
return rv;
}
@ -1082,60 +1072,6 @@ nsXMLContentSink::ProcessXSLStyleLink(nsIContent* aElement,
return rv;
}
nsresult
nsXMLContentSink::ProcessCSSStyleLink(nsIContent* aElement,
const nsString& aHref, PRBool aAlternate,
const nsString& aTitle, const nsString& aType,
const nsString& aMedia)
{
nsresult result = NS_OK;
if (aAlternate) { // if alternate, does it have title?
if (0 == aTitle.Length()) { // alternates must have title
return NS_OK; //return without error, for now
}
}
nsAutoString mimeType;
nsAutoString params;
SplitMimeType(aType, mimeType, params);
if ((0 == mimeType.Length()) || mimeType.EqualsIgnoreCase("text/css")) {
nsIURI* url = nsnull;
// XXX we need to get passed in the nsILoadGroup here!
// nsILoadGroup* group = mDocument->GetDocumentLoadGroup();
result = NS_NewURI(&url, aHref, mDocumentBaseURL/*, group*/);
if (NS_OK != result) {
return NS_OK; // The URL is bad, move along, don't propogate the error (for now)
}
PRBool blockParser = PR_FALSE;
if (! aAlternate) {
if (0 < aTitle.Length()) { // possibly preferred sheet
if (0 == mPreferredStyle.Length()) {
mPreferredStyle = aTitle;
mCSSLoader->SetPreferredSheet(aTitle);
mDocument->SetHeaderData(nsHTMLAtoms::headerDefaultStyle, aTitle);
}
}
else { // persistent sheet, block
blockParser = PR_TRUE;
}
}
PRBool doneLoading;
result = mCSSLoader->LoadStyleLink(aElement, url, aTitle, aMedia, kNameSpaceID_Unknown,
mStyleSheetCount++,
((blockParser) ? mParser : nsnull),
doneLoading, nsnull);
NS_RELEASE(url);
if (NS_SUCCEEDED(result) && blockParser && (! doneLoading)) {
result = NS_ERROR_HTMLPARSER_BLOCK;
}
}
return result;
}
NS_IMETHODIMP
nsXMLContentSink::StyleSheetLoaded(nsICSSStyleSheet* aSheet,
PRBool aDidNotify)
@ -1156,15 +1092,16 @@ nsXMLContentSink::ProcessSTYLETag(const nsIParserNode& aNode)
nsAutoString type;
nsAutoString media;
nsCOMPtr<nsIAtom> name, prefix;
PRInt32 namespaceID;
if (NS_FAILED(mStyleElement->GetAttribute(namespaceID, *getter_AddRefs(name),src)))
return rv;
src.StripWhitespace();
for (i = 0; i < count; i++) {
PRInt32 namespaceID;
nsCOMPtr<nsIAtom> name, prefix;
mStyleElement->GetAttributeNameAt(i,namespaceID,*getter_AddRefs(name),*getter_AddRefs(prefix));
if (name.get() == nsHTMLAtoms::src) {
mStyleElement->GetAttribute(namespaceID,name,src);
src.StripWhitespace();
}
else if (name.get() == nsHTMLAtoms::title) {
if (name.get() == nsHTMLAtoms::title) {
mStyleElement->GetAttribute(namespaceID,name,title);
title.CompressWhitespace();
}
@ -1180,16 +1117,15 @@ nsXMLContentSink::ProcessSTYLETag(const nsIParserNode& aNode)
nsAutoString mimeType;
nsAutoString params;
SplitMimeType(type, mimeType, params);
nsStyleLinkElement::SplitMimeType(type, mimeType, params);
PRBool blockParser = PR_FALSE;//kBlockByDefault;
if ((0 == mimeType.Length()) || mimeType.EqualsIgnoreCase("text/css")) {
if (0 < title.Length()) { // possibly preferred sheet
if (0 == mPreferredStyle.Length()) {
mPreferredStyle = title;
mCSSLoader->SetPreferredSheet(title);
if (mimeType.IsEmpty() || mimeType.EqualsIgnoreCase("text/css")) {
if (!title.IsEmpty()) { // possibly preferred sheet
nsAutoString preferredStyle;
mDocument->GetHeaderData(nsHTMLAtoms::headerDefaultStyle, preferredStyle);
if (preferredStyle.IsEmpty()) {
mDocument->SetHeaderData(nsHTMLAtoms::headerDefaultStyle, title);
}
}
@ -1197,62 +1133,38 @@ nsXMLContentSink::ProcessSTYLETag(const nsIParserNode& aNode)
PRBool doneLoading = PR_FALSE;
nsIUnicharInputStream* uin = nsnull;
if (0 == src.Length()) {
// Create a text node holding the content
nsCOMPtr<nsIContent> text;
rv = NS_NewTextNode(getter_AddRefs(text));
if (text) {
nsCOMPtr<nsIDOMText> tc(do_QueryInterface(text));
if (tc) {
tc->SetData(mStyleText);
}
mStyleElement->AppendChildTo(text, PR_FALSE, PR_FALSE);
text->SetDocument(mDocument, PR_FALSE, PR_TRUE);
// Create a text node holding the content
nsCOMPtr<nsIContent> text;
rv = NS_NewTextNode(getter_AddRefs(text));
if (text) {
nsCOMPtr<nsIDOMText> tc(do_QueryInterface(text));
if (tc) {
tc->SetData(mStyleText);
}
// Create a string to hold the data and wrap it up in a unicode
// input stream.
rv = NS_NewStringUnicharInputStream(&uin, new nsString(mStyleText));
if (NS_OK != rv) {
return rv;
}
// Now that we have a url and a unicode input stream, parse the
// style sheet.
rv = mCSSLoader->LoadInlineStyle(mStyleElement, uin, title, media, kNameSpaceID_Unknown,
mStyleSheetCount++,
((blockParser) ? mParser : nsnull),
doneLoading, this);
NS_RELEASE(uin);
}
else {
#if 0
// This is non-standard. We support it for HTML for backwards compatibility,
// but maybe we should withdraw the support for XHTML.
// src with immediate style data doesn't add up
// XXX what does nav do?
// Use the SRC attribute value to load the URL
nsIURI* url = nsnull;
{
rv = NS_NewURI(&url, src, mDocumentBaseURL);
}
if (NS_OK != rv) {
return rv;
}
rv = mCSSLoader->LoadStyleLink(mStyleElement, url, title, media, kNameSpaceID_Unknown,
mStyleSheetCount++,
((blockParser) ? mParser : nsnull),
doneLoading, this);
NS_RELEASE(url);
#endif
mStyleElement->AppendChildTo(text, PR_FALSE, PR_FALSE);
text->SetDocument(mDocument, PR_FALSE, PR_TRUE);
}
// Create a string to hold the data and wrap it up in a unicode
// input stream.
rv = NS_NewStringUnicharInputStream(&uin, new nsString(mStyleText));
if (NS_OK != rv) {
return rv;
}
// Now that we have a url and a unicode input stream, parse the
// style sheet.
rv = mCSSLoader->LoadInlineStyle(mStyleElement, uin, title, media, kNameSpaceID_Unknown,
mStyleSheetCount++,
((blockParser) ? mParser : nsnull),
doneLoading, this);
NS_RELEASE(uin);
if (NS_SUCCEEDED(rv) && blockParser && (! doneLoading)) {
rv = NS_ERROR_HTMLPARSER_BLOCK;
}
}//if ((0 == mimeType.Length()) || mimeType.EqualsIgnoreCase("text/css"))
}//if (mimeType.IsEmpty() || mimeType.EqualsIgnoreCase("text/css"))
return rv;
}
@ -1333,38 +1245,6 @@ nsXMLContentSink::ProcessMETATag()
return rv;
}
nsresult
nsXMLContentSink::ProcessLINKTag()
{
nsresult result = NS_OK;
nsAutoString href;
nsAutoString rel;
nsAutoString title;
nsAutoString type;
nsAutoString media;
mLinkElement->GetAttribute(kNameSpaceID_HTML, nsHTMLAtoms::href, href);
mLinkElement->GetAttribute(kNameSpaceID_HTML, nsHTMLAtoms::rel, rel);
mLinkElement->GetAttribute(kNameSpaceID_HTML, nsHTMLAtoms::title, title);
mLinkElement->GetAttribute(kNameSpaceID_HTML, nsHTMLAtoms::type, type);
mLinkElement->GetAttribute(kNameSpaceID_HTML, nsHTMLAtoms::media, media);
href.CompressWhitespace();
rel.CompressWhitespace();
title.CompressWhitespace();
type.CompressWhitespace();
media.CompressWhitespace();
media.ToLowerCase(); // HTML4.0 spec is inconsistent, make it case INSENSITIVE
if (!href.IsEmpty()) {
result = ProcessStyleLink(mLinkElement, href, rel.Find("alternate") == 0, title, type, media);
}
return result;
}
NS_IMETHODIMP
nsXMLContentSink::AddProcessingInstruction(const nsIParserNode& aNode)
{
@ -1378,25 +1258,38 @@ nsXMLContentSink::AddProcessingInstruction(const nsIParserNode& aNode)
ParseProcessingInstruction(text, target, data);
result = NS_NewXMLProcessingInstruction(getter_AddRefs(node), target, data);
if (NS_OK == result) {
node->SetDocument(mDocument, PR_FALSE, PR_TRUE);
nsCOMPtr<nsIStyleSheetLinkingElement> ssle(do_QueryInterface(node));
if (ssle) {
ssle->InitStyleLinkElement(mParser, PR_FALSE);
ssle->SetEnableUpdates(PR_FALSE);
}
result = AddContentAsLeaf(node);
}
if (NS_OK == result) {
nsAutoString type, href, title, media, alternate;
if (ssle) {
ssle->SetEnableUpdates(PR_TRUE);
result = ssle->UpdateStyleSheet(PR_TRUE, mDocument, mStyleSheetCount);
if (NS_SUCCEEDED(result) || (result == NS_ERROR_HTMLPARSER_BLOCK))
mStyleSheetCount++;
}
if (NS_FAILED(result))
return result;
nsAutoString type;
result = nsParserUtils::GetQuotedAttributeValue(text, NS_ConvertASCIItoUCS2("type"), type);
// If it's a XSL stylesheet PI...
if (target.EqualsWithConversion(kStyleSheetPI) && !type.EqualsIgnoreCase("text/css")) {
nsAutoString href, title, media, alternate;
// If it's a stylesheet PI...
if (target.EqualsWithConversion(kStyleSheetPI)) {
result = nsParserUtils::GetQuotedAttributeValue(text, NS_ConvertASCIItoUCS2("href"), href);
// If there was an error or there's no href, we can't do
// anything with this PI
if ((NS_OK != result) || href.IsEmpty()) {
return NS_OK;
}
result = nsParserUtils::GetQuotedAttributeValue(text, NS_ConvertASCIItoUCS2("type"), type);
if (NS_FAILED(result)) {
type.AssignWithConversion("text/css"); // Default the type attribute to the mime type for CSS
}
result = nsParserUtils::GetQuotedAttributeValue(text, NS_ConvertASCIItoUCS2("title"), title);
if (NS_SUCCEEDED(result)) {
title.CompressWhitespace();
@ -1406,6 +1299,7 @@ nsXMLContentSink::AddProcessingInstruction(const nsIParserNode& aNode)
media.ToLowerCase();
}
result = nsParserUtils::GetQuotedAttributeValue(text, NS_ConvertASCIItoUCS2("alternate"), alternate);
result = ProcessStyleLink(node, href, alternate.Equals(NS_LITERAL_STRING("yes")),
title, type, media);
}
@ -1694,7 +1588,6 @@ nsXMLContentSink::PopContent()
void
nsXMLContentSink::StartLayout()
{
// Reset scrolling to default settings for this shell.
// This must happen before the initial reflow, when we create the root frame
nsCOMPtr<nsIScrollable> scrollableContainer(do_QueryInterface(mWebShell));

View File

@ -183,7 +183,7 @@ NS_NewXMLDocument(nsIDocument** aInstancePtrResult)
nsXMLDocument::nsXMLDocument()
: mAttrStyleSheet(nsnull), mInlineStyleSheet(nsnull),
mParser(nsnull), mCSSLoader(nsnull)
mParser(nsnull)
{
}
@ -200,7 +200,6 @@ nsXMLDocument::~nsXMLDocument()
}
if (mCSSLoader) {
mCSSLoader->DropDocumentReference();
NS_RELEASE(mCSSLoader);
}
}
@ -1085,7 +1084,7 @@ nsXMLDocument::GetCSSLoader(nsICSSLoader*& aLoader)
{
nsresult result = NS_OK;
if (! mCSSLoader) {
result = NS_NewCSSLoader(this, &mCSSLoader);
result = NS_NewCSSLoader(this, getter_AddRefs(mCSSLoader));
if (mCSSLoader) {
mCSSLoader->SetCaseSensitive(PR_TRUE);
mCSSLoader->SetQuirkMode(PR_FALSE); // No quirks in XML

View File

@ -114,7 +114,6 @@ protected:
nsString mBaseTarget;
nsIParser *mParser;
nsICSSLoader* mCSSLoader;
};

View File

@ -318,6 +318,12 @@ public:
// then use that
// - othersise set the default charset
// stop loading all sheets
NS_IMETHOD Stop(void);
// stop loading one sheet
NS_IMETHOD StopLoadingSheet(nsIURI* aURL);
#ifdef NS_DEBUG
PRBool mSyncCallback;
#endif
@ -468,7 +474,9 @@ static PRBool PR_CALLBACK DeleteSheetMap(nsHashKey* aKey, void* aData, void* aCl
CSSLoaderImpl::~CSSLoaderImpl(void)
{
NS_ASSERTION(0 == mLoadingSheets.Count(), "destructing loader while sheets loading");
if (mLoadingSheets.Count() > 0) {
Stop();
}
NS_IF_RELEASE(mParsers);
mLoadedSheets.Enumerate(ReleaseSheet);
mLoadingSheets.Enumerate(DeleteHashLoadData);
@ -1651,3 +1659,39 @@ nsresult CSSLoaderImpl::SetCharset(/*in*/ const nsString &aHTTPHeader,
}
return rv;
}
static PRBool PR_CALLBACK StopLoadingSheetCallback(nsHashKey* aKey, void* aData, void* aClosure)
{
NS_ENSURE_TRUE(aData, NS_ERROR_NULL_POINTER);
SheetLoadData* data = (SheetLoadData*)aData;
NS_ENSURE_TRUE(data->mLoader, NS_ERROR_NULL_POINTER);
NS_ENSURE_TRUE(data->mURL, NS_ERROR_NULL_POINTER);
data->mLoader->StopLoadingSheet(data->mURL);
return PR_TRUE;
}
NS_IMETHODIMP
CSSLoaderImpl::Stop()
{
if (mLoadingSheets.Count() > 0) {
mLoadingSheets.Enumerate(StopLoadingSheetCallback);
}
return NS_OK;
}
NS_IMETHODIMP
CSSLoaderImpl::StopLoadingSheet(nsIURI* aURL)
{
NS_ENSURE_TRUE(aURL, NS_ERROR_NULL_POINTER);
if (mLoadingSheets.Count() > 0) {
URLKey key(aURL);
SheetLoadData* loadData = (SheetLoadData*)mLoadingSheets.Get(&key);
if (loadData) {
Cleanup(key, loadData);
}
}
return NS_OK;
}

View File

@ -113,6 +113,11 @@ public:
// if an empty string, then it is set to the default charset
NS_IMETHOD SetCharset(/*in*/ const nsString &aCharsetSrc) = 0;
// stop loading all sheets
NS_IMETHOD Stop(void) = 0;
// stop loading one sheet
NS_IMETHOD StopLoadingSheet(nsIURI* aURL) = 0;
};
extern NS_HTML nsresult