Backed out 3 changesets (bug 739396) for Mulet perma-fail on a CLOSED TREE.

Backed out changeset 299911e6983b (bug 739396)
Backed out changeset de11af3e0964 (bug 739396)
Backed out changeset e274cb276cc5 (bug 739396)
This commit is contained in:
Ryan VanderMeulen 2014-09-10 12:21:58 -04:00
parent d394b4d3d9
commit 35a9e4dcde
8 changed files with 43 additions and 519 deletions

View File

@ -3039,95 +3039,3 @@ nsRange::Constructor(const GlobalObject& aGlobal,
return window->GetDoc()->CreateRange(aRv);
}
void
nsRange::ExcludeNonSelectableNodes(nsTArray<nsRefPtr<nsRange>>* aOutRanges)
{
MOZ_ASSERT(mIsPositioned);
MOZ_ASSERT(mEndParent);
MOZ_ASSERT(mStartParent);
nsRange* range = this;
nsRefPtr<nsRange> newRange;
while (range) {
nsCOMPtr<nsIContentIterator> iter = NS_NewPreContentIterator();
nsresult rv = iter->Init(range);
if (NS_FAILED(rv)) {
return;
}
bool added = false;
bool seenSelectable = false;
nsIContent* firstNonSelectableContent = nullptr;
while (true) {
ErrorResult err;
nsINode* node = iter->GetCurrentNode();
iter->Next();
bool selectable = true;
nsIContent* content =
node && node->IsContent() ? node->AsContent() : nullptr;
if (content) {
nsIFrame* frame = content->GetPrimaryFrame();
for (nsIContent* p = content; !frame && (p = p->GetParent()); ) {
frame = p->GetPrimaryFrame();
}
if (frame) {
frame->IsSelectable(&selectable, nullptr);
}
}
if (!selectable) {
if (!firstNonSelectableContent) {
firstNonSelectableContent = content;
}
if (iter->IsDone() && seenSelectable) {
// The tail end of the initial range is non-selectable - truncate the
// current range before the first non-selectable node.
range->SetEndBefore(*firstNonSelectableContent, err);
}
} else if (firstNonSelectableContent) {
if (range == this && !seenSelectable) {
// This is the initial range and all its nodes until now are
// non-selectable so just trim them from the start.
range->SetStartBefore(*node, err);
if (err.Failed()) {
return;
}
break; // restart the same range with a new iterator
} else {
// Save the end point before truncating the range.
nsINode* endParent = range->mEndParent;
int32_t endOffset = range->mEndOffset;
// Truncate the current range before the first non-selectable node.
range->SetEndBefore(*firstNonSelectableContent, err);
// Store it in the result (strong ref) - do this before creating
// a new range in |newRange| below so we don't drop the last ref
// to the range created in the previous iteration.
if (!added && !err.Failed()) {
aOutRanges->AppendElement(range);
}
// Create a new range for the remainder.
rv = CreateRange(node, 0, endParent, endOffset,
getter_AddRefs(newRange));
if (NS_FAILED(rv) || newRange->Collapsed()) {
newRange = nullptr;
}
range = newRange;
break; // create a new iterator for the new range, if any
}
} else {
seenSelectable = true;
if (!added) {
added = true;
aOutRanges->AppendElement(range);
}
}
if (iter->IsDone()) {
return;
}
}
}
}

View File

@ -264,19 +264,6 @@ public:
nsINode* aEndParent, int32_t aEndOffset,
bool aClampToEdge, bool aFlushLayout);
/**
* Scan this range for -moz-user-select:none nodes and split it up into
* multiple ranges to exclude those nodes. The resulting ranges are put
* in aOutRanges. If no -moz-user-select:none node is found in the range
* then |this| is unmodified and is the only range in aOutRanges.
* Otherwise, |this| will be modified so that it ends before the first
* -moz-user-select:none node and additional ranges may also be created.
* If all nodes in the range are -moz-user-select:none then aOutRanges
* will be empty.
* @param aOutRanges the resulting set of ranges
*/
void ExcludeNonSelectableNodes(nsTArray<nsRefPtr<nsRange>>* aOutRanges);
typedef nsTHashtable<nsPtrHashKey<nsRange> > RangeHashTable;
protected:
void RegisterCommonAncestor(nsINode* aNode);

