Make setting element.style.foo just parse the value instead of creating

a property:value pair and parsing that.  Speeds up setting of
element.style.top by about 5%.  Bug 99797, r=attinasi, sr=jst
This commit is contained in:
bzbarsky%mit.edu 2001-09-28 01:38:36 +00:00
Родитель 17bc1b4001
Коммит 7a6cc28476
15 изменённых файлов: 467 добавлений и 137 удалений

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

@ -142,6 +142,8 @@ public:
virtual nsresult GetCSSDeclaration(nsICSSDeclaration **aDecl,
PRBool aAllocate);
virtual nsresult SetCSSDeclaration(nsICSSDeclaration *aDecl);
virtual nsresult ParsePropertyValue(const nsAReadableString& aPropName,
const nsAReadableString& aPropValue);
virtual nsresult ParseDeclaration(const nsAReadableString& aDecl,
PRBool aParseOnlyOneDecl,
PRBool aClearOldDecl);
@ -288,37 +290,111 @@ nsDOMCSSAttributeDeclaration::SetCSSDeclaration(nsICSSDeclaration *aDecl)
return result;
}
nsresult
nsDOMCSSAttributeDeclaration::ParsePropertyValue(const nsAReadableString& aPropName,
const nsAReadableString& aPropValue)
{
nsCOMPtr<nsICSSDeclaration> decl;
nsresult result = GetCSSDeclaration(getter_AddRefs(decl), PR_TRUE);
if (!decl) {
return result;
}
nsCOMPtr<nsICSSLoader> cssLoader;
nsCOMPtr<nsICSSParser> cssParser;
nsCOMPtr<nsIURI> baseURI;
nsCOMPtr<nsIDocument> doc;
result = mContent->GetDocument(*getter_AddRefs(doc));
if (NS_FAILED(result)) {
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));
}
if (NS_FAILED(result)) {
return result;
}
PRInt32 hint;
if (doc) {
doc->BeginUpdate();
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,
nsHTMLAtoms::style,
nsIDOMMutationEvent::MODIFICATION, hint);
doc->EndUpdate();
}
if (cssLoader) {
cssLoader->RecycleParser(cssParser);
}
return NS_OK;
}
nsresult
nsDOMCSSAttributeDeclaration::ParseDeclaration(const nsAReadableString& aDecl,
PRBool aParseOnlyOneDecl,
PRBool aClearOldDecl)
{
nsICSSDeclaration *decl;
nsresult result = GetCSSDeclaration(&decl, PR_TRUE);
nsCOMPtr<nsICSSDeclaration> decl;
nsresult result = GetCSSDeclaration(getter_AddRefs(decl), PR_TRUE);
if (NS_SUCCEEDED(result) && (decl)) {
nsICSSLoader* cssLoader = nsnull;
nsICSSParser* cssParser = nsnull;
nsIURI* baseURI = nsnull;
nsIDocument* doc = nsnull;
if (decl) {
nsCOMPtr<nsICSSLoader> cssLoader;
nsCOMPtr<nsICSSParser> cssParser;
nsCOMPtr<nsIURI> baseURI;
nsCOMPtr<nsIDocument> doc;
result = mContent->GetDocument(doc);
if (NS_SUCCEEDED(result) && (nsnull != doc)) {
doc->GetBaseURL(baseURI);
result = mContent->GetDocument(*getter_AddRefs(doc));
if (doc) {
doc->GetBaseURL(*getter_AddRefs(baseURI));
nsIHTMLContentContainer* htmlContainer;
result = doc->QueryInterface(NS_GET_IID(nsIHTMLContentContainer), (void**)&htmlContainer);
if (NS_SUCCEEDED(result)) {
result = htmlContainer->GetCSSLoader(cssLoader);
NS_RELEASE(htmlContainer);
nsCOMPtr<nsIHTMLContentContainer> htmlContainer(do_QueryInterface(doc));
if (htmlContainer) {
htmlContainer->GetCSSLoader(*getter_AddRefs(cssLoader));
}
}
if (cssLoader) {
result = cssLoader->GetParserFor(nsnull, &cssParser);
result = cssLoader->GetParserFor(nsnull, getter_AddRefs(cssParser));
}
else {
result = NS_NewCSSParser(&cssParser);
result = NS_NewCSSParser(getter_AddRefs(cssParser));
}
if (NS_SUCCEEDED(result)) {
@ -380,14 +456,7 @@ nsDOMCSSAttributeDeclaration::ParseDeclaration(const nsAReadableString& aDecl,
if (cssLoader) {
cssLoader->RecycleParser(cssParser);
}
else {
NS_RELEASE(cssParser);
}
}
NS_IF_RELEASE(cssLoader);
NS_IF_RELEASE(baseURI);
NS_IF_RELEASE(doc);
NS_RELEASE(decl);
}
return result;
@ -3128,17 +3197,15 @@ nsGenericHTMLElement::ParseStyleAttribute(const nsAReadableString& aValue, nsHTM
}
if (isCSS) {
nsICSSLoader* cssLoader = nsnull;
nsICSSParser* cssParser = nsnull;
nsIHTMLContentContainer* htmlContainer;
nsCOMPtr<nsICSSLoader> cssLoader;
nsCOMPtr<nsICSSParser> cssParser;
nsCOMPtr<nsIHTMLContentContainer> htmlContainer(do_QueryInterface(mDocument));
result = mDocument->QueryInterface(NS_GET_IID(nsIHTMLContentContainer), (void**)&htmlContainer);
if (NS_SUCCEEDED(result) && htmlContainer) {
result = htmlContainer->GetCSSLoader(cssLoader);
NS_RELEASE(htmlContainer);
if (htmlContainer) {
htmlContainer->GetCSSLoader(*getter_AddRefs(cssLoader));
}
if (NS_SUCCEEDED(result) && cssLoader) {
result = cssLoader->GetParserFor(nsnull, &cssParser);
if (cssLoader) {
result = cssLoader->GetParserFor(nsnull, getter_AddRefs(cssParser));
static const char charsetStr[] = "charset=";
PRInt32 charsetOffset = styleType.Find(charsetStr, PR_TRUE);
@ -3150,32 +3217,23 @@ nsGenericHTMLElement::ParseStyleAttribute(const nsAReadableString& aValue, nsHTM
}
}
else {
result = NS_NewCSSParser(&cssParser);
result = NS_NewCSSParser(getter_AddRefs(cssParser));
}
if (NS_SUCCEEDED(result) && cssParser) {
nsIURI* docURL = nsnull;
mDocument->GetBaseURL(docURL);
if (cssParser) {
nsCOMPtr<nsIURI> docURL;
mDocument->GetBaseURL(*getter_AddRefs(docURL));
nsIStyleRule* rule;
result = cssParser->ParseStyleAttribute(aValue, docURL, &rule);
nsCOMPtr<nsIStyleRule> rule;
result = cssParser->ParseStyleAttribute(aValue, docURL, getter_AddRefs(rule));
if (cssLoader) {
cssLoader->RecycleParser(cssParser);
NS_RELEASE(cssLoader);
}
else {
NS_RELEASE(cssParser);
}
NS_IF_RELEASE(docURL);
if (NS_SUCCEEDED(result) && rule) {
if (rule) {
aResult.SetISupportsValue(rule);
NS_RELEASE(rule);
return NS_OK;
}
}
else {
NS_IF_RELEASE(cssLoader);
}
}
}
aResult.SetStringValue(aValue);

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

@ -99,6 +99,12 @@ public:
NS_IMETHOD ParseRule(nsAReadableString& aRule,
nsIURI* aBaseURL,
nsISupportsArray** aResult) = 0;
NS_IMETHOD ParseProperty(const nsAReadableString& aPropName,
const nsAReadableString& aPropValue,
nsIURI* aBaseURL,
nsICSSDeclaration* aDeclaration,
PRInt32* aHint) = 0;
// Charset management method:
// Set the charset before calling any of the Parse emthods if you want the

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

@ -606,7 +606,6 @@ CSSLoaderImpl::RecycleParser(nsICSSParser* aParser)
if (mParsers) {
mParsers->AppendElement(aParser);
}
NS_RELEASE(aParser);
}
return result;
}
@ -857,8 +856,8 @@ CSSLoaderImpl::ParseSheet(nsIUnicharInputStream* aIn,
aSheet = nsnull;
result = NS_NewCSSStyleSheet(&aSheet, aLoadData->mURL);
if (NS_SUCCEEDED(result)) {
nsICSSParser* parser;
result = GetParserFor(aSheet, &parser);
nsCOMPtr<nsICSSParser> parser;
result = GetParserFor(aSheet, getter_AddRefs(parser));
if (NS_SUCCEEDED(result)) {
mParsingData.AppendElement(aLoadData);
if (kNameSpaceID_Unknown != aLoadData->mDefaultNameSpaceID) {

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

@ -173,6 +173,12 @@ public:
nsIURI* aBaseURL,
nsISupportsArray** aResult);
NS_IMETHOD ParseProperty(const nsAReadableString& aPropName,
const nsAReadableString& aPropValue,
nsIURI* aBaseURL,
nsICSSDeclaration* aDeclaration,
PRInt32* aHint);
NS_IMETHOD GetCharset(/*out*/nsAWritableString &aCharsetDest) const;
// sets the out-param to the current charset, as set by SetCharset
NS_IMETHOD SetCharset(/*in*/ const nsAReadableString &aCharsetSrc);
@ -775,6 +781,71 @@ CSSParserImpl::ParseRule(nsAReadableString& aRule,
return NS_OK;
}
NS_IMETHODIMP
CSSParserImpl::ParseProperty(const nsAReadableString& aPropName,
const nsAReadableString& aPropValue,
nsIURI* aBaseURL,
nsICSSDeclaration* aDeclaration,
PRInt32* aHint)
{
NS_ASSERTION(nsnull != aBaseURL, "need base URL");
NS_ASSERTION(nsnull != aDeclaration, "Need declaration to parse into!");
nsString* str = new nsString(aPropValue);
if (!str) {
return NS_ERROR_OUT_OF_MEMORY;
}
nsCOMPtr<nsIUnicharInputStream> input;
nsresult rv = NS_NewStringUnicharInputStream(getter_AddRefs(input), str);
if (NS_FAILED(rv)) {
delete str;
return rv;
}
rv = InitScanner(input, aBaseURL);
if (NS_FAILED(rv)) {
return rv;
}
mSection = eCSSSection_General;
PRInt32 errorCode = NS_OK;
PRInt32 hint = NS_STYLE_HINT_NONE;
if (aHint) {
*aHint = hint;
}
nsCSSProperty propID = nsCSSProps::LookupProperty(aPropName);
if (eCSSProperty_UNKNOWN == propID) { // unknown property
REPORT_UNEXPECTED(NS_LITERAL_STRING("Unknown property '") +
aPropName +
NS_LITERAL_STRING("'. Declaration dropped."));
OUTPUT_ERROR();
ReleaseScanner();
return NS_OK;
}
if (! ParseProperty(errorCode, aDeclaration, propID, hint)) {
REPORT_UNEXPECTED(
NS_LITERAL_STRING("Error in parsing value for property '") +
aPropName +
NS_LITERAL_STRING("'. Declaration dropped."));
OUTPUT_ERROR();
if (errorCode != -1) { // -1 means EOF which we ignore
ReleaseScanner();
return errorCode;
}
}
CLEAR_ERROR();
if (aHint && hint > *aHint) {
*aHint = hint;
}
ReleaseScanner();
return NS_OK;
}
//----------------------------------------------------------------------
PRBool CSSParserImpl::GetToken(PRInt32& aErrorCode, PRBool aSkipWS)

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

@ -1066,6 +1066,8 @@ public:
virtual nsresult GetCSSDeclaration(nsICSSDeclaration **aDecl,
PRBool aAllocate);
virtual nsresult SetCSSDeclaration(nsICSSDeclaration *aDecl);
virtual nsresult ParsePropertyValue(const nsAReadableString& aPropName,
const nsAReadableString& aPropValue);
virtual nsresult ParseDeclaration(const nsAReadableString& aDecl,
PRBool aParseOnlyOneDecl,
PRBool aClearOldDecl);
@ -1150,44 +1152,100 @@ DOMCSSDeclarationImpl::SetCSSDeclaration(nsICSSDeclaration *aDecl)
return NS_OK;
}
nsresult
DOMCSSDeclarationImpl::ParsePropertyValue(const nsAReadableString& aPropName,
const nsAReadableString& aPropValue)
{
nsCOMPtr<nsICSSDeclaration> decl;
nsresult result = GetCSSDeclaration(getter_AddRefs(decl), PR_TRUE);
if (!decl) {
return result;
}
nsCOMPtr<nsICSSLoader> cssLoader;
nsCOMPtr<nsICSSParser> cssParser;
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));
}
if (NS_FAILED(result)) {
return result;
}
PRInt32 hint;
if (owningDoc) {
owningDoc->BeginUpdate();
}
result = cssParser->ParseProperty(aPropName, aPropValue, baseURI, decl, &hint);
if (NS_SUCCEEDED(result)) {
if (cssSheet) {
cssSheet->SetModified(PR_TRUE);
}
if (owningDoc) {
owningDoc->StyleRuleChanged(cssSheet, mRule, hint);
owningDoc->EndUpdate();
}
}
if (cssLoader) {
cssLoader->RecycleParser(cssParser);
}
return result;
}
nsresult
DOMCSSDeclarationImpl::ParseDeclaration(const nsAReadableString& aDecl,
PRBool aParseOnlyOneDecl,
PRBool aClearOldDecl)
{
nsICSSDeclaration *decl;
nsresult result = GetCSSDeclaration(&decl, PR_TRUE);
nsCOMPtr<nsICSSDeclaration> decl;
nsresult result = GetCSSDeclaration(getter_AddRefs(decl), PR_TRUE);
if (NS_SUCCEEDED(result) && (decl)) {
nsICSSLoader* cssLoader = nsnull;
nsICSSParser* cssParser = nsnull;
nsIURI* baseURI = nsnull;
nsICSSStyleSheet* cssSheet = nsnull;
nsIDocument* owningDoc = nsnull;
if (decl) {
nsCOMPtr<nsICSSLoader> cssLoader;
nsCOMPtr<nsICSSParser> cssParser;
nsCOMPtr<nsIURI> baseURI;
nsCOMPtr<nsICSSStyleSheet> cssSheet;
nsCOMPtr<nsIDocument> owningDoc;
nsIStyleSheet* sheet = nsnull;
nsCOMPtr<nsIStyleSheet> sheet;
if (mRule) {
mRule->GetStyleSheet(sheet);
mRule->GetStyleSheet(*getter_AddRefs(sheet));
if (sheet) {
sheet->GetURL(baseURI);
sheet->GetOwningDocument(owningDoc);
sheet->QueryInterface(NS_GET_IID(nsICSSStyleSheet), (void**)&cssSheet);
sheet->GetURL(*getter_AddRefs(baseURI));
sheet->GetOwningDocument(*getter_AddRefs(owningDoc));
cssSheet = do_QueryInterface(sheet);
if (owningDoc) {
nsIHTMLContentContainer* htmlContainer;
result = owningDoc->QueryInterface(NS_GET_IID(nsIHTMLContentContainer), (void**)&htmlContainer);
if (NS_SUCCEEDED(result)) {
result = htmlContainer->GetCSSLoader(cssLoader);
NS_RELEASE(htmlContainer);
nsCOMPtr<nsIHTMLContentContainer> htmlContainer(do_QueryInterface(owningDoc));
if (htmlContainer) {
htmlContainer->GetCSSLoader(*getter_AddRefs(cssLoader));
}
}
NS_RELEASE(sheet);
}
}
if (cssLoader) {
result = cssLoader->GetParserFor(nsnull, &cssParser);
result = cssLoader->GetParserFor(nsnull, getter_AddRefs(cssParser));
}
else {
result = NS_NewCSSParser(&cssParser);
result = NS_NewCSSParser(getter_AddRefs(cssParser));
}
if (NS_SUCCEEDED(result)) {
@ -1230,15 +1288,7 @@ DOMCSSDeclarationImpl::ParseDeclaration(const nsAReadableString& aDecl,
if (cssLoader) {
cssLoader->RecycleParser(cssParser);
}
else {
NS_RELEASE(cssParser);
}
}
NS_IF_RELEASE(cssLoader);
NS_IF_RELEASE(baseURI);
NS_IF_RELEASE(cssSheet);
NS_IF_RELEASE(owningDoc);
NS_RELEASE(decl);
}
return result;

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

@ -2911,6 +2911,10 @@ CSSStyleSheetImpl::InsertRule(const nsAReadableString& aRule,
result = mDocument->EndUpdate();
NS_ENSURE_SUCCESS(result, result);
}
if (loader) {
loader->RecycleParser(css);
}
*aReturn = aIndex;
return NS_OK;
@ -3076,6 +3080,10 @@ CSSStyleSheetImpl::InsertRuleIntoGroup(nsAReadableString & aRule, nsICSSGroupRul
result = mDocument->EndUpdate();
NS_ENSURE_SUCCESS(result, result);
if (loader) {
loader->RecycleParser(css);
}
*_retval = aIndex;
return NS_OK;
}

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

@ -198,21 +198,16 @@ nsDOMCSSDeclaration::SetProperty(const nsAReadableString& aPropertyName,
const nsAReadableString& aValue,
const nsAReadableString& aPriority)
{
if (!aValue.Length()) {
if (aValue.IsEmpty()) {
// If the new value of the property is an empty string we remove the
// property.
nsAutoString tmp;
return RemoveProperty(aPropertyName, tmp);
}
nsAutoString declString;
declString.Assign(aPropertyName);
declString.Append(PRUnichar(':'));
declString.Append(aValue);
declString.Append(aPriority);
return ParseDeclaration(declString, PR_TRUE, PR_FALSE);
return ParseDeclaration(aPropertyName + NS_LITERAL_STRING(":") +
aValue + aPriority,
PR_TRUE, PR_FALSE);
}
/**
@ -223,9 +218,14 @@ CallSetProperty(nsDOMCSSDeclaration* aDecl,
const nsAReadableString& aPropName,
const nsAReadableString& aValue)
{
PRUnichar nullChar = PRUnichar('\0');
return aDecl->SetProperty(aPropName, aValue,
nsDependentString(&nullChar, PRUint32(0)));
if (aValue.IsEmpty()) {
// If the new value of the property is an empty string we remove the
// property.
nsAutoString tmp;
return aDecl->RemoveProperty(aPropName, tmp);
}
return aDecl->ParsePropertyValue(aPropName, aValue);
}
#define IMPL_CSSPROP(attname_, propname_) \

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

@ -82,6 +82,8 @@ public:
// Note! This will only set the declaration if a style rule already exists
virtual nsresult SetCSSDeclaration(nsICSSDeclaration *aDecl) = 0;
virtual nsresult ParsePropertyValue(const nsAReadableString& aPropName,
const nsAReadableString& aPropValue) = 0;
virtual nsresult ParseDeclaration(const nsAReadableString& aDecl,
PRBool aParseOnlyOneDecl,
PRBool aClearOldDecl) = 0;

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

@ -606,7 +606,6 @@ CSSLoaderImpl::RecycleParser(nsICSSParser* aParser)
if (mParsers) {
mParsers->AppendElement(aParser);
}
NS_RELEASE(aParser);
}
return result;
}
@ -857,8 +856,8 @@ CSSLoaderImpl::ParseSheet(nsIUnicharInputStream* aIn,
aSheet = nsnull;
result = NS_NewCSSStyleSheet(&aSheet, aLoadData->mURL);
if (NS_SUCCEEDED(result)) {
nsICSSParser* parser;
result = GetParserFor(aSheet, &parser);
nsCOMPtr<nsICSSParser> parser;
result = GetParserFor(aSheet, getter_AddRefs(parser));
if (NS_SUCCEEDED(result)) {
mParsingData.AppendElement(aLoadData);
if (kNameSpaceID_Unknown != aLoadData->mDefaultNameSpaceID) {

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

@ -173,6 +173,12 @@ public:
nsIURI* aBaseURL,
nsISupportsArray** aResult);
NS_IMETHOD ParseProperty(const nsAReadableString& aPropName,
const nsAReadableString& aPropValue,
nsIURI* aBaseURL,
nsICSSDeclaration* aDeclaration,
PRInt32* aHint);
NS_IMETHOD GetCharset(/*out*/nsAWritableString &aCharsetDest) const;
// sets the out-param to the current charset, as set by SetCharset
NS_IMETHOD SetCharset(/*in*/ const nsAReadableString &aCharsetSrc);
@ -775,6 +781,71 @@ CSSParserImpl::ParseRule(nsAReadableString& aRule,
return NS_OK;
}
NS_IMETHODIMP
CSSParserImpl::ParseProperty(const nsAReadableString& aPropName,
const nsAReadableString& aPropValue,
nsIURI* aBaseURL,
nsICSSDeclaration* aDeclaration,
PRInt32* aHint)
{
NS_ASSERTION(nsnull != aBaseURL, "need base URL");
NS_ASSERTION(nsnull != aDeclaration, "Need declaration to parse into!");
nsString* str = new nsString(aPropValue);
if (!str) {
return NS_ERROR_OUT_OF_MEMORY;
}
nsCOMPtr<nsIUnicharInputStream> input;
nsresult rv = NS_NewStringUnicharInputStream(getter_AddRefs(input), str);
if (NS_FAILED(rv)) {
delete str;
return rv;
}
rv = InitScanner(input, aBaseURL);
if (NS_FAILED(rv)) {
return rv;
}
mSection = eCSSSection_General;
PRInt32 errorCode = NS_OK;
PRInt32 hint = NS_STYLE_HINT_NONE;
if (aHint) {
*aHint = hint;
}
nsCSSProperty propID = nsCSSProps::LookupProperty(aPropName);
if (eCSSProperty_UNKNOWN == propID) { // unknown property
REPORT_UNEXPECTED(NS_LITERAL_STRING("Unknown property '") +
aPropName +
NS_LITERAL_STRING("'. Declaration dropped."));
OUTPUT_ERROR();
ReleaseScanner();
return NS_OK;
}
if (! ParseProperty(errorCode, aDeclaration, propID, hint)) {
REPORT_UNEXPECTED(
NS_LITERAL_STRING("Error in parsing value for property '") +
aPropName +
NS_LITERAL_STRING("'. Declaration dropped."));
OUTPUT_ERROR();
if (errorCode != -1) { // -1 means EOF which we ignore
ReleaseScanner();
return errorCode;
}
}
CLEAR_ERROR();
if (aHint && hint > *aHint) {
*aHint = hint;
}
ReleaseScanner();
return NS_OK;
}
//----------------------------------------------------------------------
PRBool CSSParserImpl::GetToken(PRInt32& aErrorCode, PRBool aSkipWS)

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

@ -1066,6 +1066,8 @@ public:
virtual nsresult GetCSSDeclaration(nsICSSDeclaration **aDecl,
PRBool aAllocate);
virtual nsresult SetCSSDeclaration(nsICSSDeclaration *aDecl);
virtual nsresult ParsePropertyValue(const nsAReadableString& aPropName,
const nsAReadableString& aPropValue);
virtual nsresult ParseDeclaration(const nsAReadableString& aDecl,
PRBool aParseOnlyOneDecl,
PRBool aClearOldDecl);
@ -1150,44 +1152,100 @@ DOMCSSDeclarationImpl::SetCSSDeclaration(nsICSSDeclaration *aDecl)
return NS_OK;
}
nsresult
DOMCSSDeclarationImpl::ParsePropertyValue(const nsAReadableString& aPropName,
const nsAReadableString& aPropValue)
{
nsCOMPtr<nsICSSDeclaration> decl;
nsresult result = GetCSSDeclaration(getter_AddRefs(decl), PR_TRUE);
if (!decl) {
return result;
}
nsCOMPtr<nsICSSLoader> cssLoader;
nsCOMPtr<nsICSSParser> cssParser;
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));
}
if (NS_FAILED(result)) {
return result;
}
PRInt32 hint;
if (owningDoc) {
owningDoc->BeginUpdate();
}
result = cssParser->ParseProperty(aPropName, aPropValue, baseURI, decl, &hint);
if (NS_SUCCEEDED(result)) {
if (cssSheet) {
cssSheet->SetModified(PR_TRUE);
}
if (owningDoc) {
owningDoc->StyleRuleChanged(cssSheet, mRule, hint);
owningDoc->EndUpdate();
}
}
if (cssLoader) {
cssLoader->RecycleParser(cssParser);
}
return result;
}
nsresult
DOMCSSDeclarationImpl::ParseDeclaration(const nsAReadableString& aDecl,
PRBool aParseOnlyOneDecl,
PRBool aClearOldDecl)
{
nsICSSDeclaration *decl;
nsresult result = GetCSSDeclaration(&decl, PR_TRUE);
nsCOMPtr<nsICSSDeclaration> decl;
nsresult result = GetCSSDeclaration(getter_AddRefs(decl), PR_TRUE);
if (NS_SUCCEEDED(result) && (decl)) {
nsICSSLoader* cssLoader = nsnull;
nsICSSParser* cssParser = nsnull;
nsIURI* baseURI = nsnull;
nsICSSStyleSheet* cssSheet = nsnull;
nsIDocument* owningDoc = nsnull;
if (decl) {
nsCOMPtr<nsICSSLoader> cssLoader;
nsCOMPtr<nsICSSParser> cssParser;
nsCOMPtr<nsIURI> baseURI;
nsCOMPtr<nsICSSStyleSheet> cssSheet;
nsCOMPtr<nsIDocument> owningDoc;
nsIStyleSheet* sheet = nsnull;
nsCOMPtr<nsIStyleSheet> sheet;
if (mRule) {
mRule->GetStyleSheet(sheet);
mRule->GetStyleSheet(*getter_AddRefs(sheet));
if (sheet) {
sheet->GetURL(baseURI);
sheet->GetOwningDocument(owningDoc);
sheet->QueryInterface(NS_GET_IID(nsICSSStyleSheet), (void**)&cssSheet);
sheet->GetURL(*getter_AddRefs(baseURI));
sheet->GetOwningDocument(*getter_AddRefs(owningDoc));
cssSheet = do_QueryInterface(sheet);
if (owningDoc) {
nsIHTMLContentContainer* htmlContainer;
result = owningDoc->QueryInterface(NS_GET_IID(nsIHTMLContentContainer), (void**)&htmlContainer);
if (NS_SUCCEEDED(result)) {
result = htmlContainer->GetCSSLoader(cssLoader);
NS_RELEASE(htmlContainer);
nsCOMPtr<nsIHTMLContentContainer> htmlContainer(do_QueryInterface(owningDoc));
if (htmlContainer) {
htmlContainer->GetCSSLoader(*getter_AddRefs(cssLoader));
}
}
NS_RELEASE(sheet);
}
}
if (cssLoader) {
result = cssLoader->GetParserFor(nsnull, &cssParser);
result = cssLoader->GetParserFor(nsnull, getter_AddRefs(cssParser));
}
else {
result = NS_NewCSSParser(&cssParser);
result = NS_NewCSSParser(getter_AddRefs(cssParser));
}
if (NS_SUCCEEDED(result)) {
@ -1230,15 +1288,7 @@ DOMCSSDeclarationImpl::ParseDeclaration(const nsAReadableString& aDecl,
if (cssLoader) {
cssLoader->RecycleParser(cssParser);
}
else {
NS_RELEASE(cssParser);
}
}
NS_IF_RELEASE(cssLoader);
NS_IF_RELEASE(baseURI);
NS_IF_RELEASE(cssSheet);
NS_IF_RELEASE(owningDoc);
NS_RELEASE(decl);
}
return result;

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

@ -2911,6 +2911,10 @@ CSSStyleSheetImpl::InsertRule(const nsAReadableString& aRule,
result = mDocument->EndUpdate();
NS_ENSURE_SUCCESS(result, result);
}
if (loader) {
loader->RecycleParser(css);
}
*aReturn = aIndex;
return NS_OK;
@ -3076,6 +3080,10 @@ CSSStyleSheetImpl::InsertRuleIntoGroup(nsAReadableString & aRule, nsICSSGroupRul
result = mDocument->EndUpdate();
NS_ENSURE_SUCCESS(result, result);
if (loader) {
loader->RecycleParser(css);
}
*_retval = aIndex;
return NS_OK;
}

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

@ -198,21 +198,16 @@ nsDOMCSSDeclaration::SetProperty(const nsAReadableString& aPropertyName,
const nsAReadableString& aValue,
const nsAReadableString& aPriority)
{
if (!aValue.Length()) {
if (aValue.IsEmpty()) {
// If the new value of the property is an empty string we remove the
// property.
nsAutoString tmp;
return RemoveProperty(aPropertyName, tmp);
}
nsAutoString declString;
declString.Assign(aPropertyName);
declString.Append(PRUnichar(':'));
declString.Append(aValue);
declString.Append(aPriority);
return ParseDeclaration(declString, PR_TRUE, PR_FALSE);
return ParseDeclaration(aPropertyName + NS_LITERAL_STRING(":") +
aValue + aPriority,
PR_TRUE, PR_FALSE);
}
/**
@ -223,9 +218,14 @@ CallSetProperty(nsDOMCSSDeclaration* aDecl,
const nsAReadableString& aPropName,
const nsAReadableString& aValue)
{
PRUnichar nullChar = PRUnichar('\0');
return aDecl->SetProperty(aPropName, aValue,
nsDependentString(&nullChar, PRUint32(0)));
if (aValue.IsEmpty()) {
// If the new value of the property is an empty string we remove the
// property.
nsAutoString tmp;
return aDecl->RemoveProperty(aPropName, tmp);
}
return aDecl->ParsePropertyValue(aPropName, aValue);
}
#define IMPL_CSSPROP(attname_, propname_) \

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

@ -82,6 +82,8 @@ public:
// Note! This will only set the declaration if a style rule already exists
virtual nsresult SetCSSDeclaration(nsICSSDeclaration *aDecl) = 0;
virtual nsresult ParsePropertyValue(const nsAReadableString& aPropName,
const nsAReadableString& aPropValue) = 0;
virtual nsresult ParseDeclaration(const nsAReadableString& aDecl,
PRBool aParseOnlyOneDecl,
PRBool aClearOldDecl) = 0;

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

@ -99,6 +99,12 @@ public:
NS_IMETHOD ParseRule(nsAReadableString& aRule,
nsIURI* aBaseURL,
nsISupportsArray** aResult) = 0;
NS_IMETHOD ParseProperty(const nsAReadableString& aPropName,
const nsAReadableString& aPropValue,
nsIURI* aBaseURL,
nsICSSDeclaration* aDeclaration,
PRInt32* aHint) = 0;
// Charset management method:
// Set the charset before calling any of the Parse emthods if you want the