зеркало из https://github.com/mozilla/gecko-dev.git
Bug 768748 part 1 - Clean up nsHTMLEditor::IsNext/PrevCharWhitespace; r=ehsan
This commit is contained in:
Родитель
4e1178db04
Коммит
37d4deed65
|
@ -3906,24 +3906,6 @@ nsEditor::AreNodesSameType(nsIContent* aNode1, nsIContent* aNode2)
|
|||
}
|
||||
|
||||
|
||||
// IsTextOrElementNode: true if node of dom type element or text
|
||||
//
|
||||
bool
|
||||
nsEditor::IsTextOrElementNode(nsIDOMNode *aNode)
|
||||
{
|
||||
if (!aNode)
|
||||
{
|
||||
NS_NOTREACHED("null node passed to IsTextOrElementNode()");
|
||||
return false;
|
||||
}
|
||||
|
||||
PRUint16 nodeType;
|
||||
aNode->GetNodeType(&nodeType);
|
||||
return ((nodeType == nsIDOMNode::ELEMENT_NODE) || (nodeType == nsIDOMNode::TEXT_NODE));
|
||||
}
|
||||
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// IsTextNode: true if node of dom type text
|
||||
//
|
||||
|
|
|
@ -590,7 +590,6 @@ public:
|
|||
bool NodesSameType(nsIDOMNode *aNode1, nsIDOMNode *aNode2);
|
||||
virtual bool AreNodesSameType(nsIContent* aNode1, nsIContent* aNode2);
|
||||
|
||||
static bool IsTextOrElementNode(nsIDOMNode *aNode);
|
||||
static bool IsTextNode(nsIDOMNode *aNode);
|
||||
static bool IsTextNode(nsINode *aNode);
|
||||
|
||||
|
|
|
@ -5290,7 +5290,7 @@ nsHTMLEditRules::GetPromotedPoint(RulesEndpoint aWhere, nsIDOMNode *aNode,
|
|||
actionID == nsEditor::kOpDeleteText)
|
||||
{
|
||||
bool isSpace, isNBSP;
|
||||
nsCOMPtr<nsIDOMNode> temp;
|
||||
nsCOMPtr<nsIContent> temp;
|
||||
// for text actions, we want to look backwards (or forwards, as appropriate)
|
||||
// for additional whitespace or nbsp's. We may have to act on these later even though
|
||||
// they are outside of the initial selection. Even if they are in another node!
|
||||
|
@ -5299,10 +5299,12 @@ nsHTMLEditRules::GetPromotedPoint(RulesEndpoint aWhere, nsIDOMNode *aNode,
|
|||
do
|
||||
{
|
||||
PRInt32 prevOffset;
|
||||
mHTMLEditor->IsPrevCharWhitespace(node, offset, &isSpace, &isNBSP,
|
||||
address_of(temp), &prevOffset);
|
||||
nsCOMPtr<nsIContent> content = do_QueryInterface(node);
|
||||
mHTMLEditor->IsPrevCharInNodeWhitespace(content, offset, &isSpace,
|
||||
&isNBSP, getter_AddRefs(temp),
|
||||
&prevOffset);
|
||||
if (isSpace || isNBSP) {
|
||||
node = temp;
|
||||
node = temp->AsDOMNode();
|
||||
offset = prevOffset;
|
||||
} else {
|
||||
break;
|
||||
|
@ -5317,10 +5319,12 @@ nsHTMLEditRules::GetPromotedPoint(RulesEndpoint aWhere, nsIDOMNode *aNode,
|
|||
do
|
||||
{
|
||||
PRInt32 nextOffset;
|
||||
mHTMLEditor->IsNextCharWhitespace(node, offset, &isSpace, &isNBSP,
|
||||
address_of(temp), &nextOffset);
|
||||
nsCOMPtr<nsIContent> content = do_QueryInterface(node);
|
||||
mHTMLEditor->IsNextCharInNodeWhitespace(content, offset, &isSpace,
|
||||
&isNBSP, getter_AddRefs(temp),
|
||||
&nextOffset);
|
||||
if (isSpace || isNBSP) {
|
||||
node = temp;
|
||||
node = temp->AsDOMNode();
|
||||
offset = nextOffset;
|
||||
} else {
|
||||
break;
|
||||
|
|
|
@ -64,6 +64,7 @@
|
|||
#include "nsIFrame.h"
|
||||
#include "nsIParserService.h"
|
||||
#include "mozilla/dom/Element.h"
|
||||
#include "nsTextFragment.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::widget;
|
||||
|
@ -847,195 +848,70 @@ nsHTMLEditor::GetBlockNodeParent(nsIDOMNode *aNode)
|
|||
return p.forget();
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// NextNodeInBlock: gets the next/prev node in the block, if any. Next node
|
||||
// must be an element or text node, others are ignored
|
||||
already_AddRefed<nsIDOMNode>
|
||||
nsHTMLEditor::NextNodeInBlock(nsIDOMNode *aNode, IterDirection aDir)
|
||||
{
|
||||
NS_ENSURE_TRUE(aNode, nsnull);
|
||||
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIContentIterator> iter =
|
||||
do_CreateInstance("@mozilla.org/content/post-content-iterator;1", &rv);
|
||||
NS_ENSURE_SUCCESS(rv, nsnull);
|
||||
|
||||
// much gnashing of teeth as we twit back and forth between content and domnode types
|
||||
nsCOMPtr<nsIContent> content = do_QueryInterface(aNode);
|
||||
nsCOMPtr<nsIDOMNode> blockParent;
|
||||
bool isBlock;
|
||||
if (NS_SUCCEEDED(NodeIsBlockStatic(aNode, &isBlock)) && isBlock) {
|
||||
blockParent = aNode;
|
||||
} else {
|
||||
blockParent = GetBlockNodeParent(aNode);
|
||||
}
|
||||
NS_ENSURE_TRUE(blockParent, nsnull);
|
||||
nsCOMPtr<nsIContent> blockContent = do_QueryInterface(blockParent);
|
||||
NS_ENSURE_TRUE(blockContent, nsnull);
|
||||
|
||||
if (NS_FAILED(iter->Init(blockContent))) {
|
||||
return nsnull;
|
||||
}
|
||||
if (NS_FAILED(iter->PositionAt(content))) {
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
while (!iter->IsDone()) {
|
||||
// ignore nodes that aren't elements or text, or that are the
|
||||
// block parent
|
||||
nsCOMPtr<nsIDOMNode> node = do_QueryInterface(iter->GetCurrentNode());
|
||||
if (node && IsTextOrElementNode(node) && node != blockParent &&
|
||||
node != aNode)
|
||||
return node.forget();
|
||||
|
||||
if (aDir == kIterForward)
|
||||
iter->Next();
|
||||
else
|
||||
iter->Prev();
|
||||
}
|
||||
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
static const PRUnichar nbsp = 160;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// IsNextCharWhitespace: checks the adjacent content in the same block
|
||||
// to see if following selection is whitespace or nbsp
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// IsNextCharInNodeWhitespace: checks the adjacent content in the same node to
|
||||
// see if following selection is whitespace or nbsp
|
||||
void
|
||||
nsHTMLEditor::IsNextCharWhitespace(nsIDOMNode *aParentNode,
|
||||
PRInt32 aOffset,
|
||||
bool *outIsSpace,
|
||||
bool *outIsNBSP,
|
||||
nsCOMPtr<nsIDOMNode> *outNode,
|
||||
PRInt32 *outOffset)
|
||||
nsHTMLEditor::IsNextCharInNodeWhitespace(nsIContent* aContent,
|
||||
PRInt32 aOffset,
|
||||
bool* outIsSpace,
|
||||
bool* outIsNBSP,
|
||||
nsIContent** outNode,
|
||||
PRInt32* outOffset)
|
||||
{
|
||||
MOZ_ASSERT(outIsSpace && outIsNBSP);
|
||||
MOZ_ASSERT(aContent && outIsSpace && outIsNBSP);
|
||||
MOZ_ASSERT((outNode && outOffset) || (!outNode && !outOffset));
|
||||
*outIsSpace = false;
|
||||
*outIsNBSP = false;
|
||||
if (outNode) *outNode = nsnull;
|
||||
if (outOffset) *outOffset = -1;
|
||||
|
||||
nsAutoString tempString;
|
||||
PRUint32 strLength;
|
||||
nsCOMPtr<nsIDOMText> textNode = do_QueryInterface(aParentNode);
|
||||
if (textNode)
|
||||
{
|
||||
textNode->GetLength(&strLength);
|
||||
if ((PRUint32)aOffset < strLength)
|
||||
{
|
||||
// easy case: next char is in same node
|
||||
textNode->SubstringData(aOffset,aOffset+1,tempString);
|
||||
*outIsSpace = nsCRT::IsAsciiSpace(tempString.First());
|
||||
*outIsNBSP = (tempString.First() == nbsp);
|
||||
if (outNode) *outNode = do_QueryInterface(aParentNode);
|
||||
if (outOffset) *outOffset = aOffset+1; // yes, this is _past_ the character;
|
||||
return;
|
||||
}
|
||||
if (outNode && outOffset) {
|
||||
*outNode = nsnull;
|
||||
*outOffset = -1;
|
||||
}
|
||||
|
||||
// harder case: next char in next node.
|
||||
nsCOMPtr<nsIDOMNode> node = NextNodeInBlock(aParentNode, kIterForward);
|
||||
nsCOMPtr<nsIDOMNode> tmp;
|
||||
while (node)
|
||||
{
|
||||
bool isBlock (false);
|
||||
NodeIsBlock(node, &isBlock);
|
||||
if (isBlock) // skip over bold, italic, link, ect nodes
|
||||
{
|
||||
if (IsTextNode(node) && IsEditable(node))
|
||||
{
|
||||
textNode = do_QueryInterface(node);
|
||||
textNode->GetLength(&strLength);
|
||||
if (strLength)
|
||||
{
|
||||
textNode->SubstringData(0,1,tempString);
|
||||
*outIsSpace = nsCRT::IsAsciiSpace(tempString.First());
|
||||
*outIsNBSP = (tempString.First() == nbsp);
|
||||
if (outNode) *outNode = do_QueryInterface(node);
|
||||
if (outOffset) *outOffset = 1; // yes, this is _past_ the character;
|
||||
return;
|
||||
}
|
||||
// else it's an empty text node, or not editable; skip it.
|
||||
}
|
||||
else // node is an image or some other thingy that doesn't count as whitespace
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if (aContent->IsNodeOfType(nsINode::eTEXT) &&
|
||||
(PRUint32)aOffset < aContent->Length()) {
|
||||
PRUnichar ch = aContent->GetText()->CharAt(aOffset);
|
||||
*outIsSpace = nsCRT::IsAsciiSpace(ch);
|
||||
*outIsNBSP = (ch == nbsp);
|
||||
if (outNode && outOffset) {
|
||||
NS_IF_ADDREF(*outNode = aContent);
|
||||
// yes, this is _past_ the character
|
||||
*outOffset = aOffset + 1;
|
||||
}
|
||||
tmp = node;
|
||||
node = NextNodeInBlock(tmp, kIterForward);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// IsPrevCharWhitespace: checks the adjacent content in the same block
|
||||
// to see if following selection is whitespace
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// IsPrevCharInNodeWhitespace: checks the adjacent content in the same node to
|
||||
// see if following selection is whitespace
|
||||
void
|
||||
nsHTMLEditor::IsPrevCharWhitespace(nsIDOMNode *aParentNode,
|
||||
PRInt32 aOffset,
|
||||
bool *outIsSpace,
|
||||
bool *outIsNBSP,
|
||||
nsCOMPtr<nsIDOMNode> *outNode,
|
||||
PRInt32 *outOffset)
|
||||
nsHTMLEditor::IsPrevCharInNodeWhitespace(nsIContent* aContent,
|
||||
PRInt32 aOffset,
|
||||
bool* outIsSpace,
|
||||
bool* outIsNBSP,
|
||||
nsIContent** outNode,
|
||||
PRInt32* outOffset)
|
||||
{
|
||||
MOZ_ASSERT(outIsSpace && outIsNBSP);
|
||||
MOZ_ASSERT(aContent && outIsSpace && outIsNBSP);
|
||||
MOZ_ASSERT((outNode && outOffset) || (!outNode && !outOffset));
|
||||
*outIsSpace = false;
|
||||
*outIsNBSP = false;
|
||||
if (outNode) *outNode = nsnull;
|
||||
if (outOffset) *outOffset = -1;
|
||||
|
||||
nsAutoString tempString;
|
||||
PRUint32 strLength;
|
||||
nsCOMPtr<nsIDOMText> textNode = do_QueryInterface(aParentNode);
|
||||
if (textNode)
|
||||
{
|
||||
if (aOffset > 0)
|
||||
{
|
||||
// easy case: prev char is in same node
|
||||
textNode->SubstringData(aOffset-1,aOffset,tempString);
|
||||
*outIsSpace = nsCRT::IsAsciiSpace(tempString.First());
|
||||
*outIsNBSP = (tempString.First() == nbsp);
|
||||
if (outNode) *outNode = do_QueryInterface(aParentNode);
|
||||
if (outOffset) *outOffset = aOffset-1;
|
||||
return;
|
||||
}
|
||||
if (outNode && outOffset) {
|
||||
*outNode = nsnull;
|
||||
*outOffset = -1;
|
||||
}
|
||||
|
||||
// harder case: prev char in next node
|
||||
nsCOMPtr<nsIDOMNode> node = NextNodeInBlock(aParentNode, kIterBackward);
|
||||
nsCOMPtr<nsIDOMNode> tmp;
|
||||
while (node)
|
||||
{
|
||||
bool isBlock (false);
|
||||
NodeIsBlock(node, &isBlock);
|
||||
if (isBlock) // skip over bold, italic, link, ect nodes
|
||||
{
|
||||
if (IsTextNode(node) && IsEditable(node))
|
||||
{
|
||||
textNode = do_QueryInterface(node);
|
||||
textNode->GetLength(&strLength);
|
||||
if (strLength)
|
||||
{
|
||||
// you could use nsIContent::TextIsOnlyWhitespace here
|
||||
textNode->SubstringData(strLength-1,strLength,tempString);
|
||||
*outIsSpace = nsCRT::IsAsciiSpace(tempString.First());
|
||||
*outIsNBSP = (tempString.First() == nbsp);
|
||||
if (outNode) *outNode = do_QueryInterface(aParentNode);
|
||||
if (outOffset) *outOffset = strLength-1;
|
||||
return;
|
||||
}
|
||||
// else it's an empty text node, or not editable; skip it.
|
||||
}
|
||||
else // node is an image or some other thingy that doesn't count as whitespace
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if (aContent->IsNodeOfType(nsINode::eTEXT) && aOffset > 0) {
|
||||
PRUnichar ch = aContent->GetText()->CharAt(aOffset - 1);
|
||||
*outIsSpace = nsCRT::IsAsciiSpace(ch);
|
||||
*outIsNBSP = (ch == nbsp);
|
||||
if (outNode && outOffset) {
|
||||
NS_IF_ADDREF(*outNode = aContent);
|
||||
*outOffset = aOffset - 1;
|
||||
}
|
||||
// otherwise we found a node we want to skip, keep going
|
||||
tmp = node;
|
||||
node = NextNodeInBlock(tmp, kIterBackward);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -229,19 +229,18 @@ public:
|
|||
/* ------------ Block methods moved from nsEditor -------------- */
|
||||
static already_AddRefed<nsIDOMNode> GetBlockNodeParent(nsIDOMNode *aNode);
|
||||
|
||||
static already_AddRefed<nsIDOMNode> NextNodeInBlock(nsIDOMNode *aNode, IterDirection aDir);
|
||||
void IsNextCharWhitespace(nsIDOMNode *aParentNode,
|
||||
PRInt32 aOffset,
|
||||
bool *outIsSpace,
|
||||
bool *outIsNBSP,
|
||||
nsCOMPtr<nsIDOMNode> *outNode = 0,
|
||||
PRInt32 *outOffset = 0);
|
||||
void IsPrevCharWhitespace(nsIDOMNode *aParentNode,
|
||||
PRInt32 aOffset,
|
||||
bool *outIsSpace,
|
||||
bool *outIsNBSP,
|
||||
nsCOMPtr<nsIDOMNode> *outNode = 0,
|
||||
PRInt32 *outOffset = 0);
|
||||
void IsNextCharInNodeWhitespace(nsIContent* aContent,
|
||||
PRInt32 aOffset,
|
||||
bool* outIsSpace,
|
||||
bool* outIsNBSP,
|
||||
nsIContent** outNode = nsnull,
|
||||
PRInt32* outOffset = 0);
|
||||
void IsPrevCharInNodeWhitespace(nsIContent* aContent,
|
||||
PRInt32 aOffset,
|
||||
bool* outIsSpace,
|
||||
bool* outIsNBSP,
|
||||
nsIContent** outNode = nsnull,
|
||||
PRInt32* outOffset = 0);
|
||||
|
||||
/* ------------ Overrides of nsEditor interface methods -------------- */
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче