LCOV - code coverage report
Current view: directory - parser/htmlparser/src - CNavDTD.h (source / functions) Found Hit Coverage
Test: app.info Lines: 7 6 85.7 %
Date: 2012-06-02 Functions: 6 3 50.0 %

       1                 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2                 : /* vim: set sw=2 ts=2 et tw=78: */
       3                 : /* ***** BEGIN LICENSE BLOCK *****
       4                 :  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
       5                 :  *
       6                 :  * The contents of this file are subject to the Mozilla Public License Version
       7                 :  * 1.1 (the "License"); you may not use this file except in compliance with
       8                 :  * the License. You may obtain a copy of the License at
       9                 :  * http://www.mozilla.org/MPL/
      10                 :  *
      11                 :  * Software distributed under the License is distributed on an "AS IS" basis,
      12                 :  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
      13                 :  * for the specific language governing rights and limitations under the
      14                 :  * License.
      15                 :  *
      16                 :  * The Original Code is mozilla.org code.
      17                 :  *
      18                 :  * The Initial Developer of the Original Code is
      19                 :  * Netscape Communications Corporation.
      20                 :  * Portions created by the Initial Developer are Copyright (C) 1998
      21                 :  * the Initial Developer. All Rights Reserved.
      22                 :  *
      23                 :  * Contributor(s):
      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                 :  * MODULE NOTES:
      41                 :  *
      42                 :  * NavDTD is an implementation of the nsIDTD interface.
      43                 :  * In particular, this class captures the behaviors of the original 
      44                 :  * Navigator parser productions.
      45                 :  *
      46                 :  * This DTD, like any other in NGLayout, provides a few basic services:
      47                 :  *  - First, the DTD collaborates with the Parser class to convert plain 
      48                 :  *    text into a sequence of HTMLTokens. 
      49                 :  *  - Second, the DTD describes containment rules for known elements. 
      50                 :  *  - Third the DTD controls and coordinates the interaction between the
      51                 :  *    parsing system and content sink. (The content sink is the interface
      52                 :  *    that serves as a proxy for content model).
      53                 :  *  - Fourth the DTD maintains an internal style-stack to handle residual (leaky)
      54                 :  *    style tags.
      55                 :  *
      56                 :  * You're most likely working in this class file because
      57                 :  * you want to add or change a behavior inherent in this DTD. The remainder
      58                 :  * of this section will describe what you need to do to affect the kind of
      59                 :  * change you want in this DTD.
      60                 :  *
      61                 :  * RESIDUAL-STYLE HANDLNG:
      62                 :  *   There are a number of ways to represent style in an HTML document.
      63                 :  *    1) explicit style tags (<B>, <I> etc)
      64                 :  *    2) implicit styles (like those implicit in <Hn>)
      65                 :  *    3) CSS based styles
      66                 :  *
      67                 :  *   Residual style handling results from explicit style tags that are
      68                 :  *   not closed. Consider this example: <p>text <b>bold </p>
      69                 :  *   When the <p> tag closes, the <b> tag is NOT automatically closed.
      70                 :  *   Unclosed style tags are handled by the process we call residual-style 
      71                 :  *   tag handling. 
      72                 :  *
      73                 :  *   There are two aspects to residual style tag handling. The first is the 
      74                 :  *   construction and managing of a stack of residual style tags. The 
      75                 :  *   second is the automatic emission of residual style tags onto leaf content
      76                 :  *   in subsequent portions of the document.This step is necessary to propagate
      77                 :  *   the expected style behavior to subsequent portions of the document.
      78                 :  *
      79                 :  *   Construction and managing the residual style stack is an inline process that
      80                 :  *   occurs during the model building phase of the parse process. During the model-
      81                 :  *   building phase of the parse process, a content stack is maintained which tracks
      82                 :  *   the open container hierarchy. If a style tag(s) fails to be closed when a normal
      83                 :  *   container is closed, that style tag is placed onto the residual style stack. If
      84                 :  *   that style tag is subsequently closed (in most contexts), it is popped off the
      85                 :  *   residual style stack -- and are of no further concern.
      86                 :  *
      87                 :  *   Residual style tag emission occurs when the style stack is not empty, and leaf
      88                 :  *   content occurs. In our earlier example, the <b> tag "leaked" out of the <p> 
      89                 :  *   container. Just before the next leaf is emitted (in this or another container) the 
      90                 :  *   style tags that are on the stack are emitted in succession. These same residual
      91                 :  *   style tags get closed automatically when the leaf's container closes, or if a
      92                 :  *   child container is opened.
      93                 :  * 
      94                 :  *         
      95                 :  */
      96                 : #ifndef NS_NAVHTMLDTD__
      97                 : #define NS_NAVHTMLDTD__
      98                 : 
      99                 : #include "nsIDTD.h"
     100                 : #include "nsISupports.h"
     101                 : #include "nsIParser.h"
     102                 : #include "nsHTMLTags.h"
     103                 : #include "nsDeque.h"
     104                 : #include "nsParserCIID.h"
     105                 : #include "nsDTDUtils.h"
     106                 : #include "nsParser.h"
     107                 : #include "nsCycleCollectionParticipant.h"
     108                 : 
     109                 : class nsIHTMLContentSink;
     110                 : class nsIParserNode;
     111                 : class nsDTDContext;
     112                 : class nsEntryStack;
     113                 : class nsITokenizer;
     114                 : class nsCParserNode;
     115                 : class nsTokenAllocator;
     116                 : 
     117                 : /***************************************************************
     118                 :   Now the main event: CNavDTD.
     119                 : 
     120                 :   This not so simple class performs all the duties of token 
     121                 :   construction and model building. It works in conjunction with
     122                 :   an nsParser.
     123                 :  ***************************************************************/
     124                 : 
     125                 : #ifdef _MSC_VER
     126                 : #pragma warning( disable : 4275 )
     127                 : #endif
     128                 : 
     129                 : class CNavDTD : public nsIDTD
     130                 : {
     131                 : #ifdef _MSC_VER
     132                 : #pragma warning( default : 4275 )
     133                 : #endif
     134                 : 
     135                 : public:
     136                 :     /**
     137                 :      *  Common constructor for navdtd. You probably want to call
     138                 :      *  NS_NewNavHTMLDTD().
     139                 :      */
     140                 :     CNavDTD();
     141                 :     virtual ~CNavDTD();
     142                 : 
     143                 :     /**
     144                 :      * This method is offered publically for the sole use from
     145                 :      * nsParser::ParseFragment. In general, you should prefer to use methods
     146                 :      * that are directly on nsIDTD, since those will be guaranteed to do the
     147                 :      * right thing.
     148                 :      *
     149                 :      * @param aNode The parser node that contains the token information for
     150                 :      *              this tag.
     151                 :      * @param aTag The actual tag that is being opened (should correspond to
     152                 :      *             aNode.
     153                 :      * @param aStyleStack The style stack that aNode might be a member of
     154                 :      *                    (usually null).
     155                 :      */
     156                 :     nsresult OpenContainer(const nsCParserNode *aNode,
     157                 :                            eHTMLTags aTag,
     158                 :                            nsEntryStack* aStyleStack = nsnull);
     159                 : 
     160               0 :     NS_DECL_CYCLE_COLLECTING_ISUPPORTS
     161                 :     NS_DECL_NSIDTD
     162            1576 :     NS_DECL_CYCLE_COLLECTION_CLASS(CNavDTD)
     163                 : 
     164                 : private:
     165                 :     /**
     166                 :      *  This method is called to determine whether or not a tag
     167                 :      *  of one type can contain a tag of another type.
     168                 :      *  
     169                 :      *  @param   aParent Tag of parent container
     170                 :      *  @param   aChild Tag of child container
     171                 :      *  @return  true if parent can contain child
     172                 :      */
     173                 :     bool CanPropagate(eHTMLTags aParent,
     174                 :                         eHTMLTags aChild,
     175                 :                         PRInt32 aParentContains);
     176                 : 
     177                 :     /**
     178                 :      *  This method gets called to determine whether a given 
     179                 :      *  child tag can be omitted by the given parent.
     180                 :      *  
     181                 :      *  @param   aParent Parent tag being asked about omitting given child
     182                 :      *  @param   aChild Child tag being tested for omittability by parent
     183                 :      *  @param   aParentContains Can be 0,1,-1 (false,true, unknown)
     184                 :      *                           XXX should be PRInt32, not bool
     185                 :      *  @return  true if given tag can be omitted
     186                 :      */
     187                 :     bool CanOmit(eHTMLTags aParent, 
     188                 :                    eHTMLTags aChild,
     189                 :                    PRInt32& aParentContains);
     190                 : 
     191                 :     /**
     192                 :      * Looking at aParent, try to see if we can propagate from aChild to
     193                 :      * aParent. If aParent is a TR tag, then see if we can start at TD instead
     194                 :      * of at aChild.
     195                 :      *
     196                 :      * @param   aParent Tag type of parent
     197                 :      * @param   aChild Tag type of child
     198                 :      * @return  true if closure was achieved -- otherwise false
     199                 :      */
     200                 :     bool ForwardPropagate(nsString& aSequence,
     201                 :                             eHTMLTags aParent,
     202                 :                             eHTMLTags aChild);
     203                 : 
     204                 :     /**
     205                 :      * Given aParent that does not contain aChild, starting with aChild's
     206                 :      * first root tag, try to find aParent. If we can reach aParent simply by
     207                 :      * going up each first root tag, then return true. Otherwise, we could not
     208                 :      * propagate from aChild up to aParent, so return false.
     209                 :      *
     210                 :      * @param   aParent Tag type of parent
     211                 :      * @param   aChild Tag type of child
     212                 :      * @return  true if closure was achieved -- other false
     213                 :      */
     214                 :     bool BackwardPropagate(nsString& aSequence,
     215                 :                              eHTMLTags aParent,
     216                 :                              eHTMLTags aChild) const;
     217                 : 
     218                 :     /**
     219                 :      * Attempt forward and/or backward propagation for the given child within
     220                 :      * the current context vector stack. And actually open the required tags.
     221                 :      *
     222                 :      * @param   aParent The tag we're trying to open this element inside of.
     223                 :      * @param   aChild Type of child to be propagated.
     224                 :      */
     225                 :     void CreateContextStackFor(eHTMLTags aParent, eHTMLTags aChild);
     226                 : 
     227                 :     /**
     228                 :      * Ask if a given container is open anywhere on its stack
     229                 :      *
     230                 :      * @param   id of container you want to test for
     231                 :      * @return  TRUE if the given container type is open -- otherwise FALSE
     232                 :      */
     233                 :     bool HasOpenContainer(eHTMLTags aContainer) const;
     234                 : 
     235                 :     /**
     236                 :      * This method allows the caller to determine if a any member
     237                 :      * in a set of tags is currently open.
     238                 :      *
     239                 :      * @param   aTagSet A set of tags you care about.
     240                 :      * @return  true if any of the members of aTagSet are currently open.
     241                 :      */
     242                 :     bool HasOpenContainer(const eHTMLTags aTagSet[], PRInt32 aCount) const;
     243                 : 
     244                 :     /**
     245                 :      * Accessor that retrieves the tag type of the topmost item on the DTD's
     246                 :      * tag stack.
     247                 :      *
     248                 :      * @return The tag type (may be unknown)
     249                 :      */
     250                 :     eHTMLTags GetTopNode() const;
     251                 : 
     252                 :     /**
     253                 :      * Finds the topmost occurrence of given tag within context vector stack.
     254                 :      *
     255                 :      * @param   tag to be found
     256                 :      * @return  index of topmost tag occurrence -- may be -1 (kNotFound).
     257                 :      */
     258                 :     PRInt32 LastOf(eHTMLTags aTagSet[], PRInt32 aCount) const;
     259                 : 
     260                 :     nsresult HandleToken(CToken* aToken);
     261                 : 
     262                 :     /**
     263                 :      *  This method gets called when a start token has been
     264                 :      *  encountered in the parse process. If the current container
     265                 :      *  can contain this tag, then add it. Otherwise, you have
     266                 :      *  two choices: 1) create an implicit container for this tag
     267                 :      *                  to be stored in
     268                 :      *               2) close the top container, and add this to
     269                 :      *                  whatever container ends up on top.
     270                 :      *
     271                 :      *  @param   aToken -- next (start) token to be handled
     272                 :      *  @return  Whether or not we should block the parser.
     273                 :      */
     274                 :     nsresult    HandleStartToken(CToken* aToken);
     275                 : 
     276                 :     /** 
     277                 :      *  This method gets called when a start token has been 
     278                 :      *  encountered in the parse process. If the current container
     279                 :      *  can contain this tag, then add it. Otherwise, you have
     280                 :      *  two choices: 1) create an implicit container for this tag
     281                 :      *                  to be stored in
     282                 :      *               2) close the top container, and add this to
     283                 :      *                  whatever container ends up on top.
     284                 :      *   
     285                 :      *  @param   aToken Next (start) token to be handled.
     286                 :      *  @param   aChildTag The tag corresponding to aToken.
     287                 :      *  @param   aNode CParserNode representing this start token
     288                 :      *  @return  A potential request to block the parser.
     289                 :      */
     290                 :     nsresult    HandleDefaultStartToken(CToken* aToken, eHTMLTags aChildTag,
     291                 :                                         nsCParserNode *aNode);
     292                 :     nsresult    HandleEndToken(CToken* aToken);
     293                 :     nsresult    HandleEntityToken(CToken* aToken);
     294                 :     nsresult    HandleCommentToken(CToken* aToken);
     295                 :     nsresult    HandleAttributeToken(CToken* aToken);
     296                 :     nsresult    HandleProcessingInstructionToken(CToken* aToken);
     297                 :     nsresult    HandleDocTypeDeclToken(CToken* aToken);
     298                 :     nsresult    BuildNeglectedTarget(eHTMLTags aTarget, eHTMLTokenTypes aType);
     299                 : 
     300                 :     nsresult OpenHTML(const nsCParserNode *aNode);
     301                 :     nsresult OpenBody(const nsCParserNode *aNode);
     302                 : 
     303                 :     /**
     304                 :      * The special purpose methods automatically close
     305                 :      * one or more open containers.
     306                 :      * @return  error code - 0 if all went well.
     307                 :      */
     308                 :     nsresult CloseContainer(const eHTMLTags aTag, bool aMalformed);
     309                 :     nsresult CloseContainersTo(eHTMLTags aTag, bool aClosedByStartTag);
     310                 :     nsresult CloseContainersTo(PRInt32 anIndex, eHTMLTags aTag,
     311                 :                                bool aClosedByStartTag);
     312                 :     nsresult CloseResidualStyleTags(const eHTMLTags aTag,
     313                 :                                     bool aClosedByStartTag);
     314                 : 
     315                 :     /**
     316                 :      * Causes leaf to be added to sink at current vector pos.
     317                 :      * @param   aNode is leaf node to be added.
     318                 :      * @return  error code - 0 if all went well.
     319                 :      */
     320                 :     nsresult AddLeaf(const nsIParserNode *aNode);
     321                 :     nsresult AddHeadContent(nsIParserNode *aNode);
     322                 : 
     323                 :     /**
     324                 :      * This set of methods is used to create and manage the set of
     325                 :      * transient styles that occur as a result of poorly formed HTML
     326                 :      * or bugs in the original navigator.
     327                 :      *
     328                 :      * @param   aTag -- represents the transient style tag to be handled.
     329                 :      * @return  error code -- usually 0
     330                 :      */
     331                 :     nsresult  OpenTransientStyles(eHTMLTags aChildTag,
     332                 :                                   bool aCloseInvalid = true);
     333                 :     void      PopStyle(eHTMLTags aTag);
     334                 : 
     335              54 :     nsresult  PushIntoMisplacedStack(CToken* aToken)
     336                 :     {
     337              54 :       NS_ENSURE_ARG_POINTER(aToken);
     338              54 :       aToken->SetNewlineCount(0); // Note: We have already counted the newlines for these tokens
     339                 : 
     340              54 :       mMisplacedContent.Push(aToken);
     341              54 :       return NS_OK;
     342                 :     }
     343                 : 
     344                 : protected:
     345                 : 
     346                 :     nsresult        CollectAttributes(nsIParserNode* aNode,eHTMLTags aTag,PRInt32 aCount);
     347                 : 
     348                 :     /**
     349                 :      * This gets called before we've handled a given start tag.
     350                 :      * It's a generic hook to let us do pre processing.
     351                 :      *
     352                 :      * @param   aToken contains the tag in question
     353                 :      * @param   aTag is the tag itself.
     354                 :      * @param   aNode is the node (tag) with associated attributes.
     355                 :      * @return  NS_OK if we should continue, a failure code otherwise.
     356                 :      */
     357                 :     nsresult        WillHandleStartTag(CToken* aToken,eHTMLTags aChildTag,nsIParserNode& aNode);
     358                 :     nsresult        DidHandleStartTag(nsIParserNode& aNode,eHTMLTags aChildTag);
     359                 : 
     360                 :     /**
     361                 :      *  This method gets called when a start token has been encountered that
     362                 :      *  the parent wants to omit. It stashes it in the current element if that
     363                 :      *  element accepts such misplaced tokens.
     364                 :      *
     365                 :      *  @param   aToken Next (start) token to be handled
     366                 :      *  @param   aChildTag id of the child in question
     367                 :      *  @param   aParent id of the parent in question
     368                 :      *  @param   aNode CParserNode representing this start token
     369                 :      */
     370                 :     void            HandleOmittedTag(CToken* aToken, eHTMLTags aChildTag,
     371                 :                                      eHTMLTags aParent, nsIParserNode *aNode);
     372                 :     nsresult        HandleSavedTokens(PRInt32 anIndex);
     373                 :     nsresult        HandleKeyGen(nsIParserNode *aNode);
     374                 :     bool            IsAlternateTag(eHTMLTags aTag);
     375                 :     bool            IsBlockElement(PRInt32 aTagID, PRInt32 aParentID) const;
     376                 :     bool            IsInlineElement(PRInt32 aTagID, PRInt32 aParentID) const;
     377                 : 
     378                 :     nsDeque             mMisplacedContent;
     379                 :     
     380                 :     nsCOMPtr<nsIHTMLContentSink> mSink;
     381                 :     nsTokenAllocator*   mTokenAllocator;
     382                 :     nsDTDContext*       mBodyContext;
     383                 :     nsDTDContext*       mTempContext;
     384                 :     bool                mCountLines;
     385                 :     nsITokenizer*       mTokenizer; // weak
     386                 :    
     387                 :     nsString            mFilename; 
     388                 :     nsString            mScratch;  //used for various purposes; non-persistent
     389                 :     nsCString           mMimeType;
     390                 : 
     391                 :     nsNodeAllocator     mNodeAllocator;
     392                 :     nsDTDMode           mDTDMode;
     393                 :     eParserDocType      mDocType;
     394                 :     eParserCommands     mParserCommand;   //tells us to viewcontent/viewsource/viewerrors...
     395                 : 
     396                 :     PRInt32             mLineNumber;
     397                 :     PRInt32             mOpenMapCount;
     398                 :     PRInt32             mHeadContainerPosition;
     399                 : 
     400                 :     PRUint16            mFlags;
     401                 : };
     402                 : 
     403                 : #endif 
     404                 : 
     405                 : 
     406                 : 

Generated by: LCOV version 1.7