layout/generic/Selection.h

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/layout/generic/Selection.h	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,287 @@
     1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     1.5 +/* vim: set ts=2 et sw=2 tw=80: */
     1.6 +/* This Source Code Form is subject to the terms of the Mozilla Public
     1.7 + * License, v. 2.0. If a copy of the MPL was not distributed with this file,
     1.8 + * You can obtain one at http://mozilla.org/MPL/2.0/. */
     1.9 +
    1.10 +#ifndef mozilla_Selection_h__
    1.11 +#define mozilla_Selection_h__
    1.12 +
    1.13 +#include "nsIWeakReference.h"
    1.14 +
    1.15 +#include "nsISelection.h"
    1.16 +#include "nsISelectionController.h"
    1.17 +#include "nsISelectionPrivate.h"
    1.18 +#include "nsRange.h"
    1.19 +#include "nsThreadUtils.h"
    1.20 +#include "mozilla/TextRange.h"
    1.21 +#include "nsWrapperCache.h"
    1.22 +
    1.23 +struct CachedOffsetForFrame;
    1.24 +class nsAutoScrollTimer;
    1.25 +class nsIContentIterator;
    1.26 +class nsIFrame;
    1.27 +class nsFrameSelection;
    1.28 +struct SelectionDetails;
    1.29 +
    1.30 +namespace mozilla {
    1.31 +class ErrorResult;
    1.32 +}
    1.33 +
    1.34 +struct RangeData
    1.35 +{
    1.36 +  RangeData(nsRange* aRange)
    1.37 +    : mRange(aRange)
    1.38 +  {}
    1.39 +
    1.40 +  nsRefPtr<nsRange> mRange;
    1.41 +  mozilla::TextRangeStyle mTextRangeStyle;
    1.42 +};
    1.43 +
    1.44 +// Note, the ownership of mozilla::dom::Selection depends on which way the
    1.45 +// object is created. When nsFrameSelection has created Selection,
    1.46 +// addreffing/releasing the Selection object is aggregated to nsFrameSelection.
    1.47 +// Otherwise normal addref/release is used.  This ensures that nsFrameSelection
    1.48 +// is never deleted before its Selections.
    1.49 +namespace mozilla {
    1.50 +namespace dom {
    1.51 +
    1.52 +class Selection : public nsISelectionPrivate,
    1.53 +                  public nsWrapperCache,
    1.54 +                  public nsSupportsWeakReference
    1.55 +{
    1.56 +public:
    1.57 +  Selection();
    1.58 +  Selection(nsFrameSelection *aList);
    1.59 +  virtual ~Selection();
    1.60 +
    1.61 +  NS_DECL_CYCLE_COLLECTING_ISUPPORTS
    1.62 +  NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_AMBIGUOUS(Selection, nsISelectionPrivate)
    1.63 +  NS_DECL_NSISELECTION
    1.64 +  NS_DECL_NSISELECTIONPRIVATE
    1.65 +
    1.66 +  nsIDocument* GetParentObject() const;
    1.67 +
    1.68 +  // utility methods for scrolling the selection into view
    1.69 +  nsPresContext* GetPresContext() const;
    1.70 +  nsIPresShell* GetPresShell() const;
    1.71 +  nsFrameSelection* GetFrameSelection() const { return mFrameSelection; }
    1.72 +  // Returns a rect containing the selection region, and frame that that
    1.73 +  // position is relative to. For SELECTION_ANCHOR_REGION or
    1.74 +  // SELECTION_FOCUS_REGION the rect is a zero-width rectangle. For
    1.75 +  // SELECTION_WHOLE_SELECTION the rect contains both the anchor and focus
    1.76 +  // region rects.
    1.77 +  nsIFrame*     GetSelectionAnchorGeometry(SelectionRegion aRegion, nsRect *aRect);
    1.78 +  // Returns the position of the region (SELECTION_ANCHOR_REGION or
    1.79 +  // SELECTION_FOCUS_REGION only), and frame that that position is relative to.
    1.80 +  // The 'position' is a zero-width rectangle.
    1.81 +  nsIFrame*     GetSelectionEndPointGeometry(SelectionRegion aRegion, nsRect *aRect);
    1.82 +
    1.83 +  nsresult      PostScrollSelectionIntoViewEvent(
    1.84 +                                        SelectionRegion aRegion,
    1.85 +                                        int32_t aFlags,
    1.86 +                                        nsIPresShell::ScrollAxis aVertical,
    1.87 +                                        nsIPresShell::ScrollAxis aHorizontal);
    1.88 +  enum {
    1.89 +    SCROLL_SYNCHRONOUS = 1<<1,
    1.90 +    SCROLL_FIRST_ANCESTOR_ONLY = 1<<2,
    1.91 +    SCROLL_DO_FLUSH = 1<<3,
    1.92 +    SCROLL_OVERFLOW_HIDDEN = 1<<5
    1.93 +  };
    1.94 +  // aDoFlush only matters if aIsSynchronous is true.  If not, we'll just flush
    1.95 +  // when the scroll event fires so we make sure to scroll to the right place.
    1.96 +  nsresult      ScrollIntoView(SelectionRegion aRegion,
    1.97 +                               nsIPresShell::ScrollAxis aVertical =
    1.98 +                                 nsIPresShell::ScrollAxis(),
    1.99 +                               nsIPresShell::ScrollAxis aHorizontal =
   1.100 +                                 nsIPresShell::ScrollAxis(),
   1.101 +                               int32_t aFlags = 0);
   1.102 +  nsresult      SubtractRange(RangeData* aRange, nsRange* aSubtract,
   1.103 +                              nsTArray<RangeData>* aOutput);
   1.104 +  nsresult      AddItem(nsRange *aRange, int32_t* aOutIndex);
   1.105 +  nsresult      RemoveItem(nsRange *aRange);
   1.106 +  nsresult      RemoveCollapsedRanges();
   1.107 +  nsresult      Clear(nsPresContext* aPresContext);
   1.108 +  nsresult      Collapse(nsINode* aParentNode, int32_t aOffset);
   1.109 +  nsresult      Extend(nsINode* aParentNode, int32_t aOffset);
   1.110 +  nsRange*      GetRangeAt(int32_t aIndex);
   1.111 +  int32_t GetRangeCount() { return mRanges.Length(); }
   1.112 +
   1.113 +  // Get the anchor-to-focus range if we don't care which end is
   1.114 +  // anchor and which end is focus.
   1.115 +  const nsRange* GetAnchorFocusRange() const {
   1.116 +    return mAnchorFocusRange;
   1.117 +  }
   1.118 +
   1.119 +  nsDirection  GetDirection(){return mDirection;}
   1.120 +  void         SetDirection(nsDirection aDir){mDirection = aDir;}
   1.121 +  nsresult     SetAnchorFocusToRange(nsRange *aRange);
   1.122 +  void         ReplaceAnchorFocusRange(nsRange *aRange);
   1.123 +
   1.124 +  //  NS_IMETHOD   GetPrimaryFrameForRangeEndpoint(nsIDOMNode *aNode, int32_t aOffset, bool aIsEndNode, nsIFrame **aResultFrame);
   1.125 +  NS_IMETHOD   GetPrimaryFrameForAnchorNode(nsIFrame **aResultFrame);
   1.126 +  NS_IMETHOD   GetPrimaryFrameForFocusNode(nsIFrame **aResultFrame, int32_t *aOffset, bool aVisual);
   1.127 +  NS_IMETHOD   LookUpSelection(nsIContent *aContent, int32_t aContentOffset, int32_t aContentLength,
   1.128 +                             SelectionDetails **aReturnDetails, SelectionType aType, bool aSlowCheck);
   1.129 +  NS_IMETHOD   Repaint(nsPresContext* aPresContext);
   1.130 +
   1.131 +  // Note: StartAutoScrollTimer might destroy arbitrary frames etc.
   1.132 +  nsresult     StartAutoScrollTimer(nsIFrame *aFrame,
   1.133 +                                    nsPoint& aPoint,
   1.134 +                                    uint32_t aDelay);
   1.135 +
   1.136 +  nsresult     StopAutoScrollTimer();
   1.137 +
   1.138 +  JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
   1.139 +
   1.140 +  // WebIDL methods
   1.141 +  nsINode*     GetAnchorNode();
   1.142 +  uint32_t     AnchorOffset();
   1.143 +  nsINode*     GetFocusNode();
   1.144 +  uint32_t     FocusOffset();
   1.145 +
   1.146 +  bool IsCollapsed();
   1.147 +  void Collapse(nsINode& aNode, uint32_t aOffset, mozilla::ErrorResult& aRv);
   1.148 +  void CollapseToStart(mozilla::ErrorResult& aRv);
   1.149 +  void CollapseToEnd(mozilla::ErrorResult& aRv);
   1.150 +
   1.151 +  void Extend(nsINode& aNode, uint32_t aOffset, mozilla::ErrorResult& aRv);
   1.152 +
   1.153 +  void SelectAllChildren(nsINode& aNode, mozilla::ErrorResult& aRv);
   1.154 +  void DeleteFromDocument(mozilla::ErrorResult& aRv);
   1.155 +
   1.156 +  uint32_t RangeCount() const
   1.157 +  {
   1.158 +    return mRanges.Length();
   1.159 +  }
   1.160 +  nsRange* GetRangeAt(uint32_t aIndex, mozilla::ErrorResult& aRv);
   1.161 +  void AddRange(nsRange& aRange, mozilla::ErrorResult& aRv);
   1.162 +  void RemoveRange(nsRange& aRange, mozilla::ErrorResult& aRv);
   1.163 +  void RemoveAllRanges(mozilla::ErrorResult& aRv);
   1.164 +
   1.165 +  void Stringify(nsAString& aResult);
   1.166 +
   1.167 +  bool ContainsNode(nsINode* aNode, bool aPartlyContained, mozilla::ErrorResult& aRv);
   1.168 +
   1.169 +  void Modify(const nsAString& aAlter, const nsAString& aDirection,
   1.170 +              const nsAString& aGranularity, mozilla::ErrorResult& aRv);
   1.171 +
   1.172 +  bool GetInterlinePosition(mozilla::ErrorResult& aRv);
   1.173 +  void SetInterlinePosition(bool aValue, mozilla::ErrorResult& aRv);
   1.174 +
   1.175 +  void ToStringWithFormat(const nsAString& aFormatType,
   1.176 +                          uint32_t aFlags,
   1.177 +                          int32_t aWrapColumn,
   1.178 +                          nsAString& aReturn,
   1.179 +                          mozilla::ErrorResult& aRv);
   1.180 +  void AddSelectionListener(nsISelectionListener* aListener,
   1.181 +                            mozilla::ErrorResult& aRv);
   1.182 +  void RemoveSelectionListener(nsISelectionListener* aListener,
   1.183 +                               mozilla::ErrorResult& aRv);
   1.184 +
   1.185 +  int16_t Type() const { return mType; }
   1.186 +
   1.187 +  void GetRangesForInterval(nsINode& aBeginNode, int32_t aBeginOffset,
   1.188 +                            nsINode& aEndNode, int32_t aEndOffset,
   1.189 +                            bool aAllowAdjacent,
   1.190 +                            nsTArray<nsRefPtr<nsRange>>& aReturn,
   1.191 +                            mozilla::ErrorResult& aRv);
   1.192 +
   1.193 +  void ScrollIntoView(int16_t aRegion, bool aIsSynchronous,
   1.194 +                      int16_t aVPercent, int16_t aHPercent,
   1.195 +                      mozilla::ErrorResult& aRv);
   1.196 +
   1.197 +private:
   1.198 +  friend class ::nsAutoScrollTimer;
   1.199 +
   1.200 +  // Note: DoAutoScroll might destroy arbitrary frames etc.
   1.201 +  nsresult DoAutoScroll(nsIFrame *aFrame, nsPoint& aPoint);
   1.202 +
   1.203 +public:
   1.204 +  SelectionType GetType(){return mType;}
   1.205 +  void          SetType(SelectionType aType){mType = aType;}
   1.206 +
   1.207 +  nsresult     NotifySelectionListeners();
   1.208 +
   1.209 +private:
   1.210 +
   1.211 +  class ScrollSelectionIntoViewEvent;
   1.212 +  friend class ScrollSelectionIntoViewEvent;
   1.213 +
   1.214 +  class ScrollSelectionIntoViewEvent : public nsRunnable {
   1.215 +  public:
   1.216 +    NS_DECL_NSIRUNNABLE
   1.217 +    ScrollSelectionIntoViewEvent(Selection* aSelection,
   1.218 +                                 SelectionRegion aRegion,
   1.219 +                                 nsIPresShell::ScrollAxis aVertical,
   1.220 +                                 nsIPresShell::ScrollAxis aHorizontal,
   1.221 +                                 int32_t aFlags)
   1.222 +      : mSelection(aSelection),
   1.223 +        mRegion(aRegion),
   1.224 +        mVerticalScroll(aVertical),
   1.225 +        mHorizontalScroll(aHorizontal),
   1.226 +        mFlags(aFlags) {
   1.227 +      NS_ASSERTION(aSelection, "null parameter");
   1.228 +    }
   1.229 +    void Revoke() { mSelection = nullptr; }
   1.230 +  private:
   1.231 +    Selection *mSelection;
   1.232 +    SelectionRegion mRegion;
   1.233 +    nsIPresShell::ScrollAxis mVerticalScroll;
   1.234 +    nsIPresShell::ScrollAxis mHorizontalScroll;
   1.235 +    int32_t mFlags;
   1.236 +  };
   1.237 +
   1.238 +  void setAnchorFocusRange(int32_t aIndex); // pass in index into mRanges;
   1.239 +                                            // negative value clears
   1.240 +                                            // mAnchorFocusRange
   1.241 +  nsresult     SelectAllFramesForContent(nsIContentIterator *aInnerIter,
   1.242 +                               nsIContent *aContent,
   1.243 +                               bool aSelected);
   1.244 +  nsresult     selectFrames(nsPresContext* aPresContext, nsRange *aRange, bool aSelect);
   1.245 +  nsresult     getTableCellLocationFromRange(nsRange *aRange, int32_t *aSelectionType, int32_t *aRow, int32_t *aCol);
   1.246 +  nsresult     addTableCellRange(nsRange *aRange, bool *aDidAddRange, int32_t *aOutIndex);
   1.247 +
   1.248 +  nsresult FindInsertionPoint(
   1.249 +      nsTArray<RangeData>* aElementArray,
   1.250 +      nsINode* aPointNode, int32_t aPointOffset,
   1.251 +      nsresult (*aComparator)(nsINode*,int32_t,nsRange*,int32_t*),
   1.252 +      int32_t* aPoint);
   1.253 +  bool EqualsRangeAtPoint(nsINode* aBeginNode, int32_t aBeginOffset,
   1.254 +                            nsINode* aEndNode, int32_t aEndOffset,
   1.255 +                            int32_t aRangeIndex);
   1.256 +  nsresult GetIndicesForInterval(nsINode* aBeginNode, int32_t aBeginOffset,
   1.257 +                                 nsINode* aEndNode, int32_t aEndOffset,
   1.258 +                                 bool aAllowAdjacent,
   1.259 +                                 int32_t* aStartIndex, int32_t* aEndIndex);
   1.260 +  RangeData* FindRangeData(nsIDOMRange* aRange);
   1.261 +
   1.262 +  // These are the ranges inside this selection. They are kept sorted in order
   1.263 +  // of DOM start position.
   1.264 +  //
   1.265 +  // This data structure is sorted by the range beginnings. As the ranges are
   1.266 +  // disjoint, it is also implicitly sorted by the range endings. This allows
   1.267 +  // us to perform binary searches when searching for existence of a range,
   1.268 +  // giving us O(log n) search time.
   1.269 +  //
   1.270 +  // Inserting a new range requires finding the overlapping interval, requiring
   1.271 +  // two binary searches plus up to an additional 6 DOM comparisons. If this
   1.272 +  // proves to be a performance concern, then an interval tree may be a
   1.273 +  // possible solution, allowing the calculation of the overlap interval in
   1.274 +  // O(log n) time, though this would require rebalancing and other overhead.
   1.275 +  nsTArray<RangeData> mRanges;
   1.276 +
   1.277 +  nsRefPtr<nsRange> mAnchorFocusRange;
   1.278 +  nsRefPtr<nsFrameSelection> mFrameSelection;
   1.279 +  nsRefPtr<nsAutoScrollTimer> mAutoScrollTimer;
   1.280 +  nsCOMArray<nsISelectionListener> mSelectionListeners;
   1.281 +  nsRevocableEventPtr<ScrollSelectionIntoViewEvent> mScrollEvent;
   1.282 +  CachedOffsetForFrame *mCachedOffsetForFrame;
   1.283 +  nsDirection mDirection;
   1.284 +  SelectionType mType;
   1.285 +};
   1.286 +
   1.287 +} // namespace dom
   1.288 +} // namespace mozilla
   1.289 +
   1.290 +#endif // mozilla_Selection_h__

mercurial