Bug 1278014 part.2 Define mozilla::SelectionType as an enum class and use it instead of RawSelectionType as far as possible r?smaug draft
authorMasayuki Nakano <masayuki@d-toybox.com>
Thu, 09 Jun 2016 16:59:15 +0900
changeset 377055 520cc372c7906188dfa3dbc151a36805e21d8907
parent 377054 929c2618e7d9259bf9f959af9cf9c9abb46d8456
child 377056 e9627a95e4fe5f532537b40c08c00fb3cf3928d6
push id20740
push usermasayuki@d-toybox.com
push dateThu, 09 Jun 2016 15:36:42 +0000
reviewerssmaug
bugs1278014
milestone50.0a1
Bug 1278014 part.2 Define mozilla::SelectionType as an enum class and use it instead of RawSelectionType as far as possible r?smaug This patch defines mozilla::SelectionType as an enum class. This is safer than nsISelectionController::SELECTION_* since setting illegal value to its variable is checked at build time. So, as far as possible, this should be used everywhere (but of course, this isn't available in scriptable interfaces). And also this implements some useful methods for managing SelectionType and RawSelectionType which are implemented in layout/nsSelection.cpp because nsISelectionController is implemented by both PresShell and nsTextEditorState. Therefore, implementing one of them may make hard to find them. On the other hand, nsSelection.cpp is a better file name to look for them. Note that this patch creates mozilla::Selection::RawType() for binding. Native code should keep using Selection::Type() but the binding code needs to use RawType() due to impossible to convert from SelectionType to RawSelectionType without explicit cast. MozReview-Commit-ID: 81vX7A0hHQN
accessible/base/SelectionManager.cpp
accessible/generic/HyperTextAccessible-inl.h
accessible/generic/HyperTextAccessible.cpp
accessible/generic/HyperTextAccessible.h
dom/base/nsCopySupport.cpp
dom/base/nsFocusManager.cpp
dom/base/nsGlobalWindow.cpp
dom/base/nsGlobalWindowCommands.cpp
dom/base/nsISelectionController.idl
dom/bindings/Bindings.conf
dom/html/nsTextEditorState.cpp
editor/libeditor/IMETextTxn.cpp
editor/libeditor/nsEditor.cpp
editor/libeditor/nsEditor.h
layout/base/AccessibleCaretManager.cpp
layout/base/nsDocumentViewer.cpp
layout/base/nsIPresShell.h
layout/base/nsPresShell.cpp
layout/base/nsPresShell.h
layout/generic/Selection.h
layout/generic/nsFrame.cpp
layout/generic/nsFrameSelection.h
layout/generic/nsSelection.cpp
layout/generic/nsTextFrame.cpp
layout/generic/nsTextFrame.h
layout/printing/nsPrintEngine.cpp
widget/TextRange.h
widget/WidgetEventImpl.cpp
--- a/accessible/base/SelectionManager.cpp
+++ b/accessible/base/SelectionManager.cpp
@@ -55,23 +55,23 @@ SelectionManager::ClearControlSelectionL
   NS_ASSERTION(frameSel, "No frame selection for the element!");
 
   mCurrCtrlFrame = nullptr;
   if (!frameSel)
     return;
 
   // Remove 'this' registered as selection listener for the normal selection.
   Selection* normalSel =
-    frameSel->GetSelection(nsISelectionController::SELECTION_NORMAL);
+    frameSel->GetSelection(SelectionType::SELECTION_NORMAL);
   normalSel->RemoveSelectionListener(this);
 
   // Remove 'this' registered as selection listener for the spellcheck
   // selection.
   Selection* spellSel =
-    frameSel->GetSelection(nsISelectionController::SELECTION_SPELLCHECK);
+    frameSel->GetSelection(SelectionType::SELECTION_SPELLCHECK);
   spellSel->RemoveSelectionListener(this);
 }
 
 void
 SelectionManager::SetControlSelectionListener(dom::Element* aFocusedElm)
 {
   // When focus moves such that the caret is part of a new frame selection
   // this removes the old selection listener and attaches a new one for
@@ -84,55 +84,55 @@ SelectionManager::SetControlSelectionLis
 
   const nsFrameSelection* frameSel = mCurrCtrlFrame->GetConstFrameSelection();
   NS_ASSERTION(frameSel, "No frame selection for focused element!");
   if (!frameSel)
     return;
 
   // Register 'this' as selection listener for the normal selection.
   Selection* normalSel =
-    frameSel->GetSelection(nsISelectionController::SELECTION_NORMAL);
+    frameSel->GetSelection(SelectionType::SELECTION_NORMAL);
   normalSel->AddSelectionListener(this);
 
   // Register 'this' as selection listener for the spell check selection.
   Selection* spellSel =
-    frameSel->GetSelection(nsISelectionController::SELECTION_SPELLCHECK);
+    frameSel->GetSelection(SelectionType::SELECTION_SPELLCHECK);
   spellSel->AddSelectionListener(this);
 }
 
 void
 SelectionManager::AddDocSelectionListener(nsIPresShell* aPresShell)
 {
   const nsFrameSelection* frameSel = aPresShell->ConstFrameSelection();
 
   // Register 'this' as selection listener for the normal selection.
   Selection* normalSel =
-    frameSel->GetSelection(nsISelectionController::SELECTION_NORMAL);
+    frameSel->GetSelection(SelectionType::SELECTION_NORMAL);
   normalSel->AddSelectionListener(this);
 
   // Register 'this' as selection listener for the spell check selection.
   Selection* spellSel =
-    frameSel->GetSelection(nsISelectionController::SELECTION_SPELLCHECK);
+    frameSel->GetSelection(SelectionType::SELECTION_SPELLCHECK);
   spellSel->AddSelectionListener(this);
 }
 
 void
 SelectionManager::RemoveDocSelectionListener(nsIPresShell* aPresShell)
 {
   const nsFrameSelection* frameSel = aPresShell->ConstFrameSelection();
 
   // Remove 'this' registered as selection listener for the normal selection.
   Selection* normalSel =
-    frameSel->GetSelection(nsISelectionController::SELECTION_NORMAL);
+    frameSel->GetSelection(SelectionType::SELECTION_NORMAL);
   normalSel->RemoveSelectionListener(this);
 
   // Remove 'this' registered as selection listener for the spellcheck
   // selection.
   Selection* spellSel =
-    frameSel->GetSelection(nsISelectionController::SELECTION_SPELLCHECK);
+    frameSel->GetSelection(SelectionType::SELECTION_SPELLCHECK);
   spellSel->RemoveSelectionListener(this);
 }
 
 void
 SelectionManager::ProcessTextSelChangeEvent(AccEvent* aEvent)
 {
   // Fire selection change event if it's not pure caret-move selection change,
   // i.e. the accessible has or had not collapsed selection.
@@ -220,20 +220,20 @@ SelectionManager::ProcessSelectionChange
   }
 
   HyperTextAccessible* text = nsAccUtils::GetTextContainer(cntrNode);
   if (!text) {
     NS_NOTREACHED("We must reach document accessible implementing text interface!");
     return;
   }
 
-  if (selection->GetType() == nsISelectionController::SELECTION_NORMAL) {
+  if (selection->GetType() == SelectionType::SELECTION_NORMAL) {
     RefPtr<AccEvent> event =
       new AccTextSelChangeEvent(text, selection, aSelData->mReason);
     text->Document()->FireDelayedEvent(event);
 
-  } else if (selection->GetType() == nsISelectionController::SELECTION_SPELLCHECK) {
+  } else if (selection->GetType() == SelectionType::SELECTION_SPELLCHECK) {
     // XXX: fire an event for container accessible of the focus/anchor range
     // of the spelcheck selection.
     text->Document()->FireDelayedEvent(nsIAccessibleEvent::EVENT_TEXT_ATTRIBUTE_CHANGED,
                                        text);
   }
 }
--- a/accessible/generic/HyperTextAccessible-inl.h
+++ b/accessible/generic/HyperTextAccessible-inl.h
@@ -165,17 +165,17 @@ HyperTextAccessible::FrameSelection() co
   return frame ? frame->GetFrameSelection() : nullptr;
 }
 
 inline dom::Selection*
 HyperTextAccessible::DOMSelection() const
 {
   RefPtr<nsFrameSelection> frameSelection = FrameSelection();
   return frameSelection ?
-    frameSelection->GetSelection(nsISelectionController::SELECTION_NORMAL) :
+    frameSelection->GetSelection(SelectionType::SELECTION_NORMAL) :
     nullptr;
 }
 
 } // namespace a11y
 } // namespace mozilla
 
 #endif
 
