Fix incorrect values for saving ordered lists as text.

This commit is contained in:
wolfbeast 2019-12-06 14:54:57 +01:00 • committed by Roy Tam
commit 5a102074d1
2 changed files with 33 additions and 29 deletions

View file

@ -53,7 +53,6 @@ static int32_t GetUnicharStringWidth(const char16_t* pwcs, int32_t n);
// Someday may want to make this non-const: // Someday may want to make this non-const:
static const uint32_t TagStackSize = 500; static const uint32_t TagStackSize = 500;
static const uint32_t OLStackSize = 100;
nsresult nsresult
NS_NewPlainTextSerializer(nsIContentSerializer** aSerializer) NS_NewPlainTextSerializer(nsIContentSerializer** aSerializer)
@ -100,10 +99,6 @@ nsPlainTextSerializer::nsPlainTextSerializer()
mTagStackIndex = 0; mTagStackIndex = 0;
mIgnoreAboveIndex = (uint32_t)kNotFound; mIgnoreAboveIndex = (uint32_t)kNotFound;
// initialize the OL stack, where numbers for ordered lists are kept
mOLStack = new int32_t[OLStackSize];
mOLStackIndex = 0;
mULCount = 0; mULCount = 0;
mIgnoredChildNodeLevel = 0; mIgnoredChildNodeLevel = 0;
@ -112,7 +107,6 @@ nsPlainTextSerializer::nsPlainTextSerializer()
nsPlainTextSerializer::~nsPlainTextSerializer() nsPlainTextSerializer::~nsPlainTextSerializer()
{ {
delete[] mTagStack; delete[] mTagStack;
delete[] mOLStack;
NS_WARNING_ASSERTION(mHeadLevel == 0, "Wrong head level!"); NS_WARNING_ASSERTION(mHeadLevel == 0, "Wrong head level!");
} }
@ -189,6 +183,8 @@ nsPlainTextSerializer::Init(uint32_t aFlags, uint32_t aWrapColumn,
// XXX We should let the caller decide whether to do this or not // XXX We should let the caller decide whether to do this or not
mFlags &= ~nsIDocumentEncoder::OutputNoFramesContent; mFlags &= ~nsIDocumentEncoder::OutputNoFramesContent;
MOZ_ASSERT(mOLStack.IsEmpty());
return NS_OK; return NS_OK;
} }
@ -438,6 +434,8 @@ nsPlainTextSerializer::AppendDocumentStart(nsIDocument *aDocument,
return NS_OK; return NS_OK;
} }
int32_t kOlStackDummyValue = 0;
nsresult nsresult
nsPlainTextSerializer::DoOpenContainer(nsIAtom* aTag) nsPlainTextSerializer::DoOpenContainer(nsIAtom* aTag)
{ {
@ -616,44 +614,45 @@ nsPlainTextSerializer::DoOpenContainer(nsIAtom* aTag)
} }
else if (aTag == nsGkAtoms::ul) { else if (aTag == nsGkAtoms::ul) {
// Indent here to support nested lists, which aren't included in li :-( // Indent here to support nested lists, which aren't included in li :-(
EnsureVerticalSpace(mULCount + mOLStackIndex == 0 ? 1 : 0); EnsureVerticalSpace(IsInOLOrUL() ? 0 : 1);
// Must end the current line before we change indention // Must end the current line before we change indention
mIndent += kIndentSizeList; mIndent += kIndentSizeList;
mULCount++; mULCount++;
} }
else if (aTag == nsGkAtoms::ol) { else if (aTag == nsGkAtoms::ol) {
EnsureVerticalSpace(mULCount + mOLStackIndex == 0 ? 1 : 0); EnsureVerticalSpace(IsInOLOrUL() ? 0 : 1);
if (mFlags & nsIDocumentEncoder::OutputFormatted) { if (mFlags & nsIDocumentEncoder::OutputFormatted) {
// Must end the current line before we change indention // Must end the current line before we change indention
if (mOLStackIndex < OLStackSize) { nsAutoString startAttr;
nsAutoString startAttr; int32_t startVal = 1;
int32_t startVal = 1; if (NS_SUCCEEDED(GetAttributeValue(nsGkAtoms::start, startAttr))) {
if (NS_SUCCEEDED(GetAttributeValue(nsGkAtoms::start, startAttr))) { nsresult rv = NS_OK;
nsresult rv = NS_OK; startVal = startAttr.ToInteger(&rv);
startVal = startAttr.ToInteger(&rv); if (NS_FAILED(rv)) {
if (NS_FAILED(rv)) startVal = 1;
startVal = 1;
} }
mOLStack[mOLStackIndex++] = startVal;
} }
mOLStack.AppendElement(startVal);
} else { } else {
mOLStackIndex++; mOLStack.AppendElement(kOlStackDummyValue);
} }
mIndent += kIndentSizeList; // see ul mIndent += kIndentSizeList; // see ul
} }
else if (aTag == nsGkAtoms::li && else if (aTag == nsGkAtoms::li &&
(mFlags & nsIDocumentEncoder::OutputFormatted)) { (mFlags & nsIDocumentEncoder::OutputFormatted)) {
if (mTagStackIndex > 1 && IsInOL()) { if (mTagStackIndex > 1 && IsInOL()) {
if (mOLStackIndex > 0) { if (!mOLStack.IsEmpty()) {
nsAutoString valueAttr; nsAutoString valueAttr;
if (NS_SUCCEEDED(GetAttributeValue(nsGkAtoms::value, valueAttr))) { if (NS_SUCCEEDED(GetAttributeValue(nsGkAtoms::value, valueAttr))) {
nsresult rv = NS_OK; nsresult rv = NS_OK;
int32_t valueAttrVal = valueAttr.ToInteger(&rv); int32_t valueAttrVal = valueAttr.ToInteger(&rv);
if (NS_SUCCEEDED(rv)) if (NS_SUCCEEDED(rv)) {
mOLStack[mOLStackIndex-1] = valueAttrVal; mOLStack.LastElement() = valueAttrVal;
}
} }
// This is what nsBulletFrame does for OLs: // This is what nsBulletFrame does for OLs:
mInIndentString.AppendInt(mOLStack[mOLStackIndex-1]++, 10); mInIndentString.AppendInt(mOLStack.LastElement(), 10);
mOLStack.LastElement()++;
} }
else { else {
mInIndentString.Append(char16_t('#')); mInIndentString.Append(char16_t('#'));
@ -878,7 +877,8 @@ nsPlainTextSerializer::DoCloseContainer(nsIAtom* aTag)
else if (aTag == nsGkAtoms::ul) { else if (aTag == nsGkAtoms::ul) {
FlushLine(); FlushLine();
mIndent -= kIndentSizeList; mIndent -= kIndentSizeList;
if (--mULCount + mOLStackIndex == 0) { --mULCount;
if (!IsInOLOrUL()) {
mFloatingLines = 1; mFloatingLines = 1;
mLineBreakDue = true; mLineBreakDue = true;
} }
@ -886,9 +886,9 @@ nsPlainTextSerializer::DoCloseContainer(nsIAtom* aTag)
else if (aTag == nsGkAtoms::ol) { else if (aTag == nsGkAtoms::ol) {
FlushLine(); // Doing this after decreasing OLStackIndex would be wrong. FlushLine(); // Doing this after decreasing OLStackIndex would be wrong.
mIndent -= kIndentSizeList; mIndent -= kIndentSizeList;
NS_ASSERTION(mOLStackIndex, "Wrong OLStack level!"); NS_ASSERTION(!mOLStack.IsEmpty(), "Wrong OLStack level!");
mOLStackIndex--; mOLStack.RemoveElementAt(mOLStack.Length() - 1);
if (mULCount + mOLStackIndex == 0) { if (!IsInOLOrUL()) {
mFloatingLines = 1; mFloatingLines = 1;
mLineBreakDue = true; mLineBreakDue = true;
} }
@ -1861,6 +1861,10 @@ nsPlainTextSerializer::IsInOL()
return false; return false;
} }
bool nsPlainTextSerializer::IsInOLOrUL() const {
return (mULCount > 0) || !mOLStack.IsEmpty();
}
/* /*
@return 0 = no header, 1 = h1, ..., 6 = h6 @return 0 = no header, 1 = h1, ..., 6 = h6
*/ */

View file

@ -81,6 +81,7 @@ private:
void Write(const nsAString& aString); void Write(const nsAString& aString);
bool IsInPre(); bool IsInPre();
bool IsInOL(); bool IsInOL();
bool IsInOLOrUL() const;
bool IsCurrentNodeConverted(); bool IsCurrentNodeConverted();
bool MustSuppressLeaf(); bool MustSuppressLeaf();
@ -218,8 +219,7 @@ private:
uint32_t mIgnoreAboveIndex; uint32_t mIgnoreAboveIndex;
// The stack for ordered lists // The stack for ordered lists
int32_t *mOLStack; AutoTArray<int32_t, 100> mOLStack;
uint32_t mOLStackIndex;
uint32_t mULCount; uint32_t mULCount;