This checkin contains combined work of rickg and harishd

Harishd's Changes:
 Fix for bugs
 2749    - Tweaked strict comment handling, i.e., <!------> is now treated as an illegal comment in strict mode
16934   - Rectifed reporting of JS line error when a newline is found within a tag.
15204   - Made TEXTAREA content to reflect the source document.
11979, 16826  - Stoping the parser properly on receiving the stop-error message.
17594   - Added code to parse <!DOCTYPE> content correctly.
17496   - Building up the stack for orphaned OPTIONs

r=rickg

Rickg's Changes:
  rickg will be posting comments on his changes by 11/12/99.

r=harishd
This commit is contained in:
harishd%netscape.com 1999-11-13 03:53:11 +00:00
Родитель 70bc2b5e0f
Коммит aa7503d71d
70 изменённых файлов: 3338 добавлений и 2946 удалений

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -104,6 +104,7 @@ class nsDTDContext;
class nsEntryStack;
class nsITokenizer;
class nsCParserNode;
class CTokenRecycler;
/***************************************************************
Now the main event: CNavDTD.
@ -187,6 +188,7 @@ CLASS_EXPORT_HTMLPARS CNavDTD : public nsIDTD {
PRBool aNotifySink,
nsString& aSourceType,
eParseMode aParseMode,
nsString& aCommand,
nsIContentSink* aSink=0);
/**
@ -289,7 +291,7 @@ CLASS_EXPORT_HTMLPARS CNavDTD : public nsIDTD {
* @param aChild -- int tag of child container
* @return PR_TRUE if parent can contain child
*/
virtual PRBool CanPropagate(eHTMLTags aParent,eHTMLTags aChild) const;
virtual PRBool CanPropagate(eHTMLTags aParent,eHTMLTags aChild,PRBool aParentContains) const;
/**
* This method gets called to determine whether a given
@ -298,9 +300,10 @@ CLASS_EXPORT_HTMLPARS CNavDTD : public nsIDTD {
* @update gess 3/25/98
* @param aParent -- parent tag being asked about omitting given child
* @param aChild -- child tag being tested for omittability by parent
* @param aParentContains -- can be 0,1,-1 (false,true, unknown)
* @return PR_TRUE if given tag can be omitted
*/
virtual PRBool CanOmit(eHTMLTags aParent,eHTMLTags aChild)const;
virtual PRBool CanOmit(eHTMLTags aParent,eHTMLTags aChild,PRBool& aParentContains) const;
/**
* This method gets called to determine whether a given
@ -375,7 +378,7 @@ CLASS_EXPORT_HTMLPARS CNavDTD : public nsIDTD {
* @param tag to be found
* @return index of topmost tag occurance -- may be -1 (kNotFound).
*/
virtual PRInt32 GetTopmostIndexOf(eHTMLTags aTag) const;
// virtual PRInt32 GetTopmostIndexOf(eHTMLTags aTag) const;
/**
* Finds the topmost occurance of given tag within context vector stack.
@ -415,12 +418,12 @@ CLASS_EXPORT_HTMLPARS CNavDTD : public nsIDTD {
* @return error code representing construction state; usually 0.
*/
nsresult HandleStartToken(CToken* aToken);
nsresult HandleDefaultStartToken(CToken* aToken,eHTMLTags aChildTag,nsIParserNode& aNode);
nsresult HandleDefaultStartToken(CToken* aToken,eHTMLTags aChildTag,nsIParserNode *aNode);
nsresult HandleEndToken(CToken* aToken);
nsresult HandleEntityToken(CToken* aToken);
nsresult HandleCommentToken(CToken* aToken);
nsresult HandleAttributeToken(CToken* aToken);
nsresult HandleScriptToken(nsCParserNode& aNode);
nsresult HandleScriptToken(const nsIParserNode *aNode);
nsresult HandleStyleToken(CToken* aToken);
nsresult HandleProcessingInstructionToken(CToken* aToken);
nsresult HandleDocTypeDeclToken(CToken* aToken);
@ -439,13 +442,13 @@ CLASS_EXPORT_HTMLPARS CNavDTD : public nsIDTD {
* @param node to be opened in content sink.
* @return error code representing error condition-- usually 0.
*/
nsresult OpenHTML(const nsIParserNode& aNode);
nsresult OpenHead(const nsIParserNode& aNode);
nsresult OpenBody(const nsIParserNode& aNode);
nsresult OpenForm(const nsIParserNode& aNode);
nsresult OpenMap(const nsIParserNode& aNode);
nsresult OpenFrameset(const nsIParserNode& aNode);
nsresult OpenContainer(const nsIParserNode& aNode,PRBool aClosedByStartTag);
nsresult OpenHTML(const nsIParserNode *aNode);
nsresult OpenHead(const nsIParserNode *aNode);
nsresult OpenBody(const nsIParserNode *aNode);
nsresult OpenForm(const nsIParserNode *aNode);
nsresult OpenMap(const nsIParserNode *aNode);
nsresult OpenFrameset(const nsIParserNode *aNode);
nsresult OpenContainer(const nsIParserNode *aNode,eHTMLTags aTag,PRBool aClosedByStartTag,PRInt32 aResidualStyleLevel=-1);
/**
* The next set of methods close the given HTML element.
@ -454,13 +457,12 @@ CLASS_EXPORT_HTMLPARS CNavDTD : public nsIDTD {
* @param HTML (node) to be opened in content sink.
* @return error code - 0 if all went well.
*/
nsresult CloseHTML(const nsIParserNode& aNode);
nsresult CloseHead(const nsIParserNode& aNode);
nsresult CloseBody(const nsIParserNode& aNode);
nsresult CloseForm(const nsIParserNode& aNode);
nsresult CloseMap(const nsIParserNode& aNode);
nsresult CloseFrameset(const nsIParserNode& aNode);
nsresult CloseContainer(const nsIParserNode& aNode,eHTMLTags anActualTag,PRBool aClosedByStartTag);
nsresult CloseHTML(const nsIParserNode *aNode);
nsresult CloseHead(const nsIParserNode *aNode);
nsresult CloseBody(const nsIParserNode *aNode);
nsresult CloseForm(const nsIParserNode *aNode);
nsresult CloseMap(const nsIParserNode *aNode);
nsresult CloseFrameset(const nsIParserNode *aNode);
/**
* The special purpose methods automatically close
@ -468,7 +470,7 @@ CLASS_EXPORT_HTMLPARS CNavDTD : public nsIDTD {
* @update gess5/11/98
* @return error code - 0 if all went well.
*/
nsresult CloseTopmostContainer();
nsresult CloseContainer(const nsIParserNode *aNode,eHTMLTags aTarget,PRBool aClosedByStartTag);
nsresult CloseContainersTo(eHTMLTags aTag,PRBool aClosedByStartTag);
nsresult CloseContainersTo(PRInt32 anIndex,eHTMLTags aTag,PRBool aClosedByStartTag);
@ -478,8 +480,8 @@ CLASS_EXPORT_HTMLPARS CNavDTD : public nsIDTD {
* @param aNode is leaf node to be added.
* @return error code - 0 if all went well.
*/
nsresult AddLeaf(const nsIParserNode& aNode);
nsresult AddHeadLeaf(nsIParserNode& aNode);
nsresult AddLeaf(const nsIParserNode *aNode);
nsresult AddHeadLeaf(nsIParserNode *aNode);
/**
* This set of methods is used to create and manage the set of
@ -492,8 +494,7 @@ CLASS_EXPORT_HTMLPARS CNavDTD : public nsIDTD {
*/
nsresult OpenTransientStyles(eHTMLTags aChildTag);
nsresult CloseTransientStyles(eHTMLTags aChildTag);
nsresult UpdateStyleStackForOpenTag(eHTMLTags aTag,eHTMLTags aActualTag);
nsresult UpdateStyleStackForCloseTag(eHTMLTags aTag,eHTMLTags aActualTag);
nsresult PopStyle(eHTMLTags aTag);
nsresult DoFragment(PRBool aFlag);
@ -503,8 +504,8 @@ protected:
nsresult CollectSkippedContent(nsCParserNode& aNode,PRInt32& aCount);
nsresult WillHandleStartTag(CToken* aToken,eHTMLTags aChildTag,nsCParserNode& aNode);
nsresult DidHandleStartTag(nsCParserNode& aNode,eHTMLTags aChildTag);
nsresult HandleOmittedTag(CToken* aToken,eHTMLTags aChildTag,eHTMLTags aParent,nsIParserNode& aNode);
nsresult HandleSavedTokensAbove(eHTMLTags aTag);
nsresult HandleOmittedTag(CToken* aToken,eHTMLTags aChildTag,eHTMLTags aParent,nsIParserNode *aNode);
nsresult HandleSavedTokens(PRInt32 anIndex);
nsCParserNode* CreateNode(void);
void RecycleNode(nsCParserNode* aNode);
@ -514,6 +515,7 @@ protected:
nsDTDContext* mBodyContext;
nsDTDContext* mFormContext;
nsDTDContext* mMapContext;
nsDTDContext* mTempContext;
PRBool mHasOpenForm;
PRBool mHasOpenMap;
PRInt32 mHasOpenHead;
@ -525,9 +527,11 @@ protected:
PRInt32 mLineNumber;
nsParser* mParser;
nsITokenizer* mTokenizer;
CTokenRecycler* mTokenRecycler;
nsDeque mMisplacedContent;
nsDeque mSkippedContent;
PRBool mHasOpenScript;
PRBool mSaveBadTokens;
eHTMLTags mSkipTarget;
nsDeque mSharedNodes;
nsresult mDTDState;
@ -535,6 +539,11 @@ protected:
PRUint32 mComputedCRC32;
PRUint32 mExpectedCRC32;
nsAutoString mScratch; //used for various purposes; non-persistent
#ifdef NS_DEBUG
PRInt32 gNodeCount;
#endif
};

Просмотреть файл

@ -191,7 +191,7 @@ eAutoDetectResult COtherDTD::CanParse(nsString& aContentType, nsString& aCommand
* @param aNode -- CParserNode representing this start token
* @return PR_TRUE if all went well; PR_FALSE if error occured
*/
nsresult COtherDTD::HandleDefaultStartToken(CToken* aToken,eHTMLTags aChildTag,nsIParserNode& aNode) {
nsresult COtherDTD::HandleDefaultStartToken(CToken* aToken,eHTMLTags aChildTag,nsIParserNode *aNode) {
return CNavDTD::HandleDefaultStartToken(aToken,aChildTag,aNode);
}
@ -279,7 +279,7 @@ nsresult COtherDTD::HandleAttributeToken(CToken* aToken) {
* @param aToken -- next (start) token to be handled
* @return PR_TRUE if all went well; PR_FALSE if error occured
*/
nsresult COtherDTD::HandleScriptToken(nsCParserNode& aNode) {
nsresult COtherDTD::HandleScriptToken(const nsIParserNode* aNode) {
return CNavDTD::HandleScriptToken(aNode);
}
@ -337,8 +337,8 @@ NS_IMETHODIMP COtherDTD::ConvertEntityToUnicode(const nsString& aEntity, PRInt32
* @param aTag -- tag to test for containership
* @return PR_TRUE if given tag can contain other tags
*/
PRBool COtherDTD::CanOmit(eHTMLTags aParent,eHTMLTags aChild) const {
return CNavDTD::CanOmit(aParent,aChild);
PRBool COtherDTD::CanOmit(eHTMLTags aParent,eHTMLTags aChild,PRInt32 aParentContains) const {
return CNavDTD::CanOmit(aParent,aChild,aParentContains);
}
@ -388,7 +388,7 @@ nsresult COtherDTD::CloseTransientStyles(eHTMLTags aTag){
* @param aNode -- next node to be added to model
* @return TRUE if ok, FALSE if error
*/
nsresult COtherDTD::OpenHTML(const nsIParserNode& aNode){
nsresult COtherDTD::OpenHTML(const nsIParserNode *aNode){
return CNavDTD::OpenHTML(aNode);
}
@ -401,7 +401,7 @@ nsresult COtherDTD::OpenHTML(const nsIParserNode& aNode){
* @param aNode -- next node to be removed from our model
* @return TRUE if ok, FALSE if error
*/
nsresult COtherDTD::CloseHTML(const nsIParserNode& aNode){
nsresult COtherDTD::CloseHTML(const nsIParserNode *aNode){
return CNavDTD::CloseHTML(aNode);
}
@ -414,7 +414,7 @@ nsresult COtherDTD::CloseHTML(const nsIParserNode& aNode){
* @param aNode -- next node to be added to model
* @return TRUE if ok, FALSE if error
*/
nsresult COtherDTD::OpenHead(const nsIParserNode& aNode){
nsresult COtherDTD::OpenHead(const nsIParserNode *aNode){
return CNavDTD::OpenHead(aNode);
}
@ -426,7 +426,7 @@ nsresult COtherDTD::OpenHead(const nsIParserNode& aNode){
* @param aNode -- next node to be removed from our model
* @return TRUE if ok, FALSE if error
*/
nsresult COtherDTD::CloseHead(const nsIParserNode& aNode){
nsresult COtherDTD::CloseHead(const nsIParserNode *aNode){
return CNavDTD::CloseHead(aNode);
}
@ -438,7 +438,7 @@ nsresult COtherDTD::CloseHead(const nsIParserNode& aNode){
* @param aNode -- next node to be added to model
* @return TRUE if ok, FALSE if error
*/
nsresult COtherDTD::OpenBody(const nsIParserNode& aNode){
nsresult COtherDTD::OpenBody(const nsIParserNode *aNode){
return CNavDTD::OpenBody(aNode);
}
@ -450,7 +450,7 @@ nsresult COtherDTD::OpenBody(const nsIParserNode& aNode){
* @param aNode -- next node to be removed from our model
* @return TRUE if ok, FALSE if error
*/
nsresult COtherDTD::CloseBody(const nsIParserNode& aNode){
nsresult COtherDTD::CloseBody(const nsIParserNode *aNode){
return CNavDTD::CloseBody(aNode);
}
@ -462,7 +462,7 @@ nsresult COtherDTD::CloseBody(const nsIParserNode& aNode){
* @param aNode -- next node to be added to model
* @return TRUE if ok, FALSE if error
*/
nsresult COtherDTD::OpenForm(const nsIParserNode& aNode){
nsresult COtherDTD::OpenForm(const nsIParserNode *aNode){
return CNavDTD::OpenForm(aNode);
}
@ -474,7 +474,7 @@ nsresult COtherDTD::OpenForm(const nsIParserNode& aNode){
* @param aNode -- next node to be removed from our model
* @return TRUE if ok, FALSE if error
*/
nsresult COtherDTD::CloseForm(const nsIParserNode& aNode){
nsresult COtherDTD::CloseForm(const nsIParserNode *aNode){
return CNavDTD::CloseForm(aNode);
}
@ -486,7 +486,7 @@ nsresult COtherDTD::CloseForm(const nsIParserNode& aNode){
* @param aNode -- next node to be added to model
* @return TRUE if ok, FALSE if error
*/
nsresult COtherDTD::OpenMap(const nsIParserNode& aNode){
nsresult COtherDTD::OpenMap(const nsIParserNode *aNode){
return CNavDTD::OpenMap(aNode);
}
@ -498,7 +498,7 @@ nsresult COtherDTD::OpenMap(const nsIParserNode& aNode){
* @param aNode -- next node to be removed from our model
* @return TRUE if ok, FALSE if error
*/
nsresult COtherDTD::CloseMap(const nsIParserNode& aNode){
nsresult COtherDTD::CloseMap(const nsIParserNode *aNode){
return CNavDTD::CloseMap(aNode);
}
@ -510,7 +510,7 @@ nsresult COtherDTD::CloseMap(const nsIParserNode& aNode){
* @param aNode -- next node to be added to model
* @return TRUE if ok, FALSE if error
*/
nsresult COtherDTD::OpenFrameset(const nsIParserNode& aNode){
nsresult COtherDTD::OpenFrameset(const nsIParserNode *aNode){
return CNavDTD::OpenFrameset(aNode);
}
@ -522,7 +522,7 @@ nsresult COtherDTD::OpenFrameset(const nsIParserNode& aNode){
* @param aNode -- next node to be removed from our model
* @return TRUE if ok, FALSE if error
*/
nsresult COtherDTD::CloseFrameset(const nsIParserNode& aNode){
nsresult COtherDTD::CloseFrameset(const nsIParserNode *aNode){
return CNavDTD::CloseFrameset(aNode);
}
@ -534,8 +534,8 @@ nsresult COtherDTD::CloseFrameset(const nsIParserNode& aNode){
* @param aNode -- next node to be added to model
* @return TRUE if ok, FALSE if error
*/
nsresult COtherDTD::OpenContainer(const nsIParserNode& aNode,PRBool aUpdateStyleStack){
return CNavDTD::OpenContainer(aNode,aUpdateStyleStack);
nsresult COtherDTD::OpenContainer(const nsIParserNode *aNode,eHTMLTags aTarget,PRBool aUpdateStyleStack,PRInt32 aResidualStyleLevel){
return CNavDTD::OpenContainer(aNode,aTarget,aUpdateStyleStack,aResidualStyleLevel);
}
/**
@ -546,8 +546,8 @@ nsresult COtherDTD::OpenContainer(const nsIParserNode& aNode,PRBool aUpdateStyle
* @param aNode -- next node to be removed from our model
* @return TRUE if ok, FALSE if error
*/
nsresult COtherDTD::CloseContainer(const nsIParserNode& aNode,eHTMLTags aTag,PRBool aUpdateStyles){
return CNavDTD::CloseContainer(aNode,aTag,aUpdateStyles);
nsresult COtherDTD::CloseContainer(const nsIParserNode *aNode,eHTMLTags aTarget,PRBool aUpdateStyles){
return CNavDTD::CloseContainer(aNode,aTarget,aUpdateStyles);
}
/**
@ -558,8 +558,8 @@ nsresult COtherDTD::CloseContainer(const nsIParserNode& aNode,eHTMLTags aTag,PRB
* @param
* @return TRUE if ok, FALSE if error
*/
nsresult COtherDTD::CloseContainersTo(PRInt32 anIndex,eHTMLTags aTag,PRBool aUpdateStyles){
return CNavDTD::CloseContainersTo(anIndex,aTag,aUpdateStyles);
nsresult COtherDTD::CloseContainersTo(PRInt32 anIndex,eHTMLTags aTarget,PRBool aUpdateStyles){
return CNavDTD::CloseContainersTo(anIndex,aTarget,aUpdateStyles);
}
/**
@ -570,21 +570,10 @@ nsresult COtherDTD::CloseContainersTo(PRInt32 anIndex,eHTMLTags aTag,PRBool aUpd
* @param
* @return TRUE if ok, FALSE if error
*/
nsresult COtherDTD::CloseContainersTo(eHTMLTags aTag,PRBool aUpdateStyles){
return CNavDTD::CloseContainersTo(aTag,aUpdateStyles);
nsresult COtherDTD::CloseContainersTo(eHTMLTags aTarget,PRBool aUpdateStyles){
return CNavDTD::CloseContainersTo(aTarget,aUpdateStyles);
}
/**
* This method causes the topmost container on the stack
* to be closed.
* @update gess4/6/98
* @see CloseContainer()
* @param
* @return TRUE if ok, FALSE if error
*/
nsresult COtherDTD::CloseTopmostContainer(){
return CNavDTD::CloseTopmostContainer();
}
/**
* This method does two things: 1st, help construct
@ -594,7 +583,7 @@ nsresult COtherDTD::CloseTopmostContainer(){
* @param aNode -- next node to be added to model
* @return TRUE if ok, FALSE if error
*/
nsresult COtherDTD::AddLeaf(const nsIParserNode& aNode){
nsresult COtherDTD::AddLeaf(const nsIParserNode *aNode){
return CNavDTD::AddLeaf(aNode);
}
@ -614,18 +603,6 @@ nsresult COtherDTD::CreateContextStackFor(eHTMLTags aChildTag){
}
/**
* This method causes all explicit style-tag containers that
* are opened to be reflected on our internal style-stack.
*
* @update gess6/4/98
* @param aTag is the id of the html container being opened
* @return 0 if all is well.
*/
nsresult COtherDTD::UpdateStyleStackForOpenTag(eHTMLTags aTag,eHTMLTags anActualTag){
return CNavDTD::UpdateStyleStackForOpenTag(aTag,anActualTag);
} //update...
/**
* This method gets called when an explicit style close-tag is encountered.
* It results in the style tag id being popped from our internal style stack.
@ -634,8 +611,8 @@ nsresult COtherDTD::UpdateStyleStackForOpenTag(eHTMLTags aTag,eHTMLTags anActual
* @param
* @return 0 if all went well (which it always does)
*/
nsresult COtherDTD::UpdateStyleStackForCloseTag(eHTMLTags aTag,eHTMLTags anActualTag){
return CNavDTD::UpdateStyleStackForCloseTag(aTag,anActualTag);
nsresult COtherDTD::PopStyle(eHTMLTags aTag){
return CNavDTD::PopStyle(aTag);
} //update...
/**

Просмотреть файл

@ -123,7 +123,7 @@ class COtherDTD : public CNavDTD {
* @param aTag -- tag to test for containership
* @return PR_TRUE if given tag can contain other tags
*/
virtual PRBool CanOmit(eHTMLTags aParent,eHTMLTags aChild)const;
virtual PRBool CanOmit(eHTMLTags aParent,eHTMLTags aChild,PRInt32 aParentContains)const;
/**
* Give rest of world access to our tag enums, so that CanContain(), etc,
@ -155,7 +155,7 @@ class COtherDTD : public CNavDTD {
* @param aNode is a node be updated with info from given token
* @return TRUE if the token was handled.
*/
nsresult HandleDefaultStartToken(CToken* aToken,eHTMLTags aChildTag,nsIParserNode& aNode);
nsresult HandleDefaultStartToken(CToken* aToken,eHTMLTags aChildTag,nsIParserNode *aNode);
/**
* This method gets called when an end token has been consumed and needs
@ -200,7 +200,7 @@ class COtherDTD : public CNavDTD {
* @param aToken is the script token to be handled
* @return TRUE if the token was handled.
*/
nsresult HandleScriptToken(nsCParserNode& aNode);
nsresult HandleScriptToken(const nsIParserNode *aNode);
/**
* This method gets called when a style token has been consumed and needs
@ -220,146 +220,38 @@ private:
//*************************************************
/**
* This cover method opens the given node as a HTML item in
* content sink.
* @update gess5/11/98
* @param HTML (node) to be opened in content sink.
* @return TRUE if all went well.
*/
nsresult OpenHTML(const nsIParserNode& aNode);
/**
* The next set of method open given HTML elements of
* various types.
*
* @update gess5/11/98
* @param
* @return
* @param node to be opened in content sink.
* @return error code representing error condition-- usually 0.
*/
nsresult CloseHTML(const nsIParserNode& aNode);
nsresult OpenHTML(const nsIParserNode *aNode);
nsresult OpenHead(const nsIParserNode *aNode);
nsresult OpenBody(const nsIParserNode *aNode);
nsresult OpenForm(const nsIParserNode *aNode);
nsresult OpenMap(const nsIParserNode *aNode);
nsresult OpenFrameset(const nsIParserNode *aNode);
nsresult OpenContainer(const nsIParserNode *aNode,eHTMLTags aTag,PRBool aUpdateStyleStack,PRInt32 aResidualStyleLevel=-1);
/**
* This cover method opens the given node as a head item in
* content sink.
* The next set of methods close the given HTML element.
*
* @update gess5/11/98
* @param HEAD (node) to be opened in content sink.
* @return TRUE if all went well.
* @param HTML (node) to be opened in content sink.
* @return error code - 0 if all went well.
*/
nsresult OpenHead(const nsIParserNode& aNode);
nsresult CloseHTML(const nsIParserNode *aNode);
nsresult CloseHead(const nsIParserNode *aNode);
nsresult CloseBody(const nsIParserNode *aNode);
nsresult CloseForm(const nsIParserNode *aNode);
nsresult CloseMap(const nsIParserNode *aNode);
nsresult CloseFrameset(const nsIParserNode *aNode);
/**
* This cover method causes the content-sink head to be closed
* @update gess5/11/98
* @param aNode is the node to be closed in sink (usually ignored)
* @return TRUE if all went well.
*/
nsresult CloseHead(const nsIParserNode& aNode);
/**
* This cover method opens the given node as a body item in
* content sink.
* @update gess5/11/98
* @param BODY (node) to be opened in content sink.
* @return TRUE if all went well.
*/
nsresult OpenBody(const nsIParserNode& aNode);
/**
* This cover method causes the content-sink body to be closed
* @update gess5/11/98
* @param aNode is the body node to be closed in sink (usually ignored)
* @return TRUE if all went well.
*/
nsresult CloseBody(const nsIParserNode& aNode);
/**
* This cover method opens the given node as a form item in
* content sink.
* @update gess5/11/98
* @param FORM (node) to be opened in content sink.
* @return TRUE if all went well.
*/
nsresult OpenForm(const nsIParserNode& aNode);
/**
* This cover method causes the content-sink form to be closed
* @update gess5/11/98
* @param aNode is the form node to be closed in sink (usually ignored)
* @return TRUE if all went well.
*/
nsresult CloseForm(const nsIParserNode& aNode);
/**
* This cover method opens the given node as a form item in
* content sink.
* @update gess5/11/98
* @param FORM (node) to be opened in content sink.
* @return TRUE if all went well.
*/
nsresult OpenMap(const nsIParserNode& aNode);
/**
* This cover method causes the content-sink form to be closed
* @update gess5/11/98
* @param aNode is the form node to be closed in sink (usually ignored)
* @return TRUE if all went well.
*/
nsresult CloseMap(const nsIParserNode& aNode);
/**
* This cover method opens the given node as a frameset item in
* content sink.
* @update gess5/11/98
* @param FRAMESET (node) to be opened in content sink.
* @return TRUE if all went well.
*/
nsresult OpenFrameset(const nsIParserNode& aNode);
/**
* This cover method causes the content-sink frameset to be closed
* @update gess5/11/98
* @param aNode is the frameeset node to be closed in sink (usually ignored)
* @return TRUE if all went well.
*/
nsresult CloseFrameset(const nsIParserNode& aNode);
/**
* This cover method opens the given node as a generic container in
* content sink.
* @update gess5/11/98
* @param generic container (node) to be opened in content sink.
* @return TRUE if all went well.
*/
nsresult OpenContainer(const nsIParserNode& aNode,PRBool aUpdateStyleStack);
/**
* This cover method causes a generic containre in the content-sink to be closed
* @update gess5/11/98
* @param aNode is the node to be closed in sink (usually ignored)
* @return TRUE if all went well.
*/
nsresult CloseContainer(const nsIParserNode& aNode,eHTMLTags anActualTag,PRBool aUpdateStyles);
/**
* This cover method causes the topmost container to be closed in sink
* @update gess5/11/98
* @return TRUE if all went well.
*/
nsresult CloseTopmostContainer();
/**
* Cause all containers down to topmost given tag to be closed
* @update gess5/11/98
* @param aTag is the tag at which auto-closure should stop (inclusive)
* @return TRUE if all went well -- otherwise FALSE
*/
nsresult CloseContainer(const nsIParserNode *aNode,eHTMLTags aTarget,PRBool aUpdateStyles);
nsresult CloseContainersTo(eHTMLTags aTag,PRBool aUpdateStyles);
/**
* Cause all containers down to given position to be closed
* @update gess5/11/98
* @param anIndex is the stack pos at which auto-closure should stop (inclusive)
* @return TRUE if all went well -- otherwise FALSE
*/
nsresult CloseContainersTo(PRInt32 anIndex,eHTMLTags aTag,PRBool aUpdateStyles);
nsresult CloseContainersTo(PRInt32 anIndex,eHTMLTags aTarget,PRBool aUpdateStyles);
/**
* Causes leaf to be added to sink at current vector pos.
@ -367,7 +259,7 @@ private:
* @param aNode is leaf node to be added.
* @return TRUE if all went well -- FALSE otherwise.
*/
nsresult AddLeaf(const nsIParserNode& aNode);
nsresult AddLeaf(const nsIParserNode *aNode);
/**
@ -381,8 +273,7 @@ private:
nsresult OpenTransientStyles(eHTMLTags aTag);
nsresult CloseTransientStyles(eHTMLTags aTag);
nsresult UpdateStyleStackForOpenTag(eHTMLTags aTag,eHTMLTags aActualTag);
nsresult UpdateStyleStackForCloseTag(eHTMLTags aTag,eHTMLTags aActualTag);
nsresult PopStyle(eHTMLTags aTag);
nsresult DoFragment(PRBool aFlag);

Просмотреть файл

@ -261,7 +261,9 @@ eAutoDetectResult CRtfDTD::CanParse(nsString& aContentType, nsString& aCommand,
* @param
* @return
*/
NS_IMETHODIMP CRtfDTD::WillBuildModel(nsString& aFilename,PRBool aNotifySink,nsString& aSourceType,eParseMode aParseMode,nsIContentSink* aSink){
NS_IMETHODIMP CRtfDTD::WillBuildModel(nsString& aFilename,PRBool aNotifySink,
nsString& aSourceType,eParseMode aParseMode,
nsString& aCommand,nsIContentSink* aSink){
nsresult result=NS_OK;
return result;
}

Просмотреть файл

@ -202,6 +202,7 @@ class CRtfDTD : public nsIDTD {
PRBool aNotifySink,
nsString& aSourceType,
eParseMode aParseMode,
nsString& aCommand,
nsIContentSink* aSink=0);
/**

Просмотреть файл

@ -24,6 +24,7 @@
#include "nsDTDUtils.h"
#include "CNavDTD.h"
#include "nsIParserNode.h"
#include "nsParserNode.h"
#include "nsIObserverService.h"
#include "nsIServiceManager.h"
@ -33,9 +34,6 @@ MOZ_DECL_CTOR_COUNTER(nsDTDContext);
MOZ_DECL_CTOR_COUNTER(CTokenRecycler);
MOZ_DECL_CTOR_COUNTER(CObserverService);
/***************************************************************
First, define the tagstack class
***************************************************************/
/**
@ -61,12 +59,24 @@ nsEntryStack::~nsEntryStack() {
MOZ_COUNT_DTOR(nsEntryStack);
if(mEntries)
if(mEntries) {
if(0<mCount) {
PRInt32 anIndex=0;
for(anIndex=0;anIndex<mCount;anIndex++){
if(mEntries[anIndex].mStyles)
delete mEntries[anIndex].mStyles;
//add code here to recycle the node if you have one...
}
}
delete [] mEntries;
mCount=mCapacity=0;
mEntries=0;
}
mCount=mCapacity=0;
}
/**
* Resets state of stack to be empty.
* @update harishd 04/04/99
@ -75,17 +85,24 @@ void nsEntryStack::Empty(void) {
mCount=0;
}
/**
*
* @update gess 04/22/99
*/
void nsEntryStack::Push(eHTMLTags aTag) {
if(mCount==mCapacity){
nsTagEntry* temp=new nsTagEntry[mCapacity+=50];
void nsEntryStack::EnsureCapacityFor(PRInt32 aNewMax,PRInt32 aShiftOffset) {
if(mCapacity<aNewMax){
const int kDelta=16;
PRInt32 theSize = kDelta * ((aNewMax / kDelta) + 1);
nsTagEntry* temp=new nsTagEntry[theSize];
mCapacity=theSize;
if(temp){
PRUint32 index=0;
PRInt32 index=0;
for(index=0;index<mCount;index++) {
temp[index]=mEntries[index];
temp[aShiftOffset+index]=mEntries[index];
}
delete [] mEntries;
mEntries=temp;
@ -93,10 +110,76 @@ void nsEntryStack::Push(eHTMLTags aTag) {
else{
//XXX HACK! This is very bad! We failed to get memory.
}
} //if
}
/**
*
* @update gess 04/22/99
*/
void nsEntryStack::Push(const nsIParserNode* aNode,PRInt32 aResidualStyleLevel) {
if(aNode) {
EnsureCapacityFor(mCount+1);
((nsCParserNode*)aNode)->mUseCount++;
((nsCParserNode*)aNode)->mToken->mUseCount++;
mEntries[mCount].mTag=(eHTMLTags)aNode->GetNodeType();
mEntries[mCount].mNode=(nsIParserNode*)aNode;
mEntries[mCount].mLevel=aResidualStyleLevel;
mEntries[mCount].mParent=0;
mEntries[mCount++].mStyles=0;
}
}
/**
* This method inserts the given node onto the front of this stack
*
* @update gess 11/10/99
*/
void nsEntryStack::PushFront(const nsIParserNode* aNode,PRInt32 aResidualStyleLevel) {
if(aNode) {
if(mCount<mCapacity) {
PRInt32 index=0;
for(index=mCount;index>0;index--) {
mEntries[index]=mEntries[index-1];
}
}
else EnsureCapacityFor(mCount+1,1);
((nsCParserNode*)aNode)->mUseCount++;
((nsCParserNode*)aNode)->mToken->mUseCount++;
mEntries[0].mTag=(eHTMLTags)aNode->GetNodeType();
mEntries[0].mNode=(nsIParserNode*)aNode;
mEntries[0].mLevel=aResidualStyleLevel;
mEntries[0].mParent=0;
mEntries[0].mStyles=0;
mCount++;
}
}
/**
*
* @update gess 11/10/99
*/
void nsEntryStack::Append(nsEntryStack *aStack) {
if(aStack) {
PRInt32 theCount=aStack->mCount;
EnsureCapacityFor(mCount+aStack->mCount,0);
PRInt32 theIndex=0;
for(theIndex=0;theIndex<theCount;theIndex++){
mEntries[mCount]=aStack->mEntries[theIndex];
mEntries[mCount++].mLevel=-1;
}
}
mEntries[mCount].mTag=aTag;
mEntries[mCount].mBankIndex=-1;
mEntries[mCount++].mStyleIndex=-1;
}
@ -105,10 +188,17 @@ void nsEntryStack::Push(eHTMLTags aTag) {
* @update harishd 04/04/99
* @update gess 04/21/99
*/
eHTMLTags nsEntryStack::Pop() {
eHTMLTags result=eHTMLTag_unknown;
nsIParserNode* nsEntryStack::Pop(void) {
nsIParserNode *result=0;
if(0<mCount) {
result=mEntries[--mCount].mTag;
result=mEntries[--mCount].mNode;
((nsCParserNode*)result)->mUseCount--;
((nsCParserNode*)result)->mToken->mUseCount--;
mEntries[mCount].mNode=0;
mEntries[mCount].mStyles=0;
}
return result;
}
@ -131,9 +221,22 @@ eHTMLTags nsEntryStack::First() const {
* @update harishd 04/04/99
* @update gess 04/21/99
*/
eHTMLTags nsEntryStack::TagAt(PRUint32 anIndex) const {
nsIParserNode* nsEntryStack::NodeAt(PRInt32 anIndex) const {
nsIParserNode* result=0;
if((0<mCount) && (anIndex<mCount)) {
result=mEntries[anIndex].mNode;
}
return result;
}
/**
*
* @update harishd 04/04/99
* @update gess 04/21/99
*/
eHTMLTags nsEntryStack::TagAt(PRInt32 anIndex) const {
eHTMLTags result=eHTMLTag_unknown;
if(anIndex<mCount) {
if((0<mCount) && (anIndex<mCount)) {
result=mEntries[anIndex].mTag;
}
return result;
@ -143,12 +246,12 @@ eHTMLTags nsEntryStack::TagAt(PRUint32 anIndex) const {
*
* @update gess 04/21/99
*/
nsTagEntry& nsEntryStack::EntryAt(PRUint32 anIndex) const {
static nsTagEntry gSentinel;
if(anIndex<mCount) {
return mEntries[anIndex];
nsTagEntry* nsEntryStack::EntryAt(PRInt32 anIndex) const {
nsTagEntry *result=0;
if((0<mCount) && (anIndex<mCount)) {
result=&mEntries[anIndex];
}
return gSentinel;
return result;
}
@ -157,9 +260,9 @@ nsTagEntry& nsEntryStack::EntryAt(PRUint32 anIndex) const {
* @update harishd 04/04/99
* @update gess 04/21/99
*/
eHTMLTags nsEntryStack::operator[](PRUint32 anIndex) const {
eHTMLTags nsEntryStack::operator[](PRInt32 anIndex) const {
eHTMLTags result=eHTMLTag_unknown;
if(anIndex<mCount) {
if((0<mCount) && (anIndex<mCount)) {
result=mEntries[anIndex].mTag;
}
return result;
@ -172,9 +275,14 @@ eHTMLTags nsEntryStack::operator[](PRUint32 anIndex) const {
* @update gess 04/21/99
*/
eHTMLTags nsEntryStack::Last() const {
return TagAt(mCount-1);
eHTMLTags result=eHTMLTag_unknown;
if(0<mCount) {
result=mEntries[mCount-1].mTag;
}
return result;
}
#if 0
/**
*
* @update harishd 04/04/99
@ -189,8 +297,7 @@ PRInt32 nsEntryStack::GetTopmostIndexOf(eHTMLTags aTag) const {
return kNotFound;
}
#endif
/***************************************************************
@ -202,12 +309,12 @@ PRInt32 nsEntryStack::GetTopmostIndexOf(eHTMLTags aTag) const {
*
* @update gess9/10/98
*/
nsDTDContext::nsDTDContext() : mStack(), mSkipped(0), mStyles(0) {
nsDTDContext::nsDTDContext() : mStack() {
MOZ_COUNT_CTOR(nsDTDContext);
#ifdef NS_DEBUG
nsCRT::zero(mTags,sizeof(mTags));
memset(mXTags,0,sizeof(mXTags));
#endif
}
@ -217,21 +324,7 @@ nsDTDContext::nsDTDContext() : mStack(), mSkipped(0), mStyles(0) {
* @update gess9/10/98
*/
nsDTDContext::~nsDTDContext() {
MOZ_COUNT_DTOR(nsDTDContext);
PRInt32 theSize=mSkipped.GetSize();
if(theSize>0) {
CTokenDeallocator theDeallocator;
for(PRInt32 i=0;i<theSize;i++) {
nsDeque* theDeque=(nsDeque*)mSkipped.Pop();
if(theDeque) {
if(theDeque->GetSize()>0) theDeque->ForEach(theDeallocator);
delete theDeque;
theDeque=nsnull;
}
}
}
}
/**
@ -239,40 +332,25 @@ nsDTDContext::~nsDTDContext() {
* @update gess7/9/98, harishd 04/04/99
*/
PRInt32 nsDTDContext::GetCount(void) {
return mStack.GetCount();
return mStack.mCount;
}
/**
*
* @update gess7/9/98
*/
PRBool nsDTDContext::HasOpenContainer(eHTMLTags aTag) const {
PRInt32 theIndex=mStack.FindLast(aTag);
return PRBool(-1<theIndex);
}
/**
*
* @update gess7/9/98, harishd 04/04/99
* @update gess7/9/98
*/
void nsDTDContext::Push(eHTMLTags aTag) {
#ifdef NS_DEBUG
if(mStack.mCount < eMaxTags)
mTags[mStack.mCount]=aTag;
#endif
mStack.Push(aTag);
}
/**
* @update gess7/9/98, harishd 04/04/99
*/
eHTMLTags nsDTDContext::Pop() {
#ifdef NS_DEBUG
if ((mStack.mCount>0) && (mStack.mCount <= eMaxTags))
mTags[mStack.mCount-1]=eHTMLTag_unknown;
#endif
nsEntryStack* theStyles=0;
nsTagEntry& theEntry=mStack.EntryAt(mStack.mCount-1);
PRInt32 theIndex=theEntry.mStyleIndex;
if(-1<theIndex){
theStyles=(nsEntryStack*)mStyles.ObjectAt(theIndex);
delete theStyles;
}
eHTMLTags result=mStack.Pop();
PRInt32 nsDTDContext::GetTopmostIndexOf(eHTMLTags aTag) const {
PRInt32 result=mStack.FindLast(aTag);
return result;
}
@ -280,7 +358,53 @@ eHTMLTags nsDTDContext::Pop() {
*
* @update gess7/9/98
*/
eHTMLTags nsDTDContext::First() const {
void nsDTDContext::Push(const nsIParserNode* aNode,PRInt32 aResidualStyleLevel) {
if(aNode) {
#ifdef NS_DEBUG
eHTMLTags theTag=(eHTMLTags)aNode->GetNodeType();
int size=mStack.mCount;
if(size< eMaxTags)
mXTags[size]=theTag;
#endif
mStack.Push((nsIParserNode*)aNode,aResidualStyleLevel);
}
}
/**
* @update gess 11/11/99,
* harishd 04/04/99
*/
nsIParserNode* nsDTDContext::Pop(nsEntryStack *&aStack) {
PRInt32 theSize=mStack.mCount;
nsIParserNode *result=0;
if(0<theSize) {
#ifdef NS_DEBUG
if ((theSize>0) && (theSize <= eMaxTags))
mXTags[theSize-1]=eHTMLTag_unknown;
#endif
nsTagEntry* theEntry=mStack.EntryAt(mStack.mCount-1);
if(theEntry) {
aStack=theEntry->mStyles;
}
result=mStack.Pop();
}
return result;
}
/**
*
* @update gess7/9/98
*/
eHTMLTags nsDTDContext::First(void) const {
return mStack.First();
}
@ -293,14 +417,6 @@ eHTMLTags nsDTDContext::TagAt(PRInt32 anIndex) const {
}
/**
*
* @update gess7/9/98
*/
eHTMLTags nsDTDContext::operator[](PRInt32 anIndex) const {
return mStack[anIndex];
}
/**
*
* @update gess7/9/98
@ -309,132 +425,108 @@ eHTMLTags nsDTDContext::Last() const {
return mStack.Last();
}
/**
*
* @update gess7/9/98
*/
nsEntryStack* nsDTDContext::GetStylesAt(PRUint32 anIndex) const {
nsEntryStack* nsDTDContext::GetStylesAt(PRInt32 anIndex) const {
nsEntryStack* result=0;
if(anIndex<mStack.mCount){
nsTagEntry& theEntry=mStack.EntryAt(anIndex);
PRInt32 theIndex=theEntry.mStyleIndex;
if(-1<theIndex){
result=(nsEntryStack*)mStyles.ObjectAt(theIndex);
nsTagEntry* theEntry=mStack.EntryAt(anIndex);
if(theEntry) {
result=theEntry->mStyles;
}
}
return result;
}
/**
*
* @update gess 04/28/99
*/
void nsDTDContext::PushStyle(eHTMLTags aTag){
void nsDTDContext::PushStyle(const nsIParserNode* aNode){
nsTagEntry& theEntry=mStack.EntryAt(mStack.mCount-1);
//ok, now go get the right tokenbank deque...
nsEntryStack* theStack=0;
if(-1<theEntry.mStyleIndex)
theStack=(nsEntryStack*)mStyles.ObjectAt(theEntry.mStyleIndex);
if(!theStack){
//time to make a databank for this element...
theStack=new nsEntryStack();
if(theStack){
mStyles.Push(theStack);
theEntry.mStyleIndex=mStyles.GetSize()-1;
nsTagEntry* theEntry=mStack.EntryAt(mStack.mCount-1);
if(theEntry ) {
nsEntryStack* theStack=theEntry->mStyles;
if(!theStack) {
theStack=theEntry->mStyles=new nsEntryStack();
}
else{
//XXX Hack! This is very back, we've failed to get memory.
if(theStack) {
theStack->Push(aNode);
theEntry=&theStack->mEntries[theStack->mCount-1];
if(theEntry) {
theEntry->mParent=theStack;
}
}
if(theStack){
theStack->Push(aTag);
}
} //if
}
/**
* Call this when you have an EntryStack full of styles
* that you want to push at this level.
*
* @update gess 04/28/99
*/
void nsDTDContext::PushStyles(nsEntryStack *aStyles){
if(aStyles) {
nsTagEntry* theEntry=mStack.EntryAt(mStack.mCount-1);
if(theEntry ) {
nsEntryStack* theStyles=theEntry->mStyles;
if(!theStyles) {
theEntry->mStyles=aStyles;
}
else theStyles->Append(aStyles);
} //if
}//if
}
/**
*
* @update gess 04/28/99
*/
eHTMLTags nsDTDContext::PopStyle(void){
eHTMLTags result=eHTMLTag_unknown;
nsTagEntry& theEntry=mStack.EntryAt(mStack.mCount-1);
//ok, now go get the right tokenbank deque...
nsEntryStack* theStack=0;
if(-1<theEntry.mStyleIndex)
theStack=(nsEntryStack*)mStyles.ObjectAt(theEntry.mStyleIndex);
if(theStack){
nsIParserNode* nsDTDContext::PopStyle(void){
nsIParserNode* result=0;
nsTagEntry *theEntry=mStack.EntryAt(mStack.mCount-1);
if(theEntry && (theEntry->mNode)) {
if(kNotFound<theEntry->mLevel){
nsEntryStack *theStack=mStack.mEntries[theEntry->mLevel].mStyles;
if(theStack) {
result=theStack->Pop();
}
return result;
}
/**
*
* @update harishd 04/04/99
* @update gess 04/21/99
*/
void nsDTDContext::SaveToken(CToken* aToken, PRInt32 aID)
{
NS_PRECONDITION(aID <= mStack.GetCount() && aID > -1,"Out of bounds");
if(aToken) {
nsTagEntry& theEntry=mStack.EntryAt(aID);
//ok, now go get the right tokenbank deque...
nsDeque* theDeque=0;
if(-1<theEntry.mBankIndex)
theDeque=(nsDeque*)mSkipped.ObjectAt(theEntry.mBankIndex);
if(!theDeque){
//time to make a databank for this element...
theDeque=new nsDeque(0);
if(theDeque){
mSkipped.Push(theDeque);
theEntry.mBankIndex=mSkipped.GetSize()-1;
}
else{
//XXX Hack! This is very back, we've failed to get memory.
}
}
theDeque->Push(aToken);
}
}
/**
*
* @update harishd 04/04/99
* @update gess 04/21/99
*/
CToken* nsDTDContext::RestoreTokenFrom(PRInt32 aID)
{
NS_PRECONDITION(aID <= mStack.GetCount() && aID > -1,"Out of bounds");
CToken* result=0;
if(0<mStack.GetCount()) {
nsTagEntry theEntry=mStack.EntryAt(aID);
nsDeque* theDeque=(nsDeque*)mSkipped.ObjectAt(theEntry.mBankIndex);
if(theDeque){
result=(CToken*)theDeque->PopFront();
}
}
} //if
return result;
}
/**
*
* @update harishd 04/04/99
* @update gess 04/21/99
* @update gess 04/28/99
*/
PRInt32 nsDTDContext::TokenCountAt(PRInt32 aID)
{
NS_PRECONDITION(aID <= mStack.GetCount(),"Out of bounds");
nsIParserNode* nsDTDContext::PopStyle(eHTMLTags aTag){
nsTagEntry theEntry=mStack.EntryAt(aID);
nsDeque* theDeque=(nsDeque*)mSkipped.ObjectAt(theEntry.mBankIndex);
if(theDeque){
return theDeque->GetSize();
PRInt32 theLevel=0;
PRInt32 sindex=0;
for(theLevel=mStack.mCount-1;theLevel>0;theLevel--) {
nsEntryStack *theStack=mStack.mEntries[theLevel].mStyles;
if(theStack) {
if(aTag==theStack->Last()) {
return theStack->Pop();
} else {
// NS_ERROR("bad residual style entry");
}
}
}
return kNotFound;
return 0;
}
/**************************************************************
@ -452,7 +544,7 @@ CTokenRecycler::CTokenRecycler() : nsITokenRecycler(),mEmpty("") {
int i=0;
for(i=0;i<eToken_last-1;i++) {
mTokenCache[i]=new nsDeque(new CTokenDeallocator());
mTokenCache[i]=new nsDeque(0);
#ifdef NS_DEBUG
mTotals[i]=0;
#endif
@ -470,15 +562,17 @@ CTokenRecycler::~CTokenRecycler() {
//begin by deleting all the known (recycled) tokens...
//We're also deleting the cache-deques themselves.
int i;
CTokenDeallocator theDeallocator;
for(i=0;i<eToken_last-1;i++) {
if(0!=mTokenCache[i]) {
mTokenCache[i]->ForEach(theDeallocator);
delete mTokenCache[i];
mTokenCache[i]=0;
}
}
}
class CTokenFinder: public nsDequeFunctor{
public:
CTokenFinder(CToken* aToken) {mToken=aToken;}
@ -500,14 +594,18 @@ public:
void CTokenRecycler::RecycleToken(CToken* aToken) {
if(aToken) {
PRInt32 theType=aToken->GetTokenType();
mTokenCache[theType-1]->Push(aToken);
#if 0
//This should be disabled since it's only debug code.
CTokenFinder finder(aToken);
CToken* theMatch;
theMatch=(CToken*)mTokenCache[theType-1]->FirstThat(finder);
if(theMatch) {
printf("dup token: %p\n",theMatch);
}
#endif
aToken->mUseCount=1;
mTokenCache[theType-1]->Push(aToken);
}
}
@ -793,10 +891,15 @@ void CObserverService::RegisterObservers(nsString& aTopic) {
* @return if SUCCESS return NS_OK else return ERROR code.
*/
nsresult CObserverService::Notify(eHTMLTags aTag,nsIParserNode& aNode,PRUint32 aUniqueID, const char* aCommand,
nsAutoString& aCharsetValue,nsCharsetSource& aCharsetSource) {
nsIParser* aParser) {
nsresult result=NS_OK;
nsDeque* theDeque=GetObserversForTag(aTag);
if(theDeque){
nsAutoString theCharsetValue;
nsCharsetSource theCharsetSource;
aParser->GetDocumentCharset(theCharsetValue,theCharsetSource);
PRInt32 theAttrCount =aNode.GetAttributeCount();
PRUint32 theDequeSize=theDeque->GetSize();
if(0<theDequeSize){
@ -813,12 +916,12 @@ nsresult CObserverService::Notify(eHTMLTags aTag,nsIParserNode& aNode,PRUint32 a
// Add pseudo attribute in the end
if(index < 50) {
theKeys[index]=theCharsetKey.GetUnicode();
theValues[index] = aCharsetValue.GetUnicode();
theValues[index] = theCharsetValue.GetUnicode();
index++;
}
if(index < 50) {
theKeys[index]=theSourceKey.GetUnicode();
PRInt32 sourceInt = aCharsetSource;
PRInt32 sourceInt = theCharsetSource;
intValue.Append(sourceInt,10);
theValues[index] = intValue.GetUnicode();
index++;

Просмотреть файл

@ -61,71 +61,99 @@ void DebugDumpContainmentRules(nsIDTD& theDTD,const char* aFilename,const char*
void DebugDumpContainmentRules2(nsIDTD& theDTD,const char* aFilename,const char* aTitle);
PRUint32 AccumulateCRC(PRUint32 crc_accum, char *data_blk_ptr, int data_blk_size);
/**************************************************************
This is the place to store the "bad-content" tokens, and the
also the regular tags.
**************************************************************/
/***************************************************************
The dtdcontext class defines an ordered list of tags (a context).
***************************************************************/
/***************************************************************
First, define the tagstack class
***************************************************************/
class nsEntryStack; //forware declare to make compilers happy.
struct nsTagEntry {
eHTMLTags mTag;
PRInt8 mBankIndex;
PRInt8 mStyleIndex;
eHTMLTags mTag; //for speedier access to tag id
nsIParserNode* mNode;
PRInt32 mLevel;
nsEntryStack* mParent;
nsEntryStack* mStyles;
};
class nsEntryStack {
public:
nsEntryStack();
~nsEntryStack();
void Push(eHTMLTags aTag);
eHTMLTags Pop();
void EnsureCapacityFor(PRInt32 aNewMax, PRInt32 aShiftOffset=0);
void Push(const nsIParserNode* aNode,PRInt32 aResidualStyleLevel=-1);
void PushFront(const nsIParserNode* aNode,PRInt32 aResidualStyleLevel=-1);
void Append(nsEntryStack *theStack);
nsIParserNode* Pop(void);
nsIParserNode* NodeAt(PRInt32 anIndex) const;
eHTMLTags First() const;
eHTMLTags TagAt(PRUint32 anIndex) const;
nsTagEntry& EntryAt(PRUint32 anIndex) const;
PRInt32 GetTopmostIndexOf(eHTMLTags aTag) const;
eHTMLTags operator[](PRUint32 anIndex) const;
eHTMLTags TagAt(PRInt32 anIndex) const;
nsTagEntry* EntryAt(PRInt32 anIndex) const;
eHTMLTags operator[](PRInt32 anIndex) const;
eHTMLTags Last() const;
void Empty(void);
PRInt32 GetCount(void) const {return mCount;}
inline PRInt32 FindFirst(eHTMLTags aTag) const {
PRInt32 index=-1;
if(0<mCount) {
while(++index<mCount) {
if(aTag==mEntries[index].mTag) {
return index;
}
} //while
}
return kNotFound;
}
inline PRInt32 FindLast(eHTMLTags aTag) const {
PRInt32 index=mCount;
while(--index>=0) {
if(aTag==mEntries[index].mTag) {
return index;
}
}
return kNotFound;
}
nsTagEntry* mEntries;
PRUint32 mCount;
PRUint32 mCapacity;
PRInt32 mCount;
PRInt32 mCapacity;
};
/***************************************************************
The dtdcontext class defines the current tag context (both
structural and stylistic). This small utility class allows us
to push/pop contexts at will, which makes handling styles in
certainly (unfriendly) elements (like tables) much easier.
***************************************************************/
class nsDTDContext {
public:
nsDTDContext();
~nsDTDContext();
void Push(eHTMLTags aTag);
eHTMLTags Pop();
eHTMLTags First() const;
void Push(const nsIParserNode* aNode,PRInt32 aResidualStyleLevel=-1);
nsIParserNode* Pop(nsEntryStack*& aStack);
eHTMLTags First(void) const;
eHTMLTags Last(void) const;
eHTMLTags TagAt(PRInt32 anIndex) const;
eHTMLTags operator[](PRInt32 anIndex) const;
eHTMLTags Last() const;
eHTMLTags operator[](PRInt32 anIndex) const {return TagAt(anIndex);}
PRBool HasOpenContainer(eHTMLTags aTag) const;
PRInt32 GetTopmostIndexOf(eHTMLTags aTag) const;
void Empty(void);
PRInt32 GetCount(void);
nsEntryStack* GetStylesAt(PRUint32 anIndex) const;
void PushStyle(eHTMLTags aTag);
eHTMLTags PopStyle(void);
nsEntryStack* GetStylesAt(PRInt32 anIndex) const;
void PushStyle(const nsIParserNode* aNode);
void PushStyles(nsEntryStack *theStyles);
nsIParserNode* PopStyle(void);
nsIParserNode* PopStyle(eHTMLTags aTag);
void SaveToken(CToken* aToken, PRInt32 aID);
CToken* RestoreTokenFrom(PRInt32 aID);
PRInt32 TokenCountAt(PRInt32 aID);
nsEntryStack mStack; //this will hold a list of tagentries...
nsEntryStack mStack;
nsDeque mSkipped; //each entry will hold a deque full of skipped tokens...
nsDeque mStyles; //each entry will hold a tagstack full of style tags...
#ifdef NS_DEBUG
enum { eMaxTags = 100 };
eHTMLTags mTags[eMaxTags];
eHTMLTags mXTags[eMaxTags];
#endif
};
@ -163,6 +191,7 @@ public:
protected:
nsDeque* mTokenCache[eToken_last-1];
nsString mEmpty;
#ifdef NS_DEBUG
int mTotals[eToken_last-1];
#endif
@ -192,13 +221,18 @@ public:
* @param aTagSet -- set of tags to be searched
* @return
*/
inline PRInt32 IndexOfTagInSet(PRInt32 aTag,const eHTMLTags aTagSet[],PRInt32 aCount) {
PRInt32 theIndex;
inline PRInt32 IndexOfTagInSet(PRInt32 aTag,const eHTMLTags* aTagSet,PRInt32 aCount) {
for(theIndex=0;theIndex<aCount;theIndex++)
if(aTag==aTagSet[theIndex]) {
return theIndex;
const eHTMLTags* theEnd=aTagSet+aCount;
const eHTMLTags* theTag=aTagSet;
while(theTag<theEnd) {
if(aTag==*theTag) {
return theTag-aTagSet;
}
theTag++;
}
return kNotFound;
}
@ -210,7 +244,7 @@ inline PRInt32 IndexOfTagInSet(PRInt32 aTag,const eHTMLTags aTagSet[],PRInt32 aC
* @param aTagSet -- set of tags to be searched
* @return
*/
inline PRBool FindTagInSet(PRInt32 aTag,const eHTMLTags aTagSet[],PRInt32 aCount) {
inline PRBool FindTagInSet(PRInt32 aTag,const eHTMLTags *aTagSet,PRInt32 aCount) {
return PRBool(-1<IndexOfTagInSet(aTag,aTagSet,aCount));
}
@ -220,11 +254,13 @@ inline PRBool FindTagInSet(PRInt32 aTag,const eHTMLTags aTagSet[],PRInt32 aCount
* @param
* @return
*/
inline PRBool BufferContainsHTML(nsString& aBuffer){
inline PRBool BufferContainsHTML(nsString& aBuffer,PRBool& aHasXMLFragment){
PRBool result=PR_FALSE;
nsString temp;
aBuffer.Left(temp,200);
temp.ToLowerCase();
aHasXMLFragment=PRBool(-1<temp.Find("<?xml"));
if((-1<temp.Find("<html ") || (-1<temp.Find("!doctype html public")))) {
result=PR_TRUE;
}
@ -257,7 +293,7 @@ public:
nsDeque* GetObserversForTag(eHTMLTags aTag);
nsresult Notify(eHTMLTags aTag,nsIParserNode& aNode,
PRUint32 aUniqueID, const char* aCommand,
nsAutoString& aCharsetValue,nsCharsetSource& aCharsetSource);
nsIParser* aParser);
protected:
void RegisterObservers(nsString& aTopicList);

Просмотреть файл

@ -36,9 +36,16 @@
* @param
* @return
*/
PRBool Contains(eHTMLTags aTag,TagList& aTagList){
PRBool result=FindTagInSet(aTag,aTagList.mTags,aTagList.mCount);
return result;
PRInt32 GetTopmostIndexOf(nsDTDContext& aContext,TagList& aTagList){
int max = aContext.GetCount();
int index;
for(index=max-1;index>=0;index--){
PRBool result=FindTagInSet(aContext[index],aTagList.mTags,aTagList.mCount);
if(result) {
return index;
}
}
return kNotFound;
}
/**
@ -47,11 +54,12 @@ PRBool Contains(eHTMLTags aTag,TagList& aTagList){
* @param
* @return
*/
PRInt32 GetTopmostIndexOf(nsEntryStack& aTagStack,TagList& aTagList){
int max = aTagStack.GetCount();
int index=0;
for(index=max-1;index>=0;index--){
if(FindTagInSet(aTagStack[index],aTagList.mTags,aTagList.mCount)) {
PRInt32 GetBottommostIndexOf(nsDTDContext& aContext,PRInt32 aStartOffset,TagList& aTagList){
int max = aContext.GetCount();
int index;
for(index=aStartOffset;index<max;index++){
PRBool result=FindTagInSet(aContext[index],aTagList.mTags,aTagList.mCount);
if(result) {
return index;
}
}
@ -91,8 +99,8 @@ TagList gInTR={1,{eHTMLTag_tr}};
TagList gInDL={2,{eHTMLTag_dl,eHTMLTag_body}};
TagList gInFrameset={1,{eHTMLTag_frameset}};
TagList gInNoframes={1,{eHTMLTag_noframes}};
TagList gInP={4,{eHTMLTag_address,eHTMLTag_form,eHTMLTag_span,eHTMLTag_table}};
TagList gOptgroupParents={2,{eHTMLTag_optgroup,eHTMLTag_select}};
TagList gInP={3,{eHTMLTag_address,eHTMLTag_span,eHTMLTag_table}};
TagList gOptgroupParents={2,{eHTMLTag_select,eHTMLTag_optgroup}};
TagList gBodyParents={2,{eHTMLTag_html,eHTMLTag_noframes}};
TagList gColParents={2,{eHTMLTag_table,eHTMLTag_colgroup}};
TagList gFramesetParents={2,{eHTMLTag_html,eHTMLTag_frameset}};
@ -571,7 +579,7 @@ void InitializeElementTable(void) {
/*req-parent excl-parent*/ eHTMLTag_unknown,eHTMLTag_unknown,
/*rootnodes,endrootnodes*/ &gRootTags,&gRootTags,
/*autoclose starttags and endtags*/ 0,0,0,0,
/*parent,incl,exclgroups*/ kSpecial, (kSelf|SPECIALTYPE), kNone,
/*parent,incl,exclgroups*/ kSpecial|kFontStyle, (kSelf|SPECIALTYPE), kNone,
/*special props, prop-range*/ 0,kDefaultPropRange,
/*special parents,kids,skip*/ 0,&gFontKids,eHTMLTag_unknown);
@ -942,7 +950,7 @@ void InitializeElementTable(void) {
/*rootnodes,endrootnodes*/ &gOptgroupParents,&gOptgroupParents,
/*autoclose starttags and endtags*/ 0,0,0,0,
/*parent,incl,exclgroups*/ kNone, kPCDATA, kFlowEntity,
/*special props, prop-range*/ kNoPropagate|kNoStyleLeaksIn, kDefaultPropRange,
/*special props, prop-range*/ kNoStyleLeaksIn, kDefaultPropRange,
/*special parents,kids,skip*/ &gOptgroupParents,&gContainsText,eHTMLTag_unknown);
Initialize(
@ -1309,7 +1317,7 @@ void InitializeElementTable(void) {
/*rootnodes,endrootnodes*/ &gRootTags,&gRootTags,
/*autoclose starttags and endtags*/ 0,0,0,0,
/*parent,incl,exclgroups*/ kFlowEntity, kNone, kNone,
/*special props, prop-range*/ kOmitEndTag,kNoPropRange,
/*special props, prop-range*/ kOmitEndTag|kLegalOpen,kNoPropRange,
/*special parents,kids,skip*/ 0,0,eHTMLTag_unknown);
Initialize(
@ -1341,15 +1349,16 @@ void InitializeElementTable(void) {
}//if
};
int nsHTMLElement::GetSynonymousGroups(int aGroup) {
int nsHTMLElement::GetSynonymousGroups(eHTMLTags aTag) {
int result=0;
switch(aGroup) {
int theGroup=gHTMLElements[aTag].mParentBits;
switch(theGroup) {
case kPhrase:
case kSpecial:
case kFontStyle:
result=aGroup;
result=theGroup;
break;
case kHTMLContent:
@ -1373,6 +1382,32 @@ int nsHTMLElement::GetSynonymousGroups(int aGroup) {
break;
}
if(eHTMLTag_font==aTag) //hack for backward compatibility
result+=kFontStyle;
return result;
}
/**
*
* @update gess 01/04/99
* @param
* @return
*/
inline PRBool TestBits(int aBitset,int aTest) {
PRInt32 result=aBitset & aTest;
return (aTest) ? PRBool(result==aTest) : PR_FALSE; //was aTest
}
/**
*
* @update gess1/21/99
* @param
* @return
*/
PRBool nsHTMLElement::HasSpecialProperty(PRInt32 aProperty) const{
PRBool result=TestBits(mSpecialProperties,aProperty);
return result;
}
@ -1386,24 +1421,11 @@ PRBool nsHTMLElement::IsContainer(eHTMLTags aChild) {
PRBool result=(eHTMLTag_unknown==aChild);
if(!result){
result=!gHTMLElements[aChild].HasSpecialProperty(kNonContainer);
result=!TestBits(gHTMLElements[aChild].mSpecialProperties,kNonContainer);
}
return result;
}
/**
*
* @update gess 01/04/99
* @param
* @return
*/
inline PRBool TestBits(int aBitset,int aTest) {
PRInt32 result=aBitset & aTest;
return (aTest) ? PRBool(result==aTest) : PR_FALSE; //was aTest
}
/**
*
* @update gess 01/04/99
@ -1564,7 +1586,7 @@ PRBool nsHTMLElement::CanExclude(eHTMLTags aChild) const{
//Note that special kids takes precedence over exclusions...
if(mSpecialKids) {
if(Contains(aChild,*mSpecialKids)) {
if(FindTagInSet(aChild,mSpecialKids->mTags,mSpecialKids->mCount)) {
return PR_FALSE;
}
}
@ -1608,7 +1630,7 @@ PRBool nsHTMLElement::CanOmitStartTag(eHTMLTags aChild) const{
* @return
*/
PRBool nsHTMLElement::IsChildOfHead(eHTMLTags aChild) {
PRBool result=Contains(aChild,gHeadKids);
PRBool result=FindTagInSet(aChild,gHeadKids.mTags,gHeadKids.mCount);
return result;
}
@ -1622,8 +1644,9 @@ PRBool nsHTMLElement::IsChildOfHead(eHTMLTags aChild) {
PRBool nsHTMLElement::SectionContains(eHTMLTags aChild,PRBool allowDepthSearch) {
PRBool result=PR_FALSE;
TagList* theRootTags=gHTMLElements[aChild].GetRootTags();
if(theRootTags){
if(!Contains(mTagID,*theRootTags)){
if(!FindTagInSet(mTagID,theRootTags->mTags,theRootTags->mCount)){
eHTMLTags theRootBase=GetTagAt(0,*theRootTags);
if((eHTMLTag_unknown!=theRootBase) && (allowDepthSearch))
result=SectionContains(theRootBase,allowDepthSearch);
@ -1640,21 +1663,40 @@ PRBool nsHTMLElement::SectionContains(eHTMLTags aChild,PRBool allowDepthSearch)
* @return
*/
PRBool nsHTMLElement::IsStyleTag(eHTMLTags aChild) {
static eHTMLTags gStyleTags[]={
eHTMLTag_a, eHTMLTag_acronym, eHTMLTag_b,
eHTMLTag_bdo, eHTMLTag_big, eHTMLTag_blink,
eHTMLTag_center, eHTMLTag_cite, eHTMLTag_code,
eHTMLTag_del, eHTMLTag_dfn, eHTMLTag_em,
eHTMLTag_font, eHTMLTag_i, eHTMLTag_ins,
eHTMLTag_kbd, eHTMLTag_q,
eHTMLTag_s, eHTMLTag_samp, eHTMLTag_small,
eHTMLTag_span, eHTMLTag_strike, eHTMLTag_strong,
eHTMLTag_sub, eHTMLTag_sup, eHTMLTag_tt,
eHTMLTag_u, eHTMLTag_var
PRBool result=PR_FALSE;
switch(aChild) {
case eHTMLTag_a:
case eHTMLTag_acronym:
case eHTMLTag_b:
case eHTMLTag_bdo:
case eHTMLTag_big:
case eHTMLTag_blink:
case eHTMLTag_center:
case eHTMLTag_cite:
case eHTMLTag_code:
case eHTMLTag_del:
case eHTMLTag_dfn:
case eHTMLTag_em:
case eHTMLTag_font:
case eHTMLTag_i:
case eHTMLTag_ins:
case eHTMLTag_kbd:
case eHTMLTag_q:
case eHTMLTag_s:
case eHTMLTag_samp:
case eHTMLTag_small:
case eHTMLTag_span:
case eHTMLTag_strike:
case eHTMLTag_strong:
case eHTMLTag_sub:
case eHTMLTag_sup:
case eHTMLTag_tt:
case eHTMLTag_u:
case eHTMLTag_var:
result=PR_TRUE;
default:
break;
};
PRBool result=FindTagInSet(aChild,gStyleTags,sizeof(gStyleTags)/sizeof(eHTMLTag_body));
return result;
}
@ -1665,7 +1707,7 @@ PRBool nsHTMLElement::IsStyleTag(eHTMLTags aChild) {
* @return
*/
PRBool nsHTMLElement::IsHeadingTag(eHTMLTags aChild) {
return Contains(aChild,gHeadingTags);
return FindTagInSet(aChild,gHeadingTags.mTags,gHeadingTags.mCount);
}
@ -1699,8 +1741,16 @@ PRBool nsHTMLElement::IsMemberOf(PRInt32 aSet) const{
* @return
*/
PRBool nsHTMLElement::IsWhitespaceTag(eHTMLTags aChild) {
static eHTMLTags gWSTags[]={eHTMLTag_newline, eHTMLTag_whitespace};
PRBool result=FindTagInSet(aChild,gWSTags,sizeof(gWSTags)/sizeof(eHTMLTag_body));
PRBool result=PR_FALSE;
switch(aChild) {
case eHTMLTag_newline:
case eHTMLTag_whitespace:
result=PR_TRUE;
break;
default:
break;
}
return result;
}
@ -1711,8 +1761,18 @@ PRBool nsHTMLElement::IsWhitespaceTag(eHTMLTags aChild) {
* @return
*/
PRBool nsHTMLElement::IsTextTag(eHTMLTags aChild) {
static eHTMLTags gTextTags[]={eHTMLTag_text,eHTMLTag_entity,eHTMLTag_newline, eHTMLTag_whitespace};
PRBool result=FindTagInSet(aChild,gTextTags,sizeof(gTextTags)/sizeof(eHTMLTag_body));
PRBool result=PR_FALSE;
switch(aChild) {
case eHTMLTag_text:
case eHTMLTag_entity:
case eHTMLTag_newline:
case eHTMLTag_whitespace:
result=PR_TRUE;
break;
default:
break;
}
return result;
}
@ -1738,7 +1798,7 @@ PRBool nsHTMLElement::CanAutoCloseTag(eHTMLTags aTag) const{
if((mTagID>=eHTMLTag_unknown) & (mTagID<=eHTMLTag_userdefined)) {
TagList* theTagList=gHTMLElements[mTagID].GetNonAutoCloseEndTags();
if(theTagList) {
result=!Contains(aTag,*theTagList);
result=!FindTagInSet(aTag,theTagList->mTags,theTagList->mCount);
}
}
return result;
@ -1750,14 +1810,14 @@ PRBool nsHTMLElement::CanAutoCloseTag(eHTMLTags aTag) const{
* @param
* @return
*/
eHTMLTags nsHTMLElement::GetCloseTargetForEndTag(nsEntryStack& aTagStack,PRInt32 anIndex) const{
eHTMLTags nsHTMLElement::GetCloseTargetForEndTag(nsDTDContext& aContext,PRInt32 anIndex) const{
eHTMLTags result=eHTMLTag_unknown;
int theCount=aTagStack.GetCount();
int theCount=aContext.GetCount();
int theIndex=theCount;
if(IsMemberOf(kPhrase)){
while((--theIndex>=anIndex) && (eHTMLTag_unknown==result)){
eHTMLTags theTag=aTagStack.TagAt(theIndex);
eHTMLTags theTag=aContext.TagAt(theIndex);
if(theTag!=mTagID) {
//phrasal elements can close other phrasals, along with fontstyle and special tags...
if(!gHTMLElements[theTag].IsMemberOf(kSpecial|kFontStyle|kPhrase)) {
@ -1772,7 +1832,7 @@ eHTMLTags nsHTMLElement::GetCloseTargetForEndTag(nsEntryStack& aTagStack,PRInt32
}
else if(IsMemberOf(kSpecial)){
while((--theIndex>=anIndex) && (eHTMLTag_unknown==result)){
eHTMLTags theTag=aTagStack.TagAt(theIndex);
eHTMLTags theTag=aContext.TagAt(theIndex);
if(theTag!=mTagID) {
//phrasal elements can close other phrasals, along with fontstyle and special tags...
if(gHTMLElements[theTag].IsMemberOf(kSpecial) ||
@ -1790,7 +1850,7 @@ eHTMLTags nsHTMLElement::GetCloseTargetForEndTag(nsEntryStack& aTagStack,PRInt32
}
else if(IsMemberOf(kFormControl|kExtensions)){
while((--theIndex>=anIndex) && (eHTMLTag_unknown==result)){
eHTMLTags theTag=aTagStack.TagAt(theIndex);
eHTMLTags theTag=aContext.TagAt(theIndex);
if(theTag!=mTagID) {
if(!CanContain(theTag)) {
break; //it's not something I can close
@ -1802,9 +1862,9 @@ eHTMLTags nsHTMLElement::GetCloseTargetForEndTag(nsEntryStack& aTagStack,PRInt32
}
}
}
else if(IsMemberOf(kFontStyle)){
eHTMLTags theTag=aTagStack.Last();
if(gHTMLElements[theTag].IsMemberOf(kFontStyle)) {
else if(IsStyleTag(mTagID)){
eHTMLTags theTag=aContext.Last();
if(IsStyleTag(theTag)) {
result=theTag;
}
}
@ -1833,7 +1893,7 @@ PRBool nsHTMLElement::CanContain(eHTMLTags aChild) const{
TagList* theCloseTags=gHTMLElements[aChild].GetAutoCloseStartTags();
if(theCloseTags){
if(Contains(mTagID,*theCloseTags))
if(FindTagInSet(mTagID,theCloseTags->mTags,theCloseTags->mCount))
return PR_FALSE;
}
@ -1867,7 +1927,7 @@ PRBool nsHTMLElement::CanContain(eHTMLTags aChild) const{
}
if(mSpecialKids) {
if(Contains(aChild,*mSpecialKids)) {
if(FindTagInSet(aChild,mSpecialKids->mTags,mSpecialKids->mCount)) {
return PR_TRUE;
}
}
@ -1878,17 +1938,6 @@ PRBool nsHTMLElement::CanContain(eHTMLTags aChild) const{
}
/**
*
* @update gess1/21/99
* @param
* @return
*/
PRBool nsHTMLElement::HasSpecialProperty(PRInt32 aProperty) const{
PRBool result=TestBits(mSpecialProperties,aProperty);
return result;
}
void nsHTMLElement::DebugDumpContainment(const char* aFilename,const char* aTitle){
#ifdef RICKG_DEBUG

Просмотреть файл

@ -40,8 +40,7 @@ struct TagList {
eHTMLTags mTags[10];
};
extern PRBool Contains(eHTMLTags aTag,TagList& aTagList);
extern PRInt32 GetTopmostIndexOf(nsEntryStack& aTagStack,TagList& aTagList);
extern PRInt32 GetTopmostIndexOf(nsDTDContext& aContext,TagList& aTagList);
extern eHTMLTags GetTagAt(PRUint32 anIndex,TagList& aTagList);
//*********************************************************************************************
@ -67,7 +66,7 @@ struct nsHTMLElement {
static PRBool IsInlineEntity(eHTMLTags aTag);
static PRBool IsFlowEntity(eHTMLTags aTag);
static PRBool IsBlockCloser(eHTMLTags aTag);
static int GetSynonymousGroups(int aGroup);
static int GetSynonymousGroups(eHTMLTags aTag);
TagList* GetSynonymousTags(void) const {return mSynonymousTags;}
TagList* GetRootTags(void) const {return mRootNodes;}
@ -75,7 +74,7 @@ struct nsHTMLElement {
TagList* GetAutoCloseStartTags(void) const {return mAutocloseStart;}
TagList* GetAutoCloseEndTags(void) const {return mAutocloseEnd;}
TagList* GetNonAutoCloseEndTags(void) const {return mDontAutocloseEnd;}
eHTMLTags GetCloseTargetForEndTag(nsEntryStack& aTagStack,PRInt32 anIndex) const;
eHTMLTags GetCloseTargetForEndTag(nsDTDContext& aContext,PRInt32 anIndex) const;
TagList* GetSpecialChildren(void) const {return mSpecialKids;}
TagList* GetSpecialParents(void) const {return mSpecialParents;}

Просмотреть файл

@ -200,7 +200,9 @@ eAutoDetectResult nsExpatDTD::CanParse(nsString& aContentType, nsString& aComman
* @param
* @return
*/
NS_IMETHODIMP nsExpatDTD::WillBuildModel(nsString& aFilename,PRBool aNotifySink,nsString& aSourceType,eParseMode aParseMode,nsIContentSink* aSink){
NS_IMETHODIMP nsExpatDTD::WillBuildModel(nsString& aFilename,PRBool aNotifySink,
nsString& aSourceType,eParseMode aParseMode,
nsString& aString,nsIContentSink* aSink){
nsresult result=NS_OK;
mFilename=aFilename;

Просмотреть файл

@ -110,6 +110,7 @@ class nsExpatDTD : public nsIDTD {
PRBool aNotifySink,
nsString& aSourceType,
eParseMode aParseMode,
nsString& aString,
nsIContentSink* aSink=0);
/**

Просмотреть файл

@ -29,6 +29,7 @@
* model.
*/
#include "nsHTMLToTXTSinkStream.h"
#include "nsHTMLTokens.h"
#include "nsString.h"
@ -44,16 +45,15 @@
#include "nsIOutputStream.h"
#include "nsFileStream.h"
static NS_DEFINE_CID(kCharsetConverterManagerCID, NS_ICHARSETCONVERTERMANAGER_CID);
const PRInt32 gTabSize=4;
const PRInt32 gOLNumberWidth = 3;
const PRInt32 gIndentSizeList = MaxInt(gTabSize, gOLNumberWidth + 3);
// Indention of non-first lines of ul and ol
const PRInt32 gTabSize=2;
static PRBool IsInline(eHTMLTags aTag);
static PRBool IsBlockLevel(eHTMLTags aTag);
/**
* Inits the encoder instance variable for the sink based on the charset
*
@ -72,6 +72,7 @@ nsresult nsHTMLToTXTSinkStream::InitEncoder(const nsString& aCharset)
return res;
}
nsICharsetAlias* calias = nsnull;
res = nsServiceManager::GetService(kCharsetAliasCID,
kICharsetAliasIID,
@ -109,6 +110,7 @@ nsresult nsHTMLToTXTSinkStream::InitEncoder(const nsString& aCharset)
return res;
}
/**
* This method gets called as part of our COM-like interfaces.
* Its purpose is to create an interface to parser object
@ -145,9 +147,11 @@ nsHTMLToTXTSinkStream::QueryInterface(const nsIID& aIID, void** aInstancePtr)
return NS_OK;
}
NS_IMPL_ADDREF(nsHTMLToTXTSinkStream)
NS_IMPL_RELEASE(nsHTMLToTXTSinkStream)
// Someday may want to make this non-const:
static const PRUint32 TagStackSize = 500;
static const PRUint32 OLStackSize = 100;
@ -187,6 +191,7 @@ nsHTMLToTXTSinkStream::nsHTMLToTXTSinkStream()
mOLStackIndex = 0;
}
/**
*
* @update gpk02/03/99
@ -228,6 +233,7 @@ nsHTMLToTXTSinkStream::Initialize(nsIOutputStream* aOutStream,
* @param
* @return
*/
NS_IMETHODIMP
nsHTMLToTXTSinkStream::SetCharsetOverride(const nsString* aCharset)
{
@ -239,6 +245,8 @@ nsHTMLToTXTSinkStream::SetCharsetOverride(const nsString* aCharset)
return NS_OK;
}
/**
* This method gets called by the parser when it encounters
* a title tag and wants to set the document title in the sink.
@ -248,8 +256,7 @@ nsHTMLToTXTSinkStream::SetCharsetOverride(const nsString* aCharset)
* @return PR_TRUE if successful.
*/
NS_IMETHODIMP
nsHTMLToTXTSinkStream::SetTitle(const nsString& aValue)
{
nsHTMLToTXTSinkStream::SetTitle(const nsString& aValue){
return NS_OK;
}
@ -272,6 +279,7 @@ NS_IMETHODIMP \
nsHTMLToTXTSinkStream::closetag(const nsIParserNode& aNode) \
{ return CloseContainer(aNode); }
USE_GENERAL_OPEN_METHOD(OpenHTML)
USE_GENERAL_CLOSE_METHOD(CloseHTML)
USE_GENERAL_OPEN_METHOD(OpenHead)
@ -336,6 +344,7 @@ nsHTMLToTXTSinkStream::AddProcessingInstruction(const nsIParserNode& aNode){
* This gets called by the parser when it encounters
* a DOCTYPE declaration in the HTML document.
*/
NS_IMETHODIMP
nsHTMLToTXTSinkStream::AddDocTypeDecl(const nsIParserNode& aNode, PRInt32 aMode)
{
@ -396,15 +405,6 @@ PRBool nsHTMLToTXTSinkStream::DoOutput()
return mDoFragment || inBody;
}
nsAutoString
Spaces(PRInt32 count)
{
nsAutoString result;
while (result.Length() < count)
result += ' ';
return result;
}
/**
* This method is used to a general container.
* This includes: OL,UL,DIR,SPAN,TABLE,H[1..6],etc.
@ -416,6 +416,7 @@ Spaces(PRInt32 count)
NS_IMETHODIMP
nsHTMLToTXTSinkStream::OpenContainer(const nsIParserNode& aNode)
{
eHTMLTags type = (eHTMLTags)aNode.GetNodeType();
#ifdef DEBUG_bratell
printf("OpenContainer: %d ", type);
@ -439,6 +440,7 @@ nsHTMLToTXTSinkStream::OpenContainer(const nsIParserNode& aNode)
if (type == eHTMLTag_body)
{
// body -> can turn on cacheing unless it's already preformatted
if(!(mFlags & nsIDocumentEncoder::OutputPreformatted) &&
((mFlags & nsIDocumentEncoder::OutputFormatted) ||
@ -446,6 +448,7 @@ nsHTMLToTXTSinkStream::OpenContainer(const nsIParserNode& aNode)
mCacheLine = PR_TRUE;
}
// Try to figure out here whether we have a
// preformatted style attribute.
//
@ -492,53 +495,29 @@ nsHTMLToTXTSinkStream::OpenContainer(const nsIParserNode& aNode)
if (!DoOutput())
return NS_OK;
if (type == eHTMLTag_p)
EnsureVerticalSpace(1); // Should this be 0 in unformatted case?
// Else make sure we'll separate block level tags,
// even if we're about to leave before doing any other formatting.
// Oddly, I can't find a case where this actually makes any difference.
//else if (IsBlockLevel(type))
// EnsureVerticalSpace(0);
// The rest of this routine is formatted output stuff,
// which we should skip if we're not formatted:
if (!(mFlags & nsIDocumentEncoder::OutputFormatted))
return NS_OK;
if (type == eHTMLTag_ul)
{
// Indent here to support nested list, which aren't included in li :-(
mIndent += gIndentSizeList;
EnsureVerticalSpace(1);
}
else if (type == eHTMLTag_ol)
if (type == eHTMLTag_ol)
{
if (mOLStackIndex < OLStackSize)
mOLStack[mOLStackIndex++] = 1; // XXX should get it from the node!
mIndent += gIndentSizeList; // see ul
EnsureVerticalSpace(1);
}
else if (type == eHTMLTag_li)
if (type == eHTMLTag_li)
{
nsAutoString temp = Spaces(gIndentSizeList - gOLNumberWidth - 2);
nsAutoString temp("*");
if (mTagStackIndex > 1 && mTagStack[mTagStackIndex-2] == eHTMLTag_ol)
{
nsAutoString number;
if (mOLStackIndex > 0)
{
// This is what nsBulletFrame does for OLs:
number.Append(mOLStack[mOLStackIndex-1]++, 10);
else
number += "#";
temp += Spaces(gOLNumberWidth - number.Length()) + number + '.';
char cbuf[40];
PR_snprintf(cbuf, sizeof(cbuf), "%ld.", (mOLStack[mOLStackIndex-1])++);
temp = cbuf;
}
else
temp += Spaces(gOLNumberWidth) + "*";
temp += ' ';
mIndent -= gIndentSizeList; // don't indent first line so much
Write(temp); //CHANGE: does not work as intended. waiting for bug #17883
mIndent += gIndentSizeList;
temp = "#";
}
Write(temp);
// mColPos++; This is done in Write(temp) above
}
else if (type == eHTMLTag_blockquote)
{
@ -560,50 +539,26 @@ nsHTMLToTXTSinkStream::OpenContainer(const nsIParserNode& aNode)
{
EnsureVerticalSpace(0);
}
else if (type == eHTMLTag_a)
// Finally, the list of tags before which we want some vertical space:
switch (type)
{
nsAutoString url;
if (NS_SUCCEEDED(GetValueOfAttribute(aNode, "href", url)))
mURL = url;
else
mURL.Truncate();
}
else if (type == eHTMLTag_img)
case eHTMLTag_table:
case eHTMLTag_ul:
case eHTMLTag_ol:
case eHTMLTag_p:
{
nsAutoString url;
if (NS_SUCCEEDED(GetValueOfAttribute(aNode, "src", url)))
{
nsAutoString temp, desc;
if (NS_SUCCEEDED(GetValueOfAttribute(aNode, "alt", desc)))
{
temp += " (";
temp += desc;
temp += " <URL:";
temp += url;
temp += ">) ";
EnsureVerticalSpace((mFlags & nsIDocumentEncoder::OutputFormatted) ? 1 : 0);
break;
}
else
{
temp += " <URL:";
temp += url;
temp += "> ";
default:
break;
}
Write(temp);
}
}
else if (type == eHTMLTag_sup)
Write("^");
//don't know a plain text representation of sub
else if (type == eHTMLTag_strong || type == eHTMLTag_b)
Write("*");
else if (type == eHTMLTag_em || type == eHTMLTag_i)
Write("/");
else if (type == eHTMLTag_u)
Write("_");
return NS_OK;
}
/**
* This method is used to close a generic container.
*
@ -621,47 +576,10 @@ nsHTMLToTXTSinkStream::CloseContainer(const nsIParserNode& aNode)
if (mTagStackIndex > 0)
--mTagStackIndex;
// End current line if we're ending a block level tag
if (IsBlockLevel(type)) {
if((type == eHTMLTag_body) || (type == eHTMLTag_html)) {
// We want the output to end with a new line,
// but in preformatted areas like text fields,
// we can't emit newlines that weren't there.
if (mPreFormatted || (mFlags & nsIDocumentEncoder::OutputPreformatted))
FlushLine();
else
EnsureVerticalSpace(0);
} else if ((type == eHTMLTag_tr) ||
(type == eHTMLTag_li) ||
(type == eHTMLTag_blockquote)) {
EnsureVerticalSpace(0);
} else {
// All other blocks get 1 vertical space after them
// in formatted mode, otherwise 0.
// This is hard. Sometimes 0 is a better number, but
// how to know?
EnsureVerticalSpace((mFlags & nsIDocumentEncoder::OutputFormatted) ? 1 : 0);
}
}
// The rest of this routine is formatted output stuff,
// which we should skip if we're not formatted:
if (!(mFlags & nsIDocumentEncoder::OutputFormatted))
return NS_OK;
if (type == eHTMLTag_ul)
{
mIndent -= gIndentSizeList;
}
else if (type == eHTMLTag_ol)
{
FlushLine(); // Doing this after decreasing OLStackIndex would be wrong.
if (type == eHTMLTag_ol)
--mOLStackIndex;
mIndent -= gIndentSizeList;
}
else if (type == eHTMLTag_blockquote)
{
FlushLine();
if (mCiteQuoteLevel>0)
mCiteQuoteLevel--;
else if(mIndent >= gTabSize)
@ -686,29 +604,33 @@ nsHTMLToTXTSinkStream::CloseContainer(const nsIParserNode& aNode)
mInWhitespace = PR_TRUE;
}
}
else if (type == eHTMLTag_a)
{ // these brackets must stay here
if (!mURL.IsEmpty())
{
nsAutoString temp(" <URL:");
temp += mURL;
temp += ">";
Write(temp);
// End current line if we're ending a block level tag
if(IsBlockLevel(type)) {
if((type == eHTMLTag_body) || (type == eHTMLTag_html)) {
// We want the output to end with a new line,
// but in preformatted areas like text fields,
// we can't emit newlines that weren't there.
if (mPreFormatted || (mFlags & nsIDocumentEncoder::OutputPreformatted))
FlushLine();
else
EnsureVerticalSpace(0);
} else if((type == eHTMLTag_tr) ||
(type == eHTMLTag_blockquote)) {
EnsureVerticalSpace(0);
} else {
// All other blocks get 1 vertical space after them
// in formatted mode, otherwise 0.
// This is hard. Sometimes 0 is a better number, but
// how to know?
EnsureVerticalSpace((mFlags & nsIDocumentEncoder::OutputFormatted) ? 1 : 0);
}
}
else if (type == eHTMLTag_sup)
Write(" ");
else if (type == eHTMLTag_strong || type == eHTMLTag_b)
Write("*");
else if (type == eHTMLTag_em || type == eHTMLTag_i)
Write("/");
else if (type == eHTMLTag_u)
Write("_");
return NS_OK;
}
/**
* This method is used to add a leaf to the currently
* open container.
@ -766,9 +688,16 @@ nsHTMLToTXTSinkStream::AddLeaf(const nsIParserNode& aNode)
&& (mTagStack[mTagStackIndex-1] == eHTMLTag_pre)) ||
(mPreFormatted && !mWrapColumn))
{
Write(text); // XXX: spacestuffing (maybe call AddToLine if mCacheLine==true)
text = aNode.GetText();
WriteSimple(text);
mColPos += text.Length();
mEmptyLines = -1;
} else if(!mInWhitespace) {
Write(" ");
if(mCacheLine) {
AddToLine(" ");
} else {
WriteSimple(" ");
}
mInWhitespace = PR_TRUE;
}
}
@ -783,16 +712,6 @@ nsHTMLToTXTSinkStream::AddLeaf(const nsIParserNode& aNode)
EnsureVerticalSpace(mEmptyLines+1);
}
}
else if (type == eHTMLTag_hr &&
(mFlags & nsIDocumentEncoder::OutputFormatted))
{
// Make a line of dashes as wide as the wrap width
nsAutoString line;
int width = (mWrapColumn > 0 ? mWrapColumn : 25);
while (line.Length() < width)
line += '-';
Write(line);
}
return NS_OK;
}
@ -811,6 +730,8 @@ void nsHTMLToTXTSinkStream::EnsureBufferSize(PRInt32 aNewSize)
}
}
void nsHTMLToTXTSinkStream::EncodeToBuffer(const nsString& aSrc)
{
if (mUnicodeEncoder == nsnull)
@ -821,6 +742,8 @@ void nsHTMLToTXTSinkStream::EncodeToBuffer(const nsString& aSrc)
return;
}
#define CH_NBSP 160
PRInt32 length = aSrc.Length();
nsresult result;
@ -836,16 +759,17 @@ void nsHTMLToTXTSinkStream::EncodeToBuffer(const nsString& aSrc)
if (NS_SUCCEEDED(result))
result = mUnicodeEncoder->Finish(mBuffer,&temp);
// XXX UGH! This is awful and needs to be removed.
#define CH_NBSP 160
for (PRInt32 i = 0; i < mBufferLength; i++)
{
if (mBuffer[i] == char(CH_NBSP))
mBuffer[i] = ' ';
}
}
}
void
nsHTMLToTXTSinkStream::EnsureVerticalSpace(PRInt32 noOfRows)
{
@ -853,23 +777,19 @@ nsHTMLToTXTSinkStream::EnsureVerticalSpace(PRInt32 noOfRows)
EndLine(PR_FALSE);
}
// This empties the current line cache without adding a NEWLINE.
// Should not be used if line wrapping is of importance since
// this function destroys the cache information.
void
nsHTMLToTXTSinkStream::FlushLine()
{
if(mCurrentLine.Length()>0) {
if(0 == mColPos)
WriteQuotesAndIndent();
WriteSimple(mCurrentLine);
mColPos += mCurrentLine.Length();
mCurrentLine.SetString("");
}
}
/**
* WriteSimple places the contents of aString into either the output stream
* or the output string.
@ -973,19 +893,7 @@ nsHTMLToTXTSinkStream::AddToLine(const nsString &linefragment)
mCurrentLine.Right(restOfLine, linelength-goodSpace-1);
mCurrentLine.Cut(goodSpace, linelength-goodSpace);
EndLine(PR_TRUE);
mCurrentLine.SetString("");
// Space stuff new line?
if(mFlags & nsIDocumentEncoder::OutputFormatFlowed) {
if((restOfLine[0] == '>') ||
(restOfLine[0] == ' ') ||
(!restOfLine.Compare("From ",PR_FALSE,5))) {
// Space stuffing a la RFC 2646 if this will be used in a mail,
// but how can I know that??? Now space stuffing is done always
// when formatting text as HTML and that is wrong! XXX: Fix this!
mCurrentLine.Append(' ');
}
}
mCurrentLine.Append(restOfLine);
mCurrentLine.SetString(restOfLine);
linelength = mCurrentLine.Length();
mEmptyLines = -1;
} else {
@ -1008,9 +916,8 @@ nsHTMLToTXTSinkStream::EndLine(PRBool softlinebreak)
return;
}
WriteQuotesAndIndent();
// Remove SPACE from the end of the line.
while(' ' == mCurrentLine[mCurrentLine.Length()-1])
mCurrentLine.SetLength(mCurrentLine.Length()-1);
// Remove whitespace from the end of the line.
mCurrentLine.CompressWhitespace(PR_FALSE,PR_TRUE);
if(mFlags & nsIDocumentEncoder::OutputFormatFlowed) {
// Add the soft part of the soft linebreak (RFC 2646 4.1)
mCurrentLine.Append(' ');
@ -1029,9 +936,7 @@ nsHTMLToTXTSinkStream::EndLine(PRBool softlinebreak)
if(mCurrentLine.Length()>0)
mEmptyLines=-1;
// Output current line
// Remove SPACE from the end of the line.
while(' ' == mCurrentLine[mCurrentLine.Length()-1])
mCurrentLine.SetLength(mCurrentLine.Length()-1);
mCurrentLine.CompressWhitespace(PR_FALSE,PR_TRUE);
mCurrentLine.Append(NS_LINEBREAK);
WriteSimple(mCurrentLine);
mCurrentLine.SetString("");
@ -1071,6 +976,7 @@ nsHTMLToTXTSinkStream::WriteQuotesAndIndent()
}
}
#ifdef DEBUG_akkana_not
#define DEBUG_wrapping 1
#endif
@ -1089,6 +995,8 @@ nsHTMLToTXTSinkStream::Write(const nsString& aString)
nsAllocator::Free(foo);
#endif
PRInt32 bol = 0;
PRInt32 newline;
@ -1097,8 +1005,10 @@ nsHTMLToTXTSinkStream::Write(const nsString& aString)
// Don't wrap mail-quoted text
// Yes do! /Daniel Bratell
// PRUint32 wrapcol = (mCiteQuote ? 0 : mWrapColumn);
// PRInt32 prefixwidth = (mCiteQuoteLevel>0?mCiteQuoteLevel+1:0)+mIndent;
// PRInt32 linewidth = mWrapColumn-prefixwidth;
// if ((!(mFlags & nsIDocumentEncoder::OutputFormatted)
// && !(mFlags & nsIDocumentEncoder::OutputWrap)) ||
// ((mTagStackIndex > 0) &&
@ -1111,8 +1021,7 @@ nsHTMLToTXTSinkStream::Write(const nsString& aString)
// intelligent wrapping without clearing the mCurrentLine
// buffer before!!!
NS_ASSERTION(mCurrentLine.Length() == 0,
"Mixed wrapping data and nonwrapping data on the same line");
NS_ASSERTION(mCurrentLine.Length() == 0, "Mixed wrapping data and nonwrapping data on the same line");
// Put the mail quote "> " chars in, if appropriate.
// Have to put it in before every line.
@ -1172,9 +1081,10 @@ nsHTMLToTXTSinkStream::Write(const nsString& aString)
return;
}
// Intelligent handling of text
// If needed, strip out all "end of lines"
// and multiple whitespace between words
// Strip out all "end of lines" and multiple whitespace between words
PRInt32 nextpos;
nsAutoString tempstr;
@ -1200,8 +1110,7 @@ nsHTMLToTXTSinkStream::Write(const nsString& aString)
bol=totLen;
mInWhitespace=PR_FALSE;
} else {
if(mInWhitespace && (nextpos == bol) &&
!(mFlags & nsIDocumentEncoder::OutputPreformatted)) {
if(mInWhitespace && (nextpos == bol)) {
// Skip whitespace
bol++;
continue;
@ -1210,30 +1119,24 @@ nsHTMLToTXTSinkStream::Write(const nsString& aString)
if(nextpos == bol) {
// Note that we are in whitespace.
mInWhitespace = PR_TRUE;
nsAutoString whitestring=aString[nextpos];
if(!mCacheLine) {
WriteSimple(whitestring);
WriteSimple(" ");
} else {
AddToLine(whitestring);
AddToLine(" ");
}
bol++;
continue;
}
aString.Mid(tempstr,bol,nextpos-bol);
if(mFlags & nsIDocumentEncoder::OutputPreformatted) {
bol = nextpos;
} else {
tempstr.Append(" ");
bol = nextpos + 1;
mInWhitespace = PR_TRUE;
}
if(!mCacheLine) {
WriteSimple(tempstr);
} else {
AddToLine(tempstr);
}
mInWhitespace = PR_TRUE;
bol = nextpos + 1;
}
} // Continue looping over the string
}
@ -1249,6 +1152,7 @@ nsHTMLToTXTSinkStream::WillBuildModel(void){
return NS_OK;
}
/**
* This method gets called when the parser concludes the process
* of building the content model via the content sink.
@ -1262,6 +1166,7 @@ nsHTMLToTXTSinkStream::DidBuildModel(PRInt32 aQualityLevel) {
return NS_OK;
}
/**
* This method gets called when the parser gets i/o blocked,
* and wants to notify the sink that it may be a while before
@ -1274,6 +1179,7 @@ nsHTMLToTXTSinkStream::WillInterrupt(void) {
return NS_OK;
}
/**
* This method gets called when the parser i/o gets unblocked,
* and we're about to start dumping content again to the sink.
@ -1296,6 +1202,7 @@ nsHTMLToTXTSinkStream::NotifyError(const nsParserError* aError)
return NS_OK;
}
PRBool IsInline(eHTMLTags aTag)
{
PRBool result = PR_FALSE;
@ -1332,11 +1239,13 @@ PRBool IsInline(eHTMLTags aTag)
case eHTMLTag_u:
case eHTMLTag_var:
case eHTMLTag_wbr:
result = PR_TRUE;
break;
default:
break;
}
return result;
}
@ -1345,3 +1254,4 @@ PRBool IsBlockLevel(eHTMLTags aTag)
{
return !IsInline(aTag);
}

Просмотреть файл

@ -188,7 +188,10 @@ CToken* nsHTMLTokenizer::PeekToken() {
* @return ptr to token or NULL
*/
CToken* nsHTMLTokenizer::PopToken() {
return (CToken*)mTokenDeque.PopFront();
CToken* result=nsnull;
result=(CToken*)mTokenDeque.PopFront();
if(result) result->mUseCount=0;
return result;
}
@ -200,6 +203,7 @@ CToken* nsHTMLTokenizer::PopToken() {
*/
CToken* nsHTMLTokenizer::PushTokenFront(CToken* theToken) {
mTokenDeque.PushFront(theToken);
theToken->mUseCount=1;
return theToken;
}
@ -211,6 +215,7 @@ CToken* nsHTMLTokenizer::PushTokenFront(CToken* theToken) {
*/
CToken* nsHTMLTokenizer::PushToken(CToken* theToken) {
mTokenDeque.Push(theToken);
theToken->mUseCount=1;
return theToken;
}
@ -502,7 +507,10 @@ nsresult nsHTMLTokenizer::ConsumeStartTag(PRUnichar aChar,CToken*& aToken,nsScan
In the case that we just read a <SCRIPT> or <STYLE> tags, we should go and
consume all the content itself.
*/
if(NS_SUCCEEDED(result))
if(NS_SUCCEEDED(result)) {
RecordTrailingContent((CStartToken*)aToken,aScanner);
if((eHTMLTag_style==theTag) || (eHTMLTag_script==theTag)) {
nsAutoString endTag(nsHTMLTags::GetStringValue(theTag));
endTag.Insert("</",0,2);
@ -513,6 +521,7 @@ nsresult nsHTMLTokenizer::ConsumeStartTag(PRUnichar aChar,CToken*& aToken,nsScan
AddToken(textToken,result,mTokenDeque,theRecycler);
AddToken(endToken,result,mTokenDeque,theRecycler);
}
}
//EEEEECCCCKKKK!!!
//This code is confusing, so pay attention.
@ -743,3 +752,26 @@ nsresult nsHTMLTokenizer::ConsumeProcessingInstruction(PRUnichar aChar,CToken*&
return result;
}
/**
* This method keeps a copy of contents within the start token.
* The stored content could later be used in displaying TEXTAREA,
* and also in view source.
*
* @update harishd 11/09/99
* @param aStartToken: The token whose trailing contents are to be recorded
* @param aScanner: see nsScanner.h
*
*/
void nsHTMLTokenizer::RecordTrailingContent(CStartToken* aStartToken, nsScanner& aScanner) {
if(aStartToken) {
PRInt32 theOrigin =aStartToken->mOrigin;
PRInt32 theCurrOffset =aScanner.GetOffset();
PRInt32 theLength =(theCurrOffset>theOrigin)? theCurrOffset-theOrigin:-1;
if(theLength>1) {
nsString& theRawXXX =aStartToken->mTrailingContent;
const PRUnichar* theBuff =(aScanner.GetBuffer()).GetUnicode();
theRawXXX.Append(&theBuff[theOrigin],theLength);
}
}
}

Просмотреть файл

@ -89,6 +89,8 @@ protected:
virtual nsresult ConsumeSpecialMarkup(PRUnichar aChar,CToken*& aToken,nsScanner& aScanner);
virtual nsresult ConsumeProcessingInstruction(PRUnichar aChar,CToken*& aToken,nsScanner& aScanner);
virtual void RecordTrailingContent(CStartToken* aStartToken,nsScanner& aScanner);
static void AddToken(CToken*& aToken,nsresult aResult,nsDeque& aDeque,CTokenRecycler* aRecycler);
nsDeque mTokenDeque;

Просмотреть файл

@ -87,6 +87,7 @@ void CHTMLToken::SetStringValue(const char* name){
CStartToken::CStartToken(eHTMLTags aTag) : CHTMLToken(aTag) {
mAttributed=PR_FALSE;
mEmpty=PR_FALSE;
mOrigin=-1;
}
/*
@ -99,6 +100,7 @@ CStartToken::CStartToken(eHTMLTags aTag) : CHTMLToken(aTag) {
CStartToken::CStartToken(nsString& aString,eHTMLTags aTag) : CHTMLToken(aString,aTag) {
mAttributed=PR_FALSE;
mEmpty=PR_FALSE;
mOrigin=-1;
}
@ -111,7 +113,10 @@ CStartToken::CStartToken(nsString& aString,eHTMLTags aTag) : CHTMLToken(aString,
void CStartToken::Reinitialize(PRInt32 aTag, const nsString& aString){
CToken::Reinitialize(aTag,aString);
mAttributed=PR_FALSE;
mUseCount=0; //assume recycling is needed by default.
mEmpty=PR_FALSE;
mOrigin=-1;
mTrailingContent.Truncate();
}
/*
@ -218,7 +223,9 @@ nsresult CStartToken::Consume(PRUnichar aChar, nsScanner& aScanner,PRInt32 aMode
//and see if the next char is ">". If so, we have a complete
//tag without attributes.
if(NS_OK==result) {
mOrigin=aScanner.GetOffset(); // We need this position to record the trailing contents of the start token
result=aScanner.SkipWhitespace();
mNewlineCount += aScanner.GetNewlinesSkipped();
if(NS_OK==result) {
result=aScanner.GetChar(aChar);
if(NS_OK==result) {
@ -259,8 +266,7 @@ void CStartToken::DebugDumpSource(nsOutputStream& out) {
void CStartToken::GetSource(nsString& anOutputString){
anOutputString="<";
anOutputString+=mTextValue;
if(!mAttributed)
anOutputString+=">";
anOutputString+=(mTrailingContent.Length()>0)? mTrailingContent:'>';
}
/*
@ -465,18 +471,23 @@ nsresult CTextToken::Consume(PRUnichar aChar, nsScanner& aScanner,PRInt32 aMode)
result=aScanner.GetChar(theNextChar);
}
mTextValue.Append("\n");
mNewlineCount++;
}
mTextValue.Append("\n");
mNewlineCount++;
break;
case kLF:
if((kLF==theNextChar) || (kCR==theNextChar)) {
result=aScanner.GetChar(theNextChar);
mTextValue.Append("\n");
mNewlineCount++;
}
mTextValue.Append("\n");
mNewlineCount++;
break;
default:
mTextValue.Append("\n");
mNewlineCount++;
break;
} //switch
}
@ -744,7 +755,7 @@ nsresult ConsumeStrictComment(PRUnichar aChar, nsScanner& aScanner,nsString& aSt
}
aString+=temp;
if(NS_OK==result) {
result=aScanner.ReadWhile(aString,gMinus,PR_TRUE,PR_FALSE); //get all available '---'
// result=aScanner.ReadWhile(aString,gMinus,PR_TRUE,PR_FALSE); //get all available '---'
if(NS_OK==result) {
temp="->";
result=aScanner.ReadUntil(aString,temp,PR_FALSE,PR_FALSE);
@ -1013,6 +1024,7 @@ nsresult CNewlineToken::Consume(PRUnichar aChar, nsScanner& aScanner,PRInt32 aMo
* @return
*/
CAttributeToken::CAttributeToken() : CHTMLToken(eHTMLTag_unknown) {
mHasEqualWithoutValue=PR_FALSE;
}
/*
@ -1025,6 +1037,7 @@ CAttributeToken::CAttributeToken() : CHTMLToken(eHTMLTag_unknown) {
CAttributeToken::CAttributeToken(const nsString& aName) : CHTMLToken(aName),
mTextKey() {
mLastAttribute=PR_FALSE;
mHasEqualWithoutValue=PR_FALSE;
}
/*
@ -1038,6 +1051,7 @@ CAttributeToken::CAttributeToken(const nsString& aName) : CHTMLToken(aName),
CAttributeToken::CAttributeToken(const nsString& aKey, const nsString& aName) : CHTMLToken(aName) {
mTextKey = aKey;
mLastAttribute=PR_FALSE;
mHasEqualWithoutValue=PR_FALSE;
}
/**
@ -1050,6 +1064,7 @@ void CAttributeToken::Reinitialize(PRInt32 aTag, const nsString& aString){
CHTMLToken::Reinitialize(aTag,aString);
mTextKey.Truncate();
mLastAttribute=PR_FALSE;
mHasEqualWithoutValue=PR_FALSE;
}
/*
@ -1250,6 +1265,7 @@ nsresult CAttributeToken::Consume(PRUnichar aChar, nsScanner& aScanner,PRInt32 a
result=ConsumeQuotedString(aChar,mTextValue,aScanner);
}
else if(kGreaterThan==aChar){
mHasEqualWithoutValue=PR_TRUE;
result=aScanner.PutBack(aChar);
}
#if 0
@ -1910,7 +1926,39 @@ CDoctypeDeclToken::CDoctypeDeclToken(eHTMLTags aTag) : CHTMLToken(aTag) {
}
nsresult CDoctypeDeclToken::Consume(PRUnichar aChar, nsScanner& aScanner,PRInt32 aMode) {
return ConsumeComment(aChar,aScanner,mTextValue);
nsresult result=NS_OK;
mTextValue="<!";
static const char* theTerminals="\">[";
PRBool done=PR_FALSE;
result=aScanner.ReadUntil(mTextValue,theTerminals,PR_TRUE,PR_FALSE);
while(!done && NS_OK==result){
result=aScanner.Peek(aChar);
if(result==NS_OK) {
if(kQuote==aChar) {
result=aScanner.GetChar(aChar);
if(NS_OK==result) mTextValue += aChar; // append the quote that you just got
result=aScanner.ReadUntil(mTextValue,kQuote,PR_TRUE);
if(NS_OK==result && aMode!=eParseMode_noquirks)
result=aScanner.ReadWhile(mTextValue,"\"",PR_TRUE,PR_FALSE); // consume multiple quotes
}
else if(kLeftSquareBracket==aChar) {
result=aScanner.ReadUntil(mTextValue,kRightSquareBracket,PR_TRUE);
}
else if(kGreaterThan==aChar){
result=aScanner.ReadUntil(mTextValue,kGreaterThan,PR_TRUE);
done=PR_TRUE;
}
else {
result=aScanner.GetChar(aChar);
if(result==NS_OK) mTextValue += aChar;
}
}
}
return result;
}
const char* CDoctypeDeclToken::GetClassName(void) {

Просмотреть файл

@ -129,6 +129,8 @@ class CStartToken: public CHTMLToken {
virtual void Reinitialize(PRInt32 aTag, const nsString& aString);
nsAutoString mTrailingContent;
PRInt32 mOrigin;
protected:
PRBool mAttributed;
PRBool mEmpty;
@ -272,8 +274,9 @@ class CAttributeToken: public CHTMLToken {
PRBool mLastAttribute;
virtual void Reinitialize(PRInt32 aTag, const nsString& aString);
protected:
PRBool mHasEqualWithoutValue;
nsString mTextKey;
};

Просмотреть файл

@ -110,6 +110,7 @@ class nsIDTD : public nsISupports {
PRBool aNotifySink,
nsString& aSourceType,
eParseMode aParseMode,
nsString& aCommand,
nsIContentSink* aSink=0)=0;
/**

Просмотреть файл

@ -146,6 +146,7 @@ class nsIParser : public nsISupports {
* @return nada
*/
virtual void SetDocumentCharset(nsString& aCharset, nsCharsetSource aSource)=0;
virtual void GetDocumentCharset(nsString& oCharset, nsCharsetSource& oSource)=0;
virtual nsIParserFilter* SetParserFilter(nsIParserFilter* aFilter) = 0;

Просмотреть файл

@ -420,16 +420,21 @@ PRBool FindSuitableDTD( CParserContext& aParserContext,nsString& aCommand,nsStri
PRInt32 theDTDIndex=0;
nsIDTD* theBestDTD=0;
nsIDTD* theDTD=0;
PRBool thePrimaryFound=PR_FALSE;
while((theDTDIndex<=gSharedObjects.mDTDDeque.GetSize()) && (aParserContext.mAutoDetectStatus!=ePrimaryDetect)){
theDTD=(nsIDTD*)gSharedObjects.mDTDDeque.ObjectAt(theDTDIndex++);
if(theDTD) {
aParserContext.mAutoDetectStatus=theDTD->CanParse(aParserContext.mSourceType,aCommand,aBuffer,0);
if((eValidDetect==aParserContext.mAutoDetectStatus) || (ePrimaryDetect==aParserContext.mAutoDetectStatus)) {
if(eValidDetect==aParserContext.mAutoDetectStatus){
theBestDTD=theDTD;
}
else if(ePrimaryDetect==aParserContext.mAutoDetectStatus) {
theBestDTD=theDTD;
thePrimaryFound=PR_TRUE;
}
if((theDTDIndex==gSharedObjects.mDTDDeque.GetSize()) && (!theBestDTD)) {
}
if((theDTDIndex==gSharedObjects.mDTDDeque.GetSize()) && (!thePrimaryFound)) {
if(!gSharedObjects.mHasXMLDTD) {
NS_NewWellFormed_DTD(&theDTD); //do this to view XML files...
gSharedObjects.mDTDDeque.Push(theDTD);
@ -556,6 +561,7 @@ nsresult nsParser::WillBuildModel(nsString& aFilename,nsIDTD* aDefaultDTD){
PRBool(0==mParserContext->mPrevContext),
mParserContext->mSourceType,
mParserContext->mParseMode,
mCommand,
mSink);
}//if
}//if
@ -953,6 +959,7 @@ nsresult nsParser::ResumeParse(nsIDTD* aDefaultDTD, PRBool aIsFinalChunk) {
if((!mParserContext->mMultipart) || (mInternalState==NS_ERROR_HTMLPARSER_STOPPARSING) ||
((eOnStop==mParserContext->mStreamListenerState) && (NS_OK==result))){
DidBuildModel(mStreamStatus);
MOZ_TIMER_DEBUGLOG(("Stop: Parse Time: nsParser::ResumeParse(), this=%p\n", this));
@ -1131,9 +1138,7 @@ nsresult nsParser::OnStartRequest(nsIChannel* channel, nsISupports* aContext)
#define UCS4_2143 "X-ISO-10646-UCS-4-2143"
#define UCS4_3412 "X-ISO-10646-UCS-4-3412"
static PRBool detectByteOrderMark(const unsigned char* aBytes, PRInt32 aLen,
nsString& oCharset, nsCharsetSource& oCharsetSource)
{
static PRBool detectByteOrderMark(const unsigned char* aBytes, PRInt32 aLen, nsString& oCharset, nsCharsetSource& oCharsetSource) {
oCharsetSource= kCharsetFromAutoDetection;
oCharset = "";
// see http://www.w3.org/TR/1998/REC-xml-19980210#sec-oCharseting
@ -1395,6 +1400,7 @@ nsresult nsParser::Tokenize(PRBool aIsFinalChunk){
nsITokenizer* theTokenizer=mParserContext->mDTD->GetTokenizer();
if(theTokenizer){
MOZ_TIMER_START(mTokenizeTime);
WillTokenize(aIsFinalChunk);

Просмотреть файл

@ -33,6 +33,7 @@
#include "nsHTMLEntities.h"
#include "nsHTMLTokenizer.h"
#include "nsXMLTokenizer.h"
//#include "nsTextTokenizer.h"
#include "nsExpatTokenizer.h"
#include "nsIParserService.h"
@ -190,6 +191,7 @@ nsParserModule::Shutdown()
nsHTMLTokenizer::FreeTokenRecycler();
nsXMLTokenizer::FreeTokenRecycler();
nsExpatTokenizer::FreeTokenRecycler();
// nsTextTokenizer::FreeTokenRecycler();
nsParser::FreeSharedObjects();
mInitialized = PR_FALSE;
}

Просмотреть файл

@ -56,6 +56,8 @@ nsCParserNode::nsCParserNode(CToken* aToken,PRInt32 aLineNumber,nsITokenRecycler
mLineNumber=aLineNumber;
mToken=aToken;
mRecycler=aRecycler;
mUseCount=0;
mIsResidual=PR_FALSE;
}
static void RecycleTokens(nsITokenRecycler* aRecycler,nsDeque& aDeque) {
@ -99,6 +101,9 @@ nsresult nsCParserNode::Init(CToken* aToken,PRInt32 aLineNumber,nsITokenRecycler
if(mAttributes && (mAttributes->GetSize()))
RecycleTokens(mRecycler,*mAttributes);
mToken=aToken;
mUseCount=0;
mIsResidual=PR_FALSE;
mSkippedContent.Truncate();
return NS_OK;
}

Просмотреть файл

@ -115,6 +115,7 @@ class nsCParserNode : public nsIParserNode {
*/
virtual PRInt32 GetTokenType() const;
//***************************************
//methods for accessing key/value pairs
//***************************************
@ -173,11 +174,12 @@ class nsCParserNode : public nsIParserNode {
*/
virtual CToken* PopAttributeToken();
protected:
PRInt32 mLineNumber;
CToken* mToken;
nsDeque* mAttributes;
nsAutoString mSkippedContent;
PRInt32 mUseCount;
PRBool mIsResidual;
nsITokenRecycler* mRecycler;
};

Просмотреть файл

@ -67,6 +67,7 @@ nsScanner::nsScanner(nsString& anHTMLString, const nsString& aCharset, nsCharset
mCharset = "";
mCharsetSource = kCharsetUninitialized;
SetDocumentCharset(aCharset, aSource);
mNewlinesSkipped=0;
}
/**
@ -96,6 +97,7 @@ nsScanner::nsScanner(nsString& aFilename,PRBool aCreateStream, const nsString& a
mCharset = "";
mCharsetSource = kCharsetUninitialized;
SetDocumentCharset(aCharset, aSource);
mNewlinesSkipped=0;
}
/**
@ -122,6 +124,7 @@ nsScanner::nsScanner(nsString& aFilename,nsInputStream& aStream,const nsString&
mCharset = "";
mCharsetSource = kCharsetUninitialized;
SetDocumentCharset(aCharset, aSource);
mNewlinesSkipped=0;
}
@ -454,15 +457,17 @@ nsresult nsScanner::SkipWhitespace(void) {
PRInt32 theOrigin=mOffset;
PRBool found=PR_FALSE;
mNewlinesSkipped = 0;
#if 1
while(NS_OK==result) {
theChar=theBuf[mOffset++];
if(theChar) {
switch(theChar) {
case ' ':
case '\n': mNewlinesSkipped++;
case ' ' :
case '\r':
case '\n':
case '\b':
case '\t':
found=PR_TRUE;

Просмотреть файл

@ -312,6 +312,7 @@ class nsScanner {
void SetIncremental(PRBool anIncrValue) {mIncremental=anIncrValue;}
PRUint32 GetOffset(void) {return mOffset;}
PRInt32 GetNewlinesSkipped(void) { return mNewlinesSkipped; }
protected:
@ -337,6 +338,7 @@ class nsScanner {
nsString mCharset;
nsIUnicodeDecoder *mUnicodeDecoder;
nsString mUnicodeXferBuf;
PRInt32 mNewlinesSkipped;
};
#endif

Просмотреть файл

@ -46,7 +46,8 @@ CToken::CToken(PRInt32 aTag) : mTextValue() {
mAttrCount=0;
TokenCount++;
mOrigin=eSource;
mRecycle=PR_TRUE;
mUseCount=0;
mNewlineCount=0;
}
/**
@ -61,7 +62,8 @@ CToken::CToken(const nsString& aName) : mTextValue(aName) {
mAttrCount=0;
TokenCount++;
mOrigin=eSource;
mRecycle=PR_TRUE;
mUseCount=0;
mNewlineCount=0;
}
/**
@ -76,7 +78,8 @@ CToken::CToken(const char* aName) : mTextValue(aName) {
mAttrCount=0;
TokenCount++;
mOrigin=eSource;
mRecycle=PR_TRUE;
mUseCount=0;
mNewlineCount=0;
}
/**
@ -106,7 +109,8 @@ void CToken::Reinitialize(PRInt32 aTag, const nsString& aString){
mTypeID=aTag;
mAttrCount=0;
mOrigin=eSource;
mRecycle=PR_TRUE;
mUseCount=0;
mNewlineCount=0;
}
/**

Просмотреть файл

@ -204,7 +204,8 @@ class CToken {
static int GetTokenCount();
eTokenOrigin mOrigin;
PRBool mRecycle;
PRInt32 mUseCount;
PRInt32 mNewlineCount;
protected:
PRInt32 mTypeID;

Просмотреть файл

@ -195,7 +195,9 @@ PRBool CValidDTD::CanConvert(nsString& aSourceType, nsString& aTargetType, PRInt
* @param
* @return
*/
NS_IMETHODIMP CValidDTD::WillBuildModel(nsString& aFilename,PRBool aNotifySink,nsString& aSourceType,eParseMode aParseMode,nsIContentSink* aSink){
NS_IMETHODIMP CValidDTD::WillBuildModel(nsString& aFilename,PRBool aNotifySink,
nsString& aSourceType,eParseMode aParseMode,
nsString& aCommand,nsIContentSink* aSink){
nsresult result=NS_OK;
return result;
}

Просмотреть файл

@ -115,7 +115,12 @@ class CValidDTD : public nsIDTD {
* @param aFilename is the name of the file being parsed.
* @return error code (almost always 0)
*/
NS_IMETHOD WillBuildModel(nsString& aFilename,PRBool aNotifySink,nsString& aSourceType,eParseMode aParseMode,nsIContentSink* aSink=0);
NS_IMETHOD WillBuildModel(nsString& aFilename,
PRBool aNotifySink,
nsString& aSourceType,
eParseMode aParseMode,
nsString& aCommand,
nsIContentSink* aSink=0);
/**
* The parser uses a code sandwich to wrap the parsing process. Before
* the process begins, WillBuildModel() is called. Afterwards the parser

Просмотреть файл

@ -54,6 +54,7 @@
#include "nsIContentSink.h"
#include "nsIHTMLContentSink.h"
#include "nsHTMLTokenizer.h"
//#include "nsTextTokenizer.h"
#include "prenv.h" //this is here for debug reasons...
#include "prtypes.h" //this is here for debug reasons...
@ -204,7 +205,7 @@ public:
* @param
* @return
*/
CViewSourceHTML::CViewSourceHTML() : nsIDTD(), mFilename(""),
CViewSourceHTML::CViewSourceHTML() : nsIDTD(),
mStartTag("start"), mEndTag("end"), mCommentTag("comment"),
mDocTypeTag("doctype"), mPITag("pi"), mEntityTag("entity"),
mText("txt"), mKey("key"), mValue("val")
@ -214,6 +215,7 @@ CViewSourceHTML::CViewSourceHTML() : nsIDTD(), mFilename(""),
mSink=0;
mLineNumber=0;
mTokenizer=0;
mIsText=PR_FALSE;
#ifdef rickgdebug
gDumpFile = new fstream("c:/temp/viewsource.xml",ios::trunc);
@ -289,9 +291,10 @@ eAutoDetectResult CViewSourceHTML::CanParse(nsString& aContentType, nsString& aC
* @param
* @return
*/
NS_IMETHODIMP CViewSourceHTML::WillBuildModel(nsString& aFilename,PRBool aNotifySink,nsString& aSourceType,eParseMode aParseMode,nsIContentSink* aSink){
NS_IMETHODIMP CViewSourceHTML::WillBuildModel(nsString& aFilename,PRBool aNotifySink,
nsString& aSourceType,eParseMode aParseMode,
nsString& aCommand,nsIContentSink* aSink){
nsresult result=NS_OK;
mFilename=aFilename;
#ifdef RAPTOR_PERF_METRICS
vsTimer.Reset();
@ -302,18 +305,15 @@ NS_IMETHODIMP CViewSourceHTML::WillBuildModel(nsString& aFilename,PRBool aNotify
mSink=(nsIXMLContentSink*)aSink;
if((aNotifySink) && (mSink)) {
mLineNumber=0;
result = mSink->WillBuildModel();
static const char* theHeader="<?xml version=\"1.0\"?>";
CToken ssToken(theHeader);
nsCParserNode ssNode(&ssToken);
result= mSink->AddCharacterData(ssNode);
#ifdef rickgdebug
#ifdef rickgdebug
(*gDumpFile) << theHeader << endl;
(*gDumpFile) << "<viewsource xmlns=\"viewsource\">" << endl;
#endif
#endif
//now let's automatically open the root container...
CToken theToken("viewsource");
@ -323,6 +323,11 @@ NS_IMETHODIMP CViewSourceHTML::WillBuildModel(nsString& aFilename,PRBool aNotify
theNode.AddAttribute(&theAttr);
mSink->OpenContainer(theNode);
}
mIsText=!aCommand.Equals(kViewSourceCommand);
mLineNumber=0;
result = mSink->WillBuildModel();
START_TIMER();
return result;
}
@ -338,7 +343,8 @@ NS_IMETHODIMP CViewSourceHTML::WillBuildModel(nsString& aFilename,PRBool aNotify
NS_IMETHODIMP CViewSourceHTML::BuildModel(nsIParser* aParser,nsITokenizer* aTokenizer,nsITokenObserver* anObserver,nsIContentSink* aSink) {
nsresult result=NS_OK;
if(aTokenizer) {
if(aTokenizer && aParser) {
nsITokenizer* oldTokenizer=mTokenizer;
mTokenizer=aTokenizer;
gTokenRecycler=(CTokenRecycler*)mTokenizer->GetTokenRecycler();
@ -384,7 +390,7 @@ NS_IMETHODIMP CViewSourceHTML::DidBuildModel(nsresult anErrorCode,PRBool aNotify
mSink=(nsIXMLContentSink*)aParser->GetContentSink();
if((aNotifySink) && (mSink)) {
//now let's automatically close the pre...
//now let's automatically auto-opened containers...
#ifdef rickgdebug
if(gDumpFile){
@ -394,11 +400,12 @@ NS_IMETHODIMP CViewSourceHTML::DidBuildModel(nsresult anErrorCode,PRBool aNotify
}
#endif
if(!mIsText) {
//now let's automatically close the root container...
CToken theToken("viewsource");
nsCParserNode theNode(&theToken,0);
mSink->CloseContainer(theNode);
}
result = mSink->DidBuildModel(1);
}
@ -451,8 +458,12 @@ nsresult CViewSourceHTML::Terminate(void)
* @return ptr to tokenizer
*/
nsITokenizer* CViewSourceHTML::GetTokenizer(void) {
if(!mTokenizer)
mTokenizer=new nsHTMLTokenizer();
if(!mTokenizer) {
/*if(mIsText)
mTokenizer = new nsTextTokenizer();
else */
mTokenizer = new nsHTMLTokenizer();
}
return mTokenizer;
}
@ -694,7 +705,7 @@ nsresult CViewSourceHTML::WriteAttributes(PRInt32 attrCount) {
CToken theKeyToken(theAttrToken->GetKey());
result=WriteTag(mKey,&theKeyToken,0,PR_FALSE);
nsString& theValue=theToken->GetStringValueXXX();
if(0<theValue.Length()) {
if((0<theValue.Length()) || (theAttrToken->mHasEqualWithoutValue)){
result=WriteTag(mValue,theToken,0,PR_FALSE);
}
}
@ -760,7 +771,6 @@ nsresult CViewSourceHTML::WriteTag(nsString &theXMLTagName,CToken* aToken,PRInt3
mSink->CloseContainer(theContext.mEndNode); //emit </starttag>...
START_TIMER();
#ifdef rickgdebug
cstr.Assign(theXMLTagName);
(*gDumpFile) << "</" << cstr << ">";
@ -852,17 +862,13 @@ NS_IMETHODIMP CViewSourceHTML::HandleToken(CToken* aToken,nsIParser* aParser) {
case eToken_start:
result=WriteTag(mStartTag,aToken,aToken->GetAttributeCount(),PR_TRUE);
if(mParser && (NS_OK==result)) {
nsAutoString charsetValue;
nsCharsetSource charsetSource;
if((!mIsText) && mParser && (NS_OK==result)) {
CObserverService& theService=mParser->GetObserverService();
CParserContext* pc=mParser->PeekContext();
void* theDocID=(pc)? pc->mKey:0;
eHTMLTags theTag=(eHTMLTags)theToken->GetTypeID();
mParser->GetDocumentCharset(charsetValue,charsetSource);
eHTMLTags theTag = (eHTMLTags)aToken->GetTypeID();
result=theService.Notify(theTag,theContext.mTokenNode,(PRUint32)theDocID,
kViewSourceCommand,charsetValue,charsetSource);
result=theService.Notify(theTag,theContext.mTokenNode,(PRUint32)theDocID,kViewSourceCommand,mParser);
}
theContext.mTokenNode.Init(0,0,gTokenRecycler); //now recycle.
break;

Просмотреть файл

@ -108,10 +108,11 @@ class CViewSourceHTML: public nsIDTD {
* @param aFilename is the name of the file being parsed.
* @return error code (almost always 0)
*/
NS_IMETHOD WillBuildModel( nsString& aFilename,
NS_IMETHOD WillBuildModel(nsString& aFilename,
PRBool aNotifySink,
nsString& aSourceType,
eParseMode aParseMode,
nsString& aCommand,
nsIContentSink* aSink=0);
/**
* The parser uses a code sandwich to wrap the parsing process. Before
@ -267,7 +268,6 @@ protected:
nsParser* mParser;
nsIXMLContentSink* mSink;
nsString mFilename;
PRInt32 mLineNumber;
nsITokenizer* mTokenizer;
nsAutoString mStartTag;
@ -279,6 +279,7 @@ protected:
nsAutoString mText;
nsAutoString mKey;
nsAutoString mValue;
PRBool mIsText;
};
extern NS_HTMLPARS nsresult NS_NewViewSourceHTML(nsIDTD** aInstancePtrResult);

Просмотреть файл

@ -206,7 +206,9 @@ eAutoDetectResult CWellFormedDTD::CanParse(nsString& aContentType, nsString& aCo
* @param
* @return
*/
NS_IMETHODIMP CWellFormedDTD::WillBuildModel(nsString& aFilename,PRBool aNotifySink,nsString& aSourceType,eParseMode aParseMode,nsIContentSink* aSink){
NS_IMETHODIMP CWellFormedDTD::WillBuildModel(nsString& aFilename,PRBool aNotifySink,
nsString& aSourceType,eParseMode aParseMode,
nsString& aCommand,nsIContentSink* aSink){
nsresult result=NS_OK;
mFilename=aFilename;

Просмотреть файл

@ -106,6 +106,7 @@ class CWellFormedDTD : public nsIDTD {
PRBool aNotifySink,
nsString& aSourceType,
eParseMode aParseMode,
nsString& aCommand,
nsIContentSink* aSink=0);
/**
* The parser uses a code sandwich to wrap the parsing process. Before

Просмотреть файл

@ -40,6 +40,7 @@
#include "prmem.h"
#include "nsXMLTokenizer.h"
static NS_DEFINE_IID(kIHTMLContentSinkIID, NS_IHTML_CONTENT_SINK_IID);
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
static NS_DEFINE_IID(kIDTDIID, NS_IDTD_IID);
static NS_DEFINE_IID(kClassIID, NS_XIF_DTD_CID);
@ -334,6 +335,7 @@ nsXIFDTD::nsXIFDTD() : nsIDTD(){
mLowerCaseAttributes=PR_TRUE;
mLowerCaseTags=PR_TRUE;
mCharset = "";
mSink=0;
}
/**
@ -345,7 +347,7 @@ nsXIFDTD::nsXIFDTD() : nsIDTD(){
*/
nsXIFDTD::~nsXIFDTD(){
DeleteTokenHandlers();
// NS_RELEASE(mSink);
NS_IF_RELEASE(mSink);
}
@ -428,12 +430,17 @@ eAutoDetectResult nsXIFDTD::CanParse(nsString& aContentType, nsString& aCommand,
* @param
* @return
*/
nsresult nsXIFDTD::WillBuildModel(nsString& aFilename,PRBool aNotifySink,nsString& aSourceType,eParseMode aParseMode,nsIContentSink* aSink){
nsresult nsXIFDTD::WillBuildModel(nsString& aFilename,PRBool aNotifySink,
nsString& aSourceType,eParseMode aParseMode,
nsString& aCommand,nsIContentSink* aSink){
nsresult result=NS_OK;
mSink=(nsIHTMLContentSink*)aSink;
if(mSink) {
mSink->WillBuildModel();
if(aSink) {
if(aSink && (!mSink)) {
result=aSink->QueryInterface(kIHTMLContentSinkIID, (void **)&mSink);
}
result = aSink->WillBuildModel();
}
return result;
}

Просмотреть файл

@ -156,10 +156,11 @@ class nsXIFDTD : public nsIDTD {
* @param
* @return
*/
NS_IMETHOD WillBuildModel( nsString& aFilename,
NS_IMETHOD WillBuildModel(nsString& aFilename,
PRBool aNotifySink,
nsString& aSourceType,
eParseMode aParseMode,
nsString& aCommand,
nsIContentSink* aSink=0);
/**
* The parser uses a code sandwich to wrap the parsing process. Before

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -104,6 +104,7 @@ class nsDTDContext;
class nsEntryStack;
class nsITokenizer;
class nsCParserNode;
class CTokenRecycler;
/***************************************************************
Now the main event: CNavDTD.
@ -187,6 +188,7 @@ CLASS_EXPORT_HTMLPARS CNavDTD : public nsIDTD {
PRBool aNotifySink,
nsString& aSourceType,
eParseMode aParseMode,
nsString& aCommand,
nsIContentSink* aSink=0);
/**
@ -289,7 +291,7 @@ CLASS_EXPORT_HTMLPARS CNavDTD : public nsIDTD {
* @param aChild -- int tag of child container
* @return PR_TRUE if parent can contain child
*/
virtual PRBool CanPropagate(eHTMLTags aParent,eHTMLTags aChild) const;
virtual PRBool CanPropagate(eHTMLTags aParent,eHTMLTags aChild,PRBool aParentContains) const;
/**
* This method gets called to determine whether a given
@ -298,9 +300,10 @@ CLASS_EXPORT_HTMLPARS CNavDTD : public nsIDTD {
* @update gess 3/25/98
* @param aParent -- parent tag being asked about omitting given child
* @param aChild -- child tag being tested for omittability by parent
* @param aParentContains -- can be 0,1,-1 (false,true, unknown)
* @return PR_TRUE if given tag can be omitted
*/
virtual PRBool CanOmit(eHTMLTags aParent,eHTMLTags aChild)const;
virtual PRBool CanOmit(eHTMLTags aParent,eHTMLTags aChild,PRBool& aParentContains) const;
/**
* This method gets called to determine whether a given
@ -375,7 +378,7 @@ CLASS_EXPORT_HTMLPARS CNavDTD : public nsIDTD {
* @param tag to be found
* @return index of topmost tag occurance -- may be -1 (kNotFound).
*/
virtual PRInt32 GetTopmostIndexOf(eHTMLTags aTag) const;
// virtual PRInt32 GetTopmostIndexOf(eHTMLTags aTag) const;
/**
* Finds the topmost occurance of given tag within context vector stack.
@ -415,12 +418,12 @@ CLASS_EXPORT_HTMLPARS CNavDTD : public nsIDTD {
* @return error code representing construction state; usually 0.
*/
nsresult HandleStartToken(CToken* aToken);
nsresult HandleDefaultStartToken(CToken* aToken,eHTMLTags aChildTag,nsIParserNode& aNode);
nsresult HandleDefaultStartToken(CToken* aToken,eHTMLTags aChildTag,nsIParserNode *aNode);
nsresult HandleEndToken(CToken* aToken);
nsresult HandleEntityToken(CToken* aToken);
nsresult HandleCommentToken(CToken* aToken);
nsresult HandleAttributeToken(CToken* aToken);
nsresult HandleScriptToken(nsCParserNode& aNode);
nsresult HandleScriptToken(const nsIParserNode *aNode);
nsresult HandleStyleToken(CToken* aToken);
nsresult HandleProcessingInstructionToken(CToken* aToken);
nsresult HandleDocTypeDeclToken(CToken* aToken);
@ -439,13 +442,13 @@ CLASS_EXPORT_HTMLPARS CNavDTD : public nsIDTD {
* @param node to be opened in content sink.
* @return error code representing error condition-- usually 0.
*/
nsresult OpenHTML(const nsIParserNode& aNode);
nsresult OpenHead(const nsIParserNode& aNode);
nsresult OpenBody(const nsIParserNode& aNode);
nsresult OpenForm(const nsIParserNode& aNode);
nsresult OpenMap(const nsIParserNode& aNode);
nsresult OpenFrameset(const nsIParserNode& aNode);
nsresult OpenContainer(const nsIParserNode& aNode,PRBool aClosedByStartTag);
nsresult OpenHTML(const nsIParserNode *aNode);
nsresult OpenHead(const nsIParserNode *aNode);
nsresult OpenBody(const nsIParserNode *aNode);
nsresult OpenForm(const nsIParserNode *aNode);
nsresult OpenMap(const nsIParserNode *aNode);
nsresult OpenFrameset(const nsIParserNode *aNode);
nsresult OpenContainer(const nsIParserNode *aNode,eHTMLTags aTag,PRBool aClosedByStartTag,PRInt32 aResidualStyleLevel=-1);
/**
* The next set of methods close the given HTML element.
@ -454,13 +457,12 @@ CLASS_EXPORT_HTMLPARS CNavDTD : public nsIDTD {
* @param HTML (node) to be opened in content sink.
* @return error code - 0 if all went well.
*/
nsresult CloseHTML(const nsIParserNode& aNode);
nsresult CloseHead(const nsIParserNode& aNode);
nsresult CloseBody(const nsIParserNode& aNode);
nsresult CloseForm(const nsIParserNode& aNode);
nsresult CloseMap(const nsIParserNode& aNode);
nsresult CloseFrameset(const nsIParserNode& aNode);
nsresult CloseContainer(const nsIParserNode& aNode,eHTMLTags anActualTag,PRBool aClosedByStartTag);
nsresult CloseHTML(const nsIParserNode *aNode);
nsresult CloseHead(const nsIParserNode *aNode);
nsresult CloseBody(const nsIParserNode *aNode);
nsresult CloseForm(const nsIParserNode *aNode);
nsresult CloseMap(const nsIParserNode *aNode);
nsresult CloseFrameset(const nsIParserNode *aNode);
/**
* The special purpose methods automatically close
@ -468,7 +470,7 @@ CLASS_EXPORT_HTMLPARS CNavDTD : public nsIDTD {
* @update gess5/11/98
* @return error code - 0 if all went well.
*/
nsresult CloseTopmostContainer();
nsresult CloseContainer(const nsIParserNode *aNode,eHTMLTags aTarget,PRBool aClosedByStartTag);
nsresult CloseContainersTo(eHTMLTags aTag,PRBool aClosedByStartTag);
nsresult CloseContainersTo(PRInt32 anIndex,eHTMLTags aTag,PRBool aClosedByStartTag);
@ -478,8 +480,8 @@ CLASS_EXPORT_HTMLPARS CNavDTD : public nsIDTD {
* @param aNode is leaf node to be added.
* @return error code - 0 if all went well.
*/
nsresult AddLeaf(const nsIParserNode& aNode);
nsresult AddHeadLeaf(nsIParserNode& aNode);
nsresult AddLeaf(const nsIParserNode *aNode);
nsresult AddHeadLeaf(nsIParserNode *aNode);
/**
* This set of methods is used to create and manage the set of
@ -492,8 +494,7 @@ CLASS_EXPORT_HTMLPARS CNavDTD : public nsIDTD {
*/
nsresult OpenTransientStyles(eHTMLTags aChildTag);
nsresult CloseTransientStyles(eHTMLTags aChildTag);
nsresult UpdateStyleStackForOpenTag(eHTMLTags aTag,eHTMLTags aActualTag);
nsresult UpdateStyleStackForCloseTag(eHTMLTags aTag,eHTMLTags aActualTag);
nsresult PopStyle(eHTMLTags aTag);
nsresult DoFragment(PRBool aFlag);
@ -503,8 +504,8 @@ protected:
nsresult CollectSkippedContent(nsCParserNode& aNode,PRInt32& aCount);
nsresult WillHandleStartTag(CToken* aToken,eHTMLTags aChildTag,nsCParserNode& aNode);
nsresult DidHandleStartTag(nsCParserNode& aNode,eHTMLTags aChildTag);
nsresult HandleOmittedTag(CToken* aToken,eHTMLTags aChildTag,eHTMLTags aParent,nsIParserNode& aNode);
nsresult HandleSavedTokensAbove(eHTMLTags aTag);
nsresult HandleOmittedTag(CToken* aToken,eHTMLTags aChildTag,eHTMLTags aParent,nsIParserNode *aNode);
nsresult HandleSavedTokens(PRInt32 anIndex);
nsCParserNode* CreateNode(void);
void RecycleNode(nsCParserNode* aNode);
@ -514,6 +515,7 @@ protected:
nsDTDContext* mBodyContext;
nsDTDContext* mFormContext;
nsDTDContext* mMapContext;
nsDTDContext* mTempContext;
PRBool mHasOpenForm;
PRBool mHasOpenMap;
PRInt32 mHasOpenHead;
@ -525,9 +527,11 @@ protected:
PRInt32 mLineNumber;
nsParser* mParser;
nsITokenizer* mTokenizer;
CTokenRecycler* mTokenRecycler;
nsDeque mMisplacedContent;
nsDeque mSkippedContent;
PRBool mHasOpenScript;
PRBool mSaveBadTokens;
eHTMLTags mSkipTarget;
nsDeque mSharedNodes;
nsresult mDTDState;
@ -535,6 +539,11 @@ protected:
PRUint32 mComputedCRC32;
PRUint32 mExpectedCRC32;
nsAutoString mScratch; //used for various purposes; non-persistent
#ifdef NS_DEBUG
PRInt32 gNodeCount;
#endif
};

Просмотреть файл

@ -191,7 +191,7 @@ eAutoDetectResult COtherDTD::CanParse(nsString& aContentType, nsString& aCommand
* @param aNode -- CParserNode representing this start token
* @return PR_TRUE if all went well; PR_FALSE if error occured
*/
nsresult COtherDTD::HandleDefaultStartToken(CToken* aToken,eHTMLTags aChildTag,nsIParserNode& aNode) {
nsresult COtherDTD::HandleDefaultStartToken(CToken* aToken,eHTMLTags aChildTag,nsIParserNode *aNode) {
return CNavDTD::HandleDefaultStartToken(aToken,aChildTag,aNode);
}
@ -279,7 +279,7 @@ nsresult COtherDTD::HandleAttributeToken(CToken* aToken) {
* @param aToken -- next (start) token to be handled
* @return PR_TRUE if all went well; PR_FALSE if error occured
*/
nsresult COtherDTD::HandleScriptToken(nsCParserNode& aNode) {
nsresult COtherDTD::HandleScriptToken(const nsIParserNode* aNode) {
return CNavDTD::HandleScriptToken(aNode);
}
@ -337,8 +337,8 @@ NS_IMETHODIMP COtherDTD::ConvertEntityToUnicode(const nsString& aEntity, PRInt32
* @param aTag -- tag to test for containership
* @return PR_TRUE if given tag can contain other tags
*/
PRBool COtherDTD::CanOmit(eHTMLTags aParent,eHTMLTags aChild) const {
return CNavDTD::CanOmit(aParent,aChild);
PRBool COtherDTD::CanOmit(eHTMLTags aParent,eHTMLTags aChild,PRInt32 aParentContains) const {
return CNavDTD::CanOmit(aParent,aChild,aParentContains);
}
@ -388,7 +388,7 @@ nsresult COtherDTD::CloseTransientStyles(eHTMLTags aTag){
* @param aNode -- next node to be added to model
* @return TRUE if ok, FALSE if error
*/
nsresult COtherDTD::OpenHTML(const nsIParserNode& aNode){
nsresult COtherDTD::OpenHTML(const nsIParserNode *aNode){
return CNavDTD::OpenHTML(aNode);
}
@ -401,7 +401,7 @@ nsresult COtherDTD::OpenHTML(const nsIParserNode& aNode){
* @param aNode -- next node to be removed from our model
* @return TRUE if ok, FALSE if error
*/
nsresult COtherDTD::CloseHTML(const nsIParserNode& aNode){
nsresult COtherDTD::CloseHTML(const nsIParserNode *aNode){
return CNavDTD::CloseHTML(aNode);
}
@ -414,7 +414,7 @@ nsresult COtherDTD::CloseHTML(const nsIParserNode& aNode){
* @param aNode -- next node to be added to model
* @return TRUE if ok, FALSE if error
*/
nsresult COtherDTD::OpenHead(const nsIParserNode& aNode){
nsresult COtherDTD::OpenHead(const nsIParserNode *aNode){
return CNavDTD::OpenHead(aNode);
}
@ -426,7 +426,7 @@ nsresult COtherDTD::OpenHead(const nsIParserNode& aNode){
* @param aNode -- next node to be removed from our model
* @return TRUE if ok, FALSE if error
*/
nsresult COtherDTD::CloseHead(const nsIParserNode& aNode){
nsresult COtherDTD::CloseHead(const nsIParserNode *aNode){
return CNavDTD::CloseHead(aNode);
}
@ -438,7 +438,7 @@ nsresult COtherDTD::CloseHead(const nsIParserNode& aNode){
* @param aNode -- next node to be added to model
* @return TRUE if ok, FALSE if error
*/
nsresult COtherDTD::OpenBody(const nsIParserNode& aNode){
nsresult COtherDTD::OpenBody(const nsIParserNode *aNode){
return CNavDTD::OpenBody(aNode);
}
@ -450,7 +450,7 @@ nsresult COtherDTD::OpenBody(const nsIParserNode& aNode){
* @param aNode -- next node to be removed from our model
* @return TRUE if ok, FALSE if error
*/
nsresult COtherDTD::CloseBody(const nsIParserNode& aNode){
nsresult COtherDTD::CloseBody(const nsIParserNode *aNode){
return CNavDTD::CloseBody(aNode);
}
@ -462,7 +462,7 @@ nsresult COtherDTD::CloseBody(const nsIParserNode& aNode){
* @param aNode -- next node to be added to model
* @return TRUE if ok, FALSE if error
*/
nsresult COtherDTD::OpenForm(const nsIParserNode& aNode){
nsresult COtherDTD::OpenForm(const nsIParserNode *aNode){
return CNavDTD::OpenForm(aNode);
}
@ -474,7 +474,7 @@ nsresult COtherDTD::OpenForm(const nsIParserNode& aNode){
* @param aNode -- next node to be removed from our model
* @return TRUE if ok, FALSE if error
*/
nsresult COtherDTD::CloseForm(const nsIParserNode& aNode){
nsresult COtherDTD::CloseForm(const nsIParserNode *aNode){
return CNavDTD::CloseForm(aNode);
}
@ -486,7 +486,7 @@ nsresult COtherDTD::CloseForm(const nsIParserNode& aNode){
* @param aNode -- next node to be added to model
* @return TRUE if ok, FALSE if error
*/
nsresult COtherDTD::OpenMap(const nsIParserNode& aNode){
nsresult COtherDTD::OpenMap(const nsIParserNode *aNode){
return CNavDTD::OpenMap(aNode);
}
@ -498,7 +498,7 @@ nsresult COtherDTD::OpenMap(const nsIParserNode& aNode){
* @param aNode -- next node to be removed from our model
* @return TRUE if ok, FALSE if error
*/
nsresult COtherDTD::CloseMap(const nsIParserNode& aNode){
nsresult COtherDTD::CloseMap(const nsIParserNode *aNode){
return CNavDTD::CloseMap(aNode);
}
@ -510,7 +510,7 @@ nsresult COtherDTD::CloseMap(const nsIParserNode& aNode){
* @param aNode -- next node to be added to model
* @return TRUE if ok, FALSE if error
*/
nsresult COtherDTD::OpenFrameset(const nsIParserNode& aNode){
nsresult COtherDTD::OpenFrameset(const nsIParserNode *aNode){
return CNavDTD::OpenFrameset(aNode);
}
@ -522,7 +522,7 @@ nsresult COtherDTD::OpenFrameset(const nsIParserNode& aNode){
* @param aNode -- next node to be removed from our model
* @return TRUE if ok, FALSE if error
*/
nsresult COtherDTD::CloseFrameset(const nsIParserNode& aNode){
nsresult COtherDTD::CloseFrameset(const nsIParserNode *aNode){
return CNavDTD::CloseFrameset(aNode);
}
@ -534,8 +534,8 @@ nsresult COtherDTD::CloseFrameset(const nsIParserNode& aNode){
* @param aNode -- next node to be added to model
* @return TRUE if ok, FALSE if error
*/
nsresult COtherDTD::OpenContainer(const nsIParserNode& aNode,PRBool aUpdateStyleStack){
return CNavDTD::OpenContainer(aNode,aUpdateStyleStack);
nsresult COtherDTD::OpenContainer(const nsIParserNode *aNode,eHTMLTags aTarget,PRBool aUpdateStyleStack,PRInt32 aResidualStyleLevel){
return CNavDTD::OpenContainer(aNode,aTarget,aUpdateStyleStack,aResidualStyleLevel);
}
/**
@ -546,8 +546,8 @@ nsresult COtherDTD::OpenContainer(const nsIParserNode& aNode,PRBool aUpdateStyle
* @param aNode -- next node to be removed from our model
* @return TRUE if ok, FALSE if error
*/
nsresult COtherDTD::CloseContainer(const nsIParserNode& aNode,eHTMLTags aTag,PRBool aUpdateStyles){
return CNavDTD::CloseContainer(aNode,aTag,aUpdateStyles);
nsresult COtherDTD::CloseContainer(const nsIParserNode *aNode,eHTMLTags aTarget,PRBool aUpdateStyles){
return CNavDTD::CloseContainer(aNode,aTarget,aUpdateStyles);
}
/**
@ -558,8 +558,8 @@ nsresult COtherDTD::CloseContainer(const nsIParserNode& aNode,eHTMLTags aTag,PRB
* @param
* @return TRUE if ok, FALSE if error
*/
nsresult COtherDTD::CloseContainersTo(PRInt32 anIndex,eHTMLTags aTag,PRBool aUpdateStyles){
return CNavDTD::CloseContainersTo(anIndex,aTag,aUpdateStyles);
nsresult COtherDTD::CloseContainersTo(PRInt32 anIndex,eHTMLTags aTarget,PRBool aUpdateStyles){
return CNavDTD::CloseContainersTo(anIndex,aTarget,aUpdateStyles);
}
/**
@ -570,21 +570,10 @@ nsresult COtherDTD::CloseContainersTo(PRInt32 anIndex,eHTMLTags aTag,PRBool aUpd
* @param
* @return TRUE if ok, FALSE if error
*/
nsresult COtherDTD::CloseContainersTo(eHTMLTags aTag,PRBool aUpdateStyles){
return CNavDTD::CloseContainersTo(aTag,aUpdateStyles);
nsresult COtherDTD::CloseContainersTo(eHTMLTags aTarget,PRBool aUpdateStyles){
return CNavDTD::CloseContainersTo(aTarget,aUpdateStyles);
}
/**
* This method causes the topmost container on the stack
* to be closed.
* @update gess4/6/98
* @see CloseContainer()
* @param
* @return TRUE if ok, FALSE if error
*/
nsresult COtherDTD::CloseTopmostContainer(){
return CNavDTD::CloseTopmostContainer();
}
/**
* This method does two things: 1st, help construct
@ -594,7 +583,7 @@ nsresult COtherDTD::CloseTopmostContainer(){
* @param aNode -- next node to be added to model
* @return TRUE if ok, FALSE if error
*/
nsresult COtherDTD::AddLeaf(const nsIParserNode& aNode){
nsresult COtherDTD::AddLeaf(const nsIParserNode *aNode){
return CNavDTD::AddLeaf(aNode);
}
@ -614,18 +603,6 @@ nsresult COtherDTD::CreateContextStackFor(eHTMLTags aChildTag){
}
/**
* This method causes all explicit style-tag containers that
* are opened to be reflected on our internal style-stack.
*
* @update gess6/4/98
* @param aTag is the id of the html container being opened
* @return 0 if all is well.
*/
nsresult COtherDTD::UpdateStyleStackForOpenTag(eHTMLTags aTag,eHTMLTags anActualTag){
return CNavDTD::UpdateStyleStackForOpenTag(aTag,anActualTag);
} //update...
/**
* This method gets called when an explicit style close-tag is encountered.
* It results in the style tag id being popped from our internal style stack.
@ -634,8 +611,8 @@ nsresult COtherDTD::UpdateStyleStackForOpenTag(eHTMLTags aTag,eHTMLTags anActual
* @param
* @return 0 if all went well (which it always does)
*/
nsresult COtherDTD::UpdateStyleStackForCloseTag(eHTMLTags aTag,eHTMLTags anActualTag){
return CNavDTD::UpdateStyleStackForCloseTag(aTag,anActualTag);
nsresult COtherDTD::PopStyle(eHTMLTags aTag){
return CNavDTD::PopStyle(aTag);
} //update...
/**

Просмотреть файл

@ -123,7 +123,7 @@ class COtherDTD : public CNavDTD {
* @param aTag -- tag to test for containership
* @return PR_TRUE if given tag can contain other tags
*/
virtual PRBool CanOmit(eHTMLTags aParent,eHTMLTags aChild)const;
virtual PRBool CanOmit(eHTMLTags aParent,eHTMLTags aChild,PRInt32 aParentContains)const;
/**
* Give rest of world access to our tag enums, so that CanContain(), etc,
@ -155,7 +155,7 @@ class COtherDTD : public CNavDTD {
* @param aNode is a node be updated with info from given token
* @return TRUE if the token was handled.
*/
nsresult HandleDefaultStartToken(CToken* aToken,eHTMLTags aChildTag,nsIParserNode& aNode);
nsresult HandleDefaultStartToken(CToken* aToken,eHTMLTags aChildTag,nsIParserNode *aNode);
/**
* This method gets called when an end token has been consumed and needs
@ -200,7 +200,7 @@ class COtherDTD : public CNavDTD {
* @param aToken is the script token to be handled
* @return TRUE if the token was handled.
*/
nsresult HandleScriptToken(nsCParserNode& aNode);
nsresult HandleScriptToken(const nsIParserNode *aNode);
/**
* This method gets called when a style token has been consumed and needs
@ -220,146 +220,38 @@ private:
//*************************************************
/**
* This cover method opens the given node as a HTML item in
* content sink.
* @update gess5/11/98
* @param HTML (node) to be opened in content sink.
* @return TRUE if all went well.
*/
nsresult OpenHTML(const nsIParserNode& aNode);
/**
* The next set of method open given HTML elements of
* various types.
*
* @update gess5/11/98
* @param
* @return
* @param node to be opened in content sink.
* @return error code representing error condition-- usually 0.
*/
nsresult CloseHTML(const nsIParserNode& aNode);
nsresult OpenHTML(const nsIParserNode *aNode);
nsresult OpenHead(const nsIParserNode *aNode);
nsresult OpenBody(const nsIParserNode *aNode);
nsresult OpenForm(const nsIParserNode *aNode);
nsresult OpenMap(const nsIParserNode *aNode);
nsresult OpenFrameset(const nsIParserNode *aNode);
nsresult OpenContainer(const nsIParserNode *aNode,eHTMLTags aTag,PRBool aUpdateStyleStack,PRInt32 aResidualStyleLevel=-1);
/**
* This cover method opens the given node as a head item in
* content sink.
* The next set of methods close the given HTML element.
*
* @update gess5/11/98
* @param HEAD (node) to be opened in content sink.
* @return TRUE if all went well.
* @param HTML (node) to be opened in content sink.
* @return error code - 0 if all went well.
*/
nsresult OpenHead(const nsIParserNode& aNode);
nsresult CloseHTML(const nsIParserNode *aNode);
nsresult CloseHead(const nsIParserNode *aNode);
nsresult CloseBody(const nsIParserNode *aNode);
nsresult CloseForm(const nsIParserNode *aNode);
nsresult CloseMap(const nsIParserNode *aNode);
nsresult CloseFrameset(const nsIParserNode *aNode);
/**
* This cover method causes the content-sink head to be closed
* @update gess5/11/98
* @param aNode is the node to be closed in sink (usually ignored)
* @return TRUE if all went well.
*/
nsresult CloseHead(const nsIParserNode& aNode);
/**
* This cover method opens the given node as a body item in
* content sink.
* @update gess5/11/98
* @param BODY (node) to be opened in content sink.
* @return TRUE if all went well.
*/
nsresult OpenBody(const nsIParserNode& aNode);
/**
* This cover method causes the content-sink body to be closed
* @update gess5/11/98
* @param aNode is the body node to be closed in sink (usually ignored)
* @return TRUE if all went well.
*/
nsresult CloseBody(const nsIParserNode& aNode);
/**
* This cover method opens the given node as a form item in
* content sink.
* @update gess5/11/98
* @param FORM (node) to be opened in content sink.
* @return TRUE if all went well.
*/
nsresult OpenForm(const nsIParserNode& aNode);
/**
* This cover method causes the content-sink form to be closed
* @update gess5/11/98
* @param aNode is the form node to be closed in sink (usually ignored)
* @return TRUE if all went well.
*/
nsresult CloseForm(const nsIParserNode& aNode);
/**
* This cover method opens the given node as a form item in
* content sink.
* @update gess5/11/98
* @param FORM (node) to be opened in content sink.
* @return TRUE if all went well.
*/
nsresult OpenMap(const nsIParserNode& aNode);
/**
* This cover method causes the content-sink form to be closed
* @update gess5/11/98
* @param aNode is the form node to be closed in sink (usually ignored)
* @return TRUE if all went well.
*/
nsresult CloseMap(const nsIParserNode& aNode);
/**
* This cover method opens the given node as a frameset item in
* content sink.
* @update gess5/11/98
* @param FRAMESET (node) to be opened in content sink.
* @return TRUE if all went well.
*/
nsresult OpenFrameset(const nsIParserNode& aNode);
/**
* This cover method causes the content-sink frameset to be closed
* @update gess5/11/98
* @param aNode is the frameeset node to be closed in sink (usually ignored)
* @return TRUE if all went well.
*/
nsresult CloseFrameset(const nsIParserNode& aNode);
/**
* This cover method opens the given node as a generic container in
* content sink.
* @update gess5/11/98
* @param generic container (node) to be opened in content sink.
* @return TRUE if all went well.
*/
nsresult OpenContainer(const nsIParserNode& aNode,PRBool aUpdateStyleStack);
/**
* This cover method causes a generic containre in the content-sink to be closed
* @update gess5/11/98
* @param aNode is the node to be closed in sink (usually ignored)
* @return TRUE if all went well.
*/
nsresult CloseContainer(const nsIParserNode& aNode,eHTMLTags anActualTag,PRBool aUpdateStyles);
/**
* This cover method causes the topmost container to be closed in sink
* @update gess5/11/98
* @return TRUE if all went well.
*/
nsresult CloseTopmostContainer();
/**
* Cause all containers down to topmost given tag to be closed
* @update gess5/11/98
* @param aTag is the tag at which auto-closure should stop (inclusive)
* @return TRUE if all went well -- otherwise FALSE
*/
nsresult CloseContainer(const nsIParserNode *aNode,eHTMLTags aTarget,PRBool aUpdateStyles);
nsresult CloseContainersTo(eHTMLTags aTag,PRBool aUpdateStyles);
/**
* Cause all containers down to given position to be closed
* @update gess5/11/98
* @param anIndex is the stack pos at which auto-closure should stop (inclusive)
* @return TRUE if all went well -- otherwise FALSE
*/
nsresult CloseContainersTo(PRInt32 anIndex,eHTMLTags aTag,PRBool aUpdateStyles);
nsresult CloseContainersTo(PRInt32 anIndex,eHTMLTags aTarget,PRBool aUpdateStyles);
/**
* Causes leaf to be added to sink at current vector pos.
@ -367,7 +259,7 @@ private:
* @param aNode is leaf node to be added.
* @return TRUE if all went well -- FALSE otherwise.
*/
nsresult AddLeaf(const nsIParserNode& aNode);
nsresult AddLeaf(const nsIParserNode *aNode);
/**
@ -381,8 +273,7 @@ private:
nsresult OpenTransientStyles(eHTMLTags aTag);
nsresult CloseTransientStyles(eHTMLTags aTag);
nsresult UpdateStyleStackForOpenTag(eHTMLTags aTag,eHTMLTags aActualTag);
nsresult UpdateStyleStackForCloseTag(eHTMLTags aTag,eHTMLTags aActualTag);
nsresult PopStyle(eHTMLTags aTag);
nsresult DoFragment(PRBool aFlag);

Просмотреть файл

@ -261,7 +261,9 @@ eAutoDetectResult CRtfDTD::CanParse(nsString& aContentType, nsString& aCommand,
* @param
* @return
*/
NS_IMETHODIMP CRtfDTD::WillBuildModel(nsString& aFilename,PRBool aNotifySink,nsString& aSourceType,eParseMode aParseMode,nsIContentSink* aSink){
NS_IMETHODIMP CRtfDTD::WillBuildModel(nsString& aFilename,PRBool aNotifySink,
nsString& aSourceType,eParseMode aParseMode,
nsString& aCommand,nsIContentSink* aSink){
nsresult result=NS_OK;
return result;
}

Просмотреть файл

@ -202,6 +202,7 @@ class CRtfDTD : public nsIDTD {
PRBool aNotifySink,
nsString& aSourceType,
eParseMode aParseMode,
nsString& aCommand,
nsIContentSink* aSink=0);
/**

Просмотреть файл

@ -24,6 +24,7 @@
#include "nsDTDUtils.h"
#include "CNavDTD.h"
#include "nsIParserNode.h"
#include "nsParserNode.h"
#include "nsIObserverService.h"
#include "nsIServiceManager.h"
@ -33,9 +34,6 @@ MOZ_DECL_CTOR_COUNTER(nsDTDContext);
MOZ_DECL_CTOR_COUNTER(CTokenRecycler);
MOZ_DECL_CTOR_COUNTER(CObserverService);
/***************************************************************
First, define the tagstack class
***************************************************************/
/**
@ -61,12 +59,24 @@ nsEntryStack::~nsEntryStack() {
MOZ_COUNT_DTOR(nsEntryStack);
if(mEntries)
if(mEntries) {
if(0<mCount) {
PRInt32 anIndex=0;
for(anIndex=0;anIndex<mCount;anIndex++){
if(mEntries[anIndex].mStyles)
delete mEntries[anIndex].mStyles;
//add code here to recycle the node if you have one...
}
}
delete [] mEntries;
mCount=mCapacity=0;
mEntries=0;
}
mCount=mCapacity=0;
}
/**
* Resets state of stack to be empty.
* @update harishd 04/04/99
@ -75,17 +85,24 @@ void nsEntryStack::Empty(void) {
mCount=0;
}
/**
*
* @update gess 04/22/99
*/
void nsEntryStack::Push(eHTMLTags aTag) {
if(mCount==mCapacity){
nsTagEntry* temp=new nsTagEntry[mCapacity+=50];
void nsEntryStack::EnsureCapacityFor(PRInt32 aNewMax,PRInt32 aShiftOffset) {
if(mCapacity<aNewMax){
const int kDelta=16;
PRInt32 theSize = kDelta * ((aNewMax / kDelta) + 1);
nsTagEntry* temp=new nsTagEntry[theSize];
mCapacity=theSize;
if(temp){
PRUint32 index=0;
PRInt32 index=0;
for(index=0;index<mCount;index++) {
temp[index]=mEntries[index];
temp[aShiftOffset+index]=mEntries[index];
}
delete [] mEntries;
mEntries=temp;
@ -93,10 +110,76 @@ void nsEntryStack::Push(eHTMLTags aTag) {
else{
//XXX HACK! This is very bad! We failed to get memory.
}
} //if
}
/**
*
* @update gess 04/22/99
*/
void nsEntryStack::Push(const nsIParserNode* aNode,PRInt32 aResidualStyleLevel) {
if(aNode) {
EnsureCapacityFor(mCount+1);
((nsCParserNode*)aNode)->mUseCount++;
((nsCParserNode*)aNode)->mToken->mUseCount++;
mEntries[mCount].mTag=(eHTMLTags)aNode->GetNodeType();
mEntries[mCount].mNode=(nsIParserNode*)aNode;
mEntries[mCount].mLevel=aResidualStyleLevel;
mEntries[mCount].mParent=0;
mEntries[mCount++].mStyles=0;
}
}
/**
* This method inserts the given node onto the front of this stack
*
* @update gess 11/10/99
*/
void nsEntryStack::PushFront(const nsIParserNode* aNode,PRInt32 aResidualStyleLevel) {
if(aNode) {
if(mCount<mCapacity) {
PRInt32 index=0;
for(index=mCount;index>0;index--) {
mEntries[index]=mEntries[index-1];
}
}
else EnsureCapacityFor(mCount+1,1);
((nsCParserNode*)aNode)->mUseCount++;
((nsCParserNode*)aNode)->mToken->mUseCount++;
mEntries[0].mTag=(eHTMLTags)aNode->GetNodeType();
mEntries[0].mNode=(nsIParserNode*)aNode;
mEntries[0].mLevel=aResidualStyleLevel;
mEntries[0].mParent=0;
mEntries[0].mStyles=0;
mCount++;
}
}
/**
*
* @update gess 11/10/99
*/
void nsEntryStack::Append(nsEntryStack *aStack) {
if(aStack) {
PRInt32 theCount=aStack->mCount;
EnsureCapacityFor(mCount+aStack->mCount,0);
PRInt32 theIndex=0;
for(theIndex=0;theIndex<theCount;theIndex++){
mEntries[mCount]=aStack->mEntries[theIndex];
mEntries[mCount++].mLevel=-1;
}
}
mEntries[mCount].mTag=aTag;
mEntries[mCount].mBankIndex=-1;
mEntries[mCount++].mStyleIndex=-1;
}
@ -105,10 +188,17 @@ void nsEntryStack::Push(eHTMLTags aTag) {
* @update harishd 04/04/99
* @update gess 04/21/99
*/
eHTMLTags nsEntryStack::Pop() {
eHTMLTags result=eHTMLTag_unknown;
nsIParserNode* nsEntryStack::Pop(void) {
nsIParserNode *result=0;
if(0<mCount) {
result=mEntries[--mCount].mTag;
result=mEntries[--mCount].mNode;
((nsCParserNode*)result)->mUseCount--;
((nsCParserNode*)result)->mToken->mUseCount--;
mEntries[mCount].mNode=0;
mEntries[mCount].mStyles=0;
}
return result;
}
@ -131,9 +221,22 @@ eHTMLTags nsEntryStack::First() const {
* @update harishd 04/04/99
* @update gess 04/21/99
*/
eHTMLTags nsEntryStack::TagAt(PRUint32 anIndex) const {
nsIParserNode* nsEntryStack::NodeAt(PRInt32 anIndex) const {
nsIParserNode* result=0;
if((0<mCount) && (anIndex<mCount)) {
result=mEntries[anIndex].mNode;
}
return result;
}
/**
*
* @update harishd 04/04/99
* @update gess 04/21/99
*/
eHTMLTags nsEntryStack::TagAt(PRInt32 anIndex) const {
eHTMLTags result=eHTMLTag_unknown;
if(anIndex<mCount) {
if((0<mCount) && (anIndex<mCount)) {
result=mEntries[anIndex].mTag;
}
return result;
@ -143,12 +246,12 @@ eHTMLTags nsEntryStack::TagAt(PRUint32 anIndex) const {
*
* @update gess 04/21/99
*/
nsTagEntry& nsEntryStack::EntryAt(PRUint32 anIndex) const {
static nsTagEntry gSentinel;
if(anIndex<mCount) {
return mEntries[anIndex];
nsTagEntry* nsEntryStack::EntryAt(PRInt32 anIndex) const {
nsTagEntry *result=0;
if((0<mCount) && (anIndex<mCount)) {
result=&mEntries[anIndex];
}
return gSentinel;
return result;
}
@ -157,9 +260,9 @@ nsTagEntry& nsEntryStack::EntryAt(PRUint32 anIndex) const {
* @update harishd 04/04/99
* @update gess 04/21/99
*/
eHTMLTags nsEntryStack::operator[](PRUint32 anIndex) const {
eHTMLTags nsEntryStack::operator[](PRInt32 anIndex) const {
eHTMLTags result=eHTMLTag_unknown;
if(anIndex<mCount) {
if((0<mCount) && (anIndex<mCount)) {
result=mEntries[anIndex].mTag;
}
return result;
@ -172,9 +275,14 @@ eHTMLTags nsEntryStack::operator[](PRUint32 anIndex) const {
* @update gess 04/21/99
*/
eHTMLTags nsEntryStack::Last() const {
return TagAt(mCount-1);
eHTMLTags result=eHTMLTag_unknown;
if(0<mCount) {
result=mEntries[mCount-1].mTag;
}
return result;
}
#if 0
/**
*
* @update harishd 04/04/99
@ -189,8 +297,7 @@ PRInt32 nsEntryStack::GetTopmostIndexOf(eHTMLTags aTag) const {
return kNotFound;
}
#endif
/***************************************************************
@ -202,12 +309,12 @@ PRInt32 nsEntryStack::GetTopmostIndexOf(eHTMLTags aTag) const {
*
* @update gess9/10/98
*/
nsDTDContext::nsDTDContext() : mStack(), mSkipped(0), mStyles(0) {
nsDTDContext::nsDTDContext() : mStack() {
MOZ_COUNT_CTOR(nsDTDContext);
#ifdef NS_DEBUG
nsCRT::zero(mTags,sizeof(mTags));
memset(mXTags,0,sizeof(mXTags));
#endif
}
@ -217,21 +324,7 @@ nsDTDContext::nsDTDContext() : mStack(), mSkipped(0), mStyles(0) {
* @update gess9/10/98
*/
nsDTDContext::~nsDTDContext() {
MOZ_COUNT_DTOR(nsDTDContext);
PRInt32 theSize=mSkipped.GetSize();
if(theSize>0) {
CTokenDeallocator theDeallocator;
for(PRInt32 i=0;i<theSize;i++) {
nsDeque* theDeque=(nsDeque*)mSkipped.Pop();
if(theDeque) {
if(theDeque->GetSize()>0) theDeque->ForEach(theDeallocator);
delete theDeque;
theDeque=nsnull;
}
}
}
}
/**
@ -239,40 +332,25 @@ nsDTDContext::~nsDTDContext() {
* @update gess7/9/98, harishd 04/04/99
*/
PRInt32 nsDTDContext::GetCount(void) {
return mStack.GetCount();
return mStack.mCount;
}
/**
*
* @update gess7/9/98
*/
PRBool nsDTDContext::HasOpenContainer(eHTMLTags aTag) const {
PRInt32 theIndex=mStack.FindLast(aTag);
return PRBool(-1<theIndex);
}
/**
*
* @update gess7/9/98, harishd 04/04/99
* @update gess7/9/98
*/
void nsDTDContext::Push(eHTMLTags aTag) {
#ifdef NS_DEBUG
if(mStack.mCount < eMaxTags)
mTags[mStack.mCount]=aTag;
#endif
mStack.Push(aTag);
}
/**
* @update gess7/9/98, harishd 04/04/99
*/
eHTMLTags nsDTDContext::Pop() {
#ifdef NS_DEBUG
if ((mStack.mCount>0) && (mStack.mCount <= eMaxTags))
mTags[mStack.mCount-1]=eHTMLTag_unknown;
#endif
nsEntryStack* theStyles=0;
nsTagEntry& theEntry=mStack.EntryAt(mStack.mCount-1);
PRInt32 theIndex=theEntry.mStyleIndex;
if(-1<theIndex){
theStyles=(nsEntryStack*)mStyles.ObjectAt(theIndex);
delete theStyles;
}
eHTMLTags result=mStack.Pop();
PRInt32 nsDTDContext::GetTopmostIndexOf(eHTMLTags aTag) const {
PRInt32 result=mStack.FindLast(aTag);
return result;
}
@ -280,7 +358,53 @@ eHTMLTags nsDTDContext::Pop() {
*
* @update gess7/9/98
*/
eHTMLTags nsDTDContext::First() const {
void nsDTDContext::Push(const nsIParserNode* aNode,PRInt32 aResidualStyleLevel) {
if(aNode) {
#ifdef NS_DEBUG
eHTMLTags theTag=(eHTMLTags)aNode->GetNodeType();
int size=mStack.mCount;
if(size< eMaxTags)
mXTags[size]=theTag;
#endif
mStack.Push((nsIParserNode*)aNode,aResidualStyleLevel);
}
}
/**
* @update gess 11/11/99,
* harishd 04/04/99
*/
nsIParserNode* nsDTDContext::Pop(nsEntryStack *&aStack) {
PRInt32 theSize=mStack.mCount;
nsIParserNode *result=0;
if(0<theSize) {
#ifdef NS_DEBUG
if ((theSize>0) && (theSize <= eMaxTags))
mXTags[theSize-1]=eHTMLTag_unknown;
#endif
nsTagEntry* theEntry=mStack.EntryAt(mStack.mCount-1);
if(theEntry) {
aStack=theEntry->mStyles;
}
result=mStack.Pop();
}
return result;
}
/**
*
* @update gess7/9/98
*/
eHTMLTags nsDTDContext::First(void) const {
return mStack.First();
}
@ -293,14 +417,6 @@ eHTMLTags nsDTDContext::TagAt(PRInt32 anIndex) const {
}
/**
*
* @update gess7/9/98
*/
eHTMLTags nsDTDContext::operator[](PRInt32 anIndex) const {
return mStack[anIndex];
}
/**
*
* @update gess7/9/98
@ -309,132 +425,108 @@ eHTMLTags nsDTDContext::Last() const {
return mStack.Last();
}
/**
*
* @update gess7/9/98
*/
nsEntryStack* nsDTDContext::GetStylesAt(PRUint32 anIndex) const {
nsEntryStack* nsDTDContext::GetStylesAt(PRInt32 anIndex) const {
nsEntryStack* result=0;
if(anIndex<mStack.mCount){
nsTagEntry& theEntry=mStack.EntryAt(anIndex);
PRInt32 theIndex=theEntry.mStyleIndex;
if(-1<theIndex){
result=(nsEntryStack*)mStyles.ObjectAt(theIndex);
nsTagEntry* theEntry=mStack.EntryAt(anIndex);
if(theEntry) {
result=theEntry->mStyles;
}
}
return result;
}
/**
*
* @update gess 04/28/99
*/
void nsDTDContext::PushStyle(eHTMLTags aTag){
void nsDTDContext::PushStyle(const nsIParserNode* aNode){
nsTagEntry& theEntry=mStack.EntryAt(mStack.mCount-1);
//ok, now go get the right tokenbank deque...
nsEntryStack* theStack=0;
if(-1<theEntry.mStyleIndex)
theStack=(nsEntryStack*)mStyles.ObjectAt(theEntry.mStyleIndex);
if(!theStack){
//time to make a databank for this element...
theStack=new nsEntryStack();
if(theStack){
mStyles.Push(theStack);
theEntry.mStyleIndex=mStyles.GetSize()-1;
nsTagEntry* theEntry=mStack.EntryAt(mStack.mCount-1);
if(theEntry ) {
nsEntryStack* theStack=theEntry->mStyles;
if(!theStack) {
theStack=theEntry->mStyles=new nsEntryStack();
}
else{
//XXX Hack! This is very back, we've failed to get memory.
if(theStack) {
theStack->Push(aNode);
theEntry=&theStack->mEntries[theStack->mCount-1];
if(theEntry) {
theEntry->mParent=theStack;
}
}
if(theStack){
theStack->Push(aTag);
}
} //if
}
/**
* Call this when you have an EntryStack full of styles
* that you want to push at this level.
*
* @update gess 04/28/99
*/
void nsDTDContext::PushStyles(nsEntryStack *aStyles){
if(aStyles) {
nsTagEntry* theEntry=mStack.EntryAt(mStack.mCount-1);
if(theEntry ) {
nsEntryStack* theStyles=theEntry->mStyles;
if(!theStyles) {
theEntry->mStyles=aStyles;
}
else theStyles->Append(aStyles);
} //if
}//if
}
/**
*
* @update gess 04/28/99
*/
eHTMLTags nsDTDContext::PopStyle(void){
eHTMLTags result=eHTMLTag_unknown;
nsTagEntry& theEntry=mStack.EntryAt(mStack.mCount-1);
//ok, now go get the right tokenbank deque...
nsEntryStack* theStack=0;
if(-1<theEntry.mStyleIndex)
theStack=(nsEntryStack*)mStyles.ObjectAt(theEntry.mStyleIndex);
if(theStack){
nsIParserNode* nsDTDContext::PopStyle(void){
nsIParserNode* result=0;
nsTagEntry *theEntry=mStack.EntryAt(mStack.mCount-1);
if(theEntry && (theEntry->mNode)) {
if(kNotFound<theEntry->mLevel){
nsEntryStack *theStack=mStack.mEntries[theEntry->mLevel].mStyles;
if(theStack) {
result=theStack->Pop();
}
return result;
}
/**
*
* @update harishd 04/04/99
* @update gess 04/21/99
*/
void nsDTDContext::SaveToken(CToken* aToken, PRInt32 aID)
{
NS_PRECONDITION(aID <= mStack.GetCount() && aID > -1,"Out of bounds");
if(aToken) {
nsTagEntry& theEntry=mStack.EntryAt(aID);
//ok, now go get the right tokenbank deque...
nsDeque* theDeque=0;
if(-1<theEntry.mBankIndex)
theDeque=(nsDeque*)mSkipped.ObjectAt(theEntry.mBankIndex);
if(!theDeque){
//time to make a databank for this element...
theDeque=new nsDeque(0);
if(theDeque){
mSkipped.Push(theDeque);
theEntry.mBankIndex=mSkipped.GetSize()-1;
}
else{
//XXX Hack! This is very back, we've failed to get memory.
}
}
theDeque->Push(aToken);
}
}
/**
*
* @update harishd 04/04/99
* @update gess 04/21/99
*/
CToken* nsDTDContext::RestoreTokenFrom(PRInt32 aID)
{
NS_PRECONDITION(aID <= mStack.GetCount() && aID > -1,"Out of bounds");
CToken* result=0;
if(0<mStack.GetCount()) {
nsTagEntry theEntry=mStack.EntryAt(aID);
nsDeque* theDeque=(nsDeque*)mSkipped.ObjectAt(theEntry.mBankIndex);
if(theDeque){
result=(CToken*)theDeque->PopFront();
}
}
} //if
return result;
}
/**
*
* @update harishd 04/04/99
* @update gess 04/21/99
* @update gess 04/28/99
*/
PRInt32 nsDTDContext::TokenCountAt(PRInt32 aID)
{
NS_PRECONDITION(aID <= mStack.GetCount(),"Out of bounds");
nsIParserNode* nsDTDContext::PopStyle(eHTMLTags aTag){
nsTagEntry theEntry=mStack.EntryAt(aID);
nsDeque* theDeque=(nsDeque*)mSkipped.ObjectAt(theEntry.mBankIndex);
if(theDeque){
return theDeque->GetSize();
PRInt32 theLevel=0;
PRInt32 sindex=0;
for(theLevel=mStack.mCount-1;theLevel>0;theLevel--) {
nsEntryStack *theStack=mStack.mEntries[theLevel].mStyles;
if(theStack) {
if(aTag==theStack->Last()) {
return theStack->Pop();
} else {
// NS_ERROR("bad residual style entry");
}
}
}
return kNotFound;
return 0;
}
/**************************************************************
@ -452,7 +544,7 @@ CTokenRecycler::CTokenRecycler() : nsITokenRecycler(),mEmpty("") {
int i=0;
for(i=0;i<eToken_last-1;i++) {
mTokenCache[i]=new nsDeque(new CTokenDeallocator());
mTokenCache[i]=new nsDeque(0);
#ifdef NS_DEBUG
mTotals[i]=0;
#endif
@ -470,15 +562,17 @@ CTokenRecycler::~CTokenRecycler() {
//begin by deleting all the known (recycled) tokens...
//We're also deleting the cache-deques themselves.
int i;
CTokenDeallocator theDeallocator;
for(i=0;i<eToken_last-1;i++) {
if(0!=mTokenCache[i]) {
mTokenCache[i]->ForEach(theDeallocator);
delete mTokenCache[i];
mTokenCache[i]=0;
}
}
}
class CTokenFinder: public nsDequeFunctor{
public:
CTokenFinder(CToken* aToken) {mToken=aToken;}
@ -500,14 +594,18 @@ public:
void CTokenRecycler::RecycleToken(CToken* aToken) {
if(aToken) {
PRInt32 theType=aToken->GetTokenType();
mTokenCache[theType-1]->Push(aToken);
#if 0
//This should be disabled since it's only debug code.
CTokenFinder finder(aToken);
CToken* theMatch;
theMatch=(CToken*)mTokenCache[theType-1]->FirstThat(finder);
if(theMatch) {
printf("dup token: %p\n",theMatch);
}
#endif
aToken->mUseCount=1;
mTokenCache[theType-1]->Push(aToken);
}
}
@ -793,10 +891,15 @@ void CObserverService::RegisterObservers(nsString& aTopic) {
* @return if SUCCESS return NS_OK else return ERROR code.
*/
nsresult CObserverService::Notify(eHTMLTags aTag,nsIParserNode& aNode,PRUint32 aUniqueID, const char* aCommand,
nsAutoString& aCharsetValue,nsCharsetSource& aCharsetSource) {
nsIParser* aParser) {
nsresult result=NS_OK;
nsDeque* theDeque=GetObserversForTag(aTag);
if(theDeque){
nsAutoString theCharsetValue;
nsCharsetSource theCharsetSource;
aParser->GetDocumentCharset(theCharsetValue,theCharsetSource);
PRInt32 theAttrCount =aNode.GetAttributeCount();
PRUint32 theDequeSize=theDeque->GetSize();
if(0<theDequeSize){
@ -813,12 +916,12 @@ nsresult CObserverService::Notify(eHTMLTags aTag,nsIParserNode& aNode,PRUint32 a
// Add pseudo attribute in the end
if(index < 50) {
theKeys[index]=theCharsetKey.GetUnicode();
theValues[index] = aCharsetValue.GetUnicode();
theValues[index] = theCharsetValue.GetUnicode();
index++;
}
if(index < 50) {
theKeys[index]=theSourceKey.GetUnicode();
PRInt32 sourceInt = aCharsetSource;
PRInt32 sourceInt = theCharsetSource;
intValue.Append(sourceInt,10);
theValues[index] = intValue.GetUnicode();
index++;

Просмотреть файл

@ -61,71 +61,99 @@ void DebugDumpContainmentRules(nsIDTD& theDTD,const char* aFilename,const char*
void DebugDumpContainmentRules2(nsIDTD& theDTD,const char* aFilename,const char* aTitle);
PRUint32 AccumulateCRC(PRUint32 crc_accum, char *data_blk_ptr, int data_blk_size);
/**************************************************************
This is the place to store the "bad-content" tokens, and the
also the regular tags.
**************************************************************/
/***************************************************************
The dtdcontext class defines an ordered list of tags (a context).
***************************************************************/
/***************************************************************
First, define the tagstack class
***************************************************************/
class nsEntryStack; //forware declare to make compilers happy.
struct nsTagEntry {
eHTMLTags mTag;
PRInt8 mBankIndex;
PRInt8 mStyleIndex;
eHTMLTags mTag; //for speedier access to tag id
nsIParserNode* mNode;
PRInt32 mLevel;
nsEntryStack* mParent;
nsEntryStack* mStyles;
};
class nsEntryStack {
public:
nsEntryStack();
~nsEntryStack();
void Push(eHTMLTags aTag);
eHTMLTags Pop();
void EnsureCapacityFor(PRInt32 aNewMax, PRInt32 aShiftOffset=0);
void Push(const nsIParserNode* aNode,PRInt32 aResidualStyleLevel=-1);
void PushFront(const nsIParserNode* aNode,PRInt32 aResidualStyleLevel=-1);
void Append(nsEntryStack *theStack);
nsIParserNode* Pop(void);
nsIParserNode* NodeAt(PRInt32 anIndex) const;
eHTMLTags First() const;
eHTMLTags TagAt(PRUint32 anIndex) const;
nsTagEntry& EntryAt(PRUint32 anIndex) const;
PRInt32 GetTopmostIndexOf(eHTMLTags aTag) const;
eHTMLTags operator[](PRUint32 anIndex) const;
eHTMLTags TagAt(PRInt32 anIndex) const;
nsTagEntry* EntryAt(PRInt32 anIndex) const;
eHTMLTags operator[](PRInt32 anIndex) const;
eHTMLTags Last() const;
void Empty(void);
PRInt32 GetCount(void) const {return mCount;}
inline PRInt32 FindFirst(eHTMLTags aTag) const {
PRInt32 index=-1;
if(0<mCount) {
while(++index<mCount) {
if(aTag==mEntries[index].mTag) {
return index;
}
} //while
}
return kNotFound;
}
inline PRInt32 FindLast(eHTMLTags aTag) const {
PRInt32 index=mCount;
while(--index>=0) {
if(aTag==mEntries[index].mTag) {
return index;
}
}
return kNotFound;
}
nsTagEntry* mEntries;
PRUint32 mCount;
PRUint32 mCapacity;
PRInt32 mCount;
PRInt32 mCapacity;
};
/***************************************************************
The dtdcontext class defines the current tag context (both
structural and stylistic). This small utility class allows us
to push/pop contexts at will, which makes handling styles in
certainly (unfriendly) elements (like tables) much easier.
***************************************************************/
class nsDTDContext {
public:
nsDTDContext();
~nsDTDContext();
void Push(eHTMLTags aTag);
eHTMLTags Pop();
eHTMLTags First() const;
void Push(const nsIParserNode* aNode,PRInt32 aResidualStyleLevel=-1);
nsIParserNode* Pop(nsEntryStack*& aStack);
eHTMLTags First(void) const;
eHTMLTags Last(void) const;
eHTMLTags TagAt(PRInt32 anIndex) const;
eHTMLTags operator[](PRInt32 anIndex) const;
eHTMLTags Last() const;
eHTMLTags operator[](PRInt32 anIndex) const {return TagAt(anIndex);}
PRBool HasOpenContainer(eHTMLTags aTag) const;
PRInt32 GetTopmostIndexOf(eHTMLTags aTag) const;
void Empty(void);
PRInt32 GetCount(void);
nsEntryStack* GetStylesAt(PRUint32 anIndex) const;
void PushStyle(eHTMLTags aTag);
eHTMLTags PopStyle(void);
nsEntryStack* GetStylesAt(PRInt32 anIndex) const;
void PushStyle(const nsIParserNode* aNode);
void PushStyles(nsEntryStack *theStyles);
nsIParserNode* PopStyle(void);
nsIParserNode* PopStyle(eHTMLTags aTag);
void SaveToken(CToken* aToken, PRInt32 aID);
CToken* RestoreTokenFrom(PRInt32 aID);
PRInt32 TokenCountAt(PRInt32 aID);
nsEntryStack mStack; //this will hold a list of tagentries...
nsEntryStack mStack;
nsDeque mSkipped; //each entry will hold a deque full of skipped tokens...
nsDeque mStyles; //each entry will hold a tagstack full of style tags...
#ifdef NS_DEBUG
enum { eMaxTags = 100 };
eHTMLTags mTags[eMaxTags];
eHTMLTags mXTags[eMaxTags];
#endif
};
@ -163,6 +191,7 @@ public:
protected:
nsDeque* mTokenCache[eToken_last-1];
nsString mEmpty;
#ifdef NS_DEBUG
int mTotals[eToken_last-1];
#endif
@ -192,13 +221,18 @@ public:
* @param aTagSet -- set of tags to be searched
* @return
*/
inline PRInt32 IndexOfTagInSet(PRInt32 aTag,const eHTMLTags aTagSet[],PRInt32 aCount) {
PRInt32 theIndex;
inline PRInt32 IndexOfTagInSet(PRInt32 aTag,const eHTMLTags* aTagSet,PRInt32 aCount) {
for(theIndex=0;theIndex<aCount;theIndex++)
if(aTag==aTagSet[theIndex]) {
return theIndex;
const eHTMLTags* theEnd=aTagSet+aCount;
const eHTMLTags* theTag=aTagSet;
while(theTag<theEnd) {
if(aTag==*theTag) {
return theTag-aTagSet;
}
theTag++;
}
return kNotFound;
}
@ -210,7 +244,7 @@ inline PRInt32 IndexOfTagInSet(PRInt32 aTag,const eHTMLTags aTagSet[],PRInt32 aC
* @param aTagSet -- set of tags to be searched
* @return
*/
inline PRBool FindTagInSet(PRInt32 aTag,const eHTMLTags aTagSet[],PRInt32 aCount) {
inline PRBool FindTagInSet(PRInt32 aTag,const eHTMLTags *aTagSet,PRInt32 aCount) {
return PRBool(-1<IndexOfTagInSet(aTag,aTagSet,aCount));
}
@ -220,11 +254,13 @@ inline PRBool FindTagInSet(PRInt32 aTag,const eHTMLTags aTagSet[],PRInt32 aCount
* @param
* @return
*/
inline PRBool BufferContainsHTML(nsString& aBuffer){
inline PRBool BufferContainsHTML(nsString& aBuffer,PRBool& aHasXMLFragment){
PRBool result=PR_FALSE;
nsString temp;
aBuffer.Left(temp,200);
temp.ToLowerCase();
aHasXMLFragment=PRBool(-1<temp.Find("<?xml"));
if((-1<temp.Find("<html ") || (-1<temp.Find("!doctype html public")))) {
result=PR_TRUE;
}
@ -257,7 +293,7 @@ public:
nsDeque* GetObserversForTag(eHTMLTags aTag);
nsresult Notify(eHTMLTags aTag,nsIParserNode& aNode,
PRUint32 aUniqueID, const char* aCommand,
nsAutoString& aCharsetValue,nsCharsetSource& aCharsetSource);
nsIParser* aParser);
protected:
void RegisterObservers(nsString& aTopicList);

Просмотреть файл

@ -36,9 +36,16 @@
* @param
* @return
*/
PRBool Contains(eHTMLTags aTag,TagList& aTagList){
PRBool result=FindTagInSet(aTag,aTagList.mTags,aTagList.mCount);
return result;
PRInt32 GetTopmostIndexOf(nsDTDContext& aContext,TagList& aTagList){
int max = aContext.GetCount();
int index;
for(index=max-1;index>=0;index--){
PRBool result=FindTagInSet(aContext[index],aTagList.mTags,aTagList.mCount);
if(result) {
return index;
}
}
return kNotFound;
}
/**
@ -47,11 +54,12 @@ PRBool Contains(eHTMLTags aTag,TagList& aTagList){
* @param
* @return
*/
PRInt32 GetTopmostIndexOf(nsEntryStack& aTagStack,TagList& aTagList){
int max = aTagStack.GetCount();
int index=0;
for(index=max-1;index>=0;index--){
if(FindTagInSet(aTagStack[index],aTagList.mTags,aTagList.mCount)) {
PRInt32 GetBottommostIndexOf(nsDTDContext& aContext,PRInt32 aStartOffset,TagList& aTagList){
int max = aContext.GetCount();
int index;
for(index=aStartOffset;index<max;index++){
PRBool result=FindTagInSet(aContext[index],aTagList.mTags,aTagList.mCount);
if(result) {
return index;
}
}
@ -91,8 +99,8 @@ TagList gInTR={1,{eHTMLTag_tr}};
TagList gInDL={2,{eHTMLTag_dl,eHTMLTag_body}};
TagList gInFrameset={1,{eHTMLTag_frameset}};
TagList gInNoframes={1,{eHTMLTag_noframes}};
TagList gInP={4,{eHTMLTag_address,eHTMLTag_form,eHTMLTag_span,eHTMLTag_table}};
TagList gOptgroupParents={2,{eHTMLTag_optgroup,eHTMLTag_select}};
TagList gInP={3,{eHTMLTag_address,eHTMLTag_span,eHTMLTag_table}};
TagList gOptgroupParents={2,{eHTMLTag_select,eHTMLTag_optgroup}};
TagList gBodyParents={2,{eHTMLTag_html,eHTMLTag_noframes}};
TagList gColParents={2,{eHTMLTag_table,eHTMLTag_colgroup}};
TagList gFramesetParents={2,{eHTMLTag_html,eHTMLTag_frameset}};
@ -571,7 +579,7 @@ void InitializeElementTable(void) {
/*req-parent excl-parent*/ eHTMLTag_unknown,eHTMLTag_unknown,
/*rootnodes,endrootnodes*/ &gRootTags,&gRootTags,
/*autoclose starttags and endtags*/ 0,0,0,0,
/*parent,incl,exclgroups*/ kSpecial, (kSelf|SPECIALTYPE), kNone,
/*parent,incl,exclgroups*/ kSpecial|kFontStyle, (kSelf|SPECIALTYPE), kNone,
/*special props, prop-range*/ 0,kDefaultPropRange,
/*special parents,kids,skip*/ 0,&gFontKids,eHTMLTag_unknown);
@ -942,7 +950,7 @@ void InitializeElementTable(void) {
/*rootnodes,endrootnodes*/ &gOptgroupParents,&gOptgroupParents,
/*autoclose starttags and endtags*/ 0,0,0,0,
/*parent,incl,exclgroups*/ kNone, kPCDATA, kFlowEntity,
/*special props, prop-range*/ kNoPropagate|kNoStyleLeaksIn, kDefaultPropRange,
/*special props, prop-range*/ kNoStyleLeaksIn, kDefaultPropRange,
/*special parents,kids,skip*/ &gOptgroupParents,&gContainsText,eHTMLTag_unknown);
Initialize(
@ -1309,7 +1317,7 @@ void InitializeElementTable(void) {
/*rootnodes,endrootnodes*/ &gRootTags,&gRootTags,
/*autoclose starttags and endtags*/ 0,0,0,0,
/*parent,incl,exclgroups*/ kFlowEntity, kNone, kNone,
/*special props, prop-range*/ kOmitEndTag,kNoPropRange,
/*special props, prop-range*/ kOmitEndTag|kLegalOpen,kNoPropRange,
/*special parents,kids,skip*/ 0,0,eHTMLTag_unknown);
Initialize(
@ -1341,15 +1349,16 @@ void InitializeElementTable(void) {
}//if
};
int nsHTMLElement::GetSynonymousGroups(int aGroup) {
int nsHTMLElement::GetSynonymousGroups(eHTMLTags aTag) {
int result=0;
switch(aGroup) {
int theGroup=gHTMLElements[aTag].mParentBits;
switch(theGroup) {
case kPhrase:
case kSpecial:
case kFontStyle:
result=aGroup;
result=theGroup;
break;
case kHTMLContent:
@ -1373,6 +1382,32 @@ int nsHTMLElement::GetSynonymousGroups(int aGroup) {
break;
}
if(eHTMLTag_font==aTag) //hack for backward compatibility
result+=kFontStyle;
return result;
}
/**
*
* @update gess 01/04/99
* @param
* @return
*/
inline PRBool TestBits(int aBitset,int aTest) {
PRInt32 result=aBitset & aTest;
return (aTest) ? PRBool(result==aTest) : PR_FALSE; //was aTest
}
/**
*
* @update gess1/21/99
* @param
* @return
*/
PRBool nsHTMLElement::HasSpecialProperty(PRInt32 aProperty) const{
PRBool result=TestBits(mSpecialProperties,aProperty);
return result;
}
@ -1386,24 +1421,11 @@ PRBool nsHTMLElement::IsContainer(eHTMLTags aChild) {
PRBool result=(eHTMLTag_unknown==aChild);
if(!result){
result=!gHTMLElements[aChild].HasSpecialProperty(kNonContainer);
result=!TestBits(gHTMLElements[aChild].mSpecialProperties,kNonContainer);
}
return result;
}
/**
*
* @update gess 01/04/99
* @param
* @return
*/
inline PRBool TestBits(int aBitset,int aTest) {
PRInt32 result=aBitset & aTest;
return (aTest) ? PRBool(result==aTest) : PR_FALSE; //was aTest
}
/**
*
* @update gess 01/04/99
@ -1564,7 +1586,7 @@ PRBool nsHTMLElement::CanExclude(eHTMLTags aChild) const{
//Note that special kids takes precedence over exclusions...
if(mSpecialKids) {
if(Contains(aChild,*mSpecialKids)) {
if(FindTagInSet(aChild,mSpecialKids->mTags,mSpecialKids->mCount)) {
return PR_FALSE;
}
}
@ -1608,7 +1630,7 @@ PRBool nsHTMLElement::CanOmitStartTag(eHTMLTags aChild) const{
* @return
*/
PRBool nsHTMLElement::IsChildOfHead(eHTMLTags aChild) {
PRBool result=Contains(aChild,gHeadKids);
PRBool result=FindTagInSet(aChild,gHeadKids.mTags,gHeadKids.mCount);
return result;
}
@ -1622,8 +1644,9 @@ PRBool nsHTMLElement::IsChildOfHead(eHTMLTags aChild) {
PRBool nsHTMLElement::SectionContains(eHTMLTags aChild,PRBool allowDepthSearch) {
PRBool result=PR_FALSE;
TagList* theRootTags=gHTMLElements[aChild].GetRootTags();
if(theRootTags){
if(!Contains(mTagID,*theRootTags)){
if(!FindTagInSet(mTagID,theRootTags->mTags,theRootTags->mCount)){
eHTMLTags theRootBase=GetTagAt(0,*theRootTags);
if((eHTMLTag_unknown!=theRootBase) && (allowDepthSearch))
result=SectionContains(theRootBase,allowDepthSearch);
@ -1640,21 +1663,40 @@ PRBool nsHTMLElement::SectionContains(eHTMLTags aChild,PRBool allowDepthSearch)
* @return
*/
PRBool nsHTMLElement::IsStyleTag(eHTMLTags aChild) {
static eHTMLTags gStyleTags[]={
eHTMLTag_a, eHTMLTag_acronym, eHTMLTag_b,
eHTMLTag_bdo, eHTMLTag_big, eHTMLTag_blink,
eHTMLTag_center, eHTMLTag_cite, eHTMLTag_code,
eHTMLTag_del, eHTMLTag_dfn, eHTMLTag_em,
eHTMLTag_font, eHTMLTag_i, eHTMLTag_ins,
eHTMLTag_kbd, eHTMLTag_q,
eHTMLTag_s, eHTMLTag_samp, eHTMLTag_small,
eHTMLTag_span, eHTMLTag_strike, eHTMLTag_strong,
eHTMLTag_sub, eHTMLTag_sup, eHTMLTag_tt,
eHTMLTag_u, eHTMLTag_var
PRBool result=PR_FALSE;
switch(aChild) {
case eHTMLTag_a:
case eHTMLTag_acronym:
case eHTMLTag_b:
case eHTMLTag_bdo:
case eHTMLTag_big:
case eHTMLTag_blink:
case eHTMLTag_center:
case eHTMLTag_cite:
case eHTMLTag_code:
case eHTMLTag_del:
case eHTMLTag_dfn:
case eHTMLTag_em:
case eHTMLTag_font:
case eHTMLTag_i:
case eHTMLTag_ins:
case eHTMLTag_kbd:
case eHTMLTag_q:
case eHTMLTag_s:
case eHTMLTag_samp:
case eHTMLTag_small:
case eHTMLTag_span:
case eHTMLTag_strike:
case eHTMLTag_strong:
case eHTMLTag_sub:
case eHTMLTag_sup:
case eHTMLTag_tt:
case eHTMLTag_u:
case eHTMLTag_var:
result=PR_TRUE;
default:
break;
};
PRBool result=FindTagInSet(aChild,gStyleTags,sizeof(gStyleTags)/sizeof(eHTMLTag_body));
return result;
}
@ -1665,7 +1707,7 @@ PRBool nsHTMLElement::IsStyleTag(eHTMLTags aChild) {
* @return
*/
PRBool nsHTMLElement::IsHeadingTag(eHTMLTags aChild) {
return Contains(aChild,gHeadingTags);
return FindTagInSet(aChild,gHeadingTags.mTags,gHeadingTags.mCount);
}
@ -1699,8 +1741,16 @@ PRBool nsHTMLElement::IsMemberOf(PRInt32 aSet) const{
* @return
*/
PRBool nsHTMLElement::IsWhitespaceTag(eHTMLTags aChild) {
static eHTMLTags gWSTags[]={eHTMLTag_newline, eHTMLTag_whitespace};
PRBool result=FindTagInSet(aChild,gWSTags,sizeof(gWSTags)/sizeof(eHTMLTag_body));
PRBool result=PR_FALSE;
switch(aChild) {
case eHTMLTag_newline:
case eHTMLTag_whitespace:
result=PR_TRUE;
break;
default:
break;
}
return result;
}
@ -1711,8 +1761,18 @@ PRBool nsHTMLElement::IsWhitespaceTag(eHTMLTags aChild) {
* @return
*/
PRBool nsHTMLElement::IsTextTag(eHTMLTags aChild) {
static eHTMLTags gTextTags[]={eHTMLTag_text,eHTMLTag_entity,eHTMLTag_newline, eHTMLTag_whitespace};
PRBool result=FindTagInSet(aChild,gTextTags,sizeof(gTextTags)/sizeof(eHTMLTag_body));
PRBool result=PR_FALSE;
switch(aChild) {
case eHTMLTag_text:
case eHTMLTag_entity:
case eHTMLTag_newline:
case eHTMLTag_whitespace:
result=PR_TRUE;
break;
default:
break;
}
return result;
}
@ -1738,7 +1798,7 @@ PRBool nsHTMLElement::CanAutoCloseTag(eHTMLTags aTag) const{
if((mTagID>=eHTMLTag_unknown) & (mTagID<=eHTMLTag_userdefined)) {
TagList* theTagList=gHTMLElements[mTagID].GetNonAutoCloseEndTags();
if(theTagList) {
result=!Contains(aTag,*theTagList);
result=!FindTagInSet(aTag,theTagList->mTags,theTagList->mCount);
}
}
return result;
@ -1750,14 +1810,14 @@ PRBool nsHTMLElement::CanAutoCloseTag(eHTMLTags aTag) const{
* @param
* @return
*/
eHTMLTags nsHTMLElement::GetCloseTargetForEndTag(nsEntryStack& aTagStack,PRInt32 anIndex) const{
eHTMLTags nsHTMLElement::GetCloseTargetForEndTag(nsDTDContext& aContext,PRInt32 anIndex) const{
eHTMLTags result=eHTMLTag_unknown;
int theCount=aTagStack.GetCount();
int theCount=aContext.GetCount();
int theIndex=theCount;
if(IsMemberOf(kPhrase)){
while((--theIndex>=anIndex) && (eHTMLTag_unknown==result)){
eHTMLTags theTag=aTagStack.TagAt(theIndex);
eHTMLTags theTag=aContext.TagAt(theIndex);
if(theTag!=mTagID) {
//phrasal elements can close other phrasals, along with fontstyle and special tags...
if(!gHTMLElements[theTag].IsMemberOf(kSpecial|kFontStyle|kPhrase)) {
@ -1772,7 +1832,7 @@ eHTMLTags nsHTMLElement::GetCloseTargetForEndTag(nsEntryStack& aTagStack,PRInt32
}
else if(IsMemberOf(kSpecial)){
while((--theIndex>=anIndex) && (eHTMLTag_unknown==result)){
eHTMLTags theTag=aTagStack.TagAt(theIndex);
eHTMLTags theTag=aContext.TagAt(theIndex);
if(theTag!=mTagID) {
//phrasal elements can close other phrasals, along with fontstyle and special tags...
if(gHTMLElements[theTag].IsMemberOf(kSpecial) ||
@ -1790,7 +1850,7 @@ eHTMLTags nsHTMLElement::GetCloseTargetForEndTag(nsEntryStack& aTagStack,PRInt32
}
else if(IsMemberOf(kFormControl|kExtensions)){
while((--theIndex>=anIndex) && (eHTMLTag_unknown==result)){
eHTMLTags theTag=aTagStack.TagAt(theIndex);
eHTMLTags theTag=aContext.TagAt(theIndex);
if(theTag!=mTagID) {
if(!CanContain(theTag)) {
break; //it's not something I can close
@ -1802,9 +1862,9 @@ eHTMLTags nsHTMLElement::GetCloseTargetForEndTag(nsEntryStack& aTagStack,PRInt32
}
}
}
else if(IsMemberOf(kFontStyle)){
eHTMLTags theTag=aTagStack.Last();
if(gHTMLElements[theTag].IsMemberOf(kFontStyle)) {
else if(IsStyleTag(mTagID)){
eHTMLTags theTag=aContext.Last();
if(IsStyleTag(theTag)) {
result=theTag;
}
}
@ -1833,7 +1893,7 @@ PRBool nsHTMLElement::CanContain(eHTMLTags aChild) const{
TagList* theCloseTags=gHTMLElements[aChild].GetAutoCloseStartTags();
if(theCloseTags){
if(Contains(mTagID,*theCloseTags))
if(FindTagInSet(mTagID,theCloseTags->mTags,theCloseTags->mCount))
return PR_FALSE;
}
@ -1867,7 +1927,7 @@ PRBool nsHTMLElement::CanContain(eHTMLTags aChild) const{
}
if(mSpecialKids) {
if(Contains(aChild,*mSpecialKids)) {
if(FindTagInSet(aChild,mSpecialKids->mTags,mSpecialKids->mCount)) {
return PR_TRUE;
}
}
@ -1878,17 +1938,6 @@ PRBool nsHTMLElement::CanContain(eHTMLTags aChild) const{
}
/**
*
* @update gess1/21/99
* @param
* @return
*/
PRBool nsHTMLElement::HasSpecialProperty(PRInt32 aProperty) const{
PRBool result=TestBits(mSpecialProperties,aProperty);
return result;
}
void nsHTMLElement::DebugDumpContainment(const char* aFilename,const char* aTitle){
#ifdef RICKG_DEBUG

Просмотреть файл

@ -40,8 +40,7 @@ struct TagList {
eHTMLTags mTags[10];
};
extern PRBool Contains(eHTMLTags aTag,TagList& aTagList);
extern PRInt32 GetTopmostIndexOf(nsEntryStack& aTagStack,TagList& aTagList);
extern PRInt32 GetTopmostIndexOf(nsDTDContext& aContext,TagList& aTagList);
extern eHTMLTags GetTagAt(PRUint32 anIndex,TagList& aTagList);
//*********************************************************************************************
@ -67,7 +66,7 @@ struct nsHTMLElement {
static PRBool IsInlineEntity(eHTMLTags aTag);
static PRBool IsFlowEntity(eHTMLTags aTag);
static PRBool IsBlockCloser(eHTMLTags aTag);
static int GetSynonymousGroups(int aGroup);
static int GetSynonymousGroups(eHTMLTags aTag);
TagList* GetSynonymousTags(void) const {return mSynonymousTags;}
TagList* GetRootTags(void) const {return mRootNodes;}
@ -75,7 +74,7 @@ struct nsHTMLElement {
TagList* GetAutoCloseStartTags(void) const {return mAutocloseStart;}
TagList* GetAutoCloseEndTags(void) const {return mAutocloseEnd;}
TagList* GetNonAutoCloseEndTags(void) const {return mDontAutocloseEnd;}
eHTMLTags GetCloseTargetForEndTag(nsEntryStack& aTagStack,PRInt32 anIndex) const;
eHTMLTags GetCloseTargetForEndTag(nsDTDContext& aContext,PRInt32 anIndex) const;
TagList* GetSpecialChildren(void) const {return mSpecialKids;}
TagList* GetSpecialParents(void) const {return mSpecialParents;}

Просмотреть файл

@ -200,7 +200,9 @@ eAutoDetectResult nsExpatDTD::CanParse(nsString& aContentType, nsString& aComman
* @param
* @return
*/
NS_IMETHODIMP nsExpatDTD::WillBuildModel(nsString& aFilename,PRBool aNotifySink,nsString& aSourceType,eParseMode aParseMode,nsIContentSink* aSink){
NS_IMETHODIMP nsExpatDTD::WillBuildModel(nsString& aFilename,PRBool aNotifySink,
nsString& aSourceType,eParseMode aParseMode,
nsString& aString,nsIContentSink* aSink){
nsresult result=NS_OK;
mFilename=aFilename;

Просмотреть файл

@ -110,6 +110,7 @@ class nsExpatDTD : public nsIDTD {
PRBool aNotifySink,
nsString& aSourceType,
eParseMode aParseMode,
nsString& aString,
nsIContentSink* aSink=0);
/**

Просмотреть файл

@ -29,6 +29,7 @@
* model.
*/
#include "nsHTMLToTXTSinkStream.h"
#include "nsHTMLTokens.h"
#include "nsString.h"
@ -44,16 +45,15 @@
#include "nsIOutputStream.h"
#include "nsFileStream.h"
static NS_DEFINE_CID(kCharsetConverterManagerCID, NS_ICHARSETCONVERTERMANAGER_CID);
const PRInt32 gTabSize=4;
const PRInt32 gOLNumberWidth = 3;
const PRInt32 gIndentSizeList = MaxInt(gTabSize, gOLNumberWidth + 3);
// Indention of non-first lines of ul and ol
const PRInt32 gTabSize=2;
static PRBool IsInline(eHTMLTags aTag);
static PRBool IsBlockLevel(eHTMLTags aTag);
/**
* Inits the encoder instance variable for the sink based on the charset
*
@ -72,6 +72,7 @@ nsresult nsHTMLToTXTSinkStream::InitEncoder(const nsString& aCharset)
return res;
}
nsICharsetAlias* calias = nsnull;
res = nsServiceManager::GetService(kCharsetAliasCID,
kICharsetAliasIID,
@ -109,6 +110,7 @@ nsresult nsHTMLToTXTSinkStream::InitEncoder(const nsString& aCharset)
return res;
}
/**
* This method gets called as part of our COM-like interfaces.
* Its purpose is to create an interface to parser object
@ -145,9 +147,11 @@ nsHTMLToTXTSinkStream::QueryInterface(const nsIID& aIID, void** aInstancePtr)
return NS_OK;
}
NS_IMPL_ADDREF(nsHTMLToTXTSinkStream)
NS_IMPL_RELEASE(nsHTMLToTXTSinkStream)
// Someday may want to make this non-const:
static const PRUint32 TagStackSize = 500;
static const PRUint32 OLStackSize = 100;
@ -187,6 +191,7 @@ nsHTMLToTXTSinkStream::nsHTMLToTXTSinkStream()
mOLStackIndex = 0;
}
/**
*
* @update gpk02/03/99
@ -228,6 +233,7 @@ nsHTMLToTXTSinkStream::Initialize(nsIOutputStream* aOutStream,
* @param
* @return
*/
NS_IMETHODIMP
nsHTMLToTXTSinkStream::SetCharsetOverride(const nsString* aCharset)
{
@ -239,6 +245,8 @@ nsHTMLToTXTSinkStream::SetCharsetOverride(const nsString* aCharset)
return NS_OK;
}
/**
* This method gets called by the parser when it encounters
* a title tag and wants to set the document title in the sink.
@ -248,8 +256,7 @@ nsHTMLToTXTSinkStream::SetCharsetOverride(const nsString* aCharset)
* @return PR_TRUE if successful.
*/
NS_IMETHODIMP
nsHTMLToTXTSinkStream::SetTitle(const nsString& aValue)
{
nsHTMLToTXTSinkStream::SetTitle(const nsString& aValue){
return NS_OK;
}
@ -272,6 +279,7 @@ NS_IMETHODIMP \
nsHTMLToTXTSinkStream::closetag(const nsIParserNode& aNode) \
{ return CloseContainer(aNode); }
USE_GENERAL_OPEN_METHOD(OpenHTML)
USE_GENERAL_CLOSE_METHOD(CloseHTML)
USE_GENERAL_OPEN_METHOD(OpenHead)
@ -336,6 +344,7 @@ nsHTMLToTXTSinkStream::AddProcessingInstruction(const nsIParserNode& aNode){
* This gets called by the parser when it encounters
* a DOCTYPE declaration in the HTML document.
*/
NS_IMETHODIMP
nsHTMLToTXTSinkStream::AddDocTypeDecl(const nsIParserNode& aNode, PRInt32 aMode)
{
@ -396,15 +405,6 @@ PRBool nsHTMLToTXTSinkStream::DoOutput()
return mDoFragment || inBody;
}
nsAutoString
Spaces(PRInt32 count)
{
nsAutoString result;
while (result.Length() < count)
result += ' ';
return result;
}
/**
* This method is used to a general container.
* This includes: OL,UL,DIR,SPAN,TABLE,H[1..6],etc.
@ -416,6 +416,7 @@ Spaces(PRInt32 count)
NS_IMETHODIMP
nsHTMLToTXTSinkStream::OpenContainer(const nsIParserNode& aNode)
{
eHTMLTags type = (eHTMLTags)aNode.GetNodeType();
#ifdef DEBUG_bratell
printf("OpenContainer: %d ", type);
@ -439,6 +440,7 @@ nsHTMLToTXTSinkStream::OpenContainer(const nsIParserNode& aNode)
if (type == eHTMLTag_body)
{
// body -> can turn on cacheing unless it's already preformatted
if(!(mFlags & nsIDocumentEncoder::OutputPreformatted) &&
((mFlags & nsIDocumentEncoder::OutputFormatted) ||
@ -446,6 +448,7 @@ nsHTMLToTXTSinkStream::OpenContainer(const nsIParserNode& aNode)
mCacheLine = PR_TRUE;
}
// Try to figure out here whether we have a
// preformatted style attribute.
//
@ -492,53 +495,29 @@ nsHTMLToTXTSinkStream::OpenContainer(const nsIParserNode& aNode)
if (!DoOutput())
return NS_OK;
if (type == eHTMLTag_p)
EnsureVerticalSpace(1); // Should this be 0 in unformatted case?
// Else make sure we'll separate block level tags,
// even if we're about to leave before doing any other formatting.
// Oddly, I can't find a case where this actually makes any difference.
//else if (IsBlockLevel(type))
// EnsureVerticalSpace(0);
// The rest of this routine is formatted output stuff,
// which we should skip if we're not formatted:
if (!(mFlags & nsIDocumentEncoder::OutputFormatted))
return NS_OK;
if (type == eHTMLTag_ul)
{
// Indent here to support nested list, which aren't included in li :-(
mIndent += gIndentSizeList;
EnsureVerticalSpace(1);
}
else if (type == eHTMLTag_ol)
if (type == eHTMLTag_ol)
{
if (mOLStackIndex < OLStackSize)
mOLStack[mOLStackIndex++] = 1; // XXX should get it from the node!
mIndent += gIndentSizeList; // see ul
EnsureVerticalSpace(1);
}
else if (type == eHTMLTag_li)
if (type == eHTMLTag_li)
{
nsAutoString temp = Spaces(gIndentSizeList - gOLNumberWidth - 2);
nsAutoString temp("*");
if (mTagStackIndex > 1 && mTagStack[mTagStackIndex-2] == eHTMLTag_ol)
{
nsAutoString number;
if (mOLStackIndex > 0)
{
// This is what nsBulletFrame does for OLs:
number.Append(mOLStack[mOLStackIndex-1]++, 10);
else
number += "#";
temp += Spaces(gOLNumberWidth - number.Length()) + number + '.';
char cbuf[40];
PR_snprintf(cbuf, sizeof(cbuf), "%ld.", (mOLStack[mOLStackIndex-1])++);
temp = cbuf;
}
else
temp += Spaces(gOLNumberWidth) + "*";
temp += ' ';
mIndent -= gIndentSizeList; // don't indent first line so much
Write(temp); //CHANGE: does not work as intended. waiting for bug #17883
mIndent += gIndentSizeList;
temp = "#";
}
Write(temp);
// mColPos++; This is done in Write(temp) above
}
else if (type == eHTMLTag_blockquote)
{
@ -560,50 +539,26 @@ nsHTMLToTXTSinkStream::OpenContainer(const nsIParserNode& aNode)
{
EnsureVerticalSpace(0);
}
else if (type == eHTMLTag_a)
// Finally, the list of tags before which we want some vertical space:
switch (type)
{
nsAutoString url;
if (NS_SUCCEEDED(GetValueOfAttribute(aNode, "href", url)))
mURL = url;
else
mURL.Truncate();
}
else if (type == eHTMLTag_img)
case eHTMLTag_table:
case eHTMLTag_ul:
case eHTMLTag_ol:
case eHTMLTag_p:
{
nsAutoString url;
if (NS_SUCCEEDED(GetValueOfAttribute(aNode, "src", url)))
{
nsAutoString temp, desc;
if (NS_SUCCEEDED(GetValueOfAttribute(aNode, "alt", desc)))
{
temp += " (";
temp += desc;
temp += " <URL:";
temp += url;
temp += ">) ";
EnsureVerticalSpace((mFlags & nsIDocumentEncoder::OutputFormatted) ? 1 : 0);
break;
}
else
{
temp += " <URL:";
temp += url;
temp += "> ";
default:
break;
}
Write(temp);
}
}
else if (type == eHTMLTag_sup)
Write("^");
//don't know a plain text representation of sub
else if (type == eHTMLTag_strong || type == eHTMLTag_b)
Write("*");
else if (type == eHTMLTag_em || type == eHTMLTag_i)
Write("/");
else if (type == eHTMLTag_u)
Write("_");
return NS_OK;
}
/**
* This method is used to close a generic container.
*
@ -621,47 +576,10 @@ nsHTMLToTXTSinkStream::CloseContainer(const nsIParserNode& aNode)
if (mTagStackIndex > 0)
--mTagStackIndex;
// End current line if we're ending a block level tag
if (IsBlockLevel(type)) {
if((type == eHTMLTag_body) || (type == eHTMLTag_html)) {
// We want the output to end with a new line,
// but in preformatted areas like text fields,
// we can't emit newlines that weren't there.
if (mPreFormatted || (mFlags & nsIDocumentEncoder::OutputPreformatted))
FlushLine();
else
EnsureVerticalSpace(0);
} else if ((type == eHTMLTag_tr) ||
(type == eHTMLTag_li) ||
(type == eHTMLTag_blockquote)) {
EnsureVerticalSpace(0);
} else {
// All other blocks get 1 vertical space after them
// in formatted mode, otherwise 0.
// This is hard. Sometimes 0 is a better number, but
// how to know?
EnsureVerticalSpace((mFlags & nsIDocumentEncoder::OutputFormatted) ? 1 : 0);
}
}
// The rest of this routine is formatted output stuff,
// which we should skip if we're not formatted:
if (!(mFlags & nsIDocumentEncoder::OutputFormatted))
return NS_OK;
if (type == eHTMLTag_ul)
{
mIndent -= gIndentSizeList;
}
else if (type == eHTMLTag_ol)
{
FlushLine(); // Doing this after decreasing OLStackIndex would be wrong.
if (type == eHTMLTag_ol)
--mOLStackIndex;
mIndent -= gIndentSizeList;
}
else if (type == eHTMLTag_blockquote)
{
FlushLine();
if (mCiteQuoteLevel>0)
mCiteQuoteLevel--;
else if(mIndent >= gTabSize)
@ -686,29 +604,33 @@ nsHTMLToTXTSinkStream::CloseContainer(const nsIParserNode& aNode)
mInWhitespace = PR_TRUE;
}
}
else if (type == eHTMLTag_a)
{ // these brackets must stay here
if (!mURL.IsEmpty())
{
nsAutoString temp(" <URL:");
temp += mURL;
temp += ">";
Write(temp);
// End current line if we're ending a block level tag
if(IsBlockLevel(type)) {
if((type == eHTMLTag_body) || (type == eHTMLTag_html)) {
// We want the output to end with a new line,
// but in preformatted areas like text fields,
// we can't emit newlines that weren't there.
if (mPreFormatted || (mFlags & nsIDocumentEncoder::OutputPreformatted))
FlushLine();
else
EnsureVerticalSpace(0);
} else if((type == eHTMLTag_tr) ||
(type == eHTMLTag_blockquote)) {
EnsureVerticalSpace(0);
} else {
// All other blocks get 1 vertical space after them
// in formatted mode, otherwise 0.
// This is hard. Sometimes 0 is a better number, but
// how to know?
EnsureVerticalSpace((mFlags & nsIDocumentEncoder::OutputFormatted) ? 1 : 0);
}
}
else if (type == eHTMLTag_sup)
Write(" ");
else if (type == eHTMLTag_strong || type == eHTMLTag_b)
Write("*");
else if (type == eHTMLTag_em || type == eHTMLTag_i)
Write("/");
else if (type == eHTMLTag_u)
Write("_");
return NS_OK;
}
/**
* This method is used to add a leaf to the currently
* open container.
@ -766,9 +688,16 @@ nsHTMLToTXTSinkStream::AddLeaf(const nsIParserNode& aNode)
&& (mTagStack[mTagStackIndex-1] == eHTMLTag_pre)) ||
(mPreFormatted && !mWrapColumn))
{
Write(text); // XXX: spacestuffing (maybe call AddToLine if mCacheLine==true)
text = aNode.GetText();
WriteSimple(text);
mColPos += text.Length();
mEmptyLines = -1;
} else if(!mInWhitespace) {
Write(" ");
if(mCacheLine) {
AddToLine(" ");
} else {
WriteSimple(" ");
}
mInWhitespace = PR_TRUE;
}
}
@ -783,16 +712,6 @@ nsHTMLToTXTSinkStream::AddLeaf(const nsIParserNode& aNode)
EnsureVerticalSpace(mEmptyLines+1);
}
}
else if (type == eHTMLTag_hr &&
(mFlags & nsIDocumentEncoder::OutputFormatted))
{
// Make a line of dashes as wide as the wrap width
nsAutoString line;
int width = (mWrapColumn > 0 ? mWrapColumn : 25);
while (line.Length() < width)
line += '-';
Write(line);
}
return NS_OK;
}
@ -811,6 +730,8 @@ void nsHTMLToTXTSinkStream::EnsureBufferSize(PRInt32 aNewSize)
}
}
void nsHTMLToTXTSinkStream::EncodeToBuffer(const nsString& aSrc)
{
if (mUnicodeEncoder == nsnull)
@ -821,6 +742,8 @@ void nsHTMLToTXTSinkStream::EncodeToBuffer(const nsString& aSrc)
return;
}
#define CH_NBSP 160
PRInt32 length = aSrc.Length();
nsresult result;
@ -836,16 +759,17 @@ void nsHTMLToTXTSinkStream::EncodeToBuffer(const nsString& aSrc)
if (NS_SUCCEEDED(result))
result = mUnicodeEncoder->Finish(mBuffer,&temp);
// XXX UGH! This is awful and needs to be removed.
#define CH_NBSP 160
for (PRInt32 i = 0; i < mBufferLength; i++)
{
if (mBuffer[i] == char(CH_NBSP))
mBuffer[i] = ' ';
}
}
}
void
nsHTMLToTXTSinkStream::EnsureVerticalSpace(PRInt32 noOfRows)
{
@ -853,23 +777,19 @@ nsHTMLToTXTSinkStream::EnsureVerticalSpace(PRInt32 noOfRows)
EndLine(PR_FALSE);
}
// This empties the current line cache without adding a NEWLINE.
// Should not be used if line wrapping is of importance since
// this function destroys the cache information.
void
nsHTMLToTXTSinkStream::FlushLine()
{
if(mCurrentLine.Length()>0) {
if(0 == mColPos)
WriteQuotesAndIndent();
WriteSimple(mCurrentLine);
mColPos += mCurrentLine.Length();
mCurrentLine.SetString("");
}
}
/**
* WriteSimple places the contents of aString into either the output stream
* or the output string.
@ -973,19 +893,7 @@ nsHTMLToTXTSinkStream::AddToLine(const nsString &linefragment)
mCurrentLine.Right(restOfLine, linelength-goodSpace-1);
mCurrentLine.Cut(goodSpace, linelength-goodSpace);
EndLine(PR_TRUE);
mCurrentLine.SetString("");
// Space stuff new line?
if(mFlags & nsIDocumentEncoder::OutputFormatFlowed) {
if((restOfLine[0] == '>') ||
(restOfLine[0] == ' ') ||
(!restOfLine.Compare("From ",PR_FALSE,5))) {
// Space stuffing a la RFC 2646 if this will be used in a mail,
// but how can I know that??? Now space stuffing is done always
// when formatting text as HTML and that is wrong! XXX: Fix this!
mCurrentLine.Append(' ');
}
}
mCurrentLine.Append(restOfLine);
mCurrentLine.SetString(restOfLine);
linelength = mCurrentLine.Length();
mEmptyLines = -1;
} else {
@ -1008,9 +916,8 @@ nsHTMLToTXTSinkStream::EndLine(PRBool softlinebreak)
return;
}
WriteQuotesAndIndent();
// Remove SPACE from the end of the line.
while(' ' == mCurrentLine[mCurrentLine.Length()-1])
mCurrentLine.SetLength(mCurrentLine.Length()-1);
// Remove whitespace from the end of the line.
mCurrentLine.CompressWhitespace(PR_FALSE,PR_TRUE);
if(mFlags & nsIDocumentEncoder::OutputFormatFlowed) {
// Add the soft part of the soft linebreak (RFC 2646 4.1)
mCurrentLine.Append(' ');
@ -1029,9 +936,7 @@ nsHTMLToTXTSinkStream::EndLine(PRBool softlinebreak)
if(mCurrentLine.Length()>0)
mEmptyLines=-1;
// Output current line
// Remove SPACE from the end of the line.
while(' ' == mCurrentLine[mCurrentLine.Length()-1])
mCurrentLine.SetLength(mCurrentLine.Length()-1);
mCurrentLine.CompressWhitespace(PR_FALSE,PR_TRUE);
mCurrentLine.Append(NS_LINEBREAK);
WriteSimple(mCurrentLine);
mCurrentLine.SetString("");
@ -1071,6 +976,7 @@ nsHTMLToTXTSinkStream::WriteQuotesAndIndent()
}
}
#ifdef DEBUG_akkana_not
#define DEBUG_wrapping 1
#endif
@ -1089,6 +995,8 @@ nsHTMLToTXTSinkStream::Write(const nsString& aString)
nsAllocator::Free(foo);
#endif
PRInt32 bol = 0;
PRInt32 newline;
@ -1097,8 +1005,10 @@ nsHTMLToTXTSinkStream::Write(const nsString& aString)
// Don't wrap mail-quoted text
// Yes do! /Daniel Bratell
// PRUint32 wrapcol = (mCiteQuote ? 0 : mWrapColumn);
// PRInt32 prefixwidth = (mCiteQuoteLevel>0?mCiteQuoteLevel+1:0)+mIndent;
// PRInt32 linewidth = mWrapColumn-prefixwidth;
// if ((!(mFlags & nsIDocumentEncoder::OutputFormatted)
// && !(mFlags & nsIDocumentEncoder::OutputWrap)) ||
// ((mTagStackIndex > 0) &&
@ -1111,8 +1021,7 @@ nsHTMLToTXTSinkStream::Write(const nsString& aString)
// intelligent wrapping without clearing the mCurrentLine
// buffer before!!!
NS_ASSERTION(mCurrentLine.Length() == 0,
"Mixed wrapping data and nonwrapping data on the same line");
NS_ASSERTION(mCurrentLine.Length() == 0, "Mixed wrapping data and nonwrapping data on the same line");
// Put the mail quote "> " chars in, if appropriate.
// Have to put it in before every line.
@ -1172,9 +1081,10 @@ nsHTMLToTXTSinkStream::Write(const nsString& aString)
return;
}
// Intelligent handling of text
// If needed, strip out all "end of lines"
// and multiple whitespace between words
// Strip out all "end of lines" and multiple whitespace between words
PRInt32 nextpos;
nsAutoString tempstr;
@ -1200,8 +1110,7 @@ nsHTMLToTXTSinkStream::Write(const nsString& aString)
bol=totLen;
mInWhitespace=PR_FALSE;
} else {
if(mInWhitespace && (nextpos == bol) &&
!(mFlags & nsIDocumentEncoder::OutputPreformatted)) {
if(mInWhitespace && (nextpos == bol)) {
// Skip whitespace
bol++;
continue;
@ -1210,30 +1119,24 @@ nsHTMLToTXTSinkStream::Write(const nsString& aString)
if(nextpos == bol) {
// Note that we are in whitespace.
mInWhitespace = PR_TRUE;
nsAutoString whitestring=aString[nextpos];
if(!mCacheLine) {
WriteSimple(whitestring);
WriteSimple(" ");
} else {
AddToLine(whitestring);
AddToLine(" ");
}
bol++;
continue;
}
aString.Mid(tempstr,bol,nextpos-bol);
if(mFlags & nsIDocumentEncoder::OutputPreformatted) {
bol = nextpos;
} else {
tempstr.Append(" ");
bol = nextpos + 1;
mInWhitespace = PR_TRUE;
}
if(!mCacheLine) {
WriteSimple(tempstr);
} else {
AddToLine(tempstr);
}
mInWhitespace = PR_TRUE;
bol = nextpos + 1;
}
} // Continue looping over the string
}
@ -1249,6 +1152,7 @@ nsHTMLToTXTSinkStream::WillBuildModel(void){
return NS_OK;
}
/**
* This method gets called when the parser concludes the process
* of building the content model via the content sink.
@ -1262,6 +1166,7 @@ nsHTMLToTXTSinkStream::DidBuildModel(PRInt32 aQualityLevel) {
return NS_OK;
}
/**
* This method gets called when the parser gets i/o blocked,
* and wants to notify the sink that it may be a while before
@ -1274,6 +1179,7 @@ nsHTMLToTXTSinkStream::WillInterrupt(void) {
return NS_OK;
}
/**
* This method gets called when the parser i/o gets unblocked,
* and we're about to start dumping content again to the sink.
@ -1296,6 +1202,7 @@ nsHTMLToTXTSinkStream::NotifyError(const nsParserError* aError)
return NS_OK;
}
PRBool IsInline(eHTMLTags aTag)
{
PRBool result = PR_FALSE;
@ -1332,11 +1239,13 @@ PRBool IsInline(eHTMLTags aTag)
case eHTMLTag_u:
case eHTMLTag_var:
case eHTMLTag_wbr:
result = PR_TRUE;
break;
default:
break;
}
return result;
}
@ -1345,3 +1254,4 @@ PRBool IsBlockLevel(eHTMLTags aTag)
{
return !IsInline(aTag);
}

Просмотреть файл

@ -188,7 +188,10 @@ CToken* nsHTMLTokenizer::PeekToken() {
* @return ptr to token or NULL
*/
CToken* nsHTMLTokenizer::PopToken() {
return (CToken*)mTokenDeque.PopFront();
CToken* result=nsnull;
result=(CToken*)mTokenDeque.PopFront();
if(result) result->mUseCount=0;
return result;
}
@ -200,6 +203,7 @@ CToken* nsHTMLTokenizer::PopToken() {
*/
CToken* nsHTMLTokenizer::PushTokenFront(CToken* theToken) {
mTokenDeque.PushFront(theToken);
theToken->mUseCount=1;
return theToken;
}
@ -211,6 +215,7 @@ CToken* nsHTMLTokenizer::PushTokenFront(CToken* theToken) {
*/
CToken* nsHTMLTokenizer::PushToken(CToken* theToken) {
mTokenDeque.Push(theToken);
theToken->mUseCount=1;
return theToken;
}
@ -502,7 +507,10 @@ nsresult nsHTMLTokenizer::ConsumeStartTag(PRUnichar aChar,CToken*& aToken,nsScan
In the case that we just read a <SCRIPT> or <STYLE> tags, we should go and
consume all the content itself.
*/
if(NS_SUCCEEDED(result))
if(NS_SUCCEEDED(result)) {
RecordTrailingContent((CStartToken*)aToken,aScanner);
if((eHTMLTag_style==theTag) || (eHTMLTag_script==theTag)) {
nsAutoString endTag(nsHTMLTags::GetStringValue(theTag));
endTag.Insert("</",0,2);
@ -513,6 +521,7 @@ nsresult nsHTMLTokenizer::ConsumeStartTag(PRUnichar aChar,CToken*& aToken,nsScan
AddToken(textToken,result,mTokenDeque,theRecycler);
AddToken(endToken,result,mTokenDeque,theRecycler);
}
}
//EEEEECCCCKKKK!!!
//This code is confusing, so pay attention.
@ -743,3 +752,26 @@ nsresult nsHTMLTokenizer::ConsumeProcessingInstruction(PRUnichar aChar,CToken*&
return result;
}
/**
* This method keeps a copy of contents within the start token.
* The stored content could later be used in displaying TEXTAREA,
* and also in view source.
*
* @update harishd 11/09/99
* @param aStartToken: The token whose trailing contents are to be recorded
* @param aScanner: see nsScanner.h
*
*/
void nsHTMLTokenizer::RecordTrailingContent(CStartToken* aStartToken, nsScanner& aScanner) {
if(aStartToken) {
PRInt32 theOrigin =aStartToken->mOrigin;
PRInt32 theCurrOffset =aScanner.GetOffset();
PRInt32 theLength =(theCurrOffset>theOrigin)? theCurrOffset-theOrigin:-1;
if(theLength>1) {
nsString& theRawXXX =aStartToken->mTrailingContent;
const PRUnichar* theBuff =(aScanner.GetBuffer()).GetUnicode();
theRawXXX.Append(&theBuff[theOrigin],theLength);
}
}
}

Просмотреть файл

@ -89,6 +89,8 @@ protected:
virtual nsresult ConsumeSpecialMarkup(PRUnichar aChar,CToken*& aToken,nsScanner& aScanner);
virtual nsresult ConsumeProcessingInstruction(PRUnichar aChar,CToken*& aToken,nsScanner& aScanner);
virtual void RecordTrailingContent(CStartToken* aStartToken,nsScanner& aScanner);
static void AddToken(CToken*& aToken,nsresult aResult,nsDeque& aDeque,CTokenRecycler* aRecycler);
nsDeque mTokenDeque;

Просмотреть файл

@ -87,6 +87,7 @@ void CHTMLToken::SetStringValue(const char* name){
CStartToken::CStartToken(eHTMLTags aTag) : CHTMLToken(aTag) {
mAttributed=PR_FALSE;
mEmpty=PR_FALSE;
mOrigin=-1;
}
/*
@ -99,6 +100,7 @@ CStartToken::CStartToken(eHTMLTags aTag) : CHTMLToken(aTag) {
CStartToken::CStartToken(nsString& aString,eHTMLTags aTag) : CHTMLToken(aString,aTag) {
mAttributed=PR_FALSE;
mEmpty=PR_FALSE;
mOrigin=-1;
}
@ -111,7 +113,10 @@ CStartToken::CStartToken(nsString& aString,eHTMLTags aTag) : CHTMLToken(aString,
void CStartToken::Reinitialize(PRInt32 aTag, const nsString& aString){
CToken::Reinitialize(aTag,aString);
mAttributed=PR_FALSE;
mUseCount=0; //assume recycling is needed by default.
mEmpty=PR_FALSE;
mOrigin=-1;
mTrailingContent.Truncate();
}
/*
@ -218,7 +223,9 @@ nsresult CStartToken::Consume(PRUnichar aChar, nsScanner& aScanner,PRInt32 aMode
//and see if the next char is ">". If so, we have a complete
//tag without attributes.
if(NS_OK==result) {
mOrigin=aScanner.GetOffset(); // We need this position to record the trailing contents of the start token
result=aScanner.SkipWhitespace();
mNewlineCount += aScanner.GetNewlinesSkipped();
if(NS_OK==result) {
result=aScanner.GetChar(aChar);
if(NS_OK==result) {
@ -259,8 +266,7 @@ void CStartToken::DebugDumpSource(nsOutputStream& out) {
void CStartToken::GetSource(nsString& anOutputString){
anOutputString="<";
anOutputString+=mTextValue;
if(!mAttributed)
anOutputString+=">";
anOutputString+=(mTrailingContent.Length()>0)? mTrailingContent:'>';
}
/*
@ -465,18 +471,23 @@ nsresult CTextToken::Consume(PRUnichar aChar, nsScanner& aScanner,PRInt32 aMode)
result=aScanner.GetChar(theNextChar);
}
mTextValue.Append("\n");
mNewlineCount++;
}
mTextValue.Append("\n");
mNewlineCount++;
break;
case kLF:
if((kLF==theNextChar) || (kCR==theNextChar)) {
result=aScanner.GetChar(theNextChar);
mTextValue.Append("\n");
mNewlineCount++;
}
mTextValue.Append("\n");
mNewlineCount++;
break;
default:
mTextValue.Append("\n");
mNewlineCount++;
break;
} //switch
}
@ -744,7 +755,7 @@ nsresult ConsumeStrictComment(PRUnichar aChar, nsScanner& aScanner,nsString& aSt
}
aString+=temp;
if(NS_OK==result) {
result=aScanner.ReadWhile(aString,gMinus,PR_TRUE,PR_FALSE); //get all available '---'
// result=aScanner.ReadWhile(aString,gMinus,PR_TRUE,PR_FALSE); //get all available '---'
if(NS_OK==result) {
temp="->";
result=aScanner.ReadUntil(aString,temp,PR_FALSE,PR_FALSE);
@ -1013,6 +1024,7 @@ nsresult CNewlineToken::Consume(PRUnichar aChar, nsScanner& aScanner,PRInt32 aMo
* @return
*/
CAttributeToken::CAttributeToken() : CHTMLToken(eHTMLTag_unknown) {
mHasEqualWithoutValue=PR_FALSE;
}
/*
@ -1025,6 +1037,7 @@ CAttributeToken::CAttributeToken() : CHTMLToken(eHTMLTag_unknown) {
CAttributeToken::CAttributeToken(const nsString& aName) : CHTMLToken(aName),
mTextKey() {
mLastAttribute=PR_FALSE;
mHasEqualWithoutValue=PR_FALSE;
}
/*
@ -1038,6 +1051,7 @@ CAttributeToken::CAttributeToken(const nsString& aName) : CHTMLToken(aName),
CAttributeToken::CAttributeToken(const nsString& aKey, const nsString& aName) : CHTMLToken(aName) {
mTextKey = aKey;
mLastAttribute=PR_FALSE;
mHasEqualWithoutValue=PR_FALSE;
}
/**
@ -1050,6 +1064,7 @@ void CAttributeToken::Reinitialize(PRInt32 aTag, const nsString& aString){
CHTMLToken::Reinitialize(aTag,aString);
mTextKey.Truncate();
mLastAttribute=PR_FALSE;
mHasEqualWithoutValue=PR_FALSE;
}
/*
@ -1250,6 +1265,7 @@ nsresult CAttributeToken::Consume(PRUnichar aChar, nsScanner& aScanner,PRInt32 a
result=ConsumeQuotedString(aChar,mTextValue,aScanner);
}
else if(kGreaterThan==aChar){
mHasEqualWithoutValue=PR_TRUE;
result=aScanner.PutBack(aChar);
}
#if 0
@ -1910,7 +1926,39 @@ CDoctypeDeclToken::CDoctypeDeclToken(eHTMLTags aTag) : CHTMLToken(aTag) {
}
nsresult CDoctypeDeclToken::Consume(PRUnichar aChar, nsScanner& aScanner,PRInt32 aMode) {
return ConsumeComment(aChar,aScanner,mTextValue);
nsresult result=NS_OK;
mTextValue="<!";
static const char* theTerminals="\">[";
PRBool done=PR_FALSE;
result=aScanner.ReadUntil(mTextValue,theTerminals,PR_TRUE,PR_FALSE);
while(!done && NS_OK==result){
result=aScanner.Peek(aChar);
if(result==NS_OK) {
if(kQuote==aChar) {
result=aScanner.GetChar(aChar);
if(NS_OK==result) mTextValue += aChar; // append the quote that you just got
result=aScanner.ReadUntil(mTextValue,kQuote,PR_TRUE);
if(NS_OK==result && aMode!=eParseMode_noquirks)
result=aScanner.ReadWhile(mTextValue,"\"",PR_TRUE,PR_FALSE); // consume multiple quotes
}
else if(kLeftSquareBracket==aChar) {
result=aScanner.ReadUntil(mTextValue,kRightSquareBracket,PR_TRUE);
}
else if(kGreaterThan==aChar){
result=aScanner.ReadUntil(mTextValue,kGreaterThan,PR_TRUE);
done=PR_TRUE;
}
else {
result=aScanner.GetChar(aChar);
if(result==NS_OK) mTextValue += aChar;
}
}
}
return result;
}
const char* CDoctypeDeclToken::GetClassName(void) {

Просмотреть файл

@ -129,6 +129,8 @@ class CStartToken: public CHTMLToken {
virtual void Reinitialize(PRInt32 aTag, const nsString& aString);
nsAutoString mTrailingContent;
PRInt32 mOrigin;
protected:
PRBool mAttributed;
PRBool mEmpty;
@ -272,8 +274,9 @@ class CAttributeToken: public CHTMLToken {
PRBool mLastAttribute;
virtual void Reinitialize(PRInt32 aTag, const nsString& aString);
protected:
PRBool mHasEqualWithoutValue;
nsString mTextKey;
};

Просмотреть файл

@ -110,6 +110,7 @@ class nsIDTD : public nsISupports {
PRBool aNotifySink,
nsString& aSourceType,
eParseMode aParseMode,
nsString& aCommand,
nsIContentSink* aSink=0)=0;
/**

Просмотреть файл

@ -146,6 +146,7 @@ class nsIParser : public nsISupports {
* @return nada
*/
virtual void SetDocumentCharset(nsString& aCharset, nsCharsetSource aSource)=0;
virtual void GetDocumentCharset(nsString& oCharset, nsCharsetSource& oSource)=0;
virtual nsIParserFilter* SetParserFilter(nsIParserFilter* aFilter) = 0;

Просмотреть файл

@ -420,16 +420,21 @@ PRBool FindSuitableDTD( CParserContext& aParserContext,nsString& aCommand,nsStri
PRInt32 theDTDIndex=0;
nsIDTD* theBestDTD=0;
nsIDTD* theDTD=0;
PRBool thePrimaryFound=PR_FALSE;
while((theDTDIndex<=gSharedObjects.mDTDDeque.GetSize()) && (aParserContext.mAutoDetectStatus!=ePrimaryDetect)){
theDTD=(nsIDTD*)gSharedObjects.mDTDDeque.ObjectAt(theDTDIndex++);
if(theDTD) {
aParserContext.mAutoDetectStatus=theDTD->CanParse(aParserContext.mSourceType,aCommand,aBuffer,0);
if((eValidDetect==aParserContext.mAutoDetectStatus) || (ePrimaryDetect==aParserContext.mAutoDetectStatus)) {
if(eValidDetect==aParserContext.mAutoDetectStatus){
theBestDTD=theDTD;
}
else if(ePrimaryDetect==aParserContext.mAutoDetectStatus) {
theBestDTD=theDTD;
thePrimaryFound=PR_TRUE;
}
if((theDTDIndex==gSharedObjects.mDTDDeque.GetSize()) && (!theBestDTD)) {
}
if((theDTDIndex==gSharedObjects.mDTDDeque.GetSize()) && (!thePrimaryFound)) {
if(!gSharedObjects.mHasXMLDTD) {
NS_NewWellFormed_DTD(&theDTD); //do this to view XML files...
gSharedObjects.mDTDDeque.Push(theDTD);
@ -556,6 +561,7 @@ nsresult nsParser::WillBuildModel(nsString& aFilename,nsIDTD* aDefaultDTD){
PRBool(0==mParserContext->mPrevContext),
mParserContext->mSourceType,
mParserContext->mParseMode,
mCommand,
mSink);
}//if
}//if
@ -953,6 +959,7 @@ nsresult nsParser::ResumeParse(nsIDTD* aDefaultDTD, PRBool aIsFinalChunk) {
if((!mParserContext->mMultipart) || (mInternalState==NS_ERROR_HTMLPARSER_STOPPARSING) ||
((eOnStop==mParserContext->mStreamListenerState) && (NS_OK==result))){
DidBuildModel(mStreamStatus);
MOZ_TIMER_DEBUGLOG(("Stop: Parse Time: nsParser::ResumeParse(), this=%p\n", this));
@ -1131,9 +1138,7 @@ nsresult nsParser::OnStartRequest(nsIChannel* channel, nsISupports* aContext)
#define UCS4_2143 "X-ISO-10646-UCS-4-2143"
#define UCS4_3412 "X-ISO-10646-UCS-4-3412"
static PRBool detectByteOrderMark(const unsigned char* aBytes, PRInt32 aLen,
nsString& oCharset, nsCharsetSource& oCharsetSource)
{
static PRBool detectByteOrderMark(const unsigned char* aBytes, PRInt32 aLen, nsString& oCharset, nsCharsetSource& oCharsetSource) {
oCharsetSource= kCharsetFromAutoDetection;
oCharset = "";
// see http://www.w3.org/TR/1998/REC-xml-19980210#sec-oCharseting
@ -1395,6 +1400,7 @@ nsresult nsParser::Tokenize(PRBool aIsFinalChunk){
nsITokenizer* theTokenizer=mParserContext->mDTD->GetTokenizer();
if(theTokenizer){
MOZ_TIMER_START(mTokenizeTime);
WillTokenize(aIsFinalChunk);

Просмотреть файл

@ -33,6 +33,7 @@
#include "nsHTMLEntities.h"
#include "nsHTMLTokenizer.h"
#include "nsXMLTokenizer.h"
//#include "nsTextTokenizer.h"
#include "nsExpatTokenizer.h"
#include "nsIParserService.h"
@ -190,6 +191,7 @@ nsParserModule::Shutdown()
nsHTMLTokenizer::FreeTokenRecycler();
nsXMLTokenizer::FreeTokenRecycler();
nsExpatTokenizer::FreeTokenRecycler();
// nsTextTokenizer::FreeTokenRecycler();
nsParser::FreeSharedObjects();
mInitialized = PR_FALSE;
}

Просмотреть файл

@ -56,6 +56,8 @@ nsCParserNode::nsCParserNode(CToken* aToken,PRInt32 aLineNumber,nsITokenRecycler
mLineNumber=aLineNumber;
mToken=aToken;
mRecycler=aRecycler;
mUseCount=0;
mIsResidual=PR_FALSE;
}
static void RecycleTokens(nsITokenRecycler* aRecycler,nsDeque& aDeque) {
@ -99,6 +101,9 @@ nsresult nsCParserNode::Init(CToken* aToken,PRInt32 aLineNumber,nsITokenRecycler
if(mAttributes && (mAttributes->GetSize()))
RecycleTokens(mRecycler,*mAttributes);
mToken=aToken;
mUseCount=0;
mIsResidual=PR_FALSE;
mSkippedContent.Truncate();
return NS_OK;
}

Просмотреть файл

@ -115,6 +115,7 @@ class nsCParserNode : public nsIParserNode {
*/
virtual PRInt32 GetTokenType() const;
//***************************************
//methods for accessing key/value pairs
//***************************************
@ -173,11 +174,12 @@ class nsCParserNode : public nsIParserNode {
*/
virtual CToken* PopAttributeToken();
protected:
PRInt32 mLineNumber;
CToken* mToken;
nsDeque* mAttributes;
nsAutoString mSkippedContent;
PRInt32 mUseCount;
PRBool mIsResidual;
nsITokenRecycler* mRecycler;
};

Просмотреть файл

@ -67,6 +67,7 @@ nsScanner::nsScanner(nsString& anHTMLString, const nsString& aCharset, nsCharset
mCharset = "";
mCharsetSource = kCharsetUninitialized;
SetDocumentCharset(aCharset, aSource);
mNewlinesSkipped=0;
}
/**
@ -96,6 +97,7 @@ nsScanner::nsScanner(nsString& aFilename,PRBool aCreateStream, const nsString& a
mCharset = "";
mCharsetSource = kCharsetUninitialized;
SetDocumentCharset(aCharset, aSource);
mNewlinesSkipped=0;
}
/**
@ -122,6 +124,7 @@ nsScanner::nsScanner(nsString& aFilename,nsInputStream& aStream,const nsString&
mCharset = "";
mCharsetSource = kCharsetUninitialized;
SetDocumentCharset(aCharset, aSource);
mNewlinesSkipped=0;
}
@ -454,15 +457,17 @@ nsresult nsScanner::SkipWhitespace(void) {
PRInt32 theOrigin=mOffset;
PRBool found=PR_FALSE;
mNewlinesSkipped = 0;
#if 1
while(NS_OK==result) {
theChar=theBuf[mOffset++];
if(theChar) {
switch(theChar) {
case ' ':
case '\n': mNewlinesSkipped++;
case ' ' :
case '\r':
case '\n':
case '\b':
case '\t':
found=PR_TRUE;

Просмотреть файл

@ -312,6 +312,7 @@ class nsScanner {
void SetIncremental(PRBool anIncrValue) {mIncremental=anIncrValue;}
PRUint32 GetOffset(void) {return mOffset;}
PRInt32 GetNewlinesSkipped(void) { return mNewlinesSkipped; }
protected:
@ -337,6 +338,7 @@ class nsScanner {
nsString mCharset;
nsIUnicodeDecoder *mUnicodeDecoder;
nsString mUnicodeXferBuf;
PRInt32 mNewlinesSkipped;
};
#endif

Просмотреть файл

@ -46,7 +46,8 @@ CToken::CToken(PRInt32 aTag) : mTextValue() {
mAttrCount=0;
TokenCount++;
mOrigin=eSource;
mRecycle=PR_TRUE;
mUseCount=0;
mNewlineCount=0;
}
/**
@ -61,7 +62,8 @@ CToken::CToken(const nsString& aName) : mTextValue(aName) {
mAttrCount=0;
TokenCount++;
mOrigin=eSource;
mRecycle=PR_TRUE;
mUseCount=0;
mNewlineCount=0;
}
/**
@ -76,7 +78,8 @@ CToken::CToken(const char* aName) : mTextValue(aName) {
mAttrCount=0;
TokenCount++;
mOrigin=eSource;
mRecycle=PR_TRUE;
mUseCount=0;
mNewlineCount=0;
}
/**
@ -106,7 +109,8 @@ void CToken::Reinitialize(PRInt32 aTag, const nsString& aString){
mTypeID=aTag;
mAttrCount=0;
mOrigin=eSource;
mRecycle=PR_TRUE;
mUseCount=0;
mNewlineCount=0;
}
/**

Просмотреть файл

@ -204,7 +204,8 @@ class CToken {
static int GetTokenCount();
eTokenOrigin mOrigin;
PRBool mRecycle;
PRInt32 mUseCount;
PRInt32 mNewlineCount;
protected:
PRInt32 mTypeID;

Просмотреть файл

@ -195,7 +195,9 @@ PRBool CValidDTD::CanConvert(nsString& aSourceType, nsString& aTargetType, PRInt
* @param
* @return
*/
NS_IMETHODIMP CValidDTD::WillBuildModel(nsString& aFilename,PRBool aNotifySink,nsString& aSourceType,eParseMode aParseMode,nsIContentSink* aSink){
NS_IMETHODIMP CValidDTD::WillBuildModel(nsString& aFilename,PRBool aNotifySink,
nsString& aSourceType,eParseMode aParseMode,
nsString& aCommand,nsIContentSink* aSink){
nsresult result=NS_OK;
return result;
}

Просмотреть файл

@ -115,7 +115,12 @@ class CValidDTD : public nsIDTD {
* @param aFilename is the name of the file being parsed.
* @return error code (almost always 0)
*/
NS_IMETHOD WillBuildModel(nsString& aFilename,PRBool aNotifySink,nsString& aSourceType,eParseMode aParseMode,nsIContentSink* aSink=0);
NS_IMETHOD WillBuildModel(nsString& aFilename,
PRBool aNotifySink,
nsString& aSourceType,
eParseMode aParseMode,
nsString& aCommand,
nsIContentSink* aSink=0);
/**
* The parser uses a code sandwich to wrap the parsing process. Before
* the process begins, WillBuildModel() is called. Afterwards the parser

Просмотреть файл

@ -54,6 +54,7 @@
#include "nsIContentSink.h"
#include "nsIHTMLContentSink.h"
#include "nsHTMLTokenizer.h"
//#include "nsTextTokenizer.h"
#include "prenv.h" //this is here for debug reasons...
#include "prtypes.h" //this is here for debug reasons...
@ -204,7 +205,7 @@ public:
* @param
* @return
*/
CViewSourceHTML::CViewSourceHTML() : nsIDTD(), mFilename(""),
CViewSourceHTML::CViewSourceHTML() : nsIDTD(),
mStartTag("start"), mEndTag("end"), mCommentTag("comment"),
mDocTypeTag("doctype"), mPITag("pi"), mEntityTag("entity"),
mText("txt"), mKey("key"), mValue("val")
@ -214,6 +215,7 @@ CViewSourceHTML::CViewSourceHTML() : nsIDTD(), mFilename(""),
mSink=0;
mLineNumber=0;
mTokenizer=0;
mIsText=PR_FALSE;
#ifdef rickgdebug
gDumpFile = new fstream("c:/temp/viewsource.xml",ios::trunc);
@ -289,9 +291,10 @@ eAutoDetectResult CViewSourceHTML::CanParse(nsString& aContentType, nsString& aC
* @param
* @return
*/
NS_IMETHODIMP CViewSourceHTML::WillBuildModel(nsString& aFilename,PRBool aNotifySink,nsString& aSourceType,eParseMode aParseMode,nsIContentSink* aSink){
NS_IMETHODIMP CViewSourceHTML::WillBuildModel(nsString& aFilename,PRBool aNotifySink,
nsString& aSourceType,eParseMode aParseMode,
nsString& aCommand,nsIContentSink* aSink){
nsresult result=NS_OK;
mFilename=aFilename;
#ifdef RAPTOR_PERF_METRICS
vsTimer.Reset();
@ -302,18 +305,15 @@ NS_IMETHODIMP CViewSourceHTML::WillBuildModel(nsString& aFilename,PRBool aNotify
mSink=(nsIXMLContentSink*)aSink;
if((aNotifySink) && (mSink)) {
mLineNumber=0;
result = mSink->WillBuildModel();
static const char* theHeader="<?xml version=\"1.0\"?>";
CToken ssToken(theHeader);
nsCParserNode ssNode(&ssToken);
result= mSink->AddCharacterData(ssNode);
#ifdef rickgdebug
#ifdef rickgdebug
(*gDumpFile) << theHeader << endl;
(*gDumpFile) << "<viewsource xmlns=\"viewsource\">" << endl;
#endif
#endif
//now let's automatically open the root container...
CToken theToken("viewsource");
@ -323,6 +323,11 @@ NS_IMETHODIMP CViewSourceHTML::WillBuildModel(nsString& aFilename,PRBool aNotify
theNode.AddAttribute(&theAttr);
mSink->OpenContainer(theNode);
}
mIsText=!aCommand.Equals(kViewSourceCommand);
mLineNumber=0;
result = mSink->WillBuildModel();
START_TIMER();
return result;
}
@ -338,7 +343,8 @@ NS_IMETHODIMP CViewSourceHTML::WillBuildModel(nsString& aFilename,PRBool aNotify
NS_IMETHODIMP CViewSourceHTML::BuildModel(nsIParser* aParser,nsITokenizer* aTokenizer,nsITokenObserver* anObserver,nsIContentSink* aSink) {
nsresult result=NS_OK;
if(aTokenizer) {
if(aTokenizer && aParser) {
nsITokenizer* oldTokenizer=mTokenizer;
mTokenizer=aTokenizer;
gTokenRecycler=(CTokenRecycler*)mTokenizer->GetTokenRecycler();
@ -384,7 +390,7 @@ NS_IMETHODIMP CViewSourceHTML::DidBuildModel(nsresult anErrorCode,PRBool aNotify
mSink=(nsIXMLContentSink*)aParser->GetContentSink();
if((aNotifySink) && (mSink)) {
//now let's automatically close the pre...
//now let's automatically auto-opened containers...
#ifdef rickgdebug
if(gDumpFile){
@ -394,11 +400,12 @@ NS_IMETHODIMP CViewSourceHTML::DidBuildModel(nsresult anErrorCode,PRBool aNotify
}
#endif
if(!mIsText) {
//now let's automatically close the root container...
CToken theToken("viewsource");
nsCParserNode theNode(&theToken,0);
mSink->CloseContainer(theNode);
}
result = mSink->DidBuildModel(1);
}
@ -451,8 +458,12 @@ nsresult CViewSourceHTML::Terminate(void)
* @return ptr to tokenizer
*/
nsITokenizer* CViewSourceHTML::GetTokenizer(void) {
if(!mTokenizer)
mTokenizer=new nsHTMLTokenizer();
if(!mTokenizer) {
/*if(mIsText)
mTokenizer = new nsTextTokenizer();
else */
mTokenizer = new nsHTMLTokenizer();
}
return mTokenizer;
}
@ -694,7 +705,7 @@ nsresult CViewSourceHTML::WriteAttributes(PRInt32 attrCount) {
CToken theKeyToken(theAttrToken->GetKey());
result=WriteTag(mKey,&theKeyToken,0,PR_FALSE);
nsString& theValue=theToken->GetStringValueXXX();
if(0<theValue.Length()) {
if((0<theValue.Length()) || (theAttrToken->mHasEqualWithoutValue)){
result=WriteTag(mValue,theToken,0,PR_FALSE);
}
}
@ -760,7 +771,6 @@ nsresult CViewSourceHTML::WriteTag(nsString &theXMLTagName,CToken* aToken,PRInt3
mSink->CloseContainer(theContext.mEndNode); //emit </starttag>...
START_TIMER();
#ifdef rickgdebug
cstr.Assign(theXMLTagName);
(*gDumpFile) << "</" << cstr << ">";
@ -852,17 +862,13 @@ NS_IMETHODIMP CViewSourceHTML::HandleToken(CToken* aToken,nsIParser* aParser) {
case eToken_start:
result=WriteTag(mStartTag,aToken,aToken->GetAttributeCount(),PR_TRUE);
if(mParser && (NS_OK==result)) {
nsAutoString charsetValue;
nsCharsetSource charsetSource;
if((!mIsText) && mParser && (NS_OK==result)) {
CObserverService& theService=mParser->GetObserverService();
CParserContext* pc=mParser->PeekContext();
void* theDocID=(pc)? pc->mKey:0;
eHTMLTags theTag=(eHTMLTags)theToken->GetTypeID();
mParser->GetDocumentCharset(charsetValue,charsetSource);
eHTMLTags theTag = (eHTMLTags)aToken->GetTypeID();
result=theService.Notify(theTag,theContext.mTokenNode,(PRUint32)theDocID,
kViewSourceCommand,charsetValue,charsetSource);
result=theService.Notify(theTag,theContext.mTokenNode,(PRUint32)theDocID,kViewSourceCommand,mParser);
}
theContext.mTokenNode.Init(0,0,gTokenRecycler); //now recycle.
break;

Просмотреть файл

@ -108,10 +108,11 @@ class CViewSourceHTML: public nsIDTD {
* @param aFilename is the name of the file being parsed.
* @return error code (almost always 0)
*/
NS_IMETHOD WillBuildModel( nsString& aFilename,
NS_IMETHOD WillBuildModel(nsString& aFilename,
PRBool aNotifySink,
nsString& aSourceType,
eParseMode aParseMode,
nsString& aCommand,
nsIContentSink* aSink=0);
/**
* The parser uses a code sandwich to wrap the parsing process. Before
@ -267,7 +268,6 @@ protected:
nsParser* mParser;
nsIXMLContentSink* mSink;
nsString mFilename;
PRInt32 mLineNumber;
nsITokenizer* mTokenizer;
nsAutoString mStartTag;
@ -279,6 +279,7 @@ protected:
nsAutoString mText;
nsAutoString mKey;
nsAutoString mValue;
PRBool mIsText;
};
extern NS_HTMLPARS nsresult NS_NewViewSourceHTML(nsIDTD** aInstancePtrResult);

Просмотреть файл

@ -206,7 +206,9 @@ eAutoDetectResult CWellFormedDTD::CanParse(nsString& aContentType, nsString& aCo
* @param
* @return
*/
NS_IMETHODIMP CWellFormedDTD::WillBuildModel(nsString& aFilename,PRBool aNotifySink,nsString& aSourceType,eParseMode aParseMode,nsIContentSink* aSink){
NS_IMETHODIMP CWellFormedDTD::WillBuildModel(nsString& aFilename,PRBool aNotifySink,
nsString& aSourceType,eParseMode aParseMode,
nsString& aCommand,nsIContentSink* aSink){
nsresult result=NS_OK;
mFilename=aFilename;

Просмотреть файл

@ -106,6 +106,7 @@ class CWellFormedDTD : public nsIDTD {
PRBool aNotifySink,
nsString& aSourceType,
eParseMode aParseMode,
nsString& aCommand,
nsIContentSink* aSink=0);
/**
* The parser uses a code sandwich to wrap the parsing process. Before

Просмотреть файл

@ -40,6 +40,7 @@
#include "prmem.h"
#include "nsXMLTokenizer.h"
static NS_DEFINE_IID(kIHTMLContentSinkIID, NS_IHTML_CONTENT_SINK_IID);
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
static NS_DEFINE_IID(kIDTDIID, NS_IDTD_IID);
static NS_DEFINE_IID(kClassIID, NS_XIF_DTD_CID);
@ -334,6 +335,7 @@ nsXIFDTD::nsXIFDTD() : nsIDTD(){
mLowerCaseAttributes=PR_TRUE;
mLowerCaseTags=PR_TRUE;
mCharset = "";
mSink=0;
}
/**
@ -345,7 +347,7 @@ nsXIFDTD::nsXIFDTD() : nsIDTD(){
*/
nsXIFDTD::~nsXIFDTD(){
DeleteTokenHandlers();
// NS_RELEASE(mSink);
NS_IF_RELEASE(mSink);
}
@ -428,12 +430,17 @@ eAutoDetectResult nsXIFDTD::CanParse(nsString& aContentType, nsString& aCommand,
* @param
* @return
*/
nsresult nsXIFDTD::WillBuildModel(nsString& aFilename,PRBool aNotifySink,nsString& aSourceType,eParseMode aParseMode,nsIContentSink* aSink){
nsresult nsXIFDTD::WillBuildModel(nsString& aFilename,PRBool aNotifySink,
nsString& aSourceType,eParseMode aParseMode,
nsString& aCommand,nsIContentSink* aSink){
nsresult result=NS_OK;
mSink=(nsIHTMLContentSink*)aSink;
if(mSink) {
mSink->WillBuildModel();
if(aSink) {
if(aSink && (!mSink)) {
result=aSink->QueryInterface(kIHTMLContentSinkIID, (void **)&mSink);
}
result = aSink->WillBuildModel();
}
return result;
}

Просмотреть файл

@ -156,10 +156,11 @@ class nsXIFDTD : public nsIDTD {
* @param
* @return
*/
NS_IMETHOD WillBuildModel( nsString& aFilename,
NS_IMETHOD WillBuildModel(nsString& aFilename,
PRBool aNotifySink,
nsString& aSourceType,
eParseMode aParseMode,
nsString& aCommand,
nsIContentSink* aSink=0);
/**
* The parser uses a code sandwich to wrap the parsing process. Before