--- a/accessible/generic/HyperTextAccessible.cpp
+++ b/accessible/generic/HyperTextAccessible.cpp
@@ -1439,17 +1439,17 @@ HyperTextAccessible::CaretLineNumber()
 {
   // Provide the line number for the caret, relative to the
   // currently focused node. Use a 1-based index
   RefPtr<nsFrameSelection> frameSelection = FrameSelection();
   if (!frameSelection)
     return -1;
 
   dom::Selection* domSel =
-    frameSelection->GetSelection(nsISelectionController::SELECTION_NORMAL);
+    frameSelection->GetSelection(SelectionType::SELECTION_NORMAL);
   if (!domSel)
     return - 1;
 
   nsINode* caretNode = domSel->GetFocusNode();
   if (!caretNode || !caretNode->IsContent())
     return -1;
 
   nsIContent* caretContent = caretNode->AsContent();
@@ -1541,26 +1541,26 @@ HyperTextAccessible::GetCaretRect(nsIWid
   if (!charRect.IsEmpty()) {
     caretRect.height -= charRect.y - caretRect.y;
     caretRect.y = charRect.y;
   }
   return caretRect;
 }
 
 void
-HyperTextAccessible::GetSelectionDOMRanges(int16_t aType,
+HyperTextAccessible::GetSelectionDOMRanges(SelectionType aSelectionType,
                                            nsTArray<nsRange*>* aRanges)
 {
   // Ignore selection if it is not visible.
   RefPtr<nsFrameSelection> frameSelection = FrameSelection();
   if (!frameSelection ||
       frameSelection->GetDisplaySelection() <= nsISelectionController::SELECTION_HIDDEN)
     return;
 
-  dom::Selection* domSel = frameSelection->GetSelection(aType);
+  dom::Selection* domSel = frameSelection->GetSelection(aSelectionType);
   if (!domSel)
     return;
 
   nsCOMPtr<nsINode> startNode = GetNode();
 
   nsCOMPtr<nsIEditor> editor = GetEditor();
   if (editor) {
     nsCOMPtr<nsIDOMElement> editorRoot;
@@ -1586,29 +1586,29 @@ HyperTextAccessible::GetSelectionDOMRang
     }
   }
 }
 
 int32_t
 HyperTextAccessible::SelectionCount()
 {
   nsTArray<nsRange*> ranges;
-  GetSelectionDOMRanges(nsISelectionController::SELECTION_NORMAL, &ranges);
+  GetSelectionDOMRanges(SelectionType::SELECTION_NORMAL, &ranges);
   return ranges.Length();
 }
 
 bool
 HyperTextAccessible::SelectionBoundsAt(int32_t aSelectionNum,
                                        int32_t* aStartOffset,
                                        int32_t* aEndOffset)
 {
   *aStartOffset = *aEndOffset = 0;
 
   nsTArray<nsRange*> ranges;
-  GetSelectionDOMRanges(nsISelectionController::SELECTION_NORMAL, &ranges);
+  GetSelectionDOMRanges(SelectionType::SELECTION_NORMAL, &ranges);
 
   uint32_t rangeCount = ranges.Length();
   if (aSelectionNum < 0 || aSelectionNum >= static_cast<int32_t>(rangeCount))
     return false;
 
   nsRange* range = ranges[aSelectionNum];
 
   // Get start and end points.
@@ -2132,17 +2132,17 @@ HyperTextAccessible::GetSpellTextAttr(ns
                                       uint32_t* aStartOffset,
                                       uint32_t* aEndOffset,
                                       nsIPersistentProperties* aAttributes)
 {
   RefPtr<nsFrameSelection> fs = FrameSelection();
   if (!fs)
     return;
 
-  dom::Selection* domSel = fs->GetSelection(nsISelectionController::SELECTION_SPELLCHECK);
+  dom::Selection* domSel = fs->GetSelection(SelectionType::SELECTION_SPELLCHECK);
   if (!domSel)
     return;
 
   int32_t rangeCount = domSel->RangeCount();
   if (rangeCount <= 0)
     return;
 
   uint32_t startOffset = 0, endOffset = 0;
--- a/accessible/generic/HyperTextAccessible.h
+++ b/accessible/generic/HyperTextAccessible.h
@@ -513,17 +513,18 @@ protected:
   /**
    * Return frame selection object for the accessible.
    */
   already_AddRefed<nsFrameSelection> FrameSelection() const;
 
   /**
    * Return selection ranges within the accessible subtree.
    */
-  void GetSelectionDOMRanges(int16_t aType, nsTArray<nsRange*>* aRanges);
+  void GetSelectionDOMRanges(SelectionType aSelectionType,
+                             nsTArray<nsRange*>* aRanges);
 
   nsresult SetSelectionRange(int32_t aStartPos, int32_t aEndPos);
 
   /**
    * Convert the given DOM point to a DOM point in non-generated contents.
    *
    * If aDOMPoint is in ::before, the result is immediately after it.
    * If aDOMPoint is in ::after, the result is immediately before it.
--- a/dom/base/nsCopySupport.cpp
+++ b/dom/base/nsCopySupport.cpp
@@ -567,17 +567,18 @@ nsCopySupport::GetSelectionForCopy(nsIDo
       if (selCon) {
         selCon->GetSelection(nsISelectionController::SELECTION_NORMAL, aSelection);
         return content;
       }
     }
   }
 
   // if no selection was found, use the main selection for the window
-  NS_IF_ADDREF(*aSelection = presShell->GetCurrentSelection(nsISelectionController::SELECTION_NORMAL));
+  NS_IF_ADDREF(*aSelection =
+                 presShell->GetCurrentSelection(SelectionType::SELECTION_NORMAL));
   return nullptr;
 }
 
 bool
 nsCopySupport::CanCopy(nsIDocument* aDocument)
 {
   if (!aDocument)
     return false;
--- a/dom/base/nsFocusManager.cpp
+++ b/dom/base/nsFocusManager.cpp
@@ -2243,18 +2243,18 @@ nsFocusManager::UpdateCaret(bool aMoveCa
 
 void
 nsFocusManager::MoveCaretToFocus(nsIPresShell* aPresShell, nsIContent* aContent)
 {
   // domDoc is a document interface we can create a range with
   nsCOMPtr<nsIDOMDocument> domDoc = do_QueryInterface(aPresShell->GetDocument());
   if (domDoc) {
     RefPtr<nsFrameSelection> frameSelection = aPresShell->FrameSelection();
-    nsCOMPtr<nsISelection> domSelection = frameSelection->
-      GetSelection(nsISelectionController::SELECTION_NORMAL);
+    nsCOMPtr<nsISelection> domSelection =
+      frameSelection->GetSelection(SelectionType::SELECTION_NORMAL);
     if (domSelection) {
       nsCOMPtr<nsIDOMNode> currentFocusNode(do_QueryInterface(aContent));
       // First clear the selection. This way, if there is no currently focused
       // content, the selection will just be cleared.
       domSelection->RemoveAllRanges();
       if (currentFocusNode) {
         nsCOMPtr<nsIDOMRange> newRange;
         nsresult rv = domDoc->CreateRange(getter_AddRefs(newRange));
@@ -2304,18 +2304,18 @@ nsFocusManager::SetCaretVisible(nsIPresS
     if (focusFrame)
       frameSelection = focusFrame->GetFrameSelection();
   }
 
   RefPtr<nsFrameSelection> docFrameSelection = aPresShell->FrameSelection();
 
   if (docFrameSelection && caret &&
      (frameSelection == docFrameSelection || !aContent)) {
-    nsISelection* domSelection = docFrameSelection->
-      GetSelection(nsISelectionController::SELECTION_NORMAL);
+    nsISelection* domSelection =
+      docFrameSelection->GetSelection(SelectionType::SELECTION_NORMAL);
     if (domSelection) {
       nsCOMPtr<nsISelectionController> selCon(do_QueryInterface(aPresShell));
       if (!selCon) {
         return NS_ERROR_FAILURE;
       }
       // First, hide the caret to prevent attempting to show it in SetCaretDOMSelection
       selCon->SetCaretEnabled(false);
 
@@ -2347,18 +2347,17 @@ nsFocusManager::GetSelectionLocation(nsI
 
   nsPresContext* presContext = aPresShell->GetPresContext();
   NS_ASSERTION(presContext, "mPresContent is null!!");
 
   RefPtr<nsFrameSelection> frameSelection = aPresShell->FrameSelection();
 
   nsCOMPtr<nsISelection> domSelection;
   if (frameSelection) {
-    domSelection = frameSelection->
-      GetSelection(nsISelectionController::SELECTION_NORMAL);
+    domSelection = frameSelection->GetSelection(SelectionType::SELECTION_NORMAL);
   }
 
   nsCOMPtr<nsIDOMNode> startNode, endNode;
   bool isCollapsed = false;
   nsCOMPtr<nsIContent> startContent, endContent;
   int32_t startOffset = 0;
   if (domSelection) {
     domSelection->GetIsCollapsed(&isCollapsed);
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -9432,17 +9432,18 @@ nsGlobalWindow::GetSelectionOuter()
     return nullptr;
   }
 
   nsCOMPtr<nsIPresShell> presShell = mDocShell->GetPresShell();
   if (!presShell) {
     return nullptr;
   }
 
-  return static_cast<Selection*>(presShell->GetCurrentSelection(nsISelectionController::SELECTION_NORMAL));
+  return static_cast<Selection*>(
+           presShell->GetCurrentSelection(SelectionType::SELECTION_NORMAL));
 }
 
 Selection*
 nsGlobalWindow::GetSelection(ErrorResult& aError)
 {
   FORWARD_TO_OUTER_OR_THROW(GetSelectionOuter, (), aError, nullptr);
 }
 
--- a/dom/base/nsGlobalWindowCommands.cpp
+++ b/dom/base/nsGlobalWindowCommands.cpp
@@ -538,17 +538,17 @@ nsClipboardCommand::DoCommand(const char
   bool actionTaken = false;
   bool notCancelled =
     nsCopySupport::FireClipboardEvent(eventMessage,
                                       nsIClipboard::kGlobalClipboard,
                                       presShell, nullptr, &actionTaken);
 
   if (notCancelled && !strcmp(aCommandName, "cmd_copyAndCollapseToEnd")) {
     dom::Selection *sel =
-      presShell->GetCurrentSelection(nsISelectionController::SELECTION_NORMAL);
+      presShell->GetCurrentSelection(SelectionType::SELECTION_NORMAL);
     NS_ENSURE_TRUE(sel, NS_ERROR_FAILURE);
     sel->CollapseToEnd();
   }
 
   if (actionTaken) {
     return NS_OK;
   }
   return NS_ERROR_FAILURE;
--- a/dom/base/nsISelectionController.idl
+++ b/dom/base/nsISelectionController.idl
@@ -277,11 +277,36 @@ interface nsISelectionController : nsISe
 %{ C++
    #define NS_ISELECTIONCONTROLLER_CID \
    { 0x513b9460, 0xd56a, 0x4c4e, \
    { 0xb6, 0xf9, 0x0b, 0x8a, 0xe4, 0x37, 0x2a, 0x3b }}
 
 namespace mozilla {
 
 typedef short RawSelectionType;
+enum class SelectionType : RawSelectionType
+{
+  SELECTION_NONE = nsISelectionController::SELECTION_NONE,
+  SELECTION_NORMAL = nsISelectionController::SELECTION_NORMAL,
+  SELECTION_SPELLCHECK = nsISelectionController::SELECTION_SPELLCHECK,
+  SELECTION_IME_RAWINPUT = nsISelectionController::SELECTION_IME_RAWINPUT,
+  SELECTION_IME_SELECTEDRAWTEXT =
+    nsISelectionController::SELECTION_IME_SELECTEDRAWTEXT,
+  SELECTION_IME_CONVERTEDTEXT =
+    nsISelectionController::SELECTION_IME_CONVERTEDTEXT,
+  SELECTION_IME_SELECTEDCONVERTEDTEXT =
+    nsISelectionController::SELECTION_IME_SELECTEDCONVERTEDTEXT,
+  SELECTION_ACCESSIBILITY =
+    nsISelectionController::SELECTION_ACCESSIBILITY,
+  SELECTION_FIND = nsISelectionController::SELECTION_FIND,
+  SELECTION_URLSECONDARY = nsISelectionController::SELECTION_URLSECONDARY,
+  SELECTION_URLSTRIKEOUT = nsISelectionController::SELECTION_URLSTRIKEOUT,
+};
+
+const char* ToChar(SelectionType aSelectionType);
+bool IsValidSelectionType(RawSelectionType aRawSelectionType);
+SelectionType ToSelectionType(RawSelectionType aRawSelectionType);
+RawSelectionType ToRawSelectionType(SelectionType aSelectionType);
+bool operator &(SelectionType aSelectionType,
+                RawSelectionType aRawSelectionTypes);
 
 } // namespace mozilla
 %}
--- a/dom/bindings/Bindings.conf
+++ b/dom/bindings/Bindings.conf
@@ -972,16 +972,22 @@ DOMInterfaces = {
 'RGBColor': {
     'nativeType': 'nsDOMCSSRGBColor',
 },
 
 'Screen': {
     'nativeType': 'nsScreen',
 },
 
+'Selection': {
+    'binaryNames': {
+        'type': 'rawType'
+    }
+},
+
 'ServiceWorker': {
     'nativeType': 'mozilla::dom::workers::ServiceWorker',
     'headerFile': 'mozilla/dom/workers/bindings/ServiceWorker.h',
 },
 
 'ServiceWorkerGlobalScope': {
     'headerFile': 'mozilla/dom/WorkerScope.h',
     'workers': True,
--- a/dom/html/nsTextEditorState.cpp
+++ b/dom/html/nsTextEditorState.cpp
@@ -223,21 +223,23 @@ public:
   nsFrameSelection* GetConstFrameSelection()
     { return mFrameSelection; }
 
   //NSISELECTIONCONTROLLER INTERFACES
   NS_IMETHOD SetDisplaySelection(int16_t toggle) override;
   NS_IMETHOD GetDisplaySelection(int16_t* _retval) override;
   NS_IMETHOD SetSelectionFlags(int16_t aInEnable) override;
   NS_IMETHOD GetSelectionFlags(int16_t *aOutEnable) override;
-  NS_IMETHOD GetSelection(int16_t type, nsISelection** _retval) override;
-  NS_IMETHOD ScrollSelectionIntoView(int16_t aType, int16_t aRegion, int16_t aFlags) override;
-  NS_IMETHOD RepaintSelection(int16_t type) override;
-  NS_IMETHOD RepaintSelection(nsPresContext* aPresContext,
-                              RawSelectionType aRawSelectionType);
+  NS_IMETHOD GetSelection(RawSelectionType aRawSelectionType,
+                          nsISelection** aSelection) override;
+  NS_IMETHOD ScrollSelectionIntoView(RawSelectionType aRawSelectionType,
+                                     int16_t aRegion, int16_t aFlags) override;
+  NS_IMETHOD RepaintSelection(RawSelectionType aRawSelectionType) override;
+  nsresult RepaintSelection(nsPresContext* aPresContext,
+                            SelectionType aSelectionType);
   NS_IMETHOD SetCaretEnabled(bool enabled) override;
   NS_IMETHOD SetCaretReadOnly(bool aReadOnly) override;
   NS_IMETHOD GetCaretEnabled(bool* _retval) override;
   NS_IMETHOD GetCaretVisible(bool* _retval) override;
   NS_IMETHOD SetCaretVisibilityDuringSelection(bool aVisibility) override;
   NS_IMETHOD PhysicalMove(int16_t aDirection, int16_t aAmount, bool aExtend) override;
   NS_IMETHOD CharacterMove(bool aForward, bool aExtend) override;
   NS_IMETHOD CharacterExtendForDelete() override;
@@ -331,56 +333,76 @@ nsTextInputSelectionImpl::SetSelectionFl
 NS_IMETHODIMP
 nsTextInputSelectionImpl::GetSelectionFlags(int16_t *aOutEnable)
 {
   *aOutEnable = nsISelectionDisplay::DISPLAY_TEXT;
   return NS_OK; 
 }
 
 NS_IMETHODIMP
-nsTextInputSelectionImpl::GetSelection(int16_t type, nsISelection **_retval)
+nsTextInputSelectionImpl::GetSelection(RawSelectionType aRawSelectionType,
+                                       nsISelection** aSelection)
 {
   if (!mFrameSelection)
     return NS_ERROR_NULL_POINTER;
-    
-  *_retval = mFrameSelection->GetSelection(type);
-  
-  if (!(*_retval))
+
+  if (!IsValidSelectionType(aRawSelectionType)) {
+    return NS_ERROR_INVALID_ARG;
+  }
+
+  *aSelection =
+    mFrameSelection->GetSelection(ToSelectionType(aRawSelectionType));
+
+  if (!(*aSelection)) {
     return NS_ERROR_FAILURE;
+  }
 
-  NS_ADDREF(*_retval);
+  NS_ADDREF(*aSelection);
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsTextInputSelectionImpl::ScrollSelectionIntoView(int16_t aType, int16_t aRegion, int16_t aFlags)
+nsTextInputSelectionImpl::ScrollSelectionIntoView(
+                            RawSelectionType aRawSelectionType,
+                            int16_t aRegion,
+                            int16_t aFlags)
 {
   if (!mFrameSelection) 
     return NS_ERROR_FAILURE; 
 
-  return mFrameSelection->ScrollSelectionIntoView(aType, aRegion, aFlags);
+  if (!IsValidSelectionType(aRawSelectionType)) {
+    return NS_ERROR_INVALID_ARG;
+  }
+
+  return mFrameSelection->ScrollSelectionIntoView(
+                            ToSelectionType(aRawSelectionType),
+                            aRegion, aFlags);
 }
 
 NS_IMETHODIMP
-nsTextInputSelectionImpl::RepaintSelection(int16_t type)
+nsTextInputSelectionImpl::RepaintSelection(RawSelectionType aRawSelectionType)
 {
   if (!mFrameSelection)
     return NS_ERROR_FAILURE;
 
-  return mFrameSelection->RepaintSelection(type);
+  if (!IsValidSelectionType(aRawSelectionType)) {
+    return NS_ERROR_INVALID_ARG;
+  }
+
+  return mFrameSelection->RepaintSelection(ToSelectionType(aRawSelectionType));
 }
 
-NS_IMETHODIMP
+nsresult
 nsTextInputSelectionImpl::RepaintSelection(nsPresContext* aPresContext,
-                                           RawSelectionType aRawSelectionType)
+                                           SelectionType aSelectionType)
 {
   if (!mFrameSelection)
     return NS_ERROR_FAILURE;
 
-  return mFrameSelection->RepaintSelection(aRawSelectionType);
+  return mFrameSelection->RepaintSelection(aSelectionType);
 }
 
 NS_IMETHODIMP
 nsTextInputSelectionImpl::SetCaretEnabled(bool enabled)
 {
   if (!mPresShellWeak) return NS_ERROR_NOT_INITIALIZED;
 
   nsCOMPtr<nsIPresShell> shell = do_QueryReferent(mPresShellWeak);
@@ -400,18 +422,18 @@ nsTextInputSelectionImpl::SetCaretReadOn
 {
   if (!mPresShellWeak) return NS_ERROR_NOT_INITIALIZED;
   nsresult result;
   nsCOMPtr<nsIPresShell> shell = do_QueryReferent(mPresShellWeak, &result);
   if (shell)
   {
     RefPtr<nsCaret> caret = shell->GetCaret();
     if (caret) {
-      nsISelection* domSel = mFrameSelection->
-        GetSelection(nsISelectionController::SELECTION_NORMAL);
+      nsISelection* domSel =
+        mFrameSelection->GetSelection(SelectionType::SELECTION_NORMAL);
       if (domSel)
         caret->SetCaretReadOnly(aReadOnly);
       return NS_OK;
     }
   }
   return NS_ERROR_FAILURE;
 }
 
@@ -443,18 +465,18 @@ nsTextInputSelectionImpl::SetCaretVisibi
 {
   if (!mPresShellWeak) return NS_ERROR_NOT_INITIALIZED;
   nsresult result;
   nsCOMPtr<nsIPresShell> shell = do_QueryReferent(mPresShellWeak, &result);
   if (shell)
   {
     RefPtr<nsCaret> caret = shell->GetCaret();
     if (caret) {
-      nsISelection* domSel = mFrameSelection->
-        GetSelection(nsISelectionController::SELECTION_NORMAL);
+      nsISelection* domSel =
+        mFrameSelection->GetSelection(SelectionType::SELECTION_NORMAL);
       if (domSel)
         caret->SetVisibilityDuringSelection(aVisibility);
       return NS_OK;
     }
   }
   return NS_ERROR_FAILURE;
 }
 
--- a/editor/libeditor/IMETextTxn.cpp
+++ b/editor/libeditor/IMETextTxn.cpp
@@ -129,33 +129,16 @@ NS_IMETHODIMP
 IMETextTxn::GetTxnDescription(nsAString& aString)
 {
   aString.AssignLiteral("IMETextTxn: ");
   aString += mStringToInsert;
   return NS_OK;
 }
 
 /* ============ private methods ================== */
-static RawSelectionType
-ToRawSelectionType(TextRangeType aTextRangeType)
-{
-  switch (aTextRangeType) {
-    case TextRangeType::eRawClause:
-      return nsISelectionController::SELECTION_IME_RAWINPUT;
-    case TextRangeType::eSelectedRawClause:
-      return nsISelectionController::SELECTION_IME_SELECTEDRAWTEXT;
-    case TextRangeType::eConvertedClause:
-      return nsISelectionController::SELECTION_IME_CONVERTEDTEXT;
-    case TextRangeType::eSelectedClause:
-      return nsISelectionController::SELECTION_IME_SELECTEDCONVERTEDTEXT;
-    default:
-      MOZ_CRASH("Selection type is invalid");
-      return nsISelectionController::SELECTION_NORMAL;
-  }
-}
 
 nsresult
 IMETextTxn::SetSelectionForRanges()
 {
   return SetIMESelection(mEditor, mTextNode, mOffset,
                          mStringToInsert.Length(), mRanges);
 }
 
--- a/editor/libeditor/nsEditor.cpp
+++ b/editor/libeditor/nsEditor.cpp
@@ -635,34 +635,34 @@ nsEditor::DeleteSelection(EDirection aAc
   MOZ_ASSERT(aStripWrappers == eStrip || aStripWrappers == eNoStrip);
   return DeleteSelectionImpl(aAction, aStripWrappers);
 }
 
 
 NS_IMETHODIMP
 nsEditor::GetSelection(nsISelection** aSelection)
 {
-  return GetSelection(nsISelectionController::SELECTION_NORMAL, aSelection);
+  return GetSelection(SelectionType::SELECTION_NORMAL, aSelection);
 }
 
 nsresult
-nsEditor::GetSelection(int16_t aSelectionType, nsISelection** aSelection)
+nsEditor::GetSelection(SelectionType aSelectionType, nsISelection** aSelection)
 {
   NS_ENSURE_TRUE(aSelection, NS_ERROR_NULL_POINTER);
   *aSelection = nullptr;
   nsCOMPtr<nsISelectionController> selcon;
   GetSelectionController(getter_AddRefs(selcon));
   if (!selcon) {
     return NS_ERROR_NOT_INITIALIZED;
   }
-  return selcon->GetSelection(aSelectionType, aSelection);  // does an addref
+  return selcon->GetSelection(ToRawSelectionType(aSelectionType), aSelection);
 }
 
 Selection*
-nsEditor::GetSelection(int16_t aSelectionType)
+nsEditor::GetSelection(SelectionType aSelectionType)
 {
   nsCOMPtr<nsISelection> sel;
   nsresult res = GetSelection(aSelectionType, getter_AddRefs(sel));
   if (NS_FAILED(res)) {
     return nullptr;
   }
 
   return static_cast<Selection*>(sel.get());
@@ -2665,20 +2665,20 @@ struct SavedRange {
 nsresult
 nsEditor::SplitNodeImpl(nsIContent& aExistingRightNode,
                         int32_t aOffset,
                         nsIContent& aNewLeftNode)
 {
   // Remember all selection points.
   AutoTArray<SavedRange, 10> savedRanges;
   for (size_t i = 0; i < nsISelectionController::NUM_SELECTIONTYPES - 1; ++i) {
-    RawSelectionType type(1 << i);
+    SelectionType selectionType(ToSelectionType(1 << i));
     SavedRange range;
-    range.mSelection = GetSelection(type);
-    if (type == nsISelectionController::SELECTION_NORMAL) {
+    range.mSelection = GetSelection(selectionType);
+    if (selectionType == SelectionType::SELECTION_NORMAL) {
       NS_ENSURE_TRUE(range.mSelection, NS_ERROR_NULL_POINTER);
     } else if (!range.mSelection) {
       // For non-normal selections, skip over the non-existing ones.
       continue;
     }
 
     for (uint32_t j = 0; j < range.mSelection->RangeCount(); ++j) {
       RefPtr<nsRange> r = range.mSelection->GetRangeAt(j);
@@ -2750,18 +2750,17 @@ nsEditor::SplitNodeImpl(nsIContent& aExi
     // If we have not seen the selection yet, clear all of its ranges.
     if (range.mSelection != previousSelection) {
       nsresult rv = range.mSelection->RemoveAllRanges();
       NS_ENSURE_SUCCESS(rv, rv);
       previousSelection = range.mSelection;
     }
 
     if (shouldSetSelection &&
-        range.mSelection->Type() ==
-          nsISelectionController::SELECTION_NORMAL) {
+        range.mSelection->Type() == SelectionType::SELECTION_NORMAL) {
       // If the editor should adjust the selection, don't bother restoring
       // the ranges for the normal selection here.
       continue;
     }
 
     // Split the selection into existing node and new node.
     if (range.mStartNode == &aExistingRightNode) {
       if (range.mStartOffset < aOffset) {
@@ -2812,20 +2811,20 @@ nsEditor::JoinNodesImpl(nsINode* aNodeTo
   int32_t joinOffset;
   GetNodeLocation(aNodeToJoin, &joinOffset);
   int32_t keepOffset;
   nsINode* parent = GetNodeLocation(aNodeToKeep, &keepOffset);
 
   // Remember all selection points.
   AutoTArray<SavedRange, 10> savedRanges;
   for (size_t i = 0; i < nsISelectionController::NUM_SELECTIONTYPES - 1; ++i) {
-    RawSelectionType type(1 << i);
+    SelectionType selectionType(ToSelectionType(1 << i));
     SavedRange range;
-    range.mSelection = GetSelection(type);
-    if (type == nsISelectionController::SELECTION_NORMAL) {
+    range.mSelection = GetSelection(selectionType);
+    if (selectionType == SelectionType::SELECTION_NORMAL) {
       NS_ENSURE_TRUE(range.mSelection, NS_ERROR_NULL_POINTER);
     } else if (!range.mSelection) {
       // For non-normal selections, skip over the non-existing ones.
       continue;
     }
 
     for (uint32_t j = 0; j < range.mSelection->RangeCount(); ++j) {
       RefPtr<nsRange> r = range.mSelection->GetRangeAt(j);
@@ -2904,18 +2903,17 @@ nsEditor::JoinNodesImpl(nsINode* aNodeTo
     // If we have not seen the selection yet, clear all of its ranges.
     if (range.mSelection != previousSelection) {
       nsresult rv = range.mSelection->RemoveAllRanges();
       NS_ENSURE_SUCCESS(rv, rv);
       previousSelection = range.mSelection;
     }
 
     if (shouldSetSelection &&
-        range.mSelection->Type() ==
-          nsISelectionController::SELECTION_NORMAL) {
+        range.mSelection->Type() == SelectionType::SELECTION_NORMAL) {
       // If the editor should adjust the selection, don't bother restoring
       // the ranges for the normal selection here.
       continue;
     }
 
     // Check to see if we joined nodes where selection starts.
     if (range.mStartNode == aNodeToJoin) {
       range.mStartNode = aNodeToKeep;
@@ -5142,24 +5140,24 @@ nsEditor::GetIMESelectionStartOffsetIn(n
   MOZ_ASSERT(aTextNode, "aTextNode must not be nullptr");
 
   nsCOMPtr<nsISelectionController> selectionController;
   nsresult rv = GetSelectionController(getter_AddRefs(selectionController));
   NS_ENSURE_SUCCESS(rv, -1);
   NS_ENSURE_TRUE(selectionController, -1);
 
   int32_t minOffset = INT32_MAX;
-  static const RawSelectionType kIMERawSelectionTypes[] = {
-    nsISelectionController::SELECTION_IME_RAWINPUT,
-    nsISelectionController::SELECTION_IME_SELECTEDRAWTEXT,
-    nsISelectionController::SELECTION_IME_CONVERTEDTEXT,
-    nsISelectionController::SELECTION_IME_SELECTEDCONVERTEDTEXT
+  static const SelectionType kIMESelectionTypes[] = {
+    SelectionType::SELECTION_IME_RAWINPUT,
+    SelectionType::SELECTION_IME_SELECTEDRAWTEXT,
+    SelectionType::SELECTION_IME_CONVERTEDTEXT,
+    SelectionType::SELECTION_IME_SELECTEDCONVERTEDTEXT
   };
-  for (auto rawSelectionType : kIMERawSelectionTypes) {
-    RefPtr<Selection> selection = GetSelection(rawSelectionType);
+  for (auto selectionType : kIMESelectionTypes) {
+    RefPtr<Selection> selection = GetSelection(selectionType);
     if (!selection) {
       continue;
     }
     for (uint32_t i = 0; i < selection->RangeCount(); i++) {
       RefPtr<nsRange> range = selection->GetRangeAt(i);
       if (NS_WARN_IF(!range)) {
         continue;
       }
--- a/editor/libeditor/nsEditor.h
+++ b/editor/libeditor/nsEditor.h
@@ -408,17 +408,18 @@ protected:
   }
 
   /**
    * EnsureComposition() should be called by composition event handlers.  This
    * tries to get the composition for the event and set it to mComposition.
    */
   void EnsureComposition(mozilla::WidgetCompositionEvent* aCompositionEvent);
 
-  nsresult GetSelection(int16_t aSelectionType, nsISelection** aSelection);
+  nsresult GetSelection(mozilla::SelectionType aSelectionType,
+                        nsISelection** aSelection);
 
 public:
 
   /** All editor operations which alter the doc should be prefaced
    *  with a call to StartOperation, naming the action and direction */
   NS_IMETHOD StartOperation(EditAction opID,
                             nsIEditor::EDirection aDirection);
 
@@ -611,18 +612,18 @@ public:
                                       nsIDOMNode** outEndNode,
                                       int32_t* outEndOffset);
   static nsresult GetEndNodeAndOffset(Selection* aSelection,
                                       nsINode** aEndNode,
                                       int32_t* aEndOffset);
 #if DEBUG_JOE
   static void DumpNode(nsIDOMNode *aNode, int32_t indent=0);
 #endif
-  Selection* GetSelection(int16_t aSelectionType =
-      nsISelectionController::SELECTION_NORMAL);
+  Selection* GetSelection(mozilla::SelectionType aSelectionType =
+                            mozilla::SelectionType::SELECTION_NORMAL);
 
   // Helpers to add a node to the selection.
   // Used by table cell selection methods
   nsresult CreateRange(nsIDOMNode *aStartParent, int32_t aStartOffset,
                        nsIDOMNode *aEndParent, int32_t aEndOffset,
                        nsRange** aRange);
 
   // Creates a range with just the supplied node and appends that to the selection
--- a/layout/base/AccessibleCaretManager.cpp
+++ b/layout/base/AccessibleCaretManager.cpp
@@ -699,17 +699,17 @@ AccessibleCaretManager::OnKeyboardEvent(
 
 Selection*
 AccessibleCaretManager::GetSelection() const
 {
   RefPtr<nsFrameSelection> fs = GetFrameSelection();
   if (!fs) {
     return nullptr;
   }
-  return fs->GetSelection(nsISelectionController::SELECTION_NORMAL);
+  return fs->GetSelection(SelectionType::SELECTION_NORMAL);
 }
 
 already_AddRefed<nsFrameSelection>
 AccessibleCaretManager::GetFrameSelection() const
 {
   if (!mPresShell) {
     return nullptr;
   }
--- a/layout/base/nsDocumentViewer.cpp
+++ b/layout/base/nsDocumentViewer.cpp
@@ -2546,17 +2546,17 @@ nsDocumentViewer::CreateDeviceContext(ns
 // own selection, which cannot be accessed with this method.
 mozilla::dom::Selection*
 nsDocumentViewer::GetDocumentSelection()
 {
   if (!mPresShell) {
     return nullptr;
   }
 
-  return mPresShell->GetCurrentSelection(nsISelectionController::SELECTION_NORMAL);
+  return mPresShell->GetCurrentSelection(SelectionType::SELECTION_NORMAL);
 }
 
 /* ========================================================================================
  * nsIContentViewerEdit
  * ======================================================================================== */
 
 NS_IMETHODIMP nsDocumentViewer::ClearSelection()
 {
--- a/layout/base/nsIPresShell.h
+++ b/layout/base/nsIPresShell.h
@@ -828,17 +828,17 @@ public:
   /**
     * Gets the current state of non text selection effects
     * @return   current state of non text selection,
     *           as set by SetDisplayNonTextSelection
     */
   int16_t GetSelectionFlags() const { return mSelectionFlags; }
 
   virtual mozilla::dom::Selection*
-    GetCurrentSelection(mozilla::RawSelectionType aType) = 0;
+    GetCurrentSelection(mozilla::SelectionType aSelectionType) = 0;
 
   /**
     * Interface to dispatch events via the presshell
     * @note The caller must have a strong reference to the PresShell.
     */
   virtual nsresult HandleEventWithTarget(
                                  mozilla::WidgetEvent* aEvent,
                                  nsIFrame* aFrame,
--- a/layout/base/nsPresShell.cpp
+++ b/layout/base/nsPresShell.cpp
@@ -1532,54 +1532,66 @@ PresShell::GetDisplaySelection(int16_t *
 
 NS_IMETHODIMP
 PresShell::GetSelection(RawSelectionType aRawSelectionType,
                         nsISelection **aSelection)
 {
   if (!aSelection || !mSelection)
     return NS_ERROR_NULL_POINTER;
 
-  *aSelection = mSelection->GetSelection(aRawSelectionType);
+  if (!IsValidSelectionType(aRawSelectionType)) {
+    return NS_ERROR_INVALID_ARG;
+  }
+
+  *aSelection = mSelection->GetSelection(ToSelectionType(aRawSelectionType));
 
   if (!(*aSelection))
     return NS_ERROR_INVALID_ARG;
 
   NS_ADDREF(*aSelection);
 
   return NS_OK;
 }
 
 Selection*
-PresShell::GetCurrentSelection(RawSelectionType aRawSelectionType)
+PresShell::GetCurrentSelection(SelectionType aSelectionType)
 {
   if (!mSelection)
     return nullptr;
 
-  return mSelection->GetSelection(aRawSelectionType);
+  return mSelection->GetSelection(aSelectionType);
 }
 
 NS_IMETHODIMP
 PresShell::ScrollSelectionIntoView(RawSelectionType aRawSelectionType,
                                    SelectionRegion aRegion,
                                    int16_t aFlags)
 {
   if (!mSelection)
     return NS_ERROR_NULL_POINTER;
 
-  return mSelection->ScrollSelectionIntoView(aRawSelectionType, aRegion,
-                                             aFlags);
+  if (!IsValidSelectionType(aRawSelectionType)) {
+    return NS_ERROR_INVALID_ARG;
+  }
+
+  return mSelection->ScrollSelectionIntoView(ToSelectionType(aRawSelectionType),
+                                             aRegion, aFlags);
 }
 
 NS_IMETHODIMP
 PresShell::RepaintSelection(RawSelectionType aRawSelectionType)
 {
   if (!mSelection)
     return NS_ERROR_NULL_POINTER;
 
-  return mSelection->RepaintSelection(aRawSelectionType);
+  if (!IsValidSelectionType(aRawSelectionType)) {
+    return NS_ERROR_INVALID_ARG;
+  }
+
+  return mSelection->RepaintSelection(ToSelectionType(aRawSelectionType));
 }
 
 // Make shell be a document observer
 void
 PresShell::BeginObservingDocument()
 {
   if (mDocument && !mIsDestroying) {
     mDocument->AddObserver(this);
@@ -2734,18 +2746,18 @@ nsIPresShell::GetFrameToScrollAsScrollab
   nsIFocusManager* fm = nsFocusManager::GetFocusManager();
   if (fm && mDocument) {
     nsCOMPtr<nsIDOMElement> focusedElement;
     fm->GetFocusedElementForWindow(mDocument->GetWindow(), false, nullptr,
                                    getter_AddRefs(focusedElement));
     focusedContent = do_QueryInterface(focusedElement);
   }
   if (!focusedContent && mSelection) {
-    nsISelection* domSelection = mSelection->
-      GetSelection(nsISelectionController::SELECTION_NORMAL);
+    nsISelection* domSelection =
+      mSelection->GetSelection(SelectionType::SELECTION_NORMAL);
     if (domSelection) {
       nsCOMPtr<nsIDOMNode> focusedNode;
       domSelection->GetFocusNode(getter_AddRefs(focusedNode));
       focusedContent = do_QueryInterface(focusedNode);
     }
   }
   if (focusedContent) {
     nsIFrame* startFrame = focusedContent->GetPrimaryFrame();
@@ -3065,18 +3077,18 @@ PresShell::GoToAnchor(const nsAString& a
     RefPtr<nsIDOMRange> jumpToRange = new nsRange(mDocument);
     while (content && content->GetFirstChild()) {
       content = content->GetFirstChild();
     }
     nsCOMPtr<nsIDOMNode> node(do_QueryInterface(content));
     NS_ASSERTION(node, "No nsIDOMNode for descendant of anchor");
     jumpToRange->SelectNodeContents(node);
     // Select the anchor
-    nsISelection* sel = mSelection->
-      GetSelection(nsISelectionController::SELECTION_NORMAL);
+    nsISelection* sel =
+      mSelection->GetSelection(SelectionType::SELECTION_NORMAL);
     if (sel) {
       sel->RemoveAllRanges();
       sel->AddRange(jumpToRange);
       if (!selectAnchor) {
         // Use a caret (collapsed selection) at the start of the anchor
         sel->CollapseToStart();
       }
     }
--- a/layout/base/nsPresShell.h
+++ b/layout/base/nsPresShell.h
@@ -75,16 +75,17 @@ class PresShell final : public nsIPresSh
                         public nsISelectionController,
                         public nsIObserver,
                         public nsSupportsWeakReference
 {
   template <typename T> using Maybe = mozilla::Maybe<T>;
   using Nothing = mozilla::Nothing;
   using OnNonvisible = mozilla::OnNonvisible;
   using RawSelectionType = mozilla::RawSelectionType;
+  using SelectionType = mozilla::SelectionType;
   template <typename T> using UniquePtr = mozilla::UniquePtr<T>;
   using VisibilityCounter = mozilla::VisibilityCounter;
   using VisibleFrames = mozilla::VisibleFrames;
   using VisibleRegions = mozilla::VisibleRegions;
 
 public:
   PresShell();
 
@@ -105,17 +106,17 @@ public:
   virtual void Destroy() override;
   virtual void MakeZombie() override;
 
   virtual void UpdatePreferenceStyles() override;
 
   NS_IMETHOD GetSelection(RawSelectionType aRawSelectionType,
                           nsISelection** aSelection) override;
   virtual mozilla::dom::Selection*
-    GetCurrentSelection(RawSelectionType aRawSelectionType) override;
+    GetCurrentSelection(SelectionType aSelectionType) override;
 
   NS_IMETHOD SetDisplaySelection(int16_t aToggle) override;
   NS_IMETHOD GetDisplaySelection(int16_t *aToggle) override;
   NS_IMETHOD ScrollSelectionIntoView(RawSelectionType aRawSelectionType,
                                      SelectionRegion aRegion,
                                      int16_t aFlags) override;
   NS_IMETHOD RepaintSelection(RawSelectionType aRawSelectionType) override;
 
--- a/layout/generic/Selection.h
+++ b/layout/generic/Selection.h
@@ -134,17 +134,17 @@ public:
 
   //  NS_IMETHOD   GetPrimaryFrameForRangeEndpoint(nsIDOMNode *aNode, int32_t aOffset, bool aIsEndNode, nsIFrame **aResultFrame);
   NS_IMETHOD   GetPrimaryFrameForAnchorNode(nsIFrame **aResultFrame);
   NS_IMETHOD   GetPrimaryFrameForFocusNode(nsIFrame **aResultFrame, int32_t *aOffset, bool aVisual);
   NS_IMETHOD   LookUpSelection(nsIContent *aContent,
                                int32_t aContentOffset,
                                int32_t aContentLength,
                                SelectionDetails** aReturnDetails,
-                               RawSelectionType aRawSelectionType,
+                               SelectionType aSelectionType,
                                bool aSlowCheck);
   NS_IMETHOD   Repaint(nsPresContext* aPresContext);
 
   // Note: StartAutoScrollTimer might destroy arbitrary frames etc.
   nsresult     StartAutoScrollTimer(nsIFrame *aFrame,
                                     nsPoint& aPoint,
                                     uint32_t aDelay);
 
@@ -195,17 +195,21 @@ public:
                           int32_t aWrapColumn,
                           nsAString& aReturn,
                           mozilla::ErrorResult& aRv);
   void AddSelectionListener(nsISelectionListener* aListener,
                             mozilla::ErrorResult& aRv);
   void RemoveSelectionListener(nsISelectionListener* aListener,
                                mozilla::ErrorResult& aRv);
 
-  int16_t Type() const { return mRawSelectionType; }
+  RawSelectionType RawType() const
+  {
+    return ToRawSelectionType(mSelectionType);
+  }
+  SelectionType Type() const { return mSelectionType; }
 
   void GetRangesForInterval(nsINode& aBeginNode, int32_t aBeginOffset,
                             nsINode& aEndNode, int32_t aEndOffset,
                             bool aAllowAdjacent,
                             nsTArray<RefPtr<nsRange>>& aReturn,
                             mozilla::ErrorResult& aRv);
 
   void ScrollIntoView(int16_t aRegion, bool aIsSynchronous,
@@ -217,20 +221,20 @@ public:
   bool IsBlockingSelectionChangeEvents() const;
 private:
   friend class ::nsAutoScrollTimer;
 
   // Note: DoAutoScroll might destroy arbitrary frames etc.
   nsresult DoAutoScroll(nsIFrame *aFrame, nsPoint& aPoint);
 
 public:
-  RawSelectionType GetType() const { return mRawSelectionType; }
-  void SetType(RawSelectionType aRawSelectionType)
+  SelectionType GetType() const { return mSelectionType; }
+  void SetType(SelectionType aSelectionType)
   {
-    mRawSelectionType = aRawSelectionType;
+    mSelectionType = aSelectionType;
   }
 
   nsresult     NotifySelectionListeners();
 
   friend struct AutoUserInitiated;
   struct MOZ_RAII AutoUserInitiated
   {
     explicit AutoUserInitiated(Selection* aSelection
@@ -321,17 +325,17 @@ private:
 
   RefPtr<nsRange> mAnchorFocusRange;
   RefPtr<nsFrameSelection> mFrameSelection;
   RefPtr<nsAutoScrollTimer> mAutoScrollTimer;
   nsCOMArray<nsISelectionListener> mSelectionListeners;
   nsRevocableEventPtr<ScrollSelectionIntoViewEvent> mScrollEvent;
   CachedOffsetForFrame *mCachedOffsetForFrame;
   nsDirection mDirection;
-  RawSelectionType mRawSelectionType;
+  SelectionType mSelectionType;
   /**
    * True if the current selection operation was initiated by user action.
    * It determines whether we exclude -moz-user-select:none nodes or not,
    * as well as whether selectstart events will be fired.
    */
   bool mUserInitiated;
 
   // Non-zero if we don't want any changes we make to the selection to be
--- a/layout/generic/nsFrame.cpp
+++ b/layout/generic/nsFrame.cpp
@@ -1818,17 +1818,17 @@ nsFrame::DisplaySelectionOverlay(nsDispl
   SelectionDetails *details;
   //look up to see what selection(s) are on this frame
   details = frameSelection->LookUpSelection(newContent, offset, 1, false);
   if (!details)
     return;
   
   bool normal = false;
   while (details) {
-    if (details->mRawSelectionType == nsISelectionController::SELECTION_NORMAL) {
+    if (details->mSelectionType == SelectionType::SELECTION_NORMAL) {
       normal = true;
     }
     SelectionDetails *next = details->mNext;
     delete details;
     details = next;
   }
 
   if (!normal && aContentType == nsISelectionDisplay::DISPLAY_IMAGES) {
@@ -3370,20 +3370,20 @@ nsFrame::HandlePress(nsPresContext* aPre
     while (curDetail)
     {
       //
       // If the user clicked inside a selection, then just
       // return without doing anything. We will handle placing
       // the caret later on when the mouse is released. We ignore
       // the spellcheck, find and url formatting selections.
       //
-      if (curDetail->mRawSelectionType != nsISelectionController::SELECTION_SPELLCHECK &&
-          curDetail->mRawSelectionType != nsISelectionController::SELECTION_FIND &&
-          curDetail->mRawSelectionType != nsISelectionController::SELECTION_URLSECONDARY &&
-          curDetail->mRawSelectionType != nsISelectionController::SELECTION_URLSTRIKEOUT &&
+      if (curDetail->mSelectionType != SelectionType::SELECTION_SPELLCHECK &&
+          curDetail->mSelectionType != SelectionType::SELECTION_FIND &&
+          curDetail->mSelectionType != SelectionType::SELECTION_URLSECONDARY &&
+          curDetail->mSelectionType != SelectionType::SELECTION_URLSTRIKEOUT &&
           curDetail->mStart <= offsets.StartOffset() &&
           offsets.EndOffset() <= curDetail->mEnd)
       {
         inSelection = true;
       }
 
       SelectionDetails *nextDetail = curDetail->mNext;
       delete curDetail;
--- a/layout/generic/nsFrameSelection.h
+++ b/layout/generic/nsFrameSelection.h
@@ -40,17 +40,17 @@ struct SelectionDetails
     MOZ_COUNT_CTOR(SelectionDetails);
   }
   ~SelectionDetails() {
     MOZ_COUNT_DTOR(SelectionDetails);
   }
 #endif
   int32_t mStart;
   int32_t mEnd;
-  mozilla::RawSelectionType mRawSelectionType;
+  mozilla::SelectionType mSelectionType;
   mozilla::TextRangeStyle mTextRangeStyle;
   SelectionDetails *mNext;
 };
 
 class nsIPresShell;
 class nsIScrollableFrame;
 
 /** PeekOffsetStruct is used to group various arguments (both input and output)
@@ -340,47 +340,45 @@ public:
   /**
     if we are in table cell selection mode. aka ctrl click in table cell
    */
   bool GetTableCellSelection() const { return mSelectingTableCellMode != 0; }
   void ClearTableCellSelection() { mSelectingTableCellMode = 0; }
 
   /** GetSelection
    * no query interface for selection. must use this method now.
-   * @param aRawSelectionType The constants defined in nsISelectionController
-   *                          for the selection you want.
+   * @param aSelectionType The selection type what you want.
    */
   mozilla::dom::Selection*
-    GetSelection(mozilla::RawSelectionType aRawSelectionType) const;
+    GetSelection(mozilla::SelectionType aSelectionType) const;
 
   /**
    * ScrollSelectionIntoView scrolls a region of the selection,
    * so that it is visible in the scrolled view.
    *
-   * @param aRawSelectionType the selection to scroll into view.
+   * @param aSelectionType the selection to scroll into view.
    * @param aRegion the region inside the selection to scroll into view.
    * @param aFlags the scroll flags.  Valid bits include:
    * SCROLL_SYNCHRONOUS: when set, scrolls the selection into view
    * before returning. If not set, posts a request which is processed
    * at some point after the method returns.
    * SCROLL_FIRST_ANCESTOR_ONLY: if set, only the first ancestor will be scrolled
    * into view.
    *
    */
   /*unsafe*/
-  nsresult ScrollSelectionIntoView(mozilla::RawSelectionType aRawSelectionType,
+  nsresult ScrollSelectionIntoView(mozilla::SelectionType aSelectionType,
                                    SelectionRegion aRegion,
                                    int16_t aFlags) const;
 
   /** RepaintSelection repaints the selected frames that are inside the selection
-   *  specified by aRawSelectionType.
-   * @param aRawSelectionType The constants defined in nsISelectionController
-   *                          for the seleciton you want.
+   *  specified by aSelectionType.
+   * @param aSelectionType The selection type what you want to repaint.
    */
-  nsresult RepaintSelection(mozilla::RawSelectionType aRawSelectionType) const;
+  nsresult RepaintSelection(mozilla::SelectionType aSelectionType) const;
 
   /** GetFrameForNodeOffset given a node and its child offset, return the nsIFrame and
    *  the offset into that frame. 
    * @param aNode input parameter for the node to look at
    * @param aOffset offset into above node.
    * @param aReturnOffset will contain offset into frame.
    */
   virtual nsIFrame* GetFrameForNodeOffset(nsIContent*        aNode,
@@ -677,18 +675,17 @@ private:
   void         SetDesiredPos(nsPoint aPos); //set the mDesiredPos
 
   uint32_t     GetBatching() const {return mBatching; }
   bool         GetNotifyFrames() const { return mNotifyFrames; }
   void         SetDirty(bool aDirty=true){if (mBatching) mChangesDuringBatching = aDirty;}
 
   // nsFrameSelection may get deleted when calling this,
   // so remember to use nsCOMPtr when needed.
-  nsresult     NotifySelectionListeners(
-                 mozilla::RawSelectionType aRawSelectionType);
+  nsresult     NotifySelectionListeners(mozilla::SelectionType aSelectionType);
 
   RefPtr<mozilla::dom::Selection> mDomSelections[nsISelectionController::NUM_SELECTIONTYPES];
 
   // Table selection support.
   nsITableCellLayout* GetCellLayout(nsIContent *aCellContent) const;
 
   nsresult SelectBlockOfCells(nsIContent *aStartNode, nsIContent *aEndNode);
   nsresult SelectRowOrColumn(nsIContent *aCellContent, uint32_t aTarget);
--- a/layout/generic/nsSelection.cpp
+++ b/layout/generic/nsSelection.cpp
@@ -98,17 +98,98 @@ static nsINode* GetCellParent(nsINode *a
 
 #ifdef PRINT_RANGE
 static void printRange(nsRange *aDomRange);
 #define DEBUG_OUT_RANGE(x)  printRange(x)
 #else
 #define DEBUG_OUT_RANGE(x)  
 #endif // PRINT_RANGE
 
-
+/******************************************************************************
+ * Utility methods defined in nsISelectionController.idl
+ ******************************************************************************/
+
+namespace mozilla {
+
+const char*
+ToChar(SelectionType aSelectionType)
+{
+  switch (aSelectionType) {
+    case SelectionType::SELECTION_NONE:
+      return "SelectionType::eNone";
+    case SelectionType::SELECTION_NORMAL:
+      return "SelectionType::eNormal";
+    case SelectionType::SELECTION_SPELLCHECK:
+      return "SelectionType::eSpellCheck";
+    case SelectionType::SELECTION_IME_RAWINPUT:
+      return "SelectionType::eIMERawClause";
+    case SelectionType::SELECTION_IME_SELECTEDRAWTEXT:
+      return "SelectionType::eIMESelectedRawClause";
+    case SelectionType::SELECTION_IME_CONVERTEDTEXT:
+      return "SelectionType::eIMEConvertedClause";
+    case SelectionType::SELECTION_IME_SELECTEDCONVERTEDTEXT:
+      return "SelectionType::eIMESelectedClause";
+    case SelectionType::SELECTION_ACCESSIBILITY:
+      return "SelectionType::eAccessibility";
+    case SelectionType::SELECTION_FIND:
+      return "SelectionType::eFind";
+    case SelectionType::SELECTION_URLSECONDARY:
+      return "SelectionType::eURLSecondary";
+    case SelectionType::SELECTION_URLSTRIKEOUT:
+      return "SelectionType::eURLStrikeout";
+    default:
+      return "Invalid SelectionType";
+  }
+}
+
+bool
+IsValidSelectionType(RawSelectionType aRawSelectionType)
+{
+  switch (static_cast<SelectionType>(aRawSelectionType)) {
+    case SelectionType::SELECTION_NONE:
+    case SelectionType::SELECTION_NORMAL:
+    case SelectionType::SELECTION_SPELLCHECK:
+    case SelectionType::SELECTION_IME_RAWINPUT:
+    case SelectionType::SELECTION_IME_SELECTEDRAWTEXT:
+    case SelectionType::SELECTION_IME_CONVERTEDTEXT:
+    case SelectionType::SELECTION_IME_SELECTEDCONVERTEDTEXT:
+    case SelectionType::SELECTION_ACCESSIBILITY:
+    case SelectionType::SELECTION_FIND:
+    case SelectionType::SELECTION_URLSECONDARY:
+    case SelectionType::SELECTION_URLSTRIKEOUT:
+      return true;
+    default:
+      return false;
+  }
+}
+
+SelectionType
+ToSelectionType(RawSelectionType aRawSelectionType)
+{
+  MOZ_ASSERT(IsValidSelectionType(aRawSelectionType));
+  return static_cast<SelectionType>(aRawSelectionType);
+}
+
+RawSelectionType
+ToRawSelectionType(SelectionType aSelectionType)
+{
+  return static_cast<RawSelectionType>(aSelectionType);
+}
+
+bool operator &(SelectionType aSelectionType,
+                RawSelectionType aRawSelectionTypes)
+{
+  return (ToRawSelectionType(aSelectionType) & aRawSelectionTypes) != 0;
+}
+
+} // namespace mozilla
+
+/******************************************************************************
+ * nsPeekOffsetStruct
+ ******************************************************************************/
 
 //#define DEBUG_SELECTION // uncomment for printf describing every collapse and extend.
 //#define DEBUG_NAVIGATION
 
 
 //#define DEBUG_TABLE_SELECTION 1
 
 nsPeekOffsetStruct::nsPeekOffsetStruct(nsSelectionAmount aAmount,
@@ -258,56 +339,67 @@ nsresult NS_NewDomSelection(nsISelection
 {
   Selection* rlist = new Selection;
   *aDomSelection = (nsISelection *)rlist;
   NS_ADDREF(rlist);
   return NS_OK;
 }
 
 static int8_t
-GetIndexFromRawSelectionType(RawSelectionType aRawSelectionType)
-{
-    switch (aRawSelectionType) {
-    case nsISelectionController::SELECTION_NORMAL: return 0;
-    case nsISelectionController::SELECTION_SPELLCHECK: return 1;
-    case nsISelectionController::SELECTION_IME_RAWINPUT: return 2;
-    case nsISelectionController::SELECTION_IME_SELECTEDRAWTEXT: return 3;
-    case nsISelectionController::SELECTION_IME_CONVERTEDTEXT: return 4;
-    case nsISelectionController::SELECTION_IME_SELECTEDCONVERTEDTEXT: return 5;
-    case nsISelectionController::SELECTION_ACCESSIBILITY: return 6;
-    case nsISelectionController::SELECTION_FIND: return 7;
-    case nsISelectionController::SELECTION_URLSECONDARY: return 8;
-    case nsISelectionController::SELECTION_URLSTRIKEOUT: return 9;
+GetIndexFromSelectionType(SelectionType aSelectionType)
+{
+  switch (aSelectionType) {
+    case SelectionType::SELECTION_NORMAL:
+      return 0;
+    case SelectionType::SELECTION_SPELLCHECK:
+      return 1;
+    case SelectionType::SELECTION_IME_RAWINPUT:
+      return 2;
+    case SelectionType::SELECTION_IME_SELECTEDRAWTEXT:
+      return 3;
+    case SelectionType::SELECTION_IME_CONVERTEDTEXT:
+      return 4;
+    case SelectionType::SELECTION_IME_SELECTEDCONVERTEDTEXT:
+      return 5;
+    case SelectionType::SELECTION_ACCESSIBILITY:
+      return 6;
+    case SelectionType::SELECTION_FIND:
+      return 7;
+    case SelectionType::SELECTION_URLSECONDARY:
+      return 8;
+    case SelectionType::SELECTION_URLSTRIKEOUT:
+      return 9;
     default:
       return -1;
-    }
-    /* NOTREACHED */
-}
-
-static RawSelectionType
-GetRawSelectionTypeFromIndex(int8_t aIndex)
-{
-  switch (aIndex)
-  {
-    case 0: return nsISelectionController::SELECTION_NORMAL;
-    case 1: return nsISelectionController::SELECTION_SPELLCHECK;
-    case 2: return nsISelectionController::SELECTION_IME_RAWINPUT;
-    case 3: return nsISelectionController::SELECTION_IME_SELECTEDRAWTEXT;
-    case 4: return nsISelectionController::SELECTION_IME_CONVERTEDTEXT;
-    case 5: return nsISelectionController::SELECTION_IME_SELECTEDCONVERTEDTEXT;
-    case 6: return nsISelectionController::SELECTION_ACCESSIBILITY;
-    case 7: return nsISelectionController::SELECTION_FIND;
-    case 8: return nsISelectionController::SELECTION_URLSECONDARY;
-    case 9: return nsISelectionController::SELECTION_URLSTRIKEOUT;
-    default:
-      return nsISelectionController::SELECTION_NORMAL;
   }
   /* NOTREACHED */
 }
 
+static SelectionType
+GetSelectionTypeFromIndex(int8_t aIndex)
+{
+  static const SelectionType kSelectionTypes[] = {
+    SelectionType::SELECTION_NORMAL,
+    SelectionType::SELECTION_SPELLCHECK,
+    SelectionType::SELECTION_IME_RAWINPUT,
+    SelectionType::SELECTION_IME_SELECTEDRAWTEXT,
+    SelectionType::SELECTION_IME_CONVERTEDTEXT,
+    SelectionType::SELECTION_IME_SELECTEDCONVERTEDTEXT,
+    SelectionType::SELECTION_ACCESSIBILITY,
+    SelectionType::SELECTION_FIND,
+    SelectionType::SELECTION_URLSECONDARY,
+    SelectionType::SELECTION_URLSTRIKEOUT
+  };
+  if (NS_WARN_IF(aIndex < 0) ||
+      NS_WARN_IF(static_cast<size_t>(aIndex) >= ArrayLength(kSelectionTypes))) {
+    return SelectionType::SELECTION_NORMAL;
+  }
+  return kSelectionTypes[aIndex];
+}
+
 /*
 The limiter is used specifically for the text areas and textfields
 In that case it is the DIV tag that is anonymously created for the text
 areas/fields.  Text nodes and BR nodes fall beneath it.  In the case of a 
 BR node the limiter will be the parent and the offset will point before or
 after the BR node.  In the case of the text node the parent content is 
 the text node itself and the offset will be the exact character position.
 The offset is not important to check for validity.  Simply look at the 
@@ -431,17 +523,17 @@ struct MOZ_RAII AutoPrepareFocusRange
 
 ////////////BEGIN nsFrameSelection methods
 
 nsFrameSelection::nsFrameSelection()
 {
   int32_t i;
   for (i = 0;i<nsISelectionController::NUM_SELECTIONTYPES;i++){
     mDomSelections[i] = new Selection(this);
-    mDomSelections[i]->SetType(GetRawSelectionTypeFromIndex(i));
+    mDomSelections[i]->SetType(GetSelectionTypeFromIndex(i));
   }
   mBatching = 0;
   mChangesDuringBatching = false;
   mNotifyFrames = true;
   
   mMouseDoubleDownState = false;
   
   mHint = CARET_ASSOCIATE_BEFORE;
@@ -453,18 +545,17 @@ nsFrameSelection::nsFrameSelection()
   mSelectedCellIndex = 0;
 
   // Check to see if the autocopy pref is enabled
   //   and add the autocopy listener if it is
   if (Preferences::GetBool("clipboard.autocopy")) {
     nsAutoCopyListener *autoCopy = nsAutoCopyListener::GetInstance();
 
     if (autoCopy) {
-      int8_t index =
-        GetIndexFromRawSelectionType(nsISelectionController::SELECTION_NORMAL);
+      int8_t index = GetIndexFromSelectionType(SelectionType::SELECTION_NORMAL);
       if (mDomSelections[index]) {
         autoCopy->Listen(mDomSelections[index]);
       }
     }
   }
 
   mDisplaySelection = nsISelectionController::SELECTION_OFF;
   mSelectionChangeReason = nsISelectionListener::NO_REASON;
@@ -539,18 +630,17 @@ nsFrameSelection::FetchDesiredPos(nsPoin
     return NS_OK;
   }
 
   RefPtr<nsCaret> caret = mShell->GetCaret();
   if (!caret) {
     return NS_ERROR_NULL_POINTER;
   }
 
-  int8_t index =
-    GetIndexFromRawSelectionType(nsISelectionController::SELECTION_NORMAL);
+  int8_t index = GetIndexFromSelectionType(SelectionType::SELECTION_NORMAL);
   caret->SetSelection(mDomSelections[index]);
 
   nsRect coord;
   nsIFrame* caretFrame = caret->GetGeometry(&coord);
   if (!caretFrame) {
     return NS_ERROR_FAILURE;
   }
   nsPoint viewOffset(0, 0);
@@ -605,18 +695,17 @@ nsFrameSelection::ConstrainFrameAndPoint
   //
   // Get the frame and content for the selection's anchor point!
   //
 
   nsresult result;
   nsCOMPtr<nsIDOMNode> anchorNode;
   int32_t anchorOffset = 0;
 
-  int8_t index =
-    GetIndexFromRawSelectionType(nsISelectionController::SELECTION_NORMAL);
+  int8_t index = GetIndexFromSelectionType(SelectionType::SELECTION_NORMAL);
   if (!mDomSelections[index])
     return NS_ERROR_NULL_POINTER;
 
   result = mDomSelections[index]->GetAnchorNode(getter_AddRefs(anchorNode));
 
   if (NS_FAILED(result))
     return result;
 
@@ -824,26 +913,24 @@ nsFrameSelection::Init(nsIPresShell *aSh
     prefCachesInitialized = true;
 
     Preferences::AddBoolVarCache(&sSelectionEventsEnabled,
                                  "dom.select_events.enabled", false);
   }
 
   RefPtr<AccessibleCaretEventHub> eventHub = mShell->GetAccessibleCaretEventHub();
   if (eventHub) {
-    int8_t index =
-      GetIndexFromRawSelectionType(nsISelectionController::SELECTION_NORMAL);
+    int8_t index = GetIndexFromSelectionType(SelectionType::SELECTION_NORMAL);
     if (mDomSelections[index]) {
       mDomSelections[index]->AddSelectionListener(eventHub);
     }
   }
 
   if (sSelectionEventsEnabled) {
-    int8_t index =
-      GetIndexFromRawSelectionType(nsISelectionController::SELECTION_NORMAL);
+    int8_t index = GetIndexFromSelectionType(SelectionType::SELECTION_NORMAL);
     if (mDomSelections[index]) {
       // The Selection instance will hold a strong reference to its selectionchangelistener
       // so we don't have to worry about that!
       RefPtr<SelectionChangeListener> listener = new SelectionChangeListener;
       mDomSelections[index]->AddSelectionListener(listener);
     }
   }
 }
@@ -872,18 +959,17 @@ nsFrameSelection::MoveCaret(nsDirection 
 
   nsPresContext *context = mShell->GetPresContext();
   if (!context)
     return NS_ERROR_FAILURE;
 
   bool isCollapsed;
   nsPoint desiredPos(0, 0); //we must keep this around and revalidate it when its just UP/DOWN
 
-  int8_t index =
-    GetIndexFromRawSelectionType(nsISelectionController::SELECTION_NORMAL);
+  int8_t index = GetIndexFromSelectionType(SelectionType::SELECTION_NORMAL);
   RefPtr<Selection> sel = mDomSelections[index];
   if (!sel)
     return NS_ERROR_NULL_POINTER;
 
   int32_t scrollFlags = Selection::SCROLL_FOR_CARET_MOVE;
   nsINode* focusNode = sel->GetFocusNode();
   if (focusNode &&
       (focusNode->IsEditable() ||
@@ -1360,18 +1446,17 @@ nsFrameSelection::GetFrameFromLevel(nsIF
 
   return NS_OK;
 }
 
 
 nsresult
 nsFrameSelection::MaintainSelection(nsSelectionAmount aAmount)
 {
-  int8_t index =
-    GetIndexFromRawSelectionType(nsISelectionController::SELECTION_NORMAL);
+  int8_t index = GetIndexFromSelectionType(SelectionType::SELECTION_NORMAL);
   if (!mDomSelections[index])
     return NS_ERROR_NULL_POINTER;
 
   mMaintainedAmount = aAmount;
 
   const nsRange* anchorFocusRange =
     mDomSelections[index]->GetAnchorFocusRange();
   if (anchorFocusRange && aAmount != eSelectNoAmount) {
@@ -1465,18 +1550,17 @@ nsFrameSelection::AdjustForMaintainedSel
 {
   if (!mMaintainRange)
     return false;
 
   if (!aContent) {
     return false;
   }
 
-  int8_t index =
-    GetIndexFromRawSelectionType(nsISelectionController::SELECTION_NORMAL);
+  int8_t index = GetIndexFromSelectionType(SelectionType::SELECTION_NORMAL);
   if (!mDomSelections[index])
     return false;
 
   nsINode* rangeStartNode = mMaintainRange->GetStartParent();
   nsINode* rangeEndNode = mMaintainRange->GetEndParent();
   int32_t rangeStartOffset = mMaintainRange->StartOffset();
   int32_t rangeEndOffset = mMaintainRange->EndOffset();
 
@@ -1532,18 +1616,17 @@ nsFrameSelection::HandleClick(nsIContent
   if (!mDragSelectingCells)
   {
     BidiLevelFromClick(aNewFocus, aContentOffset);
     PostReason(nsISelectionListener::MOUSEDOWN_REASON + nsISelectionListener::DRAG_REASON);
     if (aContinueSelection &&
         AdjustForMaintainedSelection(aNewFocus, aContentOffset))
       return NS_OK; //shift clicked to maintained selection. rejected.
 
-    int8_t index =
-      GetIndexFromRawSelectionType(nsISelectionController::SELECTION_NORMAL);
+    int8_t index = GetIndexFromSelectionType(SelectionType::SELECTION_NORMAL);
     AutoPrepareFocusRange prep(mDomSelections[index], aContinueSelection, aMultipleSelection);
     return TakeFocus(aNewFocus, aContentOffset, aContentEndOffset, aHint,
                      aContinueSelection, aMultipleSelection);
   }
   
   return NS_OK;
 }
 
@@ -1616,29 +1699,27 @@ nsFrameSelection::HandleDrag(nsIFrame *a
               true, false, offsets.associate);
 }
 
 nsresult
 nsFrameSelection::StartAutoScrollTimer(nsIFrame *aFrame,
                                        nsPoint   aPoint,
                                        uint32_t  aDelay)
 {
-  int8_t index =
-    GetIndexFromRawSelectionType(nsISelectionController::SELECTION_NORMAL);
+  int8_t index = GetIndexFromSelectionType(SelectionType::SELECTION_NORMAL);
   if (!mDomSelections[index])
     return NS_ERROR_NULL_POINTER;
 
   return mDomSelections[index]->StartAutoScrollTimer(aFrame, aPoint, aDelay);
 }
 
 void
 nsFrameSelection::StopAutoScrollTimer()
 {
-  int8_t index =
-    GetIndexFromRawSelectionType(nsISelectionController::SELECTION_NORMAL);
+  int8_t index = GetIndexFromSelectionType(SelectionType::SELECTION_NORMAL);
   if (!mDomSelections[index])
     return;
 
   mDomSelections[index]->StopAutoScrollTimer();
 }
 
 /**
 hard to go from nodes to frames, easy the other way!
@@ -1662,18 +1743,17 @@ nsFrameSelection::TakeFocus(nsIContent* 
   // Clear all table selection data
   mSelectingTableCellMode = 0;
   mDragSelectingCells = false;
   mStartSelectedCell = nullptr;
   mEndSelectedCell = nullptr;
   mAppendStartSelectedCell = nullptr;
   mHint = aHint;
   
-  int8_t index =
-    GetIndexFromRawSelectionType(nsISelectionController::SELECTION_NORMAL);
+  int8_t index = GetIndexFromSelectionType(SelectionType::SELECTION_NORMAL);
   if (!mDomSelections[index])
     return NS_ERROR_NULL_POINTER;
 
   Maybe<Selection::AutoUserInitiated> userSelect;
   if (IsUserSelectionReason()) {
     userSelect.emplace(mDomSelections[index]);
   }
 
@@ -1776,17 +1856,17 @@ printf(" * TakeFocus - moving into new c
           mDomSelections[index]->Extend(aNewFocus, aContentOffset);
       }
     }
   }
 
   // Don't notify selection listeners if batching is on:
   if (GetBatching())
     return NS_OK;
-  return NotifySelectionListeners(nsISelectionController::SELECTION_NORMAL);
+  return NotifySelectionListeners(SelectionType::SELECTION_NORMAL);
 }
 
 
 SelectionDetails*
 nsFrameSelection::LookUpSelection(nsIContent *aContent,
                                   int32_t aContentOffset,
                                   int32_t aContentLength,
                                   bool aSlowCheck) const
@@ -1795,17 +1875,17 @@ nsFrameSelection::LookUpSelection(nsICon
     return nullptr;
 
   SelectionDetails* details = nullptr;
 
   for (int32_t j = 0; j < nsISelectionController::NUM_SELECTIONTYPES; j++) {
     if (mDomSelections[j]) {
       mDomSelections[j]->LookUpSelection(aContent, aContentOffset,
                                          aContentLength, &details,
-                                         static_cast<RawSelectionType>(1<<j),
+                                         ToSelectionType(1 << j),
                                          aSlowCheck);
     }
   }
 
   return details;
 }
 
 void
@@ -1814,37 +1894,38 @@ nsFrameSelection::SetDragState(bool aSta
   if (mDragState == aState)
     return;
 
   mDragState = aState;
     
   if (!mDragState)
   {
     mDragSelectingCells = false;
+    // Notify that reason is mouse up.
     PostReason(nsISelectionListener::MOUSEUP_REASON);
-    NotifySelectionListeners(nsISelectionController::SELECTION_NORMAL); //notify that reason is mouse up please.
+    NotifySelectionListeners(SelectionType::SELECTION_NORMAL);
   }
 }
 
 Selection*
-nsFrameSelection::GetSelection(RawSelectionType aRawSelectionType) const
-{
-  int8_t index = GetIndexFromRawSelectionType(aRawSelectionType);
+nsFrameSelection::GetSelection(SelectionType aSelectionType) const
+{
+  int8_t index = GetIndexFromSelectionType(aSelectionType);
   if (index < 0)
     return nullptr;
 
   return mDomSelections[index];
 }
 
 nsresult
-nsFrameSelection::ScrollSelectionIntoView(RawSelectionType aRawSelectionType,
+nsFrameSelection::ScrollSelectionIntoView(SelectionType aSelectionType,
                                           SelectionRegion aRegion,
                                           int16_t         aFlags) const
 {
-  int8_t index = GetIndexFromRawSelectionType(aRawSelectionType);
+  int8_t index = GetIndexFromSelectionType(aSelectionType);
   if (index < 0)
     return NS_ERROR_INVALID_ARG;
 
   if (!mDomSelections[index])
     return NS_ERROR_NULL_POINTER;
 
   nsIPresShell::ScrollAxis verticalScroll = nsIPresShell::ScrollAxis();
   int32_t flags = Selection::SCROLL_DO_FLUSH;
@@ -1868,19 +1949,19 @@ nsFrameSelection::ScrollSelectionIntoVie
   // flushed and PresShell/PresContext/Frames may be dead. See bug 418470.
   return mDomSelections[index]->ScrollIntoView(aRegion,
                                                verticalScroll,
                                                nsIPresShell::ScrollAxis(),
                                                flags);
 }
 
 nsresult
-nsFrameSelection::RepaintSelection(RawSelectionType aRawSelectionType) const
-{
-  int8_t index = GetIndexFromRawSelectionType(aRawSelectionType);
+nsFrameSelection::RepaintSelection(SelectionType aSelectionType) const
+{
+  int8_t index = GetIndexFromSelectionType(aSelectionType);
   if (index < 0)
     return NS_ERROR_INVALID_ARG;
   if (!mDomSelections[index])
     return NS_ERROR_NULL_POINTER;
   NS_ENSURE_STATE(mShell);
   return mDomSelections[index]->Repaint(mShell->GetPresContext());
 }
  
@@ -2043,17 +2124,17 @@ nsFrameSelection::CommonPageMove(bool aF
   //get the frame from the scrollable view
 
   nsIFrame* scrolledFrame = aScrollableFrame->GetScrolledFrame();
   if (!scrolledFrame)
     return;
 
   // find out where the caret is.
   // we should know mDesiredPos value of nsFrameSelection, but I havent seen that behavior in other windows applications yet.
-  nsISelection* domSel = GetSelection(nsISelectionController::SELECTION_NORMAL);
+  nsISelection* domSel = GetSelection(SelectionType::SELECTION_NORMAL);
   if (!domSel) {
     return;
   }
 
   nsRect caretPos;
   nsIFrame* caretFrame = nsCaret::GetGeometry(domSel, &caretPos);
   if (!caretFrame) 
     return;
@@ -2108,18 +2189,17 @@ nsFrameSelection::PhysicalMove(int16_t a
     return NS_ERROR_FAILURE;
   }
 
   nsPresContext *context = mShell->GetPresContext();
   if (!context) {
     return NS_ERROR_FAILURE;
   }
 
-  int8_t index =
-    GetIndexFromRawSelectionType(nsISelectionController::SELECTION_NORMAL);
+  int8_t index = GetIndexFromSelectionType(SelectionType::SELECTION_NORMAL);
   RefPtr<Selection> sel = mDomSelections[index];
   if (!sel) {
     return NS_ERROR_NULL_POINTER;
   }
 
   // Map the abstract movement amounts (0-1) to direction-specific
   // selection units.
   static const nsSelectionAmount inlineAmount[] =
@@ -2266,18 +2346,17 @@ nsFrameSelection::SelectAll()
     if (!doc)
       return NS_ERROR_FAILURE;
     rootContent = doc->GetRootElement();
     if (!rootContent)
       return NS_ERROR_FAILURE;
   }
   int32_t numChildren = rootContent->GetChildCount();
   PostReason(nsISelectionListener::NO_REASON);
-  int8_t index =
-    GetIndexFromRawSelectionType(nsISelectionController::SELECTION_NORMAL);
+  int8_t index = GetIndexFromSelectionType(SelectionType::SELECTION_NORMAL);
   AutoPrepareFocusRange prep(mDomSelections[index], false, false);
   return TakeFocus(rootContent, 0, numChildren, CARET_ASSOCIATE_BEFORE, false, false);
 }
 
 //////////END FRAMESELECTION
 
 void
 nsFrameSelection::StartBatchChanges()
@@ -2290,25 +2369,25 @@ nsFrameSelection::EndBatchChanges(int16_
 {
   mBatching--;
   NS_ASSERTION(mBatching >=0,"Bad mBatching");
 
   if (mBatching == 0 && mChangesDuringBatching) {
     int16_t postReason = PopReason() | aReason;
     PostReason(postReason);
     mChangesDuringBatching = false;
-    NotifySelectionListeners(nsISelectionController::SELECTION_NORMAL);
+    NotifySelectionListeners(SelectionType::SELECTION_NORMAL);
   }
 }
 
 
 nsresult
-nsFrameSelection::NotifySelectionListeners(RawSelectionType aRawSelectionType)
-{
-  int8_t index = GetIndexFromRawSelectionType(aRawSelectionType);
+nsFrameSelection::NotifySelectionListeners(SelectionType aSelectionType)
+{
+  int8_t index = GetIndexFromSelectionType(aSelectionType);
   if (index >=0 && mDomSelections[index])
   {
     return mDomSelections[index]->NotifySelectionListeners();
   }
   return NS_ERROR_FAILURE;
 }
 
 // Start of Table Selection methods
@@ -2325,18 +2404,17 @@ nsFrameSelection::GetCellLayout(nsIConte
   nsITableCellLayout *cellLayoutObject =
     do_QueryFrame(aCellContent->GetPrimaryFrame());
   return cellLayoutObject;
 }
 
 nsresult
 nsFrameSelection::ClearNormalSelection()
 {
-  int8_t index =
-    GetIndexFromRawSelectionType(nsISelectionController::SELECTION_NORMAL);
+  int8_t index = GetIndexFromSelectionType(SelectionType::SELECTION_NORMAL);
   if (!mDomSelections[index])
     return NS_ERROR_NULL_POINTER;
 
   return mDomSelections[index]->RemoveAllRanges();
 }
 
 static nsIContent*
 GetFirstSelectedContent(nsRange* aRange)
@@ -2372,18 +2450,17 @@ nsFrameSelection::HandleTableSelection(n
 
   nsresult result = NS_OK;
 
   nsIContent *childContent = aParentContent->GetChildAt(aContentOffset);
 
   // When doing table selection, always set the direction to next so
   // we can be sure that anchorNode's offset always points to the
   // selected cell
-  int8_t index =
-    GetIndexFromRawSelectionType(nsISelectionController::SELECTION_NORMAL);
+  int8_t index = GetIndexFromSelectionType(SelectionType::SELECTION_NORMAL);
   if (!mDomSelections[index])
     return NS_ERROR_NULL_POINTER;
 
   mDomSelections[index]->SetDirection(eDirNext);
 
   // Stack-class to wrap all table selection changes in 
   //  BeginBatchChanges() / EndBatchChanges()
   SelectionBatcher selectionBatcher(mDomSelections[index]);
@@ -2716,18 +2793,17 @@ nsFrameSelection::SelectBlockOfCells(nsI
 nsresult
 nsFrameSelection::UnselectCells(nsIContent *aTableContent,
                                 int32_t aStartRowIndex,
                                 int32_t aStartColumnIndex,
                                 int32_t aEndRowIndex,
                                 int32_t aEndColumnIndex,
                                 bool aRemoveOutsideOfCellRange)
 {
-  int8_t index =
-    GetIndexFromRawSelectionType(nsISelectionController::SELECTION_NORMAL);
+  int8_t index = GetIndexFromSelectionType(SelectionType::SELECTION_NORMAL);
   if (!mDomSelections[index])
     return NS_ERROR_NULL_POINTER;
 
   nsTableOuterFrame* tableFrame = do_QueryFrame(aTableContent->GetPrimaryFrame());
   if (!tableFrame)
     return NS_ERROR_FAILURE;
 
   int32_t minRowIndex = std::min(aStartRowIndex, aEndRowIndex);
@@ -2797,18 +2873,17 @@ nsFrameSelection::UnselectCells(nsIConte
 
 nsresult
 nsFrameSelection::AddCellsToSelection(nsIContent *aTableContent,
                                       int32_t aStartRowIndex,
                                       int32_t aStartColumnIndex,
                                       int32_t aEndRowIndex,
                                       int32_t aEndColumnIndex)
 {
-  int8_t index =
-    GetIndexFromRawSelectionType(nsISelectionController::SELECTION_NORMAL);
+  int8_t index = GetIndexFromSelectionType(SelectionType::SELECTION_NORMAL);
   if (!mDomSelections[index])
     return NS_ERROR_NULL_POINTER;
 
   nsTableOuterFrame* tableFrame = do_QueryFrame(aTableContent->GetPrimaryFrame());
   if (!tableFrame) // Check that |table| is a table.
     return NS_ERROR_FAILURE;
 
   nsresult result = NS_OK;
@@ -2996,18 +3071,17 @@ nsFrameSelection::GetFirstCellNodeInRang
     return nullptr;
 
   return childContent;
 }
 
 nsRange*
 nsFrameSelection::GetFirstCellRange()
 {
-  int8_t index =
-    GetIndexFromRawSelectionType(nsISelectionController::SELECTION_NORMAL);
+  int8_t index = GetIndexFromSelectionType(SelectionType::SELECTION_NORMAL);
   if (!mDomSelections[index])
     return nullptr;
 
   nsRange* firstRange = mDomSelections[index]->GetRangeAt(0);
   if (!GetFirstCellNodeInRange(firstRange)) {
     return nullptr;
   }
 
@@ -3015,18 +3089,17 @@ nsFrameSelection::GetFirstCellRange()
   mSelectedCellIndex = 1;
 
   return firstRange;
 }
 
 nsRange*
 nsFrameSelection::GetNextCellRange()
 {
-  int8_t index =
-    GetIndexFromRawSelectionType(nsISelectionController::SELECTION_NORMAL);
+  int8_t index = GetIndexFromSelectionType(SelectionType::SELECTION_NORMAL);
   if (!mDomSelections[index])
     return nullptr;
 
   nsRange* range = mDomSelections[index]->GetRangeAt(mSelectedCellIndex);
 
   // Get first node in next range of selection - test if it's a cell
   if (!GetFirstCellNodeInRange(range)) {
     return nullptr;
@@ -3243,33 +3316,31 @@ nsFrameSelection::CreateAndAddRange(nsIN
   RefPtr<nsRange> range = new nsRange(aParentNode);
 
   // Set range around child at given offset
   nsresult result = range->SetStart(aParentNode, aOffset);
   if (NS_FAILED(result)) return result;
   result = range->SetEnd(aParentNode, aOffset+1);
   if (NS_FAILED(result)) return result;
   
-  int8_t index =
-    GetIndexFromRawSelectionType(nsISelectionController::SELECTION_NORMAL);
+  int8_t index = GetIndexFromSelectionType(SelectionType::SELECTION_NORMAL);
   if (!mDomSelections[index])
     return NS_ERROR_NULL_POINTER;
 
   return mDomSelections[index]->AddRange(range);
 }
 
 // End of Table Selection
 
 void
 nsFrameSelection::SetAncestorLimiter(nsIContent *aLimiter)
 {
   if (mAncestorLimiter != aLimiter) {
     mAncestorLimiter = aLimiter;
-    int8_t index =
-      GetIndexFromRawSelectionType(nsISelectionController::SELECTION_NORMAL);
+    int8_t index = GetIndexFromSelectionType(SelectionType::SELECTION_NORMAL);
     if (!mDomSelections[index])
       return;
 
     if (!IsValidSelectionPoint(this, mDomSelections[index]->GetFocusNode())) {
       ClearNormalSelection();
       if (mAncestorLimiter) {
         PostReason(nsISelectionListener::NO_REASON);
         TakeFocus(mAncestorLimiter, 0, 0, CARET_ASSOCIATE_BEFORE, false, false);
@@ -3287,18 +3358,17 @@ nsFrameSelection::SetAncestorLimiter(nsI
 
 nsresult
 nsFrameSelection::DeleteFromDocument()
 {
   nsresult res;
 
   // If we're already collapsed, then we do nothing (bug 719503).
   bool isCollapsed;
-  int8_t index =
-    GetIndexFromRawSelectionType(nsISelectionController::SELECTION_NORMAL);
+  int8_t index = GetIndexFromSelectionType(SelectionType::SELECTION_NORMAL);
   if (!mDomSelections[index])
     return NS_ERROR_NULL_POINTER;
 
   mDomSelections[index]->GetIsCollapsed( &isCollapsed);
   if (isCollapsed)
   {
     return NS_OK;
   }
@@ -3338,18 +3408,17 @@ nsFrameSelection::SetDelayedCaretData(Wi
   }
 }
 
 void
 nsFrameSelection::DisconnectFromPresShell()
 {
   RefPtr<AccessibleCaretEventHub> eventHub = mShell->GetAccessibleCaretEventHub();
   if (eventHub) {
-    int8_t index =
-      GetIndexFromRawSelectionType(nsISelectionController::SELECTION_NORMAL);
+    int8_t index = GetIndexFromSelectionType(SelectionType::SELECTION_NORMAL);
     mDomSelections[index]->RemoveSelectionListener(eventHub);
   }
 
   StopAutoScrollTimer();
   for (int32_t i = 0; i < nsISelectionController::NUM_SELECTIONTYPES; i++) {
     mDomSelections[i]->Clear(nullptr);
   }
   mShell = nullptr;
@@ -3363,27 +3432,27 @@ nsFrameSelection::DisconnectFromPresShel
 
 // mozilla::dom::Selection implementation
 
 // note: this can return a nil anchor node
 
 Selection::Selection()
   : mCachedOffsetForFrame(nullptr)
   , mDirection(eDirNext)
-  , mRawSelectionType(nsISelectionController::SELECTION_NORMAL)
+  , mSelectionType(SelectionType::SELECTION_NORMAL)
   , mUserInitiated(false)
   , mSelectionChangeBlockerCount(0)
 {
 }
 
 Selection::Selection(nsFrameSelection* aList)
   : mFrameSelection(aList)
   , mCachedOffsetForFrame(nullptr)
   , mDirection(eDirNext)
-  , mRawSelectionType(nsISelectionController::SELECTION_NORMAL)
+  , mSelectionType(SelectionType::SELECTION_NORMAL)
   , mUserInitiated(false)
   , mSelectionChangeBlockerCount(0)
 {
 }
 
 Selection::~Selection()
 {
   setAnchorFocusRange(-1);
@@ -3738,17 +3807,17 @@ Selection::AddItem(nsRange* aItem, int32
 
   NS_ASSERTION(aOutIndex, "aOutIndex can't be null");
 
   if (mUserInitiated) {
     AutoTArray<RefPtr<nsRange>, 4> rangesToAdd;
     *aOutIndex = -1;
 
     if (!aNoStartSelect &&
-        mRawSelectionType == nsISelectionController::SELECTION_NORMAL &&
+        mSelectionType == SelectionType::SELECTION_NORMAL &&
         nsFrameSelection::sSelectionEventsEnabled && Collapsed() &&
         !IsBlockingSelectionChangeEvents()) {
       // First, we generate the ranges to add with a scratch range, which is a
       // clone of the original range passed in. We do this seperately, because the
       // selectstart event could have caused the world to change, and required
       // ranges to be re-generated
       RefPtr<nsRange> scratchRange = aItem->CloneRange();
       UserSelectRangesToAdd(scratchRange, rangesToAdd);
@@ -3979,18 +4048,17 @@ Selection::Clear(nsPresContext* aPresCon
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 Selection::GetType(int16_t* aType)
 {
   NS_ENSURE_ARG_POINTER(aType);
-  *aType = Type();
-
+  *aType = ToRawSelectionType(Type());
   return NS_OK;
 }
 
 // RangeMatches*Point
 //
 //    Compares the range beginning or ending point, and returns true if it
 //    exactly matches the given DOM point.
 
@@ -4331,29 +4399,29 @@ Selection::SelectAllFramesForContent(nsI
   nsIFrame *frame;
   if (NS_SUCCEEDED(result))
   {
     // First select frame of content passed in
     frame = aContent->GetPrimaryFrame();
     if (frame && frame->GetType() == nsGkAtoms::textFrame) {
       nsTextFrame* textFrame = static_cast<nsTextFrame*>(frame);
       textFrame->SetSelectedRange(0, aContent->GetText()->GetLength(),
-                                  aSelected, mRawSelectionType);
+                                  aSelected, mSelectionType);
     }
     // Now iterated through the child frames and set them
     while (!aInnerIter->IsDone()) {
       nsCOMPtr<nsIContent> innercontent =
         do_QueryInterface(aInnerIter->GetCurrentNode());
 
       frame = innercontent->GetPrimaryFrame();
       if (frame) {
         if (frame->GetType() == nsGkAtoms::textFrame) {
           nsTextFrame* textFrame = static_cast<nsTextFrame*>(frame);
           textFrame->SetSelectedRange(0, innercontent->GetText()->GetLength(),
-                                      aSelected, mRawSelectionType);
+                                      aSelected, mSelectionType);
         } else {
           frame->InvalidateFrameSubtree();  // frame continuations?
         }
       }
 
       aInnerIter->Next();
     }
 
@@ -4407,17 +4475,17 @@ Selection::selectFrames(nsPresContext* a
       uint32_t startOffset = aRange->StartOffset();
       uint32_t endOffset;
       if (aRange->GetEndParent() == content) {
         endOffset = aRange->EndOffset();
       } else {
         endOffset = content->Length();
       }
       textFrame->SetSelectedRange(startOffset, endOffset, aSelect,
-                                  mRawSelectionType);
+                                  mSelectionType);
     }
   }
 
   iter->First();
   nsCOMPtr<nsIContentIterator> inneriter = NS_NewContentIterator();
   for (iter->First(); !iter->IsDone(); iter->Next()) {
     content = do_QueryInterface(iter->GetCurrentNode());
     SelectAllFramesForContent(inneriter, content, aSelect);
@@ -4431,17 +4499,17 @@ Selection::selectFrames(nsPresContext* a
     NS_ENSURE_TRUE(content, res);
 
     if (content->IsNodeOfType(nsINode::eTEXT)) {
       nsIFrame* frame = content->GetPrimaryFrame();
       // The frame could be an SVG text frame, in which case we'll ignore it.
       if (frame && frame->GetType() == nsGkAtoms::textFrame) {
         nsTextFrame* textFrame = static_cast<nsTextFrame*>(frame);
         textFrame->SetSelectedRange(0, aRange->EndOffset(), aSelect,
-                                    mRawSelectionType);
+                                    mSelectionType);
       }
     }
   }
   return NS_OK;
 }
 
 
 // Selection::LookUpSelection
@@ -4467,17 +4535,17 @@ Selection::selectFrames(nsPresContext* a
 //    this case to make it faster by doing the same thing the previous version
 //    of this function did in the case of 1 range. This would also mean that
 //    the aSlowCheck flag would have meaning again.
 
 NS_IMETHODIMP
 Selection::LookUpSelection(nsIContent* aContent, int32_t aContentOffset,
                            int32_t aContentLength,
                            SelectionDetails** aReturnDetails,
-                           RawSelectionType aRawSelectionType,
+                           SelectionType aSelectionType,
                            bool aSlowCheck)
 {
   nsresult rv;
   if (!aContent || ! aReturnDetails)
     return NS_ERROR_NULL_POINTER;
 
   // it is common to have no ranges, to optimize that
   if (mRanges.Length() == 0)
@@ -4534,17 +4602,17 @@ Selection::LookUpSelection(nsIContent* a
     if (start < 0)
       continue; // the ranges do not overlap the input range
 
     SelectionDetails* details = new SelectionDetails;
 
     details->mNext = *aReturnDetails;
     details->mStart = start;
     details->mEnd = end;
-    details->mRawSelectionType = aRawSelectionType;
+    details->mSelectionType = aSelectionType;
     RangeData *rd = FindRangeData(range);
     if (rd) {
       details->mTextRangeStyle = rd->mTextRangeStyle;
     }
     *aReturnDetails = details;
   }
   return NS_OK;
 }
@@ -4850,17 +4918,17 @@ Selection::AddRange(nsRange& aRange, Err
 
   if (rangeIndex < 0) {
     return;
   }
 
   setAnchorFocusRange(rangeIndex);
   
   // Make sure the caret appears on the next line, if at a newline
-  if (mRawSelectionType == nsISelectionController::SELECTION_NORMAL) {
+  if (mSelectionType == SelectionType::SELECTION_NORMAL) {
     SetInterlinePosition(true);
   }
 
   RefPtr<nsPresContext>  presContext = GetPresContext();
   selectFrames(presContext, &aRange, true);
 
   if (!mFrameSelection)
     return;//nothing to do
@@ -4947,18 +5015,17 @@ Selection::RemoveRange(nsRange& aRange, 
   if (&aRange == mAnchorFocusRange) {
     // Reset anchor to LAST range or clear it if there are no ranges.
     setAnchorFocusRange(cnt - 1);
 
     // When the selection is user-created it makes sense to scroll the range
     // into view. The spell-check selection, however, is created and destroyed
     // in the background. We don't want to scroll in this case or the view
     // might appear to be moving randomly (bug 337871).
-    if (mRawSelectionType != nsISelectionController::SELECTION_SPELLCHECK &&
-        cnt > 0) {
+    if (mSelectionType != SelectionType::SELECTION_SPELLCHECK && cnt > 0) {
       ScrollIntoView(nsISelectionController::SELECTION_FOCUS_REGION);
     }
   }
 
   if (!mFrameSelection)
     return;//nothing to do
   rv = mFrameSelection->NotifySelectionListeners(GetType());
   if (NS_FAILED(rv)) {
@@ -6356,19 +6423,18 @@ Selection::SetSelectionDirection(nsDirec
 JSObject*
 Selection::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
   return mozilla::dom::SelectionBinding::Wrap(aCx, this, aGivenProto);
 }
 
 // AutoHideSelectionChanges
 AutoHideSelectionChanges::AutoHideSelectionChanges(const nsFrameSelection* aFrame)
-  : AutoHideSelectionChanges(aFrame ?
-                             aFrame->GetSelection(nsISelectionController::SELECTION_NORMAL) :
-                             nullptr)
+  : AutoHideSelectionChanges(
+      aFrame ? aFrame->GetSelection(SelectionType::SELECTION_NORMAL) : nullptr)
 {}
 
 // nsAutoCopyListener
 
 nsAutoCopyListener* nsAutoCopyListener::sInstance = nullptr;
 
 NS_IMPL_ISUPPORTS(nsAutoCopyListener, nsISelectionListener)
 
--- a/layout/generic/nsTextFrame.cpp
+++ b/layout/generic/nsTextFrame.cpp
@@ -335,29 +335,29 @@ public:
   enum {
     eIndexRawInput = 0,
     eIndexSelRawText,
     eIndexConvText,
     eIndexSelConvText,
     eIndexSpellChecker
   };
 
-  static int32_t GetUnderlineStyleIndexForRawSelectionType(
-                   RawSelectionType aRawSelectionType)
+  static int32_t GetUnderlineStyleIndexForSelectionType(
+                   SelectionType aSelectionType)
   {
-    switch (aRawSelectionType) {
-      case nsISelectionController::SELECTION_IME_RAWINPUT:
+    switch (aSelectionType) {
+      case SelectionType::SELECTION_IME_RAWINPUT:
         return eIndexRawInput;
-      case nsISelectionController::SELECTION_IME_SELECTEDRAWTEXT:
+      case SelectionType::SELECTION_IME_SELECTEDRAWTEXT:
         return eIndexSelRawText;
-      case nsISelectionController::SELECTION_IME_CONVERTEDTEXT:
+      case SelectionType::SELECTION_IME_CONVERTEDTEXT:
         return eIndexConvText;
-      case nsISelectionController::SELECTION_IME_SELECTEDCONVERTEDTEXT:
+      case SelectionType::SELECTION_IME_SELECTEDCONVERTEDTEXT:
         return eIndexSelConvText;
-      case nsISelectionController::SELECTION_SPELLCHECK:
+      case SelectionType::SELECTION_SPELLCHECK:
         return eIndexSpellChecker;
       default:
         NS_WARNING("non-IME selection type");
         return eIndexRawInput;
     }
   }
 
   nscolor GetSystemFieldForegroundColor();
@@ -5409,38 +5409,38 @@ nsTextFrame::ComputeDescentLimitForSelec
   if (lineHeight <= aFontMetrics.maxHeight) {
     return aFontMetrics.maxDescent;
   }
   return aFontMetrics.maxDescent + (lineHeight - aFontMetrics.maxHeight) / 2;
 }
 
 
 // Make sure this stays in sync with DrawSelectionDecorations below
-static const RawSelectionType RawSelectionTypesWithDecorations =
+static const RawSelectionType kRawSelectionTypesWithDecorations =
   nsISelectionController::SELECTION_SPELLCHECK |
   nsISelectionController::SELECTION_URLSTRIKEOUT |
   nsISelectionController::SELECTION_IME_RAWINPUT |
   nsISelectionController::SELECTION_IME_SELECTEDRAWTEXT |
   nsISelectionController::SELECTION_IME_CONVERTEDTEXT |
   nsISelectionController::SELECTION_IME_SELECTEDCONVERTEDTEXT;
 
 /* static */
 gfxFloat
 nsTextFrame::ComputeSelectionUnderlineHeight(
                nsPresContext* aPresContext,
                const gfxFont::Metrics& aFontMetrics,
-               RawSelectionType aRawSelectionType)
-{
-  switch (aRawSelectionType) {
-    case nsISelectionController::SELECTION_IME_RAWINPUT:
-    case nsISelectionController::SELECTION_IME_SELECTEDRAWTEXT:
-    case nsISelectionController::SELECTION_IME_CONVERTEDTEXT:
-    case nsISelectionController::SELECTION_IME_SELECTEDCONVERTEDTEXT:
+               SelectionType aSelectionType)
+{
+  switch (aSelectionType) {
+    case SelectionType::SELECTION_IME_RAWINPUT:
+    case SelectionType::SELECTION_IME_SELECTEDRAWTEXT:
+    case SelectionType::SELECTION_IME_CONVERTEDTEXT:
+    case SelectionType::SELECTION_IME_SELECTEDCONVERTEDTEXT:
       return aFontMetrics.underlineSize;
-    case nsISelectionController::SELECTION_SPELLCHECK: {
+    case SelectionType::SELECTION_SPELLCHECK: {
       // The thickness of the spellchecker underline shouldn't honor the font
       // metrics.  It should be constant pixels value which is decided from the
       // default font size.  Note that if the actual font size is smaller than
       // the default font size, we should use the actual font size because the
       // computed value from the default font size can be too thick for the
       // current font size.
       int32_t defaultFontSize =
         aPresContext->AppUnitsToDevPixels(nsStyleFont(aPresContext).mFont.size);
@@ -5490,23 +5490,23 @@ nsTextFrame::PaintDecorationLine(const P
     }
   } else {
     nsCSSRendering::PaintDecorationLine(
       this, *aParams.context->GetDrawTarget(), params);
   }
 }
 
 /**
- * This, plus RawSelectionTypesWithDecorations, encapsulates all knowledge about
- * drawing text decoration for selections.
+ * This, plus kRawSelectionTypesWithDecorations, encapsulates all knowledge
+ * about drawing text decoration for selections.
  */
 void
 nsTextFrame::DrawSelectionDecorations(gfxContext* aContext,
                                       const LayoutDeviceRect& aDirtyRect,
-                                      RawSelectionType aRawSelectionType,
+                                      SelectionType aSelectionType,
                                       nsTextPaintStyle& aTextPaintStyle,
                                       const TextRangeStyle &aRangeStyle,
                                       const Point& aPt,
                                       gfxFloat aICoordInFrame,
                                       gfxFloat aWidth,
                                       gfxFloat aAscent,
                                       const gfxFont::Metrics& aFontMetrics,
                                       DrawPathCallbacks* aCallbacks,
@@ -5515,42 +5515,41 @@ nsTextFrame::DrawSelectionDecorations(gf
                                       uint8_t aDecoration)
 {
   PaintDecorationLineParams params;
   params.context = aContext;
   params.dirtyRect = aDirtyRect;
   params.pt = aPt;
   params.lineSize = Size(
       aWidth, ComputeSelectionUnderlineHeight(aTextPaintStyle.PresContext(),
-                                              aFontMetrics, aRawSelectionType));
+                                              aFontMetrics, aSelectionType));
   params.ascent = aAscent;
   params.offset = aDecoration == NS_STYLE_TEXT_DECORATION_LINE_UNDERLINE ?
                   aFontMetrics.underlineOffset : aFontMetrics.maxAscent;
   params.decoration = aDecoration;
   params.decorationType = DecorationType::Selection;
   params.callbacks = aCallbacks;
   params.vertical = aVertical;
   params.descentLimit =
     ComputeDescentLimitForSelectionUnderline(aTextPaintStyle.PresContext(),
                                              aFontMetrics);
 
   float relativeSize;
   int32_t index =
-    nsTextPaintStyle::GetUnderlineStyleIndexForRawSelectionType(
-      aRawSelectionType);
+    nsTextPaintStyle::GetUnderlineStyleIndexForSelectionType(aSelectionType);
   bool weDefineSelectionUnderline =
     aTextPaintStyle.GetSelectionUnderlineForPaint(index, &params.color,
                                                   &relativeSize, &params.style);
 
 
-  switch (aRawSelectionType) {
-    case nsISelectionController::SELECTION_IME_RAWINPUT:
-    case nsISelectionController::SELECTION_IME_SELECTEDRAWTEXT:
-    case nsISelectionController::SELECTION_IME_CONVERTEDTEXT:
-    case nsISelectionController::SELECTION_IME_SELECTEDCONVERTEDTEXT: {
+  switch (aSelectionType) {
+    case SelectionType::SELECTION_IME_RAWINPUT:
+    case SelectionType::SELECTION_IME_SELECTEDRAWTEXT:
+    case SelectionType::SELECTION_IME_CONVERTEDTEXT:
+    case SelectionType::SELECTION_IME_SELECTEDCONVERTEDTEXT: {
       // IME decoration lines should not be drawn on the both ends, i.e., we
       // need to cut both edges of the decoration lines.  Because same style
       // IME selections can adjoin, but the users need to be able to know
       // where are the boundaries of the selections.
       //
       //  X: underline
       //
       //     IME selection #1        IME selection #2      IME selection #3
@@ -5582,35 +5581,35 @@ nsTextFrame::DrawSelectionDecorations(gf
         }
         // If foreground color or background color is defined, the both colors
         // are computed by GetSelectionTextColors().  Then, we should use its
         // foreground color always.  The color should have sufficient contrast
         // with the background color.
         else if (aRangeStyle.IsForegroundColorDefined() ||
                  aRangeStyle.IsBackgroundColorDefined()) {
           nscolor bg;
-          GetSelectionTextColors(aRawSelectionType, aTextPaintStyle,
+          GetSelectionTextColors(aSelectionType, aTextPaintStyle,
                                  aRangeStyle, &params.color, &bg);
         }
         // Otherwise, use the foreground color of the frame.
         else {
           params.color = aTextPaintStyle.GetTextColor();
         }
       } else if (!weDefineSelectionUnderline) {
         // IME doesn't specify the selection style and we don't define selection
         // underline.
         return;
       }
       break;
     }
-    case nsISelectionController::SELECTION_SPELLCHECK:
+    case SelectionType::SELECTION_SPELLCHECK:
       if (!weDefineSelectionUnderline)
         return;
       break;
-    case nsISelectionController::SELECTION_URLSTRIKEOUT: {
+    case SelectionType::SELECTION_URLSTRIKEOUT: {
       nscoord inflationMinFontSize =
         nsLayoutUtils::InflationMinFontSizeFor(this);
       float inflation =
         GetInflationForTextDecorations(this, inflationMinFontSize);
       const gfxFont::Metrics metrics =
         GetFirstFontMetrics(GetFontGroupForFrame(this, inflation), aVertical);
 
       relativeSize = 2.0f;
@@ -5626,36 +5625,36 @@ nsTextFrame::DrawSelectionDecorations(gf
   params.lineSize.height *= relativeSize;
   params.icoordInFrame = (aVertical ? params.pt.y - aPt.y
                                     : params.pt.x - aPt.x) + aICoordInFrame;
   PaintDecorationLine(params);
 }
 
 /* static */
 bool
-nsTextFrame::GetSelectionTextColors(RawSelectionType aRawSelectionType,
+nsTextFrame::GetSelectionTextColors(SelectionType aSelectionType,
                                     nsTextPaintStyle& aTextPaintStyle,
                                     const TextRangeStyle &aRangeStyle,
                                     nscolor* aForeground,
                                     nscolor* aBackground)
 {
-  switch (aRawSelectionType) {
-    case nsISelectionController::SELECTION_NORMAL:
+  switch (aSelectionType) {
+    case SelectionType::SELECTION_NORMAL:
       return aTextPaintStyle.GetSelectionColors(aForeground, aBackground);
-    case nsISelectionController::SELECTION_FIND:
+    case SelectionType::SELECTION_FIND:
       aTextPaintStyle.GetHighlightColors(aForeground, aBackground);
       return true;
-    case nsISelectionController::SELECTION_URLSECONDARY:
+    case SelectionType::SELECTION_URLSECONDARY:
       aTextPaintStyle.GetURLSecondaryColor(aForeground);
       *aBackground = NS_RGBA(0,0,0,0);
       return true;
-    case nsISelectionController::SELECTION_IME_RAWINPUT:
-    case nsISelectionController::SELECTION_IME_SELECTEDRAWTEXT:
-    case nsISelectionController::SELECTION_IME_CONVERTEDTEXT:
-    case nsISelectionController::SELECTION_IME_SELECTEDCONVERTEDTEXT:
+    case SelectionType::SELECTION_IME_RAWINPUT:
+    case SelectionType::SELECTION_IME_SELECTEDRAWTEXT:
+    case SelectionType::SELECTION_IME_CONVERTEDTEXT:
+    case SelectionType::SELECTION_IME_SELECTEDCONVERTEDTEXT:
       if (aRangeStyle.IsDefined()) {
         if (!aRangeStyle.IsForegroundColorDefined() &&
             !aRangeStyle.IsBackgroundColorDefined()) {
           *aForeground = aTextPaintStyle.GetTextColor();
           *aBackground = NS_RGBA(0,0,0,0);
           return false;
         }
         if (aRangeStyle.IsForegroundColorDefined()) {
@@ -5673,40 +5672,40 @@ nsTextFrame::GetSelectionTextColors(RawS
           // If background color is defined but foreground color isn't defined,
           // we can assume that IME must expect that the foreground color is
           // same as system's field text color.
           *aForeground = aTextPaintStyle.GetSystemFieldForegroundColor();
         }
         return true;
       }
       aTextPaintStyle.GetIMESelectionColors(
-        nsTextPaintStyle::GetUnderlineStyleIndexForRawSelectionType(
-          aRawSelectionType),
+        nsTextPaintStyle::GetUnderlineStyleIndexForSelectionType(
+          aSelectionType),
         aForeground, aBackground);
       return true;
     default:
       *aForeground = aTextPaintStyle.GetTextColor();
       *aBackground = NS_RGBA(0,0,0,0);
       return false;
   }
 }
 
 /**
  * This sets *aShadow to the appropriate shadow, if any, for the given
  * type of selection. Returns true if *aShadow was set.
  * If text-shadow was not specified, *aShadow is left untouched
  * (NOT reset to null), and the function returns false.
  */
 static bool GetSelectionTextShadow(nsIFrame* aFrame,
-                                   RawSelectionType aRawSelectionType,
+                                   SelectionType aSelectionType,
                                    nsTextPaintStyle& aTextPaintStyle,
                                    nsCSSShadowArray** aShadow)
 {
-  switch (aRawSelectionType) {
-    case nsISelectionController::SELECTION_NORMAL:
+  switch (aSelectionType) {
+    case SelectionType::SELECTION_NORMAL:
       return aTextPaintStyle.GetSelectionShadow(aShadow);
     default:
       return false;
   }
 }
 
 /**
  * This class lets us iterate over chunks of text in a uniform selection state,
@@ -5731,23 +5730,23 @@ public:
   /**
    * Returns the next segment of uniformly selected (or not) text.
    * @param aXOffset the offset from the origin of the frame to the start
    * of the text (the left baseline origin for LTR, the right baseline origin
    * for RTL)
    * @param aRange the transformed string range of the text for this segment
    * @param aHyphenWidth if a hyphen is to be rendered after the text, the
    * width of the hyphen, otherwise zero
-   * @param aRawSelectionType the selection type for this segment
+   * @param aSelectionType the selection type for this segment
    * @param aStyle the selection style for this segment
    * @return false if there are no more segments
    */
   bool GetNextSegment(gfxFloat* aXOffset, gfxTextRun::Range* aRange,
                       gfxFloat* aHyphenWidth,
-                      RawSelectionType* aRawSelectionType,
+                      SelectionType* aSelectionType,
                       TextRangeStyle* aStyle);
   void UpdateWithAdvance(gfxFloat aAdvance) {
     mXOffset += aAdvance*mTextRun->GetDirection();
   }
 
 private:
   SelectionDetails**      mSelectionDetails;
   PropertyProvider&       mProvider;
@@ -5766,29 +5765,29 @@ SelectionIterator::SelectionIterator(Sel
     mOriginalRange(aRange), mXOffset(aXOffset)
 {
   mIterator.SetOriginalOffset(aRange.start);
 }
 
 bool SelectionIterator::GetNextSegment(gfxFloat* aXOffset,
                                        gfxTextRun::Range* aRange,
                                        gfxFloat* aHyphenWidth,
-                                       RawSelectionType* aRawSelectionType,
+                                       SelectionType* aSelectionType,
                                        TextRangeStyle* aStyle)
 {
   if (mIterator.GetOriginalOffset() >= int32_t(mOriginalRange.end))
     return false;
   
   // save offset into transformed string now
   uint32_t runOffset = mIterator.GetSkippedOffset();
   
   uint32_t index = mIterator.GetOriginalOffset() - mOriginalRange.start;
   SelectionDetails* sdptr = mSelectionDetails[index];
-  RawSelectionType rawSelectionType =
-    sdptr ? sdptr->mRawSelectionType : nsISelectionController::SELECTION_NONE;
+  SelectionType selectionType =
+    sdptr ? sdptr->mSelectionType : SelectionType::SELECTION_NONE;
   TextRangeStyle style;
   if (sdptr) {
     style = sdptr->mTextRangeStyle;
   }
   for (++index; index < mOriginalRange.Length(); ++index) {
     if (sdptr != mSelectionDetails[index])
       break;
   }
@@ -5806,17 +5805,17 @@ bool SelectionIterator::GetNextSegment(g
   aRange->start = runOffset;
   aRange->end = mIterator.GetSkippedOffset();
   *aXOffset = mXOffset;
   *aHyphenWidth = 0;
   if (mIterator.GetOriginalOffset() == int32_t(mOriginalRange.end) &&
       haveHyphenBreak) {
     *aHyphenWidth = mProvider.GetHyphenWidth();
   }
-  *aRawSelectionType = rawSelectionType;
+  *aSelectionType = selectionType;
   *aStyle = style;
   return true;
 }
 
 static void
 AddHyphenToMetrics(nsTextFrame* aTextFrame, gfxTextRun* aBaseTextRun,
                    gfxTextRun::Metrics* aMetrics,
                    gfxFont::BoundingBoxType aBoundingBoxType,
@@ -5942,31 +5941,31 @@ nsTextFrame::PaintTextWithSelectionColor
   }
 
   SelectionDetails *sdptr = aDetails;
   bool anyBackgrounds = false;
   while (sdptr) {
     int32_t start = std::max(0, sdptr->mStart - int32_t(contentRange.start));
     int32_t end = std::min(int32_t(contentRange.Length()),
                            sdptr->mEnd - int32_t(contentRange.start));
-    RawSelectionType rawSelectionType = sdptr->mRawSelectionType;
+    SelectionType selectionType = sdptr->mSelectionType;
     if (start < end) {
-      allRawSelectionTypes |= rawSelectionType;
+      allRawSelectionTypes |= ToRawSelectionType(selectionType);
       // Ignore selections that don't set colors
       nscolor foreground, background;
-      if (GetSelectionTextColors(rawSelectionType, *aParams.textPaintStyle,
+      if (GetSelectionTextColors(selectionType, *aParams.textPaintStyle,
                                  sdptr->mTextRangeStyle,
                                  &foreground, &background)) {
         if (NS_GET_A(background) > 0) {
           anyBackgrounds = true;
         }
         for (int32_t i = start; i < end; ++i) {
           // Favour normal selection over IME selections
           if (!prevailingSelections[i] ||
-              rawSelectionType < prevailingSelections[i]->mRawSelectionType) {
+              selectionType < prevailingSelections[i]->mSelectionType) {
             prevailingSelections[i] = sdptr;
           }
         }
       }
     }
     sdptr = sdptr->mNext;
   }
   *aAllRawSelectionTypes = allRawSelectionTypes;
@@ -5977,29 +5976,29 @@ nsTextFrame::PaintTextWithSelectionColor
   }
 
   bool vertical = mTextRun->IsVertical();
   const gfxFloat startIOffset = vertical ?
     aParams.textBaselinePt.y - aParams.framePt.y :
     aParams.textBaselinePt.x - aParams.framePt.x;
   gfxFloat iOffset, hyphenWidth;
   Range range; // in transformed string
-  RawSelectionType rawSelectionType;
   TextRangeStyle rangeStyle;
   // Draw background colors
   if (anyBackgrounds && (!aParams.generateTextMask ||
                          aParams.paintSelectionBackground)) {
     int32_t appUnitsPerDevPixel =
       aParams.textPaintStyle->PresContext()->AppUnitsPerDevPixel();
     SelectionIterator iterator(prevailingSelections, contentRange,
                                *aParams.provider, mTextRun, startIOffset);
+    SelectionType selectionType;
     while (iterator.GetNextSegment(&iOffset, &range, &hyphenWidth,
-                                   &rawSelectionType, &rangeStyle)) {
+                                   &selectionType, &rangeStyle)) {
       nscolor foreground, background;
-      GetSelectionTextColors(rawSelectionType, *aParams.textPaintStyle,
+      GetSelectionTextColors(selectionType, *aParams.textPaintStyle,
                              rangeStyle, &foreground, &background);
       // Draw background color
       gfxFloat advance = hyphenWidth +
         mTextRun->GetAdvanceWidth(range, aParams.provider);
       if (NS_GET_A(background) > 0) {
         nsRect bgRect;
         gfxFloat offs = iOffset - (mTextRun->IsInlineReversed() ? advance : 0);
         if (vertical) {
@@ -6035,34 +6034,35 @@ nsTextFrame::PaintTextWithSelectionColor
   PaintShadowParams shadowParams(aParams);
   shadowParams.provider = aParams.provider;
   shadowParams.clipEdges = &aClipEdges;
 
   // Draw text
   const nsStyleText* textStyle = StyleText();
   SelectionIterator iterator(prevailingSelections, contentRange,
                              *aParams.provider, mTextRun, startIOffset);
+  SelectionType selectionType;
   while (iterator.GetNextSegment(&iOffset, &range, &hyphenWidth,
-                                 &rawSelectionType, &rangeStyle)) {
+                                 &selectionType, &rangeStyle)) {
     nscolor foreground, background;
     if (aParams.generateTextMask) {
       foreground = NS_RGBA(0, 0, 0, 255);
     } else {
-      GetSelectionTextColors(rawSelectionType, *aParams.textPaintStyle,
+      GetSelectionTextColors(selectionType, *aParams.textPaintStyle,
                              rangeStyle, &foreground, &background);
     }
 
     gfxPoint textBaselinePt = vertical ?
       gfxPoint(aParams.textBaselinePt.x, aParams.framePt.y + iOffset) :
       gfxPoint(aParams.framePt.x + iOffset, aParams.textBaselinePt.y);
 
     // Determine what shadow, if any, to draw - either from textStyle
     // or from the ::-moz-selection pseudo-class if specified there
     nsCSSShadowArray* shadow = textStyle->GetTextShadow();
-    GetSelectionTextShadow(this, rawSelectionType, *aParams.textPaintStyle,
+    GetSelectionTextShadow(this, selectionType, *aParams.textPaintStyle,
                            &shadow);
     if (shadow) {
       nscoord startEdge = iOffset;
       if (mTextRun->IsInlineReversed()) {
         startEdge -= hyphenWidth +
           mTextRun->GetAdvanceWidth(range, aParams.provider);
       }
       shadowParams.range = range;
@@ -6082,17 +6082,17 @@ nsTextFrame::PaintTextWithSelectionColor
     iterator.UpdateWithAdvance(advance);
   }
   return true;
 }
 
 void
 nsTextFrame::PaintTextSelectionDecorations(
     const PaintTextSelectionParams& aParams,
-    SelectionDetails* aDetails, RawSelectionType aRawSelectionType)
+    SelectionDetails* aDetails, SelectionType aSelectionType)
 {
   // Hide text decorations if we're currently hiding @font-face fallback text
   if (aParams.provider->GetFontGroup()->ShouldSkipDrawing())
     return;
 
   // Figure out which characters will be decorated for this selection.
   const gfxTextRun::Range& contentRange = aParams.contentRange;
   AutoTArray<SelectionDetails*, BIG_TEXT_NODE_SIZE> selectedCharsBuffer;
@@ -6102,17 +6102,17 @@ nsTextFrame::PaintTextSelectionDecoratio
     return;
   }
   for (uint32_t i = 0; i < contentRange.Length(); ++i) {
     selectedChars[i] = nullptr;
   }
 
   SelectionDetails *sdptr = aDetails;
   while (sdptr) {
-    if (sdptr->mRawSelectionType == aRawSelectionType) {
+    if (sdptr->mSelectionType == aSelectionType) {
       int32_t start = std::max(0, sdptr->mStart - int32_t(contentRange.start));
       int32_t end = std::min(int32_t(contentRange.Length()),
                              sdptr->mEnd - int32_t(contentRange.start));
       for (int32_t i = start; i < end; ++i) {
         selectedChars[i] = sdptr;
       }
     }
     sdptr = sdptr->mNext;
@@ -6146,34 +6146,34 @@ nsTextFrame::PaintTextSelectionDecoratio
   // XXX aTextBaselinePt is in AppUnits, shouldn't it be nsFloatPoint?
   Point pt;
   if (verticalRun) {
     pt.x = (aParams.textBaselinePt.x - mAscent) / app;
   } else {
     pt.y = (aParams.textBaselinePt.y - mAscent) / app;
   }
   gfxFloat decorationOffsetDir = mTextRun->IsSidewaysLeft() ? -1.0 : 1.0;
-  RawSelectionType rawSelectionType;
+  SelectionType nextSelectionType;
   TextRangeStyle selectedStyle;
   while (iterator.GetNextSegment(&iOffset, &range, &hyphenWidth,
-                                 &rawSelectionType, &selectedStyle)) {
+                                 &nextSelectionType, &selectedStyle)) {
     gfxFloat advance = hyphenWidth +
       mTextRun->GetAdvanceWidth(range, aParams.provider);
-    if (rawSelectionType == aRawSelectionType) {
+    if (nextSelectionType == aSelectionType) {
       if (verticalRun) {
         pt.y = (aParams.framePt.y + iOffset -
                (mTextRun->IsInlineReversed() ? advance : 0)) / app;
       } else {
         pt.x = (aParams.framePt.x + iOffset -
                (mTextRun->IsInlineReversed() ? advance : 0)) / app;
       }
       gfxFloat width = Abs(advance) / app;
       gfxFloat xInFrame = pt.x - (aParams.framePt.x / app);
       DrawSelectionDecorations(
-        aParams.context, aParams.dirtyRect, aRawSelectionType,
+        aParams.context, aParams.dirtyRect, aSelectionType,
         *aParams.textPaintStyle, selectedStyle, pt, xInFrame,
         width, mAscent / app, decorationMetrics, aParams.callbacks,
         verticalRun, decorationOffsetDir, kDecoration);
     }
     iterator.UpdateWithAdvance(advance);
   }
 }
 
@@ -6194,25 +6194,25 @@ nsTextFrame::PaintTextWithSelection(
                                     aClipEdges)) {
     DestroySelectionDetails(details);
     return false;
   }
   // Iterate through just the selection rawSelectionTypes that paint decorations
   // and paint decorations for any that actually occur in this frame. Paint
   // higher-numbered selection rawSelectionTypes below lower-numered ones on the
   // general principal that lower-numbered selections are higher priority.
-  allRawSelectionTypes &= RawSelectionTypesWithDecorations;
+  allRawSelectionTypes &= kRawSelectionTypesWithDecorations;
   for (int32_t i = nsISelectionController::NUM_SELECTIONTYPES - 1;
        i >= 1; --i) {
-    RawSelectionType rawSelectionType = 1 << (i - 1);
-    if (allRawSelectionTypes & rawSelectionType) {
-      // There is some selection of this rawSelectionType. Try to paint its
+    SelectionType selectionType = ToSelectionType(1 << (i - 1));
+    if (selectionType & allRawSelectionTypes) {
+      // There is some selection of this selectionType. Try to paint its
       // decorations (there might not be any for this type but that's OK,
       // PaintTextSelectionDecorations will exit early).
-      PaintTextSelectionDecorations(aParams, details, rawSelectionType);
+      PaintTextSelectionDecorations(aParams, details, selectionType);
     }
   }
 
   DestroySelectionDetails(details);
   return true;
 }
 
 void
@@ -6288,34 +6288,34 @@ nsTextFrame::GetCaretColorAt(int32_t aOf
       isSolidTextColor = false;
     }
   }
 
   nsTextPaintStyle textPaintStyle(this);
   textPaintStyle.SetResolveColors(isSolidTextColor);
   SelectionDetails* details = GetSelectionDetails();
   SelectionDetails* sdptr = details;
-  RawSelectionType rawSelectionType = 0;
+  SelectionType selectionType = SelectionType::SELECTION_NONE;
   while (sdptr) {
     int32_t start = std::max(0, sdptr->mStart - contentOffset);
     int32_t end = std::min(contentLength, sdptr->mEnd - contentOffset);
     if (start <= offsetInFrame && offsetInFrame < end &&
-        (rawSelectionType == 0 ||
-         sdptr->mRawSelectionType < rawSelectionType)) {
+        (selectionType == SelectionType::SELECTION_NONE ||
+         sdptr->mSelectionType < selectionType)) {
       nscolor foreground, background;
-      if (GetSelectionTextColors(sdptr->mRawSelectionType, textPaintStyle,
+      if (GetSelectionTextColors(sdptr->mSelectionType, textPaintStyle,
                                  sdptr->mTextRangeStyle,
                                  &foreground, &background)) {
         if (!isSolidTextColor &&
             NS_IS_SELECTION_SPECIAL_COLOR(foreground)) {
           result = NS_RGBA(0, 0, 0, 255);
         } else {
           result = foreground;
         }
-        rawSelectionType = sdptr->mRawSelectionType;
+        selectionType = sdptr->mSelectionType;
       }
     }
     sdptr = sdptr->mNext;
   }
 
   DestroySelectionDetails(details);
   return result;
 }
@@ -6901,17 +6901,17 @@ nsTextFrame::IsVisibleInSelection(nsISel
   SelectionDetails* details = GetSelectionDetails();
   bool found = false;
     
   // where are the selection points "really"
   SelectionDetails *sdptr = details;
   while (sdptr) {
     if (sdptr->mEnd > GetContentOffset() &&
         sdptr->mStart < GetContentEnd() &&
-        sdptr->mRawSelectionType == nsISelectionController::SELECTION_NORMAL) {
+        sdptr->mSelectionType == SelectionType::SELECTION_NORMAL) {
       found = true;
       break;
     }
     sdptr = sdptr->mNext;
   }
   DestroySelectionDetails(details);
 
   return found;
@@ -7072,24 +7072,25 @@ nsTextFrame::CombineSelectionUnderlineRe
   params.offset = fontGroup->GetUnderlineOffset();
   params.descentLimit =
     ComputeDescentLimitForSelectionUnderline(aPresContext, metrics);
   params.vertical = verticalRun;
 
   SelectionDetails *details = GetSelectionDetails();
   for (SelectionDetails *sd = details; sd; sd = sd->mNext) {
     if (sd->mStart == sd->mEnd ||
-        !(sd->mRawSelectionType & RawSelectionTypesWithDecorations))
+        !(sd->mSelectionType & kRawSelectionTypesWithDecorations)) {
       continue;
+    }
 
     float relativeSize;
     int32_t index =
-      nsTextPaintStyle::GetUnderlineStyleIndexForRawSelectionType(
-        sd->mRawSelectionType);
-    if (sd->mRawSelectionType == nsISelectionController::SELECTION_SPELLCHECK) {
+      nsTextPaintStyle::GetUnderlineStyleIndexForSelectionType(
+        sd->mSelectionType);
+    if (sd->mSelectionType == SelectionType::SELECTION_SPELLCHECK) {
       if (!nsTextPaintStyle::GetSelectionUnderline(aPresContext, index, nullptr,
                                                    &relativeSize,
                                                    &params.style)) {
         continue;
       }
     } else {
       // IME selections
       TextRangeStyle& rangeStyle = sd->mTextRangeStyle;
@@ -7106,17 +7107,17 @@ nsTextFrame::CombineSelectionUnderlineRe
         continue;
       }
     }
     nsRect decorationArea;
 
     params.lineSize =
       Size(aPresContext->AppUnitsToGfxUnits(aRect.width),
            ComputeSelectionUnderlineHeight(aPresContext, metrics,
-                                           sd->mRawSelectionType));
+                                           sd->mSelectionType));
     relativeSize = std::max(relativeSize, 1.0f);
     params.lineSize.height *= relativeSize;
     decorationArea =
       nsCSSRendering::GetTextDecorationRect(aPresContext, params);
     aRect.UnionRect(aRect, decorationArea);
   }
   DestroySelectionDetails(details);
 
@@ -7129,17 +7130,17 @@ nsTextFrame::IsFrameSelected() const
   NS_ASSERTION(!GetContent() || GetContent()->IsSelectionDescendant(),
                "use the public IsSelected() instead");
   return nsRange::IsNodeSelected(GetContent(), GetContentOffset(),
                                  GetContentEnd());
 }
 
 void
 nsTextFrame::SetSelectedRange(uint32_t aStart, uint32_t aEnd, bool aSelected,
-                              RawSelectionType aRawSelectionType)
+                              SelectionType aSelectionType)
 {
   NS_ASSERTION(!GetPrevContinuation(), "Should only be called for primary frame");
   DEBUG_VERIFY_NOT_DIRTY(mState);
 
   // Selection is collapsed, which can't affect text frame rendering
   if (aStart == aEnd)
     return;
 
@@ -7148,17 +7149,17 @@ nsTextFrame::SetSelectedRange(uint32_t a
     f = static_cast<nsTextFrame*>(f->GetNextContinuation());
   }
 
   nsPresContext* presContext = PresContext();
   while (f && f->GetContentOffset() < int32_t(aEnd)) {
     // We may need to reflow to recompute the overflow area for
     // spellchecking or IME underline if their underline is thicker than
     // the normal decoration line.
-    if (aRawSelectionType & RawSelectionTypesWithDecorations) {
+    if (aSelectionType & kRawSelectionTypesWithDecorations) {
       bool didHaveOverflowingSelection =
         (f->GetStateBits() & TEXT_SELECTION_UNDERLINE_OVERFLOWED) != 0;
       nsRect r(nsPoint(0, 0), GetSize());
       bool willHaveOverflowingSelection =
         aSelected && f->CombineSelectionUnderlineRect(presContext, r);
       if (didHaveOverflowingSelection || willHaveOverflowingSelection) {
         presContext->PresShell()->FrameNeedsReflow(f,
                                                    nsIPresShell::eStyleChange,
--- a/layout/generic/nsTextFrame.h
+++ b/layout/generic/nsTextFrame.h
@@ -29,16 +29,17 @@ struct SelectionDetails;
 class nsTextFragment;
 
 class nsDisplayTextGeometry;
 class nsDisplayText;
 
 class nsTextFrame : public nsFrame {
   typedef mozilla::LayoutDeviceRect LayoutDeviceRect;
   typedef mozilla::RawSelectionType RawSelectionType;
+  typedef mozilla::SelectionType SelectionType;
   typedef mozilla::TextRangeStyle TextRangeStyle;
   typedef mozilla::gfx::DrawTarget DrawTarget;
   typedef mozilla::gfx::Point Point;
   typedef mozilla::gfx::Rect Rect;
   typedef mozilla::gfx::Size Size;
   typedef gfxTextRun::Range Range;
 
 public:
@@ -155,17 +156,17 @@ public:
    * the selection state of the given character range has changed.
    * Text in the range is unconditionally invalidated
    * (Selection::Repaint depends on this).
    * @param aSelected true if the selection has been added to the range,
    * false otherwise
    * @param aType the type of selection added or removed
    */
   void SetSelectedRange(uint32_t aStart, uint32_t aEnd, bool aSelected,
-                        RawSelectionType aRawSelectionType);
+                        SelectionType aSelectionType);
 
   virtual FrameSearchResult PeekOffsetNoAmount(bool aForward, int32_t* aOffset) override;
   virtual FrameSearchResult PeekOffsetCharacter(bool aForward, int32_t* aOffset,
                                      bool aRespectClusters = true) override;
   virtual FrameSearchResult PeekOffsetWord(bool aForward, bool aWordSelectEatSpace, bool aIsKeyboardSelect,
                                 int32_t* aOffset, PeekWordState* aState) override;
 
   virtual nsresult CheckVisibility(nsPresContext* aContext, int32_t aStartIndex, int32_t aEndIndex, bool aRecurse, bool *aFinished, bool *_retval) override;
@@ -452,17 +453,17 @@ public:
   bool PaintTextWithSelectionColors(
          const PaintTextSelectionParams& aParams,
          SelectionDetails* aDetails,
          RawSelectionType* aAllRawSelectionTypes,
          const nsCharClipDisplayItem::ClipEdges& aClipEdges);
   // helper: paint text decorations for text selected by aSelectionType
   void PaintTextSelectionDecorations(const PaintTextSelectionParams& aParams,
                                      SelectionDetails* aDetails,
-                                     RawSelectionType aRawSelectionType);
+                                     SelectionType aSelectionType);
 
   void DrawEmphasisMarks(gfxContext* aContext,
                          mozilla::WritingMode aWM,
                          const gfxPoint& aTextBaselinePt,
                          const gfxPoint& aFramePt, Range aRange,
                          const nscolor* aDecorationOverrideColor,
                          PropertyProvider* aProvider);
 
@@ -731,17 +732,17 @@ protected:
   bool CombineSelectionUnderlineRect(nsPresContext* aPresContext,
                                        nsRect& aRect);
 
   /**
    * Utility methods to paint selection.
    */
   void DrawSelectionDecorations(gfxContext* aContext,
                                 const LayoutDeviceRect& aDirtyRect,
-                                mozilla::RawSelectionType aRawSelectionType,
+                                mozilla::SelectionType aSelectionType,
                                 nsTextPaintStyle& aTextPaintStyle,
                                 const TextRangeStyle &aRangeStyle,
                                 const Point& aPt,
                                 gfxFloat aICoordInFrame,
                                 gfxFloat aWidth,
                                 gfxFloat aAscent,
                                 const gfxFont::Metrics& aFontMetrics,
                                 DrawPathCallbacks* aCallbacks,
@@ -764,29 +765,29 @@ protected:
   /**
    * This function encapsulates all knowledge of how selections affect
    * foreground and background colors.
    * @param aForeground the foreground color to use
    * @param aBackground the background color to use, or RGBA(0,0,0,0) if no
    *                    background should be painted
    * @return            true if the selection affects colors, false otherwise
    */
-  static bool GetSelectionTextColors(RawSelectionType aRawSelectionType,
+  static bool GetSelectionTextColors(SelectionType aSelectionType,
                                      nsTextPaintStyle& aTextPaintStyle,
                                      const TextRangeStyle &aRangeStyle,
                                      nscolor* aForeground,
                                      nscolor* aBackground);
   /**
    * ComputeSelectionUnderlineHeight() computes selection underline height of
    * the specified selection type from the font metrics.
    */
   static gfxFloat ComputeSelectionUnderlineHeight(
                     nsPresContext* aPresContext,
                     const gfxFont::Metrics& aFontMetrics,
-                    RawSelectionType aRawSelectionType);
+                    SelectionType aSelectionType);
 
   ContentOffsets GetCharacterOffsetAtFramePointInternal(nsPoint aPoint,
                    bool aForInsertionPoint);
 
   void ClearFrameOffsetCache();
 
   virtual bool HasAnyNoncollapsedCharacters() override;
 
--- a/layout/printing/nsPrintEngine.cpp
+++ b/layout/printing/nsPrintEngine.cpp
@@ -1094,17 +1094,17 @@ nsPrintEngine::IsThereARangeSelection(ns
   }
 
   if (!presShell)
     return false;
 
   // check here to see if there is a range selection
   // so we know whether to turn on the "Selection" radio button
   Selection* selection =
-    presShell->GetCurrentSelection(nsISelectionController::SELECTION_NORMAL);
+    presShell->GetCurrentSelection(SelectionType::SELECTION_NORMAL);
   if (!selection) {
     return false;
   }
 
   int32_t rangeCount = selection->RangeCount();
   if (!rangeCount) {
     return false;
   }
@@ -1955,19 +1955,19 @@ nsresult
 nsPrintEngine::UpdateSelectionAndShrinkPrintObject(nsPrintObject* aPO,
                                                    bool aDocumentIsTopLevel)
 {
   nsCOMPtr<nsIPresShell> displayShell = aPO->mDocShell->GetPresShell();
   // Transfer Selection Ranges to the new Print PresShell
   RefPtr<Selection> selection, selectionPS;
   // It's okay if there is no display shell, just skip copying the selection
   if (displayShell) {
-    selection = displayShell->GetCurrentSelection(nsISelectionController::SELECTION_NORMAL);
+    selection = displayShell->GetCurrentSelection(SelectionType::SELECTION_NORMAL);
   }
-  selectionPS = aPO->mPresShell->GetCurrentSelection(nsISelectionController::SELECTION_NORMAL);
+  selectionPS = aPO->mPresShell->GetCurrentSelection(SelectionType::SELECTION_NORMAL);
 
   // Reset all existing selection ranges that might have been added by calling
   // this function before.
   if (selectionPS) {
     selectionPS->RemoveAllRanges();
   }
   if (selection && selectionPS) {
     int32_t cnt = selection->RangeCount();
@@ -2368,19 +2368,19 @@ CloneRangeToSelection(nsRange* aRange, n
 
 static nsresult CloneSelection(nsIDocument* aOrigDoc, nsIDocument* aDoc)
 {
   nsIPresShell* origShell = aOrigDoc->GetShell();
   nsIPresShell* shell = aDoc->GetShell();
   NS_ENSURE_STATE(origShell && shell);
 
   RefPtr<Selection> origSelection =
-    origShell->GetCurrentSelection(nsISelectionController::SELECTION_NORMAL);
+    origShell->GetCurrentSelection(SelectionType::SELECTION_NORMAL);
   RefPtr<Selection> selection =
-    shell->GetCurrentSelection(nsISelectionController::SELECTION_NORMAL);
+    shell->GetCurrentSelection(SelectionType::SELECTION_NORMAL);
   NS_ENSURE_STATE(origSelection && selection);
 
   int32_t rangeCount = origSelection->RangeCount();
   for (int32_t i = 0; i < rangeCount; ++i) {
       CloneRangeToSelection(origSelection->GetRangeAt(i), aDoc, selection);
   }
   return NS_OK;
 }
--- a/widget/TextRange.h
+++ b/widget/TextRange.h
@@ -6,16 +6,17 @@
 #ifndef mozilla_TextRage_h_
 #define mozilla_TextRage_h_
 
 #include <stdint.h>
 
 #include "mozilla/EventForwards.h"
 
 #include "nsColor.h"
+#include "nsISelectionController.h"
 #include "nsITextInputProcessor.h"
 #include "nsStyleConsts.h"
 #include "nsTArray.h"
 
 namespace mozilla {
 
 /******************************************************************************
  * mozilla::TextRangeStyle
@@ -137,16 +138,22 @@ enum class TextRangeType : RawTextRangeT
   eConvertedClause   = nsITextInputProcessor::ATTR_CONVERTED_CLAUSE,
   eSelectedClause    = nsITextInputProcessor::ATTR_SELECTED_CLAUSE
 };
 
 bool IsValidRawTextRangeValue(RawTextRangeType aRawTextRangeValue);
 RawTextRangeType ToRawTextRangeType(TextRangeType aTextRangeType);
 TextRangeType ToTextRangeType(RawTextRangeType aRawTextRangeType);
 const char* ToChar(TextRangeType aTextRangeType);
+SelectionType ToSelectionType(TextRangeType aTextRangeType);
+
+inline RawSelectionType ToRawSelectionType(TextRangeType aTextRangeType)
+{
+  return ToRawSelectionType(ToSelectionType(aTextRangeType));
+}
 
 struct TextRange
 {
   TextRange()
     : mStartOffset(0)
     , mEndOffset(0)
     , mRangeType(TextRangeType::eUninitialized)
   {
--- a/widget/WidgetEventImpl.cpp
+++ b/widget/WidgetEventImpl.cpp
@@ -102,16 +102,34 @@ ToChar(TextRangeType aTextRangeType)
       return "TextRangeType::eConvertedClause";
     case TextRangeType::eSelectedClause:
       return "TextRangeType::eSelectedClause";
     default:
       return "Invalid TextRangeType";
   }
 }
 
+SelectionType
+ToSelectionType(TextRangeType aTextRangeType)
+{
+  switch (aTextRangeType) {
+    case TextRangeType::eRawClause:
+      return SelectionType::SELECTION_IME_RAWINPUT;
+    case TextRangeType::eSelectedRawClause:
+      return SelectionType::SELECTION_IME_SELECTEDRAWTEXT;
+    case TextRangeType::eConvertedClause:
+      return SelectionType::SELECTION_IME_CONVERTEDTEXT;
+    case TextRangeType::eSelectedClause:
+      return SelectionType::SELECTION_IME_SELECTEDCONVERTEDTEXT;
+    default:
+      MOZ_CRASH("TextRangeType is invalid");
+      return SelectionType::SELECTION_NORMAL;
+  }
+}
+
 /******************************************************************************
  * As*Event() implementation
  ******************************************************************************/
 
 #define NS_ROOT_EVENT_CLASS(aPrefix, aName)
 #define NS_EVENT_CLASS(aPrefix, aName) \
 aPrefix##aName* \
 WidgetEvent::As##aName() \