mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-30 00:01:50 +00:00
fixes for bugs:
This commit is contained in:
parent
5a825e5b27
commit
edc5638e7c
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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) ||
|
||||
|
@ -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;
|
||||
|
@ -383,6 +383,8 @@ public:
|
||||
PRBool aMozBRDoesntCount = PR_FALSE,
|
||||
PRBool aListOrCellNotEmpty = PR_FALSE,
|
||||
PRBool aSafeToAskFrames = PR_FALSE);
|
||||
|
||||
PRBool IsBlockNode(nsIDOMNode *aNode);
|
||||
|
||||
protected:
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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) ||
|
||||
|
@ -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;
|
||||
|
@ -383,6 +383,8 @@ public:
|
||||
PRBool aMozBRDoesntCount = PR_FALSE,
|
||||
PRBool aListOrCellNotEmpty = PR_FALSE,
|
||||
PRBool aSafeToAskFrames = PR_FALSE);
|
||||
|
||||
PRBool IsBlockNode(nsIDOMNode *aNode);
|
||||
|
||||
protected:
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user