diff --git a/dom/base/nsCopySupport.cpp b/dom/base/nsCopySupport.cpp index 60a94d9884..9517a30fa6 100644 --- a/dom/base/nsCopySupport.cpp +++ b/dom/base/nsCopySupport.cpp @@ -298,6 +298,8 @@ nsCopySupport::GetTransferableForNode(nsINode* aNode, { nsCOMPtr selection; // Make a temporary selection with aNode in a single range. + // XXX For better performance, we should try to get rid of the + // Selection object here. See BMO bug 1245883 nsresult rv = NS_NewDomSelection(getter_AddRefs(selection)); NS_ENSURE_SUCCESS(rv, rv); nsCOMPtr node = do_QueryInterface(aNode); @@ -305,7 +307,9 @@ nsCopySupport::GetTransferableForNode(nsINode* aNode, nsRefPtr 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; diff --git a/dom/base/nsDocumentEncoder.cpp b/dom/base/nsDocumentEncoder.cpp index 3471ebac36..7ea49009b4 100644 --- a/dom/base/nsDocumentEncoder.cpp +++ b/dom/base/nsDocumentEncoder.cpp @@ -1396,6 +1396,9 @@ nsHTMLCopyEncoder::SetSelection(nsISelection* aSelection) } #endif + // XXX For better performance, we should try to get rid of the + // Selection object here. See BMO bug 1245883 + // also consider ourselves in a text widget if we can't find an html document nsCOMPtr htmlDoc = do_QueryInterface(mDocument); if (!(htmlDoc && mDocument->IsHTML())) { @@ -1423,7 +1426,10 @@ nsHTMLCopyEncoder::SetSelection(nsISelection* aSelection) rv = PromoteRange(myRange); NS_ENSURE_SUCCESS(rv, rv); - rv = mSelection->AddRange(myRange); + ErrorResult result; + nsRange* r = static_cast(myRange.get()); + mSelection->AsSelection()->AddRangeInternal(*r, mDocument, result); + rv = result.StealNSResult(); NS_ENSURE_SUCCESS(rv, rv); } diff --git a/layout/generic/Selection.h b/layout/generic/Selection.h index 875bc01e20..14ad1e78ef 100644 --- a/layout/generic/Selection.h +++ b/layout/generic/Selection.h @@ -24,6 +24,8 @@ class nsIContentIterator; class nsIFrame; class nsFrameSelection; struct SelectionDetails; +class nsCopySupport; +class nsHTMLCopyEncoder; namespace mozilla { class ErrorResult; @@ -209,6 +211,12 @@ private: // 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 (BMO bug 1245883) in the following classes: + friend class ::nsCopySupport; + friend class ::nsHTMLCopyEncoder; + void AddRangeInternal(nsRange& aRange, nsIDocument* aDocument, ErrorResult&); + public: SelectionType GetType(){return mType;} void SetType(SelectionType aType){mType = aType;} diff --git a/layout/generic/nsSelection.cpp b/layout/generic/nsSelection.cpp index 6d1808df6e..fb8fcd66a5 100644 --- a/layout/generic/nsSelection.cpp +++ b/layout/generic/nsSelection.cpp @@ -4632,6 +4632,22 @@ Selection::AddRange(nsIDOMRange* aDOMRange) 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(); + 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 bool didAddRange;