diff --git a/mozilla/content/html/style/src/nsCSSParser.cpp b/mozilla/content/html/style/src/nsCSSParser.cpp
index fb3ea116644..c7151c28d87 100644
--- a/mozilla/content/html/style/src/nsCSSParser.cpp
+++ b/mozilla/content/html/style/src/nsCSSParser.cpp
@@ -3330,6 +3330,34 @@ done:
return found;
}
+static PRInt32 ComputeChangeHint(nsCSSProperty aPropID,
+ const nsCSSValue& aOldValue,
+ const nsCSSValue& aValue)
+{
+ NS_ASSERTION(aOldValue != aValue,
+ "ComputeChangeHint should not be called with equal values");
+
+ switch (aPropID) {
+ case eCSSProperty_opacity:
+ // If the opacity is changing to or from 1.0, then reframe to (possibly)
+ // cause a view to be created or eliminated
+ // Otherwise we just need a visual change. This is important because
+ // opacity is frequently used for fade effects, and we don't want to reframe
+ // for every step of the fade.
+ if (aOldValue.GetUnit() == eCSSUnit_Number && aValue.GetUnit() == eCSSUnit_Number) {
+ if (aOldValue.GetFloatValue() == 1.0 || aValue.GetFloatValue() == 1.0) {
+ // XXX: it would be better to pass out a hint NS_STYLE_HINT_VIEWCHANGE,
+ // but it does not exist
+ return NS_STYLE_HINT_FRAMECHANGE;
+ } else {
+ return NS_STYLE_HINT_VISUAL;
+ }
+ }
+ }
+
+ return nsCSSProps::kHintTable[aPropID];
+}
+
nsresult CSSParserImpl::AppendValue(nsCSSDeclaration* aDeclaration, nsCSSProperty aPropID,
const nsCSSValue& aValue, PRInt32& aChangeHint)
{
@@ -3339,8 +3367,10 @@ nsresult CSSParserImpl::AppendValue(nsCSSDeclaration* aDeclaration, nsCSSPropert
if (aValue != oldValue) {
result = aDeclaration->AppendValue(aPropID, aValue);
- if (aChangeHint < nsCSSProps::kHintTable[aPropID]) {
- aChangeHint = nsCSSProps::kHintTable[aPropID];
+
+ PRInt32 newHint = ComputeChangeHint(aPropID, oldValue, aValue);
+ if (aChangeHint < newHint) {
+ aChangeHint = newHint;
}
}
return result;
diff --git a/mozilla/content/shared/public/nsCSSPropList.h b/mozilla/content/shared/public/nsCSSPropList.h
index ca415b05f5d..ce14a5df95e 100644
--- a/mozilla/content/shared/public/nsCSSPropList.h
+++ b/mozilla/content/shared/public/nsCSSPropList.h
@@ -89,7 +89,7 @@ CSS_PROP(-moz-outline-radius-bottomleft, _moz_outline_radius_bottomLeft, VISUAL)
CSS_PROP(-moz-outline-radius-bottomright, _moz_outline_radius_bottomRight, VISUAL)
CSS_PROP(azimuth, azimuth, AURAL)
CSS_PROP(background, background, VISUAL)
-CSS_PROP(background-attachment, background_attachment, VISUAL)
+CSS_PROP(background-attachment, background_attachment, FRAMECHANGE)
CSS_PROP(background-color, background_color, VISUAL)
CSS_PROP(background-image, background_image, VISUAL)
CSS_PROP(background-position, background_position, VISUAL)
@@ -188,7 +188,7 @@ CSS_PROP(max-height, max_height, REFLOW)
CSS_PROP(max-width, max_width, REFLOW)
CSS_PROP(min-height, min_height, REFLOW)
CSS_PROP(min-width, min_width, REFLOW)
-CSS_PROP(-moz-opacity, opacity, VISUAL) // XXX bug 3935
+CSS_PROP(-moz-opacity, opacity, FRAMECHANGE) // XXX bug 3935
CSS_PROP(orphans, orphans, REFLOW)
CSS_PROP(-moz-outline, outline, VISUAL) // XXX This is temporary fix for nsbeta3+ Bug 48973, turning outline into -moz-outline XXX bug 48973
CSS_PROP(-moz-outline-color, outline_color, VISUAL) // XXX bug 48973
diff --git a/mozilla/content/shared/src/nsStyleStruct.cpp b/mozilla/content/shared/src/nsStyleStruct.cpp
index 665d6bf4378..5e9b21d6a08 100644
--- a/mozilla/content/shared/src/nsStyleStruct.cpp
+++ b/mozilla/content/shared/src/nsStyleStruct.cpp
@@ -978,6 +978,12 @@ nsStyleBackground::nsStyleBackground(const nsStyleBackground& aSource)
PRInt32 nsStyleBackground::CalcDifference(const nsStyleBackground& aOther) const
{
+ if (mBackgroundAttachment != aOther.mBackgroundAttachment
+ && (NS_STYLE_BG_ATTACHMENT_FIXED == mBackgroundAttachment) ||
+ (NS_STYLE_BG_ATTACHMENT_FIXED == aOther.mBackgroundAttachment))
+ // this might require creation of a view
+ return NS_STYLE_HINT_FRAMECHANGE;
+
if ((mBackgroundAttachment == aOther.mBackgroundAttachment) &&
(mBackgroundFlags == aOther.mBackgroundFlags) &&
(mBackgroundRepeat == aOther.mBackgroundRepeat) &&
@@ -1075,13 +1081,18 @@ nsStyleVisibility::nsStyleVisibility(const nsStyleVisibility& aSource)
PRInt32 nsStyleVisibility::CalcDifference(const nsStyleVisibility& aOther) const
{
- if (mOpacity != aOther.mOpacity)
- return NS_STYLE_HINT_VISUAL;
+ if (mOpacity != aOther.mOpacity
+ && ((mOpacity < 1.0) != (aOther.mOpacity < 1.0)))
+ // might need to create a view to handle change from 1.0 to partial opacity
+ return NS_STYLE_HINT_FRAMECHANGE;
if ((mDirection == aOther.mDirection) &&
(mLanguage == aOther.mLanguage)) {
if ((mVisible == aOther.mVisible)) {
- return NS_STYLE_HINT_NONE;
+ if (mOpacity == aOther.mOpacity)
+ return NS_STYLE_HINT_NONE;
+ else
+ return NS_STYLE_HINT_VISUAL;
}
if ((mVisible != aOther.mVisible) &&
((NS_STYLE_VISIBILITY_COLLAPSE == mVisible) ||
diff --git a/mozilla/layout/style/nsCSSParser.cpp b/mozilla/layout/style/nsCSSParser.cpp
index fb3ea116644..c7151c28d87 100644
--- a/mozilla/layout/style/nsCSSParser.cpp
+++ b/mozilla/layout/style/nsCSSParser.cpp
@@ -3330,6 +3330,34 @@ done:
return found;
}
+static PRInt32 ComputeChangeHint(nsCSSProperty aPropID,
+ const nsCSSValue& aOldValue,
+ const nsCSSValue& aValue)
+{
+ NS_ASSERTION(aOldValue != aValue,
+ "ComputeChangeHint should not be called with equal values");
+
+ switch (aPropID) {
+ case eCSSProperty_opacity:
+ // If the opacity is changing to or from 1.0, then reframe to (possibly)
+ // cause a view to be created or eliminated
+ // Otherwise we just need a visual change. This is important because
+ // opacity is frequently used for fade effects, and we don't want to reframe
+ // for every step of the fade.
+ if (aOldValue.GetUnit() == eCSSUnit_Number && aValue.GetUnit() == eCSSUnit_Number) {
+ if (aOldValue.GetFloatValue() == 1.0 || aValue.GetFloatValue() == 1.0) {
+ // XXX: it would be better to pass out a hint NS_STYLE_HINT_VIEWCHANGE,
+ // but it does not exist
+ return NS_STYLE_HINT_FRAMECHANGE;
+ } else {
+ return NS_STYLE_HINT_VISUAL;
+ }
+ }
+ }
+
+ return nsCSSProps::kHintTable[aPropID];
+}
+
nsresult CSSParserImpl::AppendValue(nsCSSDeclaration* aDeclaration, nsCSSProperty aPropID,
const nsCSSValue& aValue, PRInt32& aChangeHint)
{
@@ -3339,8 +3367,10 @@ nsresult CSSParserImpl::AppendValue(nsCSSDeclaration* aDeclaration, nsCSSPropert
if (aValue != oldValue) {
result = aDeclaration->AppendValue(aPropID, aValue);
- if (aChangeHint < nsCSSProps::kHintTable[aPropID]) {
- aChangeHint = nsCSSProps::kHintTable[aPropID];
+
+ PRInt32 newHint = ComputeChangeHint(aPropID, oldValue, aValue);
+ if (aChangeHint < newHint) {
+ aChangeHint = newHint;
}
}
return result;
diff --git a/mozilla/layout/style/nsCSSPropList.h b/mozilla/layout/style/nsCSSPropList.h
index ca415b05f5d..ce14a5df95e 100644
--- a/mozilla/layout/style/nsCSSPropList.h
+++ b/mozilla/layout/style/nsCSSPropList.h
@@ -89,7 +89,7 @@ CSS_PROP(-moz-outline-radius-bottomleft, _moz_outline_radius_bottomLeft, VISUAL)
CSS_PROP(-moz-outline-radius-bottomright, _moz_outline_radius_bottomRight, VISUAL)
CSS_PROP(azimuth, azimuth, AURAL)
CSS_PROP(background, background, VISUAL)
-CSS_PROP(background-attachment, background_attachment, VISUAL)
+CSS_PROP(background-attachment, background_attachment, FRAMECHANGE)
CSS_PROP(background-color, background_color, VISUAL)
CSS_PROP(background-image, background_image, VISUAL)
CSS_PROP(background-position, background_position, VISUAL)
@@ -188,7 +188,7 @@ CSS_PROP(max-height, max_height, REFLOW)
CSS_PROP(max-width, max_width, REFLOW)
CSS_PROP(min-height, min_height, REFLOW)
CSS_PROP(min-width, min_width, REFLOW)
-CSS_PROP(-moz-opacity, opacity, VISUAL) // XXX bug 3935
+CSS_PROP(-moz-opacity, opacity, FRAMECHANGE) // XXX bug 3935
CSS_PROP(orphans, orphans, REFLOW)
CSS_PROP(-moz-outline, outline, VISUAL) // XXX This is temporary fix for nsbeta3+ Bug 48973, turning outline into -moz-outline XXX bug 48973
CSS_PROP(-moz-outline-color, outline_color, VISUAL) // XXX bug 48973
diff --git a/mozilla/layout/style/nsStyleStruct.cpp b/mozilla/layout/style/nsStyleStruct.cpp
index 665d6bf4378..5e9b21d6a08 100644
--- a/mozilla/layout/style/nsStyleStruct.cpp
+++ b/mozilla/layout/style/nsStyleStruct.cpp
@@ -978,6 +978,12 @@ nsStyleBackground::nsStyleBackground(const nsStyleBackground& aSource)
PRInt32 nsStyleBackground::CalcDifference(const nsStyleBackground& aOther) const
{
+ if (mBackgroundAttachment != aOther.mBackgroundAttachment
+ && (NS_STYLE_BG_ATTACHMENT_FIXED == mBackgroundAttachment) ||
+ (NS_STYLE_BG_ATTACHMENT_FIXED == aOther.mBackgroundAttachment))
+ // this might require creation of a view
+ return NS_STYLE_HINT_FRAMECHANGE;
+
if ((mBackgroundAttachment == aOther.mBackgroundAttachment) &&
(mBackgroundFlags == aOther.mBackgroundFlags) &&
(mBackgroundRepeat == aOther.mBackgroundRepeat) &&
@@ -1075,13 +1081,18 @@ nsStyleVisibility::nsStyleVisibility(const nsStyleVisibility& aSource)
PRInt32 nsStyleVisibility::CalcDifference(const nsStyleVisibility& aOther) const
{
- if (mOpacity != aOther.mOpacity)
- return NS_STYLE_HINT_VISUAL;
+ if (mOpacity != aOther.mOpacity
+ && ((mOpacity < 1.0) != (aOther.mOpacity < 1.0)))
+ // might need to create a view to handle change from 1.0 to partial opacity
+ return NS_STYLE_HINT_FRAMECHANGE;
if ((mDirection == aOther.mDirection) &&
(mLanguage == aOther.mLanguage)) {
if ((mVisible == aOther.mVisible)) {
- return NS_STYLE_HINT_NONE;
+ if (mOpacity == aOther.mOpacity)
+ return NS_STYLE_HINT_NONE;
+ else
+ return NS_STYLE_HINT_VISUAL;
}
if ((mVisible != aOther.mVisible) &&
((NS_STYLE_VISIBILITY_COLLAPSE == mVisible) ||