Handle style attribute changes in XUL through the normal style change mechanism rather than forcing a reframe. Change nsIStyledContent::WalkInlineStyleRules to nsIStyledContent::GetInlineStyleRule to simplify nsCSSFrameConstructor::AttributeChanged. b=156971 sr=hyatt r=bzbarsky

This commit is contained in:
dbaron%fas.harvard.edu 2002-08-16 11:29:20 +00:00
Родитель 166505939a
Коммит d4cc4f7061
13 изменённых файлов: 91 добавлений и 212 удалений

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

@ -61,7 +61,7 @@ public:
NS_IMETHOD HasClass(nsIAtom* aClass, PRBool aCaseSensitive) const = 0;
NS_IMETHOD WalkContentStyleRules(nsRuleWalker* aRuleWalker) = 0;
NS_IMETHOD WalkInlineStyleRules(nsRuleWalker* aRuleWalker) = 0;
NS_IMETHOD GetInlineStyleRule(nsIStyleRule** aStyleRule) = 0;
/** NRA ***
* Get a hint that tells the style system what to do when

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

@ -2156,9 +2156,10 @@ nsGenericElement::WalkContentStyleRules(nsRuleWalker* aRuleWalker)
}
NS_IMETHODIMP
nsGenericElement::WalkInlineStyleRules(nsRuleWalker* aRuleWalker)
nsGenericElement::GetInlineStyleRule(nsIStyleRule** aStyleRule)
{
return NS_ERROR_NOT_IMPLEMENTED;
*aStyleRule = nsnull;
return NS_OK;
}
NS_IMETHODIMP

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

@ -400,7 +400,7 @@ public:
NS_IMETHOD GetClasses(nsVoidArray& aArray) const;
NS_IMETHOD HasClass(nsIAtom* aClass, PRBool aCaseSensitive) const;
NS_IMETHOD WalkContentStyleRules(nsRuleWalker* aRuleWalker);
NS_IMETHOD WalkInlineStyleRules(nsRuleWalker* aRuleWalker);
NS_IMETHOD GetInlineStyleRule(nsIStyleRule** aStyleRule);
NS_IMETHOD GetMappedAttributeImpact(const nsIAtom* aAttribute,
PRInt32 aModType, PRInt32& aHint) const;

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

@ -2280,26 +2280,22 @@ nsGenericHTMLElement::WalkContentStyleRules(nsRuleWalker* aRuleWalker)
}
nsresult
nsGenericHTMLElement::WalkInlineStyleRules(nsRuleWalker* aRuleWalker)
nsGenericHTMLElement::GetInlineStyleRule(nsIStyleRule** aStyleRule)
{
nsresult result = NS_ERROR_NULL_POINTER;
nsCOMPtr<nsIStyleRule> rule;
*aStyleRule = nsnull;
if (aRuleWalker && mAttributes) {
if (mAttributes) {
nsHTMLValue value;
if (NS_CONTENT_ATTR_HAS_VALUE == mAttributes->GetAttribute(nsHTMLAtoms::style, value)) {
if (eHTMLUnit_ISupports == value.GetUnit()) {
nsCOMPtr<nsISupports> supports = getter_AddRefs(value.GetISupportsValue());
if (supports)
rule = do_QueryInterface(supports, &result);
CallQueryInterface(supports, aStyleRule);
}
}
}
if (rule)
aRuleWalker->Forward(rule, PR_TRUE);
return result;
return NS_OK;
}
nsresult

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

@ -214,7 +214,7 @@ public:
NS_IMETHOD GetClasses(nsVoidArray& aArray) const;
NS_IMETHOD HasClass(nsIAtom* aClass, PRBool aCaseSensitive) const;
NS_IMETHOD WalkContentStyleRules(nsRuleWalker* aRuleWalker);
NS_IMETHOD WalkInlineStyleRules(nsRuleWalker* aRuleWalker);
NS_IMETHOD GetInlineStyleRule(nsIStyleRule** aStyleRule);
NS_IMETHOD GetBaseURL(nsIURI*& aBaseURL) const;
NS_IMETHOD GetBaseTarget(nsAString& aBaseTarget) const;

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

@ -354,9 +354,13 @@ HTMLCSSStyleSheetImpl::RulesMatching(ElementRuleProcessorData* aData,
{
nsIStyledContent *styledContent = aData->mStyledContent;
if (styledContent)
if (styledContent) {
// just get the one and only style rule from the content's STYLE attribute
styledContent->WalkInlineStyleRules(aData->mRuleWalker);
nsCOMPtr<nsIStyleRule> rule;
styledContent->GetInlineStyleRule(getter_AddRefs(rule));
if (rule)
aData->mRuleWalker->Forward(rule, PR_TRUE);
}
return NS_OK;
}

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

@ -446,14 +446,9 @@ nsSVGElement::WalkContentStyleRules(nsRuleWalker* aRuleWalker)
}
NS_IMETHODIMP
nsSVGElement::WalkInlineStyleRules(nsRuleWalker* aRuleWalker)
nsSVGElement::GetInlineStyleRule(nsIStyleRule** aStyleRule)
{
nsCOMPtr<nsIStyleRule> rule;
mStyle->GetStyleRule(mDocument, getter_AddRefs(rule));
if (aRuleWalker && rule) {
aRuleWalker->Forward(rule, PR_TRUE);
}
return NS_OK;
return mStyle->GetStyleRule(mDocument, aStyleRule);
}
NS_IMETHODIMP

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

@ -143,7 +143,7 @@ public:
// NS_IMETHOD HasClass(nsIAtom* aClass) const;
NS_IMETHOD WalkContentStyleRules(nsRuleWalker* aRuleWalker);
NS_IMETHOD WalkInlineStyleRules(nsRuleWalker* aRuleWalker);
NS_IMETHOD GetInlineStyleRule(nsIStyleRule** aStyleRule);
NS_IMETHOD GetMappedAttributeImpact(const nsIAtom* aAttribute, PRInt32 aModType,
PRInt32& aHint) const;

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

@ -3858,23 +3858,19 @@ nsXULElement::WalkContentStyleRules(nsRuleWalker* aRuleWalker)
}
NS_IMETHODIMP
nsXULElement::WalkInlineStyleRules(nsRuleWalker* aRuleWalker)
nsXULElement::GetInlineStyleRule(nsIStyleRule** aStyleRule)
{
// Fetch the cached style rule from the attributes.
nsresult result = NS_ERROR_NULL_POINTER;
nsCOMPtr<nsIStyleRule> rule;
if (aRuleWalker) {
if (Attributes()) {
result = Attributes()->GetInlineStyleRule(*getter_AddRefs(rule));
}
else if (mPrototype && mPrototype->mInlineStyleRule) {
rule = mPrototype->mInlineStyleRule;
result = NS_OK;
}
nsresult result = NS_OK;
if (Attributes()) {
result = Attributes()->GetInlineStyleRule(*aStyleRule);
}
else if (mPrototype) {
*aStyleRule = mPrototype->mInlineStyleRule;
NS_IF_ADDREF(*aStyleRule);
} else {
*aStyleRule = nsnull;
}
if (rule)
aRuleWalker->Forward(rule, PR_TRUE);
return result;
}
@ -3902,13 +3898,6 @@ nsXULElement::GetMappedAttributeImpact(const nsIAtom* aAttribute, PRInt32 aModTy
// VERY IMPORTANT! This has a huge positive performance impact!
aHint = NS_STYLE_HINT_ATTRCHANGE;
}
else if (aAttribute == nsXULAtoms::style) {
// well, okay, "style=" maps to style. This is totally
// non-optimal, because it's very likely that the frame
// *won't* change. Oh well, you're a tool for setting the
// "style" attribute anyway.
aHint = NS_STYLE_HINT_FRAMECHANGE;
}
else if (NodeInfo()->Equals(nsXULAtoms::window) ||
NodeInfo()->Equals(nsXULAtoms::page) ||
NodeInfo()->Equals(nsXULAtoms::dialog) ||

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

@ -470,7 +470,7 @@ public:
NS_IMETHOD HasClass(nsIAtom* aClass, PRBool aCaseSensitive) const;
NS_IMETHOD WalkContentStyleRules(nsRuleWalker* aRuleWalker);
NS_IMETHOD WalkInlineStyleRules(nsRuleWalker* aRuleWalker);
NS_IMETHOD GetInlineStyleRule(nsIStyleRule** aStyleRule);
NS_IMETHOD GetMappedAttributeImpact(const nsIAtom* aAttribute, PRInt32 aModType,
PRInt32& aHint) const;

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

@ -8084,6 +8084,7 @@ nsCSSFrameConstructor::FindPreviousSibling(nsIPresShell* aPresShell,
// If the frame is out-of-flow, GPFF() will have returned the
// out-of-flow frame; we want the placeholder.
// XXXldb Why not check NS_FRAME_OUT_OF_FLOW state bit?
const nsStyleDisplay* display;
prevSibling->GetStyleData(eStyleStruct_Display,
(const nsStyleStruct*&)display);
@ -8094,6 +8095,7 @@ nsCSSFrameConstructor::FindPreviousSibling(nsIPresShell* aPresShell,
if (display->mDisplay == NS_STYLE_DISPLAY_POPUP) {
nsIFrame* placeholderFrame;
aPresShell->GetPlaceholderFrameFor(prevSibling, &placeholderFrame);
// XXXldb Was this supposed to be a null-check of placeholderFrame?
if (prevSibling)
prevSibling = placeholderFrame;
}
@ -10651,98 +10653,41 @@ nsCSSFrameConstructor::AttributeChanged(nsIPresContext* aPresContext,
#endif // INCLUDE_XUL
// check for inline style. we need to clear the data at the style context's rule
// node whenever the inline style property changes.
// check for inline style. we need to clear the data at the style
// context's rule node whenever the inline style property changes.
nsCOMPtr<nsIStyleContext> styleContext;
nsCOMPtr<nsIStyleRule> rule;
PRBool inlineStyle = PR_FALSE;
if (aAttribute == nsHTMLAtoms::style) {
nsCOMPtr<nsIHTMLContent> html(do_QueryInterface(aContent));
if (html) {
nsHTMLValue val;
html->GetHTMLAttribute(nsHTMLAtoms::style, val);
if (eHTMLUnit_ISupports == val.GetUnit()) {
inlineStyle = PR_TRUE;
nsCOMPtr<nsIStyledContent> scontent(do_QueryInterface(aContent));
scontent->GetInlineStyleRule(getter_AddRefs(rule));
if (rule) {
inlineStyle = PR_TRUE;
// This style rule exists and we need to blow away any computed data that this
// rule cached in the rule tree.
rule = getter_AddRefs((nsIStyleRule*)val.GetISupportsValue());
if (primaryStyleFrame)
primaryStyleFrame->GetStyleContext(getter_AddRefs(styleContext));
else {
// We might be in the undisplayed map. Retrieve the style context from there.
nsCOMPtr<nsIFrameManager> frameManager;
shell->GetFrameManager(getter_AddRefs(frameManager));
frameManager->GetUndisplayedContent(aContent, getter_AddRefs(styleContext));
// This style rule exists and we need to blow away any computed
// data that this rule cached in the rule tree.
if (primaryStyleFrame)
primaryStyleFrame->GetStyleContext(getter_AddRefs(styleContext));
else {
// We might be in the undisplayed map. Retrieve the style context from there.
nsCOMPtr<nsIFrameManager> frameManager;
shell->GetFrameManager(getter_AddRefs(frameManager));
frameManager->GetUndisplayedContent(aContent, getter_AddRefs(styleContext));
#ifdef DEBUG
if (!styleContext) {
nsCOMPtr<nsIContent> parent;
aContent->GetParent(*getter_AddRefs(parent));
if (parent) {
nsIFrame* parentFrame;
shell->GetPrimaryFrameFor(parent, &parentFrame);
NS_ASSERTION(!parentFrame,
"parent frame but no child frame or undisplayed entry");
}
}
#endif
}
}
}
#ifdef MOZ_SVG
else { // XXX should check we're in SVG NS
nsCOMPtr<nsIDOMElement> domel(do_QueryInterface(aContent));
if (domel) {
// XXX there must be a better way of doing this
nsCOMPtr<nsIDOMAttr> attr;
domel->GetAttributeNode(NS_LITERAL_STRING("style"), getter_AddRefs(attr));
if (attr) {
nsCOMPtr<nsISVGAttribute> svgattr(do_QueryInterface(attr));
if (svgattr) {
nsCOMPtr<nsISVGValue> value;
svgattr->GetSVGValue(getter_AddRefs(value));
if (value) {
nsCOMPtr<nsISVGStyleValue> stylevalue(do_QueryInterface(value));
if (stylevalue) {
nsCOMPtr<nsIDocument> doc;
aContent->GetDocument(*getter_AddRefs(doc));
if (doc) {
stylevalue->GetStyleRule(doc, getter_AddRefs(rule));
if (rule) {
inlineStyle = PR_TRUE;
// ----
if (primaryFrame)
primaryFrame->GetStyleContext(getter_AddRefs(styleContext));
else {
// We might be in the undisplayed map. Retrieve the style context from there.
nsCOMPtr<nsIFrameManager> frameManager;
shell->GetFrameManager(getter_AddRefs(frameManager));
frameManager->GetUndisplayedContent(aContent, getter_AddRefs(styleContext));
#ifdef DEBUG
if (!styleContext) {
nsCOMPtr<nsIContent> parent;
aContent->GetParent(*getter_AddRefs(parent));
if (parent) {
nsIFrame* parentFrame;
shell->GetPrimaryFrameFor(parent, &parentFrame);
NS_ASSERTION(!parentFrame,
"parent frame but no child frame "
"or undisplayed entry");
}
}
#endif
}
//-----
}
}
}
}
if (!styleContext) {
nsCOMPtr<nsIContent> parent;
aContent->GetParent(*getter_AddRefs(parent));
if (parent) {
nsIFrame* parentFrame;
shell->GetPrimaryFrameFor(parent, &parentFrame);
NS_ASSERTION(!parentFrame,
"parent frame but no child frame or undisplayed entry");
}
}
#endif
}
}
#endif
}
// first see if we need to manage the style system:

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

@ -8084,6 +8084,7 @@ nsCSSFrameConstructor::FindPreviousSibling(nsIPresShell* aPresShell,
// If the frame is out-of-flow, GPFF() will have returned the
// out-of-flow frame; we want the placeholder.
// XXXldb Why not check NS_FRAME_OUT_OF_FLOW state bit?
const nsStyleDisplay* display;
prevSibling->GetStyleData(eStyleStruct_Display,
(const nsStyleStruct*&)display);
@ -8094,6 +8095,7 @@ nsCSSFrameConstructor::FindPreviousSibling(nsIPresShell* aPresShell,
if (display->mDisplay == NS_STYLE_DISPLAY_POPUP) {
nsIFrame* placeholderFrame;
aPresShell->GetPlaceholderFrameFor(prevSibling, &placeholderFrame);
// XXXldb Was this supposed to be a null-check of placeholderFrame?
if (prevSibling)
prevSibling = placeholderFrame;
}
@ -10651,98 +10653,41 @@ nsCSSFrameConstructor::AttributeChanged(nsIPresContext* aPresContext,
#endif // INCLUDE_XUL
// check for inline style. we need to clear the data at the style context's rule
// node whenever the inline style property changes.
// check for inline style. we need to clear the data at the style
// context's rule node whenever the inline style property changes.
nsCOMPtr<nsIStyleContext> styleContext;
nsCOMPtr<nsIStyleRule> rule;
PRBool inlineStyle = PR_FALSE;
if (aAttribute == nsHTMLAtoms::style) {
nsCOMPtr<nsIHTMLContent> html(do_QueryInterface(aContent));
if (html) {
nsHTMLValue val;
html->GetHTMLAttribute(nsHTMLAtoms::style, val);
if (eHTMLUnit_ISupports == val.GetUnit()) {
inlineStyle = PR_TRUE;
nsCOMPtr<nsIStyledContent> scontent(do_QueryInterface(aContent));
scontent->GetInlineStyleRule(getter_AddRefs(rule));
if (rule) {
inlineStyle = PR_TRUE;
// This style rule exists and we need to blow away any computed data that this
// rule cached in the rule tree.
rule = getter_AddRefs((nsIStyleRule*)val.GetISupportsValue());
if (primaryStyleFrame)
primaryStyleFrame->GetStyleContext(getter_AddRefs(styleContext));
else {
// We might be in the undisplayed map. Retrieve the style context from there.
nsCOMPtr<nsIFrameManager> frameManager;
shell->GetFrameManager(getter_AddRefs(frameManager));
frameManager->GetUndisplayedContent(aContent, getter_AddRefs(styleContext));
// This style rule exists and we need to blow away any computed
// data that this rule cached in the rule tree.
if (primaryStyleFrame)
primaryStyleFrame->GetStyleContext(getter_AddRefs(styleContext));
else {
// We might be in the undisplayed map. Retrieve the style context from there.
nsCOMPtr<nsIFrameManager> frameManager;
shell->GetFrameManager(getter_AddRefs(frameManager));
frameManager->GetUndisplayedContent(aContent, getter_AddRefs(styleContext));
#ifdef DEBUG
if (!styleContext) {
nsCOMPtr<nsIContent> parent;
aContent->GetParent(*getter_AddRefs(parent));
if (parent) {
nsIFrame* parentFrame;
shell->GetPrimaryFrameFor(parent, &parentFrame);
NS_ASSERTION(!parentFrame,
"parent frame but no child frame or undisplayed entry");
}
}
#endif
}
}
}
#ifdef MOZ_SVG
else { // XXX should check we're in SVG NS
nsCOMPtr<nsIDOMElement> domel(do_QueryInterface(aContent));
if (domel) {
// XXX there must be a better way of doing this
nsCOMPtr<nsIDOMAttr> attr;
domel->GetAttributeNode(NS_LITERAL_STRING("style"), getter_AddRefs(attr));
if (attr) {
nsCOMPtr<nsISVGAttribute> svgattr(do_QueryInterface(attr));
if (svgattr) {
nsCOMPtr<nsISVGValue> value;
svgattr->GetSVGValue(getter_AddRefs(value));
if (value) {
nsCOMPtr<nsISVGStyleValue> stylevalue(do_QueryInterface(value));
if (stylevalue) {
nsCOMPtr<nsIDocument> doc;
aContent->GetDocument(*getter_AddRefs(doc));
if (doc) {
stylevalue->GetStyleRule(doc, getter_AddRefs(rule));
if (rule) {
inlineStyle = PR_TRUE;
// ----
if (primaryFrame)
primaryFrame->GetStyleContext(getter_AddRefs(styleContext));
else {
// We might be in the undisplayed map. Retrieve the style context from there.
nsCOMPtr<nsIFrameManager> frameManager;
shell->GetFrameManager(getter_AddRefs(frameManager));
frameManager->GetUndisplayedContent(aContent, getter_AddRefs(styleContext));
#ifdef DEBUG
if (!styleContext) {
nsCOMPtr<nsIContent> parent;
aContent->GetParent(*getter_AddRefs(parent));
if (parent) {
nsIFrame* parentFrame;
shell->GetPrimaryFrameFor(parent, &parentFrame);
NS_ASSERTION(!parentFrame,
"parent frame but no child frame "
"or undisplayed entry");
}
}
#endif
}
//-----
}
}
}
}
if (!styleContext) {
nsCOMPtr<nsIContent> parent;
aContent->GetParent(*getter_AddRefs(parent));
if (parent) {
nsIFrame* parentFrame;
shell->GetPrimaryFrameFor(parent, &parentFrame);
NS_ASSERTION(!parentFrame,
"parent frame but no child frame or undisplayed entry");
}
}
#endif
}
}
#endif
}
// first see if we need to manage the style system:

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

@ -354,9 +354,13 @@ HTMLCSSStyleSheetImpl::RulesMatching(ElementRuleProcessorData* aData,
{
nsIStyledContent *styledContent = aData->mStyledContent;
if (styledContent)
if (styledContent) {
// just get the one and only style rule from the content's STYLE attribute
styledContent->WalkInlineStyleRules(aData->mRuleWalker);
nsCOMPtr<nsIStyleRule> rule;
styledContent->GetInlineStyleRule(getter_AddRefs(rule));
if (rule)
aData->mRuleWalker->Forward(rule, PR_TRUE);
}
return NS_OK;
}