Bug 173388 - Use TABs to seperate table cell when converting HTML -> Text (copying from a web page).

This commit is contained in:
bratell%lysator.liu.se 2002-12-19 06:22:55 +00:00
parent 687cf48363
commit 304c608514
4 changed files with 86 additions and 32 deletions

View File

@ -239,6 +239,46 @@ nsPlainTextSerializer::Init(PRUint32 aFlags, PRUint32 aWrapColumn,
return NS_OK; return NS_OK;
} }
PRBool
nsPlainTextSerializer::GetLastBool(const nsVoidArray& aStack)
{
PRUint32 size = aStack.Count();
if (size == 0) {
return PR_FALSE;
}
return NS_REINTERPRET_CAST(PRBool, aStack.ElementAt(size-1));
}
void
nsPlainTextSerializer::SetLastBool(nsVoidArray& aStack, PRBool aValue)
{
PRUint32 size = aStack.Count();
if (size > 0) {
aStack.ReplaceElementAt(NS_REINTERPRET_CAST(void*, aValue), size-1);
}
else {
NS_ERROR("There is no \"Last\" value");
}
}
void
nsPlainTextSerializer::PushBool(nsVoidArray& aStack, PRBool aValue)
{
aStack.AppendElement(NS_REINTERPRET_CAST(void*, aValue));
}
PRBool
nsPlainTextSerializer::PopBool(nsVoidArray& aStack)
{
PRBool returnValue = PR_FALSE;
PRUint32 size = aStack.Count();
if (size > 0) {
returnValue = NS_REINTERPRET_CAST(PRBool, aStack.ElementAt(size-1));
aStack.RemoveElementAt(size-1);
}
return returnValue;
}
NS_IMETHODIMP NS_IMETHODIMP
nsPlainTextSerializer::Initialize(nsAString* aOutString, nsPlainTextSerializer::Initialize(nsAString* aOutString,
PRUint32 aFlags, PRUint32 aWrapCol) PRUint32 aFlags, PRUint32 aWrapCol)
@ -654,18 +694,28 @@ nsPlainTextSerializer::DoOpenContainer(const nsIParserNode* aNode, PRInt32 aTag)
if (type == eHTMLTag_p || type == eHTMLTag_pre) { if (type == eHTMLTag_p || type == eHTMLTag_pre) {
EnsureVerticalSpace(1); // Should this be 0 in unformatted case? EnsureVerticalSpace(1); // Should this be 0 in unformatted case?
} }
else if (type == eHTMLTag_tr) {
PushBool(mHasWrittenCellsForRow, PR_FALSE);
}
else if (type == eHTMLTag_td || type == eHTMLTag_th) { else if (type == eHTMLTag_td || type == eHTMLTag_th) {
// We must make sure that the content of two table cells get a // We must make sure that the content of two table cells get a
// space between them. // space between them.
// Fow now, I will only add a SPACE. Could be a TAB or something // To make the seperation between cells most obvious and
// else but I'm not sure everything can handle the TAB so SPACE // importable, we use a TAB.
// seems like a better solution. if (GetLastBool(mHasWrittenCellsForRow)) {
if(!mInWhitespace) { // Bypass |Write| so that the TAB isn't compressed away.
// Maybe add something else? Several spaces? A TAB? SPACE+TAB? AddToLine(NS_LITERAL_STRING("\t").get(), 1);
AddToLine(kSpace.get(), 1);
mInWhitespace = PR_TRUE; mInWhitespace = PR_TRUE;
} }
else if (mHasWrittenCellsForRow.Count() == 0) {
// We don't always see a <tr> (nor a <table>) before the <td> if we're
// copying part of a table
PushBool(mHasWrittenCellsForRow, PR_TRUE); // will never be popped
}
else {
SetLastBool(mHasWrittenCellsForRow, PR_TRUE);
}
} }
else if (type == eHTMLTag_ul) { else if (type == eHTMLTag_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 :-(
@ -741,7 +791,7 @@ nsPlainTextSerializer::DoOpenContainer(const nsIParserNode* aNode, PRInt32 aTag)
PRBool isInCiteBlockquote = PRBool isInCiteBlockquote =
NS_SUCCEEDED(rv) && value.EqualsIgnoreCase("cite"); NS_SUCCEEDED(rv) && value.EqualsIgnoreCase("cite");
// Push // Push
mIsInCiteBlockquote.AppendElement((void*)isInCiteBlockquote); PushBool(mIsInCiteBlockquote, isInCiteBlockquote);
if (isInCiteBlockquote) { if (isInCiteBlockquote) {
mCiteQuoteLevel++; mCiteQuoteLevel++;
} }
@ -767,7 +817,7 @@ nsPlainTextSerializer::DoOpenContainer(const nsIParserNode* aNode, PRInt32 aTag)
// Push on stack // Push on stack
PRBool currentNodeIsConverted = IsCurrentNodeConverted(aNode); PRBool currentNodeIsConverted = IsCurrentNodeConverted(aNode);
mCurrentNodeIsConverted.AppendElement((void*)currentNodeIsConverted); PushBool(mCurrentNodeIsConverted, currentNodeIsConverted);
if (type == eHTMLTag_h1 || type == eHTMLTag_h2 || if (type == eHTMLTag_h1 || type == eHTMLTag_h2 ||
type == eHTMLTag_h3 || type == eHTMLTag_h4 || type == eHTMLTag_h3 || type == eHTMLTag_h4 ||
@ -893,8 +943,14 @@ nsPlainTextSerializer::DoCloseContainer(PRInt32 aTag)
// so just return now: // so just return now:
return NS_OK; return NS_OK;
} }
else if ((type == eHTMLTag_tr) || else if (type == eHTMLTag_tr) {
(type == eHTMLTag_li) || PopBool(mHasWrittenCellsForRow);
// Should always end a line, but get no more whitespace
if (mFloatingLines < 0)
mFloatingLines = 0;
mLineBreakDue = PR_TRUE;
}
else if ((type == eHTMLTag_li) ||
(type == eHTMLTag_dt)) { (type == eHTMLTag_dt)) {
// Items that should always end a line, but get no more whitespace // Items that should always end a line, but get no more whitespace
if (mFloatingLines < 0) if (mFloatingLines < 0)
@ -942,12 +998,7 @@ nsPlainTextSerializer::DoCloseContainer(PRInt32 aTag)
FlushLine(); // Is this needed? FlushLine(); // Is this needed?
// Pop // Pop
PRBool isInCiteBlockquote = PR_FALSE; PRBool isInCiteBlockquote = PopBool(mIsInCiteBlockquote);
if (mIsInCiteBlockquote.Count() > 0) {
isInCiteBlockquote =
(PRBool)mIsInCiteBlockquote[mIsInCiteBlockquote.Count()-1];
mIsInCiteBlockquote.RemoveElementAt(mIsInCiteBlockquote.Count()-1);
}
if (isInCiteBlockquote) { if (isInCiteBlockquote) {
mCiteQuoteLevel--; mCiteQuoteLevel--;
@ -986,12 +1037,7 @@ nsPlainTextSerializer::DoCloseContainer(PRInt32 aTag)
////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////
// Pop the currentConverted stack // Pop the currentConverted stack
PRBool currentNodeIsConverted = PR_FALSE; PRBool currentNodeIsConverted = PopBool(mCurrentNodeIsConverted);
if (mCurrentNodeIsConverted.Count() > 0) {
currentNodeIsConverted =
(PRBool)mCurrentNodeIsConverted[mCurrentNodeIsConverted.Count()-1];
mCurrentNodeIsConverted.RemoveElementAt(mCurrentNodeIsConverted.Count()-1);
}
if (type == eHTMLTag_h1 || type == eHTMLTag_h2 || if (type == eHTMLTag_h1 || type == eHTMLTag_h2 ||
type == eHTMLTag_h3 || type == eHTMLTag_h4 || type == eHTMLTag_h3 || type == eHTMLTag_h4 ||
@ -1057,8 +1103,6 @@ nsPlainTextSerializer::DoAddLeaf(const nsIParserNode *aNode, PRInt32 aTag,
if (mLineBreakDue) if (mLineBreakDue)
EnsureVerticalSpace(mFloatingLines); EnsureVerticalSpace(mFloatingLines);
PRBool currentNodeIsConverted = IsCurrentNodeConverted(aNode);
eHTMLTags type = (eHTMLTags)aTag; eHTMLTags type = (eHTMLTags)aTag;
if ((mTagStackIndex > 1 && if ((mTagStackIndex > 1 &&
@ -1096,7 +1140,8 @@ nsPlainTextSerializer::DoAddLeaf(const nsIParserNode *aNode, PRInt32 aTag,
PRInt32 err = 0; PRInt32 err = 0;
entity = str.ToInteger(&err, kAutoDetect); // NCR entity = str.ToInteger(&err, kAutoDetect); // NCR
} }
nsAutoString temp(entity); nsAutoString temp;
temp.Append(PRUnichar(entity));
Write(temp); Write(temp);
} }
} }

View File

@ -167,6 +167,12 @@ protected:
{ {
return !mInHead; return !mInHead;
} }
// Stack handling functions
PRBool GetLastBool(const nsVoidArray& aStack);
void SetLastBool(nsVoidArray& aStack, PRBool aValue);
void PushBool(nsVoidArray& aStack, PRBool aValue);
PRBool PopBool(nsVoidArray& aStack);
protected: protected:
nsString mCurrentLine; nsString mCurrentLine;
@ -235,6 +241,9 @@ protected:
nsCOMPtr<nsIContent> mContent; nsCOMPtr<nsIContent> mContent;
// For handling table rows
nsAutoVoidArray mHasWrittenCellsForRow; // really an array of bools
// Values gotten in OpenContainer that is (also) needed in CloseContainer // Values gotten in OpenContainer that is (also) needed in CloseContainer
nsAutoVoidArray mCurrentNodeIsConverted; // really an array of bools nsAutoVoidArray mCurrentNodeIsConverted; // really an array of bools
nsAutoVoidArray mIsInCiteBlockquote; // really an array of bools nsAutoVoidArray mIsInCiteBlockquote; // really an array of bools

View File

@ -1,6 +1,6 @@
Below is a table. Below is a table.
Row 1 Col 1 Row 1 Col 2 Row 1 Col 3 Row 1 Col 1 Row 1 Col 2 Row 1 Col 3
Row 2 Col 1 Row 2 Col 2 Row 2 Col 3 Row 2 Col 1 Row 2 Col 2 Row 2 Col 3
Row 3 Col 1 Row 3 Col 2 Row 3 Col 3 Row 3 Col 1 Row 3 Col 2 Row 3 Col 3
Here is after table. Here is after table.

View File

@ -1,6 +1,6 @@
Below is a table. Below is a table.
Row 1 Col 1 Row 1 Col 2 Row 1 Col 3 Row 1 Col 1 Row 1 Col 2 Row 1 Col 3
Row 2 Col 1 Row 2 Col 2 Row 2 Col 3 Row 2 Col 1 Row 2 Col 2 Row 2 Col 3
Row 3 Col 1 Row 3 Col 2 Row 3 Col 3 Row 3 Col 1 Row 3 Col 2 Row 3 Col 3
Here is after table. Here is after table.