Bug 1341137 part 2 - Provide a way to add ranges to Selection objects that aren't associated with a shell/nsFrameSelection. r=smaug
authorMats Palmgren <mats@mozilla.com>
Sat, 25 Feb 2017 11:33:34 +0100
changeset 344932 31f4db063fe85475ac31401318a6dfa80bccd28f
parent 344931 e9764fc002e8791215e13accf181ad5902c85d09
child 344933 3fd74df6d77fb1384481c370c7c155fc5065cdeb
push id37977
push userphilringnalda@gmail.com
push dateSat, 25 Feb 2017 21:34:46 +0000
treeherderautoland@10bfa931c92f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug
bugs1341137
milestone54.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1341137 part 2 - Provide a way to add ranges to Selection objects that aren't associated with a shell/nsFrameSelection. r=smaug
dom/base/nsCopySupport.cpp
dom/base/nsDocumentEncoder.cpp
layout/generic/Selection.h
layout/generic/nsSelection.cpp
--- 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