#578: M1580320 M1584170

This commit is contained in:
Cameron Kaiser 2019-11-19 21:26:25 -08:00
parent 45c95c3dad
commit 216c8ff731
3 changed files with 51 additions and 63 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)
@ -101,10 +100,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;
@ -113,7 +108,6 @@ nsPlainTextSerializer::nsPlainTextSerializer()
nsPlainTextSerializer::~nsPlainTextSerializer() nsPlainTextSerializer::~nsPlainTextSerializer()
{ {
delete[] mTagStack; delete[] mTagStack;
delete[] mOLStack;
NS_WARN_IF_FALSE(mHeadLevel == 0, "Wrong head level!"); NS_WARN_IF_FALSE(mHeadLevel == 0, "Wrong head level!");
} }
@ -199,6 +193,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;
} }
@ -447,6 +443,8 @@ nsPlainTextSerializer::AppendDocumentStart(nsIDocument *aDocument,
return NS_OK; return NS_OK;
} }
constexpr int32_t kOlStackDummyValue = 0;
nsresult nsresult
nsPlainTextSerializer::DoOpenContainer(nsIAtom* aTag) nsPlainTextSerializer::DoOpenContainer(nsIAtom* aTag)
{ {
@ -625,53 +623,52 @@ 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('#'));
} }
mInIndentString.Append(char16_t('.')); mInIndentString.Append(char16_t('.'));
} } else {
else {
static char bulletCharArray[] = "*o+#"; static char bulletCharArray[] = "*o+#";
uint32_t index = mULCount > 0 ? (mULCount - 1) : 3; uint32_t index = mULCount > 0 ? (mULCount - 1) : 3;
char bulletChar = bulletCharArray[index % 4]; char bulletChar = bulletCharArray[index % 4];
@ -679,33 +676,26 @@ nsPlainTextSerializer::DoOpenContainer(nsIAtom* aTag)
} }
mInIndentString.Append(char16_t(' ')); mInIndentString.Append(char16_t(' '));
} } else if (aTag == nsGkAtoms::dl) {
else if (aTag == nsGkAtoms::dl) {
EnsureVerticalSpace(1); EnsureVerticalSpace(1);
} } else if (aTag == nsGkAtoms::dt) {
else if (aTag == nsGkAtoms::dt) {
EnsureVerticalSpace(0); EnsureVerticalSpace(0);
} } else if (aTag == nsGkAtoms::dd) {
else if (aTag == nsGkAtoms::dd) {
EnsureVerticalSpace(0); EnsureVerticalSpace(0);
mIndent += kIndentSizeDD; mIndent += kIndentSizeDD;
} } else if (aTag == nsGkAtoms::span) {
else if (aTag == nsGkAtoms::span) {
++mSpanLevel; ++mSpanLevel;
} } else if (aTag == nsGkAtoms::blockquote) {
else if (aTag == nsGkAtoms::blockquote) {
// Push // Push
PushBool(mIsInCiteBlockquote, isInCiteBlockquote); PushBool(mIsInCiteBlockquote, isInCiteBlockquote);
if (isInCiteBlockquote) { if (isInCiteBlockquote) {
EnsureVerticalSpace(0); EnsureVerticalSpace(0);
mCiteQuoteLevel++; mCiteQuoteLevel++;
} } else {
else {
EnsureVerticalSpace(1); EnsureVerticalSpace(1);
mIndent += kTabSize; // Check for some maximum value? mIndent += kTabSize; // Check for some maximum value?
} }
} } else if (aTag == nsGkAtoms::q) {
else if (aTag == nsGkAtoms::q) {
Write(NS_LITERAL_STRING("\"")); Write(NS_LITERAL_STRING("\""));
} }
@ -887,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;
} }
@ -895,31 +886,26 @@ 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!"); MOZ_ASSERT(!mOLStack.IsEmpty(), "Wrong OLStack level!");
mOLStackIndex--; mOLStack.RemoveElementAt(mOLStack.Length() - 1); // mOLStack.RemoveLastElement();
if (mULCount + mOLStackIndex == 0) { if (!IsInOlOrUl()) {
mFloatingLines = 1; mFloatingLines = 1;
mLineBreakDue = true; mLineBreakDue = true;
} }
} } else if (aTag == nsGkAtoms::dl) {
else if (aTag == nsGkAtoms::dl) {
mFloatingLines = 1; mFloatingLines = 1;
mLineBreakDue = true; mLineBreakDue = true;
} } else if (aTag == nsGkAtoms::dd) {
else if (aTag == nsGkAtoms::dd) {
FlushLine(); FlushLine();
mIndent -= kIndentSizeDD; mIndent -= kIndentSizeDD;
} } else if (aTag == nsGkAtoms::span) {
else if (aTag == nsGkAtoms::span) {
NS_ASSERTION(mSpanLevel, "Span level will be negative!"); NS_ASSERTION(mSpanLevel, "Span level will be negative!");
--mSpanLevel; --mSpanLevel;
} } else if (aTag == nsGkAtoms::div) {
else if (aTag == nsGkAtoms::div) {
if (mFloatingLines < 0) if (mFloatingLines < 0)
mFloatingLines = 0; mFloatingLines = 0;
mLineBreakDue = true; mLineBreakDue = true;
} } else if (aTag == nsGkAtoms::blockquote) {
else if (aTag == nsGkAtoms::blockquote) {
FlushLine(); // Is this needed? FlushLine(); // Is this needed?
// Pop // Pop
@ -930,17 +916,14 @@ nsPlainTextSerializer::DoCloseContainer(nsIAtom* aTag)
mCiteQuoteLevel--; mCiteQuoteLevel--;
mFloatingLines = 0; mFloatingLines = 0;
mHasWrittenCiteBlockquote = true; mHasWrittenCiteBlockquote = true;
} } else {
else {
mIndent -= kTabSize; mIndent -= kTabSize;
mFloatingLines = 1; mFloatingLines = 1;
} }
mLineBreakDue = true; mLineBreakDue = true;
} } else if (aTag == nsGkAtoms::q) {
else if (aTag == nsGkAtoms::q) {
Write(NS_LITERAL_STRING("\"")); Write(NS_LITERAL_STRING("\""));
} } else if (IsElementBlock(mElement) && aTag != nsGkAtoms::script) {
else if (IsElementBlock(mElement) && aTag != nsGkAtoms::script) {
// All other blocks get 1 vertical space after them // All other blocks get 1 vertical space after them
// in formatted mode, otherwise 0. // in formatted mode, otherwise 0.
// This is hard. Sometimes 0 is a better number, but // This is hard. Sometimes 0 is a better number, but
@ -1866,6 +1849,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();
@ -222,8 +223,7 @@ private:
uint32_t mIgnoreAboveIndex; uint32_t mIgnoreAboveIndex;
// The stack for ordered lists // The stack for ordered lists
int32_t *mOLStack; nsAutoTArray<int32_t, 100> mOLStack;
uint32_t mOLStackIndex;
uint32_t mULCount; uint32_t mULCount;

View File

@ -487,7 +487,8 @@ public:
void GetFingerprint(nsAString& fingerprint) void GetFingerprint(nsAString& fingerprint)
{ {
char *tmp; char *tmp;
GetFingerprint(&tmp); nsresult rv = GetFingerprint(&tmp);
NS_ENSURE_SUCCESS_VOID(rv);
fingerprint.AssignASCII(tmp); fingerprint.AssignASCII(tmp);
delete[] tmp; delete[] tmp;
} }