Bug 552914 nsEditor::mFlags is never modified by SetFlags() r=smaug
authorMasayuki Nakano <masayuki@d-toybox.com>
Mon, 12 Apr 2010 11:35:18 +0900
changeset 40703 97aec61ae55fadd69e95efba84b2b3496f342bc9
parent 40702 b501122477cc9f5ca715b132813ce33af260c97b
child 40704 9acb882b289039eb3f616a1d10e73a14a8294057
push id12755
push usermasayuki@d-toybox.com
push dateMon, 12 Apr 2010 02:36:42 +0000
treeherdermozilla-central@97aec61ae55f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug
bugs552914
milestone1.9.3a5pre
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
Bug 552914 nsEditor::mFlags is never modified by SetFlags() r=smaug
editor/idl/nsIPlaintextEditor.idl
editor/libeditor/base/nsEditRules.h
editor/libeditor/base/nsEditor.cpp
editor/libeditor/base/nsEditor.h
editor/libeditor/base/nsEditorEventListener.cpp
editor/libeditor/html/nsHTMLDataTransfer.cpp
editor/libeditor/html/nsHTMLEditRules.cpp
editor/libeditor/html/nsHTMLEditRules.h
editor/libeditor/html/nsHTMLEditor.cpp
editor/libeditor/html/nsHTMLEditor.h
editor/libeditor/text/nsPlaintextDataTransfer.cpp
editor/libeditor/text/nsPlaintextEditor.cpp
editor/libeditor/text/nsPlaintextEditor.h
editor/libeditor/text/nsTextEditRules.cpp
editor/libeditor/text/nsTextEditRules.h
--- a/editor/idl/nsIPlaintextEditor.idl
+++ b/editor/idl/nsIPlaintextEditor.idl
@@ -39,28 +39,44 @@
 
 interface nsIDOMKeyEvent;
 
 [scriptable, uuid(1480e196-0d5c-40cf-8563-ed8a33eabcf2)]
 interface nsIPlaintextEditor : nsISupports
 {
 
   // XXX Why aren't these in nsIEditor?
-  const long eEditorPlaintextMask       = 0x0001; /* only plain text entry is allowed via events */
-  const long eEditorSingleLineMask      = 0x0002; /* enter key and CR-LF handled specially */
-  const long eEditorPasswordMask        = 0x0004; /* text is not entered into content, only a representative character */
-  const long eEditorReadonlyMask        = 0x0008; /* editing events are disabled.  Editor may still accept focus. */
-  const long eEditorDisabledMask        = 0x0010; /* all events are disabled (like scrolling).  Editor will not accept focus. */
-  const long eEditorFilterInputMask     = 0x0020; /* text input is limited to certain character types, use mFilter */
-  const long eEditorMailMask            = 0x0040; /* use mail-compose editing rules */
-  const long eEditorUseAsyncUpdatesMask = 0x0080; /* prevent immediate reflows and view refreshes */
-  const long eEditorEnableWrapHackMask  = 0x0100; /* allow the editor to set font: monospace on the root node */
-  const long eEditorWidgetMask          = 0x0200; /* bit for widgets */
-  const long eEditorNoCSSMask           = 0x0400; /* this HTML editor should not create css styles */
-  const long eEditorAllowInteraction    = 0x0800; /*  */
+  // only plain text entry is allowed via events
+  const long eEditorPlaintextMask       = 0x0001;
+  // enter key and CR-LF handled specially
+  const long eEditorSingleLineMask      = 0x0002;
+  // text is not entered into content, only a representative character
+  const long eEditorPasswordMask        = 0x0004;
+  // editing events are disabled.  Editor may still accept focus.
+  const long eEditorReadonlyMask        = 0x0008;
+  // all events are disabled (like scrolling).  Editor will not accept focus.
+  const long eEditorDisabledMask        = 0x0010;
+  // text input is limited to certain character types, use mFilter
+  const long eEditorFilterInputMask     = 0x0020;
+  // use mail-compose editing rules
+  const long eEditorMailMask            = 0x0040;
+  // prevent immediate reflows and view refreshes
+  const long eEditorUseAsyncUpdatesMask = 0x0080;
+  // allow the editor to set font: monospace on the root node
+  const long eEditorEnableWrapHackMask  = 0x0100;
+  // bit for widgets (form elements)
+  const long eEditorWidgetMask          = 0x0200;
+  // this HTML editor should not create css styles
+  const long eEditorNoCSSMask           = 0x0400;
+  // whether HTML document specific actions are executed or not.
+  // e.g., if this flag is set, the editor doesn't handle Tab key.
+  // besides, anchors of HTML are not clickable.
+  const long eEditorAllowInteraction    = 0x0800;
+  // when this is set, the characters in password editor are always masked.
+  // see bug 530367 for the detail.
   const long eEditorDontEchoPassword    = 0x1000;
 
   /*
    * The valid values for newlines handling.
    * Can't change the values unless we remove
    * use of the pref.
    */
   const long eNewlinesPasteIntact                = 0;
--- a/editor/libeditor/base/nsEditRules.h
+++ b/editor/libeditor/base/nsEditRules.h
@@ -33,20 +33,20 @@
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #ifndef nsEditRules_h__
 #define nsEditRules_h__
 
-// 783223c9-153a-4e01-8422-39a3afe469da
+// FB45AC36-E8F1-44ae-8FB7-466E1BE119B0
 #define NS_IEDITRULES_IID \
-{ 0x783223c9, 0x153a, 0x4e01, \
-  { 0x84, 0x22, 0x39, 0xa3, 0xaf, 0xe4, 0x69, 0xda } }
+{ 0xfb45ac36, 0xe8f1, 0x44ae, \
+  { 0x8f, 0xb7, 0x46, 0x6e, 0x1b, 0xe1, 0x19, 0xb0 } }
 
 class nsPlaintextEditor;
 class nsISelection;
 
 /***************************************************************************
  * base for an object to encapsulate any additional info needed to be passed
  * to rules system by the editor
  */
@@ -67,23 +67,21 @@ class nsRulesInfo
 class nsIEditRules : public nsISupports
 {
 public:
   NS_DECLARE_STATIC_IID_ACCESSOR(NS_IEDITRULES_IID)
   
 //Interfaces for addref and release and queryinterface
 //NOTE: Use   NS_DECL_ISUPPORTS_INHERITED in any class inherited from nsIEditRules
 
-  NS_IMETHOD Init(nsPlaintextEditor *aEditor, PRUint32 aFlags)=0;
+  NS_IMETHOD Init(nsPlaintextEditor *aEditor)=0;
   NS_IMETHOD DetachEditor()=0;
   NS_IMETHOD BeforeEdit(PRInt32 action, nsIEditor::EDirection aDirection)=0;
   NS_IMETHOD AfterEdit(PRInt32 action, nsIEditor::EDirection aDirection)=0;
   NS_IMETHOD WillDoAction(nsISelection *aSelection, nsRulesInfo *aInfo, PRBool *aCancel, PRBool *aHandled)=0;
   NS_IMETHOD DidDoAction(nsISelection *aSelection, nsRulesInfo *aInfo, nsresult aResult)=0;
-  NS_IMETHOD GetFlags(PRUint32 *aFlags)=0;
-  NS_IMETHOD SetFlags(PRUint32 aFlags)=0;
   NS_IMETHOD DocumentIsEmpty(PRBool *aDocumentIsEmpty)=0;
 };
 
 NS_DEFINE_STATIC_IID_ACCESSOR(nsIEditRules, NS_IEDITRULES_IID)
 
 #endif //nsEditRules_h__
 
--- a/editor/libeditor/base/nsEditor.cpp
+++ b/editor/libeditor/base/nsEditor.cpp
@@ -226,20 +226,23 @@ NS_IMPL_CYCLE_COLLECTING_RELEASE_AMBIGUO
 
 NS_IMETHODIMP
 nsEditor::Init(nsIDOMDocument *aDoc, nsIPresShell* aPresShell, nsIContent *aRoot, nsISelectionController *aSelCon, PRUint32 aFlags)
 {
   NS_PRECONDITION(nsnull!=aDoc && nsnull!=aPresShell, "bad arg");
   if ((nsnull==aDoc) || (nsnull==aPresShell))
     return NS_ERROR_NULL_POINTER;
 
-  mFlags = aFlags;
   mDocWeak = do_GetWeakReference(aDoc);  // weak reference to doc
   mPresShellWeak = do_GetWeakReference(aPresShell);   // weak reference to pres shell
   mSelConWeak = do_GetWeakReference(aSelCon);   // weak reference to selectioncontroller
+
+  nsresult rv = SetFlags(aFlags);
+  NS_ASSERTION(NS_SUCCEEDED(rv), "SetFlags() failed");
+
   nsCOMPtr<nsIPresShell> ps = do_QueryReferent(mPresShellWeak);
   if (!ps) return NS_ERROR_NOT_INITIALIZED;
   
   //set up root element if we are passed one.  
   if (aRoot)
     mRootElement = do_QueryInterface(aRoot);
 
   nsCOMPtr<nsINode> document = do_QueryInterface(aDoc);
@@ -478,21 +481,17 @@ nsEditor::GetDesiredSpellCheckState()
   }
 
   if (spellcheckLevel == 0) {
     return PR_FALSE;                    // Spellchecking forced off globally
   }
 
   // Check for password/readonly/disabled, which are not spellchecked
   // regardless of DOM
-  PRUint32 flags;
-  if (NS_SUCCEEDED(GetFlags(&flags)) &&
-      flags & (nsIPlaintextEditor::eEditorPasswordMask |
-               nsIPlaintextEditor::eEditorReadonlyMask |
-               nsIPlaintextEditor::eEditorDisabledMask)) {
+  if (IsPasswordEditor() || IsReadonly() || IsDisabled()) {
     return PR_FALSE;
   }
 
   nsCOMPtr<nsIPresShell> presShell;
   rv = GetPresShell(getter_AddRefs(presShell));
   if (NS_SUCCEEDED(rv)) {
     nsPresContext* context = presShell->GetPresContext();
     if (context && !context->IsDynamic()) {
@@ -2110,18 +2109,19 @@ nsEditor::ForceCompositionEnd()
 // We should use nsILookAndFeel to resolve this
 
 #if defined(XP_MAC) || defined(XP_MACOSX) || defined(XP_WIN) || defined(XP_OS2)
   if(! mInIMEMode)
     return NS_OK;
 #endif
 
 #ifdef XP_UNIX
-  if(mFlags & nsIPlaintextEditor::eEditorPasswordMask)
-	return NS_OK;
+  if(IsPasswordEditor()) {
+    return NS_OK;
+  }
 #endif
 
   nsCOMPtr<nsIWidget> widget;
   nsresult res = GetWidget(getter_AddRefs(widget));
   if (NS_FAILED(res))
     return res;
 
   if (widget) {
@@ -2134,35 +2134,30 @@ nsEditor::ForceCompositionEnd()
 }
 
 NS_IMETHODIMP
 nsEditor::GetPreferredIMEState(PRUint32 *aState)
 {
   NS_ENSURE_ARG_POINTER(aState);
   *aState = nsIContent::IME_STATUS_ENABLE;
 
-  PRUint32 flags;
-  nsresult rv = GetFlags(&flags);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  if (flags & (nsIPlaintextEditor::eEditorReadonlyMask |
-               nsIPlaintextEditor::eEditorDisabledMask)) {
+  if (IsReadonly() || IsDisabled()) {
     *aState = nsIContent::IME_STATUS_DISABLE;
     return NS_OK;
   }
 
   nsCOMPtr<nsIContent> content = do_QueryInterface(GetRoot());
   NS_ENSURE_TRUE(content, NS_ERROR_FAILURE);
 
   nsIFrame* frame = content->GetPrimaryFrame();
   NS_ENSURE_TRUE(frame, NS_ERROR_FAILURE);
 
   switch (frame->GetStyleUIReset()->mIMEMode) {
     case NS_STYLE_IME_MODE_AUTO:
-      if (flags & (nsIPlaintextEditor::eEditorPasswordMask))
+      if (IsPasswordEditor())
         *aState = nsIContent::IME_STATUS_PASSWORD;
       break;
     case NS_STYLE_IME_MODE_DISABLED:
       // we should use password state for |ime-mode: disabled;|.
       *aState = nsIContent::IME_STATUS_PASSWORD;
       break;
     case NS_STYLE_IME_MODE_ACTIVE:
       *aState |= nsIContent::IME_STATUS_OPEN;
--- a/editor/libeditor/base/nsEditor.h
+++ b/editor/libeditor/base/nsEditor.h
@@ -38,16 +38,17 @@
 
 #ifndef __editor_h__
 #define __editor_h__
 
 #include "nsCOMPtr.h"
 #include "nsWeakReference.h"
 
 #include "nsIEditor.h"
+#include "nsIPlaintextEditor.h"
 #include "nsIEditorIMESupport.h"
 #include "nsIPhonetic.h"
 
 #include "nsIAtom.h"
 #include "nsIDOMDocument.h"
 #include "nsISelection.h"
 #include "nsIDOMCharacterData.h"
 #include "nsIPrivateTextRange.h"
@@ -575,16 +576,82 @@ public:
                                     nsIDOMNode *aEndNode,
                                     PRInt32 aEndOffset);
 
   already_AddRefed<nsPIDOMEventTarget> GetPIDOMEventTarget();
 
   // Fast non-refcounting editor root element accessor
   nsIDOMElement *GetRoot();
 
+  // Accessor methods to flags
+  PRBool IsPlaintextEditor() const
+  {
+    return (mFlags & nsIPlaintextEditor::eEditorPlaintextMask) != 0;
+  }
+
+  PRBool IsSingleLineEditor() const
+  {
+    return (mFlags & nsIPlaintextEditor::eEditorSingleLineMask) != 0;
+  }
+
+  PRBool IsPasswordEditor() const
+  {
+    return (mFlags & nsIPlaintextEditor::eEditorPasswordMask) != 0;
+  }
+
+  PRBool IsReadonly() const
+  {
+    return (mFlags & nsIPlaintextEditor::eEditorReadonlyMask) != 0;
+  }
+
+  PRBool IsDisabled() const
+  {
+    return (mFlags & nsIPlaintextEditor::eEditorDisabledMask) != 0;
+  }
+
+  PRBool IsInputFiltered() const
+  {
+    return (mFlags & nsIPlaintextEditor::eEditorFilterInputMask) != 0;
+  }
+
+  PRBool IsMailEditor() const
+  {
+    return (mFlags & nsIPlaintextEditor::eEditorMailMask) != 0;
+  }
+
+  PRBool UseAsyncUpdate() const
+  {
+    return (mFlags & nsIPlaintextEditor::eEditorUseAsyncUpdatesMask) != 0;
+  }
+
+  PRBool IsWrapHackEnabled() const
+  {
+    return (mFlags & nsIPlaintextEditor::eEditorEnableWrapHackMask) != 0;
+  }
+
+  PRBool IsFormWidget() const
+  {
+    return (mFlags & nsIPlaintextEditor::eEditorWidgetMask) != 0;
+  }
+
+  PRBool NoCSS() const
+  {
+    return (mFlags & nsIPlaintextEditor::eEditorNoCSSMask) != 0;
+  }
+
+  PRBool IsInteractionAllowed() const
+  {
+    return (mFlags & nsIPlaintextEditor::eEditorAllowInteraction) != 0;
+  }
+
+  PRBool DontEchoPassword() const
+  {
+    return (mFlags & nsIPlaintextEditor::eEditorDontEchoPassword) != 0;
+  }
+
 protected:
 
   PRUint32        mModCount;		// number of modifications (for undo/redo stack)
   PRUint32        mFlags;		// behavior flags. See nsIPlaintextEditor.idl for the flags we use.
   
   nsWeakPtr       mPresShellWeak;   // weak reference to the nsIPresShell
   nsWeakPtr       mSelConWeak;   // weak reference to the nsISelectionController
   nsIViewManager *mViewManager;
--- a/editor/libeditor/base/nsEditorEventListener.cpp
+++ b/editor/libeditor/base/nsEditorEventListener.cpp
@@ -173,40 +173,30 @@ nsEditorEventListener::KeyPress(nsIDOMEv
 
   nsCOMPtr<nsIDOMKeyEvent>keyEvent = do_QueryInterface(aKeyEvent);
   if (!keyEvent) 
   {
     //non-key event passed to keypress.  bad things.
     return NS_OK;
   }
 
-  // we should check a flag here to see if we should be using built-in key bindings
-  // mEditor->GetFlags(&flags);
-  // if (flags & ...)
-
   PRUint32 keyCode;
   keyEvent->GetKeyCode(&keyCode);
 
   // if we are readonly or disabled, then do nothing.
-  PRUint32 flags;
-  if (NS_SUCCEEDED(mEditor->GetFlags(&flags)))
+  nsEditor* editor = static_cast<nsEditor*>(mEditor);
+  if (editor->IsReadonly() || editor->IsDisabled())
   {
-    if (flags & nsIPlaintextEditor::eEditorReadonlyMask || 
-        flags & nsIPlaintextEditor::eEditorDisabledMask) 
-    {
-      // consume backspace for disabled and readonly textfields, to prevent
-      // back in history, which could be confusing to users
-      if (keyCode == nsIDOMKeyEvent::DOM_VK_BACK_SPACE)
-        aKeyEvent->PreventDefault();
+    // consume backspace for disabled and readonly textfields, to prevent
+    // back in history, which could be confusing to users
+    if (keyCode == nsIDOMKeyEvent::DOM_VK_BACK_SPACE)
+      aKeyEvent->PreventDefault();
 
-      return NS_OK;
-    }
+    return NS_OK;
   }
-  else
-    return NS_ERROR_FAILURE;  // Editor unable to handle this.
 
   nsCOMPtr<nsIPlaintextEditor> textEditor (do_QueryInterface(mEditor));
   if (!textEditor) return NS_ERROR_NO_INTERFACE;
 
   // if there is no charCode, then it's a key that doesn't map to a character,
   // so look for special keys using keyCode.
   if (0 != keyCode)
   {
@@ -257,36 +247,35 @@ nsEditorEventListener::KeyPress(nsIDOMEv
         if (isAnyModifierKeyButShift || isShiftModifierKey)
            return NS_OK;
         mEditor->DeleteSelection(nsIEditor::eNext);
         aKeyEvent->PreventDefault(); // consumed
         return NS_OK; 
         break;
  
       case nsIDOMKeyEvent::DOM_VK_TAB:
-        if ((flags & nsIPlaintextEditor::eEditorSingleLineMask) ||
-            (flags & nsIPlaintextEditor::eEditorPasswordMask)   ||
-            (flags & nsIPlaintextEditor::eEditorWidgetMask)     ||
-            (flags & nsIPlaintextEditor::eEditorAllowInteraction))
+        if (editor->IsSingleLineEditor() || editor->IsPasswordEditor() ||
+            editor->IsFormWidget() || editor->IsInteractionAllowed()) {
           return NS_OK; // let it be used for focus switching
+        }
 
         if (isAnyModifierKeyButShift)
           return NS_OK;
 
         // else we insert the tab straight through
         textEditor->HandleKeyPress(keyEvent);
         // let HandleKeyPress consume the event
         return NS_OK; 
 
       case nsIDOMKeyEvent::DOM_VK_RETURN:
       case nsIDOMKeyEvent::DOM_VK_ENTER:
         if (isAnyModifierKeyButShift)
           return NS_OK;
 
-        if (!(flags & nsIPlaintextEditor::eEditorSingleLineMask))
+        if (!editor->IsSingleLineEditor())
         {
           textEditor->HandleKeyPress(keyEvent);
           aKeyEvent->PreventDefault(); // consumed
         }
         return NS_OK;
     }
   }
 
@@ -428,41 +417,35 @@ nsEditorEventListener::MouseOut(nsIDOMEv
 
 /**
  * nsIDOMTextListener implementation
  */
 
 NS_IMETHODIMP
 nsEditorEventListener::HandleText(nsIDOMEvent* aTextEvent)
 {
-   nsCOMPtr<nsIPrivateTextEvent> textEvent = do_QueryInterface(aTextEvent);
-   if (!textEvent) {
-      //non-ui event passed in.  bad things.
-      return NS_OK;
-   }
+  nsCOMPtr<nsIPrivateTextEvent> textEvent = do_QueryInterface(aTextEvent);
+  if (!textEvent) {
+     //non-ui event passed in.  bad things.
+     return NS_OK;
+  }
 
-   nsAutoString                      composedText;
-   nsresult                          result;
-   nsCOMPtr<nsIPrivateTextRangeList> textRangeList;
+  nsAutoString                      composedText;
+  nsCOMPtr<nsIPrivateTextRangeList> textRangeList;
 
-   textEvent->GetText(composedText);
-   textRangeList = textEvent->GetInputRange();
-   nsCOMPtr<nsIEditorIMESupport> imeEditor = do_QueryInterface(mEditor, &result);
-   if (imeEditor) {
-     PRUint32 flags;
-     // if we are readonly or disabled, then do nothing.
-     if (NS_SUCCEEDED(mEditor->GetFlags(&flags))) {
-       if (flags & nsIPlaintextEditor::eEditorReadonlyMask || 
-           flags & nsIPlaintextEditor::eEditorDisabledMask) {
-         return NS_OK;
-       }
-     }
-     result = imeEditor->SetCompositionString(composedText, textRangeList);
-   }
-   return result;
+  textEvent->GetText(composedText);
+  textRangeList = textEvent->GetInputRange();
+
+  nsEditor* editor = static_cast<nsEditor*>(mEditor);
+  // if we are readonly or disabled, then do nothing.
+  if (editor->IsReadonly() || editor->IsDisabled()) {
+    return NS_OK;
+  }
+
+  return editor->SetCompositionString(composedText, textRangeList);
 }
 
 /**
  * Drag event implementation
  */
 
 nsresult
 nsEditorEventListener::DragGesture(nsIDOMDragEvent* aDragEvent)
@@ -612,21 +595,18 @@ nsEditorEventListener::Drop(nsIDOMDragEv
     if (!dropParent->IsEditable())
       return NS_OK;
   }
 
   PRBool canDrop = CanDrop(aMouseEvent);
   if (!canDrop)
   {
     // was it because we're read-only?
-
-    PRUint32 flags;
-    if (NS_SUCCEEDED(mEditor->GetFlags(&flags))
-        && ((flags & nsIPlaintextEditor::eEditorDisabledMask) ||
-            (flags & nsIPlaintextEditor::eEditorReadonlyMask)) )
+    nsEditor* editor = static_cast<nsEditor*>(mEditor);
+    if (editor->IsReadonly() || editor->IsDisabled())
     {
       // it was decided to "eat" the event as this is the "least surprise"
       // since someone else handling it might be unintentional and the 
       // user could probably re-drag to be not over the disabled/readonly 
       // editfields if that is what is desired.
       return aMouseEvent->StopPropagation();
     }
     return NS_OK;
@@ -638,22 +618,18 @@ nsEditorEventListener::Drop(nsIDOMDragEv
   // ScrollSelectionIntoView.
   return mEditor->InsertFromDrop(aMouseEvent);
 }
 
 PRBool
 nsEditorEventListener::CanDrop(nsIDOMDragEvent* aEvent)
 {
   // if the target doc is read-only, we can't drop
-  PRUint32 flags;
-  if (NS_FAILED(mEditor->GetFlags(&flags)))
-    return PR_FALSE;
-
-  if ((flags & nsIPlaintextEditor::eEditorDisabledMask) || 
-      (flags & nsIPlaintextEditor::eEditorReadonlyMask)) {
+  nsEditor* editor = static_cast<nsEditor*>(mEditor);
+  if (editor->IsReadonly() || editor->IsDisabled()) {
     return PR_FALSE;
   }
 
   // XXX cache this between drag events?
   nsresult rv;
   nsCOMPtr<nsIDragService> dragService = do_GetService("@mozilla.org/widget/dragservice;1", &rv);
 
   // does the drag have flavors we can accept?
@@ -664,18 +640,17 @@ nsEditorEventListener::CanDrop(nsIDOMDra
 
   PRBool flavorSupported = PR_FALSE;
   dragSession->IsDataFlavorSupported(kUnicodeMime, &flavorSupported);
 
   if (!flavorSupported)
     dragSession->IsDataFlavorSupported(kMozTextInternal, &flavorSupported);
 
   // if we aren't plaintext editing, we can accept more flavors
-  if (!flavorSupported 
-     && (flags & nsIPlaintextEditor::eEditorPlaintextMask) == 0)
+  if (!flavorSupported && !editor->IsPlaintextEditor())
   {
     dragSession->IsDataFlavorSupported(kHTMLMime, &flavorSupported);
     if (!flavorSupported)
       dragSession->IsDataFlavorSupported(kFileMime, &flavorSupported);
 #if 0
     if (!flavorSupported)
       dragSession->IsDataFlavorSupported(kJPEGImageMime, &flavorSupported);
 #endif
@@ -755,34 +730,31 @@ nsEditorEventListener::HandleEndComposit
   return static_cast<nsEditor*>(mEditor)->EndComposition();
 }
 
 /**
  * nsIDOMFocusListener implementation
  */
 
 static already_AddRefed<nsIContent>
-FindSelectionRoot(nsIEditor *aEditor, nsIContent *aContent)
+FindSelectionRoot(nsEditor *aEditor, nsIContent *aContent)
 {
-  PRUint32 flags;
-  aEditor->GetFlags(&flags);
-
   nsIDocument *document = aContent->GetCurrentDoc();
   if (!document) {
     return nsnull;
   }
 
   nsIContent *root;
   if (document->HasFlag(NODE_IS_EDITABLE)) {
     NS_IF_ADDREF(root = document->GetRootContent());
 
     return root;
   }
 
-  if (flags & nsIPlaintextEditor::eEditorReadonlyMask) {
+  if (aEditor->IsReadonly()) {
     // We still want to allow selection in a readonly editor.
     nsCOMPtr<nsIDOMElement> rootElement;
     aEditor->GetRootElement(getter_AddRefs(rootElement));
     if (!rootElement) {
       return nsnull;
     }
 
     CallQueryInterface(rootElement, &root);
@@ -812,26 +784,25 @@ nsEditorEventListener::Focus(nsIDOMEvent
   NS_ENSURE_ARG(aEvent);
 
   nsCOMPtr<nsIDOMEventTarget> target;
   aEvent->GetTarget(getter_AddRefs(target));
 
   // turn on selection and caret
   if (mEditor)
   {
-    PRUint32 flags;
-    mEditor->GetFlags(&flags);
-    if (! (flags & nsIPlaintextEditor::eEditorDisabledMask))
+    nsEditor* editor = static_cast<nsEditor*>(mEditor);
+    if (!editor->IsDisabled())
     { // only enable caret and selection if the editor is not disabled
       nsCOMPtr<nsIContent> content = do_QueryInterface(target);
 
       PRBool targetIsEditableDoc = PR_FALSE;
       nsCOMPtr<nsIContent> editableRoot;
       if (content) {
-        editableRoot = FindSelectionRoot(mEditor, content);
+        editableRoot = FindSelectionRoot(editor, content);
 
         // make sure that the element is really focused in case an earlier
         // listener in the chain changed the focus.
         if (editableRoot) {
           nsIFocusManager* fm = nsFocusManager::GetFocusManager();
           NS_ENSURE_TRUE(fm, NS_OK);
 
           nsCOMPtr<nsIDOMElement> element;
@@ -859,18 +830,17 @@ nsEditorEventListener::Focus(nsIDOMEvent
           if (caret) {
             caret->SetIgnoreUserModify(PR_FALSE);
             if (selection) {
               caret->SetCaretDOMSelection(selection);
             }
           }
         }
 
-        const PRBool kIsReadonly = (flags & nsIPlaintextEditor::eEditorReadonlyMask) != 0;
-        selCon->SetCaretReadOnly(kIsReadonly);
+        selCon->SetCaretReadOnly(editor->IsReadonly());
         selCon->SetCaretEnabled(PR_TRUE);
         selCon->SetDisplaySelection(nsISelectionController::SELECTION_ON);
         selCon->RepaintSelection(nsISelectionController::SELECTION_NORMAL);
 
         nsCOMPtr<nsISelectionPrivate> selectionPrivate =
           do_QueryInterface(selection);
         if (selectionPrivate)
         {
@@ -929,23 +899,20 @@ nsEditorEventListener::Blur(nsIDOMEvent*
           nsRefPtr<nsCaret> caret = presShell->GetCaret();
           if (caret) {
             caret->SetIgnoreUserModify(PR_TRUE);
           }
         }
 
         selCon->SetCaretEnabled(PR_FALSE);
 
-        PRUint32 flags;
-        mEditor->GetFlags(&flags);
-        if((flags & nsIPlaintextEditor::eEditorWidgetMask)  ||
-          (flags & nsIPlaintextEditor::eEditorPasswordMask) ||
-          (flags & nsIPlaintextEditor::eEditorReadonlyMask) ||
-          (flags & nsIPlaintextEditor::eEditorDisabledMask) ||
-          (flags & nsIPlaintextEditor::eEditorFilterInputMask))
+        nsEditor* editor = static_cast<nsEditor*>(mEditor);
+        if(editor->IsFormWidget() || editor->IsPasswordEditor() ||
+           editor->IsReadonly() || editor->IsDisabled() ||
+           editor->IsInputFiltered())
         {
           selCon->SetDisplaySelection(nsISelectionController::SELECTION_HIDDEN);//hide but do NOT turn off
         }
         else
         {
           selCon->SetDisplaySelection(nsISelectionController::SELECTION_DISABLED);
         }
 
--- a/editor/libeditor/html/nsHTMLDataTransfer.cpp
+++ b/editor/libeditor/html/nsHTMLDataTransfer.cpp
@@ -1098,17 +1098,18 @@ NS_IMETHODIMP nsHTMLEditor::PrepareHTMLT
   if (NS_FAILED(rv))
     return rv;
 
   // Get the nsITransferable interface for getting the data from the clipboard
   if (aTransferable)
   {
     // Create the desired DataFlavor for the type of data
     // we want to get out of the transferable
-    if ((mFlags & eEditorPlaintextMask) == 0)  // This should only happen in html editors, not plaintext
+    // This should only happen in html editors, not plaintext
+    if (!IsPlaintextEditor())
     {
       if (!aHavePrivFlavor) 
       {
         (*aTransferable)->AddDataFlavor(kNativeHTMLMime);
       }
       (*aTransferable)->AddDataFlavor(kHTMLMime);
       (*aTransferable)->AddDataFlavor(kFileMime);
 
@@ -1722,22 +1723,17 @@ nsHTMLEditor::PutDragDataInTransferable(
   nsresult rv = SetupDocEncoder(getter_AddRefs(docEncoder));
   if (NS_FAILED(rv)) return rv;
   NS_ENSURE_TRUE(docEncoder, NS_ERROR_FAILURE);
 
   // grab a string
   nsAutoString buffer, parents, info;
 
   // find out if we're a plaintext control or not
-  PRUint32 editorFlags = 0;
-  rv = GetFlags(&editorFlags);
-  if (NS_FAILED(rv)) return rv;
-
-  PRBool bIsPlainTextControl = ((editorFlags & eEditorPlaintextMask) != 0);
-  if (!bIsPlainTextControl)
+  if (!IsPlaintextEditor())
   {
     // encode the selection as html with contextual info
     rv = docEncoder->EncodeToStringWithContext(parents, info, buffer);
     if (NS_FAILED(rv)) return rv;
   }
   else
   {
     // encode the selection
@@ -1755,17 +1751,17 @@ nsHTMLEditor::PutDragDataInTransferable(
   NS_ENSURE_SUCCESS(rv, rv);
   rv = dataWrapper->SetData(buffer);
   if (NS_FAILED(rv)) return rv;
 
   /* create html flavor transferable */
   nsCOMPtr<nsITransferable> trans = do_CreateInstance("@mozilla.org/widget/transferable;1");
   NS_ENSURE_TRUE(trans, NS_ERROR_FAILURE);
 
-  if (bIsPlainTextControl)
+  if (IsPlaintextEditor())
   {
     // Add the unicode flavor to the transferable
     rv = trans->AddDataFlavor(kUnicodeMime);
     if (NS_FAILED(rv)) return rv;
 
     // QI the data object an |nsISupports| so that when the transferable holds
     // onto it, it will addref the correct interface.
     nsCOMPtr<nsISupports> genericDataObj(do_QueryInterface(dataWrapper));
@@ -1994,24 +1990,21 @@ NS_IMETHODIMP nsHTMLEditor::CanPaste(PRI
 
   // can't paste if readonly
   if (!IsModifiable())
     return NS_OK;
 
   nsresult rv;
   nsCOMPtr<nsIClipboard> clipboard(do_GetService("@mozilla.org/widget/clipboard;1", &rv));
   if (NS_FAILED(rv)) return rv;
-  
-  PRUint32 editorFlags;
-  GetFlags(&editorFlags);
-  
+
   PRBool haveFlavors;
 
   // Use the flavors depending on the current editor mask
-  if ((editorFlags & eEditorPlaintextMask))
+  if (IsPlaintextEditor())
     rv = clipboard->HasDataMatchingFlavors(textEditorFlavors,
                                            NS_ARRAY_LENGTH(textEditorFlavors),
                                            aSelectionType, &haveFlavors);
   else
     rv = clipboard->HasDataMatchingFlavors(textHtmlEditorFlavors,
                                            NS_ARRAY_LENGTH(textHtmlEditorFlavors),
                                            aSelectionType, &haveFlavors);
   
@@ -2034,23 +2027,20 @@ NS_IMETHODIMP nsHTMLEditor::CanPasteTran
   // If |aTransferable| is null, assume that a paste will succeed.
   if (!aTransferable) {
     *aCanPaste = PR_TRUE;
     return NS_OK;
   }
 
   // Peek in |aTransferable| to see if it contains a supported MIME type.
 
-  PRUint32 editorFlags;
-  GetFlags(&editorFlags);
-  
   // Use the flavors depending on the current editor mask
   const char ** flavors;
   unsigned length;
-  if ((editorFlags & eEditorPlaintextMask)) {
+  if (IsPlaintextEditor()) {
     flavors = textEditorFlavors;
     length = NS_ARRAY_LENGTH(textEditorFlavors);
   } else {
     flavors = textHtmlEditorFlavors;
     length = NS_ARRAY_LENGTH(textHtmlEditorFlavors);
   }
 
   for (unsigned int i = 0; i < length; i++, flavors++) {
@@ -2070,17 +2060,17 @@ NS_IMETHODIMP nsHTMLEditor::CanPasteTran
 }
 
 
 // 
 // HTML PasteAsQuotation: Paste in a blockquote type=cite
 //
 NS_IMETHODIMP nsHTMLEditor::PasteAsQuotation(PRInt32 aSelectionType)
 {
-  if (mFlags & eEditorPlaintextMask)
+  if (IsPlaintextEditor())
     return PasteAsPlaintextQuotation(aSelectionType);
 
   nsAutoString citation;
   return PasteAsCitedQuotation(citation, aSelectionType);
 }
 
 NS_IMETHODIMP nsHTMLEditor::PasteAsCitedQuotation(const nsAString & aCitation,
                                                   PRInt32 aSelectionType)
@@ -2276,17 +2266,17 @@ nsHTMLEditor::InsertTextWithQuotations(c
   EndTransaction();
 
   return rv;
 }
 
 NS_IMETHODIMP nsHTMLEditor::InsertAsQuotation(const nsAString & aQuotedText,
                                               nsIDOMNode **aNodeInserted)
 {
-  if (mFlags & eEditorPlaintextMask)
+  if (IsPlaintextEditor())
     return InsertAsPlaintextQuotation(aQuotedText, PR_TRUE, aNodeInserted);
 
   nsAutoString citation;
   return InsertAsCitedQuotation(aQuotedText, citation, PR_FALSE,
                                 aNodeInserted);
 }
 
 // Insert plaintext as a quotation, with cite marks (e.g. "> ").
@@ -2411,17 +2401,17 @@ nsHTMLEditor::Rewrap(PRBool aRespectNewl
 
 NS_IMETHODIMP
 nsHTMLEditor::InsertAsCitedQuotation(const nsAString & aQuotedText,
                                      const nsAString & aCitation,
                                      PRBool aInsertHTML,
                                      nsIDOMNode **aNodeInserted)
 {
   // Don't let anyone insert html into a "plaintext" editor:
-  if (mFlags & eEditorPlaintextMask)
+  if (IsPlaintextEditor())
   {
     NS_ASSERTION(!aInsertHTML, "InsertAsCitedQuotation: trying to insert html into plaintext editor");
     return InsertAsPlaintextQuotation(aQuotedText, PR_TRUE, aNodeInserted);
   }
 
   nsCOMPtr<nsIDOMNode> newNode;
   nsresult res = NS_OK;
 
--- a/editor/libeditor/html/nsHTMLEditRules.cpp
+++ b/editor/libeditor/html/nsHTMLEditRules.cpp
@@ -243,23 +243,23 @@ NS_IMPL_RELEASE_INHERITED(nsHTMLEditRule
 NS_IMPL_QUERY_INTERFACE_INHERITED2(nsHTMLEditRules, nsTextEditRules, nsIHTMLEditRules, nsIEditActionListener)
 
 
 /********************************************************
  *  Public methods 
  ********************************************************/
 
 NS_IMETHODIMP
-nsHTMLEditRules::Init(nsPlaintextEditor *aEditor, PRUint32 aFlags)
+nsHTMLEditRules::Init(nsPlaintextEditor *aEditor)
 {
   mHTMLEditor = static_cast<nsHTMLEditor*>(aEditor);
   nsresult res;
   
   // call through to base class Init 
-  res = nsTextEditRules::Init(aEditor, aFlags);
+  res = nsTextEditRules::Init(aEditor);
   if (NS_FAILED(res)) return res;
 
   // cache any prefs we care about
   nsCOMPtr<nsIPrefBranch> prefBranch =
     do_GetService(NS_PREFSERVICE_CONTRACTID, &res);
   if (NS_FAILED(res)) return res;
 
   char *returnInEmptyLIKillsList = 0;
@@ -1368,18 +1368,16 @@ nsHTMLEditRules::WillInsertText(PRInt32 
   
   // initialize out param
   *aCancel = PR_FALSE;
   *aHandled = PR_TRUE;
   nsresult res;
   nsCOMPtr<nsIDOMNode> selNode;
   PRInt32 selOffset;
 
-  PRBool bPlaintext = mFlags & nsIPlaintextEditor::eEditorPlaintextMask;
-
   // if the selection isn't collapsed, delete it.
   PRBool bCollapsed;
   res = aSelection->GetIsCollapsed(&bCollapsed);
   if (NS_FAILED(res)) return res;
   if (!bCollapsed)
   {
     res = mHTMLEditor->DeleteSelection(nsIEditor::eNone);
     if (NS_FAILED(res)) return res;
@@ -1445,17 +1443,17 @@ nsHTMLEditRules::WillInsertText(PRInt32 
     const PRUnichar *unicodeBuf = tString.get();
     nsCOMPtr<nsIDOMNode> unused;
     PRInt32 pos = 0;
     NS_NAMED_LITERAL_STRING(newlineStr, LFSTR);
         
     // for efficiency, break out the pre case separately.  This is because
     // its a lot cheaper to search the input string for only newlines than
     // it is to search for both tabs and newlines.
-    if (isPRE || bPlaintext)
+    if (isPRE || IsPlaintextEditor())
     {
       while (unicodeBuf && (pos != -1) && (pos < (PRInt32)(*inString).Length()))
       {
         PRInt32 oldPos = pos;
         PRInt32 subStrLen;
         pos = tString.FindChar(nsCRT::LF, oldPos);
 
         if (pos != -1) 
@@ -1578,18 +1576,16 @@ nsHTMLEditRules::WillLoadHTML(nsISelecti
 
 nsresult
 nsHTMLEditRules::WillInsertBreak(nsISelection *aSelection, PRBool *aCancel, PRBool *aHandled)
 {
   if (!aSelection || !aCancel || !aHandled) { return NS_ERROR_NULL_POINTER; }
   // initialize out param
   *aCancel = PR_FALSE;
   *aHandled = PR_FALSE;
-  
-  PRBool bPlaintext = mFlags & nsIPlaintextEditor::eEditorPlaintextMask;
 
   // if the selection isn't collapsed, delete it.
   PRBool bCollapsed;
   nsresult res = aSelection->GetIsCollapsed(&bCollapsed);
   if (NS_FAILED(res)) return res;
   if (!bCollapsed)
   {
     res = mHTMLEditor->DeleteSelection(nsIEditor::eNone);
@@ -1600,19 +1596,19 @@ nsHTMLEditRules::WillInsertBreak(nsISele
   if (NS_FAILED(res)) return res;
   
   // initialize out param
   // we want to ignore result of WillInsert()
   *aCancel = PR_FALSE;
   
   // split any mailcites in the way.
   // should we abort this if we encounter table cell boundaries?
-  if (mFlags & nsIPlaintextEditor::eEditorMailMask)
-  {
-    res = SplitMailCites(aSelection, bPlaintext, aHandled);
+  if (IsMailEditor())
+  {
+    res = SplitMailCites(aSelection, IsPlaintextEditor(), aHandled);
     if (NS_FAILED(res)) return res;
     if (*aHandled) return NS_OK;
   }
 
   // smart splitting rules
   nsCOMPtr<nsIDOMNode> node;
   PRInt32 offset;
   
@@ -1692,17 +1688,17 @@ nsHTMLEditRules::StandardBreakImpl(nsIDO
 {
   nsCOMPtr<nsIDOMNode> brNode;
   PRBool bAfterBlock = PR_FALSE;
   PRBool bBeforeBlock = PR_FALSE;
   nsresult res = NS_OK;
   nsCOMPtr<nsIDOMNode> node(aNode);
   nsCOMPtr<nsISelectionPrivate> selPriv(do_QueryInterface(aSelection));
   
-  if (mFlags & nsIPlaintextEditor::eEditorPlaintextMask)
+  if (IsPlaintextEditor())
   {
     res = mHTMLEditor->CreateBR(node, aOffset, address_of(brNode));
   }
   else
   {
     nsWSRunObject wsObj(mHTMLEditor, node, aOffset);
     nsCOMPtr<nsIDOMNode> visNode, linkNode;
     PRInt32 visOffset=0, newOffset;
@@ -1912,18 +1908,16 @@ nsHTMLEditRules::WillDeleteSelection(nsI
   // if there is only bogus content, cancel the operation
   if (mBogusNode) 
   {
     *aCancel = PR_TRUE;
     return NS_OK;
   }
 
   nsresult res = NS_OK;
-  PRBool bPlaintext = mFlags & nsIPlaintextEditor::eEditorPlaintextMask;
-  
   PRBool bCollapsed, join = PR_FALSE;
   res = aSelection->GetIsCollapsed(&bCollapsed);
   if (NS_FAILED(res)) return res;
 
   // origCollapsed is used later to determine whether we should join 
   // blocks. We don't really care about bCollapsed because it will be 
   // modified by ExtendSelectionForDelete later. JoinBlocks should 
   // happen if the original selection is collapsed and the cursor is 
@@ -2358,17 +2352,17 @@ nsHTMLEditRules::WillDeleteSelection(nsI
   nsCOMPtr<nsIDOMNode> endNode;
   PRInt32 endOffset;
   res = mHTMLEditor->GetEndNodeAndOffset(aSelection, address_of(endNode), &endOffset);
   if (NS_FAILED(res)) return res; 
   if (!endNode) return NS_ERROR_FAILURE;
 
   // figure out if the endpoints are in nodes that can be merged  
   // adjust surrounding whitespace in preperation to delete selection
-  if (!bPlaintext)
+  if (!IsPlaintextEditor())
   {
     nsAutoTxnsConserveSelection dontSpazMySelection(mHTMLEditor);
     res = nsWSRunObject::PrepareToDeleteRange(mHTMLEditor,
                                             address_of(startNode), &startOffset, 
                                             address_of(endNode), &endOffset);
     if (NS_FAILED(res)) return res; 
   }
   
@@ -2383,20 +2377,20 @@ nsHTMLEditRules::WillDeleteSelection(nsI
       res = mHTMLEditor->DeleteSelectionImpl(aAction);
       if (NS_FAILED(res)) return res; 
     }
     else
     {
       // figure out mailcite ancestors
       nsCOMPtr<nsIDOMNode> endCiteNode, startCiteNode;
       res = GetTopEnclosingMailCite(startNode, address_of(startCiteNode), 
-                                    mFlags & nsIPlaintextEditor::eEditorPlaintextMask);
+                                    IsPlaintextEditor());
       if (NS_FAILED(res)) return res; 
       res = GetTopEnclosingMailCite(endNode, address_of(endCiteNode), 
-                                    mFlags & nsIPlaintextEditor::eEditorPlaintextMask);
+                                    IsPlaintextEditor());
       if (NS_FAILED(res)) return res; 
       
       // if we only have a mailcite at one of the two endpoints, set the directionality
       // of the deletion so that the selection will end up outside the mailcite.
       if (startCiteNode && !endCiteNode)
       {
         aAction = nsIEditor::eNext;
       }
@@ -2992,17 +2986,17 @@ nsHTMLEditRules::DidDeleteSelection(nsIS
   PRInt32 startOffset;
   nsresult res = mEditor->GetStartNodeAndOffset(aSelection, address_of(startNode), &startOffset);
   if (NS_FAILED(res)) return res;
   if (!startNode) return NS_ERROR_FAILURE;
   
   // find any enclosing mailcite
   nsCOMPtr<nsIDOMNode> citeNode;
   res = GetTopEnclosingMailCite(startNode, address_of(citeNode), 
-                                mFlags & nsIPlaintextEditor::eEditorPlaintextMask);
+                                IsPlaintextEditor());
   if (NS_FAILED(res)) return res;
   if (citeNode)
   {
     PRBool isEmpty = PR_TRUE, seenBR = PR_FALSE;
     mHTMLEditor->IsEmptyNodeImpl(citeNode, &isEmpty, PR_TRUE, PR_TRUE, PR_FALSE, &seenBR);
     if (isEmpty)
     {
       nsCOMPtr<nsIDOMNode> parent, brNode;
--- a/editor/libeditor/html/nsHTMLEditRules.h
+++ b/editor/libeditor/html/nsHTMLEditRules.h
@@ -81,17 +81,17 @@ public:
 
   NS_DECL_ISUPPORTS_INHERITED
   
             nsHTMLEditRules();
   virtual   ~nsHTMLEditRules();
 
 
   // nsIEditRules methods
-  NS_IMETHOD Init(nsPlaintextEditor *aEditor, PRUint32 aFlags);
+  NS_IMETHOD Init(nsPlaintextEditor *aEditor);
   NS_IMETHOD DetachEditor();
   NS_IMETHOD BeforeEdit(PRInt32 action, nsIEditor::EDirection aDirection);
   NS_IMETHOD AfterEdit(PRInt32 action, nsIEditor::EDirection aDirection);
   NS_IMETHOD WillDoAction(nsISelection *aSelection, nsRulesInfo *aInfo, PRBool *aCancel, PRBool *aHandled);
   NS_IMETHOD DidDoAction(nsISelection *aSelection, nsRulesInfo *aInfo, nsresult aResult);
 
   // nsIHTMLEditRules methods
   
--- a/editor/libeditor/html/nsHTMLEditor.cpp
+++ b/editor/libeditor/html/nsHTMLEditor.cpp
@@ -267,51 +267,49 @@ nsHTMLEditor::Init(nsIDOMDocument *aDoc,
   {
     // block to scope nsAutoEditInitRulesTrigger
     nsAutoEditInitRulesTrigger rulesTrigger(static_cast<nsPlaintextEditor*>(this), rulesRes);
 
     // Init the plaintext editor
     result = nsPlaintextEditor::Init(aDoc, aPresShell, aRoot, aSelCon, aFlags);
     if (NS_FAILED(result)) { return result; }
 
-    UpdateForFlags(aFlags);
-
     // disable Composer-only features
-    if (aFlags & eEditorMailMask)
+    if (IsMailEditor())
     {
       SetAbsolutePositioningEnabled(PR_FALSE);
       SetSnapToGridEnabled(PR_FALSE);
     }
 
     // Init the HTML-CSS utils
     if (mHTMLCSSUtils)
       delete mHTMLCSSUtils;
     result = NS_NewHTMLCSSUtils(&mHTMLCSSUtils);
     if (NS_FAILED(result)) { return result; }
     mHTMLCSSUtils->Init(this);
 
     // disable links
     nsPresContext *context = aPresShell->GetPresContext();
     if (!context) return NS_ERROR_NULL_POINTER;
-    if (!(mFlags & (eEditorPlaintextMask | eEditorAllowInteraction))) {
+    if (!IsPlaintextEditor() && !IsInteractionAllowed()) {
       mLinkHandler = context->GetLinkHandler();
 
       context->SetLinkHandler(nsnull);
     }
 
     // init the type-in state
     mTypeInState = new TypeInState();
     if (!mTypeInState) {return NS_ERROR_NULL_POINTER;}
     NS_ADDREF(mTypeInState);
 
     // init the selection listener for image resizing
     mSelectionListenerP = new ResizerSelectionListener(this);
     if (!mSelectionListenerP) {return NS_ERROR_NULL_POINTER;}
 
-    if (!(mFlags & eEditorAllowInteraction)) {
+    if (!IsInteractionAllowed()) {
       // ignore any errors from this in case the file is missing
       AddOverrideStyleSheet(NS_LITERAL_STRING("resource://gre/res/EditorOverride.css"));
     }
 
     nsCOMPtr<nsISelection>selection;
     result = GetSelection(getter_AddRefs(selection));
     if (NS_FAILED(result)) { return result; }
     if (selection) 
@@ -383,40 +381,37 @@ nsHTMLEditor::RemoveEventListeners()
 
   mMouseMotionListenerP = nsnull;
   mResizeEventListenerP = nsnull;
 
   nsPlaintextEditor::RemoveEventListeners();
 }
 
 NS_IMETHODIMP 
-nsHTMLEditor::GetFlags(PRUint32 *aFlags)
-{
-  if (!mRules || !aFlags) { return NS_ERROR_NULL_POINTER; }
-  return mRules->GetFlags(aFlags);
-}
-
-NS_IMETHODIMP 
 nsHTMLEditor::SetFlags(PRUint32 aFlags)
 {
-  if (!mRules) { return NS_ERROR_NULL_POINTER; }
-
-  UpdateForFlags(aFlags);
-
-  return mRules->SetFlags(aFlags);
+  nsresult rv = nsPlaintextEditor::SetFlags(aFlags);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  // Sets mCSSAware to correspond to aFlags. This toggles whether CSS is
+  // used to style elements in the editor. Note that the editor is only CSS
+  // aware by default in Composer and in the mail editor.
+  mCSSAware = !NoCSS() && !IsMailEditor();
+
+  return NS_OK;
 }
 
 NS_IMETHODIMP
 nsHTMLEditor::InitRules()
 {
   // instantiate the rules for the html editor
   nsresult res = NS_NewHTMLEditRules(getter_AddRefs(mRules));
   if (NS_FAILED(res)) return res;
   if (!mRules) return NS_ERROR_UNEXPECTED;
-  res = mRules->Init(static_cast<nsPlaintextEditor*>(this), mFlags);
+  res = mRules->Init(static_cast<nsPlaintextEditor*>(this));
   
   return res;
 }
 
 NS_IMETHODIMP
 nsHTMLEditor::BeginningOfDocument()
 {
   if (!mDocWeak || !mPresShellWeak) { return NS_ERROR_NOT_INITIALIZED; }
@@ -1138,21 +1133,17 @@ nsHTMLEditor::GetIsDocumentEditable(PRBo
   GetDocument(getter_AddRefs(doc));
   *aIsDocumentEditable = doc ? IsModifiable() : PR_FALSE;
 
   return NS_OK;
 }
 
 PRBool nsHTMLEditor::IsModifiable()
 {
-  PRUint32 flags;
-  if (NS_SUCCEEDED(GetFlags(&flags)))
-    return ((flags & nsIPlaintextEditor::eEditorReadonlyMask) == 0);
-  else
-    return PR_FALSE;
+  return !IsReadonly();
 }
 
 #ifdef XP_MAC
 #pragma mark -
 #pragma mark  nsIHTMLEditor methods 
 #pragma mark -
 #endif
 
@@ -1208,17 +1199,17 @@ NS_IMETHODIMP nsHTMLEditor::HandleKeyPre
     // this royally blows: because tabs come in from keyDowns instead
     // of keyPress, and because GetCharCode refuses to work for keyDown
     // i have to play games.
     if (keyCode == nsIDOMKeyEvent::DOM_VK_TAB) character = '\t';
     else aKeyEvent->GetCharCode(&character);
     
     if (keyCode == nsIDOMKeyEvent::DOM_VK_TAB)
     {
-      if (!(mFlags & eEditorPlaintextMask)) {
+      if (!IsPlaintextEditor()) {
         nsCOMPtr<nsISelection>selection;
         res = GetSelection(getter_AddRefs(selection));
         if (NS_FAILED(res)) return res;
         PRInt32 offset;
         nsCOMPtr<nsIDOMNode> node, blockParent;
         res = GetStartNodeAndOffset(selection, address_of(node), &offset);
         if (NS_FAILED(res)) return res;
         if (!node) return NS_ERROR_FAILURE;
@@ -1254,17 +1245,17 @@ NS_IMETHODIMP nsHTMLEditor::HandleKeyPre
       if (isShift)
         return NS_OK; // don't type text for shift tabs
     }
     else if (keyCode == nsIDOMKeyEvent::DOM_VK_RETURN
              || keyCode == nsIDOMKeyEvent::DOM_VK_ENTER)
     {
       aKeyEvent->PreventDefault();
       nsString empty;
-      if (isShift && !(mFlags&eEditorPlaintextMask))
+      if (isShift && !IsPlaintextEditor())
       {
         return TypedText(empty, eTypedBR);  // only inserts a br node
       }
       else 
       {
         return TypedText(empty, eTypedBreak);  // uses rules to figure out what to insert
       }
     }
@@ -5114,28 +5105,23 @@ nsHTMLEditor::SetIsCSSEnabled(PRBool aIs
 {
   nsresult  err = NS_ERROR_NOT_INITIALIZED;
   if (mHTMLCSSUtils)
   {
     err = mHTMLCSSUtils->SetCSSEnabled(aIsCSSPrefChecked);
   }
   // Disable the eEditorNoCSSMask flag if we're enabling StyleWithCSS.
   if (NS_SUCCEEDED(err)) {
-    PRUint32 flags = 0;
-    err = GetFlags(&flags);
-    NS_ENSURE_SUCCESS(err, err);
-
+    PRUint32 flags = mFlags;
     if (aIsCSSPrefChecked) {
       // Turn off NoCSS as we're enabling CSS
-      if (flags & eEditorNoCSSMask) {
-        flags -= eEditorNoCSSMask;
-      }
-    } else if (!(flags & eEditorNoCSSMask)) {
+      flags &= ~eEditorNoCSSMask;
+    } else {
       // Turn on NoCSS, as we're disabling CSS.
-      flags += eEditorNoCSSMask;
+      flags |= eEditorNoCSSMask;
     }
 
     err = SetFlags(flags);
     NS_ENSURE_SUCCESS(err, err);
   }
   return err;
 }
 
--- a/editor/libeditor/html/nsHTMLEditor.h
+++ b/editor/libeditor/html/nsHTMLEditor.h
@@ -307,17 +307,16 @@ public:
   nsresult EndUpdateViewBatch();
 
   /** prepare the editor for use */
   NS_IMETHOD Init(nsIDOMDocument *aDoc, nsIPresShell *aPresShell,  nsIContent *aRoot, nsISelectionController *aSelCon, PRUint32 aFlags);
   
   /** Internal, static version */
   static nsresult NodeIsBlockStatic(nsIDOMNode *aNode, PRBool *aIsBlock);
 
-  NS_IMETHOD GetFlags(PRUint32 *aFlags);
   NS_IMETHOD SetFlags(PRUint32 aFlags);
 
   NS_IMETHOD Paste(PRInt32 aSelectionType);
   NS_IMETHOD CanPaste(PRInt32 aSelectionType, PRBool *aCanPaste);
 
   NS_IMETHOD PasteTransferable(nsITransferable *aTransferable);
   NS_IMETHOD CanPasteTransferable(nsITransferable *aTransferable, PRBool *aCanPaste);
 
@@ -427,23 +426,16 @@ protected:
 
   NS_IMETHOD  InitRules();
 
   // Create the event listeners for the editor to install
   virtual nsresult CreateEventListeners();
 
   virtual void RemoveEventListeners();
 
-  // Sets mCSSAware to correspond to aFlags. This toggles whether CSS is
-  // used to style elements in the editor. Note that the editor is only CSS
-  // aware by default in Composer and in the mail editor.
-  void UpdateForFlags(PRUint32 aFlags) {
-    mCSSAware = ((aFlags & (eEditorNoCSSMask | eEditorMailMask)) == 0);
-  }
-
   // Return TRUE if aElement is a table-related elemet and caret was set
   PRBool SetCaretInTableCell(nsIDOMElement* aElement);
   PRBool IsElementInBody(nsIDOMElement* aElement);
 
   // inline style caching
   void ClearInlineStylesCache();
   
   // key event helpers
--- a/editor/libeditor/text/nsPlaintextDataTransfer.cpp
+++ b/editor/libeditor/text/nsPlaintextDataTransfer.cpp
@@ -521,26 +521,20 @@ NS_IMETHODIMP nsPlaintextEditor::CanPast
 nsresult
 nsPlaintextEditor::SetupDocEncoder(nsIDocumentEncoder **aDocEncoder)
 {
   nsCOMPtr<nsIDOMDocument> domDoc;
   nsresult rv = GetDocument(getter_AddRefs(domDoc));
   if (NS_FAILED(rv)) return rv;
 
   // find out if we're a plaintext control or not
-  PRUint32 editorFlags = 0;
-  rv = GetFlags(&editorFlags);
-  if (NS_FAILED(rv)) return rv;
-
-  PRBool bIsPlainTextControl = ((editorFlags & eEditorPlaintextMask) != 0);
-
   // get correct mimeType and document encoder flags set
   nsAutoString mimeType;
   PRUint32 docEncoderFlags = 0;
-  if (bIsPlainTextControl)
+  if (IsPlaintextEditor())
   {
     docEncoderFlags |= nsIDocumentEncoder::OutputBodyOnly | nsIDocumentEncoder::OutputPreformatted;
     mimeType.AssignLiteral(kUnicodeMime);
   }
   else
     mimeType.AssignLiteral(kHTMLMime);
 
   // set up docEncoder
@@ -588,22 +582,17 @@ nsPlaintextEditor::PutDragDataInTransfer
   rv = dataWrapper->SetData(buffer);
   if (NS_FAILED(rv)) return rv;
 
   /* create html flavor transferable */
   nsCOMPtr<nsITransferable> trans = do_CreateInstance("@mozilla.org/widget/transferable;1", &rv);
   NS_ENSURE_SUCCESS(rv, rv);
 
   // find out if we're a plaintext control or not
-  PRUint32 editorFlags = 0;
-  rv = GetFlags(&editorFlags);
-  if (NS_FAILED(rv)) return rv;
-
-  PRBool bIsPlainTextControl = ((editorFlags & eEditorPlaintextMask) != 0);
-  if (bIsPlainTextControl)
+  if (IsPlaintextEditor())
   {
     // Add the unicode flavor to the transferable
     rv = trans->AddDataFlavor(kUnicodeMime);
     if (NS_FAILED(rv)) return rv;
   }
   else
   {
     rv = trans->AddDataFlavor(kHTMLMime);
@@ -614,16 +603,16 @@ nsPlaintextEditor::PutDragDataInTransfer
 
     rv = trans->SetConverter(htmlConverter);
     if (NS_FAILED(rv)) return rv;
   }
 
   // QI the data object an |nsISupports| so that when the transferable holds
   // onto it, it will addref the correct interface.
   nsCOMPtr<nsISupports> nsisupportsDataWrapper = do_QueryInterface(dataWrapper);
-  rv = trans->SetTransferData(bIsPlainTextControl ? kUnicodeMime : kHTMLMime,
+  rv = trans->SetTransferData(IsPlaintextEditor() ? kUnicodeMime : kHTMLMime,
                    nsisupportsDataWrapper, buffer.Length() * sizeof(PRUnichar));
   if (NS_FAILED(rv)) return rv;
 
   *aTransferable = trans;
   NS_ADDREF(*aTransferable);
   return NS_OK;
 }
--- a/editor/libeditor/text/nsPlaintextEditor.cpp
+++ b/editor/libeditor/text/nsPlaintextEditor.cpp
@@ -300,39 +300,24 @@ nsPlaintextEditor::SetDocumentCharacterS
         } 
       } 
     } 
   } 
 
   return result; 
 } 
 
-NS_IMETHODIMP 
-nsPlaintextEditor::GetFlags(PRUint32 *aFlags)
-{
-  if (!mRules || !aFlags) { return NS_ERROR_NULL_POINTER; }
-  return mRules->GetFlags(aFlags);
-}
-
-
-NS_IMETHODIMP 
-nsPlaintextEditor::SetFlags(PRUint32 aFlags)
-{
-  if (!mRules) { return NS_ERROR_NULL_POINTER; }
-  return mRules->SetFlags(aFlags);
-}
-
 
 NS_IMETHODIMP nsPlaintextEditor::InitRules()
 {
   // instantiate the rules for this text editor
   nsresult res = NS_NewTextEditRules(getter_AddRefs(mRules));
   if (NS_FAILED(res)) return res;
   if (!mRules) return NS_ERROR_UNEXPECTED;
-  return mRules->Init(this, mFlags);
+  return mRules->Init(this);
 }
 
 
 NS_IMETHODIMP
 nsPlaintextEditor::GetIsDocumentEditable(PRBool *aIsDocumentEditable)
 {
   NS_ENSURE_ARG_POINTER(aIsDocumentEditable);
 
@@ -340,21 +325,17 @@ nsPlaintextEditor::GetIsDocumentEditable
   GetDocument(getter_AddRefs(doc));
   *aIsDocumentEditable = doc ? IsModifiable() : PR_FALSE;
 
   return NS_OK;
 }
 
 PRBool nsPlaintextEditor::IsModifiable()
 {
-  PRUint32 flags;
-  if (NS_SUCCEEDED(GetFlags(&flags)))
-    return ((flags & eEditorReadonlyMask) == 0);
-
-  return PR_FALSE;
+  return !IsReadonly();
 }
 
 
 #ifdef XP_MAC
 #pragma mark -
 #pragma mark  nsIHTMLEditor methods 
 #pragma mark -
 #endif
@@ -866,17 +847,17 @@ NS_IMETHODIMP nsPlaintextEditor::InsertL
   return res;
 }
 
 NS_IMETHODIMP
 nsPlaintextEditor::BeginComposition()
 {
   NS_ENSURE_TRUE(!mInIMEMode, NS_OK);
 
-  if(mFlags & nsIPlaintextEditor::eEditorPasswordMask)  {
+  if (IsPasswordEditor())  {
     if (mRules) {
       nsIEditRules *p = mRules.get();
       nsTextEditRules *textEditRules = static_cast<nsTextEditRules *>(p);
       textEditRules->ResetIMETextPWBuf();
     }
     else  {
       return NS_ERROR_NULL_POINTER;
     }
@@ -988,19 +969,17 @@ static void CutStyle(const char* stylena
 // 
 NS_IMETHODIMP 
 nsPlaintextEditor::SetWrapWidth(PRInt32 aWrapColumn)
 {
   SetWrapColumn(aWrapColumn);
 
   // Make sure we're a plaintext editor, otherwise we shouldn't
   // do the rest of this.
-  PRUint32 flags = 0;
-  GetFlags(&flags);
-  if (!(flags & eEditorPlaintextMask))
+  if (!IsPlaintextEditor())
     return NS_OK;
 
   // Ought to set a style sheet here ...
   // Probably should keep around an mPlaintextStyleSheet for this purpose.
   nsIDOMElement *rootElement = GetRoot();
   if (!rootElement)
     return NS_ERROR_NULL_POINTER;
 
@@ -1021,24 +1000,24 @@ nsPlaintextEditor::SetWrapWidth(PRInt32 
   {
     styleValue.Trim("; \t", PR_FALSE, PR_TRUE);
     styleValue.AppendLiteral("; ");
   }
 
   // Make sure we have fixed-width font.  This should be done for us,
   // but it isn't, see bug 22502, so we have to add "font: -moz-fixed;".
   // Only do this if we're wrapping.
-  if ((flags & eEditorEnableWrapHackMask) && aWrapColumn >= 0)
+  if (IsWrapHackEnabled() && aWrapColumn >= 0)
     styleValue.AppendLiteral("font-family: -moz-fixed; ");
 
   // If "mail.compose.wrap_to_window_width" is set, and we're a mail editor,
   // then remember our wrap width (for output purposes) but set the visual
   // wrapping to window width.
   // We may reset mWrapToWindow here, based on the pref's current value.
-  if (flags & eEditorMailMask)
+  if (IsMailEditor())
   {
     nsresult rv;
     nsCOMPtr<nsIPrefBranch> prefBranch =
       do_GetService(NS_PREFSERVICE_CONTRACTID, &rv);
     if (NS_SUCCEEDED(rv))
       prefBranch->GetBoolPref("mail.compose.wrap_to_window_width",
                               &mWrapToWindow);
   }
--- a/editor/libeditor/text/nsPlaintextEditor.h
+++ b/editor/libeditor/text/nsPlaintextEditor.h
@@ -106,19 +106,16 @@ public:
   
   NS_IMETHOD GetDocumentIsEmpty(PRBool *aDocumentIsEmpty);
   NS_IMETHOD GetIsDocumentEditable(PRBool *aIsDocumentEditable);
 
   NS_IMETHOD DeleteSelection(EDirection aAction);
 
   NS_IMETHOD SetDocumentCharacterSet(const nsACString & characterSet);
 
-  NS_IMETHOD GetFlags(PRUint32 *aFlags);
-  NS_IMETHOD SetFlags(PRUint32 aFlags);
-
   NS_IMETHOD Undo(PRUint32 aCount);
   NS_IMETHOD Redo(PRUint32 aCount);
 
   NS_IMETHOD Cut();
   NS_IMETHOD CanCut(PRBool *aCanCut);
   NS_IMETHOD Copy();
   NS_IMETHOD CanCopy(PRBool *aCanCopy);
   NS_IMETHOD Paste(PRInt32 aSelectionType);
--- a/editor/libeditor/text/nsTextEditRules.cpp
+++ b/editor/libeditor/text/nsTextEditRules.cpp
@@ -67,17 +67,17 @@
 #include "nsIDOMNodeFilter.h"
 
 // for IBMBIDI
 #include "nsFrameSelection.h"
 
 static NS_DEFINE_CID(kLookAndFeelCID, NS_LOOKANDFEEL_CID);
 
 #define CANCEL_OPERATION_IF_READONLY_OR_DISABLED \
-  if ((mFlags & nsIPlaintextEditor::eEditorReadonlyMask) || (mFlags & nsIPlaintextEditor::eEditorDisabledMask)) \
+  if (IsReadonly() || IsDisabled()) \
   {                     \
     *aCancel = PR_TRUE; \
     return NS_OK;       \
   };
 
 
 nsresult
 NS_NewTextEditRules(nsIEditRules** aInstancePtrResult)
@@ -93,17 +93,16 @@ NS_NewTextEditRules(nsIEditRules** aInst
  *  Constructor/Destructor 
  ********************************************************/
 
 nsTextEditRules::nsTextEditRules()
 : mEditor(nsnull)
 , mPasswordText()
 , mPasswordIMEText()
 , mPasswordIMEIndex(0)
-, mFlags(0) // initialized to 0 ("no flags set").  Real initial value is given in Init()
 , mActionNesting(0)
 , mLockRulesSniffing(PR_FALSE)
 , mDidExplicitlySetInterline(PR_FALSE)
 , mTheAction(0)
 , mLastStart(0)
 , mLastLength(0)
 {
 }
@@ -131,23 +130,21 @@ NS_INTERFACE_MAP_END
 NS_IMPL_CYCLE_COLLECTING_ADDREF(nsTextEditRules)
 NS_IMPL_CYCLE_COLLECTING_RELEASE(nsTextEditRules)
 
 /********************************************************
  *  Public methods 
  ********************************************************/
 
 NS_IMETHODIMP
-nsTextEditRules::Init(nsPlaintextEditor *aEditor, PRUint32 aFlags)
+nsTextEditRules::Init(nsPlaintextEditor *aEditor)
 {
   if (!aEditor) { return NS_ERROR_NULL_POINTER; }
 
   mEditor = aEditor;  // we hold a non-refcounted reference back to our editor
-  // call SetFlags only aftet mEditor has been initialized!
-  SetFlags(aFlags);
   nsCOMPtr<nsISelection> selection;
   mEditor->GetSelection(getter_AddRefs(selection));
   NS_ASSERTION(selection, "editor cannot get selection");
 
   // Cache our body node, if available.
   nsIDOMNode *body = mEditor->GetRoot();
 
   // Put in a magic br if needed. This method handles null selection,
@@ -160,17 +157,17 @@ nsTextEditRules::Init(nsPlaintextEditor 
   PRInt32 rangeCount;
   res = selection->GetRangeCount(&rangeCount);
   NS_ENSURE_SUCCESS(res, res);
   if (!rangeCount) {
     res = mEditor->EndOfDocument();
     NS_ENSURE_SUCCESS(res, res);
   }
 
-  if (mFlags & nsIPlaintextEditor::eEditorPlaintextMask)
+  if (IsPlaintextEditor())
   {
     // ensure trailing br node
     res = CreateTrailingBRIfNeeded();
     if (NS_FAILED(res)) return res;
   }
 
   if (body)
   {
@@ -212,38 +209,16 @@ nsTextEditRules::DetachEditor()
   if (mTimer)
     mTimer->Cancel();
 
   mEditor = nsnull;
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsTextEditRules::GetFlags(PRUint32 *aFlags)
-{
-  if (!aFlags) { return NS_ERROR_NULL_POINTER; }
-  *aFlags = mFlags;
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsTextEditRules::SetFlags(PRUint32 aFlags)
-{
-  if (mFlags == aFlags) return NS_OK;
-  
-  // XXX - this won't work if body element already has
-  // a style attribute on it, don't know why.
-  // SetFlags() is really meant to only be called once
-  // and at editor init time.  
-
-  mFlags = aFlags;
-  return NS_OK;
-}
-
-NS_IMETHODIMP
 nsTextEditRules::BeforeEdit(PRInt32 action, nsIEditor::EDirection aDirection)
 {
   if (mLockRulesSniffing) return NS_OK;
   
   nsAutoLockRulesSniffing lockIt(this);
   mDidExplicitlySetInterline = PR_FALSE;
   
   // get the selection and cache the position before editing
@@ -452,17 +427,17 @@ nsTextEditRules::DidInsert(nsISelection 
 }
 
 nsresult
 nsTextEditRules::WillInsertBreak(nsISelection *aSelection, PRBool *aCancel, PRBool *aHandled)
 {
   if (!aSelection || !aCancel || !aHandled) { return NS_ERROR_NULL_POINTER; }
   CANCEL_OPERATION_IF_READONLY_OR_DISABLED
   *aHandled = PR_FALSE;
-  if (mFlags & nsIPlaintextEditor::eEditorSingleLineMask) {
+  if (IsSingleLineEditor()) {
     *aCancel = PR_TRUE;
   }
   else 
   {
     *aCancel = PR_FALSE;
 
     // if the selection isn't collapsed, delete it.
     PRBool bCollapsed;
@@ -485,17 +460,19 @@ nsTextEditRules::WillInsertBreak(nsISele
 }
 
 nsresult
 nsTextEditRules::DidInsertBreak(nsISelection *aSelection, nsresult aResult)
 {
   // we only need to execute the stuff below if we are a plaintext editor.
   // html editors have a different mechanism for putting in mozBR's
   // (because there are a bunch more places you have to worry about it in html) 
-  if (!nsIPlaintextEditor::eEditorPlaintextMask & mFlags) return NS_OK;
+  if (!IsPlaintextEditor()) {
+    return NS_OK;
+  }
 
   // if we are at the end of the document, we need to insert 
   // a special mozBR following the normal br, and then set the
   // selection to stick to the mozBR.
   PRInt32 selOffset;
   nsCOMPtr<nsIDOMNode> selNode;
   nsresult res;
   res = mEditor->GetStartNodeAndOffset(aSelection, address_of(selNode), &selOffset);
@@ -549,17 +526,17 @@ GetTextNode(nsISelection *selection, nsE
         return nsnull;
       }
     }
   }
   return selNode.forget();
 }
 #ifdef DEBUG
 #define ASSERT_PASSWORD_LENGTHS_EQUAL()                                \
-  if (mFlags & nsIPlaintextEditor::eEditorPasswordMask) {              \
+  if (IsPasswordEditor()) {                                            \
     PRInt32 txtLen;                                                    \
     mEditor->GetTextLength(&txtLen);                                   \
     NS_ASSERTION(mPasswordText.Length() == txtLen,                     \
                  "password length not equal to number of asterisks");  \
   }
 #else
 #define ASSERT_PASSWORD_LENGTHS_EQUAL()
 #endif
@@ -664,17 +641,17 @@ nsTextEditRules::WillInsertText(PRInt32 
   // NOTE, this function copies inString into outString for us.
   nsresult res = TruncateInsertionIfNeeded(aSelection, inString, outString, aMaxLength);
   if (NS_FAILED(res)) return res;
   
   PRUint32 start = 0;
   PRUint32 end = 0;  
 
   // handle password field docs
-  if (mFlags & nsIPlaintextEditor::eEditorPasswordMask)
+  if (IsPasswordEditor())
   {
     res = mEditor->GetTextSelectionOffsets(aSelection, start, end);
     NS_ASSERTION((NS_SUCCEEDED(res)), "getTextSelectionOffsets failed!");
     if (NS_FAILED(res)) return res;
   }
 
   // if the selection isn't collapsed, delete it.
   PRBool bCollapsed;
@@ -690,17 +667,17 @@ nsTextEditRules::WillInsertText(PRInt32 
   if (NS_FAILED(res)) return res;
   // initialize out param
   // we want to ignore result of WillInsert()
   *aCancel = PR_FALSE;
   
   // handle password field data
   // this has the side effect of changing all the characters in aOutString
   // to the replacement character
-  if (mFlags & nsIPlaintextEditor::eEditorPasswordMask)
+  if (IsPasswordEditor())
   {
     if (aAction == kInsertTextIME)  {
       res = RemoveIMETextFromPWBuf(start, outString);
       if (NS_FAILED(res)) return res;
     }
   }
 
   // People have lots of different ideas about what text fields
@@ -708,33 +685,32 @@ nsTextEditRules::WillInsertText(PRInt32 
   // The six possible options are:
   // 0. paste newlines intact
   // 1. paste up to the first newline (default)
   // 2. replace newlines with spaces
   // 3. strip newlines
   // 4. replace with commas
   // 5. strip newlines and surrounding whitespace
   // So find out what we're expected to do:
-  if (nsIPlaintextEditor::eEditorSingleLineMask & mFlags)
+  if (IsSingleLineEditor())
   {
     nsAutoString tString(*outString);
 
     HandleNewLines(tString, mEditor->mNewlineHandling);
 
     outString->Assign(tString);
   }
 
-  if (mFlags & nsIPlaintextEditor::eEditorPasswordMask)
+  if (IsPasswordEditor())
   {
     // manage the password buffer
     mPasswordText.Insert(*outString, start);
 
     nsCOMPtr<nsILookAndFeel> lookAndFeel = do_GetService(kLookAndFeelCID);
-    if (lookAndFeel->GetEchoPassword() && 
-        !(mFlags & nsIPlaintextEditor::eEditorDontEchoPassword)) {
+    if (lookAndFeel->GetEchoPassword() && !DontEchoPassword()) {
       HideLastPWInput();
       mLastStart = start;
       mLastLength = outString->Length();
       if (mTimer)
       {
         mTimer->Cancel();
       }
       else
@@ -815,17 +791,17 @@ nsTextEditRules::WillInsertText(PRInt32 
           pos = tString.Length();
         }
 
         nsDependentSubstring subStr(tString, oldPos, subStrLen);
         
         // is it a return?
         if (subStr.EqualsLiteral(LFSTR))
         {
-          if (nsIPlaintextEditor::eEditorSingleLineMask & mFlags)
+          if (IsSingleLineEditor())
           {
             NS_ASSERTION((mEditor->mNewlineHandling == nsIPlaintextEditor::eNewlinesPasteIntact),
                   "Newline improperly getting into single-line edit field!");
             res = mEditor->InsertTextImpl(subStr, address_of(curNode), &curOffset, doc);
           }
           else
           {
             res = mEditor->CreateBRImpl(address_of(curNode), &curOffset, address_of(unused), nsIEditor::eNone);
@@ -932,17 +908,17 @@ nsTextEditRules::DidInsertText(nsISelect
 
 nsresult
 nsTextEditRules::WillSetTextProperty(nsISelection *aSelection, PRBool *aCancel, PRBool *aHandled)
 {
   if (!aSelection || !aCancel || !aHandled) 
     { return NS_ERROR_NULL_POINTER; }
 
   // XXX: should probably return a success value other than NS_OK that means "not allowed"
-  if (nsIPlaintextEditor::eEditorPlaintextMask & mFlags) {
+  if (IsPlaintextEditor()) {
     *aCancel = PR_TRUE;
   }
   return NS_OK;
 }
 
 nsresult
 nsTextEditRules::DidSetTextProperty(nsISelection *aSelection, nsresult aResult)
 {
@@ -951,17 +927,17 @@ nsTextEditRules::DidSetTextProperty(nsIS
 
 nsresult
 nsTextEditRules::WillRemoveTextProperty(nsISelection *aSelection, PRBool *aCancel, PRBool *aHandled)
 {
   if (!aSelection || !aCancel || !aHandled) 
     { return NS_ERROR_NULL_POINTER; }
 
   // XXX: should probably return a success value other than NS_OK that means "not allowed"
-  if (nsIPlaintextEditor::eEditorPlaintextMask & mFlags) {
+  if (IsPlaintextEditor()) {
     *aCancel = PR_TRUE;
   }
   return NS_OK;
 }
 
 nsresult
 nsTextEditRules::DidRemoveTextProperty(nsISelection *aSelection, nsresult aResult)
 {
@@ -984,17 +960,17 @@ nsTextEditRules::WillDeleteSelection(nsI
   // if there is only bogus content, cancel the operation
   if (mBogusNode) {
     *aCancel = PR_TRUE;
     return NS_OK;
   }
 
   nsresult res = NS_OK;
 
-  if (mFlags & nsIPlaintextEditor::eEditorPasswordMask)
+  if (IsPasswordEditor())
   {
     res = mEditor->ExtendSelectionForDelete(aSelection, &aCollapsedAction);
     NS_ENSURE_SUCCESS(res, res);
 
     // manage the password buffer
     PRUint32 start, end;
     mEditor->GetTextSelectionOffsets(aSelection, start, end);
     NS_ENSURE_SUCCESS(res, res);
@@ -1190,17 +1166,17 @@ nsTextEditRules::WillOutputText(nsISelec
   // initialize out param
   *aCancel = PR_FALSE;
   *aHandled = PR_FALSE;
 
   nsAutoString outputFormat(*aOutputFormat);
   ToLowerCase(outputFormat);
   if (outputFormat.EqualsLiteral("text/plain"))
   { // only use these rules for plain text output
-    if (mFlags & nsIPlaintextEditor::eEditorPasswordMask)
+    if (IsPasswordEditor())
     {
       *aOutString = mPasswordText;
       *aHandled = PR_TRUE;
     }
     else if (mBogusNode)
     { // this means there's no content, so output null string
       aOutString->Truncate();
       *aHandled = PR_TRUE;
@@ -1292,17 +1268,17 @@ nsTextEditRules::ReplaceNewlines(nsIDOMR
   }
   return res;
 }
 
 nsresult
 nsTextEditRules::CreateTrailingBRIfNeeded()
 {
   // but only if we aren't a single line edit field
-  if (mFlags & nsIPlaintextEditor::eEditorSingleLineMask)
+  if (IsSingleLineEditor())
     return NS_OK;
   nsIDOMNode *body = mEditor->GetRoot();
   if (!body)
     return NS_ERROR_NULL_POINTER;
   nsCOMPtr<nsIDOMNode> lastChild;
   nsresult res = body->GetLastChild(getter_AddRefs(lastChild));
   // assuming CreateBogusNodeIfNeeded() has been called first
   if (NS_FAILED(res)) return res;  
@@ -1391,18 +1367,17 @@ nsTextEditRules::TruncateInsertionIfNeed
                                            nsAString  *aOutString,
                                            PRInt32          aMaxLength)
 {
   if (!aSelection || !aInString || !aOutString) {return NS_ERROR_NULL_POINTER;}
   
   nsresult res = NS_OK;
   *aOutString = *aInString;
   
-  if ((-1 != aMaxLength) && (mFlags & nsIPlaintextEditor::eEditorPlaintextMask)
-      && !mEditor->IsIMEComposing() )
+  if ((-1 != aMaxLength) && IsPlaintextEditor() && !mEditor->IsIMEComposing() )
   {
     // Get the current text length.
     // Get the length of inString.
     // Get the length of the selection.
     //   If selection is collapsed, it is length 0.
     //   Subtract the length of the selection from the len(doc) 
     //   since we'll delete the selection on insert.
     //   This is resultingDocLength.
--- a/editor/libeditor/text/nsTextEditRules.h
+++ b/editor/libeditor/text/nsTextEditRules.h
@@ -63,24 +63,22 @@ public:
   NS_DECL_NSITIMERCALLBACK
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsTextEditRules, nsIEditRules)
   
               nsTextEditRules();
   virtual     ~nsTextEditRules();
 
   // nsIEditRules methods
-  NS_IMETHOD Init(nsPlaintextEditor *aEditor, PRUint32 aFlags);
+  NS_IMETHOD Init(nsPlaintextEditor *aEditor);
   NS_IMETHOD DetachEditor();
   NS_IMETHOD BeforeEdit(PRInt32 action, nsIEditor::EDirection aDirection);
   NS_IMETHOD AfterEdit(PRInt32 action, nsIEditor::EDirection aDirection);
   NS_IMETHOD WillDoAction(nsISelection *aSelection, nsRulesInfo *aInfo, PRBool *aCancel, PRBool *aHandled);
   NS_IMETHOD DidDoAction(nsISelection *aSelection, nsRulesInfo *aInfo, nsresult aResult);
-  NS_IMETHOD GetFlags(PRUint32 *aFlags);
-  NS_IMETHOD SetFlags(PRUint32 aFlags);
   NS_IMETHOD DocumentIsEmpty(PRBool *aDocumentIsEmpty);
 
   // nsTextEditRules action id's
   enum 
   {
     kDefault             = 0,
     // any editor that has a txn mgr
     kUndo                = 1000,
@@ -230,25 +228,53 @@ protected:
   nsresult CheckBidiLevelForDeletion(nsISelection         *aSelection,
                                      nsIDOMNode           *aSelNode, 
                                      PRInt32               aSelOffset, 
                                      nsIEditor::EDirection aAction,
                                      PRBool               *aCancel);
 
   nsresult HideLastPWInput();
 
+  PRBool IsPasswordEditor() const
+  {
+    return mEditor ? mEditor->IsPasswordEditor() : PR_FALSE;
+  }
+  PRBool IsSingleLineEditor() const
+  {
+    return mEditor ? mEditor->IsSingleLineEditor() : PR_FALSE;
+  }
+  PRBool IsPlaintextEditor() const
+  {
+    return mEditor ? mEditor->IsPlaintextEditor() : PR_FALSE;
+  }
+  PRBool IsReadonly() const
+  {
+    return mEditor ? mEditor->IsReadonly() : PR_FALSE;
+  }
+  PRBool IsDisabled() const
+  {
+    return mEditor ? mEditor->IsDisabled() : PR_FALSE;
+  }
+  PRBool IsMailEditor() const
+  {
+    return mEditor ? mEditor->IsMailEditor() : PR_FALSE;
+  }
+  PRBool DontEchoPassword() const
+  {
+    return mEditor ? mEditor->DontEchoPassword() : PR_FALSE;
+  }
+
   // data members
   nsPlaintextEditor   *mEditor;        // note that we do not refcount the editor
   nsString             mPasswordText;  // a buffer we use to store the real value of password editors
   nsString             mPasswordIMEText;  // a buffer we use to track the IME composition string
   PRUint32             mPasswordIMEIndex;
   nsCOMPtr<nsIDOMNode> mBogusNode;     // magic node acts as placeholder in empty doc
   nsCOMPtr<nsIDOMNode> mCachedSelectionNode;    // cached selected node
   PRInt32              mCachedSelectionOffset;  // cached selected offset
-  PRUint32             mFlags;
   PRUint32             mActionNesting;
   PRPackedBool         mLockRulesSniffing;
   PRPackedBool         mDidExplicitlySetInterline;
   PRPackedBool         mDeleteBidiImmediately; // in bidirectional text, delete
                                                // characters not visually 
                                                // adjacent to the caret without
                                                // moving the caret first.
   PRInt32              mTheAction;     // the top level editor action