bug 229575 : refactor some code that was common between

the xml and html content sinks into nsContentSink
r=sicking sr=jst


git-svn-id: svn://10.0.0.236/trunk@151948 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
hpradhan%hotpop.com 2004-01-28 12:14:17 +00:00
parent 839ea54af6
commit 6f4724db9f
5 changed files with 137 additions and 247 deletions

View File

@ -39,6 +39,7 @@
#include "nsIScriptLoader.h"
#include "nsIDocument.h"
#include "nsICSSLoader.h"
#include "nsStyleConsts.h"
#include "nsStyleLinkElement.h"
#include "nsINodeInfo.h"
#include "nsIDocShell.h"
@ -49,11 +50,14 @@
#include "nsIURI.h"
#include "nsNetUtil.h"
#include "nsIHttpChannel.h"
#include "nsIContent.h"
#include "nsIDOMHTMLScriptElement.h"
#include "nsIParser.h"
#include "nsContentErrors.h"
#include "nsIPresShell.h"
#include "nsIPresContext.h"
#include "nsIViewManager.h"
#include "nsIScrollableView.h"
#include "nsIContentViewer.h"
#include "nsIAtom.h"
#include "nsHTMLAtoms.h"
@ -140,6 +144,7 @@ NS_IMPL_ISUPPORTS3(nsContentSink,
nsIScriptLoaderObserver)
nsContentSink::nsContentSink()
: mNeedToBlockParser(PR_FALSE)
{
}
@ -714,6 +719,31 @@ nsContentSink::ProcessStyleLink(nsIContent* aElement,
return rv;
}
nsresult
nsContentSink::ProcessMETATag(nsIContent* aContent)
{
NS_ASSERTION(aContent, "missing base-element");
nsresult rv = NS_OK;
// set any HTTP-EQUIV data into document's header data as well as url
nsAutoString header;
aContent->GetAttr(kNameSpaceID_None, nsHTMLAtoms::httpEquiv, header);
if (!header.IsEmpty()) {
nsAutoString result;
aContent->GetAttr(kNameSpaceID_None, nsHTMLAtoms::content, result);
if (!result.IsEmpty()) {
ToLowerCase(header);
nsCOMPtr<nsIAtom> fieldAtom(do_GetAtom(header));
rv = ProcessHeaderData(fieldAtom, result, aContent);
}
}
return rv;
}
void
nsContentSink::PrefetchHref(const nsAString &aHref, PRBool aExplicit)
{
@ -892,3 +922,87 @@ nsContentSink::RefreshIfEnabled(nsIViewManager* vm)
return NS_OK;
}
void
nsContentSink::StartLayout(PRBool aIsFrameset)
{
PRUint32 i, ns = mDocument->GetNumberOfShells();
for (i = 0; i < ns; i++) {
nsIPresShell *shell = mDocument->GetShellAt(i);
if (shell) {
// Make sure we don't call InitialReflow() for a shell that has
// already called it. This can happen when the layout frame for
// an iframe is constructed *between* the Embed() call for the
// docshell in the iframe, and the content sink's call to OpenBody().
// (Bug 153815)
PRBool didInitialReflow = PR_FALSE;
shell->GetDidInitialReflow(&didInitialReflow);
if (didInitialReflow) {
// XXX: The assumption here is that if something already
// called InitialReflow() on this shell, it also did some of
// the setup below, so we do nothing and just move on to the
// next shell in the list.
continue;
}
// Make shell an observer for next time
shell->BeginObservingDocument();
// Resize-reflow this time
nsCOMPtr<nsIPresContext> cx;
shell->GetPresContext(getter_AddRefs(cx));
nsRect r;
cx->GetVisibleArea(r);
shell->InitialReflow(r.width, r.height);
// Now trigger a refresh
RefreshIfEnabled(shell->GetViewManager());
}
}
// If the document we are loading has a reference or it is a
// frameset document, disable the scroll bars on the views.
if (mDocumentURI) {
nsCAutoString ref;
// Since all URI's that pass through here aren't URL's we can't
// rely on the nsIURI implementation for providing a way for
// finding the 'ref' part of the URI, we'll haveto revert to
// string routines for finding the data past '#'
mDocumentURI->GetSpec(ref);
nsReadingIterator<char> start, end;
ref.BeginReading(start);
ref.EndReading(end);
if (FindCharInReadable('#', start, end)) {
++start; // Skip over the '#'
mRef = Substring(start, end);
}
}
if (!mRef.IsEmpty() || aIsFrameset) {
// Disable the scroll bars.
for (i = 0; i < ns; i++) {
nsIPresShell *shell = mDocument->GetShellAt(i);
nsIViewManager* vm = shell->GetViewManager();
if (vm) {
nsIView* rootView = nsnull;
vm->GetRootView(rootView);
nsCOMPtr<nsIScrollableView> sview(do_QueryInterface(rootView));
if (sview) {
sview->SetScrollPreference(nsScrollPreference_kNeverScroll);
}
}
}
}
}

