mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-01-24 05:44:10 +00:00
Bug 507936 - Should join node when deleting at end of paragraph. r=peterv
This commit is contained in:
parent
992145aea6
commit
cb757fbca3
@ -1920,10 +1920,17 @@ nsHTMLEditRules::WillDeleteSelection(nsISelection *aSelection,
|
||||
nsresult res = NS_OK;
|
||||
PRBool bPlaintext = mFlags & nsIPlaintextEditor::eEditorPlaintextMask;
|
||||
|
||||
PRBool bCollapsed;
|
||||
PRBool bCollapsed, join = PR_FALSE;
|
||||
res = aSelection->GetIsCollapsed(&bCollapsed);
|
||||
if (NS_FAILED(res)) return res;
|
||||
|
||||
|
||||
// origCollapsed is used later to determine whether we should join
|
||||
// blocks. We don't really care about bCollapsed because it will be
|
||||
// modified by ExtendSelectionForDelete later. JoinBlocks should
|
||||
// happen if the original selection is collapsed and the cursor is
|
||||
// at the end of a block element, in which case ExtendSelectionForDelete
|
||||
// would always make the selection not collapsed.
|
||||
PRBool origCollapsed = bCollapsed;
|
||||
nsCOMPtr<nsIDOMNode> startNode, selNode;
|
||||
PRInt32 startOffset, selOffset;
|
||||
|
||||
@ -2467,6 +2474,8 @@ nsHTMLEditRules::WillDeleteSelection(nsISelection *aSelection,
|
||||
if (NS_FAILED(res)) return res;
|
||||
if (!enumerator) return NS_ERROR_UNEXPECTED;
|
||||
|
||||
join = PR_TRUE;
|
||||
|
||||
for (enumerator->First(); NS_OK!=enumerator->IsDone(); enumerator->Next())
|
||||
{
|
||||
nsCOMPtr<nsISupports> currentItem;
|
||||
@ -2493,6 +2502,17 @@ nsHTMLEditRules::WillDeleteSelection(nsISelection *aSelection,
|
||||
nsIDOMNode* somenode = arrayOfNodes[0];
|
||||
res = DeleteNonTableElements(somenode);
|
||||
arrayOfNodes.RemoveObjectAt(0);
|
||||
// If something visible is deleted, no need to join.
|
||||
// Visible means all nodes except non-visible textnodes and breaks.
|
||||
if (join && origCollapsed) {
|
||||
if (mHTMLEditor->IsTextNode(somenode)) {
|
||||
mHTMLEditor->IsVisTextNode(somenode, &join, PR_TRUE);
|
||||
}
|
||||
else {
|
||||
join = nsTextEditUtils::IsBreak(somenode) &&
|
||||
!mHTMLEditor->IsVisBreak(somenode);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -2526,14 +2546,6 @@ nsHTMLEditRules::WillDeleteSelection(nsISelection *aSelection,
|
||||
}
|
||||
}
|
||||
|
||||
PRBool join = leftBlockParent == rightBlockParent;
|
||||
if (!join) {
|
||||
nsCOMPtr<nsINode> parent1 = do_QueryInterface(leftParent);
|
||||
nsCOMPtr<nsINode> parent2 = do_QueryInterface(rightParent);
|
||||
PRUint16 pos = nsContentUtils::ComparePosition(parent1, parent2);
|
||||
join = (pos & (nsIDOM3Node::DOCUMENT_POSITION_CONTAINS |
|
||||
nsIDOM3Node::DOCUMENT_POSITION_CONTAINED_BY)) != 0;
|
||||
}
|
||||
if (join) {
|
||||
res = JoinBlocks(address_of(leftParent), address_of(rightParent),
|
||||
aCancel);
|
||||
@ -2542,7 +2554,15 @@ nsHTMLEditRules::WillDeleteSelection(nsISelection *aSelection,
|
||||
}
|
||||
}
|
||||
}
|
||||
if (aAction == nsIEditor::eNext)
|
||||
//If we're joining blocks: if deleting forward the selection should be
|
||||
//collapsed to the end of the selection, if deleting backward the selection
|
||||
//should be collapsed to the beginning of the selection. But if we're not
|
||||
//joining then the selection should collapse to the beginning of the
|
||||
//selection if we'redeleting forward, because the end of the selection will
|
||||
//still be in the next block. And same thing for deleting backwards
|
||||
//(selection should collapse to the end, because the beginning will still
|
||||
//be in the first block). See Bug 507936
|
||||
if (join ? aAction == nsIEditor::eNext : aAction == nsIEditor::ePrevious)
|
||||
{
|
||||
res = aSelection->Collapse(endNode,endOffset);
|
||||
}
|
||||
|
@ -19,14 +19,18 @@ function execTests() {
|
||||
var sel = win.getSelection();
|
||||
win.focus();
|
||||
|
||||
function setupTest(html, firstChildOffsetForCaret) {
|
||||
function setupTest(html, firstChildOffsetForCaret, node) {
|
||||
// Work around bug 474255 --- we need to have nonempty content before we turn on
|
||||
// editing, or the tests below break because the editor doesn't notice when we
|
||||
// insert non-empty content using innerHTML.
|
||||
doc.designMode = 'off';
|
||||
editor.innerHTML = html;
|
||||
doc.designMode = 'on';
|
||||
sel.collapse(editor.firstChild, firstChildOffsetForCaret);
|
||||
var n = editor.firstChild;
|
||||
if (node) {
|
||||
n = node();
|
||||
}
|
||||
sel.collapse(n, firstChildOffsetForCaret);
|
||||
}
|
||||
|
||||
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
|
||||
@ -211,6 +215,47 @@ function execTests() {
|
||||
setupTest("<p>Bug</p>\n<p>502259</p>", 1);
|
||||
testDelete(function(){return editor.firstChild.firstChild;}, 3, "<p>Bug502259</p>", true);
|
||||
|
||||
// Tests for Bug 507936
|
||||
var nodecallback = function(){return editor.firstChild.firstChild.lastChild.firstChild.lastChild;};
|
||||
setupTest("<ol><li>one<ol><li>two</li></ol></li></ol>\n<p>three</p>", 3, nodecallback);
|
||||
testDelete(nodecallback, 0, "<ol><li>one<ol><li>twothree</li></ol></li></ol>", true);
|
||||
|
||||
setupTest("<ol><li>one<ol><li>two</li></ol></li></ol>\n<hr>\n<p>three</p>", 3, nodecallback);
|
||||
testDelete(nodecallback, 3,
|
||||
"<ol><li>one<ol><li>two</li></ol></li></ol><p>three</p>", true);
|
||||
|
||||
// Tests for Bug 519751
|
||||
var nodecallback = function(){return editor.firstChild.lastChild;};
|
||||
setupTest("<p>one</p><ol><li>two</li><li>three</li></ol>", 3, nodecallback);
|
||||
testDelete(nodecallback, 0, "<p>onetwo</p><ol><li>three</li></ol>", true);
|
||||
|
||||
nodecallback = function(){return editor.firstChild.childNodes[1].firstChild;};
|
||||
setupTest("<ol><li>one</li><li>two</li></ol><ol><li>three</li><li>four</li></ol>", 3, nodecallback);
|
||||
testDelete(function(){return editor.firstChild.childNodes[2].firstChild;},
|
||||
0, "<ol><li>one</li><li>two</li><li>three</li><li>four</li></ol>", true);
|
||||
/*todo_is(false, true, 'The above testDelete should use the same nodecallback' +
|
||||
'as in the proceeding setupTest: the cursor should stay at the end of "two", while currently it is at the beginning of "three" after delete');*/
|
||||
|
||||
// More Tests for Bug 507936
|
||||
nodecallback = function(){return editor.firstChild.firstChild.firstChild;}
|
||||
setupTest("<div><div>abcdef</div><div>bar</div><div>ghi</div></div>", 5, nodecallback);
|
||||
sel.extend(editor.lastChild.lastChild.lastChild, 1);
|
||||
testDelete(editor.lastChild.lastChild.lastChild, 5, "<div><div>abcdehi</div></div>", true);
|
||||
|
||||
setupTest("<div><div>abcdef</div><div>ghi</div></div>", 5, nodecallback);
|
||||
sel.extend(editor.lastChild.lastChild.lastChild, 1);
|
||||
testDelete(editor.lastChild.lastChild.lastChild, 5, "<div><div>abcdehi</div></div>", true);
|
||||
|
||||
nodecallback = function(){return editor.firstChild.firstChild;}
|
||||
setupTest("<div>abcdef<div><div>bar</div>ghi</div></div>", 5, nodecallback);
|
||||
sel.extend(editor.lastChild.lastChild.lastChild, 1);
|
||||
expectednodecallback = function(){return editor.lastChild.lastChild;}
|
||||
testDelete(expectednodecallback, 0, "<div>abcdehi</div>", true);
|
||||
|
||||
setupTest("<div>abcdef<div>ghi</div></div>", 5, nodecallback);
|
||||
sel.extend(editor.lastChild.lastChild.lastChild, 1);
|
||||
testDelete(expectednodecallback, 0, "<div>abcdehi</div>", true);
|
||||
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user