editor/libeditor/base/nsSelectionState.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.

michael@0 1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
michael@0 2 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 3 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 5
michael@0 6 #ifndef __selectionstate_h__
michael@0 7 #define __selectionstate_h__
michael@0 8
michael@0 9 #include "nsCOMPtr.h"
michael@0 10 #include "nsIDOMNode.h"
michael@0 11 #include "nsINode.h"
michael@0 12 #include "nsTArray.h"
michael@0 13 #include "nscore.h"
michael@0 14
michael@0 15 class nsCycleCollectionTraversalCallback;
michael@0 16 class nsIDOMCharacterData;
michael@0 17 class nsIDOMRange;
michael@0 18 class nsISelection;
michael@0 19 class nsRange;
michael@0 20 namespace mozilla {
michael@0 21 namespace dom {
michael@0 22 class Selection;
michael@0 23 }
michael@0 24 }
michael@0 25
michael@0 26 /***************************************************************************
michael@0 27 * class for recording selection info. stores selection as collection of
michael@0 28 * { {startnode, startoffset} , {endnode, endoffset} } tuples. Can't store
michael@0 29 * ranges since dom gravity will possibly change the ranges.
michael@0 30 */
michael@0 31
michael@0 32 // first a helper struct for saving/setting ranges
michael@0 33 struct nsRangeStore MOZ_FINAL
michael@0 34 {
michael@0 35 nsRangeStore();
michael@0 36
michael@0 37 private:
michael@0 38 // Private destructor, to discourage deletion outside of Release():
michael@0 39 ~nsRangeStore();
michael@0 40
michael@0 41 public:
michael@0 42 nsresult StoreRange(nsIDOMRange *aRange);
michael@0 43 nsresult GetRange(nsRange** outRange);
michael@0 44
michael@0 45 NS_INLINE_DECL_REFCOUNTING(nsRangeStore)
michael@0 46
michael@0 47 nsCOMPtr<nsIDOMNode> startNode;
michael@0 48 int32_t startOffset;
michael@0 49 nsCOMPtr<nsIDOMNode> endNode;
michael@0 50 int32_t endOffset;
michael@0 51 // DEBUG: static int32_t n;
michael@0 52 };
michael@0 53
michael@0 54 class nsSelectionState
michael@0 55 {
michael@0 56 public:
michael@0 57
michael@0 58 nsSelectionState();
michael@0 59 ~nsSelectionState();
michael@0 60
michael@0 61 void DoTraverse(nsCycleCollectionTraversalCallback &cb);
michael@0 62 void DoUnlink() { MakeEmpty(); }
michael@0 63
michael@0 64 void SaveSelection(mozilla::dom::Selection *aSel);
michael@0 65 nsresult RestoreSelection(nsISelection *aSel);
michael@0 66 bool IsCollapsed();
michael@0 67 bool IsEqual(nsSelectionState *aSelState);
michael@0 68 void MakeEmpty();
michael@0 69 bool IsEmpty();
michael@0 70 protected:
michael@0 71 nsTArray<nsRefPtr<nsRangeStore> > mArray;
michael@0 72
michael@0 73 friend class nsRangeUpdater;
michael@0 74 };
michael@0 75
michael@0 76 class nsRangeUpdater
michael@0 77 {
michael@0 78 public:
michael@0 79
michael@0 80 nsRangeUpdater();
michael@0 81 ~nsRangeUpdater();
michael@0 82
michael@0 83 void RegisterRangeItem(nsRangeStore *aRangeItem);
michael@0 84 void DropRangeItem(nsRangeStore *aRangeItem);
michael@0 85 nsresult RegisterSelectionState(nsSelectionState &aSelState);
michael@0 86 nsresult DropSelectionState(nsSelectionState &aSelState);
michael@0 87
michael@0 88 // editor selection gravity routines. Note that we can't always depend on
michael@0 89 // DOM Range gravity to do what we want to the "real" selection. For instance,
michael@0 90 // if you move a node, that corresponds to deleting it and reinserting it.
michael@0 91 // DOM Range gravity will promote the selection out of the node on deletion,
michael@0 92 // which is not what you want if you know you are reinserting it.
michael@0 93 nsresult SelAdjCreateNode(nsIDOMNode *aParent, int32_t aPosition);
michael@0 94 nsresult SelAdjInsertNode(nsIDOMNode *aParent, int32_t aPosition);
michael@0 95 void SelAdjDeleteNode(nsIDOMNode *aNode);
michael@0 96 nsresult SelAdjSplitNode(nsIDOMNode *aOldRightNode, int32_t aOffset, nsIDOMNode *aNewLeftNode);
michael@0 97 nsresult SelAdjJoinNodes(nsIDOMNode *aLeftNode,
michael@0 98 nsIDOMNode *aRightNode,
michael@0 99 nsIDOMNode *aParent,
michael@0 100 int32_t aOffset,
michael@0 101 int32_t aOldLeftNodeLength);
michael@0 102 nsresult SelAdjInsertText(nsIDOMCharacterData *aTextNode, int32_t aOffset, const nsAString &aString);
michael@0 103 nsresult SelAdjDeleteText(nsIDOMCharacterData *aTextNode, int32_t aOffset, int32_t aLength);
michael@0 104 // the following gravity routines need will/did sandwiches, because the other gravity
michael@0 105 // routines will be called inside of these sandwiches, but should be ignored.
michael@0 106 nsresult WillReplaceContainer();
michael@0 107 nsresult DidReplaceContainer(nsIDOMNode *aOriginalNode, nsIDOMNode *aNewNode);
michael@0 108 nsresult WillRemoveContainer();
michael@0 109 nsresult DidRemoveContainer(nsIDOMNode *aNode, nsIDOMNode *aParent, int32_t aOffset, uint32_t aNodeOrigLen);
michael@0 110 nsresult WillInsertContainer();
michael@0 111 nsresult DidInsertContainer();
michael@0 112 void WillMoveNode();
michael@0 113 void DidMoveNode(nsINode* aOldParent, int32_t aOldOffset,
michael@0 114 nsINode* aNewParent, int32_t aNewOffset);
michael@0 115 protected:
michael@0 116 nsTArray<nsRefPtr<nsRangeStore> > mArray;
michael@0 117 bool mLock;
michael@0 118 };
michael@0 119
michael@0 120
michael@0 121 /***************************************************************************
michael@0 122 * helper class for using nsSelectionState. stack based class for doing
michael@0 123 * preservation of dom points across editor actions
michael@0 124 */
michael@0 125
michael@0 126 class MOZ_STACK_CLASS nsAutoTrackDOMPoint
michael@0 127 {
michael@0 128 private:
michael@0 129 nsRangeUpdater &mRU;
michael@0 130 nsCOMPtr<nsIDOMNode> *mNode;
michael@0 131 int32_t *mOffset;
michael@0 132 nsRefPtr<nsRangeStore> mRangeItem;
michael@0 133 public:
michael@0 134 nsAutoTrackDOMPoint(nsRangeUpdater &aRangeUpdater, nsCOMPtr<nsIDOMNode> *aNode, int32_t *aOffset) :
michael@0 135 mRU(aRangeUpdater)
michael@0 136 ,mNode(aNode)
michael@0 137 ,mOffset(aOffset)
michael@0 138 {
michael@0 139 mRangeItem = new nsRangeStore();
michael@0 140 mRangeItem->startNode = *mNode;
michael@0 141 mRangeItem->endNode = *mNode;
michael@0 142 mRangeItem->startOffset = *mOffset;
michael@0 143 mRangeItem->endOffset = *mOffset;
michael@0 144 mRU.RegisterRangeItem(mRangeItem);
michael@0 145 }
michael@0 146
michael@0 147 ~nsAutoTrackDOMPoint()
michael@0 148 {
michael@0 149 mRU.DropRangeItem(mRangeItem);
michael@0 150 *mNode = mRangeItem->startNode;
michael@0 151 *mOffset = mRangeItem->startOffset;
michael@0 152 }
michael@0 153 };
michael@0 154
michael@0 155
michael@0 156
michael@0 157 /***************************************************************************
michael@0 158 * another helper class for nsSelectionState. stack based class for doing
michael@0 159 * Will/DidReplaceContainer()
michael@0 160 */
michael@0 161
michael@0 162 class MOZ_STACK_CLASS nsAutoReplaceContainerSelNotify
michael@0 163 {
michael@0 164 private:
michael@0 165 nsRangeUpdater &mRU;
michael@0 166 nsIDOMNode *mOriginalNode;
michael@0 167 nsIDOMNode *mNewNode;
michael@0 168
michael@0 169 public:
michael@0 170 nsAutoReplaceContainerSelNotify(nsRangeUpdater &aRangeUpdater, nsIDOMNode *aOriginalNode, nsIDOMNode *aNewNode) :
michael@0 171 mRU(aRangeUpdater)
michael@0 172 ,mOriginalNode(aOriginalNode)
michael@0 173 ,mNewNode(aNewNode)
michael@0 174 {
michael@0 175 mRU.WillReplaceContainer();
michael@0 176 }
michael@0 177
michael@0 178 ~nsAutoReplaceContainerSelNotify()
michael@0 179 {
michael@0 180 mRU.DidReplaceContainer(mOriginalNode, mNewNode);
michael@0 181 }
michael@0 182 };
michael@0 183
michael@0 184
michael@0 185 /***************************************************************************
michael@0 186 * another helper class for nsSelectionState. stack based class for doing
michael@0 187 * Will/DidRemoveContainer()
michael@0 188 */
michael@0 189
michael@0 190 class MOZ_STACK_CLASS nsAutoRemoveContainerSelNotify
michael@0 191 {
michael@0 192 private:
michael@0 193 nsRangeUpdater &mRU;
michael@0 194 nsIDOMNode *mNode;
michael@0 195 nsIDOMNode *mParent;
michael@0 196 int32_t mOffset;
michael@0 197 uint32_t mNodeOrigLen;
michael@0 198
michael@0 199 public:
michael@0 200 nsAutoRemoveContainerSelNotify(nsRangeUpdater& aRangeUpdater,
michael@0 201 nsINode* aNode,
michael@0 202 nsINode* aParent,
michael@0 203 int32_t aOffset,
michael@0 204 uint32_t aNodeOrigLen)
michael@0 205 : mRU(aRangeUpdater)
michael@0 206 , mNode(aNode->AsDOMNode())
michael@0 207 , mParent(aParent->AsDOMNode())
michael@0 208 , mOffset(aOffset)
michael@0 209 , mNodeOrigLen(aNodeOrigLen)
michael@0 210 {
michael@0 211 mRU.WillRemoveContainer();
michael@0 212 }
michael@0 213
michael@0 214 ~nsAutoRemoveContainerSelNotify()
michael@0 215 {
michael@0 216 mRU.DidRemoveContainer(mNode, mParent, mOffset, mNodeOrigLen);
michael@0 217 }
michael@0 218 };
michael@0 219
michael@0 220 /***************************************************************************
michael@0 221 * another helper class for nsSelectionState. stack based class for doing
michael@0 222 * Will/DidInsertContainer()
michael@0 223 */
michael@0 224
michael@0 225 class MOZ_STACK_CLASS nsAutoInsertContainerSelNotify
michael@0 226 {
michael@0 227 private:
michael@0 228 nsRangeUpdater &mRU;
michael@0 229
michael@0 230 public:
michael@0 231 nsAutoInsertContainerSelNotify(nsRangeUpdater &aRangeUpdater) :
michael@0 232 mRU(aRangeUpdater)
michael@0 233 {
michael@0 234 mRU.WillInsertContainer();
michael@0 235 }
michael@0 236
michael@0 237 ~nsAutoInsertContainerSelNotify()
michael@0 238 {
michael@0 239 mRU.DidInsertContainer();
michael@0 240 }
michael@0 241 };
michael@0 242
michael@0 243
michael@0 244 /***************************************************************************
michael@0 245 * another helper class for nsSelectionState. stack based class for doing
michael@0 246 * Will/DidMoveNode()
michael@0 247 */
michael@0 248
michael@0 249 class MOZ_STACK_CLASS nsAutoMoveNodeSelNotify
michael@0 250 {
michael@0 251 private:
michael@0 252 nsRangeUpdater &mRU;
michael@0 253 nsINode* mOldParent;
michael@0 254 nsINode* mNewParent;
michael@0 255 int32_t mOldOffset;
michael@0 256 int32_t mNewOffset;
michael@0 257
michael@0 258 public:
michael@0 259 nsAutoMoveNodeSelNotify(nsRangeUpdater &aRangeUpdater,
michael@0 260 nsINode* aOldParent,
michael@0 261 int32_t aOldOffset,
michael@0 262 nsINode* aNewParent,
michael@0 263 int32_t aNewOffset)
michael@0 264 : mRU(aRangeUpdater)
michael@0 265 , mOldParent(aOldParent)
michael@0 266 , mNewParent(aNewParent)
michael@0 267 , mOldOffset(aOldOffset)
michael@0 268 , mNewOffset(aNewOffset)
michael@0 269 {
michael@0 270 MOZ_ASSERT(aOldParent);
michael@0 271 MOZ_ASSERT(aNewParent);
michael@0 272 mRU.WillMoveNode();
michael@0 273 }
michael@0 274
michael@0 275 ~nsAutoMoveNodeSelNotify()
michael@0 276 {
michael@0 277 mRU.DidMoveNode(mOldParent, mOldOffset, mNewParent, mNewOffset);
michael@0 278 }
michael@0 279 };
michael@0 280
michael@0 281 #endif
michael@0 282
michael@0 283

mercurial