LCOV - code coverage report
Current view: directory - content/html/content/src - nsTextEditorState.h (source / functions) Found Hit Coverage
Test: app.info Lines: 41 4 9.8 %
Date: 2012-06-02 Functions: 22 4 18.2 %

       1                 : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2                 : /* vim: set sw=2 ts=2 et tw=80: */
       3                 : /* ***** BEGIN LICENSE BLOCK *****
       4                 :  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
       5                 :  *
       6                 :  * The contents of this file are subject to the Mozilla Public License Version
       7                 :  * 1.1 (the "License"); you may not use this file except in compliance with
       8                 :  * the License. You may obtain a copy of the License at
       9                 :  * http://www.mozilla.org/MPL/
      10                 :  *
      11                 :  * Software distributed under the License is distributed on an "AS IS" basis,
      12                 :  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
      13                 :  * for the specific language governing rights and limitations under the
      14                 :  * License.
      15                 :  *
      16                 :  * The Original Code is Mozilla.org client code.
      17                 :  *
      18                 :  * The Initial Developer of the Original Code is Mozilla Foundation.
      19                 :  * Portions created by the Initial Developer are Copyright (C) 2009
      20                 :  * the Initial Developer. All Rights Reserved.
      21                 :  *
      22                 :  * Contributor(s):
      23                 :  *   Ehsan Akhgari <ehsan@mozilla.com> (Original Author)
      24                 :  *
      25                 :  * Alternatively, the contents of this file may be used under the terms of
      26                 :  * either of the GNU General Public License Version 2 or later (the "GPL"),
      27                 :  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
      28                 :  * in which case the provisions of the GPL or the LGPL are applicable instead
      29                 :  * of those above. If you wish to allow use of your version of this file only
      30                 :  * under the terms of either the GPL or the LGPL, and not to allow others to
      31                 :  * use your version of this file under the terms of the MPL, indicate your
      32                 :  * decision by deleting the provisions above and replace them with the notice
      33                 :  * and other provisions required by the GPL or the LGPL. If you do not delete
      34                 :  * the provisions above, a recipient may use your version of this file under
      35                 :  * the terms of any one of the MPL, the GPL or the LGPL.
      36                 :  *
      37                 :  * ***** END LICENSE BLOCK ***** */
      38                 : 
      39                 : #ifndef nsTextEditorState_h__
      40                 : #define nsTextEditorState_h__
      41                 : 
      42                 : #include "nsAutoPtr.h"
      43                 : #include "nsString.h"
      44                 : #include "nsITextControlElement.h"
      45                 : #include "nsITextControlFrame.h"
      46                 : #include "nsCycleCollectionParticipant.h"
      47                 : 
      48                 : class nsTextInputListener;
      49                 : class nsTextControlFrame;
      50                 : class nsTextInputSelectionImpl;
      51                 : class nsAnonDivObserver;
      52                 : class nsISelectionController;
      53                 : class nsFrameSelection;
      54                 : class nsIEditor;
      55                 : class nsITextControlElement;
      56                 : 
      57                 : /**
      58                 :  * nsTextEditorState is a class which is responsible for managing the state of
      59                 :  * plaintext controls.  This currently includes the following HTML elements:
      60                 :  *   <input type=text>
      61                 :  *   <input type=password>
      62                 :  *   <textarea>
      63                 :  * and also XUL controls such as <textbox> which use one of these elements behind
      64                 :  * the scenes.
      65                 :  *
      66                 :  * This class is held as a member of nsHTMLInputElement and nsHTMLTextAreaElement.
      67                 :  * The public functions in this class include the public APIs which content/ uses.
      68                 :  * Layout code uses the nsITextControlElement interface to invoke functions on this
      69                 :  * class.
      70                 :  *
      71                 :  * The design motivation behind this class is maintaining all of the things which
      72                 :  * collectively are considered the "state" of the text control in a single location.
      73                 :  * This state includes several things:
      74                 :  *
      75                 :  *  * The control's value.  This value is stored in the mValue member, and is only
      76                 :  *    used when there is no frame for the control, or when the editor object has
      77                 :  *    not been initialized yet.
      78                 :  *
      79                 :  *  * The control's associated frame.  This value is stored in the mBoundFrame member.
      80                 :  *    A text control might never have an associated frame during its life cycle,
      81                 :  *    or might have several different ones, but at any given moment in time there is
      82                 :  *    a maximum of 1 bound frame to each text control.
      83                 :  *
      84                 :  *  * The control's associated editor.  This value is stored in the mEditor member.
      85                 :  *    An editor is initilized for the control only when necessary (that is, when either
      86                 :  *    the user is about to interact with the text control, or when some other code
      87                 :  *    needs to access the editor object.  Without a frame bound to the control, an
      88                 :  *    editor is never initialzied.  Once initialized, the editor might outlive the frame,
      89                 :  *    in which case the same editor will be used if a new frame gets bound to the
      90                 :  *    text control.
      91                 :  *
      92                 :  *  * The anonymous content associated with the text control's frame, including the
      93                 :  *    value div (the DIV element responsible for holding the value of the text control)
      94                 :  *    and the placeholder div (the DIV element responsible for holding the placeholder
      95                 :  *    value of the text control.)  These values are stored in the mRootNode and
      96                 :  *    mPlaceholderDiv members, respectively.  They will be created when a
      97                 :  *    frame is bound to the text control.  They will be destroyed when the frame is
      98                 :  *    unbound from the object.  We could try and hold on to the anonymous content
      99                 :  *    between different frames, but unfortunately that is not currently possible
     100                 :  *    because they are not unbound from the document in time.
     101                 :  *
     102                 :  *  * The frame selection controller.  This value is stored in the mSelCon member.
     103                 :  *    The frame selection controller is responsible for maintaining the selection state
     104                 :  *    on a frame.  It is created when a frame is bound to the text control element,
     105                 :  *    and will be destroy when the frame is being unbound from the text control element.
     106                 :  *    It is created alongside with the frame selection object which is stored in the
     107                 :  *    mFrameSel member.
     108                 :  *
     109                 :  *  * The editor text listener.  This value is stored in the mTextListener member.
     110                 :  *    Its job is to listen to selection and keyboard events, and act accordingly.
     111                 :  *    It is created when an a frame is first bound to the control, and will be destroyed
     112                 :  *    when the frame is unbound from the text control element.
     113                 :  *
     114                 :  *  * The editor's cached value.  This value is stored in the mCachedValue member.
     115                 :  *    It is used to improve the performance of append operations to the text
     116                 :  *    control.  A mutation observer stored in the mMutationObserver has the job of
     117                 :  *    invalidating this cache when the anonymous contect containing the value is
     118                 :  *    changed.
     119                 :  *
     120                 :  *  * The editor's cached selection properties.  These vales are stored in the
     121                 :  *    mSelectionProperties member, and include the selection's start, end and
     122                 :  *    direction. They are only used when there is no frame available for the
     123                 :  *    text field.
     124                 :  *
     125                 :  *
     126                 :  * As a general rule, nsTextEditorState objects own the value of the text control, and any
     127                 :  * attempt to retrieve or set the value must be made through those objects.  Internally,
     128                 :  * the value can be represented in several different ways, based on the state the control is
     129                 :  * in.
     130                 :  *
     131                 :  *   * When the control is first initialized, its value is equal to the default value of
     132                 :  *     the DOM node.  For <input> text controls, this default value is the value of the
     133                 :  *     value attribute.  For <textarea> elements, this default value is the value of the
     134                 :  *     text node children of the element.
     135                 :  *
     136                 :  *   * If the value has been changed through the DOM node (before the editor for the object
     137                 :  *     is initialized), the value is stored as a simple string inside the mValue member of
     138                 :  *     the nsTextEditorState object.
     139                 :  *
     140                 :  *   * If an editor has been initialized for the control, the value is set and retrievd via
     141                 :  *     the nsIPlaintextEditor interface, and is internally managed by the editor as the
     142                 :  *     native anonymous content tree attached to the control's frame.
     143                 :  *
     144                 :  *   * If the text editor state object is unbound from the control's frame, the value is
     145                 :  *     transferred to the mValue member variable, and will be managed there until a new
     146                 :  *     frame is bound to the text editor state object.
     147                 :  */
     148                 : 
     149                 : class RestoreSelectionState;
     150                 : 
     151                 : class nsTextEditorState {
     152                 : public:
     153                 :   explicit nsTextEditorState(nsITextControlElement* aOwningElement);
     154                 :   ~nsTextEditorState();
     155                 : 
     156            1464 :   NS_DECL_CYCLE_COLLECTION_NATIVE_CLASS(nsTextEditorState)
     157               5 :   NS_INLINE_DECL_REFCOUNTING(nsTextEditorState)
     158                 : 
     159                 :   nsIEditor* GetEditor();
     160                 :   nsISelectionController* GetSelectionController() const;
     161                 :   nsFrameSelection* GetConstFrameSelection();
     162                 :   nsresult BindToFrame(nsTextControlFrame* aFrame);
     163                 :   void UnbindFromFrame(nsTextControlFrame* aFrame);
     164                 :   nsresult PrepareEditor(const nsAString *aValue = nsnull);
     165                 :   void InitializeKeyboardEventListeners();
     166                 : 
     167                 :   void SetValue(const nsAString& aValue, bool aUserInput);
     168                 :   void GetValue(nsAString& aValue, bool aIgnoreWrap) const;
     169               0 :   void EmptyValue() { if (mValue) mValue->Truncate(); }
     170               0 :   bool IsEmpty() const { return mValue ? mValue->IsEmpty() : true; }
     171                 : 
     172                 :   nsresult CreatePlaceholderNode();
     173                 : 
     174               0 :   nsIContent* GetRootNode() {
     175               0 :     if (!mRootNode)
     176               0 :       CreateRootNode();
     177               0 :     return mRootNode;
     178                 :   }
     179               0 :   nsIContent* GetPlaceholderNode() {
     180               0 :     return mPlaceholderDiv;
     181                 :   }
     182                 : 
     183               0 :   bool IsSingleLineTextControl() const {
     184               0 :     return mTextCtrlElement->IsSingleLineTextControl();
     185                 :   }
     186                 :   bool IsTextArea() const {
     187                 :     return mTextCtrlElement->IsTextArea();
     188                 :   }
     189               0 :   bool IsPlainTextControl() const {
     190               0 :     return mTextCtrlElement->IsPlainTextControl();
     191                 :   }
     192               0 :   bool IsPasswordTextControl() const {
     193               0 :     return mTextCtrlElement->IsPasswordTextControl();
     194                 :   }
     195                 :   PRInt32 GetCols() {
     196                 :     return mTextCtrlElement->GetCols();
     197                 :   }
     198               0 :   PRInt32 GetWrapCols() {
     199               0 :     return mTextCtrlElement->GetWrapCols();
     200                 :   }
     201                 :   PRInt32 GetRows() {
     202                 :     return mTextCtrlElement->GetRows();
     203                 :   }
     204                 : 
     205                 :   // placeholder methods
     206                 :   void SetPlaceholderClass(bool aVisible, bool aNotify);
     207                 :   void UpdatePlaceholderText(bool aNotify); 
     208                 : 
     209                 :   /**
     210                 :    * Get the maxlength attribute
     211                 :    * @param aMaxLength the value of the max length attr
     212                 :    * @returns false if attr not defined
     213                 :    */
     214                 :   bool GetMaxLength(PRInt32* aMaxLength);
     215                 : 
     216                 :   /* called to free up native keybinding services */
     217                 :   static NS_HIDDEN_(void) ShutDown();
     218                 : 
     219               0 :   void ClearValueCache() { mCachedValue.Truncate(); }
     220                 : 
     221                 :   void HideSelectionIfBlurred();
     222                 : 
     223                 :   struct SelectionProperties {
     224               1 :     SelectionProperties() : mStart(0), mEnd(0),
     225               1 :       mDirection(nsITextControlFrame::eForward) {}
     226               0 :     bool IsDefault() const {
     227                 :       return mStart == 0 && mEnd == 0 &&
     228               0 :              mDirection == nsITextControlFrame::eForward;
     229                 :     }
     230                 :     PRInt32 mStart, mEnd;
     231                 :     nsITextControlFrame::SelectionDirection mDirection;
     232                 :   };
     233                 : 
     234               0 :   bool IsSelectionCached() const { return mSelectionCached; }
     235               0 :   SelectionProperties& GetSelectionProperties() {
     236               0 :     return mSelectionProperties;
     237                 :   }
     238               0 :   void WillInitEagerly() { mSelectionRestoreEagerInit = true; }
     239               0 :   bool HasNeverInitializedBefore() const { return !mEverInited; }
     240                 : 
     241                 : private:
     242                 :   friend class RestoreSelectionState;
     243                 : 
     244                 :   // not copy constructible
     245                 :   nsTextEditorState(const nsTextEditorState&);
     246                 :   // not assignable
     247                 :   void operator= (const nsTextEditorState&);
     248                 : 
     249                 :   nsresult CreateRootNode();
     250                 : 
     251                 :   void ValueWasChanged(bool aNotify);
     252                 : 
     253                 :   void DestroyEditor();
     254                 :   void Clear();
     255                 : 
     256                 :   nsresult InitializeRootNode();
     257                 : 
     258               0 :   void FinishedRestoringSelection() { mRestoringSelection = nsnull; }
     259                 : 
     260                 :   class InitializationGuard {
     261                 :   public:
     262               0 :     explicit InitializationGuard(nsTextEditorState& aState) :
     263                 :       mState(aState),
     264               0 :       mGuardSet(false)
     265                 :     {
     266               0 :       if (!mState.mInitializing) {
     267               0 :         mGuardSet = true;
     268               0 :         mState.mInitializing = true;
     269                 :       }
     270               0 :     }
     271               0 :     ~InitializationGuard() {
     272               0 :       if (mGuardSet) {
     273               0 :         mState.mInitializing = false;
     274                 :       }
     275               0 :     }
     276               0 :     bool IsInitializingRecursively() const {
     277               0 :       return !mGuardSet;
     278                 :     }
     279                 :   private:
     280                 :     nsTextEditorState& mState;
     281                 :     bool mGuardSet;
     282                 :   };
     283                 :   friend class InitializationGuard;
     284                 :   friend class PrepareEditorEvent;
     285                 : 
     286                 :   nsITextControlElement* const mTextCtrlElement;
     287                 :   nsRefPtr<nsTextInputSelectionImpl> mSelCon;
     288                 :   RestoreSelectionState* mRestoringSelection;
     289                 :   nsCOMPtr<nsIEditor> mEditor;
     290                 :   nsCOMPtr<nsIContent> mRootNode;
     291                 :   nsCOMPtr<nsIContent> mPlaceholderDiv;
     292                 :   nsTextControlFrame* mBoundFrame;
     293                 :   nsTextInputListener* mTextListener;
     294                 :   nsAutoPtr<nsCString> mValue;
     295                 :   nsRefPtr<nsAnonDivObserver> mMutationObserver;
     296                 :   mutable nsString mCachedValue; // Caches non-hard-wrapped value on a multiline control.
     297                 :   bool mEverInited; // Have we ever been initialized?
     298                 :   bool mEditorInitialized;
     299                 :   bool mInitializing; // Whether we're in the process of initialization
     300                 :   bool mValueTransferInProgress; // Whether a value is being transferred to the frame
     301                 :   bool mSelectionCached; // Whether mSelectionProperties is valid
     302                 :   mutable bool mSelectionRestoreEagerInit; // Whether we're eager initing because of selection restore
     303                 :   SelectionProperties mSelectionProperties;
     304                 : };
     305                 : 
     306                 : #endif

Generated by: LCOV version 1.7