View File

@ -656,5 +656,3 @@ skip-if = buildapp == 'b2g' || e10s
support-files = file_bug1011748_redirect.sjs file_bug1011748_OK.sjs
[test_bug1025933.html]
[test_element.matches.html]
[test_user_select.html]
skip-if = buildapp == 'b2g'

View File

@ -1,259 +0,0 @@
<!DOCTYPE>
<html>
<head>
<title>-moz-user-select selection tests</title>
<script src="/tests/SimpleTest/SimpleTest.js"></script>
<script src="/tests/SimpleTest/EventUtils.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
<style type="text/css">
@font-face {
font-family: Ahem;
src: url("Ahem.ttf");
}
body { font-family: Ahem; font-size: 20px; }
s { -moz-user-select: none; }
n { display: none; }
</style>
</head>
<body>
<div id="test1">aaaaaaa<s>bbbbbbbb</s>ccccccc</div>
<div id="test2"><s>aaaaaaa</s>bbbbbbbbccccccc</div>
<div id="test3">aaaaaaabbbbbbbb<s>ccccccc</s></div>
<div id="test4">aaaaaaa<x><s>bbbbbbbb</s></x>ccccccc</div>
<div id="test5"><x><s>aaaaaaa</s></x>bbbbbbbbccccccc</div>
<div id="test6">aaaaaaabbbbbbbb<x><s>ccccccc</s></x></div>
<div id="test7">aaaaaaa<x><s><n>bbbb</n>bbbb</s></x>ccccccc</div>
<div id="test8"><x><s>aa<n>aaa</n>aa</s></x>bbbbbbbbccccccc</div>
<div id="test9">aaaaaaabbbbbbbb<x><s>cc<n>ccccc</n></s></x></div>
<div id="testA">aaaaaaa<n>bbb<s>bbbbb</s></n>ccccccc</div>
<div id="testB"><n><s>aaaa</s>aaa</n>bbbbbbbbccccccc</div>
<div id="testC">aaaaaaabbbbbbbb<n>cc<s>c</s>cccc</n></div>
<iframe id="testD" src="data:text/html,<body>aaaa<span style='-moz-user-select:none'>bbbb</span>cccc"></iframe>
<pre id="test">
<script class="testbody" type="text/javascript">
function test()
{
function clear(w)
{
var sel = (w ? w : window).getSelection();
sel.removeAllRanges();
}
function dragSelect(e, x1, x2, x3)
{
dir = x2 > x1 ? 1 : -1;
synthesizeMouse(e, x1, 5, { type: "mousedown" });
synthesizeMouse(e, x1 + dir, 5, { type: "mousemove" });
if (x3)
synthesizeMouse(e, x3, 5, { type: "mousemove" });
synthesizeMouse(e, x2 - dir, 5, { type: "mousemove" });
synthesizeMouse(e, x2, 5, { type: "mouseup" });
}
function shiftClick(e, x)
{
synthesizeMouse(e, x, 5, { type: "mousedown", shiftKey: true });
synthesizeMouse(e, x, 5, { type: "mouseup", shiftKey: true });
}
function init(arr, e)
{
clear();
var sel = window.getSelection();
for (i = 0; i < arr.length; ++i) {
var data = arr[i];
var r = new Range()
r.setStart(node(e, data[0]), data[1]);
r.setEnd(node(e, data[2]), data[3]);
sel.addRange(r);
}
}
function checkText(text, e)
{
var sel = window.getSelection();
is(sel.toString(), text, e.id + ": selected text")
}
function checkRangeText(text, index)
{
var r = window.getSelection().getRangeAt(index);
is(r.toString(), text, e.id + ": range["+index+"].toString()")
}
function node(e, index)
{
return index == -1 ? e : e.childNodes[index];
}
function checkRanges(arr, e)
{
var sel = window.getSelection();
is(sel.rangeCount, arr.length, e.id + ": Selection range count");
for (i = 0; i < arr.length; ++i) {
var expected = arr[i];
var r = sel.getRangeAt(i);
is(r.startContainer, node(e, expected[0]), e.id + ": range["+i+"].startContainer");
is(r.startOffset, expected[1], e.id + ": range["+i+"].startOffset");
is(r.endContainer, node(e, expected[2]), e.id + ": range["+i+"].endContainer");
is(r.endOffset, expected[3], e.id + ": range["+i+"].endOffset");
}
}
// ======================================================
// ================== dragSelect tests ==================
// ======================================================
var e = document.getElementById('test1');
dragSelect(e, 20, 340);
checkText('aaaaaacc', e);
checkRanges([[0,1,-1,1], [2,0,2,2]], e);
clear();
dragSelect(e, 20, 260, 120);
checkText('aaaaa', e);
checkRanges([[0,1,0,6]], e);
clear();
e = document.getElementById('test2');
dragSelect(e, 20, 340);
checkText('', e);
checkRanges([], e);
clear();
dragSelect(e, 340, 20, 140);
checkText('bbbbbbbbcc', e);
checkRanges([[1,0,1,10]], e);
clear();
e = document.getElementById('test3');
dragSelect(e, 20, 340, 295);
checkText('aaaaaabbbbbbbb', e);
checkRanges([[0,1,0,15]], e);
clear();
e = document.getElementById('test4');
dragSelect(e, 20, 340);
checkText('aaaaaacc', e);
checkRanges([[0,1,1,0], [2,0,2,2]], e);
clear();
e = document.getElementById('test5');
dragSelect(e, 340, 20, 140);
checkText('bbbbbbbbcc', e);
checkRanges([[1,0,1,10]], e);
clear();
e = document.getElementById('test6');
dragSelect(e, 20, 340, 295);
checkText('aaaaaabbbbbbbb', e);
checkRanges([[0,1,0,15]], e);
clear();
e = document.getElementById('test7');
dragSelect(e, 20, 340);
checkText('aaaaaacccccc', e);
checkRanges([[0,1,1,0], [2,0,2,6]], e);
clear();
e = document.getElementById('test8');
dragSelect(e, 340, 20, 140);
checkText('bbbbbccccc', e);
checkRanges([[1,3,1,13]], e);
clear();
e = document.getElementById('test9');
dragSelect(e, 20, 340, 295);
checkText('aaaaaabbbbbbbb', e);
checkRanges([[0,1,0,15]], e);
clear();
e = document.getElementById('testA');
dragSelect(e, 20, 340);
checkText('aaaaaaccccccc', e);
checkRanges([[0,1,2,7]], e);
checkRangeText('aaaaaabbbbbbbbccccccc', 0);
clear();
e = document.getElementById('testB');
dragSelect(e, 340, 20, 140);
checkText('bbbbbbbccccccc', e);
checkRanges([[1,1,1,15]], e);
clear();
e = document.getElementById('test9');
dragSelect(e, 20, 340, 295);
checkText('aaaaaabbbbbbbb', e);
checkRanges([[0,1,0,15]], e);
// ======================================================
// ================== shift+click tests =================
// ======================================================
// test extending a selection that starts in a -moz-user-select:none node
clear();
e = document.getElementById('test2');
init([[0,0,0,1]], e);
checkRangeText('aaaaaaa', 0);
checkText('', e);
shiftClick(e, 340);
checkRangeText('bbbbbbbbcc', 0);
checkText('bbbbbbbbcc', e);
checkRanges([[-1,1,1,10]], e);
// test extending a selection that end in a -moz-user-select:none node
clear();
e = document.getElementById('test3');
init([[1,0,1,1]], e);
checkRangeText('ccccccc', 0);
checkText('', e);
shiftClick(e, 20);
checkRangeText('aaaaaabbbbbbbb', 0);
checkText('aaaaaabbbbbbbb', e);
checkRanges([[0,1,-1,1]], e);
// ======================================================
// ==================== Script tests ====================
// ======================================================
clear();
e = document.getElementById('testD');
clear(e.contentWindow);
sel = e.contentWindow.getSelection();
sel.selectAllChildren(e.contentDocument.body);
is(window.getSelection().rangeCount, 0, "testD: no selection in outer window");
is(sel.toString(), 'aaaacccc', "testD: scripted selection");
is(sel.rangeCount, 1, "testD: scripted selection isn't filtered");
is(sel.getRangeAt(0).toString(), 'aaaabbbbcccc', "testD: scripted selection isn't filtered");
// ======================================================
// ================== Kbd command tests =================
// ======================================================
clear();
e = document.getElementById('testD');
clear(e.contentWindow);
e.contentWindow.focus();
synthesizeKey("a", { accelKey:true }, e.contentWindow);
sel = e.contentWindow.getSelection();
is(window.getSelection().rangeCount, 0, "testD: no selection in outer window");
is(sel.toString(), 'aaaacccc', "testD: kbd selection");
is(sel.rangeCount, 2, "testD: kbd selection is filtered");
is(sel.getRangeAt(0).toString(), 'aaaa', "testD: kbd selection is filtered");
is(sel.getRangeAt(1).toString(), 'cccc', "testD: kbd selection is filtered");
clear();
SimpleTest.finish();
}
window.onload = function() { setTimeout(test, 0); };
SimpleTest.waitForExplicitFinish();
</script>
</pre>
</body>
</html>

