зеркало из https://github.com/mozilla/gecko-dev.git
Backed out changeset bba587e03e0b (bug 1265800)
This commit is contained in:
Родитель
73836dc023
Коммит
9df7aba907
|
@ -2486,8 +2486,7 @@ HTMLEditRules::InsertBRIfNeeded(Selection* aSelection)
|
|||
|
||||
/**
|
||||
* GetGoodSelPointForNode() finds where at a node you would want to set the
|
||||
* selection if you were trying to have a caret next to it. Always returns a
|
||||
* valid value (unless mHTMLEditor has gone away).
|
||||
* selection if you were trying to have a caret next to it.
|
||||
*
|
||||
* @param aNode The node
|
||||
* @param aAction Which edge to find: eNext indicates beginning,
|
||||
|
@ -2498,8 +2497,7 @@ HTMLEditRules::GetGoodSelPointForNode(nsINode& aNode,
|
|||
nsIEditor::EDirection aAction)
|
||||
{
|
||||
NS_ENSURE_TRUE(mHTMLEditor, EditorDOMPoint());
|
||||
if (aNode.GetAsText() || mHTMLEditor->IsContainer(&aNode) ||
|
||||
NS_WARN_IF(!aNode.GetParentNode())) {
|
||||
if (aNode.GetAsText() || mHTMLEditor->IsContainer(&aNode)) {
|
||||
return EditorDOMPoint(&aNode,
|
||||
aAction == nsIEditor::ePrevious ? aNode.Length() : 0);
|
||||
}
|
||||
|
@ -7360,15 +7358,26 @@ HTMLEditRules::AdjustSelection(Selection* aSelection,
|
|||
NS_ENSURE_SUCCESS(res, res);
|
||||
nearNode = do_QueryInterface(nearNodeDOM);
|
||||
|
||||
if (!nearNode) {
|
||||
return NS_OK;
|
||||
if (nearNode)
|
||||
{
|
||||
// is the nearnode a text node?
|
||||
textNode = do_QueryInterface(nearNode);
|
||||
if (textNode)
|
||||
{
|
||||
int32_t offset = 0;
|
||||
// put selection in right place:
|
||||
if (aAction == nsIEditor::ePrevious)
|
||||
textNode->GetLength((uint32_t*)&offset);
|
||||
res = aSelection->Collapse(nearNode,offset);
|
||||
}
|
||||
else // must be break or image
|
||||
{
|
||||
selNode = EditorBase::GetNodeLocation(nearNode, &selOffset);
|
||||
if (aAction == nsIEditor::ePrevious) selOffset++; // want to be beyond it if we backed up to it
|
||||
res = aSelection->Collapse(selNode, selOffset);
|
||||
}
|
||||
}
|
||||
EditorDOMPoint pt = GetGoodSelPointForNode(*nearNode, aAction);
|
||||
res = aSelection->Collapse(pt.node, pt.offset);
|
||||
if (NS_WARN_IF(NS_FAILED(res))) {
|
||||
return res;
|
||||
}
|
||||
return NS_OK;
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -953,14 +953,16 @@ HTMLEditor::IsVisBreak(nsINode* aNode)
|
|||
return false;
|
||||
}
|
||||
// Check if there is a later node in block after br
|
||||
nsCOMPtr<nsINode> priorNode = GetPriorHTMLNode(aNode, true);
|
||||
if (priorNode && TextEditUtils::IsBreak(priorNode)) {
|
||||
return true;
|
||||
}
|
||||
nsCOMPtr<nsINode> nextNode = GetNextHTMLNode(aNode, true);
|
||||
if (nextNode && TextEditUtils::IsBreak(nextNode)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// A single line break before a block boundary is not displayed, so e.g.
|
||||
// foo<p>bar<br></p> and foo<br><p>bar</p> display the same as foo<p>bar</p>.
|
||||
// But if there are multiple <br>s in a row, all but the last are visible.
|
||||
// If we are right before block boundary, then br not visible
|
||||
if (!nextNode) {
|
||||
// This break is trailer in block, it's not visible
|
||||
return false;
|
||||
|
@ -970,13 +972,6 @@ HTMLEditor::IsVisBreak(nsINode* aNode)
|
|||
return false;
|
||||
}
|
||||
|
||||
// If there's an inline node after this one that's not a break, and also a
|
||||
// prior break, this break must be visible.
|
||||
nsCOMPtr<nsINode> priorNode = GetPriorHTMLNode(aNode, true);
|
||||
if (priorNode && TextEditUtils::IsBreak(priorNode)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Sigh. We have to use expensive whitespace calculation code to
|
||||
// determine what is going on
|
||||
int32_t selOffset;
|
||||
|
|
|
@ -37644,12 +37644,6 @@
|
|||
]
|
||||
},
|
||||
"testharness": {
|
||||
"XMLHttpRequest/event-error.html": [
|
||||
{
|
||||
"path": "XMLHttpRequest/event-error.html",
|
||||
"url": "/XMLHttpRequest/event-error.html"
|
||||
}
|
||||
],
|
||||
"css-shapes/basic-shape-circle-ellipse-serialization.html": [
|
||||
{
|
||||
"path": "css-shapes/basic-shape-circle-ellipse-serialization.html",
|
||||
|
@ -37662,12 +37656,6 @@
|
|||
"url": "/domparsing/style_attribute_html.html"
|
||||
}
|
||||
],
|
||||
"editing/other/delete.html": [
|
||||
{
|
||||
"path": "editing/other/delete.html",
|
||||
"url": "/editing/other/delete.html"
|
||||
}
|
||||
],
|
||||
"html/semantics/forms/the-form-element/form-submission-sandbox.html": [
|
||||
{
|
||||
"path": "html/semantics/forms/the-form-element/form-submission-sandbox.html",
|
||||
|
|
|
@ -1,20 +0,0 @@
|
|||
[delete.html]
|
||||
type: testharness
|
||||
[2: "<p><br></p><p><br></p>" 0,0-1,0 delete]
|
||||
expected: FAIL
|
||||
|
||||
[3: "<p><br></p><p><br></p>" 0,0-1,0 forwarddelete]
|
||||
expected: FAIL
|
||||
|
||||
[4: "<p><br></p><p><br></p>" 1,0-0,0 delete]
|
||||
expected: FAIL
|
||||
|
||||
[5: "<p><br></p><p><br></p>" 1,0-0,0 forwarddelete]
|
||||
expected: FAIL
|
||||
|
||||
[13: "<p><br></p><p><br></p>\\n" 1,0 delete]
|
||||
expected: FAIL
|
||||
|
||||
[15: "\\n<p><tt>x</tt></p><p><tt><br></tt></p><p><tt><br></tt></p>\\n" 3,0,0 delete]
|
||||
expected: FAIL
|
||||
|
|
@ -1,14 +1,9 @@
|
|||
Most of this directory tests conformance to the editing spec written long ago
|
||||
by Aryeh Gregor. Nobody actually implements the spec, but the tests are still
|
||||
useful for regression testing. The files in data/ were generated from a
|
||||
JavaScript implementation of the specification using a complex procedure that
|
||||
can't actually be replicated right now as-is. Editing them manually is
|
||||
possible, but they're not really meant to be human-readable. If anyone is
|
||||
interested, it would be possible for Aryeh to get the test generation procedure
|
||||
working again. Or you could look into the repository history and figure out
|
||||
how to do it yourself, if you're brave.
|
||||
|
||||
There is also a directory other/ that contains additional editor-related tests.
|
||||
They aren't necessarily based on any specification, but try to specify sensible
|
||||
behavior, and are meant to be helpful with regression testing for existing
|
||||
implementations and finding bugs in new implementations.
|
||||
This suite tests conformance to the editing spec written long ago by Aryeh
|
||||
Gregor. Nobody actually implements the spec, but the tests are still useful
|
||||
for regression testing. The files in data/ were generated from a JavaScript
|
||||
implementation of the specification using a complex procedure that can't
|
||||
actually be replicated right now as-is. Editing them manually is possible, but
|
||||
they're not really meant to be human-readable. If anyone is interested, it
|
||||
would be possible for Aryeh to get the test generation procedure working again.
|
||||
Or you could look into the repository history and figure out how to do it
|
||||
yourself, if you're brave.
|
||||
|
|
|
@ -1,149 +0,0 @@
|
|||
<!doctype html>
|
||||
<meta charset=utf-8>
|
||||
<title>Deletion tests</title>
|
||||
<script src=/resources/testharness.js></script>
|
||||
<script src=/resources/testharnessreport.js></script>
|
||||
<div contenteditable></div>
|
||||
<script>
|
||||
var div = document.querySelector("div");
|
||||
|
||||
// Format: [start html, start pos, expected html, expected pos, command]
|
||||
// Positions are a sequence of offsets starting from div, e.g., "1,2,0"
|
||||
// translates to node = div.childNodes[1].childNodes[2], offset = 0. For a
|
||||
// non-collapsed selection, use a hyphen, like "0,0-1,0". The selections are
|
||||
// created with collapse() followed by extend() to allow reverse selections, so
|
||||
// order is significant.
|
||||
//
|
||||
// Expected values can be arrays, in which case any is acceptable.
|
||||
var tests = [
|
||||
["<p><br></p><p><br></p>", "1,0", "<p><br></p>", "0,0", "delete"],
|
||||
["<p><br></p><p><br></p>", "0,0", "<p><br></p>", "0,0", "forwarddelete"],
|
||||
|
||||
// Range
|
||||
["<p><br></p><p><br></p>", "0,0-1,0", "<p><br></p>", "0,0", "delete"],
|
||||
["<p><br></p><p><br></p>", "0,0-1,0", "<p><br></p>", "0,0", "forwarddelete"],
|
||||
["<p><br></p><p><br></p>", "1,0-0,0", "<p><br></p>", "0,0", "delete"],
|
||||
["<p><br></p><p><br></p>", "1,0-0,0", "<p><br></p>", "0,0", "forwarddelete"],
|
||||
|
||||
// Different start values
|
||||
["<p>x<br></p><p><br></p>", "1,0",
|
||||
// WebKit/Blink like to get rid of the extra <br>
|
||||
["<p>x<br></p>", "<p>x</p>"],
|
||||
// The selection should really be collapsed inside the text node, but in the
|
||||
// parent is close enough.
|
||||
["0,0,1", "0,1"], "delete"],
|
||||
["<p><br><br></p><p><br></p>", "1,0", "<p><br><br></p>", "0,1", "delete"],
|
||||
["<p><br></p><p><br><br></p>", "1,1",
|
||||
"<p><br></p><p><br></p>", "1,0", "delete"],
|
||||
["<p><br><br><br></p>", "0,2", "<p><br><br></p>", "0,1", "delete"],
|
||||
["<p><br></p><p><br><br><br></p>", "1,2",
|
||||
"<p><br></p><p><br><br></p>", "1,1", "delete"],
|
||||
["<p><br><br></p><p><br><br></p>", "1,1",
|
||||
"<p><br><br></p><p><br></p>", "1,0", "delete"],
|
||||
["<p><br></p><br>", "1", "<p><br></p>", "0,0", "delete"],
|
||||
|
||||
// The trailing \n in these cases is actually significant, because it was
|
||||
// necessary to trigger an actual Gecko bug (somehow!).
|
||||
["<p><br></p><p><br></p>\n", "1,0", "<p><br></p>\n", "0,0", "delete"],
|
||||
["<p><br></p><p><br></p>\n", "0,0", "<p><br></p>\n", "0,0", "forwarddelete"],
|
||||
["\n<p><tt>x</tt></p><p><tt><br></tt></p><p><tt><br></tt></p>\n", "3,0,0",
|
||||
"\n<p><tt>x</tt></p><p><tt><br></tt></p>\n", "2,0,0", "delete"],
|
||||
];
|
||||
|
||||
div.focus();
|
||||
|
||||
for (var i = 0; i < tests.length; i++) {
|
||||
test(function() {
|
||||
var test = tests[i];
|
||||
div.innerHTML = test[0];
|
||||
setSelection(test[1]);
|
||||
|
||||
document.execCommand(test[4], false, "");
|
||||
|
||||
if (typeof test[2] == "string") {
|
||||
assert_equals(div.innerHTML, test[2], "innerHTML");
|
||||
} else {
|
||||
assert_in_array(div.innerHTML, test[2], "innerHTML");
|
||||
}
|
||||
|
||||
var actualSel = recordSelection();
|
||||
var expectedSel = [];
|
||||
if (typeof test[3] == "string") {
|
||||
test[3] = [test[3]];
|
||||
}
|
||||
for (var j = 0; j < test[3].length; j++) {
|
||||
setSelection(test[3][j]);
|
||||
expectedSel.push(recordSelection());
|
||||
}
|
||||
assertSelectionEquals(actualSel, expectedSel, test[2]);
|
||||
}, i + ": " + format_value(tests[i][0]) + " " + tests[i][1] +
|
||||
" " + tests[i][4]);
|
||||
}
|
||||
|
||||
function setSelection(selstr) {
|
||||
var parts = selstr.split("-");
|
||||
var collapsePoint = getPointFromArray(parts[0].split(","));
|
||||
getSelection().collapse(collapsePoint[0], collapsePoint[1]);
|
||||
|
||||
if (parts[1]) {
|
||||
var extendPoint = getPointFromArray(parts[1].split(","));
|
||||
getSelection().extend(extendPoint[0], extendPoint[1]);
|
||||
}
|
||||
}
|
||||
|
||||
function getPointFromArray(offsets) {
|
||||
var retNode = div, retOffset;
|
||||
var offset;
|
||||
while (offset = offsets.shift()) {
|
||||
if (!offsets.length) {
|
||||
retOffset = offset;
|
||||
} else {
|
||||
retNode = retNode.childNodes[offset];
|
||||
}
|
||||
}
|
||||
return [retNode, retOffset];
|
||||
}
|
||||
|
||||
function recordSelection() {
|
||||
return [getSelection().anchorNode, getSelection().anchorOffset,
|
||||
getSelection().focusNode, getSelection().focusOffset];
|
||||
}
|
||||
|
||||
function assertSelectionEquals(actual, expected, html) {
|
||||
if (typeof expected == "string") {
|
||||
expected = [expected];
|
||||
}
|
||||
var pass = false;
|
||||
for (var i = 0; i < expected.length; i++) {
|
||||
if (expected[i][0] === actual[0] &&
|
||||
expected[i][1] === actual[1] &&
|
||||
expected[i][2] === actual[2] &&
|
||||
expected[i][3] === actual[3]) {
|
||||
pass = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
assert_true(pass, "Wrong selection, expected " + formatSel(expected) +
|
||||
", got " + formatSel(actual) +
|
||||
" (in HTML " + format_value(html) + ")");
|
||||
}
|
||||
|
||||
function formatSel(arr) {
|
||||
if (arr.length == 1) {
|
||||
arr = arr[0];
|
||||
}
|
||||
if (Array.isArray(arr[0])) {
|
||||
var ret = [];
|
||||
for (var i = 0; i < arr.length; i++) {
|
||||
ret.push(formatSel(arr[i]));
|
||||
}
|
||||
return ret.join(" or ");
|
||||
}
|
||||
if (arr[0] == arr[2] && arr[1] == arr[3]) {
|
||||
return "collapsed (" + format_value(arr[0]) + ", " + arr[1] + ")";
|
||||
}
|
||||
return "(" + format_value(arr[0]) + ", " + arr[1] +
|
||||
")-(" + format_value(arr[2]) + ", " + arr[3] + ")";
|
||||
}
|
||||
</script>
|
Загрузка…
Ссылка в новой задаче