зеркало из https://github.com/mozilla/pjs.git
Significantly reduce the amount of time we blow on style reresolution by
tracking the attributes which appear in CSS selectors, and only firing a complete reresolution when we change one of those. In the irrelevant-attr case, we just let the frame update itself and get on with our lives right away. Fixed 38378, r=brendan, booyah. Also, when setting an attribute to the same value that it currently holds, don't think about it especially hard, and _don't_ go anywhere near the style code. Fixed 21879, r=brendan, boo_yah_.
This commit is contained in:
Родитель
d251adb613
Коммит
8f7d1fbff0
|
@ -71,6 +71,11 @@ public:
|
|||
virtual void List(FILE* out = stdout, PRInt32 aIndent = 0) const = 0;
|
||||
|
||||
virtual void SizeOf(nsISizeOfHandler *aSizeofHandler, PRUint32 &aSize) = 0;
|
||||
|
||||
// If changing the given attribute cannot affect style context, aAffects
|
||||
// will be PR_FALSE on return.
|
||||
NS_IMETHOD AttributeAffectsStyle(nsIAtom *aAttribute, nsIContent *aContent,
|
||||
PRBool &aAffects) = 0;
|
||||
};
|
||||
|
||||
#endif /* nsIStyleSheet_h___ */
|
||||
|
|
|
@ -191,6 +191,9 @@ public:
|
|||
NS_DECL_NSITIMERECORDER
|
||||
#endif
|
||||
|
||||
NS_IMETHOD AttributeAffectsStyle(nsIAtom *aAttribute, nsIContent *aContent,
|
||||
PRBool &aAffects);
|
||||
|
||||
private:
|
||||
// These are not supported and are not implemented!
|
||||
StyleSetImpl(const StyleSetImpl& aCopy);
|
||||
|
@ -1354,6 +1357,46 @@ void StyleSetImpl::ResetUniqueStyleItems(void)
|
|||
uniqueItems->Clear();
|
||||
}
|
||||
|
||||
struct AttributeContentPair {
|
||||
nsIAtom *attribute;
|
||||
nsIContent *content;
|
||||
};
|
||||
|
||||
static PRBool
|
||||
EnumAffectsStyle(nsISupports *aElement, void *aData)
|
||||
{
|
||||
nsIStyleSheet *sheet = NS_STATIC_CAST(nsIStyleSheet *, aElement);
|
||||
AttributeContentPair *pair = (AttributeContentPair *)aData;
|
||||
PRBool affects;
|
||||
if (NS_FAILED(sheet->AttributeAffectsStyle(pair->attribute, pair->content,
|
||||
affects)) || affects)
|
||||
return PR_FALSE; // stop checking
|
||||
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
StyleSetImpl::AttributeAffectsStyle(nsIAtom *aAttribute, nsIContent *aContent,
|
||||
PRBool &aAffects)
|
||||
{
|
||||
AttributeContentPair pair;
|
||||
pair.attribute = aAttribute;
|
||||
pair.content = aContent;
|
||||
|
||||
/* check until we find a sheet that will be affected */
|
||||
if ((mDocSheets && !mDocSheets->EnumerateForwards(EnumAffectsStyle, &pair)) ||
|
||||
(mOverrideSheets && !mOverrideSheets->EnumerateForwards(EnumAffectsStyle,
|
||||
&pair)) ||
|
||||
(mBackstopSheets && !mBackstopSheets->EnumerateForwards(EnumAffectsStyle,
|
||||
&pair))) {
|
||||
aAffects = PR_TRUE;
|
||||
} else {
|
||||
aAffects = PR_FALSE;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* SizeOf method:
|
||||
*
|
||||
|
|
|
@ -1280,12 +1280,22 @@ nsGenericHTMLElement::SetAttribute(PRInt32 aNameSpaceID,
|
|||
return result;
|
||||
}
|
||||
|
||||
// don't do any update if old == new
|
||||
nsAutoString strValue;
|
||||
result = GetAttribute(aNameSpaceID, aAttribute, strValue);
|
||||
if ((NS_CONTENT_ATTR_NOT_THERE != result) && aValue.Equals(strValue)) {
|
||||
NS_RELEASE(htmlContent);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (aNotify && (nsnull != mDocument)) {
|
||||
mDocument->BeginUpdate();
|
||||
}
|
||||
|
||||
// set as string value to avoid another string copy
|
||||
PRBool impact = NS_STYLE_HINT_NONE;
|
||||
htmlContent->GetMappedAttributeImpact(aAttribute, impact);
|
||||
|
||||
if (nsnull != mDocument) { // set attr via style sheet
|
||||
nsIHTMLStyleSheet* sheet = GetAttrStyleSheet(mDocument);
|
||||
if (nsnull != sheet) {
|
||||
|
|
|
@ -459,6 +459,7 @@ public:
|
|||
|
||||
nsINameSpace* mNameSpace;
|
||||
PRInt32 mDefaultNameSpaceID;
|
||||
nsHashtable mRelevantAttributes;
|
||||
|
||||
static nsIIOService* gIOService;
|
||||
static nsrefcnt gRefcnt;
|
||||
|
@ -518,6 +519,15 @@ public:
|
|||
NS_IMETHOD AppendStyleSheet(nsICSSStyleSheet* aSheet);
|
||||
NS_IMETHOD InsertStyleSheetAt(nsICSSStyleSheet* aSheet, PRInt32 aIndex);
|
||||
|
||||
|
||||
// If changing the given attribute cannot affect style context, aAffects
|
||||
// will be PR_FALSE on return.
|
||||
NS_IMETHOD AttributeAffectsStyle(nsIAtom *aAttribute, nsIContent *aContent,
|
||||
PRBool &aAffects);
|
||||
|
||||
// Find attributes in selector for rule, for use with AttributeAffectsStyle
|
||||
NS_IMETHOD CheckRuleForAttributes(nsICSSRule* aRule);
|
||||
|
||||
// XXX do these belong here or are they generic?
|
||||
NS_IMETHOD PrependStyleRule(nsICSSRule* aRule);
|
||||
NS_IMETHOD AppendStyleRule(nsICSSRule* aRule);
|
||||
|
@ -1090,7 +1100,8 @@ CSSStyleSheetInner::CSSStyleSheetInner(nsICSSStyleSheet* aParentSheet)
|
|||
mURL(nsnull),
|
||||
mOrderedRules(nsnull),
|
||||
mNameSpace(nsnull),
|
||||
mDefaultNameSpaceID(kNameSpaceID_None)
|
||||
mDefaultNameSpaceID(kNameSpaceID_None),
|
||||
mRelevantAttributes()
|
||||
{
|
||||
MOZ_COUNT_CTOR(CSSStyleSheetInner);
|
||||
if (gRefcnt++ == 0) {
|
||||
|
@ -1117,12 +1128,24 @@ CloneRuleInto(nsISupports* aRule, void* aArray)
|
|||
return PR_TRUE;
|
||||
}
|
||||
|
||||
static PRBool
|
||||
CopyRelevantAttributes(nsHashKey *aAttrKey, void *aAtom, void *aTable)
|
||||
{
|
||||
nsHashtable *table = NS_STATIC_CAST(nsHashtable *, aTable);
|
||||
AtomKey *key = NS_STATIC_CAST(AtomKey *, aAttrKey);
|
||||
table->Put(key, key->mAtom);
|
||||
// we don't need to addref the atom here, because we're also copying the
|
||||
// rules when we clone, and that will add a ref for us
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
CSSStyleSheetInner::CSSStyleSheetInner(CSSStyleSheetInner& aCopy,
|
||||
nsICSSStyleSheet* aParentSheet)
|
||||
: mSheets(),
|
||||
mURL(aCopy.mURL),
|
||||
mNameSpace(nsnull),
|
||||
mDefaultNameSpaceID(aCopy.mDefaultNameSpaceID)
|
||||
mDefaultNameSpaceID(aCopy.mDefaultNameSpaceID),
|
||||
mRelevantAttributes()
|
||||
{
|
||||
MOZ_COUNT_CTOR(CSSStyleSheetInner);
|
||||
if (gRefcnt++ == 0) {
|
||||
|
@ -1144,6 +1167,8 @@ CSSStyleSheetInner::CSSStyleSheetInner(CSSStyleSheetInner& aCopy,
|
|||
else {
|
||||
mOrderedRules = nsnull;
|
||||
}
|
||||
aCopy.mRelevantAttributes.Enumerate(CopyRelevantAttributes,
|
||||
&mRelevantAttributes);
|
||||
RebuildNameSpaces();
|
||||
}
|
||||
|
||||
|
@ -1840,6 +1865,21 @@ CSSStyleSheetImpl::InsertStyleSheetAt(nsICSSStyleSheet* aSheet, PRInt32 aIndex)
|
|||
return result;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
CSSStyleSheetImpl::AttributeAffectsStyle(nsIAtom *aAttribute,
|
||||
nsIContent *aContent,
|
||||
PRBool &aAffects)
|
||||
{
|
||||
AtomKey key(aAttribute);
|
||||
aAffects = !!mInner->mRelevantAttributes.Get(&key);
|
||||
for (CSSStyleSheetImpl *child = mFirstChild;
|
||||
child && !aAffects;
|
||||
child = child->mNext) {
|
||||
child->AttributeAffectsStyle(aAttribute, aContent, aAffects);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
CSSStyleSheetImpl::PrependStyleRule(nsICSSRule* aRule)
|
||||
{
|
||||
|
@ -1859,6 +1899,8 @@ CSSStyleSheetImpl::PrependStyleRule(nsICSSRule* aRule)
|
|||
if (nsICSSRule::NAMESPACE_RULE == type) {
|
||||
// no api to prepend a namespace (ugh), release old ones and re-create them all
|
||||
mInner->RebuildNameSpaces();
|
||||
} else {
|
||||
CheckRuleForAttributes(aRule);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1906,12 +1948,59 @@ CSSStyleSheetImpl::AppendStyleRule(nsICSSRule* aRule)
|
|||
mInner->mNameSpace = newNameSpace; // takes ref
|
||||
}
|
||||
}
|
||||
} else {
|
||||
CheckRuleForAttributes(aRule);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
static PRBool
|
||||
CheckRuleForAttributesEnum(nsISupports *aRule, void *aData)
|
||||
{
|
||||
nsICSSRule *rule = NS_STATIC_CAST(nsICSSRule *, aRule);
|
||||
CSSStyleSheetImpl *sheet = NS_STATIC_CAST(CSSStyleSheetImpl *, aData);
|
||||
return NS_SUCCEEDED(sheet->CheckRuleForAttributes(rule));
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
CSSStyleSheetImpl::CheckRuleForAttributes(nsICSSRule *aRule)
|
||||
{
|
||||
PRInt32 ruleType;
|
||||
aRule->GetType(ruleType);
|
||||
switch (ruleType) {
|
||||
case nsICSSRule::MEDIA_RULE: {
|
||||
nsICSSMediaRule *mediaRule = (nsICSSMediaRule *)aRule;
|
||||
return mediaRule->EnumerateRulesForwards(CheckRuleForAttributesEnum,
|
||||
(void *)this);
|
||||
}
|
||||
case nsICSSRule::STYLE_RULE: {
|
||||
nsICSSStyleRule *styleRule = NS_STATIC_CAST(nsICSSStyleRule *, aRule);
|
||||
nsCSSSelector *iter;
|
||||
for (iter = styleRule->FirstSelector(); iter; iter = iter->mNext) {
|
||||
nsAttrSelector *sel;
|
||||
for (sel = iter->mAttrList; sel; sel = sel->mNext) {
|
||||
/* store it in this sheet's attributes-that-matter table */
|
||||
/* XXX store tag name too, but handle collisions */
|
||||
#ifdef DEBUG_shaver_off
|
||||
nsAutoString str;
|
||||
sel->mAttr->ToString(str);
|
||||
char * chars = str.ToNewCString();
|
||||
fprintf(stderr, "[%s@%p]", chars, this);
|
||||
nsAllocator::Free(chars);
|
||||
#endif
|
||||
AtomKey key(sel->mAttr);
|
||||
mInner->mRelevantAttributes.Put(&key, sel->mAttr);
|
||||
}
|
||||
}
|
||||
} /* fall-through */
|
||||
default:
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
CSSStyleSheetImpl::StyleRuleCount(PRInt32& aCount) const
|
||||
{
|
||||
|
|
|
@ -367,6 +367,10 @@ public:
|
|||
|
||||
virtual void SizeOf(nsISizeOfHandler *aSizeofHandler, PRUint32 &aSize);
|
||||
|
||||
// If changing the given attribute cannot affect style context, aAffects
|
||||
// will be PR_FALSE on return.
|
||||
NS_IMETHOD AttributeAffectsStyle(nsIAtom *aAttribute, nsIContent *aContent,
|
||||
PRBool &aAffects);
|
||||
private:
|
||||
// These are not supported and are not implemented!
|
||||
HTMLCSSStyleSheetImpl(const HTMLCSSStyleSheetImpl& aCopy);
|
||||
|
@ -761,6 +765,16 @@ void HTMLCSSStyleSheetImpl::SizeOf(nsISizeOfHandler *aSizeOfHandler, PRUint32 &a
|
|||
}
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
HTMLCSSStyleSheetImpl::AttributeAffectsStyle(nsIAtom *aAttribute,
|
||||
nsIContent *aContent,
|
||||
PRBool &aAffects)
|
||||
{
|
||||
// XXX can attributes affect rules in these?
|
||||
aAffects = PR_FALSE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// XXX For backwards compatibility and convenience
|
||||
NS_HTML nsresult
|
||||
NS_NewHTMLCSSStyleSheet(nsIHTMLCSSStyleSheet** aInstancePtrResult, nsIURI* aURL,
|
||||
|
|
|
@ -654,6 +654,10 @@ public:
|
|||
|
||||
virtual void SizeOf(nsISizeOfHandler *aSizeofHandler, PRUint32 &aSize);
|
||||
|
||||
// If changing the given attribute cannot affect style context, aAffects
|
||||
// will be PR_FALSE on return.
|
||||
NS_IMETHOD AttributeAffectsStyle(nsIAtom *aAttribute, nsIContent *aContent,
|
||||
PRBool &aAffects);
|
||||
private:
|
||||
// These are not supported and are not implemented!
|
||||
HTMLStyleSheetImpl(const HTMLStyleSheetImpl& aCopy);
|
||||
|
@ -1506,6 +1510,16 @@ void HTMLStyleSheetImpl::SizeOf(nsISizeOfHandler *aSizeOfHandler, PRUint32 &aSiz
|
|||
// that's it
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
HTMLStyleSheetImpl::AttributeAffectsStyle(nsIAtom *aAttribute,
|
||||
nsIContent *aContent,
|
||||
PRBool &aAffects)
|
||||
{
|
||||
// XXX we should be checking to see if this is an href on an <A> being
|
||||
// XXX tweaked, in which case we really want to restyle
|
||||
aAffects = PR_FALSE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// XXX For convenience and backwards compatibility
|
||||
NS_HTML nsresult
|
||||
|
|
|
@ -9539,9 +9539,24 @@ nsCSSFrameConstructor::AttributeChanged(nsIPresContext* aPresContext,
|
|||
changeList.AppendChange(primaryFrame, aContent, maxHint);
|
||||
nsCOMPtr<nsIFrameManager> frameManager;
|
||||
shell->GetFrameManager(getter_AddRefs(frameManager));
|
||||
frameManager->ComputeStyleChangeFor(aPresContext, primaryFrame,
|
||||
aNameSpaceID, aAttribute,
|
||||
changeList, aHint, maxHint);
|
||||
|
||||
PRBool affects;
|
||||
frameManager->AttributeAffectsStyle(aAttribute, aContent, affects);
|
||||
if (affects) {
|
||||
#ifdef DEBUG_shaver
|
||||
fputc('+', stderr);
|
||||
#endif
|
||||
// there is an effect, so compute it
|
||||
frameManager->ComputeStyleChangeFor(aPresContext, primaryFrame,
|
||||
aNameSpaceID, aAttribute,
|
||||
changeList, aHint, maxHint);
|
||||
} else {
|
||||
#ifdef DEBUG_shaver
|
||||
fputc('-', stderr);
|
||||
#endif
|
||||
// let this frame update itself, but don't walk the whole frame tree
|
||||
maxHint = NS_STYLE_HINT_VISUAL;
|
||||
}
|
||||
|
||||
switch (maxHint) { // maxHint is hint for primary only
|
||||
case NS_STYLE_HINT_RECONSTRUCT_ALL:
|
||||
|
|
|
@ -235,6 +235,8 @@ public:
|
|||
nsStyleChangeList& aChangeList,
|
||||
PRInt32 aMinChange,
|
||||
PRInt32& aTopLevelChange);
|
||||
NS_IMETHOD AttributeAffectsStyle(nsIAtom *aAttribute, nsIContent *aContent,
|
||||
PRBool &aAffects);
|
||||
|
||||
NS_IMETHOD CaptureFrameState(nsIPresContext* aPresContext,
|
||||
nsIFrame* aFrame,
|
||||
|
@ -1386,6 +1388,12 @@ FrameManager::ComputeStyleChangeFor(nsIPresContext* aPresContext,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
FrameManager::AttributeAffectsStyle(nsIAtom *aAttribute, nsIContent *aContent,
|
||||
PRBool &aAffects)
|
||||
{
|
||||
return mStyleSet->AttributeAffectsStyle(aAttribute, aContent, aAffects);
|
||||
}
|
||||
|
||||
static nsresult
|
||||
CaptureFrameStateFor(nsIPresContext* aPresContext, nsIFrame* aFrame, nsILayoutHistoryState* aState)
|
||||
|
|
|
@ -146,6 +146,10 @@ public:
|
|||
PRInt32 aMinChange,
|
||||
PRInt32& aTopLevelChange) = 0;
|
||||
|
||||
// Determine whether an attribute affects style
|
||||
NS_IMETHOD AttributeAffectsStyle(nsIAtom *aAttribute, nsIContent *aContent,
|
||||
PRBool &aAffects) = 0;
|
||||
|
||||
/**
|
||||
* Capture/restore frame state for the frame subtree rooted at aFrame.
|
||||
* aState is the document state storage object onto which each frame
|
||||
|
|
|
@ -186,6 +186,11 @@ public:
|
|||
virtual void SizeOf(nsISizeOfHandler *aSizeofHandler, PRUint32 &aSize) = 0;
|
||||
virtual void ResetUniqueStyleItems(void) = 0;
|
||||
|
||||
// If changing the given attribute cannot affect style context, aAffects
|
||||
// will be PR_FALSE on return.
|
||||
NS_IMETHOD AttributeAffectsStyle(nsIAtom *aAttribute, nsIContent *aContent,
|
||||
PRBool &aAffects) = 0;
|
||||
|
||||
#ifdef DEBUG_SC_SHARING
|
||||
// add and remove from the cache of all contexts
|
||||
NS_IMETHOD AddStyleContext(nsIStyleContext *aNewStyleContext) = 0;
|
||||
|
|
|
@ -1,76 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*/
|
||||
#ifndef nsIStyleSheet_h___
|
||||
#define nsIStyleSheet_h___
|
||||
|
||||
#include <stdio.h>
|
||||
#include "nsISupports.h"
|
||||
|
||||
class nsISizeOfHandler;
|
||||
|
||||
class nsIAtom;
|
||||
class nsString;
|
||||
class nsIURI;
|
||||
class nsIStyleRule;
|
||||
class nsISupportsArray;
|
||||
class nsIPresContext;
|
||||
class nsIContent;
|
||||
class nsIDocument;
|
||||
class nsIStyleContext;
|
||||
class nsIStyleRuleProcessor;
|
||||
|
||||
// IID for the nsIStyleSheet interface {8c4a80a0-ad6a-11d1-8031-006008159b5a}
|
||||
#define NS_ISTYLE_SHEET_IID \
|
||||
{0x8c4a80a0, 0xad6a, 0x11d1, {0x80, 0x31, 0x00, 0x60, 0x08, 0x15, 0x9b, 0x5a}}
|
||||
|
||||
class nsIStyleSheet : public nsISupports {
|
||||
public:
|
||||
static const nsIID& GetIID() { static nsIID iid = NS_ISTYLE_SHEET_IID; return iid; }
|
||||
|
||||
// basic style sheet data
|
||||
NS_IMETHOD GetURL(nsIURI*& aURL) const = 0;
|
||||
NS_IMETHOD GetTitle(nsString& aTitle) const = 0;
|
||||
NS_IMETHOD GetType(nsString& aType) const = 0;
|
||||
NS_IMETHOD GetMediumCount(PRInt32& aCount) const = 0;
|
||||
NS_IMETHOD GetMediumAt(PRInt32 aIndex, nsIAtom*& aMedium) const = 0;
|
||||
NS_IMETHOD UseForMedium(nsIAtom* aMedium) const = 0;
|
||||
|
||||
NS_IMETHOD GetEnabled(PRBool& aEnabled) const = 0;
|
||||
NS_IMETHOD SetEnabled(PRBool aEnabled) = 0;
|
||||
|
||||
// style sheet owner info
|
||||
NS_IMETHOD GetParentSheet(nsIStyleSheet*& aParent) const = 0; // may be null
|
||||
NS_IMETHOD GetOwningDocument(nsIDocument*& aDocument) const = 0; // may be null
|
||||
NS_IMETHOD SetOwningDocument(nsIDocument* aDocument) = 0;
|
||||
|
||||
// style rule processor access
|
||||
NS_IMETHOD GetStyleRuleProcessor(nsIStyleRuleProcessor*& aProcessor,
|
||||
nsIStyleRuleProcessor* aPrevProcessor) = 0;
|
||||
|
||||
// XXX style rule enumerations
|
||||
|
||||
virtual void List(FILE* out = stdout, PRInt32 aIndent = 0) const = 0;
|
||||
|
||||
virtual void SizeOf(nsISizeOfHandler *aSizeofHandler, PRUint32 &aSize) = 0;
|
||||
};
|
||||
|
||||
#endif /* nsIStyleSheet_h___ */
|
|
@ -191,6 +191,9 @@ public:
|
|||
NS_DECL_NSITIMERECORDER
|
||||
#endif
|
||||
|
||||
NS_IMETHOD AttributeAffectsStyle(nsIAtom *aAttribute, nsIContent *aContent,
|
||||
PRBool &aAffects);
|
||||
|
||||
private:
|
||||
// These are not supported and are not implemented!
|
||||
StyleSetImpl(const StyleSetImpl& aCopy);
|
||||
|
@ -1354,6 +1357,46 @@ void StyleSetImpl::ResetUniqueStyleItems(void)
|
|||
uniqueItems->Clear();
|
||||
}
|
||||
|
||||
struct AttributeContentPair {
|
||||
nsIAtom *attribute;
|
||||
nsIContent *content;
|
||||
};
|
||||
|
||||
static PRBool
|
||||
EnumAffectsStyle(nsISupports *aElement, void *aData)
|
||||
{
|
||||
nsIStyleSheet *sheet = NS_STATIC_CAST(nsIStyleSheet *, aElement);
|
||||
AttributeContentPair *pair = (AttributeContentPair *)aData;
|
||||
PRBool affects;
|
||||
if (NS_FAILED(sheet->AttributeAffectsStyle(pair->attribute, pair->content,
|
||||
affects)) || affects)
|
||||
return PR_FALSE; // stop checking
|
||||
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
StyleSetImpl::AttributeAffectsStyle(nsIAtom *aAttribute, nsIContent *aContent,
|
||||
PRBool &aAffects)
|
||||
{
|
||||
AttributeContentPair pair;
|
||||
pair.attribute = aAttribute;
|
||||
pair.content = aContent;
|
||||
|
||||
/* check until we find a sheet that will be affected */
|
||||
if ((mDocSheets && !mDocSheets->EnumerateForwards(EnumAffectsStyle, &pair)) ||
|
||||
(mOverrideSheets && !mOverrideSheets->EnumerateForwards(EnumAffectsStyle,
|
||||
&pair)) ||
|
||||
(mBackstopSheets && !mBackstopSheets->EnumerateForwards(EnumAffectsStyle,
|
||||
&pair))) {
|
||||
aAffects = PR_TRUE;
|
||||
} else {
|
||||
aAffects = PR_FALSE;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* SizeOf method:
|
||||
*
|
||||
|
|
|
@ -235,6 +235,8 @@ public:
|
|||
nsStyleChangeList& aChangeList,
|
||||
PRInt32 aMinChange,
|
||||
PRInt32& aTopLevelChange);
|
||||
NS_IMETHOD AttributeAffectsStyle(nsIAtom *aAttribute, nsIContent *aContent,
|
||||
PRBool &aAffects);
|
||||
|
||||
NS_IMETHOD CaptureFrameState(nsIPresContext* aPresContext,
|
||||
nsIFrame* aFrame,
|
||||
|
@ -1386,6 +1388,12 @@ FrameManager::ComputeStyleChangeFor(nsIPresContext* aPresContext,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
FrameManager::AttributeAffectsStyle(nsIAtom *aAttribute, nsIContent *aContent,
|
||||
PRBool &aAffects)
|
||||
{
|
||||
return mStyleSet->AttributeAffectsStyle(aAttribute, aContent, aAffects);
|
||||
}
|
||||
|
||||
static nsresult
|
||||
CaptureFrameStateFor(nsIPresContext* aPresContext, nsIFrame* aFrame, nsILayoutHistoryState* aState)
|
||||
|
|
|
@ -1280,12 +1280,22 @@ nsGenericHTMLElement::SetAttribute(PRInt32 aNameSpaceID,
|
|||
return result;
|
||||
}
|
||||
|
||||
// don't do any update if old == new
|
||||
nsAutoString strValue;
|
||||
result = GetAttribute(aNameSpaceID, aAttribute, strValue);
|
||||
if ((NS_CONTENT_ATTR_NOT_THERE != result) && aValue.Equals(strValue)) {
|
||||
NS_RELEASE(htmlContent);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (aNotify && (nsnull != mDocument)) {
|
||||
mDocument->BeginUpdate();
|
||||
}
|
||||
|
||||
// set as string value to avoid another string copy
|
||||
PRBool impact = NS_STYLE_HINT_NONE;
|
||||
htmlContent->GetMappedAttributeImpact(aAttribute, impact);
|
||||
|
||||
if (nsnull != mDocument) { // set attr via style sheet
|
||||
nsIHTMLStyleSheet* sheet = GetAttrStyleSheet(mDocument);
|
||||
if (nsnull != sheet) {
|
||||
|
|
|
@ -9539,9 +9539,24 @@ nsCSSFrameConstructor::AttributeChanged(nsIPresContext* aPresContext,
|
|||
changeList.AppendChange(primaryFrame, aContent, maxHint);
|
||||
nsCOMPtr<nsIFrameManager> frameManager;
|
||||
shell->GetFrameManager(getter_AddRefs(frameManager));
|
||||
frameManager->ComputeStyleChangeFor(aPresContext, primaryFrame,
|
||||
aNameSpaceID, aAttribute,
|
||||
changeList, aHint, maxHint);
|
||||
|
||||
PRBool affects;
|
||||
frameManager->AttributeAffectsStyle(aAttribute, aContent, affects);
|
||||
if (affects) {
|
||||
#ifdef DEBUG_shaver
|
||||
fputc('+', stderr);
|
||||
#endif
|
||||
// there is an effect, so compute it
|
||||
frameManager->ComputeStyleChangeFor(aPresContext, primaryFrame,
|
||||
aNameSpaceID, aAttribute,
|
||||
changeList, aHint, maxHint);
|
||||
} else {
|
||||
#ifdef DEBUG_shaver
|
||||
fputc('-', stderr);
|
||||
#endif
|
||||
// let this frame update itself, but don't walk the whole frame tree
|
||||
maxHint = NS_STYLE_HINT_VISUAL;
|
||||
}
|
||||
|
||||
switch (maxHint) { // maxHint is hint for primary only
|
||||
case NS_STYLE_HINT_RECONSTRUCT_ALL:
|
||||
|
|
|
@ -459,6 +459,7 @@ public:
|
|||
|
||||
nsINameSpace* mNameSpace;
|
||||
PRInt32 mDefaultNameSpaceID;
|
||||
nsHashtable mRelevantAttributes;
|
||||
|
||||
static nsIIOService* gIOService;
|
||||
static nsrefcnt gRefcnt;
|
||||
|
@ -518,6 +519,15 @@ public:
|
|||
NS_IMETHOD AppendStyleSheet(nsICSSStyleSheet* aSheet);
|
||||
NS_IMETHOD InsertStyleSheetAt(nsICSSStyleSheet* aSheet, PRInt32 aIndex);
|
||||
|
||||
|
||||
// If changing the given attribute cannot affect style context, aAffects
|
||||
// will be PR_FALSE on return.
|
||||
NS_IMETHOD AttributeAffectsStyle(nsIAtom *aAttribute, nsIContent *aContent,
|
||||
PRBool &aAffects);
|
||||
|
||||
// Find attributes in selector for rule, for use with AttributeAffectsStyle
|
||||
NS_IMETHOD CheckRuleForAttributes(nsICSSRule* aRule);
|
||||
|
||||
// XXX do these belong here or are they generic?
|
||||
NS_IMETHOD PrependStyleRule(nsICSSRule* aRule);
|
||||
NS_IMETHOD AppendStyleRule(nsICSSRule* aRule);
|
||||
|
@ -1090,7 +1100,8 @@ CSSStyleSheetInner::CSSStyleSheetInner(nsICSSStyleSheet* aParentSheet)
|
|||
mURL(nsnull),
|
||||
mOrderedRules(nsnull),
|
||||
mNameSpace(nsnull),
|
||||
mDefaultNameSpaceID(kNameSpaceID_None)
|
||||
mDefaultNameSpaceID(kNameSpaceID_None),
|
||||
mRelevantAttributes()
|
||||
{
|
||||
MOZ_COUNT_CTOR(CSSStyleSheetInner);
|
||||
if (gRefcnt++ == 0) {
|
||||
|
@ -1117,12 +1128,24 @@ CloneRuleInto(nsISupports* aRule, void* aArray)
|
|||
return PR_TRUE;
|
||||
}
|
||||
|
||||
static PRBool
|
||||
CopyRelevantAttributes(nsHashKey *aAttrKey, void *aAtom, void *aTable)
|
||||
{
|
||||
nsHashtable *table = NS_STATIC_CAST(nsHashtable *, aTable);
|
||||
AtomKey *key = NS_STATIC_CAST(AtomKey *, aAttrKey);
|
||||
table->Put(key, key->mAtom);
|
||||
// we don't need to addref the atom here, because we're also copying the
|
||||
// rules when we clone, and that will add a ref for us
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
CSSStyleSheetInner::CSSStyleSheetInner(CSSStyleSheetInner& aCopy,
|
||||
nsICSSStyleSheet* aParentSheet)
|
||||
: mSheets(),
|
||||
mURL(aCopy.mURL),
|
||||
mNameSpace(nsnull),
|
||||
mDefaultNameSpaceID(aCopy.mDefaultNameSpaceID)
|
||||
mDefaultNameSpaceID(aCopy.mDefaultNameSpaceID),
|
||||
mRelevantAttributes()
|
||||
{
|
||||
MOZ_COUNT_CTOR(CSSStyleSheetInner);
|
||||
if (gRefcnt++ == 0) {
|
||||
|
@ -1144,6 +1167,8 @@ CSSStyleSheetInner::CSSStyleSheetInner(CSSStyleSheetInner& aCopy,
|
|||
else {
|
||||
mOrderedRules = nsnull;
|
||||
}
|
||||
aCopy.mRelevantAttributes.Enumerate(CopyRelevantAttributes,
|
||||
&mRelevantAttributes);
|
||||
RebuildNameSpaces();
|
||||
}
|
||||
|
||||
|
@ -1840,6 +1865,21 @@ CSSStyleSheetImpl::InsertStyleSheetAt(nsICSSStyleSheet* aSheet, PRInt32 aIndex)
|
|||
return result;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
CSSStyleSheetImpl::AttributeAffectsStyle(nsIAtom *aAttribute,
|
||||
nsIContent *aContent,
|
||||
PRBool &aAffects)
|
||||
{
|
||||
AtomKey key(aAttribute);
|
||||
aAffects = !!mInner->mRelevantAttributes.Get(&key);
|
||||
for (CSSStyleSheetImpl *child = mFirstChild;
|
||||
child && !aAffects;
|
||||
child = child->mNext) {
|
||||
child->AttributeAffectsStyle(aAttribute, aContent, aAffects);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
CSSStyleSheetImpl::PrependStyleRule(nsICSSRule* aRule)
|
||||
{
|
||||
|
@ -1859,6 +1899,8 @@ CSSStyleSheetImpl::PrependStyleRule(nsICSSRule* aRule)
|
|||
if (nsICSSRule::NAMESPACE_RULE == type) {
|
||||
// no api to prepend a namespace (ugh), release old ones and re-create them all
|
||||
mInner->RebuildNameSpaces();
|
||||
} else {
|
||||
CheckRuleForAttributes(aRule);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1906,12 +1948,59 @@ CSSStyleSheetImpl::AppendStyleRule(nsICSSRule* aRule)
|
|||
mInner->mNameSpace = newNameSpace; // takes ref
|
||||
}
|
||||
}
|
||||
} else {
|
||||
CheckRuleForAttributes(aRule);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
static PRBool
|
||||
CheckRuleForAttributesEnum(nsISupports *aRule, void *aData)
|
||||
{
|
||||
nsICSSRule *rule = NS_STATIC_CAST(nsICSSRule *, aRule);
|
||||
CSSStyleSheetImpl *sheet = NS_STATIC_CAST(CSSStyleSheetImpl *, aData);
|
||||
return NS_SUCCEEDED(sheet->CheckRuleForAttributes(rule));
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
CSSStyleSheetImpl::CheckRuleForAttributes(nsICSSRule *aRule)
|
||||
{
|
||||
PRInt32 ruleType;
|
||||
aRule->GetType(ruleType);
|
||||
switch (ruleType) {
|
||||
case nsICSSRule::MEDIA_RULE: {
|
||||
nsICSSMediaRule *mediaRule = (nsICSSMediaRule *)aRule;
|
||||
return mediaRule->EnumerateRulesForwards(CheckRuleForAttributesEnum,
|
||||
(void *)this);
|
||||
}
|
||||
case nsICSSRule::STYLE_RULE: {
|
||||
nsICSSStyleRule *styleRule = NS_STATIC_CAST(nsICSSStyleRule *, aRule);
|
||||
nsCSSSelector *iter;
|
||||
for (iter = styleRule->FirstSelector(); iter; iter = iter->mNext) {
|
||||
nsAttrSelector *sel;
|
||||
for (sel = iter->mAttrList; sel; sel = sel->mNext) {
|
||||
/* store it in this sheet's attributes-that-matter table */
|
||||
/* XXX store tag name too, but handle collisions */
|
||||
#ifdef DEBUG_shaver_off
|
||||
nsAutoString str;
|
||||
sel->mAttr->ToString(str);
|
||||
char * chars = str.ToNewCString();
|
||||
fprintf(stderr, "[%s@%p]", chars, this);
|
||||
nsAllocator::Free(chars);
|
||||
#endif
|
||||
AtomKey key(sel->mAttr);
|
||||
mInner->mRelevantAttributes.Put(&key, sel->mAttr);
|
||||
}
|
||||
}
|
||||
} /* fall-through */
|
||||
default:
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
CSSStyleSheetImpl::StyleRuleCount(PRInt32& aCount) const
|
||||
{
|
||||
|
|
|
@ -367,6 +367,10 @@ public:
|
|||
|
||||
virtual void SizeOf(nsISizeOfHandler *aSizeofHandler, PRUint32 &aSize);
|
||||
|
||||
// If changing the given attribute cannot affect style context, aAffects
|
||||
// will be PR_FALSE on return.
|
||||
NS_IMETHOD AttributeAffectsStyle(nsIAtom *aAttribute, nsIContent *aContent,
|
||||
PRBool &aAffects);
|
||||
private:
|
||||
// These are not supported and are not implemented!
|
||||
HTMLCSSStyleSheetImpl(const HTMLCSSStyleSheetImpl& aCopy);
|
||||
|
@ -761,6 +765,16 @@ void HTMLCSSStyleSheetImpl::SizeOf(nsISizeOfHandler *aSizeOfHandler, PRUint32 &a
|
|||
}
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
HTMLCSSStyleSheetImpl::AttributeAffectsStyle(nsIAtom *aAttribute,
|
||||
nsIContent *aContent,
|
||||
PRBool &aAffects)
|
||||
{
|
||||
// XXX can attributes affect rules in these?
|
||||
aAffects = PR_FALSE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// XXX For backwards compatibility and convenience
|
||||
NS_HTML nsresult
|
||||
NS_NewHTMLCSSStyleSheet(nsIHTMLCSSStyleSheet** aInstancePtrResult, nsIURI* aURL,
|
||||
|
|
|
@ -654,6 +654,10 @@ public:
|
|||
|
||||
virtual void SizeOf(nsISizeOfHandler *aSizeofHandler, PRUint32 &aSize);
|
||||
|
||||
// If changing the given attribute cannot affect style context, aAffects
|
||||
// will be PR_FALSE on return.
|
||||
NS_IMETHOD AttributeAffectsStyle(nsIAtom *aAttribute, nsIContent *aContent,
|
||||
PRBool &aAffects);
|
||||
private:
|
||||
// These are not supported and are not implemented!
|
||||
HTMLStyleSheetImpl(const HTMLStyleSheetImpl& aCopy);
|
||||
|
@ -1506,6 +1510,16 @@ void HTMLStyleSheetImpl::SizeOf(nsISizeOfHandler *aSizeOfHandler, PRUint32 &aSiz
|
|||
// that's it
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
HTMLStyleSheetImpl::AttributeAffectsStyle(nsIAtom *aAttribute,
|
||||
nsIContent *aContent,
|
||||
PRBool &aAffects)
|
||||
{
|
||||
// XXX we should be checking to see if this is an href on an <A> being
|
||||
// XXX tweaked, in which case we really want to restyle
|
||||
aAffects = PR_FALSE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// XXX For convenience and backwards compatibility
|
||||
NS_HTML nsresult
|
||||
|
|
|
@ -459,6 +459,7 @@ public:
|
|||
|
||||
nsINameSpace* mNameSpace;
|
||||
PRInt32 mDefaultNameSpaceID;
|
||||
nsHashtable mRelevantAttributes;
|
||||
|
||||
static nsIIOService* gIOService;
|
||||
static nsrefcnt gRefcnt;
|
||||
|
@ -518,6 +519,15 @@ public:
|
|||
NS_IMETHOD AppendStyleSheet(nsICSSStyleSheet* aSheet);
|
||||
NS_IMETHOD InsertStyleSheetAt(nsICSSStyleSheet* aSheet, PRInt32 aIndex);
|
||||
|
||||
|
||||
// If changing the given attribute cannot affect style context, aAffects
|
||||
// will be PR_FALSE on return.
|
||||
NS_IMETHOD AttributeAffectsStyle(nsIAtom *aAttribute, nsIContent *aContent,
|
||||
PRBool &aAffects);
|
||||
|
||||
// Find attributes in selector for rule, for use with AttributeAffectsStyle
|
||||
NS_IMETHOD CheckRuleForAttributes(nsICSSRule* aRule);
|
||||
|
||||
// XXX do these belong here or are they generic?
|
||||
NS_IMETHOD PrependStyleRule(nsICSSRule* aRule);
|
||||
NS_IMETHOD AppendStyleRule(nsICSSRule* aRule);
|
||||
|
@ -1090,7 +1100,8 @@ CSSStyleSheetInner::CSSStyleSheetInner(nsICSSStyleSheet* aParentSheet)
|
|||
mURL(nsnull),
|
||||
mOrderedRules(nsnull),
|
||||
mNameSpace(nsnull),
|
||||
mDefaultNameSpaceID(kNameSpaceID_None)
|
||||
mDefaultNameSpaceID(kNameSpaceID_None),
|
||||
mRelevantAttributes()
|
||||
{
|
||||
MOZ_COUNT_CTOR(CSSStyleSheetInner);
|
||||
if (gRefcnt++ == 0) {
|
||||
|
@ -1117,12 +1128,24 @@ CloneRuleInto(nsISupports* aRule, void* aArray)
|
|||
return PR_TRUE;
|
||||
}
|
||||
|
||||
static PRBool
|
||||
CopyRelevantAttributes(nsHashKey *aAttrKey, void *aAtom, void *aTable)
|
||||
{
|
||||
nsHashtable *table = NS_STATIC_CAST(nsHashtable *, aTable);
|
||||
AtomKey *key = NS_STATIC_CAST(AtomKey *, aAttrKey);
|
||||
table->Put(key, key->mAtom);
|
||||
// we don't need to addref the atom here, because we're also copying the
|
||||
// rules when we clone, and that will add a ref for us
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
CSSStyleSheetInner::CSSStyleSheetInner(CSSStyleSheetInner& aCopy,
|
||||
nsICSSStyleSheet* aParentSheet)
|
||||
: mSheets(),
|
||||
mURL(aCopy.mURL),
|
||||
mNameSpace(nsnull),
|
||||
mDefaultNameSpaceID(aCopy.mDefaultNameSpaceID)
|
||||
mDefaultNameSpaceID(aCopy.mDefaultNameSpaceID),
|
||||
mRelevantAttributes()
|
||||
{
|
||||
MOZ_COUNT_CTOR(CSSStyleSheetInner);
|
||||
if (gRefcnt++ == 0) {
|
||||
|
@ -1144,6 +1167,8 @@ CSSStyleSheetInner::CSSStyleSheetInner(CSSStyleSheetInner& aCopy,
|
|||
else {
|
||||
mOrderedRules = nsnull;
|
||||
}
|
||||
aCopy.mRelevantAttributes.Enumerate(CopyRelevantAttributes,
|
||||
&mRelevantAttributes);
|
||||
RebuildNameSpaces();
|
||||
}
|
||||
|
||||
|
@ -1840,6 +1865,21 @@ CSSStyleSheetImpl::InsertStyleSheetAt(nsICSSStyleSheet* aSheet, PRInt32 aIndex)
|
|||
return result;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
CSSStyleSheetImpl::AttributeAffectsStyle(nsIAtom *aAttribute,
|
||||
nsIContent *aContent,
|
||||
PRBool &aAffects)
|
||||
{
|
||||
AtomKey key(aAttribute);
|
||||
aAffects = !!mInner->mRelevantAttributes.Get(&key);
|
||||
for (CSSStyleSheetImpl *child = mFirstChild;
|
||||
child && !aAffects;
|
||||
child = child->mNext) {
|
||||
child->AttributeAffectsStyle(aAttribute, aContent, aAffects);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
CSSStyleSheetImpl::PrependStyleRule(nsICSSRule* aRule)
|
||||
{
|
||||
|
@ -1859,6 +1899,8 @@ CSSStyleSheetImpl::PrependStyleRule(nsICSSRule* aRule)
|
|||
if (nsICSSRule::NAMESPACE_RULE == type) {
|
||||
// no api to prepend a namespace (ugh), release old ones and re-create them all
|
||||
mInner->RebuildNameSpaces();
|
||||
} else {
|
||||
CheckRuleForAttributes(aRule);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1906,12 +1948,59 @@ CSSStyleSheetImpl::AppendStyleRule(nsICSSRule* aRule)
|
|||
mInner->mNameSpace = newNameSpace; // takes ref
|
||||
}
|
||||
}
|
||||
} else {
|
||||
CheckRuleForAttributes(aRule);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
static PRBool
|
||||
CheckRuleForAttributesEnum(nsISupports *aRule, void *aData)
|
||||
{
|
||||
nsICSSRule *rule = NS_STATIC_CAST(nsICSSRule *, aRule);
|
||||
CSSStyleSheetImpl *sheet = NS_STATIC_CAST(CSSStyleSheetImpl *, aData);
|
||||
return NS_SUCCEEDED(sheet->CheckRuleForAttributes(rule));
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
CSSStyleSheetImpl::CheckRuleForAttributes(nsICSSRule *aRule)
|
||||
{
|
||||
PRInt32 ruleType;
|
||||
aRule->GetType(ruleType);
|
||||
switch (ruleType) {
|
||||
case nsICSSRule::MEDIA_RULE: {
|
||||
nsICSSMediaRule *mediaRule = (nsICSSMediaRule *)aRule;
|
||||
return mediaRule->EnumerateRulesForwards(CheckRuleForAttributesEnum,
|
||||
(void *)this);
|
||||
}
|
||||
case nsICSSRule::STYLE_RULE: {
|
||||
nsICSSStyleRule *styleRule = NS_STATIC_CAST(nsICSSStyleRule *, aRule);
|
||||
nsCSSSelector *iter;
|
||||
for (iter = styleRule->FirstSelector(); iter; iter = iter->mNext) {
|
||||
nsAttrSelector *sel;
|
||||
for (sel = iter->mAttrList; sel; sel = sel->mNext) {
|
||||
/* store it in this sheet's attributes-that-matter table */
|
||||
/* XXX store tag name too, but handle collisions */
|
||||
#ifdef DEBUG_shaver_off
|
||||
nsAutoString str;
|
||||
sel->mAttr->ToString(str);
|
||||
char * chars = str.ToNewCString();
|
||||
fprintf(stderr, "[%s@%p]", chars, this);
|
||||
nsAllocator::Free(chars);
|
||||
#endif
|
||||
AtomKey key(sel->mAttr);
|
||||
mInner->mRelevantAttributes.Put(&key, sel->mAttr);
|
||||
}
|
||||
}
|
||||
} /* fall-through */
|
||||
default:
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
CSSStyleSheetImpl::StyleRuleCount(PRInt32& aCount) const
|
||||
{
|
||||
|
|
|
@ -367,6 +367,10 @@ public:
|
|||
|
||||
virtual void SizeOf(nsISizeOfHandler *aSizeofHandler, PRUint32 &aSize);
|
||||
|
||||
// If changing the given attribute cannot affect style context, aAffects
|
||||
// will be PR_FALSE on return.
|
||||
NS_IMETHOD AttributeAffectsStyle(nsIAtom *aAttribute, nsIContent *aContent,
|
||||
PRBool &aAffects);
|
||||
private:
|
||||
// These are not supported and are not implemented!
|
||||
HTMLCSSStyleSheetImpl(const HTMLCSSStyleSheetImpl& aCopy);
|
||||
|
@ -761,6 +765,16 @@ void HTMLCSSStyleSheetImpl::SizeOf(nsISizeOfHandler *aSizeOfHandler, PRUint32 &a
|
|||
}
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
HTMLCSSStyleSheetImpl::AttributeAffectsStyle(nsIAtom *aAttribute,
|
||||
nsIContent *aContent,
|
||||
PRBool &aAffects)
|
||||
{
|
||||
// XXX can attributes affect rules in these?
|
||||
aAffects = PR_FALSE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// XXX For backwards compatibility and convenience
|
||||
NS_HTML nsresult
|
||||
NS_NewHTMLCSSStyleSheet(nsIHTMLCSSStyleSheet** aInstancePtrResult, nsIURI* aURL,
|
||||
|
|
|
@ -654,6 +654,10 @@ public:
|
|||
|
||||
virtual void SizeOf(nsISizeOfHandler *aSizeofHandler, PRUint32 &aSize);
|
||||
|
||||
// If changing the given attribute cannot affect style context, aAffects
|
||||
// will be PR_FALSE on return.
|
||||
NS_IMETHOD AttributeAffectsStyle(nsIAtom *aAttribute, nsIContent *aContent,
|
||||
PRBool &aAffects);
|
||||
private:
|
||||
// These are not supported and are not implemented!
|
||||
HTMLStyleSheetImpl(const HTMLStyleSheetImpl& aCopy);
|
||||
|
@ -1506,6 +1510,16 @@ void HTMLStyleSheetImpl::SizeOf(nsISizeOfHandler *aSizeOfHandler, PRUint32 &aSiz
|
|||
// that's it
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
HTMLStyleSheetImpl::AttributeAffectsStyle(nsIAtom *aAttribute,
|
||||
nsIContent *aContent,
|
||||
PRBool &aAffects)
|
||||
{
|
||||
// XXX we should be checking to see if this is an href on an <A> being
|
||||
// XXX tweaked, in which case we really want to restyle
|
||||
aAffects = PR_FALSE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// XXX For convenience and backwards compatibility
|
||||
NS_HTML nsresult
|
||||
|
|
|
@ -71,6 +71,11 @@ public:
|
|||
virtual void List(FILE* out = stdout, PRInt32 aIndent = 0) const = 0;
|
||||
|
||||
virtual void SizeOf(nsISizeOfHandler *aSizeofHandler, PRUint32 &aSize) = 0;
|
||||
|
||||
// If changing the given attribute cannot affect style context, aAffects
|
||||
// will be PR_FALSE on return.
|
||||
NS_IMETHOD AttributeAffectsStyle(nsIAtom *aAttribute, nsIContent *aContent,
|
||||
PRBool &aAffects) = 0;
|
||||
};
|
||||
|
||||
#endif /* nsIStyleSheet_h___ */
|
||||
|
|
|
@ -191,6 +191,9 @@ public:
|
|||
NS_DECL_NSITIMERECORDER
|
||||
#endif
|
||||
|
||||
NS_IMETHOD AttributeAffectsStyle(nsIAtom *aAttribute, nsIContent *aContent,
|
||||
PRBool &aAffects);
|
||||
|
||||
private:
|
||||
// These are not supported and are not implemented!
|
||||
StyleSetImpl(const StyleSetImpl& aCopy);
|
||||
|
@ -1354,6 +1357,46 @@ void StyleSetImpl::ResetUniqueStyleItems(void)
|
|||
uniqueItems->Clear();
|
||||
}
|
||||
|
||||
struct AttributeContentPair {
|
||||
nsIAtom *attribute;
|
||||
nsIContent *content;
|
||||
};
|
||||
|
||||
static PRBool
|
||||
EnumAffectsStyle(nsISupports *aElement, void *aData)
|
||||
{
|
||||
nsIStyleSheet *sheet = NS_STATIC_CAST(nsIStyleSheet *, aElement);
|
||||
AttributeContentPair *pair = (AttributeContentPair *)aData;
|
||||
PRBool affects;
|
||||
if (NS_FAILED(sheet->AttributeAffectsStyle(pair->attribute, pair->content,
|
||||
affects)) || affects)
|
||||
return PR_FALSE; // stop checking
|
||||
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
StyleSetImpl::AttributeAffectsStyle(nsIAtom *aAttribute, nsIContent *aContent,
|
||||
PRBool &aAffects)
|
||||
{
|
||||
AttributeContentPair pair;
|
||||
pair.attribute = aAttribute;
|
||||
pair.content = aContent;
|
||||
|
||||
/* check until we find a sheet that will be affected */
|
||||
if ((mDocSheets && !mDocSheets->EnumerateForwards(EnumAffectsStyle, &pair)) ||
|
||||
(mOverrideSheets && !mOverrideSheets->EnumerateForwards(EnumAffectsStyle,
|
||||
&pair)) ||
|
||||
(mBackstopSheets && !mBackstopSheets->EnumerateForwards(EnumAffectsStyle,
|
||||
&pair))) {
|
||||
aAffects = PR_TRUE;
|
||||
} else {
|
||||
aAffects = PR_FALSE;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* SizeOf method:
|
||||
*
|
||||
|
|
Загрузка…
Ссылка в новой задаче