parser/html/nsHtml5TreeOperation.h

Wed, 31 Dec 2014 13:27:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 13:27:57 +0100
branch
TOR_BUG_3246
changeset 6
8bccb770b82d
permissions
-rw-r--r--

Ignore runtime configuration files generated during quality assurance.

     1 /* This Source Code Form is subject to the terms of the Mozilla Public
     2  * License, v. 2.0. If a copy of the MPL was not distributed with this
     3  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     5 #ifndef nsHtml5TreeOperation_h
     6 #define nsHtml5TreeOperation_h
     8 #include "nsHtml5DocumentMode.h"
     9 #include "nsHtml5HtmlAttributes.h"
    10 #include "nsXPCOMStrings.h"
    11 #include "mozilla/dom/FromParser.h"
    13 class nsIContent;
    14 class nsHtml5TreeOpExecutor;
    15 class nsHtml5StateSnapshot;
    16 class nsHtml5DocumentBuilder;
    18 enum eHtml5TreeOperation {
    19 #ifdef DEBUG
    20   eTreeOpUninitialized,
    21 #endif
    22   // main HTML5 ops
    23   eTreeOpAppend,
    24   eTreeOpDetach,
    25   eTreeOpAppendChildrenToNewParent,
    26   eTreeOpFosterParent,
    27   eTreeOpAppendToDocument,
    28   eTreeOpAddAttributes,
    29   eTreeOpDocumentMode,
    30   eTreeOpCreateElementNetwork,
    31   eTreeOpCreateElementNotNetwork,
    32   eTreeOpSetFormElement,
    33   eTreeOpAppendText,
    34   eTreeOpAppendIsindexPrompt,
    35   eTreeOpFosterParentText,
    36   eTreeOpAppendComment,
    37   eTreeOpAppendCommentToDocument,
    38   eTreeOpAppendDoctypeToDocument,
    39   eTreeOpGetDocumentFragmentForTemplate,
    40   // Gecko-specific on-pop ops
    41   eTreeOpMarkAsBroken,
    42   eTreeOpRunScript,
    43   eTreeOpRunScriptAsyncDefer,
    44   eTreeOpPreventScriptExecution,
    45   eTreeOpDoneAddingChildren,
    46   eTreeOpDoneCreatingElement,
    47   eTreeOpFlushPendingAppendNotifications,
    48   eTreeOpSetDocumentCharset,
    49   eTreeOpNeedsCharsetSwitchTo,
    50   eTreeOpUpdateStyleSheet,
    51   eTreeOpProcessMeta,
    52   eTreeOpProcessOfflineManifest,
    53   eTreeOpMarkMalformedIfScript,
    54   eTreeOpStreamEnded,
    55   eTreeOpSetStyleLineNumber,
    56   eTreeOpSetScriptLineNumberAndFreeze,
    57   eTreeOpSvgLoad,
    58   eTreeOpMaybeComplainAboutCharset,
    59   eTreeOpAddClass,
    60   eTreeOpAddViewSourceHref,
    61   eTreeOpAddError,
    62   eTreeOpAddLineNumberId,
    63   eTreeOpAddErrorAtom,
    64   eTreeOpAddErrorTwoAtoms,
    65   eTreeOpStartLayout
    66 };
    68 class nsHtml5TreeOperationStringPair {
    69   private:
    70     nsString mPublicId;
    71     nsString mSystemId;
    72   public:
    73     nsHtml5TreeOperationStringPair(const nsAString& aPublicId, 
    74                                    const nsAString& aSystemId)
    75       : mPublicId(aPublicId)
    76       , mSystemId(aSystemId)
    77     {
    78       MOZ_COUNT_CTOR(nsHtml5TreeOperationStringPair);
    79     }
    81     ~nsHtml5TreeOperationStringPair()
    82     {
    83       MOZ_COUNT_DTOR(nsHtml5TreeOperationStringPair);    
    84     }
    86     inline void Get(nsAString& aPublicId, nsAString& aSystemId)
    87     {
    88       aPublicId.Assign(mPublicId);
    89       aSystemId.Assign(mSystemId);
    90     }
    91 };
    93 class nsHtml5TreeOperation {
    95   public:
    96     /**
    97      * Atom is used inside the parser core are either static atoms that are
    98      * the same as Gecko-wide static atoms or they are dynamic atoms scoped by
    99      * both thread and parser to a particular nsHtml5AtomTable. In order to
   100      * such scoped atoms coming into contact with the rest of Gecko, atoms
   101      * that are about to exit the parser must go through this method which
   102      * reobtains dynamic atoms from the Gecko-global atom table.
   103      *
   104      * @param aAtom a potentially parser-scoped atom
   105      * @return an nsIAtom that's pointer comparable on the main thread with
   106      *         other not-parser atoms.
   107      */
   108     static inline already_AddRefed<nsIAtom> Reget(nsIAtom* aAtom)
   109     {
   110       if (!aAtom || aAtom->IsStaticAtom()) {
   111         return dont_AddRef(aAtom);
   112       }
   113       nsAutoString str;
   114       aAtom->ToString(str);
   115       return do_GetAtom(str);
   116     }
   118     static nsresult AppendTextToTextNode(const char16_t* aBuffer,
   119                                          uint32_t aLength,
   120                                          nsIContent* aTextNode,
   121                                          nsHtml5DocumentBuilder* aBuilder);
   123     static nsresult AppendText(const char16_t* aBuffer,
   124                                uint32_t aLength,
   125                                nsIContent* aParent,
   126                                nsHtml5DocumentBuilder* aBuilder);
   128     static nsresult Append(nsIContent* aNode,
   129                            nsIContent* aParent,
   130                            nsHtml5DocumentBuilder* aBuilder);
   132     static nsresult AppendToDocument(nsIContent* aNode,
   133                                      nsHtml5DocumentBuilder* aBuilder);
   135     static void Detach(nsIContent* aNode, nsHtml5DocumentBuilder* aBuilder);
   137     static nsresult AppendChildrenToNewParent(nsIContent* aNode,
   138                                               nsIContent* aParent,
   139                                               nsHtml5DocumentBuilder* aBuilder);
   141     static nsresult FosterParent(nsIContent* aNode,
   142                                  nsIContent* aParent,
   143                                  nsIContent* aTable,
   144                                  nsHtml5DocumentBuilder* aBuilder);
   146     static nsresult AddAttributes(nsIContent* aNode,
   147                                   nsHtml5HtmlAttributes* aAttributes,
   148                                   nsHtml5DocumentBuilder* aBuilder);
   150     static nsIContent* CreateElement(int32_t aNs,
   151                                      nsIAtom* aName,
   152                                      nsHtml5HtmlAttributes* aAttributes,
   153                                      mozilla::dom::FromParser aFromParser,
   154                                      nsHtml5DocumentBuilder* aBuilder);
   156     static void SetFormElement(nsIContent* aNode, nsIContent* aParent);
   158     static nsresult AppendIsindexPrompt(nsIContent* parent,
   159                                         nsHtml5DocumentBuilder* aBuilder);
   161     static nsresult FosterParentText(nsIContent* aStackParent,
   162                                      char16_t* aBuffer,
   163                                      uint32_t aLength,
   164                                      nsIContent* aTable,
   165                                      nsHtml5DocumentBuilder* aBuilder);
   167     static nsresult AppendComment(nsIContent* aParent,
   168                                   char16_t* aBuffer,
   169                                   int32_t aLength,
   170                                   nsHtml5DocumentBuilder* aBuilder);
   172     static nsresult AppendCommentToDocument(char16_t* aBuffer,
   173                                            int32_t aLength,
   174                                            nsHtml5DocumentBuilder* aBuilder);
   176     static nsresult AppendDoctypeToDocument(nsIAtom* aName,
   177                                             const nsAString& aPublicId,
   178                                             const nsAString& aSystemId,
   179                                             nsHtml5DocumentBuilder* aBuilder);
   181     static nsIContent* GetDocumentFragmentForTemplate(nsIContent* aNode);
   183     static void PreventScriptExecution(nsIContent* aNode);
   185     static void DoneAddingChildren(nsIContent* aNode,
   186                                    nsHtml5DocumentBuilder* aBuilder);
   188     static void DoneCreatingElement(nsIContent* aNode);
   190     static void SvgLoad(nsIContent* aNode);
   192     static void MarkMalformedIfScript(nsIContent* aNode);
   194     nsHtml5TreeOperation();
   196     ~nsHtml5TreeOperation();
   198     inline void Init(eHtml5TreeOperation aOpCode)
   199     {
   200       NS_PRECONDITION(mOpCode == eTreeOpUninitialized,
   201         "Op code must be uninitialized when initializing.");
   202       mOpCode = aOpCode;
   203     }
   205     inline void Init(eHtml5TreeOperation aOpCode, nsIContentHandle* aNode)
   206     {
   207       NS_PRECONDITION(mOpCode == eTreeOpUninitialized,
   208         "Op code must be uninitialized when initializing.");
   209       NS_PRECONDITION(aNode, "Initialized tree op with null node.");
   210       mOpCode = aOpCode;
   211       mOne.node = static_cast<nsIContent**>(aNode);
   212     }
   214     inline void Init(eHtml5TreeOperation aOpCode, 
   215                      nsIContentHandle* aNode,
   216                      nsIContentHandle* aParent)
   217     {
   218       NS_PRECONDITION(mOpCode == eTreeOpUninitialized,
   219         "Op code must be uninitialized when initializing.");
   220       NS_PRECONDITION(aNode, "Initialized tree op with null node.");
   221       NS_PRECONDITION(aParent, "Initialized tree op with null parent.");
   222       mOpCode = aOpCode;
   223       mOne.node = static_cast<nsIContent**>(aNode);
   224       mTwo.node = static_cast<nsIContent**>(aParent);
   225     }
   227     inline void Init(eHtml5TreeOperation aOpCode, 
   228                      const nsACString& aString,
   229                      int32_t aInt32)
   230     {
   231       NS_PRECONDITION(mOpCode == eTreeOpUninitialized,
   232         "Op code must be uninitialized when initializing.");
   234       int32_t len = aString.Length();
   235       char* str = new char[len + 1];
   236       const char* start = aString.BeginReading();
   237       for (int32_t i = 0; i < len; ++i) {
   238         str[i] = start[i];
   239       }
   240       str[len] = '\0';
   242       mOpCode = aOpCode;
   243       mOne.charPtr = str;
   244       mFour.integer = aInt32;
   245     }
   247     inline void Init(eHtml5TreeOperation aOpCode,
   248                      const nsACString& aString,
   249                      int32_t aInt32,
   250                      int32_t aLineNumber)
   251     {
   252       Init(aOpCode, aString, aInt32);
   253       mTwo.integer = aLineNumber;
   254     }
   256     inline void Init(eHtml5TreeOperation aOpCode,
   257                      nsIContentHandle* aNode,
   258                      nsIContentHandle* aParent,
   259                      nsIContentHandle* aTable)
   260     {
   261       NS_PRECONDITION(mOpCode == eTreeOpUninitialized,
   262         "Op code must be uninitialized when initializing.");
   263       NS_PRECONDITION(aNode, "Initialized tree op with null node.");
   264       NS_PRECONDITION(aParent, "Initialized tree op with null parent.");
   265       NS_PRECONDITION(aTable, "Initialized tree op with null table.");
   266       mOpCode = aOpCode;
   267       mOne.node = static_cast<nsIContent**>(aNode);
   268       mTwo.node = static_cast<nsIContent**>(aParent);
   269       mThree.node = static_cast<nsIContent**>(aTable);
   270     }
   272     inline void Init(nsHtml5DocumentMode aMode)
   273     {
   274       NS_PRECONDITION(mOpCode == eTreeOpUninitialized,
   275         "Op code must be uninitialized when initializing.");
   276       mOpCode = eTreeOpDocumentMode;
   277       mOne.mode = aMode;
   278     }
   280     inline void InitScript(nsIContentHandle* aNode)
   281     {
   282       NS_PRECONDITION(mOpCode == eTreeOpUninitialized,
   283         "Op code must be uninitialized when initializing.");
   284       NS_PRECONDITION(aNode, "Initialized tree op with null node.");
   285       mOpCode = eTreeOpRunScript;
   286       mOne.node = static_cast<nsIContent**>(aNode);
   287       mTwo.state = nullptr;
   288     }
   290     inline void Init(int32_t aNamespace, 
   291                      nsIAtom* aName, 
   292                      nsHtml5HtmlAttributes* aAttributes,
   293                      nsIContentHandle* aTarget,
   294                      bool aFromNetwork)
   295     {
   296       NS_PRECONDITION(mOpCode == eTreeOpUninitialized,
   297         "Op code must be uninitialized when initializing.");
   298       NS_PRECONDITION(aName, "Initialized tree op with null name.");
   299       NS_PRECONDITION(aTarget, "Initialized tree op with null target node.");
   300       mOpCode = aFromNetwork ?
   301                 eTreeOpCreateElementNetwork :
   302                 eTreeOpCreateElementNotNetwork;
   303       mFour.integer = aNamespace;
   304       mOne.node = static_cast<nsIContent**>(aTarget);
   305       mTwo.atom = aName;
   306       if (aAttributes == nsHtml5HtmlAttributes::EMPTY_ATTRIBUTES) {
   307         mThree.attributes = nullptr;
   308       } else {
   309         mThree.attributes = aAttributes;
   310       }
   311     }
   313     inline void Init(eHtml5TreeOperation aOpCode, 
   314                      char16_t* aBuffer, 
   315                      int32_t aLength, 
   316                      nsIContentHandle* aStackParent,
   317                      nsIContentHandle* aTable)
   318     {
   319       NS_PRECONDITION(mOpCode == eTreeOpUninitialized,
   320         "Op code must be uninitialized when initializing.");
   321       NS_PRECONDITION(aBuffer, "Initialized tree op with null buffer.");
   322       mOpCode = aOpCode;
   323       mOne.node = static_cast<nsIContent**>(aStackParent);
   324       mTwo.unicharPtr = aBuffer;
   325       mThree.node = static_cast<nsIContent**>(aTable);
   326       mFour.integer = aLength;
   327     }
   329     inline void Init(eHtml5TreeOperation aOpCode, 
   330                      char16_t* aBuffer, 
   331                      int32_t aLength, 
   332                      nsIContentHandle* aParent)
   333     {
   334       NS_PRECONDITION(mOpCode == eTreeOpUninitialized,
   335         "Op code must be uninitialized when initializing.");
   336       NS_PRECONDITION(aBuffer, "Initialized tree op with null buffer.");
   337       mOpCode = aOpCode;
   338       mOne.node = static_cast<nsIContent**>(aParent);
   339       mTwo.unicharPtr = aBuffer;
   340       mFour.integer = aLength;
   341     }
   343     inline void Init(eHtml5TreeOperation aOpCode, 
   344                      char16_t* aBuffer, 
   345                      int32_t aLength)
   346     {
   347       NS_PRECONDITION(mOpCode == eTreeOpUninitialized,
   348         "Op code must be uninitialized when initializing.");
   349       NS_PRECONDITION(aBuffer, "Initialized tree op with null buffer.");
   350       mOpCode = aOpCode;
   351       mTwo.unicharPtr = aBuffer;
   352       mFour.integer = aLength;
   353     }
   355     inline void Init(nsIContentHandle* aElement,
   356                      nsHtml5HtmlAttributes* aAttributes)
   357     {
   358       NS_PRECONDITION(mOpCode == eTreeOpUninitialized,
   359         "Op code must be uninitialized when initializing.");
   360       NS_PRECONDITION(aElement, "Initialized tree op with null element.");
   361       mOpCode = eTreeOpAddAttributes;
   362       mOne.node = static_cast<nsIContent**>(aElement);
   363       mTwo.attributes = aAttributes;
   364     }
   366     inline void Init(nsIAtom* aName, 
   367                      const nsAString& aPublicId, 
   368                      const nsAString& aSystemId)
   369     {
   370       NS_PRECONDITION(mOpCode == eTreeOpUninitialized,
   371         "Op code must be uninitialized when initializing.");
   372       mOpCode = eTreeOpAppendDoctypeToDocument;
   373       mOne.atom = aName;
   374       mTwo.stringPair = new nsHtml5TreeOperationStringPair(aPublicId, aSystemId);
   375     }
   377     inline void Init(nsIContentHandle* aElement,
   378                      const char* aMsgId,
   379                      nsIAtom* aAtom,
   380                      nsIAtom* aOtherAtom)
   381     {
   382       NS_PRECONDITION(mOpCode == eTreeOpUninitialized,
   383         "Op code must be uninitialized when initializing.");
   384       mOpCode = eTreeOpAddError;
   385       mOne.node = static_cast<nsIContent**>(aElement);
   386       mTwo.charPtr = (char*)aMsgId;
   387       mThree.atom = aAtom;
   388       mFour.atom = aOtherAtom;
   389     }
   391     inline void Init(nsIContentHandle* aElement,
   392                      const char* aMsgId,
   393                      nsIAtom* aAtom)
   394     {
   395       Init(aElement, aMsgId, aAtom, nullptr);
   396     }
   398     inline void Init(nsIContentHandle* aElement,
   399                      const char* aMsgId)
   400     {
   401       Init(aElement, aMsgId, nullptr, nullptr);
   402     }
   404     inline void Init(const char* aMsgId,
   405                      bool aError,
   406                      int32_t aLineNumber)
   407     {
   408       NS_PRECONDITION(mOpCode == eTreeOpUninitialized,
   409         "Op code must be uninitialized when initializing.");
   410       mOpCode = eTreeOpMaybeComplainAboutCharset;
   411       mOne.charPtr = const_cast<char*>(aMsgId);
   412       mTwo.integer = aError;
   413       mThree.integer = aLineNumber;
   414     }
   416     inline void Init(eHtml5TreeOperation aOpCode, const nsAString& aString)
   417     {
   418       NS_PRECONDITION(mOpCode == eTreeOpUninitialized,
   419         "Op code must be uninitialized when initializing.");
   421       char16_t* str = NS_StringCloneData(aString);
   422       mOpCode = aOpCode;
   423       mOne.unicharPtr = str;
   424     }
   426     inline void Init(eHtml5TreeOperation aOpCode,
   427                      nsIContentHandle* aNode,
   428                      int32_t aInt)
   429     {
   430       NS_PRECONDITION(mOpCode == eTreeOpUninitialized,
   431         "Op code must be uninitialized when initializing.");
   432       NS_PRECONDITION(aNode, "Initialized tree op with null node.");
   433       mOpCode = aOpCode;
   434       mOne.node = static_cast<nsIContent**>(aNode);
   435       mFour.integer = aInt;
   436     }
   438     inline void Init(nsresult aRv)
   439     {
   440       NS_PRECONDITION(mOpCode == eTreeOpUninitialized,
   441         "Op code must be uninitialized when initializing.");
   442       NS_PRECONDITION(NS_FAILED(aRv), "Initialized tree op with non-failure.");
   443       mOpCode = eTreeOpMarkAsBroken;
   444       mOne.result = aRv;
   445     }
   447     inline void InitAddClass(nsIContentHandle* aNode, const char16_t* aClass)
   448     {
   449       NS_PRECONDITION(mOpCode == eTreeOpUninitialized,
   450         "Op code must be uninitialized when initializing.");
   451       NS_PRECONDITION(aNode, "Initialized tree op with null node.");
   452       NS_PRECONDITION(aClass, "Initialized tree op with null string.");
   453       // aClass must be a literal string that does not need freeing
   454       mOpCode = eTreeOpAddClass;
   455       mOne.node = static_cast<nsIContent**>(aNode);
   456       mTwo.unicharPtr = (char16_t*)aClass;
   457     }
   459     inline void InitAddLineNumberId(nsIContentHandle* aNode,
   460                                     const int32_t aLineNumber)
   461     {
   462       NS_PRECONDITION(mOpCode == eTreeOpUninitialized,
   463         "Op code must be uninitialized when initializing.");
   464       NS_PRECONDITION(aNode, "Initialized tree op with null node.");
   465       NS_PRECONDITION(aLineNumber > 0, "Initialized tree op with line number.");
   466       // aClass must be a literal string that does not need freeing
   467       mOpCode = eTreeOpAddLineNumberId;
   468       mOne.node = static_cast<nsIContent**>(aNode);
   469       mFour.integer = aLineNumber;
   470     }
   472     inline bool IsRunScript()
   473     {
   474       return mOpCode == eTreeOpRunScript;
   475     }
   477     inline void SetSnapshot(nsAHtml5TreeBuilderState* aSnapshot, int32_t aLine)
   478     {
   479       NS_ASSERTION(IsRunScript(), 
   480         "Setting a snapshot for a tree operation other than eTreeOpRunScript!");
   481       NS_PRECONDITION(aSnapshot, "Initialized tree op with null snapshot.");
   482       mTwo.state = aSnapshot;
   483       mFour.integer = aLine;
   484     }
   486     nsresult Perform(nsHtml5TreeOpExecutor* aBuilder,
   487                      nsIContent** aScriptElement);
   489   private:
   490     // possible optimization:
   491     // Make the queue take items the size of pointer and make the op code
   492     // decide how many operands it dequeues after it.
   493     eHtml5TreeOperation mOpCode;
   494     union {
   495       nsIContent**                    node;
   496       nsIAtom*                        atom;
   497       nsHtml5HtmlAttributes*          attributes;
   498       nsHtml5DocumentMode             mode;
   499       char16_t*                       unicharPtr;
   500       char*                           charPtr;
   501       nsHtml5TreeOperationStringPair* stringPair;
   502       nsAHtml5TreeBuilderState*       state;
   503       int32_t                         integer;
   504       nsresult                        result;
   505     }                   mOne, mTwo, mThree, mFour;
   506 };
   508 #endif // nsHtml5TreeOperation_h

mercurial