css::Declaration* nsDOMCSSAttributeDeclaration::GetCSSDeclaration(PRBool aAllocate) { if (!mElement) return nsnull; css::StyleRule* cssRule; #ifdef MOZ_SMIL if (mIsSMILOverride) cssRule = mElement->GetSMILOverrideStyleRule(); else #endif // MOZ_SMIL cssRule = mElement->GetInlineStyleRule(); if (cssRule) { return cssRule->GetDeclaration(); } if (!aAllocate) { return nsnull; } // cannot fail css::Declaration *decl = new css::Declaration(); decl->InitializeEmpty(); nsRefPtr<css::StyleRule> newRule = NS_NewCSSStyleRule(nsnull, decl); // this *can* fail (inside SetAttrAndNotify, at least). nsresult rv; #ifdef MOZ_SMIL if (mIsSMILOverride) rv = mElement->SetSMILOverrideStyleRule(newRule, PR_FALSE); else #endif // MOZ_SMIL rv = mElement->SetInlineStyleRule(newRule, PR_FALSE); if (NS_FAILED(rv)) { return nsnull; // the decl will be destroyed along with the style rule } return decl; }
void nsSVGElement::UpdateContentStyleRule() { NS_ASSERTION(!mContentStyleRule, "we already have a content style rule"); nsIDocument* doc = GetOwnerDoc(); if (!doc) { NS_ERROR("SVG element without owner document"); return; } nsCOMPtr<nsIURI> baseURI = GetBaseURI(); nsIURI *docURI = doc->GetDocumentURI(); nsICSSLoader* cssLoader = doc->CSSLoader(); nsCSSDeclaration* declaration = nsnull; nsCOMPtr<nsICSSParser> parser; nsresult rv = NS_OK; PRUint32 attrCount = mAttrsAndChildren.AttrCount(); for (PRUint32 i = 0; i < attrCount; ++i) { const nsAttrName* attrName = mAttrsAndChildren.AttrNameAt(i); if (!attrName->IsAtom() || !IsAttributeMapped(attrName->Atom())) continue; if (!declaration) { // Create the nsCSSDeclaration. declaration = new nsCSSDeclaration(); if (!declaration) { NS_WARNING("Failed to allocate nsCSSDeclaration"); return; } if (!declaration->InitializeEmpty()) { NS_WARNING("could not initialize nsCSSDeclaration"); declaration->RuleAbort(); // deletes declaration return; } // Try to fetch the CSS Parser from the document. rv = cssLoader->GetParserFor(nsnull, getter_AddRefs(parser)); if (NS_FAILED(rv)) { NS_WARNING("failed to get a css parser"); declaration->RuleAbort(); // deletes declaration return; } // SVG and CSS differ slightly in their interpretation of some of // the attributes. SVG allows attributes of the form: font-size="5" // (style="font-size: 5" if using a style attribute) // where CSS requires units: font-size="5pt" (style="font-size: 5pt") // Set a flag to pass information to the parser so that we can use // the CSS parser to parse the font-size attribute. Note that this // does *not* affect the use of CSS stylesheets, which will still // require units. parser->SetSVGMode(PR_TRUE); } nsAutoString name; attrName->Atom()->ToString(name); nsAutoString value; mAttrsAndChildren.AttrAt(i)->ToString(value); PRBool changed; parser->ParseProperty(nsCSSProps::LookupProperty(name), value, docURI, baseURI, NodePrincipal(), declaration, &changed); } if (declaration) { rv = NS_NewCSSStyleRule(getter_AddRefs(mContentStyleRule), nsnull, declaration); if (NS_FAILED(rv)) { NS_WARNING("could not create contentstylerule"); declaration->RuleAbort(); // deletes declaration } // Recycle the parser parser->SetSVGMode(PR_FALSE); cssLoader->RecycleParser(parser); } }