1998-04-13 20:24:54 +00:00
|
|
|
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
|
|
|
*
|
|
|
|
* The contents of this file are subject to the Netscape Public License
|
|
|
|
* Version 1.0 (the "NPL"); you may not use this file except in
|
|
|
|
* compliance with the NPL. You may obtain a copy of the NPL at
|
|
|
|
* http://www.mozilla.org/NPL/
|
|
|
|
*
|
|
|
|
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
|
|
|
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
|
|
|
* for the specific language governing rights and limitations under the
|
|
|
|
* NPL.
|
|
|
|
*
|
|
|
|
* The Initial Developer of this code under the NPL is Netscape
|
|
|
|
* Communications Corporation. Portions created by Netscape are
|
|
|
|
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
|
|
|
* Reserved.
|
|
|
|
*/
|
|
|
|
#include "nsIHTMLContentSink.h"
|
|
|
|
#include "nsIStyleSheet.h"
|
|
|
|
#include "nsIUnicharInputStream.h"
|
|
|
|
#include "nsIHTMLContent.h"
|
|
|
|
#include "nsIURL.h"
|
|
|
|
#include "nsHTMLDocument.h"
|
|
|
|
#include "nsIPresShell.h"
|
|
|
|
#include "nsIPresContext.h"
|
1998-06-23 01:34:25 +00:00
|
|
|
#include "nsIViewManager.h"
|
1998-06-23 00:52:21 +00:00
|
|
|
#include "nsHTMLTokens.h"
|
1998-04-13 20:24:54 +00:00
|
|
|
#include "nsCRT.h"
|
|
|
|
#include "prtime.h"
|
|
|
|
#include "prlog.h"
|
|
|
|
|
|
|
|
#include "nsHTMLParts.h"
|
|
|
|
#include "nsTablePart.h"
|
|
|
|
#include "nsTableRow.h"
|
|
|
|
#include "nsTableCell.h"
|
1998-06-27 22:57:52 +00:00
|
|
|
#include "nsIDOMText.h"
|
1998-04-13 20:24:54 +00:00
|
|
|
|
|
|
|
#include "nsHTMLForms.h"
|
|
|
|
#include "nsIFormManager.h"
|
1998-05-08 20:18:06 +00:00
|
|
|
#include "nsIFormControl.h"
|
1998-04-13 20:24:54 +00:00
|
|
|
#include "nsIImageMap.h"
|
|
|
|
|
1998-04-22 22:12:24 +00:00
|
|
|
#include "nsRepository.h"
|
|
|
|
|
1998-07-22 23:42:47 +00:00
|
|
|
#include "nsIScrollableView.h"
|
|
|
|
#include "nsHTMLAtoms.h"
|
|
|
|
#include "nsIFrame.h"
|
|
|
|
|
1998-07-18 21:47:56 +00:00
|
|
|
#include "nsIWebShell.h"
|
1998-06-11 16:46:33 +00:00
|
|
|
extern nsresult NS_NewHTMLIFrame(nsIHTMLContent** aInstancePtrResult,
|
1998-07-18 21:47:56 +00:00
|
|
|
nsIAtom* aTag, nsIWebShell* aWebShell); // XXX move
|
1998-07-20 18:52:40 +00:00
|
|
|
extern nsresult NS_NewHTMLFrame(nsIHTMLContent** aInstancePtrResult,
|
|
|
|
nsIAtom* aTag, nsIWebShell* aWebShell); // XXX move
|
|
|
|
extern nsresult NS_NewHTMLFrameset(nsIHTMLContent** aInstancePtrResult,
|
|
|
|
nsIAtom* aTag, nsIWebShell* aWebShell); // XXX move
|
1998-07-18 21:47:56 +00:00
|
|
|
|
1998-04-13 20:24:54 +00:00
|
|
|
// XXX attribute values have entities in them - use the parsers expander!
|
|
|
|
|
|
|
|
// XXX Go through a factory for this one
|
|
|
|
#include "nsICSSParser.h"
|
|
|
|
|
|
|
|
#ifdef NS_DEBUG
|
1998-06-30 23:51:53 +00:00
|
|
|
static PRLogModuleInfo* gSinkLogModuleInfo;
|
1998-04-13 20:24:54 +00:00
|
|
|
|
1998-06-30 23:51:53 +00:00
|
|
|
#define SINK_TRACE_CALLS 0x1
|
|
|
|
#define SINK_TRACE_REFLOW 0x2
|
1998-04-13 20:24:54 +00:00
|
|
|
|
1998-06-30 23:51:53 +00:00
|
|
|
#define SINK_LOG_TEST(_lm,_bit) (PRIntn((_lm)->level) & (_bit))
|
1998-04-13 20:24:54 +00:00
|
|
|
|
1998-06-30 23:51:53 +00:00
|
|
|
#define SINK_TRACE(_bit,_args) \
|
|
|
|
PR_BEGIN_MACRO \
|
|
|
|
if (SINK_LOG_TEST(gSinkLogModuleInfo,_bit)) { \
|
|
|
|
PR_LogPrint _args; \
|
|
|
|
} \
|
|
|
|
PR_END_MACRO
|
1998-07-11 03:51:50 +00:00
|
|
|
|
1998-07-14 01:57:51 +00:00
|
|
|
#define SINK_TRACE_NODE(_bit,_msg,_node) \
|
|
|
|
PR_BEGIN_MACRO \
|
|
|
|
if (SINK_LOG_TEST(gSinkLogModuleInfo,_bit)) { \
|
|
|
|
char cbuf[40]; \
|
|
|
|
const char* cp; \
|
1998-07-27 18:04:38 +00:00
|
|
|
PRInt32 nt = (_node).GetNodeType(); \
|
|
|
|
if ((nt > PRInt32(eHTMLTag_unknown)) && \
|
|
|
|
(nt < PRInt32(eHTMLTag_text))) { \
|
1998-07-14 01:57:51 +00:00
|
|
|
cp = NS_EnumToTag(nsHTMLTag((_node).GetNodeType())); \
|
|
|
|
} else { \
|
|
|
|
(_node).GetText().ToCString(cbuf, sizeof(cbuf)); \
|
|
|
|
cp = cbuf; \
|
|
|
|
} \
|
1998-07-27 18:04:38 +00:00
|
|
|
PR_LogPrint("%s: this=%p node='%s'", _msg, this, cp); \
|
1998-07-14 01:57:51 +00:00
|
|
|
} \
|
1998-07-11 03:51:50 +00:00
|
|
|
PR_END_MACRO
|
|
|
|
|
1998-06-30 23:51:53 +00:00
|
|
|
#else
|
|
|
|
#define SINK_TRACE(_bit,_args)
|
1998-07-11 03:51:50 +00:00
|
|
|
#define SINK_TRACE_NODE(_bit,_msg,_node)
|
1998-06-30 23:51:53 +00:00
|
|
|
#endif
|
1998-04-13 20:24:54 +00:00
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
|
1998-07-22 23:42:47 +00:00
|
|
|
static NS_DEFINE_IID(kIScrollableViewIID, NS_ISCROLLABLEVIEW_IID);
|
1998-07-15 22:31:10 +00:00
|
|
|
static NS_DEFINE_IID(kIHTMLContentSinkIID, NS_IHTML_CONTENT_SINK_IID);
|
1998-05-08 20:18:06 +00:00
|
|
|
static NS_DEFINE_IID(kIFormControlIID, NS_IFORMCONTROL_IID);
|
1998-04-13 20:24:54 +00:00
|
|
|
|
|
|
|
class HTMLContentSink : public nsIHTMLContentSink {
|
|
|
|
public:
|
|
|
|
|
|
|
|
HTMLContentSink();
|
|
|
|
~HTMLContentSink();
|
|
|
|
|
|
|
|
void* operator new(size_t size) {
|
|
|
|
void* rv = ::operator new(size);
|
|
|
|
nsCRT::zero(rv, size);
|
|
|
|
return (void*) rv;
|
|
|
|
}
|
|
|
|
|
1998-07-18 21:47:56 +00:00
|
|
|
nsresult Init(nsIDocument* aDoc,
|
|
|
|
nsIURL* aURL,
|
|
|
|
nsIWebShell* aContainer);
|
1998-04-13 20:24:54 +00:00
|
|
|
nsIHTMLContent* GetCurrentContainer(eHTMLTags* aType);
|
1998-07-12 00:18:26 +00:00
|
|
|
nsIHTMLContent* GetTableParent();
|
1998-04-13 20:24:54 +00:00
|
|
|
|
1998-07-15 22:31:10 +00:00
|
|
|
// nsISupports
|
|
|
|
NS_DECL_ISUPPORTS
|
1998-04-13 20:24:54 +00:00
|
|
|
|
1998-07-15 22:31:10 +00:00
|
|
|
// nsIContentSink
|
|
|
|
NS_IMETHOD WillBuildModel(void);
|
|
|
|
NS_IMETHOD DidBuildModel(PRInt32 aQualityLevel);
|
|
|
|
NS_IMETHOD WillInterrupt(void);
|
|
|
|
NS_IMETHOD WillResume(void);
|
|
|
|
|
|
|
|
// nsIHTMLContentSink
|
|
|
|
NS_IMETHOD PushMark();
|
|
|
|
NS_IMETHOD SetTitle(const nsString& aValue);
|
|
|
|
NS_IMETHOD OpenHTML(const nsIParserNode& aNode);
|
|
|
|
NS_IMETHOD CloseHTML(const nsIParserNode& aNode);
|
|
|
|
NS_IMETHOD OpenHead(const nsIParserNode& aNode);
|
|
|
|
NS_IMETHOD CloseHead(const nsIParserNode& aNode);
|
|
|
|
NS_IMETHOD OpenBody(const nsIParserNode& aNode);
|
|
|
|
NS_IMETHOD CloseBody(const nsIParserNode& aNode);
|
|
|
|
NS_IMETHOD OpenForm(const nsIParserNode& aNode);
|
|
|
|
NS_IMETHOD CloseForm(const nsIParserNode& aNode);
|
|
|
|
NS_IMETHOD OpenFrameset(const nsIParserNode& aNode);
|
|
|
|
NS_IMETHOD CloseFrameset(const nsIParserNode& aNode);
|
1998-07-20 18:52:40 +00:00
|
|
|
NS_IMETHOD OpenMap(const nsIParserNode& aNode);
|
|
|
|
NS_IMETHOD CloseMap(const nsIParserNode& aNode);
|
1998-07-15 22:31:10 +00:00
|
|
|
NS_IMETHOD OpenContainer(const nsIParserNode& aNode);
|
|
|
|
NS_IMETHOD CloseContainer(const nsIParserNode& aNode);
|
|
|
|
NS_IMETHOD AddLeaf(const nsIParserNode& aNode);
|
1998-05-07 21:11:07 +00:00
|
|
|
|
1998-04-13 20:24:54 +00:00
|
|
|
protected:
|
|
|
|
|
|
|
|
void StartLayout();
|
|
|
|
|
|
|
|
void ReflowNewContent();
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
// Leaf tag handler routines that translate a leaf tag into a
|
|
|
|
// content object, processing all of the tag attributes.
|
|
|
|
|
|
|
|
nsresult ProcessAREATag(const nsIParserNode& aNode);
|
|
|
|
nsresult ProcessBASETag(const nsIParserNode& aNode);
|
1998-06-26 15:08:55 +00:00
|
|
|
nsresult ProcessMETATag(const nsIParserNode& aNode);
|
1998-04-13 20:24:54 +00:00
|
|
|
nsresult ProcessSTYLETag(const nsIParserNode& aNode);
|
1998-06-25 22:26:52 +00:00
|
|
|
nsresult ProcessSCRIPTTag(const nsIParserNode& aNode);
|
1998-04-13 20:24:54 +00:00
|
|
|
|
|
|
|
nsresult ProcessBRTag(nsIHTMLContent** aInstancePtrResult,
|
|
|
|
const nsIParserNode& aNode);
|
1998-07-15 00:49:26 +00:00
|
|
|
nsresult ProcessEMBEDTag(nsIHTMLContent** aInstancePtrResult,
|
|
|
|
const nsIParserNode& aNode);
|
1998-07-20 18:52:40 +00:00
|
|
|
nsresult ProcessFrameTag(nsIHTMLContent** aInstancePtrResult,
|
|
|
|
const nsIParserNode& aNode);
|
1998-04-13 20:24:54 +00:00
|
|
|
nsresult ProcessHRTag(nsIHTMLContent** aInstancePtrResult,
|
|
|
|
const nsIParserNode& aNode);
|
|
|
|
nsresult ProcessINPUTTag(nsIHTMLContent** aInstancePtrResult,
|
|
|
|
const nsIParserNode& aNode);
|
|
|
|
nsresult ProcessIMGTag(nsIHTMLContent** aInstancePtrResult,
|
|
|
|
const nsIParserNode& aNode);
|
|
|
|
nsresult ProcessSPACERTag(nsIHTMLContent** aInstancePtrResult,
|
|
|
|
const nsIParserNode& aNode);
|
1998-04-22 22:12:24 +00:00
|
|
|
nsresult ProcessTEXTAREATag(nsIHTMLContent** aInstancePtrResult,
|
|
|
|
const nsIParserNode& aNode);
|
1998-04-13 20:24:54 +00:00
|
|
|
nsresult ProcessWBRTag(nsIHTMLContent** aInstancePtrResult,
|
|
|
|
const nsIParserNode& aNode);
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
|
1998-04-22 23:24:43 +00:00
|
|
|
nsresult ProcessOpenSELECTTag(nsIHTMLContent** aInstancePtrResult,
|
|
|
|
const nsIParserNode& aNode);
|
|
|
|
nsresult ProcessCloseSELECTTag(const nsIParserNode& aNode);
|
1998-05-08 23:08:43 +00:00
|
|
|
nsresult ProcessOpenOPTIONTag(nsIHTMLContent** aInstancePtrResult,
|
|
|
|
const nsIParserNode& aNode);
|
1998-04-22 23:24:43 +00:00
|
|
|
nsresult ProcessCloseOPTIONTag(const nsIParserNode& aNode);
|
|
|
|
nsresult ProcessOPTIONTagContent(const nsIParserNode& aNode);
|
|
|
|
|
1998-06-11 16:46:33 +00:00
|
|
|
nsresult ProcessIFRAMETag(nsIHTMLContent** aInstancePtrResult,
|
|
|
|
const nsIParserNode& aNode);
|
1998-07-20 18:52:40 +00:00
|
|
|
nsresult ProcessFRAMESETTag(nsIHTMLContent** aInstancePtrResult,
|
|
|
|
const nsIParserNode& aNode);
|
1998-04-22 23:24:43 +00:00
|
|
|
//----------------------------------------------------------------------
|
|
|
|
|
1998-06-27 22:57:52 +00:00
|
|
|
void FlushText();
|
|
|
|
|
|
|
|
nsresult AddText(const nsString& aText, nsIHTMLContent** aContent);
|
|
|
|
|
1998-07-12 00:18:26 +00:00
|
|
|
void AppendToCorrectParent(nsHTMLTag aParentTag,
|
|
|
|
nsIHTMLContent* aParent,
|
|
|
|
nsHTMLTag aChildTag,
|
|
|
|
nsIHTMLContent* aChild,
|
|
|
|
PRBool aAllowReflow);
|
|
|
|
|
1998-04-13 20:24:54 +00:00
|
|
|
void GetAttributeValueAt(const nsIParserNode& aNode,
|
|
|
|
PRInt32 aIndex,
|
|
|
|
nsString& aResult);
|
|
|
|
|
1998-04-22 22:12:24 +00:00
|
|
|
PRBool FindAttribute(const nsIParserNode& aNode,
|
|
|
|
const nsString& aKeyName,
|
|
|
|
nsString& aResult);
|
|
|
|
|
1998-04-13 20:24:54 +00:00
|
|
|
nsresult AddAttributes(const nsIParserNode& aNode,
|
|
|
|
nsIHTMLContent* aInstancePtrResult);
|
|
|
|
|
1998-07-24 18:20:27 +00:00
|
|
|
void AddBaseTagInfo(nsIHTMLContent* aContent);
|
|
|
|
|
1998-07-20 18:52:40 +00:00
|
|
|
nsIHTMLContent* GetBodyOrFrameset() { if (mBody) return mBody; else return mFrameset; }
|
|
|
|
|
1998-04-13 20:24:54 +00:00
|
|
|
nsresult LoadStyleSheet(nsIURL* aURL,
|
|
|
|
nsIUnicharInputStream* aUIN);
|
|
|
|
|
1998-07-22 23:42:47 +00:00
|
|
|
void ScrollToRef();
|
|
|
|
|
1998-04-13 20:24:54 +00:00
|
|
|
nsIDocument* mDocument;
|
|
|
|
nsIURL* mDocumentURL;
|
|
|
|
|
|
|
|
eHTMLTags mNodeStack[100];/* XXX */
|
|
|
|
nsIHTMLContent* mContainerStack[100];/* XXX */
|
|
|
|
PRInt32 mStackPos;
|
|
|
|
nsString* mTitle;
|
|
|
|
nsString mBaseHREF;
|
|
|
|
nsString mBaseTarget;
|
|
|
|
nsIStyleSheet* mStyleSheet;
|
|
|
|
nsIFormManager* mCurrentForm;
|
|
|
|
nsIImageMap* mCurrentMap;
|
1998-05-08 20:18:06 +00:00
|
|
|
nsIHTMLContent* mCurrentSelect;
|
|
|
|
nsIHTMLContent* mCurrentOption;
|
1998-06-27 22:57:52 +00:00
|
|
|
nsIDOMText* mCurrentText;
|
1998-04-13 20:24:54 +00:00
|
|
|
|
|
|
|
nsIHTMLContent* mRoot;
|
|
|
|
nsIHTMLContent* mBody;
|
1998-07-20 18:52:40 +00:00
|
|
|
nsIHTMLContent* mFrameset;
|
1998-06-04 21:33:44 +00:00
|
|
|
nsIHTMLContent* mHead;
|
1998-04-13 20:24:54 +00:00
|
|
|
|
|
|
|
PRTime mLastUpdateTime;
|
|
|
|
PRTime mUpdateDelta;
|
|
|
|
PRBool mLayoutStarted;
|
1998-06-03 15:58:52 +00:00
|
|
|
PRInt32 mInMonolithicContainer;
|
1998-07-18 21:47:56 +00:00
|
|
|
nsIWebShell* mWebShell;
|
1998-07-20 18:52:40 +00:00
|
|
|
|
1998-07-22 23:42:47 +00:00
|
|
|
nsString* mRef;
|
|
|
|
nsScrollPreference mOriginalScrollPreference;
|
|
|
|
PRBool mNotAtRef;
|
|
|
|
nsIHTMLContent* mRefContent;
|
|
|
|
|
1998-07-20 18:52:40 +00:00
|
|
|
// XXX The parser needs to keep track of body tags and frameset tags
|
|
|
|
// and tell the content sink if they are to be ignored. For example, in nav4
|
|
|
|
// <html><body><frameset> ignores the frameset and
|
|
|
|
// <html><frameset><body> ignores the body
|
1998-04-13 20:24:54 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
// Note: operator new zeros our memory
|
|
|
|
HTMLContentSink::HTMLContentSink()
|
|
|
|
{
|
1998-07-07 22:20:00 +00:00
|
|
|
#ifdef NS_DEBUG
|
1998-06-30 23:51:53 +00:00
|
|
|
if (nsnull == gSinkLogModuleInfo) {
|
|
|
|
gSinkLogModuleInfo = PR_NewLogModule("htmlcontentsink");
|
1998-04-13 20:24:54 +00:00
|
|
|
}
|
1998-07-07 22:20:00 +00:00
|
|
|
#endif
|
1998-04-13 20:24:54 +00:00
|
|
|
|
|
|
|
// Set the first update delta to be 50ms
|
|
|
|
LL_I2L(mUpdateDelta, PR_USEC_PER_MSEC * 50);
|
1998-07-22 23:42:47 +00:00
|
|
|
|
|
|
|
mNotAtRef = PR_TRUE;
|
1998-04-13 20:24:54 +00:00
|
|
|
}
|
1998-05-21 20:37:41 +00:00
|
|
|
|
1998-04-13 20:24:54 +00:00
|
|
|
HTMLContentSink::~HTMLContentSink()
|
|
|
|
{
|
1998-06-04 21:33:44 +00:00
|
|
|
NS_IF_RELEASE(mHead);
|
1998-04-13 20:24:54 +00:00
|
|
|
NS_IF_RELEASE(mBody);
|
1998-07-20 18:52:40 +00:00
|
|
|
NS_IF_RELEASE(mFrameset);
|
1998-04-13 20:24:54 +00:00
|
|
|
NS_IF_RELEASE(mRoot);
|
1998-04-16 21:49:49 +00:00
|
|
|
NS_IF_RELEASE(mDocument);
|
1998-04-13 20:24:54 +00:00
|
|
|
NS_IF_RELEASE(mDocumentURL);
|
|
|
|
NS_IF_RELEASE(mStyleSheet);
|
|
|
|
NS_IF_RELEASE(mCurrentForm);
|
|
|
|
NS_IF_RELEASE(mCurrentMap);
|
1998-04-22 23:24:43 +00:00
|
|
|
NS_IF_RELEASE(mCurrentSelect);
|
|
|
|
NS_IF_RELEASE(mCurrentOption);
|
1998-07-18 21:47:56 +00:00
|
|
|
NS_IF_RELEASE(mWebShell);
|
1998-07-22 23:42:47 +00:00
|
|
|
NS_IF_RELEASE(mRefContent);
|
1998-05-08 20:18:06 +00:00
|
|
|
|
1998-04-13 20:24:54 +00:00
|
|
|
if (nsnull != mTitle) {
|
|
|
|
delete mTitle;
|
|
|
|
}
|
1998-07-22 23:42:47 +00:00
|
|
|
if (nsnull != mRef) {
|
|
|
|
delete mRef;
|
|
|
|
}
|
1998-04-13 20:24:54 +00:00
|
|
|
}
|
|
|
|
|
1998-07-06 22:15:55 +00:00
|
|
|
nsresult
|
|
|
|
HTMLContentSink::Init(nsIDocument* aDoc,
|
|
|
|
nsIURL* aDocURL,
|
1998-07-18 21:47:56 +00:00
|
|
|
nsIWebShell* aWebShell)
|
1998-04-13 20:24:54 +00:00
|
|
|
{
|
1998-04-16 21:49:49 +00:00
|
|
|
NS_IF_RELEASE(mDocument);
|
1998-04-13 20:24:54 +00:00
|
|
|
mDocument = aDoc;
|
1998-04-16 21:49:49 +00:00
|
|
|
NS_IF_ADDREF(mDocument);
|
1998-04-13 20:24:54 +00:00
|
|
|
|
1998-04-16 21:49:49 +00:00
|
|
|
NS_IF_RELEASE(mDocumentURL);
|
1998-04-13 20:24:54 +00:00
|
|
|
mDocumentURL = aDocURL;
|
1998-04-16 21:49:49 +00:00
|
|
|
NS_IF_ADDREF(mDocumentURL);
|
1998-04-13 20:24:54 +00:00
|
|
|
|
1998-07-18 21:47:56 +00:00
|
|
|
NS_IF_RELEASE(mWebShell);
|
|
|
|
mWebShell = aWebShell;
|
|
|
|
NS_IF_ADDREF(mWebShell);
|
1998-06-23 22:25:28 +00:00
|
|
|
|
1998-07-27 18:04:38 +00:00
|
|
|
SINK_TRACE(SINK_TRACE_CALLS,
|
|
|
|
("HTMLContentSink::Init: this=%p url='%s'",
|
|
|
|
this, aDocURL->GetSpec()));
|
1998-07-30 16:06:22 +00:00
|
|
|
return NS_OK;
|
1998-04-13 20:24:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMPL_ISUPPORTS(HTMLContentSink,kIHTMLContentSinkIID)
|
|
|
|
|
1998-07-15 22:31:10 +00:00
|
|
|
NS_IMETHODIMP
|
1998-06-27 22:57:52 +00:00
|
|
|
HTMLContentSink::OpenHTML(const nsIParserNode& aNode)
|
|
|
|
{
|
|
|
|
FlushText();
|
|
|
|
|
1998-07-11 03:51:50 +00:00
|
|
|
SINK_TRACE_NODE(SINK_TRACE_CALLS,
|
|
|
|
"HTMLContentSink::OpenHTML", aNode);
|
1998-04-13 20:24:54 +00:00
|
|
|
NS_PRECONDITION(0 == mStackPos, "bad stack pos");
|
|
|
|
|
|
|
|
mNodeStack[0] = (eHTMLTags)aNode.GetNodeType();
|
|
|
|
mContainerStack[0] = mRoot;
|
|
|
|
mStackPos = 1;
|
|
|
|
|
1998-07-15 22:31:10 +00:00
|
|
|
return NS_OK;
|
1998-04-13 20:24:54 +00:00
|
|
|
}
|
|
|
|
|
1998-07-15 22:31:10 +00:00
|
|
|
NS_IMETHODIMP
|
1998-06-27 22:57:52 +00:00
|
|
|
HTMLContentSink::CloseHTML(const nsIParserNode& aNode)
|
1998-04-13 20:24:54 +00:00
|
|
|
{
|
1998-06-27 22:57:52 +00:00
|
|
|
FlushText();
|
|
|
|
|
1998-07-11 03:51:50 +00:00
|
|
|
SINK_TRACE_NODE(SINK_TRACE_CALLS,
|
|
|
|
"HTMLContentSink::CloseHTML", aNode);
|
1998-04-13 20:24:54 +00:00
|
|
|
|
1998-07-20 18:52:40 +00:00
|
|
|
// XXX this is the way it used to be
|
|
|
|
//NS_ASSERTION(mStackPos > 0, "bad bad");
|
|
|
|
//mNodeStack[--mStackPos] = eHTMLTag_unknown;
|
|
|
|
if (mStackPos > 0) {
|
|
|
|
mNodeStack[--mStackPos] = eHTMLTag_unknown;
|
|
|
|
}
|
1998-04-13 20:24:54 +00:00
|
|
|
|
|
|
|
NS_IF_RELEASE(mCurrentForm);
|
|
|
|
|
1998-07-15 22:31:10 +00:00
|
|
|
return NS_OK;
|
1998-04-13 20:24:54 +00:00
|
|
|
}
|
|
|
|
|
1998-07-15 22:31:10 +00:00
|
|
|
NS_IMETHODIMP
|
1998-06-27 22:57:52 +00:00
|
|
|
HTMLContentSink::OpenHead(const nsIParserNode& aNode)
|
1998-04-13 20:24:54 +00:00
|
|
|
{
|
1998-06-27 22:57:52 +00:00
|
|
|
FlushText();
|
|
|
|
|
1998-07-11 03:51:50 +00:00
|
|
|
SINK_TRACE_NODE(SINK_TRACE_CALLS,
|
|
|
|
"HTMLContentSink::OpenHead", aNode);
|
1998-04-13 20:24:54 +00:00
|
|
|
|
1998-06-04 21:33:44 +00:00
|
|
|
mNodeStack[mStackPos] = (eHTMLTags)aNode.GetNodeType();
|
|
|
|
mContainerStack[mStackPos] = mHead;
|
|
|
|
mStackPos++;
|
1998-07-15 22:31:10 +00:00
|
|
|
return NS_OK;
|
1998-04-13 20:24:54 +00:00
|
|
|
}
|
|
|
|
|
1998-07-15 22:31:10 +00:00
|
|
|
NS_IMETHODIMP
|
1998-06-27 22:57:52 +00:00
|
|
|
HTMLContentSink::CloseHead(const nsIParserNode& aNode)
|
1998-04-13 20:24:54 +00:00
|
|
|
{
|
1998-06-27 22:57:52 +00:00
|
|
|
FlushText();
|
|
|
|
|
1998-07-11 03:51:50 +00:00
|
|
|
SINK_TRACE_NODE(SINK_TRACE_CALLS,
|
|
|
|
"HTMLContentSink::CloseHead", aNode);
|
1998-04-13 20:24:54 +00:00
|
|
|
|
|
|
|
NS_ASSERTION(mStackPos > 0, "bad bad");
|
|
|
|
mNodeStack[--mStackPos] = eHTMLTag_unknown;
|
1998-07-15 22:31:10 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
HTMLContentSink::PushMark()
|
|
|
|
{
|
|
|
|
return NS_OK;
|
1998-04-13 20:24:54 +00:00
|
|
|
}
|
|
|
|
|
1998-07-15 22:31:10 +00:00
|
|
|
NS_IMETHODIMP
|
1998-06-27 22:57:52 +00:00
|
|
|
HTMLContentSink::SetTitle(const nsString& aValue)
|
1998-04-13 20:24:54 +00:00
|
|
|
{
|
1998-06-27 22:57:52 +00:00
|
|
|
FlushText();
|
|
|
|
|
1998-04-13 20:24:54 +00:00
|
|
|
if (nsnull == mTitle) {
|
|
|
|
mTitle = new nsString(aValue);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
*mTitle = aValue;
|
|
|
|
}
|
|
|
|
mTitle->CompressWhitespace(PR_TRUE, PR_TRUE);
|
|
|
|
((nsHTMLDocument*)mDocument)->SetTitle(*mTitle);
|
1998-06-26 16:12:51 +00:00
|
|
|
|
|
|
|
nsIAtom* atom = NS_NewAtom("TITLE");
|
|
|
|
nsIHTMLContent* it = nsnull;
|
|
|
|
nsresult rv = NS_NewHTMLTitle(&it, atom, aValue);
|
|
|
|
if (NS_OK == rv) {
|
|
|
|
mHead->AppendChild(it, PR_FALSE);
|
|
|
|
}
|
|
|
|
NS_RELEASE(atom);
|
1998-07-15 22:31:10 +00:00
|
|
|
return NS_OK;
|
1998-04-13 20:24:54 +00:00
|
|
|
}
|
|
|
|
|
1998-07-15 22:31:10 +00:00
|
|
|
NS_IMETHODIMP
|
1998-06-27 22:57:52 +00:00
|
|
|
HTMLContentSink::OpenBody(const nsIParserNode& aNode)
|
1998-04-13 20:24:54 +00:00
|
|
|
{
|
1998-06-27 22:57:52 +00:00
|
|
|
FlushText();
|
|
|
|
|
1998-07-11 03:51:50 +00:00
|
|
|
SINK_TRACE_NODE(SINK_TRACE_CALLS,
|
|
|
|
"HTMLContentSink::OpenBody", aNode);
|
1998-04-13 20:24:54 +00:00
|
|
|
|
|
|
|
mNodeStack[mStackPos] = (eHTMLTags)aNode.GetNodeType();
|
1998-07-20 18:52:40 +00:00
|
|
|
|
|
|
|
// Make body container
|
1998-07-27 18:04:38 +00:00
|
|
|
NS_ASSERTION(nsnull == mBody, "yikes");
|
1998-07-20 18:52:40 +00:00
|
|
|
NS_IF_RELEASE(mBody);
|
|
|
|
nsIAtom* atom = NS_NewAtom("BODY");
|
|
|
|
if (nsnull == atom) {
|
|
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
|
|
}
|
|
|
|
nsresult rv = NS_NewBodyPart(&mBody, atom);
|
|
|
|
NS_RELEASE(atom);
|
|
|
|
if (NS_OK != rv) {
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
1998-04-13 20:24:54 +00:00
|
|
|
mContainerStack[mStackPos] = mBody;
|
|
|
|
mStackPos++;
|
|
|
|
|
|
|
|
// Add attributes to the body content object, but only if it's really a body
|
|
|
|
// tag that is triggering the OpenBody.
|
1998-07-14 01:57:51 +00:00
|
|
|
if (eHTMLTag_body == aNode.GetNodeType()) {
|
1998-04-13 20:24:54 +00:00
|
|
|
AddAttributes(aNode, mBody);
|
|
|
|
// XXX If the body already existed and has been reflowed somewhat
|
|
|
|
// then we need to trigger a style change
|
|
|
|
}
|
|
|
|
|
1998-07-06 22:15:55 +00:00
|
|
|
if (!mLayoutStarted) {
|
1998-04-13 20:24:54 +00:00
|
|
|
// XXX This has to be done now that the body is in because we
|
|
|
|
// don't know how to handle a content-appended reflow if the
|
|
|
|
// root has no children
|
1998-06-30 23:51:53 +00:00
|
|
|
SINK_TRACE(SINK_TRACE_REFLOW,
|
|
|
|
("HTMLContentSink::OpenBody: start layout"));
|
1998-07-08 23:15:32 +00:00
|
|
|
|
|
|
|
// This is done here instead of earlier because we need the
|
|
|
|
// attributes from the real body tag before we initiate reflow.
|
|
|
|
mRoot->AppendChild(mBody, PR_FALSE);
|
1998-04-13 20:24:54 +00:00
|
|
|
StartLayout();
|
|
|
|
}
|
|
|
|
|
1998-07-15 22:31:10 +00:00
|
|
|
return NS_OK;
|
1998-04-13 20:24:54 +00:00
|
|
|
}
|
|
|
|
|
1998-07-15 22:31:10 +00:00
|
|
|
NS_IMETHODIMP
|
1998-06-27 22:57:52 +00:00
|
|
|
HTMLContentSink::CloseBody(const nsIParserNode& aNode)
|
1998-04-13 20:24:54 +00:00
|
|
|
{
|
1998-06-27 22:57:52 +00:00
|
|
|
FlushText();
|
|
|
|
|
1998-07-11 03:51:50 +00:00
|
|
|
SINK_TRACE_NODE(SINK_TRACE_CALLS,
|
|
|
|
"HTMLContentSink::CloseBody", aNode);
|
1998-04-13 20:24:54 +00:00
|
|
|
|
|
|
|
NS_ASSERTION(mStackPos > 0, "bad bad");
|
|
|
|
mNodeStack[--mStackPos] = eHTMLTag_unknown;
|
|
|
|
|
|
|
|
// Reflow any lingering content
|
|
|
|
|
1998-07-15 22:31:10 +00:00
|
|
|
return NS_OK;
|
1998-04-13 20:24:54 +00:00
|
|
|
}
|
|
|
|
|
1998-04-22 22:12:24 +00:00
|
|
|
static NS_DEFINE_IID(kIFormManagerIID, NS_IFORMMANAGER_IID);
|
1998-04-13 20:24:54 +00:00
|
|
|
|
1998-07-15 22:31:10 +00:00
|
|
|
NS_IMETHODIMP
|
1998-06-27 22:57:52 +00:00
|
|
|
HTMLContentSink::OpenForm(const nsIParserNode& aNode)
|
1998-04-13 20:24:54 +00:00
|
|
|
{
|
1998-06-27 22:57:52 +00:00
|
|
|
FlushText();
|
|
|
|
|
1998-07-11 03:51:50 +00:00
|
|
|
SINK_TRACE_NODE(SINK_TRACE_CALLS,
|
|
|
|
"HTMLContentSink::OpenForm", aNode);
|
1998-04-13 20:24:54 +00:00
|
|
|
|
|
|
|
// Close out previous form if it's there
|
|
|
|
if (nsnull != mCurrentForm) {
|
|
|
|
NS_RELEASE(mCurrentForm);
|
|
|
|
mCurrentForm = nsnull;
|
|
|
|
}
|
|
|
|
|
1998-04-22 22:12:24 +00:00
|
|
|
nsresult rv;
|
|
|
|
nsAutoString classID;
|
|
|
|
if (FindAttribute(aNode, "classid", classID)) {
|
|
|
|
// Translate classid string into an nsID
|
|
|
|
char cbuf[50];
|
|
|
|
classID.ToCString(cbuf, sizeof(cbuf));
|
|
|
|
nsID clid;
|
|
|
|
if (clid.Parse(cbuf)) {
|
|
|
|
// Create a form manager using the repository
|
|
|
|
nsIFactory* fac;
|
|
|
|
rv = NSRepository::FindFactory(clid, &fac);
|
|
|
|
if (NS_OK == rv) {
|
|
|
|
rv = fac->CreateInstance(nsnull, kIFormManagerIID,
|
|
|
|
(void**)&mCurrentForm);
|
|
|
|
#ifdef NS_DEBUG
|
|
|
|
if (NS_OK != rv) {
|
|
|
|
printf("OpenForm: can't create form manager instance: %d\n", rv);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
NS_RELEASE(fac);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
#ifdef NS_DEBUG
|
|
|
|
printf("OpenForm: can't find '%s' in the repository\n", cbuf);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
#ifdef NS_DEBUG
|
|
|
|
printf("OpenForm: classID is invalid: '%s'\n", cbuf);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (nsnull == mCurrentForm) {
|
|
|
|
// Create new form
|
1998-07-14 01:57:51 +00:00
|
|
|
nsAutoString tmp("FORM");
|
1998-04-22 22:12:24 +00:00
|
|
|
nsIAtom* atom = NS_NewAtom(tmp);
|
|
|
|
rv = NS_NewHTMLForm(&mCurrentForm, atom);
|
|
|
|
NS_RELEASE(atom);
|
|
|
|
}
|
1998-04-13 20:24:54 +00:00
|
|
|
|
|
|
|
if (NS_OK == rv) {
|
|
|
|
// Add tag attributes to the form
|
|
|
|
nsAutoString k, v;
|
|
|
|
PRInt32 ac = aNode.GetAttributeCount();
|
|
|
|
for (PRInt32 i = 0; i < ac; i++) {
|
|
|
|
// Get upper-cased key
|
|
|
|
const nsString& key = aNode.GetKeyAt(i);
|
|
|
|
k.SetLength(0);
|
|
|
|
k.Append(key);
|
|
|
|
k.ToUpperCase();
|
|
|
|
|
|
|
|
// Get value and remove mandatory quotes
|
|
|
|
GetAttributeValueAt(aNode, i, v);
|
|
|
|
mCurrentForm->SetAttribute(k, v);
|
|
|
|
}
|
1998-08-04 00:05:22 +00:00
|
|
|
// XXX Temporary code till forms become real content
|
|
|
|
// Add the form to the document
|
|
|
|
((nsHTMLDocument*)mDocument)->AddForm(mCurrentForm);
|
1998-04-13 20:24:54 +00:00
|
|
|
}
|
|
|
|
|
1998-07-15 22:31:10 +00:00
|
|
|
return NS_OK;
|
1998-04-13 20:24:54 +00:00
|
|
|
}
|
|
|
|
|
1998-07-15 22:31:10 +00:00
|
|
|
NS_IMETHODIMP
|
1998-06-27 22:57:52 +00:00
|
|
|
HTMLContentSink::CloseForm(const nsIParserNode& aNode)
|
1998-04-13 20:24:54 +00:00
|
|
|
{
|
1998-06-27 22:57:52 +00:00
|
|
|
FlushText();
|
|
|
|
|
1998-07-11 03:51:50 +00:00
|
|
|
SINK_TRACE_NODE(SINK_TRACE_CALLS,
|
|
|
|
"HTMLContentSink::CloseForm", aNode);
|
1998-04-13 20:24:54 +00:00
|
|
|
|
|
|
|
if (nsnull != mCurrentForm) {
|
|
|
|
NS_RELEASE(mCurrentForm);
|
|
|
|
mCurrentForm = nsnull;
|
|
|
|
}
|
1998-07-15 22:31:10 +00:00
|
|
|
return NS_OK;
|
1998-04-13 20:24:54 +00:00
|
|
|
}
|
|
|
|
|
1998-07-20 18:52:40 +00:00
|
|
|
// XXX this is a copy of OpenBody, consolidate!
|
|
|
|
NS_IMETHODIMP
|
|
|
|
HTMLContentSink::OpenFrameset(const nsIParserNode& aNode)
|
|
|
|
{
|
|
|
|
FlushText();
|
|
|
|
|
|
|
|
SINK_TRACE_NODE(SINK_TRACE_CALLS,
|
|
|
|
"HTMLContentSink::OpenFrameset", aNode);
|
|
|
|
|
|
|
|
mNodeStack[mStackPos] = (eHTMLTags)aNode.GetNodeType();
|
|
|
|
|
|
|
|
// Make frameset container
|
|
|
|
NS_IF_RELEASE(mFrameset);
|
|
|
|
nsIAtom* atom = NS_NewAtom("FRAMESET");
|
|
|
|
if (nsnull == atom) {
|
|
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
|
|
}
|
|
|
|
nsresult rv = NS_NewHTMLFrameset(&mFrameset, atom, nsnull);
|
1998-07-21 23:20:04 +00:00
|
|
|
mFrameset->SetDocument(mDocument);
|
1998-07-20 18:52:40 +00:00
|
|
|
NS_RELEASE(atom);
|
|
|
|
if (NS_OK != rv) {
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
mContainerStack[mStackPos] = mFrameset;
|
|
|
|
mStackPos++;
|
|
|
|
|
|
|
|
// Add attributes to the frameset content object
|
|
|
|
AddAttributes(aNode, mFrameset);
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
HTMLContentSink::CloseFrameset(const nsIParserNode& aNode)
|
|
|
|
{
|
|
|
|
FlushText();
|
|
|
|
|
1998-07-21 23:20:04 +00:00
|
|
|
mRoot->AppendChild(mFrameset, PR_TRUE);
|
|
|
|
|
1998-07-20 18:52:40 +00:00
|
|
|
SINK_TRACE_NODE(SINK_TRACE_CALLS,
|
|
|
|
"HTMLContentSink::CloseFrameset", aNode);
|
|
|
|
|
|
|
|
NS_ASSERTION(mStackPos > 0, "bad bad");
|
|
|
|
mNodeStack[--mStackPos] = eHTMLTag_unknown;
|
|
|
|
|
|
|
|
// Reflow any lingering content
|
|
|
|
if (!mLayoutStarted) {
|
|
|
|
StartLayout();
|
|
|
|
}
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
1998-07-15 22:31:10 +00:00
|
|
|
NS_IMETHODIMP
|
|
|
|
HTMLContentSink::OpenMap(const nsIParserNode& aNode)
|
|
|
|
{
|
|
|
|
FlushText();
|
|
|
|
|
|
|
|
SINK_TRACE_NODE(SINK_TRACE_CALLS,
|
|
|
|
"HTMLContentSink::OpenMap", aNode);
|
|
|
|
|
|
|
|
// Close out previous form if it's there
|
|
|
|
if (nsnull != mCurrentMap) {
|
|
|
|
NS_RELEASE(mCurrentMap);
|
|
|
|
mCurrentMap = nsnull;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsAutoString tmp("MAP");
|
|
|
|
nsIAtom* atom = NS_NewAtom(tmp);
|
|
|
|
nsresult rv = NS_NewImageMap(&mCurrentMap, atom);
|
|
|
|
NS_RELEASE(atom);
|
|
|
|
if (NS_OK == rv) {
|
|
|
|
// Look for name attribute and set the map name
|
|
|
|
nsAutoString name;
|
|
|
|
if (FindAttribute(aNode, "name", name)) {
|
|
|
|
// XXX leading, trailing, interior non=-space ws is removed
|
|
|
|
name.StripWhitespace();
|
|
|
|
mCurrentMap->SetName(name);
|
|
|
|
}
|
|
|
|
// Add the map to the document
|
|
|
|
((nsHTMLDocument*)mDocument)->AddImageMap(mCurrentMap);
|
|
|
|
}
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
HTMLContentSink::CloseMap(const nsIParserNode& aNode)
|
|
|
|
{
|
|
|
|
FlushText();
|
|
|
|
|
|
|
|
SINK_TRACE_NODE(SINK_TRACE_CALLS,
|
|
|
|
"HTMLContentSink::CloseMap", aNode);
|
|
|
|
|
|
|
|
if (nsnull != mCurrentMap) {
|
|
|
|
NS_RELEASE(mCurrentMap);
|
|
|
|
mCurrentMap = nsnull;
|
|
|
|
}
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
1998-04-13 20:24:54 +00:00
|
|
|
|
1998-07-15 22:31:10 +00:00
|
|
|
NS_IMETHODIMP
|
1998-06-27 22:57:52 +00:00
|
|
|
HTMLContentSink::OpenContainer(const nsIParserNode& aNode)
|
1998-04-13 20:24:54 +00:00
|
|
|
{
|
1998-06-27 22:57:52 +00:00
|
|
|
FlushText();
|
|
|
|
|
1998-07-11 03:51:50 +00:00
|
|
|
SINK_TRACE_NODE(SINK_TRACE_CALLS,
|
|
|
|
"HTMLContentSink::OpenContainer", aNode);
|
1998-04-13 20:24:54 +00:00
|
|
|
|
1998-07-14 01:57:51 +00:00
|
|
|
nsHTMLTag nodeType = nsHTMLTag(aNode.GetNodeType());/* XXX bad parser api */
|
|
|
|
nsAutoString tmp;
|
|
|
|
if (eHTMLTag_userdefined == nodeType) {
|
|
|
|
tmp.Append(aNode.GetText());
|
|
|
|
tmp.ToUpperCase();
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
tmp.Append(NS_EnumToTag(nodeType));
|
|
|
|
}
|
1998-04-13 20:24:54 +00:00
|
|
|
nsIAtom* atom = NS_NewAtom(tmp);
|
|
|
|
|
1998-04-22 23:24:43 +00:00
|
|
|
eHTMLTags parentType;
|
|
|
|
nsIHTMLContent* parent = GetCurrentContainer(&parentType);
|
|
|
|
switch (parentType) {
|
|
|
|
case eHTMLTag_select:
|
|
|
|
break;
|
|
|
|
case eHTMLTag_option:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
1998-04-13 20:24:54 +00:00
|
|
|
nsresult rv;
|
|
|
|
nsIHTMLContent* container = nsnull;
|
1998-07-14 01:57:51 +00:00
|
|
|
switch (nodeType) {
|
|
|
|
case eHTMLTag_map:
|
1998-07-15 22:31:10 +00:00
|
|
|
NS_NOTREACHED("bad parser: map != container");
|
|
|
|
break;
|
1998-04-13 20:24:54 +00:00
|
|
|
|
1998-07-15 00:22:15 +00:00
|
|
|
case eHTMLTag_applet:
|
|
|
|
rv = NS_NewHTMLApplet(&container, atom);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case eHTMLTag_object:
|
|
|
|
rv = NS_NewHTMLObject(&container, atom);
|
|
|
|
break;
|
|
|
|
|
1998-07-14 01:57:51 +00:00
|
|
|
case eHTMLTag_table:
|
|
|
|
rv = NS_NewTablePart(&container, atom);
|
|
|
|
mInMonolithicContainer++;
|
|
|
|
break;
|
1998-04-13 20:24:54 +00:00
|
|
|
|
1998-07-14 01:57:51 +00:00
|
|
|
case eHTMLTag_caption:
|
|
|
|
rv = NS_NewTableCaptionPart(&container, atom);
|
|
|
|
break;
|
1998-04-13 20:24:54 +00:00
|
|
|
|
1998-07-14 01:57:51 +00:00
|
|
|
case eHTMLTag_tr:
|
|
|
|
rv = NS_NewTableRowPart(&container, atom);
|
|
|
|
break;
|
1998-04-13 20:24:54 +00:00
|
|
|
|
1998-07-14 01:57:51 +00:00
|
|
|
case eHTMLTag_tbody:
|
|
|
|
case eHTMLTag_thead:
|
|
|
|
case eHTMLTag_tfoot:
|
|
|
|
rv = NS_NewTableRowGroupPart(&container, atom);
|
|
|
|
break;
|
1998-04-13 20:24:54 +00:00
|
|
|
|
1998-07-14 01:57:51 +00:00
|
|
|
case eHTMLTag_colgroup:
|
|
|
|
rv = NS_NewTableColGroupPart(&container, atom);
|
|
|
|
break;
|
1998-04-13 20:24:54 +00:00
|
|
|
|
1998-07-14 01:57:51 +00:00
|
|
|
case eHTMLTag_col:
|
|
|
|
rv = NS_NewTableColPart(&container, atom);
|
|
|
|
break;
|
1998-04-13 20:24:54 +00:00
|
|
|
|
1998-07-14 01:57:51 +00:00
|
|
|
case eHTMLTag_td:
|
|
|
|
case eHTMLTag_th:
|
|
|
|
rv = NS_NewTableCellPart(&container, atom);
|
|
|
|
break;
|
1998-04-13 20:24:54 +00:00
|
|
|
|
1998-07-14 01:57:51 +00:00
|
|
|
case eHTMLTag_select:
|
|
|
|
rv = ProcessOpenSELECTTag(&container, aNode);
|
|
|
|
break;
|
1998-04-22 23:24:43 +00:00
|
|
|
|
1998-07-14 01:57:51 +00:00
|
|
|
case eHTMLTag_option:
|
|
|
|
rv = ProcessOpenOPTIONTag(&container, aNode);
|
|
|
|
break;
|
1998-04-22 23:24:43 +00:00
|
|
|
|
1998-07-14 01:57:51 +00:00
|
|
|
case eHTMLTag_iframe:
|
|
|
|
rv = ProcessIFRAMETag(&container, aNode);
|
|
|
|
break;
|
1998-06-11 16:46:33 +00:00
|
|
|
|
1998-07-20 18:52:40 +00:00
|
|
|
case eHTMLTag_frameset:
|
|
|
|
if (!mFrameset) {
|
|
|
|
rv = OpenFrameset(aNode); // top level frameset
|
|
|
|
} else {
|
|
|
|
rv = ProcessFRAMESETTag(&container, aNode);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
1998-07-14 01:57:51 +00:00
|
|
|
default:
|
|
|
|
rv = NS_NewHTMLContainer(&container, atom);
|
|
|
|
break;
|
1998-04-13 20:24:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// XXX for now assume that if it's a container, it's a simple container
|
|
|
|
mNodeStack[mStackPos] = (eHTMLTags) aNode.GetNodeType();
|
|
|
|
mContainerStack[mStackPos] = container;
|
|
|
|
|
|
|
|
if (nsnull != container) {
|
|
|
|
container->SetDocument(mDocument);
|
|
|
|
rv = AddAttributes(aNode, container);
|
1998-07-24 18:20:27 +00:00
|
|
|
if (eHTMLTag_a == nodeType) {
|
|
|
|
AddBaseTagInfo(container);
|
|
|
|
if ((nsnull != mRef) && (nsnull == mRefContent)) {
|
|
|
|
nsHTMLValue value;
|
|
|
|
container->GetAttribute(nsHTMLAtoms::name, value);
|
|
|
|
if (eHTMLUnit_String == value.GetUnit()) {
|
|
|
|
nsAutoString tmp;
|
|
|
|
value.GetStringValue(tmp);
|
|
|
|
if (mRef->EqualsIgnoreCase(tmp)) {
|
|
|
|
// Winner. We just found the content that is the named anchor
|
|
|
|
mRefContent = container;
|
|
|
|
NS_ADDREF(container);
|
|
|
|
}
|
1998-07-22 23:42:47 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
1998-04-13 20:24:54 +00:00
|
|
|
mStackPos++;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_RELEASE(atom);
|
1998-07-15 22:31:10 +00:00
|
|
|
return rv;
|
1998-04-13 20:24:54 +00:00
|
|
|
}
|
|
|
|
|
1998-07-15 22:31:10 +00:00
|
|
|
NS_IMETHODIMP
|
1998-06-27 22:57:52 +00:00
|
|
|
HTMLContentSink::CloseContainer(const nsIParserNode& aNode)
|
1998-04-13 20:24:54 +00:00
|
|
|
{
|
1998-06-27 22:57:52 +00:00
|
|
|
FlushText();
|
|
|
|
|
1998-07-11 03:51:50 +00:00
|
|
|
SINK_TRACE_NODE(SINK_TRACE_CALLS,
|
|
|
|
"HTMLContentSink::CloseContainer", aNode);
|
1998-04-13 20:24:54 +00:00
|
|
|
|
|
|
|
switch (aNode.GetNodeType()) {
|
|
|
|
case eHTMLTag_map:
|
1998-07-15 22:31:10 +00:00
|
|
|
NS_NOTREACHED("bad parser: map's in CloseContainer");
|
1998-04-13 20:24:54 +00:00
|
|
|
NS_IF_RELEASE(mCurrentMap);
|
1998-07-15 22:31:10 +00:00
|
|
|
return NS_OK;
|
1998-07-27 18:04:38 +00:00
|
|
|
case eHTMLTag_body:
|
|
|
|
case eHTMLTag_html:
|
|
|
|
case eHTMLTag_head:
|
|
|
|
NS_NOTREACHED("bad parser: calling CloseContainer for bad tag");
|
|
|
|
return NS_OK;
|
1998-04-13 20:24:54 +00:00
|
|
|
}
|
|
|
|
|
1998-07-14 01:57:51 +00:00
|
|
|
// XXX we could assert things about the top tag name
|
1998-04-13 20:24:54 +00:00
|
|
|
if (0 == mStackPos) {
|
|
|
|
// Can't pop empty stack
|
1998-07-15 22:31:10 +00:00
|
|
|
return NS_OK;
|
1998-04-13 20:24:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
--mStackPos;
|
|
|
|
nsIHTMLContent* container = mContainerStack[mStackPos];
|
|
|
|
mNodeStack[mStackPos] = eHTMLTag_unknown;
|
|
|
|
mContainerStack[mStackPos] = nsnull;
|
|
|
|
|
1998-04-22 23:24:43 +00:00
|
|
|
|
1998-05-13 17:43:35 +00:00
|
|
|
nsIHTMLContent* parent = nsnull;
|
|
|
|
|
1998-04-22 23:24:43 +00:00
|
|
|
switch (aNode.GetNodeType()) {
|
|
|
|
case eHTMLTag_option:
|
|
|
|
ProcessCloseOPTIONTag(aNode);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case eHTMLTag_select:
|
1998-05-13 17:43:35 +00:00
|
|
|
ProcessCloseSELECTTag(aNode); // add fall through
|
1998-06-03 15:58:52 +00:00
|
|
|
break;
|
1998-04-22 23:24:43 +00:00
|
|
|
|
1998-06-03 15:58:52 +00:00
|
|
|
case eHTMLTag_table:
|
|
|
|
mInMonolithicContainer--;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (nsnull != container) {
|
|
|
|
// Now that this container is complete, append it to it's parent
|
|
|
|
eHTMLTags parentType;
|
|
|
|
parent = GetCurrentContainer(&parentType);
|
|
|
|
container->Compact();
|
1998-07-20 18:52:40 +00:00
|
|
|
// don't append the top level frameset to its parent, this was done in OpenFrameset
|
|
|
|
// XXX this is necessary because the parser is calling OpenContainer, CloseContainer
|
|
|
|
// on framesets. It should be calling OpenFrameset.
|
|
|
|
if (container == mFrameset) {
|
|
|
|
return CloseFrameset(aNode);
|
|
|
|
}
|
1998-06-03 15:58:52 +00:00
|
|
|
|
|
|
|
if (nsnull != parent) {
|
1998-07-20 18:52:40 +00:00
|
|
|
PRBool allowReflow = parent == GetBodyOrFrameset();
|
1998-06-30 23:51:53 +00:00
|
|
|
#ifdef NS_DEBUG
|
|
|
|
if (allowReflow) {
|
|
|
|
SINK_TRACE(SINK_TRACE_REFLOW,
|
|
|
|
("HTMLContentSink::CloseContainer: reflow after append"));
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
1998-07-12 00:18:26 +00:00
|
|
|
AppendToCorrectParent(parentType, parent,
|
|
|
|
(nsHTMLTag) aNode.GetNodeType(), container,
|
|
|
|
allowReflow);
|
1998-07-08 23:15:32 +00:00
|
|
|
#ifdef NS_DEBUG
|
|
|
|
if (allowReflow && (((PRInt32)gSinkLogModuleInfo->level) > 127)) {
|
1998-08-05 01:43:42 +00:00
|
|
|
mRoot->List(stdout, 0);
|
1998-07-09 17:08:40 +00:00
|
|
|
PRInt32 i, ns = mDocument->GetNumberOfShells();
|
|
|
|
for (i = 0; i < ns; i++) {
|
|
|
|
nsIPresShell* shell = mDocument->GetShellAt(i);
|
|
|
|
if (nsnull != shell) {
|
|
|
|
nsIViewManager* vm = shell->GetViewManager();
|
|
|
|
if(vm) {
|
|
|
|
nsIView* rootView = vm->GetRootView();
|
|
|
|
nsRect rect;
|
|
|
|
rootView->GetBounds(rect);
|
|
|
|
rect.x = 0;
|
|
|
|
rect.y = 0;
|
1998-07-24 21:05:50 +00:00
|
|
|
vm->UpdateView(rootView, rect, NS_VMREFRESH_IMMEDIATE);
|
1998-07-09 17:08:40 +00:00
|
|
|
NS_RELEASE(rootView);
|
|
|
|
}
|
|
|
|
NS_RELEASE(vm);
|
|
|
|
NS_RELEASE(shell);
|
|
|
|
}
|
|
|
|
}
|
1998-07-08 23:15:32 +00:00
|
|
|
printf("tick...\n");
|
|
|
|
PR_Sleep(PR_SecondsToInterval(3));
|
|
|
|
}
|
|
|
|
#endif
|
1998-06-03 15:58:52 +00:00
|
|
|
#if XXX
|
1998-07-20 18:52:40 +00:00
|
|
|
if (parent == GetBodyOrFrameset()) {
|
1998-06-03 15:58:52 +00:00
|
|
|
// We just closed a child of the body off. Trigger a
|
|
|
|
// content-appended reflow if enough time has elapsed
|
|
|
|
PRTime now = PR_Now();
|
|
|
|
/* XXX this expression doesn't compile on the Mac
|
|
|
|
kipp said it had to do with a type issue.
|
|
|
|
if (now - mLastUpdateTime >= mUpdateDelta) {
|
|
|
|
mLastUpdateTime = now;
|
|
|
|
mUpdateDelta += mUpdateDelta;
|
|
|
|
ReflowNewContent();
|
|
|
|
}*/
|
1998-04-13 20:24:54 +00:00
|
|
|
}
|
1998-06-03 15:58:52 +00:00
|
|
|
#endif
|
1998-04-13 20:24:54 +00:00
|
|
|
}
|
1998-07-27 18:04:38 +00:00
|
|
|
NS_ASSERTION(container != mBody, "whoops");
|
1998-06-03 15:58:52 +00:00
|
|
|
NS_RELEASE(container);
|
1998-04-13 20:24:54 +00:00
|
|
|
}
|
1998-04-22 23:24:43 +00:00
|
|
|
|
1998-07-15 22:31:10 +00:00
|
|
|
return NS_OK;
|
1998-04-13 20:24:54 +00:00
|
|
|
}
|
|
|
|
|
1998-06-27 22:57:52 +00:00
|
|
|
/**
|
|
|
|
* This method gets called when the parser begins the process
|
|
|
|
* of building the content model via the content sink.
|
|
|
|
*
|
|
|
|
* @update 5/7/98 gess
|
|
|
|
*/
|
1998-07-15 22:31:10 +00:00
|
|
|
NS_IMETHODIMP
|
1998-06-27 22:57:52 +00:00
|
|
|
HTMLContentSink::WillBuildModel(void)
|
|
|
|
{
|
1998-07-30 16:06:22 +00:00
|
|
|
// Make root part
|
|
|
|
NS_IF_RELEASE(mRoot);
|
|
|
|
nsresult rv = NS_NewRootPart(&mRoot, mDocument);
|
|
|
|
if (NS_OK != rv) {
|
|
|
|
return rv;
|
1998-06-27 22:57:52 +00:00
|
|
|
}
|
|
|
|
|
1998-07-30 16:06:22 +00:00
|
|
|
// Make head container
|
|
|
|
NS_IF_RELEASE(mHead);
|
|
|
|
nsIAtom* atom = NS_NewAtom("HEAD");
|
|
|
|
if (nsnull == atom) {
|
|
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
|
|
}
|
|
|
|
rv = NS_NewHTMLHead(&mHead, atom);
|
|
|
|
NS_RELEASE(atom);
|
|
|
|
if (NS_OK != rv) {
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
mRoot->AppendChild(mHead, PR_FALSE);
|
|
|
|
|
|
|
|
// Notify document that the load is beginning
|
|
|
|
mDocument->BeginLoad();
|
|
|
|
|
1998-07-15 22:31:10 +00:00
|
|
|
return NS_OK;
|
1998-06-27 22:57:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* This method gets called when the parser concludes the process
|
|
|
|
* of building the content model via the content sink.
|
|
|
|
*
|
|
|
|
* @param aQualityLevel describes how well formed the doc was.
|
|
|
|
* 0=GOOD; 1=FAIR; 2=POOR;
|
|
|
|
* @update 6/21/98 gess
|
|
|
|
*/
|
1998-07-15 22:31:10 +00:00
|
|
|
NS_IMETHODIMP
|
1998-06-30 23:51:53 +00:00
|
|
|
HTMLContentSink::DidBuildModel(PRInt32 aQualityLevel)
|
|
|
|
{
|
1998-06-27 22:57:52 +00:00
|
|
|
PRInt32 i, ns = mDocument->GetNumberOfShells();
|
|
|
|
for (i = 0; i < ns; i++) {
|
|
|
|
nsIPresShell* shell = mDocument->GetShellAt(i);
|
|
|
|
if (nsnull != shell) {
|
|
|
|
nsIViewManager* vm = shell->GetViewManager();
|
|
|
|
if(vm) {
|
|
|
|
vm->SetQuality(nsContentQuality(aQualityLevel));
|
|
|
|
}
|
|
|
|
NS_RELEASE(vm);
|
|
|
|
NS_RELEASE(shell);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1998-07-23 15:29:04 +00:00
|
|
|
// XXX sigh
|
|
|
|
ScrollToRef();
|
|
|
|
|
1998-06-30 23:51:53 +00:00
|
|
|
SINK_TRACE(SINK_TRACE_REFLOW,
|
|
|
|
("HTMLContentSink::DidBuildModel: layout new content"));
|
1998-06-27 22:57:52 +00:00
|
|
|
ReflowNewContent();
|
|
|
|
mDocument->EndLoad();
|
1998-07-15 22:31:10 +00:00
|
|
|
|
|
|
|
return NS_OK;
|
1998-06-27 22:57:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* This method gets called when the parser gets i/o blocked,
|
|
|
|
* and wants to notify the sink that it may be a while before
|
|
|
|
* more data is available.
|
|
|
|
*
|
|
|
|
* @update 5/7/98 gess
|
|
|
|
*/
|
1998-07-15 22:31:10 +00:00
|
|
|
NS_IMETHODIMP
|
1998-06-27 22:57:52 +00:00
|
|
|
HTMLContentSink::WillInterrupt(void)
|
|
|
|
{
|
1998-07-27 18:04:38 +00:00
|
|
|
SINK_TRACE(SINK_TRACE_CALLS,
|
|
|
|
("HTMLContentSink::WillInterrupt: this=%p", this));
|
1998-07-15 22:31:10 +00:00
|
|
|
return NS_OK;
|
1998-06-27 22:57:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* This method gets called when the parser i/o gets unblocked,
|
|
|
|
* and we're about to start dumping content again to the sink.
|
|
|
|
*
|
|
|
|
* @update 5/7/98 gess
|
|
|
|
*/
|
1998-07-15 22:31:10 +00:00
|
|
|
NS_IMETHODIMP
|
1998-06-27 22:57:52 +00:00
|
|
|
HTMLContentSink::WillResume(void)
|
|
|
|
{
|
1998-07-27 18:04:38 +00:00
|
|
|
SINK_TRACE(SINK_TRACE_CALLS,
|
|
|
|
("HTMLContentSink::WillResume: this=%p", this));
|
1998-07-15 22:31:10 +00:00
|
|
|
return NS_OK;
|
1998-06-27 22:57:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
|
1998-07-22 23:42:47 +00:00
|
|
|
void
|
|
|
|
HTMLContentSink::StartLayout()
|
1998-04-13 20:24:54 +00:00
|
|
|
{
|
|
|
|
if (!mLayoutStarted) {
|
|
|
|
PRInt32 i, ns = mDocument->GetNumberOfShells();
|
|
|
|
for (i = 0; i < ns; i++) {
|
|
|
|
nsIPresShell* shell = mDocument->GetShellAt(i);
|
|
|
|
if (nsnull != shell) {
|
1998-06-30 23:51:53 +00:00
|
|
|
// Make shell an observer for next time
|
|
|
|
shell->BeginObservingDocument();
|
|
|
|
|
|
|
|
// Resize-reflow this time
|
1998-04-13 20:24:54 +00:00
|
|
|
nsIPresContext* cx = shell->GetPresContext();
|
1998-05-22 18:38:33 +00:00
|
|
|
nsRect r;
|
|
|
|
cx->GetVisibleArea(r);
|
1998-04-13 20:24:54 +00:00
|
|
|
shell->ResizeReflow(r.width, r.height);
|
|
|
|
NS_RELEASE(cx);
|
1998-07-30 16:06:22 +00:00
|
|
|
|
|
|
|
// Now trigger a refresh
|
|
|
|
nsIViewManager* vm = shell->GetViewManager();
|
|
|
|
if (nsnull != vm) {
|
|
|
|
vm->EnableRefresh();
|
|
|
|
NS_RELEASE(vm);
|
|
|
|
}
|
|
|
|
|
1998-04-13 20:24:54 +00:00
|
|
|
NS_RELEASE(shell);
|
|
|
|
}
|
|
|
|
}
|
1998-07-22 23:42:47 +00:00
|
|
|
|
1998-07-27 05:59:37 +00:00
|
|
|
// If the document we are loading has a reference or it is a top level
|
|
|
|
// frameset document, disable the scroll bars on the views.
|
1998-07-22 23:42:47 +00:00
|
|
|
const char* ref = mDocumentURL->GetRef();
|
|
|
|
if (nsnull != ref) {
|
|
|
|
mRef = new nsString(ref);
|
1998-07-27 05:59:37 +00:00
|
|
|
}
|
|
|
|
PRBool topLevelFrameset = PR_FALSE;
|
|
|
|
if (mFrameset && mWebShell) {
|
|
|
|
nsIWebShell* rootWebShell;
|
|
|
|
mWebShell->GetRootWebShell(rootWebShell);
|
|
|
|
if (mWebShell == rootWebShell) {
|
|
|
|
topLevelFrameset = PR_TRUE;
|
|
|
|
}
|
|
|
|
NS_IF_RELEASE(rootWebShell);
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((nsnull != ref) || topLevelFrameset) {
|
1998-07-22 23:42:47 +00:00
|
|
|
// XXX support more than one presentation-shell here
|
|
|
|
|
|
|
|
// Get initial scroll preference and save it away; disable the
|
|
|
|
// scroll bars.
|
|
|
|
PRInt32 i, ns = mDocument->GetNumberOfShells();
|
|
|
|
for (i = 0; i < ns; i++) {
|
|
|
|
nsIPresShell* shell = mDocument->GetShellAt(i);
|
|
|
|
if (nsnull != shell) {
|
|
|
|
nsIViewManager* vm = shell->GetViewManager();
|
|
|
|
if (nsnull != vm) {
|
|
|
|
nsIView* rootView = vm->GetRootView();
|
|
|
|
if (nsnull != rootView) {
|
|
|
|
nsIScrollableView* sview = nsnull;
|
|
|
|
rootView->QueryInterface(kIScrollableViewIID, (void**) &sview);
|
|
|
|
if (nsnull != sview) {
|
1998-07-27 05:59:37 +00:00
|
|
|
mOriginalScrollPreference = (topLevelFrameset)
|
|
|
|
? nsScrollPreference_kNeverScroll
|
|
|
|
: sview->GetScrollPreference();
|
1998-07-22 23:42:47 +00:00
|
|
|
sview->SetScrollPreference(nsScrollPreference_kNeverScroll);
|
|
|
|
NS_RELEASE(sview);
|
|
|
|
}
|
|
|
|
NS_RELEASE(rootView);
|
|
|
|
}
|
|
|
|
NS_RELEASE(vm);
|
|
|
|
}
|
|
|
|
NS_RELEASE(shell);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1998-04-13 20:24:54 +00:00
|
|
|
mLayoutStarted = PR_TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1998-07-22 23:42:47 +00:00
|
|
|
void
|
|
|
|
HTMLContentSink::ReflowNewContent()
|
1998-04-13 20:24:54 +00:00
|
|
|
{
|
1998-07-16 18:19:53 +00:00
|
|
|
// Trigger reflows in each of the presentation shells
|
|
|
|
mDocument->ContentAppended(mBody);
|
1998-07-23 15:29:04 +00:00
|
|
|
// ScrollToRef();
|
1998-04-13 20:24:54 +00:00
|
|
|
}
|
|
|
|
|
1998-07-22 23:42:47 +00:00
|
|
|
void
|
|
|
|
HTMLContentSink::ScrollToRef()
|
|
|
|
{
|
|
|
|
if (mNotAtRef && (nsnull != mRef) && (nsnull != mRefContent)) {
|
|
|
|
// See if the ref content has been reflowed by finding it's frame
|
|
|
|
PRInt32 i, ns = mDocument->GetNumberOfShells();
|
|
|
|
for (i = 0; i < ns; i++) {
|
|
|
|
nsIPresShell* shell = mDocument->GetShellAt(i);
|
|
|
|
if (nsnull != shell) {
|
|
|
|
nsIFrame* frame = shell->FindFrameWithContent(mRefContent);
|
|
|
|
if (nsnull != frame) {
|
|
|
|
nsIViewManager* vm = shell->GetViewManager();
|
|
|
|
if (nsnull != vm) {
|
|
|
|
nsIView* rootView = vm->GetRootView();
|
|
|
|
if (nsnull != rootView) {
|
|
|
|
nsIScrollableView* sview = nsnull;
|
|
|
|
rootView->QueryInterface(kIScrollableViewIID, (void**) &sview);
|
|
|
|
if (nsnull != sview) {
|
|
|
|
// Determine the x,y scroll offsets for the given
|
|
|
|
// frame. The offsets are relative to the
|
|
|
|
// ScrollableView's upper left corner so we need frame
|
|
|
|
// coordinates that are relative to that.
|
|
|
|
nsPoint offset;
|
|
|
|
nsIView* view;
|
|
|
|
frame->GetOffsetFromView(offset, view);
|
|
|
|
if (view == rootView) {
|
1998-07-23 15:29:04 +00:00
|
|
|
// XXX write me!
|
|
|
|
// printf("view==rootView ");
|
1998-07-22 23:42:47 +00:00
|
|
|
}
|
|
|
|
NS_IF_RELEASE(view);
|
|
|
|
nscoord x = 0;
|
|
|
|
nscoord y = offset.y;
|
1998-07-23 15:29:04 +00:00
|
|
|
#if 0
|
1998-07-22 23:42:47 +00:00
|
|
|
nsIPresContext* cx = shell->GetPresContext();
|
|
|
|
float t2p = cx->GetTwipsToPixels();
|
1998-07-31 23:34:45 +00:00
|
|
|
printf("x=%d y=%d\n", NSTwipsToIntPixels(x, t2p), NSTwipsToIntPixels(y, t2p));
|
1998-07-22 23:42:47 +00:00
|
|
|
NS_RELEASE(cx);
|
1998-07-23 15:29:04 +00:00
|
|
|
#endif
|
1998-07-22 23:42:47 +00:00
|
|
|
sview->SetScrollPreference(mOriginalScrollPreference);
|
|
|
|
sview->ScrollTo(x, y, NS_VMREFRESH_IMMEDIATE);
|
|
|
|
|
|
|
|
// Note that we did this so that we don't bother doing it again
|
|
|
|
mNotAtRef = PR_FALSE;
|
1998-07-23 15:29:04 +00:00
|
|
|
NS_RELEASE(sview);
|
1998-07-22 23:42:47 +00:00
|
|
|
}
|
|
|
|
NS_RELEASE(rootView);
|
|
|
|
}
|
|
|
|
NS_RELEASE(vm);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
NS_RELEASE(shell);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
nsIHTMLContent*
|
|
|
|
HTMLContentSink::GetCurrentContainer(eHTMLTags* aType)
|
1998-04-13 20:24:54 +00:00
|
|
|
{
|
|
|
|
nsIHTMLContent* parent;
|
1998-07-22 23:42:47 +00:00
|
|
|
if (mStackPos <= 2) { // assume HTML and BODY/FRAMESET are on the stack
|
1998-07-20 18:52:40 +00:00
|
|
|
if (mBody) {
|
|
|
|
parent = mBody;
|
|
|
|
*aType = eHTMLTag_body;
|
|
|
|
} else {
|
|
|
|
parent = mFrameset;
|
|
|
|
*aType = eHTMLTag_frameset;
|
|
|
|
}
|
1998-04-13 20:24:54 +00:00
|
|
|
} else {
|
|
|
|
parent = mContainerStack[mStackPos - 1];
|
|
|
|
*aType = mNodeStack[mStackPos - 1];
|
|
|
|
}
|
|
|
|
return parent;
|
|
|
|
}
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
|
|
|
|
// Leaf tag handling code
|
|
|
|
|
1998-07-15 22:31:10 +00:00
|
|
|
NS_IMETHODIMP HTMLContentSink::AddLeaf(const nsIParserNode& aNode)
|
1998-04-13 20:24:54 +00:00
|
|
|
{
|
1998-08-05 01:43:42 +00:00
|
|
|
NS_ASSERTION(mStackPos > 0, "bad parser");
|
1998-07-11 03:51:50 +00:00
|
|
|
SINK_TRACE_NODE(SINK_TRACE_CALLS,
|
|
|
|
"HTMLContentSink::AddLeaf", aNode);
|
1998-04-13 20:24:54 +00:00
|
|
|
|
|
|
|
// Check for nodes that require special handling
|
|
|
|
switch (aNode.GetNodeType()) {
|
|
|
|
case eHTMLTag_style:
|
1998-06-27 22:57:52 +00:00
|
|
|
FlushText();
|
1998-04-13 20:24:54 +00:00
|
|
|
ProcessSTYLETag(aNode);
|
1998-07-15 22:31:10 +00:00
|
|
|
return NS_OK;
|
1998-04-13 20:24:54 +00:00
|
|
|
|
|
|
|
case eHTMLTag_script:
|
1998-06-25 22:26:52 +00:00
|
|
|
// XXX SCRIPT tag evaluation is currently turned off till we
|
|
|
|
// get more scripts working.
|
1998-06-27 22:57:52 +00:00
|
|
|
FlushText();
|
1998-06-25 22:26:52 +00:00
|
|
|
ProcessSCRIPTTag(aNode);
|
1998-07-15 22:31:10 +00:00
|
|
|
return NS_OK;
|
1998-04-13 20:24:54 +00:00
|
|
|
|
|
|
|
case eHTMLTag_area:
|
1998-06-27 22:57:52 +00:00
|
|
|
FlushText();
|
1998-04-13 20:24:54 +00:00
|
|
|
ProcessAREATag(aNode);
|
1998-07-15 22:31:10 +00:00
|
|
|
return NS_OK;
|
1998-06-26 15:08:55 +00:00
|
|
|
|
|
|
|
case eHTMLTag_meta:
|
|
|
|
// Add meta objects to the head object
|
1998-06-27 22:57:52 +00:00
|
|
|
FlushText();
|
1998-06-26 15:08:55 +00:00
|
|
|
ProcessMETATag(aNode);
|
1998-07-15 22:31:10 +00:00
|
|
|
return NS_OK;
|
1998-07-24 18:20:27 +00:00
|
|
|
|
|
|
|
case eHTMLTag_base:
|
|
|
|
ProcessBASETag(aNode);
|
|
|
|
return NS_OK;
|
1998-04-13 20:24:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
eHTMLTags parentType;
|
|
|
|
nsIHTMLContent* parent = GetCurrentContainer(&parentType);
|
|
|
|
|
1998-05-08 20:18:06 +00:00
|
|
|
switch (parentType) {
|
|
|
|
/*case eHTMLTag_table:
|
1998-04-13 20:24:54 +00:00
|
|
|
case eHTMLTag_tr:
|
1998-04-22 23:24:43 +00:00
|
|
|
case eHTMLTag_tbody:
|
1998-04-21 16:36:46 +00:00
|
|
|
case eHTMLTag_thead:
|
|
|
|
case eHTMLTag_tfoot:
|
1998-04-13 20:24:54 +00:00
|
|
|
// XXX Discard leaf content (those annoying \n's really) in
|
|
|
|
// table's or table rows
|
|
|
|
return PR_TRUE;
|
1998-05-08 20:18:06 +00:00
|
|
|
*/
|
1998-04-22 23:24:43 +00:00
|
|
|
case eHTMLTag_option:
|
1998-06-27 22:57:52 +00:00
|
|
|
FlushText();
|
1998-04-22 23:24:43 +00:00
|
|
|
ProcessOPTIONTagContent(aNode);
|
1998-07-15 22:31:10 +00:00
|
|
|
return NS_OK;
|
1998-04-22 23:24:43 +00:00
|
|
|
|
|
|
|
case eHTMLTag_select:
|
|
|
|
// Discard content in a select that's not an option
|
|
|
|
if (eHTMLTag_option != aNode.GetNodeType()) {
|
1998-07-15 22:31:10 +00:00
|
|
|
return NS_OK;
|
1998-04-22 23:24:43 +00:00
|
|
|
}
|
|
|
|
break;
|
1998-04-13 20:24:54 +00:00
|
|
|
}
|
1998-05-08 20:18:06 +00:00
|
|
|
|
1998-07-22 17:40:05 +00:00
|
|
|
PRBool sleazyTextHackXXX = PR_FALSE;
|
|
|
|
|
1998-04-13 20:24:54 +00:00
|
|
|
nsresult rv = NS_OK;
|
|
|
|
nsIHTMLContent* leaf = nsnull;
|
|
|
|
switch (aNode.GetTokenType()) {
|
|
|
|
case eToken_start:
|
|
|
|
switch (aNode.GetNodeType()) {
|
|
|
|
case eHTMLTag_br:
|
1998-06-27 22:57:52 +00:00
|
|
|
FlushText();
|
1998-04-13 20:24:54 +00:00
|
|
|
rv = ProcessBRTag(&leaf, aNode);
|
|
|
|
break;
|
1998-07-20 18:52:40 +00:00
|
|
|
case eHTMLTag_frame:
|
|
|
|
FlushText();
|
|
|
|
rv = ProcessFrameTag(&leaf, aNode);
|
|
|
|
break;
|
1998-04-13 20:24:54 +00:00
|
|
|
case eHTMLTag_hr:
|
1998-06-27 22:57:52 +00:00
|
|
|
FlushText();
|
1998-04-13 20:24:54 +00:00
|
|
|
rv = ProcessHRTag(&leaf, aNode);
|
|
|
|
break;
|
|
|
|
case eHTMLTag_input:
|
1998-06-27 22:57:52 +00:00
|
|
|
FlushText();
|
1998-04-13 20:24:54 +00:00
|
|
|
rv = ProcessINPUTTag(&leaf, aNode);
|
|
|
|
break;
|
|
|
|
case eHTMLTag_img:
|
1998-06-27 22:57:52 +00:00
|
|
|
FlushText();
|
1998-04-13 20:24:54 +00:00
|
|
|
rv = ProcessIMGTag(&leaf, aNode);
|
|
|
|
break;
|
|
|
|
case eHTMLTag_spacer:
|
1998-06-27 22:57:52 +00:00
|
|
|
FlushText();
|
1998-04-13 20:24:54 +00:00
|
|
|
rv = ProcessSPACERTag(&leaf, aNode);
|
|
|
|
break;
|
1998-04-22 22:12:24 +00:00
|
|
|
case eHTMLTag_textarea:
|
1998-06-27 22:57:52 +00:00
|
|
|
FlushText();
|
1998-04-22 22:12:24 +00:00
|
|
|
ProcessTEXTAREATag(&leaf, aNode);
|
|
|
|
break;
|
1998-07-15 00:49:26 +00:00
|
|
|
case eHTMLTag_embed:
|
1998-08-07 01:49:12 +00:00
|
|
|
FlushText();
|
1998-07-15 00:49:26 +00:00
|
|
|
rv = ProcessEMBEDTag(&leaf, aNode);
|
|
|
|
break;
|
1998-04-13 20:24:54 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case eToken_text:
|
|
|
|
case eToken_whitespace:
|
|
|
|
case eToken_newline:
|
1998-06-27 22:57:52 +00:00
|
|
|
rv = AddText(aNode.GetText(), &leaf);
|
1998-07-22 17:40:05 +00:00
|
|
|
sleazyTextHackXXX = PR_TRUE;
|
1998-04-13 20:24:54 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case eToken_entity:
|
|
|
|
{
|
|
|
|
nsAutoString tmp;
|
1998-06-27 22:57:52 +00:00
|
|
|
PRInt32 unicode = aNode.TranslateToUnicodeStr(tmp);
|
1998-04-13 20:24:54 +00:00
|
|
|
if (unicode < 0) {
|
1998-06-27 22:57:52 +00:00
|
|
|
rv = AddText(aNode.GetText(), &leaf);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
rv = AddText(tmp, &leaf);
|
1998-04-13 20:24:54 +00:00
|
|
|
}
|
1998-07-22 17:40:05 +00:00
|
|
|
sleazyTextHackXXX = PR_TRUE;
|
1998-04-13 20:24:54 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case eToken_skippedcontent:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (NS_OK == rv) {
|
|
|
|
if (nsnull != leaf) {
|
|
|
|
if (nsnull != parent) {
|
1998-07-12 00:18:26 +00:00
|
|
|
AppendToCorrectParent(parentType, parent,
|
|
|
|
(nsHTMLTag) aNode.GetNodeType(), leaf,
|
1998-07-15 17:06:53 +00:00
|
|
|
PR_FALSE);
|
1998-07-22 17:40:05 +00:00
|
|
|
if (sleazyTextHackXXX) {
|
|
|
|
// XXX Prevent incremental reflows on the text as it pours in
|
|
|
|
leaf->SetDocument(nsnull);
|
|
|
|
}
|
1998-04-13 20:24:54 +00:00
|
|
|
} else {
|
|
|
|
// XXX drop stuff on the floor that doesn't have a container!
|
|
|
|
// Bad parser!
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
NS_IF_RELEASE(leaf);
|
|
|
|
|
1998-07-15 22:31:10 +00:00
|
|
|
return rv;
|
1998-04-13 20:24:54 +00:00
|
|
|
}
|
|
|
|
|
1998-07-12 00:18:26 +00:00
|
|
|
// Special handling code to push unexpected table content out of the
|
|
|
|
// table and into the table's parent, just before the table. Because
|
|
|
|
// the table is a container, it will not have been added to it's
|
|
|
|
// parent yet so we can just append the inappropriate content.
|
|
|
|
void
|
|
|
|
HTMLContentSink::AppendToCorrectParent(nsHTMLTag aParentTag,
|
|
|
|
nsIHTMLContent* aParent,
|
|
|
|
nsHTMLTag aChildTag,
|
|
|
|
nsIHTMLContent* aChild,
|
|
|
|
PRBool aAllowReflow)
|
|
|
|
{
|
|
|
|
nsIHTMLContent* realParent = aParent;
|
|
|
|
|
|
|
|
// These are the tags that are allowed in a table
|
|
|
|
static char tableTagSet[] = {
|
|
|
|
eHTMLTag_tbody, eHTMLTag_thead, eHTMLTag_tfoot,
|
|
|
|
eHTMLTag_tr, eHTMLTag_col, eHTMLTag_colgroup,
|
|
|
|
eHTMLTag_caption,/* XXX ok? */
|
|
|
|
0,
|
|
|
|
};
|
|
|
|
|
|
|
|
// These are the tags that are allowed in a tbody/thead/tfoot
|
|
|
|
static char tbodyTagSet[] = {
|
|
|
|
eHTMLTag_tr,
|
|
|
|
eHTMLTag_caption,/* XXX ok? */
|
|
|
|
0,
|
|
|
|
};
|
|
|
|
|
|
|
|
// These are the tags that are allowed in a colgroup
|
|
|
|
static char colgroupTagSet[] = {
|
|
|
|
eHTMLTag_col,
|
|
|
|
0,
|
|
|
|
};
|
|
|
|
|
|
|
|
// These are the tags that are allowed in a tr
|
|
|
|
static char trTagSet[] = {
|
|
|
|
eHTMLTag_td, eHTMLTag_th,
|
|
|
|
0,
|
|
|
|
};
|
|
|
|
|
|
|
|
switch (aParentTag) {
|
|
|
|
case eHTMLTag_table:
|
|
|
|
if (0 == strchr(tableTagSet, aChildTag)) {
|
|
|
|
realParent = GetTableParent();
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case eHTMLTag_tbody:
|
|
|
|
case eHTMLTag_thead:
|
|
|
|
case eHTMLTag_tfoot:
|
|
|
|
if (0 == strchr(tbodyTagSet, aChildTag)) {
|
|
|
|
realParent = GetTableParent();
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case eHTMLTag_col:
|
|
|
|
realParent = GetTableParent();
|
|
|
|
break;
|
|
|
|
|
|
|
|
case eHTMLTag_colgroup:
|
|
|
|
if (0 == strchr(colgroupTagSet, aChildTag)) {
|
|
|
|
realParent = GetTableParent();
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case eHTMLTag_tr:
|
|
|
|
if (0 == strchr(trTagSet, aChildTag)) {
|
|
|
|
realParent = GetTableParent();
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
realParent->AppendChild(aChild, aAllowReflow);
|
1998-07-22 23:42:47 +00:00
|
|
|
if (aAllowReflow) {
|
1998-07-23 15:29:04 +00:00
|
|
|
// ScrollToRef();
|
1998-07-22 23:42:47 +00:00
|
|
|
}
|
1998-07-12 00:18:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Find the parent of the currently open table
|
|
|
|
nsIHTMLContent*
|
|
|
|
HTMLContentSink::GetTableParent()
|
|
|
|
{
|
|
|
|
PRInt32 sp = mStackPos - 1;
|
|
|
|
while (sp >= 0) {
|
|
|
|
switch (mNodeStack[sp]) {
|
|
|
|
case eHTMLTag_table:
|
|
|
|
case eHTMLTag_tr:
|
|
|
|
case eHTMLTag_tbody:
|
|
|
|
case eHTMLTag_thead:
|
|
|
|
case eHTMLTag_tfoot:
|
|
|
|
case eHTMLTag_col:
|
|
|
|
case eHTMLTag_colgroup:
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
return mContainerStack[sp];
|
|
|
|
}
|
|
|
|
sp--;
|
|
|
|
}
|
1998-07-20 18:52:40 +00:00
|
|
|
return GetBodyOrFrameset();
|
1998-07-12 00:18:26 +00:00
|
|
|
}
|
|
|
|
|
1998-06-27 22:57:52 +00:00
|
|
|
nsresult
|
|
|
|
HTMLContentSink::AddText(const nsString& aText, nsIHTMLContent** aContent)
|
|
|
|
{
|
|
|
|
nsresult rv;
|
|
|
|
if (nsnull != mCurrentText) {
|
|
|
|
mCurrentText->Append((nsString&)aText);/* XXX fix dom text api!!! */
|
|
|
|
*aContent = nsnull;
|
|
|
|
rv = NS_OK;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
static NS_DEFINE_IID(kIDOMTextIID, NS_IDOMTEXT_IID);
|
|
|
|
rv = NS_NewHTMLText(aContent, aText.GetUnicode(), aText.Length());
|
|
|
|
if (NS_OK == rv) {
|
|
|
|
(*aContent)->QueryInterface(kIDOMTextIID, (void**) &mCurrentText);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
HTMLContentSink::FlushText()
|
|
|
|
{
|
|
|
|
if (nsnull != mCurrentText) {
|
1998-07-22 17:40:05 +00:00
|
|
|
// XXX sleazyTextHackXXX repair document pointer in text object
|
|
|
|
static NS_DEFINE_IID(kIContentIID, NS_ICONTENT_IID);
|
|
|
|
nsIContent* content = nsnull;
|
|
|
|
mCurrentText->QueryInterface(kIContentIID, (void**) &content);
|
|
|
|
content->SetDocument(mDocument);
|
1998-06-27 22:57:52 +00:00
|
|
|
NS_RELEASE(mCurrentText);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1998-04-13 20:24:54 +00:00
|
|
|
void HTMLContentSink::GetAttributeValueAt(const nsIParserNode& aNode,
|
|
|
|
PRInt32 aIndex,
|
|
|
|
nsString& aResult)
|
|
|
|
{
|
|
|
|
// Copy value
|
|
|
|
const nsString& value = aNode.GetValueAt(aIndex);
|
|
|
|
aResult.Truncate();
|
|
|
|
aResult.Append(value);
|
|
|
|
|
|
|
|
// strip quotes if present
|
|
|
|
PRUnichar first = aResult.First();
|
|
|
|
if ((first == '"') || (first == '\'')) {
|
|
|
|
if (aResult.Last() == first) {
|
|
|
|
aResult.Cut(0, 1);
|
|
|
|
PRInt32 pos = aResult.Length() - 1;
|
|
|
|
if (pos >= 0) {
|
|
|
|
aResult.Cut(pos, 1);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
// Mismatched quotes - leave them in
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1998-04-22 22:12:24 +00:00
|
|
|
PRBool HTMLContentSink::FindAttribute(const nsIParserNode& aNode,
|
|
|
|
const nsString& aKeyName,
|
|
|
|
nsString& aResult)
|
|
|
|
{
|
|
|
|
PRInt32 ac = aNode.GetAttributeCount();
|
|
|
|
for (PRInt32 i = 0; i < ac; i++) {
|
|
|
|
const nsString& key = aNode.GetKeyAt(i);
|
|
|
|
if (key.EqualsIgnoreCase(aKeyName)) {
|
|
|
|
// Get value and remove mandatory quotes
|
|
|
|
GetAttributeValueAt(aNode, i, aResult);
|
|
|
|
return PR_TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return PR_FALSE;
|
|
|
|
}
|
|
|
|
|
1998-04-13 20:24:54 +00:00
|
|
|
nsresult HTMLContentSink::AddAttributes(const nsIParserNode& aNode,
|
|
|
|
nsIHTMLContent* aInstancePtrResult)
|
|
|
|
{
|
|
|
|
nsIContent* content = (nsIContent*) aInstancePtrResult;
|
|
|
|
|
|
|
|
// Add tag attributes to the content attributes
|
|
|
|
nsAutoString k, v;
|
|
|
|
PRInt32 ac = aNode.GetAttributeCount();
|
|
|
|
for (PRInt32 i = 0; i < ac; i++) {
|
|
|
|
// Get upper-cased key
|
|
|
|
const nsString& key = aNode.GetKeyAt(i);
|
|
|
|
k.Truncate();
|
|
|
|
k.Append(key);
|
|
|
|
k.ToUpperCase();
|
|
|
|
|
|
|
|
// Get value and remove mandatory quotes
|
|
|
|
GetAttributeValueAt(aNode, i, v);
|
|
|
|
|
|
|
|
content->SetAttribute(k, v);
|
|
|
|
}
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
1998-07-24 18:20:27 +00:00
|
|
|
void
|
|
|
|
HTMLContentSink::AddBaseTagInfo(nsIHTMLContent* aContent)
|
|
|
|
{
|
|
|
|
if (mBaseHREF.Length() > 0) {
|
|
|
|
nsHTMLValue value(mBaseHREF);
|
|
|
|
aContent->SetAttribute(nsHTMLAtoms::_baseHref, value);
|
|
|
|
}
|
|
|
|
if (mBaseTarget.Length() > 0) {
|
|
|
|
nsHTMLValue value(mBaseTarget);
|
|
|
|
aContent->SetAttribute(nsHTMLAtoms::_baseTarget, value);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1998-04-13 20:24:54 +00:00
|
|
|
nsresult HTMLContentSink::ProcessAREATag(const nsIParserNode& aNode)
|
|
|
|
{
|
|
|
|
if (nsnull != mCurrentMap) {
|
|
|
|
nsAutoString shape, coords, href, target(mBaseTarget), alt;
|
|
|
|
PRInt32 ac = aNode.GetAttributeCount();
|
|
|
|
PRBool suppress = PR_FALSE;
|
|
|
|
for (PRInt32 i = 0; i < ac; i++) {
|
|
|
|
// Get upper-cased key
|
|
|
|
const nsString& key = aNode.GetKeyAt(i);
|
|
|
|
if (key.EqualsIgnoreCase("shape")) {
|
|
|
|
GetAttributeValueAt(aNode, i, shape);
|
|
|
|
}
|
|
|
|
else if (key.EqualsIgnoreCase("coords")) {
|
|
|
|
GetAttributeValueAt(aNode, i, coords);
|
|
|
|
}
|
|
|
|
else if (key.EqualsIgnoreCase("href")) {
|
|
|
|
GetAttributeValueAt(aNode, i, href);
|
|
|
|
href.StripWhitespace();
|
|
|
|
}
|
|
|
|
else if (key.EqualsIgnoreCase("target")) {
|
|
|
|
GetAttributeValueAt(aNode, i, target);
|
|
|
|
}
|
|
|
|
else if (key.EqualsIgnoreCase("alt")) {
|
|
|
|
GetAttributeValueAt(aNode, i, alt);
|
|
|
|
}
|
|
|
|
else if (key.EqualsIgnoreCase("suppress")) {
|
|
|
|
suppress = PR_TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
mCurrentMap->AddArea(mBaseHREF, shape, coords, href, target, alt,
|
|
|
|
suppress);
|
|
|
|
}
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult HTMLContentSink::ProcessBASETag(const nsIParserNode& aNode)
|
|
|
|
{
|
|
|
|
PRInt32 ac = aNode.GetAttributeCount();
|
|
|
|
for (PRInt32 i = 0; i < ac; i++) {
|
|
|
|
const nsString& key = aNode.GetKeyAt(i);
|
|
|
|
if (key.EqualsIgnoreCase("href")) {
|
1998-07-24 18:20:27 +00:00
|
|
|
GetAttributeValueAt(aNode, i, mBaseHREF);
|
1998-04-13 20:24:54 +00:00
|
|
|
} else if (key.EqualsIgnoreCase("target")) {
|
1998-07-24 18:20:27 +00:00
|
|
|
GetAttributeValueAt(aNode, i, mBaseTarget);
|
1998-04-13 20:24:54 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
1998-06-26 15:08:55 +00:00
|
|
|
nsresult
|
|
|
|
HTMLContentSink::ProcessMETATag(const nsIParserNode& aNode)
|
|
|
|
{
|
|
|
|
nsresult rv = NS_OK;
|
|
|
|
if (nsnull != mHead) {
|
1998-07-14 01:57:51 +00:00
|
|
|
nsAutoString tmp("META");
|
1998-06-26 15:08:55 +00:00
|
|
|
nsIAtom* atom = NS_NewAtom(tmp);
|
|
|
|
|
|
|
|
nsIHTMLContent* it = nsnull;
|
|
|
|
rv = NS_NewHTMLMeta(&it, atom) ;
|
|
|
|
if (NS_OK == rv) {
|
|
|
|
rv = AddAttributes(aNode, it);
|
|
|
|
mHead->AppendChild(it, PR_FALSE);
|
|
|
|
}
|
|
|
|
NS_RELEASE(atom);
|
|
|
|
}
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
1998-04-13 20:24:54 +00:00
|
|
|
nsresult HTMLContentSink::ProcessBRTag(nsIHTMLContent** aInstancePtrResult,
|
|
|
|
const nsIParserNode& aNode)
|
|
|
|
{
|
|
|
|
nsresult rv = NS_OK;
|
1998-07-14 01:57:51 +00:00
|
|
|
nsAutoString tmp("BR");
|
1998-04-13 20:24:54 +00:00
|
|
|
nsIAtom* atom = NS_NewAtom(tmp);
|
|
|
|
rv = NS_NewHTMLBreak(aInstancePtrResult, atom);
|
|
|
|
if (NS_OK == rv) {
|
|
|
|
rv = AddAttributes(aNode, *aInstancePtrResult);
|
|
|
|
}
|
|
|
|
NS_RELEASE(atom);
|
|
|
|
return rv;
|
|
|
|
}
|
1998-07-15 00:49:26 +00:00
|
|
|
nsresult HTMLContentSink::ProcessEMBEDTag(nsIHTMLContent** aInstancePtrResult,
|
|
|
|
const nsIParserNode& aNode)
|
|
|
|
{
|
|
|
|
nsresult rv = NS_OK;
|
|
|
|
nsAutoString tmp("EMBED");
|
|
|
|
nsIAtom* atom = NS_NewAtom(tmp);
|
|
|
|
rv = NS_NewHTMLEmbed(aInstancePtrResult, atom);
|
|
|
|
if (NS_OK == rv) {
|
|
|
|
rv = AddAttributes(aNode, *aInstancePtrResult);
|
|
|
|
}
|
|
|
|
NS_RELEASE(atom);
|
|
|
|
return rv;
|
|
|
|
}
|
1998-04-13 20:24:54 +00:00
|
|
|
|
|
|
|
nsresult HTMLContentSink::ProcessHRTag(nsIHTMLContent** aInstancePtrResult,
|
|
|
|
const nsIParserNode& aNode)
|
|
|
|
{
|
|
|
|
nsresult rv = NS_OK;
|
1998-07-14 01:57:51 +00:00
|
|
|
nsAutoString tmp("HR");
|
1998-04-13 20:24:54 +00:00
|
|
|
nsIAtom* atom = NS_NewAtom(tmp);
|
|
|
|
rv = NS_NewHRulePart(aInstancePtrResult, atom);
|
|
|
|
if (NS_OK == rv) {
|
|
|
|
rv = AddAttributes(aNode, *aInstancePtrResult);
|
|
|
|
}
|
|
|
|
NS_RELEASE(atom);
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult HTMLContentSink::ProcessIMGTag(nsIHTMLContent** aInstancePtrResult,
|
|
|
|
const nsIParserNode& aNode)
|
|
|
|
{
|
1998-07-14 01:57:51 +00:00
|
|
|
nsAutoString tmp("IMG");
|
1998-04-13 20:24:54 +00:00
|
|
|
nsIAtom* atom = NS_NewAtom(tmp);
|
|
|
|
nsresult rv = NS_NewHTMLImage(aInstancePtrResult, atom);
|
|
|
|
if (NS_OK == rv) {
|
|
|
|
rv = AddAttributes(aNode, *aInstancePtrResult);
|
1998-07-24 18:20:27 +00:00
|
|
|
AddBaseTagInfo(*aInstancePtrResult);
|
1998-04-13 20:24:54 +00:00
|
|
|
}
|
1998-07-24 18:20:27 +00:00
|
|
|
|
1998-04-13 20:24:54 +00:00
|
|
|
NS_RELEASE(atom);
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult HTMLContentSink::ProcessSPACERTag(nsIHTMLContent** aInstancePtrResult,
|
|
|
|
const nsIParserNode& aNode)
|
|
|
|
{
|
1998-07-14 01:57:51 +00:00
|
|
|
nsAutoString tmp("SPACER");
|
1998-04-13 20:24:54 +00:00
|
|
|
nsIAtom* atom = NS_NewAtom(tmp);
|
|
|
|
nsresult rv = NS_NewHTMLSpacer(aInstancePtrResult, atom);
|
|
|
|
if (NS_OK == rv) {
|
|
|
|
rv = AddAttributes(aNode, *aInstancePtrResult);
|
|
|
|
}
|
|
|
|
NS_RELEASE(atom);
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
1998-06-25 22:26:52 +00:00
|
|
|
#define SCRIPT_BUF_SIZE 1024
|
|
|
|
|
|
|
|
nsresult HTMLContentSink::ProcessSCRIPTTag(const nsIParserNode& aNode)
|
|
|
|
{
|
|
|
|
nsresult rv = NS_OK;
|
|
|
|
PRInt32 i, ac = aNode.GetAttributeCount();
|
|
|
|
|
|
|
|
// Look for SRC attribute
|
|
|
|
nsString* src = nsnull;
|
|
|
|
for (i = 0; i < ac; i++) {
|
|
|
|
const nsString& key = aNode.GetKeyAt(i);
|
|
|
|
if (key.EqualsIgnoreCase("src")) {
|
|
|
|
src = new nsString(aNode.GetValueAt(i));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
char *script = nsnull;
|
|
|
|
PRInt32 len = 0;
|
|
|
|
|
|
|
|
// If there is a SRC attribute, (for now) read from the
|
|
|
|
// stream synchronously and hold the data in a string.
|
|
|
|
if (nsnull != src) {
|
|
|
|
// Use the SRC attribute value to open a blocking stream
|
|
|
|
nsIURL* url = nsnull;
|
1998-07-24 18:20:27 +00:00
|
|
|
nsAutoString absURL;
|
1998-07-21 16:43:48 +00:00
|
|
|
nsIURL* docURL = mDocument->GetDocumentURL();
|
1998-07-24 18:20:27 +00:00
|
|
|
rv = NS_MakeAbsoluteURL(docURL, mBaseHREF, *src, absURL);
|
1998-07-21 16:43:48 +00:00
|
|
|
if (NS_OK != rv) {
|
|
|
|
return rv;
|
|
|
|
}
|
1998-07-24 18:20:27 +00:00
|
|
|
NS_RELEASE(docURL);
|
1998-07-21 16:43:48 +00:00
|
|
|
rv = NS_NewURL(&url, nsnull, absURL);
|
1998-06-25 22:26:52 +00:00
|
|
|
delete src;
|
|
|
|
if (NS_OK != rv) {
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
PRInt32 ec;
|
|
|
|
nsIInputStream* iin = url->Open(&ec);
|
|
|
|
if (nsnull == iin) {
|
|
|
|
NS_RELEASE(url);
|
|
|
|
return (nsresult) ec;/* XXX fix url->Open */
|
|
|
|
}
|
|
|
|
|
|
|
|
// Drain the stream by reading from it a chunk at a time
|
|
|
|
nsString data;
|
1998-07-23 20:35:43 +00:00
|
|
|
PRInt32 nb;
|
|
|
|
nsresult err;
|
1998-06-25 22:26:52 +00:00
|
|
|
do {
|
|
|
|
char buf[SCRIPT_BUF_SIZE];
|
|
|
|
|
1998-07-23 20:35:43 +00:00
|
|
|
err = iin->Read(buf, 0, SCRIPT_BUF_SIZE, &nb);
|
|
|
|
if (NS_OK == err) {
|
1998-06-25 22:26:52 +00:00
|
|
|
data.Append((const char *)buf, nb);
|
|
|
|
}
|
1998-07-23 20:35:43 +00:00
|
|
|
} while (err == NS_OK);
|
1998-06-25 22:26:52 +00:00
|
|
|
|
1998-07-23 20:35:43 +00:00
|
|
|
if (NS_BASE_STREAM_EOF == err) {
|
1998-06-25 22:26:52 +00:00
|
|
|
script = data.ToNewCString();
|
|
|
|
len = data.Length();
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
rv = NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_RELEASE(iin);
|
|
|
|
NS_RELEASE(url);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
// Otherwise, get the text content of the script tag
|
|
|
|
const nsString& content = aNode.GetSkippedContent();
|
|
|
|
script = content.ToNewCString();
|
|
|
|
len = content.Length();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (nsnull != script) {
|
|
|
|
nsIScriptContextOwner *owner;
|
|
|
|
nsIScriptContext *context;
|
|
|
|
owner = mDocument->GetScriptContextOwner();
|
|
|
|
if (nsnull != owner) {
|
|
|
|
|
|
|
|
rv = owner->GetScriptContext(&context);
|
|
|
|
if (rv != NS_OK) {
|
|
|
|
NS_RELEASE(owner);
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
jsval val;
|
|
|
|
PRBool result = context->EvaluateString(script, len, &val);
|
|
|
|
|
|
|
|
if (PR_FALSE == result) {
|
|
|
|
rv = NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_RELEASE(context);
|
|
|
|
NS_RELEASE(owner);
|
|
|
|
}
|
|
|
|
delete script;
|
|
|
|
}
|
|
|
|
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
1998-04-13 20:24:54 +00:00
|
|
|
// 3 ways to load a style sheet: inline, style src=, link tag
|
|
|
|
// XXX What does nav do if we have SRC= and some style data inline?
|
1998-07-24 18:20:27 +00:00
|
|
|
|
|
|
|
// XXX This code and ProcessSCRIPTTag share alot in common; clean that up!
|
1998-04-13 20:24:54 +00:00
|
|
|
nsresult HTMLContentSink::ProcessSTYLETag(const nsIParserNode& aNode)
|
|
|
|
{
|
|
|
|
nsresult rv = NS_OK;
|
|
|
|
PRInt32 i, ac = aNode.GetAttributeCount();
|
|
|
|
|
|
|
|
nsString* src = nsnull;
|
|
|
|
for (i = 0; i < ac; i++) {
|
|
|
|
const nsString& key = aNode.GetKeyAt(i);
|
|
|
|
if (key.EqualsIgnoreCase("src")) {
|
|
|
|
src = new nsString(aNode.GetValueAt(i));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// The skipped content contains the inline style data
|
|
|
|
const nsString& content = aNode.GetSkippedContent();
|
|
|
|
|
|
|
|
nsIURL* url = nsnull;
|
|
|
|
nsIUnicharInputStream* uin = nsnull;
|
|
|
|
if (nsnull == src) {
|
|
|
|
// Create a string to hold the data and wrap it up in a unicode
|
|
|
|
// input stream.
|
|
|
|
rv = NS_NewStringUnicharInputStream(&uin, new nsString(content));
|
|
|
|
if (NS_OK != rv) {
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Use the document's url since the style data came from there
|
|
|
|
url = mDocumentURL;
|
|
|
|
NS_IF_ADDREF(url);
|
|
|
|
} else {
|
|
|
|
// src with immediate style data doesn't add up
|
|
|
|
// XXX what does nav do?
|
1998-07-24 18:20:27 +00:00
|
|
|
nsAutoString absURL;
|
|
|
|
nsIURL* docURL = mDocument->GetDocumentURL();
|
|
|
|
rv = NS_MakeAbsoluteURL(docURL, mBaseHREF, *src, absURL);
|
|
|
|
if (NS_OK != rv) {
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
NS_RELEASE(docURL);
|
|
|
|
rv = NS_NewURL(&url, nsnull, absURL);
|
1998-04-13 20:24:54 +00:00
|
|
|
delete src;
|
|
|
|
if (NS_OK != rv) {
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
PRInt32 ec;
|
|
|
|
nsIInputStream* iin = url->Open(&ec);
|
|
|
|
if (nsnull == iin) {
|
|
|
|
NS_RELEASE(url);
|
|
|
|
return (nsresult) ec;/* XXX fix url->Open */
|
|
|
|
}
|
|
|
|
rv = NS_NewConverterStream(&uin, nsnull, iin);
|
|
|
|
NS_RELEASE(iin);
|
|
|
|
if (NS_OK != rv) {
|
|
|
|
NS_RELEASE(url);
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Now that we have a url and a unicode input stream, parse the
|
|
|
|
// style sheet.
|
|
|
|
rv = LoadStyleSheet(url, uin);
|
|
|
|
NS_RELEASE(uin);
|
|
|
|
NS_RELEASE(url);
|
|
|
|
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult HTMLContentSink::LoadStyleSheet(nsIURL* aURL,
|
|
|
|
nsIUnicharInputStream* aUIN)
|
|
|
|
{
|
|
|
|
/* XXX use repository */
|
|
|
|
nsICSSParser* parser;
|
|
|
|
nsresult rv = NS_NewCSSParser(&parser);
|
|
|
|
if (NS_OK == rv) {
|
|
|
|
if (nsnull != mStyleSheet) {
|
|
|
|
parser->SetStyleSheet(mStyleSheet);
|
|
|
|
// XXX we do probably need to trigger a style change reflow
|
|
|
|
// when we are finished if this is adding data to the same sheet
|
|
|
|
}
|
1998-05-28 18:40:23 +00:00
|
|
|
nsIStyleSheet* sheet = nsnull;
|
|
|
|
// XXX note: we are ignoring rv until the error code stuff in the
|
|
|
|
// input routines is converted to use nsresult's
|
|
|
|
parser->Parse(aUIN, mDocumentURL, sheet);
|
1998-04-13 20:24:54 +00:00
|
|
|
if (nsnull != sheet) {
|
|
|
|
if (nsnull == mStyleSheet) {
|
|
|
|
// Add in the sheet the first time; if we update the sheet
|
|
|
|
// with new data (mutliple style tags in the same document)
|
|
|
|
// then the sheet will be updated by the css parser and
|
|
|
|
// therefore we don't need to add it to the document)
|
|
|
|
mDocument->AddStyleSheet(sheet);
|
|
|
|
mStyleSheet = sheet;
|
|
|
|
}
|
|
|
|
rv = NS_OK;
|
|
|
|
} else {
|
|
|
|
rv = NS_ERROR_OUT_OF_MEMORY;/* XXX */
|
|
|
|
}
|
|
|
|
NS_RELEASE(parser);
|
|
|
|
}
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
nsresult HTMLContentSink::ProcessINPUTTag(nsIHTMLContent** aInstancePtrResult,
|
|
|
|
const nsIParserNode& aNode)
|
|
|
|
{
|
1998-07-14 01:57:51 +00:00
|
|
|
nsAutoString tmp("INPUT");
|
1998-04-13 20:24:54 +00:00
|
|
|
nsIAtom* atom = NS_NewAtom(tmp);
|
|
|
|
|
|
|
|
nsresult rv = NS_ERROR_NOT_INITIALIZED;
|
|
|
|
|
|
|
|
// Find type attribute and then create the appropriate form element
|
1998-04-22 22:12:24 +00:00
|
|
|
nsAutoString val;
|
|
|
|
if (FindAttribute(aNode, "type", val)) {
|
|
|
|
if (val.EqualsIgnoreCase("submit")) {
|
|
|
|
rv = NS_NewHTMLInputSubmit(aInstancePtrResult, atom, mCurrentForm);
|
|
|
|
}
|
|
|
|
else if (val.EqualsIgnoreCase("reset")) {
|
|
|
|
rv = NS_NewHTMLInputReset(aInstancePtrResult, atom, mCurrentForm);
|
|
|
|
}
|
|
|
|
else if (val.EqualsIgnoreCase("button")) {
|
|
|
|
rv = NS_NewHTMLInputButton(aInstancePtrResult, atom, mCurrentForm);
|
|
|
|
}
|
|
|
|
else if (val.EqualsIgnoreCase("checkbox")) {
|
|
|
|
rv = NS_NewHTMLInputCheckbox(aInstancePtrResult, atom, mCurrentForm);
|
|
|
|
}
|
|
|
|
else if (val.EqualsIgnoreCase("file")) {
|
|
|
|
rv = NS_NewHTMLInputFile(aInstancePtrResult, atom, mCurrentForm);
|
|
|
|
}
|
|
|
|
else if (val.EqualsIgnoreCase("hidden")) {
|
|
|
|
rv = NS_NewHTMLInputHidden(aInstancePtrResult, atom, mCurrentForm);
|
|
|
|
}
|
|
|
|
else if (val.EqualsIgnoreCase("image")) {
|
|
|
|
rv = NS_NewHTMLInputImage(aInstancePtrResult, atom, mCurrentForm);
|
|
|
|
}
|
|
|
|
else if (val.EqualsIgnoreCase("password")) {
|
|
|
|
rv = NS_NewHTMLInputPassword(aInstancePtrResult, atom, mCurrentForm);
|
|
|
|
}
|
|
|
|
else if (val.EqualsIgnoreCase("radio")) {
|
|
|
|
rv = NS_NewHTMLInputRadio(aInstancePtrResult, atom, mCurrentForm);
|
|
|
|
}
|
|
|
|
else if (val.EqualsIgnoreCase("text")) {
|
|
|
|
rv = NS_NewHTMLInputText(aInstancePtrResult, atom, mCurrentForm);
|
|
|
|
}
|
1998-07-20 18:52:40 +00:00
|
|
|
else if (val.EqualsIgnoreCase("frameset1")) { // TEMP hack XXX
|
|
|
|
// rv = NS_NewHTMLFrameset(aInstancePtrResult, atom, mWebWidget, 1);
|
1998-04-24 21:37:30 +00:00
|
|
|
}
|
1998-07-20 18:52:40 +00:00
|
|
|
else if (val.EqualsIgnoreCase("frameset2")) { // TEMP hack XXX
|
|
|
|
// rv = NS_NewHTMLFrameset(aInstancePtrResult, atom, mWebWidget, 2);
|
1998-04-24 21:37:30 +00:00
|
|
|
}
|
1998-07-20 18:52:40 +00:00
|
|
|
else if (val.EqualsIgnoreCase("frameset3")) { // TEMP hack XXX
|
|
|
|
// rv = NS_NewHTMLFrameset(aInstancePtrResult, atom, mWebWidget, 3);
|
1998-04-28 18:59:38 +00:00
|
|
|
}
|
1998-04-22 22:12:24 +00:00
|
|
|
else {
|
|
|
|
rv = NS_NewHTMLInputSubmit(aInstancePtrResult, atom, mCurrentForm);
|
1998-04-13 20:24:54 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (NS_ERROR_NOT_INITIALIZED == rv) {
|
|
|
|
// Create textfield when no type is specified
|
|
|
|
rv = NS_NewHTMLInputText(aInstancePtrResult, atom, mCurrentForm);
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((NS_OK == rv) && (nsnull != *aInstancePtrResult)) {
|
|
|
|
// Add remaining attributes from the tag
|
|
|
|
rv = AddAttributes(aNode, *aInstancePtrResult);
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_RELEASE(atom);
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
1998-07-20 18:52:40 +00:00
|
|
|
nsresult HTMLContentSink::ProcessFrameTag(nsIHTMLContent** aInstancePtrResult,
|
|
|
|
const nsIParserNode& aNode)
|
|
|
|
{
|
1998-07-27 18:04:38 +00:00
|
|
|
// XXX kipp was here: ignore frame tags that aren't in a frameset!
|
|
|
|
nsresult rv = NS_OK;
|
|
|
|
if (nsnull != mFrameset) {
|
|
|
|
nsAutoString tmp("FRAME");
|
|
|
|
nsIAtom* atom = NS_NewAtom(tmp);
|
1998-07-20 18:52:40 +00:00
|
|
|
|
1998-07-27 18:04:38 +00:00
|
|
|
rv = NS_NewHTMLFrame(aInstancePtrResult, atom, mWebShell);
|
|
|
|
if (NS_OK == rv) {
|
|
|
|
rv = AddAttributes(aNode, *aInstancePtrResult);
|
|
|
|
}
|
1998-07-20 18:52:40 +00:00
|
|
|
|
1998-07-27 18:04:38 +00:00
|
|
|
NS_RELEASE(atom);
|
|
|
|
}
|
1998-07-20 18:52:40 +00:00
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
1998-04-22 22:12:24 +00:00
|
|
|
nsresult
|
|
|
|
HTMLContentSink::ProcessTEXTAREATag(nsIHTMLContent** aInstancePtrResult,
|
|
|
|
const nsIParserNode& aNode)
|
|
|
|
{
|
1998-07-14 01:57:51 +00:00
|
|
|
nsAutoString tmp("TEXTAREA");
|
1998-04-22 22:12:24 +00:00
|
|
|
nsIAtom* atom = NS_NewAtom(tmp);
|
|
|
|
|
|
|
|
const nsString& content = aNode.GetSkippedContent();
|
|
|
|
|
|
|
|
nsresult rv = NS_NewHTMLTextArea(aInstancePtrResult, atom, mCurrentForm);
|
|
|
|
if ((NS_OK == rv) && (nsnull != *aInstancePtrResult)) {
|
|
|
|
// Add remaining attributes from the tag
|
|
|
|
rv = AddAttributes(aNode, *aInstancePtrResult);
|
1998-05-08 20:18:06 +00:00
|
|
|
if (0 < content.Length()) {
|
|
|
|
nsIFormControl* control;
|
|
|
|
rv = (*aInstancePtrResult)->QueryInterface(kIFormControlIID, (void **)&control);
|
|
|
|
if (NS_OK == rv) {
|
|
|
|
control->SetContent(content);
|
|
|
|
}
|
|
|
|
}
|
1998-04-22 22:12:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
NS_RELEASE(atom);
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
1998-04-22 23:24:43 +00:00
|
|
|
nsresult
|
|
|
|
HTMLContentSink::ProcessOpenSELECTTag(nsIHTMLContent** aInstancePtrResult,
|
|
|
|
const nsIParserNode& aNode)
|
|
|
|
{
|
1998-07-14 01:57:51 +00:00
|
|
|
nsAutoString tmp("SELECT");
|
1998-04-22 23:24:43 +00:00
|
|
|
nsIAtom* atom = NS_NewAtom(tmp);
|
|
|
|
|
|
|
|
if (nsnull != mCurrentSelect) {
|
|
|
|
NS_RELEASE(mCurrentSelect);
|
|
|
|
}
|
1998-05-08 20:18:06 +00:00
|
|
|
nsresult rv = NS_NewHTMLSelect(&mCurrentSelect, atom, mCurrentForm);
|
1998-04-22 23:24:43 +00:00
|
|
|
if ((NS_OK == rv) && (nsnull != mCurrentSelect)) {
|
|
|
|
// Add remaining attributes from the tag
|
1998-05-08 23:08:43 +00:00
|
|
|
//rv = AddAttributes(aNode, mCurrentSelect);
|
1998-04-22 23:24:43 +00:00
|
|
|
*aInstancePtrResult = mCurrentSelect;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_RELEASE(atom);
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
HTMLContentSink::ProcessCloseSELECTTag(const nsIParserNode& aNode)
|
|
|
|
{
|
1998-05-08 20:18:06 +00:00
|
|
|
NS_IF_RELEASE(mCurrentSelect);
|
|
|
|
mCurrentSelect = nsnull;
|
1998-04-22 23:24:43 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
1998-05-08 23:08:43 +00:00
|
|
|
HTMLContentSink::ProcessOpenOPTIONTag(nsIHTMLContent** aInstancePtrResult,
|
1998-07-14 01:57:51 +00:00
|
|
|
const nsIParserNode& aNode)
|
1998-04-22 23:24:43 +00:00
|
|
|
{
|
|
|
|
nsresult rv = NS_OK;
|
|
|
|
if (nsnull != mCurrentSelect) {
|
|
|
|
if (nsnull != mCurrentOption) {
|
|
|
|
NS_RELEASE(mCurrentOption);
|
|
|
|
}
|
1998-07-14 01:57:51 +00:00
|
|
|
nsAutoString tmp("OPTION");
|
1998-05-08 20:18:06 +00:00
|
|
|
nsIAtom* atom = NS_NewAtom(tmp);
|
|
|
|
rv = NS_NewHTMLOption(&mCurrentOption, atom);
|
|
|
|
if ((NS_OK == rv) && (nsnull != mCurrentSelect)) {
|
1998-08-03 19:21:26 +00:00
|
|
|
// Add another reference to the option since we remember it both
|
|
|
|
// on our container stack and in mCurrentOption
|
|
|
|
NS_ADDREF(mCurrentOption);
|
|
|
|
|
1998-05-08 20:18:06 +00:00
|
|
|
// Add remaining attributes from the tag
|
1998-05-08 23:08:43 +00:00
|
|
|
//rv = AddAttributes(aNode, mCurrentOption);
|
1998-05-13 17:43:35 +00:00
|
|
|
*aInstancePtrResult = mCurrentOption;
|
1998-05-08 20:18:06 +00:00
|
|
|
}
|
|
|
|
NS_RELEASE(atom);
|
1998-04-22 23:24:43 +00:00
|
|
|
}
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
HTMLContentSink::ProcessCloseOPTIONTag(const nsIParserNode& aNode)
|
|
|
|
{
|
1998-05-08 20:18:06 +00:00
|
|
|
NS_IF_RELEASE(mCurrentOption);
|
|
|
|
mCurrentOption = nsnull;
|
1998-04-22 23:24:43 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
HTMLContentSink::ProcessOPTIONTagContent(const nsIParserNode& aNode)
|
|
|
|
{
|
1998-05-08 20:18:06 +00:00
|
|
|
if ((nsnull != mCurrentSelect) && (nsnull != mCurrentOption)) {
|
1998-06-06 20:25:11 +00:00
|
|
|
nsIFormControl* control = nsnull;
|
|
|
|
mCurrentOption->QueryInterface(kIFormControlIID, (void **)&control);
|
|
|
|
if (nsnull != control) {
|
|
|
|
// Get current content and append on the new content
|
|
|
|
nsAutoString currentText;
|
|
|
|
control->GetContent(currentText);
|
|
|
|
|
|
|
|
switch (aNode.GetTokenType()) {
|
|
|
|
case eToken_text:
|
|
|
|
case eToken_whitespace:
|
|
|
|
case eToken_newline:
|
|
|
|
currentText.Append(aNode.GetText());
|
|
|
|
break;
|
|
|
|
|
|
|
|
case eToken_entity:
|
|
|
|
{
|
|
|
|
nsAutoString tmp2("");
|
|
|
|
PRInt32 unicode = aNode.TranslateToUnicodeStr(tmp2);
|
|
|
|
if (unicode < 0) {
|
|
|
|
currentText.Append(aNode.GetText());
|
|
|
|
} else {
|
|
|
|
currentText.Append(tmp2);
|
|
|
|
}
|
1998-04-22 23:24:43 +00:00
|
|
|
}
|
1998-06-06 20:25:11 +00:00
|
|
|
break;
|
1998-04-22 23:24:43 +00:00
|
|
|
}
|
1998-06-06 20:25:11 +00:00
|
|
|
control->SetContent(currentText);
|
1998-08-03 19:21:26 +00:00
|
|
|
NS_RELEASE(control);
|
1998-04-22 23:24:43 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
1998-06-11 16:46:33 +00:00
|
|
|
nsresult
|
|
|
|
HTMLContentSink::ProcessIFRAMETag(nsIHTMLContent** aInstancePtrResult,
|
|
|
|
const nsIParserNode& aNode)
|
|
|
|
{
|
1998-07-14 01:57:51 +00:00
|
|
|
nsAutoString tmp("IFRAME");
|
1998-06-11 16:46:33 +00:00
|
|
|
nsIAtom* atom = NS_NewAtom(tmp);
|
|
|
|
|
1998-07-18 21:47:56 +00:00
|
|
|
nsresult rv = NS_NewHTMLIFrame(aInstancePtrResult, atom, mWebShell);
|
1998-06-11 16:46:33 +00:00
|
|
|
|
|
|
|
NS_RELEASE(atom);
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
1998-07-20 18:52:40 +00:00
|
|
|
nsresult
|
|
|
|
HTMLContentSink::ProcessFRAMESETTag(nsIHTMLContent** aInstancePtrResult,
|
|
|
|
const nsIParserNode& aNode)
|
|
|
|
{
|
|
|
|
nsAutoString tmp("FRAMESET");
|
|
|
|
nsIAtom* atom = NS_NewAtom(tmp);
|
|
|
|
|
1998-07-27 05:59:37 +00:00
|
|
|
nsresult rv = NS_NewHTMLFrameset(aInstancePtrResult, atom, mWebShell);
|
1998-07-20 18:52:40 +00:00
|
|
|
|
|
|
|
NS_RELEASE(atom);
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
1998-04-13 20:24:54 +00:00
|
|
|
nsresult HTMLContentSink::ProcessWBRTag(nsIHTMLContent** aInstancePtrResult,
|
|
|
|
const nsIParserNode& aNode)
|
|
|
|
{
|
1998-07-14 01:57:51 +00:00
|
|
|
nsAutoString tmp("WBR");
|
1998-04-13 20:24:54 +00:00
|
|
|
nsIAtom* atom = NS_NewAtom(tmp);
|
|
|
|
nsresult rv = NS_NewHTMLWordBreak(aInstancePtrResult, atom);
|
|
|
|
if (NS_OK == rv) {
|
|
|
|
rv = AddAttributes(aNode, *aInstancePtrResult);
|
|
|
|
}
|
|
|
|
NS_RELEASE(atom);
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
1998-06-23 01:34:25 +00:00
|
|
|
|
1998-04-13 20:24:54 +00:00
|
|
|
//----------------------------------------------------------------------
|
|
|
|
|
|
|
|
nsresult NS_NewHTMLContentSink(nsIHTMLContentSink** aInstancePtrResult,
|
|
|
|
nsIDocument* aDoc,
|
1998-06-23 22:25:28 +00:00
|
|
|
nsIURL* aURL,
|
1998-07-18 21:47:56 +00:00
|
|
|
nsIWebShell* aWebShell)
|
1998-04-13 20:24:54 +00:00
|
|
|
{
|
|
|
|
NS_PRECONDITION(nsnull != aInstancePtrResult, "null ptr");
|
|
|
|
if (nsnull == aInstancePtrResult) {
|
|
|
|
return NS_ERROR_NULL_POINTER;
|
|
|
|
}
|
|
|
|
HTMLContentSink* it = new HTMLContentSink();
|
|
|
|
if (nsnull == it) {
|
|
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
|
|
}
|
1998-07-18 21:47:56 +00:00
|
|
|
nsresult rv = it->Init(aDoc, aURL, aWebShell);
|
1998-04-13 20:24:54 +00:00
|
|
|
if (NS_OK != rv) {
|
|
|
|
delete it;
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
return it->QueryInterface(kIHTMLContentSinkIID, (void **)aInstancePtrResult);
|
|
|
|
}
|