зеркало из https://github.com/mozilla/gecko-dev.git
bug 272702: Remove skipped content. This simplifies the code handling <script>, <style> and related tags and makes the nsIHTMLContentSink interface just that much easier to implement. This also allows <object> tags to appear in the head with children. r=sicking sr=jst
This commit is contained in:
Родитель
b8d0775c65
Коммит
973abde5a4
|
@ -304,43 +304,9 @@ mozSanitizingHTMLSerializer::OpenContainer(const nsIParserNode& aNode)
|
|||
NS_IMETHODIMP
|
||||
mozSanitizingHTMLSerializer::CloseContainer(const nsHTMLTag aTag)
|
||||
{
|
||||
// XXX Why do we need this?
|
||||
// mParserNode = NS_CONST_CAST(nsIParserNode*, &aNode);
|
||||
return DoCloseContainer(aTag);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
mozSanitizingHTMLSerializer::AddHeadContent(const nsIParserNode& aNode)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
eHTMLTags type = (eHTMLTags)aNode.GetNodeType();
|
||||
if (eHTMLTag_whitespace == type ||
|
||||
eHTMLTag_newline == type ||
|
||||
eHTMLTag_text == type ||
|
||||
eHTMLTag_entity == type) {
|
||||
rv = AddLeaf(aNode);
|
||||
}
|
||||
else if (eHTMLTag_title == type) {
|
||||
NS_ASSERTION(mParser, "Only CNavDTD treats title this way.");
|
||||
|
||||
nsString skippedContent;
|
||||
PRInt32 lineNo;
|
||||
|
||||
nsCOMPtr<nsIDTD> dtd;
|
||||
mParser->GetDTD(getter_AddRefs(dtd));
|
||||
NS_ENSURE_TRUE(dtd, NS_ERROR_UNEXPECTED);
|
||||
|
||||
dtd->CollectSkippedContent(type, skippedContent, lineNo);
|
||||
SetTitle(skippedContent);
|
||||
}
|
||||
else {
|
||||
rv = OpenContainer(aNode);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
rv = CloseContainer(type);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
mozSanitizingHTMLSerializer::AddLeaf(const nsIParserNode& aNode)
|
||||
{
|
||||
|
@ -403,6 +369,14 @@ mozSanitizingHTMLSerializer::OpenHead(const nsIParserNode& aNode)
|
|||
return OpenContainer(aNode);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
mozSanitizingHTMLSerializer::OpenHead()
|
||||
{
|
||||
// XXX We don't have a parser node here, is it okay to ignore this?
|
||||
// return OpenContainer(aNode);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
mozSanitizingHTMLSerializer::CloseHead()
|
||||
{
|
||||
|
@ -559,36 +533,6 @@ mozSanitizingHTMLSerializer::DoAddLeaf(PRInt32 aTag,
|
|||
// using + operator here might give an infinitive loop, see above.
|
||||
// not adding ";", because Gecko delivers that as part of |aText| (freaky)
|
||||
}
|
||||
else if (type == eHTMLTag_script ||
|
||||
type == eHTMLTag_style ||
|
||||
type == eHTMLTag_server)
|
||||
{
|
||||
// These special tags require some extra care. The parser gives them
|
||||
// to us as leaves, but they're really containers. Their content is
|
||||
// contained in the "skipped content" of the parser. This code is
|
||||
// adapted from nsHTMLContentSink.cpp
|
||||
nsString skippedContent;
|
||||
PRInt32 lineNo;
|
||||
|
||||
NS_ASSERTION(mParser, "We are receiving containers as leaves with "
|
||||
"no skipped content.");
|
||||
|
||||
nsCOMPtr<nsIDTD> dtd;
|
||||
mParser->GetDTD(getter_AddRefs(dtd));
|
||||
NS_ENSURE_TRUE(dtd, NS_ERROR_UNEXPECTED);
|
||||
|
||||
// Note: we want to collect the skipped content no matter what. We
|
||||
// may end up throwing it away anyway, but the DTD doesn't care
|
||||
// about that.
|
||||
dtd->CollectSkippedContent(type, skippedContent, lineNo);
|
||||
|
||||
DoOpenContainer(type);
|
||||
if (IsAllowedTag(type))
|
||||
{
|
||||
Write(skippedContent);
|
||||
}
|
||||
DoCloseContainer(type);
|
||||
}
|
||||
else
|
||||
{
|
||||
DoOpenContainer(type);
|
||||
|
|
|
@ -93,14 +93,12 @@ public:
|
|||
|
||||
// nsIContentSink
|
||||
NS_IMETHOD WillBuildModel(void) { return NS_OK; }
|
||||
NS_IMETHOD DidBuildModel(void)
|
||||
{ nsCOMPtr<nsIParser> temp(mParser); mParser = nsnull; return NS_OK; }
|
||||
NS_IMETHOD DidBuildModel(void) { return NS_OK; }
|
||||
NS_IMETHOD WillInterrupt(void) { return NS_OK; }
|
||||
NS_IMETHOD WillResume(void) { return NS_OK; }
|
||||
NS_IMETHOD SetParser(nsIParser* aParser) { mParser = aParser; return NS_OK; }
|
||||
NS_IMETHOD SetParser(nsIParser* aParser) { return NS_OK; }
|
||||
NS_IMETHOD OpenContainer(const nsIParserNode& aNode);
|
||||
NS_IMETHOD CloseContainer(const nsHTMLTag aTag);
|
||||
NS_IMETHOD AddHeadContent(const nsIParserNode& aNode);
|
||||
NS_IMETHOD AddLeaf(const nsIParserNode& aNode);
|
||||
NS_IMETHOD AddComment(const nsIParserNode& aNode) { return NS_OK; }
|
||||
NS_IMETHOD AddProcessingInstruction(const nsIParserNode& aNode)
|
||||
|
@ -114,6 +112,7 @@ public:
|
|||
NS_IMETHOD OpenHTML(const nsIParserNode& aNode);
|
||||
NS_IMETHOD CloseHTML();
|
||||
NS_IMETHOD OpenHead(const nsIParserNode& aNode);
|
||||
NS_IMETHOD OpenHead();
|
||||
NS_IMETHOD CloseHead();
|
||||
NS_IMETHOD SetTitle(const nsString& aValue);
|
||||
NS_IMETHOD OpenBody(const nsIParserNode& aNode);
|
||||
|
@ -162,7 +161,6 @@ protected:
|
|||
nsAString* mOutputString;
|
||||
nsIParserNode* mParserNode;
|
||||
nsCOMPtr<nsIParserService> mParserService;
|
||||
nsCOMPtr<nsIParser> mParser;
|
||||
};
|
||||
|
||||
nsresult
|
||||
|
|
|
@ -468,19 +468,6 @@ nsPlainTextSerializer::CloseContainer(const nsHTMLTag aTag)
|
|||
return DoCloseContainer(aTag);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPlainTextSerializer::AddHeadContent(const nsIParserNode& aNode)
|
||||
{
|
||||
if (eHTMLTag_title == aNode.GetNodeType()) {
|
||||
// XXX collect the skipped content
|
||||
return NS_OK;
|
||||
}
|
||||
OpenHead(aNode);
|
||||
nsresult rv = AddLeaf(aNode);
|
||||
CloseHead();
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPlainTextSerializer::AddLeaf(const nsIParserNode& aNode)
|
||||
{
|
||||
|
@ -527,6 +514,13 @@ nsPlainTextSerializer::OpenHead(const nsIParserNode& aNode)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPlainTextSerializer::OpenHead()
|
||||
{
|
||||
mInHead = PR_TRUE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPlainTextSerializer::CloseHead()
|
||||
{
|
||||
|
|
|
@ -96,7 +96,6 @@ public:
|
|||
NS_IMETHOD SetParser(nsIParser* aParser) { return NS_OK; }
|
||||
NS_IMETHOD OpenContainer(const nsIParserNode& aNode);
|
||||
NS_IMETHOD CloseContainer(const nsHTMLTag aTag);
|
||||
NS_IMETHOD AddHeadContent(const nsIParserNode& aNode);
|
||||
NS_IMETHOD AddLeaf(const nsIParserNode& aNode);
|
||||
NS_IMETHOD AddComment(const nsIParserNode& aNode) { return NS_OK; }
|
||||
NS_IMETHOD AddProcessingInstruction(const nsIParserNode& aNode) { return NS_OK; }
|
||||
|
@ -106,10 +105,10 @@ public:
|
|||
virtual nsISupports *GetTarget() { return nsnull; }
|
||||
|
||||
// nsIHTMLContentSink
|
||||
NS_IMETHOD SetTitle(const nsString& aValue) { return NS_OK; }
|
||||
NS_IMETHOD OpenHTML(const nsIParserNode& aNode);
|
||||
NS_IMETHOD CloseHTML();
|
||||
NS_IMETHOD OpenHead(const nsIParserNode& aNode);
|
||||
NS_IMETHOD OpenHead();
|
||||
NS_IMETHOD CloseHead();
|
||||
NS_IMETHOD OpenBody(const nsIParserNode& aNode);
|
||||
NS_IMETHOD CloseBody();
|
||||
|
|
|
@ -309,7 +309,7 @@ class nsHTMLScriptElement : public nsGenericHTMLElement,
|
|||
public nsIScriptElement
|
||||
{
|
||||
public:
|
||||
nsHTMLScriptElement(nsINodeInfo *aNodeInfo);
|
||||
nsHTMLScriptElement(nsINodeInfo *aNodeInfo, PRBool aFromParser);
|
||||
virtual ~nsHTMLScriptElement();
|
||||
|
||||
// nsISupports
|
||||
|
@ -357,6 +357,8 @@ public:
|
|||
|
||||
virtual nsresult GetInnerHTML(nsAString& aInnerHTML);
|
||||
virtual nsresult SetInnerHTML(const nsAString& aInnerHTML);
|
||||
virtual void DoneAddingChildren();
|
||||
virtual PRBool IsDoneAddingChildren();
|
||||
|
||||
protected:
|
||||
PRBool IsOnloadEventForWindow();
|
||||
|
@ -364,6 +366,7 @@ protected:
|
|||
PRUint32 mLineNumber;
|
||||
PRPackedBool mIsEvaluated;
|
||||
PRPackedBool mEvaluating;
|
||||
PRPackedBool mDoneAddingChildren;
|
||||
|
||||
// Pointer to the script handler helper object (OWNING reference)
|
||||
nsHTMLScriptEventHandler *mScriptEventHandler;
|
||||
|
@ -385,11 +388,13 @@ protected:
|
|||
};
|
||||
|
||||
|
||||
NS_IMPL_NS_NEW_HTML_ELEMENT(Script)
|
||||
NS_IMPL_NS_NEW_HTML_ELEMENT_CHECK_PARSER(Script)
|
||||
|
||||
|
||||
nsHTMLScriptElement::nsHTMLScriptElement(nsINodeInfo *aNodeInfo)
|
||||
: nsGenericHTMLElement(aNodeInfo)
|
||||
nsHTMLScriptElement::nsHTMLScriptElement(nsINodeInfo *aNodeInfo,
|
||||
PRBool aFromParser)
|
||||
: nsGenericHTMLElement(aNodeInfo),
|
||||
mDoneAddingChildren(!aFromParser)
|
||||
{
|
||||
mLineNumber = 0;
|
||||
mIsEvaluated = PR_FALSE;
|
||||
|
@ -484,7 +489,7 @@ nsHTMLScriptElement::CloneNode(PRBool aDeep, nsIDOMNode** aReturn)
|
|||
{
|
||||
*aReturn = nsnull;
|
||||
|
||||
nsHTMLScriptElement* it = new nsHTMLScriptElement(mNodeInfo);
|
||||
nsHTMLScriptElement* it = new nsHTMLScriptElement(mNodeInfo, PR_FALSE);
|
||||
if (!it) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
@ -538,6 +543,19 @@ nsHTMLScriptElement::SetInnerHTML(const nsAString& aInnerHTML)
|
|||
return ReplaceContentsWithText(aInnerHTML, PR_TRUE);
|
||||
}
|
||||
|
||||
void
|
||||
nsHTMLScriptElement::DoneAddingChildren()
|
||||
{
|
||||
mDoneAddingChildren = PR_TRUE;
|
||||
MaybeProcessScript();
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsHTMLScriptElement::IsDoneAddingChildren()
|
||||
{
|
||||
return mDoneAddingChildren;
|
||||
}
|
||||
|
||||
// variation of this code in nsSVGScriptElement - check if changes
|
||||
// need to be transfered when modifying
|
||||
|
||||
|
@ -646,7 +664,7 @@ nsHTMLScriptElement::GetScriptLineNumber()
|
|||
void
|
||||
nsHTMLScriptElement::MaybeProcessScript()
|
||||
{
|
||||
if (mIsEvaluated || mEvaluating || !IsInDoc()) {
|
||||
if (mIsEvaluated || mEvaluating || !mDoneAddingChildren || !IsInDoc()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set sw=2 ts=2 et tw=78: */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
|
@ -235,7 +236,6 @@ public:
|
|||
// nsIHTMLContentSink
|
||||
NS_IMETHOD OpenContainer(const nsIParserNode& aNode);
|
||||
NS_IMETHOD CloseContainer(const nsHTMLTag aTag);
|
||||
NS_IMETHOD AddHeadContent(const nsIParserNode& aNode);
|
||||
NS_IMETHOD AddLeaf(const nsIParserNode& aNode);
|
||||
NS_IMETHOD AddComment(const nsIParserNode& aNode);
|
||||
NS_IMETHOD AddProcessingInstruction(const nsIParserNode& aNode);
|
||||
|
@ -247,10 +247,10 @@ public:
|
|||
NS_IMETHOD NotifyTagObservers(nsIParserNode* aNode);
|
||||
NS_IMETHOD BeginContext(PRInt32 aID);
|
||||
NS_IMETHOD EndContext(PRInt32 aID);
|
||||
NS_IMETHOD SetTitle(const nsString& aValue);
|
||||
NS_IMETHOD OpenHTML(const nsIParserNode& aNode);
|
||||
NS_IMETHOD CloseHTML();
|
||||
NS_IMETHOD OpenHead(const nsIParserNode& aNode);
|
||||
NS_IMETHOD OpenHead();
|
||||
NS_IMETHOD CloseHead();
|
||||
NS_IMETHOD OpenBody(const nsIParserNode& aNode);
|
||||
NS_IMETHOD CloseBody();
|
||||
|
@ -278,7 +278,7 @@ public:
|
|||
protected:
|
||||
PRBool IsTimeToNotify();
|
||||
|
||||
nsresult SetDocumentTitle(const nsAString& aTitle, const nsIParserNode* aNode);
|
||||
nsresult UpdateDocumentTitle();
|
||||
// If aCheckIfPresent is true, will only set an attribute in cases
|
||||
// when it's not already set.
|
||||
nsresult AddAttributes(const nsIParserNode& aNode, nsIContent* aContent,
|
||||
|
@ -337,14 +337,14 @@ protected:
|
|||
nsGenericHTMLElement* mFrameset;
|
||||
nsGenericHTMLElement* mHead;
|
||||
|
||||
nsString mSkippedContent;
|
||||
|
||||
// Do we notify based on time?
|
||||
PRPackedBool mNotifyOnTimer;
|
||||
|
||||
PRPackedBool mLayoutStarted;
|
||||
PRPackedBool mScrolledToRefAlready;
|
||||
PRPackedBool mInTitle;
|
||||
|
||||
nsString mTitleString;
|
||||
PRInt32 mInNotification;
|
||||
nsRefPtr<nsGenericHTMLElement> mCurrentForm;
|
||||
nsCOMPtr<nsIContent> mCurrentMap;
|
||||
|
@ -407,8 +407,11 @@ protected:
|
|||
nsresult ProcessLINKTag(const nsIParserNode& aNode);
|
||||
nsresult ProcessMAPTag(nsIContent* aContent);
|
||||
nsresult ProcessMETATag(const nsIParserNode& aNode);
|
||||
nsresult ProcessSCRIPTTag(const nsIParserNode& aNode);
|
||||
nsresult ProcessSTYLETag(const nsIParserNode& aNode);
|
||||
|
||||
// Routines for tags that require special handling when we reach their end
|
||||
// tag.
|
||||
nsresult ProcessSCRIPTEndTag(nsGenericHTMLElement* content);
|
||||
nsresult ProcessSTYLEEndTag(nsGenericHTMLElement* content);
|
||||
|
||||
nsresult OpenHeadContext();
|
||||
nsresult CloseHeadContext();
|
||||
|
@ -466,7 +469,7 @@ public:
|
|||
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
// nsIRequest
|
||||
// nsIRequest
|
||||
NS_IMETHOD GetName(nsACString &result)
|
||||
{
|
||||
result.AssignLiteral("about:layout-dummy-request");
|
||||
|
@ -523,7 +526,7 @@ public:
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
// nsIChannel
|
||||
// nsIChannel
|
||||
NS_IMETHOD GetOriginalURI(nsIURI **aOriginalURI)
|
||||
{
|
||||
*aOriginalURI = gURI;
|
||||
|
@ -1167,6 +1170,25 @@ SinkContext::OpenContainer(const nsIParserNode& aNode)
|
|||
mStack[mStackPos].mNumFlushed = 0;
|
||||
mStack[mStackPos].mInsertionPoint = -1;
|
||||
|
||||
// XXX Need to do this before we start adding attributes.
|
||||
if (nodeType == eHTMLTag_style) {
|
||||
nsCOMPtr<nsIStyleSheetLinkingElement> ssle = do_QueryInterface(content);
|
||||
NS_ASSERTION(ssle, "Style content isn't a style sheet?");
|
||||
ssle->SetLineNumber(aNode.GetSourceLineNumber());
|
||||
|
||||
// Now disable updates so that every time we add an attribute or child
|
||||
// text token, we don't try to update the style sheet.
|
||||
if (!mSink->mInsideNoXXXTag) {
|
||||
ssle->InitStyleLinkElement(mSink->mParser, PR_FALSE);
|
||||
}
|
||||
else {
|
||||
// We're not going to be evaluating this style anyway.
|
||||
ssle->InitStyleLinkElement(nsnull, PR_TRUE);
|
||||
}
|
||||
|
||||
ssle->SetEnableUpdates(PR_FALSE);
|
||||
}
|
||||
|
||||
// Make sure to add base tag info, if needed, before setting any other
|
||||
// attributes -- what URI attrs do will depend on the base URI. Only do this
|
||||
// for elements that have useful URI attributes.
|
||||
|
@ -1175,6 +1197,9 @@ SinkContext::OpenContainer(const nsIParserNode& aNode)
|
|||
// Containers with "href="
|
||||
case eHTMLTag_a:
|
||||
case eHTMLTag_map:
|
||||
|
||||
// Containers with "src="
|
||||
case eHTMLTag_script:
|
||||
|
||||
// Containers with "action="
|
||||
case eHTMLTag_form:
|
||||
|
@ -1228,16 +1253,31 @@ SinkContext::OpenContainer(const nsIParserNode& aNode)
|
|||
case eHTMLTag_noembed:
|
||||
case eHTMLTag_noframes:
|
||||
mSink->mInsideNoXXXTag++;
|
||||
|
||||
break;
|
||||
|
||||
case eHTMLTag_map:
|
||||
mSink->ProcessMAPTag(content);
|
||||
break;
|
||||
|
||||
case eHTMLTag_iframe:
|
||||
mSink->mNumOpenIFRAMES++;
|
||||
|
||||
break;
|
||||
|
||||
case eHTMLTag_script:
|
||||
{
|
||||
nsCOMPtr<nsIScriptElement> sele = do_QueryInterface(content);
|
||||
NS_ASSERTION(sele, "Script content isn't a script element?");
|
||||
sele->SetScriptLineNumber(aNode.GetSourceLineNumber());
|
||||
}
|
||||
break;
|
||||
|
||||
case eHTMLTag_title:
|
||||
if (mSink->mDocument->GetDocumentTitle().IsVoid()) {
|
||||
// The first title wins.
|
||||
mSink->mInTitle = PR_TRUE;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -1340,8 +1380,23 @@ SinkContext::CloseContainer(const nsHTMLTag aTag)
|
|||
case eHTMLTag_object:
|
||||
case eHTMLTag_applet:
|
||||
content->DoneAddingChildren();
|
||||
|
||||
break;
|
||||
|
||||
case eHTMLTag_script:
|
||||
result = mSink->ProcessSCRIPTEndTag(content);
|
||||
break;
|
||||
|
||||
case eHTMLTag_style:
|
||||
result = mSink->ProcessSTYLEEndTag(content);
|
||||
break;
|
||||
|
||||
case eHTMLTag_title:
|
||||
if (mSink->mInTitle) {
|
||||
mSink->UpdateDocumentTitle();
|
||||
mSink->mInTitle = PR_FALSE;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -1586,6 +1641,11 @@ SinkContext::AddText(const nsAString& aText)
|
|||
if (addLen == 0) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (mSink->mInTitle) {
|
||||
// Hang onto the title text specially.
|
||||
mSink->mTitleString.Append(aText);
|
||||
}
|
||||
|
||||
// Create buffer when we first need it
|
||||
if (mTextSize == 0) {
|
||||
|
@ -2458,25 +2518,6 @@ HTMLContentSink::EndContext(PRInt32 aPosition)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
HTMLContentSink::SetTitle(const nsString& aValue)
|
||||
{
|
||||
MOZ_TIMER_DEBUGLOG(("Start: nsHTMLContentSink::SetTitle()\n"));
|
||||
MOZ_TIMER_START(mWatch);
|
||||
|
||||
nsresult rv = OpenHeadContext();
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
rv = SetDocumentTitle(aValue, nsnull);
|
||||
}
|
||||
CloseHeadContext();
|
||||
|
||||
MOZ_TIMER_DEBUGLOG(("Stop: nsHTMLContentSink::SetTitle()\n"));
|
||||
MOZ_TIMER_STOP(mWatch);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
HTMLContentSink::OpenHTML(const nsIParserNode& aNode)
|
||||
{
|
||||
|
@ -2532,7 +2573,7 @@ HTMLContentSink::CloseHTML()
|
|||
NS_IMETHODIMP
|
||||
HTMLContentSink::OpenHead(const nsIParserNode& aNode)
|
||||
{
|
||||
MOZ_TIMER_DEBUGLOG(("Start: nsHTMLContentSink::OpenHead()\n"));
|
||||
MOZ_TIMER_DEBUGLOG(("Start: nsHTMLContentSink::OpenHead(nsIParserNode)\n"));
|
||||
MOZ_TIMER_START(mWatch);
|
||||
SINK_TRACE_NODE(SINK_TRACE_CALLS,
|
||||
"HTMLContentSink::OpenHead",
|
||||
|
@ -2540,7 +2581,7 @@ HTMLContentSink::OpenHead(const nsIParserNode& aNode)
|
|||
|
||||
nsresult rv = OpenHeadContext();
|
||||
if (NS_FAILED(rv)) {
|
||||
MOZ_TIMER_DEBUGLOG(("Stop: nsHTMLContentSink::OpenHead()\n"));
|
||||
MOZ_TIMER_DEBUGLOG(("Stop: nsHTMLContentSink::OpenHead(nsIParserNode)\n"));
|
||||
MOZ_TIMER_STOP(mWatch);
|
||||
return rv;
|
||||
}
|
||||
|
@ -2555,6 +2596,20 @@ HTMLContentSink::OpenHead(const nsIParserNode& aNode)
|
|||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
HTMLContentSink::OpenHead()
|
||||
{
|
||||
MOZ_TIMER_DEBUGLOG(("Start: nsHTMLContentSink::OpenHead()\n"));
|
||||
MOZ_TIMER_START(mWatch);
|
||||
|
||||
nsresult rv = OpenHeadContext();
|
||||
|
||||
MOZ_TIMER_DEBUGLOG(("Stop: nsHTMLContentSink::OpenHead()\n"));
|
||||
MOZ_TIMER_STOP(mWatch);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
HTMLContentSink::CloseHead()
|
||||
{
|
||||
|
@ -2917,37 +2972,6 @@ HTMLContentSink::CloseContainer(const eHTMLTags aTag)
|
|||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
HTMLContentSink::AddHeadContent(const nsIParserNode& aNode)
|
||||
{
|
||||
MOZ_TIMER_DEBUGLOG(("Start: nsHTMLContentSink::AddHeadContent()\n"));
|
||||
MOZ_TIMER_START(mWatch);
|
||||
|
||||
nsresult rv = OpenHeadContext();
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
nsHTMLTag type = nsHTMLTag(aNode.GetNodeType());
|
||||
if (eHTMLTag_title == type) {
|
||||
nsCOMPtr<nsIDTD> dtd;
|
||||
mParser->GetDTD(getter_AddRefs(dtd));
|
||||
if (dtd) {
|
||||
nsAutoString title;
|
||||
PRInt32 lineNo = 0;
|
||||
dtd->CollectSkippedContent(eHTMLTag_title, title, lineNo);
|
||||
rv = SetDocumentTitle(title, &aNode);
|
||||
}
|
||||
}
|
||||
else {
|
||||
rv = AddLeaf(aNode);
|
||||
}
|
||||
CloseHeadContext();
|
||||
}
|
||||
|
||||
MOZ_TIMER_DEBUGLOG(("Stop: nsHTMLContentSink::AddHeadContent()\n"));
|
||||
MOZ_TIMER_STOP(mWatch);
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
HTMLContentSink::AddLeaf(const nsIParserNode& aNode)
|
||||
{
|
||||
|
@ -2976,16 +3000,6 @@ HTMLContentSink::AddLeaf(const nsIParserNode& aNode)
|
|||
mCurrentContext->FlushTextAndRelease();
|
||||
rv = ProcessMETATag(aNode);
|
||||
|
||||
break;
|
||||
case eHTMLTag_style:
|
||||
mCurrentContext->FlushTextAndRelease();
|
||||
rv = ProcessSTYLETag(aNode);
|
||||
|
||||
break;
|
||||
case eHTMLTag_script:
|
||||
mCurrentContext->FlushTextAndRelease();
|
||||
rv = ProcessSCRIPTTag(aNode);
|
||||
|
||||
break;
|
||||
default:
|
||||
rv = mCurrentContext->AddLeaf(aNode);
|
||||
|
@ -3000,53 +3014,27 @@ HTMLContentSink::AddLeaf(const nsIParserNode& aNode)
|
|||
}
|
||||
|
||||
nsresult
|
||||
HTMLContentSink::SetDocumentTitle(const nsAString& aTitle, const nsIParserNode* aNode)
|
||||
HTMLContentSink::UpdateDocumentTitle()
|
||||
{
|
||||
MOZ_TIMER_DEBUGLOG(("Start: nsHTMLContentSink::SetDocumentTitle()\n"));
|
||||
MOZ_TIMER_DEBUGLOG(("Start: nsHTMLContentSink::UpdateDocumentTitle()\n"));
|
||||
MOZ_TIMER_START(mWatch);
|
||||
NS_ASSERTION(mCurrentContext == mHeadContext, "title not in head");
|
||||
|
||||
if (!mDocument->GetDocumentTitle().IsVoid()) {
|
||||
// If the title was already set then don't try to overwrite it
|
||||
// when a new title is encountered - For backwards compatiblity
|
||||
MOZ_TIMER_DEBUGLOG(("Stop: nsHTMLContentSink::SetDocumentTitle()\n"));
|
||||
MOZ_TIMER_DEBUGLOG(("Stop: nsHTMLContentSink::UpdateDocumentTitle()\n"));
|
||||
MOZ_TIMER_STOP(mWatch);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsAutoString title(aTitle);
|
||||
title.CompressWhitespace(PR_TRUE, PR_TRUE);
|
||||
// Use mTitleString.
|
||||
mTitleString.CompressWhitespace(PR_TRUE, PR_TRUE);
|
||||
|
||||
nsCOMPtr<nsIDOMNSDocument> domDoc(do_QueryInterface(mDocument));
|
||||
domDoc->SetTitle(title);
|
||||
domDoc->SetTitle(mTitleString);
|
||||
|
||||
nsCOMPtr<nsINodeInfo> nodeInfo;
|
||||
nsresult rv = mNodeInfoManager->GetNodeInfo(nsHTMLAtoms::title, nsnull,
|
||||
kNameSpaceID_None,
|
||||
getter_AddRefs(nodeInfo));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
mTitleString.Truncate();
|
||||
|
||||
nsRefPtr<nsGenericHTMLElement> it = NS_NewHTMLTitleElement(nodeInfo);
|
||||
if (!it) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
if (aNode) {
|
||||
AddAttributes(*aNode, it);
|
||||
}
|
||||
|
||||
nsCOMPtr<nsITextContent> text;
|
||||
rv = NS_NewTextNode(getter_AddRefs(text));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
text->SetText(title, PR_TRUE);
|
||||
|
||||
it->AppendChildTo(text, PR_FALSE);
|
||||
|
||||
mHead->AppendChildTo(it, PR_FALSE);
|
||||
|
||||
MOZ_TIMER_DEBUGLOG(("Stop: nsHTMLContentSink::SetDocumentTitle()\n"));
|
||||
MOZ_TIMER_DEBUGLOG(("Stop: nsHTMLContentSink::UpdateDocumentTitle()\n"));
|
||||
MOZ_TIMER_STOP(mWatch);
|
||||
|
||||
return NS_OK;
|
||||
|
@ -4010,67 +3998,13 @@ HTMLContentSink::PostEvaluateScript()
|
|||
}
|
||||
|
||||
nsresult
|
||||
HTMLContentSink::ProcessSCRIPTTag(const nsIParserNode& aNode)
|
||||
HTMLContentSink::ProcessSCRIPTEndTag(nsGenericHTMLElement *content)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
nsCOMPtr<nsIScriptElement> sele = do_QueryInterface(content);
|
||||
NS_ASSERTION(sele, "Not really closing a script tag?");
|
||||
|
||||
// Create content object
|
||||
NS_ASSERTION(mCurrentContext->mStackPos > 0, "leaf w/o container");
|
||||
if (mCurrentContext->mStackPos <= 0) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
// Inserting the element into the document may execute a script.
|
||||
// This can potentially make the parent go away. So, hold
|
||||
// on to it till we are done.
|
||||
nsRefPtr<nsGenericHTMLElement> parent =
|
||||
mCurrentContext->mStack[mCurrentContext->mStackPos - 1].mContent;
|
||||
nsCOMPtr<nsIContent> element;
|
||||
nsCOMPtr<nsINodeInfo> nodeInfo;
|
||||
mNodeInfoManager->GetNodeInfo(nsHTMLAtoms::script, nsnull, kNameSpaceID_None,
|
||||
getter_AddRefs(nodeInfo));
|
||||
|
||||
rv = NS_NewHTMLElement(getter_AddRefs(element), nodeInfo);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
element->SetContentID(mDocument->GetAndIncrementContentID());
|
||||
|
||||
// Add in the attributes and add the script content object to the
|
||||
// head container.
|
||||
AddBaseTagInfo(element);
|
||||
rv = AddAttributes(aNode, element);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDTD> dtd;
|
||||
mParser->GetDTD(getter_AddRefs(dtd));
|
||||
NS_ENSURE_TRUE(dtd, NS_ERROR_FAILURE);
|
||||
|
||||
nsCOMPtr<nsIScriptElement> sele(do_QueryInterface(element));
|
||||
nsAutoString script;
|
||||
PRInt32 lineNo = 0;
|
||||
|
||||
dtd->CollectSkippedContent(eHTMLTag_script, script, lineNo);
|
||||
|
||||
if (sele) {
|
||||
sele->SetScriptLineNumber((PRUint32)lineNo);
|
||||
}
|
||||
|
||||
// Create a text node holding the content. First, get the text
|
||||
// content of the script tag
|
||||
|
||||
if (!script.IsEmpty()) {
|
||||
nsCOMPtr<nsITextContent> text;
|
||||
rv = NS_NewTextNode(getter_AddRefs(text));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
text->SetText(script, PR_TRUE);
|
||||
|
||||
element->AppendChildTo(text, PR_FALSE);
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIScriptLoader> loader;
|
||||
if (mFrameset) {
|
||||
|
@ -4089,7 +4023,7 @@ HTMLContentSink::ProcessSCRIPTTag(const nsIParserNode& aNode)
|
|||
|
||||
// Don't include script loading and evaluation in the stopwatch
|
||||
// that is measuring content creation time
|
||||
MOZ_TIMER_DEBUGLOG(("Stop: nsHTMLContentSink::ProcessSCRIPTTag()\n"));
|
||||
MOZ_TIMER_DEBUGLOG(("Stop: nsHTMLContentSink::ProcessSCRIPTEndTag()\n"));
|
||||
MOZ_TIMER_STOP(mWatch);
|
||||
|
||||
// Assume that we're going to block the parser with a script load.
|
||||
|
@ -4100,23 +4034,10 @@ HTMLContentSink::ProcessSCRIPTTag(const nsIParserNode& aNode)
|
|||
mScriptElements.AppendObject(sele);
|
||||
}
|
||||
|
||||
// Now flush out tags so that the script will actually be bound to a
|
||||
// document and will evaluate as soon as it's appended.
|
||||
SINK_TRACE(SINK_TRACE_CALLS,
|
||||
("HTMLContentSink::ProcessSCRIPTTag: flushing tags before "
|
||||
"appending script"));
|
||||
mCurrentContext->FlushTags(PR_FALSE);
|
||||
// Now tell the script that it's ready to go. This will execute the script
|
||||
// and call our ScriptAvailable method.
|
||||
content->DoneAddingChildren();
|
||||
|
||||
// Insert the child into the content tree. This will evaluate the
|
||||
// script as well.
|
||||
if (mCurrentContext->mStack[mCurrentContext->mStackPos - 1].mInsertionPoint != -1) {
|
||||
parent->InsertChildAt(element,
|
||||
mCurrentContext->mStack[mCurrentContext->mStackPos - 1].mInsertionPoint++,
|
||||
PR_FALSE);
|
||||
} else {
|
||||
parent->AppendChildTo(element, PR_FALSE);
|
||||
}
|
||||
|
||||
// To prevent script evaluation in a frameset document, we suspended
|
||||
// the script loader. Now that the script content has been handled,
|
||||
// let's resume the script loader.
|
||||
|
@ -4137,81 +4058,18 @@ HTMLContentSink::ProcessSCRIPTTag(const nsIParserNode& aNode)
|
|||
// XXX What does nav do if we have SRC= and some style data inline?
|
||||
|
||||
nsresult
|
||||
HTMLContentSink::ProcessSTYLETag(const nsIParserNode& aNode)
|
||||
HTMLContentSink::ProcessSTYLEEndTag(nsGenericHTMLElement* content)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
nsGenericHTMLElement* parent = nsnull;
|
||||
|
||||
if (mCurrentContext) {
|
||||
parent = mCurrentContext->mStack[mCurrentContext->mStackPos - 1].mContent;
|
||||
}
|
||||
|
||||
if (!parent) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Create content object
|
||||
nsCOMPtr<nsINodeInfo> nodeInfo;
|
||||
mNodeInfoManager->GetNodeInfo(nsHTMLAtoms::style, nsnull, kNameSpaceID_None,
|
||||
getter_AddRefs(nodeInfo));
|
||||
|
||||
nsCOMPtr<nsIContent> element;
|
||||
rv = NS_NewHTMLElement(getter_AddRefs(element), nodeInfo);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
element->SetContentID(mDocument->GetAndIncrementContentID());
|
||||
|
||||
nsCOMPtr<nsIStyleSheetLinkingElement> ssle = do_QueryInterface(element);
|
||||
nsCOMPtr<nsIStyleSheetLinkingElement> ssle = do_QueryInterface(content);
|
||||
|
||||
NS_ASSERTION(ssle,
|
||||
"html:style doesn't implement nsIStyleSheetLinkingElement");
|
||||
|
||||
if (ssle) {
|
||||
// XXX need prefs. check here.
|
||||
if (!mInsideNoXXXTag) {
|
||||
ssle->InitStyleLinkElement(mParser, PR_FALSE);
|
||||
ssle->SetEnableUpdates(PR_FALSE);
|
||||
} else {
|
||||
ssle->InitStyleLinkElement(nsnull, PR_TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
// Add in the attributes and add the style content object to the
|
||||
// head container.
|
||||
AddBaseTagInfo(element);
|
||||
rv = AddAttributes(aNode, element);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
// The skipped content contains the inline style data
|
||||
nsCOMPtr<nsIDTD> dtd;
|
||||
mParser->GetDTD(getter_AddRefs(dtd));
|
||||
NS_ENSURE_TRUE(dtd, NS_ERROR_FAILURE);
|
||||
|
||||
nsAutoString content;
|
||||
PRInt32 lineNo = 0;
|
||||
|
||||
dtd->CollectSkippedContent(eHTMLTag_style, content, lineNo);
|
||||
|
||||
if (ssle) {
|
||||
ssle->SetLineNumber(lineNo);
|
||||
}
|
||||
|
||||
if (!content.IsEmpty()) {
|
||||
// Create a text node holding the content
|
||||
nsCOMPtr<nsITextContent> text;
|
||||
rv = NS_NewTextNode(getter_AddRefs(text));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
text->SetText(content, PR_TRUE);
|
||||
|
||||
element->AppendChildTo(text, PR_FALSE);
|
||||
}
|
||||
|
||||
parent->AppendChildTo(element, PR_FALSE);
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
if (ssle) {
|
||||
// Note: if we are inside a noXXX tag, then we init'ed this style element
|
||||
// with mDontLoadStyle = PR_TRUE, so these two calls will have no effect.
|
||||
ssle->SetEnableUpdates(PR_TRUE);
|
||||
rv = ssle->UpdateStyleSheet(nsnull, nsnull);
|
||||
}
|
||||
|
|
|
@ -90,10 +90,10 @@ public:
|
|||
// nsIHTMLContentSink
|
||||
NS_IMETHOD BeginContext(PRInt32 aID);
|
||||
NS_IMETHOD EndContext(PRInt32 aID);
|
||||
NS_IMETHOD SetTitle(const nsString& aValue);
|
||||
NS_IMETHOD OpenHTML(const nsIParserNode& aNode);
|
||||
NS_IMETHOD CloseHTML();
|
||||
NS_IMETHOD OpenHead(const nsIParserNode& aNode);
|
||||
NS_IMETHOD OpenHead();
|
||||
NS_IMETHOD CloseHead();
|
||||
NS_IMETHOD OpenBody(const nsIParserNode& aNode);
|
||||
NS_IMETHOD CloseBody();
|
||||
|
@ -115,7 +115,6 @@ public:
|
|||
NS_IMETHOD NotifyTagObservers(nsIParserNode* aNode) { return NS_OK; }
|
||||
NS_IMETHOD OpenContainer(const nsIParserNode& aNode);
|
||||
NS_IMETHOD CloseContainer(const nsHTMLTag aTag);
|
||||
NS_IMETHOD AddHeadContent(const nsIParserNode& aNode);
|
||||
NS_IMETHOD AddLeaf(const nsIParserNode& aNode);
|
||||
NS_IMETHOD AddComment(const nsIParserNode& aNode);
|
||||
NS_IMETHOD AddProcessingInstruction(const nsIParserNode& aNode);
|
||||
|
@ -143,7 +142,6 @@ public:
|
|||
void AddBaseTagInfo(nsIContent* aContent);
|
||||
|
||||
nsresult Init();
|
||||
nsresult SetDocumentTitle(const nsAString& aString, const nsIParserNode* aNode);
|
||||
|
||||
PRPackedBool mAllContent;
|
||||
PRPackedBool mProcessing;
|
||||
|
@ -299,12 +297,6 @@ nsHTMLFragmentContentSink::EndContext(PRInt32 aID)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLFragmentContentSink::SetTitle(const nsString& aValue)
|
||||
{
|
||||
return SetDocumentTitle(aValue, nsnull);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLFragmentContentSink::OpenHTML(const nsIParserNode& aNode)
|
||||
{
|
||||
|
@ -323,6 +315,14 @@ nsHTMLFragmentContentSink::OpenHead(const nsIParserNode& aNode)
|
|||
return OpenContainer(aNode);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLFragmentContentSink::OpenHead()
|
||||
{
|
||||
// The DTD uses this function when the head is being forced open by a tag in
|
||||
// the body. We can safely ignore it, for now.
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLFragmentContentSink::CloseHead()
|
||||
{
|
||||
|
@ -338,9 +338,8 @@ nsHTMLFragmentContentSink::OpenBody(const nsIParserNode& aNode)
|
|||
mSeenBody = PR_TRUE;
|
||||
return OpenContainer(aNode);
|
||||
}
|
||||
else {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
@ -410,36 +409,6 @@ nsHTMLFragmentContentSink::AddBaseTagInfo(nsIContent* aContent)
|
|||
}
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsHTMLFragmentContentSink::SetDocumentTitle(const nsAString& aString, const nsIParserNode* aNode)
|
||||
{
|
||||
NS_ENSURE_TRUE(mNodeInfoManager, NS_ERROR_NOT_INITIALIZED);
|
||||
|
||||
nsCOMPtr<nsINodeInfo> nodeInfo;
|
||||
nsresult rv = mNodeInfoManager->GetNodeInfo(nsHTMLAtoms::title, nsnull,
|
||||
kNameSpaceID_None,
|
||||
getter_AddRefs(nodeInfo));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsRefPtr<nsGenericHTMLElement> content = NS_NewHTMLTitleElement(nodeInfo);
|
||||
NS_ENSURE_TRUE(content, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
nsIContent *parent = GetCurrentContent();
|
||||
|
||||
if (!parent) {
|
||||
parent = mRoot;
|
||||
}
|
||||
|
||||
if (aNode) {
|
||||
AddAttributes(*aNode, content);
|
||||
}
|
||||
|
||||
rv = parent->AppendChildTo(content, PR_FALSE);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return AddTextToContent(content, aString);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLFragmentContentSink::OpenContainer(const nsIParserNode& aNode)
|
||||
{
|
||||
|
@ -520,28 +489,9 @@ nsHTMLFragmentContentSink::CloseContainer(const nsHTMLTag aTag)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLFragmentContentSink::AddHeadContent(const nsIParserNode& aNode)
|
||||
{
|
||||
return AddLeaf(aNode);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLFragmentContentSink::AddLeaf(const nsIParserNode& aNode)
|
||||
{
|
||||
if (eHTMLTag_title == aNode.GetNodeType()) {
|
||||
nsCOMPtr<nsIDTD> dtd;
|
||||
mParser->GetDTD(getter_AddRefs(dtd));
|
||||
NS_ENSURE_TRUE(dtd, NS_ERROR_FAILURE);
|
||||
|
||||
nsAutoString skippedContent;
|
||||
PRInt32 lineNo = 0;
|
||||
|
||||
dtd->CollectSkippedContent(eHTMLTag_title, skippedContent, lineNo);
|
||||
|
||||
return SetDocumentTitle(skippedContent, &aNode);
|
||||
}
|
||||
|
||||
NS_ENSURE_TRUE(mNodeInfoManager, NS_ERROR_NOT_INITIALIZED);
|
||||
|
||||
nsresult result = NS_OK;
|
||||
|
@ -594,22 +544,7 @@ nsHTMLFragmentContentSink::AddLeaf(const nsIParserNode& aNode)
|
|||
}
|
||||
}
|
||||
|
||||
if(nodeType == eHTMLTag_script ||
|
||||
nodeType == eHTMLTag_style ||
|
||||
nodeType == eHTMLTag_server) {
|
||||
|
||||
// Create a text node holding the content
|
||||
nsCOMPtr<nsIDTD> dtd;
|
||||
mParser->GetDTD(getter_AddRefs(dtd));
|
||||
NS_ENSURE_TRUE(dtd, NS_ERROR_FAILURE);
|
||||
|
||||
nsAutoString skippedContent;
|
||||
PRInt32 lineNo = 0;
|
||||
|
||||
dtd->CollectSkippedContent(nodeType, skippedContent, lineNo);
|
||||
result=AddTextToContent(content, skippedContent);
|
||||
}
|
||||
else if (nodeType == eHTMLTag_img || nodeType == eHTMLTag_frame
|
||||
if (nodeType == eHTMLTag_img || nodeType == eHTMLTag_frame
|
||||
|| nodeType == eHTMLTag_input) // elements with 'SRC='
|
||||
AddBaseTagInfo(content);
|
||||
else if (nodeType == eHTMLTag_base)
|
||||
|
|
|
@ -59,7 +59,9 @@
|
|||
#include "nsITokenizer.h"
|
||||
|
||||
#define NS_IDTD_IID \
|
||||
{ 0xa6cf9053, 0x15b3, 0x11d2,{0x93, 0x2e, 0x00, 0x80, 0x5f, 0x8a, 0xdd, 0x32}}
|
||||
{ 0xab54d8ec, 0xc31c, 0x434b, \
|
||||
{ 0xa7, 0x64, 0xb4, 0xe9, 0xcd, 0x60, 0xc5, 0xc1 } }
|
||||
|
||||
|
||||
enum eAutoDetectResult {
|
||||
eUnknownDetect,
|
||||
|
@ -200,8 +202,6 @@ public:
|
|||
NS_IMETHOD_(void) Terminate() = 0;
|
||||
|
||||
NS_IMETHOD_(PRInt32) GetType() = 0;
|
||||
|
||||
NS_IMETHOD CollectSkippedContent(PRInt32 aTag, nsAString& aContent, PRInt32 &aLineNo) = 0;
|
||||
};
|
||||
|
||||
#define NS_DECL_NSIDTD \
|
||||
|
@ -216,7 +216,6 @@ public:
|
|||
NS_IMETHOD WillInterruptParse(nsIContentSink* aSink = 0);\
|
||||
NS_IMETHOD_(PRBool) CanContain(PRInt32 aParent,PRInt32 aChild) const;\
|
||||
NS_IMETHOD_(PRBool) IsContainer(PRInt32 aTag) const;\
|
||||
NS_IMETHOD CollectSkippedContent(PRInt32 aTag, nsAString& aContent, PRInt32 &aLineNo);\
|
||||
NS_IMETHOD_(void) Terminate();\
|
||||
NS_IMETHOD_(PRInt32) GetType();
|
||||
#endif /* nsIDTD_h___ */
|
||||
|
|
|
@ -38,9 +38,6 @@
|
|||
#define nsIHTMLContentSink_h___
|
||||
|
||||
/**
|
||||
* MODULE NOTES:
|
||||
* @update gess 4/1/98
|
||||
*
|
||||
* This file declares the concrete HTMLContentSink class.
|
||||
* This class is used during the parsing process as the
|
||||
* primary interface between the parser and the content
|
||||
|
@ -86,7 +83,9 @@
|
|||
#include "nsHTMLTags.h"
|
||||
|
||||
#define NS_IHTML_CONTENT_SINK_IID \
|
||||
{ 0x59929de5, 0xe60b, 0x48b1,{0x81, 0x69, 0x48, 0x47, 0xb5, 0xc9, 0x44, 0x29}}
|
||||
{ 0x73b5a072, 0x0f87, 0x4d07, \
|
||||
{ 0xa8, 0x16, 0xe6, 0xac, 0x73, 0xa7, 0x04, 0x3c } }
|
||||
|
||||
|
||||
#if defined(XP_MAC) || defined(WINCE)
|
||||
#define MAX_REFLOW_DEPTH 75 //setting to 75 to prevent layout from crashing on mac. Bug 55095.
|
||||
|
@ -102,15 +101,6 @@ public:
|
|||
|
||||
NS_DEFINE_STATIC_IID_ACCESSOR(NS_IHTML_CONTENT_SINK_IID)
|
||||
|
||||
/**
|
||||
* This method gets called by the parser when it encounters
|
||||
* a title tag and wants to set the document title in the sink.
|
||||
*
|
||||
* @update 4/1/98 gess
|
||||
* @param nsString reference to new title value
|
||||
*/
|
||||
NS_IMETHOD SetTitle(const nsString& aValue) = 0;
|
||||
|
||||
/**
|
||||
* This method is used to open the outer HTML container.
|
||||
*
|
||||
|
@ -133,6 +123,13 @@ public:
|
|||
*/
|
||||
NS_IMETHOD OpenHead(const nsIParserNode& aNode) = 0;
|
||||
|
||||
/**
|
||||
* This method is used to open the HEAD container. It is useful if a tag
|
||||
* is forcing us to open the head (probably again), like if we find a <meta>
|
||||
* tag in the body.
|
||||
*/
|
||||
NS_IMETHOD OpenHead() = 0;
|
||||
|
||||
/**
|
||||
* This method is used to close the only HEAD container.
|
||||
*/
|
||||
|
@ -262,13 +259,6 @@ public:
|
|||
*/
|
||||
NS_IMETHOD CloseContainer(const nsHTMLTag aTag) = 0;
|
||||
|
||||
/**
|
||||
* This gets called by the parser to contents to
|
||||
* the head container
|
||||
*
|
||||
*/
|
||||
NS_IMETHOD AddHeadContent(const nsIParserNode& aNode) = 0;
|
||||
|
||||
/**
|
||||
* This gets called by the parser when you want to add
|
||||
* a leaf node to the current container in the content
|
||||
|
@ -303,7 +293,7 @@ public:
|
|||
* This method is called by the parser when it encounters
|
||||
* a document type declaration.
|
||||
*
|
||||
* XXX Should the parser also part the internal subset?
|
||||
* XXX Should the parser also parse the internal subset?
|
||||
*
|
||||
* @param nsIParserNode reference to parser node interface
|
||||
*/
|
||||
|
|
|
@ -113,11 +113,11 @@ static const char kInvalidTagStackPos[] = "Error: invalid tag stack position";
|
|||
#define NS_DTD_FLAG_HAS_OPEN_HEAD 0x00000001
|
||||
#define NS_DTD_FLAG_HAS_OPEN_BODY 0x00000002
|
||||
#define NS_DTD_FLAG_HAS_OPEN_FORM 0x00000004
|
||||
#define NS_DTD_FLAG_HAS_OPEN_SCRIPT 0x00000008
|
||||
#define NS_DTD_FLAG_HAS_EXPLICIT_HEAD 0x00000008
|
||||
#define NS_DTD_FLAG_HAD_BODY 0x00000010
|
||||
#define NS_DTD_FLAG_HAD_FRAMESET 0x00000020
|
||||
#define NS_DTD_FLAG_ENABLE_RESIDUAL_STYLE 0x00000040
|
||||
#define NS_DTD_FLAG_ALTERNATE_CONTENT 0x00000080 // NOFRAMES, NOSCRIPT
|
||||
#define NS_DTD_FLAG_ALTERNATE_CONTENT 0x00000080 // NOFRAMES, NOSCRIPT
|
||||
#define NS_DTD_FLAG_MISPLACED_CONTENT 0x00000100
|
||||
#define NS_DTD_FLAG_IN_MISPLACED_CONTENT 0x00000200
|
||||
#define NS_DTD_FLAG_STOP_PARSING 0x00000400
|
||||
|
@ -167,7 +167,6 @@ NS_IMPL_RELEASE(CNavDTD)
|
|||
*/
|
||||
CNavDTD::CNavDTD() : nsIDTD(),
|
||||
mMisplacedContent(0),
|
||||
mSkippedContent(0),
|
||||
mSink(0),
|
||||
mTokenAllocator(0),
|
||||
mTempContext(0),
|
||||
|
@ -176,9 +175,9 @@ CNavDTD::CNavDTD() : nsIDTD(),
|
|||
mDTDMode(eDTDMode_quirks),
|
||||
mDocType(eHTML3_Quirks), // why not eHTML_Quirks?
|
||||
mParserCommand(eViewNormal),
|
||||
mSkipTarget(eHTMLTag_unknown),
|
||||
mLineNumber(1),
|
||||
mOpenMapCount(0),
|
||||
mHeadContainerPosition(-1),
|
||||
mFlags(NS_DTD_FLAG_NONE)
|
||||
{
|
||||
mBodyContext=new nsDTDContext();
|
||||
|
@ -341,7 +340,6 @@ nsresult CNavDTD::WillBuildModel(const CParserContext& aParserContext,
|
|||
mParserCommand = aParserContext.mParserCommand;
|
||||
mMimeType = aParserContext.mMimeType;
|
||||
mDocType = aParserContext.mDocType;
|
||||
mSkipTarget = eHTMLTag_unknown;
|
||||
mTokenizer = aTokenizer;
|
||||
mBodyContext->SetNodeAllocator(&mNodeAllocator);
|
||||
|
||||
|
@ -475,10 +473,9 @@ nsresult CNavDTD::BuildModel(nsIParser* aParser,nsITokenizer* aTokenizer,nsIToke
|
|||
// Script so we should not allow it to be interrupted.
|
||||
// We also need to make sure that an interruption does not override
|
||||
// a request to block the parser.
|
||||
if ((mParser->CanInterrupt()) &&
|
||||
(nsnull == mParser->PeekContext()->mPrevContext) &&
|
||||
(eHTMLTag_unknown==mSkipTarget) &&
|
||||
NS_SUCCEEDED(result)) {
|
||||
if (mParser->CanInterrupt() &&
|
||||
!mParser->PeekContext()->mPrevContext &&
|
||||
NS_SUCCEEDED(result)) {
|
||||
result = NS_ERROR_HTMLPARSER_INTERRUPTED;
|
||||
break;
|
||||
}
|
||||
|
@ -532,12 +529,6 @@ nsresult CNavDTD::DidBuildModel(nsresult anErrorCode,
|
|||
nsresult result = NS_OK;
|
||||
if (aParser && aNotifySink) {
|
||||
if (NS_OK == anErrorCode) {
|
||||
if (eHTMLTag_unknown != mSkipTarget) {
|
||||
// Looks like there is an open target ( ex. <title> ).
|
||||
// Create a matching target to handle the unclosed target.
|
||||
result = BuildNeglectedTarget(mSkipTarget, eToken_end, aParser, aSink);
|
||||
NS_ENSURE_SUCCESS(result , result);
|
||||
}
|
||||
if (!(mFlags & (NS_DTD_FLAG_HAD_FRAMESET | NS_DTD_FLAG_HAD_BODY))) {
|
||||
// This document is not a frameset document, however, it did not contain
|
||||
// a body tag either. So, make one!. Note: Body tag is optional per spec..
|
||||
|
@ -673,81 +664,6 @@ PRBool HasOpenTagOfType(PRInt32 aType, const nsDTDContext& aContext) {
|
|||
return PR_FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
InPlaceConvertLineEndings( nsAString& aString )
|
||||
{
|
||||
// go from '\r\n' or '\r' to '\n'
|
||||
nsAString::iterator iter;
|
||||
aString.BeginWriting(iter);
|
||||
|
||||
PRUnichar* S = iter.get();
|
||||
size_t N = iter.size_forward();
|
||||
|
||||
// this fragment must be the entire string because
|
||||
// (a) no multi-fragment string is writable, so only an illegal cast could give us one, and
|
||||
// (b) else we would have to do more work (watching for |to| to fall off the end)
|
||||
NS_ASSERTION(aString.Length() == N, "You cheated... multi-fragment strings are never writable!");
|
||||
|
||||
// we scan/convert in two phases (but only one pass over the string)
|
||||
// until we have to skip a character, we only need to touch end-of-line chars
|
||||
// after that, we'll have to start moving every character we want to keep
|
||||
|
||||
// use array indexing instead of pointers, because compilers optimize that better
|
||||
|
||||
|
||||
// this first loop just converts line endings... no characters get moved
|
||||
size_t i = 0;
|
||||
PRBool just_saw_cr = PR_FALSE;
|
||||
for ( ; i < N; ++i )
|
||||
{
|
||||
// if it's something we need to convert...
|
||||
if ( S[i] == '\r' )
|
||||
{
|
||||
S[i] = '\n';
|
||||
just_saw_cr = PR_TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
// else, if it's something we need to skip...
|
||||
// i.e., a '\n' immediately following a '\r',
|
||||
// then we need to start moving any character we want to keep
|
||||
// and we have a second loop for that, so get out of this one
|
||||
if ( S[i] == '\n' && just_saw_cr )
|
||||
break;
|
||||
|
||||
just_saw_cr = PR_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// this second loop handles the rest of the buffer, moving characters down
|
||||
// _and_ converting line-endings as it goes
|
||||
// start the loop at |from = i| so that that |just_saw_cr| gets cleared automatically
|
||||
size_t to = i;
|
||||
for ( size_t from = i; from < N; ++from )
|
||||
{
|
||||
// if it's something we need to convert...
|
||||
if ( S[from] == '\r' )
|
||||
{
|
||||
S[to++] = '\n';
|
||||
just_saw_cr = PR_TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
// else, if it's something we need to copy...
|
||||
// i.e., NOT a '\n' immediately following a '\r'
|
||||
if ( S[from] != '\n' || !just_saw_cr )
|
||||
S[to++] = S[from];
|
||||
|
||||
just_saw_cr = PR_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
// if we chopped characters out of the string, we need to shorten it logically
|
||||
if ( to < N )
|
||||
aString.SetLength(to);
|
||||
}
|
||||
|
||||
/**
|
||||
* This big dispatch method is used to route token handler calls to the right place.
|
||||
* What's wrong with it? This table, and the dispatch methods themselves need to be
|
||||
|
@ -765,37 +681,12 @@ nsresult CNavDTD::HandleToken(CToken* aToken,nsIParser* aParser){
|
|||
CHTMLToken* theToken= NS_STATIC_CAST(CHTMLToken*, aToken);
|
||||
eHTMLTokenTypes theType=eHTMLTokenTypes(theToken->GetTokenType());
|
||||
eHTMLTags theTag=(eHTMLTags)theToken->GetTypeID();
|
||||
PRBool execSkipContent=PR_FALSE;
|
||||
|
||||
aToken->SetLineNumber(mLineNumber);
|
||||
|
||||
mLineNumber += aToken->GetNewlineCount();
|
||||
|
||||
/* ---------------------------------------------------------------------------------
|
||||
To understand this little piece of code, you need to look below too.
|
||||
In essence, this code caches "skipped content" until we find a given skiptarget.
|
||||
Once we find the skiptarget, we take all skipped content up to that point and
|
||||
coallate it. Then we push those tokens back onto the tokenizer deque.
|
||||
---------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
// printf("token: %p\n",aToken);
|
||||
|
||||
if(mSkipTarget){ //handle a preexisting target...
|
||||
if((theTag==mSkipTarget) && (eToken_end==theType)){
|
||||
mSkipTarget=eHTMLTag_unknown; //stop skipping.
|
||||
//mTokenizer->PushTokenFront(aToken); //push the end token...
|
||||
execSkipContent=PR_TRUE;
|
||||
IF_FREE(aToken, mTokenAllocator);
|
||||
theToken=(CHTMLToken*)mSkippedContent.PopFront();
|
||||
theType=eToken_start;
|
||||
}
|
||||
else {
|
||||
mSkippedContent.Push(theToken);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
else if(mFlags & NS_DTD_FLAG_MISPLACED_CONTENT) {
|
||||
if(mFlags & NS_DTD_FLAG_MISPLACED_CONTENT) {
|
||||
// Included TD & TH to fix Bug# 20797
|
||||
static eHTMLTags gLegalElements[]={eHTMLTag_table,eHTMLTag_thead,eHTMLTag_tbody,
|
||||
eHTMLTag_tr,eHTMLTag_td,eHTMLTag_th,eHTMLTag_tfoot};
|
||||
|
@ -831,12 +722,6 @@ nsresult CNavDTD::HandleToken(CToken* aToken,nsIParser* aParser){
|
|||
NS_ENSURE_SUCCESS(result, result);
|
||||
|
||||
mBodyContext->mContextTopIndex = -1;
|
||||
|
||||
if (mSkipTarget) {
|
||||
mSkippedContent.Push(theToken);
|
||||
return result;
|
||||
}
|
||||
// Fall through if the skipped content collection is |not| in progress - bug 124788
|
||||
}
|
||||
else {
|
||||
PushIntoMisplacedStack(theToken);
|
||||
|
@ -853,145 +738,135 @@ nsresult CNavDTD::HandleToken(CToken* aToken,nsIParser* aParser){
|
|||
deque until we can deal with it.
|
||||
---------------------------------------------------------------------------------
|
||||
*/
|
||||
if(!execSkipContent) {
|
||||
switch(theTag) {
|
||||
case eHTMLTag_html:
|
||||
case eHTMLTag_noframes:
|
||||
case eHTMLTag_noscript:
|
||||
case eHTMLTag_script:
|
||||
case eHTMLTag_doctypeDecl:
|
||||
case eHTMLTag_instruction:
|
||||
break;
|
||||
|
||||
switch(theTag) {
|
||||
case eHTMLTag_html:
|
||||
case eHTMLTag_noframes:
|
||||
case eHTMLTag_noscript:
|
||||
case eHTMLTag_script:
|
||||
case eHTMLTag_doctypeDecl:
|
||||
case eHTMLTag_instruction:
|
||||
break;
|
||||
default:
|
||||
if(!gHTMLElements[eHTMLTag_html].SectionContains(theTag,PR_FALSE)) {
|
||||
if(!(mFlags & (NS_DTD_FLAG_HAD_BODY |
|
||||
NS_DTD_FLAG_HAD_FRAMESET |
|
||||
NS_DTD_FLAG_ALTERNATE_CONTENT))) {
|
||||
|
||||
//For bug examples from this code, see bugs: 18928, 20989.
|
||||
//At this point we know the body/frameset aren't open.
|
||||
//If the child belongs in the head, then handle it (which may open the head);
|
||||
//otherwise, push it onto the misplaced stack.
|
||||
|
||||
PRBool isExclusive=PR_FALSE;
|
||||
PRBool theChildBelongsInHead=gHTMLElements[eHTMLTag_head].IsChildOfHead(theTag,isExclusive);
|
||||
if(theChildBelongsInHead && !isExclusive) {
|
||||
if (mMisplacedContent.GetSize() == 0) {
|
||||
// This tag can either be in the body or the head. Since
|
||||
// there is no indication that the body should be open,
|
||||
// put this token in the head.
|
||||
break;
|
||||
}
|
||||
|
||||
// Otherwise, we have received some indication that the body is
|
||||
// "open", so push this token onto the misplaced content stack.
|
||||
theChildBelongsInHead = PR_FALSE;
|
||||
}
|
||||
|
||||
if(!theChildBelongsInHead) {
|
||||
eHTMLTags top = mBodyContext->Last();
|
||||
NS_ASSERTION(top != eHTMLTag_userdefined,
|
||||
"Userdefined tags should act as leaves in the head");
|
||||
if (top != eHTMLTag_head &&
|
||||
gHTMLElements[top].CanContain(theTag, mDTDMode)) {
|
||||
// Some tags (such as <object> and <script>) are opened in the
|
||||
// head and allow other non-head content to be children.
|
||||
// Note: Userdefined tags in the head act like leaves.
|
||||
break;
|
||||
}
|
||||
|
||||
//If you're here then we found a child of the body that was out of place.
|
||||
//We're going to move it to the body by storing it temporarily on the misplaced stack.
|
||||
//However, in quirks mode, a few tags request, ambiguosly, for a BODY. - Bugs 18928, 24204.-
|
||||
PushIntoMisplacedStack(aToken);
|
||||
|
||||
if (IsAlternateTag(theTag)) {
|
||||
// These tags' contents are consumed as CDATA. If we simply
|
||||
// pushed them on the misplaced content stack, the CDATA
|
||||
// contents would force us to open a body, which could be
|
||||
// wrong. So we collect the whole tag as misplaced in one
|
||||
// gulp. Note that the tokenizer guarantees that there will
|
||||
// be an end tag.
|
||||
CToken *current = aToken;
|
||||
while (current->GetTokenType() != eToken_end ||
|
||||
current->GetTypeID() != theTag) {
|
||||
current = NS_STATIC_CAST(CToken *, mTokenizer->PopToken());
|
||||
NS_ASSERTION(current, "The tokenizer is not creating good "
|
||||
"alternate tags");
|
||||
PushIntoMisplacedStack(current);
|
||||
}
|
||||
|
||||
// XXX Add code to also collect incorrect attributes on the
|
||||
// end tag.
|
||||
}
|
||||
|
||||
if(DoesRequireBody(aToken,mTokenizer)) {
|
||||
CToken* theBodyToken=NS_STATIC_CAST(CToken*,mTokenAllocator->CreateTokenOfType(eToken_start,eHTMLTag_body,NS_LITERAL_STRING("body")));
|
||||
result=HandleToken(theBodyToken,aParser);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
} //if
|
||||
} //if
|
||||
}//switch
|
||||
|
||||
if(theToken){
|
||||
mParser=(nsParser*)aParser;
|
||||
|
||||
switch(theType) {
|
||||
case eToken_text:
|
||||
case eToken_start:
|
||||
case eToken_whitespace:
|
||||
case eToken_newline:
|
||||
result=HandleStartToken(theToken); break;
|
||||
|
||||
case eToken_end:
|
||||
result=HandleEndToken(theToken); break;
|
||||
|
||||
case eToken_cdatasection:
|
||||
case eToken_comment:
|
||||
case eToken_markupDecl:
|
||||
result=HandleCommentToken(theToken); break;
|
||||
|
||||
case eToken_entity:
|
||||
result=HandleEntityToken(theToken); break;
|
||||
|
||||
case eToken_attribute:
|
||||
result=HandleAttributeToken(theToken); break;
|
||||
|
||||
case eToken_instruction:
|
||||
result=HandleProcessingInstructionToken(theToken); break;
|
||||
|
||||
case eToken_doctypeDecl:
|
||||
result=HandleDocTypeDeclToken(theToken); break;
|
||||
|
||||
default:
|
||||
if(!gHTMLElements[eHTMLTag_html].SectionContains(theTag,PR_FALSE)) {
|
||||
if(!(mFlags & (NS_DTD_FLAG_HAD_BODY |
|
||||
NS_DTD_FLAG_HAD_FRAMESET |
|
||||
NS_DTD_FLAG_ALTERNATE_CONTENT))) {
|
||||
|
||||
//For bug examples from this code, see bugs: 18928, 20989.
|
||||
//At this point we know the body/frameset aren't open.
|
||||
//If the child belongs in the head, then handle it (which may open the head);
|
||||
//otherwise, push it onto the misplaced stack.
|
||||
|
||||
PRBool isExclusive=PR_FALSE;
|
||||
PRBool theChildBelongsInHead=gHTMLElements[eHTMLTag_head].IsChildOfHead(theTag,isExclusive);
|
||||
if(theChildBelongsInHead && !isExclusive) {
|
||||
if (mMisplacedContent.GetSize() == 0) {
|
||||
// This tag can either be in the body or the head. Since
|
||||
// there is no indication that the body should be open,
|
||||
// put this token in the head.
|
||||
break;
|
||||
}
|
||||
|
||||
// Otherwise, we have received some indication that the body is
|
||||
// "open", so push this token onto the misplaced content stack.
|
||||
theChildBelongsInHead = PR_FALSE;
|
||||
}
|
||||
|
||||
if(!theChildBelongsInHead) {
|
||||
|
||||
//If you're here then we found a child of the body that was out of place.
|
||||
//We're going to move it to the body by storing it temporarily on the misplaced stack.
|
||||
//However, in quirks mode, a few tags request, ambiguosly, for a BODY. - Bugs 18928, 24204.-
|
||||
PushIntoMisplacedStack(aToken);
|
||||
|
||||
if (IsAlternateTag(theTag)) {
|
||||
// These tags' contents are consumed as CDATA. If we simply
|
||||
// pushed them on the misplaced content stack, the CDATA
|
||||
// contents would force us to open a body, which could be
|
||||
// wrong. So we collect the whole tag as misplaced in one
|
||||
// gulp. Note that the tokenizer guarantees that there will
|
||||
// be an end tag.
|
||||
CToken *current = aToken;
|
||||
while (current->GetTokenType() != eToken_end ||
|
||||
current->GetTypeID() != theTag) {
|
||||
current = NS_STATIC_CAST(CToken *, mTokenizer->PopToken());
|
||||
NS_ASSERTION(current, "The tokenizer is not creating good "
|
||||
"alternate tags");
|
||||
PushIntoMisplacedStack(current);
|
||||
}
|
||||
|
||||
// XXX Add code to also collect incorrect attributes on the
|
||||
// end tag.
|
||||
}
|
||||
|
||||
if(DoesRequireBody(aToken,mTokenizer)) {
|
||||
CToken* theBodyToken=NS_STATIC_CAST(CToken*,mTokenAllocator->CreateTokenOfType(eToken_start,eHTMLTag_body,NS_LITERAL_STRING("body")));
|
||||
result=HandleToken(theBodyToken,aParser);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
} //if
|
||||
} //if
|
||||
break;
|
||||
}//switch
|
||||
|
||||
} //if
|
||||
|
||||
if(theToken){
|
||||
//Before dealing with the token normally, we need to deal with skip targets
|
||||
CStartToken* theStartToken=NS_STATIC_CAST(CStartToken*,aToken);
|
||||
if((!execSkipContent) &&
|
||||
(theType!=eToken_end) &&
|
||||
(eHTMLTag_unknown==mSkipTarget) &&
|
||||
(gHTMLElements[theTag].mSkipTarget) &&
|
||||
(!theStartToken->IsEmpty())) { // added empty token check for bug 44186
|
||||
//create a new target
|
||||
NS_ASSERTION(mSkippedContent.GetSize() == 0, "all the skipped content tokens did not get handled");
|
||||
mSkippedContent.Empty();
|
||||
mSkipTarget=gHTMLElements[theTag].mSkipTarget;
|
||||
mSkippedContent.Push(theToken);
|
||||
|
||||
if(NS_SUCCEEDED(result) || (NS_ERROR_HTMLPARSER_BLOCK==result)) {
|
||||
IF_FREE(theToken, mTokenAllocator);
|
||||
}
|
||||
else if(result==NS_ERROR_HTMLPARSER_STOPPARSING) {
|
||||
mFlags |= NS_DTD_FLAG_STOP_PARSING;
|
||||
}
|
||||
else {
|
||||
|
||||
mParser=(nsParser*)aParser;
|
||||
|
||||
switch(theType) {
|
||||
case eToken_text:
|
||||
case eToken_start:
|
||||
case eToken_whitespace:
|
||||
case eToken_newline:
|
||||
result=HandleStartToken(theToken); break;
|
||||
|
||||
case eToken_end:
|
||||
result=HandleEndToken(theToken); break;
|
||||
|
||||
case eToken_cdatasection:
|
||||
case eToken_comment:
|
||||
case eToken_markupDecl:
|
||||
result=HandleCommentToken(theToken); break;
|
||||
|
||||
case eToken_entity:
|
||||
result=HandleEntityToken(theToken); break;
|
||||
|
||||
case eToken_attribute:
|
||||
result=HandleAttributeToken(theToken); break;
|
||||
|
||||
case eToken_instruction:
|
||||
result=HandleProcessingInstructionToken(theToken); break;
|
||||
|
||||
case eToken_doctypeDecl:
|
||||
result=HandleDocTypeDeclToken(theToken); break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}//switch
|
||||
|
||||
|
||||
if(NS_SUCCEEDED(result) || (NS_ERROR_HTMLPARSER_BLOCK==result)) {
|
||||
IF_FREE(theToken, mTokenAllocator);
|
||||
}
|
||||
else if(result==NS_ERROR_HTMLPARSER_STOPPARSING) {
|
||||
mFlags |= NS_DTD_FLAG_STOP_PARSING;
|
||||
}
|
||||
else {
|
||||
return NS_OK;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}//if
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -1357,22 +1232,6 @@ nsresult CNavDTD::WillHandleStartTag(CToken* aToken,eHTMLTags aTag,nsIParserNode
|
|||
MOZ_TIMER_DEBUGLOG(("Start: Parse Time: CNavDTD::WillHandleStartTag(), this=%p\n", this));
|
||||
START_TIMER()
|
||||
|
||||
if(NS_SUCCEEDED(result)) {
|
||||
// This code is here to make sure the head is closed before we deal
|
||||
// with any tags that don't belong in the head. If the tag is not exclusive
|
||||
// then we do not have enough information, and we have to trust the logic
|
||||
// in HandleToken() to not hand us non-exclusive tokens
|
||||
PRBool isExclusive = PR_FALSE;
|
||||
PRBool isChildOfHead =
|
||||
gHTMLElements[eHTMLTag_head].IsChildOfHead(aTag, isExclusive);
|
||||
|
||||
if (NS_SUCCEEDED(result) && ((mFlags & NS_DTD_FLAG_HAS_OPEN_HEAD) &&
|
||||
isExclusive &&
|
||||
!isChildOfHead)) {
|
||||
result = CloseHead();
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -1439,17 +1298,6 @@ nsresult CNavDTD::HandleOmittedTag(CToken* aToken,eHTMLTags aChildTag,eHTMLTags
|
|||
// If the token is attributed then save those attributes too.
|
||||
if(attrCount > 0) PushMisplacedAttributes(*aNode,mMisplacedContent,attrCount);
|
||||
|
||||
if(gHTMLElements[aChildTag].mSkipTarget) {
|
||||
nsAutoString theString;
|
||||
PRInt32 lineNo = 0;
|
||||
|
||||
result = CollectSkippedContent(aChildTag, theString, lineNo);
|
||||
NS_ENSURE_SUCCESS(result, result);
|
||||
|
||||
PushIntoMisplacedStack(mTokenAllocator->CreateTokenOfType(eToken_text,eHTMLTag_text,theString));
|
||||
PushIntoMisplacedStack(mTokenAllocator->CreateTokenOfType(eToken_end,aChildTag));
|
||||
}
|
||||
|
||||
mFlags |= NS_DTD_FLAG_MISPLACED_CONTENT; // This state would help us in gathering all the misplaced elements
|
||||
}//if
|
||||
}//if
|
||||
|
@ -1597,6 +1445,8 @@ nsresult CNavDTD::HandleStartToken(CToken* aToken) {
|
|||
}
|
||||
break;
|
||||
case eHTMLTag_head:
|
||||
mFlags |= NS_DTD_FLAG_HAS_EXPLICIT_HEAD;
|
||||
|
||||
if(mFlags & (NS_DTD_FLAG_HAD_BODY | NS_DTD_FLAG_HAD_FRAMESET)) {
|
||||
result=HandleOmittedTag(aToken,theChildTag,theParent,theNode);
|
||||
isTokenHandled=PR_TRUE;
|
||||
|
@ -1610,7 +1460,7 @@ nsresult CNavDTD::HandleStartToken(CToken* aToken) {
|
|||
PRBool isExclusive=PR_FALSE;
|
||||
theHeadIsParent=nsHTMLElement::IsChildOfHead(theChildTag,isExclusive);
|
||||
|
||||
switch(theChildTag) {
|
||||
switch(theChildTag) {
|
||||
case eHTMLTag_area:
|
||||
if(!mOpenMapCount) isTokenHandled=PR_TRUE;
|
||||
|
||||
|
@ -1640,10 +1490,9 @@ nsresult CNavDTD::HandleStartToken(CToken* aToken) {
|
|||
// as such to make sure that we don't pull scripts outside the head
|
||||
// into the body.
|
||||
isExclusive = !(mFlags & NS_DTD_FLAG_HAD_BODY);
|
||||
mFlags |= NS_DTD_FLAG_HAS_OPEN_SCRIPT;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
default:;
|
||||
}//switch
|
||||
|
||||
if(!isTokenHandled) {
|
||||
|
@ -1657,12 +1506,12 @@ nsresult CNavDTD::HandleStartToken(CToken* aToken) {
|
|||
theHeadIsParent = theHeadIsParent &&
|
||||
(isExclusive ||
|
||||
(prefersBody
|
||||
? (mFlags & NS_DTD_FLAG_HAS_OPEN_HEAD)
|
||||
? (mFlags & NS_DTD_FLAG_HAS_EXPLICIT_HEAD)
|
||||
: !(mFlags & NS_DTD_FLAG_HAD_BODY)));
|
||||
|
||||
if(theHeadIsParent) {
|
||||
// These tokens prefer to be in the head.
|
||||
result = AddHeadLeaf(theNode);
|
||||
result = AddHeadContent(theNode);
|
||||
}
|
||||
else {
|
||||
result = HandleDefaultStartToken(aToken,theChildTag,theNode);
|
||||
|
@ -1842,13 +1691,8 @@ nsresult CNavDTD::HandleEndToken(CToken* aToken) {
|
|||
CollectAttributes(nsnull,theChildTag,attrCount);
|
||||
|
||||
switch(theChildTag) {
|
||||
|
||||
case eHTMLTag_script:
|
||||
mFlags &= ~NS_DTD_FLAG_HAS_OPEN_SCRIPT;
|
||||
case eHTMLTag_style:
|
||||
case eHTMLTag_link:
|
||||
case eHTMLTag_meta:
|
||||
case eHTMLTag_title:
|
||||
break;
|
||||
|
||||
case eHTMLTag_head:
|
||||
|
@ -1877,6 +1721,23 @@ nsresult CNavDTD::HandleEndToken(CToken* aToken) {
|
|||
StripWSFollowingTag(theChildTag,mTokenizer,mTokenAllocator,mLineNumber);
|
||||
break;
|
||||
|
||||
case eHTMLTag_script:
|
||||
// Note: we don't fall through to the default case because
|
||||
// CloseContainersTo() has the bad habit of closing tags that are opened
|
||||
// by document.write(). Fortunately, the tokenizer guarantees that no
|
||||
// actual tags appear between <script> and </script> so we won't be
|
||||
// closing the wrong tag.
|
||||
if (mBodyContext->Last() != eHTMLTag_script) {
|
||||
// Except if we're here, then there's probably a stray script tag.
|
||||
NS_ASSERTION(mBodyContext->LastOf(eHTMLTag_script) == kNotFound,
|
||||
"Mishandling scripts in CNavDTD");
|
||||
break;
|
||||
}
|
||||
|
||||
mBodyContext->Pop();
|
||||
result = CloseContainer(eHTMLTag_script, theChildTag, PR_FALSE);
|
||||
break;
|
||||
|
||||
default:
|
||||
{
|
||||
//now check to see if this token should be omitted, or
|
||||
|
@ -2012,7 +1873,7 @@ nsresult CNavDTD::HandleSavedTokens(PRInt32 anIndex) {
|
|||
theToken=(CToken*)mMisplacedContent.PopFront();
|
||||
if(theToken) {
|
||||
theTag = (eHTMLTags)theToken->GetTypeID();
|
||||
attrCount = (gHTMLElements[theTag].mSkipTarget)? 0:theToken->GetAttributeCount();
|
||||
attrCount = theToken->GetAttributeCount();
|
||||
// Put back attributes, which once got popped out, into the tokenizer
|
||||
for(PRInt32 j=0;j<attrCount; ++j){
|
||||
CToken* theAttrToken = (CToken*)mMisplacedContent.PopFront();
|
||||
|
@ -2156,31 +2017,6 @@ nsresult CNavDTD::HandleAttributeToken(CToken* aToken) {
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method gets called when a script token has been
|
||||
* encountered in the parse process. n
|
||||
*
|
||||
* @update gess 3/25/98
|
||||
* @param aToken -- next (start) token to be handled
|
||||
* @return PR_TRUE if all went well; PR_FALSE if error occured
|
||||
*/
|
||||
nsresult CNavDTD::HandleScriptToken(const nsIParserNode *aNode) {
|
||||
// PRInt32 attrCount=aNode.GetAttributeCount(PR_TRUE);
|
||||
|
||||
STOP_TIMER();
|
||||
MOZ_TIMER_DEBUGLOG(("Stop: Parse Time: CNavDTD::HandleScriptToken(), this=%p\n", this));
|
||||
|
||||
nsresult result=AddLeaf(aNode);
|
||||
|
||||
mParser->SetCanInterrupt(PR_FALSE);
|
||||
|
||||
MOZ_TIMER_DEBUGLOG(("Start: Parse Time: CNavDTD::HandleScriptToken(), this=%p\n", this));
|
||||
START_TIMER();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This method gets called when an "instruction" token has been
|
||||
* encountered in the parse process.
|
||||
|
@ -2266,15 +2102,11 @@ nsresult CNavDTD::CollectAttributes(nsIParserNode *aNode,eHTMLTags aTag,PRInt32
|
|||
int attr=0;
|
||||
|
||||
nsresult result=NS_OK;
|
||||
int theAvailTokenCount=mTokenizer->GetCount() + mSkippedContent.GetSize();
|
||||
int theAvailTokenCount=mTokenizer->GetCount();
|
||||
if(aCount<=theAvailTokenCount) {
|
||||
CToken* theToken=0;
|
||||
eHTMLTags theSkipTarget=gHTMLElements[aTag].mSkipTarget;
|
||||
for(attr=0;attr<aCount;++attr){
|
||||
if((eHTMLTag_unknown!=theSkipTarget) && mSkippedContent.GetSize())
|
||||
theToken=NS_STATIC_CAST(CToken*,mSkippedContent.PopFront());
|
||||
else
|
||||
theToken=mTokenizer->PopToken();
|
||||
theToken=mTokenizer->PopToken();
|
||||
if(theToken) {
|
||||
eHTMLTokenTypes theType=eHTMLTokenTypes(theToken->GetTokenType());
|
||||
if(theType!=eToken_attribute) {
|
||||
|
@ -2313,55 +2145,6 @@ nsresult CNavDTD::CollectAttributes(nsIParserNode *aNode,eHTMLTags aTag,PRInt32
|
|||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Causes the next skipped-content token (if any) to
|
||||
* be consumed by this node.
|
||||
*
|
||||
* @update gess 4Sep2000
|
||||
* @param node to consume skipped-content
|
||||
* @param holds the number of skipped content elements encountered
|
||||
* @return Error condition.
|
||||
*/
|
||||
NS_IMETHODIMP
|
||||
CNavDTD::CollectSkippedContent(PRInt32 aTag, nsAString& aContent, PRInt32 &aLineNo) {
|
||||
|
||||
NS_ASSERTION(aTag >= eHTMLTag_unknown && aTag <= NS_HTML_TAG_MAX, "tag array out of bounds");
|
||||
|
||||
aContent.Truncate();
|
||||
|
||||
NS_ASSERTION(eHTMLTag_unknown != gHTMLElements[aTag].mSkipTarget, "cannot collect content for this tag");
|
||||
if (eHTMLTag_unknown == gHTMLElements[aTag].mSkipTarget) {
|
||||
// This tag doesn't support skipped content.
|
||||
aLineNo = -1;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
aLineNo = mLineNumber;
|
||||
mScratch.Truncate();
|
||||
PRInt32 i = 0;
|
||||
PRInt32 tagCount = mSkippedContent.GetSize();
|
||||
for (i = 0; i< tagCount; ++i){
|
||||
CHTMLToken* theNextToken = (CHTMLToken*)mSkippedContent.PopFront();
|
||||
if (theNextToken) {
|
||||
theNextToken->AppendSourceTo(aContent);
|
||||
}
|
||||
|
||||
IF_FREE(theNextToken, mTokenAllocator);
|
||||
}
|
||||
|
||||
InPlaceConvertLineEndings(aContent);
|
||||
|
||||
// Note: TITLE content is PCDATA and hence the newlines are already accounted for.
|
||||
mLineNumber += (aTag != eHTMLTag_title) ? aContent.CountChar(kNewLine) : 0;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/***********************************************************************************
|
||||
The preceeding tables determine the set of elements each tag can contain...
|
||||
***********************************************************************************/
|
||||
|
||||
/**
|
||||
* This method is called to determine whether or not a tag
|
||||
* of one type can contain a tag of another type.
|
||||
|
@ -2908,7 +2691,12 @@ nsresult CNavDTD::OpenHead(const nsIParserNode *aNode)
|
|||
|
||||
if (!(mFlags & NS_DTD_FLAG_HAS_OPEN_HEAD)) {
|
||||
mFlags |= NS_DTD_FLAG_HAS_OPEN_HEAD;
|
||||
result = mSink ? mSink->OpenHead(*aNode) : NS_OK;
|
||||
if (mSink && aNode) {
|
||||
result = mSink->OpenHead(*aNode);
|
||||
}
|
||||
else if (mSink) {
|
||||
result = mSink->OpenHead();
|
||||
}
|
||||
}
|
||||
|
||||
MOZ_TIMER_DEBUGLOG(("Start: Parse Time: CNavDTD::OpenHead(), this=%p\n", this));
|
||||
|
@ -2965,6 +2753,10 @@ nsresult CNavDTD::OpenBody(const nsCParserNode *aNode)
|
|||
STOP_TIMER();
|
||||
MOZ_TIMER_DEBUGLOG(("Stop: Parse Time: CNavDTD::OpenBody(), this=%p\n", this));
|
||||
|
||||
// Make sure the head is closed by the time the body is opened.
|
||||
CloseHead();
|
||||
|
||||
// Now we can open the body.
|
||||
result = (mSink) ? mSink->OpenBody(*aNode) : NS_OK;
|
||||
|
||||
MOZ_TIMER_DEBUGLOG(("Start: Parse Time: CNavDTD::OpenBody(), this=%p\n", this));
|
||||
|
@ -3205,10 +2997,6 @@ CNavDTD::OpenContainer(const nsCParserNode *aNode,
|
|||
}
|
||||
break;
|
||||
|
||||
case eHTMLTag_style:
|
||||
case eHTMLTag_title:
|
||||
break;
|
||||
|
||||
case eHTMLTag_map:
|
||||
result = OpenMap(aNode);
|
||||
break;
|
||||
|
@ -3221,10 +3009,6 @@ CNavDTD::OpenContainer(const nsCParserNode *aNode,
|
|||
result = OpenFrameset(aNode);
|
||||
break;
|
||||
|
||||
case eHTMLTag_script:
|
||||
result = HandleScriptToken(aNode);
|
||||
break;
|
||||
|
||||
case eHTMLTag_noembed:
|
||||
// <noembed> is unconditionally alternate content.
|
||||
done = PR_FALSE;
|
||||
|
@ -3292,9 +3076,6 @@ CNavDTD::CloseContainer(const eHTMLTags aTag, eHTMLTags aTarget,PRBool aClosedBy
|
|||
case eHTMLTag_html:
|
||||
result=CloseHTML(); break;
|
||||
|
||||
case eHTMLTag_style:
|
||||
break;
|
||||
|
||||
case eHTMLTag_head:
|
||||
result=CloseHead();
|
||||
break;
|
||||
|
@ -3322,12 +3103,22 @@ CNavDTD::CloseContainer(const eHTMLTags aTag, eHTMLTags aTarget,PRBool aClosedBy
|
|||
// switch from alternate content state to regular state
|
||||
mFlags &= ~NS_DTD_FLAG_ALTERNATE_CONTENT;
|
||||
// falling thro' intentionally....
|
||||
case eHTMLTag_title:
|
||||
default:
|
||||
STOP_TIMER();
|
||||
MOZ_TIMER_DEBUGLOG(("Stop: Parse Time: CNavDTD::CloseContainer(), this=%p\n", this));
|
||||
|
||||
result=(mSink) ? mSink->CloseContainer(aTag) : NS_OK;
|
||||
result = mSink
|
||||
? mSink->CloseContainer(aTag)
|
||||
: NS_OK; // XXX Can this case really happen?
|
||||
|
||||
// If we were dealing with a head container in the body, make sure to
|
||||
// close the head context now, so that body content doesn't get sucked
|
||||
// into the head.
|
||||
if ((mFlags & NS_DTD_FLAG_HAD_BODY) &&
|
||||
mBodyContext->GetCount() == mHeadContainerPosition) {
|
||||
result = CloseHead();
|
||||
mHeadContainerPosition = -1;
|
||||
}
|
||||
|
||||
MOZ_TIMER_DEBUGLOG(("Start: Parse Time: CNavDTD::CloseContainer(), this=%p\n", this));
|
||||
START_TIMER();
|
||||
|
@ -3586,7 +3377,7 @@ nsresult CNavDTD::AddLeaf(const nsIParserNode *aNode){
|
|||
* @param aNode -- next node to be added to model
|
||||
* @return error code; 0 means OK
|
||||
*/
|
||||
nsresult CNavDTD::AddHeadLeaf(nsIParserNode *aNode){
|
||||
nsresult CNavDTD::AddHeadContent(nsIParserNode *aNode){
|
||||
nsresult result=NS_OK;
|
||||
|
||||
static eHTMLTags gNoXTags[] = {eHTMLTag_noembed,eHTMLTag_noframes};
|
||||
|
@ -3604,11 +3395,35 @@ nsresult CNavDTD::AddHeadLeaf(nsIParserNode *aNode){
|
|||
|
||||
if (mSink) {
|
||||
STOP_TIMER();
|
||||
MOZ_TIMER_DEBUGLOG(("Stop: Parse Time: CNavDTD::AddHeadLeaf(), this=%p\n", this));
|
||||
|
||||
result = mSink->AddHeadContent(*aNode);
|
||||
|
||||
MOZ_TIMER_DEBUGLOG(("Start: Parse Time: CNavDTD::AddHeadLeaf(), this=%p\n", this));
|
||||
MOZ_TIMER_DEBUGLOG(("Stop: Parse Time: CNavDTD::AddHeadContent(), this=%p\n", this));
|
||||
|
||||
// Make sure the head is opened. This might just be a no-op.
|
||||
result = OpenHead(nsnull);
|
||||
|
||||
// Note: userdefined tags in the head are treated as leaves.
|
||||
if (!nsHTMLElement::IsContainer(theTag) || theTag == eHTMLTag_userdefined) {
|
||||
result = mSink->AddLeaf(*aNode);
|
||||
|
||||
if (mFlags & NS_DTD_FLAG_HAD_BODY) {
|
||||
// Close the head now so that body content doesn't get sucked into it.
|
||||
CloseHead();
|
||||
}
|
||||
}
|
||||
else {
|
||||
if ((mFlags & NS_DTD_FLAG_HAD_BODY) && mHeadContainerPosition == -1) {
|
||||
// Keep track of this so that we know when to close the head, when
|
||||
// this tag is done with.
|
||||
mHeadContainerPosition = mBodyContext->GetCount();
|
||||
}
|
||||
|
||||
mBodyContext->Push(NS_STATIC_CAST(nsCParserNode*, aNode), nsnull,
|
||||
PR_FALSE);
|
||||
|
||||
// Note: The head context is already opened.
|
||||
result = mSink->OpenContainer(*aNode);
|
||||
}
|
||||
|
||||
MOZ_TIMER_DEBUGLOG(("Start: Parse Time: CNavDTD::AddHeadContent(), this=%p\n", this));
|
||||
START_TIMER();
|
||||
}
|
||||
return result;
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* vim: set sw=2 ts=2 et tw=78: */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
|
@ -271,7 +272,6 @@ public:
|
|||
nsresult HandleEntityToken(CToken* aToken);
|
||||
nsresult HandleCommentToken(CToken* aToken);
|
||||
nsresult HandleAttributeToken(CToken* aToken);
|
||||
nsresult HandleScriptToken(const nsIParserNode *aNode);
|
||||
nsresult HandleProcessingInstructionToken(CToken* aToken);
|
||||
nsresult HandleDocTypeDeclToken(CToken* aToken);
|
||||
nsresult BuildNeglectedTarget(eHTMLTags aTarget, eHTMLTokenTypes aType,
|
||||
|
@ -337,7 +337,7 @@ public:
|
|||
* @return error code - 0 if all went well.
|
||||
*/
|
||||
nsresult AddLeaf(const nsIParserNode *aNode);
|
||||
nsresult AddHeadLeaf(nsIParserNode *aNode);
|
||||
nsresult AddHeadContent(nsIParserNode *aNode);
|
||||
|
||||
/**
|
||||
* This set of methods is used to create and manage the set of
|
||||
|
@ -365,7 +365,6 @@ public:
|
|||
protected:
|
||||
|
||||
nsresult CollectAttributes(nsIParserNode* aNode,eHTMLTags aTag,PRInt32 aCount);
|
||||
nsresult CollectSkippedContent(nsIParserNode& aNode,PRInt32& aCount);
|
||||
nsresult WillHandleStartTag(CToken* aToken,eHTMLTags aChildTag,nsIParserNode& aNode);
|
||||
nsresult DidHandleStartTag(nsIParserNode& aNode,eHTMLTags aChildTag);
|
||||
nsresult HandleOmittedTag(CToken* aToken,eHTMLTags aChildTag,eHTMLTags aParent,nsIParserNode *aNode);
|
||||
|
@ -376,7 +375,6 @@ protected:
|
|||
PRBool IsInlineElement(PRInt32 aTagID, PRInt32 aParentID) const;
|
||||
|
||||
nsDeque mMisplacedContent;
|
||||
nsDeque mSkippedContent;
|
||||
|
||||
nsIHTMLContentSink* mSink;
|
||||
nsTokenAllocator* mTokenAllocator;
|
||||
|
@ -394,9 +392,9 @@ protected:
|
|||
eParserDocType mDocType;
|
||||
eParserCommands mParserCommand; //tells us to viewcontent/viewsource/viewerrors...
|
||||
|
||||
eHTMLTags mSkipTarget;
|
||||
PRInt32 mLineNumber;
|
||||
PRInt32 mOpenMapCount;
|
||||
PRInt32 mHeadContainerPosition;
|
||||
|
||||
PRUint16 mFlags;
|
||||
};
|
||||
|
|
|
@ -291,6 +291,9 @@ nsCParserNode* nsEntryStack::Pop(void)
|
|||
|
||||
// XXX If this NS_ENSURE_TRUE fails, it means that the style stack was
|
||||
// empty before we were removed.
|
||||
#ifdef DEBUG_mrbkap
|
||||
NS_ASSERTION(scount != 0, "preventing a potential crash.");
|
||||
#endif
|
||||
NS_ENSURE_TRUE(scount != 0, result);
|
||||
|
||||
PRUint32 sindex = 0;
|
||||
|
|
|
@ -194,12 +194,6 @@ const nsHTMLElement gHTMLElements[] = {
|
|||
/*contain-func*/ 0
|
||||
},
|
||||
{
|
||||
/*************************************************
|
||||
Note: I changed A to contain flow elements
|
||||
since it's such a popular (but illegal)
|
||||
idiom.
|
||||
*************************************************/
|
||||
|
||||
/*tag*/ eHTMLTag_a,
|
||||
/*req-parent excl-parent*/ eHTMLTag_unknown,eHTMLTag_unknown,
|
||||
/*rootnodes,endrootnodes*/ &gRootTags,&gRootTags,
|
||||
|
@ -905,7 +899,7 @@ const nsHTMLElement gHTMLElements[] = {
|
|||
/*req-parent excl-parent*/ eHTMLTag_unknown,eHTMLTag_unknown,
|
||||
/*rootnodes,endrootnodes*/ &gRootTags,&gRootTags,
|
||||
/*autoclose starttags and endtags*/ 0,0,0,0,
|
||||
/*parent,incl,exclgroups*/ kSpecial, (kFlowEntity|kInlineEntity|kSelf), kNone, // XXX should have a kHeadMisc parent too
|
||||
/*parent,incl,exclgroups*/ kSpecial|kHeadMisc, (kFlowEntity|kSelf), kNone,
|
||||
/*special props, prop-range*/ kNoStyleLeaksOut,kDefaultPropRange,
|
||||
/*special parents,kids,skip*/ 0,&gContainsParam,eHTMLTag_unknown,
|
||||
/*contain-func*/ 0
|
||||
|
@ -1017,7 +1011,7 @@ const nsHTMLElement gHTMLElements[] = {
|
|||
/*autoclose starttags and endtags*/ 0,0,0,0,
|
||||
/*parent,incl,exclgroups*/ (kSpecial|kHeadContent), kCDATA, kNone, // note: this is kHeadContent since shipping this breaks things.
|
||||
/*special props, prop-range*/ kNoStyleLeaksIn|kLegalOpen, kNoPropRange,
|
||||
/*special parents,kids,skip*/ 0,&gContainsText,eHTMLTag_script,
|
||||
/*special parents,kids,skip*/ 0,&gContainsText,eHTMLTag_unknown,
|
||||
/*contain-func*/ 0
|
||||
},
|
||||
{
|
||||
|
@ -1037,7 +1031,7 @@ const nsHTMLElement gHTMLElements[] = {
|
|||
/*autoclose starttags and endtags*/ 0,0,0,0,
|
||||
/*parent,incl,exclgroups*/ (kSpecial|kHeadMisc), kCDATA, kNone,
|
||||
/*special props, prop-range*/ (kNoStyleLeaksIn|kLegalOpen), kNoPropRange,
|
||||
/*special parents,kids,skip*/ 0,&gContainsText,eHTMLTag_server,
|
||||
/*special parents,kids,skip*/ 0,&gContainsText,eHTMLTag_unknown,
|
||||
/*contain-func*/ 0
|
||||
},
|
||||
{
|
||||
|
@ -1115,8 +1109,8 @@ const nsHTMLElement gHTMLElements[] = {
|
|||
/*rootnodes,endrootnodes*/ &gInHead,&gInHead,
|
||||
/*autoclose starttags and endtags*/ 0,0,0,0,
|
||||
/*parent,incl,exclgroups*/ kHeadContent, kCDATA, kNone,
|
||||
/*special props, prop-range*/ kNoStyleLeaksIn|kNonContainer, kNoPropRange,
|
||||
/*special parents,kids,skip*/ &gInHead,0,eHTMLTag_style,
|
||||
/*special props, prop-range*/ kNoStyleLeaksIn, kNoPropRange,
|
||||
/*special parents,kids,skip*/ &gInHead,0,eHTMLTag_unknown,
|
||||
/*contain-func*/ 0
|
||||
},
|
||||
{
|
||||
|
@ -1217,7 +1211,7 @@ const nsHTMLElement gHTMLElements[] = {
|
|||
/*autoclose starttags and endtags*/ 0,0,0,0,
|
||||
/*parent,incl,exclgroups*/ kHeadContent,kPCDATA, kNone,
|
||||
/*special props, prop-range*/ kNoStyleLeaksIn, kNoPropRange,
|
||||
/*special parents,kids,skip*/ &gInHead,&gContainsText,eHTMLTag_title,
|
||||
/*special parents,kids,skip*/ &gInHead,&gContainsText,eHTMLTag_unknown,
|
||||
/*contain-func*/ 0
|
||||
},
|
||||
{
|
||||
|
|
|
@ -1155,13 +1155,6 @@ nsExpatDriver::GetType()
|
|||
|
||||
/*************************** Unused methods **********************************/
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsExpatDriver::CollectSkippedContent(PRInt32 aTag, nsAString& aContent,
|
||||
PRInt32 &aLineNo)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP_(CToken*)
|
||||
nsExpatDriver::PushTokenFront(CToken* aToken)
|
||||
{
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set sw=2 ts=2 et tw=78: */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
|
@ -47,16 +48,6 @@ static NS_DEFINE_IID(kIHTMLContentSinkIID, NS_IHTML_CONTENT_SINK_IID);
|
|||
static NS_DEFINE_IID(kILoggingSinkIID, NS_ILOGGING_SINK_IID);
|
||||
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
|
||||
|
||||
// list of tags that have skipped content
|
||||
static const char gSkippedContentTags[] = {
|
||||
eHTMLTag_style,
|
||||
eHTMLTag_script,
|
||||
eHTMLTag_server,
|
||||
eHTMLTag_title,
|
||||
0
|
||||
};
|
||||
|
||||
|
||||
nsresult
|
||||
NS_NewHTMLLoggingSink(nsIContentSink** aInstancePtrResult)
|
||||
{
|
||||
|
@ -73,7 +64,7 @@ NS_NewHTMLLoggingSink(nsIContentSink** aInstancePtrResult)
|
|||
|
||||
nsLoggingSink::nsLoggingSink() {
|
||||
mOutput = 0;
|
||||
mLevel=-1;
|
||||
mLevel=-1;
|
||||
mSink=0;
|
||||
mParser=0;
|
||||
}
|
||||
|
@ -244,36 +235,6 @@ nsLoggingSink::CloseContainer(const nsHTMLTag aTag) {
|
|||
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsLoggingSink::AddHeadContent(const nsIParserNode& aNode) {
|
||||
eHTMLTags type = (eHTMLTags)aNode.GetNodeType();
|
||||
|
||||
if (type == eHTMLTag_title) {
|
||||
nsCOMPtr<nsIDTD> dtd;
|
||||
mParser->GetDTD(getter_AddRefs(dtd));
|
||||
NS_ENSURE_TRUE(dtd, NS_ERROR_FAILURE);
|
||||
|
||||
nsString theString;
|
||||
PRInt32 lineNo = 0;
|
||||
|
||||
dtd->CollectSkippedContent(type, theString, lineNo);
|
||||
SetTitle(theString);
|
||||
}
|
||||
else {
|
||||
LeafNode(aNode);
|
||||
}
|
||||
|
||||
nsresult theResult=NS_OK;
|
||||
|
||||
//then proxy the call to the real sink if you have one.
|
||||
if(mSink) {
|
||||
theResult=mSink->AddHeadContent(aNode);
|
||||
}
|
||||
|
||||
return theResult;
|
||||
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsLoggingSink::AddLeaf(const nsIParserNode& aNode) {
|
||||
LeafNode(aNode);
|
||||
|
@ -365,31 +326,6 @@ nsLoggingSink::AddComment(const nsIParserNode& aNode){
|
|||
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsLoggingSink::SetTitle(const nsString& aValue) {
|
||||
|
||||
char* tmp = nsnull;
|
||||
GetNewCString(aValue, &tmp);
|
||||
WriteTabs(mOutput,++mLevel);
|
||||
if(tmp) {
|
||||
PR_fprintf(mOutput, "<title value=\"%s\"/>\n", tmp);
|
||||
nsMemory::Free(tmp);
|
||||
}
|
||||
--mLevel;
|
||||
|
||||
nsresult theResult=NS_OK;
|
||||
|
||||
//then proxy the call to the real sink if you have one.
|
||||
if(mSink) {
|
||||
theResult=mSink->SetTitle(aValue);
|
||||
}
|
||||
|
||||
return theResult;
|
||||
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsLoggingSink::OpenHTML(const nsIParserNode& aNode) {
|
||||
OpenNode("html", aNode);
|
||||
|
@ -434,6 +370,21 @@ nsLoggingSink::OpenHead(const nsIParserNode& aNode) {
|
|||
return theResult;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsLoggingSink::OpenHead() {
|
||||
WriteTabs(mOutput,++mLevel);
|
||||
PR_fprintf(mOutput,"<open container=head>\n");
|
||||
|
||||
nsresult theResult=NS_OK;
|
||||
|
||||
//then proxy the call to the real sink if you have one.
|
||||
if(mSink) {
|
||||
theResult=mSink->OpenHead();
|
||||
}
|
||||
|
||||
return theResult;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsLoggingSink::CloseHead() {
|
||||
CloseNode("head");
|
||||
|
@ -645,23 +596,6 @@ nsLoggingSink::WriteAttributes(const nsIParserNode& aNode) {
|
|||
}
|
||||
}
|
||||
|
||||
if (0 != strchr(gSkippedContentTags, aNode.GetNodeType())) {
|
||||
nsCOMPtr<nsIDTD> dtd;
|
||||
mParser->GetDTD(getter_AddRefs(dtd));
|
||||
NS_ENSURE_TRUE(dtd, NS_ERROR_FAILURE);
|
||||
|
||||
nsString theString;
|
||||
PRInt32 lineNo = 0;
|
||||
|
||||
dtd->CollectSkippedContent(aNode.GetNodeType(), theString, lineNo);
|
||||
char* content = nsnull;
|
||||
GetNewCString(theString, &content);
|
||||
if(content) {
|
||||
PR_fprintf(mOutput, " <content value=\"");
|
||||
PR_fprintf(mOutput, "%s\"/>\n", content) ;
|
||||
nsMemory::Free(content);
|
||||
}
|
||||
}
|
||||
WriteTabs(mOutput,1+mLevel);
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -673,43 +607,31 @@ nsLoggingSink::WillWriteAttributes(const nsIParserNode& aNode)
|
|||
if (0 != ac) {
|
||||
return PR_TRUE;
|
||||
}
|
||||
if (0 != strchr(gSkippedContentTags, aNode.GetNodeType())) {
|
||||
nsCOMPtr<nsIDTD> dtd;
|
||||
mParser->GetDTD(getter_AddRefs(dtd));
|
||||
NS_ENSURE_TRUE(dtd, NS_ERROR_FAILURE);
|
||||
|
||||
nsString content;
|
||||
PRInt32 lineNo = 0;
|
||||
|
||||
dtd->CollectSkippedContent(aNode.GetNodeType(), content, lineNo);
|
||||
if (!content.IsEmpty()) {
|
||||
return PR_TRUE;
|
||||
}
|
||||
}
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsLoggingSink::LeafNode(const nsIParserNode& aNode)
|
||||
{
|
||||
WriteTabs(mOutput,1+mLevel);
|
||||
nsHTMLTag nodeType = nsHTMLTag(aNode.GetNodeType());
|
||||
WriteTabs(mOutput,1+mLevel);
|
||||
nsHTMLTag nodeType = nsHTMLTag(aNode.GetNodeType());
|
||||
|
||||
if ((nodeType >= eHTMLTag_unknown) &&
|
||||
(nodeType <= nsHTMLTag(NS_HTML_TAG_MAX))) {
|
||||
const PRUnichar* tag = nsHTMLTags::GetStringValue(nodeType);
|
||||
|
||||
if(tag)
|
||||
if(tag)
|
||||
PR_fprintf(mOutput, "<leaf tag=\"%s\"", NS_ConvertUCS2toUTF8(tag).get());
|
||||
else PR_fprintf(mOutput, "<leaf tag=\"???\"");
|
||||
else
|
||||
PR_fprintf(mOutput, "<leaf tag=\"???\"");
|
||||
|
||||
if (WillWriteAttributes(aNode)) {
|
||||
PR_fprintf(mOutput, ">\n");
|
||||
PR_fprintf(mOutput, ">\n");
|
||||
WriteAttributes(aNode);
|
||||
PR_fprintf(mOutput, "</leaf>\n");
|
||||
PR_fprintf(mOutput, "</leaf>\n");
|
||||
}
|
||||
else {
|
||||
PR_fprintf(mOutput, "/>\n");
|
||||
PR_fprintf(mOutput, "/>\n");
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
@ -717,32 +639,32 @@ nsLoggingSink::LeafNode(const nsIParserNode& aNode)
|
|||
nsAutoString tmp;
|
||||
char* str = nsnull;
|
||||
switch (nodeType) {
|
||||
case eHTMLTag_whitespace:
|
||||
case eHTMLTag_text:
|
||||
GetNewCString(aNode.GetText(), &str);
|
||||
if(str) {
|
||||
PR_fprintf(mOutput, "<text value=\"%s\"/>\n", str);
|
||||
nsMemory::Free(str);
|
||||
}
|
||||
break;
|
||||
case eHTMLTag_whitespace:
|
||||
case eHTMLTag_text:
|
||||
GetNewCString(aNode.GetText(), &str);
|
||||
if(str) {
|
||||
PR_fprintf(mOutput, "<text value=\"%s\"/>\n", str);
|
||||
nsMemory::Free(str);
|
||||
}
|
||||
break;
|
||||
|
||||
case eHTMLTag_newline:
|
||||
PR_fprintf(mOutput, "<newline/>\n");
|
||||
break;
|
||||
case eHTMLTag_newline:
|
||||
PR_fprintf(mOutput, "<newline/>\n");
|
||||
break;
|
||||
|
||||
case eHTMLTag_entity:
|
||||
tmp.Append(aNode.GetText());
|
||||
tmp.Cut(0, 1);
|
||||
pos = tmp.Length() - 1;
|
||||
if (pos >= 0) {
|
||||
tmp.Cut(pos, 1);
|
||||
}
|
||||
PR_fprintf(mOutput, "<entity value=\"%s\"/>\n", NS_LossyConvertUCS2toASCII(tmp).get());
|
||||
break;
|
||||
case eHTMLTag_entity:
|
||||
tmp.Append(aNode.GetText());
|
||||
tmp.Cut(0, 1);
|
||||
pos = tmp.Length() - 1;
|
||||
if (pos >= 0) {
|
||||
tmp.Cut(pos, 1);
|
||||
}
|
||||
PR_fprintf(mOutput, "<entity value=\"%s\"/>\n", NS_LossyConvertUCS2toASCII(tmp).get());
|
||||
break;
|
||||
|
||||
default:
|
||||
NS_NOTREACHED("unsupported leaf node type");
|
||||
}//switch
|
||||
default:
|
||||
NS_NOTREACHED("unsupported leaf node type");
|
||||
}//switch
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -67,7 +67,6 @@ public:
|
|||
NS_IMETHOD SetParser(nsIParser* aParser);
|
||||
NS_IMETHOD OpenContainer(const nsIParserNode& aNode);
|
||||
NS_IMETHOD CloseContainer(const nsHTMLTag aTag);
|
||||
NS_IMETHOD AddHeadContent(const nsIParserNode& aNode);
|
||||
NS_IMETHOD AddLeaf(const nsIParserNode& aNode);
|
||||
NS_IMETHOD AddComment(const nsIParserNode& aNode);
|
||||
NS_IMETHOD AddProcessingInstruction(const nsIParserNode& aNode);
|
||||
|
@ -77,10 +76,10 @@ public:
|
|||
virtual nsISupports *GetTarget() { return nsnull; }
|
||||
|
||||
// nsIHTMLContentSink
|
||||
NS_IMETHOD SetTitle(const nsString& aValue);
|
||||
NS_IMETHOD OpenHTML(const nsIParserNode& aNode);
|
||||
NS_IMETHOD CloseHTML();
|
||||
NS_IMETHOD OpenHead(const nsIParserNode& aNode);
|
||||
NS_IMETHOD OpenHead();
|
||||
NS_IMETHOD CloseHead();
|
||||
NS_IMETHOD OpenBody(const nsIParserNode& aNode);
|
||||
NS_IMETHOD CloseBody();
|
||||
|
@ -116,10 +115,10 @@ public:
|
|||
|
||||
protected:
|
||||
PRFileDesc *mOutput;
|
||||
int mLevel;
|
||||
int mLevel;
|
||||
nsIHTMLContentSink *mSink;
|
||||
PRBool mAutoDeleteOutput;
|
||||
nsIParser* mParser;
|
||||
PRBool mAutoDeleteOutput;
|
||||
nsIParser* mParser;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -74,13 +74,14 @@ nsresult ParseData(char* anInputStream,char* anOutputStream) {
|
|||
return result;
|
||||
}
|
||||
|
||||
PRFileDesc* in = PR_Open(anInputStream, PR_RDONLY, 777);
|
||||
PRFileDesc* in = PR_Open(anInputStream, PR_RDONLY, 0777);
|
||||
if (!in) {
|
||||
printf("\nUnable to open input file - %s\n", anInputStream);
|
||||
return result;
|
||||
}
|
||||
|
||||
PRFileDesc* out = PR_Open(anOutputStream, PR_CREATE_FILE|PR_WRONLY, 777);
|
||||
PRFileDesc* out = PR_Open(anOutputStream,
|
||||
PR_CREATE_FILE|PR_TRUNCATE|PR_RDWR, 0777);
|
||||
if (!out) {
|
||||
printf("\nUnable to open output file - %s\n", anOutputStream);
|
||||
return result;
|
||||
|
|
Загрузка…
Ссылка в новой задаче