From c177c29b51541e38cb33d6aa5be316b4ceab20e8 Mon Sep 17 00:00:00 2001 From: "rbs%maths.uq.edu.au" Date: Thu, 10 Jan 2002 04:42:55 +0000 Subject: [PATCH] Fix MathML bug 114909 - dynamically changing the displaystyle attribute in tag doesn't change display --- layout/mathml/base/src/nsIMathMLFrame.h | 5 +- .../base/src/nsMathMLContainerFrame.cpp | 34 +++-- .../mathml/base/src/nsMathMLContainerFrame.h | 7 +- layout/mathml/base/src/nsMathMLFrame.h | 5 +- layout/mathml/base/src/nsMathMLmfracFrame.cpp | 62 ++++++++ layout/mathml/base/src/nsMathMLmfracFrame.h | 16 ++ layout/mathml/base/src/nsMathMLmoverFrame.cpp | 41 +++++ layout/mathml/base/src/nsMathMLmoverFrame.h | 8 + .../mathml/base/src/nsMathMLmstyleFrame.cpp | 143 +++++++++++++++--- layout/mathml/base/src/nsMathMLmstyleFrame.h | 18 ++- layout/mathml/base/src/nsMathMLmtableFrame.h | 10 +- .../mathml/base/src/nsMathMLmunderFrame.cpp | 41 +++++ layout/mathml/base/src/nsMathMLmunderFrame.h | 8 + .../base/src/nsMathMLmunderoverFrame.cpp | 46 ++++++ .../mathml/base/src/nsMathMLmunderoverFrame.h | 8 + 15 files changed, 400 insertions(+), 52 deletions(-) diff --git a/layout/mathml/base/src/nsIMathMLFrame.h b/layout/mathml/base/src/nsIMathMLFrame.h index d5d75711b0b..2ff6aa65a24 100644 --- a/layout/mathml/base/src/nsIMathMLFrame.h +++ b/layout/mathml/base/src/nsIMathMLFrame.h @@ -277,9 +277,8 @@ public: * http://groups.google.com/groups?selm=3A9192B5.D22B6C38%40maths.uq.edu.au */ NS_IMETHOD - ReResolveScriptStyle(nsIPresContext* aPresContext, - nsIStyleContext* aParentContext, - PRInt32 aParentScriptLevel) = 0; + ReResolveScriptStyle(nsIPresContext* aPresContext, + PRInt32 aParentScriptLevel) = 0; }; // struct used by a frame to modulate its presentation diff --git a/layout/mathml/base/src/nsMathMLContainerFrame.cpp b/layout/mathml/base/src/nsMathMLContainerFrame.cpp index 991c290ba96..23801b25129 100644 --- a/layout/mathml/base/src/nsMathMLContainerFrame.cpp +++ b/layout/mathml/base/src/nsMathMLContainerFrame.cpp @@ -554,20 +554,28 @@ nsMathMLContainerFrame::PropagatePresentationDataFor(nsIPresContext* aPresContex PRUint32 aFlagsValues, PRUint32 aFlagsToUpdate) { + if (!aFlagsToUpdate && !aScriptLevelIncrement) + return; nsIMathMLFrame* mathMLFrame; aFrame->QueryInterface(NS_GET_IID(nsIMathMLFrame), (void**)&mathMLFrame); if (mathMLFrame) { // update mathMLFrame->UpdatePresentationData(aPresContext, aScriptLevelIncrement, aFlagsValues, aFlagsToUpdate); + // propagate using the base method to make sure that the control + // is passed on to MathML frames that may be overloading the method + mathMLFrame->UpdatePresentationDataFromChildAt(aPresContext, + 0, -1, aScriptLevelIncrement, aFlagsValues, aFlagsToUpdate); } - // propagate down the subtrees - nsIFrame* childFrame; - aFrame->FirstChild(aPresContext, nsnull, &childFrame); - while (childFrame) { - PropagatePresentationDataFor(aPresContext, childFrame, - aScriptLevelIncrement, aFlagsValues, aFlagsToUpdate); - childFrame->GetNextSibling(&childFrame); + else { + // propagate down the subtrees + nsIFrame* childFrame; + aFrame->FirstChild(aPresContext, nsnull, &childFrame); + while (childFrame) { + PropagatePresentationDataFor(aPresContext, childFrame, + aScriptLevelIncrement, aFlagsValues, aFlagsToUpdate); + childFrame->GetNextSibling(&childFrame); + } } } @@ -599,7 +607,7 @@ nsMathMLContainerFrame::PropagateScriptStyleFor(nsIPresContext* aPresContext, nsCOMPtr content; aFrame->GetContent(getter_AddRefs(content)); - if (0 == gap) { + if (!gap) { // unset any -moz-math-font-size attribute without notifying that we want a reflow content->UnsetAttr(kNameSpaceID_None, nsMathMLAtoms::fontsize, PR_FALSE); } @@ -681,7 +689,15 @@ nsMathMLContainerFrame::PropagateScriptStyleFor(nsIPresContext* aPresContext, nsIFrame* childFrame; aFrame->FirstChild(aPresContext, nsnull, &childFrame); while (childFrame) { - PropagateScriptStyleFor(aPresContext, childFrame, aParentScriptLevel); + childFrame->QueryInterface(NS_GET_IID(nsIMathMLFrame), (void**)&mathMLFrame); + if (mathMLFrame) { + // propagate using the base method to make sure that the control + // is passed on to MathML frames that may be overloading the method + mathMLFrame->ReResolveScriptStyle(aPresContext, aParentScriptLevel); + } + else { + PropagateScriptStyleFor(aPresContext, childFrame, aParentScriptLevel); + } childFrame->GetNextSibling(&childFrame); } } diff --git a/layout/mathml/base/src/nsMathMLContainerFrame.h b/layout/mathml/base/src/nsMathMLContainerFrame.h index d5abebd9342..94eb91bea7a 100644 --- a/layout/mathml/base/src/nsMathMLContainerFrame.h +++ b/layout/mathml/base/src/nsMathMLContainerFrame.h @@ -90,6 +90,8 @@ public: PRUint32 aFlagsValues, PRUint32 aFlagsToUpdate) { + if (!aFlagsToUpdate && !aScriptLevelIncrement) + return NS_OK; PRInt32 index = 0; nsIFrame* childFrame = mFrames.FirstChild(); while (childFrame) { @@ -105,9 +107,8 @@ public: } NS_IMETHOD - ReResolveScriptStyle(nsIPresContext* aPresContext, - nsIStyleContext* aParentContext, - PRInt32 aParentScriptLevel) + ReResolveScriptStyle(nsIPresContext* aPresContext, + PRInt32 aParentScriptLevel) { PropagateScriptStyleFor(aPresContext, this, aParentScriptLevel); return NS_OK; diff --git a/layout/mathml/base/src/nsMathMLFrame.h b/layout/mathml/base/src/nsMathMLFrame.h index 259c9842420..aaf11d6a78a 100644 --- a/layout/mathml/base/src/nsMathMLFrame.h +++ b/layout/mathml/base/src/nsMathMLFrame.h @@ -145,9 +145,8 @@ public: } NS_IMETHOD - ReResolveScriptStyle(nsIPresContext* aPresContext, - nsIStyleContext* aParentContext, - PRInt32 aParentScriptLevel) + ReResolveScriptStyle(nsIPresContext* aPresContext, + PRInt32 aParentScriptLevel) { return NS_OK; } diff --git a/layout/mathml/base/src/nsMathMLmfracFrame.cpp b/layout/mathml/base/src/nsMathMLmfracFrame.cpp index dce2b602a13..e0f2b1d221f 100644 --- a/layout/mathml/base/src/nsMathMLmfracFrame.cpp +++ b/layout/mathml/base/src/nsMathMLmfracFrame.cpp @@ -461,6 +461,68 @@ nsMathMLmfracFrame::AttributeChanged(nsIPresContext* aPresContext, aAttribute, aModType, aHint); } +NS_IMETHODIMP +nsMathMLmfracFrame::UpdatePresentationData(nsIPresContext* aPresContext, + PRInt32 aScriptLevelIncrement, + PRUint32 aFlagsValues, + PRUint32 aFlagsToUpdate) +{ + // mfrac is special... The REC says: + // The element sets displaystyle to "false", or if it was already + // false increments scriptlevel by 1, within numerator and denominator. + // @see similar peculiarities for , , + + // This means that + // 1. If our displaystyle is being changed from true to false, we have + // to propagate an inner scriptlevel increment to our children + // 2. If the displaystyle is changed from false to true, we have to undo + // any incrementation that was done on the inner scriptlevel + + if (NS_MATHML_IS_DISPLAYSTYLE(aFlagsToUpdate)) { + if (mInnerScriptLevel > mPresentationData.scriptLevel) { + // we get here if our displaystyle is currently false + NS_ASSERTION(!NS_MATHML_IS_DISPLAYSTYLE(mPresentationData.flags), "out of sync"); + if (NS_MATHML_IS_DISPLAYSTYLE(aFlagsValues)) { + // ...and is being set to true, so undo the inner increment now + mInnerScriptLevel = mPresentationData.scriptLevel; + UpdatePresentationDataFromChildAt(aPresContext, 0, -1, -1, 0, 0); + } + } + else { + // case of mInnerScriptLevel == mPresentationData.scriptLevel, our + // current displaystyle is true; we increment the inner scriptlevel if + // our displaystyle is about to be set to false; since mInnerScriptLevel + // is changed, we can only get here once + NS_ASSERTION(NS_MATHML_IS_DISPLAYSTYLE(mPresentationData.flags), "out of sync"); + if (!NS_MATHML_IS_DISPLAYSTYLE(aFlagsValues)) { + mInnerScriptLevel = mPresentationData.scriptLevel + 1; + UpdatePresentationDataFromChildAt(aPresContext, 0, -1, 1, 0, 0); + } + } + } + + mInnerScriptLevel += aScriptLevelIncrement; + return nsMathMLContainerFrame:: + UpdatePresentationData(aPresContext, aScriptLevelIncrement, aFlagsValues, aFlagsToUpdate); +} + +NS_IMETHODIMP +nsMathMLmfracFrame::UpdatePresentationDataFromChildAt(nsIPresContext* aPresContext, + PRInt32 aFirstIndex, + PRInt32 aLastIndex, + PRInt32 aScriptLevelIncrement, + PRUint32 aFlagsValues, + PRUint32 aFlagsToUpdate) +{ + // The element sets displaystyle to "false" within numerator and + // denominator so we disable the displaystyle bit to retain what we set earlier + aFlagsToUpdate &= ~NS_MATHML_DISPLAYSTYLE; + aFlagsValues &= ~NS_MATHML_DISPLAYSTYLE; + return nsMathMLContainerFrame:: + UpdatePresentationDataFromChildAt(aPresContext, aFirstIndex, aLastIndex, + aScriptLevelIncrement, aFlagsValues, aFlagsToUpdate); +} + // ---------------------- // the Style System will use these to pass the proper style context to our MathMLChar NS_IMETHODIMP diff --git a/layout/mathml/base/src/nsMathMLmfracFrame.h b/layout/mathml/base/src/nsMathMLmfracFrame.h index a37ef752b8d..cefd96df680 100644 --- a/layout/mathml/base/src/nsMathMLmfracFrame.h +++ b/layout/mathml/base/src/nsMathMLmfracFrame.h @@ -112,6 +112,20 @@ public: nsFramePaintLayer aWhichLayer, PRUint32 aFlags = 0); + NS_IMETHOD + UpdatePresentationData(nsIPresContext* aPresContext, + PRInt32 aScriptLevelIncrement, + PRUint32 aFlagsValues, + PRUint32 aFlagsToUpdate); + + NS_IMETHOD + UpdatePresentationDataFromChildAt(nsIPresContext* aPresContext, + PRInt32 aFirstIndex, + PRInt32 aLastIndex, + PRInt32 aScriptLevelIncrement, + PRUint32 aFlagsValues, + PRUint32 aFlagsToUpdate); + NS_IMETHOD SetInitialChildList(nsIPresContext* aPresContext, nsIAtom* aListName, @@ -126,6 +140,7 @@ public: // while the denominator is compressed PRInt32 increment = NS_MATHML_IS_DISPLAYSTYLE(mPresentationData.flags) ? 0 : 1; + mInnerScriptLevel = mPresentationData.scriptLevel + increment; UpdatePresentationDataFromChildAt(aPresContext, 0, -1, increment, ~NS_MATHML_DISPLAYSTYLE, NS_MATHML_DISPLAYSTYLE); @@ -171,6 +186,7 @@ protected: return PR_FALSE; } + PRInt32 mInnerScriptLevel; nsRect mLineRect; nsMathMLChar* mSlashChar; }; diff --git a/layout/mathml/base/src/nsMathMLmoverFrame.cpp b/layout/mathml/base/src/nsMathMLmoverFrame.cpp index 986adcfa81a..d1356af14ca 100644 --- a/layout/mathml/base/src/nsMathMLmoverFrame.cpp +++ b/layout/mathml/base/src/nsMathMLmoverFrame.cpp @@ -105,6 +105,47 @@ nsMathMLmoverFrame::UpdatePresentationData(nsIPresContext* aPresContext, return NS_OK; } +NS_IMETHODIMP +nsMathMLmoverFrame::UpdatePresentationDataFromChildAt(nsIPresContext* aPresContext, + PRInt32 aFirstIndex, + PRInt32 aLastIndex, + PRInt32 aScriptLevelIncrement, + PRUint32 aFlagsValues, + PRUint32 aFlagsToUpdate) +{ + // mover is special... The REC says: + // Within overscript, always sets displaystyle to "false", + // but increments scriptlevel by 1 only when accent is "false". + // This means that + // 1. don't allow displaystyle to change in the overscript + // 2. if the value of the accent is changed, we need to recompute the + // scriptlevel of the overscript. The problem is that the accent + // can change in the deep down the embellished hierarchy + + // Do #1 here, never allow displaystyle to be changed in the overscript + PRInt32 index = 0; + nsIFrame* childFrame = mFrames.FirstChild(); + while (childFrame) { + if ((index >= aFirstIndex) && + ((aLastIndex <= 0) || ((aLastIndex > 0) && (index <= aLastIndex)))) { + if (index > 0) { + // disable the flag + aFlagsToUpdate &= ~NS_MATHML_DISPLAYSTYLE; + aFlagsValues &= ~NS_MATHML_DISPLAYSTYLE; + } + PropagatePresentationDataFor(aPresContext, childFrame, + aScriptLevelIncrement, aFlagsValues, aFlagsToUpdate); + } + index++; + childFrame->GetNextSibling(&childFrame); + } + return NS_OK; + + // XXX For #2, if the inner changes, is has to trigger + // XXX a re-computation of all flags that depend on its state + // XXX in the entire embellished hierarchy +} + NS_IMETHODIMP nsMathMLmoverFrame::SetInitialChildList(nsIPresContext* aPresContext, nsIAtom* aListName, diff --git a/layout/mathml/base/src/nsMathMLmoverFrame.h b/layout/mathml/base/src/nsMathMLmoverFrame.h index 5f71181fcc8..b97b0d2d470 100644 --- a/layout/mathml/base/src/nsMathMLmoverFrame.h +++ b/layout/mathml/base/src/nsMathMLmoverFrame.h @@ -59,6 +59,14 @@ public: PRUint32 aFlagsValues, PRUint32 aFlagsToUpdate); + NS_IMETHOD + UpdatePresentationDataFromChildAt(nsIPresContext* aPresContext, + PRInt32 aFirstIndex, + PRInt32 aLastIndex, + PRInt32 aScriptLevelIncrement, + PRUint32 aFlagsValues, + PRUint32 aFlagsToUpdate); + protected: nsMathMLmoverFrame(); virtual ~nsMathMLmoverFrame(); diff --git a/layout/mathml/base/src/nsMathMLmstyleFrame.cpp b/layout/mathml/base/src/nsMathMLmstyleFrame.cpp index 0b726204053..b0124518138 100644 --- a/layout/mathml/base/src/nsMathMLmstyleFrame.cpp +++ b/layout/mathml/base/src/nsMathMLmstyleFrame.cpp @@ -77,9 +77,15 @@ nsMathMLmstyleFrame::Init(nsIPresContext* aPresContext, nsresult rv = nsMathMLContainerFrame::Init(aPresContext, aContent, aParent, aContext, aPrevInFlow); mEmbellishData.flags |= NS_MATHML_STRETCH_ALL_CHILDREN_VERTICALLY; - mPresentationData.mstyle = this; + // cache the values that we would have if we were not special... + // In the event of dynamic updates, e.g., if our displastyle and/or + // scriptlevel attributes are removed, we will recover our state using + // these cached values + mInheritedScriptLevel = mPresentationData.scriptLevel; + mInheritedDisplayStyle = mPresentationData.flags & NS_MATHML_DISPLAYSTYLE; + // see if the displaystyle attribute is there nsAutoString value; if (NS_CONTENT_ATTR_HAS_VALUE == mContent->GetAttr(kNameSpaceID_None, @@ -118,19 +124,29 @@ nsMathMLmstyleFrame::Init(nsIPresContext* aPresContext, } NS_IMETHODIMP -nsMathMLmstyleFrame::UpdatePresentationData(PRInt32 aScriptLevelIncrement, - PRUint32 aFlagsValues, - PRUint32 aFlagsToUpdate) +nsMathMLmstyleFrame::UpdatePresentationData(nsIPresContext* aPresContext, + PRInt32 aScriptLevelIncrement, + PRUint32 aFlagsValues, + PRUint32 aFlagsToUpdate) { // mstyle is special... // Since UpdatePresentationData() can be called by a parent frame, the // scriptlevel and displaystyle attributes of mstyle must take precedence. // Update only if attributes are not there + // But... cache the values that we would have if we were not special... + // In the event of dynamic updates, e.g., if our displastyle and/or + // scriptlevel attributes are removed, we will recover our state using + // these cached values + mInheritedScriptLevel += aScriptLevelIncrement; + if (NS_MATHML_IS_DISPLAYSTYLE(aFlagsToUpdate)) { + mInheritedDisplayStyle = aFlagsValues & NS_MATHML_DISPLAYSTYLE; + } + + // see if updating the displaystyle flag is allowed if (!NS_MATHML_IS_MSTYLE_WITH_DISPLAYSTYLE(mPresentationData.flags)) { - // update the flag if it is relevant to this call + // see if the displaystyle flag is relevant to this call if (NS_MATHML_IS_DISPLAYSTYLE(aFlagsToUpdate)) { - // updating the displaystyle flag is allowed if (NS_MATHML_IS_DISPLAYSTYLE(aFlagsValues)) { mPresentationData.flags |= NS_MATHML_DISPLAYSTYLE; } @@ -140,19 +156,20 @@ nsMathMLmstyleFrame::UpdatePresentationData(PRInt32 aScriptLevelIncrement, } } + // see if updating the scriptlevel is allowed if (!NS_MATHML_IS_MSTYLE_WITH_EXPLICIT_SCRIPTLEVEL(mPresentationData.flags)) { mPresentationData.scriptLevel += aScriptLevelIncrement; } + // see if the compression flag is relevant to this call if (NS_MATHML_IS_COMPRESSED(aFlagsToUpdate)) { - // updating the compression flag is allowed if (NS_MATHML_IS_COMPRESSED(aFlagsValues)) { // 'compressed' means 'prime' style in App. G, TeXbook mPresentationData.flags |= NS_MATHML_COMPRESSED; } // no else. the flag is sticky. it retains its value once it is set } - + return NS_OK; } @@ -168,35 +185,111 @@ nsMathMLmstyleFrame::UpdatePresentationDataFromChildAt(nsIPresContext* aPresCont // Since UpdatePresentationDataFromChildAt() can be called by a parent frame, // wee need to ensure that the attributes of mstyle take precedence - // see if the caller cares about the displaystyle flag - PRBool displaystyleChanged = PR_FALSE; if (NS_MATHML_IS_DISPLAYSTYLE(aFlagsToUpdate)) { - if (!NS_MATHML_IS_MSTYLE_WITH_DISPLAYSTYLE(mPresentationData.flags)) { - // updating the displaystyle flag is allowed - displaystyleChanged = PR_TRUE; - } - else { - // our value takes precedence, updating is not allowed + if (NS_MATHML_IS_MSTYLE_WITH_DISPLAYSTYLE(mPresentationData.flags)) { + // our current state takes precedence, updating is not allowed aFlagsToUpdate &= ~NS_MATHML_DISPLAYSTYLE; + aFlagsValues &= ~NS_MATHML_DISPLAYSTYLE; } } - // see if the caller cares about the compression flag - PRBool compressionChanged = PR_FALSE; - if (NS_MATHML_IS_COMPRESSED(aFlagsToUpdate)) { - compressionChanged = PR_TRUE; - } - if (NS_MATHML_IS_MSTYLE_WITH_EXPLICIT_SCRIPTLEVEL(mPresentationData.flags)) { + // our current state takes precedence, updating is not allowed aScriptLevelIncrement = 0; } - if (!aScriptLevelIncrement && !displaystyleChanged && !compressionChanged) - return NS_OK; // quick return, there is nothing to change - // let the base class worry about the update return nsMathMLContainerFrame::UpdatePresentationDataFromChildAt( aPresContext, aFirstIndex, aLastIndex, aScriptLevelIncrement, aFlagsValues, aFlagsToUpdate); } + +NS_IMETHODIMP +nsMathMLmstyleFrame::AttributeChanged(nsIPresContext* aPresContext, + nsIContent* aContent, + PRInt32 aNameSpaceID, + nsIAtom* aAttribute, + PRInt32 aModType, + PRInt32 aHint) +{ + if (nsMathMLAtoms::displaystyle_ == aAttribute || + nsMathMLAtoms::scriptlevel_ == aAttribute) { + nsPresentationData oldData = mPresentationData; + // process our attributes + nsAutoString value; + if (NS_CONTENT_ATTR_NOT_THERE == mContent->GetAttr(kNameSpaceID_None, + nsMathMLAtoms::scriptlevel_, value)) { + // when our scriptlevel attribute is gone, we recover our inherited scriptlevel + mPresentationData.flags &= ~NS_MATHML_MSTYLE_WITH_EXPLICIT_SCRIPTLEVEL; + mPresentationData.scriptLevel = mInheritedScriptLevel; + } + else { + PRInt32 errorCode, userValue; + userValue = value.ToInteger(&errorCode); + if (!errorCode) { + if (value[0] != '+' && value[0] != '-') { + // record that it is an explicit value + mPresentationData.flags |= NS_MATHML_MSTYLE_WITH_EXPLICIT_SCRIPTLEVEL; + mPresentationData.scriptLevel = userValue; + } + else { + // incremental value... + mPresentationData.flags &= ~NS_MATHML_MSTYLE_WITH_EXPLICIT_SCRIPTLEVEL; + mPresentationData.scriptLevel = mInheritedScriptLevel + userValue; + } + } + } + if (NS_CONTENT_ATTR_NOT_THERE == mContent->GetAttr(kNameSpaceID_None, + nsMathMLAtoms::displaystyle_, value)) { + // when our displaystyle attribute is gone, we recover our inherited displaystyle + mPresentationData.flags &= ~NS_MATHML_MSTYLE_WITH_DISPLAYSTYLE; + mPresentationData.flags |= mInheritedDisplayStyle & NS_MATHML_DISPLAYSTYLE; + } + else { + if (value.Equals(NS_LITERAL_STRING("true"))) { + mPresentationData.flags |= NS_MATHML_MSTYLE_WITH_DISPLAYSTYLE; + mPresentationData.flags |= NS_MATHML_DISPLAYSTYLE; + } + else if (value.Equals(NS_LITERAL_STRING("false"))) { + mPresentationData.flags |= NS_MATHML_MSTYLE_WITH_DISPLAYSTYLE; + mPresentationData.flags &= ~NS_MATHML_DISPLAYSTYLE; + } + } + + // propagate to our children if something changed + if (oldData.flags != mPresentationData.flags || + oldData.scriptLevel != mPresentationData.scriptLevel) { + PRUint32 newValues = 0, whichFlags = 0; + if (NS_MATHML_IS_DISPLAYSTYLE(oldData.flags) != + NS_MATHML_IS_DISPLAYSTYLE(mPresentationData.flags)) { + newValues = NS_MATHML_DISPLAYSTYLE & mPresentationData.flags; + whichFlags = NS_MATHML_DISPLAYSTYLE; + } + // use the base method here because we really want to reflect any updates + nsMathMLContainerFrame::UpdatePresentationDataFromChildAt(aPresContext, 0, -1, + mPresentationData.scriptLevel - oldData.scriptLevel, newValues, whichFlags); + // now walk up to our immediate ancestor that implements the + // nsIMathMLFrame interface and grab its scriptlevel + PRInt32 parentScriptLevel = oldData.scriptLevel; + nsIFrame* parent = mParent; + while (parent) { + nsIMathMLFrame* mathMLFrame; + parent->QueryInterface(NS_GET_IID(nsIMathMLFrame), (void**)&mathMLFrame); + if (mathMLFrame) { + nsPresentationData parentData; + mathMLFrame->GetPresentationData(parentData); + parentScriptLevel = parentData.scriptLevel; + break; + } + parent->GetParent(&parent); + } + // re-resolve style data in our subtree to sync any change of script sizes + PropagateScriptStyleFor(aPresContext, this, parentScriptLevel); + } + } + + return nsMathMLContainerFrame:: + AttributeChanged(aPresContext, aContent, aNameSpaceID, + aAttribute, aModType, aHint); +} diff --git a/layout/mathml/base/src/nsMathMLmstyleFrame.h b/layout/mathml/base/src/nsMathMLmstyleFrame.h index b3fed12862a..fdc69931b2a 100644 --- a/layout/mathml/base/src/nsMathMLmstyleFrame.h +++ b/layout/mathml/base/src/nsMathMLmstyleFrame.h @@ -34,6 +34,14 @@ class nsMathMLmstyleFrame : public nsMathMLContainerFrame { public: friend nsresult NS_NewMathMLmstyleFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame); + NS_IMETHOD + AttributeChanged(nsIPresContext* aPresContext, + nsIContent* aContent, + PRInt32 aNameSpaceID, + nsIAtom* aAttribute, + PRInt32 aModType, + PRInt32 aHint); + NS_IMETHOD Init(nsIPresContext* aPresContext, nsIContent* aContent, @@ -42,9 +50,10 @@ public: nsIFrame* aPrevInFlow); NS_IMETHOD - UpdatePresentationData(PRInt32 aScriptLevelIncrement, - PRUint32 aFlagsValues, - PRUint32 aFlagsToUpdate); + UpdatePresentationData(nsIPresContext* aPresContext, + PRInt32 aScriptLevelIncrement, + PRUint32 aFlagsValues, + PRUint32 aFlagsToUpdate); NS_IMETHOD UpdatePresentationDataFromChildAt(nsIPresContext* aPresContext, @@ -73,6 +82,9 @@ protected: virtual ~nsMathMLmstyleFrame(); virtual PRIntn GetSkipSides() const { return 0; } + + PRUint32 mInheritedDisplayStyle; + PRInt32 mInheritedScriptLevel; }; #endif /* nsMathMLmstyleFrame_h___ */ diff --git a/layout/mathml/base/src/nsMathMLmtableFrame.h b/layout/mathml/base/src/nsMathMLmtableFrame.h index 6622c469287..77ae09e3969 100644 --- a/layout/mathml/base/src/nsMathMLmtableFrame.h +++ b/layout/mathml/base/src/nsMathMLmtableFrame.h @@ -63,9 +63,8 @@ public: } NS_IMETHOD - ReResolveScriptStyle(nsIPresContext* aPresContext, - nsIStyleContext* aParentContext, - PRInt32 aParentScriptLevel) + ReResolveScriptStyle(nsIPresContext* aPresContext, + PRInt32 aParentScriptLevel) { nsMathMLContainerFrame::PropagateScriptStyleFor(aPresContext, this, aParentScriptLevel); return NS_OK; @@ -127,9 +126,8 @@ public: } NS_IMETHOD - ReResolveScriptStyle(nsIPresContext* aPresContext, - nsIStyleContext* aParentContext, - PRInt32 aParentScriptLevel) + ReResolveScriptStyle(nsIPresContext* aPresContext, + PRInt32 aParentScriptLevel) { nsMathMLContainerFrame::PropagateScriptStyleFor(aPresContext, this, aParentScriptLevel); return NS_OK; diff --git a/layout/mathml/base/src/nsMathMLmunderFrame.cpp b/layout/mathml/base/src/nsMathMLmunderFrame.cpp index 9874588c702..57b1c60e573 100644 --- a/layout/mathml/base/src/nsMathMLmunderFrame.cpp +++ b/layout/mathml/base/src/nsMathMLmunderFrame.cpp @@ -105,6 +105,47 @@ nsMathMLmunderFrame::UpdatePresentationData(nsIPresContext* aPresContext, return NS_OK; } +NS_IMETHODIMP +nsMathMLmunderFrame::UpdatePresentationDataFromChildAt(nsIPresContext* aPresContext, + PRInt32 aFirstIndex, + PRInt32 aLastIndex, + PRInt32 aScriptLevelIncrement, + PRUint32 aFlagsValues, + PRUint32 aFlagsToUpdate) +{ + // munder is special... The REC says: + // Within underscript, always sets displaystyle to "false", + // but increments scriptlevel by 1 only when accentunder is "false". + // This means that + // 1. don't allow displaystyle to change in the underscript + // 2. if the value of the accent is changed, we need to recompute the + // scriptlevel of the underscript. The problem is that the accent + // can change in the deep down the embellished hierarchy + + // Do #1 here, never allow displaystyle to be changed in the underscript + PRInt32 index = 0; + nsIFrame* childFrame = mFrames.FirstChild(); + while (childFrame) { + if ((index >= aFirstIndex) && + ((aLastIndex <= 0) || ((aLastIndex > 0) && (index <= aLastIndex)))) { + if (index > 0) { + // disable the flag + aFlagsToUpdate &= ~NS_MATHML_DISPLAYSTYLE; + aFlagsValues &= ~NS_MATHML_DISPLAYSTYLE; + } + PropagatePresentationDataFor(aPresContext, childFrame, + aScriptLevelIncrement, aFlagsValues, aFlagsToUpdate); + } + index++; + childFrame->GetNextSibling(&childFrame); + } + return NS_OK; + + // XXX For #2, if the inner changes, is has to trigger + // XXX a re-computation of all flags that depend on its state + // XXX in the entire embellished hierarchy +} + NS_IMETHODIMP nsMathMLmunderFrame::SetInitialChildList(nsIPresContext* aPresContext, nsIAtom* aListName, diff --git a/layout/mathml/base/src/nsMathMLmunderFrame.h b/layout/mathml/base/src/nsMathMLmunderFrame.h index 9fb4ee1bd26..a0ff250f924 100644 --- a/layout/mathml/base/src/nsMathMLmunderFrame.h +++ b/layout/mathml/base/src/nsMathMLmunderFrame.h @@ -59,6 +59,14 @@ public: PRUint32 aFlagsValues, PRUint32 aFlagsToUpdate); + NS_IMETHOD + UpdatePresentationDataFromChildAt(nsIPresContext* aPresContext, + PRInt32 aFirstIndex, + PRInt32 aLastIndex, + PRInt32 aScriptLevelIncrement, + PRUint32 aFlagsValues, + PRUint32 aFlagsToUpdate); + protected: nsMathMLmunderFrame(); virtual ~nsMathMLmunderFrame(); diff --git a/layout/mathml/base/src/nsMathMLmunderoverFrame.cpp b/layout/mathml/base/src/nsMathMLmunderoverFrame.cpp index 0bb15dbdd66..8a18e9be816 100644 --- a/layout/mathml/base/src/nsMathMLmunderoverFrame.cpp +++ b/layout/mathml/base/src/nsMathMLmunderoverFrame.cpp @@ -105,6 +105,52 @@ nsMathMLmunderoverFrame::UpdatePresentationData(nsIPresContext* aPresContext, return NS_OK; } +NS_IMETHODIMP +nsMathMLmunderoverFrame::UpdatePresentationDataFromChildAt(nsIPresContext* aPresContext, + PRInt32 aFirstIndex, + PRInt32 aLastIndex, + PRInt32 aScriptLevelIncrement, + PRUint32 aFlagsValues, + PRUint32 aFlagsToUpdate) +{ + // munderover is special... The REC says: + // Within underscript, always sets displaystyle to "false", + // but increments scriptlevel by 1 only when accentunder is "false". + // Within underscript, always sets displaystyle to "false", + // but increments scriptlevel by 1 only when accentunder is "false". + // This means that + // 1. don't allow displaystyle to change in the underscript & overscript + // 2a if the value of the accent is changed, we need to recompute the + // scriptlevel of the underscript. The problem is that the accent + // can change in the deep down the embellished hierarchy + // 2b if the value of the accent is changed, we need to recompute the + // scriptlevel of the overscript. The problem is that the accent + // can change in the deep down the embellished hierarchy + + // Do #1 here, prevent displaystyle to be changed in the underscript & overscript + PRInt32 index = 0; + nsIFrame* childFrame = mFrames.FirstChild(); + while (childFrame) { + if ((index >= aFirstIndex) && + ((aLastIndex <= 0) || ((aLastIndex > 0) && (index <= aLastIndex)))) { + if (index > 0) { + // disable the flag + aFlagsToUpdate &= ~NS_MATHML_DISPLAYSTYLE; + aFlagsValues &= ~NS_MATHML_DISPLAYSTYLE; + } + PropagatePresentationDataFor(aPresContext, childFrame, + aScriptLevelIncrement, aFlagsValues, aFlagsToUpdate); + } + index++; + childFrame->GetNextSibling(&childFrame); + } + return NS_OK; + + // XXX For #2, if the inner changes, is has to trigger + // XXX a re-computation of all flags that depend on its state + // XXX in the entire embellished hierarchy +} + NS_IMETHODIMP nsMathMLmunderoverFrame::SetInitialChildList(nsIPresContext* aPresContext, nsIAtom* aListName, diff --git a/layout/mathml/base/src/nsMathMLmunderoverFrame.h b/layout/mathml/base/src/nsMathMLmunderoverFrame.h index 85be5565110..24a500851b6 100644 --- a/layout/mathml/base/src/nsMathMLmunderoverFrame.h +++ b/layout/mathml/base/src/nsMathMLmunderoverFrame.h @@ -59,6 +59,14 @@ public: PRUint32 aFlagsValues, PRUint32 aFlagsToUpdate); + NS_IMETHOD + UpdatePresentationDataFromChildAt(nsIPresContext* aPresContext, + PRInt32 aFirstIndex, + PRInt32 aLastIndex, + PRInt32 aScriptLevelIncrement, + PRUint32 aFlagsValues, + PRUint32 aFlagsToUpdate); + protected: nsMathMLmunderoverFrame(); virtual ~nsMathMLmunderoverFrame();