Back to index

lightning-sunbird  0.9+nobinonly
nsHTMLFragmentContentSink.cpp
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
00002 /* vim: set sw=2 ts=2 et tw=80: */
00003 /* ***** BEGIN LICENSE BLOCK *****
00004  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00005  *
00006  * The contents of this file are subject to the Mozilla Public License Version
00007  * 1.1 (the "License"); you may not use this file except in compliance with
00008  * the License. You may obtain a copy of the License at
00009  * http://www.mozilla.org/MPL/
00010  *
00011  * Software distributed under the License is distributed on an "AS IS" basis,
00012  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00013  * for the specific language governing rights and limitations under the
00014  * License.
00015  *
00016  * The Original Code is mozilla.org code.
00017  *
00018  * The Initial Developer of the Original Code is
00019  * Netscape Communications Corporation.
00020  * Portions created by the Initial Developer are Copyright (C) 1998
00021  * the Initial Developer. All Rights Reserved.
00022  *
00023  * Contributor(s):
00024  *   Robert Sayre <sayrer@gmail.com>
00025  *
00026  * Alternatively, the contents of this file may be used under the terms of
00027  * either of the GNU General Public License Version 2 or later (the "GPL"),
00028  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00029  * in which case the provisions of the GPL or the LGPL are applicable instead
00030  * of those above. If you wish to allow use of your version of this file only
00031  * under the terms of either the GPL or the LGPL, and not to allow others to
00032  * use your version of this file under the terms of the MPL, indicate your
00033  * decision by deleting the provisions above and replace them with the notice
00034  * and other provisions required by the GPL or the LGPL. If you do not delete
00035  * the provisions above, a recipient may use your version of this file under
00036  * the terms of any one of the MPL, the GPL or the LGPL.
00037  *
00038  * ***** END LICENSE BLOCK ***** */
00039 #include "nsCOMPtr.h"
00040 #include "nsIServiceManager.h"
00041 #include "nsIFragmentContentSink.h"
00042 #include "nsIHTMLContentSink.h"
00043 #include "nsIParser.h"
00044 #include "nsIParserService.h"
00045 #include "nsHTMLAtoms.h"
00046 #include "nsHTMLTokens.h"
00047 #include "nsGenericHTMLElement.h"
00048 #include "nsIDOMText.h"
00049 #include "nsIDOMComment.h"
00050 #include "nsIDOMHTMLFormElement.h"
00051 #include "nsIDOMDocumentFragment.h"
00052 #include "nsVoidArray.h"
00053 #include "nsITextContent.h"
00054 #include "nsINameSpaceManager.h"
00055 #include "nsIDocument.h"
00056 #include "nsINodeInfo.h"
00057 #include "prmem.h"
00058 #include "nsReadableUtils.h"
00059 #include "nsUnicharUtils.h"
00060 #include "nsContentUtils.h"
00061 #include "nsEscape.h"
00062 #include "nsNodeInfoManager.h"
00063 #include "nsContentCreatorFunctions.h"
00064 #include "nsIScriptSecurityManager.h"
00065 #include "nsContentSink.h"
00066 #include "nsTHashtable.h"
00067 #include "nsNetUtil.h"
00068 //
00069 // XXX THIS IS TEMPORARY CODE
00070 // There's a considerable amount of copied code from the
00071 // regular nsHTMLContentSink. All of it will be factored
00072 // at some pointe really soon!
00073 //
00074 
00075 class nsHTMLFragmentContentSink : public nsIFragmentContentSink,
00076                                   public nsIHTMLContentSink {
00077 public:
00078   nsHTMLFragmentContentSink(PRBool aAllContent = PR_FALSE);
00079   virtual ~nsHTMLFragmentContentSink();
00080 
00081   // nsISupports
00082   NS_DECL_ISUPPORTS
00083 
00084   // nsIContentSink
00085   NS_IMETHOD WillBuildModel(void);
00086   NS_IMETHOD DidBuildModel(void);
00087   NS_IMETHOD WillInterrupt(void);
00088   NS_IMETHOD WillResume(void);
00089   NS_IMETHOD SetParser(nsIParser* aParser);
00090   virtual void FlushPendingNotifications(mozFlushType aType) { }
00091   NS_IMETHOD SetDocumentCharset(nsACString& aCharset) { return NS_OK; }
00092   virtual nsISupports *GetTarget() { return mTargetDocument; }
00093 
00094   // nsIHTMLContentSink
00095   NS_IMETHOD BeginContext(PRInt32 aID);
00096   NS_IMETHOD EndContext(PRInt32 aID);
00097   NS_IMETHOD SetTitle(const nsString& aValue);
00098   NS_IMETHOD OpenHTML(const nsIParserNode& aNode);
00099   NS_IMETHOD CloseHTML();
00100   NS_IMETHOD OpenHead(const nsIParserNode& aNode);
00101   NS_IMETHOD CloseHead();
00102   NS_IMETHOD OpenBody(const nsIParserNode& aNode);
00103   NS_IMETHOD CloseBody();
00104   NS_IMETHOD OpenForm(const nsIParserNode& aNode);
00105   NS_IMETHOD CloseForm();
00106   NS_IMETHOD OpenFrameset(const nsIParserNode& aNode);
00107   NS_IMETHOD CloseFrameset();
00108   NS_IMETHOD IsEnabled(PRInt32 aTag, PRBool* aReturn) {
00109     *aReturn = PR_TRUE;
00110     return NS_OK;
00111   }
00112   NS_IMETHOD_(PRBool) IsFormOnStack() { return PR_FALSE; }
00113   NS_IMETHOD OpenMap(const nsIParserNode& aNode);
00114   NS_IMETHOD CloseMap();
00115   NS_IMETHOD WillProcessTokens(void) { return NS_OK; }
00116   NS_IMETHOD DidProcessTokens(void) { return NS_OK; }
00117   NS_IMETHOD WillProcessAToken(void) { return NS_OK; }
00118   NS_IMETHOD DidProcessAToken(void) { return NS_OK; }
00119   NS_IMETHOD NotifyTagObservers(nsIParserNode* aNode) { return NS_OK; }
00120   NS_IMETHOD OpenContainer(const nsIParserNode& aNode);
00121   NS_IMETHOD CloseContainer(const nsHTMLTag aTag);
00122   NS_IMETHOD AddHeadContent(const nsIParserNode& aNode);
00123   NS_IMETHOD AddLeaf(const nsIParserNode& aNode);
00124   NS_IMETHOD AddComment(const nsIParserNode& aNode);
00125   NS_IMETHOD AddProcessingInstruction(const nsIParserNode& aNode);
00126   NS_IMETHOD AddDocTypeDecl(const nsIParserNode& aNode);
00127 
00128   // nsIFragmentContentSink
00129   NS_IMETHOD GetFragment(nsIDOMDocumentFragment** aFragment);
00130   NS_IMETHOD SetTargetDocument(nsIDocument* aDocument);
00131   NS_IMETHOD WillBuildContent();
00132   NS_IMETHOD DidBuildContent();
00133   NS_IMETHOD IgnoreFirstContainer();
00134 
00135   nsIContent* GetCurrentContent();
00136   PRInt32 PushContent(nsIContent *aContent);
00137   nsIContent* PopContent();
00138 
00139   virtual nsresult AddAttributes(const nsIParserNode& aNode,
00140                                  nsIContent* aContent);
00141 
00142   nsresult AddText(const nsAString& aString);
00143   nsresult AddTextToContent(nsIContent* aContent, const nsAString& aText);
00144   nsresult FlushText();
00145 
00146   void ProcessBaseTag(nsIContent* aContent);
00147   void AddBaseTagInfo(nsIContent* aContent);
00148 
00149   nsresult Init();
00150   nsresult SetDocumentTitle(const nsAString& aString, const nsIParserNode* aNode);
00151 
00152   PRPackedBool mAllContent;
00153   PRPackedBool mProcessing;
00154   PRPackedBool mSeenBody;
00155   PRPackedBool mIgnoreContainer;
00156 
00157   nsCOMPtr<nsIContent> mRoot;
00158   nsCOMPtr<nsIParser> mParser;
00159 
00160   nsVoidArray* mContentStack;
00161 
00162   PRUnichar* mText;
00163   PRInt32 mTextLength;
00164   PRInt32 mTextSize;
00165 
00166   nsString mBaseHREF;
00167   nsString mBaseTarget;
00168 
00169   nsCOMPtr<nsIDocument> mTargetDocument;
00170   nsRefPtr<nsNodeInfoManager> mNodeInfoManager;
00171 };
00172 
00173 static nsresult
00174 NewHTMLFragmentContentSinkHelper(PRBool aAllContent, nsIFragmentContentSink** aResult)
00175 {
00176   NS_PRECONDITION(aResult, "Null out ptr");
00177   if (nsnull == aResult) {
00178     return NS_ERROR_NULL_POINTER;
00179   }
00180 
00181   nsHTMLFragmentContentSink* it = new nsHTMLFragmentContentSink(aAllContent);
00182   if (nsnull == it) {
00183     return NS_ERROR_OUT_OF_MEMORY;
00184   }
00185   
00186   NS_ADDREF(*aResult = it);
00187   
00188   return NS_OK;
00189 }
00190 
00191 nsresult
00192 NS_NewHTMLFragmentContentSink2(nsIFragmentContentSink** aResult)
00193 {
00194   return NewHTMLFragmentContentSinkHelper(PR_TRUE,aResult);
00195 }
00196 
00197 nsresult
00198 NS_NewHTMLFragmentContentSink(nsIFragmentContentSink** aResult)
00199 {
00200   return NewHTMLFragmentContentSinkHelper(PR_FALSE,aResult);
00201 }
00202 
00203 nsHTMLFragmentContentSink::nsHTMLFragmentContentSink(PRBool aAllContent)
00204   : mAllContent(aAllContent),
00205     mProcessing(aAllContent),
00206     mSeenBody(!aAllContent),
00207     mIgnoreContainer(PR_FALSE),
00208     mContentStack(nsnull),
00209     mText(nsnull),
00210     mTextLength(0),
00211     mTextSize(0)
00212 {
00213 }
00214 
00215 nsHTMLFragmentContentSink::~nsHTMLFragmentContentSink()
00216 {
00217   // Should probably flush the text buffer here, just to make sure:
00218   //FlushText();
00219 
00220   if (nsnull != mContentStack) {
00221     // there shouldn't be anything here except in an error condition
00222     PRInt32 indx = mContentStack->Count();
00223     while (0 < indx--) {
00224       nsIContent* content = (nsIContent*)mContentStack->ElementAt(indx);
00225       NS_RELEASE(content);
00226     }
00227     delete mContentStack;
00228   }
00229 
00230   PR_FREEIF(mText);
00231 }
00232 
00233 NS_IMPL_ADDREF(nsHTMLFragmentContentSink)
00234 NS_IMPL_RELEASE(nsHTMLFragmentContentSink)
00235 
00236 NS_INTERFACE_MAP_BEGIN(nsHTMLFragmentContentSink)
00237   NS_INTERFACE_MAP_ENTRY(nsIFragmentContentSink)
00238   NS_INTERFACE_MAP_ENTRY(nsIHTMLContentSink)
00239   NS_INTERFACE_MAP_ENTRY(nsIContentSink)
00240   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIFragmentContentSink)
00241 NS_INTERFACE_MAP_END
00242 
00243 
00244 NS_IMETHODIMP 
00245 nsHTMLFragmentContentSink::WillBuildModel(void)
00246 {
00247   if (mRoot) {
00248     return NS_OK;
00249   }
00250 
00251   NS_ASSERTION(mNodeInfoManager, "Need a nodeinfo manager!");
00252 
00253   nsCOMPtr<nsIDOMDocumentFragment> frag;
00254   nsresult rv = NS_NewDocumentFragment(getter_AddRefs(frag), mNodeInfoManager);
00255   NS_ENSURE_SUCCESS(rv, rv);
00256 
00257   mRoot = do_QueryInterface(frag, &rv);
00258   
00259   return rv;
00260 }
00261 
00262 NS_IMETHODIMP
00263 nsHTMLFragmentContentSink::DidBuildModel(void)
00264 {
00265   FlushText();
00266 
00267   // Drop our reference to the parser to get rid of a circular
00268   // reference.
00269   mParser = nsnull;
00270 
00271   return NS_OK;
00272 }
00273 
00274 NS_IMETHODIMP
00275 nsHTMLFragmentContentSink::WillInterrupt(void)
00276 {
00277   return NS_OK;
00278 }
00279 
00280 NS_IMETHODIMP
00281 nsHTMLFragmentContentSink::WillResume(void)
00282 {
00283   return NS_OK;
00284 }
00285 
00286 NS_IMETHODIMP
00287 nsHTMLFragmentContentSink::SetParser(nsIParser* aParser)
00288 {
00289   mParser = aParser;
00290 
00291   return NS_OK;
00292 }
00293 
00294 NS_IMETHODIMP
00295 nsHTMLFragmentContentSink::BeginContext(PRInt32 aID)
00296 {
00297   return NS_OK;
00298 }
00299 
00300 NS_IMETHODIMP
00301 nsHTMLFragmentContentSink::EndContext(PRInt32 aID)
00302 {
00303   return NS_OK;
00304 }
00305 
00306 NS_IMETHODIMP
00307 nsHTMLFragmentContentSink::SetTitle(const nsString& aValue)
00308 {
00309   return SetDocumentTitle(aValue, nsnull);
00310 }
00311 
00312 NS_IMETHODIMP
00313 nsHTMLFragmentContentSink::OpenHTML(const nsIParserNode& aNode)
00314 {
00315   return NS_OK;
00316 }
00317 
00318 NS_IMETHODIMP
00319 nsHTMLFragmentContentSink::CloseHTML()
00320 {
00321   return NS_OK;
00322 }
00323 
00324 NS_IMETHODIMP
00325 nsHTMLFragmentContentSink::OpenHead(const nsIParserNode& aNode)
00326 {
00327   return OpenContainer(aNode);
00328 }
00329 
00330 NS_IMETHODIMP
00331 nsHTMLFragmentContentSink::CloseHead()
00332 {
00333   return CloseContainer(eHTMLTag_head);
00334 }
00335 
00336 NS_IMETHODIMP
00337 nsHTMLFragmentContentSink::OpenBody(const nsIParserNode& aNode)
00338 {
00339   // Ignore repeated BODY elements. The DTD is just sending them
00340   // to us for compatibility reasons that don't apply here.
00341   if (!mSeenBody) {
00342     mSeenBody = PR_TRUE;
00343     return OpenContainer(aNode);
00344   }
00345   else {
00346     return NS_OK;
00347   }
00348 }
00349 
00350 NS_IMETHODIMP
00351 nsHTMLFragmentContentSink::CloseBody()
00352 {
00353   return CloseContainer(eHTMLTag_body);
00354 }
00355 
00356 NS_IMETHODIMP
00357 nsHTMLFragmentContentSink::OpenForm(const nsIParserNode& aNode)
00358 {
00359   return OpenContainer(aNode);
00360 }
00361 
00362 NS_IMETHODIMP
00363 nsHTMLFragmentContentSink::CloseForm()
00364 {
00365   return CloseContainer(eHTMLTag_form);
00366 }
00367 
00368 NS_IMETHODIMP
00369 nsHTMLFragmentContentSink::OpenFrameset(const nsIParserNode& aNode)
00370 {
00371   return OpenContainer(aNode);
00372 }
00373 
00374 NS_IMETHODIMP
00375 nsHTMLFragmentContentSink::CloseFrameset()
00376 {
00377   return CloseContainer(eHTMLTag_frameset);
00378 }
00379 
00380 NS_IMETHODIMP
00381 nsHTMLFragmentContentSink::OpenMap(const nsIParserNode& aNode)
00382 {
00383   return OpenContainer(aNode);
00384 }
00385 
00386 NS_IMETHODIMP
00387 nsHTMLFragmentContentSink::CloseMap()
00388 {
00389   return CloseContainer(eHTMLTag_map);
00390 }
00391 
00392 void
00393 nsHTMLFragmentContentSink::ProcessBaseTag(nsIContent* aContent)
00394 {
00395   nsAutoString value;
00396   if (NS_CONTENT_ATTR_HAS_VALUE == aContent->GetAttr(kNameSpaceID_None, nsHTMLAtoms::href, value)) {
00397     mBaseHREF = value;
00398   }
00399   if (NS_CONTENT_ATTR_HAS_VALUE == aContent->GetAttr(kNameSpaceID_None, nsHTMLAtoms::target, value)) {
00400     mBaseTarget = value;
00401   }
00402 }
00403 
00404 void
00405 nsHTMLFragmentContentSink::AddBaseTagInfo(nsIContent* aContent)
00406 {
00407   if (aContent) {
00408     if (!mBaseHREF.IsEmpty()) {
00409       aContent->SetAttr(kNameSpaceID_None, nsHTMLAtoms::_baseHref, mBaseHREF, PR_FALSE);
00410     }
00411     if (!mBaseTarget.IsEmpty()) {
00412       aContent->SetAttr(kNameSpaceID_None, nsHTMLAtoms::_baseTarget, mBaseTarget, PR_FALSE);
00413     }
00414   }
00415 }
00416 
00417 nsresult
00418 nsHTMLFragmentContentSink::SetDocumentTitle(const nsAString& aString, const nsIParserNode* aNode)
00419 {
00420   NS_ENSURE_TRUE(mNodeInfoManager, NS_ERROR_NOT_INITIALIZED);
00421 
00422   nsCOMPtr<nsINodeInfo> nodeInfo;
00423   nsresult rv = mNodeInfoManager->GetNodeInfo(nsHTMLAtoms::title, nsnull,
00424                                               kNameSpaceID_None,
00425                                               getter_AddRefs(nodeInfo));
00426   NS_ENSURE_SUCCESS(rv, rv);
00427 
00428   nsRefPtr<nsGenericHTMLElement> content = NS_NewHTMLTitleElement(nodeInfo);
00429   NS_ENSURE_TRUE(content, NS_ERROR_OUT_OF_MEMORY);
00430 
00431   nsIContent *parent = GetCurrentContent();
00432 
00433   if (!parent) {
00434     parent = mRoot;
00435   }
00436 
00437   if (aNode) {
00438     AddAttributes(*aNode, content);
00439   }
00440 
00441   rv = parent->AppendChildTo(content, PR_FALSE);
00442   NS_ENSURE_SUCCESS(rv, rv);
00443 
00444   return AddTextToContent(content, aString);
00445 }
00446 
00447 NS_IMETHODIMP
00448 nsHTMLFragmentContentSink::OpenContainer(const nsIParserNode& aNode)
00449 {
00450   NS_ENSURE_TRUE(mNodeInfoManager, NS_ERROR_NOT_INITIALIZED);
00451 
00452   nsresult result = NS_OK;
00453 
00454   if (mProcessing && !mIgnoreContainer) {
00455     FlushText();
00456 
00457     nsHTMLTag nodeType = nsHTMLTag(aNode.GetNodeType());
00458     nsIContent *content = nsnull;
00459 
00460     nsCOMPtr<nsINodeInfo> nodeInfo;
00461 
00462     if (nodeType == eHTMLTag_userdefined) {
00463       result =
00464         mNodeInfoManager->GetNodeInfo(aNode.GetText(), nsnull,
00465                                       kNameSpaceID_None,
00466                                       getter_AddRefs(nodeInfo));
00467     } else {
00468       nsIParserService* parserService =
00469         nsContentUtils::GetParserServiceWeakRef();
00470       if (!parserService)
00471         return NS_ERROR_OUT_OF_MEMORY;
00472 
00473       nsIAtom *name = parserService->HTMLIdToAtomTag(nodeType);
00474       NS_ASSERTION(name, "This should not happen!");
00475 
00476       result = mNodeInfoManager->GetNodeInfo(name, nsnull, kNameSpaceID_None,
00477                                              getter_AddRefs(nodeInfo));
00478     }
00479 
00480     NS_ENSURE_SUCCESS(result, result);
00481 
00482     result = NS_NewHTMLElement(&content, nodeInfo);
00483 
00484     if (NS_OK == result) {
00485       result = AddAttributes(aNode, content);
00486       if (NS_OK == result) {
00487         nsIContent *parent = GetCurrentContent();
00488 
00489         if (nsnull == parent) {
00490           parent = mRoot;
00491         }
00492 
00493         parent->AppendChildTo(content, PR_FALSE);
00494         PushContent(content);
00495       }
00496     }
00497 
00498     if (nodeType == eHTMLTag_table
00499         || nodeType == eHTMLTag_thead
00500         || nodeType == eHTMLTag_tbody
00501         || nodeType == eHTMLTag_tfoot
00502         || nodeType == eHTMLTag_tr
00503         || nodeType == eHTMLTag_td
00504         || nodeType == eHTMLTag_th)
00505       // XXX if navigator_quirks_mode (only body in html supports background)
00506       AddBaseTagInfo(content); 
00507   }
00508   else if (mProcessing && mIgnoreContainer) {
00509     mIgnoreContainer = PR_FALSE;
00510   }
00511 
00512   return result;
00513 }
00514 
00515 NS_IMETHODIMP
00516 nsHTMLFragmentContentSink::CloseContainer(const nsHTMLTag aTag)
00517 {
00518   if (mProcessing && (nsnull != GetCurrentContent())) {
00519     nsIContent* content;
00520     FlushText();
00521     content = PopContent();
00522     NS_RELEASE(content);
00523   }
00524   return NS_OK;
00525 }
00526 
00527 NS_IMETHODIMP
00528 nsHTMLFragmentContentSink::AddHeadContent(const nsIParserNode& aNode)
00529 {
00530   return AddLeaf(aNode);
00531 }
00532 
00533 NS_IMETHODIMP
00534 nsHTMLFragmentContentSink::AddLeaf(const nsIParserNode& aNode)
00535 {
00536   if (eHTMLTag_title == aNode.GetNodeType()) {
00537     nsCOMPtr<nsIDTD> dtd;
00538     mParser->GetDTD(getter_AddRefs(dtd));
00539     NS_ENSURE_TRUE(dtd, NS_ERROR_FAILURE);
00540 
00541     nsAutoString skippedContent;
00542     PRInt32 lineNo = 0;
00543 
00544     dtd->CollectSkippedContent(eHTMLTag_title, skippedContent, lineNo);
00545 
00546     return SetDocumentTitle(skippedContent, &aNode);
00547   }
00548 
00549   NS_ENSURE_TRUE(mNodeInfoManager, NS_ERROR_NOT_INITIALIZED);
00550 
00551   nsresult result = NS_OK;
00552 
00553   switch (aNode.GetTokenType()) {
00554     case eToken_start:
00555       {
00556         FlushText();
00557 
00558         // Create new leaf content object
00559         nsCOMPtr<nsIContent> content;
00560         nsHTMLTag nodeType = nsHTMLTag(aNode.GetNodeType());
00561 
00562         nsIParserService* parserService =
00563           nsContentUtils::GetParserServiceWeakRef();
00564         if (!parserService)
00565           return NS_ERROR_OUT_OF_MEMORY;
00566 
00567         nsCOMPtr<nsINodeInfo> nodeInfo;
00568 
00569         if (nodeType == eHTMLTag_userdefined) {
00570           result =
00571             mNodeInfoManager->GetNodeInfo(aNode.GetText(), nsnull,
00572                                           kNameSpaceID_None,
00573                                           getter_AddRefs(nodeInfo));
00574         } else {
00575           nsIAtom *name = parserService->HTMLIdToAtomTag(nodeType);
00576           NS_ASSERTION(name, "This should not happen!");
00577 
00578           result = mNodeInfoManager->GetNodeInfo(name, nsnull,
00579                                                  kNameSpaceID_None,
00580                                                  getter_AddRefs(nodeInfo));
00581         }
00582 
00583         NS_ENSURE_SUCCESS(result, result);
00584 
00585         if(NS_SUCCEEDED(result)) {
00586           result = NS_NewHTMLElement(getter_AddRefs(content), nodeInfo);
00587 
00588           if (NS_OK == result) {
00589             result = AddAttributes(aNode, content);
00590             if (NS_OK == result) {
00591               nsIContent *parent = GetCurrentContent();
00592 
00593               if (nsnull == parent) {
00594                 parent = mRoot;
00595               }
00596 
00597               parent->AppendChildTo(content, PR_FALSE);
00598             }
00599           }
00600 
00601           if(nodeType == eHTMLTag_script    ||
00602              nodeType == eHTMLTag_style     ||
00603              nodeType == eHTMLTag_server) {
00604 
00605             // Create a text node holding the content
00606             nsCOMPtr<nsIDTD> dtd;
00607             mParser->GetDTD(getter_AddRefs(dtd));
00608             NS_ENSURE_TRUE(dtd, NS_ERROR_FAILURE);
00609 
00610             nsAutoString skippedContent;
00611             PRInt32 lineNo = 0;
00612 
00613             dtd->CollectSkippedContent(nodeType, skippedContent, lineNo);
00614             result=AddTextToContent(content, skippedContent);
00615           }
00616           else if (nodeType == eHTMLTag_img || nodeType == eHTMLTag_frame
00617               || nodeType == eHTMLTag_input)    // elements with 'SRC='
00618               AddBaseTagInfo(content);
00619           else if (nodeType == eHTMLTag_base)
00620               ProcessBaseTag(content);
00621         }
00622       }
00623       break;
00624     case eToken_text:
00625     case eToken_whitespace:
00626     case eToken_newline:
00627       result = AddText(aNode.GetText());
00628       break;
00629 
00630     case eToken_entity:
00631       {
00632         nsAutoString tmp;
00633         PRInt32 unicode = aNode.TranslateToUnicodeStr(tmp);
00634         if (unicode < 0) {
00635           result = AddText(aNode.GetText());
00636         }
00637         else {
00638           result = AddText(tmp);
00639         }
00640       }
00641       break;
00642   }
00643 
00644   return result;
00645 }
00646 
00647 NS_IMETHODIMP
00648 nsHTMLFragmentContentSink::AddComment(const nsIParserNode& aNode)
00649 {
00650   nsIContent *comment;
00651   nsIDOMComment *domComment;
00652   nsresult result = NS_OK;
00653 
00654   FlushText();
00655 
00656   result = NS_NewCommentNode(&comment, mNodeInfoManager);
00657   if (NS_SUCCEEDED(result)) {
00658     result = CallQueryInterface(comment, &domComment);
00659     if (NS_SUCCEEDED(result)) {
00660       domComment->AppendData(aNode.GetText());
00661       NS_RELEASE(domComment);
00662 
00663       nsIContent *parent = GetCurrentContent();
00664 
00665       if (nsnull == parent) {
00666         parent = mRoot;
00667       }
00668 
00669       parent->AppendChildTo(comment, PR_FALSE);
00670     }
00671     NS_RELEASE(comment);
00672   }
00673 
00674   return NS_OK;
00675 }
00676 
00677 NS_IMETHODIMP
00678 nsHTMLFragmentContentSink::AddProcessingInstruction(const nsIParserNode& aNode)
00679 {
00680   return NS_OK;
00681 }
00682 
00688 NS_IMETHODIMP
00689 nsHTMLFragmentContentSink::AddDocTypeDecl(const nsIParserNode& aNode)
00690 {
00691   return NS_OK;
00692 }
00693 
00694 NS_IMETHODIMP
00695 nsHTMLFragmentContentSink::GetFragment(nsIDOMDocumentFragment** aFragment)
00696 {
00697   if (mRoot) {
00698     return CallQueryInterface(mRoot, aFragment);
00699   }
00700 
00701   *aFragment = nsnull;
00702 
00703   return NS_OK;
00704 }
00705 
00706 NS_IMETHODIMP
00707 nsHTMLFragmentContentSink::SetTargetDocument(nsIDocument* aTargetDocument)
00708 {
00709   NS_ENSURE_ARG_POINTER(aTargetDocument);
00710 
00711   mTargetDocument = aTargetDocument;
00712   mNodeInfoManager = aTargetDocument->NodeInfoManager();
00713 
00714   return NS_OK;
00715 }
00716 
00717 NS_IMETHODIMP
00718 nsHTMLFragmentContentSink::WillBuildContent()
00719 {
00720   mProcessing = PR_TRUE;
00721 
00722   return NS_OK;
00723 }
00724 
00725 NS_IMETHODIMP
00726 nsHTMLFragmentContentSink::DidBuildContent()
00727 {
00728   if (!mAllContent) {
00729     FlushText();
00730     DidBuildModel(); // Release our ref to the parser now.
00731     mProcessing = PR_FALSE;
00732   }
00733 
00734   return NS_OK;
00735 }
00736 
00737 NS_IMETHODIMP
00738 nsHTMLFragmentContentSink::IgnoreFirstContainer()
00739 {
00740   mIgnoreContainer = PR_TRUE;
00741   return NS_OK;
00742 }
00743 
00744 nsIContent*
00745 nsHTMLFragmentContentSink::GetCurrentContent()
00746 {
00747   if (nsnull != mContentStack) {
00748     PRInt32 indx = mContentStack->Count() - 1;
00749     if (indx >= 0)
00750       return (nsIContent *)mContentStack->ElementAt(indx);
00751   }
00752   return nsnull;
00753 }
00754 
00755 PRInt32
00756 nsHTMLFragmentContentSink::PushContent(nsIContent *aContent)
00757 {
00758   if (nsnull == mContentStack) {
00759     mContentStack = new nsVoidArray();
00760   }
00761 
00762   mContentStack->AppendElement((void *)aContent);
00763   return mContentStack->Count();
00764 }
00765 
00766 nsIContent*
00767 nsHTMLFragmentContentSink::PopContent()
00768 {
00769   nsIContent* content = nsnull;
00770   if (nsnull != mContentStack) {
00771     PRInt32 indx = mContentStack->Count() - 1;
00772     if (indx >= 0) {
00773       content = (nsIContent *)mContentStack->ElementAt(indx);
00774       mContentStack->RemoveElementAt(indx);
00775     }
00776   }
00777   return content;
00778 }
00779 
00780 #define NS_ACCUMULATION_BUFFER_SIZE 4096
00781 
00782 nsresult
00783 nsHTMLFragmentContentSink::AddText(const nsAString& aString)
00784 {
00785   PRInt32 addLen = aString.Length();
00786   if (0 == addLen) {
00787     return NS_OK;
00788   }
00789 
00790   // Create buffer when we first need it
00791   if (0 == mTextSize) {
00792     mText = (PRUnichar *) PR_MALLOC(sizeof(PRUnichar) * NS_ACCUMULATION_BUFFER_SIZE);
00793     if (nsnull == mText) {
00794       return NS_ERROR_OUT_OF_MEMORY;
00795     }
00796     mTextSize = NS_ACCUMULATION_BUFFER_SIZE;
00797   }
00798 
00799   // Copy data from string into our buffer; flush buffer when it fills up
00800   PRInt32 offset = 0;
00801   PRBool  isLastCharCR = PR_FALSE;
00802   while (0 != addLen) {
00803     PRInt32 amount = mTextSize - mTextLength;
00804     if (amount > addLen) {
00805       amount = addLen;
00806     }
00807     if (0 == amount) {
00808       nsresult rv = FlushText();
00809       if (NS_OK != rv) {
00810         return rv;
00811       }
00812     }
00813     mTextLength +=
00814       nsContentUtils::CopyNewlineNormalizedUnicodeTo(aString,
00815                                                      offset,
00816                                                      &mText[mTextLength],
00817                                                      amount,
00818                                                      isLastCharCR);
00819     offset += amount;
00820     addLen -= amount;
00821   }
00822 
00823   return NS_OK;
00824 }
00825 
00826 nsresult
00827 nsHTMLFragmentContentSink::AddTextToContent(nsIContent* aContent, const nsAString& aText) {
00828   NS_ASSERTION(aContent !=nsnull, "can't add text w/o a content");
00829 
00830   nsresult result=NS_OK;
00831 
00832   if(aContent) {
00833     if (!aText.IsEmpty()) {
00834       nsCOMPtr<nsITextContent> text;
00835       result = NS_NewTextNode(getter_AddRefs(text), mNodeInfoManager);
00836       if (NS_SUCCEEDED(result)) {
00837         text->SetText(aText, PR_TRUE);
00838 
00839         result = aContent->AppendChildTo(text, PR_FALSE);
00840       }
00841     }
00842   }
00843   return result;
00844 }
00845 
00846 nsresult
00847 nsHTMLFragmentContentSink::FlushText()
00848 {
00849   if (0 == mTextLength) {
00850     return NS_OK;
00851   }
00852 
00853   nsCOMPtr<nsITextContent> content;
00854   nsresult rv = NS_NewTextNode(getter_AddRefs(content), mNodeInfoManager);
00855   NS_ENSURE_SUCCESS(rv, rv);
00856 
00857   // Set the text in the text node
00858   content->SetText(mText, mTextLength, PR_FALSE);
00859 
00860   // Add text to its parent
00861   nsIContent *parent = GetCurrentContent();
00862 
00863   if (!parent) {
00864     parent = mRoot;
00865   }
00866 
00867   rv = parent->AppendChildTo(content, PR_FALSE);
00868 
00869   mTextLength = 0;
00870 
00871   return rv;
00872 }
00873 
00874 // XXX Code copied from nsHTMLContentSink. It should be shared.
00875 nsresult
00876 nsHTMLFragmentContentSink::AddAttributes(const nsIParserNode& aNode,
00877                                          nsIContent* aContent)
00878 {
00879   // Add tag attributes to the content attributes
00880 
00881   PRInt32 ac = aNode.GetAttributeCount();
00882 
00883   if (ac == 0) {
00884     // No attributes, nothing to do. Do an early return to avoid
00885     // constructing the nsAutoString object for nothing.
00886 
00887     return NS_OK;
00888   }
00889 
00890   nsCAutoString k;
00891   nsHTMLTag nodeType = nsHTMLTag(aNode.GetNodeType());
00892 
00893   // The attributes are on the parser node in the order they came in in the
00894   // source.  What we want to happen if a single attribute is set multiple
00895   // times on an element is that the first time should "win".  That is, <input
00896   // value="foo" value="bar"> should show "foo".  So we loop over the
00897   // attributes backwards; this ensures that the first attribute in the set
00898   // wins.  This does mean that we do some extra work in the case when the same
00899   // attribute is set multiple times, but we save a HasAttr call in the much
00900   // more common case of reasonable HTML.
00901 
00902   for (PRInt32 i = ac - 1; i >= 0; i--) {
00903     // Get lower-cased key
00904     const nsAString& key = aNode.GetKeyAt(i);
00905     // Copy up-front to avoid shared-buffer overhead (and convert to UTF-8
00906     // at the same time since that's what the atom table uses).
00907     CopyUTF16toUTF8(key, k);
00908     ToLowerCase(k);
00909 
00910     nsCOMPtr<nsIAtom> keyAtom = do_GetAtom(k);
00911 
00912     // Get value and remove mandatory quotes
00913     static const char* kWhitespace = "\n\r\t\b";
00914     const nsAString& v =
00915       nsContentUtils::TrimCharsInSet(kWhitespace, aNode.GetValueAt(i));
00916 
00917     if (nodeType == eHTMLTag_a && keyAtom == nsHTMLAtoms::name) {
00918       NS_ConvertUCS2toUTF8 cname(v);
00919       NS_ConvertUTF8toUCS2 uv(nsUnescape(cname.BeginWriting()));
00920 
00921       // Add attribute to content
00922       aContent->SetAttr(kNameSpaceID_None, keyAtom, uv, PR_FALSE);
00923     } else {
00924       // Add attribute to content
00925       aContent->SetAttr(kNameSpaceID_None, keyAtom, v, PR_FALSE);
00926     }
00927   }
00928 
00929   return NS_OK;
00930 }
00931 
00932 // nsHTMLParanoidFragmentSink
00933 
00934 // Find the whitelist of allowed elements and attributes in
00935 // nsContentSink.h We share it with nsHTMLParanoidFragmentSink
00936 
00937 class nsHTMLParanoidFragmentSink : public nsHTMLFragmentContentSink
00938 {
00939 public:
00940   nsHTMLParanoidFragmentSink();
00941 
00942   static nsresult Init();
00943   static void Cleanup();
00944 
00945   // nsISupports
00946   NS_DECL_ISUPPORTS_INHERITED
00947 
00948   NS_IMETHOD OpenContainer(const nsIParserNode& aNode);
00949   NS_IMETHOD CloseContainer(const nsHTMLTag aTag);
00950   NS_IMETHOD AddLeaf(const nsIParserNode& aNode);
00951   NS_IMETHOD AddComment(const nsIParserNode& aNode);
00952   NS_IMETHOD AddProcessingInstruction(const nsIParserNode& aNode);
00953 
00954   nsresult AddAttributes(const nsIParserNode& aNode,
00955                          nsIContent* aContent);
00956 protected:
00957   nsresult NameFromType(const nsHTMLTag aTag,
00958                         nsIAtom **aResult);
00959 
00960   nsresult NameFromNode(const nsIParserNode& aNode,
00961                         nsIAtom **aResult);
00962   
00963   PRBool mSkip; // used when we descend into <style> or <script>
00964 
00965   // Use nsTHashTable as a hash set for our whitelists
00966   static nsTHashtable<nsISupportsHashKey>* sAllowedTags;
00967   static nsTHashtable<nsISupportsHashKey>* sAllowedAttributes;
00968 };
00969 
00970 nsTHashtable<nsISupportsHashKey>* nsHTMLParanoidFragmentSink::sAllowedTags;
00971 nsTHashtable<nsISupportsHashKey>* nsHTMLParanoidFragmentSink::sAllowedAttributes;
00972 
00973 nsHTMLParanoidFragmentSink::nsHTMLParanoidFragmentSink():
00974   nsHTMLFragmentContentSink(PR_FALSE), mSkip(PR_FALSE)
00975 {
00976 }
00977 
00978 nsresult
00979 nsHTMLParanoidFragmentSink::Init()
00980 {
00981   nsresult rv = NS_ERROR_FAILURE;
00982   
00983   if (sAllowedTags) {
00984     return NS_OK;
00985   }
00986 
00987   PRUint32 size = NS_ARRAY_LENGTH(kDefaultAllowedTags);
00988   sAllowedTags = new nsTHashtable<nsISupportsHashKey>();
00989   if (sAllowedTags) {
00990     rv = sAllowedTags->Init(size);
00991     for (PRUint32 i = 0; i < size && NS_SUCCEEDED(rv); i++) {
00992       if (!sAllowedTags->PutEntry(*kDefaultAllowedTags[i])) {
00993         rv = NS_ERROR_OUT_OF_MEMORY;
00994       }
00995     }
00996   }
00997 
00998   size = NS_ARRAY_LENGTH(kDefaultAllowedAttributes);
00999   sAllowedAttributes = new nsTHashtable<nsISupportsHashKey>();
01000   if (sAllowedAttributes && NS_SUCCEEDED(rv)) {
01001     rv = sAllowedAttributes->Init(size);
01002     for (PRUint32 i = 0; i < size && NS_SUCCEEDED(rv); i++) {
01003       if (!sAllowedAttributes->PutEntry(*kDefaultAllowedAttributes[i])) {
01004         rv = NS_ERROR_OUT_OF_MEMORY;
01005       }
01006     }
01007   }
01008 
01009   if (NS_FAILED(rv)) {
01010     NS_WARNING("Failed to populate whitelist hash sets");
01011     Cleanup();
01012     return rv; 
01013   }
01014 
01015   return rv;
01016 }
01017 
01018 void
01019 nsHTMLParanoidFragmentSink::Cleanup()
01020 {
01021   if (sAllowedTags) {
01022     delete sAllowedTags;
01023     sAllowedTags = nsnull;
01024   }
01025   
01026   if (sAllowedAttributes) {
01027     delete sAllowedAttributes;
01028     sAllowedAttributes = nsnull;
01029   }
01030 }
01031 
01032 nsresult
01033 NS_NewHTMLParanoidFragmentSink(nsIFragmentContentSink** aResult)
01034 {
01035   nsHTMLParanoidFragmentSink* it = new nsHTMLParanoidFragmentSink();
01036   if (!it) {
01037     return NS_ERROR_OUT_OF_MEMORY;
01038   }
01039   nsresult rv = nsHTMLParanoidFragmentSink::Init();
01040   NS_ENSURE_SUCCESS(rv, rv);
01041   NS_ADDREF(*aResult = it);
01042   
01043   return NS_OK;
01044 }
01045 
01046 void
01047 NS_HTMLParanoidFragmentSinkShutdown()
01048 {
01049   nsHTMLParanoidFragmentSink::Cleanup();
01050 }
01051 
01052 NS_IMPL_ISUPPORTS_INHERITED0(nsHTMLParanoidFragmentSink,
01053                              nsHTMLFragmentContentSink)
01054 
01055 nsresult
01056 nsHTMLParanoidFragmentSink::NameFromType(const nsHTMLTag aTag,
01057                                          nsIAtom **aResult)
01058 {
01059   nsIParserService* parserService = nsContentUtils::GetParserServiceWeakRef();
01060   if (!parserService) {
01061     return NS_ERROR_OUT_OF_MEMORY;
01062   }
01063   NS_IF_ADDREF(*aResult = parserService->HTMLIdToAtomTag(aTag));
01064   
01065   return NS_OK;
01066 }
01067 
01068 nsresult
01069 nsHTMLParanoidFragmentSink::NameFromNode(const nsIParserNode& aNode,
01070                                          nsIAtom **aResult)
01071 {
01072   nsresult rv;
01073   eHTMLTags type = (eHTMLTags)aNode.GetNodeType();
01074   
01075   *aResult = nsnull;
01076   if (type == eHTMLTag_userdefined) {
01077     nsCOMPtr<nsINodeInfo> nodeInfo;
01078     rv =
01079       mNodeInfoManager->GetNodeInfo(aNode.GetText(), nsnull,
01080                                     kNameSpaceID_None,
01081                                     getter_AddRefs(nodeInfo));
01082     NS_ENSURE_SUCCESS(rv, rv);
01083     NS_IF_ADDREF(*aResult = nodeInfo->NameAtom());
01084   } else {
01085     rv = NameFromType(type, aResult);
01086   }
01087   return rv;
01088 }
01089 
01090 // nsHTMLFragmentContentSink
01091 
01092 nsresult
01093 nsHTMLParanoidFragmentSink::AddAttributes(const nsIParserNode& aNode,
01094                                           nsIContent* aContent)
01095 {
01096   PRInt32 ac = aNode.GetAttributeCount();
01097 
01098   if (ac == 0) {
01099     return NS_OK;
01100   }
01101 
01102   nsCAutoString k;
01103   nsHTMLTag nodeType = nsHTMLTag(aNode.GetNodeType());
01104 
01105   nsresult rv;
01106   // use this to check for safe URIs in the few attributes that allow them
01107   nsIScriptSecurityManager* secMan = nsContentUtils::GetSecurityManager();
01108   nsCOMPtr<nsIURI> baseURI;
01109 
01110   for (PRInt32 i = ac - 1; i >= 0; i--) {
01111     rv = NS_OK;
01112     const nsAString& key = aNode.GetKeyAt(i);
01113     CopyUTF16toUTF8(key, k);
01114     ToLowerCase(k);
01115 
01116     nsCOMPtr<nsIAtom> keyAtom = do_GetAtom(k);
01117 
01118     // not an allowed attribute
01119     if (!sAllowedAttributes || !sAllowedAttributes->GetEntry(keyAtom)) {
01120       continue;
01121     }
01122 
01123     // Get value and remove mandatory quotes
01124     static const char* kWhitespace = "\n\r\t\b";
01125     const nsAString& v =
01126       nsContentUtils::TrimCharsInSet(kWhitespace, aNode.GetValueAt(i));
01127 
01128     // check the attributes we allow that contain URIs
01129     if (IsAttrURI(keyAtom)) {
01130       if (!baseURI) {
01131         baseURI = aContent->GetBaseURI();
01132       }
01133       nsCOMPtr<nsIURI> attrURI;
01134       rv = NS_NewURI(getter_AddRefs(attrURI), v, nsnull, baseURI);
01135       if (NS_SUCCEEDED(rv)) {
01136         rv = secMan->CheckLoadURIWithPrincipal(mTargetDocument->GetPrincipal(),
01137                                                attrURI,
01138                                                nsIScriptSecurityManager::DISALLOW_SCRIPT_OR_DATA);
01139       }
01140     }
01141     
01142     // skip to the next attribute if we encountered issues with the
01143     // current value
01144     if (NS_FAILED(rv)) {
01145       continue;
01146     }
01147 
01148     if (nodeType == eHTMLTag_a && keyAtom == nsHTMLAtoms::name) {
01149       NS_ConvertUTF16toUTF8 cname(v);
01150       NS_ConvertUTF8toUTF16 uv(nsUnescape(cname.BeginWriting()));
01151       // Add attribute to content
01152       aContent->SetAttr(kNameSpaceID_None, keyAtom, uv, PR_FALSE);
01153     } else {
01154       // Add attribute to content
01155       aContent->SetAttr(kNameSpaceID_None, keyAtom, v, PR_FALSE);
01156     }
01157 
01158     if (nodeType == eHTMLTag_a || 
01159         nodeType == eHTMLTag_form ||
01160         nodeType == eHTMLTag_img ||
01161         nodeType == eHTMLTag_map ||
01162         nodeType == eHTMLTag_q ||
01163         nodeType == eHTMLTag_blockquote ||
01164         nodeType == eHTMLTag_input) {
01165       AddBaseTagInfo(aContent);
01166     }
01167   }
01168 
01169   return NS_OK;
01170 }
01171 
01172 NS_IMETHODIMP
01173 nsHTMLParanoidFragmentSink::OpenContainer(const nsIParserNode& aNode)
01174 {
01175   nsresult rv = NS_OK;
01176   
01177   // bail if it's a script or style, or we're already inside one of those
01178   eHTMLTags type = (eHTMLTags)aNode.GetNodeType();
01179   if (type == eHTMLTag_script || type == eHTMLTag_style) {
01180     mSkip = PR_TRUE;
01181     return rv;
01182   }
01183 
01184   nsCOMPtr<nsIAtom> name;
01185   rv = NameFromNode(aNode, getter_AddRefs(name));
01186   NS_ENSURE_SUCCESS(rv, rv);
01187 
01188   // not on whitelist
01189   if (!sAllowedTags || !sAllowedTags->GetEntry(name)) {
01190     return NS_OK;
01191   }
01192 
01193   return nsHTMLFragmentContentSink::OpenContainer(aNode);
01194 }
01195 
01196 NS_IMETHODIMP
01197 nsHTMLParanoidFragmentSink::CloseContainer(const nsHTMLTag aTag)
01198 {
01199   nsresult rv = NS_OK;
01200 
01201   if (mSkip) {
01202     mSkip = PR_FALSE;
01203     return rv;
01204   }
01205 
01206   nsCOMPtr<nsIAtom> name;
01207   rv = NameFromType(aTag, getter_AddRefs(name));
01208   NS_ENSURE_SUCCESS(rv, rv);
01209   
01210   // not on whitelist
01211   if (!sAllowedTags || !sAllowedTags->GetEntry(name)) {
01212     return NS_OK;
01213   }
01214 
01215   return nsHTMLFragmentContentSink::CloseContainer(aTag);
01216 }
01217 
01218 NS_IMETHODIMP
01219 nsHTMLParanoidFragmentSink::AddLeaf(const nsIParserNode& aNode)
01220 {
01221   NS_ENSURE_TRUE(mNodeInfoManager, NS_ERROR_NOT_INITIALIZED);
01222   
01223   nsresult rv = NS_OK;
01224 
01225 #ifndef MOZILLA_1_8_BRANCH
01226   if (mSkip) {
01227     return rv;
01228   }
01229 #endif
01230 
01231   if (aNode.GetTokenType() == eToken_start) {
01232     nsCOMPtr<nsIAtom> name;
01233     rv = NameFromNode(aNode, getter_AddRefs(name));
01234     NS_ENSURE_SUCCESS(rv, rv);
01235 
01236 #ifdef MOZILLA_1_8_BRANCH
01237     // we have to do this on the branch for some late 90s reason
01238     if (name == nsHTMLAtoms::script || name == nsHTMLAtoms::style) {
01239       nsCOMPtr<nsIDTD> dtd;
01240       mParser->GetDTD(getter_AddRefs(dtd));
01241       NS_ENSURE_TRUE(dtd, NS_ERROR_FAILURE);
01242 
01243       nsAutoString skippedContent;
01244       PRInt32 lineNo = 0;                
01245       dtd->CollectSkippedContent(aNode.GetTokenType(),
01246                                  skippedContent, lineNo);
01247     }
01248 #endif
01249 
01250     // We will process base tags, but we won't include them
01251     // in the output
01252     if (name == nsHTMLAtoms::base) {
01253       nsCOMPtr<nsIContent> content;
01254       nsCOMPtr<nsINodeInfo> nodeInfo;
01255       nsIParserService* parserService = nsContentUtils::GetParserServiceWeakRef();
01256       if (!parserService)
01257         return NS_ERROR_OUT_OF_MEMORY;
01258       rv = mNodeInfoManager->GetNodeInfo(name, nsnull,
01259                                          kNameSpaceID_None,
01260                                          getter_AddRefs(nodeInfo));
01261       NS_ENSURE_SUCCESS(rv, rv);
01262       rv = NS_NewHTMLElement(getter_AddRefs(content), nodeInfo);
01263       NS_ENSURE_SUCCESS(rv, rv);
01264       AddAttributes(aNode, content);
01265       ProcessBaseTag(content);
01266       return NS_OK;
01267     }
01268 
01269     if (!sAllowedTags || !sAllowedTags->GetEntry(name)) {
01270       return NS_OK;
01271     }
01272   }
01273 
01274   return nsHTMLFragmentContentSink::AddLeaf(aNode);
01275 }
01276 
01277 NS_IMETHODIMP
01278 nsHTMLParanoidFragmentSink::AddComment(const nsIParserNode& aNode)
01279 {
01280   // no comments
01281   return NS_OK;
01282 }
01283 
01284 NS_IMETHODIMP
01285 nsHTMLParanoidFragmentSink::AddProcessingInstruction(const nsIParserNode& aNode)
01286 {
01287   // no PIs
01288   return NS_OK;
01289 }