LCOV - code coverage report
Current view: top level - editor/libeditor - TypeInState.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 0 160 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 30 0.0 %
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 "TypeInState.h"
       7             : 
       8             : #include <stddef.h>
       9             : 
      10             : #include "nsError.h"
      11             : #include "mozilla/EditorBase.h"
      12             : #include "mozilla/mozalloc.h"
      13             : #include "mozilla/dom/Selection.h"
      14             : #include "nsAString.h"
      15             : #include "nsDebug.h"
      16             : #include "nsGkAtoms.h"
      17             : #include "nsIDOMNode.h"
      18             : #include "nsISupportsBase.h"
      19             : #include "nsISupportsImpl.h"
      20             : #include "nsReadableUtils.h"
      21             : #include "nsStringFwd.h"
      22             : 
      23             : class nsIAtom;
      24             : class nsIDOMDocument;
      25             : 
      26             : namespace mozilla {
      27             : 
      28             : using namespace dom;
      29             : 
      30             : /********************************************************************
      31             :  * mozilla::TypeInState
      32             :  *******************************************************************/
      33             : 
      34           0 : NS_IMPL_CYCLE_COLLECTION(TypeInState, mLastSelectionContainer)
      35           0 : NS_IMPL_CYCLE_COLLECTING_ADDREF(TypeInState)
      36           0 : NS_IMPL_CYCLE_COLLECTING_RELEASE(TypeInState)
      37           0 : NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(TypeInState)
      38           0 :   NS_INTERFACE_MAP_ENTRY(nsISelectionListener)
      39           0 :   NS_INTERFACE_MAP_ENTRY(nsISupports)
      40           0 : NS_INTERFACE_MAP_END
      41             : 
      42           0 : TypeInState::TypeInState()
      43             :   : mRelativeFontSize(0)
      44           0 :   , mLastSelectionOffset(0)
      45             : {
      46           0 :   Reset();
      47           0 : }
      48             : 
      49           0 : TypeInState::~TypeInState()
      50             : {
      51             :   // Call Reset() to release any data that may be in
      52             :   // mClearedArray and mSetArray.
      53             : 
      54           0 :   Reset();
      55           0 : }
      56             : 
      57             : nsresult
      58           0 : TypeInState::UpdateSelState(Selection* aSelection)
      59             : {
      60           0 :   NS_ENSURE_TRUE(aSelection, NS_ERROR_NULL_POINTER);
      61             : 
      62           0 :   if (!aSelection->Collapsed()) {
      63           0 :     return NS_OK;
      64             :   }
      65             : 
      66           0 :   return EditorBase::GetStartNodeAndOffset(
      67           0 :                        aSelection, getter_AddRefs(mLastSelectionContainer),
      68           0 :                        &mLastSelectionOffset);
      69             : }
      70             : 
      71             : 
      72             : NS_IMETHODIMP
      73           0 : TypeInState::NotifySelectionChanged(nsIDOMDocument* aDOMDocument,
      74             :                                     nsISelection* aSelection,
      75             :                                     int16_t aReason)
      76             : {
      77             :   // XXX: Selection currently generates bogus selection changed notifications
      78             :   // XXX: (bug 140303). It can notify us when the selection hasn't actually
      79             :   // XXX: changed, and it notifies us more than once for the same change.
      80             :   // XXX:
      81             :   // XXX: The following code attempts to work around the bogus notifications,
      82             :   // XXX: and should probably be removed once bug 140303 is fixed.
      83             :   // XXX:
      84             :   // XXX: This code temporarily fixes the problem where clicking the mouse in
      85             :   // XXX: the same location clears the type-in-state.
      86             :   RefPtr<Selection> selection =
      87           0 :     aSelection ? aSelection->AsSelection() : nullptr;
      88             : 
      89           0 :   if (aSelection) {
      90           0 :     int32_t rangeCount = selection->RangeCount();
      91             : 
      92           0 :     if (selection->Collapsed() && rangeCount) {
      93           0 :       nsCOMPtr<nsIDOMNode> selNode;
      94           0 :       int32_t selOffset = 0;
      95             : 
      96             :       nsresult rv =
      97           0 :         EditorBase::GetStartNodeAndOffset(selection, getter_AddRefs(selNode),
      98           0 :                                           &selOffset);
      99             : 
     100           0 :       NS_ENSURE_SUCCESS(rv, rv);
     101             : 
     102           0 :       if (selNode &&
     103           0 :           selNode == mLastSelectionContainer &&
     104           0 :           selOffset == mLastSelectionOffset) {
     105             :         // We got a bogus selection changed notification!
     106           0 :         return NS_OK;
     107             :       }
     108             : 
     109           0 :       mLastSelectionContainer = selNode;
     110           0 :       mLastSelectionOffset = selOffset;
     111             :     } else {
     112           0 :       mLastSelectionContainer = nullptr;
     113           0 :       mLastSelectionOffset = 0;
     114             :     }
     115             :   }
     116             : 
     117           0 :   Reset();
     118           0 :   return NS_OK;
     119             : }
     120             : 
     121             : void
     122           0 : TypeInState::Reset()
     123             : {
     124           0 :   for (size_t i = 0, n = mClearedArray.Length(); i < n; i++) {
     125           0 :     delete mClearedArray[i];
     126             :   }
     127           0 :   mClearedArray.Clear();
     128           0 :   for (size_t i = 0, n = mSetArray.Length(); i < n; i++) {
     129           0 :     delete mSetArray[i];
     130             :   }
     131           0 :   mSetArray.Clear();
     132           0 : }
     133             : 
     134             : 
     135             : void
     136           0 : TypeInState::SetProp(nsIAtom* aProp,
     137             :                      const nsAString& aAttr,
     138             :                      const nsAString& aValue)
     139             : {
     140             :   // special case for big/small, these nest
     141           0 :   if (nsGkAtoms::big == aProp) {
     142           0 :     mRelativeFontSize++;
     143           0 :     return;
     144             :   }
     145           0 :   if (nsGkAtoms::small == aProp) {
     146           0 :     mRelativeFontSize--;
     147           0 :     return;
     148             :   }
     149             : 
     150             :   int32_t index;
     151           0 :   if (IsPropSet(aProp, aAttr, nullptr, index)) {
     152             :     // if it's already set, update the value
     153           0 :     mSetArray[index]->value = aValue;
     154           0 :     return;
     155             :   }
     156             : 
     157             :   // Make a new propitem and add it to the list of set properties.
     158           0 :   mSetArray.AppendElement(new PropItem(aProp, aAttr, aValue));
     159             : 
     160             :   // remove it from the list of cleared properties, if we have a match
     161           0 :   RemovePropFromClearedList(aProp, aAttr);
     162             : }
     163             : 
     164             : 
     165             : void
     166           0 : TypeInState::ClearAllProps()
     167             : {
     168             :   // null prop means "all" props
     169           0 :   ClearProp(nullptr, EmptyString());
     170           0 : }
     171             : 
     172             : void
     173           0 : TypeInState::ClearProp(nsIAtom* aProp,
     174             :                        const nsAString& aAttr)
     175             : {
     176             :   // if it's already cleared we are done
     177           0 :   if (IsPropCleared(aProp, aAttr)) {
     178           0 :     return;
     179             :   }
     180             : 
     181             :   // make a new propitem
     182           0 :   PropItem* item = new PropItem(aProp, aAttr, EmptyString());
     183             : 
     184             :   // remove it from the list of set properties, if we have a match
     185           0 :   RemovePropFromSetList(aProp, aAttr);
     186             : 
     187             :   // add it to the list of cleared properties
     188           0 :   mClearedArray.AppendElement(item);
     189             : }
     190             : 
     191             : 
     192             : /**
     193             :  * TakeClearProperty() hands back next property item on the clear list.
     194             :  * Caller assumes ownership of PropItem and must delete it.
     195             :  */
     196             : UniquePtr<PropItem>
     197           0 : TypeInState::TakeClearProperty()
     198             : {
     199           0 :   size_t count = mClearedArray.Length();
     200           0 :   if (!count) {
     201           0 :     return nullptr;
     202             :   }
     203             : 
     204           0 :   --count; // indices are zero based
     205           0 :   PropItem* propItem = mClearedArray[count];
     206           0 :   mClearedArray.RemoveElementAt(count);
     207           0 :   return UniquePtr<PropItem>(propItem);
     208             : }
     209             : 
     210             : /**
     211             :  * TakeSetProperty() hands back next poroperty item on the set list.
     212             :  * Caller assumes ownership of PropItem and must delete it.
     213             :  */
     214             : UniquePtr<PropItem>
     215           0 : TypeInState::TakeSetProperty()
     216             : {
     217           0 :   size_t count = mSetArray.Length();
     218           0 :   if (!count) {
     219           0 :     return nullptr;
     220             :   }
     221           0 :   count--; // indices are zero based
     222           0 :   PropItem* propItem = mSetArray[count];
     223           0 :   mSetArray.RemoveElementAt(count);
     224           0 :   return UniquePtr<PropItem>(propItem);
     225             : }
     226             : 
     227             : /**
     228             :  * TakeRelativeFontSize() hands back relative font value, which is then
     229             :  * cleared out.
     230             :  */
     231             : int32_t
     232           0 : TypeInState::TakeRelativeFontSize()
     233             : {
     234           0 :   int32_t relSize = mRelativeFontSize;
     235           0 :   mRelativeFontSize = 0;
     236           0 :   return relSize;
     237             : }
     238             : 
     239             : void
     240           0 : TypeInState::GetTypingState(bool& isSet,
     241             :                             bool& theSetting,
     242             :                             nsIAtom* aProp)
     243             : {
     244           0 :   GetTypingState(isSet, theSetting, aProp, EmptyString(), nullptr);
     245           0 : }
     246             : 
     247             : void
     248           0 : TypeInState::GetTypingState(bool& isSet,
     249             :                             bool& theSetting,
     250             :                             nsIAtom* aProp,
     251             :                             const nsString& aAttr,
     252             :                             nsString* aValue)
     253             : {
     254           0 :   if (IsPropSet(aProp, aAttr, aValue)) {
     255           0 :     isSet = true;
     256           0 :     theSetting = true;
     257           0 :   } else if (IsPropCleared(aProp, aAttr)) {
     258           0 :     isSet = true;
     259           0 :     theSetting = false;
     260             :   } else {
     261           0 :     isSet = false;
     262             :   }
     263           0 : }
     264             : 
     265             : void
     266           0 : TypeInState::RemovePropFromSetList(nsIAtom* aProp,
     267             :                                    const nsAString& aAttr)
     268             : {
     269             :   int32_t index;
     270           0 :   if (!aProp) {
     271             :     // clear _all_ props
     272           0 :     for (size_t i = 0, n = mSetArray.Length(); i < n; i++) {
     273           0 :       delete mSetArray[i];
     274             :     }
     275           0 :     mSetArray.Clear();
     276           0 :     mRelativeFontSize=0;
     277           0 :   } else if (FindPropInList(aProp, aAttr, nullptr, mSetArray, index)) {
     278           0 :     delete mSetArray[index];
     279           0 :     mSetArray.RemoveElementAt(index);
     280             :   }
     281           0 : }
     282             : 
     283             : void
     284           0 : TypeInState::RemovePropFromClearedList(nsIAtom* aProp,
     285             :                                        const nsAString& aAttr)
     286             : {
     287             :   int32_t index;
     288           0 :   if (FindPropInList(aProp, aAttr, nullptr, mClearedArray, index)) {
     289           0 :     delete mClearedArray[index];
     290           0 :     mClearedArray.RemoveElementAt(index);
     291             :   }
     292           0 : }
     293             : 
     294             : bool
     295           0 : TypeInState::IsPropSet(nsIAtom* aProp,
     296             :                        const nsAString& aAttr,
     297             :                        nsAString* outValue)
     298             : {
     299             :   int32_t i;
     300           0 :   return IsPropSet(aProp, aAttr, outValue, i);
     301             : }
     302             : 
     303             : bool
     304           0 : TypeInState::IsPropSet(nsIAtom* aProp,
     305             :                        const nsAString& aAttr,
     306             :                        nsAString* outValue,
     307             :                        int32_t& outIndex)
     308             : {
     309             :   // linear search.  list should be short.
     310           0 :   size_t count = mSetArray.Length();
     311           0 :   for (size_t i = 0; i < count; i++) {
     312           0 :     PropItem *item = mSetArray[i];
     313           0 :     if (item->tag == aProp && item->attr == aAttr) {
     314           0 :       if (outValue) {
     315           0 :         *outValue = item->value;
     316             :       }
     317           0 :       outIndex = i;
     318           0 :       return true;
     319             :     }
     320             :   }
     321           0 :   return false;
     322             : }
     323             : 
     324             : 
     325             : bool
     326           0 : TypeInState::IsPropCleared(nsIAtom* aProp,
     327             :                            const nsAString& aAttr)
     328             : {
     329             :   int32_t i;
     330           0 :   return IsPropCleared(aProp, aAttr, i);
     331             : }
     332             : 
     333             : 
     334             : bool
     335           0 : TypeInState::IsPropCleared(nsIAtom* aProp,
     336             :                            const nsAString& aAttr,
     337             :                            int32_t& outIndex)
     338             : {
     339           0 :   if (FindPropInList(aProp, aAttr, nullptr, mClearedArray, outIndex)) {
     340           0 :     return true;
     341             :   }
     342           0 :   if (FindPropInList(0, EmptyString(), nullptr, mClearedArray, outIndex)) {
     343             :     // special case for all props cleared
     344           0 :     outIndex = -1;
     345           0 :     return true;
     346             :   }
     347           0 :   return false;
     348             : }
     349             : 
     350             : bool
     351           0 : TypeInState::FindPropInList(nsIAtom* aProp,
     352             :                             const nsAString& aAttr,
     353             :                             nsAString* outValue,
     354             :                             nsTArray<PropItem*>& aList,
     355             :                             int32_t& outIndex)
     356             : {
     357             :   // linear search.  list should be short.
     358           0 :   size_t count = aList.Length();
     359           0 :   for (size_t i = 0; i < count; i++) {
     360           0 :     PropItem *item = aList[i];
     361           0 :     if (item->tag == aProp && item->attr == aAttr) {
     362           0 :       if (outValue) {
     363           0 :         *outValue = item->value;
     364             :       }
     365           0 :       outIndex = i;
     366           0 :       return true;
     367             :     }
     368             :   }
     369           0 :   return false;
     370             : }
     371             : 
     372             : /********************************************************************
     373             :  * mozilla::PropItem: helper struct for mozilla::TypeInState
     374             :  *******************************************************************/
     375             : 
     376           0 : PropItem::PropItem()
     377           0 :   : tag(nullptr)
     378             : {
     379           0 :   MOZ_COUNT_CTOR(PropItem);
     380           0 : }
     381             : 
     382           0 : PropItem::PropItem(nsIAtom* aTag,
     383             :                    const nsAString& aAttr,
     384           0 :                    const nsAString &aValue)
     385             :   : tag(aTag)
     386             :   , attr(aAttr)
     387           0 :   , value(aValue)
     388             : {
     389           0 :   MOZ_COUNT_CTOR(PropItem);
     390           0 : }
     391             : 
     392           0 : PropItem::~PropItem()
     393             : {
     394           0 :   MOZ_COUNT_DTOR(PropItem);
     395           0 : }
     396             : 
     397             : } // namespace mozilla

Generated by: LCOV version 1.13