Bug 1185307 part.2 Replace upcast from nsISelection to mozilla::dom::Selection with nsISelection::AsSelection() r?smaug draft
authorMasayuki Nakano <masayuki@d-toybox.com>
Fri, 17 Jun 2016 22:32:49 +0900
changeset 380007 a86c0e7e9758b97dc2648afc0cff049daec61e77
parent 380006 ca8fdcf1473c7854bef16578a5f8cd09501ba093
child 523618 f8a6dfa39b6f3f13e0dea41de80ead14662bfee6
push id21108
push usermasayuki@d-toybox.com
push dateMon, 20 Jun 2016 10:11:38 +0000
reviewerssmaug
bugs1185307
milestone50.0a1
Bug 1185307 part.2 Replace upcast from nsISelection to mozilla::dom::Selection with nsISelection::AsSelection() r?smaug MozReview-Commit-ID: Gs3oiAgJFG9
accessible/base/SelectionManager.cpp
dom/base/nsDocumentEncoder.cpp
dom/base/nsGlobalWindow.cpp
dom/events/ContentEventHandler.cpp
editor/composer/nsEditorSpellCheck.cpp
editor/libeditor/TypeInState.cpp
editor/libeditor/nsEditor.cpp
editor/libeditor/nsHTMLEditRules.cpp
editor/libeditor/nsTextEditRulesBidi.cpp
editor/txtsvc/nsTextServicesDocument.cpp
layout/base/nsCaret.cpp
layout/base/nsPresShell.cpp
layout/forms/nsTextControlFrame.cpp
layout/generic/nsSelection.cpp
--- a/accessible/base/SelectionManager.cpp
+++ b/accessible/base/SelectionManager.cpp
@@ -162,32 +162,34 @@ SelectionManager::ProcessTextSelChangeEv
   }
 }
 
 NS_IMETHODIMP
 SelectionManager::NotifySelectionChanged(nsIDOMDocument* aDOMDocument,
                                          nsISelection* aSelection,
                                          int16_t aReason)
 {
-  NS_ENSURE_ARG(aDOMDocument);
+  if (NS_WARN_IF(!aDOMDocument) || NS_WARN_IF(!aSelection)) {
+    return NS_ERROR_INVALID_ARG;
+  }
 
   nsCOMPtr<nsIDocument> documentNode(do_QueryInterface(aDOMDocument));
   DocAccessible* document = GetAccService()->GetDocAccessible(documentNode);
 
 #ifdef A11Y_LOG
   if (logging::IsEnabled(logging::eSelection))
     logging::SelChange(aSelection, document, aReason);
 #endif
 
   if (document) {
     // Selection manager has longer lifetime than any document accessible,
     // so that we are guaranteed that the notification is processed before
     // the selection manager is destroyed.
     RefPtr<SelData> selData =
-      new SelData(static_cast<Selection*>(aSelection), aReason);
+      new SelData(aSelection->AsSelection(), aReason);
     document->HandleNotification<SelectionManager, SelData>
       (this, &SelectionManager::ProcessSelectionChanged, selData);
   }
 
   return NS_OK;
 }
 
 void
