1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
9 #include "mozilla/Assertions.h" // for MOZ_ASSERT, etc.
10 #include "mozilla/TypedEnum.h" // for MOZ_BEGIN_ENUM_CLASS, etc.
11 #include "mozilla/dom/Text.h"
12 #include "nsAutoPtr.h" // for nsRefPtr
13 #include "nsCOMArray.h" // for nsCOMArray
14 #include "nsCOMPtr.h" // for already_AddRefed, nsCOMPtr
15 #include "nsCycleCollectionParticipant.h"
16 #include "nsGkAtoms.h"
17 #include "nsIEditor.h" // for nsIEditor::EDirection, etc
18 #include "nsIEditorIMESupport.h" // for NS_DECL_NSIEDITORIMESUPPORT, etc
19 #include "nsIObserver.h" // for NS_DECL_NSIOBSERVER, etc
20 #include "nsIPhonetic.h" // for NS_DECL_NSIPHONETIC, etc
21 #include "nsIPlaintextEditor.h" // for nsIPlaintextEditor, etc
22 #include "nsISupportsImpl.h" // for nsEditor::Release, etc
23 #include "nsIWeakReferenceUtils.h" // for nsWeakPtr
24 #include "nsLiteralString.h" // for NS_LITERAL_STRING
25 #include "nsSelectionState.h" // for nsRangeUpdater, etc
26 #include "nsString.h" // for nsCString
27 #include "nsWeakReference.h" // for nsSupportsWeakReference
28 #include "nscore.h" // for nsresult, nsAString, etc
30 class AddStyleSheetTxn
;
32 class EditAggregateTxn
;
34 class RemoveStyleSheetTxn
;
35 class SplitElementTxn
;
38 class nsIDOMCharacterData
;
39 class nsIDOMDataTransfer
;
43 class nsIDOMEventListener
;
44 class nsIDOMEventTarget
;
49 class nsIDocumentStateListener
;
50 class nsIEditActionListener
;
51 class nsIEditorObserver
;
52 class nsIInlineSpellChecker
;
61 class nsTransactionManager
;
66 class TextComposition
;
69 class ChangeAttributeTxn
;
70 class CreateElementTxn
;
81 } // namespace mozilla
87 } // namespace mozilla
89 #define kMOZEditorBogusNodeAttrAtom nsGkAtoms::mozeditorbogusnode
90 #define kMOZEditorBogusNodeValue NS_LITERAL_STRING("TRUE")
92 // This is int32_t instead of int16_t because nsIInlineSpellChecker.idl's
93 // spellCheckAfterEditorChange is defined to take it as a long.
94 MOZ_BEGIN_ENUM_CLASS(EditAction
, int32_t)
108 insertIMEText
= 2001,
109 deleteSelection
= 2002,
110 setTextProperty
= 2003,
111 removeTextProperty
= 2004,
120 makeBasicBlock
= 3005,
122 makeDefListItem
= 3007,
123 insertElement
= 3008,
124 insertQuotation
= 3009,
127 resetTextProperties
= 3014,
128 setAbsolutePosition
= 3015,
129 removeAbsolutePosition
= 3016,
130 decreaseZIndex
= 3017,
131 increaseZIndex
= 3018
132 MOZ_END_ENUM_CLASS(EditAction
)
134 inline bool operator!(const EditAction
& aOp
)
136 return aOp
== EditAction::none
;
139 /** implementation of an editor object. it will be the controller/focal point
140 * for the main editor services. i.e. the GUIManager, publishing, transaction
141 * manager, event interfaces. the idea for the event interfaces is to have them
142 * delegate the actual commands to the editor independent of the XPFE implementation.
144 class nsEditor
: public nsIEditor
,
145 public nsIEditorIMESupport
,
146 public nsSupportsWeakReference
,
158 /** The default constructor. This should suffice. the setting of the interfaces is done
159 * after the construction of the editor class.
164 /** The default destructor. This should suffice. Should this be pure virtual
165 * for someone to derive from the nsEditor later? I don't believe so.
170 //Interfaces for addref and release and queryinterface
171 //NOTE: Use NS_DECL_ISUPPORTS_INHERITED in any class inherited from nsEditor
172 NS_DECL_CYCLE_COLLECTING_ISUPPORTS
173 NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsEditor
,
176 /* ------------ utility methods -------------- */
177 already_AddRefed
<nsIDOMDocument
> GetDOMDocument();
178 already_AddRefed
<nsIDocument
> GetDocument();
179 already_AddRefed
<nsIPresShell
> GetPresShell();
180 already_AddRefed
<nsIWidget
> GetWidget();
181 enum NotificationForEditorObservers
183 eNotifyEditorObserversOfEnd
,
184 eNotifyEditorObserversOfBefore
,
185 eNotifyEditorObserversOfCancel
187 void NotifyEditorObservers(NotificationForEditorObservers aNotification
);
189 /* ------------ nsIEditor methods -------------- */
192 /* ------------ nsIEditorIMESupport methods -------------- */
193 NS_DECL_NSIEDITORIMESUPPORT
195 /* ------------ nsIObserver methods -------------- */
203 virtual bool IsModifiableNode(nsINode
*aNode
);
205 NS_IMETHOD
InsertTextImpl(const nsAString
& aStringToInsert
,
206 nsCOMPtr
<nsIDOMNode
> *aInOutNode
,
207 int32_t *aInOutOffset
,
208 nsIDOMDocument
*aDoc
);
209 nsresult
InsertTextIntoTextNodeImpl(const nsAString
& aStringToInsert
,
210 mozilla::dom::Text
& aTextNode
,
212 bool aSuppressIME
= false);
213 NS_IMETHOD
DeleteSelectionImpl(EDirection aAction
,
214 EStripWrappers aStripWrappers
);
215 NS_IMETHOD
DeleteSelectionAndCreateNode(const nsAString
& aTag
,
216 nsIDOMNode
** aNewNode
);
218 /* helper routines for node/parent manipulations */
219 nsresult
DeleteNode(nsINode
* aNode
);
220 nsresult
InsertNode(nsIContent
& aNode
, nsINode
& aParent
, int32_t aPosition
);
221 enum ECloneAttributes
{ eDontCloneAttributes
, eCloneAttributes
};
222 already_AddRefed
<mozilla::dom::Element
> ReplaceContainer(
223 mozilla::dom::Element
* aOldContainer
,
225 nsIAtom
* aAttribute
= nullptr,
226 const nsAString
* aValue
= nullptr,
227 ECloneAttributes aCloneAttributes
= eDontCloneAttributes
);
228 void CloneAttributes(mozilla::dom::Element
* aDest
,
229 mozilla::dom::Element
* aSource
);
231 nsresult
RemoveContainer(nsIContent
* aNode
);
232 already_AddRefed
<mozilla::dom::Element
> InsertContainerAbove(
235 nsIAtom
* aAttribute
= nullptr,
236 const nsAString
* aValue
= nullptr);
237 nsresult
JoinNodes(nsINode
* aNodeToKeep
, nsIContent
* aNodeToMove
);
238 nsresult
MoveNode(nsIContent
* aNode
, nsINode
* aParent
, int32_t aOffset
);
240 /* Method to replace certain CreateElementNS() calls.
242 nsIAtom* aTag - tag you want
244 already_AddRefed
<mozilla::dom::Element
> CreateHTMLContent(nsIAtom
* aTag
);
246 // IME event handlers
247 virtual nsresult
BeginIMEComposition(mozilla::WidgetCompositionEvent
* aEvent
);
248 virtual nsresult
UpdateIMEComposition(nsIDOMEvent
* aDOMTextEvent
) = 0;
249 void EndIMEComposition();
251 void SwitchTextDirectionTo(uint32_t aDirection
);
254 nsresult
DetermineCurrentDirection();
255 void FireInputEvent();
257 /** Create a transaction for setting aAttribute to aValue on aElement. Never
260 already_AddRefed
<mozilla::dom::ChangeAttributeTxn
>
261 CreateTxnForSetAttribute(mozilla::dom::Element
& aElement
,
262 nsIAtom
& aAttribute
, const nsAString
& aValue
);
264 /** Create a transaction for removing aAttribute on aElement. Never returns
267 already_AddRefed
<mozilla::dom::ChangeAttributeTxn
>
268 CreateTxnForRemoveAttribute(mozilla::dom::Element
& aElement
,
269 nsIAtom
& aAttribute
);
271 /** create a transaction for creating a new child node of aParent of type aTag.
273 already_AddRefed
<mozilla::dom::CreateElementTxn
>
274 CreateTxnForCreateElement(nsIAtom
& aTag
,
278 already_AddRefed
<mozilla::dom::Element
> CreateNode(nsIAtom
* aTag
,
282 /** create a transaction for inserting aNode as a child of aParent.
284 already_AddRefed
<mozilla::dom::InsertNodeTxn
>
285 CreateTxnForInsertNode(nsIContent
& aNode
, nsINode
& aParent
, int32_t aOffset
);
287 /** create a transaction for removing aNode from its parent.
289 nsresult
CreateTxnForDeleteNode(nsINode
* aNode
, DeleteNodeTxn
** aTxn
);
292 nsresult
CreateTxnForDeleteSelection(EDirection aAction
,
293 EditAggregateTxn
** aTxn
,
298 nsresult
CreateTxnForDeleteInsertionPoint(nsRange
* aRange
,
300 EditAggregateTxn
* aTxn
,
306 /** Create a transaction for inserting aStringToInsert into aTextNode. Never
309 already_AddRefed
<mozilla::dom::InsertTextTxn
>
310 CreateTxnForInsertText(const nsAString
& aStringToInsert
,
311 mozilla::dom::Text
& aTextNode
, int32_t aOffset
);
313 // Never returns null.
314 already_AddRefed
<mozilla::dom::IMETextTxn
>
315 CreateTxnForIMEText(const nsAString
& aStringToInsert
);
317 /** create a transaction for adding a style sheet
319 NS_IMETHOD
CreateTxnForAddStyleSheet(mozilla::CSSStyleSheet
* aSheet
,
320 AddStyleSheetTxn
* *aTxn
);
322 /** create a transaction for removing a style sheet
324 NS_IMETHOD
CreateTxnForRemoveStyleSheet(mozilla::CSSStyleSheet
* aSheet
,
325 RemoveStyleSheetTxn
* *aTxn
);
327 nsresult
DeleteText(nsGenericDOMDataNode
& aElement
,
328 uint32_t aOffset
, uint32_t aLength
);
330 // NS_IMETHOD DeleteRange(nsIDOMRange *aRange);
332 already_AddRefed
<mozilla::dom::DeleteTextTxn
>
333 CreateTxnForDeleteText(nsGenericDOMDataNode
& aElement
,
334 uint32_t aOffset
, uint32_t aLength
);
336 already_AddRefed
<mozilla::dom::DeleteTextTxn
>
337 CreateTxnForDeleteCharacter(nsGenericDOMDataNode
& aData
, uint32_t aOffset
,
338 EDirection aDirection
);
340 NS_IMETHOD
CreateTxnForSplitNode(nsIDOMNode
*aNode
,
342 SplitElementTxn
**aTxn
);
344 NS_IMETHOD
CreateTxnForJoinNode(nsIDOMNode
*aLeftNode
,
345 nsIDOMNode
*aRightNode
,
346 JoinElementTxn
**aTxn
);
349 * This method first deletes the selection, if it's not collapsed. Then if
350 * the selection lies in a CharacterData node, it splits it. If the
351 * selection is at this point collapsed in a CharacterData node, it's
352 * adjusted to be collapsed right before or after the node instead (which is
353 * always possible, since the node was split).
355 nsresult
DeleteSelectionAndPrepareToCreateNode();
358 // called after a transaction is done successfully
359 void DoAfterDoTransaction(nsITransaction
*aTxn
);
360 // called after a transaction is undone successfully
361 void DoAfterUndoTransaction();
362 // called after a transaction is redone successfully
363 void DoAfterRedoTransaction();
367 eDocumentToBeDestroyed
,
368 eDocumentStateChanged
369 } TDocumentListenerNotification
;
371 // tell the doc state listeners that the doc state has changed
372 NS_IMETHOD
NotifyDocumentListeners(TDocumentListenerNotification aNotificationType
);
374 /** make the given selection span the entire document */
375 NS_IMETHOD
SelectEntireDocument(nsISelection
*aSelection
);
377 /** helper method for scrolling the selection into view after
378 * an edit operation. aScrollToAnchor should be true if you
379 * want to scroll to the point where the selection was started.
380 * If false, it attempts to scroll the end of the selection into view.
382 * Editor methods *should* call this method instead of the versions
383 * in the various selection interfaces, since this version makes sure
384 * that the editor's sync/async settings for reflowing, painting, and
387 NS_IMETHOD
ScrollSelectionIntoView(bool aScrollToAnchor
);
389 // Convenience method; forwards to IsBlockNode(nsINode*).
390 bool IsBlockNode(nsIDOMNode
* aNode
);
391 // stub. see comment in source.
392 virtual bool IsBlockNode(nsINode
* aNode
);
394 // helper for GetPriorNode and GetNextNode
395 nsIContent
* FindNextLeafNode(nsINode
*aCurrentNode
,
397 bool bNoBlockCrossing
);
399 // install the event listeners for the editor
400 virtual nsresult
InstallEventListeners();
402 virtual void CreateEventListeners();
404 // unregister and release our event listeners
405 virtual void RemoveEventListeners();
408 * Return true if spellchecking should be enabled for this editor.
410 bool GetDesiredSpellCheckState();
412 bool CanEnableSpellCheck()
414 // Check for password/readonly/disabled, which are not spellchecked
415 // regardless of DOM. Also, check to see if spell check should be skipped or not.
416 return !IsPasswordEditor() && !IsReadonly() && !IsDisabled() && !ShouldSkipSpellCheck();
420 * EnsureComposition() should be composition event handlers or text event
421 * handler. This tries to get the composition for the event and set it to
424 void EnsureComposition(mozilla::WidgetGUIEvent
* aEvent
);
428 /** All editor operations which alter the doc should be prefaced
429 * with a call to StartOperation, naming the action and direction */
430 NS_IMETHOD
StartOperation(EditAction opID
,
431 nsIEditor::EDirection aDirection
);
433 /** All editor operations which alter the doc should be followed
434 * with a call to EndOperation */
435 NS_IMETHOD
EndOperation();
437 /** routines for managing the preservation of selection across
438 * various editor actions */
439 bool ArePreservingSelection();
440 void PreserveSelectionAcrossActions(mozilla::dom::Selection
* aSel
);
441 nsresult
RestorePreservedSelection(nsISelection
*aSel
);
442 void StopPreservingSelection();
445 * SplitNode() creates a new node identical to an existing node, and split the contents between the two nodes
446 * @param aExistingRightNode the node to split. It will become the new node's next sibling.
447 * @param aOffset the offset of aExistingRightNode's content|children to do the split at
448 * @param aNewLeftNode [OUT] the new node resulting from the split, becomes aExistingRightNode's previous sibling.
449 * @param aParent the parent of aExistingRightNode
451 nsresult
SplitNodeImpl(nsIDOMNode
*aExistingRightNode
,
453 nsIDOMNode
*aNewLeftNode
,
454 nsIDOMNode
*aParent
);
457 * JoinNodes() takes 2 nodes and merge their content|children.
458 * @param aNodeToKeep The node that will remain after the join.
459 * @param aNodeToJoin The node that will be joined with aNodeToKeep.
460 * There is no requirement that the two nodes be of the same type.
461 * @param aParent The parent of aNodeToKeep
463 nsresult
JoinNodesImpl(nsINode
* aNodeToKeep
,
464 nsINode
* aNodeToJoin
,
468 * Return the offset of aChild in aParent. Asserts fatally if parent or
469 * child is null, or parent is not child's parent.
471 static int32_t GetChildOffset(nsIDOMNode
*aChild
,
472 nsIDOMNode
*aParent
);
475 * Set outOffset to the offset of aChild in the parent.
476 * Returns the parent of aChild.
478 static already_AddRefed
<nsIDOMNode
> GetNodeLocation(nsIDOMNode
* aChild
,
480 static nsINode
* GetNodeLocation(nsINode
* aChild
, int32_t* aOffset
);
482 /** returns the number of things inside aNode in the out-param aCount.
483 * @param aNode is the node to get the length of.
484 * If aNode is text, returns number of characters.
485 * If not, returns number of children nodes.
486 * @param aCount [OUT] the result of the above calculation.
488 static nsresult
GetLengthOfDOMNode(nsIDOMNode
*aNode
, uint32_t &aCount
);
490 /** get the node immediately prior to aCurrentNode
491 * @param aCurrentNode the node from which we start the search
492 * @param aEditableNode if true, only return an editable node
493 * @param aResultNode [OUT] the node that occurs before aCurrentNode in the tree,
494 * skipping non-editable nodes if aEditableNode is true.
495 * If there is no prior node, aResultNode will be nullptr.
496 * @param bNoBlockCrossing If true, don't move across "block" nodes, whatever that means.
498 nsresult
GetPriorNode(nsIDOMNode
*aCurrentNode
,
500 nsCOMPtr
<nsIDOMNode
> *aResultNode
,
501 bool bNoBlockCrossing
= false);
502 nsIContent
* GetPriorNode(nsINode
* aCurrentNode
, bool aEditableNode
,
503 bool aNoBlockCrossing
= false);
505 // and another version that takes a {parent,offset} pair rather than a node
506 nsresult
GetPriorNode(nsIDOMNode
*aParentNode
,
509 nsCOMPtr
<nsIDOMNode
> *aResultNode
,
510 bool bNoBlockCrossing
= false);
511 nsIContent
* GetPriorNode(nsINode
* aParentNode
,
514 bool aNoBlockCrossing
= false);
517 /** get the node immediately after to aCurrentNode
518 * @param aCurrentNode the node from which we start the search
519 * @param aEditableNode if true, only return an editable node
520 * @param aResultNode [OUT] the node that occurs after aCurrentNode in the tree,
521 * skipping non-editable nodes if aEditableNode is true.
522 * If there is no prior node, aResultNode will be nullptr.
524 nsresult
GetNextNode(nsIDOMNode
*aCurrentNode
,
526 nsCOMPtr
<nsIDOMNode
> *aResultNode
,
527 bool bNoBlockCrossing
= false);
528 nsIContent
* GetNextNode(nsINode
* aCurrentNode
,
530 bool bNoBlockCrossing
= false);
532 // and another version that takes a {parent,offset} pair rather than a node
533 nsresult
GetNextNode(nsIDOMNode
*aParentNode
,
536 nsCOMPtr
<nsIDOMNode
> *aResultNode
,
537 bool bNoBlockCrossing
= false);
538 nsIContent
* GetNextNode(nsINode
* aParentNode
,
541 bool aNoBlockCrossing
= false);
543 // Helper for GetNextNode and GetPriorNode
544 nsIContent
* FindNode(nsINode
*aCurrentNode
,
547 bool bNoBlockCrossing
);
549 * Get the rightmost child of aCurrentNode;
550 * return nullptr if aCurrentNode has no children.
552 nsIDOMNode
* GetRightmostChild(nsIDOMNode
* aCurrentNode
,
553 bool bNoBlockCrossing
= false);
554 nsIContent
* GetRightmostChild(nsINode
*aCurrentNode
,
555 bool bNoBlockCrossing
= false);
558 * Get the leftmost child of aCurrentNode;
559 * return nullptr if aCurrentNode has no children.
561 nsIDOMNode
* GetLeftmostChild(nsIDOMNode
* aCurrentNode
,
562 bool bNoBlockCrossing
= false);
563 nsIContent
* GetLeftmostChild(nsINode
*aCurrentNode
,
564 bool bNoBlockCrossing
= false);
566 /** returns true if aNode is of the type implied by aTag */
567 static inline bool NodeIsType(nsIDOMNode
*aNode
, nsIAtom
*aTag
)
569 return GetTag(aNode
) == aTag
;
572 /** returns true if aParent can contain a child of type aTag */
573 bool CanContain(nsIDOMNode
* aParent
, nsIDOMNode
* aChild
);
574 bool CanContainTag(nsIDOMNode
* aParent
, nsIAtom
* aTag
);
575 bool TagCanContain(nsIAtom
* aParentTag
, nsIDOMNode
* aChild
);
576 virtual bool TagCanContainTag(nsIAtom
* aParentTag
, nsIAtom
* aChildTag
);
578 /** returns true if aNode is our root node */
579 bool IsRoot(nsIDOMNode
* inNode
);
580 bool IsRoot(nsINode
* inNode
);
581 bool IsEditorRoot(nsINode
* aNode
);
583 /** returns true if aNode is a descendant of our root node */
584 bool IsDescendantOfRoot(nsIDOMNode
* inNode
);
585 bool IsDescendantOfRoot(nsINode
* inNode
);
586 bool IsDescendantOfEditorRoot(nsIDOMNode
* aNode
);
587 bool IsDescendantOfEditorRoot(nsINode
* aNode
);
589 /** returns true if aNode is a container */
590 virtual bool IsContainer(nsINode
* aNode
);
591 virtual bool IsContainer(nsIDOMNode
* aNode
);
593 /** returns true if aNode is an editable node */
594 bool IsEditable(nsIDOMNode
*aNode
);
595 virtual bool IsEditable(nsINode
* aNode
);
597 /** returns true if aNode is a MozEditorBogus node */
598 bool IsMozEditorBogusNode(nsINode
* aNode
);
600 /** counts number of editable child nodes */
601 uint32_t CountEditableChildren(nsINode
* aNode
);
603 /** Find the deep first and last children. */
604 nsINode
* GetFirstEditableNode(nsINode
* aRoot
);
607 * Returns current composition.
609 mozilla::TextComposition
* GetComposition() const;
611 * Returns true if there is composition string and not fixed.
613 bool IsIMEComposing() const;
615 /** from html rules code - migration in progress */
616 static nsresult
GetTagString(nsIDOMNode
*aNode
, nsAString
& outString
);
617 static nsIAtom
*GetTag(nsIDOMNode
*aNode
);
619 bool NodesSameType(nsIDOMNode
*aNode1
, nsIDOMNode
*aNode2
);
620 virtual bool AreNodesSameType(nsIContent
* aNode1
, nsIContent
* aNode2
);
622 static bool IsTextNode(nsIDOMNode
*aNode
);
623 static bool IsTextNode(nsINode
*aNode
);
625 static nsCOMPtr
<nsIDOMNode
> GetChildAt(nsIDOMNode
*aParent
, int32_t aOffset
);
626 static nsCOMPtr
<nsIDOMNode
> GetNodeAtRangeOffsetPoint(nsIDOMNode
* aParentOrNode
, int32_t aOffset
);
628 static nsresult
GetStartNodeAndOffset(nsISelection
*aSelection
, nsIDOMNode
**outStartNode
, int32_t *outStartOffset
);
629 static nsresult
GetStartNodeAndOffset(mozilla::dom::Selection
* aSelection
,
630 nsINode
** aStartNode
,
631 int32_t* aStartOffset
);
632 static nsresult
GetEndNodeAndOffset(nsISelection
*aSelection
, nsIDOMNode
**outEndNode
, int32_t *outEndOffset
);
633 static nsresult
GetEndNodeAndOffset(mozilla::dom::Selection
* aSelection
,
635 int32_t* aEndOffset
);
637 static void DumpNode(nsIDOMNode
*aNode
, int32_t indent
=0);
639 mozilla::dom::Selection
* GetSelection();
641 // Helpers to add a node to the selection.
642 // Used by table cell selection methods
643 nsresult
CreateRange(nsIDOMNode
*aStartParent
, int32_t aStartOffset
,
644 nsIDOMNode
*aEndParent
, int32_t aEndOffset
,
645 nsIDOMRange
**aRange
);
647 // Creates a range with just the supplied node and appends that to the selection
648 nsresult
AppendNodeToSelectionAsRange(nsIDOMNode
*aNode
);
649 // When you are using AppendNodeToSelectionAsRange, call this first to start a new selection
650 nsresult
ClearSelection();
652 nsresult
IsPreformatted(nsIDOMNode
*aNode
, bool *aResult
);
654 nsresult
SplitNodeDeep(nsIDOMNode
*aNode
,
655 nsIDOMNode
*aSplitPointParent
,
656 int32_t aSplitPointOffset
,
658 bool aNoEmptyContainers
= false,
659 nsCOMPtr
<nsIDOMNode
> *outLeftNode
= 0,
660 nsCOMPtr
<nsIDOMNode
> *outRightNode
= 0);
661 nsresult
JoinNodeDeep(nsIDOMNode
*aLeftNode
, nsIDOMNode
*aRightNode
, nsCOMPtr
<nsIDOMNode
> *aOutJoinNode
, int32_t *outOffset
);
663 nsresult
GetString(const nsAString
& name
, nsAString
& value
);
665 void BeginUpdateViewBatch(void);
666 virtual nsresult
EndUpdateViewBatch(void);
668 bool GetShouldTxnSetSelection();
670 virtual nsresult
HandleKeyPressEvent(nsIDOMKeyEvent
* aKeyEvent
);
672 nsresult
HandleInlineSpellCheck(EditAction action
,
673 nsISelection
*aSelection
,
674 nsIDOMNode
*previousSelectedNode
,
675 int32_t previousSelectedOffset
,
676 nsIDOMNode
*aStartNode
,
677 int32_t aStartOffset
,
678 nsIDOMNode
*aEndNode
,
681 virtual already_AddRefed
<mozilla::dom::EventTarget
> GetDOMEventTarget() = 0;
683 // Fast non-refcounting editor root element accessor
684 mozilla::dom::Element
*GetRoot();
686 // Likewise, but gets the editor's root instead, which is different for HTML
688 virtual mozilla::dom::Element
* GetEditorRoot();
690 // Likewise, but gets the text control element instead of the root for
692 mozilla::dom::Element
* GetExposedRoot();
694 // Accessor methods to flags
695 bool IsPlaintextEditor() const
697 return (mFlags
& nsIPlaintextEditor::eEditorPlaintextMask
) != 0;
700 bool IsSingleLineEditor() const
702 return (mFlags
& nsIPlaintextEditor::eEditorSingleLineMask
) != 0;
705 bool IsPasswordEditor() const
707 return (mFlags
& nsIPlaintextEditor::eEditorPasswordMask
) != 0;
710 bool IsReadonly() const
712 return (mFlags
& nsIPlaintextEditor::eEditorReadonlyMask
) != 0;
715 bool IsDisabled() const
717 return (mFlags
& nsIPlaintextEditor::eEditorDisabledMask
) != 0;
720 bool IsInputFiltered() const
722 return (mFlags
& nsIPlaintextEditor::eEditorFilterInputMask
) != 0;
725 bool IsMailEditor() const
727 return (mFlags
& nsIPlaintextEditor::eEditorMailMask
) != 0;
730 bool IsWrapHackEnabled() const
732 return (mFlags
& nsIPlaintextEditor::eEditorEnableWrapHackMask
) != 0;
735 bool IsFormWidget() const
737 return (mFlags
& nsIPlaintextEditor::eEditorWidgetMask
) != 0;
742 return (mFlags
& nsIPlaintextEditor::eEditorNoCSSMask
) != 0;
745 bool IsInteractionAllowed() const
747 return (mFlags
& nsIPlaintextEditor::eEditorAllowInteraction
) != 0;
750 bool DontEchoPassword() const
752 return (mFlags
& nsIPlaintextEditor::eEditorDontEchoPassword
) != 0;
755 bool ShouldSkipSpellCheck() const
757 return (mFlags
& nsIPlaintextEditor::eEditorSkipSpellCheck
) != 0;
760 bool IsTabbable() const
762 return IsSingleLineEditor() || IsPasswordEditor() || IsFormWidget() ||
763 IsInteractionAllowed();
766 bool HasIndependentSelection() const
768 return !!mSelConWeak
;
771 // Get the input event target. This might return null.
772 virtual already_AddRefed
<nsIContent
> GetInputEventTargetContent() = 0;
774 // Get the focused content, if we're focused. Returns null otherwise.
775 virtual already_AddRefed
<nsIContent
> GetFocusedContent();
777 // Get the focused content for the argument of some IMEStateManager's
779 virtual already_AddRefed
<nsIContent
> GetFocusedContentForIME();
781 // Whether the editor is active on the DOM window. Note that when this
782 // returns true but GetFocusedContent() returns null, it means that this editor was
783 // focused when the DOM window was active.
784 virtual bool IsActiveInDOMWindow();
786 // Whether the aEvent should be handled by this editor or not. When this
787 // returns FALSE, The aEvent shouldn't be handled on this editor,
788 // i.e., The aEvent should be handled by another inner editor or ancestor
790 virtual bool IsAcceptableInputEvent(nsIDOMEvent
* aEvent
);
792 // FindSelectionRoot() returns a selection root of this editor when aNode
793 // gets focus. aNode must be a content node or a document node. When the
794 // target isn't a part of this editor, returns nullptr. If this is for
795 // designMode, you should set the document node to aNode except that an
796 // element in the document has focus.
797 virtual already_AddRefed
<nsIContent
> FindSelectionRoot(nsINode
* aNode
);
799 // Initializes selection and caret for the editor. If aEventTarget isn't
800 // a host of the editor, i.e., the editor doesn't get focus, this does
802 nsresult
InitializeSelection(nsIDOMEventTarget
* aFocusEventTarget
);
804 // Finalizes selection and caret for the editor.
805 void FinalizeSelection();
807 // This method has to be called by nsEditorEventListener::Focus.
808 // All actions that have to be done when the editor is focused needs to be
810 void OnFocus(nsIDOMEventTarget
* aFocusEventTarget
);
812 // Used to insert content from a data transfer into the editable area.
813 // This is called for each item in the data transfer, with the index of
814 // each item passed as aIndex.
815 virtual nsresult
InsertFromDataTransfer(mozilla::dom::DataTransfer
*aDataTransfer
,
817 nsIDOMDocument
*aSourceDoc
,
818 nsIDOMNode
*aDestinationNode
,
820 bool aDoDeleteSelection
) = 0;
822 virtual nsresult
InsertFromDrop(nsIDOMEvent
* aDropEvent
) = 0;
824 virtual already_AddRefed
<nsIDOMNode
> FindUserSelectAllNode(nsIDOMNode
* aNode
) { return nullptr; }
833 nsCString mContentMIMEType
; // MIME type of the doc we are editing.
835 nsCOMPtr
<nsIInlineSpellChecker
> mInlineSpellChecker
;
837 nsRefPtr
<nsTransactionManager
> mTxnMgr
;
838 nsCOMPtr
<mozilla::dom::Element
> mRootElement
; // cached root node
839 nsRefPtr
<mozilla::dom::Text
> mIMETextNode
; // current IME text node
840 nsCOMPtr
<mozilla::dom::EventTarget
> mEventTarget
; // The form field as an event receiver
841 nsCOMPtr
<nsIDOMEventListener
> mEventListener
;
842 nsWeakPtr mSelConWeak
; // weak reference to the nsISelectionController
843 nsWeakPtr mPlaceHolderTxn
; // weak reference to placeholder for begin/end batch purposes
844 nsWeakPtr mDocWeak
; // weak reference to the nsIDOMDocument
845 nsIAtom
*mPlaceHolderName
; // name of placeholder transaction
846 nsSelectionState
*mSelState
; // saved selection state for placeholder txn batching
848 // IME composition this is not null between compositionstart and
850 nsRefPtr
<mozilla::TextComposition
> mComposition
;
853 nsCOMArray
<nsIEditActionListener
> mActionListeners
; // listens to all low level actions on the doc
854 nsCOMArray
<nsIEditorObserver
> mEditorObservers
; // just notify once per high level change
855 nsCOMArray
<nsIDocumentStateListener
> mDocStateListeners
;// listen to overall doc state (dirty or not, just created, etc)
857 nsSelectionState mSavedSel
; // cached selection for nsAutoSelectionReset
858 nsRangeUpdater mRangeUpdater
; // utility class object for maintaining preserved ranges
860 uint32_t mModCount
; // number of modifications (for undo/redo stack)
861 uint32_t mFlags
; // behavior flags. See nsIPlaintextEditor.idl for the flags we use.
863 int32_t mUpdateCount
;
865 int32_t mPlaceHolderBatch
; // nesting count for batching
866 EditAction mAction
; // the current editor action
868 uint32_t mIMETextOffset
; // offset in text node where IME comp string begins
870 EDirection mDirection
; // the current direction of editor action
871 int8_t mDocDirtyState
; // -1 = not initialized
872 uint8_t mSpellcheckCheckboxState
; // a Tristate value
874 bool mShouldTxnSetSelection
; // turn off for conservative selection adjustment by txns
875 bool mDidPreDestroy
; // whether PreDestroy has been called
876 bool mDidPostCreate
; // whether PostCreate has been called
877 bool mDispatchInputEvent
;
878 bool mIsInEditAction
; // true while the instance is handling an edit action
880 friend bool NSCanUnload(nsISupports
* serviceMgr
);
881 friend class nsAutoTxnsConserveSelection
;
882 friend class nsAutoSelectionReset
;
883 friend class nsAutoRules
;
884 friend class nsRangeUpdater
;