Clean up handling of quirk doctypes and case-sensitivity in the CSSOM.

Mostly just uses the nodeinfo more and combines some redundant code into
helpers. Bug 95336, bug 10622, bug 102815
This commit is contained in:
bzbarsky%mit.edu 2001-10-19 13:50:30 +00:00
Родитель b27b16b597
Коммит c13153fb53
6 изменённых файлов: 225 добавлений и 153 удалений

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

@ -56,6 +56,7 @@ class nsIElementFactory;
#define kNameSpaceID_XLink 4
#define kNameSpaceID_HTML2 5 // This is not a real namespace
#define kNameSpaceID_XSLT 6
#define kNameSpaceID_XHTML kNameSpaceID_HTML
// 'html' is by definition bound to the namespace name "urn:w3-org-ns:HTML" XXX ???
// 'xml' is by definition bound to the namespace name "urn:Connolly:input:required" XXX

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

@ -145,6 +145,10 @@ public:
virtual nsresult GetCSSDeclaration(nsICSSDeclaration **aDecl,
PRBool aAllocate);
virtual nsresult SetCSSDeclaration(nsICSSDeclaration *aDecl);
virtual nsresult GetCSSParsingEnvironment(nsIContent* aContent,
nsIURI** aBaseURI,
nsICSSLoader** aCSSLoader,
nsICSSParser** aCSSParser);
virtual nsresult ParsePropertyValue(const nsAReadableString& aPropName,
const nsAReadableString& aPropValue);
virtual nsresult ParseDeclaration(const nsAReadableString& aDecl,
@ -293,6 +297,58 @@ nsDOMCSSAttributeDeclaration::SetCSSDeclaration(nsICSSDeclaration *aDecl)
return result;
}
/*
* This is a utility function. It will only fail if it can't get a
* parser. This means it can return NS_OK without aURI or aCSSLoader
* being initialized
*/
nsresult
nsDOMCSSAttributeDeclaration::GetCSSParsingEnvironment(nsIContent* aContent,
nsIURI** aBaseURI,
nsICSSLoader** aCSSLoader,
nsICSSParser** aCSSParser)
{
NS_ASSERTION(aContent, "Something is severely broken -- there should be an nsIContent here!");
// null out the out params since some of them may not get initialized below
*aBaseURI = nsnull;
*aCSSLoader = nsnull;
*aCSSParser = nsnull;
nsCOMPtr<nsINodeInfo> nodeInfo;
nsresult result = aContent->GetNodeInfo(*getter_AddRefs(nodeInfo));
if (NS_FAILED(result)) {
return result;
}
nsCOMPtr<nsIDocument> doc;
result = nodeInfo->GetDocument(*getter_AddRefs(doc));
if (NS_FAILED(result)) {
return result;
}
if (doc) {
doc->GetBaseURL(*aBaseURI);
nsCOMPtr<nsIHTMLContentContainer> htmlContainer(do_QueryInterface(doc));
if (htmlContainer) {
htmlContainer->GetCSSLoader(*aCSSLoader);
}
NS_ASSERTION(*aCSSLoader, "Document with no CSS loader!");
}
if (*aCSSLoader) {
result = (*aCSSLoader)->GetParserFor(nsnull, aCSSParser);
} else {
result = NS_NewCSSParser(aCSSParser);
}
if (NS_FAILED(result)) {
return result;
}
// look up our namespace. If we're XHTML, we need to be case-sensitive
// Otherwise, we should not be
(*aCSSParser)->SetCaseSensitive(nodeInfo->NamespaceEquals(kNameSpaceID_XHTML));
return NS_OK;
}
nsresult
nsDOMCSSAttributeDeclaration::ParsePropertyValue(const nsAReadableString& aPropName,
const nsAReadableString& aPropValue)
@ -314,21 +370,10 @@ nsDOMCSSAttributeDeclaration::ParsePropertyValue(const nsAReadableString& aPropN
return result;
}
if (doc) {
doc->GetBaseURL(*getter_AddRefs(baseURI));
nsCOMPtr<nsIHTMLContentContainer> htmlContainer(do_QueryInterface(doc));
if (htmlContainer) {
htmlContainer->GetCSSLoader(*getter_AddRefs(cssLoader));
}
}
if (cssLoader) {
result = cssLoader->GetParserFor(nsnull, getter_AddRefs(cssParser));
}
else {
result = NS_NewCSSParser(getter_AddRefs(cssParser));
}
result = GetCSSParsingEnvironment(mContent,
getter_AddRefs(baseURI),
getter_AddRefs(cssLoader),
getter_AddRefs(cssParser));
if (NS_FAILED(result)) {
return result;
}
@ -339,21 +384,6 @@ nsDOMCSSAttributeDeclaration::ParsePropertyValue(const nsAReadableString& aPropN
doc->AttributeWillChange(mContent, kNameSpaceID_None, nsHTMLAtoms::style);
}
nsCOMPtr<nsINodeInfo> nodeInfo;
mContent->GetNodeInfo(*getter_AddRefs(nodeInfo));
if (nodeInfo) {
nsCOMPtr<nsIDocument> doc;
nodeInfo->GetDocument(*getter_AddRefs(doc));
if (doc) {
nsCOMPtr<nsIHTMLDocument> htmlDoc(do_QueryInterface(doc));
if (htmlDoc) {
nsDTDMode mode;
htmlDoc->GetDTDMode(mode);
cssParser->SetQuirkMode(eDTDMode_strict != mode);
}
}
}
result = cssParser->ParseProperty(aPropName, aPropValue, baseURI, decl, &hint);
if (doc) {
doc->AttributeChanged(mContent, kNameSpaceID_None,
@ -384,21 +414,13 @@ nsDOMCSSAttributeDeclaration::ParseDeclaration(const nsAReadableString& aDecl,
nsCOMPtr<nsIDocument> doc;
result = mContent->GetDocument(*getter_AddRefs(doc));
if (doc) {
doc->GetBaseURL(*getter_AddRefs(baseURI));
nsCOMPtr<nsIHTMLContentContainer> htmlContainer(do_QueryInterface(doc));
if (htmlContainer) {
htmlContainer->GetCSSLoader(*getter_AddRefs(cssLoader));
}
}
if (cssLoader) {
result = cssLoader->GetParserFor(nsnull, getter_AddRefs(cssParser));
}
else {
result = NS_NewCSSParser(getter_AddRefs(cssParser));
if (NS_FAILED(result)) {
return result;
}
result = GetCSSParsingEnvironment(mContent,
getter_AddRefs(baseURI),
getter_AddRefs(cssLoader),
getter_AddRefs(cssParser));
if (NS_SUCCEEDED(result)) {
PRInt32 hint;
@ -428,21 +450,6 @@ nsDOMCSSAttributeDeclaration::ParseDeclaration(const nsAReadableString& aDecl,
}
}
nsCOMPtr<nsINodeInfo> nodeInfo;
mContent->GetNodeInfo(*getter_AddRefs(nodeInfo));
if (nodeInfo) {
nsCOMPtr<nsIDocument> doc;
nodeInfo->GetDocument(*getter_AddRefs(doc));
if (doc) {
nsCOMPtr<nsIHTMLDocument> htmlDoc(do_QueryInterface(doc));
if (htmlDoc) {
nsDTDMode mode;
htmlDoc->GetDTDMode(mode);
cssParser->SetQuirkMode(eDTDMode_strict != mode);
}
}
}
result = cssParser->ParseAndAppendDeclaration(aDecl, baseURI, decl,
aParseOnlyOneDecl, &hint);
if (result == NS_CSS_PARSER_DROP_DECLARATION) {
@ -3500,6 +3507,14 @@ nsGenericHTMLElement::ParseStyleAttribute(const nsAReadableString& aValue, nsHTM
}
else {
result = NS_NewCSSParser(getter_AddRefs(cssParser));
if (cssParser) {
// look up our namespace. If we're XHTML, we need to be case-sensitive
// Otherwise, we should not be.
nsCOMPtr<nsINodeInfo> nodeInfo;
result = GetNodeInfo(*getter_AddRefs(nodeInfo));
NS_ENSURE_SUCCESS(result, result);
cssParser->SetCaseSensitive(nodeInfo->NamespaceEquals(kNameSpaceID_XHTML));
}
}
if (cssParser) {
nsCOMPtr<nsIURI> docURL;

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

@ -1067,6 +1067,12 @@ public:
virtual nsresult GetCSSDeclaration(nsICSSDeclaration **aDecl,
PRBool aAllocate);
virtual nsresult SetCSSDeclaration(nsICSSDeclaration *aDecl);
virtual nsresult GetCSSParsingEnvironment(nsICSSStyleRule* aRule,
nsICSSStyleSheet** aSheet,
nsIDocument** aDocument,
nsIURI** aURI,
nsICSSLoader** aCSSLoader,
nsICSSParser** aCSSParser);
virtual nsresult ParsePropertyValue(const nsAReadableString& aPropName,
const nsAReadableString& aPropValue);
virtual nsresult ParseDeclaration(const nsAReadableString& aDecl,
@ -1153,6 +1159,49 @@ DOMCSSDeclarationImpl::SetCSSDeclaration(nsICSSDeclaration *aDecl)
return NS_OK;
}
/*
* This is a utility function. It will only fail if it can't get a
* parser. This means it can return NS_OK without all of aSheet,
* aDocument, aURI, aCSSLoader being initialized
*/
nsresult
DOMCSSDeclarationImpl::GetCSSParsingEnvironment(nsICSSStyleRule* aRule,
nsICSSStyleSheet** aSheet,
nsIDocument** aDocument,
nsIURI** aURI,
nsICSSLoader** aCSSLoader,
nsICSSParser** aCSSParser)
{
// null out the out params since some of them may not get initialized below
*aSheet = nsnull;
*aDocument = nsnull;
*aURI = nsnull;
*aCSSLoader = nsnull;
*aCSSParser = nsnull;
nsresult result;
nsCOMPtr<nsIStyleSheet> sheet;
if (aRule) {
aRule->GetStyleSheet(*getter_AddRefs(sheet));
if (sheet) {
CallQueryInterface(sheet, aSheet);
sheet->GetOwningDocument(*aDocument);
sheet->GetURL(*aURI);
}
}
nsCOMPtr<nsIHTMLContentContainer> htmlContainer(do_QueryInterface(*aDocument));
if (htmlContainer) {
htmlContainer->GetCSSLoader(*aCSSLoader);
}
NS_ASSERTION(*aCSSLoader || !*aDocument, "Document with no CSS loader!");
if (*aCSSLoader) {
result = (*aCSSLoader)->GetParserFor(nsnull, aCSSParser);
} else {
result = NS_NewCSSParser(aCSSParser);
}
return result;
}
nsresult
DOMCSSDeclarationImpl::ParsePropertyValue(const nsAReadableString& aPropName,
const nsAReadableString& aPropValue)
@ -1167,30 +1216,17 @@ DOMCSSDeclarationImpl::ParsePropertyValue(const nsAReadableString& aPropName,
nsCOMPtr<nsIURI> baseURI;
nsCOMPtr<nsICSSStyleSheet> cssSheet;
nsCOMPtr<nsIDocument> owningDoc;
nsCOMPtr<nsIStyleSheet> sheet;
if (mRule) {
mRule->GetStyleSheet(*getter_AddRefs(sheet));
if (sheet) {
sheet->GetURL(*getter_AddRefs(baseURI));
sheet->GetOwningDocument(*getter_AddRefs(owningDoc));
cssSheet = do_QueryInterface(sheet);
if (owningDoc) {
nsCOMPtr<nsIHTMLContentContainer> htmlContainer(do_QueryInterface(owningDoc));
if (htmlContainer) {
htmlContainer->GetCSSLoader(*getter_AddRefs(cssLoader));
}
}
}
}
if (cssLoader) {
result = cssLoader->GetParserFor(nsnull, getter_AddRefs(cssParser));
}
else {
result = NS_NewCSSParser(getter_AddRefs(cssParser));
}
result = GetCSSParsingEnvironment(mRule,
getter_AddRefs(cssSheet),
getter_AddRefs(owningDoc),
getter_AddRefs(baseURI),
getter_AddRefs(cssLoader),
getter_AddRefs(cssParser));
if (NS_FAILED(result)) {
return result;
}
PRInt32 hint;
if (owningDoc) {
owningDoc->BeginUpdate();
@ -1227,27 +1263,12 @@ DOMCSSDeclarationImpl::ParseDeclaration(const nsAReadableString& aDecl,
nsCOMPtr<nsICSSStyleSheet> cssSheet;
nsCOMPtr<nsIDocument> owningDoc;
nsCOMPtr<nsIStyleSheet> sheet;
if (mRule) {
mRule->GetStyleSheet(*getter_AddRefs(sheet));
if (sheet) {
sheet->GetURL(*getter_AddRefs(baseURI));
sheet->GetOwningDocument(*getter_AddRefs(owningDoc));
cssSheet = do_QueryInterface(sheet);
if (owningDoc) {
nsCOMPtr<nsIHTMLContentContainer> htmlContainer(do_QueryInterface(owningDoc));
if (htmlContainer) {
htmlContainer->GetCSSLoader(*getter_AddRefs(cssLoader));
}
}
}
}
if (cssLoader) {
result = cssLoader->GetParserFor(nsnull, getter_AddRefs(cssParser));
}
else {
result = NS_NewCSSParser(getter_AddRefs(cssParser));
}
result = GetCSSParsingEnvironment(mRule,
getter_AddRefs(cssSheet),
getter_AddRefs(owningDoc),
getter_AddRefs(baseURI),
getter_AddRefs(cssLoader),
getter_AddRefs(cssParser));
if (NS_SUCCEEDED(result)) {
nsCOMPtr<nsICSSDeclaration> declClone;

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

@ -2794,16 +2794,19 @@ CSSStyleSheetImpl::InsertRule(const nsAReadableString& aRule,
if (htmlContainer) {
htmlContainer->GetCSSLoader(*getter_AddRefs(loader));
}
NS_ASSERTION(loader || !mDocument, "Document with no CSS loader!");
if (loader) {
result = loader->GetParserFor(this, getter_AddRefs(css));
}
else {
result = NS_NewCSSParser(getter_AddRefs(css));
css->SetStyleSheet(this);
if (css) {
css->SetStyleSheet(this);
}
}
if (NS_FAILED(result))
return result;
if (mDocument) {
result = mDocument->BeginUpdate();
if (NS_FAILED(result))
@ -2881,6 +2884,8 @@ CSSStyleSheetImpl::InsertRule(const nsAReadableString& aRule,
result = mInner->mOrderedRules->InsertElementsAt(rules, aIndex);
NS_ENSURE_SUCCESS(result, result);
DidDirty();
nsCOMPtr<nsICSSRule> cssRule;
PRUint32 counter;
for (counter = 0; counter < rulecount; counter++) {
@ -2923,8 +2928,6 @@ CSSStyleSheetImpl::InsertRule(const nsAReadableString& aRule,
}
}
DidDirty();
if (mDocument) {
result = mDocument->EndUpdate();
NS_ENSURE_SUCCESS(result, result);
@ -3046,12 +3049,16 @@ CSSStyleSheetImpl::InsertRuleIntoGroup(nsAReadableString & aRule, nsICSSGroupRul
if (htmlContainer) {
htmlContainer->GetCSSLoader(*getter_AddRefs(loader));
}
NS_ASSERTION(loader || !mDocument, "Document with no CSS loader!");
if (loader) {
result = loader->GetParserFor(this, getter_AddRefs(css));
}
else {
result = NS_NewCSSParser(getter_AddRefs(css));
css->SetStyleSheet(this);
if (css) {
css->SetStyleSheet(this);
}
}
NS_ENSURE_SUCCESS(result, result);

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

@ -1067,6 +1067,12 @@ public:
virtual nsresult GetCSSDeclaration(nsICSSDeclaration **aDecl,
PRBool aAllocate);
virtual nsresult SetCSSDeclaration(nsICSSDeclaration *aDecl);
virtual nsresult GetCSSParsingEnvironment(nsICSSStyleRule* aRule,
nsICSSStyleSheet** aSheet,
nsIDocument** aDocument,
nsIURI** aURI,
nsICSSLoader** aCSSLoader,
nsICSSParser** aCSSParser);
virtual nsresult ParsePropertyValue(const nsAReadableString& aPropName,
const nsAReadableString& aPropValue);
virtual nsresult ParseDeclaration(const nsAReadableString& aDecl,
@ -1153,6 +1159,49 @@ DOMCSSDeclarationImpl::SetCSSDeclaration(nsICSSDeclaration *aDecl)
return NS_OK;
}
/*
* This is a utility function. It will only fail if it can't get a
* parser. This means it can return NS_OK without all of aSheet,
* aDocument, aURI, aCSSLoader being initialized
*/
nsresult
DOMCSSDeclarationImpl::GetCSSParsingEnvironment(nsICSSStyleRule* aRule,
nsICSSStyleSheet** aSheet,
nsIDocument** aDocument,
nsIURI** aURI,
nsICSSLoader** aCSSLoader,
nsICSSParser** aCSSParser)
{
// null out the out params since some of them may not get initialized below
*aSheet = nsnull;
*aDocument = nsnull;
*aURI = nsnull;
*aCSSLoader = nsnull;
*aCSSParser = nsnull;
nsresult result;
nsCOMPtr<nsIStyleSheet> sheet;
if (aRule) {
aRule->GetStyleSheet(*getter_AddRefs(sheet));
if (sheet) {
CallQueryInterface(sheet, aSheet);
sheet->GetOwningDocument(*aDocument);
sheet->GetURL(*aURI);
}
}
nsCOMPtr<nsIHTMLContentContainer> htmlContainer(do_QueryInterface(*aDocument));
if (htmlContainer) {
htmlContainer->GetCSSLoader(*aCSSLoader);
}
NS_ASSERTION(*aCSSLoader || !*aDocument, "Document with no CSS loader!");
if (*aCSSLoader) {
result = (*aCSSLoader)->GetParserFor(nsnull, aCSSParser);
} else {
result = NS_NewCSSParser(aCSSParser);
}
return result;
}
nsresult
DOMCSSDeclarationImpl::ParsePropertyValue(const nsAReadableString& aPropName,
const nsAReadableString& aPropValue)
@ -1167,30 +1216,17 @@ DOMCSSDeclarationImpl::ParsePropertyValue(const nsAReadableString& aPropName,
nsCOMPtr<nsIURI> baseURI;
nsCOMPtr<nsICSSStyleSheet> cssSheet;
nsCOMPtr<nsIDocument> owningDoc;
nsCOMPtr<nsIStyleSheet> sheet;
if (mRule) {
mRule->GetStyleSheet(*getter_AddRefs(sheet));
if (sheet) {
sheet->GetURL(*getter_AddRefs(baseURI));
sheet->GetOwningDocument(*getter_AddRefs(owningDoc));
cssSheet = do_QueryInterface(sheet);
if (owningDoc) {
nsCOMPtr<nsIHTMLContentContainer> htmlContainer(do_QueryInterface(owningDoc));
if (htmlContainer) {
htmlContainer->GetCSSLoader(*getter_AddRefs(cssLoader));
}
}
}
}
if (cssLoader) {
result = cssLoader->GetParserFor(nsnull, getter_AddRefs(cssParser));
}
else {
result = NS_NewCSSParser(getter_AddRefs(cssParser));
}
result = GetCSSParsingEnvironment(mRule,
getter_AddRefs(cssSheet),
getter_AddRefs(owningDoc),
getter_AddRefs(baseURI),
getter_AddRefs(cssLoader),
getter_AddRefs(cssParser));
if (NS_FAILED(result)) {
return result;
}
PRInt32 hint;
if (owningDoc) {
owningDoc->BeginUpdate();
@ -1227,27 +1263,12 @@ DOMCSSDeclarationImpl::ParseDeclaration(const nsAReadableString& aDecl,
nsCOMPtr<nsICSSStyleSheet> cssSheet;
nsCOMPtr<nsIDocument> owningDoc;
nsCOMPtr<nsIStyleSheet> sheet;
if (mRule) {
mRule->GetStyleSheet(*getter_AddRefs(sheet));
if (sheet) {
sheet->GetURL(*getter_AddRefs(baseURI));
sheet->GetOwningDocument(*getter_AddRefs(owningDoc));
cssSheet = do_QueryInterface(sheet);
if (owningDoc) {
nsCOMPtr<nsIHTMLContentContainer> htmlContainer(do_QueryInterface(owningDoc));
if (htmlContainer) {
htmlContainer->GetCSSLoader(*getter_AddRefs(cssLoader));
}
}
}
}
if (cssLoader) {
result = cssLoader->GetParserFor(nsnull, getter_AddRefs(cssParser));
}
else {
result = NS_NewCSSParser(getter_AddRefs(cssParser));
}
result = GetCSSParsingEnvironment(mRule,
getter_AddRefs(cssSheet),
getter_AddRefs(owningDoc),
getter_AddRefs(baseURI),
getter_AddRefs(cssLoader),
getter_AddRefs(cssParser));
if (NS_SUCCEEDED(result)) {
nsCOMPtr<nsICSSDeclaration> declClone;

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

@ -2794,16 +2794,19 @@ CSSStyleSheetImpl::InsertRule(const nsAReadableString& aRule,
if (htmlContainer) {
htmlContainer->GetCSSLoader(*getter_AddRefs(loader));
}
NS_ASSERTION(loader || !mDocument, "Document with no CSS loader!");
if (loader) {
result = loader->GetParserFor(this, getter_AddRefs(css));
}
else {
result = NS_NewCSSParser(getter_AddRefs(css));
css->SetStyleSheet(this);
if (css) {
css->SetStyleSheet(this);
}
}
if (NS_FAILED(result))
return result;
if (mDocument) {
result = mDocument->BeginUpdate();
if (NS_FAILED(result))
@ -2881,6 +2884,8 @@ CSSStyleSheetImpl::InsertRule(const nsAReadableString& aRule,
result = mInner->mOrderedRules->InsertElementsAt(rules, aIndex);
NS_ENSURE_SUCCESS(result, result);
DidDirty();
nsCOMPtr<nsICSSRule> cssRule;
PRUint32 counter;
for (counter = 0; counter < rulecount; counter++) {
@ -2923,8 +2928,6 @@ CSSStyleSheetImpl::InsertRule(const nsAReadableString& aRule,
}
}
DidDirty();
if (mDocument) {
result = mDocument->EndUpdate();
NS_ENSURE_SUCCESS(result, result);
@ -3046,12 +3049,16 @@ CSSStyleSheetImpl::InsertRuleIntoGroup(nsAReadableString & aRule, nsICSSGroupRul
if (htmlContainer) {
htmlContainer->GetCSSLoader(*getter_AddRefs(loader));
}
NS_ASSERTION(loader || !mDocument, "Document with no CSS loader!");
if (loader) {
result = loader->GetParserFor(this, getter_AddRefs(css));
}
else {
result = NS_NewCSSParser(getter_AddRefs(css));
css->SetStyleSheet(this);
if (css) {
css->SetStyleSheet(this);
}
}
NS_ENSURE_SUCCESS(result, result);