editor/libeditor/text/nsTextEditRules.h

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/editor/libeditor/text/nsTextEditRules.h	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,336 @@
     1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public
     1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this
     1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     1.8 +
     1.9 +#ifndef nsTextEditRules_h__
    1.10 +#define nsTextEditRules_h__
    1.11 +
    1.12 +#include "nsCOMPtr.h"
    1.13 +#include "nsCycleCollectionParticipant.h"
    1.14 +#include "nsEditRules.h"
    1.15 +#include "nsEditor.h"
    1.16 +#include "nsIEditor.h"
    1.17 +#include "nsISupportsImpl.h"
    1.18 +#include "nsITimer.h"
    1.19 +#include "nsPlaintextEditor.h"
    1.20 +#include "nsString.h"
    1.21 +#include "nscore.h"
    1.22 +
    1.23 +class nsIDOMElement;
    1.24 +class nsIDOMNode;
    1.25 +class nsISelection;
    1.26 +namespace mozilla {
    1.27 +namespace dom {
    1.28 +class Selection;
    1.29 +}  // namespace dom
    1.30 +}  // namespace mozilla
    1.31 +
    1.32 +/** Object that encapsulates HTML text-specific editing rules.
    1.33 +  *  
    1.34 +  * To be a good citizen, edit rules must live by these restrictions:
    1.35 +  * 1. All data manipulation is through the editor.  
    1.36 +  *    Content nodes in the document tree must <B>not</B> be manipulated directly.
    1.37 +  *    Content nodes in document fragments that are not part of the document itself
    1.38 +  *    may be manipulated at will.  Operations on document fragments must <B>not</B>
    1.39 +  *    go through the editor.
    1.40 +  * 2. Selection must not be explicitly set by the rule method.  
    1.41 +  *    Any manipulation of Selection must be done by the editor.
    1.42 +  */
    1.43 +class nsTextEditRules : public nsIEditRules, public nsITimerCallback
    1.44 +{
    1.45 +public:
    1.46 +  NS_DECL_NSITIMERCALLBACK
    1.47 +  NS_DECL_CYCLE_COLLECTING_ISUPPORTS
    1.48 +  NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsTextEditRules, nsIEditRules)
    1.49 +  
    1.50 +              nsTextEditRules();
    1.51 +  virtual     ~nsTextEditRules();
    1.52 +
    1.53 +  // nsIEditRules methods
    1.54 +  NS_IMETHOD Init(nsPlaintextEditor *aEditor);
    1.55 +  NS_IMETHOD SetInitialValue(const nsAString& aValue);
    1.56 +  NS_IMETHOD DetachEditor();
    1.57 +  NS_IMETHOD BeforeEdit(EditAction action,
    1.58 +                        nsIEditor::EDirection aDirection);
    1.59 +  NS_IMETHOD AfterEdit(EditAction action,
    1.60 +                       nsIEditor::EDirection aDirection);
    1.61 +  NS_IMETHOD WillDoAction(mozilla::dom::Selection* aSelection,
    1.62 +                          nsRulesInfo* aInfo, bool* aCancel, bool* aHandled);
    1.63 +  NS_IMETHOD DidDoAction(nsISelection *aSelection, nsRulesInfo *aInfo, nsresult aResult);
    1.64 +  NS_IMETHOD DocumentIsEmpty(bool *aDocumentIsEmpty);
    1.65 +  NS_IMETHOD DocumentModified();
    1.66 +
    1.67 +public:
    1.68 +  void ResetIMETextPWBuf();
    1.69 +
    1.70 +  /**
    1.71 +   * Handles the newline characters either according to aNewLineHandling
    1.72 +   * or to the default system prefs if aNewLineHandling is negative.
    1.73 +   *
    1.74 +   * @param aString the string to be modified in place.
    1.75 +   * @param aNewLineHandling determine the desired type of newline handling:
    1.76 +   *        * negative values:
    1.77 +   *          handle newlines according to platform defaults.
    1.78 +   *        * nsIPlaintextEditor::eNewlinesReplaceWithSpaces:
    1.79 +   *          replace newlines with spaces.
    1.80 +   *        * nsIPlaintextEditor::eNewlinesStrip:
    1.81 +   *          remove newlines from the string.
    1.82 +   *        * nsIPlaintextEditor::eNewlinesReplaceWithCommas:
    1.83 +   *          replace newlines with commas.
    1.84 +   *        * nsIPlaintextEditor::eNewlinesStripSurroundingWhitespace:
    1.85 +   *          collapse newlines and surrounding whitespace characters and
    1.86 +   *          remove them from the string.
    1.87 +   *        * nsIPlaintextEditor::eNewlinesPasteIntact:
    1.88 +   *          only remove the leading and trailing newlines.
    1.89 +   *        * nsIPlaintextEditor::eNewlinesPasteToFirst or any other value:
    1.90 +   *          remove the first newline and all characters following it.
    1.91 +   */
    1.92 +  static void HandleNewLines(nsString &aString, int32_t aNewLineHandling);
    1.93 +
    1.94 +  /**
    1.95 +   * Prepare a string buffer for being displayed as the contents of a password
    1.96 +   * field.  This function uses the platform-specific character for representing
    1.97 +   * characters entered into password fields.
    1.98 +   *
    1.99 +   * @param aOutString the output string.  When this function returns,
   1.100 +   *        aOutString will contain aLength password characters.
   1.101 +   * @param aLength the number of password characters that aOutString should
   1.102 +   *        contain.
   1.103 +   */
   1.104 +  static void FillBufWithPWChars(nsAString *aOutString, int32_t aLength);
   1.105 +
   1.106 +protected:
   1.107 +
   1.108 +  void InitFields();
   1.109 +
   1.110 +  // nsTextEditRules implementation methods
   1.111 +  nsresult WillInsertText(  EditAction aAction,
   1.112 +                            mozilla::dom::Selection* aSelection,
   1.113 +                            bool            *aCancel,
   1.114 +                            bool            *aHandled,
   1.115 +                            const nsAString *inString,
   1.116 +                            nsAString       *outString,
   1.117 +                            int32_t          aMaxLength);
   1.118 +  nsresult DidInsertText(nsISelection *aSelection, nsresult aResult);
   1.119 +  nsresult GetTopEnclosingPre(nsIDOMNode *aNode, nsIDOMNode** aOutPreNode);
   1.120 +
   1.121 +  nsresult WillInsertBreak(mozilla::dom::Selection* aSelection, bool* aCancel,
   1.122 +                           bool *aHandled, int32_t aMaxLength);
   1.123 +  nsresult DidInsertBreak(nsISelection *aSelection, nsresult aResult);
   1.124 +
   1.125 +  nsresult WillInsert(nsISelection *aSelection, bool *aCancel);
   1.126 +  nsresult DidInsert(nsISelection *aSelection, nsresult aResult);
   1.127 +
   1.128 +  nsresult WillDeleteSelection(mozilla::dom::Selection* aSelection,
   1.129 +                               nsIEditor::EDirection aCollapsedAction, 
   1.130 +                               bool *aCancel,
   1.131 +                               bool *aHandled);
   1.132 +  nsresult DidDeleteSelection(nsISelection *aSelection, 
   1.133 +                              nsIEditor::EDirection aCollapsedAction, 
   1.134 +                              nsresult aResult);
   1.135 +
   1.136 +  nsresult WillSetTextProperty(nsISelection *aSelection, bool *aCancel, bool *aHandled);
   1.137 +  nsresult DidSetTextProperty(nsISelection *aSelection, nsresult aResult);
   1.138 +
   1.139 +  nsresult WillRemoveTextProperty(nsISelection *aSelection, bool *aCancel, bool *aHandled);
   1.140 +  nsresult DidRemoveTextProperty(nsISelection *aSelection, nsresult aResult);
   1.141 +
   1.142 +  nsresult WillUndo(nsISelection *aSelection, bool *aCancel, bool *aHandled);
   1.143 +  nsresult DidUndo(nsISelection *aSelection, nsresult aResult);
   1.144 +
   1.145 +  nsresult WillRedo(nsISelection *aSelection, bool *aCancel, bool *aHandled);
   1.146 +  nsresult DidRedo(nsISelection *aSelection, nsresult aResult);
   1.147 +
   1.148 +  /** called prior to nsIEditor::OutputToString
   1.149 +    * @param aSelection
   1.150 +    * @param aInFormat  the format requested for the output, a MIME type
   1.151 +    * @param aOutText   the string to use for output, if aCancel is set to true
   1.152 +    * @param aOutCancel if set to true, the caller should cancel the operation
   1.153 +    *                   and use aOutText as the result.
   1.154 +    */
   1.155 +  nsresult WillOutputText(nsISelection *aSelection,
   1.156 +                          const nsAString  *aInFormat,
   1.157 +                          nsAString *aOutText, 
   1.158 +                          bool     *aOutCancel, 
   1.159 +                          bool *aHandled);
   1.160 +
   1.161 +  nsresult DidOutputText(nsISelection *aSelection, nsresult aResult);
   1.162 +
   1.163 +
   1.164 +  // helper functions
   1.165 +
   1.166 +  /** check for and replace a redundant trailing break */
   1.167 +  nsresult RemoveRedundantTrailingBR();
   1.168 +  
   1.169 +  /** creates a trailing break in the text doc if there is not one already */
   1.170 +  nsresult CreateTrailingBRIfNeeded();
   1.171 +  
   1.172 + /** creates a bogus text node if the document has no editable content */
   1.173 +  nsresult CreateBogusNodeIfNeeded(nsISelection *aSelection);
   1.174 +
   1.175 +  /** returns a truncated insertion string if insertion would place us
   1.176 +      over aMaxLength */
   1.177 +  nsresult TruncateInsertionIfNeeded(mozilla::dom::Selection*  aSelection,
   1.178 +                                     const nsAString          *aInString,
   1.179 +                                     nsAString                *aOutString,
   1.180 +                                     int32_t                   aMaxLength,
   1.181 +                                     bool                     *aTruncated);
   1.182 +
   1.183 +  /** Remove IME composition text from password buffer */
   1.184 +  void RemoveIMETextFromPWBuf(int32_t &aStart, nsAString *aIMEString);
   1.185 +
   1.186 +  nsresult CreateMozBR(nsIDOMNode* inParent, int32_t inOffset,
   1.187 +                       nsIDOMNode** outBRNode = nullptr);
   1.188 +
   1.189 +  nsresult CheckBidiLevelForDeletion(nsISelection         *aSelection,
   1.190 +                                     nsIDOMNode           *aSelNode, 
   1.191 +                                     int32_t               aSelOffset, 
   1.192 +                                     nsIEditor::EDirection aAction,
   1.193 +                                     bool                 *aCancel);
   1.194 +
   1.195 +  nsresult HideLastPWInput();
   1.196 +
   1.197 +  nsresult CollapseSelectionToTrailingBRIfNeeded(nsISelection *aSelection);
   1.198 +
   1.199 +  bool IsPasswordEditor() const
   1.200 +  {
   1.201 +    return mEditor ? mEditor->IsPasswordEditor() : false;
   1.202 +  }
   1.203 +  bool IsSingleLineEditor() const
   1.204 +  {
   1.205 +    return mEditor ? mEditor->IsSingleLineEditor() : false;
   1.206 +  }
   1.207 +  bool IsPlaintextEditor() const
   1.208 +  {
   1.209 +    return mEditor ? mEditor->IsPlaintextEditor() : false;
   1.210 +  }
   1.211 +  bool IsReadonly() const
   1.212 +  {
   1.213 +    return mEditor ? mEditor->IsReadonly() : false;
   1.214 +  }
   1.215 +  bool IsDisabled() const
   1.216 +  {
   1.217 +    return mEditor ? mEditor->IsDisabled() : false;
   1.218 +  }
   1.219 +  bool IsMailEditor() const
   1.220 +  {
   1.221 +    return mEditor ? mEditor->IsMailEditor() : false;
   1.222 +  }
   1.223 +  bool DontEchoPassword() const
   1.224 +  {
   1.225 +    return mEditor ? mEditor->DontEchoPassword() : false;
   1.226 +  }
   1.227 +
   1.228 +  // data members
   1.229 +  nsPlaintextEditor   *mEditor;        // note that we do not refcount the editor
   1.230 +  nsString             mPasswordText;  // a buffer we use to store the real value of password editors
   1.231 +  nsString             mPasswordIMEText;  // a buffer we use to track the IME composition string
   1.232 +  uint32_t             mPasswordIMEIndex;
   1.233 +  nsCOMPtr<nsIDOMNode> mBogusNode;     // magic node acts as placeholder in empty doc
   1.234 +  nsCOMPtr<nsIDOMNode> mCachedSelectionNode;    // cached selected node
   1.235 +  int32_t              mCachedSelectionOffset;  // cached selected offset
   1.236 +  uint32_t             mActionNesting;
   1.237 +  bool                 mLockRulesSniffing;
   1.238 +  bool                 mDidExplicitlySetInterline;
   1.239 +  bool                 mDeleteBidiImmediately; // in bidirectional text, delete
   1.240 +                                               // characters not visually 
   1.241 +                                               // adjacent to the caret without
   1.242 +                                               // moving the caret first.
   1.243 +  EditAction mTheAction;     // the top level editor action
   1.244 +  nsCOMPtr<nsITimer>   mTimer;
   1.245 +  uint32_t             mLastStart, mLastLength;
   1.246 +
   1.247 +  // friends
   1.248 +  friend class nsAutoLockRulesSniffing;
   1.249 +
   1.250 +};
   1.251 +
   1.252 +
   1.253 +
   1.254 +class nsTextRulesInfo : public nsRulesInfo
   1.255 +{
   1.256 + public:
   1.257 + 
   1.258 +  nsTextRulesInfo(EditAction aAction) :
   1.259 +    nsRulesInfo(aAction),
   1.260 +    inString(0),
   1.261 +    outString(0),
   1.262 +    outputFormat(0),
   1.263 +    maxLength(-1),
   1.264 +    collapsedAction(nsIEditor::eNext),
   1.265 +    stripWrappers(nsIEditor::eStrip),
   1.266 +    bOrdered(false),
   1.267 +    entireList(false),
   1.268 +    bulletType(0),
   1.269 +    alignType(0),
   1.270 +    blockType(0),
   1.271 +    insertElement(0)
   1.272 +    {}
   1.273 +
   1.274 +  virtual ~nsTextRulesInfo() {}
   1.275 +  
   1.276 +  // kInsertText
   1.277 +  const nsAString *inString;
   1.278 +  nsAString *outString;
   1.279 +  const nsAString *outputFormat;
   1.280 +  int32_t maxLength;
   1.281 +  
   1.282 +  // kDeleteSelection
   1.283 +  nsIEditor::EDirection collapsedAction;
   1.284 +  nsIEditor::EStripWrappers stripWrappers;
   1.285 +  
   1.286 +  // kMakeList
   1.287 +  bool bOrdered;
   1.288 +  bool entireList;
   1.289 +  const nsAString *bulletType;
   1.290 +
   1.291 +  // kAlign
   1.292 +  const nsAString *alignType;
   1.293 +  
   1.294 +  // kMakeBasicBlock
   1.295 +  const nsAString *blockType;
   1.296 +  
   1.297 +  // kInsertElement
   1.298 +  const nsIDOMElement* insertElement;
   1.299 +};
   1.300 +
   1.301 +
   1.302 +/***************************************************************************
   1.303 + * stack based helper class for StartOperation()/EndOperation() sandwich.
   1.304 + * this class sets a bool letting us know to ignore any rules sniffing
   1.305 + * that tries to occur reentrantly. 
   1.306 + */
   1.307 +class nsAutoLockRulesSniffing
   1.308 +{
   1.309 +  public:
   1.310 +  
   1.311 +  nsAutoLockRulesSniffing(nsTextEditRules *rules) : mRules(rules) 
   1.312 +                 {if (mRules) mRules->mLockRulesSniffing = true;}
   1.313 +  ~nsAutoLockRulesSniffing() 
   1.314 +                 {if (mRules) mRules->mLockRulesSniffing = false;}
   1.315 +  
   1.316 +  protected:
   1.317 +  nsTextEditRules *mRules;
   1.318 +};
   1.319 +
   1.320 +
   1.321 +
   1.322 +/***************************************************************************
   1.323 + * stack based helper class for turning on/off the edit listener.
   1.324 + */
   1.325 +class nsAutoLockListener
   1.326 +{
   1.327 +  public:
   1.328 +  
   1.329 +  nsAutoLockListener(bool *enabled) : mEnabled(enabled)
   1.330 +                 {if (mEnabled) { mOldState=*mEnabled; *mEnabled = false;}}
   1.331 +  ~nsAutoLockListener() 
   1.332 +                 {if (mEnabled) *mEnabled = mOldState;}
   1.333 +  
   1.334 +  protected:
   1.335 +  bool *mEnabled;
   1.336 +  bool mOldState;
   1.337 +};
   1.338 +
   1.339 +#endif //nsTextEditRules_h__

mercurial