LCOV - app.info - parser/htmlparser/src/CNavDTD.h

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