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:
Родитель
9ffa07fd07
Коммит
5e4e01a7c8
|
@ -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;
|
||||
|
|
Загрузка…
Ссылка в новой задаче