michael@0: /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #ifndef nsTextServicesDocument_h__ michael@0: #define nsTextServicesDocument_h__ michael@0: michael@0: #include "nsCOMPtr.h" michael@0: #include "nsCycleCollectionParticipant.h" michael@0: #include "nsIEditActionListener.h" michael@0: #include "nsISupportsImpl.h" michael@0: #include "nsITextServicesDocument.h" michael@0: #include "nsIWeakReferenceUtils.h" michael@0: #include "nsTArray.h" michael@0: #include "nscore.h" michael@0: michael@0: class OffsetEntry; michael@0: class nsIAtom; michael@0: class nsIContent; michael@0: class nsIContentIterator; michael@0: class nsIDOMCharacterData; michael@0: class nsIDOMDocument; michael@0: class nsIDOMNode; michael@0: class nsIDOMRange; michael@0: class nsIEditor; michael@0: class nsISelection; michael@0: class nsISelectionController; michael@0: class nsITextServicesFilter; michael@0: class nsString; michael@0: michael@0: /** implementation of a text services object. michael@0: * michael@0: */ michael@0: class nsTextServicesDocument : public nsITextServicesDocument, michael@0: public nsIEditActionListener michael@0: { michael@0: private: michael@0: static nsIAtom *sAAtom; michael@0: static nsIAtom *sAddressAtom; michael@0: static nsIAtom *sBigAtom; michael@0: static nsIAtom *sBAtom; michael@0: static nsIAtom *sCiteAtom; michael@0: static nsIAtom *sCodeAtom; michael@0: static nsIAtom *sDfnAtom; michael@0: static nsIAtom *sEmAtom; michael@0: static nsIAtom *sFontAtom; michael@0: static nsIAtom *sIAtom; michael@0: static nsIAtom *sKbdAtom; michael@0: static nsIAtom *sKeygenAtom; michael@0: static nsIAtom *sNobrAtom; michael@0: static nsIAtom *sSAtom; michael@0: static nsIAtom *sSampAtom; michael@0: static nsIAtom *sSmallAtom; michael@0: static nsIAtom *sSpacerAtom; michael@0: static nsIAtom *sSpanAtom; michael@0: static nsIAtom *sStrikeAtom; michael@0: static nsIAtom *sStrongAtom; michael@0: static nsIAtom *sSubAtom; michael@0: static nsIAtom *sSupAtom; michael@0: static nsIAtom *sTtAtom; michael@0: static nsIAtom *sUAtom; michael@0: static nsIAtom *sVarAtom; michael@0: static nsIAtom *sWbrAtom; michael@0: michael@0: typedef enum { eIsDone=0, // No iterator (I), or iterator doesn't point to anything valid. michael@0: eValid, // I points to first text node (TN) in current block (CB). michael@0: ePrev, // No TN in CB, I points to first TN in prev block. michael@0: eNext // No TN in CB, I points to first TN in next block. michael@0: } TSDIteratorStatus; michael@0: michael@0: nsCOMPtr mDOMDocument; michael@0: nsCOMPtrmSelCon; michael@0: nsWeakPtr mEditor; // avoid a cycle with the spell checker and editor michael@0: nsCOMPtr mIterator; michael@0: TSDIteratorStatus mIteratorStatus; michael@0: nsCOMPtr mPrevTextBlock; michael@0: nsCOMPtr mNextTextBlock; michael@0: nsTArray mOffsetTable; michael@0: michael@0: int32_t mSelStartIndex; michael@0: int32_t mSelStartOffset; michael@0: int32_t mSelEndIndex; michael@0: int32_t mSelEndOffset; michael@0: michael@0: nsCOMPtr mExtent; michael@0: michael@0: nsCOMPtr mTxtSvcFilter; michael@0: michael@0: public: michael@0: michael@0: /** The default constructor. michael@0: */ michael@0: nsTextServicesDocument(); michael@0: michael@0: /** The default destructor. michael@0: */ michael@0: virtual ~nsTextServicesDocument(); michael@0: michael@0: /** To be called at module init michael@0: */ michael@0: static void RegisterAtoms(); michael@0: michael@0: /* Macro for AddRef(), Release(), and QueryInterface() */ michael@0: NS_DECL_CYCLE_COLLECTING_ISUPPORTS michael@0: NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsTextServicesDocument, nsITextServicesDocument) michael@0: michael@0: /* nsITextServicesDocument method implementations. */ michael@0: NS_IMETHOD InitWithEditor(nsIEditor *aEditor); michael@0: NS_IMETHOD GetDocument(nsIDOMDocument **aDoc); michael@0: NS_IMETHOD SetExtent(nsIDOMRange* aDOMRange); michael@0: NS_IMETHOD ExpandRangeToWordBoundaries(nsIDOMRange *aRange); michael@0: NS_IMETHOD SetFilter(nsITextServicesFilter *aFilter); michael@0: NS_IMETHOD GetCurrentTextBlock(nsString *aStr); michael@0: NS_IMETHOD FirstBlock(); michael@0: NS_IMETHOD LastSelectedBlock(TSDBlockSelectionStatus *aSelStatus, int32_t *aSelOffset, int32_t *aSelLength); michael@0: NS_IMETHOD PrevBlock(); michael@0: NS_IMETHOD NextBlock(); michael@0: NS_IMETHOD IsDone(bool *aIsDone); michael@0: NS_IMETHOD SetSelection(int32_t aOffset, int32_t aLength); michael@0: NS_IMETHOD ScrollSelectionIntoView(); michael@0: NS_IMETHOD DeleteSelection(); michael@0: NS_IMETHOD InsertText(const nsString *aText); michael@0: michael@0: /* nsIEditActionListener method implementations. */ michael@0: NS_IMETHOD WillInsertNode(nsIDOMNode *aNode, michael@0: nsIDOMNode *aParent, michael@0: int32_t aPosition); michael@0: NS_IMETHOD DidInsertNode(nsIDOMNode *aNode, michael@0: nsIDOMNode *aParent, michael@0: int32_t aPosition, michael@0: nsresult aResult); michael@0: michael@0: NS_IMETHOD WillDeleteNode(nsIDOMNode *aChild); michael@0: NS_IMETHOD DidDeleteNode(nsIDOMNode *aChild, nsresult aResult); michael@0: michael@0: NS_IMETHOD WillSplitNode(nsIDOMNode * aExistingRightNode, michael@0: int32_t aOffset); michael@0: NS_IMETHOD DidSplitNode(nsIDOMNode *aExistingRightNode, michael@0: int32_t aOffset, michael@0: nsIDOMNode *aNewLeftNode, michael@0: nsresult aResult); michael@0: michael@0: NS_IMETHOD WillJoinNodes(nsIDOMNode *aLeftNode, michael@0: nsIDOMNode *aRightNode, michael@0: nsIDOMNode *aParent); michael@0: NS_IMETHOD DidJoinNodes(nsIDOMNode *aLeftNode, michael@0: nsIDOMNode *aRightNode, michael@0: nsIDOMNode *aParent, michael@0: nsresult aResult); michael@0: // these listen methods are unused: michael@0: NS_IMETHOD WillCreateNode(const nsAString& aTag, nsIDOMNode *aParent, int32_t aPosition); michael@0: NS_IMETHOD DidCreateNode(const nsAString& aTag, nsIDOMNode *aNode, nsIDOMNode *aParent, int32_t aPosition, nsresult aResult); michael@0: NS_IMETHOD WillInsertText(nsIDOMCharacterData *aTextNode, int32_t aOffset, const nsAString &aString); michael@0: NS_IMETHOD DidInsertText(nsIDOMCharacterData *aTextNode, int32_t aOffset, const nsAString &aString, nsresult aResult); michael@0: NS_IMETHOD WillDeleteText(nsIDOMCharacterData *aTextNode, int32_t aOffset, int32_t aLength); michael@0: NS_IMETHOD DidDeleteText(nsIDOMCharacterData *aTextNode, int32_t aOffset, int32_t aLength, nsresult aResult); michael@0: NS_IMETHOD WillDeleteSelection(nsISelection *aSelection); michael@0: NS_IMETHOD DidDeleteSelection(nsISelection *aSelection); michael@0: michael@0: /* Helper functions */ michael@0: static nsresult GetRangeEndPoints(nsIDOMRange *aRange, nsIDOMNode **aParent1, int32_t *aOffset1, nsIDOMNode **aParent2, int32_t *aOffset2); michael@0: static nsresult CreateRange(nsIDOMNode *aStartParent, int32_t aStartOffset, nsIDOMNode *aEndParent, int32_t aEndOffset, nsIDOMRange **aRange); michael@0: michael@0: private: michael@0: /* nsTextServicesDocument private methods. */ michael@0: michael@0: nsresult CreateContentIterator(nsIDOMRange *aRange, nsIContentIterator **aIterator); michael@0: michael@0: nsresult GetDocumentContentRootNode(nsIDOMNode **aNode); michael@0: nsresult CreateDocumentContentRange(nsIDOMRange **aRange); michael@0: nsresult CreateDocumentContentRootToNodeOffsetRange(nsIDOMNode *aParent, int32_t aOffset, bool aToStart, nsIDOMRange **aRange); michael@0: nsresult CreateDocumentContentIterator(nsIContentIterator **aIterator); michael@0: michael@0: nsresult AdjustContentIterator(); michael@0: michael@0: static nsresult FirstTextNode(nsIContentIterator *aIterator, TSDIteratorStatus *IteratorStatus); michael@0: static nsresult LastTextNode(nsIContentIterator *aIterator, TSDIteratorStatus *IteratorStatus); michael@0: michael@0: static nsresult FirstTextNodeInCurrentBlock(nsIContentIterator *aIterator); michael@0: static nsresult FirstTextNodeInPrevBlock(nsIContentIterator *aIterator); michael@0: static nsresult FirstTextNodeInNextBlock(nsIContentIterator *aIterator); michael@0: michael@0: nsresult GetFirstTextNodeInPrevBlock(nsIContent **aContent); michael@0: nsresult GetFirstTextNodeInNextBlock(nsIContent **aContent); michael@0: michael@0: static bool IsBlockNode(nsIContent *aContent); michael@0: static bool IsTextNode(nsIContent *aContent); michael@0: static bool IsTextNode(nsIDOMNode *aNode); michael@0: michael@0: static bool DidSkip(nsIContentIterator* aFilteredIter); michael@0: static void ClearDidSkip(nsIContentIterator* aFilteredIter); michael@0: michael@0: static bool HasSameBlockNodeParent(nsIContent *aContent1, nsIContent *aContent2); michael@0: michael@0: nsresult SetSelectionInternal(int32_t aOffset, int32_t aLength, bool aDoUpdate); michael@0: nsresult GetSelection(TSDBlockSelectionStatus *aSelStatus, int32_t *aSelOffset, int32_t *aSelLength); michael@0: nsresult GetCollapsedSelection(TSDBlockSelectionStatus *aSelStatus, int32_t *aSelOffset, int32_t *aSelLength); michael@0: nsresult GetUncollapsedSelection(TSDBlockSelectionStatus *aSelStatus, int32_t *aSelOffset, int32_t *aSelLength); michael@0: michael@0: bool SelectionIsCollapsed(); michael@0: bool SelectionIsValid(); michael@0: michael@0: static nsresult CreateOffsetTable(nsTArray *aOffsetTable, michael@0: nsIContentIterator *aIterator, michael@0: TSDIteratorStatus *aIteratorStatus, michael@0: nsIDOMRange *aIterRange, michael@0: nsString *aStr); michael@0: static nsresult ClearOffsetTable(nsTArray *aOffsetTable); michael@0: michael@0: static nsresult NodeHasOffsetEntry(nsTArray *aOffsetTable, michael@0: nsIDOMNode *aNode, michael@0: bool *aHasEntry, michael@0: int32_t *aEntryIndex); michael@0: michael@0: nsresult RemoveInvalidOffsetEntries(); michael@0: nsresult SplitOffsetEntry(int32_t aTableIndex, int32_t aOffsetIntoEntry); michael@0: michael@0: static nsresult FindWordBounds(nsTArray *offsetTable, michael@0: nsString *blockStr, michael@0: nsIDOMNode *aNode, int32_t aNodeOffset, michael@0: nsIDOMNode **aWordStartNode, michael@0: int32_t *aWordStartOffset, michael@0: nsIDOMNode **aWordEndNode, michael@0: int32_t *aWordEndOffset); michael@0: michael@0: #ifdef DEBUG_kin michael@0: void PrintOffsetTable(); michael@0: void PrintContentNode(nsIContent *aContent); michael@0: #endif michael@0: }; michael@0: michael@0: #endif // nsTextServicesDocument_h__