forked from mirrors/gecko-dev
		
	
		
			
				
	
	
		
			1083 lines
		
	
	
	
		
			40 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			1083 lines
		
	
	
	
		
			40 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 | |
| /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 | |
| /* 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/Assertions.h"
 | |
| #include "mozilla/Attributes.h"
 | |
| #include "mozilla/EventForwards.h"
 | |
| #include "mozilla/dom/Selection.h"
 | |
| #include "mozilla/Result.h"
 | |
| #include "mozilla/TextRange.h"
 | |
| #include "mozilla/UniquePtr.h"
 | |
| #include "nsIFrame.h"
 | |
| #include "nsIContent.h"
 | |
| #include "nsISelectionController.h"
 | |
| #include "nsISelectionListener.h"
 | |
| #include "nsITableCellLayout.h"
 | |
| #include "WordMovementType.h"
 | |
| #include "CaretAssociationHint.h"
 | |
| #include "nsBidiPresUtils.h"
 | |
| 
 | |
| class nsRange;
 | |
| 
 | |
| #define BIDI_LEVEL_UNDEFINED 0x80
 | |
| 
 | |
| //----------------------------------------------------------------------
 | |
| 
 | |
| // Selection interface
 | |
| 
 | |
| struct SelectionDetails {
 | |
|   SelectionDetails()
 | |
|       : mStart(), mEnd(), mSelectionType(mozilla::SelectionType::eInvalid) {
 | |
|     MOZ_COUNT_CTOR(SelectionDetails);
 | |
|   }
 | |
|   MOZ_COUNTED_DTOR(SelectionDetails)
 | |
| 
 | |
|   int32_t mStart;
 | |
|   int32_t mEnd;
 | |
|   mozilla::SelectionType mSelectionType;
 | |
|   mozilla::TextRangeStyle mTextRangeStyle;
 | |
|   mozilla::UniquePtr<SelectionDetails> mNext;
 | |
| };
 | |
| 
 | |
| struct SelectionCustomColors {
 | |
| #ifdef NS_BUILD_REFCNT_LOGGING
 | |
|   MOZ_COUNTED_DEFAULT_CTOR(SelectionCustomColors)
 | |
|   MOZ_COUNTED_DTOR(SelectionCustomColors)
 | |
| #endif
 | |
|   mozilla::Maybe<nscolor> mForegroundColor;
 | |
|   mozilla::Maybe<nscolor> mBackgroundColor;
 | |
|   mozilla::Maybe<nscolor> mAltForegroundColor;
 | |
|   mozilla::Maybe<nscolor> mAltBackgroundColor;
 | |
| };
 | |
| 
 | |
| namespace mozilla {
 | |
| class PresShell;
 | |
| }  // namespace mozilla
 | |
| 
 | |
| /** PeekOffsetStruct is used to group various arguments (both input and output)
 | |
|  *  that are passed to nsIFrame::PeekOffset(). See below for the description of
 | |
|  *  individual arguments.
 | |
|  */
 | |
