Bug 785720 - Move the MathML token frame leading/trailing whitespace trimming logic to nsTextFrame; r=roc

This commit is contained in:
Ehsan Akhgari 2012-08-30 21:32:02 -04:00
Родитель 08a19e6d9c
Коммит 6a5c1314cf
17 изменённых файлов: 103 добавлений и 34 удалений

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

@ -244,6 +244,10 @@ typedef uint64_t nsFrameState;
// placeholder. This can happen for two reasons: (1) the float was
// split, and this piece is the continuation, or (2) the entire float
// didn't fit on the page.
// Note that this bit is also shared by text frames for
// TEXT_FORCE_TRIM_WHITESPACE. That's OK because we only check the
// NS_FRAME_IS_PUSHED_FLOAT bit on frames which we already know are
// out-of-flow.
#define NS_FRAME_IS_PUSHED_FLOAT NS_FRAME_STATE_BIT(32)
// This bit acts as a loop flag for recursive paint server drawing.

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

@ -21,6 +21,10 @@ class PropertyProvider;
// reflow
#define TEXT_HAS_NONCOLLAPSED_CHARACTERS NS_FRAME_STATE_BIT(31)
// This state bit is set on frames which are forced to trim their leading and
// trailing whitespaces
#define TEXT_FORCE_TRIM_WHITESPACE NS_FRAME_STATE_BIT(32)
#define TEXT_HAS_FONT_INFLATION NS_FRAME_STATE_BIT(61)
typedef nsFrame nsTextFrameBase;

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

