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__