LCOV - code coverage report
Current view: directory - editor/libeditor/html - nsWSRunObject.h (source / functions) Found Hit Coverage
Test: app.info Lines: 12 0 0.0 %
Date: 2012-06-02 Functions: 8 0 0.0 %

       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                 :  *
      24                 :  * Alternatively, the contents of this file may be used under the terms of
      25                 :  * either of the GNU General Public License Version 2 or later (the "GPL"),
      26                 :  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
      27                 :  * in which case the provisions of the GPL or the LGPL are applicable instead
      28                 :  * of those above. If you wish to allow use of your version of this file only
      29                 :  * under the terms of either the GPL or the LGPL, and not to allow others to
      30                 :  * use your version of this file under the terms of the MPL, indicate your
      31                 :  * decision by deleting the provisions above and replace them with the notice
      32                 :  * and other provisions required by the GPL or the LGPL. If you do not delete
      33                 :  * the provisions above, a recipient may use your version of this file under
      34                 :  * the terms of any one of the MPL, the GPL or the LGPL.
      35                 :  *
      36                 :  * ***** END LICENSE BLOCK ***** */
      37                 : 
      38                 : #ifndef __wsrunobject_h__
      39                 : #define __wsrunobject_h__
      40                 : 
      41                 : #include "nsCOMPtr.h"
      42                 : #include "nsIDOMNode.h"
      43                 : #include "nsCOMArray.h"
      44                 : #include "nsIContent.h"
      45                 : #include "nsIEditor.h"
      46                 : #include "nsEditorUtils.h"
      47                 : 
      48                 : class nsIDOMDocument;
      49                 : class nsIDOMNode;
      50                 : class nsHTMLEditor;
      51                 : 
      52                 : // class nsWSRunObject represents the entire whitespace situation
      53                 : // around a given point.  It collects up a list of nodes that contain
      54                 : // whitespace and categorizes in up to 3 different WSFragments (detailed
      55                 : // below).  Each WSFragment is a collection of whitespace that is
      56                 : // either all insignificant, or that is significant.  A WSFragment could
      57                 : // consist of insignificant whitespace because it is after a block
      58                 : // boundary or after a break.  Or it could be insignificant because it
      59                 : // is before a block.  Or it could be significant because it is
      60                 : // surrounded by text, or starts and ends with nbsps, etc.
      61                 : 
      62                 : // Throughout I refer to LeadingWS, NormalWS, TrailingWS.  LeadingWS & TrailingWS
      63                 : // are runs of ascii ws that are insignificant (do not render) because they
      64                 : // are adjacent to block boundaries, or after a break.  NormalWS is ws that
      65                 : // does cause soem rendering.  Note that not all the ws in a NormalWS run need
      66                 : // render.  For example, two ascii spaces surrounded by text on both sides
      67                 : // will only render as one space (in non-preformatted stlye html), yet both
      68                 : // spaces count as NormalWS.  Together, they render as the one visible space.
      69                 : 
      70                 : class NS_STACK_CLASS nsWSRunObject
      71                 : {
      72                 :   public:
      73                 : 
      74                 :     enum BlockBoundary
      75                 :     {
      76                 :       kBeforeBlock,
      77                 :       kBlockStart,
      78                 :       kBlockEnd,
      79                 :       kAfterBlock
      80                 :     };
      81                 : 
      82                 :     // constructor / destructor -----------------------------------------------
      83                 :     nsWSRunObject(nsHTMLEditor *aEd, nsIDOMNode *aNode, PRInt32 aOffset);
      84                 :     ~nsWSRunObject();
      85                 :     
      86                 :     // public methods ---------------------------------------------------------
      87                 : 
      88                 :     // ScrubBlockBoundary removes any non-visible whitespace at the specified
      89                 :     // location relative to a block node.  
      90                 :     static nsresult ScrubBlockBoundary(nsHTMLEditor *aHTMLEd, 
      91                 :                                        nsCOMPtr<nsIDOMNode> *aBlock,
      92                 :                                        BlockBoundary aBoundary,
      93                 :                                        PRInt32 *aOffset = 0);
      94                 :     
      95                 :     // PrepareToJoinBlocks fixes up ws at the end of aLeftParent and the
      96                 :     // beginning of aRightParent in preperation for them to be joined.
      97                 :     // example of fixup: trailingws in aLeftParent needs to be removed.
      98                 :     static nsresult PrepareToJoinBlocks(nsHTMLEditor *aEd, 
      99                 :                                         nsIDOMNode *aLeftParent,
     100                 :                                         nsIDOMNode *aRightParent);
     101                 : 
     102                 :     // PrepareToDeleteRange fixes up ws before {aStartNode,aStartOffset}
     103                 :     // and after {aEndNode,aEndOffset} in preperation for content
     104                 :     // in that range to be deleted.  Note that the nodes and offsets
     105                 :     // are adjusted in response to any dom changes we make while 
     106                 :     // adjusting ws.
     107                 :     // example of fixup: trailingws before {aStartNode,aStartOffset}
     108                 :     //                   needs to be removed.
     109                 :     static nsresult PrepareToDeleteRange(nsHTMLEditor *aHTMLEd, 
     110                 :                                          nsCOMPtr<nsIDOMNode> *aStartNode,
     111                 :                                          PRInt32 *aStartOffset, 
     112                 :                                          nsCOMPtr<nsIDOMNode> *aEndNode,
     113                 :                                          PRInt32 *aEndOffset);
     114                 : 
     115                 :     // PrepareToDeleteNode fixes up ws before and after aNode in preperation 
     116                 :     // for aNode to be deleted.
     117                 :     // example of fixup: trailingws before aNode needs to be removed.
     118                 :     static nsresult PrepareToDeleteNode(nsHTMLEditor *aHTMLEd, 
     119                 :                                         nsIDOMNode *aNode);
     120                 : 
     121                 :     // PrepareToSplitAcrossBlocks fixes up ws before and after 
     122                 :     // {aSplitNode,aSplitOffset} in preperation for a block
     123                 :     // parent to be split.  Note that the aSplitNode and aSplitOffset
     124                 :     // are adjusted in response to any dom changes we make while 
     125                 :     // adjusting ws.
     126                 :     // example of fixup: normalws before {aSplitNode,aSplitOffset} 
     127                 :     //                   needs to end with nbsp.
     128                 :     static nsresult PrepareToSplitAcrossBlocks(nsHTMLEditor *aHTMLEd, 
     129                 :                                                nsCOMPtr<nsIDOMNode> *aSplitNode, 
     130                 :                                                PRInt32 *aSplitOffset);
     131                 : 
     132                 :     // InsertBreak inserts a br node at {aInOutParent,aInOutOffset}
     133                 :     // and makes any needed adjustments to ws around that point.
     134                 :     // example of fixup: normalws after {aInOutParent,aInOutOffset}
     135                 :     //                   needs to begin with nbsp.
     136                 :     nsresult InsertBreak(nsCOMPtr<nsIDOMNode> *aInOutParent, 
     137                 :                          PRInt32 *aInOutOffset, 
     138                 :                          nsCOMPtr<nsIDOMNode> *outBRNode, 
     139                 :                          nsIEditor::EDirection aSelect);
     140                 : 
     141                 :     // InsertText inserts a string at {aInOutParent,aInOutOffset}
     142                 :     // and makes any needed adjustments to ws around that point.
     143                 :     // example of fixup: trailingws before {aInOutParent,aInOutOffset}
     144                 :     //                   needs to be removed.
     145                 :     nsresult InsertText(const nsAString& aStringToInsert, 
     146                 :                         nsCOMPtr<nsIDOMNode> *aInOutNode, 
     147                 :                         PRInt32 *aInOutOffset,
     148                 :                         nsIDOMDocument *aDoc);
     149                 : 
     150                 :     // DeleteWSBackward deletes a single visible piece of ws before
     151                 :     // the ws point (the point to create the wsRunObject, passed to 
     152                 :     // its constructor).  It makes any needed conversion to adjacent
     153                 :     // ws to retain its significance.
     154                 :     nsresult DeleteWSBackward();
     155                 : 
     156                 :     // DeleteWSForward deletes a single visible piece of ws after
     157                 :     // the ws point (the point to create the wsRunObject, passed to 
     158                 :     // its constructor).  It makes any needed conversion to adjacent
     159                 :     // ws to retain its significance.
     160                 :     nsresult DeleteWSForward();
     161                 : 
     162                 :     // PriorVisibleNode returns the first piece of visible thing
     163                 :     // before {aNode,aOffset}.  If there is no visible ws qualifying
     164                 :     // it returns what is before the ws run.  Note that 
     165                 :     // {outVisNode,outVisOffset} is set to just AFTER the visible
     166                 :     // object.
     167                 :     nsresult PriorVisibleNode(nsIDOMNode *aNode, 
     168                 :                               PRInt32 aOffset, 
     169                 :                               nsCOMPtr<nsIDOMNode> *outVisNode, 
     170                 :                               PRInt32 *outVisOffset,
     171                 :                               PRInt16 *outType);
     172                 : 
     173                 :     // NextVisibleNode returns the first piece of visible thing
     174                 :     // after {aNode,aOffset}.  If there is no visible ws qualifying
     175                 :     // it returns what is after the ws run.  Note that 
     176                 :     // {outVisNode,outVisOffset} is set to just BEFORE the visible
     177                 :     // object.
     178                 :     nsresult NextVisibleNode (nsIDOMNode *aNode, 
     179                 :                               PRInt32 aOffset, 
     180                 :                               nsCOMPtr<nsIDOMNode> *outVisNode, 
     181                 :                               PRInt32 *outVisOffset,
     182                 :                               PRInt16 *outType);
     183                 :     
     184                 :     // AdjustWhitespace examines the ws object for nbsp's that can
     185                 :     // be safely converted to regular ascii space and converts them.
     186                 :     nsresult AdjustWhitespace();
     187                 :     
     188                 :     // public enums ---------------------------------------------------------
     189                 :     enum {eNone = 0};
     190                 :     enum {eLeadingWS  = 1};          // leading insignificant ws, ie, after block or br
     191                 :     enum {eTrailingWS = 1 << 1};     // trailing insignificant ws, ie, before block
     192                 :     enum {eNormalWS   = 1 << 2};     // normal significant ws, ie, after text, image, ...
     193                 :     enum {eText       = 1 << 3};     // indicates regular (non-ws) text
     194                 :     enum {eSpecial    = 1 << 4};     // indicates an inline non-container, like image
     195                 :     enum {eBreak      = 1 << 5};     // indicates a br node
     196                 :     enum {eOtherBlock = 1 << 6};     // indicates a block other than one ws run is in
     197                 :     enum {eThisBlock  = 1 << 7};     // indicates the block ws run is in
     198                 :     enum {eBlock      = eOtherBlock | eThisBlock};   // block found
     199                 :     
     200                 :     enum {eBefore = 1};
     201                 :     enum {eAfter  = 1 << 1};
     202                 :     enum {eBoth   = eBefore | eAfter};
     203                 :     
     204                 :   protected:
     205                 :     
     206                 :     // WSFragment struct ---------------------------------------------------------
     207                 :     // WSFragment represents a single run of ws (all leadingws, or all normalws,
     208                 :     // or all trailingws, or all leading+trailingws).  Note that this single run may
     209                 :     // still span multiple nodes.
     210                 :     struct WSFragment
     211               0 :     {
     212                 :       nsCOMPtr<nsIDOMNode> mStartNode;  // node where ws run starts
     213                 :       nsCOMPtr<nsIDOMNode> mEndNode;    // node where ws run ends
     214                 :       PRInt16 mStartOffset;             // offset where ws run starts
     215                 :       PRInt16 mEndOffset;               // offset where ws run ends
     216                 :       PRInt16 mType, mLeftType, mRightType;  // type of ws, and what is to left and right of it
     217                 :       WSFragment *mLeft, *mRight;            // other ws runs to left or right.  may be null.
     218                 : 
     219               0 :       WSFragment() : mStartNode(0),mEndNode(0),mStartOffset(0),
     220                 :                      mEndOffset(0),mType(0),mLeftType(0),
     221               0 :                      mRightType(0),mLeft(0),mRight(0) {}
     222                 :     };
     223                 :     
     224                 :     // WSPoint struct ------------------------------------------------------------
     225                 :     // A WSPoint struct represents a unique location within the ws run.  It is 
     226                 :     // always within a textnode that is one of the nodes stored in the list
     227                 :     // in the wsRunObject.  For convenience, the character at that point is also 
     228                 :     // stored in the struct.
     229                 :     struct NS_STACK_CLASS WSPoint
     230               0 :     {
     231                 :       nsCOMPtr<nsIContent> mTextNode;
     232                 :       PRUint32 mOffset;
     233                 :       PRUnichar mChar;
     234                 : 
     235               0 :       WSPoint() : mTextNode(0),mOffset(0),mChar(0) {}
     236               0 :       WSPoint(nsIDOMNode *aNode, PRInt32 aOffset, PRUnichar aChar) : 
     237               0 :                      mTextNode(do_QueryInterface(aNode)),mOffset(aOffset),mChar(aChar)
     238                 :       {
     239               0 :         if (!mTextNode->IsNodeOfType(nsINode::eDATA_NODE)) {
     240                 :           // Not sure if this is needed, but it'll maintain the same
     241                 :           // functionality
     242               0 :           mTextNode = nsnull;
     243                 :         }
     244               0 :       }
     245               0 :       WSPoint(nsIContent *aTextNode, PRInt32 aOffset, PRUnichar aChar) : 
     246               0 :                      mTextNode(aTextNode),mOffset(aOffset),mChar(aChar) {}
     247                 :     };    
     248                 : 
     249                 :     enum AreaRestriction
     250                 :     {
     251                 :       eAnywhere, eOutsideUserSelectAll
     252                 :     };    
     253                 :     
     254                 :     // protected methods ---------------------------------------------------------
     255                 :     // tons of utility methods.  
     256                 : 
     257                 :     /**
     258                 :      * Return the node which we will handle white-space under. This is the
     259                 :      * closest block within the DOM subtree we're editing, or if none is
     260                 :      * found, the (inline) root of the editable subtree.
     261                 :      */
     262                 :     already_AddRefed<nsIDOMNode> GetWSBoundingParent();
     263                 : 
     264                 :     nsresult GetWSNodes();
     265                 :     nsresult GetRuns();
     266                 :     void     ClearRuns();
     267                 :     nsresult MakeSingleWSRun(PRInt16 aType);
     268                 :     nsresult PrependNodeToList(nsIDOMNode *aNode);
     269                 :     nsresult AppendNodeToList(nsIDOMNode *aNode);
     270                 :     nsresult GetPreviousWSNode(nsIDOMNode *aStartNode, 
     271                 :                                nsIDOMNode *aBlockParent, 
     272                 :                                nsCOMPtr<nsIDOMNode> *aPriorNode);
     273                 :     nsresult GetPreviousWSNode(nsIDOMNode *aStartNode,
     274                 :                                PRInt16      aOffset, 
     275                 :                                nsIDOMNode  *aBlockParent, 
     276                 :                                nsCOMPtr<nsIDOMNode> *aPriorNode);
     277                 :     nsresult GetPreviousWSNode(DOMPoint aPoint,
     278                 :                                nsIDOMNode  *aBlockParent, 
     279                 :                                nsCOMPtr<nsIDOMNode> *aPriorNode);
     280                 :     nsresult GetNextWSNode(nsIDOMNode *aStartNode, 
     281                 :                            nsIDOMNode *aBlockParent, 
     282                 :                            nsCOMPtr<nsIDOMNode> *aNextNode);
     283                 :     nsresult GetNextWSNode(nsIDOMNode *aStartNode,
     284                 :                            PRInt16     aOffset, 
     285                 :                            nsIDOMNode *aBlockParent, 
     286                 :                            nsCOMPtr<nsIDOMNode> *aNextNode);
     287                 :     nsresult GetNextWSNode(DOMPoint aPoint,
     288                 :                            nsIDOMNode  *aBlockParent, 
     289                 :                            nsCOMPtr<nsIDOMNode> *aNextNode);
     290                 :     nsresult PrepareToDeleteRangePriv(nsWSRunObject* aEndObject);
     291                 :     nsresult PrepareToSplitAcrossBlocksPriv();
     292                 :     nsresult DeleteChars(nsIDOMNode *aStartNode, PRInt32 aStartOffset, 
     293                 :                          nsIDOMNode *aEndNode, PRInt32 aEndOffset,
     294                 :                          AreaRestriction aAR = eAnywhere);
     295                 :     nsresult GetCharAfter(nsIDOMNode *aNode, PRInt32 aOffset, WSPoint *outPoint);
     296                 :     nsresult GetCharBefore(nsIDOMNode *aNode, PRInt32 aOffset, WSPoint *outPoint);
     297                 :     nsresult GetCharAfter(WSPoint &aPoint, WSPoint *outPoint);
     298                 :     nsresult GetCharBefore(WSPoint &aPoint, WSPoint *outPoint);
     299                 :     nsresult ConvertToNBSP(WSPoint aPoint,
     300                 :                            AreaRestriction aAR = eAnywhere);
     301                 :     nsresult GetAsciiWSBounds(PRInt16 aDir, nsIDOMNode *aNode, PRInt32 aOffset,
     302                 :                                 nsCOMPtr<nsIDOMNode> *outStartNode, PRInt32 *outStartOffset,
     303                 :                                 nsCOMPtr<nsIDOMNode> *outEndNode, PRInt32 *outEndOffset);
     304                 :     nsresult FindRun(nsIDOMNode *aNode, PRInt32 aOffset, WSFragment **outRun, bool after);
     305                 :     PRUnichar GetCharAt(nsIContent *aTextNode, PRInt32 aOffset);
     306                 :     nsresult GetWSPointAfter(nsIDOMNode *aNode, PRInt32 aOffset, WSPoint *outPoint);
     307                 :     nsresult GetWSPointBefore(nsIDOMNode *aNode, PRInt32 aOffset, WSPoint *outPoint);
     308                 :     nsresult CheckTrailingNBSPOfRun(WSFragment *aRun);
     309                 :     nsresult CheckTrailingNBSP(WSFragment *aRun, nsIDOMNode *aNode, PRInt32 aOffset);
     310                 :     nsresult CheckLeadingNBSP(WSFragment *aRun, nsIDOMNode *aNode, PRInt32 aOffset);
     311                 :     
     312                 :     static nsresult ScrubBlockBoundaryInner(nsHTMLEditor *aHTMLEd, 
     313                 :                                        nsCOMPtr<nsIDOMNode> *aBlock,
     314                 :                                        BlockBoundary aBoundary);
     315                 :     nsresult Scrub();
     316                 :     
     317                 :     // member variables ---------------------------------------------------------
     318                 :     
     319                 :     nsCOMPtr<nsIDOMNode> mNode;           // the node passed to our constructor
     320                 :     PRInt32 mOffset;                      // the offset passed to our contructor
     321                 :     // together, the above represent the point at which we are building up ws info.
     322                 :     
     323                 :     bool    mPRE;                         // true if we are in preformatted whitespace context
     324                 :     nsCOMPtr<nsIDOMNode> mStartNode;      // node/offset where ws starts
     325                 :     PRInt32 mStartOffset;                 // ...
     326                 :     PRInt16 mStartReason;                 // reason why ws starts (eText, eOtherBlock, etc)
     327                 :     nsCOMPtr<nsIDOMNode> mStartReasonNode;// the node that implicated by start reason
     328                 :     
     329                 :     nsCOMPtr<nsIDOMNode> mEndNode;        // node/offset where ws ends
     330                 :     PRInt32 mEndOffset;                   // ...
     331                 :     PRInt16 mEndReason;                   // reason why ws ends (eText, eOtherBlock, etc)
     332                 :     nsCOMPtr<nsIDOMNode> mEndReasonNode;  // the node that implicated by end reason
     333                 :     
     334                 :     nsCOMPtr<nsIDOMNode> mFirstNBSPNode;  // location of first nbsp in ws run, if any
     335                 :     PRInt32 mFirstNBSPOffset;             // ...
     336                 :     
     337                 :     nsCOMPtr<nsIDOMNode> mLastNBSPNode;   // location of last nbsp in ws run, if any
     338                 :     PRInt32 mLastNBSPOffset;              // ...
     339                 :     
     340                 :     nsCOMArray<nsIDOMNode> mNodeArray;//the list of nodes containing ws in this run
     341                 :     
     342                 :     WSFragment *mStartRun;                // the first WSFragment in the run
     343                 :     WSFragment *mEndRun;                  // the last WSFragment in the run, may be same as first
     344                 :     
     345                 :     nsHTMLEditor *mHTMLEditor;            // non-owning.
     346                 :     
     347                 :     friend class nsHTMLEditRules;  // opening this class up for pillaging
     348                 :     friend class nsHTMLEditor;     // opening this class up for more pillaging
     349                 : };
     350                 : 
     351                 : #endif
     352                 : 

Generated by: LCOV version 1.7