Make DOM selection addRange spec-compliant, take 2.

Because of the platform structure, we have to provide a way to add ranges to
Selection objects that aren't associated with a shell/nsFrameSelection.
This commit extends the original implementation with workarounds to add
these ranges by reaching into the internal implementation for adding ranges
and calling those functions directly.
This commit is contained in:
Pale Moon
2017-03-19 12:12:27 +01:00
committed by roytam1
parent 27b63aa0cc
commit 00c0512ccb
4 changed files with 36 additions and 2 deletions
+5 -1
View File
@@ -298,6 +298,8 @@ nsCopySupport::GetTransferableForNode(nsINode* aNode,
{
nsCOMPtr<nsISelection> 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<nsIDOMNode> node = do_QueryInterface(aNode);
@@ -305,7 +307,9 @@ nsCopySupport::GetTransferableForNode(nsINode* aNode,
nsRefPtr<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;
+7 -1
View File
@@ -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<nsIHTMLDocument> 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<nsRange*>(myRange.get());
mSelection->AsSelection()->AddRangeInternal(*r, mDocument, result);
rv = result.StealNSResult();
NS_ENSURE_SUCCESS(rv, rv);
}
+8
View File
@@ -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;}
+16
View File
@@ -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;