LCOV - code coverage report
Current view: top level - editor/libeditor - SelectionState.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 47 329 14.3 %
Date: 2017-07-14 16:53:18 Functions: 10 39 25.6 %
Legend: Lines: hit not hit

          Line data    Source code
       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/. */
       5             : 
       6             : #include "mozilla/SelectionState.h"
       7             : 
       8             : #include "mozilla/Assertions.h"         // for MOZ_ASSERT, etc.
       9             : #include "mozilla/EditorUtils.h"        // for EditorUtils
      10             : #include "mozilla/dom/Selection.h"      // for Selection
      11             : #include "nsAString.h"                  // for nsAString::Length
      12             : #include "nsCycleCollectionParticipant.h"
      13             : #include "nsDebug.h"                    // for NS_ENSURE_TRUE, etc.
      14             : #include "nsError.h"                    // for NS_OK, etc.
      15             : #include "nsIContent.h"                 // for nsIContent
      16             : #include "nsIDOMCharacterData.h"        // for nsIDOMCharacterData
      17             : #include "nsIDOMNode.h"                 // for nsIDOMNode
      18             : #include "nsISupportsImpl.h"            // for nsRange::Release
      19             : #include "nsRange.h"                    // for nsRange
      20             : 
      21             : namespace mozilla {
      22             : 
      23             : using namespace dom;
      24             : 
      25             : /******************************************************************************
      26             :  * mozilla::SelectionState
      27             :  *
      28             :  * Class for recording selection info.  Stores selection as collection of
      29             :  * { {startnode, startoffset} , {endnode, endoffset} } tuples.  Can't store
      30             :  * ranges since dom gravity will possibly change the ranges.
      31             :  ******************************************************************************/
      32           3 : SelectionState::SelectionState()
      33             : {
      34           3 : }
      35             : 
      36           4 : SelectionState::~SelectionState()
      37             : {
      38           2 :   MakeEmpty();
      39           2 : }
      40             : 
      41             : void
      42           2 : SelectionState::SaveSelection(Selection* aSel)
      43             : {
      44           2 :   MOZ_ASSERT(aSel);
      45           2 :   int32_t arrayCount = mArray.Length();
      46           2 :   int32_t rangeCount = aSel->RangeCount();
      47             : 
      48             :   // if we need more items in the array, new them
      49           2 :   if (arrayCount < rangeCount) {
      50           2 :     for (int32_t i = arrayCount; i < rangeCount; i++) {
      51           1 :       mArray.AppendElement();
      52           1 :       mArray[i] = new RangeItem();
      53             :     }
      54           1 :   } else if (arrayCount > rangeCount) {
      55             :     // else if we have too many, delete them
      56           0 :     for (int32_t i = arrayCount - 1; i >= rangeCount; i--) {
      57           0 :       mArray.RemoveElementAt(i);
      58             :     }
      59             :   }
      60             : 
      61             :   // now store the selection ranges
      62           3 :   for (int32_t i = 0; i < rangeCount; i++) {
      63           1 :     mArray[i]->StoreRange(aSel->GetRangeAt(i));
      64             :   }
      65           2 : }
      66             : 
      67             : nsresult
      68           0 : SelectionState::RestoreSelection(Selection* aSel)
      69             : {
      70           0 :   NS_ENSURE_TRUE(aSel, NS_ERROR_NULL_POINTER);
      71             : 
      72             :   // clear out selection
      73           0 :   aSel->RemoveAllRanges();
      74             : 
      75             :   // set the selection ranges anew
      76           0 :   size_t arrayCount = mArray.Length();
      77           0 :   for (size_t i = 0; i < arrayCount; i++) {
      78           0 :     RefPtr<nsRange> range = mArray[i]->GetRange();
      79           0 :     NS_ENSURE_TRUE(range, NS_ERROR_UNEXPECTED);
      80             : 
      81           0 :     nsresult rv = aSel->AddRange(range);
      82           0 :     if (NS_FAILED(rv)) {
      83           0 :       return rv;
      84             :     }
      85             :   }
      86           0 :   return NS_OK;
      87             : }
      88             : 
      89             : bool
      90           0 : SelectionState::IsCollapsed()
      91             : {
      92           0 :   if (mArray.Length() != 1) {
      93           0 :     return false;
      94             :   }
      95           0 :   RefPtr<nsRange> range = mArray[0]->GetRange();
      96           0 :   NS_ENSURE_TRUE(range, false);
      97           0 :   bool bIsCollapsed = false;
      98           0 :   range->GetCollapsed(&bIsCollapsed);
      99           0 :   return bIsCollapsed;
     100             : }
     101             : 
     102             : bool
     103           0 : SelectionState::IsEqual(SelectionState* aSelState)
     104             : {
     105           0 :   NS_ENSURE_TRUE(aSelState, false);
     106           0 :   size_t myCount = mArray.Length(), itsCount = aSelState->mArray.Length();
     107           0 :   if (myCount != itsCount) {
     108           0 :     return false;
     109             :   }
     110           0 :   if (!myCount) {
     111           0 :     return false;
     112             :   }
     113             : 
     114           0 :   for (size_t i = 0; i < myCount; i++) {
     115           0 :     RefPtr<nsRange> myRange = mArray[i]->GetRange();
     116           0 :     RefPtr<nsRange> itsRange = aSelState->mArray[i]->GetRange();
     117           0 :     NS_ENSURE_TRUE(myRange && itsRange, false);
     118             : 
     119             :     int16_t compResult;
     120             :     nsresult rv;
     121           0 :     rv = myRange->CompareBoundaryPoints(nsIDOMRange::START_TO_START, itsRange, &compResult);
     122           0 :     if (NS_FAILED(rv) || compResult) {
     123           0 :       return false;
     124             :     }
     125           0 :     rv = myRange->CompareBoundaryPoints(nsIDOMRange::END_TO_END, itsRange, &compResult);
     126           0 :     if (NS_FAILED(rv) || compResult) {
     127           0 :       return false;
     128             :     }
     129             :   }
     130             :   // if we got here, they are equal
     131           0 :   return true;
     132             : }
     133             : 
     134             : void
     135           2 : SelectionState::MakeEmpty()
     136             : {
     137             :   // free any items in the array
     138           2 :   mArray.Clear();
     139           2 : }
     140             : 
     141             : bool
     142           0 : SelectionState::IsEmpty()
     143             : {
     144           0 :   return mArray.IsEmpty();
     145             : }
     146             : 
     147             : /******************************************************************************
     148             :  * mozilla::RangeUpdater
     149             :  *
     150             :  * Class for updating nsRanges in response to editor actions.
     151             :  ******************************************************************************/
     152             : 
     153           1 : RangeUpdater::RangeUpdater()
     154           1 :   : mLock(false)
     155             : {
     156           1 : }
     157             : 
     158           0 : RangeUpdater::~RangeUpdater()
     159             : {
     160             :   // nothing to do, we don't own the items in our array.
     161           0 : }
     162             : 
     163             : void
     164           0 : RangeUpdater::RegisterRangeItem(RangeItem* aRangeItem)
     165             : {
     166           0 :   if (!aRangeItem) {
     167           0 :     return;
     168             :   }
     169           0 :   if (mArray.Contains(aRangeItem)) {
     170           0 :     NS_ERROR("tried to register an already registered range");
     171           0 :     return;  // don't register it again.  It would get doubly adjusted.
     172             :   }
     173           0 :   mArray.AppendElement(aRangeItem);
     174             : }
     175             : 
     176             : void
     177           0 : RangeUpdater::DropRangeItem(RangeItem* aRangeItem)
     178             : {
     179           0 :   if (!aRangeItem) {
     180           0 :     return;
     181             :   }
     182           0 :   mArray.RemoveElement(aRangeItem);
     183             : }
     184             : 
     185             : nsresult
     186           0 : RangeUpdater::RegisterSelectionState(SelectionState& aSelState)
     187             : {
     188           0 :   size_t theCount = aSelState.mArray.Length();
     189           0 :   if (theCount < 1) {
     190           0 :     return NS_ERROR_FAILURE;
     191             :   }
     192             : 
     193           0 :   for (size_t i = 0; i < theCount; i++) {
     194           0 :     RegisterRangeItem(aSelState.mArray[i]);
     195             :   }
     196             : 
     197           0 :   return NS_OK;
     198             : }
     199             : 
     200             : nsresult
     201           0 : RangeUpdater::DropSelectionState(SelectionState& aSelState)
     202             : {
     203           0 :   size_t theCount = aSelState.mArray.Length();
     204           0 :   if (theCount < 1) {
     205           0 :     return NS_ERROR_FAILURE;
     206             :   }
     207             : 
     208           0 :   for (size_t i = 0; i < theCount; i++) {
     209           0 :     DropRangeItem(aSelState.mArray[i]);
     210             :   }
     211             : 
     212           0 :   return NS_OK;
     213             : }
     214             : 
     215             : // gravity methods:
     216             : 
     217             : nsresult
     218           3 : RangeUpdater::SelAdjCreateNode(nsINode* aParent,
     219             :                                int32_t aPosition)
     220             : {
     221           3 :   if (mLock) {
     222             :     // lock set by Will/DidReplaceParent, etc...
     223           0 :     return NS_OK;
     224             :   }
     225           3 :   NS_ENSURE_TRUE(aParent, NS_ERROR_NULL_POINTER);
     226           3 :   size_t count = mArray.Length();
     227           3 :   if (!count) {
     228           3 :     return NS_OK;
     229             :   }
     230             : 
     231           0 :   for (size_t i = 0; i < count; i++) {
     232           0 :     RangeItem* item = mArray[i];
     233           0 :     NS_ENSURE_TRUE(item, NS_ERROR_NULL_POINTER);
     234             : 
     235           0 :     if (item->mStartContainer == aParent && item->mStartOffset > aPosition) {
     236           0 :       item->mStartOffset++;
     237             :     }
     238           0 :     if (item->mEndContainer == aParent && item->mEndOffset > aPosition) {
     239           0 :       item->mEndOffset++;
     240             :     }
     241             :   }
     242           0 :   return NS_OK;
     243             : }
     244             : 
     245             : nsresult
     246           3 : RangeUpdater::SelAdjInsertNode(nsINode* aParent,
     247             :                                int32_t aPosition)
     248             : {
     249           3 :   return SelAdjCreateNode(aParent, aPosition);
     250             : }
     251             : 
     252             : void
     253           1 : RangeUpdater::SelAdjDeleteNode(nsINode* aNode)
     254             : {
     255           1 :   if (mLock) {
     256             :     // lock set by Will/DidReplaceParent, etc...
     257           1 :     return;
     258             :   }
     259           1 :   MOZ_ASSERT(aNode);
     260           1 :   size_t count = mArray.Length();
     261           1 :   if (!count) {
     262           1 :     return;
     263             :   }
     264             : 
     265           0 :   nsCOMPtr<nsINode> parent = aNode->GetParentNode();
     266           0 :   int32_t offset = parent ? parent->IndexOf(aNode) : -1;
     267             : 
     268             :   // check for range endpoints that are after aNode and in the same parent
     269           0 :   for (size_t i = 0; i < count; i++) {
     270           0 :     RangeItem* item = mArray[i];
     271           0 :     MOZ_ASSERT(item);
     272             : 
     273           0 :     if (item->mStartContainer == parent && item->mStartOffset > offset) {
     274           0 :       item->mStartOffset--;
     275             :     }
     276           0 :     if (item->mEndContainer == parent && item->mEndOffset > offset) {
     277           0 :       item->mEndOffset--;
     278             :     }
     279             : 
     280             :     // check for range endpoints that are in aNode
     281           0 :     if (item->mStartContainer == aNode) {
     282           0 :       item->mStartContainer = parent;
     283           0 :       item->mStartOffset = offset;
     284             :     }
     285           0 :     if (item->mEndContainer == aNode) {
     286           0 :       item->mEndContainer = parent;
     287           0 :       item->mEndOffset = offset;
     288             :     }
     289             : 
     290             :     // check for range endpoints that are in descendants of aNode
     291           0 :     nsCOMPtr<nsINode> oldStart;
     292           0 :     if (EditorUtils::IsDescendantOf(item->mStartContainer, aNode)) {
     293           0 :       oldStart = item->mStartContainer;  // save for efficiency hack below.
     294           0 :       item->mStartContainer = parent;
     295           0 :       item->mStartOffset = offset;
     296             :     }
     297             : 
     298             :     // avoid having to call IsDescendantOf() for common case of range startnode == range endnode.
     299           0 :     if (item->mEndContainer == oldStart ||
     300           0 :         EditorUtils::IsDescendantOf(item->mEndContainer, aNode)) {
     301           0 :       item->mEndContainer = parent;
     302           0 :       item->mEndOffset = offset;
     303             :     }
     304             :   }
     305             : }
     306             : 
     307             : nsresult
     308           0 : RangeUpdater::SelAdjSplitNode(nsIContent& aOldRightNode,
     309             :                               int32_t aOffset,
     310             :                               nsIContent* aNewLeftNode)
     311             : {
     312           0 :   if (mLock) {
     313             :     // lock set by Will/DidReplaceParent, etc...
     314           0 :     return NS_OK;
     315             :   }
     316           0 :   NS_ENSURE_TRUE(aNewLeftNode, NS_ERROR_NULL_POINTER);
     317           0 :   size_t count = mArray.Length();
     318           0 :   if (!count) {
     319           0 :     return NS_OK;
     320             :   }
     321             : 
     322           0 :   nsCOMPtr<nsINode> parent = aOldRightNode.GetParentNode();
     323           0 :   int32_t offset = parent ? parent->IndexOf(&aOldRightNode) : -1;
     324             : 
     325             :   // first part is same as inserting aNewLeftnode
     326           0 :   nsresult rv = SelAdjInsertNode(parent, offset - 1);
     327           0 :   NS_ENSURE_SUCCESS(rv, rv);
     328             : 
     329             :   // next step is to check for range enpoints inside aOldRightNode
     330           0 :   for (size_t i = 0; i < count; i++) {
     331           0 :     RangeItem* item = mArray[i];
     332           0 :     NS_ENSURE_TRUE(item, NS_ERROR_NULL_POINTER);
     333             : 
     334           0 :     if (item->mStartContainer == &aOldRightNode) {
     335           0 :       if (item->mStartOffset > aOffset) {
     336           0 :         item->mStartOffset -= aOffset;
     337             :       } else {
     338           0 :         item->mStartContainer = aNewLeftNode;
     339             :       }
     340             :     }
     341           0 :     if (item->mEndContainer == &aOldRightNode) {
     342           0 :       if (item->mEndOffset > aOffset) {
     343           0 :         item->mEndOffset -= aOffset;
     344             :       } else {
     345           0 :         item->mEndContainer = aNewLeftNode;
     346             :       }
     347             :     }
     348             :   }
     349           0 :   return NS_OK;
     350             : }
     351             : 
     352             : nsresult
     353           0 : RangeUpdater::SelAdjJoinNodes(nsINode& aLeftNode,
     354             :                               nsINode& aRightNode,
     355             :                               nsINode& aParent,
     356             :                               int32_t aOffset,
     357             :                               int32_t aOldLeftNodeLength)
     358             : {
     359           0 :   if (mLock) {
     360             :     // lock set by Will/DidReplaceParent, etc...
     361           0 :     return NS_OK;
     362             :   }
     363           0 :   size_t count = mArray.Length();
     364           0 :   if (!count) {
     365           0 :     return NS_OK;
     366             :   }
     367             : 
     368           0 :   for (size_t i = 0; i < count; i++) {
     369           0 :     RangeItem* item = mArray[i];
     370           0 :     NS_ENSURE_TRUE(item, NS_ERROR_NULL_POINTER);
     371             : 
     372           0 :     if (item->mStartContainer == &aParent) {
     373             :       // adjust start point in aParent
     374           0 :       if (item->mStartOffset > aOffset) {
     375           0 :         item->mStartOffset--;
     376           0 :       } else if (item->mStartOffset == aOffset) {
     377             :         // join keeps right hand node
     378           0 :         item->mStartContainer = &aRightNode;
     379           0 :         item->mStartOffset = aOldLeftNodeLength;
     380             :       }
     381           0 :     } else if (item->mStartContainer == &aRightNode) {
     382             :       // adjust start point in aRightNode
     383           0 :       item->mStartOffset += aOldLeftNodeLength;
     384           0 :     } else if (item->mStartContainer == &aLeftNode) {
     385             :       // adjust start point in aLeftNode
     386           0 :       item->mStartContainer = &aRightNode;
     387             :     }
     388             : 
     389           0 :     if (item->mEndContainer == &aParent) {
     390             :       // adjust end point in aParent
     391           0 :       if (item->mEndOffset > aOffset) {
     392           0 :         item->mEndOffset--;
     393           0 :       } else if (item->mEndOffset == aOffset) {
     394             :         // join keeps right hand node
     395           0 :         item->mEndContainer = &aRightNode;
     396           0 :         item->mEndOffset = aOldLeftNodeLength;
     397             :       }
     398           0 :     } else if (item->mEndContainer == &aRightNode) {
     399             :       // adjust end point in aRightNode
     400           0 :        item->mEndOffset += aOldLeftNodeLength;
     401           0 :     } else if (item->mEndContainer == &aLeftNode) {
     402             :       // adjust end point in aLeftNode
     403           0 :       item->mEndContainer = &aRightNode;
     404             :     }
     405             :   }
     406             : 
     407           0 :   return NS_OK;
     408             : }
     409             : 
     410             : void
     411           0 : RangeUpdater::SelAdjInsertText(Text& aTextNode,
     412             :                                int32_t aOffset,
     413             :                                const nsAString& aString)
     414             : {
     415           0 :   if (mLock) {
     416             :     // lock set by Will/DidReplaceParent, etc...
     417           0 :     return;
     418             :   }
     419             : 
     420           0 :   size_t count = mArray.Length();
     421           0 :   if (!count) {
     422           0 :     return;
     423             :   }
     424             : 
     425           0 :   size_t len = aString.Length();
     426           0 :   for (size_t i = 0; i < count; i++) {
     427           0 :     RangeItem* item = mArray[i];
     428           0 :     MOZ_ASSERT(item);
     429             : 
     430           0 :     if (item->mStartContainer == &aTextNode && item->mStartOffset > aOffset) {
     431           0 :       item->mStartOffset += len;
     432             :     }
     433           0 :     if (item->mEndContainer == &aTextNode && item->mEndOffset > aOffset) {
     434           0 :       item->mEndOffset += len;
     435             :     }
     436             :   }
     437           0 :   return;
     438             : }
     439             : 
     440             : nsresult
     441           0 : RangeUpdater::SelAdjDeleteText(nsIContent* aTextNode,
     442             :                                int32_t aOffset,
     443             :                                int32_t aLength)
     444             : {
     445           0 :   if (mLock) {
     446             :     // lock set by Will/DidReplaceParent, etc...
     447           0 :     return NS_OK;
     448             :   }
     449             : 
     450           0 :   size_t count = mArray.Length();
     451           0 :   if (!count) {
     452           0 :     return NS_OK;
     453             :   }
     454           0 :   NS_ENSURE_TRUE(aTextNode, NS_ERROR_NULL_POINTER);
     455             : 
     456           0 :   for (size_t i = 0; i < count; i++) {
     457           0 :     RangeItem* item = mArray[i];
     458           0 :     NS_ENSURE_TRUE(item, NS_ERROR_NULL_POINTER);
     459             : 
     460           0 :     if (item->mStartContainer == aTextNode && item->mStartOffset > aOffset) {
     461           0 :       item->mStartOffset -= aLength;
     462           0 :       if (item->mStartOffset < 0) {
     463           0 :         item->mStartOffset = 0;
     464             :       }
     465             :     }
     466           0 :     if (item->mEndContainer == aTextNode && item->mEndOffset > aOffset) {
     467           0 :       item->mEndOffset -= aLength;
     468           0 :       if (item->mEndOffset < 0) {
     469           0 :         item->mEndOffset = 0;
     470             :       }
     471             :     }
     472             :   }
     473           0 :   return NS_OK;
     474             : }
     475             : 
     476             : nsresult
     477           0 : RangeUpdater::SelAdjDeleteText(nsIDOMCharacterData* aTextNode,
     478             :                                int32_t aOffset,
     479             :                                int32_t aLength)
     480             : {
     481           0 :   nsCOMPtr<nsIContent> textNode = do_QueryInterface(aTextNode);
     482           0 :   return SelAdjDeleteText(textNode, aOffset, aLength);
     483             : }
     484             : 
     485             : nsresult
     486           0 : RangeUpdater::WillReplaceContainer()
     487             : {
     488           0 :   if (mLock) {
     489           0 :     return NS_ERROR_UNEXPECTED;
     490             :   }
     491           0 :   mLock = true;
     492           0 :   return NS_OK;
     493             : }
     494             : 
     495             : nsresult
     496           0 : RangeUpdater::DidReplaceContainer(Element* aOriginalNode,
     497             :                                   Element* aNewNode)
     498             : {
     499           0 :   NS_ENSURE_TRUE(mLock, NS_ERROR_UNEXPECTED);
     500           0 :   mLock = false;
     501             : 
     502           0 :   NS_ENSURE_TRUE(aOriginalNode && aNewNode, NS_ERROR_NULL_POINTER);
     503           0 :   size_t count = mArray.Length();
     504           0 :   if (!count) {
     505           0 :     return NS_OK;
     506             :   }
     507             : 
     508           0 :   for (size_t i = 0; i < count; i++) {
     509           0 :     RangeItem* item = mArray[i];
     510           0 :     NS_ENSURE_TRUE(item, NS_ERROR_NULL_POINTER);
     511             : 
     512           0 :     if (item->mStartContainer == aOriginalNode) {
     513           0 :       item->mStartContainer = aNewNode;
     514             :     }
     515           0 :     if (item->mEndContainer == aOriginalNode) {
     516           0 :       item->mEndContainer = aNewNode;
     517             :     }
     518             :   }
     519           0 :   return NS_OK;
     520             : }
     521             : 
     522             : nsresult
     523           0 : RangeUpdater::WillRemoveContainer()
     524             : {
     525           0 :   if (mLock) {
     526           0 :     return NS_ERROR_UNEXPECTED;
     527             :   }
     528           0 :   mLock = true;
     529           0 :   return NS_OK;
     530             : }
     531             : 
     532             : nsresult
     533           0 : RangeUpdater::DidRemoveContainer(nsINode* aNode,
     534             :                                  nsINode* aParent,
     535             :                                  int32_t aOffset,
     536             :                                  uint32_t aNodeOrigLen)
     537             : {
     538           0 :   NS_ENSURE_TRUE(mLock, NS_ERROR_UNEXPECTED);
     539           0 :   mLock = false;
     540             : 
     541           0 :   NS_ENSURE_TRUE(aNode && aParent, NS_ERROR_NULL_POINTER);
     542           0 :   size_t count = mArray.Length();
     543           0 :   if (!count) {
     544           0 :     return NS_OK;
     545             :   }
     546             : 
     547           0 :   for (size_t i = 0; i < count; i++) {
     548           0 :     RangeItem* item = mArray[i];
     549           0 :     NS_ENSURE_TRUE(item, NS_ERROR_NULL_POINTER);
     550             : 
     551           0 :     if (item->mStartContainer == aNode) {
     552           0 :       item->mStartContainer = aParent;
     553           0 :       item->mStartOffset += aOffset;
     554           0 :     } else if (item->mStartContainer == aParent &&
     555           0 :                item->mStartOffset > aOffset) {
     556           0 :       item->mStartOffset += (int32_t)aNodeOrigLen - 1;
     557             :     }
     558             : 
     559           0 :     if (item->mEndContainer == aNode) {
     560           0 :       item->mEndContainer = aParent;
     561           0 :       item->mEndOffset += aOffset;
     562           0 :     } else if (item->mEndContainer == aParent && item->mEndOffset > aOffset) {
     563           0 :       item->mEndOffset += (int32_t)aNodeOrigLen - 1;
     564             :     }
     565             :   }
     566           0 :   return NS_OK;
     567             : }
     568             : 
     569             : nsresult
     570           0 : RangeUpdater::DidRemoveContainer(nsIDOMNode* aNode,
     571             :                                  nsIDOMNode* aParent,
     572             :                                  int32_t aOffset,
     573             :                                  uint32_t aNodeOrigLen)
     574             : {
     575           0 :   nsCOMPtr<nsINode> node = do_QueryInterface(aNode);
     576           0 :   nsCOMPtr<nsINode> parent = do_QueryInterface(aParent);
     577           0 :   return DidRemoveContainer(node, parent, aOffset, aNodeOrigLen);
     578             : }
     579             : 
     580             : nsresult
     581           0 : RangeUpdater::WillInsertContainer()
     582             : {
     583           0 :   if (mLock) {
     584           0 :     return NS_ERROR_UNEXPECTED;
     585             :   }
     586           0 :   mLock = true;
     587           0 :   return NS_OK;
     588             : }
     589             : 
     590             : nsresult
     591           0 : RangeUpdater::DidInsertContainer()
     592             : {
     593           0 :   NS_ENSURE_TRUE(mLock, NS_ERROR_UNEXPECTED);
     594           0 :   mLock = false;
     595           0 :   return NS_OK;
     596             : }
     597             : 
     598             : void
     599           0 : RangeUpdater::WillMoveNode()
     600             : {
     601           0 :   mLock = true;
     602           0 : }
     603             : 
     604             : void
     605           0 : RangeUpdater::DidMoveNode(nsINode* aOldParent, int32_t aOldOffset,
     606             :                             nsINode* aNewParent, int32_t aNewOffset)
     607             : {
     608           0 :   MOZ_ASSERT(aOldParent);
     609           0 :   MOZ_ASSERT(aNewParent);
     610           0 :   NS_ENSURE_TRUE_VOID(mLock);
     611           0 :   mLock = false;
     612             : 
     613           0 :   for (size_t i = 0, count = mArray.Length(); i < count; ++i) {
     614           0 :     RangeItem* item = mArray[i];
     615           0 :     NS_ENSURE_TRUE_VOID(item);
     616             : 
     617             :     // like a delete in aOldParent
     618           0 :     if (item->mStartContainer == aOldParent &&
     619           0 :         item->mStartOffset > aOldOffset) {
     620           0 :       item->mStartOffset--;
     621             :     }
     622           0 :     if (item->mEndContainer == aOldParent && item->mEndOffset > aOldOffset) {
     623           0 :       item->mEndOffset--;
     624             :     }
     625             : 
     626             :     // and like an insert in aNewParent
     627           0 :     if (item->mStartContainer == aNewParent &&
     628           0 :         item->mStartOffset > aNewOffset) {
     629           0 :       item->mStartOffset++;
     630             :     }
     631           0 :     if (item->mEndContainer == aNewParent && item->mEndOffset > aNewOffset) {
     632           0 :       item->mEndOffset++;
     633             :     }
     634             :   }
     635             : }
     636             : 
     637             : /******************************************************************************
     638             :  * mozilla::RangeItem
     639             :  *
     640             :  * Helper struct for SelectionState.  This stores range endpoints.
     641             :  ******************************************************************************/
     642             : 
     643           1 : RangeItem::RangeItem()
     644             : {
     645           1 : }
     646             : 
     647           0 : RangeItem::~RangeItem()
     648             : {
     649           0 : }
     650             : 
     651           0 : NS_IMPL_CYCLE_COLLECTION(RangeItem, mStartContainer, mEndContainer)
     652           0 : NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(RangeItem, AddRef)
     653           0 : NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(RangeItem, Release)
     654             : 
     655             : void
     656           1 : RangeItem::StoreRange(nsRange* aRange)
     657             : {
     658           1 :   MOZ_ASSERT(aRange);
     659           1 :   mStartContainer = aRange->GetStartContainer();
     660           1 :   mStartOffset = aRange->StartOffset();
     661           1 :   mEndContainer = aRange->GetEndContainer();
     662           1 :   mEndOffset = aRange->EndOffset();
     663           1 : }
     664             : 
     665             : already_AddRefed<nsRange>
     666           0 : RangeItem::GetRange()
     667             : {
     668           0 :   RefPtr<nsRange> range = new nsRange(mStartContainer);
     669           0 :   if (NS_FAILED(range->SetStartAndEnd(mStartContainer, mStartOffset,
     670             :                                       mEndContainer, mEndOffset))) {
     671           0 :     return nullptr;
     672             :   }
     673           0 :   return range.forget();
     674             : }
     675             : 
     676             : } // namespace mozilla

Generated by: LCOV version 1.13