I fixed the content twiddling part of bug 3778. Mike has a fix for the display part of it in his tree, but determined the risk didn't

justify the benefit.  This is partly true because he and I would have had to integrate tonight before checking in, which we thought
presented some additional risk.  In any event, this bug is fixed for all cases except when the user hits enter at the end of the
document.  That is the only case in text editing when the selection will not render correctly.

Some related problems got fixed as a side benefit of my code changes.  I filed bug 3896.
This commit is contained in:
buster%netscape.com 1999-03-17 06:13:46 +00:00
Родитель e5fc02c0ec
Коммит 5a81ea8ed6
3 изменённых файлов: 150 добавлений и 65 удалений

Просмотреть файл

@ -1232,24 +1232,53 @@ NS_IMETHODIMP nsEditor::DeleteSelectionAndCreateNode(const nsString& aTag, nsIDO
}
#endif
}
// split the text node
// split the selected node
nsCOMPtr<nsIDOMNode> parentSelectedNode;
PRInt32 offsetOfSelectedNode;
result = selection->GetAnchorNodeAndOffset(getter_AddRefs(parentSelectedNode), &offsetOfSelectedNode);
if ((NS_SUCCEEDED(result)) && parentSelectedNode)
{
PRInt32 offsetOfNewNode;
nsCOMPtr<nsIDOMNode> selectedNode;
PRUint32 selectedNodeContentCount=0;
nsCOMPtr<nsIDOMCharacterData>selectedParentNodeAsText;
selectedParentNodeAsText = do_QueryInterface(parentSelectedNode);
if (selectedParentNodeAsText)
{
/* if the selection is a text node, split the text node if necesary
and compute where to put the new node
*/
if (selectedParentNodeAsText)
{
PRInt32 indexOfTextNodeInParent;
selectedNode = do_QueryInterface(parentSelectedNode);
selectedNode->GetParentNode(getter_AddRefs(parentSelectedNode));
selectedParentNodeAsText->GetLength(&selectedNodeContentCount);
nsIEditorSupport::GetChildOffset(selectedNode, parentSelectedNode, indexOfTextNodeInParent);
if ((offsetOfSelectedNode!=0) && (((PRUint32)offsetOfSelectedNode)!=selectedNodeContentCount))
{
nsCOMPtr<nsIDOMNode> newSiblingNode;
result = SplitNode(selectedNode, offsetOfSelectedNode, getter_AddRefs(newSiblingNode));
// now get the node's offset in it's parent, and insert the new tag there
if (NS_SUCCEEDED(result)) {
result = nsIEditorSupport::GetChildOffset(selectedNode, parentSelectedNode, offsetOfNewNode);
}
}
else
{ // determine where to insert the new node
if (0==offsetOfSelectedNode) {
offsetOfNewNode = indexOfTextNodeInParent; // insert new node as previous sibling to selection parent
}
else { // insert new node as last child
nsIEditorSupport::GetChildOffset(selectedNode, parentSelectedNode, offsetOfNewNode);
offsetOfNewNode++; // offsets are 0-based, and we need the index of the new node
}
}
}
/* if the selection is not a text node, split the parent node if necesary
and compute where to put the new node
*/
else
{
{ // it's an interior node
nsCOMPtr<nsIDOMNodeList>parentChildList;
parentSelectedNode->GetChildNodes(getter_AddRefs(parentChildList));
if ((NS_SUCCEEDED(result)) && parentChildList)
@ -1259,47 +1288,49 @@ NS_IMETHODIMP nsEditor::DeleteSelectionAndCreateNode(const nsString& aTag, nsIDO
{
nsCOMPtr<nsIDOMCharacterData>selectedNodeAsText;
selectedNodeAsText = do_QueryInterface(selectedNode);
if (selectedNodeAsText) {
selectedNodeAsText->GetLength(&selectedNodeContentCount);
nsCOMPtr<nsIDOMNodeList>childList;
selectedNode->GetChildNodes(getter_AddRefs(childList));
if ((NS_SUCCEEDED(result)) && childList) {
childList->GetLength(&selectedNodeContentCount);
}
else
else {
return NS_ERROR_NULL_POINTER;
}
if ((offsetOfSelectedNode!=0) && (((PRUint32)offsetOfSelectedNode)!=selectedNodeContentCount))
{
nsCOMPtr<nsIDOMNodeList>childList;
selectedNode->GetChildNodes(getter_AddRefs(childList));
if ((NS_SUCCEEDED(result)) && childList) {
childList->GetLength(&selectedNodeContentCount);
nsCOMPtr<nsIDOMNode> newSiblingNode;
result = SplitNode(selectedNode, offsetOfSelectedNode, getter_AddRefs(newSiblingNode));
// now get the node's offset in it's parent, and insert the new tag there
if (NS_SUCCEEDED(result)) {
result = nsIEditorSupport::GetChildOffset(selectedNode, parentSelectedNode, offsetOfNewNode);
}
else {
return NS_ERROR_NULL_POINTER;
}
else
{ // determine where to insert the new node
if (0==offsetOfSelectedNode) {
offsetOfNewNode = 0; // insert new node as first child
}
else { // insert new node as last child
nsIEditorSupport::GetChildOffset(selectedNode, parentSelectedNode, offsetOfNewNode);
offsetOfNewNode++; // offsets are 0-based, and we need the index of the new node
}
}
}
}
}
// we only get here if result indicates a success
PRInt32 offsetOfNewNode;
if ((offsetOfSelectedNode!=0) && (((PRUint32)offsetOfSelectedNode)!=selectedNodeContentCount))
{
nsCOMPtr<nsIDOMNode> newSiblingNode;
result = SplitNode(selectedNode, offsetOfSelectedNode, getter_AddRefs(newSiblingNode));
// now get the node's offset in it's parent, and insert the new tag there
if (NS_SUCCEEDED(result)) {
result = nsIEditorSupport::GetChildOffset(selectedNode, parentSelectedNode, offsetOfNewNode);
}
}
else {
offsetOfNewNode = offsetOfSelectedNode;
}
if (NS_SUCCEEDED(result))
{
nsCOMPtr<nsIDOMNode> newNode;
result = CreateNode(aTag, parentSelectedNode, offsetOfNewNode, getter_AddRefs(newNode));
selection->Collapse(parentSelectedNode, offsetOfNewNode);
// we want the selection to be just after the new node
selection->Collapse(parentSelectedNode, offsetOfNewNode+1);
*aNewNode = newNode;
}
}
else {
printf("InsertBreak into an empty document is not yet supported\n");
}
}
return result;
}

Просмотреть файл

@ -483,20 +483,43 @@ NS_IMETHODIMP nsTextEditor::InsertBreak()
result = newNode->GetParentNode(getter_AddRefs(parent));
if (NS_SUCCEEDED(result) && parent)
{
PRInt32 offsetInParent;
result = nsIEditorSupport::GetChildOffset(newNode, parent, offsetInParent);
PRInt32 offsetInParent=-1; // we use the -1 as a marker to see if we need to compute this or not
nsCOMPtr<nsIDOMNode>nextNode;
newNode->GetNextSibling(getter_AddRefs(nextNode));
if (nextNode)
{
nsCOMPtr<nsIDOMCharacterData>nextTextNode;
nextTextNode = do_QueryInterface(nextNode);
if (!nextTextNode) {
nextNode = do_QueryInterface(newNode);
}
else {
offsetInParent=0;
}
}
else {
nextNode = do_QueryInterface(newNode);
}
result = nsEditor::GetSelection(getter_AddRefs(selection));
if (NS_SUCCEEDED(result))
{
result = nsEditor::GetSelection(getter_AddRefs(selection));
if (NS_SUCCEEDED(result))
if (-1==offsetInParent)
{
selection->Collapse(parent, offsetInParent);
// post-process
result = mRules->DidInsertBreak(selection, result);
nextNode->GetParentNode(getter_AddRefs(parent));
result = nsIEditorSupport::GetChildOffset(nextNode, parent, offsetInParent);
if (NS_SUCCEEDED(result)) {
selection->Collapse(parent, offsetInParent+1); // +1 to insert just after the break
}
}
else
{
selection->Collapse(nextNode, offsetInParent);
}
}
}
}
// post-process, always called if WillInsertBreak didn't return cancel==PR_TRUE
result = mRules->DidInsertBreak(selection, result);
}
nsresult endTxnResult = nsEditor::EndTransaction(); // don't return this result!
NS_ASSERTION ((NS_SUCCEEDED(endTxnResult)), "bad end transaction result");

Просмотреть файл

@ -1232,24 +1232,53 @@ NS_IMETHODIMP nsEditor::DeleteSelectionAndCreateNode(const nsString& aTag, nsIDO
}
#endif
}
// split the text node
// split the selected node
nsCOMPtr<nsIDOMNode> parentSelectedNode;
PRInt32 offsetOfSelectedNode;
result = selection->GetAnchorNodeAndOffset(getter_AddRefs(parentSelectedNode), &offsetOfSelectedNode);
if ((NS_SUCCEEDED(result)) && parentSelectedNode)
{
PRInt32 offsetOfNewNode;
nsCOMPtr<nsIDOMNode> selectedNode;
PRUint32 selectedNodeContentCount=0;
nsCOMPtr<nsIDOMCharacterData>selectedParentNodeAsText;
selectedParentNodeAsText = do_QueryInterface(parentSelectedNode);
if (selectedParentNodeAsText)
{
/* if the selection is a text node, split the text node if necesary
and compute where to put the new node
*/
if (selectedParentNodeAsText)
{
PRInt32 indexOfTextNodeInParent;
selectedNode = do_QueryInterface(parentSelectedNode);
selectedNode->GetParentNode(getter_AddRefs(parentSelectedNode));
selectedParentNodeAsText->GetLength(&selectedNodeContentCount);
nsIEditorSupport::GetChildOffset(selectedNode, parentSelectedNode, indexOfTextNodeInParent);
if ((offsetOfSelectedNode!=0) && (((PRUint32)offsetOfSelectedNode)!=selectedNodeContentCount))
{
nsCOMPtr<nsIDOMNode> newSiblingNode;
result = SplitNode(selectedNode, offsetOfSelectedNode, getter_AddRefs(newSiblingNode));
// now get the node's offset in it's parent, and insert the new tag there
if (NS_SUCCEEDED(result)) {
result = nsIEditorSupport::GetChildOffset(selectedNode, parentSelectedNode, offsetOfNewNode);
}
}
else
{ // determine where to insert the new node
if (0==offsetOfSelectedNode) {
offsetOfNewNode = indexOfTextNodeInParent; // insert new node as previous sibling to selection parent
}
else { // insert new node as last child
nsIEditorSupport::GetChildOffset(selectedNode, parentSelectedNode, offsetOfNewNode);
offsetOfNewNode++; // offsets are 0-based, and we need the index of the new node
}
}
}
/* if the selection is not a text node, split the parent node if necesary
and compute where to put the new node
*/
else
{
{ // it's an interior node
nsCOMPtr<nsIDOMNodeList>parentChildList;
parentSelectedNode->GetChildNodes(getter_AddRefs(parentChildList));
if ((NS_SUCCEEDED(result)) && parentChildList)
@ -1259,47 +1288,49 @@ NS_IMETHODIMP nsEditor::DeleteSelectionAndCreateNode(const nsString& aTag, nsIDO
{
nsCOMPtr<nsIDOMCharacterData>selectedNodeAsText;
selectedNodeAsText = do_QueryInterface(selectedNode);
if (selectedNodeAsText) {
selectedNodeAsText->GetLength(&selectedNodeContentCount);
nsCOMPtr<nsIDOMNodeList>childList;
selectedNode->GetChildNodes(getter_AddRefs(childList));
if ((NS_SUCCEEDED(result)) && childList) {
childList->GetLength(&selectedNodeContentCount);
}
else
else {
return NS_ERROR_NULL_POINTER;
}
if ((offsetOfSelectedNode!=0) && (((PRUint32)offsetOfSelectedNode)!=selectedNodeContentCount))
{
nsCOMPtr<nsIDOMNodeList>childList;
selectedNode->GetChildNodes(getter_AddRefs(childList));
if ((NS_SUCCEEDED(result)) && childList) {
childList->GetLength(&selectedNodeContentCount);
nsCOMPtr<nsIDOMNode> newSiblingNode;
result = SplitNode(selectedNode, offsetOfSelectedNode, getter_AddRefs(newSiblingNode));
// now get the node's offset in it's parent, and insert the new tag there
if (NS_SUCCEEDED(result)) {
result = nsIEditorSupport::GetChildOffset(selectedNode, parentSelectedNode, offsetOfNewNode);
}
else {
return NS_ERROR_NULL_POINTER;
}
else
{ // determine where to insert the new node
if (0==offsetOfSelectedNode) {
offsetOfNewNode = 0; // insert new node as first child
}
else { // insert new node as last child
nsIEditorSupport::GetChildOffset(selectedNode, parentSelectedNode, offsetOfNewNode);
offsetOfNewNode++; // offsets are 0-based, and we need the index of the new node
}
}
}
}
}
// we only get here if result indicates a success
PRInt32 offsetOfNewNode;
if ((offsetOfSelectedNode!=0) && (((PRUint32)offsetOfSelectedNode)!=selectedNodeContentCount))
{
nsCOMPtr<nsIDOMNode> newSiblingNode;
result = SplitNode(selectedNode, offsetOfSelectedNode, getter_AddRefs(newSiblingNode));
// now get the node's offset in it's parent, and insert the new tag there
if (NS_SUCCEEDED(result)) {
result = nsIEditorSupport::GetChildOffset(selectedNode, parentSelectedNode, offsetOfNewNode);
}
}
else {
offsetOfNewNode = offsetOfSelectedNode;
}
if (NS_SUCCEEDED(result))
{
nsCOMPtr<nsIDOMNode> newNode;
result = CreateNode(aTag, parentSelectedNode, offsetOfNewNode, getter_AddRefs(newNode));
selection->Collapse(parentSelectedNode, offsetOfNewNode);
// we want the selection to be just after the new node
selection->Collapse(parentSelectedNode, offsetOfNewNode+1);
*aNewNode = newNode;
}
}
else {
printf("InsertBreak into an empty document is not yet supported\n");
}
}
return result;
}