| struct MOZ_STACK_CLASS nsPeekOffsetStruct {
 | |
|   enum class ForceEditableRegion {
 | |
|     No,
 | |
|     Yes,
 | |
|   };
 | |
| 
 | |
|   nsPeekOffsetStruct(
 | |
|       nsSelectionAmount aAmount, nsDirection aDirection, int32_t aStartOffset,
 | |
|       nsPoint aDesiredCaretPos, bool aJumpLines, bool aScrollViewStop,
 | |
|       bool aIsKeyboardSelect, bool aVisual, bool aExtend,
 | |
|       ForceEditableRegion = ForceEditableRegion::No,
 | |
|       mozilla::EWordMovementType aWordMovementType = mozilla::eDefaultBehavior,
 | |
|       bool aTrimSpaces = true);
 | |
| 
 | |
|   // 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.
 | |
| 
 | |
|   // The type of movement requested (by character, word, line, etc.)
 | |
|   nsSelectionAmount mAmount;
 | |
| 
 | |
|   // 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.
 | |
|   const nsDirection mDirection;
 | |
| 
 | |
|   // Offset into the content of the current frame where the peek starts.
 | |
|   //
 | |
|   // Used with: eSelectCharacter, eSelectWord
 | |
|   int32_t mStartOffset;
 | |
| 
 | |
|   // The desired inline coordinate for the caret (one of .x or .y will be used,
 | |
|   // depending on line's writing mode)
 | |
|   //
 | |
|   // Used with: eSelectLine.
 | |
|   const nsPoint mDesiredCaretPos;
 | |
| 
 | |
|   // 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;
 | |
| 
 | |
|   // Whether to allow jumping across line boundaries.
 | |
|   //
 | |
|   // Used with: eSelectCharacter, eSelectWord.
 | |
|   const bool mJumpLines;
 | |
| 
 | |
|   // mTrimSpaces: Whether we should trim spaces at begin/end of content
 | |
|   const bool mTrimSpaces;
 | |
| 
 | |
|   // Whether to stop when reaching a scroll view boundary.
 | |
|   //
 | |
|   // Used with: eSelectCharacter, eSelectWord, eSelectLine.
 | |
|   const bool mScrollViewStop;
 | |
| 
 | |
|   // Whether the peeking is done in response to a keyboard action.
 | |
|   //
 | |
|   // Used with: eSelectWord.
 | |
|   const bool mIsKeyboardSelect;
 | |
| 
 | |
|   // Whether bidi caret behavior is visual (true) or logical (false).
 | |
|   //
 | |
|   // Used with: eSelectCharacter, eSelectWord, eSelectBeginLine, eSelectEndLine.
 | |
|   const bool mVisual;
 | |
| 
 | |
|   // Whether the selection is being extended or moved.
 | |
|   const bool mExtend;
 | |
| 
 | |
|   // If true, the offset has to end up in an editable node, otherwise we'll keep
 | |
|   // searching.
 | |
|   const bool mForceEditableRegion;
 | |
| 
 | |
|   /*** Output arguments ***/
 | |
| 
 | |
|   // Content reached as a result of the peek.
 | |
|   nsCOMPtr<nsIContent> mResultContent;
 | |
| 
 | |
|   // Frame reached as a result of the peek.
 | |
|   //
 | |
|   // Used with: eSelectCharacter, eSelectWord.
 | |
|   nsIFrame* mResultFrame;
 | |
| 
 | |
|   // Offset into content reached as a result of the peek.
 | |
|   int32_t mContentOffset;
 | |
| 
 | |
|   // 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 {
 | |
| class SelectionChangeEventDispatcher;
 | |
| namespace dom {
 | |
| class Selection;
 | |
| }  // namespace dom
 | |
| 
 | |
| /**
 | |
|  * Constants for places that want to handle table selections.  These
 | |
|  * indicate what part of a table is being selected.
 | |
|  */
 | |
| enum class TableSelectionMode : uint32_t {
 | |
|   None,     /* Nothing being selected; not valid in all cases. */
 | |
|   Cell,     /* A cell is being selected. */
 | |
|   Row,      /* A row is being selected. */
 | |
|   Column,   /* A column is being selected. */
 | |
|   Table,    /* A table (including cells and captions) is being selected. */
 | |
|   AllCells, /* All the cells in a table are being selected. */
 | |
| };
 | |
| 
 | |
| }  // namespace mozilla
 | |
| class nsIScrollableFrame;
 | |
| 
 | |
| 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)
 | |
| 
 | |
|   enum class FocusMode {
 | |
|     kExtendSelection,     /** Keep old anchor point. */
 | |
|     kCollapseToNewPoint,  /** Collapses the Selection to the new point. */
 | |
|     kMultiRangeSelection, /** Keeps existing non-collapsed ranges and marks them
 | |
|                              as generated. */
 | |
|   };
 | |
| 
 | |
|   /**
 | |
|    * 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 aHint will tell the selection which direction geometrically to
 | |
|    * actually show the caret on. 1 = end of this line 0 = beginning of this line
 | |
|    */
 | |
