SelectionManager.h (3839B)
1 /* -*- Mode: C++; tab-width: 4; 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/. */ 5 6 #ifndef mozilla_a11y_SelectionManager_h__ 7 #define mozilla_a11y_SelectionManager_h__ 8 9 #include "nsISelectionController.h" 10 #include "nsISelectionListener.h" 11 #include "mozilla/WeakPtr.h" 12 13 namespace mozilla { 14 15 class PresShell; 16 17 namespace dom { 18 class AbstractRange; 19 class Element; 20 class Selection; 21 } // namespace dom 22 23 namespace a11y { 24 25 class AccEvent; 26 class HyperTextAccessible; 27 28 /** 29 * This special accessibility class is for the caret and selection management. 30 * There is only 1 visible caret per top level window. However, there may be 31 * several visible selections. 32 * 33 * The important selections are the one owned by each document, and the one in 34 * the currently focused control. 35 * 36 * On Windows this class is used to move an invisible system caret that 37 * shadows the Mozilla caret. Windows will also automatically map this to 38 * the MSAA caret accessible object (via OBJID_CARET) (as opposed to the root 39 * accessible tree for a window which is retrieved with OBJID_CLIENT). 40 * 41 * For ATK and IAccessible2, this class is used to fire caret move and 42 * selection change events. 43 */ 44 45 struct SelData; 46 47 class SelectionManager : public nsISelectionListener { 48 public: 49 // nsISupports 50 // implemented by derived nsAccessibilityService 51 52 // nsISelectionListener 53 NS_DECL_NSISELECTIONLISTENER 54 55 // SelectionManager 56 void Shutdown() { ClearControlSelectionListener(); } 57 58 /** 59 * Listen to selection events on the focused control. 60 * 61 * Note: only one control's selection events are listened to at a time. This 62 * will remove the previous control's selection listener. 63 */ 64 void SetControlSelectionListener(dom::Element* aFocusedElm); 65 66 /** 67 * Stop listening to selection events on the control. 68 */ 69 void ClearControlSelectionListener(); 70 71 /** 72 * Listen to selection events on the document. 73 */ 74 void AddDocSelectionListener(PresShell* aPresShell); 75 76 /** 77 * Stop listening to selection events for a given document 78 */ 79 void RemoveDocSelectionListener(PresShell* aPresShell); 80 81 /** 82 * Process delayed event, results in caret move and text selection change 83 * events. 84 */ 85 void ProcessTextSelChangeEvent(AccEvent* aEvent); 86 87 /** 88 * Gets the current caret offset/hypertext accessible pair. If there is no 89 * current pair, then returns -1 for the offset and a nullptr for the 90 * accessible. 91 */ 92 inline HyperTextAccessible* AccessibleWithCaret(int32_t* aCaret) { 93 if (aCaret) *aCaret = mCaretOffset; 94 95 return mAccWithCaret; 96 } 97 98 inline void ResetCaretOffset() { 99 mCaretOffset = -1; 100 mAccWithCaret = nullptr; 101 } 102 103 /** 104 * Called by DOM when a selection range is added/removed. 105 * We need this because nsISelectionListener isn't sufficient for spelling 106 * errors, etc., since it only tells us that there was a change, not which 107 * range changed. We don't want to unnecessarily push a cache update for all 108 * Accessibles in the entire selection. 109 * Returns false if these notifications aren't required for this selection 110 * type at this time. 111 */ 112 static bool SelectionRangeChanged(SelectionType aType, 113 const dom::AbstractRange& aRange); 114 115 ~SelectionManager(); 116 117 protected: 118 SelectionManager(); 119 120 /** 121 * Process DOM selection change. Fire selection and caret move events. 122 */ 123 void ProcessSelectionChanged(SelData* aSelData); 124 125 private: 126 // Currently focused control. 127 int32_t mCaretOffset; 128 HyperTextAccessible* mAccWithCaret; 129 WeakPtr<dom::Selection> mCurrCtrlNormalSel; 130 }; 131 132 } // namespace a11y 133 } // namespace mozilla 134 135 #endif