зеркало из https://github.com/mozilla/pjs.git
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:
Родитель
e5fc02c0ec
Коммит
5a81ea8ed6
|
@ -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;
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче