LCOV - code coverage report
Current view: directory - editor/libeditor/html - TypeInState.cpp (source / functions) Found Hit Coverage
Test: app.info Lines: 166 2 1.2 %
Date: 2012-06-02 Functions: 32 2 6.2 %

       1                 : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2                 : /* ***** BEGIN LICENSE BLOCK *****
       3                 :  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
       4                 :  *
       5                 :  * The contents of this file are subject to the Mozilla Public License Version
       6                 :  * 1.1 (the "License"); you may not use this file except in compliance with
       7                 :  * the License. You may obtain a copy of the License at
       8                 :  * http://www.mozilla.org/MPL/
       9                 :  *
      10                 :  * Software distributed under the License is distributed on an "AS IS" basis,
      11                 :  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
      12                 :  * for the specific language governing rights and limitations under the
      13                 :  * License.
      14                 :  *
      15                 :  * The Original Code is mozilla.org code.
      16                 :  *
      17                 :  * The Initial Developer of the Original Code is
      18                 :  * Netscape Communications Corporation.
      19                 :  * Portions created by the Initial Developer are Copyright (C) 1998
      20                 :  * the Initial Developer. All Rights Reserved.
      21                 :  *
      22                 :  * Contributor(s):
      23                 :  *   Pierre Phaneuf <pp@ludusdesign.com>
      24                 :  *
      25                 :  * Alternatively, the contents of this file may be used under the terms of
      26                 :  * either of the GNU General Public License Version 2 or later (the "GPL"),
      27                 :  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
      28                 :  * in which case the provisions of the GPL or the LGPL are applicable instead
      29                 :  * of those above. If you wish to allow use of your version of this file only
      30                 :  * under the terms of either the GPL or the LGPL, and not to allow others to
      31                 :  * use your version of this file under the terms of the MPL, indicate your
      32                 :  * decision by deleting the provisions above and replace them with the notice
      33                 :  * and other provisions required by the GPL or the LGPL. If you do not delete
      34                 :  * the provisions above, a recipient may use your version of this file under
      35                 :  * the terms of any one of the MPL, the GPL or the LGPL.
      36                 :  *
      37                 :  * ***** END LICENSE BLOCK ***** */
      38                 : 
      39                 : 
      40                 : #include "TypeInState.h"
      41                 : #include "nsEditor.h"
      42                 : 
      43                 : /********************************************************************
      44                 :  *                     XPCOM cruft 
      45                 :  *******************************************************************/
      46                 : 
      47            1464 : NS_IMPL_CYCLE_COLLECTION_1(TypeInState, mLastSelectionContainer)
      48               0 : NS_IMPL_CYCLE_COLLECTING_ADDREF(TypeInState)
      49               0 : NS_IMPL_CYCLE_COLLECTING_RELEASE(TypeInState)
      50               0 : NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(TypeInState)
      51               0 :   NS_INTERFACE_MAP_ENTRY(nsISelectionListener)
      52               0 :   NS_INTERFACE_MAP_ENTRY(nsISupports)
      53               0 : NS_INTERFACE_MAP_END
      54                 : 
      55                 : /********************************************************************
      56                 :  *                   public methods
      57                 :  *******************************************************************/
      58                 :  
      59               0 : TypeInState::TypeInState() :
      60                 :  mSetArray()
      61                 : ,mClearedArray()
      62                 : ,mRelativeFontSize(0)
      63               0 : ,mLastSelectionOffset(0)
      64                 : {
      65               0 :   Reset();
      66               0 : }
      67                 : 
      68               0 : TypeInState::~TypeInState()
      69                 : {
      70                 :   // Call Reset() to release any data that may be in
      71                 :   // mClearedArray and mSetArray.
      72                 : 
      73               0 :   Reset();
      74               0 : }
      75                 : 
      76               0 : nsresult TypeInState::UpdateSelState(nsISelection *aSelection)
      77                 : {
      78               0 :   NS_ENSURE_TRUE(aSelection, NS_ERROR_NULL_POINTER);
      79                 :   
      80               0 :   bool isCollapsed = false;
      81               0 :   nsresult result = aSelection->GetIsCollapsed(&isCollapsed);
      82                 : 
      83               0 :   NS_ENSURE_SUCCESS(result, result);
      84                 : 
      85               0 :   if (isCollapsed)
      86                 :   {
      87               0 :     result = nsEditor::GetStartNodeAndOffset(aSelection, getter_AddRefs(mLastSelectionContainer), &mLastSelectionOffset);
      88                 :   }
      89               0 :   return result;
      90                 : }
      91                 : 
      92                 : 
      93               0 : NS_IMETHODIMP TypeInState::NotifySelectionChanged(nsIDOMDocument *, nsISelection *aSelection, PRInt16)
      94                 : {
      95                 :   // XXX: Selection currently generates bogus selection changed notifications
      96                 :   // XXX: (bug 140303). It can notify us when the selection hasn't actually
      97                 :   // XXX: changed, and it notifies us more than once for the same change.
      98                 :   // XXX:
      99                 :   // XXX: The following code attempts to work around the bogus notifications,
     100                 :   // XXX: and should probably be removed once bug 140303 is fixed.
     101                 :   // XXX:
     102                 :   // XXX: This code temporarily fixes the problem where clicking the mouse in
     103                 :   // XXX: the same location clears the type-in-state.
     104                 : 
     105               0 :   if (aSelection)
     106                 :   {
     107               0 :     bool isCollapsed = false;
     108               0 :     nsresult result = aSelection->GetIsCollapsed(&isCollapsed);
     109               0 :     NS_ENSURE_SUCCESS(result, result);
     110                 : 
     111               0 :     PRInt32 rangeCount = 0;
     112               0 :     result = aSelection->GetRangeCount(&rangeCount);
     113               0 :     NS_ENSURE_SUCCESS(result, result);
     114                 : 
     115               0 :     if (isCollapsed && rangeCount)
     116                 :     {
     117               0 :       nsCOMPtr<nsIDOMNode> selNode;
     118               0 :       PRInt32 selOffset = 0;
     119                 : 
     120               0 :       result = nsEditor::GetStartNodeAndOffset(aSelection, getter_AddRefs(selNode), &selOffset);
     121                 : 
     122               0 :       NS_ENSURE_SUCCESS(result, result);
     123                 : 
     124               0 :       if (selNode && selNode == mLastSelectionContainer && selOffset == mLastSelectionOffset)
     125                 :       {
     126                 :         // We got a bogus selection changed notification!
     127               0 :         return NS_OK;
     128                 :       }
     129                 : 
     130               0 :       mLastSelectionContainer = selNode;
     131               0 :       mLastSelectionOffset = selOffset;
     132                 :     }
     133                 :     else
     134                 :     {
     135               0 :       mLastSelectionContainer = nsnull;
     136               0 :       mLastSelectionOffset = 0;
     137                 :     }
     138                 :   }
     139                 : 
     140               0 :   Reset(); 
     141               0 :   return NS_OK;
     142                 : }
     143                 : 
     144               0 : void TypeInState::Reset()
     145                 : {
     146               0 :   for(PRUint32 i = 0, n = mClearedArray.Length(); i < n; i++) {
     147               0 :     delete mClearedArray[i];
     148                 :   }
     149               0 :   mClearedArray.Clear();
     150               0 :   for(PRUint32 i = 0, n = mSetArray.Length(); i < n; i++) {
     151               0 :     delete mSetArray[i];
     152                 :   }
     153               0 :   mSetArray.Clear();
     154               0 : }
     155                 : 
     156                 : 
     157               0 : nsresult TypeInState::SetProp(nsIAtom *aProp, const nsString &aAttr, const nsString &aValue)
     158                 : {
     159                 :   // special case for big/small, these nest
     160               0 :   if (nsEditProperty::big == aProp)
     161                 :   {
     162               0 :     mRelativeFontSize++;
     163               0 :     return NS_OK;
     164                 :   }
     165               0 :   if (nsEditProperty::small == aProp)
     166                 :   {
     167               0 :     mRelativeFontSize--;
     168               0 :     return NS_OK;
     169                 :   }
     170                 : 
     171                 :   PRInt32 index;
     172                 :   PropItem *item;
     173                 : 
     174               0 :   if (IsPropSet(aProp,aAttr,nsnull,index))
     175                 :   {
     176                 :     // if it's already set, update the value
     177               0 :     item = mSetArray[index];
     178               0 :     item->value = aValue;
     179                 :   }
     180                 :   else 
     181                 :   {
     182                 :     // make a new propitem
     183               0 :     item = new PropItem(aProp,aAttr,aValue);
     184               0 :     NS_ENSURE_TRUE(item, NS_ERROR_OUT_OF_MEMORY);
     185                 :     
     186                 :     // add it to the list of set properties
     187               0 :     mSetArray.AppendElement(item);
     188                 :     
     189                 :     // remove it from the list of cleared properties, if we have a match
     190               0 :     RemovePropFromClearedList(aProp,aAttr);  
     191                 :   }
     192                 :     
     193               0 :   return NS_OK;
     194                 : }
     195                 : 
     196                 : 
     197               0 : nsresult TypeInState::ClearAllProps()
     198                 : {
     199                 :   // null prop means "all" props
     200               0 :   return ClearProp(nsnull,EmptyString());
     201                 : }
     202                 : 
     203               0 : nsresult TypeInState::ClearProp(nsIAtom *aProp, const nsString &aAttr)
     204                 : {
     205                 :   // if it's already cleared we are done
     206               0 :   if (IsPropCleared(aProp,aAttr)) return NS_OK;
     207                 :   
     208                 :   // make a new propitem
     209               0 :   PropItem *item = new PropItem(aProp,aAttr,EmptyString());
     210               0 :   NS_ENSURE_TRUE(item, NS_ERROR_OUT_OF_MEMORY);
     211                 :   
     212                 :   // remove it from the list of set properties, if we have a match
     213               0 :   RemovePropFromSetList(aProp,aAttr);
     214                 :   
     215                 :   // add it to the list of cleared properties
     216               0 :   mClearedArray.AppendElement(item);
     217                 :   
     218               0 :   return NS_OK;
     219                 : }
     220                 : 
     221                 : 
     222                 : /***************************************************************************
     223                 :  *    TakeClearProperty: hands back next property item on the clear list.
     224                 :  *                       caller assumes ownership of PropItem and must delete it.
     225                 :  */  
     226               0 : nsresult TypeInState::TakeClearProperty(PropItem **outPropItem)
     227                 : {
     228               0 :   NS_ENSURE_TRUE(outPropItem, NS_ERROR_NULL_POINTER);
     229               0 :   *outPropItem = nsnull;
     230               0 :   PRUint32 count = mClearedArray.Length();
     231               0 :   if (count)
     232                 :   {
     233               0 :     count--; // indizes are zero based
     234               0 :     *outPropItem = mClearedArray[count];
     235               0 :     mClearedArray.RemoveElementAt(count);
     236                 :   }
     237               0 :   return NS_OK;
     238                 : }
     239                 : 
     240                 : /***************************************************************************
     241                 :  *    TakeSetProperty: hands back next poroperty item on the set list.
     242                 :  *                     caller assumes ownership of PropItem and must delete it.
     243                 :  */  
     244               0 : nsresult TypeInState::TakeSetProperty(PropItem **outPropItem)
     245                 : {
     246               0 :   NS_ENSURE_TRUE(outPropItem, NS_ERROR_NULL_POINTER);
     247               0 :   *outPropItem = nsnull;
     248               0 :   PRUint32 count = mSetArray.Length();
     249               0 :   if (count)
     250                 :   {
     251               0 :     count--; // indizes are zero based
     252               0 :     *outPropItem = mSetArray[count];
     253               0 :     mSetArray.RemoveElementAt(count);
     254                 :   }
     255               0 :   return NS_OK;
     256                 : }
     257                 : 
     258                 : //**************************************************************************
     259                 : //    TakeRelativeFontSize: hands back relative font value, which is then
     260                 : //                          cleared out.
     261               0 : nsresult TypeInState::TakeRelativeFontSize(PRInt32 *outRelSize)
     262                 : {
     263               0 :   NS_ENSURE_TRUE(outRelSize, NS_ERROR_NULL_POINTER);
     264               0 :   *outRelSize = mRelativeFontSize;
     265               0 :   mRelativeFontSize = 0;
     266               0 :   return NS_OK;
     267                 : }
     268                 : 
     269               0 : nsresult TypeInState::GetTypingState(bool &isSet, bool &theSetting, nsIAtom *aProp)
     270                 : {
     271               0 :   return GetTypingState(isSet, theSetting, aProp, EmptyString(), nsnull);
     272                 : }
     273                 : 
     274               0 : nsresult TypeInState::GetTypingState(bool &isSet, 
     275                 :                                      bool &theSetting, 
     276                 :                                      nsIAtom *aProp,
     277                 :                                      const nsString &aAttr, 
     278                 :                                      nsString *aValue)
     279                 : {
     280               0 :   if (IsPropSet(aProp, aAttr, aValue))
     281                 :   {
     282               0 :     isSet = true;
     283               0 :     theSetting = true;
     284                 :   }
     285               0 :   else if (IsPropCleared(aProp, aAttr))
     286                 :   {
     287               0 :     isSet = true;
     288               0 :     theSetting = false;
     289                 :   }
     290                 :   else
     291                 :   {
     292               0 :     isSet = false;
     293                 :   }
     294               0 :   return NS_OK;
     295                 : }
     296                 : 
     297                 : 
     298                 : 
     299                 : /********************************************************************
     300                 :  *                   protected methods
     301                 :  *******************************************************************/
     302                 :  
     303               0 : nsresult TypeInState::RemovePropFromSetList(nsIAtom *aProp, 
     304                 :                                             const nsString &aAttr)
     305                 : {
     306                 :   PRInt32 index;
     307               0 :   if (!aProp)
     308                 :   {
     309                 :     // clear _all_ props
     310               0 :     for(PRUint32 i = 0, n = mSetArray.Length(); i < n; i++) {
     311               0 :       delete mSetArray[i];
     312                 :     }
     313               0 :     mSetArray.Clear();
     314               0 :     mRelativeFontSize=0;
     315                 :   }
     316               0 :   else if (FindPropInList(aProp, aAttr, nsnull, mSetArray, index))
     317                 :   {
     318               0 :     delete mSetArray[index];
     319               0 :     mSetArray.RemoveElementAt(index);
     320                 :   }
     321               0 :   return NS_OK;
     322                 : }
     323                 : 
     324                 : 
     325               0 : nsresult TypeInState::RemovePropFromClearedList(nsIAtom *aProp, 
     326                 :                                             const nsString &aAttr)
     327                 : {
     328                 :   PRInt32 index;
     329               0 :   if (FindPropInList(aProp, aAttr, nsnull, mClearedArray, index))
     330                 :   {
     331               0 :     delete mClearedArray[index];
     332               0 :     mClearedArray.RemoveElementAt(index);
     333                 :   }
     334               0 :   return NS_OK;
     335                 : }
     336                 : 
     337                 : 
     338               0 : bool TypeInState::IsPropSet(nsIAtom *aProp, 
     339                 :                               const nsString &aAttr,
     340                 :                               nsString* outValue)
     341                 : {
     342                 :   PRInt32 i;
     343               0 :   return IsPropSet(aProp, aAttr, outValue, i);
     344                 : }
     345                 : 
     346                 : 
     347               0 : bool TypeInState::IsPropSet(nsIAtom *aProp, 
     348                 :                               const nsString &aAttr,
     349                 :                               nsString *outValue,
     350                 :                               PRInt32 &outIndex)
     351                 : {
     352                 :   // linear search.  list should be short.
     353               0 :   PRUint32 i, count = mSetArray.Length();
     354               0 :   for (i=0; i<count; i++)
     355                 :   {
     356               0 :     PropItem *item = mSetArray[i];
     357               0 :     if ( (item->tag == aProp) &&
     358               0 :          (item->attr == aAttr) )
     359                 :     {
     360               0 :       if (outValue) *outValue = item->value;
     361               0 :       outIndex = i;
     362               0 :       return true;
     363                 :     }
     364                 :   }
     365               0 :   return false;
     366                 : }
     367                 : 
     368                 : 
     369               0 : bool TypeInState::IsPropCleared(nsIAtom *aProp, 
     370                 :                                   const nsString &aAttr)
     371                 : {
     372                 :   PRInt32 i;
     373               0 :   return IsPropCleared(aProp, aAttr, i);
     374                 : }
     375                 : 
     376                 : 
     377               0 : bool TypeInState::IsPropCleared(nsIAtom *aProp, 
     378                 :                                   const nsString &aAttr,
     379                 :                                   PRInt32 &outIndex)
     380                 : {
     381               0 :   if (FindPropInList(aProp, aAttr, nsnull, mClearedArray, outIndex))
     382               0 :     return true;
     383               0 :   if (FindPropInList(0, EmptyString(), nsnull, mClearedArray, outIndex))
     384                 :   {
     385                 :     // special case for all props cleared
     386               0 :     outIndex = -1;
     387               0 :     return true;
     388                 :   }
     389               0 :   return false;
     390                 : }
     391                 : 
     392               0 : bool TypeInState::FindPropInList(nsIAtom *aProp, 
     393                 :                                    const nsAString &aAttr,
     394                 :                                    nsAString *outValue,
     395                 :                                    nsTArray<PropItem*> &aList,
     396                 :                                    PRInt32 &outIndex)
     397                 : {
     398                 :   // linear search.  list should be short.
     399               0 :   PRUint32 i, count = aList.Length();
     400               0 :   for (i=0; i<count; i++)
     401                 :   {
     402               0 :     PropItem *item = aList[i];
     403               0 :     if ( (item->tag == aProp) &&
     404               0 :          (item->attr == aAttr) ) 
     405                 :     {
     406               0 :       if (outValue) *outValue = item->value;
     407               0 :       outIndex = i;
     408               0 :       return true;
     409                 :     }
     410                 :   }
     411               0 :   return false;
     412                 : }
     413                 : 
     414                 : 
     415                 : 
     416                 : /********************************************************************
     417                 :  *    PropItem: helper struct for TypeInState
     418                 :  *******************************************************************/
     419                 : 
     420               0 : PropItem::PropItem() : 
     421                 :  tag(nsnull)
     422                 : ,attr()
     423               0 : ,value()
     424                 : {
     425               0 :   MOZ_COUNT_CTOR(PropItem);
     426               0 : }
     427                 : 
     428               0 : PropItem::PropItem(nsIAtom *aTag, const nsAString &aAttr, const nsAString &aValue) :
     429                 :  tag(aTag)
     430                 : ,attr(aAttr)
     431               0 : ,value(aValue)
     432                 : {
     433               0 :   MOZ_COUNT_CTOR(PropItem);
     434               0 : }
     435                 : 
     436               0 : PropItem::~PropItem()
     437                 : {
     438               0 :   MOZ_COUNT_DTOR(PropItem);
     439            4392 : }

Generated by: LCOV version 1.7