LCOV - code coverage report
Current view: directory - editor/libeditor/base - PlaceholderTxn.cpp (source / functions) Found Hit Coverage
Test: app.info Lines: 119 2 1.7 %
Date: 2012-06-02 Functions: 21 2 9.5 %

       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-1999
      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                 : #include "PlaceholderTxn.h"
      40                 : #include "nsEditor.h"
      41                 : #include "IMETextTxn.h"
      42                 : #include "nsGkAtoms.h"
      43                 : 
      44               0 : PlaceholderTxn::PlaceholderTxn() :  EditAggregateTxn(), 
      45                 :                                     mAbsorb(true), 
      46                 :                                     mForwarding(nsnull),
      47                 :                                     mIMETextTxn(nsnull),
      48                 :                                     mCommitted(false),
      49                 :                                     mStartSel(nsnull),
      50                 :                                     mEndSel(),
      51               0 :                                     mEditor(nsnull)
      52                 : {
      53               0 : }
      54                 : 
      55            1464 : NS_IMPL_CYCLE_COLLECTION_CLASS(PlaceholderTxn)
      56                 : 
      57               0 : NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(PlaceholderTxn,
      58                 :                                                 EditAggregateTxn)
      59               0 :   tmp->mStartSel->DoUnlink();
      60               0 :   tmp->mEndSel.DoUnlink();
      61               0 : NS_IMPL_CYCLE_COLLECTION_UNLINK_END
      62                 : 
      63               0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(PlaceholderTxn,
      64                 :                                                   EditAggregateTxn)
      65               0 :   tmp->mStartSel->DoTraverse(cb);
      66               0 :   tmp->mEndSel.DoTraverse(cb);
      67               0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
      68                 : 
      69               0 : NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(PlaceholderTxn)
      70               0 :   NS_INTERFACE_MAP_ENTRY(nsIAbsorbingTransaction)
      71               0 :   NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
      72               0 : NS_INTERFACE_MAP_END_INHERITING(EditAggregateTxn)
      73                 : 
      74               0 : NS_IMPL_ADDREF_INHERITED(PlaceholderTxn, EditAggregateTxn)
      75               0 : NS_IMPL_RELEASE_INHERITED(PlaceholderTxn, EditAggregateTxn)
      76                 : 
      77               0 : NS_IMETHODIMP PlaceholderTxn::Init(nsIAtom *aName, nsSelectionState *aSelState, nsIEditor *aEditor)
      78                 : {
      79               0 :   NS_ENSURE_TRUE(aEditor && aSelState, NS_ERROR_NULL_POINTER);
      80                 : 
      81               0 :   mName = aName;
      82               0 :   mStartSel = aSelState;
      83               0 :   mEditor = aEditor;
      84               0 :   return NS_OK;
      85                 : }
      86                 : 
      87               0 : NS_IMETHODIMP PlaceholderTxn::DoTransaction(void)
      88                 : {
      89               0 :   return NS_OK;
      90                 : }
      91                 : 
      92               0 : NS_IMETHODIMP PlaceholderTxn::UndoTransaction(void)
      93                 : {
      94                 :   // undo txns
      95               0 :   nsresult res = EditAggregateTxn::UndoTransaction();
      96               0 :   NS_ENSURE_SUCCESS(res, res);
      97                 :   
      98               0 :   NS_ENSURE_TRUE(mStartSel, NS_ERROR_NULL_POINTER);
      99                 : 
     100                 :   // now restore selection
     101               0 :   nsCOMPtr<nsISelection> selection;
     102               0 :   res = mEditor->GetSelection(getter_AddRefs(selection));
     103               0 :   NS_ENSURE_SUCCESS(res, res);
     104               0 :   NS_ENSURE_TRUE(selection, NS_ERROR_NULL_POINTER);
     105               0 :   return mStartSel->RestoreSelection(selection);
     106                 : }
     107                 : 
     108                 : 
     109               0 : NS_IMETHODIMP PlaceholderTxn::RedoTransaction(void)
     110                 : {
     111                 :   // redo txns
     112               0 :   nsresult res = EditAggregateTxn::RedoTransaction();
     113               0 :   NS_ENSURE_SUCCESS(res, res);
     114                 :   
     115                 :   // now restore selection
     116               0 :   nsCOMPtr<nsISelection> selection;
     117               0 :   res = mEditor->GetSelection(getter_AddRefs(selection));
     118               0 :   NS_ENSURE_SUCCESS(res, res);
     119               0 :   NS_ENSURE_TRUE(selection, NS_ERROR_NULL_POINTER);
     120               0 :   return mEndSel.RestoreSelection(selection);
     121                 : }
     122                 : 
     123                 : 
     124               0 : NS_IMETHODIMP PlaceholderTxn::Merge(nsITransaction *aTransaction, bool *aDidMerge)
     125                 : {
     126               0 :   NS_ENSURE_TRUE(aDidMerge && aTransaction, NS_ERROR_NULL_POINTER);
     127                 : 
     128                 :   // set out param default value
     129               0 :   *aDidMerge=false;
     130                 :     
     131               0 :   if (mForwarding) 
     132                 :   {
     133               0 :     NS_NOTREACHED("tried to merge into a placeholder that was in forwarding mode!");
     134               0 :     return NS_ERROR_FAILURE;
     135                 :   }
     136                 : 
     137                 :   // check to see if aTransaction is one of the editor's
     138                 :   // private transactions. If not, we want to avoid merging
     139                 :   // the foreign transaction into our placeholder since we
     140                 :   // don't know what it does.
     141                 : 
     142               0 :   nsCOMPtr<nsPIEditorTransaction> pTxn = do_QueryInterface(aTransaction);
     143               0 :   NS_ENSURE_TRUE(pTxn, NS_OK); // it's foreign so just bail!
     144                 : 
     145               0 :   EditTxn *editTxn = (EditTxn*)aTransaction;  //XXX: hack, not safe!  need nsIEditTransaction!
     146                 :   // determine if this incoming txn is a placeholder txn
     147               0 :   nsCOMPtr<nsIAbsorbingTransaction> plcTxn;// = do_QueryInterface(editTxn);
     148                 :   // can't do_QueryInterface() above due to our broken transaction interfaces.
     149                 :   // instead have to brute it below. ugh. 
     150               0 :   editTxn->QueryInterface(NS_GET_IID(nsIAbsorbingTransaction), getter_AddRefs(plcTxn));
     151                 : 
     152                 :   // we are absorbing all txn's if mAbsorb is lit.
     153               0 :   if (mAbsorb)
     154                 :   { 
     155               0 :     nsRefPtr<IMETextTxn> otherTxn;
     156               0 :     if (NS_SUCCEEDED(aTransaction->QueryInterface(IMETextTxn::GetCID(), getter_AddRefs(otherTxn))) && otherTxn)
     157                 :     {
     158                 :       // special handling for IMETextTxn's: they need to merge with any previous
     159                 :       // IMETextTxn in this placeholder, if possible.
     160               0 :       if (!mIMETextTxn) 
     161                 :       {
     162                 :         // this is the first IME txn in the placeholder
     163               0 :         mIMETextTxn =otherTxn;
     164               0 :         AppendChild(editTxn);
     165                 :       }
     166                 :       else  
     167                 :       {
     168                 :         bool didMerge;
     169               0 :         mIMETextTxn->Merge(otherTxn, &didMerge);
     170               0 :         if (!didMerge)
     171                 :         {
     172                 :           // it wouldn't merge.  Earlier IME txn is already committed and will
     173                 :           // not absorb further IME txns.  So just stack this one after it
     174                 :           // and remember it as a candidate for further merges.
     175               0 :           mIMETextTxn =otherTxn;
     176               0 :           AppendChild(editTxn);
     177                 :         }
     178                 :       }
     179                 :     }
     180               0 :     else if (!plcTxn)  // see bug 171243: just drop incoming placeholders on the floor.
     181                 :     {                  // their children will be swallowed by this preexisting one.
     182               0 :       AppendChild(editTxn);
     183                 :     }
     184               0 :     *aDidMerge = true;
     185                 : //  RememberEndingSelection();
     186                 : //  efficiency hack: no need to remember selection here, as we haven't yet 
     187                 : //  finished the initial batch and we know we will be told when the batch ends.
     188                 : //  we can remeber the selection then.
     189                 :   }
     190                 :   else
     191                 :   { // merge typing or IME or deletion transactions if the selection matches
     192               0 :     if (((mName.get() == nsGkAtoms::TypingTxnName) ||
     193               0 :          (mName.get() == nsGkAtoms::IMETxnName)    ||
     194               0 :          (mName.get() == nsGkAtoms::DeleteTxnName)) 
     195               0 :          && !mCommitted ) 
     196                 :     {
     197               0 :       nsCOMPtr<nsIAbsorbingTransaction> plcTxn;// = do_QueryInterface(editTxn);
     198                 :       // can't do_QueryInterface() above due to our broken transaction interfaces.
     199                 :       // instead have to brute it below. ugh. 
     200               0 :       editTxn->QueryInterface(NS_GET_IID(nsIAbsorbingTransaction), getter_AddRefs(plcTxn));
     201               0 :       if (plcTxn)
     202                 :       {
     203               0 :         nsCOMPtr<nsIAtom> atom;
     204               0 :         plcTxn->GetTxnName(getter_AddRefs(atom));
     205               0 :         if (atom && (atom == mName))
     206                 :         {
     207                 :           // check if start selection of next placeholder matches
     208                 :           // end selection of this placeholder
     209                 :           bool isSame;
     210               0 :           plcTxn->StartSelectionEquals(&mEndSel, &isSame);
     211               0 :           if (isSame)
     212                 :           {
     213               0 :             mAbsorb = true;  // we need to start absorbing again
     214               0 :             plcTxn->ForwardEndBatchTo(this);
     215                 :             // AppendChild(editTxn);
     216                 :             // see bug 171243: we don't need to merge placeholders
     217                 :             // into placeholders.  We just reactivate merging in the pre-existing
     218                 :             // placeholder and drop the new one on the floor.  The EndPlaceHolderBatch()
     219                 :             // call on the new placeholder will be forwarded to this older one.
     220               0 :             RememberEndingSelection();
     221               0 :             *aDidMerge = true;
     222                 :           }
     223                 :         }
     224                 :       }
     225                 :     }
     226                 :   }
     227               0 :   return NS_OK;
     228                 : }
     229                 : 
     230               0 : NS_IMETHODIMP PlaceholderTxn::GetTxnDescription(nsAString& aString)
     231                 : {
     232               0 :   aString.AssignLiteral("PlaceholderTxn: ");
     233                 : 
     234               0 :   if (mName)
     235                 :   {
     236               0 :     nsAutoString name;
     237               0 :     mName->ToString(name);
     238               0 :     aString += name;
     239                 :   }
     240                 : 
     241               0 :   return NS_OK;
     242                 : }
     243                 : 
     244               0 : NS_IMETHODIMP PlaceholderTxn::GetTxnName(nsIAtom **aName)
     245                 : {
     246               0 :   return GetName(aName);
     247                 : }
     248                 : 
     249               0 : NS_IMETHODIMP PlaceholderTxn::StartSelectionEquals(nsSelectionState *aSelState, bool *aResult)
     250                 : {
     251                 :   // determine if starting selection matches the given selection state.
     252                 :   // note that we only care about collapsed selections.
     253               0 :   NS_ENSURE_TRUE(aResult && aSelState, NS_ERROR_NULL_POINTER);
     254               0 :   if (!mStartSel->IsCollapsed() || !aSelState->IsCollapsed())
     255                 :   {
     256               0 :     *aResult = false;
     257               0 :     return NS_OK;
     258                 :   }
     259               0 :   *aResult = mStartSel->IsEqual(aSelState);
     260               0 :   return NS_OK;
     261                 : }
     262                 : 
     263               0 : NS_IMETHODIMP PlaceholderTxn::EndPlaceHolderBatch()
     264                 : {
     265               0 :   mAbsorb = false;
     266                 :   
     267               0 :   if (mForwarding) 
     268                 :   {
     269               0 :     nsCOMPtr<nsIAbsorbingTransaction> plcTxn = do_QueryReferent(mForwarding);
     270               0 :     if (plcTxn) plcTxn->EndPlaceHolderBatch();
     271                 :   }
     272                 :   
     273                 :   // remember our selection state.
     274               0 :   return RememberEndingSelection();
     275                 : }
     276                 : 
     277               0 : NS_IMETHODIMP PlaceholderTxn::ForwardEndBatchTo(nsIAbsorbingTransaction *aForwardingAddress)
     278                 : {   
     279               0 :   mForwarding = do_GetWeakReference(aForwardingAddress);
     280               0 :   return NS_OK;
     281                 : }
     282                 : 
     283               0 : NS_IMETHODIMP PlaceholderTxn::Commit()
     284                 : {
     285               0 :   mCommitted = true;
     286               0 :   return NS_OK;
     287                 : }
     288                 : 
     289               0 : NS_IMETHODIMP PlaceholderTxn::RememberEndingSelection()
     290                 : {
     291               0 :   nsCOMPtr<nsISelection> selection;
     292               0 :   nsresult res = mEditor->GetSelection(getter_AddRefs(selection));
     293               0 :   NS_ENSURE_SUCCESS(res, res);
     294               0 :   NS_ENSURE_TRUE(selection, NS_ERROR_NULL_POINTER);
     295               0 :   return mEndSel.SaveSelection(selection);
     296            4392 : }
     297                 : 

Generated by: LCOV version 1.7