accessible/src/generic/HyperTextAccessible.h

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     2 /* This Source Code Form is subject to the terms of the Mozilla Public
     3  * License, v. 2.0. If a copy of the MPL was not distributed with this
     4  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     6 #ifndef mozilla_a11y_HyperTextAccessible_h__
     7 #define mozilla_a11y_HyperTextAccessible_h__
     9 #include "AccessibleWrap.h"
    10 #include "nsIAccessibleTypes.h"
    11 #include "xpcAccessibleHyperText.h"
    13 #include "nsFrameSelection.h"
    14 #include "nsISelectionController.h"
    16 namespace mozilla {
    17 namespace a11y {
    19 class TextRange;
    21 struct DOMPoint {
    22   DOMPoint() : node(nullptr), idx(0) { }
    23   DOMPoint(nsINode* aNode, int32_t aIdx) : node(aNode), idx(aIdx) { }
    25   nsINode* node;
    26   int32_t idx;
    27 };
    29 // This character marks where in the text returned via nsIAccessibleText(),
    30 // that embedded object characters exist
    31 const char16_t kEmbeddedObjectChar = 0xfffc;
    32 const char16_t kImaginaryEmbeddedObjectChar = ' ';
    33 const char16_t kForcedNewLineChar = '\n';
    35 /**
    36   * Special Accessible that knows how contain both text and embedded objects
    37   */
    38 class HyperTextAccessible : public AccessibleWrap,
    39                             public xpcAccessibleHyperText
    40 {
    41 public:
    42   HyperTextAccessible(nsIContent* aContent, DocAccessible* aDoc);
    43   virtual ~HyperTextAccessible() { }
    45   NS_DECL_ISUPPORTS_INHERITED
    47   // Accessible
    48   virtual int32_t GetLevelInternal();
    49   virtual already_AddRefed<nsIPersistentProperties> NativeAttributes() MOZ_OVERRIDE;
    50   virtual mozilla::a11y::role NativeRole();
    51   virtual uint64_t NativeState();
    53   virtual void InvalidateChildren();
    54   virtual bool RemoveChild(Accessible* aAccessible);
    56   // HyperTextAccessible (static helper method)
    58   // Convert content offset to rendered text offset
    59   nsresult ContentToRenderedOffset(nsIFrame *aFrame, int32_t aContentOffset,
    60                                    uint32_t *aRenderedOffset) const;
    62   // Convert rendered text offset to content offset
    63   nsresult RenderedToContentOffset(nsIFrame *aFrame, uint32_t aRenderedOffset,
    64                                    int32_t *aContentOffset) const;
    66   //////////////////////////////////////////////////////////////////////////////
    67   // HyperLinkAccessible
    69   /**
    70    * Return link count within this hypertext accessible.
    71    */
    72   uint32_t LinkCount()
    73     { return EmbeddedChildCount(); }
    75   /**
    76    * Return link accessible at the given index.
    77    */
    78   Accessible* LinkAt(uint32_t aIndex)
    79   {
    80     return GetEmbeddedChildAt(aIndex);
    81   }
    83   /**
    84    * Return index for the given link accessible.
    85    */
    86   int32_t LinkIndexOf(Accessible* aLink)
    87   {
    88     return GetIndexOfEmbeddedChild(aLink);
    89   }
    91   /**
    92    * Return link accessible at the given text offset.
    93    */
    94   int32_t LinkIndexAtOffset(uint32_t aOffset)
    95   {
    96     Accessible* child = GetChildAtOffset(aOffset);
    97     return child ? LinkIndexOf(child) : -1;
    98   }
   100   //////////////////////////////////////////////////////////////////////////////
   101   // HyperTextAccessible: DOM point to text offset conversions.
   103   /**
   104    * Turn a DOM point (node and offset) into a character offset of this
   105    * hypertext. Will look for closest match when the DOM node does not have
   106    * an accessible object associated with it. Will return an offset for the end
   107    * of the string if the node is not found.
   108    *
   109    * @param aNode         [in] the node to look for
   110    * @param aNodeOffset   [in] the offset to look for
   111    *                       if -1 just look directly for the node
   112    *                       if >=0 and aNode is text, this represents a char offset
   113    *                       if >=0 and aNode is not text, this represents a child node offset
   114    * @param aIsEndOffset  [in] if true, then then this offset is not inclusive. The character
   115    *                       indicated by the offset returned is at [offset - 1]. This means
   116    *                       if the passed-in offset is really in a descendant, then the offset returned
   117    *                       will come just after the relevant embedded object characer.
   118    *                       If false, then the offset is inclusive. The character indicated
   119    *                       by the offset returned is at [offset]. If the passed-in offset in inside a
   120    *                       descendant, then the returned offset will be on the relevant embedded object char.
   121    */
   122   int32_t DOMPointToOffset(nsINode* aNode, int32_t aNodeOffset,
   123                            bool aIsEndOffset = false) const;
   125   /**
   126    * Transform the given a11y point into the offset relative this hypertext.
   127    */
   128   int32_t TransformOffset(Accessible* aDescendant, int32_t aOffset,
   129                           bool aIsEndOffset) const;
   131   /**
   132    * Convert start and end hypertext offsets into DOM range.
   133    *
   134    * @param  aStartOffset  [in] the given start hypertext offset
   135    * @param  aEndOffset    [in] the given end hypertext offset
   136    * @param  aRange        [in, out] the range whose bounds to set
   137    * @return true   if conversion was successful
   138    */
   139   bool OffsetsToDOMRange(int32_t aStartOffset, int32_t aEndOffset,
   140                          nsRange* aRange);
   142   /**
   143    * Convert the given offset into DOM point.
   144    *
   145    * If offset is at text leaf then DOM point is (text node, offsetInTextNode),
   146    * if before embedded object then (parent node, indexInParent), if after then
   147    * (parent node, indexInParent + 1).
   148    */
   149   DOMPoint OffsetToDOMPoint(int32_t aOffset);
   151   /**
   152    * Return true if the used ARIA role (if any) allows the hypertext accessible
   153    * to expose text interfaces.
   154    */
   155   bool IsTextRole();
   157   //////////////////////////////////////////////////////////////////////////////
   158   // TextAccessible
   160   /**
   161    * Return character count within the hypertext accessible.
   162    */
   163   uint32_t CharacterCount() const
   164     { return GetChildOffset(ChildCount()); }
   166   /**
   167    * Get a character at the given offset (don't support magic offsets).
   168    */
   169   bool CharAt(int32_t aOffset, nsAString& aChar,
   170               int32_t* aStartOffset = nullptr, int32_t* aEndOffset = nullptr)
   171   {
   172     NS_ASSERTION(!aStartOffset == !aEndOffset,
   173                  "Offsets should be both defined or both undefined!");
   175     int32_t childIdx = GetChildIndexAtOffset(aOffset);
   176     if (childIdx == -1)
   177       return false;
   179     Accessible* child = GetChildAt(childIdx);
   180     child->AppendTextTo(aChar, aOffset - GetChildOffset(childIdx), 1);
   182     if (aStartOffset && aEndOffset) {
   183       *aStartOffset = aOffset;
   184       *aEndOffset = aOffset + aChar.Length();
   185     }
   186     return true;
   187   }
   189   char16_t CharAt(int32_t aOffset)
   190   {
   191     nsAutoString charAtOffset;
   192     CharAt(aOffset, charAtOffset);
   193     return charAtOffset.CharAt(0);
   194   }
   196   /**
   197    * Return true if char at the given offset equals to given char.
   198    */
   199   bool IsCharAt(int32_t aOffset, char16_t aChar)
   200     { return CharAt(aOffset) == aChar; }
   202   /**
   203    * Return true if terminal char is at the given offset.
   204    */
   205   bool IsLineEndCharAt(int32_t aOffset)
   206     { return IsCharAt(aOffset, '\n'); }
   208   /**
   209    * Return text between given offsets.
   210    */
   211   void TextSubstring(int32_t aStartOffset, int32_t aEndOffset, nsAString& aText);
   213   /**
   214    * Return text before/at/after the given offset corresponding to
   215    * the boundary type.
   216    */
   217   void TextBeforeOffset(int32_t aOffset, AccessibleTextBoundary aBoundaryType,
   218                        int32_t* aStartOffset, int32_t* aEndOffset,
   219                        nsAString& aText);
   220   void TextAtOffset(int32_t aOffset, AccessibleTextBoundary aBoundaryType,
   221                     int32_t* aStartOffset, int32_t* aEndOffset,
   222                     nsAString& aText);
   223   void TextAfterOffset(int32_t aOffset, AccessibleTextBoundary aBoundaryType,
   224                        int32_t* aStartOffset, int32_t* aEndOffset,
   225                        nsAString& aText);
   227   /**
   228    * Return text attributes for the given text range.
   229    */
   230   already_AddRefed<nsIPersistentProperties>
   231     TextAttributes(bool aIncludeDefAttrs, int32_t aOffset,
   232                    int32_t* aStartOffset, int32_t* aEndOffset);
   234   /**
   235    * Return text attributes applied to the accessible.
   236    */
   237   already_AddRefed<nsIPersistentProperties> DefaultTextAttributes();
   239   /**
   240    * Return text offset of the given child accessible within hypertext
   241    * accessible.
   242    *
   243    * @param  aChild           [in] accessible child to get text offset for
   244    * @param  aInvalidateAfter [in, optional] indicates whether invalidate
   245    *                           cached offsets for next siblings of the child
   246    */
   247   int32_t GetChildOffset(Accessible* aChild,
   248                          bool aInvalidateAfter = false) const
   249   {
   250     int32_t index = GetIndexOf(aChild);
   251     return index == -1 ? -1 : GetChildOffset(index, aInvalidateAfter);
   252   }
   254   /**
   255    * Return text offset for the child accessible index.
   256    */
   257   int32_t GetChildOffset(uint32_t aChildIndex,
   258                          bool aInvalidateAfter = false) const;
   260   /**
   261    * Return child accessible at the given text offset.
   262    *
   263    * @param  aOffset  [in] the given text offset
   264    */
   265   int32_t GetChildIndexAtOffset(uint32_t aOffset) const;
   267   /**
   268    * Return child accessible at the given text offset.
   269    *
   270    * @param  aOffset  [in] the given text offset
   271    */
   272   Accessible* GetChildAtOffset(uint32_t aOffset) const
   273   {
   274     return GetChildAt(GetChildIndexAtOffset(aOffset));
   275   }
   277   /**
   278    * Return true if the given offset/range is valid.
   279    */
   280   bool IsValidOffset(int32_t aOffset);
   281   bool IsValidRange(int32_t aStartOffset, int32_t aEndOffset);
   283   /**
   284    * Return an offset at the given point.
   285    */
   286   int32_t OffsetAtPoint(int32_t aX, int32_t aY, uint32_t aCoordType);
   288   /**
   289    * Return a rect of the given text range relative given coordinate system.
   290    */
   291   nsIntRect TextBounds(int32_t aStartOffset, int32_t aEndOffset,
   292                        uint32_t aCoordType = nsIAccessibleCoordinateType::COORDTYPE_SCREEN_RELATIVE);
   294   /**
   295    * Return a rect for character at given offset relative given coordinate
   296    * system.
   297    */
   298   nsIntRect CharBounds(int32_t aOffset, uint32_t aCoordType)
   299     { return TextBounds(aOffset, aOffset + 1, aCoordType); }
   301   /**
   302    * Get/set caret offset, if no caret then -1.
   303    */
   304   int32_t CaretOffset() const;
   305   void SetCaretOffset(int32_t aOffset) { SetSelectionRange(aOffset, aOffset); }
   307   /**
   308    * Provide the line number for the caret.
   309    * @return 1-based index for the line number with the caret
   310    */
   311   int32_t CaretLineNumber();
   313   /**
   314    * Return the caret rect and the widget containing the caret within this
   315    * text accessible.
   316    *
   317    * @param [out] the widget containing the caret
   318    * @return      the caret rect
   319    */
   320   nsIntRect GetCaretRect(nsIWidget** aWidget);
   322   /**
   323    * Return selected regions count within the accessible.
   324    */
   325   int32_t SelectionCount();
   327   /**
   328    * Return the start and end offset of the specified selection.
   329    */
   330   bool SelectionBoundsAt(int32_t aSelectionNum,
   331                          int32_t* aStartOffset, int32_t* aEndOffset);
   333   /*
   334    * Changes the start and end offset of the specified selection.
   335    * @return true if succeeded
   336    */
   337   bool SetSelectionBoundsAt(int32_t aSelectionNum,
   338                             int32_t aStartOffset, int32_t aEndOffset);
   340   /**
   341    * Adds a selection bounded by the specified offsets.
   342    * @return true if succeeded
   343    */
   344   bool AddToSelection(int32_t aStartOffset, int32_t aEndOffset);
   346   /*
   347    * Removes the specified selection.
   348    * @return true if succeeded
   349    */
   350   bool RemoveFromSelection(int32_t aSelectionNum);
   352   /**
   353    * Scroll the given text range into view.
   354    */
   355   void ScrollSubstringTo(int32_t aStartOffset, int32_t aEndOffset,
   356                          uint32_t aScrollType);
   358   /**
   359    * Scroll the given text range to the given point.
   360    */
   361   void ScrollSubstringToPoint(int32_t aStartOffset,
   362                               int32_t aEndOffset,
   363                               uint32_t aCoordinateType,
   364                               int32_t aX, int32_t aY);
   366   /**
   367    * Return a range that encloses the text control or the document this
   368    * accessible belongs to.
   369    */
   370   void EnclosingRange(TextRange& aRange) const;
   372   /**
   373    * Return an array of disjoint ranges for selected text within the text control
   374    * or the document this accessible belongs to.
   375    */
   376   void SelectionRanges(nsTArray<TextRange>* aRanges) const;
   378   /**
   379    * Return an array of disjoint ranges of visible text within the text control
   380    * or the document this accessible belongs to.
   381    */
   382   void VisibleRanges(nsTArray<TextRange>* aRanges) const;
   384   /**
   385    * Return a range containing the given accessible.
   386    */
   387   void RangeByChild(Accessible* aChild, TextRange& aRange) const;
   389   /**
   390    * Return a range containing an accessible at the given point.
   391    */
   392   void RangeAtPoint(int32_t aX, int32_t aY, TextRange& aRange) const;
   394   //////////////////////////////////////////////////////////////////////////////
   395   // EditableTextAccessible
   397   void ReplaceText(const nsAString& aText);
   398   void InsertText(const nsAString& aText, int32_t aPosition);
   399   void CopyText(int32_t aStartPos, int32_t aEndPos);
   400   void CutText(int32_t aStartPos, int32_t aEndPos);
   401   void DeleteText(int32_t aStartPos, int32_t aEndPos);
   402   void PasteText(int32_t aPosition);
   404   /**
   405    * Return the editor associated with the accessible.
   406    */
   407   virtual already_AddRefed<nsIEditor> GetEditor() const;
   409 protected:
   410   // Accessible
   411   virtual ENameValueFlag NativeName(nsString& aName) MOZ_OVERRIDE;
   412   virtual void CacheChildren() MOZ_OVERRIDE;
   414   // HyperTextAccessible
   416   /**
   417    * Transform magic offset into text offset.
   418    */
   419   int32_t ConvertMagicOffset(int32_t aOffset);
   421   /**
   422    * Adjust an offset the caret stays at to get a text by line boundary.
   423    */
   424   int32_t AdjustCaretOffset(int32_t aOffset) const;
   426   /**
   427    * Return true if caret is at end of line.
   428    */
   429   bool IsCaretAtEndOfLine() const;
   431   /**
   432    * Return true if the given offset points to terminal empty line if any.
   433    */
   434   bool IsEmptyLastLineOffset(int32_t aOffset)
   435   {
   436     return aOffset == static_cast<int32_t>(CharacterCount()) &&
   437       IsLineEndCharAt(aOffset - 1);
   438   }
   440   /**
   441    * Return an offset of the found word boundary.
   442    */
   443   int32_t FindWordBoundary(int32_t aOffset, nsDirection aDirection,
   444                            EWordMovementType aWordMovementType)
   445   {
   446     return FindOffset(aOffset, aDirection, eSelectWord, aWordMovementType);
   447   }
   449   /**
   450    * Used to get begin/end of previous/this/next line. Note: end of line
   451    * is an offset right before '\n' character if any, the offset is right after
   452    * '\n' character is begin of line. In case of wrap word breaks these offsets
   453    * are equal.
   454    */
   455   enum EWhichLineBoundary {
   456     ePrevLineBegin,
   457     ePrevLineEnd,
   458     eThisLineBegin,
   459     eThisLineEnd,
   460     eNextLineBegin,
   461     eNextLineEnd
   462   };
   464   /**
   465    * Return an offset for requested line boundary. See constants above.
   466    */
   467   int32_t FindLineBoundary(int32_t aOffset,
   468                            EWhichLineBoundary aWhichLineBoundary);
   470   /**
   471    * Return an offset corresponding to the given direction and selection amount
   472    * relative the given offset. A helper used to find word or line boundaries.
   473    */
   474   int32_t FindOffset(int32_t aOffset, nsDirection aDirection,
   475                      nsSelectionAmount aAmount,
   476                      EWordMovementType aWordMovementType = eDefaultBehavior);
   478   /**
   479    * Return the boundaries of the substring in case of textual frame or
   480    * frame boundaries in case of non textual frame, offsets are ignored.
   481    */
   482   nsIntRect GetBoundsInFrame(nsIFrame* aFrame,
   483                              uint32_t aStartRenderedOffset,
   484                              uint32_t aEndRenderedOffset);
   486   // Selection helpers
   488   /**
   489    * Return frame/DOM selection object for the accessible.
   490    */
   491   already_AddRefed<nsFrameSelection> FrameSelection() const;
   492   dom::Selection* DOMSelection() const;
   494   /**
   495    * Return selection ranges within the accessible subtree.
   496    */
   497   void GetSelectionDOMRanges(int16_t aType, nsTArray<nsRange*>* aRanges);
   499   nsresult SetSelectionRange(int32_t aStartPos, int32_t aEndPos);
   501   // Helpers
   502   nsresult GetDOMPointByFrameOffset(nsIFrame* aFrame, int32_t aOffset,
   503                                     Accessible* aAccessible,
   504                                     mozilla::a11y::DOMPoint* aPoint);
   506   /**
   507    * Set 'misspelled' text attribute and return range offsets where the
   508    * attibute is stretched. If the text is not misspelled at the given offset
   509    * then we expose only range offsets where text is not misspelled. The method
   510    * is used by TextAttributes() method.
   511    *
   512    * @param aIncludeDefAttrs  [in] points whether text attributes having default
   513    *                          values of attributes should be included
   514    * @param aSourceNode       [in] the node we start to traverse from
   515    * @param aStartOffset      [in, out] the start offset
   516    * @param aEndOffset        [in, out] the end offset
   517    * @param aAttributes       [out, optional] result attributes
   518    */
   519   nsresult GetSpellTextAttribute(nsINode* aNode, int32_t aNodeOffset,
   520                                  int32_t *aStartOffset,
   521                                  int32_t *aEndOffset,
   522                                  nsIPersistentProperties *aAttributes);
   524 private:
   525   /**
   526    * End text offsets array.
   527    */
   528   mutable nsTArray<uint32_t> mOffsets;
   529 };
   532 ////////////////////////////////////////////////////////////////////////////////
   533 // Accessible downcasting method
   535 inline HyperTextAccessible*
   536 Accessible::AsHyperText()
   537 {
   538   return IsHyperText() ? static_cast<HyperTextAccessible*>(this) : nullptr;
   539 }
   541 } // namespace a11y
   542 } // namespace mozilla
   544 #endif

mercurial