|   MOZ_CAN_RUN_SCRIPT nsresult HandleClick(nsIContent* aNewFocus,
 | |
|                                           uint32_t aContentOffset,
 | |
|                                           uint32_t aContentEndOffset,
 | |
|                                           FocusMode aFocusMode,
 | |
|                                           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
 | |
|    */
 | |
|   MOZ_CAN_RUN_SCRIPT void HandleDrag(nsIFrame* aFrame, const 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
 | |
|    *   * TableSelectionMode::Cell
 | |
|    *       We should select a cell (content points to the cell)
 | |
|    *   * TableSelectionMode::Row
 | |
|    *       We should select a row (content points to any cell in row)
 | |
|    *   * TableSelectionMode::Column
 | |
|    *       We should select a row (content points to any cell in column)
 | |
|    *   * TableSelectionMode::Table
 | |
|    *       We should select a table (content points to the table)
 | |
|    *   * TableSelectionMode::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
 | |
|    */
 | |
|   // TODO: replace with `MOZ_CAN_RUN_SCRIPT`.
 | |
|   [[nodiscard]] MOZ_CAN_RUN_SCRIPT_BOUNDARY nsresult
 | |
|   HandleTableSelection(nsINode* aParentContent, int32_t aContentOffset,
 | |
|                        mozilla::TableSelectionMode aTarget,
 | |
|                        mozilla::WidgetMouseEvent* aMouseEvent);
 | |
| 
 | |
|   /**
 | |
|    * Add cell to the selection with `SelectionType::eNormal`.
 | |
|    *
 | |
|    * @param  aCell  [in] HTML td element.
 | |
|    */
 | |
|   nsresult SelectCellElement(nsIContent* aCell);
 | |
| 
 | |
|  public:
 | |
|   /**
 | |
|    * 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
 | |
|    */
 | |
|   // TODO: annotate this with `MOZ_CAN_RUN_SCRIPT` instead.
 | |
|   MOZ_CAN_RUN_SCRIPT_BOUNDARY
 | |
|   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
 | |
|    */
 | |
|   // TODO: annotate this with `MOZ_CAN_RUN_SCRIPT` instead.
 | |
|   MOZ_CAN_RUN_SCRIPT_BOUNDARY
 | |
|   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.
 | |
|    */
 | |
|   MOZ_CAN_RUN_SCRIPT
 | |
|   nsresult StartAutoScrollTimer(nsIFrame* aFrame, const nsPoint& aPoint,
 | |
|                                 uint32_t aDelay);
 | |
| 
 | |
|   /**
 | |
|    * Stops any active auto scroll timer.
 | |
|    */
 | |
|   void StopAutoScrollTimer();
 | |
| 
 | |
|   /**
 | |
|    * 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 aSlowCheck will check using slow method with no shortcuts
 | |
|    */
 | |
|   mozilla::UniquePtr<SelectionDetails> LookUpSelection(nsIContent* aContent,
 | |
|                                                        int32_t aContentOffset,
 | |
|                                                        int32_t aContentLength,
 | |
|                                                        bool aSlowCheck) const;
 | |
| 
 | |
|   /**
 | |
|    * Sets the drag state to aState for resons of drag state.
 | |
|    *
 | |
|    * @param aState is the new state of drag
 | |
|    */
 | |
|   MOZ_CAN_RUN_SCRIPT
 | |
|   void SetDragState(bool aState);
 | |
| 
 | |
|   /**
 | |
|    * 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 IsInTableSelectionMode() const {
 | |
|     return mTableSelection.mMode != mozilla::TableSelectionMode::None;
 | |
|   }
 | |
|   void ClearTableCellSelection() {
 | |
|     mTableSelection.mMode = mozilla::TableSelectionMode::None;
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * 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.
 | |
|    */
 | |
|   // TODO: replace with `MOZ_CAN_RUN_SCRIPT`.
 | |
|   MOZ_CAN_RUN_SCRIPT_BOUNDARY 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);
 | |
| 
 | |
|   bool IsValidSelectionPoint(nsINode* aNode) const;
 | |
| 
 | |
|   /**
 | |
|    * 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.
 | |
|    */
 | |
|   static nsIFrame* GetFrameForNodeOffset(nsIContent* aNode, int32_t aOffset,
 | |
|                                          CaretAssociateHint aHint,
 | |
|                                          int32_t* aReturnOffset);
 | |
| 
 | |
|   /**
 | |
|    * GetFrameToPageSelect() returns a frame which is ancestor limit of
 | |
|    * per-page selection.  The frame may not be scrollable.  E.g.,
 | |
|    * when selection ancestor limit is set to a frame of an editing host of
 | |
|    * contenteditable element and it's not scrollable.
 | |
|    */
 | |
|   nsIFrame* GetFrameToPageSelect() const;
 | |
| 
 | |
|   /**
 | |
|    * This method moves caret (if aExtend is false) or expands selection (if
 | |
|    * aExtend is true).  Then, scrolls aFrame one page.  Finally, this may
 | |
|    * call ScrollSelectionIntoView() for making focus of selection visible
 | |
|    * but depending on aSelectionIntoView value.
 | |
|    *
 | |
|    * @param aForward if true, scroll forward if not scroll backward
 | |
|    * @param aExtend  if true, extend selection to the new point
 | |
|    * @param aFrame   the frame to scroll or container of per-page selection.
 | |
|    *                 if aExtend is true and selection may have ancestor limit,
 | |
|    *                 should set result of GetFrameToPageSelect().
 | |
|    * @param aSelectionIntoView
 | |
|    *                 If IfChanged, this makes selection into view only when
 | |
|    *                 selection is modified by the call.
 | |
|    *                 If Yes, this makes selection into view always.
 | |
|    */
 | |
|   enum class SelectionIntoView { IfChanged, Yes };
 | |
|   MOZ_CAN_RUN_SCRIPT nsresult PageMove(bool aForward, bool aExtend,
 | |
|                                        nsIFrame* aFrame,
 | |
|                                        SelectionIntoView aSelectionIntoView);
 | |
| 
 | |
|   void SetHint(CaretAssociateHint aHintRight) { mCaret.mHint = aHintRight; }
 | |
|   CaretAssociateHint GetHint() const { return mCaret.mHint; }
 | |
| 
 | |
|   void SetCaretBidiLevelAndMaybeSchedulePaint(nsBidiLevel aLevel);
 | |
| 
 | |
|   /**
 | |
|    * GetCaretBidiLevel gets the caret bidi level.
 | |
|    */
 | |
|   nsBidiLevel GetCaretBidiLevel() const;
 | |
| 
 | |
|   /**
 | |
|    * UndefineCaretBidiLevel sets the caret bidi level to "undefined".
 | |
|    */
 | |
|   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
 | |
|    */
 | |
|   // TODO: replace with `MOZ_CAN_RUN_SCRIPT`.
 | |
|   MOZ_CAN_RUN_SCRIPT_BOUNDARY 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
 | |
|    */
 | |
|   // TODO: replace with `MOZ_CAN_RUN_SCRIPT`.
 | |
|   MOZ_CAN_RUN_SCRIPT_BOUNDARY nsresult CharacterMove(bool aForward,
 | |
|                                                      bool aExtend);
 | |
| 
 | |
|   /**
 | |
|    * 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
 | |
|    */
 | |
|   // TODO: replace with `MOZ_CAN_RUN_SCRIPT`.
 | |
|   MOZ_CAN_RUN_SCRIPT_BOUNDARY nsresult WordMove(bool aForward, bool aExtend);
 | |
| 
 | |
|   /**
 | |
|    * 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
 | |
|    */
 | |
|   // TODO: replace with `MOZ_CAN_RUN_SCRIPT`.
 | |
|   MOZ_CAN_RUN_SCRIPT_BOUNDARY 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
 | |
|    */
 | |
|   // TODO: replace with `MOZ_CAN_RUN_SCRIPT`.
 | |
|   MOZ_CAN_RUN_SCRIPT_BOUNDARY nsresult IntraLineMove(bool aForward,
 | |
|                                                      bool aExtend);
 | |
| 
 | |
|   /**
 | |
|    * CreateRangeExtendedToNextGraphemeClusterBoundary() returns range which is
 | |
|    * extended from normal selection range to start of next grapheme cluster
 | |
|    * boundary.
 | |
|    */
 | |
|   template <typename RangeType>
 | |
|   MOZ_CAN_RUN_SCRIPT mozilla::Result<RefPtr<RangeType>, nsresult>
 | |
|   CreateRangeExtendedToNextGraphemeClusterBoundary() {
 | |
|     return CreateRangeExtendedToSomewhere<RangeType>(eDirNext, eSelectCluster,
 | |
|                                                      eLogical);
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * CreateRangeExtendedToPreviousCharacterBoundary() returns range which is
 | |
|    * extended from normal selection range to start of previous character
 | |
|    * boundary.
 | |
|    */
 | |
|   template <typename RangeType>
 | |
|   MOZ_CAN_RUN_SCRIPT mozilla::Result<RefPtr<RangeType>, nsresult>
 | |
|   CreateRangeExtendedToPreviousCharacterBoundary() {
 | |
|     return CreateRangeExtendedToSomewhere<RangeType>(
 | |
|         eDirPrevious, eSelectCharacter, eLogical);
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * CreateRangeExtendedToNextWordBoundary() returns range which is
 | |
|    * extended from normal selection range to start of next word boundary.
 | |
|    */
 | |
|   template <typename RangeType>
 | |
|   MOZ_CAN_RUN_SCRIPT mozilla::Result<RefPtr<RangeType>, nsresult>
 | |
|   CreateRangeExtendedToNextWordBoundary() {
 | |
|     return CreateRangeExtendedToSomewhere<RangeType>(eDirNext, eSelectWord,
 | |
|                                                      eLogical);
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * CreateRangeExtendedToPreviousWordBoundary() returns range which is
 | |
|    * extended from normal selection range to start of previous word boundary.
 | |
|    */
 | |
|   template <typename RangeType>
 | |
|   MOZ_CAN_RUN_SCRIPT mozilla::Result<RefPtr<RangeType>, nsresult>
 | |
|   CreateRangeExtendedToPreviousWordBoundary() {
 | |
|     return CreateRangeExtendedToSomewhere<RangeType>(eDirPrevious, eSelectWord,
 | |
|                                                      eLogical);
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * CreateRangeExtendedToPreviousHardLineBreak() returns range which is
 | |
|    * extended from normal selection range to previous hard line break.
 | |
|    */
 | |
|   template <typename RangeType>
 | |
|   MOZ_CAN_RUN_SCRIPT mozilla::Result<RefPtr<RangeType>, nsresult>
 | |
|   CreateRangeExtendedToPreviousHardLineBreak() {
 | |
|     return CreateRangeExtendedToSomewhere<RangeType>(
 | |
|         eDirPrevious, eSelectBeginLine, eLogical);
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * CreateRangeExtendedToNextHardLineBreak() returns range which is extended
 | |
|    * from normal selection range to next hard line break.
 | |
|    */
 | |
|   template <typename RangeType>
 | |
|   MOZ_CAN_RUN_SCRIPT mozilla::Result<RefPtr<RangeType>, nsresult>
 | |
|   CreateRangeExtendedToNextHardLineBreak() {
 | |
|     return CreateRangeExtendedToSomewhere<RangeType>(eDirNext, eSelectEndLine,
 | |
|                                                      eLogical);
 | |
|   }
 | |
| 
 | |
|   /** 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.
 | |
|    *
 | |
|    * @param 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() const { return mDelayedMouseEvent.mIsValid; }
 | |
|   bool IsShiftDownInDelayedCaretData() const {
 | |
|     NS_ASSERTION(mDelayedMouseEvent.mIsValid, "No valid delayed caret data");
 | |
|     return mDelayedMouseEvent.mIsShift;
 | |
|   }
 | |
|   uint32_t GetClickCountInDelayedCaretData() const {
 | |
|     NS_ASSERTION(mDelayedMouseEvent.mIsValid, "No valid delayed caret data");
 | |
|     return mDelayedMouseEvent.mClickCount;
 | |
|   }
 | |
| 
 | |
|   bool MouseDownRecorded() const {
 | |
|     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 mLimiters.mLimiter; }
 | |
| 
 | |
|   nsIContent* GetAncestorLimiter() const { return mLimiters.mAncestorLimiter; }
 | |
|   MOZ_CAN_RUN_SCRIPT_BOUNDARY void SetAncestorLimiter(nsIContent* aLimiter);
 | |
| 
 | |
|   /**
 | |
|    * 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.
 | |
|    */
 | |
|   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 normal 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);
 | |
| 
 | |
|   MOZ_CAN_RUN_SCRIPT nsresult ConstrainFrameAndPointToAnchorSubtree(
 | |
|       nsIFrame* aFrame, const nsPoint& aPoint, nsIFrame** aRetFrame,
 | |
|       nsPoint& aRetPoint) const;
 | |
| 
 | |
|   /**
 | |
|    * @param aPresShell 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
 | |
|    *
 | |
|    * @param aAccessibleCaretEnabled true if we should enable the accessible
 | |
|    * caret.
 | |
|    */
 | |
|   nsFrameSelection(mozilla::PresShell* aPresShell, nsIContent* aLimiter,
 | |
|                    bool aAccessibleCaretEnabled);
 | |
| 
 | |
|   void StartBatchChanges();
 | |
| 
 | |
|   MOZ_CAN_RUN_SCRIPT_BOUNDARY
 | |
|   /**
 | |
|    * @param aReasons potentially multiple of the reasons defined in
 | |
|    * nsISelectionListener.idl
 | |
|    */
 | |
|   void EndBatchChanges(int16_t aReasons = nsISelectionListener::NO_REASON);
 | |
| 
 | |
|   mozilla::PresShell* GetPresShell() const { return mPresShell; }
 | |
| 
 | |
|   void DisconnectFromPresShell();
 | |
|   MOZ_CAN_RUN_SCRIPT_BOUNDARY nsresult ClearNormalSelection();
 | |
| 
 | |
|   // Table selection support.
 | |
|   static nsITableCellLayout* GetCellLayout(const nsIContent* aCellContent);
 | |
| 
 | |
|  private:
 | |
|   ~nsFrameSelection();
 | |
| 
 | |
|   // TODO: in case an error is returned, it sometimes refers to a programming
 | |
|   // error, in other cases to runtime errors. This deserves to be cleaned up.
 | |
|   [[nodiscard]] MOZ_CAN_RUN_SCRIPT nsresult
 | |
|   TakeFocus(nsIContent& aNewFocus, uint32_t aContentOffset,
 | |
|             uint32_t aContentEndOffset, CaretAssociateHint aHint,
 | |
|             FocusMode aFocusMode);
 | |
| 
 | |
|   /**
 | |
|    * After moving the caret, its Bidi level is set according to the following
 | |
|    * rules:
 | |
|    *
 | |
|    * After moving over a character with left/right arrow, set to the Bidi level
 | |
|    * of the last moved over character. After Home and End, set to the paragraph
 | |
|    * embedding level. After up/down arrow, PageUp/Down, set to the lower level
 | |
|    * of the 2 surrounding characters. After mouse click, set to the level of the
 | |
|    * current frame.
 | |
|    *
 | |
|    * The following two methods use GetPrevNextBidiLevels to determine the new
 | |
|    * Bidi level. BidiLevelFromMove is called when the caret is moved in response
 | |
|    * to a keyboard event
 | |
|    *
 | |
|    * @param aPresShell is the presentation shell
 | |
|    * @param aNode is the content node
 | |
|    * @param aContentOffset is the new caret position, as an offset into aNode
 | |
|    * @param aAmount is the amount of the move that gave the caret its new
 | |
|    * position
 | |
|    * @param aHint is the hint indicating in what logical direction the caret
 | |
|    * moved
 | |
|    */
 | |
|   void BidiLevelFromMove(mozilla::PresShell* aPresShell, nsIContent* aNode,
 | |
|                          uint32_t aContentOffset, nsSelectionAmount aAmount,
 | |
|                          CaretAssociateHint aHint);
 | |
|   /**
 | |
|    * BidiLevelFromClick is called when the caret is repositioned by clicking the
 | |
|    * mouse
 | |
|    *
 | |
|    * @param aNode is the content node
 | |
|    * @param aContentOffset is the new caret position, as an offset into aNode
 | |
|    */
 | |
|   void BidiLevelFromClick(nsIContent* aNewFocus, uint32_t aContentOffset);
 | |
| 
 | |
|   static nsPrevNextBidiLevels GetPrevNextBidiLevels(nsIContent* aNode,
 | |
|                                                     uint32_t aContentOffset,
 | |
|                                                     CaretAssociateHint aHint,
 | |
|                                                     bool aJumpLines);
 | |
| 
 | |
|   /**
 | |
|    * @param aReasons potentially multiple of the reasons defined in
 | |
|    * nsISelectionListener.idl.
 | |
|    */
 | |
|   void SetChangeReasons(int16_t aReasons) {
 | |
|     mSelectionChangeReasons = aReasons;
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * @param aReasons potentially multiple of the reasons defined in
 | |
|    * nsISelectionListener.idl.
 | |
|    */
 | |
|   void AddChangeReasons(int16_t aReasons) {
 | |
|     mSelectionChangeReasons |= aReasons;
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * @return potentially multiple of the reasons defined in
 | |
|    * nsISelectionListener.idl.
 | |
|    */
 | |
|   int16_t PopChangeReasons() {
 | |
|     int16_t retval = mSelectionChangeReasons;
 | |
|     mSelectionChangeReasons = nsISelectionListener::NO_REASON;
 | |
|     return retval;
 | |
|   }
 | |
| 
 | |
|   bool IsUserSelectionReason() const {
 | |
|     return (mSelectionChangeReasons &
 | |
|             (nsISelectionListener::DRAG_REASON |
 | |
|              nsISelectionListener::MOUSEDOWN_REASON |
 | |
|              nsISelectionListener::MOUSEUP_REASON |
 | |
|              nsISelectionListener::KEYPRESS_REASON)) !=
 | |
|            nsISelectionListener::NO_REASON;
 | |
|   }
 | |
| 
 | |
|   friend class mozilla::dom::Selection;
 | |
|   friend class mozilla::SelectionChangeEventDispatcher;
 | |
|   friend struct mozilla::AutoPrepareFocusRange;
 | |
| 
 | |
|   /*HELPER METHODS*/
 | |
|   // Whether MoveCaret should use logical or visual movement,
 | |
|   // or follow the bidi.edit.caret_movement_style preference.
 | |
|   enum CaretMovementStyle { eLogical, eVisual, eUsePrefStyle };
 | |
|   MOZ_CAN_RUN_SCRIPT nsresult MoveCaret(nsDirection aDirection,
 | |
|                                         bool aContinueSelection,
 | |
|                                         nsSelectionAmount aAmount,
 | |
|                                         CaretMovementStyle aMovementStyle);
 | |
| 
 | |
|   /**
 | |
|    * PeekOffsetForCaretMove() only peek offset for caret move.  I.e., won't
 | |
|    * change selection ranges nor bidi information.
 | |
|    */
 | |
|   mozilla::Result<nsPeekOffsetStruct, nsresult> PeekOffsetForCaretMove(
 | |
|       nsDirection aDirection, bool aContinueSelection,
 | |
|       const nsSelectionAmount aAmount, CaretMovementStyle aMovementStyle,
 | |
|       const nsPoint& aDesiredCaretPos) const;
 | |
| 
 | |
|   /**
 | |
|    * CreateRangeExtendedToSomewhere() is common method to implement
 | |
|    * CreateRangeExtendedTo*().  This method creates a range extended from
 | |
|    * normal selection range.
 | |
|    */
 | |
|   template <typename RangeType>
 | |
|   MOZ_CAN_RUN_SCRIPT mozilla::Result<RefPtr<RangeType>, nsresult>
 | |
|   CreateRangeExtendedToSomewhere(nsDirection aDirection,
 | |
|                                  const nsSelectionAmount aAmount,
 | |
|                                  CaretMovementStyle aMovementStyle);
 | |
| 
 | |
|   /**
 | |
|    * IsIntraLineCaretMove() is a helper method for PeekOffsetForCaretMove()
 | |
|    * and CreateRangeExtendedToSomwhereFromNormalSelection().  This returns
 | |
|    * whether aAmount is intra line move or is crossing hard line break.
 | |
|    * This returns error if aMount is not supported by the methods.
 | |
|    */
 | |
|   static mozilla::Result<bool, nsresult> IsIntraLineCaretMove(
 | |
|       nsSelectionAmount aAmount) {
 | |
|     switch (aAmount) {
 | |
|       case eSelectCharacter:
 | |
|       case eSelectCluster:
 | |
|       case eSelectWord:
 | |
|       case eSelectWordNoSpace:
 | |
|       case eSelectBeginLine:
 | |
|       case eSelectEndLine:
 | |
|         return true;
 | |
|       case eSelectLine:
 | |
|         return false;
 | |
|       default:
 | |
|         return mozilla::Err(NS_ERROR_FAILURE);
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   void InvalidateDesiredCaretPos();  // do not listen to mDesiredCaretPos.mValue
 | |
|                                      // you must get another.
 | |
| 
 | |
|   bool IsBatching() const { return mBatching.mCounter > 0; }
 | |
| 
 | |
|   void SetChangesDuringBatchingFlag() {
 | |
|     MOZ_ASSERT(mBatching.mCounter > 0);
 | |
| 
 | |
|     mBatching.mChangesDuringBatching = true;
 | |
|   }
 | |
| 
 | |
|   // nsFrameSelection may get deleted when calling this,
 | |
|   // so remember to use nsCOMPtr when needed.
 | |
|   MOZ_CAN_RUN_SCRIPT
 | |
|   nsresult NotifySelectionListeners(mozilla::SelectionType aSelectionType);
 | |
| 
 | |
|   static nsresult GetCellIndexes(const nsIContent* aCell, int32_t& aRowIndex,
 | |
|                                  int32_t& aColIndex);
 | |
| 
 | |
|   static nsIContent* GetFirstCellNodeInRange(const nsRange* aRange);
 | |
|   // Returns non-null table if in same table, null otherwise
 | |
|   static nsIContent* IsInSameTable(const nsIContent* aContent1,
 | |
|                                    const nsIContent* aContent2);
 | |
|   // Might return null
 | |
|   static nsIContent* GetParentTable(const nsIContent* aCellNode);
 | |
| 
 | |
|   ////////////BEGIN nsFrameSelection members
 | |
| 
 | |
|   RefPtr<mozilla::dom::Selection>
 | |
|       mDomSelections[sizeof(mozilla::kPresentSelectionTypes) /
 | |
|                      sizeof(mozilla::SelectionType)];
 | |
| 
 | |
|   struct TableSelection {
 | |
|     // 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(const mozilla::dom::Selection& aNormalSelection);
 | |
| 
 | |
|     // 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(const mozilla::dom::Selection& aNormalSelection);
 | |
| 
 | |
|     [[nodiscard]] MOZ_CAN_RUN_SCRIPT nsresult
 | |
|     HandleSelection(nsINode* aParentContent, int32_t aContentOffset,
 | |
|                     mozilla::TableSelectionMode aTarget,
 | |
|                     mozilla::WidgetMouseEvent* aMouseEvent, bool aDragState,
 | |
|                     mozilla::dom::Selection& aNormalSelection);
 | |
| 
 | |
|     /**
 | |
|      * @return the closest inclusive table cell ancestor
 | |
|      *         (https://dom.spec.whatwg.org/#concept-tree-inclusive-ancestor) of
 | |
|      *         aContent, if it is actively editable.
 | |
|      */
 | |
|     static nsINode* IsContentInActivelyEditableTableCell(
 | |
|         nsPresContext* aContext, nsIContent* aContent);
 | |
| 
 | |
|     // TODO: annotate this with `MOZ_CAN_RUN_SCRIPT` instead.
 | |
|     MOZ_CAN_RUN_SCRIPT_BOUNDARY
 | |
|     nsresult SelectBlockOfCells(nsIContent* aStartCell, nsIContent* aEndCell,
 | |
|                                 mozilla::dom::Selection& aNormalSelection);
 | |
| 
 | |
|     nsresult SelectRowOrColumn(nsIContent* aCellContent,
 | |
|                                mozilla::dom::Selection& aNormalSelection);
 | |
| 
 | |
|     MOZ_CAN_RUN_SCRIPT nsresult
 | |
|     UnselectCells(const nsIContent* aTable, int32_t aStartRowIndex,
 | |
|                   int32_t aStartColumnIndex, int32_t aEndRowIndex,
 | |
|                   int32_t aEndColumnIndex, bool aRemoveOutsideOfCellRange,
 | |
|                   mozilla::dom::Selection& aNormalSelection);
 | |
| 
 | |
|     nsCOMPtr<nsINode>
 | |
|         mClosestInclusiveTableCellAncestor;  // used to snap to table selection
 | |
|     nsCOMPtr<nsIContent> mStartSelectedCell;
 | |
|     nsCOMPtr<nsIContent> mEndSelectedCell;
 | |
|     nsCOMPtr<nsIContent> mAppendStartSelectedCell;
 | |
|     nsCOMPtr<nsIContent> mUnselectCellOnMouseUp;
 | |
|     mozilla::TableSelectionMode mMode = mozilla::TableSelectionMode::None;
 | |
|     int32_t mSelectedCellIndex = 0;
 | |
|     bool mDragSelectingCells = false;
 | |
| 
 | |
|    private:
 | |
|     struct MOZ_STACK_CLASS FirstAndLastCell {
 | |
|       nsCOMPtr<nsIContent> mFirst;
 | |
|       nsCOMPtr<nsIContent> mLast;
 | |
|     };
 | |
| 
 | |
|     mozilla::Result<FirstAndLastCell, nsresult>
 | |
|     FindFirstAndLastCellOfRowOrColumn(const nsIContent& aCellContent) const;
 | |
| 
 | |
|     [[nodiscard]] MOZ_CAN_RUN_SCRIPT_BOUNDARY nsresult HandleDragSelecting(
 | |
|         mozilla::TableSelectionMode aTarget, nsIContent* aChildContent,
 | |
|         const mozilla::WidgetMouseEvent* aMouseEvent,
 | |
|         mozilla::dom::Selection& aNormalSelection);
 | |
| 
 | |
|     [[nodiscard]] MOZ_CAN_RUN_SCRIPT nsresult HandleMouseUpOrDown(
 | |
|         mozilla::TableSelectionMode aTarget, bool aDragState,
 | |
|         nsIContent* aChildContent, nsINode* aParentContent,
 | |
|         int32_t aContentOffset, const mozilla::WidgetMouseEvent* aMouseEvent,
 | |
|         mozilla::dom::Selection& aNormalSelection);
 | |
| 
 | |
|     class MOZ_STACK_CLASS RowAndColumnRelation;
 | |
|   };
 | |
| 
 | |
|   TableSelection mTableSelection;
 | |
| 
 | |
|   struct MaintainedRange {
 | |
|     /**
 | |
|      * Ensure anchor and focus of aNormalSelection are ordered appropriately
 | |
|      * relative to the maintained range.
 | |
|      */
 | |
|     MOZ_CAN_RUN_SCRIPT void AdjustNormalSelection(
 | |
|         const nsIContent* aContent, int32_t aOffset,
 | |
|         mozilla::dom::Selection& aNormalSelection) const;
 | |
| 
 | |
|     /**
 | |
|      * @param aScrollViewStop see `nsPeekOffsetStruct::mScrollViewStop`.
 | |
|      */
 | |
|     void AdjustContentOffsets(nsIFrame::ContentOffsets& aOffsets,
 | |
|                               bool aScrollViewStop) const;
 | |
| 
 | |
|     void MaintainAnchorFocusRange(
 | |
|         const mozilla::dom::Selection& aNormalSelection,
 | |
|         nsSelectionAmount aAmount);
 | |
| 
 | |
|     RefPtr<nsRange> mRange;
 | |
|     nsSelectionAmount mAmount = eSelectNoAmount;
 | |
|   };
 | |
| 
 | |
|   MaintainedRange mMaintainedRange;
 | |
| 
 | |
|   struct Batching {
 | |
|     uint32_t mCounter = 0;
 | |
|     bool mChangesDuringBatching = false;
 | |
|   };
 | |
| 
 | |
|   Batching mBatching;
 | |
| 
 | |
|   struct Limiters {
 | |
|     // Limit selection navigation to a child of this node.
 | |
|     nsCOMPtr<nsIContent> mLimiter;
 | |
|     // Limit selection navigation to a descendant of this node.
 | |
|     nsCOMPtr<nsIContent> mAncestorLimiter;
 | |
|   };
 | |
| 
 | |
|   Limiters mLimiters;
 | |
| 
 | |
|   mozilla::PresShell* mPresShell = nullptr;
 | |
|   // Reasons for notifications of selection changing.
 | |
|   // Can be multiple of the reasons defined in nsISelectionListener.idl.
 | |
|   int16_t mSelectionChangeReasons = nsISelectionListener::NO_REASON;
 | |
|   // For visual display purposes.
 | |
|   int16_t mDisplaySelection = nsISelectionController::SELECTION_OFF;
 | |
| 
 | |
|   struct Caret {
 | |
|     // Hint to tell if the selection is at the end of this line or beginning of
 | |
|     // next.
 | |
|     CaretAssociateHint mHint = mozilla::CARET_ASSOCIATE_BEFORE;
 | |
|     nsBidiLevel mBidiLevel = BIDI_LEVEL_UNDEFINED;
 | |
| 
 | |
|     bool IsVisualMovement(bool aContinueSelection,
 | |
|                           CaretMovementStyle aMovementStyle) const;
 | |
|   };
 | |
| 
 | |
|   Caret mCaret;
 | |
| 
 | |
|   nsBidiLevel mKbdBidiLevel = NSBIDI_LTR;
 | |
| 
 | |
|   class DesiredCaretPos {
 | |
|    public:
 | |
|     // the position requested by the Key Handling for up down
 | |
|     nsresult FetchPos(nsPoint& aDesiredCaretPos,
 | |
|                       const mozilla::PresShell& aPresShell,
 | |
|                       mozilla::dom::Selection& aNormalSelection) const;
 | |
| 
 | |
|     void Set(const nsPoint& aPos);
 | |
| 
 | |
|     void Invalidate();
 | |
| 
 | |
|     bool mIsSet = false;
 | |
| 
 | |
|    private:
 | |
|     nsPoint mValue;
 | |
|   };
 | |
| 
 | |
|   DesiredCaretPos mDesiredCaretPos;
 | |
| 
 | |
|   struct DelayedMouseEvent {
 | |
|     bool mIsValid = false;
 | |
|     // These values are not used since they are only valid when mIsValid is
 | |
|     // true, and setting mIsValid  always overrides these values.
 | |
|     bool mIsShift = false;
 | |
|     uint32_t mClickCount = 0;
 | |
|   };
 | |
| 
 | |
|   DelayedMouseEvent mDelayedMouseEvent;
 | |
| 
 | |
|   bool mDragState = false;  // for drag purposes
 | |
|   bool mAccessibleCaretEnabled = false;
 | |
| };
 | |
| 
 | |
| #endif /* nsFrameSelection_h___ */
 | 
