diff options
author | Matt A. Tobin <mattatobin@localhost.localdomain> | 2018-02-02 04:16:08 -0500 |
---|---|---|
committer | Matt A. Tobin <mattatobin@localhost.localdomain> | 2018-02-02 04:16:08 -0500 |
commit | 5f8de423f190bbb79a62f804151bc24824fa32d8 (patch) | |
tree | 10027f336435511475e392454359edea8e25895d /layout/generic/nsFrameSelection.h | |
parent | 49ee0794b5d912db1f95dce6eb52d781dc210db5 (diff) | |
download | uxp-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.gz |
Add m-esr52 at 52.6.0
Diffstat (limited to 'layout/generic/nsFrameSelection.h')
-rw-r--r-- | layout/generic/nsFrameSelection.h | 768 |
1 files changed, 768 insertions, 0 deletions
diff --git a/layout/generic/nsFrameSelection.h b/layout/generic/nsFrameSelection.h new file mode 100644 index 0000000000..adb24d321f --- /dev/null +++ b/layout/generic/nsFrameSelection.h @@ -0,0 +1,768 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef nsFrameSelection_h___ +#define nsFrameSelection_h___ + +#include "mozilla/Attributes.h" +#include "mozilla/EventForwards.h" +#include "mozilla/dom/Selection.h" +#include "mozilla/TextRange.h" +#include "nsIFrame.h" +#include "nsIContent.h" +#include "nsISelectionController.h" +#include "nsISelectionListener.h" +#include "nsITableCellLayout.h" +#include "nsIDOMElement.h" +#include "WordMovementType.h" +#include "CaretAssociationHint.h" +#include "nsBidiPresUtils.h" + +class nsRange; + +// IID for the nsFrameSelection interface +// 3c6ae2d0-4cf1-44a1-9e9d-2411867f19c6 +#define NS_FRAME_SELECTION_IID \ +{ 0x3c6ae2d0, 0x4cf1, 0x44a1, \ + { 0x9e, 0x9d, 0x24, 0x11, 0x86, 0x7f, 0x19, 0xc6 } } + +#define BIDI_LEVEL_UNDEFINED 0x80 + +//---------------------------------------------------------------------- + +// Selection interface + +struct SelectionDetails +{ +#ifdef NS_BUILD_REFCNT_LOGGING + SelectionDetails() { + MOZ_COUNT_CTOR(SelectionDetails); + } + ~SelectionDetails() { + MOZ_COUNT_DTOR(SelectionDetails); + } +#endif + int32_t mStart; + int32_t mEnd; + mozilla::SelectionType mSelectionType; + mozilla::TextRangeStyle mTextRangeStyle; + SelectionDetails *mNext; +}; + +class nsIPresShell; +class nsIScrollableFrame; + +/** PeekOffsetStruct is used to group various arguments (both input and output) + * that are passed to nsFrame::PeekOffset(). See below for the description of + * individual arguments. + */ +struct MOZ_STACK_CLASS nsPeekOffsetStruct +{ + nsPeekOffsetStruct(nsSelectionAmount aAmount, + nsDirection aDirection, + int32_t aStartOffset, + nsPoint aDesiredPos, + bool aJumpLines, + bool aScrollViewStop, + bool aIsKeyboardSelect, + bool aVisual, + bool aExtend, + mozilla::EWordMovementType aWordMovementType = mozilla::eDefaultBehavior); + + // Note: Most arguments (input and output) are only used with certain values + // of mAmount. These values are indicated for each argument below. + // Arguments with no such indication are used with all values of mAmount. + + /*** Input arguments ***/ + // Note: The value of some of the input arguments may be changed upon exit. + + // mAmount: The type of movement requested (by character, word, line, etc.) + nsSelectionAmount mAmount; + + // mDirection: eDirPrevious or eDirNext. + // * Note for visual bidi movement: + // eDirPrevious means 'left-then-up' if the containing block is LTR, + // 'right-then-up' if it is RTL. + // eDirNext means 'right-then-down' if the containing block is LTR, + // 'left-then-down' if it is RTL. + // Between paragraphs, eDirPrevious means "go to the visual end of the + // previous paragraph", and eDirNext means "go to the visual beginning + // of the next paragraph". + // Used with: eSelectCharacter, eSelectWord, eSelectLine, eSelectParagraph. + nsDirection mDirection; + + // mStartOffset: Offset into the content of the current frame where the peek starts. + // Used with: eSelectCharacter, eSelectWord + int32_t mStartOffset; + + // mDesiredPos: The desired inline coordinate for the caret + // (one of .x or .y will be used, depending on line's writing mode) + // Used with: eSelectLine. + nsPoint mDesiredPos; + + // mWordMovementType: An enum that determines whether to prefer the start or end of a word + // or to use the default beahvior, which is a combination of + // direction and the platform-based pref + // "layout.word_select.eat_space_to_next_word" + mozilla::EWordMovementType mWordMovementType; + + // mJumpLines: Whether to allow jumping across line boundaries. + // Used with: eSelectCharacter, eSelectWord. + bool mJumpLines; + + // mScrollViewStop: Whether to stop when reaching a scroll view boundary. + // Used with: eSelectCharacter, eSelectWord, eSelectLine. + bool mScrollViewStop; + + // mIsKeyboardSelect: Whether the peeking is done in response to a keyboard action. + // Used with: eSelectWord. + bool mIsKeyboardSelect; + + // mVisual: Whether bidi caret behavior is visual (true) or logical (false). + // Used with: eSelectCharacter, eSelectWord, eSelectBeginLine, eSelectEndLine. + bool mVisual; + + // mExtend: Whether the selection is being extended or moved. + bool mExtend; + + /*** Output arguments ***/ + + // mResultContent: Content reached as a result of the peek. + nsCOMPtr<nsIContent> mResultContent; + + // mResultFrame: Frame reached as a result of the peek. + // Used with: eSelectCharacter, eSelectWord. + nsIFrame *mResultFrame; + + // mContentOffset: Offset into content reached as a result of the peek. + int32_t mContentOffset; + + // mAttachForward: When the result position is between two frames, + // indicates which of the two frames the caret should be painted in. + // false means "the end of the frame logically before the caret", + // true means "the beginning of the frame logically after the caret". + // Used with: eSelectLine, eSelectBeginLine, eSelectEndLine. + mozilla::CaretAssociationHint mAttach; +}; + +struct nsPrevNextBidiLevels +{ + void SetData(nsIFrame* aFrameBefore, + nsIFrame* aFrameAfter, + nsBidiLevel aLevelBefore, + nsBidiLevel aLevelAfter) + { + mFrameBefore = aFrameBefore; + mFrameAfter = aFrameAfter; + mLevelBefore = aLevelBefore; + mLevelAfter = aLevelAfter; + } + nsIFrame* mFrameBefore; + nsIFrame* mFrameAfter; + nsBidiLevel mLevelBefore; + nsBidiLevel mLevelAfter; +}; + +namespace mozilla { +namespace dom { +class Selection; +class SelectionChangeListener; +} // namespace dom +} // namespace mozilla +class nsIScrollableFrame; + +/** + * Methods which are marked with *unsafe* should be handled with special care. + * They may cause nsFrameSelection to be deleted, if strong pointer isn't used, + * or they may cause other objects to be deleted. + */ + +class nsFrameSelection final { +public: + typedef mozilla::CaretAssociationHint CaretAssociateHint; + + /*interfaces for addref and release and queryinterface*/ + + NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(nsFrameSelection) + NS_DECL_CYCLE_COLLECTION_NATIVE_CLASS(nsFrameSelection) + + /** Init will initialize the frame selector with the necessary pres shell to + * be used by most of the methods + * @param aShell is the parameter to be used for most of the other calls for callbacks etc + * @param aLimiter limits the selection to nodes with aLimiter parents + */ + void Init(nsIPresShell *aShell, nsIContent *aLimiter); + + /** HandleClick will take the focus to the new frame at the new offset and + * will either extend the selection from the old anchor, or replace the old anchor. + * the old anchor and focus position may also be used to deselect things + * @param aNewfocus is the content that wants the focus + * @param aContentOffset is the content offset of the parent aNewFocus + * @param aContentOffsetEnd is the content offset of the parent aNewFocus and is specified different + * when you need to select to and include both start and end points + * @param aContinueSelection is the flag that tells the selection to keep the old anchor point or not. + * @param aMultipleSelection will tell the frame selector to replace /or not the old selection. + * cannot coexist with aContinueSelection + * @param aHint will tell the selection which direction geometrically to actually show the caret on. + * 1 = end of this line 0 = beginning of this line + */ + /*unsafe*/ + nsresult HandleClick(nsIContent *aNewFocus, + uint32_t aContentOffset, + uint32_t aContentEndOffset, + bool aContinueSelection, + bool aMultipleSelection, + CaretAssociateHint aHint); + + /** HandleDrag extends the selection to contain the frame closest to aPoint. + * @param aPresContext is the context to use when figuring out what frame contains the point. + * @param aFrame is the parent of all frames to use when searching for the closest frame to the point. + * @param aPoint is relative to aFrame + */ + /*unsafe*/ + void HandleDrag(nsIFrame *aFrame, nsPoint aPoint); + + /** HandleTableSelection will set selection to a table, cell, etc + * depending on information contained in aFlags + * @param aParentContent is the paretent of either a table or cell that user clicked or dragged the mouse in + * @param aContentOffset is the offset of the table or cell + * @param aTarget indicates what to select (defined in nsISelectionPrivate.idl/nsISelectionPrivate.h): + * TABLESELECTION_CELL We should select a cell (content points to the cell) + * TABLESELECTION_ROW We should select a row (content points to any cell in row) + * TABLESELECTION_COLUMN We should select a row (content points to any cell in column) + * TABLESELECTION_TABLE We should select a table (content points to the table) + * TABLESELECTION_ALLCELLS We should select all cells (content points to any cell in table) + * @param aMouseEvent passed in so we can get where event occurred and what keys are pressed + */ + /*unsafe*/ + nsresult HandleTableSelection(nsINode* aParentContent, + int32_t aContentOffset, + int32_t aTarget, + mozilla::WidgetMouseEvent* aMouseEvent); + + /** + * Add cell to the selection. + * + * @param aCell [in] HTML td element. + */ + virtual nsresult SelectCellElement(nsIContent *aCell); + + /** + * Add cells to the selection inside of the given cells range. + * + * @param aTable [in] HTML table element + * @param aStartRowIndex [in] row index where the cells range starts + * @param aStartColumnIndex [in] column index where the cells range starts + * @param aEndRowIndex [in] row index where the cells range ends + * @param aEndColumnIndex [in] column index where the cells range ends + */ + virtual nsresult AddCellsToSelection(nsIContent *aTable, + int32_t aStartRowIndex, + int32_t aStartColumnIndex, + int32_t aEndRowIndex, + int32_t aEndColumnIndex); + + /** + * Remove cells from selection inside of the given cell range. + * + * @param aTable [in] HTML table element + * @param aStartRowIndex [in] row index where the cells range starts + * @param aStartColumnIndex [in] column index where the cells range starts + * @param aEndRowIndex [in] row index where the cells range ends + * @param aEndColumnIndex [in] column index where the cells range ends + */ + virtual nsresult RemoveCellsFromSelection(nsIContent *aTable, + int32_t aStartRowIndex, + int32_t aStartColumnIndex, + int32_t aEndRowIndex, + int32_t aEndColumnIndex); + + /** + * Remove cells from selection outside of the given cell range. + * + * @param aTable [in] HTML table element + * @param aStartRowIndex [in] row index where the cells range starts + * @param aStartColumnIndex [in] column index where the cells range starts + * @param aEndRowIndex [in] row index where the cells range ends + * @param aEndColumnIndex [in] column index where the cells range ends + */ + virtual nsresult RestrictCellsToSelection(nsIContent *aTable, + int32_t aStartRowIndex, + int32_t aStartColumnIndex, + int32_t aEndRowIndex, + int32_t aEndColumnIndex); + + /** StartAutoScrollTimer is responsible for scrolling frames so that + * aPoint is always visible, and for selecting any frame that contains + * aPoint. The timer will also reset itself to fire again if we have + * not scrolled to the end of the document. + * @param aFrame is the outermost frame to use when searching for + * the closest frame for the point, i.e. the frame that is capturing + * the mouse + * @param aPoint is relative to aFrame. + * @param aDelay is the timer's interval. + */ + /*unsafe*/ + nsresult StartAutoScrollTimer(nsIFrame *aFrame, + nsPoint aPoint, + uint32_t aDelay); + + /** StopAutoScrollTimer stops any active auto scroll timer. + */ + void StopAutoScrollTimer(); + + /** Lookup Selection + * returns in frame coordinates the selection beginning and ending with the type of selection given + * @param aContent is the content asking + * @param aContentOffset is the starting content boundary + * @param aContentLength is the length of the content piece asking + * @param aReturnDetails linkedlist of return values for the selection. + * @param aSlowCheck will check using slow method with no shortcuts + */ + SelectionDetails* LookUpSelection(nsIContent *aContent, + int32_t aContentOffset, + int32_t aContentLength, + bool aSlowCheck) const; + + /** SetDragState(bool); + * sets the drag state to aState for resons of drag state. + * @param aState is the new state of drag + */ + /*unsafe*/ + void SetDragState(bool aState); + + /** GetDragState(bool *); + * gets the drag state to aState for resons of drag state. + * @param aState will hold the state of drag + */ + bool GetDragState() const { return mDragState; } + + /** + if we are in table cell selection mode. aka ctrl click in table cell + */ + bool GetTableCellSelection() const { return mSelectingTableCellMode != 0; } + void ClearTableCellSelection() { mSelectingTableCellMode = 0; } + + /** GetSelection + * no query interface for selection. must use this method now. + * @param aSelectionType The selection type what you want. + */ + mozilla::dom::Selection* + GetSelection(mozilla::SelectionType aSelectionType) const; + + /** + * ScrollSelectionIntoView scrolls a region of the selection, + * so that it is visible in the scrolled view. + * + * @param aSelectionType the selection to scroll into view. + * @param aRegion the region inside the selection to scroll into view. + * @param aFlags the scroll flags. Valid bits include: + * SCROLL_SYNCHRONOUS: when set, scrolls the selection into view + * before returning. If not set, posts a request which is processed + * at some point after the method returns. + * SCROLL_FIRST_ANCESTOR_ONLY: if set, only the first ancestor will be scrolled + * into view. + * + */ + /*unsafe*/ + nsresult ScrollSelectionIntoView(mozilla::SelectionType aSelectionType, + SelectionRegion aRegion, + int16_t aFlags) const; + + /** RepaintSelection repaints the selected frames that are inside the selection + * specified by aSelectionType. + * @param aSelectionType The selection type what you want to repaint. + */ + nsresult RepaintSelection(mozilla::SelectionType aSelectionType); + + /** GetFrameForNodeOffset given a node and its child offset, return the nsIFrame and + * the offset into that frame. + * @param aNode input parameter for the node to look at + * @param aOffset offset into above node. + * @param aReturnOffset will contain offset into frame. + */ + virtual nsIFrame* GetFrameForNodeOffset(nsIContent* aNode, + int32_t aOffset, + CaretAssociateHint aHint, + int32_t* aReturnOffset) const; + + /** + * Scrolling then moving caret placement code in common to text areas and + * content areas should be located in the implementer + * This method will accept the following parameters and perform the scroll + * and caret movement. It remains for the caller to call the final + * ScrollCaretIntoView if that called wants to be sure the caret is always + * visible. + * + * @param aForward if true, scroll forward if not scroll backward + * @param aExtend if true, extend selection to the new point + * @param aScrollableFrame the frame to scroll + */ + /*unsafe*/ + void CommonPageMove(bool aForward, + bool aExtend, + nsIScrollableFrame* aScrollableFrame); + + void SetHint(CaretAssociateHint aHintRight) { mHint = aHintRight; } + CaretAssociateHint GetHint() const { return mHint; } + + /** SetCaretBidiLevel sets the caret bidi level + * @param aLevel the caret bidi level + * This method is virtual since it gets called from outside of layout. + */ + virtual void SetCaretBidiLevel(nsBidiLevel aLevel); + /** GetCaretBidiLevel gets the caret bidi level + * This method is virtual since it gets called from outside of layout. + */ + virtual nsBidiLevel GetCaretBidiLevel() const; + /** UndefineCaretBidiLevel sets the caret bidi level to "undefined" + * This method is virtual since it gets called from outside of layout. + */ + virtual void UndefineCaretBidiLevel(); + + /** PhysicalMove will generally be called from the nsiselectioncontroller implementations. + * the effect being the selection will move one unit 'aAmount' in the + * given aDirection. + * @param aDirection the direction to move the selection + * @param aAmount amount of movement (char/line; word/page; eol/doc) + * @param aExtend continue selection + */ + /*unsafe*/ + nsresult PhysicalMove(int16_t aDirection, int16_t aAmount, bool aExtend); + + /** CharacterMove will generally be called from the nsiselectioncontroller implementations. + * the effect being the selection will move one character left or right. + * @param aForward move forward in document. + * @param aExtend continue selection + */ + /*unsafe*/ + nsresult CharacterMove(bool aForward, bool aExtend); + + /** CharacterExtendForDelete extends the selection forward (logically) to + * the next character cell, so that the selected cell can be deleted. + */ + /*unsafe*/ + nsresult CharacterExtendForDelete(); + + /** CharacterExtendForBackspace extends the selection backward (logically) to + * the previous character cell, so that the selected cell can be deleted. + */ + /*unsafe*/ + nsresult CharacterExtendForBackspace(); + + /** WordMove will generally be called from the nsiselectioncontroller implementations. + * the effect being the selection will move one word left or right. + * @param aForward move forward in document. + * @param aExtend continue selection + */ + /*unsafe*/ + nsresult WordMove(bool aForward, bool aExtend); + + /** WordExtendForDelete extends the selection backward or forward (logically) to the + * next word boundary, so that the selected word can be deleted. + * @param aForward select forward in document. + */ + /*unsafe*/ + nsresult WordExtendForDelete(bool aForward); + + /** LineMove will generally be called from the nsiselectioncontroller implementations. + * the effect being the selection will move one line up or down. + * @param aForward move forward in document. + * @param aExtend continue selection + */ + /*unsafe*/ + nsresult LineMove(bool aForward, bool aExtend); + + /** IntraLineMove will generally be called from the nsiselectioncontroller implementations. + * the effect being the selection will move to beginning or end of line + * @param aForward move forward in document. + * @param aExtend continue selection + */ + /*unsafe*/ + nsresult IntraLineMove(bool aForward, bool aExtend); + + /** Select All will generally be called from the nsiselectioncontroller implementations. + * it will select the whole doc + */ + /*unsafe*/ + nsresult SelectAll(); + + /** Sets/Gets The display selection enum. + */ + void SetDisplaySelection(int16_t aState) { mDisplaySelection = aState; } + int16_t GetDisplaySelection() const { return mDisplaySelection; } + + /** This method can be used to store the data received during a MouseDown + * event so that we can place the caret during the MouseUp event. + * @aMouseEvent the event received by the selection MouseDown + * handling method. A nullptr value can be use to tell this method + * that any data is storing is no longer valid. + */ + void SetDelayedCaretData(mozilla::WidgetMouseEvent* aMouseEvent); + + /** Get the delayed MouseDown event data necessary to place the + * caret during MouseUp processing. + * @return a pointer to the event received + * by the selection during MouseDown processing. It can be nullptr + * if the data is no longer valid. + */ + bool HasDelayedCaretData() { return mDelayedMouseEventValid; } + bool IsShiftDownInDelayedCaretData() + { + NS_ASSERTION(mDelayedMouseEventValid, "No valid delayed caret data"); + return mDelayedMouseEventIsShift; + } + uint32_t GetClickCountInDelayedCaretData() + { + NS_ASSERTION(mDelayedMouseEventValid, "No valid delayed caret data"); + return mDelayedMouseEventClickCount; + } + + bool MouseDownRecorded() + { + return !GetDragState() && + HasDelayedCaretData() && + GetClickCountInDelayedCaretData() < 2; + } + + /** Get the content node that limits the selection + * When searching up a nodes for parents, as in a text edit field + * in an browser page, we must stop at this node else we reach into the + * parent page, which is very bad! + */ + nsIContent* GetLimiter() const { return mLimiter; } + + nsIContent* GetAncestorLimiter() const { return mAncestorLimiter; } + /*unsafe*/ + void SetAncestorLimiter(nsIContent *aLimiter); + + /** This will tell the frame selection that a double click has been pressed + * so it can track abort future drags if inside the same selection + * @aDoubleDown has the double click down happened + */ + void SetMouseDoubleDown(bool aDoubleDown) { mMouseDoubleDownState = aDoubleDown; } + + /** This will return whether the double down flag was set. + * @return whether the double down flag was set + */ + bool GetMouseDoubleDown() const { return mMouseDoubleDownState; } + + /** GetPrevNextBidiLevels will return the frames and associated Bidi levels of the characters + * logically before and after a (collapsed) selection. + * @param aNode is the node containing the selection + * @param aContentOffset is the offset of the selection in the node + * @param aJumpLines If true, look across line boundaries. + * If false, behave as if there were base-level frames at line edges. + * + * @return A struct holding the before/after frame and the before/after level. + * + * At the beginning and end of each line there is assumed to be a frame with + * Bidi level equal to the paragraph embedding level. + * In these cases the before frame and after frame respectively will be + * nullptr. + * + * This method is virtual since it gets called from outside of layout. + */ + virtual nsPrevNextBidiLevels GetPrevNextBidiLevels(nsIContent *aNode, + uint32_t aContentOffset, + bool aJumpLines) const; + + /** GetFrameFromLevel will scan in a given direction + * until it finds a frame with a Bidi level less than or equal to a given level. + * It will return the last frame before this. + * @param aPresContext is the context to use + * @param aFrameIn is the frame to start from + * @param aDirection is the direction to scan + * @param aBidiLevel is the level to search for + * @param aFrameOut will hold the frame returned + */ + nsresult GetFrameFromLevel(nsIFrame *aFrameIn, + nsDirection aDirection, + nsBidiLevel aBidiLevel, + nsIFrame **aFrameOut) const; + + /** + * MaintainSelection will track the current selection as being "sticky". + * Dragging or extending selection will never allow for a subset + * (or the whole) of the maintained selection to become unselected. + * Primary use: double click selecting then dragging on second click + * @param aAmount the initial amount of text selected (word, line or paragraph). + * For "line", use eSelectBeginLine. + */ + nsresult MaintainSelection(nsSelectionAmount aAmount = eSelectNoAmount); + + nsresult ConstrainFrameAndPointToAnchorSubtree(nsIFrame *aFrame, + nsPoint& aPoint, + nsIFrame **aRetFrame, + nsPoint& aRetPoint); + + nsFrameSelection(); + + void StartBatchChanges(); + void EndBatchChanges(int16_t aReason = nsISelectionListener::NO_REASON); + + /*unsafe*/ + nsresult DeleteFromDocument(); + + nsIPresShell *GetShell()const { return mShell; } + + void DisconnectFromPresShell(); + nsresult ClearNormalSelection(); + +private: + ~nsFrameSelection(); + + nsresult TakeFocus(nsIContent *aNewFocus, + uint32_t aContentOffset, + uint32_t aContentEndOffset, + CaretAssociateHint aHint, + bool aContinueSelection, + bool aMultipleSelection); + + void BidiLevelFromMove(nsIPresShell* aPresShell, + nsIContent *aNode, + uint32_t aContentOffset, + nsSelectionAmount aAmount, + CaretAssociateHint aHint); + void BidiLevelFromClick(nsIContent *aNewFocus, uint32_t aContentOffset); + nsPrevNextBidiLevels GetPrevNextBidiLevels(nsIContent *aNode, + uint32_t aContentOffset, + CaretAssociateHint aHint, + bool aJumpLines) const; + + bool AdjustForMaintainedSelection(nsIContent *aContent, int32_t aOffset); + +// post and pop reasons for notifications. we may stack these later + void PostReason(int16_t aReason) { mSelectionChangeReason = aReason; } + int16_t PopReason() + { + int16_t retval = mSelectionChangeReason; + mSelectionChangeReason = nsISelectionListener::NO_REASON; + return retval; + } + bool IsUserSelectionReason() const + { + return (mSelectionChangeReason & + (nsISelectionListener::DRAG_REASON | + nsISelectionListener::MOUSEDOWN_REASON | + nsISelectionListener::MOUSEUP_REASON | + nsISelectionListener::KEYPRESS_REASON)) != + nsISelectionListener::NO_REASON; + } + + friend class mozilla::dom::Selection; + friend class mozilla::dom::SelectionChangeListener; + friend struct mozilla::AutoPrepareFocusRange; +#ifdef DEBUG + void printSelection(); // for debugging +#endif /* DEBUG */ + + void ResizeBuffer(uint32_t aNewBufSize); + +/*HELPER METHODS*/ + // Whether MoveCaret should use logical or visual movement, + // or follow the bidi.edit.caret_movement_style preference. + enum CaretMovementStyle { + eLogical, + eVisual, + eUsePrefStyle + }; + nsresult MoveCaret(nsDirection aDirection, bool aContinueSelection, + nsSelectionAmount aAmount, + CaretMovementStyle aMovementStyle); + + nsresult FetchDesiredPos(nsPoint &aDesiredPos); //the position requested by the Key Handling for up down + void InvalidateDesiredPos(); //do not listen to mDesiredPos you must get another. + void SetDesiredPos(nsPoint aPos); //set the mDesiredPos + + uint32_t GetBatching() const {return mBatching; } + bool GetNotifyFrames() const { return mNotifyFrames; } + void SetDirty(bool aDirty=true){if (mBatching) mChangesDuringBatching = aDirty;} + + // nsFrameSelection may get deleted when calling this, + // so remember to use nsCOMPtr when needed. + nsresult NotifySelectionListeners(mozilla::SelectionType aSelectionType); + // Update the selection cache on repaint when the + // selection being repainted is not empty. + nsresult UpdateSelectionCacheOnRepaintSelection(mozilla::dom:: + Selection* aSel); + + RefPtr<mozilla::dom::Selection> + mDomSelections[mozilla::kPresentSelectionTypeCount]; + + // Table selection support. + nsITableCellLayout* GetCellLayout(nsIContent *aCellContent) const; + + nsresult SelectBlockOfCells(nsIContent *aStartNode, nsIContent *aEndNode); + nsresult SelectRowOrColumn(nsIContent *aCellContent, uint32_t aTarget); + nsresult UnselectCells(nsIContent *aTable, + int32_t aStartRowIndex, int32_t aStartColumnIndex, + int32_t aEndRowIndex, int32_t aEndColumnIndex, + bool aRemoveOutsideOfCellRange); + + nsresult GetCellIndexes(nsIContent *aCell, int32_t &aRowIndex, int32_t &aColIndex); + + // Get our first range, if its first selected node is a cell. If this does + // not return null, then the first node in the returned range is a cell + // (according to GetFirstCellNodeInRange). + nsRange* GetFirstCellRange(); + // Get our next range, if its first selected node is a cell. If this does + // not return null, then the first node in the returned range is a cell + // (according to GetFirstCellNodeInRange). + nsRange* GetNextCellRange(); + nsIContent* GetFirstCellNodeInRange(nsRange *aRange) const; + // Returns non-null table if in same table, null otherwise + nsIContent* IsInSameTable(nsIContent *aContent1, nsIContent *aContent2) const; + // Might return null + nsIContent* GetParentTable(nsIContent *aCellNode) const; + nsresult CreateAndAddRange(nsINode *aParentNode, int32_t aOffset); + + nsCOMPtr<nsINode> mCellParent; //used to snap to table selection + nsCOMPtr<nsIContent> mStartSelectedCell; + nsCOMPtr<nsIContent> mEndSelectedCell; + nsCOMPtr<nsIContent> mAppendStartSelectedCell; + nsCOMPtr<nsIContent> mUnselectCellOnMouseUp; + int32_t mSelectingTableCellMode; + int32_t mSelectedCellIndex; + + // maintain selection + RefPtr<nsRange> mMaintainRange; + nsSelectionAmount mMaintainedAmount; + + //batching + int32_t mBatching; + + // Limit selection navigation to a child of this node. + nsCOMPtr<nsIContent> mLimiter; + // Limit selection navigation to a descendant of this node. + nsCOMPtr<nsIContent> mAncestorLimiter; + + nsIPresShell *mShell; + + int16_t mSelectionChangeReason; // reason for notifications of selection changing + int16_t mDisplaySelection; //for visual display purposes. + + CaretAssociateHint mHint; //hint to tell if the selection is at the end of this line or beginning of next + nsBidiLevel mCaretBidiLevel; + nsBidiLevel mKbdBidiLevel; + + nsPoint mDesiredPos; + uint32_t mDelayedMouseEventClickCount; + bool mDelayedMouseEventIsShift; + bool mDelayedMouseEventValid; + + bool mChangesDuringBatching; + bool mNotifyFrames; + bool mDragSelectingCells; + bool mDragState; //for drag purposes + bool mMouseDoubleDownState; //has the doubleclick down happened + bool mDesiredPosSet; + + int8_t mCaretMovementStyle; + + static bool sSelectionEventsEnabled; + static bool sSelectionEventsOnTextControlsEnabled; +}; + +#endif /* nsFrameSelection_h___ */ |