@ -196,6 +196,9 @@ NS_DECLARE_FRAME_PROPERTY(FontSizeInflationProperty, nullptr)
// nsTextFrame.h has
// #define TEXT_HAS_NONCOLLAPSED_CHARACTERS NS_FRAME_STATE_BIT(31)
// nsTextFrame.h has
// #define TEXT_FORCE_TRIM_WHITESPACE NS_FRAME_STATE_BIT(32)
// Set when this text frame is mentioned in the userdata for the
// uninflated textrun property
#define TEXT_IN_UNINFLATED_TEXTRUN_USER_DATA NS_FRAME_STATE_BIT(60)
@ -7612,7 +7615,8 @@ nsTextFrame::ReflowText(nsLineLayout& aLineLayout, nscoord aAvailableWidth,
length = newLineOffset + 1 - offset;
}
}
if (atStartOfLine && !textStyle->WhiteSpaceIsSignificant()) {
if ((atStartOfLine && !textStyle->WhiteSpaceIsSignificant()) ||
(GetStateBits() & TEXT_FORCE_TRIM_WHITESPACE)) {
// Skip leading whitespace. Make sure we don't skip a 'pre-line'
// newline if there is one.
int32_t skipLength = newLineOffset >= 0 ? length - 1 : length;
@ -7770,7 +7774,8 @@ nsTextFrame::ReflowText(nsLineLayout& aLineLayout, nscoord aAvailableWidth,
bool usedHyphenation;
gfxFloat trimmedWidth = 0;
gfxFloat availWidth = aAvailableWidth;
bool canTrimTrailingWhitespace = !textStyle->WhiteSpaceIsSignificant();
bool canTrimTrailingWhitespace = !textStyle->WhiteSpaceIsSignificant() ||
(GetStateBits() & TEXT_FORCE_TRIM_WHITESPACE);
int32_t unusedOffset;
gfxBreakPriority breakPriority;
aLineLayout.GetLastOptionalBreakPosition(&unusedOffset, &breakPriority);
@ -7839,11 +7844,12 @@ nsTextFrame::ReflowText(nsLineLayout& aLineLayout, nscoord aAvailableWidth,
// the line. (If we actually do end up at the end of the line, we'll have
// to trim it off again in TrimTrailingWhiteSpace, and we'd like to avoid
// having to re-do it.)
if (brokeText) {
if (brokeText ||
(GetStateBits() & TEXT_FORCE_TRIM_WHITESPACE)) {
// We're definitely going to break so our trailing whitespace should
// definitely be timmed. Record that we've already done it.
// definitely be trimmed. Record that we've already done it.
AddStateBits(TEXT_TRIMMED_TRAILING_WHITESPACE);
} else {
} else if (!(GetStateBits() & TEXT_FORCE_TRIM_WHITESPACE)) {
// We might not be at the end of the line. (Note that even if this frame
// ends in breakable whitespace, it might not be at the end of the line
// because it might be followed by breakable, but preformatted, whitespace.)

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

@ -11,6 +11,7 @@
#include "nsContentUtils.h"
#include "nsCSSFrameConstructor.h"
#include "nsMathMLTokenFrame.h"
#include "nsTextFrame.h"
nsIFrame*
NS_NewMathMLTokenFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
@ -68,6 +69,7 @@ nsMathMLTokenFrame::GetMathMLFrameType()
else if(style.EqualsLiteral("invariant")) {
nsAutoString data;
nsContentUtils::GetNodeTextContent(mContent, false, data);
data.CompressWhitespace();
eMATHVARIANT variant = nsMathMLOperators::LookupInvariantChar(data);
switch (variant) {
@ -85,35 +87,19 @@ nsMathMLTokenFrame::GetMathMLFrameType()
return eMathMLFrameType_UprightIdentifier;
}
static void
CompressWhitespace(nsIContent* aContent)
void
nsMathMLTokenFrame::ForceTrimChildTextFrames()
{
uint32_t numKids = aContent->GetChildCount();
for (uint32_t kid = 0; kid < numKids; kid++) {
nsIContent* cont = aContent->GetChildAt(kid);
if (cont && cont->IsNodeOfType(nsINode::eTEXT)) {
nsAutoString text;
cont->AppendTextTo(text);
text.CompressWhitespace();
cont->SetText(text, false); // not meant to be used if notify is needed
// Set flags on child text frames to force them to trim their leading and
// trailing whitespaces.
for (nsIFrame* childFrame = GetFirstPrincipalChild(); childFrame;
childFrame = childFrame->GetNextSibling()) {
if (childFrame->GetType() == nsGkAtoms::textFrame) {
childFrame->AddStateBits(TEXT_FORCE_TRIM_WHITESPACE);
}
}
}
NS_IMETHODIMP
nsMathMLTokenFrame::Init(nsIContent* aContent,
nsIFrame* aParent,
nsIFrame* aPrevInFlow)
{
// leading and trailing whitespace doesn't count -- bug 15402
// brute force removal for people who do <mi> a </mi> instead of <mi>a</mi>
// XXX the best fix is to skip these in nsTextFrame
CompressWhitespace(aContent);
// let the base class do its Init()
return nsMathMLContainerFrame::Init(aContent, aParent, aPrevInFlow);
}
NS_IMETHODIMP
nsMathMLTokenFrame::SetInitialChildList(ChildListID aListID,
nsFrameList& aChildList)
@ -123,11 +109,41 @@ nsMathMLTokenFrame::SetInitialChildList(ChildListID aListID,
if (NS_FAILED(rv))
return rv;
ForceTrimChildTextFrames();
SetQuotes(false);
ProcessTextData();
return rv;
}
NS_IMETHODIMP
nsMathMLTokenFrame::AppendFrames(ChildListID aListID,
nsFrameList& aChildList)
{
nsresult rv = nsMathMLContainerFrame::AppendFrames(aListID, aChildList);
if (NS_FAILED(rv))
return rv;
ForceTrimChildTextFrames();
return rv;
}
NS_IMETHODIMP
nsMathMLTokenFrame::InsertFrames(ChildListID aListID,
nsIFrame* aPrevFrame,
nsFrameList& aChildList)
{
nsresult rv = nsMathMLContainerFrame::InsertFrames(aListID, aPrevFrame,
aChildList);
if (NS_FAILED(rv))
return rv;
ForceTrimChildTextFrames();
return rv;
}
nsresult
nsMathMLTokenFrame::Reflow(nsPresContext* aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
@ -297,6 +313,7 @@ nsMathMLTokenFrame::SetTextStyle()
// Get the text content that we enclose and its length
nsAutoString data;
nsContentUtils::GetNodeTextContent(mContent, false, data);
data.CompressWhitespace();
int32_t length = data.Length();
if (!length)
return false;

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

@ -34,15 +34,19 @@ public:
virtual eMathMLFrameType GetMathMLFrameType();
NS_IMETHOD
Init(nsIContent* aContent,
nsIFrame* aParent,
nsIFrame* aPrevInFlow);
NS_IMETHOD
SetInitialChildList(ChildListID aListID,
nsFrameList& aChildList);
NS_IMETHOD
AppendFrames(ChildListID aListID,
nsFrameList& aChildList);
NS_IMETHOD
InsertFrames(ChildListID aListID,
nsIFrame* aPrevFrame,
nsFrameList& aChildList);
NS_IMETHOD
Reflow(nsPresContext* aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
@ -83,6 +87,8 @@ protected:
// helper to set the quotes of <ms>
void SetQuotes(bool aNotify);
void ForceTrimChildTextFrames();
};
#endif /* nsMathMLTokentFrame_h___ */

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

@ -122,6 +122,7 @@ nsMathMLmoFrame::ProcessTextData()
nsAutoString data;
nsContentUtils::GetNodeTextContent(mContent, false, data);
data.CompressWhitespace();
int32_t length = data.Length();
PRUnichar ch = (length == 0) ? kNullCh : data[0];

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

@ -104,3 +104,8 @@ fails == mstyle-5.xhtml mstyle-5-ref.xhtml # See bug 569125#c29
== maction-dynamic-2.html maction-dynamic-2-ref.html
== mo-lspace-rspace.html mo-lspace-rspace-ref.html
== maction-dynamic-3.html maction-dynamic-3-ref.html
== whitespace-trim-1.html whitespace-trim-1-ref.html
== whitespace-trim-2.html whitespace-trim-2-ref.html
== whitespace-trim-3.html whitespace-trim-3-ref.html
fails == whitespace-trim-4.html whitespace-trim-4-ref.html # Bug 560100
== whitespace-trim-5.html whitespace-trim-5-ref.html

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

@ -0,0 +1,2 @@
<!DOCTYPE html>
<math><mo minsize="10em">(</mo></math>

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

@ -0,0 +1,2 @@
<!DOCTYPE html>
<math><mo minsize="10em"> ( </mo></math>

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

@ -0,0 +1,2 @@
<!DOCTYPE html>
<math><mi>(</mi></math>

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

@ -0,0 +1,2 @@
<!DOCTYPE html>
<math><mi> ( </mi></math>

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

@ -0,0 +1,2 @@
<!DOCTYPE html>
<math><mi mathvariant="italic">&#x210e;</mi></math>

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

@ -0,0 +1,2 @@
<!DOCTYPE html>
<math><mi mathvariant="italic"> &#x210e; </mi></math>

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

@ -0,0 +1,2 @@
<!DOCTYPE html>
<math><ms>x</ms></math>

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

@ -0,0 +1,2 @@
<!DOCTYPE html>
<math><ms> x </ms></math>

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

@ -0,0 +1,5 @@
<!DOCTYPE html>
<math><mtext>|</mtext><mi>x</mi><mtext>|</mtext></math>
<math><mtext>|</mtext><mn>x</mn><mtext>|</mtext></math>
<math><mtext>|</mtext><mo>x</mo><mtext>|</mtext></math>
<math><mtext>|</mtext><mtext>x</mtext><mtext>|</mtext></math>

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

@ -0,0 +1,5 @@
<!DOCTYPE html>
<math><mtext>|</mtext><mi> x </mi><mtext>|</mtext></math>
<math><mtext>|</mtext><mn> x </mn><mtext>|</mtext></math>
<math><mtext>|</mtext><mo> x </mo><mtext>|</mtext></math>
<math><mtext>|</mtext><mtext> x </mtext><mtext>|</mtext></math>