mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-17 07:15:46 +00:00
Bug 1406482 - Avoid using nsINode::GetChildAt() in EditorBase::InsertTextImpl(); r=masayuki
This commit is contained in:
parent
9186f2dee6
commit
1bba75e15f
@ -2391,13 +2391,14 @@ EditorBase::FindBetterInsertionPoint(nsCOMPtr<nsIDOMNode>& aNode,
|
||||
int32_t& aOffset)
|
||||
{
|
||||
nsCOMPtr<nsINode> node = do_QueryInterface(aNode);
|
||||
FindBetterInsertionPoint(node, aOffset);
|
||||
FindBetterInsertionPoint(node, aOffset, nullptr);
|
||||
aNode = do_QueryInterface(node);
|
||||
}
|
||||
|
||||
void
|
||||
EditorBase::FindBetterInsertionPoint(nsCOMPtr<nsINode>& aNode,
|
||||
int32_t& aOffset)
|
||||
int32_t& aOffset,
|
||||
nsCOMPtr<nsIContent>* aSelChild)
|
||||
{
|
||||
if (aNode->IsNodeOfType(nsINode::eTEXT)) {
|
||||
// There is no "better" insertion point.
|
||||
@ -2424,6 +2425,9 @@ EditorBase::FindBetterInsertionPoint(nsCOMPtr<nsINode>& aNode,
|
||||
node->GetFirstChild()->IsNodeOfType(nsINode::eTEXT)) {
|
||||
aNode = node->GetFirstChild();
|
||||
aOffset = 0;
|
||||
if (aSelChild) {
|
||||
*aSelChild = nullptr;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@ -2439,6 +2443,9 @@ EditorBase::FindBetterInsertionPoint(nsCOMPtr<nsINode>& aNode,
|
||||
NS_ENSURE_TRUE_VOID(node->Length() <= INT32_MAX);
|
||||
aNode = child;
|
||||
aOffset = static_cast<int32_t>(aNode->Length());
|
||||
if (aSelChild) {
|
||||
*aSelChild = nullptr;
|
||||
}
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
@ -2450,6 +2457,9 @@ EditorBase::FindBetterInsertionPoint(nsCOMPtr<nsINode>& aNode,
|
||||
NS_ENSURE_TRUE_VOID(node->Length() <= INT32_MAX);
|
||||
aNode = child;
|
||||
aOffset = static_cast<int32_t>(aNode->Length());
|
||||
if (aSelChild) {
|
||||
*aSelChild = nullptr;
|
||||
}
|
||||
return;
|
||||
}
|
||||
child = child->GetPreviousSibling();
|
||||
@ -2467,10 +2477,16 @@ EditorBase::FindBetterInsertionPoint(nsCOMPtr<nsINode>& aNode,
|
||||
NS_ENSURE_TRUE_VOID(node->Length() <= INT32_MAX);
|
||||
aNode = node->GetPreviousSibling();
|
||||
aOffset = static_cast<int32_t>(aNode->Length());
|
||||
if (aSelChild) {
|
||||
*aSelChild = nullptr;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (node->GetParentNode() && node->GetParentNode() == root) {
|
||||
if (aSelChild) {
|
||||
*aSelChild = node->AsContent();
|
||||
}
|
||||
aNode = node->GetParentNode();
|
||||
aOffset = 0;
|
||||
return;
|
||||
@ -2481,6 +2497,7 @@ EditorBase::FindBetterInsertionPoint(nsCOMPtr<nsINode>& aNode,
|
||||
nsresult
|
||||
EditorBase::InsertTextImpl(const nsAString& aStringToInsert,
|
||||
nsCOMPtr<nsINode>* aInOutNode,
|
||||
nsCOMPtr<nsIContent>* aInOutChildAtOffset,
|
||||
int32_t* aInOutOffset,
|
||||
nsIDocument* aDoc)
|
||||
{
|
||||
@ -2502,15 +2519,17 @@ EditorBase::InsertTextImpl(const nsAString& aStringToInsert,
|
||||
|
||||
nsCOMPtr<nsINode> node = *aInOutNode;
|
||||
int32_t offset = *aInOutOffset;
|
||||
nsCOMPtr<nsIContent> child = *aInOutChildAtOffset;
|
||||
|
||||
MOZ_ASSERT(node->GetChildAt(offset) == *aInOutChildAtOffset);
|
||||
|
||||
// In some cases, the node may be the anonymous div elemnt or a mozBR
|
||||
// element. Let's try to look for better insertion point in the nearest
|
||||
// text node if there is.
|
||||
FindBetterInsertionPoint(node, offset);
|
||||
FindBetterInsertionPoint(node, offset, address_of(child));
|
||||
|
||||
// If a neighboring text node already exists, use that
|
||||
if (!node->IsNodeOfType(nsINode::eTEXT)) {
|
||||
nsIContent* child = node->GetChildAt(offset);
|
||||
if (offset && child && child->GetPreviousSibling() &&
|
||||
child->GetPreviousSibling()->IsNodeOfType(nsINode::eTEXT)) {
|
||||
node = child->GetPreviousSibling();
|
||||
@ -2566,6 +2585,7 @@ EditorBase::InsertTextImpl(const nsAString& aStringToInsert,
|
||||
|
||||
*aInOutNode = node;
|
||||
*aInOutOffset = offset;
|
||||
*aInOutChildAtOffset = nullptr;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -4966,7 +4986,7 @@ EditorBase::InitializeSelection(nsIDOMEventTarget* aFocusEventTarget)
|
||||
NS_ENSURE_TRUE(firstRange, NS_ERROR_FAILURE);
|
||||
nsCOMPtr<nsINode> startNode = firstRange->GetStartContainer();
|
||||
int32_t startOffset = firstRange->StartOffset();
|
||||
FindBetterInsertionPoint(startNode, startOffset);
|
||||
FindBetterInsertionPoint(startNode, startOffset, nullptr);
|
||||
Text* textNode = startNode->GetAsText();
|
||||
MOZ_ASSERT(textNode,
|
||||
"There must be text node if mIMETextLength is larger than 0");
|
||||
|
@ -287,6 +287,7 @@ public:
|
||||
|
||||
virtual nsresult InsertTextImpl(const nsAString& aStringToInsert,
|
||||
nsCOMPtr<nsINode>* aInOutNode,
|
||||
nsCOMPtr<nsIContent>* aInOutChildAtOffset,
|
||||
int32_t* aInOutOffset,
|
||||
nsIDocument* aDoc);
|
||||
nsresult InsertTextIntoTextNodeImpl(const nsAString& aStringToInsert,
|
||||
@ -1222,11 +1223,23 @@ public:
|
||||
/**
|
||||
* FindBetterInsertionPoint() tries to look for better insertion point which
|
||||
* is typically the nearest text node and offset in it.
|
||||
*
|
||||
* @param aNode in/out param, on input set to the node to use to start the search,
|
||||
* on output set to the node found as the better insertion point.
|
||||
* @param aOffset in/out param, on input set to the offset to use to start the
|
||||
* search, on putput set to the offset found as the better insertion
|
||||
* point.
|
||||
* @param aSelChild in/out param, on input, can be set to nullptr if the caller
|
||||
* doesn't want to pass this in, or set to a pointer to an nsCOMPtr
|
||||
* pointing to the child at the input node and offset, and on output
|
||||
* the method will make it point to the child at the output node and
|
||||
* offset returned in aNode and aOffset.
|
||||
*/
|
||||
void FindBetterInsertionPoint(nsCOMPtr<nsIDOMNode>& aNode,
|
||||
int32_t& aOffset);
|
||||
void FindBetterInsertionPoint(nsCOMPtr<nsINode>& aNode,
|
||||
int32_t& aOffset);
|
||||
int32_t& aOffset,
|
||||
nsCOMPtr<nsIContent>* aSelChild);
|
||||
|
||||
/**
|
||||
* HideCaret() hides caret with nsCaret::AddForceHide() or may show carent
|
||||
|
@ -1299,6 +1299,8 @@ HTMLEditRules::WillInsertText(EditAction aAction,
|
||||
NS_ENSURE_STATE(mHTMLEditor);
|
||||
NS_ENSURE_STATE(aSelection->GetRangeAt(0));
|
||||
nsCOMPtr<nsINode> selNode = aSelection->GetRangeAt(0)->GetStartContainer();
|
||||
nsCOMPtr<nsIContent> selChild =
|
||||
aSelection->GetRangeAt(0)->GetChildAtStartOffset();
|
||||
int32_t selOffset = aSelection->GetRangeAt(0)->StartOffset();
|
||||
NS_ENSURE_STATE(selNode);
|
||||
|
||||
@ -1323,13 +1325,15 @@ HTMLEditRules::WillInsertText(EditAction aAction,
|
||||
}
|
||||
if (inString->IsEmpty()) {
|
||||
rv = mHTMLEditor->InsertTextImpl(*inString, address_of(selNode),
|
||||
address_of(selChild),
|
||||
&selOffset, doc);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
} else {
|
||||
WSRunObject wsObj(mHTMLEditor, selNode, selOffset);
|
||||
rv = wsObj.InsertText(*inString, address_of(selNode), &selOffset, doc);
|
||||
rv = wsObj.InsertText(*inString, address_of(selNode),
|
||||
address_of(selChild), &selOffset, doc);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
@ -1401,6 +1405,7 @@ HTMLEditRules::WillInsertText(EditAction aAction,
|
||||
} else {
|
||||
NS_ENSURE_STATE(mHTMLEditor);
|
||||
rv = mHTMLEditor->InsertTextImpl(subStr, address_of(curNode),
|
||||
address_of(selChild),
|
||||
&curOffset, doc);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
@ -1433,7 +1438,8 @@ HTMLEditRules::WillInsertText(EditAction aAction,
|
||||
// is it a tab?
|
||||
if (subStr.Equals(tabStr)) {
|
||||
rv =
|
||||
wsObj.InsertText(spacesStr, address_of(curNode), &curOffset, doc);
|
||||
wsObj.InsertText(spacesStr, address_of(curNode),
|
||||
address_of(selChild), &curOffset, doc);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
pos++;
|
||||
}
|
||||
@ -1444,8 +1450,10 @@ HTMLEditRules::WillInsertText(EditAction aAction,
|
||||
nsIEditor::eNone);
|
||||
NS_ENSURE_TRUE(br, NS_ERROR_FAILURE);
|
||||
pos++;
|
||||
selChild = br->GetNextSibling();;
|
||||
} else {
|
||||
rv = wsObj.InsertText(subStr, address_of(curNode), &curOffset, doc);
|
||||
rv = wsObj.InsertText(subStr, address_of(curNode),
|
||||
address_of(selChild), &curOffset, doc);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
}
|
||||
|
@ -3118,6 +3118,7 @@ HTMLEditor::DeleteText(nsGenericDOMDataNode& aCharData,
|
||||
nsresult
|
||||
HTMLEditor::InsertTextImpl(const nsAString& aStringToInsert,
|
||||
nsCOMPtr<nsINode>* aInOutNode,
|
||||
nsCOMPtr<nsIContent>* aInOutChildAtOffset,
|
||||
int32_t* aInOutOffset,
|
||||
nsIDocument* aDoc)
|
||||
{
|
||||
@ -3126,8 +3127,9 @@ HTMLEditor::InsertTextImpl(const nsAString& aStringToInsert,
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
return EditorBase::InsertTextImpl(aStringToInsert, aInOutNode, aInOutOffset,
|
||||
aDoc);
|
||||
return EditorBase::InsertTextImpl(aStringToInsert, aInOutNode,
|
||||
aInOutChildAtOffset,
|
||||
aInOutOffset, aDoc);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -313,6 +313,7 @@ public:
|
||||
uint32_t aLength);
|
||||
virtual nsresult InsertTextImpl(const nsAString& aStringToInsert,
|
||||
nsCOMPtr<nsINode>* aInOutNode,
|
||||
nsCOMPtr<nsIContent>* aInOutChildAtOffset,
|
||||
int32_t* aInOutOffset,
|
||||
nsIDocument* aDoc) override;
|
||||
NS_IMETHOD_(bool) IsModifiableNode(nsIDOMNode* aNode) override;
|
||||
|
@ -726,6 +726,8 @@ TextEditRules::WillInsertText(EditAction aAction,
|
||||
// get the (collapsed) selection location
|
||||
NS_ENSURE_STATE(aSelection->GetRangeAt(0));
|
||||
nsCOMPtr<nsINode> selNode = aSelection->GetRangeAt(0)->GetStartContainer();
|
||||
nsCOMPtr<nsIContent> selChild =
|
||||
aSelection->GetRangeAt(0)->GetChildAtStartOffset();
|
||||
int32_t selOffset = aSelection->GetRangeAt(0)->StartOffset();
|
||||
NS_ENSURE_STATE(selNode);
|
||||
|
||||
@ -744,7 +746,8 @@ TextEditRules::WillInsertText(EditAction aAction,
|
||||
if (aAction == EditAction::insertIMEText) {
|
||||
NS_ENSURE_STATE(mTextEditor);
|
||||
// Find better insertion point to insert text.
|
||||
mTextEditor->FindBetterInsertionPoint(selNode, selOffset);
|
||||
mTextEditor->FindBetterInsertionPoint(selNode, selOffset,
|
||||
address_of(selChild));
|
||||
// If there is one or more IME selections, its minimum offset should be
|
||||
// the insertion point.
|
||||
int32_t IMESelectionOffset =
|
||||
@ -753,7 +756,7 @@ TextEditRules::WillInsertText(EditAction aAction,
|
||||
selOffset = IMESelectionOffset;
|
||||
}
|
||||
rv = mTextEditor->InsertTextImpl(*outString, address_of(selNode),
|
||||
&selOffset, doc);
|
||||
address_of(selChild), &selOffset, doc);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
} else {
|
||||
// aAction == EditAction::insertText; find where we are
|
||||
@ -765,7 +768,7 @@ TextEditRules::WillInsertText(EditAction aAction,
|
||||
AutoTransactionsConserveSelection dontChangeMySelection(mTextEditor);
|
||||
|
||||
rv = mTextEditor->InsertTextImpl(*outString, address_of(curNode),
|
||||
&curOffset, doc);
|
||||
address_of(selChild), &curOffset, doc);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (curNode) {
|
||||
|
@ -551,7 +551,7 @@ TextEditor::ExtendSelectionForDelete(Selection* aSelection,
|
||||
NS_ENSURE_TRUE(node, NS_ERROR_FAILURE);
|
||||
|
||||
// node might be anonymous DIV, so we find better text node
|
||||
FindBetterInsertionPoint(node, offset);
|
||||
FindBetterInsertionPoint(node, offset, nullptr);
|
||||
|
||||
if (IsTextNode(node)) {
|
||||
const nsTextFragment* data = node->GetAsText()->GetText();
|
||||
@ -704,6 +704,7 @@ TextEditor::InsertLineBreak()
|
||||
// get the (collapsed) selection location
|
||||
NS_ENSURE_STATE(selection->GetRangeAt(0));
|
||||
nsCOMPtr<nsINode> selNode = selection->GetRangeAt(0)->GetStartContainer();
|
||||
nsCOMPtr<nsIContent> selChild = selection->GetRangeAt(0)->GetChildAtStartOffset();
|
||||
int32_t selOffset = selection->GetRangeAt(0)->StartOffset();
|
||||
NS_ENSURE_STATE(selNode);
|
||||
|
||||
@ -722,7 +723,7 @@ TextEditor::InsertLineBreak()
|
||||
|
||||
// insert a linefeed character
|
||||
rv = InsertTextImpl(NS_LITERAL_STRING("\n"), address_of(selNode),
|
||||
&selOffset, doc);
|
||||
address_of(selChild), &selOffset, doc);
|
||||
if (!selNode) {
|
||||
rv = NS_ERROR_NULL_POINTER; // don't return here, so DidDoAction is called
|
||||
}
|
||||
|
@ -234,6 +234,7 @@ WSRunObject::InsertBreak(nsCOMPtr<nsINode>* aInOutParent,
|
||||
nsresult
|
||||
WSRunObject::InsertText(const nsAString& aStringToInsert,
|
||||
nsCOMPtr<nsINode>* aInOutParent,
|
||||
nsCOMPtr<nsIContent>* aInOutChildAtOffset,
|
||||
int32_t* aInOutOffset,
|
||||
nsIDocument* aDoc)
|
||||
{
|
||||
@ -356,7 +357,8 @@ WSRunObject::InsertText(const nsAString& aStringToInsert,
|
||||
}
|
||||
|
||||
// Ready, aim, fire!
|
||||
mHTMLEditor->InsertTextImpl(theString, aInOutParent, aInOutOffset, aDoc);
|
||||
mHTMLEditor->InsertTextImpl(theString, aInOutParent, aInOutChildAtOffset,
|
||||
aInOutOffset, aDoc);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -224,6 +224,7 @@ public:
|
||||
// trailingws before {aInOutParent,aInOutOffset} needs to be removed.
|
||||
nsresult InsertText(const nsAString& aStringToInsert,
|
||||
nsCOMPtr<nsINode>* aInOutNode,
|
||||
nsCOMPtr<nsIContent>* aInOutChildAtOffset,
|
||||
int32_t* aInOutOffset,
|
||||
nsIDocument* aDoc);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user