Bug 1341137 part 2 - Provide a way to add ranges to Selection objects that aren't associated with a shell/nsFrameSelection. r=smaug
--- a/dom/base/nsCopySupport.cpp
+++ b/dom/base/nsCopySupport.cpp
@@ -329,24 +329,28 @@ nsCopySupport::GetTransferableForSelecti
nsresult
nsCopySupport::GetTransferableForNode(nsINode* aNode,
nsIDocument* aDoc,
nsITransferable** aTransferable)
{
nsCOMPtr<nsISelection> selection;
// Make a temporary selection with aNode in a single range.
+ // XXX We should try to get rid of the Selection object here.
+ // XXX bug 1245883
nsresult rv = NS_NewDomSelection(getter_AddRefs(selection));
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIDOMNode> node = do_QueryInterface(aNode);
NS_ENSURE_TRUE(node, NS_ERROR_FAILURE);
RefPtr<nsRange> range = new nsRange(aNode);
rv = range->SelectNode(node);
NS_ENSURE_SUCCESS(rv, rv);
- rv = selection->AddRange(range);
+ ErrorResult result;
+ selection->AsSelection()->AddRangeInternal(*range, aDoc, result);
+ rv = result.StealNSResult();
NS_ENSURE_SUCCESS(rv, rv);
// It's not the primary selection - so don't skip invisible content.
uint32_t flags = 0;
return SelectionCopyHelper(selection, aDoc, false, 0, flags,
aTransferable);
}
nsresult nsCopySupport::DoHooks(nsIDocument *aDoc, nsITransferable *aTrans,
--- a/dom/base/nsDocumentEncoder.cpp
+++ b/dom/base/nsDocumentEncoder.cpp
@@ -1398,16 +1398,19 @@ nsHTMLCopyEncoder::SetSelection(nsISelec
// normalize selection if we are not in a widget
if (mIsTextWidget)
{
mSelection = aSelection;
mMimeType.AssignLiteral("text/plain");
return NS_OK;
}
+ // XXX We should try to get rid of the Selection object here.
+ // XXX bug 1245883
+
// also consider ourselves in a text widget if we can't find an html document
nsCOMPtr<nsIHTMLDocument> htmlDoc = do_QueryInterface(mDocument);
if (!(htmlDoc && mDocument->IsHTMLDocument())) {
mIsTextWidget = true;
mSelection = aSelection;
// mMimeType is set to text/plain when encoding starts.
return NS_OK;
}
@@ -1425,17 +1428,20 @@ nsHTMLCopyEncoder::SetSelection(nsISelec
nsCOMPtr<nsIDOMRange> myRange;
range->CloneRange(getter_AddRefs(myRange));
NS_ENSURE_TRUE(myRange, NS_ERROR_FAILURE);
// adjust range to include any ancestors who's children are entirely selected
rv = PromoteRange(myRange);
NS_ENSURE_SUCCESS(rv, rv);
- rv = mSelection->AddRange(myRange);
+ ErrorResult result;
+ nsRange* r = static_cast<nsRange*>(myRange.get());
+ mSelection->AsSelection()->AddRangeInternal(*r, mDocument, result);
+ rv = result.StealNSResult();
NS_ENSURE_SUCCESS(rv, rv);
}
return NS_OK;
}
NS_IMETHODIMP
nsHTMLCopyEncoder::EncodeToString(nsAString& aOutputString)
--- a/layout/generic/Selection.h
+++ b/layout/generic/Selection.h
@@ -21,16 +21,18 @@
#include "nsWrapperCache.h"
struct CachedOffsetForFrame;
class nsAutoScrollTimer;
class nsIContentIterator;
class nsIFrame;
class nsFrameSelection;
struct SelectionDetails;
+class nsCopySupport;
+class nsHTMLCopyEncoder;
namespace mozilla {
class ErrorResult;
struct AutoPrepareFocusRange;
} // namespace mozilla
struct RangeData
{
@@ -239,16 +241,22 @@ public:
void RemoveSelectionChangeBlocker();
bool IsBlockingSelectionChangeEvents() const;
private:
friend class ::nsAutoScrollTimer;
// Note: DoAutoScroll might destroy arbitrary frames etc.
nsresult DoAutoScroll(nsIFrame *aFrame, nsPoint& aPoint);
+ // 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;
+ friend class ::nsHTMLCopyEncoder;
+ void AddRangeInternal(nsRange& aRange, nsIDocument* aDocument, ErrorResult&);
+
public:
SelectionType GetType() const { return mSelectionType; }
void SetType(SelectionType aSelectionType)
{
mSelectionType = aSelectionType;
}
nsresult NotifySelectionListeners();
--- a/layout/generic/nsSelection.cpp
+++ b/layout/generic/nsSelection.cpp
@@ -4959,20 +4959,26 @@ Selection::AddRange(nsIDOMRange* aDOMRan
ErrorResult result;
AddRange(*range, result);
return result.StealNSResult();
}
void
Selection::AddRange(nsRange& aRange, ErrorResult& aRv)
{
+ return AddRangeInternal(aRange, GetParentObject(), aRv);
+}
+
+void
+Selection::AddRangeInternal(nsRange& aRange, nsIDocument* aDocument,
+ ErrorResult& aRv)
+{
nsINode* rangeRoot = aRange.GetRoot();
- nsIDocument* doc = GetParentObject();
- if (doc != rangeRoot && (!rangeRoot ||
- doc != rangeRoot->GetComposedDoc())) {
+ if (aDocument != rangeRoot && (!rangeRoot ||
+ aDocument != rangeRoot->GetComposedDoc())) {
// http://w3c.github.io/selection-api/#dom-selection-addrange
// "... if the root of the range's boundary points are the document
// associated with context object. Otherwise, this method must do nothing."
return;
}
// This inserts a table cell range in proper document order
// and returns NS_OK if range doesn't contain just one table cell