View File

@ -28,7 +28,7 @@
#include "nsILinkHandler.h"
#include "nsIDOMDocument.h"
#include "nsISelectionListener.h"
#include "mozilla/dom/Selection.h"
#include "nsISelectionPrivate.h"
#include "nsIDOMHTMLDocument.h"
#include "nsIDOMHTMLElement.h"
#include "nsContentUtils.h"
@ -316,7 +316,7 @@ private:
nsresult SyncParentSubDocMap();
mozilla::dom::Selection* GetDocumentSelection();
nsresult GetDocumentSelection(nsISelection **aSelection);
void DestroyPresShell();
void DestroyPresContext();
@ -704,12 +704,12 @@ nsDocumentViewer::InitPresentationStuff(bool aDoInitialReflow)
mSelectionListener = selectionListener;
}
nsRefPtr<mozilla::dom::Selection> selection = GetDocumentSelection();
if (!selection) {
return NS_ERROR_FAILURE;
}
nsCOMPtr<nsISelection> selection;
rv = GetDocumentSelection(getter_AddRefs(selection));
NS_ENSURE_SUCCESS(rv, rv);
rv = selection->AddSelectionListener(mSelectionListener);
nsCOMPtr<nsISelectionPrivate> selPrivate(do_QueryInterface(selection));
rv = selPrivate->AddSelectionListener(mSelectionListener);
if (NS_FAILED(rv))
return rv;
@ -2562,14 +2562,19 @@ nsDocumentViewer::CreateDeviceContext(nsView* aContainerView)
// Return the selection for the document. Note that text fields have their
// own selection, which cannot be accessed with this method.
mozilla::dom::Selection*
nsDocumentViewer::GetDocumentSelection()
nsresult nsDocumentViewer::GetDocumentSelection(nsISelection **aSelection)
{
NS_ENSURE_ARG_POINTER(aSelection);
if (!mPresShell) {
return nullptr;
return NS_ERROR_NOT_INITIALIZED;
}
return mPresShell->GetCurrentSelection(nsISelectionController::SELECTION_NORMAL);
nsCOMPtr<nsISelectionController> selcon;
selcon = do_QueryInterface(mPresShell);
if (selcon)
return selcon->GetSelection(nsISelectionController::SELECTION_NORMAL,
aSelection);
return NS_ERROR_FAILURE;
}
/* ========================================================================================
@ -2578,11 +2583,12 @@ nsDocumentViewer::GetDocumentSelection()
NS_IMETHODIMP nsDocumentViewer::ClearSelection()
{
nsresult rv;
nsCOMPtr<nsISelection> selection;
// use nsCopySupport::GetSelectionForCopy() ?
nsRefPtr<mozilla::dom::Selection> selection = GetDocumentSelection();
if (!selection) {
return NS_ERROR_FAILURE;
}
rv = GetDocumentSelection(getter_AddRefs(selection));
if (NS_FAILED(rv)) return rv;
return selection->CollapseToStart();
}
@ -2592,17 +2598,16 @@ NS_IMETHODIMP nsDocumentViewer::SelectAll()
// XXX this is a temporary implementation copied from nsWebShell
// for now. I think nsDocument and friends should have some helper
// functions to make this easier.
nsCOMPtr<nsISelection> selection;
nsresult rv;
// use nsCopySupport::GetSelectionForCopy() ?
nsRefPtr<mozilla::dom::Selection> selection = GetDocumentSelection();
if (!selection) {
return NS_ERROR_FAILURE;
}
rv = GetDocumentSelection(getter_AddRefs(selection));
if (NS_FAILED(rv)) return rv;
nsCOMPtr<nsIDOMHTMLDocument> htmldoc = do_QueryInterface(mDocument);
nsCOMPtr<nsIDOMNode> bodyNode;
nsresult rv;
if (htmldoc)
{
nsCOMPtr<nsIDOMHTMLElement>bodyElement;
@ -2620,7 +2625,6 @@ NS_IMETHODIMP nsDocumentViewer::SelectAll()
rv = selection->RemoveAllRanges();
if (NS_FAILED(rv)) return rv;
mozilla::dom::Selection::AutoApplyUserSelectStyle userSelection(selection);
rv = selection->SelectAllChildren(bodyNode);
return rv;
}
@ -3544,10 +3548,9 @@ NS_IMETHODIMP nsDocViewerSelectionListener::NotifySelectionChanged(nsIDOMDocumen
NS_ASSERTION(mDocViewer, "Should have doc viewer!");
// get the selection state
nsRefPtr<mozilla::dom::Selection> selection = mDocViewer->GetDocumentSelection();
if (!selection) {
return NS_ERROR_FAILURE;
}
nsCOMPtr<nsISelection> selection;
nsresult rv = mDocViewer->GetDocumentSelection(getter_AddRefs(selection));
if (NS_FAILED(rv)) return rv;
nsIDocument* theDoc = mDocViewer->GetDocument();
if (!theDoc) return NS_ERROR_FAILURE;
@ -4429,9 +4432,11 @@ nsDocumentViewer::DestroyPresShell()
// Break circular reference (or something)
mPresShell->EndObservingDocument();
nsRefPtr<mozilla::dom::Selection> selection = GetDocumentSelection();
if (selection && mSelectionListener)
selection->RemoveSelectionListener(mSelectionListener);
nsCOMPtr<nsISelection> selection;
GetDocumentSelection(getter_AddRefs(selection));
nsCOMPtr<nsISelectionPrivate> selPrivate = do_QueryInterface(selection);
if (selPrivate && mSelectionListener)
selPrivate->RemoveSelectionListener(mSelectionListener);
nsRefPtr<SelectionCarets> selectionCaret = mPresShell->GetSelectionCarets();
if (selectionCaret) {

View File

@ -9,13 +9,12 @@
#include "nsIWeakReference.h"
#include "mozilla/AutoRestore.h"
#include "mozilla/TextRange.h"
#include "nsISelection.h"
#include "nsISelectionController.h"
#include "nsISelectionPrivate.h"
#include "nsRange.h"
#include "nsThreadUtils.h"
#include "mozilla/TextRange.h"
#include "nsWrapperCache.h"
struct CachedOffsetForFrame;
@ -101,14 +100,8 @@ public:
int32_t aFlags = 0);
nsresult SubtractRange(RangeData* aRange, nsRange* aSubtract,
nsTArray<RangeData>* aOutput);
/**
* AddItem adds aRange to this Selection. If mApplyUserSelectStyle is true,
* then aRange is first scanned for -moz-user-select:none nodes and split up
* into multiple ranges to exclude those before adding the resulting ranges
* to this Selection.
*/
nsresult AddItem(nsRange* aRange, int32_t* aOutIndex);
nsresult RemoveItem(nsRange* aRange);
nsresult AddItem(nsRange *aRange, int32_t* aOutIndex);
nsresult RemoveItem(nsRange *aRange);
nsresult RemoveCollapsedRanges();
nsresult Clear(nsPresContext* aPresContext);
nsresult Collapse(nsINode* aParentNode, int32_t aOffset);
@ -212,19 +205,6 @@ public:
nsresult NotifySelectionListeners();
friend struct AutoApplyUserSelectStyle;
struct MOZ_STACK_CLASS AutoApplyUserSelectStyle
{
AutoApplyUserSelectStyle(Selection* aSelection
MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
: mSavedValue(aSelection->mApplyUserSelectStyle)
{
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
aSelection->mApplyUserSelectStyle = true;
}
AutoRestore<bool> mSavedValue;
MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
};
private:
class ScrollSelectionIntoViewEvent;
@ -278,11 +258,6 @@ private:
int32_t* aStartIndex, int32_t* aEndIndex);
RangeData* FindRangeData(nsIDOMRange* aRange);
/**
* Helper method for AddItem.
*/
nsresult AddItemInternal(nsRange* aRange, int32_t* aOutIndex);
// These are the ranges inside this selection. They are kept sorted in order
// of DOM start position.
//
@ -306,11 +281,6 @@ private:
CachedOffsetForFrame *mCachedOffsetForFrame;
nsDirection mDirection;
SelectionType mType;
/**
* True if the current selection operation was initiated by user action.
* It determines whether we exclude -moz-user-select:none nodes or not.
*/
bool mApplyUserSelectStyle;
};
} // namespace dom

