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 idunknown
push userunknown
push dateunknown
reviewerssmaug
bugs552914
milestone1.9.3a5pre
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