fixes for bugs:

This commit is contained in:
jfrancis%netscape.com 2001-04-17 10:15:05 +00:00
parent 5a825e5b27
commit edc5638e7c
12 changed files with 202 additions and 102 deletions

View File

@ -3494,7 +3494,8 @@ nsEditor::IsEditable(nsIDOMNode *aNode)
if (!shell) return PR_FALSE;
if (IsMozEditorBogusNode(aNode)) return PR_FALSE;
/* THIS DOESN'T WORK!
// it's not the bogus node, so see if it is an irrelevant text node
if (PR_TRUE==IsTextNode(aNode))
{
@ -3521,7 +3522,7 @@ nsEditor::IsEditable(nsIDOMNode *aNode)
return PR_FALSE;
}
}
*/
// we got this far, so see if it has a frame. If so, we'll edit it.
nsIFrame *resultFrame;
nsCOMPtr<nsIContent>content;

View File

@ -186,6 +186,8 @@ nsresult nsHTMLEditor::InsertHTMLWithCharsetAndContext(const nsAReadableString &
{
if (!mRules) return NS_ERROR_NOT_INITIALIZED;
/* all this is unneeded: parser handles this for us
// First, make sure there are no return chars in the document.
// Bad things happen if you insert returns (instead of dom newlines, \n)
// into an editor document.
@ -198,6 +200,7 @@ nsresult nsHTMLEditor::InsertHTMLWithCharsetAndContext(const nsAReadableString &
// Mac linebreaks: Map any remaining CR to LF:
inputString.ReplaceSubstring(NS_ConvertASCIItoUCS2("\r"),
NS_ConvertASCIItoUCS2("\n"));
*/
// force IME commit; set up rules sniffing and batching
ForceCompositionEnd();
@ -223,7 +226,7 @@ nsresult nsHTMLEditor::InsertHTMLWithCharsetAndContext(const nsAReadableString &
// create a dom document fragment that represents the structure to paste
nsCOMPtr<nsIDOMNode> fragmentAsNode;
PRInt32 rangeStartHint, rangeEndHint;
res = CreateDOMFragmentFromPaste(nsrange, inputString, aContextStr, aInfoStr,
res = CreateDOMFragmentFromPaste(nsrange, aInputString, aContextStr, aInfoStr,
address_of(fragmentAsNode),
&rangeStartHint, &rangeEndHint);
NS_ENSURE_SUCCESS(res, res);

View File

@ -883,15 +883,16 @@ nsHTMLEditRules::WillInsert(nsISelection *aSelection, PRBool *aCancel)
else block1 = mHTMLEditor->GetBlockNodeParent(selNode);
block2 = mHTMLEditor->GetBlockNodeParent(priorNode);
if (block1 != block2) return NS_OK;
// if we are here then the selection is right after a mozBR
// that is in the same block as the selection. We need to move
// the selection start to be before the mozBR.
res = nsEditor::GetNodeLocation(priorNode, address_of(selNode), &selOffset);
if (NS_FAILED(res)) return res;
res = aSelection->Collapse(selNode,selOffset);
if (NS_FAILED(res)) return res;
if (block1 == block2)
{
// if we are here then the selection is right after a mozBR
// that is in the same block as the selection. We need to move
// the selection start to be before the mozBR.
res = nsEditor::GetNodeLocation(priorNode, address_of(selNode), &selOffset);
if (NS_FAILED(res)) return res;
res = aSelection->Collapse(selNode,selOffset);
if (NS_FAILED(res)) return res;
}
}
// we need to get the doc
@ -901,8 +902,7 @@ nsHTMLEditRules::WillInsert(nsISelection *aSelection, PRBool *aCancel)
if (!doc) return NS_ERROR_NULL_POINTER;
// for every property that is set, insert a new inline style node
res = CreateStyleForInsertText(aSelection, doc);
return res;
return CreateStyleForInsertText(aSelection, doc);
}
nsresult
@ -998,7 +998,7 @@ nsHTMLEditRules::WillInsertText(PRInt32 aAction,
// dont spaz my selection in subtransactions
nsAutoTxnsConserveSelection dontSpazMySelection(mHTMLEditor);
nsSubsumeStr subStr;
const nsPromiseFlatString &tString = PromiseFlatString(*inString);////MJUDGE SCC NEED HELP
nsAutoString tString(*inString);
const PRUnichar *unicodeBuf = tString.get();
nsCOMPtr<nsIDOMNode> unused;
PRInt32 pos = 0;
@ -1008,21 +1008,13 @@ nsHTMLEditRules::WillInsertText(PRInt32 aAction,
// it is to search for both tabs and newlines.
if (isPRE)
{
nsAutoString newlineChar(NS_LITERAL_STRING("\n"));
char newlineChar = '\n';
while (unicodeBuf && (pos != -1) && (pos < (PRInt32)(*inString).Length()))
{
PRInt32 oldPos = pos;
PRInt32 subStrLen;
pos = -1;
nsReadingIterator<PRUnichar> beginFindIter, endFindIter, beginIter;
inString->BeginReading(beginIter);
beginFindIter = beginIter;
inString->EndReading(endFindIter);
beginFindIter.advance(oldPos);
if (FindInReadable(newlineChar,beginFindIter,endFindIter))
{
pos = Distance(beginIter,beginFindIter);
}
pos = tString.FindChar(newlineChar, PR_FALSE, oldPos);
if (pos != -1)
{
subStrLen = pos - oldPos;
@ -1032,8 +1024,8 @@ nsHTMLEditRules::WillInsertText(PRInt32 aAction,
}
else
{
subStrLen = (*inString).Length() - oldPos;
pos = (*inString).Length();
subStrLen = tString.Length() - oldPos;
pos = tString.Length();
}
subStr.Subsume((PRUnichar*)&unicodeBuf[oldPos], PR_FALSE, subStrLen);
@ -1053,22 +1045,13 @@ nsHTMLEditRules::WillInsertText(PRInt32 aAction,
}
else
{
nsAutoString specialChars;
specialChars = NS_LITERAL_STRING("\t\n");
char specialChars[] = {'\t','\n',0};
nsAutoString tabString; tabString.AssignWithConversion(" ");
while (unicodeBuf && (pos != -1) && (pos < (PRInt32)(*inString).Length()))
while (unicodeBuf && (pos != -1) && (pos < (PRInt32)inString->Length()))
{
PRInt32 oldPos = pos;
PRInt32 subStrLen;
nsReadingIterator<PRUnichar> beginFindIter,endFindIter;
(*inString).BeginReading(beginFindIter);
beginFindIter.advance(oldPos);
(*inString).EndReading(endFindIter);
nsReadingIterator<PRUnichar> distanceIter;
(*inString).BeginReading(distanceIter);
pos = -1;
if (FindInReadable((const nsAString &)specialChars,beginFindIter,endFindIter))
pos = Distance(distanceIter,beginFindIter);
pos = tString.FindCharInSet(specialChars, oldPos);
if (pos != -1)
{
@ -1079,8 +1062,8 @@ nsHTMLEditRules::WillInsertText(PRInt32 aAction,
}
else
{
subStrLen = (*inString).Length() - oldPos;
pos = (*inString).Length();
subStrLen = tString.Length() - oldPos;
pos = tString.Length();
}
subStr.Subsume((PRUnichar*)&unicodeBuf[oldPos], PR_FALSE, subStrLen);
@ -1435,7 +1418,7 @@ nsHTMLEditRules::WillDeleteSelection(nsISelection *aSelection,
res = mHTMLEditor->GetPriorHTMLNode(startNode, address_of(priorNode));
if (NS_FAILED(res)) return res;
// are they in same block?
if (mHTMLEditor->HasSameBlockNodeParent(startNode, priorNode))
if (priorNode && mHTMLEditor->HasSameBlockNodeParent(startNode, priorNode))
{
// are they same type?
if (mHTMLEditor->IsTextNode(priorNode))
@ -1546,7 +1529,7 @@ nsHTMLEditRules::WillDeleteSelection(nsISelection *aSelection,
res = mHTMLEditor->GetNextHTMLNode(startNode, address_of(nextNode));
if (NS_FAILED(res)) return res;
// are they in same block?
if (mHTMLEditor->HasSameBlockNodeParent(startNode, nextNode))
if (nextNode && mHTMLEditor->HasSameBlockNodeParent(startNode, nextNode))
{
// are they same type?
if ( mHTMLEditor->IsTextNode(nextNode) )
@ -1703,7 +1686,7 @@ nsHTMLEditRules::WillDeleteSelection(nsISelection *aSelection,
{
nsCOMPtr<nsIDOMNode> brNode;
res = mHTMLEditor->GetPriorHTMLNode(nodeToDelete, address_of(brNode));
if (nsTextEditUtils::IsBreak(brNode))
if (brNode && nsTextEditUtils::IsBreak(brNode))
{
// is brNode also a descendant of same block?
nsCOMPtr<nsIDOMNode> block, brBlock;
@ -5273,6 +5256,33 @@ nsHTMLEditRules::RemoveEmptyNodes()
PRBool bIsEmptyNode;
res = mHTMLEditor->IsEmptyNode(node, &bIsEmptyNode, PR_FALSE, PR_TRUE);
if (NS_FAILED(res)) return res;
// only consider certain nodes to be empty for purposes of removal
if (!(
nsTextEditUtils::NodeIsType(node, NS_LITERAL_STRING("b")) ||
nsTextEditUtils::NodeIsType(node, NS_LITERAL_STRING("i")) ||
nsTextEditUtils::NodeIsType(node, NS_LITERAL_STRING("u")) ||
nsTextEditUtils::NodeIsType(node, NS_LITERAL_STRING("tt")) ||
nsTextEditUtils::NodeIsType(node, NS_LITERAL_STRING("s")) ||
nsTextEditUtils::NodeIsType(node, NS_LITERAL_STRING("strike")) ||
nsTextEditUtils::NodeIsType(node, NS_LITERAL_STRING("big")) ||
nsTextEditUtils::NodeIsType(node, NS_LITERAL_STRING("small")) ||
nsTextEditUtils::NodeIsType(node, NS_LITERAL_STRING("blink")) ||
nsTextEditUtils::NodeIsType(node, NS_LITERAL_STRING("sub")) ||
nsTextEditUtils::NodeIsType(node, NS_LITERAL_STRING("sup")) ||
nsTextEditUtils::NodeIsType(node, NS_LITERAL_STRING("font")) ||
nsHTMLEditUtils::IsList(node) ||
nsHTMLEditUtils::IsParagraph(node) ||
nsHTMLEditUtils::IsHeader(node) ||
nsHTMLEditUtils::IsListItem(node) ||
nsHTMLEditUtils::IsBlockquote(node)||
nsHTMLEditUtils::IsDiv(node) ||
nsHTMLEditUtils::IsPre(node) ||
nsHTMLEditUtils::IsAddress(node) ) )
{
bIsEmptyNode = PR_FALSE;
}
if (bIsEmptyNode && !nsTextEditUtils::IsBody(node))
{
if (nsHTMLEditUtils::IsParagraph(node) ||

View File

@ -603,6 +603,14 @@ nsHTMLEditor::NodeIsBlock(nsIDOMNode *aNode, PRBool *aIsBlock)
return NodeIsBlockStatic(aNode, aIsBlock);
}
PRBool
nsHTMLEditor::IsBlockNode(nsIDOMNode *aNode)
{
PRBool isBlock;
NodeIsBlockStatic(aNode, &isBlock);
return isBlock;
}
// Non-static version for the nsIEditor interface and JavaScript
NS_IMETHODIMP
nsHTMLEditor::SetDocumentTitle(const nsAReadableString &aTitle)
@ -4451,7 +4459,6 @@ nsHTMLEditor::IsEmptyNode( nsIDOMNode *aNode,
// want to treat them as such. Also, don't call ListItems or table
// cells empty if caller desires.
if (!IsContainer(aNode) || nsHTMLEditUtils::IsAnchor(aNode) ||
nsHTMLEditUtils::IsTextarea(aNode) || nsHTMLEditUtils::IsMap(aNode) ||
(aListOrCellNotEmpty && nsHTMLEditUtils::IsListItem(aNode)) ||
(aListOrCellNotEmpty && nsHTMLEditUtils::IsTableCell(aNode)) )
{
@ -4459,6 +4466,15 @@ nsHTMLEditor::IsEmptyNode( nsIDOMNode *aNode,
return NS_OK;
}
// are we checking a block node?
PRBool isBlock = IsBlockNode(aNode);
// if so, we allow one br without violating emptiness
PRBool seenBR = PR_FALSE;
// need this for later
PRBool isListItemOrCell =
nsHTMLEditUtils::IsListItem(aNode) || nsHTMLEditUtils::IsTableCell(aNode);
// iterate over node. if no children, or all children are either
// empty text nodes or non-editable, then node qualifies as empty
nsCOMPtr<nsIContentIterator> iter;
@ -4522,9 +4538,28 @@ nsHTMLEditor::IsEmptyNode( nsIDOMNode *aNode,
// is it the node we are iterating over?
if (node.get() == aNode) break;
// is it a moz-BR and did the caller ask us not to consider those relevant?
if (!(aMozBRDoesntCount && nsTextEditUtils::IsMozBR(node)))
if ((aMozBRDoesntCount && nsTextEditUtils::IsMozBR(node)))
{
// do nothing
}
else if (isBlock && !seenBR && nsTextEditUtils::IsBreak(node))
{
// the first br in a block doesn't count
seenBR = PR_TRUE;
}
else
{
// is it an empty node of some sort?
// note: list items or table cells are not considered empty
// if they contain other lists or tables
if (isListItemOrCell)
{
if (nsHTMLEditUtils::IsList(node) || nsHTMLEditUtils::IsTable(node))
{
*outIsEmptyNode = PR_FALSE;
break;
}
}
PRBool isEmptyNode;
res = IsEmptyNode(node, &isEmptyNode, aMozBRDoesntCount, aListOrCellNotEmpty);
if (NS_FAILED(res)) return res;

View File

@ -383,6 +383,8 @@ public:
PRBool aMozBRDoesntCount = PR_FALSE,
PRBool aListOrCellNotEmpty = PR_FALSE,
PRBool aSafeToAskFrames = PR_FALSE);
PRBool IsBlockNode(nsIDOMNode *aNode);
protected:

View File

@ -486,7 +486,8 @@ nsresult nsHTMLEditor::SplitStyleAbovePoint(nsCOMPtr<nsIDOMNode> *aNode,
// split any matching style nodes above the node/offset
nsCOMPtr<nsIDOMNode> parent, tmp = *aNode;
PRInt32 offset;
while (tmp && !nsTextEditUtils::IsBody(tmp))
while (tmp && !IsBlockNode(tmp))
{
if ( (aProperty && NodeIsType(tmp, aProperty)) || // node is the correct inline prop
(aProperty == nsIEditProperty::href && nsHTMLEditUtils::IsLink(tmp)) || // node is href - test if really <a href=...
@ -509,9 +510,7 @@ PRBool nsHTMLEditor::NodeIsProperty(nsIDOMNode *aNode)
if (!aNode) return PR_FALSE;
if (!IsContainer(aNode)) return PR_FALSE;
if (!IsEditable(aNode)) return PR_FALSE;
PRBool isBlock (PR_FALSE);
NodeIsBlock(aNode, &isBlock);
if (isBlock) return PR_FALSE;
if (IsBlockNode(aNode)) return PR_FALSE;
if (NodeIsType(aNode, nsIEditProperty::a)) return PR_FALSE;
return PR_TRUE;
}

View File

@ -3494,7 +3494,8 @@ nsEditor::IsEditable(nsIDOMNode *aNode)
if (!shell) return PR_FALSE;
if (IsMozEditorBogusNode(aNode)) return PR_FALSE;
/* THIS DOESN'T WORK!
// it's not the bogus node, so see if it is an irrelevant text node
if (PR_TRUE==IsTextNode(aNode))
{
@ -3521,7 +3522,7 @@ nsEditor::IsEditable(nsIDOMNode *aNode)
return PR_FALSE;
}
}
*/
// we got this far, so see if it has a frame. If so, we'll edit it.
nsIFrame *resultFrame;
nsCOMPtr<nsIContent>content;

View File

@ -186,6 +186,8 @@ nsresult nsHTMLEditor::InsertHTMLWithCharsetAndContext(const nsAReadableString &
{
if (!mRules) return NS_ERROR_NOT_INITIALIZED;
/* all this is unneeded: parser handles this for us
// First, make sure there are no return chars in the document.
// Bad things happen if you insert returns (instead of dom newlines, \n)
// into an editor document.
@ -198,6 +200,7 @@ nsresult nsHTMLEditor::InsertHTMLWithCharsetAndContext(const nsAReadableString &
// Mac linebreaks: Map any remaining CR to LF:
inputString.ReplaceSubstring(NS_ConvertASCIItoUCS2("\r"),
NS_ConvertASCIItoUCS2("\n"));
*/
// force IME commit; set up rules sniffing and batching
ForceCompositionEnd();
@ -223,7 +226,7 @@ nsresult nsHTMLEditor::InsertHTMLWithCharsetAndContext(const nsAReadableString &
// create a dom document fragment that represents the structure to paste
nsCOMPtr<nsIDOMNode> fragmentAsNode;
PRInt32 rangeStartHint, rangeEndHint;
res = CreateDOMFragmentFromPaste(nsrange, inputString, aContextStr, aInfoStr,
res = CreateDOMFragmentFromPaste(nsrange, aInputString, aContextStr, aInfoStr,
address_of(fragmentAsNode),
&rangeStartHint, &rangeEndHint);
NS_ENSURE_SUCCESS(res, res);

View File

@ -883,15 +883,16 @@ nsHTMLEditRules::WillInsert(nsISelection *aSelection, PRBool *aCancel)
else block1 = mHTMLEditor->GetBlockNodeParent(selNode);
block2 = mHTMLEditor->GetBlockNodeParent(priorNode);
if (block1 != block2) return NS_OK;
// if we are here then the selection is right after a mozBR
// that is in the same block as the selection. We need to move
// the selection start to be before the mozBR.
res = nsEditor::GetNodeLocation(priorNode, address_of(selNode), &selOffset);
if (NS_FAILED(res)) return res;
res = aSelection->Collapse(selNode,selOffset);
if (NS_FAILED(res)) return res;
if (block1 == block2)
{
// if we are here then the selection is right after a mozBR
// that is in the same block as the selection. We need to move
// the selection start to be before the mozBR.
res = nsEditor::GetNodeLocation(priorNode, address_of(selNode), &selOffset);
if (NS_FAILED(res)) return res;
res = aSelection->Collapse(selNode,selOffset);
if (NS_FAILED(res)) return res;
}
}
// we need to get the doc
@ -901,8 +902,7 @@ nsHTMLEditRules::WillInsert(nsISelection *aSelection, PRBool *aCancel)
if (!doc) return NS_ERROR_NULL_POINTER;
// for every property that is set, insert a new inline style node
res = CreateStyleForInsertText(aSelection, doc);
return res;
return CreateStyleForInsertText(aSelection, doc);
}
nsresult
@ -998,7 +998,7 @@ nsHTMLEditRules::WillInsertText(PRInt32 aAction,
// dont spaz my selection in subtransactions
nsAutoTxnsConserveSelection dontSpazMySelection(mHTMLEditor);
nsSubsumeStr subStr;
const nsPromiseFlatString &tString = PromiseFlatString(*inString);////MJUDGE SCC NEED HELP
nsAutoString tString(*inString);
const PRUnichar *unicodeBuf = tString.get();
nsCOMPtr<nsIDOMNode> unused;
PRInt32 pos = 0;
@ -1008,21 +1008,13 @@ nsHTMLEditRules::WillInsertText(PRInt32 aAction,
// it is to search for both tabs and newlines.
if (isPRE)
{
nsAutoString newlineChar(NS_LITERAL_STRING("\n"));
char newlineChar = '\n';
while (unicodeBuf && (pos != -1) && (pos < (PRInt32)(*inString).Length()))
{
PRInt32 oldPos = pos;
PRInt32 subStrLen;
pos = -1;
nsReadingIterator<PRUnichar> beginFindIter, endFindIter, beginIter;
inString->BeginReading(beginIter);
beginFindIter = beginIter;
inString->EndReading(endFindIter);
beginFindIter.advance(oldPos);
if (FindInReadable(newlineChar,beginFindIter,endFindIter))
{
pos = Distance(beginIter,beginFindIter);
}
pos = tString.FindChar(newlineChar, PR_FALSE, oldPos);
if (pos != -1)
{
subStrLen = pos - oldPos;
@ -1032,8 +1024,8 @@ nsHTMLEditRules::WillInsertText(PRInt32 aAction,
}
else
{
subStrLen = (*inString).Length() - oldPos;
pos = (*inString).Length();
subStrLen = tString.Length() - oldPos;
pos = tString.Length();
}
subStr.Subsume((PRUnichar*)&unicodeBuf[oldPos], PR_FALSE, subStrLen);
@ -1053,22 +1045,13 @@ nsHTMLEditRules::WillInsertText(PRInt32 aAction,
}
else
{
nsAutoString specialChars;
specialChars = NS_LITERAL_STRING("\t\n");
char specialChars[] = {'\t','\n',0};
nsAutoString tabString; tabString.AssignWithConversion(" ");
while (unicodeBuf && (pos != -1) && (pos < (PRInt32)(*inString).Length()))
while (unicodeBuf && (pos != -1) && (pos < (PRInt32)inString->Length()))
{
PRInt32 oldPos = pos;
PRInt32 subStrLen;
nsReadingIterator<PRUnichar> beginFindIter,endFindIter;
(*inString).BeginReading(beginFindIter);
beginFindIter.advance(oldPos);
(*inString).EndReading(endFindIter);
nsReadingIterator<PRUnichar> distanceIter;
(*inString).BeginReading(distanceIter);
pos = -1;
if (FindInReadable((const nsAString &)specialChars,beginFindIter,endFindIter))
pos = Distance(distanceIter,beginFindIter);
pos = tString.FindCharInSet(specialChars, oldPos);
if (pos != -1)
{
@ -1079,8 +1062,8 @@ nsHTMLEditRules::WillInsertText(PRInt32 aAction,
}
else
{
subStrLen = (*inString).Length() - oldPos;
pos = (*inString).Length();
subStrLen = tString.Length() - oldPos;
pos = tString.Length();
}
subStr.Subsume((PRUnichar*)&unicodeBuf[oldPos], PR_FALSE, subStrLen);
@ -1435,7 +1418,7 @@ nsHTMLEditRules::WillDeleteSelection(nsISelection *aSelection,
res = mHTMLEditor->GetPriorHTMLNode(startNode, address_of(priorNode));
if (NS_FAILED(res)) return res;
// are they in same block?
if (mHTMLEditor->HasSameBlockNodeParent(startNode, priorNode))
if (priorNode && mHTMLEditor->HasSameBlockNodeParent(startNode, priorNode))
{
// are they same type?
if (mHTMLEditor->IsTextNode(priorNode))
@ -1546,7 +1529,7 @@ nsHTMLEditRules::WillDeleteSelection(nsISelection *aSelection,
res = mHTMLEditor->GetNextHTMLNode(startNode, address_of(nextNode));
if (NS_FAILED(res)) return res;
// are they in same block?
if (mHTMLEditor->HasSameBlockNodeParent(startNode, nextNode))
if (nextNode && mHTMLEditor->HasSameBlockNodeParent(startNode, nextNode))
{
// are they same type?
if ( mHTMLEditor->IsTextNode(nextNode) )
@ -1703,7 +1686,7 @@ nsHTMLEditRules::WillDeleteSelection(nsISelection *aSelection,
{
nsCOMPtr<nsIDOMNode> brNode;
res = mHTMLEditor->GetPriorHTMLNode(nodeToDelete, address_of(brNode));
if (nsTextEditUtils::IsBreak(brNode))
if (brNode && nsTextEditUtils::IsBreak(brNode))
{
// is brNode also a descendant of same block?
nsCOMPtr<nsIDOMNode> block, brBlock;
@ -5273,6 +5256,33 @@ nsHTMLEditRules::RemoveEmptyNodes()
PRBool bIsEmptyNode;
res = mHTMLEditor->IsEmptyNode(node, &bIsEmptyNode, PR_FALSE, PR_TRUE);
if (NS_FAILED(res)) return res;
// only consider certain nodes to be empty for purposes of removal
if (!(
nsTextEditUtils::NodeIsType(node, NS_LITERAL_STRING("b")) ||
nsTextEditUtils::NodeIsType(node, NS_LITERAL_STRING("i")) ||
nsTextEditUtils::NodeIsType(node, NS_LITERAL_STRING("u")) ||
nsTextEditUtils::NodeIsType(node, NS_LITERAL_STRING("tt")) ||
nsTextEditUtils::NodeIsType(node, NS_LITERAL_STRING("s")) ||
nsTextEditUtils::NodeIsType(node, NS_LITERAL_STRING("strike")) ||
nsTextEditUtils::NodeIsType(node, NS_LITERAL_STRING("big")) ||
nsTextEditUtils::NodeIsType(node, NS_LITERAL_STRING("small")) ||
nsTextEditUtils::NodeIsType(node, NS_LITERAL_STRING("blink")) ||
nsTextEditUtils::NodeIsType(node, NS_LITERAL_STRING("sub")) ||
nsTextEditUtils::NodeIsType(node, NS_LITERAL_STRING("sup")) ||
nsTextEditUtils::NodeIsType(node, NS_LITERAL_STRING("font")) ||
nsHTMLEditUtils::IsList(node) ||
nsHTMLEditUtils::IsParagraph(node) ||
nsHTMLEditUtils::IsHeader(node) ||
nsHTMLEditUtils::IsListItem(node) ||
nsHTMLEditUtils::IsBlockquote(node)||
nsHTMLEditUtils::IsDiv(node) ||
nsHTMLEditUtils::IsPre(node) ||
nsHTMLEditUtils::IsAddress(node) ) )
{
bIsEmptyNode = PR_FALSE;
}
if (bIsEmptyNode && !nsTextEditUtils::IsBody(node))
{
if (nsHTMLEditUtils::IsParagraph(node) ||

View File

@ -603,6 +603,14 @@ nsHTMLEditor::NodeIsBlock(nsIDOMNode *aNode, PRBool *aIsBlock)
return NodeIsBlockStatic(aNode, aIsBlock);
}
PRBool
nsHTMLEditor::IsBlockNode(nsIDOMNode *aNode)
{
PRBool isBlock;
NodeIsBlockStatic(aNode, &isBlock);
return isBlock;
}
// Non-static version for the nsIEditor interface and JavaScript
NS_IMETHODIMP
nsHTMLEditor::SetDocumentTitle(const nsAReadableString &aTitle)
@ -4451,7 +4459,6 @@ nsHTMLEditor::IsEmptyNode( nsIDOMNode *aNode,
// want to treat them as such. Also, don't call ListItems or table
// cells empty if caller desires.
if (!IsContainer(aNode) || nsHTMLEditUtils::IsAnchor(aNode) ||
nsHTMLEditUtils::IsTextarea(aNode) || nsHTMLEditUtils::IsMap(aNode) ||
(aListOrCellNotEmpty && nsHTMLEditUtils::IsListItem(aNode)) ||
(aListOrCellNotEmpty && nsHTMLEditUtils::IsTableCell(aNode)) )
{
@ -4459,6 +4466,15 @@ nsHTMLEditor::IsEmptyNode( nsIDOMNode *aNode,
return NS_OK;
}
// are we checking a block node?
PRBool isBlock = IsBlockNode(aNode);
// if so, we allow one br without violating emptiness
PRBool seenBR = PR_FALSE;
// need this for later
PRBool isListItemOrCell =
nsHTMLEditUtils::IsListItem(aNode) || nsHTMLEditUtils::IsTableCell(aNode);
// iterate over node. if no children, or all children are either
// empty text nodes or non-editable, then node qualifies as empty
nsCOMPtr<nsIContentIterator> iter;
@ -4522,9 +4538,28 @@ nsHTMLEditor::IsEmptyNode( nsIDOMNode *aNode,
// is it the node we are iterating over?
if (node.get() == aNode) break;
// is it a moz-BR and did the caller ask us not to consider those relevant?
if (!(aMozBRDoesntCount && nsTextEditUtils::IsMozBR(node)))
if ((aMozBRDoesntCount && nsTextEditUtils::IsMozBR(node)))
{
// do nothing
}
else if (isBlock && !seenBR && nsTextEditUtils::IsBreak(node))
{
// the first br in a block doesn't count
seenBR = PR_TRUE;
}
else
{
// is it an empty node of some sort?
// note: list items or table cells are not considered empty
// if they contain other lists or tables
if (isListItemOrCell)
{
if (nsHTMLEditUtils::IsList(node) || nsHTMLEditUtils::IsTable(node))
{
*outIsEmptyNode = PR_FALSE;
break;
}
}
PRBool isEmptyNode;
res = IsEmptyNode(node, &isEmptyNode, aMozBRDoesntCount, aListOrCellNotEmpty);
if (NS_FAILED(res)) return res;

View File

@ -383,6 +383,8 @@ public:
PRBool aMozBRDoesntCount = PR_FALSE,
PRBool aListOrCellNotEmpty = PR_FALSE,
PRBool aSafeToAskFrames = PR_FALSE);
PRBool IsBlockNode(nsIDOMNode *aNode);
protected:

View File

@ -486,7 +486,8 @@ nsresult nsHTMLEditor::SplitStyleAbovePoint(nsCOMPtr<nsIDOMNode> *aNode,
// split any matching style nodes above the node/offset
nsCOMPtr<nsIDOMNode> parent, tmp = *aNode;
PRInt32 offset;
while (tmp && !nsTextEditUtils::IsBody(tmp))
while (tmp && !IsBlockNode(tmp))
{
if ( (aProperty && NodeIsType(tmp, aProperty)) || // node is the correct inline prop
(aProperty == nsIEditProperty::href && nsHTMLEditUtils::IsLink(tmp)) || // node is href - test if really <a href=...
@ -509,9 +510,7 @@ PRBool nsHTMLEditor::NodeIsProperty(nsIDOMNode *aNode)
if (!aNode) return PR_FALSE;
if (!IsContainer(aNode)) return PR_FALSE;
if (!IsEditable(aNode)) return PR_FALSE;
PRBool isBlock (PR_FALSE);
NodeIsBlock(aNode, &isBlock);
if (isBlock) return PR_FALSE;
if (IsBlockNode(aNode)) return PR_FALSE;
if (NodeIsType(aNode, nsIEditProperty::a)) return PR_FALSE;
return PR_TRUE;
}