View File

@ -12,7 +12,6 @@
#include "nsIFrame.h"
#include "nsIContent.h"
#include "nsISelectionController.h"
#include "nsISelectionListener.h"
#include "nsITableCellLayout.h"
#include "nsIDOMElement.h"
#include "WordMovementType.h"
@ -614,18 +613,9 @@ private:
int16_t PopReason()
{
int16_t retval = mSelectionChangeReason;
mSelectionChangeReason = nsISelectionListener::NO_REASON;
mSelectionChangeReason = 0;
return retval;
}
bool IsUserSelectionReason() const
{
return (mSelectionChangeReason &
(nsISelectionListener::DRAG_REASON |
nsISelectionListener::MOUSEDOWN_REASON |
nsISelectionListener::MOUSEUP_REASON |
nsISelectionListener::KEYPRESS_REASON)) !=
nsISelectionListener::NO_REASON;
}
friend class mozilla::dom::Selection;
#ifdef DEBUG

View File

@ -1548,11 +1548,6 @@ nsFrameSelection::TakeFocus(nsIContent* aNewFocus,
if (!mDomSelections[index])
return NS_ERROR_NULL_POINTER;
Maybe<Selection::AutoApplyUserSelectStyle> userSelect;
if (IsUserSelectionReason()) {
userSelect.emplace(mDomSelections[index]);
}
//traverse through document and unselect crap here
if (!aContinueSelection) {//single click? setting cursor down
uint32_t batching = mBatching;//hack to use the collapse code.
@ -3108,7 +3103,6 @@ Selection::Selection()
: mCachedOffsetForFrame(nullptr)
, mDirection(eDirNext)
, mType(nsISelectionController::SELECTION_NORMAL)
, mApplyUserSelectStyle(false)
{
SetIsDOMBinding();
}
@ -3118,7 +3112,6 @@ Selection::Selection(nsFrameSelection* aList)
, mCachedOffsetForFrame(nullptr)
, mDirection(eDirNext)
, mType(nsISelectionController::SELECTION_NORMAL)
, mApplyUserSelectStyle(false)
{
SetIsDOMBinding();
}
@ -3461,25 +3454,6 @@ Selection::AddItem(nsRange* aItem, int32_t* aOutIndex)
NS_ASSERTION(aOutIndex, "aOutIndex can't be null");
if (mApplyUserSelectStyle) {
nsAutoTArray<nsRefPtr<nsRange>, 4> rangesToAdd;
aItem->ExcludeNonSelectableNodes(&rangesToAdd);
for (size_t i = 0; i < rangesToAdd.Length(); ++i) {
nsresult rv = AddItemInternal(rangesToAdd[i], aOutIndex);
NS_ENSURE_SUCCESS(rv, rv);
}
return NS_OK;
}
return AddItemInternal(aItem, aOutIndex);
}
nsresult
Selection::AddItemInternal(nsRange* aItem, int32_t* aOutIndex)
{
MOZ_ASSERT(aItem);
MOZ_ASSERT(aItem->IsPositioned());
MOZ_ASSERT(aOutIndex);
*aOutIndex = -1;
// a common case is that we have no ranges yet
@ -4469,7 +4443,8 @@ Selection::AddRange(nsRange& aRange, ErrorResult& aRv)
return;
}
if (!didAddRange) {
if (!didAddRange)
{
result = AddItem(&aRange, &rangeIndex);
if (NS_FAILED(result)) {
aRv.Throw(result);
@ -4477,10 +4452,7 @@ Selection::AddRange(nsRange& aRange, ErrorResult& aRv)
}
}
if (rangeIndex < 0) {
return;
}
NS_ASSERTION(rangeIndex >= 0, "Range index not returned");
setAnchorFocusRange(rangeIndex);
// Make sure the caret appears on the next line, if at a newline
@ -4949,48 +4921,7 @@ Selection::Extend(nsINode& aParentNode, uint32_t aOffset, ErrorResult& aRv)
return;
}
nsDirection dir = GetDirection();
// If aParentNode is inside a range in a multi-range selection we need
// to remove the ranges that follows in the selection direction and
// make that range the mAnchorFocusRange.
if (mRanges.Length() > 1) {
for (size_t i = 0; i < mRanges.Length(); ++i) {
nsRange* range = mRanges[i].mRange;
bool disconnected1 = false;
bool disconnected2 = false;
const bool isBeforeStart =
nsContentUtils::ComparePoints(range->GetStartParent(),
range->StartOffset(),
&aParentNode, aOffset,
&disconnected1) > 0;
const bool isAfterEnd =
nsContentUtils::ComparePoints(range->GetEndParent(),
range->EndOffset(),
&aParentNode, aOffset,
&disconnected2) < 0;
if (!isBeforeStart && !isAfterEnd && !disconnected1 && !disconnected2) {
// aParentNode/aOffset is inside 'range'.
mAnchorFocusRange = range;
if (dir == eDirNext) {
for (size_t j = i + 1; j < mRanges.Length(); ++j) {
nsRange* r = mRanges[j].mRange;
r->SetInSelection(false);
selectFrames(presContext, r, false);
}
mRanges.TruncateLength(i + 1);
} else {
for (size_t j = 0; j < i; ++j) {
nsRange* r = mRanges[j].mRange;
r->SetInSelection(false);
selectFrames(presContext, r, false);
}
mRanges.RemoveElementsAt(0, i);
}
break;
}
}
}
//mFrameSelection->InvalidateDesiredX();
nsINode* anchorNode = GetAnchorNode();
nsINode* focusNode = GetFocusNode();
@ -5004,6 +4935,8 @@ Selection::Extend(nsINode& aParentNode, uint32_t aOffset, ErrorResult& aRv)
int32_t startOffset = range->StartOffset();
int32_t endOffset = range->EndOffset();
nsDirection dir = GetDirection();
//compare anchor to old cursor.
// We pass |disconnected| to the following ComparePoints calls in order
@ -5229,14 +5162,6 @@ Selection::Extend(nsINode& aParentNode, uint32_t aOffset, ErrorResult& aRv)
}
}
if (mRanges.Length() > 1) {
for (size_t i = 0; i < mRanges.Length(); ++i) {
nsRange* range = mRanges[i].mRange;
MOZ_ASSERT(range->IsInSelection());
selectFrames(presContext, range, range->IsInSelection());
}
}
DEBUG_OUT_RANGE(range);
#ifdef DEBUG_SELECTION
if (eDirNext == mDirection)