fix for Bug 92331: at long last moving over to using spans instead of pre's for plaintext mailcites. Due to limited testing the pref for this is left *OFF*. we'll flip it on if everything goes well later.

This commit is contained in:
jfrancis%netscape.com 2001-12-12 06:02:15 +00:00
Родитель 9ffa07fd07
Коммит 5e4e01a7c8
6 изменённых файлов: 264 добавлений и 159 удалений

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

@ -1571,10 +1571,19 @@ nsHTMLEditor::InsertAsPlaintextQuotation(const nsAReadableString & aQuotedText,
{
preElement->SetAttribute(NS_LITERAL_STRING("_moz_quote"),
NS_LITERAL_STRING("true"));
if (quotesInPre)
{
// set style to not have unwanted vertical margins
preElement->SetAttribute(NS_LITERAL_STRING("style"),
NS_LITERAL_STRING("margin: 0 0 0 0px;"));
}
else
{
// turn off wrapping on spans
preElement->SetAttribute(NS_LITERAL_STRING("style"),
NS_LITERAL_STRING("white-space: pre;"));
}
}
// and set the selection inside it:
selection->Collapse(preNode, 0);

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

@ -1312,7 +1312,8 @@ nsHTMLEditRules::WillInsertBreak(nsISelection *aSelection, PRBool *aCancel, PRBo
if (citeNode)
{
nsCOMPtr<nsIDOMNode> brNode;
res = mHTMLEditor->SplitNodeDeep(citeNode, selNode, selOffset, &newOffset);
res = mHTMLEditor->SplitNodeDeep(citeNode, selNode, selOffset,
&newOffset, PR_TRUE);
if (NS_FAILED(res)) return res;
res = citeNode->GetParentNode(getter_AddRefs(selNode));
if (NS_FAILED(res)) return res;
@ -1322,6 +1323,12 @@ nsHTMLEditRules::WillInsertBreak(nsISelection *aSelection, PRBool *aCancel, PRBo
selPriv->SetInterlinePosition(PR_TRUE);
res = aSelection->Collapse(selNode, newOffset);
if (NS_FAILED(res)) return res;
// if citeNode wasn't a block, we also want another break before it
if (IsInlineNode(citeNode))
{
res = mHTMLEditor->CreateBR(selNode, newOffset, address_of(brNode));
if (NS_FAILED(res)) return res;
}
*aHandled = PR_TRUE;
return NS_OK;
}
@ -3087,9 +3094,12 @@ nsHTMLEditRules::WillOutdent(nsISelection *aSelection, PRBool *aCancel, PRBool *
// initialize out param
*aCancel = PR_FALSE;
*aHandled = PR_TRUE;
nsAutoSelectionReset selectionResetter(aSelection, mHTMLEditor);
nsresult res = NS_OK;
nsCOMPtr<nsIDOMNode> rememberedLeftBQ, rememberedRightBQ;
// some scoping for selection resetting - we may need to tweak it
{
nsAutoSelectionReset selectionResetter(aSelection, mHTMLEditor);
// convert the selection ranges into "promoted" selection ranges:
// this basically just expands the range to include the immediate
@ -3123,7 +3133,8 @@ nsHTMLEditRules::WillOutdent(nsISelection *aSelection, PRBool *aCancel, PRBool *
// So we need to finish up dealng with any curBlockQuote first.
if (curBlockQuote)
{
res = RemovePartOfBlock(curBlockQuote, firstBQChild, lastBQChild);
res = RemovePartOfBlock(curBlockQuote, firstBQChild, lastBQChild,
address_of(rememberedLeftBQ), address_of(rememberedRightBQ));
if (NS_FAILED(res)) return res;
curBlockQuote = 0; firstBQChild = 0; lastBQChild = 0;
}
@ -3139,7 +3150,8 @@ nsHTMLEditRules::WillOutdent(nsISelection *aSelection, PRBool *aCancel, PRBool *
// pop this list item.
if (curBlockQuote)
{
res = RemovePartOfBlock(curBlockQuote, firstBQChild, lastBQChild);
res = RemovePartOfBlock(curBlockQuote, firstBQChild, lastBQChild,
address_of(rememberedLeftBQ), address_of(rememberedRightBQ));
if (NS_FAILED(res)) return res;
curBlockQuote = 0; firstBQChild = 0; lastBQChild = 0;
}
@ -3162,7 +3174,8 @@ nsHTMLEditRules::WillOutdent(nsISelection *aSelection, PRBool *aCancel, PRBool *
// otherwise, we have progressed beyond end of curBlockQuote,
// so lets handle it now. We need to remove the portion of
// curBlockQuote that contains [firstBQChild - lastBQChild].
res = RemovePartOfBlock(curBlockQuote, firstBQChild, lastBQChild);
res = RemovePartOfBlock(curBlockQuote, firstBQChild, lastBQChild,
address_of(rememberedLeftBQ), address_of(rememberedRightBQ));
if (NS_FAILED(res)) return res;
curBlockQuote = 0; firstBQChild = 0; lastBQChild = 0;
// fall out and handle curNode
@ -3237,10 +3250,40 @@ nsHTMLEditRules::WillOutdent(nsISelection *aSelection, PRBool *aCancel, PRBool *
if (curBlockQuote)
{
// we have a blockquote we haven't finished handling
res = RemovePartOfBlock(curBlockQuote, firstBQChild, lastBQChild);
res = RemovePartOfBlock(curBlockQuote, firstBQChild, lastBQChild,
address_of(rememberedLeftBQ), address_of(rememberedRightBQ));
if (NS_FAILED(res)) return res;
}
}
// make sure selection didn't stick to last piece of content in old bq
// (only a roblem for collapsed selections)
if (rememberedLeftBQ || rememberedRightBQ)
{
PRBool bCollapsed;
res = aSelection->GetIsCollapsed(&bCollapsed);
if (bCollapsed)
{
// push selection past end of rememberedLeftBQ
nsCOMPtr<nsIDOMNode> sNode;
PRInt32 sOffset;
mHTMLEditor->GetStartNodeAndOffset(aSelection, address_of(sNode), &sOffset);
if ((sNode == rememberedLeftBQ) || nsHTMLEditUtils::IsDescendantOf(sNode, rememberedLeftBQ))
{
// selection is inside rememberedLeftBQ - push it past it.
nsEditor::GetNodeLocation(rememberedLeftBQ, address_of(sNode), &sOffset);
sOffset++;
aSelection->Collapse(sNode, sOffset);
}
// and pull selection before beginning of rememberedRightBQ
mHTMLEditor->GetStartNodeAndOffset(aSelection, address_of(sNode), &sOffset);
if ((sNode == rememberedRightBQ) || nsHTMLEditUtils::IsDescendantOf(sNode, rememberedRightBQ))
{
// selection is inside rememberedRightBQ - push it before it.
nsEditor::GetNodeLocation(rememberedRightBQ, address_of(sNode), &sOffset);
aSelection->Collapse(sNode, sOffset);
}
}
}
return res;
}
@ -3252,7 +3295,9 @@ nsHTMLEditRules::WillOutdent(nsISelection *aSelection, PRBool *aCancel, PRBool *
nsresult
nsHTMLEditRules::RemovePartOfBlock(nsIDOMNode *aBlock,
nsIDOMNode *aStartChild,
nsIDOMNode *aEndChild)
nsIDOMNode *aEndChild,
nsCOMPtr<nsIDOMNode> *aLeftNode,
nsCOMPtr<nsIDOMNode> *aRightNode)
{
if (!aBlock || !aStartChild || !aEndChild)
return NS_ERROR_NULL_POINTER;
@ -3271,6 +3316,10 @@ nsHTMLEditRules::RemovePartOfBlock(nsIDOMNode *aBlock,
if (NS_FAILED(res)) return res;
if (rightNode) aBlock = rightNode;
// remember left portion of block if caller requested
if (aLeftNode)
*aLeftNode = leftNode;
// get split point location
res = nsEditor::GetNodeLocation(aEndChild, address_of(endParent), &endOffset);
if (NS_FAILED(res)) return res;
@ -3282,8 +3331,13 @@ nsHTMLEditRules::RemovePartOfBlock(nsIDOMNode *aBlock,
if (NS_FAILED(res)) return res;
if (leftNode) aBlock = leftNode;
// remember right portion of block if caller requested
if (aRightNode)
*aRightNode = rightNode;
// get rid of part of blockquote we are outdenting
res = mHTMLEditor->RemoveBlockContainer(aBlock);
return res;
}
@ -5972,7 +6026,7 @@ nsHTMLEditRules::GetTopEnclosingMailCite(nsIDOMNode *aNode,
while (node)
{
if ( (aPlainText && nsHTMLEditUtils::IsPre(node)) ||
(!aPlainText && nsHTMLEditUtils::IsMailCite(node)) )
nsHTMLEditUtils::IsMailCite(node) )
*aOutCiteNode = node;
if (nsTextEditUtils::IsBody(node)) break;

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

@ -152,9 +152,11 @@ protected:
nsresult ReturnInParagraph(nsISelection *aSelection, nsIDOMNode *aHeader, nsIDOMNode *aTextNode, PRInt32 aOffset, PRBool *aCancel, PRBool *aHandled);
nsresult ReturnInListItem(nsISelection *aSelection, nsIDOMNode *aHeader, nsIDOMNode *aTextNode, PRInt32 aOffset);
nsresult AfterEditInner(PRInt32 action, nsIEditor::EDirection aDirection);
nsresult RemovePartOfBlock(nsIDOMNode *curBlockQuote,
nsIDOMNode *firstBQChild,
nsIDOMNode *lastBQChild);
nsresult RemovePartOfBlock(nsIDOMNode *aBlock,
nsIDOMNode *aStartChild,
nsIDOMNode *aEndChild,
nsCOMPtr<nsIDOMNode> *aLeftNode = 0,
nsCOMPtr<nsIDOMNode> *aRightNode = 0);
nsresult ConvertListType(nsIDOMNode *aList, nsCOMPtr<nsIDOMNode> *outList, const nsAReadableString& aListType, const nsAReadableString& aItemType);
nsresult CreateStyleForInsertText(nsISelection *aSelection, nsIDOMDocument *aDoc);
nsresult IsEmptyBlock(nsIDOMNode *aNode,

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

@ -376,19 +376,30 @@ PRBool
nsHTMLEditUtils::IsMailCite(nsIDOMNode *node)
{
NS_PRECONDITION(node, "null parent passed to nsHTMLEditUtils::IsMailCite");
if (IsBlockquote(node))
{
nsCOMPtr<nsIDOMElement> bqElem = do_QueryInterface(node);
nsAutoString typeAttrName(NS_LITERAL_STRING("type"));
nsAutoString typeAttrVal;
nsresult res = bqElem->GetAttribute(typeAttrName, typeAttrVal);
typeAttrVal.ToLowerCase();
nsCOMPtr<nsIDOMElement> elem = do_QueryInterface(node);
if (!elem) return PR_FALSE;
nsAutoString attrName (NS_LITERAL_STRING("type"));
// don't ask me why, but our html mailcites are id'd by "type=cite"...
nsAutoString attrVal;
nsresult res = elem->GetAttribute(attrName, attrVal);
attrVal.ToLowerCase();
if (NS_SUCCEEDED(res))
{
if (typeAttrVal.EqualsWithConversion("cite", PR_TRUE, 4))
if (attrVal.Equals(NS_LITERAL_STRING("cite")))
return PR_TRUE;
}
// ... but our plaintext mailcites by "_moz_quote=true". go figure.
attrName.Assign(NS_LITERAL_STRING("_moz_quote"));
res = elem->GetAttribute(attrName, attrVal);
if (NS_SUCCEEDED(res))
{
attrVal.ToLowerCase();
if (attrVal.Equals(NS_LITERAL_STRING("true")))
return PR_TRUE;
}
return PR_FALSE;
}
@ -413,6 +424,26 @@ nsHTMLEditUtils::IsMap(nsIDOMNode *node)
}
///////////////////////////////////////////////////////////////////////////
// IsFormWidget: true if node is a form widget of some kind
//
PRBool
nsHTMLEditUtils::IsFormWidget(nsIDOMNode *node)
{
NS_PRECONDITION(node, "null node passed to nsHTMLEditUtils::IsFormWidget");
nsAutoString tag;
nsEditor::GetTagString(node,tag);
tag.ToLowerCase();
if (tag.Equals(NS_LITERAL_STRING("textarea")) ||
tag.Equals(NS_LITERAL_STRING("select")) ||
tag.Equals(NS_LITERAL_STRING("button")) ||
tag.Equals(NS_LITERAL_STRING("input")) )
{
return PR_TRUE;
}
return PR_FALSE;
}
PRBool
nsHTMLEditUtils::IsDescendantOf(nsIDOMNode *aNode, nsIDOMNode *aParent, PRInt32 *aOffset)
{

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

@ -78,6 +78,7 @@ public:
static PRBool IsMailCite(nsIDOMNode *aNode);
static PRBool IsTextarea(nsIDOMNode *aNode);
static PRBool IsMap(nsIDOMNode *aNode);
static PRBool IsFormWidget(nsIDOMNode *aNode);
static PRBool IsDescendantOf(nsIDOMNode *aNode, nsIDOMNode *aParent, PRInt32 *aOffset = 0);
static PRBool IsLeafNode(nsIDOMNode *aNode);

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

@ -4706,8 +4706,9 @@ nsHTMLEditor::IsEmptyNode( nsIDOMNode *aNode,
// Also, if it's an anchor then dont treat it as empty - even though
// anchors are containers, named anchors are "empty" but we don't
// want to treat them as such. Also, don't call ListItems or table
// cells empty if caller desires.
// cells empty if caller desires. Form Widgets not empty.
if (!IsContainer(aNode) || nsHTMLEditUtils::IsNamedAnchor(aNode) ||
nsHTMLEditUtils::IsFormWidget(aNode) ||
(aListOrCellNotEmpty && nsHTMLEditUtils::IsListItem(aNode)) ||
(aListOrCellNotEmpty && nsHTMLEditUtils::IsTableCell(aNode)) )
{
@ -4804,6 +4805,13 @@ nsHTMLEditor::IsEmptyNode( nsIDOMNode *aNode,
break;
}
}
// is it a form widget?
else if (nsHTMLEditUtils::IsFormWidget(aNode))
{
*outIsEmptyNode = PR_FALSE;
break;
}
PRBool isEmptyNode;
res = IsEmptyNode(node, &isEmptyNode, aSingleBRDoesntCount, aListOrCellNotEmpty);
if (NS_FAILED(res)) return res;