--- a/dom/base/nsDocumentEncoder.cpp
+++ b/dom/base/nsDocumentEncoder.cpp
@@ -1407,17 +1407,17 @@ nsHTMLCopyEncoder::SetSelection(nsISelec
   // we don't tweak the selection to be outside of the magic
   // div that ender-lite text widgets are embedded in.
   
   if (!aSelection) 
     return NS_ERROR_NULL_POINTER;
   
   nsCOMPtr<nsIDOMRange> range;
   nsCOMPtr<nsIDOMNode> commonParent;
-  Selection* selection = static_cast<Selection*>(aSelection);
+  Selection* selection = aSelection->AsSelection();
   uint32_t rangeCount = selection->RangeCount();
 
   // if selection is uninitialized return
   if (!rangeCount)
     return NS_ERROR_FAILURE;
   
   // we'll just use the common parent of the first range.  Implicit assumption
   // here that multi-range selections are table cell selections, in which case
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -9422,19 +9422,19 @@ nsGlobalWindow::GetSelectionOuter()
   if (!mDocShell) {
     return nullptr;
   }
 
   nsCOMPtr<nsIPresShell> presShell = mDocShell->GetPresShell();
   if (!presShell) {
     return nullptr;
   }
-
-  return static_cast<Selection*>(
-           presShell->GetCurrentSelection(SelectionType::eNormal));
+  nsISelection* domSelection =
+    presShell->GetCurrentSelection(SelectionType::eNormal);
+  return domSelection ? domSelection->AsSelection() : nullptr;
 }
 
 Selection*
 nsGlobalWindow::GetSelection(ErrorResult& aError)
 {
   FORWARD_TO_OUTER_OR_THROW(GetSelectionOuter, (), aError, nullptr);
 }
 
--- a/dom/events/ContentEventHandler.cpp
+++ b/dom/events/ContentEventHandler.cpp
@@ -224,17 +224,20 @@ ContentEventHandler::InitCommon(Selectio
     nsCOMPtr<nsISelection> domSelection;
     nsresult rv =
       selectionController->GetSelection(
                              nsISelectionController::SELECTION_NORMAL,
                              getter_AddRefs(domSelection));
     if (NS_WARN_IF(NS_FAILED(rv))) {
       return NS_ERROR_UNEXPECTED;
     }
-    normalSelection = static_cast<Selection*>(domSelection.get());
+    if (NS_WARN_IF(!domSelection)) {
+      return NS_ERROR_NOT_AVAILABLE;
+    }
+    normalSelection = domSelection->AsSelection();
     if (NS_WARN_IF(!normalSelection)) {
       return NS_ERROR_NOT_AVAILABLE;
     }
   }
 
   rv = InitRootContent(normalSelection);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
