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