View File

@ -92,10 +92,13 @@ protected:
const nsAString& aType,
const nsAString& aMedia);
nsresult ProcessMETATag(nsIContent* aContent);
void PrefetchHref(const nsAString &aHref, PRBool aExplicit);
PRBool ScrollToRef(PRBool aReallyScroll);
nsresult RefreshIfEnabled(nsIViewManager* vm);
void StartLayout(PRBool aIsFrameset);
// Overridable hooks into script evaluation
virtual void PreEvaluateScript() {return;}

View File

@ -43,7 +43,6 @@
#include "nsCOMPtr.h"
#include "nsReadableUtils.h"
#include "nsUnicharUtils.h"
#include "nsXPIDLString.h"
#include "nsIHTMLContentSink.h"
#include "nsIInterfaceRequestor.h"
#include "nsIInterfaceRequestorUtils.h"
@ -54,7 +53,6 @@
#include "nsIURI.h"
#include "nsNetUtil.h"
#include "nsIPresShell.h"
#include "nsIPresContext.h"
#include "nsIViewManager.h"
#include "nsIWidget.h"
#include "nsIContentViewer.h"
@ -85,21 +83,17 @@
#include "nsIComponentManager.h"
#include "nsIServiceManager.h"
#include "nsIScrollableView.h"
#include "nsHTMLAtoms.h"
#include "nsContentUtils.h"
#include "nsIFrame.h"
#include "nsIChannel.h"
#include "nsIHttpChannel.h"
#include "nsIDocShell.h"
#include "nsIWebNavigation.h"
#include "nsIDocument.h"
#include "nsIDocumentObserver.h"
#include "nsIHTMLDocument.h"
#include "nsStyleConsts.h"
#include "nsINameSpaceManager.h"
#include "nsIDOMHTMLMapElement.h"
#include "nsIRefreshURI.h"
#include "nsICookieService.h"
#include "nsVoidArray.h"
#include "nsIScriptSecurityManager.h"
@ -128,7 +122,6 @@
#include "nsWeakReference.h" // nsHTMLElementFactory supports weak references
#include "nsIPrompt.h"
#include "nsLayoutCID.h"
#include "nsIFrameManager.h"
#include "nsIDocShellTreeItem.h"
#include "plevent.h"
@ -344,7 +337,6 @@ protected:
nsIHTMLContent* mFrameset;
nsIHTMLContent* mHead;
nsString mTitle;
nsString mUnicodeXferBuf;
nsString mSkippedContent;
@ -414,7 +406,7 @@ protected:
nsresult ProcessAREATag(const nsIParserNode& aNode);
nsresult ProcessBASETag(const nsIParserNode& aNode);
nsresult ProcessLINKTag(const nsIParserNode& aNode);
nsresult ProcessMAPTag(const nsIParserNode& aNode, nsIHTMLContent* aContent);
nsresult ProcessMAPTag(nsIHTMLContent* aContent);
nsresult ProcessMETATag(const nsIParserNode& aNode);
nsresult ProcessSCRIPTTag(const nsIParserNode& aNode);
nsresult ProcessSTYLETag(const nsIParserNode& aNode);
@ -422,9 +414,6 @@ protected:
nsresult OpenHeadContext();
nsresult CloseHeadContext();
// Script processing related routines
nsresult ResumeParsing();
// nsContentSink overrides
virtual void PreEvaluateScript();
virtual void PostEvaluateScript();
@ -1360,8 +1349,7 @@ SinkContext::OpenContainer(const nsIParserNode& aNode)
break;
case eHTMLTag_map:
mSink->ProcessMAPTag(aNode, content);
mSink->ProcessMAPTag(content);
break;
case eHTMLTag_iframe:
mSink->mNumOpenIFRAMES++;
@ -3765,91 +3753,7 @@ HTMLContentSink::StartLayout()
}
}
PRUint32 i, ns = mDocument->GetNumberOfShells();
for (i = 0; i < ns; i++) {
nsIPresShell *shell = mDocument->GetShellAt(i);
if (shell) {
// Make sure we don't call InitialReflow() for a shell that has
// already called it. This can happen when the layout frame for
// an iframe is constructed *between* the Embed() call for the
// docshell in the iframe, and the content sink's call to OpenBody().
// (Bug 153815)
PRBool didInitialReflow = PR_FALSE;
shell->GetDidInitialReflow(&didInitialReflow);
if (didInitialReflow) {
// XXX: The assumption here is that if something already
// called InitialReflow() on this shell, it also did some of
// the setup below, so we do nothing and just move on to the
// next shell in the list.
continue;
}
// Make shell an observer for next time
shell->BeginObservingDocument();
// Resize-reflow this time
nsCOMPtr<nsIPresContext> cx;
shell->GetPresContext(getter_AddRefs(cx));
nsRect r;
cx->GetVisibleArea(r);
shell->InitialReflow(r.width, r.height);
// Now trigger a refresh
RefreshIfEnabled(shell->GetViewManager());
}
}
// If the document we are loading has a reference or it is a
// frameset document, disable the scroll bars on the views.
if (mDocumentURI) {
nsCAutoString ref;
// Since all URI's that pass through here aren't URL's we can't
// rely on the nsIURI implementation for providing a way for
// finding the 'ref' part of the URI, we'll haveto revert to
// string routines for finding the data past '#'
rv = mDocumentURI->GetSpec(ref);
nsReadingIterator<char> start, end;
ref.BeginReading(start);
ref.EndReading(end);
if (FindCharInReadable('#', start, end)) {
++start; // Skip over the '#'
mRef = Substring(start, end);
}
}
if (!mRef.IsEmpty() || mFrameset) {
// XXX support more than one presentation-shell here
// Get initial scroll preference and save it away; disable the
// scroll bars.
ns = mDocument->GetNumberOfShells();
for (i = 0; i < ns; i++) {
nsIPresShell *shell = mDocument->GetShellAt(i);
nsIViewManager* vm = shell->GetViewManager();
if (vm) {
nsIView* rootView = nsnull;
vm->GetRootView(rootView);
if (rootView) {
nsCOMPtr<nsIScrollableView> sview(do_QueryInterface(rootView));
if (sview) {
sview->SetScrollPreference(nsScrollPreference_kNeverScroll);
}
}
}
}
}
nsContentSink::StartLayout(!!mFrameset);
}
void
@ -4135,8 +4039,7 @@ HTMLContentSink::ProcessLINKTag(const nsIParserNode& aNode)
}
nsresult
HTMLContentSink::ProcessMAPTag(const nsIParserNode& aNode,
nsIHTMLContent* aContent)
HTMLContentSink::ProcessMAPTag(nsIHTMLContent* aContent)
{
mCurrentMap = nsnull;
@ -4195,25 +4098,9 @@ HTMLContentSink::ProcessMETATag(const nsIParserNode& aNode)
// XXX It's just not sufficient to check if the parent is head. Also
// check for the preference.
if (!mInsideNoXXXTag) {
// Bug 40072: Don't evaluate METAs after FRAMESET.
if (!mFrameset) {
// set any HTTP-EQUIV data into document's header data as well as url
nsAutoString header;
it->GetAttr(kNameSpaceID_None, nsHTMLAtoms::httpEquiv, header);
if (!header.IsEmpty()) {
nsAutoString result;
it->GetAttr(kNameSpaceID_None, nsHTMLAtoms::content, result);
if (!result.IsEmpty()) {
ToLowerCase(header);
nsCOMPtr<nsIAtom> fieldAtom = do_GetAtom(header);
rv = ProcessHeaderData(fieldAtom, result, it);
}
}
}
// Bug 40072: Don't evaluate METAs after FRAMESET.
if (!mInsideNoXXXTag && !mFrameset) {
rv = nsContentSink::ProcessMETATag(it);
}
return rv;
@ -4354,17 +4241,6 @@ HTMLContentSink::DocumentWillBeDestroyed(nsIDocument *aDocument)
{
}
nsresult
HTMLContentSink::ResumeParsing()
{
nsresult result = NS_OK;
if (mParser) {
result = mParser->ContinueParsing();
}
return result;
}
void
HTMLContentSink::PreEvaluateScript()
{

View File

@ -49,7 +49,6 @@
#include "nsIXMLContent.h"
#include "nsIScriptGlobalObject.h"
#include "nsIURI.h"
#include "nsIRefreshURI.h"
#include "nsNetUtil.h"
#include "nsIDocShell.h"
#include "nsIDocShellTreeItem.h"
@ -59,7 +58,6 @@
#include "nsIPresContext.h"
#include "nsIPresShell.h"
#include "nsIViewManager.h"
#include "nsIScrollableView.h"
#include "nsIDOMComment.h"
#include "nsIDOMCDATASection.h"
#include "nsDOMDocumentType.h"
@ -143,24 +141,17 @@ NS_NewXMLContentSink(nsIXMLContentSink** aResult,
}
nsXMLContentSink::nsXMLContentSink()
: mDocElement(nsnull),
mText(nsnull),
mTextLength(0),
mTextSize(0),
mConstrainSize(PR_TRUE),
mInTitle(PR_FALSE),
mPrettyPrintXML(PR_TRUE),
mPrettyPrintHasSpecialRoot(PR_FALSE),
mPrettyPrintHasFactoredElements(PR_FALSE),
mHasProcessedBase(PR_FALSE)
{
mDocument = nsnull;
mDocumentURI = nsnull;
mDocumentBaseURI = nsnull;
mParser = nsnull;
mDocElement = nsnull;
mText = nsnull;
mTextLength = 0;
mTextSize = 0;
mConstrainSize = PR_TRUE;
mInTitle = PR_FALSE;
mCSSLoader = nsnull;
mNeedToBlockParser = PR_FALSE;
mPrettyPrintXML = PR_TRUE;
mPrettyPrintHasSpecialRoot = PR_FALSE;
mPrettyPrintHasFactoredElements = PR_FALSE;
mHasProcessedBase = PR_FALSE;
}
nsXMLContentSink::~nsXMLContentSink()
@ -290,13 +281,6 @@ nsXMLContentSink::DidBuildModel()
mDocument->EndLoad();
}
// Ref. Bug 49115
// Do this hack to make sure that the parser
// doesn't get destroyed, accidently, before
// the circularity, between sink & parser, is
// actually broken.
nsCOMPtr<nsIParser> kungFuDeathGrip(mParser);
// Drop our reference to the parser to get rid of a circular
// reference.
mParser = nsnull;
@ -709,28 +693,6 @@ nsXMLContentSink::ProcessBASETag(nsIContent* aContent)
return rv;
}
nsresult
nsXMLContentSink::ProcessMETATag(nsIContent* aContent)
{
NS_ASSERTION(aContent, "missing base-element");
nsresult rv = NS_OK;
// set any HTTP-EQUIV data into document's header data as well as url
nsAutoString header;
aContent->GetAttr(kNameSpaceID_None, nsHTMLAtoms::httpEquiv, header);
if (!header.IsEmpty()) {
nsAutoString result;
aContent->GetAttr(kNameSpaceID_None, nsHTMLAtoms::content, result);
if (!result.IsEmpty()) {
ToLowerCase(header);
nsCOMPtr<nsIAtom> fieldAtom(do_GetAtom(header));
rv = ProcessHeaderData(fieldAtom, result, aContent);
}//if (!result.IsEmpty())
}//if (!header.IsEmpty())
return rv;
}
NS_IMETHODIMP
nsXMLContentSink::SetDocumentCharset(nsACString& aCharset)
@ -853,82 +815,18 @@ nsXMLContentSink::StartLayout()
if (scrollableContainer) {
scrollableContainer->ResetScrollbarPreferences();
}
PRUint32 i, ns = mDocument->GetNumberOfShells();
for (i = 0; i < ns; i++) {
nsIPresShell *shell = mDocument->GetShellAt(i);
// Make shell an observer for next time
shell->BeginObservingDocument();
// Resize-reflow this time
nsCOMPtr<nsIPresContext> cx;
shell->GetPresContext(getter_AddRefs(cx));
nsRect r;
cx->GetVisibleArea(r);
shell->InitialReflow(r.width, r.height);
// Now trigger a refresh
RefreshIfEnabled(shell->GetViewManager());
}
if (mDocumentURI) {
nsCAutoString ref;
// Since all URI's that pass through here aren't URL's we can't
// rely on the nsIURI implementation for providing a way for
// finding the 'ref' part of the URI, we'll haveto revert to
// string routines for finding the data past '#'
mDocumentURI->GetSpec(ref);
nsReadingIterator<char> start, end;
ref.BeginReading(start);
ref.EndReading(end);
if (FindCharInReadable('#', start, end)) {
++start; // Skip over the '#'
mRef = Substring(start, end);
}
}
// If the document we are loading has a reference or it is a top level
// frameset document, disable the scroll bars on the views.
PRBool topLevelFrameset = PR_FALSE;
nsCOMPtr<nsIDocShellTreeItem> docShellAsItem(do_QueryInterface(mDocShell));
if (docShellAsItem) {
nsCOMPtr<nsIDocShellTreeItem> root;
docShellAsItem->GetSameTypeRootTreeItem(getter_AddRefs(root));
if(docShellAsItem.get() == root.get()) {
if(docShellAsItem == root) {
topLevelFrameset = PR_TRUE;
}
}
nsContentSink::StartLayout(topLevelFrameset);
if (!mRef.IsEmpty() || topLevelFrameset) {
// XXX support more than one presentation-shell here
// Get initial scroll preference and save it away; disable the
// scroll bars.
ns = mDocument->GetNumberOfShells();
for (i = 0; i < ns; i++) {
nsIPresShell *shell = mDocument->GetShellAt(i);
nsIViewManager* vm = shell->GetViewManager();
if (vm) {
nsIView* rootView = nsnull;
vm->GetRootView(rootView);
if (rootView) {
nsIScrollableView* sview = nsnull;
CallQueryInterface(rootView, &sview);
if (sview) {
sview->SetScrollPreference(nsScrollPreference_kNeverScroll);
}
}
}
}
}
}
////////////////////////////////////////////////////////////////////////

View File

@ -128,7 +128,6 @@ protected:
nsresult ProcessBASETag(nsIContent* aContent);
nsresult ProcessMETATag(nsIContent* aContent);
// nsContentSink override