@@ -2095,17 +2098,17 @@ ContentEventHandler::OnSelectionEvent(Wi
 
   // Get selection to manipulate
   // XXX why do we need to get them from ISM? This method should work fine
   //     without ISM.
   nsCOMPtr<nsISelection> sel;
   nsresult rv =
     IMEStateManager::GetFocusSelectionAndRoot(getter_AddRefs(sel),
                                               getter_AddRefs(mRootContent));
-  mSelection = static_cast<Selection*>(sel.get());
+  mSelection = sel ? sel->AsSelection() : nullptr;
   if (rv != NS_ERROR_NOT_AVAILABLE) {
     NS_ENSURE_SUCCESS(rv, rv);
   } else {
     rv = Init(aEvent);
     NS_ENSURE_SUCCESS(rv, rv);
   }
 
   // Get range from offset and length
--- a/editor/composer/nsEditorSpellCheck.cpp
+++ b/editor/composer/nsEditorSpellCheck.cpp
@@ -342,18 +342,20 @@ nsEditorSpellCheck::InitSpellChecker(nsI
   NS_ENSURE_SUCCESS(rv, rv);
 
   if (aEnableSelectionChecking) {
     // Find out if the section is collapsed or not.
     // If it isn't, we want to spellcheck just the selection.
 
     nsCOMPtr<nsISelection> domSelection;
     aEditor->GetSelection(getter_AddRefs(domSelection));
-    RefPtr<Selection> selection = static_cast<Selection*>(domSelection.get());
-    NS_ENSURE_TRUE(selection, NS_ERROR_FAILURE);
+    if (NS_WARN_IF(!domSelection)) {
+      return NS_ERROR_FAILURE;
+    }
+    RefPtr<Selection> selection = domSelection->AsSelection();
 
     int32_t count = 0;
 
     rv = selection->GetRangeCount(&count);
     NS_ENSURE_SUCCESS(rv, rv);
 
     if (count > 0) {
       RefPtr<nsRange> range = selection->GetRangeAt(0);
--- a/editor/libeditor/TypeInState.cpp
+++ b/editor/libeditor/TypeInState.cpp
@@ -78,17 +78,18 @@ NS_IMETHODIMP TypeInState::NotifySelecti
   // XXX: (bug 140303). It can notify us when the selection hasn't actually
   // XXX: changed, and it notifies us more than once for the same change.
   // XXX:
   // XXX: The following code attempts to work around the bogus notifications,
   // XXX: and should probably be removed once bug 140303 is fixed.
   // XXX:
   // XXX: This code temporarily fixes the problem where clicking the mouse in
   // XXX: the same location clears the type-in-state.
-  RefPtr<Selection> selection = static_cast<Selection*>(aSelection);
+  RefPtr<Selection> selection =
+    aSelection ? aSelection->AsSelection() : nullptr;
 
   if (aSelection) {
     int32_t rangeCount = selection->RangeCount();
 
     if (selection->Collapsed() && rangeCount) {
       nsCOMPtr<nsIDOMNode> selNode;
       int32_t selOffset = 0;
 
--- a/editor/libeditor/nsEditor.cpp
+++ b/editor/libeditor/nsEditor.cpp
@@ -656,21 +656,21 @@ nsEditor::GetSelection(SelectionType aSe
   return selcon->GetSelection(ToRawSelectionType(aSelectionType), aSelection);
 }
 
 Selection*
 nsEditor::GetSelection(SelectionType aSelectionType)
 {
   nsCOMPtr<nsISelection> sel;
   nsresult res = GetSelection(aSelectionType, getter_AddRefs(sel));
-  if (NS_FAILED(res)) {
+  if (NS_WARN_IF(NS_FAILED(res)) || NS_WARN_IF(!sel)) {
     return nullptr;
   }
 
-  return static_cast<Selection*>(sel.get());
+  return sel->AsSelection();
 }
 
 NS_IMETHODIMP
 nsEditor::DoTransaction(nsITransaction* aTxn)
 {
   if (mPlaceHolderBatch && !mPlaceHolderTxn) {
     nsCOMPtr<nsIAbsorbingTransaction> plcTxn = new PlaceholderTxn();
 
--- a/editor/libeditor/nsHTMLEditRules.cpp
+++ b/editor/libeditor/nsHTMLEditRules.cpp
@@ -8163,17 +8163,20 @@ nsHTMLEditRules::DidDeleteText(nsIDOMCha
 }
 
 NS_IMETHODIMP
 nsHTMLEditRules::WillDeleteSelection(nsISelection* aSelection)
 {
   if (!mListenerEnabled) {
     return NS_OK;
   }
-  RefPtr<Selection> selection = static_cast<Selection*>(aSelection);
+  if (NS_WARN_IF(!aSelection)) {
+    return NS_ERROR_INVALID_ARG;
+  }
+  RefPtr<Selection> selection = aSelection->AsSelection();
   // get the (collapsed) selection location
   nsCOMPtr<nsIDOMNode> selNode;
   int32_t selOffset;
 
   NS_ENSURE_STATE(mHTMLEditor);
   nsresult res = mHTMLEditor->GetStartNodeAndOffset(selection,
                                                     getter_AddRefs(selNode),
                                                     &selOffset);
--- a/editor/libeditor/nsTextEditRulesBidi.cpp
+++ b/editor/libeditor/nsTextEditRulesBidi.cpp
@@ -42,17 +42,17 @@ nsTextEditRules::CheckBidiLevelForDeleti
     return NS_OK;
 
   nsCOMPtr<nsIContent> content = do_QueryInterface(aSelNode);
   NS_ENSURE_TRUE(content, NS_ERROR_NULL_POINTER);
 
   nsBidiLevel levelBefore;
   nsBidiLevel levelAfter;
   RefPtr<nsFrameSelection> frameSelection =
-    static_cast<Selection*>(aSelection)->GetFrameSelection();
+    aSelection->AsSelection()->GetFrameSelection();
   NS_ENSURE_TRUE(frameSelection, NS_ERROR_NULL_POINTER);
 
   nsPrevNextBidiLevels levels = frameSelection->
     GetPrevNextBidiLevels(content, aSelOffset, true);
 
   levelBefore = levels.mLevelBefore;
   levelAfter = levels.mLevelAfter;
 
--- a/editor/txtsvc/nsTextServicesDocument.cpp
+++ b/editor/txtsvc/nsTextServicesDocument.cpp
@@ -518,17 +518,17 @@ nsTextServicesDocument::LastSelectedBloc
   result = mSelCon->GetSelection(nsISelectionController::SELECTION_NORMAL,
                                  getter_AddRefs(domSelection));
   if (NS_FAILED(result))
   {
     UNLOCK_DOC(this);
     return result;
   }
 
-  RefPtr<Selection> selection = static_cast<Selection*>(domSelection.get());
+  RefPtr<Selection> selection = domSelection->AsSelection();
 
   bool isCollapsed = selection->IsCollapsed();
 
   nsCOMPtr<nsIContentIterator> iter;
   RefPtr<nsRange> range;
   nsCOMPtr<nsIDOMNode>         parent;
   int32_t                      i, rangeCount, offset;
 
@@ -2521,17 +2521,17 @@ nsTextServicesDocument::GetCollapsedSele
 {
   nsCOMPtr<nsISelection> domSelection;
   nsresult result =
     mSelCon->GetSelection(nsISelectionController::SELECTION_NORMAL,
                           getter_AddRefs(domSelection));
   NS_ENSURE_SUCCESS(result, result);
   NS_ENSURE_TRUE(domSelection, NS_ERROR_FAILURE);
 
-  RefPtr<Selection> selection = static_cast<Selection*>(domSelection.get());
+  RefPtr<Selection> selection = domSelection->AsSelection();
 
   // The calling function should have done the GetIsCollapsed()
   // check already. Just assume it's collapsed!
   *aSelStatus = nsITextServicesDocument::eBlockOutside;
   *aSelOffset = *aSelLength = -1;
 
   int32_t tableCount = mOffsetTable.Length();
 
@@ -2739,17 +2739,17 @@ nsTextServicesDocument::GetUncollapsedSe
   OffsetEntry *entry;
 
   nsCOMPtr<nsISelection> domSelection;
   result = mSelCon->GetSelection(nsISelectionController::SELECTION_NORMAL,
                                  getter_AddRefs(domSelection));
   NS_ENSURE_SUCCESS(result, result);
   NS_ENSURE_TRUE(domSelection, NS_ERROR_FAILURE);
 
-  RefPtr<Selection> selection = static_cast<Selection*>(domSelection.get());
+  RefPtr<Selection> selection = domSelection->AsSelection();
 
   // It is assumed that the calling function has made sure that the
   // selection is not collapsed, and that the input params to this
   // method are initialized to some defaults.
 
   nsCOMPtr<nsIDOMNode> startParent, endParent;
   int32_t startOffset, endOffset;
   int32_t rangeCount, tableCount, i;
--- a/layout/base/nsCaret.cpp
+++ b/layout/base/nsCaret.cpp
@@ -412,28 +412,29 @@ nsCaret::GetFrameAndOffset(Selection* aS
 
   return frame;
 }
 
 /* static */ nsIFrame*
 nsCaret::GetGeometry(nsISelection* aSelection, nsRect* aRect)
 {
   int32_t frameOffset;
-  nsIFrame* frame = GetFrameAndOffset(
-      static_cast<Selection*>(aSelection), nullptr, 0, &frameOffset);
+  Selection* selection = aSelection ? aSelection->AsSelection() : nullptr;
+  nsIFrame* frame = GetFrameAndOffset(selection, nullptr, 0, &frameOffset);
   if (frame) {
     *aRect = GetGeometryForFrame(frame, frameOffset, nullptr);
   }
   return frame;
 }
 
 Selection*
 nsCaret::GetSelectionInternal()
 {
-  return static_cast<Selection*>(GetSelection());
+  nsISelection* domSelection = GetSelection();
+  return domSelection ? domSelection->AsSelection() : nullptr;
 }
 
 void nsCaret::SchedulePaint()
 {
   Selection* selection = GetSelectionInternal();
   nsINode* focusNode;
   if (mOverrideContent) {
     focusNode = mOverrideContent;
--- a/layout/base/nsPresShell.cpp
+++ b/layout/base/nsPresShell.cpp
@@ -5247,17 +5247,17 @@ PresShell::PaintRangePaintInfo(const nsT
     nsLayoutUtils::PointToGfxPoint(-aArea.TopLeft(), pc->AppUnitsPerDevPixel());
   initialTM.Translate(surfaceOffset);
 
   // temporarily hide the selection so that text is drawn normally. If a
   // selection is being rendered, use that, otherwise use the presshell's
   // selection.
   RefPtr<nsFrameSelection> frameSelection;
   if (aSelection) {
-    frameSelection = static_cast<Selection*>(aSelection)->GetFrameSelection();
+    frameSelection = aSelection->AsSelection()->GetFrameSelection();
   }
   else {
     frameSelection = FrameSelection();
   }
   int16_t oldDisplaySelection = frameSelection->GetDisplaySelection();
   frameSelection->SetDisplaySelection(nsISelectionController::SELECTION_HIDDEN);
 
   // next, paint each range in the selection
--- a/layout/forms/nsTextControlFrame.cpp
+++ b/layout/forms/nsTextControlFrame.cpp
@@ -1034,17 +1034,17 @@ nsTextControlFrame::GetSelectionRange(in
   NS_ASSERTION(txtCtrl, "Content not a text control element");
   nsISelectionController* selCon = txtCtrl->GetSelectionController();
   NS_ENSURE_TRUE(selCon, NS_ERROR_FAILURE);
   nsCOMPtr<nsISelection> selection;
   rv = selCon->GetSelection(nsISelectionController::SELECTION_NORMAL, getter_AddRefs(selection));  
   NS_ENSURE_SUCCESS(rv, rv);
   NS_ENSURE_TRUE(selection, NS_ERROR_FAILURE);
 
-  dom::Selection* sel = static_cast<dom::Selection*>(selection.get());
+  dom::Selection* sel = selection->AsSelection();
   if (aDirection) {
     nsDirection direction = sel->GetSelectionDirection();
     if (direction == eDirNext) {
       *aDirection = eForward;
     } else if (direction == eDirPrevious) {
       *aDirection = eBackward;
     } else {
       NS_NOTREACHED("Invalid nsDirection enum value");
--- a/layout/generic/nsSelection.cpp
+++ b/layout/generic/nsSelection.cpp
@@ -6550,19 +6550,17 @@ NS_INTERFACE_MAP_END
 
 NS_IMPL_CYCLE_COLLECTING_ADDREF(SelectionChangeListener)
 NS_IMPL_CYCLE_COLLECTING_RELEASE(SelectionChangeListener)
 
 NS_IMETHODIMP
 SelectionChangeListener::NotifySelectionChanged(nsIDOMDocument* aDoc,
                                                 nsISelection* aSel, int16_t aReason)
 {
-  // This cast is valid as nsISelection is a builtinclass which is only
-  // implemented by Selection.
-  RefPtr<Selection> sel = static_cast<Selection*>(aSel);
+  RefPtr<Selection> sel = aSel->AsSelection();
 
   // Check if the ranges have actually changed
   // Don't bother checking this if we are hiding changes.
   if (mOldRanges.Length() == sel->RangeCount() && !sel->IsBlockingSelectionChangeEvents()) {
     bool changed = false;
 
     for (size_t i = 0; i < mOldRanges.Length(); i++) {
       if (!mOldRanges[i].Equals(sel->GetRangeAt(i))) {