editor/libeditor/base/nsEditor.h

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     2 /* This Source Code Form is subject to the terms of the Mozilla Public
     3  * License, v. 2.0. If a copy of the MPL was not distributed with this
     4  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     6 #ifndef __editor_h__
     7 #define __editor_h__
     9 #include "mozilla/Assertions.h"         // for MOZ_ASSERT, etc.
    10 #include "mozilla/TypedEnum.h"          // for MOZ_BEGIN_ENUM_CLASS, etc.
    11 #include "nsAutoPtr.h"                  // for nsRefPtr
    12 #include "nsCOMArray.h"                 // for nsCOMArray
    13 #include "nsCOMPtr.h"                   // for already_AddRefed, nsCOMPtr
    14 #include "nsCycleCollectionParticipant.h"
    15 #include "nsEditProperty.h"             // for nsEditProperty, etc
    16 #include "nsIEditor.h"                  // for nsIEditor::EDirection, etc
    17 #include "nsIEditorIMESupport.h"        // for NS_DECL_NSIEDITORIMESUPPORT, etc
    18 #include "nsIObserver.h"                // for NS_DECL_NSIOBSERVER, etc
    19 #include "nsIPhonetic.h"                // for NS_DECL_NSIPHONETIC, etc
    20 #include "nsIPlaintextEditor.h"         // for nsIPlaintextEditor, etc
    21 #include "nsISupportsImpl.h"            // for nsEditor::Release, etc
    22 #include "nsIWeakReferenceUtils.h"      // for nsWeakPtr
    23 #include "nsLiteralString.h"            // for NS_LITERAL_STRING
    24 #include "nsSelectionState.h"           // for nsRangeUpdater, etc
    25 #include "nsString.h"                   // for nsCString
    26 #include "nsWeakReference.h"            // for nsSupportsWeakReference
    27 #include "nscore.h"                     // for nsresult, nsAString, etc
    29 class AddStyleSheetTxn;
    30 class ChangeAttributeTxn;
    31 class CreateElementTxn;
    32 class DeleteNodeTxn;
    33 class DeleteTextTxn;
    34 class EditAggregateTxn;
    35 class IMETextTxn;
    36 class InsertElementTxn;
    37 class InsertTextTxn;
    38 class JoinElementTxn;
    39 class RemoveStyleSheetTxn;
    40 class SplitElementTxn;
    41 class nsCSSStyleSheet;
    42 class nsIAtom;
    43 class nsIContent;
    44 class nsIDOMCharacterData;
    45 class nsIDOMDataTransfer;
    46 class nsIDOMDocument;
    47 class nsIDOMElement;
    48 class nsIDOMEvent;
    49 class nsIDOMEventListener;
    50 class nsIDOMEventTarget;
    51 class nsIDOMKeyEvent;
    52 class nsIDOMNode;
    53 class nsIDOMRange;
    54 class nsIDocument;
    55 class nsIDocumentStateListener;
    56 class nsIEditActionListener;
    57 class nsIEditorObserver;
    58 class nsIInlineSpellChecker;
    59 class nsINode;
    60 class nsIPresShell;
    61 class nsISelection;
    62 class nsISupports;
    63 class nsITransaction;
    64 class nsIWidget;
    65 class nsRange;
    66 class nsString;
    67 class nsTransactionManager;
    69 namespace mozilla {
    70 class TextComposition;
    72 namespace dom {
    73 class DataTransfer;
    74 class Element;
    75 class EventTarget;
    76 class Selection;
    77 }  // namespace dom
    78 }  // namespace mozilla
    80 namespace mozilla {
    81 namespace widget {
    82 struct IMEState;
    83 } // namespace widget
    84 } // namespace mozilla
    86 #define kMOZEditorBogusNodeAttrAtom nsEditProperty::mozEditorBogusNode
    87 #define kMOZEditorBogusNodeValue NS_LITERAL_STRING("TRUE")
    89 // This is int32_t instead of int16_t because nsIInlineSpellChecker.idl's
    90 // spellCheckAfterEditorChange is defined to take it as a long.
    91 MOZ_BEGIN_ENUM_CLASS(EditAction, int32_t)
    92   ignore = -1,
    93   none = 0,
    94   undo,
    95   redo,
    96   insertNode,
    97   createNode,
    98   deleteNode,
    99   splitNode,
   100   joinNode,
   101   deleteText = 1003,
   103   // text commands
   104   insertText         = 2000,
   105   insertIMEText      = 2001,
   106   deleteSelection    = 2002,
   107   setTextProperty    = 2003,
   108   removeTextProperty = 2004,
   109   outputText         = 2005,
   111   // html only action
   112   insertBreak         = 3000,
   113   makeList            = 3001,
   114   indent              = 3002,
   115   outdent             = 3003,
   116   align               = 3004,
   117   makeBasicBlock      = 3005,
   118   removeList          = 3006,
   119   makeDefListItem     = 3007,
   120   insertElement       = 3008,
   121   insertQuotation     = 3009,
   122   htmlPaste           = 3012,
   123   loadHTML            = 3013,
   124   resetTextProperties = 3014,
   125   setAbsolutePosition = 3015,
   126   removeAbsolutePosition = 3016,
   127   decreaseZIndex      = 3017,
   128   increaseZIndex      = 3018
   129 MOZ_END_ENUM_CLASS(EditAction)
   131 inline bool operator!(const EditAction& aOp)
   132 {
   133   return aOp == EditAction::none;
   134 }
   136 /** implementation of an editor object.  it will be the controller/focal point 
   137  *  for the main editor services. i.e. the GUIManager, publishing, transaction 
   138  *  manager, event interfaces. the idea for the event interfaces is to have them 
   139  *  delegate the actual commands to the editor independent of the XPFE implementation.
   140  */
   141 class nsEditor : public nsIEditor,
   142                  public nsIEditorIMESupport,
   143                  public nsSupportsWeakReference,
   144                  public nsIObserver,
   145                  public nsIPhonetic
   146 {
   147 public:
   149   enum IterDirection
   150   {
   151     kIterForward,
   152     kIterBackward
   153   };
   155   /** The default constructor. This should suffice. the setting of the interfaces is done
   156    *  after the construction of the editor class.
   157    */
   158   nsEditor();
   159   /** The default destructor. This should suffice. Should this be pure virtual 
   160    *  for someone to derive from the nsEditor later? I don't believe so.
   161    */
   162   virtual ~nsEditor();
   164 //Interfaces for addref and release and queryinterface
   165 //NOTE: Use   NS_DECL_ISUPPORTS_INHERITED in any class inherited from nsEditor
   166   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   167   NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsEditor,
   168                                            nsIEditor)
   170   /* ------------ utility methods   -------------- */
   171   already_AddRefed<nsIDOMDocument> GetDOMDocument();
   172   already_AddRefed<nsIDocument> GetDocument();
   173   already_AddRefed<nsIPresShell> GetPresShell();
   174   already_AddRefed<nsIWidget> GetWidget();
   175   void NotifyEditorObservers();
   177   /* ------------ nsIEditor methods -------------- */
   178   NS_DECL_NSIEDITOR
   180   /* ------------ nsIEditorIMESupport methods -------------- */
   181   NS_DECL_NSIEDITORIMESUPPORT
   183   /* ------------ nsIObserver methods -------------- */
   184   NS_DECL_NSIOBSERVER
   186   // nsIPhonetic
   187   NS_DECL_NSIPHONETIC
   189 public:
   191   virtual bool IsModifiableNode(nsINode *aNode);
   193   NS_IMETHOD InsertTextImpl(const nsAString& aStringToInsert, 
   194                                nsCOMPtr<nsIDOMNode> *aInOutNode, 
   195                                int32_t *aInOutOffset,
   196                                nsIDOMDocument *aDoc);
   197   nsresult InsertTextIntoTextNodeImpl(const nsAString& aStringToInsert, 
   198                                       nsIDOMCharacterData *aTextNode, 
   199                                       int32_t aOffset,
   200                                       bool aSuppressIME = false);
   201   NS_IMETHOD DeleteSelectionImpl(EDirection aAction,
   202                                  EStripWrappers aStripWrappers);
   203   NS_IMETHOD DeleteSelectionAndCreateNode(const nsAString& aTag,
   204                                            nsIDOMNode ** aNewNode);
   206   /* helper routines for node/parent manipulations */
   207   nsresult DeleteNode(nsINode* aNode);
   208   nsresult ReplaceContainer(nsINode* inNode,
   209                             mozilla::dom::Element** outNode,
   210                             const nsAString& aNodeType,
   211                             const nsAString* aAttribute = nullptr,
   212                             const nsAString* aValue = nullptr,
   213                             bool aCloneAttributes = false);
   214   nsresult ReplaceContainer(nsIDOMNode *inNode, 
   215                             nsCOMPtr<nsIDOMNode> *outNode, 
   216                             const nsAString &aNodeType,
   217                             const nsAString *aAttribute = nullptr,
   218                             const nsAString *aValue = nullptr,
   219                             bool aCloneAttributes = false);
   221   nsresult RemoveContainer(nsINode* aNode);
   222   nsresult RemoveContainer(nsIDOMNode *inNode);
   223   nsresult InsertContainerAbove(nsIContent* aNode,
   224                                 mozilla::dom::Element** aOutNode,
   225                                 const nsAString& aNodeType,
   226                                 const nsAString* aAttribute = nullptr,
   227                                 const nsAString* aValue = nullptr);
   228   nsresult InsertContainerAbove(nsIDOMNode *inNode, 
   229                                 nsCOMPtr<nsIDOMNode> *outNode, 
   230                                 const nsAString &aNodeType,
   231                                 const nsAString *aAttribute = nullptr,
   232                                 const nsAString *aValue = nullptr);
   233   nsresult JoinNodes(nsINode* aNodeToKeep, nsIContent* aNodeToMove);
   234   nsresult MoveNode(nsINode* aNode, nsINode* aParent, int32_t aOffset);
   235   nsresult MoveNode(nsIDOMNode *aNode, nsIDOMNode *aParent, int32_t aOffset);
   237   /* Method to replace certain CreateElementNS() calls. 
   238      Arguments:
   239       nsString& aTag          - tag you want
   240       nsIContent** aContent   - returned Content that was created with above namespace.
   241   */
   242   nsresult CreateHTMLContent(const nsAString& aTag,
   243                              mozilla::dom::Element** aContent);
   245   // IME event handlers
   246   virtual nsresult BeginIMEComposition(mozilla::WidgetCompositionEvent* aEvent);
   247   virtual nsresult UpdateIMEComposition(nsIDOMEvent* aDOMTextEvent) = 0;
   248   void EndIMEComposition();
   250   void SwitchTextDirectionTo(uint32_t aDirection);
   252 protected:
   253   nsresult DetermineCurrentDirection();
   254   void FireInputEvent();
   256   /** create a transaction for setting aAttribute to aValue on aElement
   257     */
   258   NS_IMETHOD CreateTxnForSetAttribute(nsIDOMElement *aElement, 
   259                                       const nsAString &  aAttribute, 
   260                                       const nsAString &  aValue,
   261                                       ChangeAttributeTxn ** aTxn);
   263   /** create a transaction for removing aAttribute on aElement
   264     */
   265   NS_IMETHOD CreateTxnForRemoveAttribute(nsIDOMElement *aElement, 
   266                                          const nsAString &  aAttribute,
   267                                          ChangeAttributeTxn ** aTxn);
   269   /** create a transaction for creating a new child node of aParent of type aTag.
   270     */
   271   NS_IMETHOD CreateTxnForCreateElement(const nsAString & aTag,
   272                                        nsIDOMNode     *aParent,
   273                                        int32_t         aPosition,
   274                                        CreateElementTxn ** aTxn);
   276   /** create a transaction for inserting aNode as a child of aParent.
   277     */
   278   NS_IMETHOD CreateTxnForInsertElement(nsIDOMNode * aNode,
   279                                        nsIDOMNode * aParent,
   280                                        int32_t      aOffset,
   281                                        InsertElementTxn ** aTxn);
   283   /** create a transaction for removing aNode from its parent.
   284     */
   285   nsresult CreateTxnForDeleteNode(nsINode* aNode, DeleteNodeTxn** aTxn);
   288   nsresult CreateTxnForDeleteSelection(EDirection aAction,
   289                                        EditAggregateTxn** aTxn,
   290                                        nsINode** aNode,
   291                                        int32_t* aOffset,
   292                                        int32_t* aLength);
   294   nsresult CreateTxnForDeleteInsertionPoint(nsRange* aRange, 
   295                                             EDirection aAction, 
   296                                             EditAggregateTxn* aTxn,
   297                                             nsINode** aNode,
   298                                             int32_t* aOffset,
   299                                             int32_t* aLength);
   302   /** create a transaction for inserting aStringToInsert into aTextNode
   303     * if aTextNode is null, the string is inserted at the current selection.
   304     */
   305   NS_IMETHOD CreateTxnForInsertText(const nsAString & aStringToInsert,
   306                                     nsIDOMCharacterData *aTextNode,
   307                                     int32_t aOffset,
   308                                     InsertTextTxn ** aTxn);
   310   NS_IMETHOD CreateTxnForIMEText(const nsAString & aStringToInsert,
   311                                  IMETextTxn ** aTxn);
   313   /** create a transaction for adding a style sheet
   314     */
   315   NS_IMETHOD CreateTxnForAddStyleSheet(nsCSSStyleSheet* aSheet, AddStyleSheetTxn* *aTxn);
   317   /** create a transaction for removing a style sheet
   318     */
   319   NS_IMETHOD CreateTxnForRemoveStyleSheet(nsCSSStyleSheet* aSheet, RemoveStyleSheetTxn* *aTxn);
   321   NS_IMETHOD DeleteText(nsIDOMCharacterData *aElement,
   322                         uint32_t             aOffset,
   323                         uint32_t             aLength);
   325 //  NS_IMETHOD DeleteRange(nsIDOMRange *aRange);
   327   nsresult CreateTxnForDeleteText(nsIDOMCharacterData* aElement,
   328                                   uint32_t             aOffset,
   329                                   uint32_t             aLength,
   330                                   DeleteTextTxn**      aTxn);
   332   nsresult CreateTxnForDeleteCharacter(nsIDOMCharacterData* aData,
   333                                        uint32_t             aOffset,
   334                                        EDirection           aDirection,
   335                                        DeleteTextTxn**      aTxn);
   337   NS_IMETHOD CreateTxnForSplitNode(nsIDOMNode *aNode,
   338                                    uint32_t    aOffset,
   339                                    SplitElementTxn **aTxn);
   341   NS_IMETHOD CreateTxnForJoinNode(nsIDOMNode  *aLeftNode,
   342                                   nsIDOMNode  *aRightNode,
   343                                   JoinElementTxn **aTxn);
   345   /**
   346    * This method first deletes the selection, if it's not collapsed.  Then if
   347    * the selection lies in a CharacterData node, it splits it.  If the
   348    * selection is at this point collapsed in a CharacterData node, it's
   349    * adjusted to be collapsed right before or after the node instead (which is
   350    * always possible, since the node was split).
   351    */
   352   nsresult DeleteSelectionAndPrepareToCreateNode();
   355   // called after a transaction is done successfully
   356   void DoAfterDoTransaction(nsITransaction *aTxn);
   357   // called after a transaction is undone successfully
   358   void DoAfterUndoTransaction();
   359   // called after a transaction is redone successfully
   360   void DoAfterRedoTransaction();
   362   typedef enum {
   363     eDocumentCreated,
   364     eDocumentToBeDestroyed,
   365     eDocumentStateChanged
   366   } TDocumentListenerNotification;
   368   // tell the doc state listeners that the doc state has changed
   369   NS_IMETHOD NotifyDocumentListeners(TDocumentListenerNotification aNotificationType);
   371   /** make the given selection span the entire document */
   372   NS_IMETHOD SelectEntireDocument(nsISelection *aSelection);
   374   /** helper method for scrolling the selection into view after
   375    *  an edit operation. aScrollToAnchor should be true if you
   376    *  want to scroll to the point where the selection was started.
   377    *  If false, it attempts to scroll the end of the selection into view.
   378    *
   379    *  Editor methods *should* call this method instead of the versions
   380    *  in the various selection interfaces, since this version makes sure
   381    *  that the editor's sync/async settings for reflowing, painting, and
   382    *  scrolling match.
   383    */
   384   NS_IMETHOD ScrollSelectionIntoView(bool aScrollToAnchor);
   386   // Convenience method; forwards to IsBlockNode(nsINode*).
   387   bool IsBlockNode(nsIDOMNode* aNode);
   388   // stub.  see comment in source.                     
   389   virtual bool IsBlockNode(nsINode* aNode);
   391   // helper for GetPriorNode and GetNextNode
   392   nsIContent* FindNextLeafNode(nsINode  *aCurrentNode,
   393                                bool      aGoForward,
   394                                bool      bNoBlockCrossing);
   396   // install the event listeners for the editor 
   397   virtual nsresult InstallEventListeners();
   399   virtual void CreateEventListeners();
   401   // unregister and release our event listeners
   402   virtual void RemoveEventListeners();
   404   /**
   405    * Return true if spellchecking should be enabled for this editor.
   406    */
   407   bool GetDesiredSpellCheckState();
   409   bool CanEnableSpellCheck()
   410   {
   411     // Check for password/readonly/disabled, which are not spellchecked
   412     // regardless of DOM. Also, check to see if spell check should be skipped or not.
   413     return !IsPasswordEditor() && !IsReadonly() && !IsDisabled() && !ShouldSkipSpellCheck();
   414   }
   416   /**
   417    * EnsureComposition() should be composition event handlers or text event
   418    * handler.  This tries to get the composition for the event and set it to
   419    * mComposition.
   420    */
   421   void EnsureComposition(mozilla::WidgetGUIEvent* aEvent);
   423 public:
   425   /** All editor operations which alter the doc should be prefaced
   426    *  with a call to StartOperation, naming the action and direction */
   427   NS_IMETHOD StartOperation(EditAction opID,
   428                             nsIEditor::EDirection aDirection);
   430   /** All editor operations which alter the doc should be followed
   431    *  with a call to EndOperation */
   432   NS_IMETHOD EndOperation();
   434   /** routines for managing the preservation of selection across 
   435    *  various editor actions */
   436   bool     ArePreservingSelection();
   437   void     PreserveSelectionAcrossActions(mozilla::dom::Selection* aSel);
   438   nsresult RestorePreservedSelection(nsISelection *aSel);
   439   void     StopPreservingSelection();
   441   /** 
   442    * SplitNode() creates a new node identical to an existing node, and split the contents between the two nodes
   443    * @param aExistingRightNode   the node to split.  It will become the new node's next sibling.
   444    * @param aOffset              the offset of aExistingRightNode's content|children to do the split at
   445    * @param aNewLeftNode         [OUT] the new node resulting from the split, becomes aExistingRightNode's previous sibling.
   446    * @param aParent              the parent of aExistingRightNode
   447    */
   448   nsresult SplitNodeImpl(nsIDOMNode *aExistingRightNode,
   449                          int32_t     aOffset,
   450                          nsIDOMNode *aNewLeftNode,
   451                          nsIDOMNode *aParent);
   453   /** 
   454    * JoinNodes() takes 2 nodes and merge their content|children.
   455    * @param aNodeToKeep   The node that will remain after the join.
   456    * @param aNodeToJoin   The node that will be joined with aNodeToKeep.
   457    *                      There is no requirement that the two nodes be of the same type.
   458    * @param aParent       The parent of aNodeToKeep
   459    */
   460   nsresult JoinNodesImpl(nsINode* aNodeToKeep,
   461                          nsINode* aNodeToJoin,
   462                          nsINode* aParent);
   464   /**
   465    * Return the offset of aChild in aParent.  Asserts fatally if parent or
   466    * child is null, or parent is not child's parent.
   467    */
   468   static int32_t GetChildOffset(nsIDOMNode *aChild,
   469                                 nsIDOMNode *aParent);
   471   /**
   472    *  Set outOffset to the offset of aChild in the parent.
   473    *  Returns the parent of aChild.
   474    */
   475   static already_AddRefed<nsIDOMNode> GetNodeLocation(nsIDOMNode* aChild,
   476                                                       int32_t* outOffset);
   477   static nsINode* GetNodeLocation(nsINode* aChild, int32_t* aOffset);
   479   /** returns the number of things inside aNode in the out-param aCount.  
   480     * @param  aNode is the node to get the length of.  
   481     *         If aNode is text, returns number of characters. 
   482     *         If not, returns number of children nodes.
   483     * @param  aCount [OUT] the result of the above calculation.
   484     */
   485   static nsresult GetLengthOfDOMNode(nsIDOMNode *aNode, uint32_t &aCount);
   487   /** get the node immediately prior to aCurrentNode
   488     * @param aCurrentNode   the node from which we start the search
   489     * @param aEditableNode  if true, only return an editable node
   490     * @param aResultNode    [OUT] the node that occurs before aCurrentNode in the tree,
   491     *                       skipping non-editable nodes if aEditableNode is true.
   492     *                       If there is no prior node, aResultNode will be nullptr.
   493     * @param bNoBlockCrossing If true, don't move across "block" nodes, whatever that means.
   494     */
   495   nsresult GetPriorNode(nsIDOMNode  *aCurrentNode, 
   496                         bool         aEditableNode,
   497                         nsCOMPtr<nsIDOMNode> *aResultNode,
   498                         bool         bNoBlockCrossing = false);
   499   nsIContent* GetPriorNode(nsINode* aCurrentNode, bool aEditableNode,
   500                            bool aNoBlockCrossing = false);
   502   // and another version that takes a {parent,offset} pair rather than a node
   503   nsresult GetPriorNode(nsIDOMNode  *aParentNode, 
   504                         int32_t      aOffset, 
   505                         bool         aEditableNode, 
   506                         nsCOMPtr<nsIDOMNode> *aResultNode,
   507                         bool         bNoBlockCrossing = false);
   508   nsIContent* GetPriorNode(nsINode* aParentNode,
   509                            int32_t aOffset,
   510                            bool aEditableNode,
   511                            bool aNoBlockCrossing = false);
   514   /** get the node immediately after to aCurrentNode
   515     * @param aCurrentNode   the node from which we start the search
   516     * @param aEditableNode  if true, only return an editable node
   517     * @param aResultNode    [OUT] the node that occurs after aCurrentNode in the tree,
   518     *                       skipping non-editable nodes if aEditableNode is true.
   519     *                       If there is no prior node, aResultNode will be nullptr.
   520     */
   521   nsresult GetNextNode(nsIDOMNode  *aCurrentNode, 
   522                        bool         aEditableNode,
   523                        nsCOMPtr<nsIDOMNode> *aResultNode,
   524                        bool         bNoBlockCrossing = false);
   525   nsIContent* GetNextNode(nsINode* aCurrentNode,
   526                           bool aEditableNode,
   527                           bool bNoBlockCrossing = false);
   529   // and another version that takes a {parent,offset} pair rather than a node
   530   nsresult GetNextNode(nsIDOMNode  *aParentNode, 
   531                        int32_t      aOffset, 
   532                        bool         aEditableNode, 
   533                        nsCOMPtr<nsIDOMNode> *aResultNode,
   534                        bool         bNoBlockCrossing = false);
   535   nsIContent* GetNextNode(nsINode* aParentNode,
   536                           int32_t aOffset,
   537                           bool aEditableNode,
   538                           bool aNoBlockCrossing = false);
   540   // Helper for GetNextNode and GetPriorNode
   541   nsIContent* FindNode(nsINode *aCurrentNode,
   542                        bool     aGoForward,
   543                        bool     aEditableNode,
   544                        bool     bNoBlockCrossing);
   545   /**
   546    * Get the rightmost child of aCurrentNode;
   547    * return nullptr if aCurrentNode has no children.
   548    */
   549   nsIDOMNode* GetRightmostChild(nsIDOMNode* aCurrentNode,
   550                                 bool bNoBlockCrossing = false);
   551   nsIContent* GetRightmostChild(nsINode *aCurrentNode,
   552                                 bool     bNoBlockCrossing = false);
   554   /**
   555    * Get the leftmost child of aCurrentNode;
   556    * return nullptr if aCurrentNode has no children.
   557    */
   558   nsIDOMNode* GetLeftmostChild(nsIDOMNode* aCurrentNode,
   559                                bool bNoBlockCrossing = false);
   560   nsIContent* GetLeftmostChild(nsINode *aCurrentNode,
   561                                bool     bNoBlockCrossing = false);
   563   /** returns true if aNode is of the type implied by aTag */
   564   static inline bool NodeIsType(nsIDOMNode *aNode, nsIAtom *aTag)
   565   {
   566     return GetTag(aNode) == aTag;
   567   }
   569   /** returns true if aParent can contain a child of type aTag */
   570   bool CanContain(nsIDOMNode* aParent, nsIDOMNode* aChild);
   571   bool CanContainTag(nsIDOMNode* aParent, nsIAtom* aTag);
   572   bool TagCanContain(nsIAtom* aParentTag, nsIDOMNode* aChild);
   573   virtual bool TagCanContainTag(nsIAtom* aParentTag, nsIAtom* aChildTag);
   575   /** returns true if aNode is our root node */
   576   bool IsRoot(nsIDOMNode* inNode);
   577   bool IsRoot(nsINode* inNode);
   578   bool IsEditorRoot(nsINode* aNode);
   580   /** returns true if aNode is a descendant of our root node */
   581   bool IsDescendantOfRoot(nsIDOMNode* inNode);
   582   bool IsDescendantOfRoot(nsINode* inNode);
   583   bool IsDescendantOfEditorRoot(nsIDOMNode* aNode);
   584   bool IsDescendantOfEditorRoot(nsINode* aNode);
   586   /** returns true if aNode is a container */
   587   virtual bool IsContainer(nsIDOMNode *aNode);
   589   /** returns true if aNode is an editable node */
   590   bool IsEditable(nsIDOMNode *aNode);
   591   virtual bool IsEditable(nsIContent *aNode);
   593   /** returns true if aNode is a MozEditorBogus node */
   594   bool IsMozEditorBogusNode(nsIContent *aNode);
   596   /** counts number of editable child nodes */
   597   uint32_t CountEditableChildren(nsINode* aNode);
   599   /** Find the deep first and last children. */
   600   nsINode* GetFirstEditableNode(nsINode* aRoot);
   602   /**
   603    * Returns current composition.
   604    */
   605   mozilla::TextComposition* GetComposition() const;
   606   /**
   607    * Returns true if there is composition string and not fixed.
   608    */
   609   bool IsIMEComposing() const;
   611   /** from html rules code - migration in progress */
   612   static nsresult GetTagString(nsIDOMNode *aNode, nsAString& outString);
   613   static nsIAtom *GetTag(nsIDOMNode *aNode);
   615   bool NodesSameType(nsIDOMNode *aNode1, nsIDOMNode *aNode2);
   616   virtual bool AreNodesSameType(nsIContent* aNode1, nsIContent* aNode2);
   618   static bool IsTextNode(nsIDOMNode *aNode);
   619   static bool IsTextNode(nsINode *aNode);
   621   static nsCOMPtr<nsIDOMNode> GetChildAt(nsIDOMNode *aParent, int32_t aOffset);
   622   static nsCOMPtr<nsIDOMNode> GetNodeAtRangeOffsetPoint(nsIDOMNode* aParentOrNode, int32_t aOffset);
   624   static nsresult GetStartNodeAndOffset(nsISelection *aSelection, nsIDOMNode **outStartNode, int32_t *outStartOffset);
   625   static nsresult GetStartNodeAndOffset(mozilla::dom::Selection* aSelection,
   626                                         nsINode** aStartNode,
   627                                         int32_t* aStartOffset);
   628   static nsresult GetEndNodeAndOffset(nsISelection *aSelection, nsIDOMNode **outEndNode, int32_t *outEndOffset);
   629   static nsresult GetEndNodeAndOffset(mozilla::dom::Selection* aSelection,
   630                                       nsINode** aEndNode,
   631                                       int32_t* aEndOffset);
   632 #if DEBUG_JOE
   633   static void DumpNode(nsIDOMNode *aNode, int32_t indent=0);
   634 #endif
   635   mozilla::dom::Selection* GetSelection();
   637   // Helpers to add a node to the selection. 
   638   // Used by table cell selection methods
   639   nsresult CreateRange(nsIDOMNode *aStartParent, int32_t aStartOffset,
   640                        nsIDOMNode *aEndParent, int32_t aEndOffset,
   641                        nsIDOMRange **aRange);
   643   // Creates a range with just the supplied node and appends that to the selection
   644   nsresult AppendNodeToSelectionAsRange(nsIDOMNode *aNode);
   645   // When you are using AppendNodeToSelectionAsRange, call this first to start a new selection
   646   nsresult ClearSelection();
   648   nsresult IsPreformatted(nsIDOMNode *aNode, bool *aResult);
   650   nsresult SplitNodeDeep(nsIDOMNode *aNode, 
   651                          nsIDOMNode *aSplitPointParent, 
   652                          int32_t aSplitPointOffset,
   653                          int32_t *outOffset,
   654                          bool    aNoEmptyContainers = false,
   655                          nsCOMPtr<nsIDOMNode> *outLeftNode = 0,
   656                          nsCOMPtr<nsIDOMNode> *outRightNode = 0);
   657   nsresult JoinNodeDeep(nsIDOMNode *aLeftNode, nsIDOMNode *aRightNode, nsCOMPtr<nsIDOMNode> *aOutJoinNode, int32_t *outOffset); 
   659   nsresult GetString(const nsAString& name, nsAString& value);
   661   void BeginUpdateViewBatch(void);
   662   virtual nsresult EndUpdateViewBatch(void);
   664   bool GetShouldTxnSetSelection();
   666   virtual nsresult HandleKeyPressEvent(nsIDOMKeyEvent* aKeyEvent);
   668   nsresult HandleInlineSpellCheck(EditAction action,
   669                                     nsISelection *aSelection,
   670                                     nsIDOMNode *previousSelectedNode,
   671                                     int32_t previousSelectedOffset,
   672                                     nsIDOMNode *aStartNode,
   673                                     int32_t aStartOffset,
   674                                     nsIDOMNode *aEndNode,
   675                                     int32_t aEndOffset);
   677   virtual already_AddRefed<mozilla::dom::EventTarget> GetDOMEventTarget() = 0;
   679   // Fast non-refcounting editor root element accessor
   680   mozilla::dom::Element *GetRoot();
   682   // Likewise, but gets the editor's root instead, which is different for HTML
   683   // editors
   684   virtual mozilla::dom::Element* GetEditorRoot();
   686   // Likewise, but gets the text control element instead of the root for
   687   // plaintext editors
   688   mozilla::dom::Element* GetExposedRoot();
   690   // Accessor methods to flags
   691   bool IsPlaintextEditor() const
   692   {
   693     return (mFlags & nsIPlaintextEditor::eEditorPlaintextMask) != 0;
   694   }
   696   bool IsSingleLineEditor() const
   697   {
   698     return (mFlags & nsIPlaintextEditor::eEditorSingleLineMask) != 0;
   699   }
   701   bool IsPasswordEditor() const
   702   {
   703     return (mFlags & nsIPlaintextEditor::eEditorPasswordMask) != 0;
   704   }
   706   bool IsReadonly() const
   707   {
   708     return (mFlags & nsIPlaintextEditor::eEditorReadonlyMask) != 0;
   709   }
   711   bool IsDisabled() const
   712   {
   713     return (mFlags & nsIPlaintextEditor::eEditorDisabledMask) != 0;
   714   }
   716   bool IsInputFiltered() const
   717   {
   718     return (mFlags & nsIPlaintextEditor::eEditorFilterInputMask) != 0;
   719   }
   721   bool IsMailEditor() const
   722   {
   723     return (mFlags & nsIPlaintextEditor::eEditorMailMask) != 0;
   724   }
   726   bool IsWrapHackEnabled() const
   727   {
   728     return (mFlags & nsIPlaintextEditor::eEditorEnableWrapHackMask) != 0;
   729   }
   731   bool IsFormWidget() const
   732   {
   733     return (mFlags & nsIPlaintextEditor::eEditorWidgetMask) != 0;
   734   }
   736   bool NoCSS() const
   737   {
   738     return (mFlags & nsIPlaintextEditor::eEditorNoCSSMask) != 0;
   739   }
   741   bool IsInteractionAllowed() const
   742   {
   743     return (mFlags & nsIPlaintextEditor::eEditorAllowInteraction) != 0;
   744   }
   746   bool DontEchoPassword() const
   747   {
   748     return (mFlags & nsIPlaintextEditor::eEditorDontEchoPassword) != 0;
   749   }
   751   bool ShouldSkipSpellCheck() const
   752   {
   753     return (mFlags & nsIPlaintextEditor::eEditorSkipSpellCheck) != 0;
   754   }
   756   bool IsTabbable() const
   757   {
   758     return IsSingleLineEditor() || IsPasswordEditor() || IsFormWidget() ||
   759            IsInteractionAllowed();
   760   }
   762   bool HasIndependentSelection() const
   763   {
   764     return !!mSelConWeak;
   765   }
   767   // Get the input event target. This might return null.
   768   virtual already_AddRefed<nsIContent> GetInputEventTargetContent() = 0;
   770   // Get the focused content, if we're focused.  Returns null otherwise.
   771   virtual already_AddRefed<nsIContent> GetFocusedContent();
   773   // Get the focused content for the argument of some IMEStateManager's
   774   // methods.
   775   virtual already_AddRefed<nsIContent> GetFocusedContentForIME();
   777   // Whether the editor is active on the DOM window.  Note that when this
   778   // returns true but GetFocusedContent() returns null, it means that this editor was
   779   // focused when the DOM window was active.
   780   virtual bool IsActiveInDOMWindow();
   782   // Whether the aEvent should be handled by this editor or not.  When this
   783   // returns FALSE, The aEvent shouldn't be handled on this editor,
   784   // i.e., The aEvent should be handled by another inner editor or ancestor
   785   // elements.
   786   virtual bool IsAcceptableInputEvent(nsIDOMEvent* aEvent);
   788   // FindSelectionRoot() returns a selection root of this editor when aNode
   789   // gets focus.  aNode must be a content node or a document node.  When the
   790   // target isn't a part of this editor, returns nullptr.  If this is for
   791   // designMode, you should set the document node to aNode except that an
   792   // element in the document has focus.
   793   virtual already_AddRefed<nsIContent> FindSelectionRoot(nsINode* aNode);
   795   // Initializes selection and caret for the editor.  If aEventTarget isn't
   796   // a host of the editor, i.e., the editor doesn't get focus, this does
   797   // nothing.
   798   nsresult InitializeSelection(nsIDOMEventTarget* aFocusEventTarget);
   800   // Finalizes selection and caret for the editor.
   801   void FinalizeSelection();
   803   // This method has to be called by nsEditorEventListener::Focus.
   804   // All actions that have to be done when the editor is focused needs to be
   805   // added here.
   806   void OnFocus(nsIDOMEventTarget* aFocusEventTarget);
   808   // Used to insert content from a data transfer into the editable area.
   809   // This is called for each item in the data transfer, with the index of
   810   // each item passed as aIndex.
   811   virtual nsresult InsertFromDataTransfer(mozilla::dom::DataTransfer *aDataTransfer,
   812                                           int32_t aIndex,
   813                                           nsIDOMDocument *aSourceDoc,
   814                                           nsIDOMNode *aDestinationNode,
   815                                           int32_t aDestOffset,
   816                                           bool aDoDeleteSelection) = 0;
   818   virtual nsresult InsertFromDrop(nsIDOMEvent* aDropEvent) = 0;
   820   virtual already_AddRefed<nsIDOMNode> FindUserSelectAllNode(nsIDOMNode* aNode) { return nullptr; }
   822 protected:
   823   enum Tristate {
   824     eTriUnset,
   825     eTriFalse,
   826     eTriTrue
   827   };
   828   // Spellchecking
   829   nsCString mContentMIMEType;       // MIME type of the doc we are editing.
   831   nsCOMPtr<nsIInlineSpellChecker> mInlineSpellChecker;
   833   nsRefPtr<nsTransactionManager> mTxnMgr;
   834   nsCOMPtr<mozilla::dom::Element> mRootElement; // cached root node
   835   nsCOMPtr<nsIDOMCharacterData>     mIMETextNode;      // current IME text node
   836   nsCOMPtr<mozilla::dom::EventTarget> mEventTarget; // The form field as an event receiver
   837   nsCOMPtr<nsIDOMEventListener> mEventListener;
   838   nsWeakPtr        mSelConWeak;          // weak reference to the nsISelectionController
   839   nsWeakPtr        mPlaceHolderTxn;      // weak reference to placeholder for begin/end batch purposes
   840   nsWeakPtr        mDocWeak;             // weak reference to the nsIDOMDocument
   841   nsIAtom          *mPlaceHolderName;    // name of placeholder transaction
   842   nsSelectionState *mSelState;           // saved selection state for placeholder txn batching
   843   nsString         *mPhonetic;
   844   // IME composition this is not null between compositionstart and
   845   // compositionend.
   846   nsRefPtr<mozilla::TextComposition> mComposition;
   848   // various listeners
   849   nsCOMArray<nsIEditActionListener> mActionListeners;  // listens to all low level actions on the doc
   850   nsCOMArray<nsIEditorObserver> mEditorObservers;  // just notify once per high level change
   851   nsCOMArray<nsIDocumentStateListener> mDocStateListeners;// listen to overall doc state (dirty or not, just created, etc)
   853   nsSelectionState  mSavedSel;           // cached selection for nsAutoSelectionReset
   854   nsRangeUpdater    mRangeUpdater;       // utility class object for maintaining preserved ranges
   856   uint32_t          mModCount;     // number of modifications (for undo/redo stack)
   857   uint32_t          mFlags;        // behavior flags. See nsIPlaintextEditor.idl for the flags we use.
   859   int32_t           mUpdateCount;
   861   int32_t           mPlaceHolderBatch;   // nesting count for batching
   862   EditAction        mAction;             // the current editor action
   864   uint32_t          mIMETextOffset;    // offset in text node where IME comp string begins
   866   EDirection        mDirection;          // the current direction of editor action
   867   int8_t            mDocDirtyState;      // -1 = not initialized
   868   uint8_t           mSpellcheckCheckboxState; // a Tristate value
   870   bool mShouldTxnSetSelection;  // turn off for conservative selection adjustment by txns
   871   bool mDidPreDestroy;    // whether PreDestroy has been called
   872   bool mDidPostCreate;    // whether PostCreate has been called
   873   bool mDispatchInputEvent;
   875   friend bool NSCanUnload(nsISupports* serviceMgr);
   876   friend class nsAutoTxnsConserveSelection;
   877   friend class nsAutoSelectionReset;
   878   friend class nsAutoRules;
   879   friend class nsRangeUpdater;
   880 };
   883 #endif

mercurial