Bug 1359397 - Don't allow Selection in nodes not in the document; r=masayuki

This matches the spec and Chrome, and seems to bring us closer to Edge
and WebKit as well.  It also matches our own behavior for addRange(),
which was changed in bug 1341137.

For collapse and selectAllChildren, we match the tests and browsers, but
the spec is incorrect at the time of this writing:
https://github.com/w3c/selection-api/pull/86

The removeAllRanges test hadn't been updated for the spec change.

MozReview-Commit-ID: DTK8283k5IP

--HG--
extra : rebase_source : 54701e7136c33ebce651d5f74c3dc1d8b944f9a3
This commit is contained in:
Aryeh Gregor 2017-08-10 15:02:08 +03:00
Родитель a3c8f6ca5b
Коммит 99a150fe57
30 изменённых файлов: 54 добавлений и 104735 удалений

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

@ -2481,6 +2481,21 @@ Selection::Collapse(nsINode& aContainer, uint32_t aOffset, ErrorResult& aRv)
return;
}
if (aContainer.NodeType() == nsIDOMNode::DOCUMENT_TYPE_NODE) {
aRv.Throw(NS_ERROR_DOM_INVALID_NODE_TYPE_ERR);
return;
}
if (aOffset > aContainer.Length()) {
aRv.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
return;
}
if (!HasSameRoot(aContainer)) {
// Return with no error
return;
}
nsCOMPtr<nsINode> container = &aContainer;
RefPtr<nsFrameSelection> frameSelection = mFrameSelection;
@ -2880,6 +2895,11 @@ Selection::Extend(nsINode& aContainer, uint32_t aOffset, ErrorResult& aRv)
return;
}
if (!HasSameRoot(aContainer)) {
// Return with no error
return;
}
nsresult res;
if (!IsValidSelectionPoint(mFrameSelection, &aContainer)) {
aRv.Throw(NS_ERROR_FAILURE);
@ -3169,6 +3189,16 @@ Selection::SelectAllChildrenJS(nsINode& aNode, ErrorResult& aRv)
void
Selection::SelectAllChildren(nsINode& aNode, ErrorResult& aRv)
{
if (aNode.NodeType() == nsIDOMNode::DOCUMENT_TYPE_NODE) {
aRv.Throw(NS_ERROR_DOM_INVALID_NODE_TYPE_ERR);
return;
}
if (!HasSameRoot(aNode)) {
// Return with no error
return;
}
if (mFrameSelection) {
mFrameSelection->PostReason(nsISelectionListener::SELECTALL_REASON);
}
@ -3971,6 +4001,12 @@ Selection::SetBaseAndExtent(nsINode& aAnchorNode, uint32_t aAnchorOffset,
return;
}
if (!HasSameRoot(aAnchorNode) ||
!HasSameRoot(aFocusNode)) {
// Return with no error
return;
}
SelectionBatcher batch(this);
int32_t relativePosition =
@ -4211,3 +4247,11 @@ AutoHideSelectionChanges::AutoHideSelectionChanges(const nsFrameSelection* aFram
: AutoHideSelectionChanges(
aFrame ? aFrame->GetSelection(SelectionType::eNormal) : nullptr)
{}
bool
Selection::HasSameRoot(nsINode& aNode)
{
nsINode* root = aNode.SubtreeRoot();
nsIDocument* doc = GetParentObject();
return doc == root || (root && doc == root->GetComposedDoc());
}

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

@ -282,6 +282,9 @@ private:
// Note: DoAutoScroll might destroy arbitrary frames etc.
nsresult DoAutoScroll(nsIFrame *aFrame, nsPoint& aPoint);
// We are not allowed to be in nodes whose root is not our document
bool HasSameRoot(nsINode& aNode);
// XXX Please don't add additional uses of this method, it's only for
// XXX supporting broken code (bug 1245883) in the following classes:
friend class ::nsCopySupport;

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

@ -23,8 +23,6 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=537046
/** Test for Bug 537046 **/
SimpleTest.expectAssertions(1);
SimpleTest.waitForExplicitFinish();
addLoadEvent(function() {
var ed = document.getElementById("editor");

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Разница между файлами не показана из-за своего большого размера Загрузить разницу

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

@ -1,182 +0,0 @@
[collapseToStartEnd.html]
type: testharness
[Range 12 [foreignPara1.firstChild, 0, foreignPara1.firstChild, 0\] collapseToStart()]
expected: FAIL
[Range 12 [foreignPara1.firstChild, 0, foreignPara1.firstChild, 0\] collapseToEnd()]
expected: FAIL
[Range 13 [foreignPara1.firstChild, 0, foreignPara1.firstChild, 1\] collapseToStart()]
expected: FAIL
[Range 13 [foreignPara1.firstChild, 0, foreignPara1.firstChild, 1\] collapseToEnd()]
expected: FAIL
[Range 14 [foreignPara1.firstChild, 2, foreignPara1.firstChild, 8\] collapseToStart()]
expected: FAIL
[Range 14 [foreignPara1.firstChild, 2, foreignPara1.firstChild, 8\] collapseToEnd()]
expected: FAIL
[Range 20 [foreignDoc.documentElement, 0, foreignDoc.documentElement, 1\] collapseToStart()]
expected: FAIL
[Range 20 [foreignDoc.documentElement, 0, foreignDoc.documentElement, 1\] collapseToEnd()]
expected: FAIL
[Range 21 [foreignDoc.head, 1, foreignDoc.head, 1\] collapseToStart()]
expected: FAIL
[Range 21 [foreignDoc.head, 1, foreignDoc.head, 1\] collapseToEnd()]
expected: FAIL
[Range 22 [foreignDoc.body, 0, foreignDoc.body, 0\] collapseToStart()]
expected: FAIL
[Range 22 [foreignDoc.body, 0, foreignDoc.body, 0\] collapseToEnd()]
expected: FAIL
[Range 34 [foreignDoc.documentElement, 1, foreignDoc.body, 0\] collapseToStart()]
expected: FAIL
[Range 34 [foreignDoc.documentElement, 1, foreignDoc.body, 0\] collapseToEnd()]
expected: FAIL
[Range 41 [foreignDoc, 0, foreignDoc, 0\] collapseToStart()]
expected: FAIL
[Range 41 [foreignDoc, 0, foreignDoc, 0\] collapseToEnd()]
expected: FAIL
[Range 42 [foreignDoc, 1, foreignComment, 2\] collapseToStart()]
expected: FAIL
[Range 42 [foreignDoc, 1, foreignComment, 2\] collapseToEnd()]
expected: FAIL
[Range 43 [foreignDoc.body, 0, foreignTextNode, 36\] collapseToStart()]
expected: FAIL
[Range 43 [foreignDoc.body, 0, foreignTextNode, 36\] collapseToEnd()]
expected: FAIL
[Range 44 [xmlDoc, 0, xmlDoc, 0\] collapseToStart()]
expected: FAIL
[Range 44 [xmlDoc, 0, xmlDoc, 0\] collapseToEnd()]
expected: FAIL
[Range 45 [xmlDoc, 1, xmlComment, 0\] collapseToStart()]
expected: FAIL
[Range 45 [xmlDoc, 1, xmlComment, 0\] collapseToEnd()]
expected: FAIL
[Range 47 [detachedForeignTextNode, 7, detachedForeignTextNode, 7\] collapseToStart()]
expected: FAIL
[Range 47 [detachedForeignTextNode, 7, detachedForeignTextNode, 7\] collapseToEnd()]
expected: FAIL
[Range 48 [detachedForeignTextNode, 0, detachedForeignTextNode, 8\] collapseToStart()]
expected: FAIL
[Range 48 [detachedForeignTextNode, 0, detachedForeignTextNode, 8\] collapseToEnd()]
expected: FAIL
[Range 49 [detachedXmlTextNode, 7, detachedXmlTextNode, 7\] collapseToStart()]
expected: FAIL
[Range 49 [detachedXmlTextNode, 7, detachedXmlTextNode, 7\] collapseToEnd()]
expected: FAIL
[Range 50 [detachedXmlTextNode, 0, detachedXmlTextNode, 8\] collapseToStart()]
expected: FAIL
[Range 50 [detachedXmlTextNode, 0, detachedXmlTextNode, 8\] collapseToEnd()]
expected: FAIL
[Range 53 [detachedForeignComment, 0, detachedForeignComment, 1\] collapseToStart()]
expected: FAIL
[Range 53 [detachedForeignComment, 0, detachedForeignComment, 1\] collapseToEnd()]
expected: FAIL
[Range 54 [detachedForeignComment, 4, detachedForeignComment, 4\] collapseToStart()]
expected: FAIL
[Range 54 [detachedForeignComment, 4, detachedForeignComment, 4\] collapseToEnd()]
expected: FAIL
[Range 55 [detachedXmlComment, 2, detachedXmlComment, 6\] collapseToStart()]
expected: FAIL
[Range 55 [detachedXmlComment, 2, detachedXmlComment, 6\] collapseToEnd()]
expected: FAIL
[Range 57 [foreignDocfrag, 0, foreignDocfrag, 0\] collapseToStart()]
expected: FAIL
[Range 57 [foreignDocfrag, 0, foreignDocfrag, 0\] collapseToEnd()]
expected: FAIL
[Range 58 [xmlDocfrag, 0, xmlDocfrag, 0\] collapseToStart()]
expected: FAIL
[Range 58 [xmlDocfrag, 0, xmlDocfrag, 0\] collapseToEnd()]
expected: FAIL
[Range 9 [detachedPara1.firstChild, 0, detachedPara1.firstChild, 0\] collapseToStart()]
expected: FAIL
[Range 9 [detachedPara1.firstChild, 0, detachedPara1.firstChild, 0\] collapseToEnd()]
expected: FAIL
[Range 10 [detachedPara1.firstChild, 0, detachedPara1.firstChild, 1\] collapseToStart()]
expected: FAIL
[Range 10 [detachedPara1.firstChild, 0, detachedPara1.firstChild, 1\] collapseToEnd()]
expected: FAIL
[Range 11 [detachedPara1.firstChild, 2, detachedPara1.firstChild, 8\] collapseToStart()]
expected: FAIL
[Range 11 [detachedPara1.firstChild, 2, detachedPara1.firstChild, 8\] collapseToEnd()]
expected: FAIL
[Range 25 [detachedPara1, 0, detachedPara1, 0\] collapseToStart()]
expected: FAIL
[Range 25 [detachedPara1, 0, detachedPara1, 0\] collapseToEnd()]
expected: FAIL
[Range 26 [detachedPara1, 0, detachedPara1, 1\] collapseToStart()]
expected: FAIL
[Range 26 [detachedPara1, 0, detachedPara1, 1\] collapseToEnd()]
expected: FAIL
[Range 46 [detachedTextNode, 0, detachedTextNode, 8\] collapseToStart()]
expected: FAIL
[Range 46 [detachedTextNode, 0, detachedTextNode, 8\] collapseToEnd()]
expected: FAIL
[Range 51 [detachedComment, 3, detachedComment, 4\] collapseToStart()]
expected: FAIL
[Range 51 [detachedComment, 3, detachedComment, 4\] collapseToEnd()]
expected: FAIL
[Range 52 [detachedComment, 5, detachedComment, 5\] collapseToStart()]
expected: FAIL
[Range 52 [detachedComment, 5, detachedComment, 5\] collapseToEnd()]
expected: FAIL
[Range 56 [docfrag, 0, docfrag, 0\] collapseToStart()]
expected: FAIL
[Range 56 [docfrag, 0, docfrag, 0\] collapseToEnd()]
expected: FAIL

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Разница между файлами не показана из-за своего большого размера Загрузить разницу

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

@ -1,50 +0,0 @@
[isCollapsed.html]
type: testharness
[Range 9 [detachedPara1.firstChild, 0, detachedPara1.firstChild, 1\]]
expected: FAIL
[Range 10 [detachedPara1.firstChild, 2, detachedPara1.firstChild, 8\]]
expected: FAIL
[Range 12 [foreignPara1.firstChild, 0, foreignPara1.firstChild, 1\]]
expected: FAIL
[Range 13 [foreignPara1.firstChild, 2, foreignPara1.firstChild, 8\]]
expected: FAIL
[Range 19 [foreignDoc.documentElement, 0, foreignDoc.documentElement, 1\]]
expected: FAIL
[Range 25 [detachedPara1, 0, detachedPara1, 1\]]
expected: FAIL
[Range 33 [foreignDoc.documentElement, 1, foreignDoc.body, 0\]]
expected: FAIL
[Range 41 [foreignDoc, 1, foreignComment, 2\]]
expected: FAIL
[Range 42 [foreignDoc.body, 0, foreignTextNode, 36\]]
expected: FAIL
[Range 44 [xmlDoc, 1, xmlComment, 0\]]
expected: FAIL
[Range 45 [detachedTextNode, 0, detachedTextNode, 8\]]
expected: FAIL
[Range 47 [detachedForeignTextNode, 0, detachedForeignTextNode, 8\]]
expected: FAIL
[Range 49 [detachedXmlTextNode, 0, detachedXmlTextNode, 8\]]
expected: FAIL
[Range 50 [detachedComment, 3, detachedComment, 4\]]
expected: FAIL
[Range 52 [detachedForeignComment, 0, detachedForeignComment, 1\]]
expected: FAIL
[Range 54 [detachedXmlComment, 2, detachedXmlComment, 6\]]
expected: FAIL

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

@ -1,191 +0,0 @@
[removeAllRanges.html]
type: testharness
[Range 12 [foreignPara1.firstChild, 0, foreignPara1.firstChild, 0\] backwards]
expected: FAIL
[Range 13 [foreignPara1.firstChild, 0, foreignPara1.firstChild, 1\] backwards]
expected: FAIL
[Range 14 [foreignPara1.firstChild, 2, foreignPara1.firstChild, 8\] backwards]
expected: FAIL
[Range 20 [foreignDoc.documentElement, 0, foreignDoc.documentElement, 1\] backwards]
expected: FAIL
[Range 21 [foreignDoc.head, 1, foreignDoc.head, 1\] backwards]
expected: FAIL
[Range 22 [foreignDoc.body, 0, foreignDoc.body, 0\] backwards]
expected: FAIL
[Range 34 [foreignDoc.documentElement, 1, foreignDoc.body, 0\] backwards]
expected: FAIL
[Range 41 [foreignDoc, 0, foreignDoc, 0\] backwards]
expected: FAIL
[Range 42 [foreignDoc, 1, foreignComment, 2\] backwards]
expected: FAIL
[Range 43 [foreignDoc.body, 0, foreignTextNode, 36\] backwards]
expected: FAIL
[Range 44 [xmlDoc, 0, xmlDoc, 0\] backwards]
expected: FAIL
[Range 45 [xmlDoc, 1, xmlComment, 0\] backwards]
expected: FAIL
[Range 47 [detachedForeignTextNode, 7, detachedForeignTextNode, 7\] backwards]
expected: FAIL
[Range 48 [detachedForeignTextNode, 0, detachedForeignTextNode, 8\] backwards]
expected: FAIL
[Range 49 [detachedXmlTextNode, 7, detachedXmlTextNode, 7\] backwards]
expected: FAIL
[Range 50 [detachedXmlTextNode, 0, detachedXmlTextNode, 8\] backwards]
expected: FAIL
[Range 53 [detachedForeignComment, 0, detachedForeignComment, 1\] backwards]
expected: FAIL
[Range 54 [detachedForeignComment, 4, detachedForeignComment, 4\] backwards]
expected: FAIL
[Range 55 [detachedXmlComment, 2, detachedXmlComment, 6\] backwards]
expected: FAIL
[Range 57 [foreignDocfrag, 0, foreignDocfrag, 0\] backwards]
expected: FAIL
[Range 58 [xmlDocfrag, 0, xmlDocfrag, 0\] backwards]
expected: FAIL
[removeAllRanges on [foreignPara1.firstChild, 0, foreignPara1.firstChild, 0\] backwards]
expected: FAIL
[empty on [foreignPara1.firstChild, 0, foreignPara1.firstChild, 0\] backwards]
expected: FAIL
[removeAllRanges on [foreignPara1.firstChild, 0, foreignPara1.firstChild, 1\] backwards]
expected: FAIL
[empty on [foreignPara1.firstChild, 0, foreignPara1.firstChild, 1\] backwards]
expected: FAIL
[removeAllRanges on [foreignPara1.firstChild, 2, foreignPara1.firstChild, 8\] backwards]
expected: FAIL
[empty on [foreignPara1.firstChild, 2, foreignPara1.firstChild, 8\] backwards]
expected: FAIL
[removeAllRanges on [foreignDoc.documentElement, 0, foreignDoc.documentElement, 1\] backwards]
expected: FAIL
[empty on [foreignDoc.documentElement, 0, foreignDoc.documentElement, 1\] backwards]
expected: FAIL
[removeAllRanges on [foreignDoc.head, 1, foreignDoc.head, 1\] backwards]
expected: FAIL
[empty on [foreignDoc.head, 1, foreignDoc.head, 1\] backwards]
expected: FAIL
[removeAllRanges on [foreignDoc.body, 0, foreignDoc.body, 0\] backwards]
expected: FAIL
[empty on [foreignDoc.body, 0, foreignDoc.body, 0\] backwards]
expected: FAIL
[removeAllRanges on [foreignDoc.documentElement, 1, foreignDoc.body, 0\] backwards]
expected: FAIL
[empty on [foreignDoc.documentElement, 1, foreignDoc.body, 0\] backwards]
expected: FAIL
[removeAllRanges on [foreignDoc, 0, foreignDoc, 0\] backwards]
expected: FAIL
[empty on [foreignDoc, 0, foreignDoc, 0\] backwards]
expected: FAIL
[removeAllRanges on [foreignDoc, 1, foreignComment, 2\] backwards]
expected: FAIL
[empty on [foreignDoc, 1, foreignComment, 2\] backwards]
expected: FAIL
[removeAllRanges on [foreignDoc.body, 0, foreignTextNode, 36\] backwards]
expected: FAIL
[empty on [foreignDoc.body, 0, foreignTextNode, 36\] backwards]
expected: FAIL
[removeAllRanges on [xmlDoc, 0, xmlDoc, 0\] backwards]
expected: FAIL
[empty on [xmlDoc, 0, xmlDoc, 0\] backwards]
expected: FAIL
[removeAllRanges on [xmlDoc, 1, xmlComment, 0\] backwards]
expected: FAIL
[empty on [xmlDoc, 1, xmlComment, 0\] backwards]
expected: FAIL
[removeAllRanges on [detachedForeignTextNode, 7, detachedForeignTextNode, 7\] backwards]
expected: FAIL
[empty on [detachedForeignTextNode, 7, detachedForeignTextNode, 7\] backwards]
expected: FAIL
[removeAllRanges on [detachedForeignTextNode, 0, detachedForeignTextNode, 8\] backwards]
expected: FAIL
[empty on [detachedForeignTextNode, 0, detachedForeignTextNode, 8\] backwards]
expected: FAIL
[removeAllRanges on [detachedXmlTextNode, 7, detachedXmlTextNode, 7\] backwards]
expected: FAIL
[empty on [detachedXmlTextNode, 7, detachedXmlTextNode, 7\] backwards]
expected: FAIL
[removeAllRanges on [detachedXmlTextNode, 0, detachedXmlTextNode, 8\] backwards]
expected: FAIL
[empty on [detachedXmlTextNode, 0, detachedXmlTextNode, 8\] backwards]
expected: FAIL
[removeAllRanges on [detachedForeignComment, 0, detachedForeignComment, 1\] backwards]
expected: FAIL
[empty on [detachedForeignComment, 0, detachedForeignComment, 1\] backwards]
expected: FAIL
[removeAllRanges on [detachedForeignComment, 4, detachedForeignComment, 4\] backwards]
expected: FAIL
[empty on [detachedForeignComment, 4, detachedForeignComment, 4\] backwards]
expected: FAIL
[removeAllRanges on [detachedXmlComment, 2, detachedXmlComment, 6\] backwards]
expected: FAIL
[empty on [detachedXmlComment, 2, detachedXmlComment, 6\] backwards]
expected: FAIL
[removeAllRanges on [foreignDocfrag, 0, foreignDocfrag, 0\] backwards]
expected: FAIL
[empty on [foreignDocfrag, 0, foreignDocfrag, 0\] backwards]
expected: FAIL
[removeAllRanges on [xmlDocfrag, 0, xmlDocfrag, 0\] backwards]
expected: FAIL
[empty on [xmlDocfrag, 0, xmlDocfrag, 0\] backwards]
expected: FAIL

Разница между файлами не показана из-за своего большого размера Загрузить разницу

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

@ -13,8 +13,13 @@ testRanges.unshift("[]");
var range = rangeFromEndpoints([paras[0].firstChild, 0, paras[0].firstChild, 1]);
function testRange(rangeDesc, method) {
var endpoints = eval(testRanges[i]);
if (endpoints.length && (!isSelectableNode(endpoints[0]) ||
!isSelectableNode(endpoints[2]))) {
return;
}
test(function() {
setSelectionForwards(eval(rangeDesc));
setSelectionForwards(endpoints);
selection[method]();
assert_equals(selection.rangeCount, 0,
"After " + method + "(), rangeCount must be 0");
@ -28,7 +33,7 @@ function testRange(rangeDesc, method) {
// Copy-pasted from above
test(function() {
setSelectionBackwards(eval(rangeDesc));
setSelectionBackwards(endpoints);
selection[method]();
assert_equals(selection.rangeCount, 0,
"After " + method + "(), rangeCount must be 0");