зеркало из https://github.com/mozilla/gecko-dev.git
Merge mozilla-central to mozilla-inbound. a=merge
This commit is contained in:
Коммит
4c6a0a2b4b
|
@ -1730,52 +1730,28 @@ HTMLEditor::InsertNodeIntoProperAncestorWithTransaction(
|
|||
|
||||
NS_IMETHODIMP
|
||||
HTMLEditor::SelectElement(Element* aElement)
|
||||
{
|
||||
if (NS_WARN_IF(!aElement)) {
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
RefPtr<Selection> selection = GetSelection();
|
||||
if (NS_WARN_IF(!selection)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
nsresult rv = SelectContentInternal(*selection, *aElement);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
HTMLEditor::SelectContentInternal(Selection& aSelection,
|
||||
nsIContent& aContentToSelect)
|
||||
{
|
||||
// Must be sure that element is contained in the document body
|
||||
if (!IsDescendantOfEditorRoot(&aContentToSelect)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
if (!IsDescendantOfEditorRoot(aElement)) {
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
|
||||
nsINode* parent = aContentToSelect.GetParentNode();
|
||||
RefPtr<Selection> selection = GetSelection();
|
||||
NS_ENSURE_TRUE(selection, NS_ERROR_NULL_POINTER);
|
||||
nsINode* parent = aElement->GetParentNode();
|
||||
if (NS_WARN_IF(!parent)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
// Don't notify selection change at collapse.
|
||||
AutoUpdateViewBatch notifySelectionChangeOnce(this);
|
||||
|
||||
// XXX Perhaps, Selection should have SelectNode(nsIContent&).
|
||||
int32_t offsetInParent = parent->ComputeIndexOf(&aContentToSelect);
|
||||
int32_t offsetInParent = parent->ComputeIndexOf(aElement);
|
||||
|
||||
// Collapse selection to just before desired element,
|
||||
nsresult rv = aSelection.Collapse(parent, offsetInParent);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
nsresult rv = selection->Collapse(parent, offsetInParent);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
// then extend it to just after
|
||||
rv = selection->Extend(parent, offsetInParent + 1);
|
||||
}
|
||||
// then extend it to just after
|
||||
rv = aSelection.Extend(parent, offsetInParent + 1);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
return NS_OK;
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
|
|
@ -771,17 +771,6 @@ protected: // Shouldn't be used by friend classes
|
|||
|
||||
virtual nsresult SelectAllInternal() override;
|
||||
|
||||
/**
|
||||
* SelectContentInternal() sets Selection to aContentToSelect to
|
||||
* aContentToSelect + 1 in parent of aContentToSelect.
|
||||
*
|
||||
* @param aSelection The Selection, callers have to guarantee the
|
||||
* lifetime.
|
||||
* @param aContentToSelect The content which should be selected.
|
||||
*/
|
||||
nsresult SelectContentInternal(Selection& aSelection,
|
||||
nsIContent& aContentToSelect);
|
||||
|
||||
/**
|
||||
* PasteInternal() pasts text with replacing selected content.
|
||||
* This tries to dispatch ePaste event first. If its defaultPrevent() is
|
||||
|
|
|
@ -3075,9 +3075,7 @@ HTMLEditor::SetSelectionAfterTableEdit(Element* aTable,
|
|||
if (cell) {
|
||||
if (aSelected) {
|
||||
// Reselect the cell
|
||||
DebugOnly<nsresult> rv = SelectContentInternal(*selection, *cell);
|
||||
NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),
|
||||
"Failed to select the cell");
|
||||
SelectElement(cell);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -281,7 +281,6 @@ skip-if = android_version == '24'
|
|||
[test_middle_click_paste.html]
|
||||
subsuite = clipboard
|
||||
skip-if = android_version == '24'
|
||||
[test_nsIHTMLEditor_selectElement.html]
|
||||
[test_objectResizing.html]
|
||||
[test_root_element_replacement.html]
|
||||
[test_select_all_without_body.html]
|
||||
|
|
|
@ -1,131 +0,0 @@
|
|||
<!DOCTYPE>
|
||||
<html>
|
||||
<head>
|
||||
<title>Test for nsIHTMLEditor.selectElement()</title>
|
||||
<script src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" href="/tests/SimpleTest/test.css">
|
||||
</head>
|
||||
<body>
|
||||
<div id="display">
|
||||
</div>
|
||||
<div id="content" contenteditable></div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
|
||||
<script class="testbody" type="application/javascript">
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
SimpleTest.waitForFocus(function() {
|
||||
let editor = document.getElementById("content");
|
||||
let selection = window.getSelection();
|
||||
|
||||
editor.innerHTML = "<p>p1<b>b1</b><i>i1</i></p><p><b>b2</b><i>i2</i>p2</p>";
|
||||
|
||||
editor.focus();
|
||||
try {
|
||||
getHTMLEditor().selectElement(editor.firstChild.firstChild);
|
||||
ok(false, "nsIHTMLEditor.selectElement() should throw an exception if given node is not an element");
|
||||
} catch (e) {
|
||||
ok(true, `nsIHTMLEditor.selectElement() should throw an exception if given node is not an element: ${e}`);
|
||||
}
|
||||
|
||||
editor.focus();
|
||||
try {
|
||||
getHTMLEditor().selectElement(editor.firstChild.firstChild.nextSibling);
|
||||
is(selection.anchorNode, editor.firstChild,
|
||||
"nsIHTMLEditor.selectElement() should set anchor node to parent of <b> element in the first paragraph");
|
||||
is(selection.anchorOffset, 1,
|
||||
"nsIHTMLEditor.selectElement() should set anchor offset to the index of <b> element in the first paragraph");
|
||||
is(selection.focusNode, editor.firstChild,
|
||||
"nsIHTMLEditor.selectElement() should set focus node to parent of <b> element in the first paragraph");
|
||||
is(selection.focusOffset, 2,
|
||||
"nsIHTMLEditor.selectElement() should set anchor offset to the index of <b> element + 1 in the first paragraph");
|
||||
} catch (e) {
|
||||
ok(false, `nsIHTMLEditor.selectElement() shouldn't throw exception when selecting an element in focused editor #1: ${e}`);
|
||||
}
|
||||
|
||||
editor.focus();
|
||||
try {
|
||||
getHTMLEditor().selectElement(editor.firstChild.nextSibling.firstChild);
|
||||
is(selection.anchorNode, editor.firstChild.nextSibling,
|
||||
"nsIHTMLEditor.selectElement() should set anchor node to parent of <b> element in the second paragraph");
|
||||
is(selection.anchorOffset, 0,
|
||||
"nsIHTMLEditor.selectElement() should set anchor offset to the index of <b> element in the second paragraph");
|
||||
is(selection.focusNode, editor.firstChild.nextSibling,
|
||||
"nsIHTMLEditor.selectElement() should set focus node to parent of <b> element in the second paragraph");
|
||||
is(selection.focusOffset, 1,
|
||||
"nsIHTMLEditor.selectElement() should set anchor offset to the index of <b> element + 1 in the second paragraph");
|
||||
} catch (e) {
|
||||
ok(false, `nsIHTMLEditor.selectElement() shouldn't throw exception when selecting an element in focused editor #2: ${e}`);
|
||||
}
|
||||
|
||||
editor.focus();
|
||||
try {
|
||||
getHTMLEditor().selectElement(editor);
|
||||
ok(false, "nsIHTMLEditor.selectElement() should throw an exception if given node is the editing host");
|
||||
} catch (e) {
|
||||
ok(true, `nsIHTMLEditor.selectElement() should throw an exception if given node is the editing host: ${e}`);
|
||||
}
|
||||
|
||||
editor.focus();
|
||||
try {
|
||||
getHTMLEditor().selectElement(editor.parentElement);
|
||||
ok(false, "nsIHTMLEditor.selectElement() should throw an exception if given node is outside of the editing host");
|
||||
} catch (e) {
|
||||
ok(true, `nsIHTMLEditor.selectElement() should throw an exception if given node is outside of the editing host: ${e}`);
|
||||
}
|
||||
|
||||
selection.removeAllRanges();
|
||||
editor.blur();
|
||||
try {
|
||||
getHTMLEditor().selectElement(editor.firstChild.nextSibling.firstChild);
|
||||
ok(false, "nsIHTMLEditor.selectElement() should throw an exception if there is no active editing host");
|
||||
} catch (e) {
|
||||
ok(true, `nsIHTMLEditor.selectElement() should throw an exception if there is no active editing host: ${e}`);
|
||||
}
|
||||
|
||||
editor.focus();
|
||||
editor.firstChild.firstChild.nextSibling.nextSibling.setAttribute("contenteditable", "false");
|
||||
try {
|
||||
getHTMLEditor().selectElement(editor.firstChild.firstChild.nextSibling.nextSibling);
|
||||
is(selection.anchorNode, editor.firstChild,
|
||||
"nsIHTMLEditor.selectElement() should set anchor node to parent of <i contenteditable=\"false\"> element in the first paragraph");
|
||||
is(selection.anchorOffset, 2,
|
||||
"nsIHTMLEditor.selectElement() should set anchor offset to the index of <i contenteditable=\"false\"> element in the first paragraph");
|
||||
is(selection.focusNode, editor.firstChild,
|
||||
"nsIHTMLEditor.selectElement() should set focus node to parent of <i contenteditable=\"false\"> element in the first paragraph");
|
||||
is(selection.focusOffset, 3,
|
||||
"nsIHTMLEditor.selectElement() should set anchor offset to the index of <i contenteditable=\"false\"> element + 1 in the first paragraph");
|
||||
} catch (e) {
|
||||
ok(false, `nsIHTMLEditor.selectElement() shouldn't throw exception when selecting an element in focused editor #3: ${e}`);
|
||||
}
|
||||
|
||||
editor.focus();
|
||||
editor.firstChild.nextSibling.setAttribute("contenteditable", "false");
|
||||
try {
|
||||
getHTMLEditor().selectElement(editor.firstChild.nextSibling.firstChild.nextSibling);
|
||||
is(selection.anchorNode, editor.firstChild.nextSibling,
|
||||
"nsIHTMLEditor.selectElement() should set anchor node to parent of <i> element in the second paragraph which is not editable");
|
||||
is(selection.anchorOffset, 1,
|
||||
"nsIHTMLEditor.selectElement() should set anchor offset to the index of <i> element in the second paragraph which is not editable");
|
||||
is(selection.focusNode, editor.firstChild.nextSibling,
|
||||
"nsIHTMLEditor.selectElement() should set focus node to parent of <i> element in the second paragraph which is not editable");
|
||||
is(selection.focusOffset, 2,
|
||||
"nsIHTMLEditor.selectElement() should set anchor offset to the index of <i> element + 1 in the second paragraph which is not editable");
|
||||
} catch (e) {
|
||||
ok(false, `nsIHTMLEditor.selectElement() shouldn't throw exception when selecting an element in focused editor #4: ${e}`);
|
||||
}
|
||||
|
||||
SimpleTest.finish();
|
||||
});
|
||||
|
||||
function getHTMLEditor() {
|
||||
var Ci = SpecialPowers.Ci;
|
||||
var editingSession = SpecialPowers.wrap(window).docShell.editingSession;
|
||||
return editingSession.getEditorForWindow(window).QueryInterface(Ci.nsIHTMLEditor);
|
||||
}
|
||||
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
Загрузка…
Ссылка в новой задаче