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:
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user