mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-15 06:15:43 +00:00
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:
parent
70bc2b5e0f
commit
aa7503d71d
File diff suppressed because it is too large
Load Diff
@ -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);
|
||||
|
||||
/**
|
||||
|
@ -23,7 +23,8 @@
|
||||
|
||||
#include "nsDTDUtils.h"
|
||||
#include "CNavDTD.h"
|
||||
#include "nsIParserNode.h"
|
||||
#include "nsIParserNode.h"
|
||||
#include "nsParserNode.h"
|
||||
|
||||
#include "nsIObserverService.h"
|
||||
#include "nsIServiceManager.h"
|
||||
@ -31,11 +32,8 @@
|
||||
MOZ_DECL_CTOR_COUNTER(nsEntryStack);
|
||||
MOZ_DECL_CTOR_COUNTER(nsDTDContext);
|
||||
MOZ_DECL_CTOR_COUNTER(CTokenRecycler);
|
||||
MOZ_DECL_CTOR_COUNTER(CObserverService);
|
||||
MOZ_DECL_CTOR_COUNTER(CObserverService);
|
||||
|
||||
/***************************************************************
|
||||
First, define the tagstack class
|
||||
***************************************************************/
|
||||
|
||||
|
||||
/**
|
||||
@ -44,9 +42,9 @@ MOZ_DECL_CTOR_COUNTER(CObserverService);
|
||||
* @update gess 04/22/99
|
||||
*/
|
||||
nsEntryStack::nsEntryStack() {
|
||||
|
||||
MOZ_COUNT_CTOR(nsEntryStack);
|
||||
|
||||
MOZ_COUNT_CTOR(nsEntryStack);
|
||||
|
||||
mCapacity=0;
|
||||
mCount=0;
|
||||
mEntries=0;
|
||||
@ -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;
|
||||
mEntries=0;
|
||||
}
|
||||
mCount=mCapacity=0;
|
||||
mEntries=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,22 +110,95 @@ void nsEntryStack::Push(eHTMLTags aTag) {
|
||||
else{
|
||||
//XXX HACK! This is very bad! We failed to get memory.
|
||||
}
|
||||
}
|
||||
mEntries[mCount].mTag=aTag;
|
||||
mEntries[mCount].mBankIndex=-1;
|
||||
mEntries[mCount++].mStyleIndex=-1;
|
||||
} //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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @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,48 +332,79 @@ nsDTDContext::~nsDTDContext() {
|
||||
* @update gess7/9/98, harishd 04/04/99
|
||||
*/
|
||||
PRInt32 nsDTDContext::GetCount(void) {
|
||||
return mStack.GetCount();
|
||||
return mStack.mCount;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @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();
|
||||
return result;
|
||||
PRBool nsDTDContext::HasOpenContainer(eHTMLTags aTag) const {
|
||||
PRInt32 theIndex=mStack.FindLast(aTag);
|
||||
return PRBool(-1<theIndex);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @update gess7/9/98
|
||||
*/
|
||||
eHTMLTags nsDTDContext::First() const {
|
||||
PRInt32 nsDTDContext::GetTopmostIndexOf(eHTMLTags aTag) const {
|
||||
PRInt32 result=mStack.FindLast(aTag);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @update gess7/9/98
|
||||
*/
|
||||
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();
|
||||
}
|
||||
|
||||
@ -294,147 +418,115 @@ eHTMLTags nsDTDContext::TagAt(PRInt32 anIndex) const {
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @update gess7/9/98
|
||||
*/
|
||||
eHTMLTags nsDTDContext::operator[](PRInt32 anIndex) const {
|
||||
return mStack[anIndex];
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @update gess7/9/98
|
||||
*/
|
||||
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
|
||||
*/
|
||||
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){
|
||||
result=theStack->Pop();
|
||||
}
|
||||
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
|
||||
*/
|
||||
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();
|
||||
}
|
||||
}
|
||||
} //if
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
/**
|
||||
*
|
||||
* @update harishd 04/04/99
|
||||
* @update gess 04/21/99
|
||||
* @update gess 04/28/99
|
||||
*/
|
||||
void nsDTDContext::SaveToken(CToken* aToken, PRInt32 aID)
|
||||
{
|
||||
NS_PRECONDITION(aID <= mStack.GetCount() && aID > -1,"Out of bounds");
|
||||
nsIParserNode* nsDTDContext::PopStyle(eHTMLTags aTag){
|
||||
|
||||
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;
|
||||
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");
|
||||
}
|
||||
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();
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @update harishd 04/04/99
|
||||
* @update gess 04/21/99
|
||||
*/
|
||||
PRInt32 nsDTDContext::TokenCountAt(PRInt32 aID)
|
||||
{
|
||||
NS_PRECONDITION(aID <= mStack.GetCount(),"Out of bounds");
|
||||
|
||||
nsTagEntry theEntry=mStack.EntryAt(aID);
|
||||
nsDeque* theDeque=(nsDeque*)mSkipped.ObjectAt(theEntry.mBankIndex);
|
||||
if(theDeque){
|
||||
return theDeque->GetSize();
|
||||
}
|
||||
}
|
||||
|
||||
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();
|
||||
eHTMLTags First() const;
|
||||
eHTMLTags TagAt(PRUint32 anIndex) const;
|
||||
nsTagEntry& EntryAt(PRUint32 anIndex) const;
|
||||
PRInt32 GetTopmostIndexOf(eHTMLTags aTag) const;
|
||||
eHTMLTags operator[](PRUint32 anIndex) const;
|
||||
eHTMLTags Last() const;
|
||||
void Empty(void);
|
||||
PRInt32 GetCount(void) const {return mCount;}
|
||||
nsEntryStack();
|
||||
~nsEntryStack();
|
||||
|
||||
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(PRInt32 anIndex) const;
|
||||
nsTagEntry* EntryAt(PRInt32 anIndex) const;
|
||||
eHTMLTags operator[](PRInt32 anIndex) const;
|
||||
eHTMLTags Last() const;
|
||||
void Empty(void);
|
||||
|
||||
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;
|
||||
eHTMLTags TagAt(PRInt32 anIndex) const;
|
||||
eHTMLTags operator[](PRInt32 anIndex) const;
|
||||
eHTMLTags Last() const;
|
||||
void Empty(void);
|
||||
PRInt32 GetCount(void);
|
||||
nsEntryStack* GetStylesAt(PRUint32 anIndex) const;
|
||||
void PushStyle(eHTMLTags aTag);
|
||||
eHTMLTags PopStyle(void);
|
||||
|
||||
void SaveToken(CToken* aToken, PRInt32 aID);
|
||||
CToken* RestoreTokenFrom(PRInt32 aID);
|
||||
PRInt32 TokenCountAt(PRInt32 aID);
|
||||
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 {return TagAt(anIndex);}
|
||||
PRBool HasOpenContainer(eHTMLTags aTag) const;
|
||||
PRInt32 GetTopmostIndexOf(eHTMLTags aTag) const;
|
||||
|
||||
void Empty(void);
|
||||
PRInt32 GetCount(void);
|
||||
nsEntryStack* GetStylesAt(PRInt32 anIndex) const;
|
||||
void PushStyle(const nsIParserNode* aNode);
|
||||
void PushStyles(nsEntryStack *theStyles);
|
||||
nsIParserNode* PopStyle(void);
|
||||
nsIParserNode* PopStyle(eHTMLTags aTag);
|
||||
|
||||
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);
|
||||
|
@ -28,18 +28,7 @@
|
||||
*/
|
||||
|
||||
#include "nsElementTable.h"
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @update gess 01/04/99
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
PRBool Contains(eHTMLTags aTag,TagList& aTagList){
|
||||
PRBool result=FindTagInSet(aTag,aTagList.mTags,aTagList.mCount);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
@ -47,11 +36,30 @@ PRBool Contains(eHTMLTags aTag,TagList& aTagList){
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
PRInt32 GetTopmostIndexOf(nsEntryStack& aTagStack,TagList& aTagList){
|
||||
int max = aTagStack.GetCount();
|
||||
int index=0;
|
||||
PRInt32 GetTopmostIndexOf(nsDTDContext& aContext,TagList& aTagList){
|
||||
int max = aContext.GetCount();
|
||||
int index;
|
||||
for(index=max-1;index>=0;index--){
|
||||
if(FindTagInSet(aTagStack[index],aTagList.mTags,aTagList.mCount)) {
|
||||
PRBool result=FindTagInSet(aContext[index],aTagList.mTags,aTagList.mCount);
|
||||
if(result) {
|
||||
return index;
|
||||
}
|
||||
}
|
||||
return kNotFound;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @update gess 01/04/99
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
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,16 +147,18 @@ 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;
|
||||
|
||||
/**
|
||||
* Construct a content sink stream.
|
||||
* @update gpk02/03/99
|
||||
* @update gpk02/03/99
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
@ -187,9 +191,10 @@ nsHTMLToTXTSinkStream::nsHTMLToTXTSinkStream()
|
||||
mOLStackIndex = 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @update gpk02/03/99
|
||||
* @update gpk02/03/99
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
@ -206,7 +211,7 @@ nsHTMLToTXTSinkStream::~nsHTMLToTXTSinkStream()
|
||||
|
||||
/**
|
||||
*
|
||||
* @update gpk04/30/99
|
||||
* @update gpk04/30/99
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
@ -224,10 +229,11 @@ nsHTMLToTXTSinkStream::Initialize(nsIOutputStream* aOutStream,
|
||||
|
||||
/**
|
||||
*
|
||||
* @update gpk04/30/99
|
||||
* @update gpk04/30/99
|
||||
* @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.
|
||||
@ -246,10 +254,9 @@ nsHTMLToTXTSinkStream::SetCharsetOverride(const nsString* aCharset)
|
||||
* @update gpk02/03/99
|
||||
* @param nsString reference to new title value
|
||||
* @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,12 +440,14 @@ 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) ||
|
||||
(mFlags & nsIDocumentEncoder::OutputWrap))) {
|
||||
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);
|
||||
char cbuf[40];
|
||||
PR_snprintf(cbuf, sizeof(cbuf), "%ld.", (mOLStack[mOLStackIndex-1])++);
|
||||
temp = cbuf;
|
||||
}
|
||||
else
|
||||
number += "#";
|
||||
temp += Spaces(gOLNumberWidth - number.Length()) + number + '.';
|
||||
temp = "#";
|
||||
}
|
||||
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;
|
||||
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)
|
||||
{
|
||||
nsAutoString url;
|
||||
if (NS_SUCCEEDED(GetValueOfAttribute(aNode, "src", url)))
|
||||
case eHTMLTag_table:
|
||||
case eHTMLTag_ul:
|
||||
case eHTMLTag_ol:
|
||||
case eHTMLTag_p:
|
||||
{
|
||||
nsAutoString temp, desc;
|
||||
if (NS_SUCCEEDED(GetValueOfAttribute(aNode, "alt", desc)))
|
||||
{
|
||||
temp += " (";
|
||||
temp += desc;
|
||||
temp += " <URL:";
|
||||
temp += url;
|
||||
temp += ">) ";
|
||||
}
|
||||
else
|
||||
{
|
||||
temp += " <URL:";
|
||||
temp += url;
|
||||
temp += "> ";
|
||||
}
|
||||
Write(temp);
|
||||
EnsureVerticalSpace((mFlags & nsIDocumentEncoder::OutputFormatted) ? 1 : 0);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
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,23 +712,13 @@ 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;
|
||||
}
|
||||
|
||||
void nsHTMLToTXTSinkStream::EnsureBufferSize(PRInt32 aNewSize)
|
||||
{
|
||||
if (mBufferSize < aNewSize)
|
||||
if (mBufferSize < aNewSize)
|
||||
{
|
||||
nsAllocator::Free(mBuffer);
|
||||
mBufferSize = 2*aNewSize+1; // make the twice as large
|
||||
@ -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(mCurrentLine);
|
||||
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;
|
||||
// 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;
|
||||
}
|
||||
|
||||
tempstr.Append(" ");
|
||||
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,16 +507,20 @@ 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);
|
||||
CToken* textToken=theRecycler->CreateTokenOfType(eToken_text,theTag);
|
||||
result=((CTextToken*)textToken)->ConsumeUntil(0,PR_TRUE,aScanner,endTag,mParseMode); //tell new token to finish consuming text...
|
||||
//endTag.Append(">");
|
||||
CToken* endToken=theRecycler->CreateTokenOfType(eToken_end,theTag,endTag);
|
||||
AddToken(textToken,result,mTokenDeque,theRecycler);
|
||||
AddToken(endToken,result,mTokenDeque,theRecycler);
|
||||
nsAutoString endTag(nsHTMLTags::GetStringValue(theTag));
|
||||
endTag.Insert("</",0,2);
|
||||
CToken* textToken=theRecycler->CreateTokenOfType(eToken_text,theTag);
|
||||
result=((CTextToken*)textToken)->ConsumeUntil(0,PR_TRUE,aScanner,endTag,mParseMode); //tell new token to finish consuming text...
|
||||
//endTag.Append(">");
|
||||
CToken* endToken=theRecycler->CreateTokenOfType(eToken_end,theTag,endTag);
|
||||
AddToken(textToken,result,mTokenDeque,theRecycler);
|
||||
AddToken(endToken,result,mTokenDeque,theRecycler);
|
||||
}
|
||||
}
|
||||
|
||||
//EEEEECCCCKKKK!!!
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
@ -88,6 +88,8 @@ protected:
|
||||
virtual nsresult ConsumeText(const nsString& aString,CToken*& aToken,nsScanner& aScanner);
|
||||
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);
|
||||
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
/*
|
||||
@ -217,8 +222,10 @@ nsresult CStartToken::Consume(PRUnichar aChar, nsScanner& aScanner,PRInt32 aMode
|
||||
//Good. Now, let's skip whitespace after the identifier,
|
||||
//and see if the next char is ">". If so, we have a complete
|
||||
//tag without attributes.
|
||||
if(NS_OK==result) {
|
||||
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) {
|
||||
|
@ -113,25 +113,27 @@ protected:
|
||||
*/
|
||||
class CStartToken: public CHTMLToken {
|
||||
public:
|
||||
CStartToken(eHTMLTags aTag);
|
||||
CStartToken(nsString& aName,eHTMLTags aTag=eHTMLTag_unknown);
|
||||
virtual nsresult Consume(PRUnichar aChar,nsScanner& aScanner,PRInt32 aMode);
|
||||
virtual PRInt32 GetTypeID(void);
|
||||
virtual const char* GetClassName(void);
|
||||
virtual PRInt32 GetTokenType(void);
|
||||
CStartToken(eHTMLTags aTag);
|
||||
CStartToken(nsString& aName,eHTMLTags aTag=eHTMLTag_unknown);
|
||||
virtual nsresult Consume(PRUnichar aChar,nsScanner& aScanner,PRInt32 aMode);
|
||||
virtual PRInt32 GetTypeID(void);
|
||||
virtual const char* GetClassName(void);
|
||||
virtual PRInt32 GetTokenType(void);
|
||||
|
||||
PRBool IsAttributed(void);
|
||||
void SetAttributed(PRBool aValue);
|
||||
PRBool IsEmpty(void);
|
||||
void SetEmpty(PRBool aValue);
|
||||
virtual void DebugDumpSource(nsOutputStream& out);
|
||||
virtual void GetSource(nsString& anOutputString);
|
||||
PRBool IsAttributed(void);
|
||||
void SetAttributed(PRBool aValue);
|
||||
PRBool IsEmpty(void);
|
||||
void SetEmpty(PRBool aValue);
|
||||
virtual void DebugDumpSource(nsOutputStream& out);
|
||||
virtual void GetSource(nsString& anOutputString);
|
||||
|
||||
virtual void Reinitialize(PRInt32 aTag, const nsString& aString);
|
||||
virtual void Reinitialize(PRInt32 aTag, const nsString& aString);
|
||||
|
||||
nsAutoString mTrailingContent;
|
||||
PRInt32 mOrigin;
|
||||
protected:
|
||||
PRBool mAttributed;
|
||||
PRBool mEmpty;
|
||||
PRBool mAttributed;
|
||||
PRBool mEmpty;
|
||||
};
|
||||
|
||||
|
||||
@ -272,9 +274,10 @@ class CAttributeToken: public CHTMLToken {
|
||||
PRBool mLastAttribute;
|
||||
virtual void Reinitialize(PRInt32 aTag, const nsString& aString);
|
||||
|
||||
protected:
|
||||
nsString mTextKey;
|
||||
};
|
||||
PRBool mHasEqualWithoutValue;
|
||||
nsString mTextKey;
|
||||
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
|
@ -106,10 +106,11 @@ class nsIDTD : public nsISupports {
|
||||
* @param aFilename--string that contains name of file being parsed (if applicable)
|
||||
* @return
|
||||
*/
|
||||
NS_IMETHOD WillBuildModel( nsString& aFilename,
|
||||
PRBool aNotifySink,
|
||||
nsString& aSourceType,
|
||||
NS_IMETHOD WillBuildModel( nsString& aFilename,
|
||||
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
|
||||
(*gDumpFile) << theHeader << endl;
|
||||
(*gDumpFile) << "<viewsource xmlns=\"viewsource\">" << endl;
|
||||
#endif
|
||||
#ifdef rickgdebug
|
||||
(*gDumpFile) << theHeader << endl;
|
||||
(*gDumpFile) << "<viewsource xmlns=\"viewsource\">" << endl;
|
||||
#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
|
||||
|
||||
//now let's automatically close the root container...
|
||||
CToken theToken("viewsource");
|
||||
nsCParserNode theNode(&theToken,0);
|
||||
mSink->CloseContainer(theNode);
|
||||
|
||||
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;
|
||||
|
||||
mParser->GetDocumentCharset(charsetValue,charsetSource);
|
||||
eHTMLTags theTag = (eHTMLTags)aToken->GetTypeID();
|
||||
result=theService.Notify(theTag,theContext.mTokenNode,(PRUint32)theDocID,
|
||||
kViewSourceCommand,charsetValue,charsetSource);
|
||||
eHTMLTags theTag=(eHTMLTags)theToken->GetTypeID();
|
||||
|
||||
result=theService.Notify(theTag,theContext.mTokenNode,(PRUint32)theDocID,kViewSourceCommand,mParser);
|
||||
}
|
||||
theContext.mTokenNode.Init(0,0,gTokenRecycler); //now recycle.
|
||||
break;
|
||||
|
@ -108,11 +108,12 @@ 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,
|
||||
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
|
||||
@ -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,11 +156,12 @@ class nsXIFDTD : public nsIDTD {
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
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
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -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);
|
||||
|
||||
/**
|
||||
|
@ -23,7 +23,8 @@
|
||||
|
||||
#include "nsDTDUtils.h"
|
||||
#include "CNavDTD.h"
|
||||
#include "nsIParserNode.h"
|
||||
#include "nsIParserNode.h"
|
||||
#include "nsParserNode.h"
|
||||
|
||||
#include "nsIObserverService.h"
|
||||
#include "nsIServiceManager.h"
|
||||
@ -31,11 +32,8 @@
|
||||
MOZ_DECL_CTOR_COUNTER(nsEntryStack);
|
||||
MOZ_DECL_CTOR_COUNTER(nsDTDContext);
|
||||
MOZ_DECL_CTOR_COUNTER(CTokenRecycler);
|
||||
MOZ_DECL_CTOR_COUNTER(CObserverService);
|
||||
MOZ_DECL_CTOR_COUNTER(CObserverService);
|
||||
|
||||
/***************************************************************
|
||||
First, define the tagstack class
|
||||
***************************************************************/
|
||||
|
||||
|
||||
/**
|
||||
@ -44,9 +42,9 @@ MOZ_DECL_CTOR_COUNTER(CObserverService);
|
||||
* @update gess 04/22/99
|
||||
*/
|
||||
nsEntryStack::nsEntryStack() {
|
||||
|
||||
MOZ_COUNT_CTOR(nsEntryStack);
|
||||
|
||||
MOZ_COUNT_CTOR(nsEntryStack);
|
||||
|
||||
mCapacity=0;
|
||||
mCount=0;
|
||||
mEntries=0;
|
||||
@ -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;
|
||||
mEntries=0;
|
||||
}
|
||||
mCount=mCapacity=0;
|
||||
mEntries=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,22 +110,95 @@ void nsEntryStack::Push(eHTMLTags aTag) {
|
||||
else{
|
||||
//XXX HACK! This is very bad! We failed to get memory.
|
||||
}
|
||||
}
|
||||
mEntries[mCount].mTag=aTag;
|
||||
mEntries[mCount].mBankIndex=-1;
|
||||
mEntries[mCount++].mStyleIndex=-1;
|
||||
} //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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @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,48 +332,79 @@ nsDTDContext::~nsDTDContext() {
|
||||
* @update gess7/9/98, harishd 04/04/99
|
||||
*/
|
||||
PRInt32 nsDTDContext::GetCount(void) {
|
||||
return mStack.GetCount();
|
||||
return mStack.mCount;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @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();
|
||||
return result;
|
||||
PRBool nsDTDContext::HasOpenContainer(eHTMLTags aTag) const {
|
||||
PRInt32 theIndex=mStack.FindLast(aTag);
|
||||
return PRBool(-1<theIndex);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @update gess7/9/98
|
||||
*/
|
||||
eHTMLTags nsDTDContext::First() const {
|
||||
PRInt32 nsDTDContext::GetTopmostIndexOf(eHTMLTags aTag) const {
|
||||
PRInt32 result=mStack.FindLast(aTag);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @update gess7/9/98
|
||||
*/
|
||||
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();
|
||||
}
|
||||
|
||||
@ -294,147 +418,115 @@ eHTMLTags nsDTDContext::TagAt(PRInt32 anIndex) const {
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @update gess7/9/98
|
||||
*/
|
||||
eHTMLTags nsDTDContext::operator[](PRInt32 anIndex) const {
|
||||
return mStack[anIndex];
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @update gess7/9/98
|
||||
*/
|
||||
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
|
||||
*/
|
||||
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){
|
||||
result=theStack->Pop();
|
||||
}
|
||||
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
|
||||
*/
|
||||
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();
|
||||
}
|
||||
}
|
||||
} //if
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
/**
|
||||
*
|
||||
* @update harishd 04/04/99
|
||||
* @update gess 04/21/99
|
||||
* @update gess 04/28/99
|
||||
*/
|
||||
void nsDTDContext::SaveToken(CToken* aToken, PRInt32 aID)
|
||||
{
|
||||
NS_PRECONDITION(aID <= mStack.GetCount() && aID > -1,"Out of bounds");
|
||||
nsIParserNode* nsDTDContext::PopStyle(eHTMLTags aTag){
|
||||
|
||||
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;
|
||||
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");
|
||||
}
|
||||
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();
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @update harishd 04/04/99
|
||||
* @update gess 04/21/99
|
||||
*/
|
||||
PRInt32 nsDTDContext::TokenCountAt(PRInt32 aID)
|
||||
{
|
||||
NS_PRECONDITION(aID <= mStack.GetCount(),"Out of bounds");
|
||||
|
||||
nsTagEntry theEntry=mStack.EntryAt(aID);
|
||||
nsDeque* theDeque=(nsDeque*)mSkipped.ObjectAt(theEntry.mBankIndex);
|
||||
if(theDeque){
|
||||
return theDeque->GetSize();
|
||||
}
|
||||
}
|
||||
|
||||
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();
|
||||
eHTMLTags First() const;
|
||||
eHTMLTags TagAt(PRUint32 anIndex) const;
|
||||
nsTagEntry& EntryAt(PRUint32 anIndex) const;
|
||||
PRInt32 GetTopmostIndexOf(eHTMLTags aTag) const;
|
||||
eHTMLTags operator[](PRUint32 anIndex) const;
|
||||
eHTMLTags Last() const;
|
||||
void Empty(void);
|
||||
PRInt32 GetCount(void) const {return mCount;}
|
||||
nsEntryStack();
|
||||
~nsEntryStack();
|
||||
|
||||
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(PRInt32 anIndex) const;
|
||||
nsTagEntry* EntryAt(PRInt32 anIndex) const;
|
||||
eHTMLTags operator[](PRInt32 anIndex) const;
|
||||
eHTMLTags Last() const;
|
||||
void Empty(void);
|
||||
|
||||
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;
|
||||
eHTMLTags TagAt(PRInt32 anIndex) const;
|
||||
eHTMLTags operator[](PRInt32 anIndex) const;
|
||||
eHTMLTags Last() const;
|
||||
void Empty(void);
|
||||
PRInt32 GetCount(void);
|
||||
nsEntryStack* GetStylesAt(PRUint32 anIndex) const;
|
||||
void PushStyle(eHTMLTags aTag);
|
||||
eHTMLTags PopStyle(void);
|
||||
|
||||
void SaveToken(CToken* aToken, PRInt32 aID);
|
||||
CToken* RestoreTokenFrom(PRInt32 aID);
|
||||
PRInt32 TokenCountAt(PRInt32 aID);
|
||||
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 {return TagAt(anIndex);}
|
||||
PRBool HasOpenContainer(eHTMLTags aTag) const;
|
||||
PRInt32 GetTopmostIndexOf(eHTMLTags aTag) const;
|
||||
|
||||
void Empty(void);
|
||||
PRInt32 GetCount(void);
|
||||
nsEntryStack* GetStylesAt(PRInt32 anIndex) const;
|
||||
void PushStyle(const nsIParserNode* aNode);
|
||||
void PushStyles(nsEntryStack *theStyles);
|
||||
nsIParserNode* PopStyle(void);
|
||||
nsIParserNode* PopStyle(eHTMLTags aTag);
|
||||
|
||||
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);
|
||||
|
@ -28,18 +28,7 @@
|
||||
*/
|
||||
|
||||
#include "nsElementTable.h"
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @update gess 01/04/99
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
PRBool Contains(eHTMLTags aTag,TagList& aTagList){
|
||||
PRBool result=FindTagInSet(aTag,aTagList.mTags,aTagList.mCount);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
@ -47,11 +36,30 @@ PRBool Contains(eHTMLTags aTag,TagList& aTagList){
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
PRInt32 GetTopmostIndexOf(nsEntryStack& aTagStack,TagList& aTagList){
|
||||
int max = aTagStack.GetCount();
|
||||
int index=0;
|
||||
PRInt32 GetTopmostIndexOf(nsDTDContext& aContext,TagList& aTagList){
|
||||
int max = aContext.GetCount();
|
||||
int index;
|
||||
for(index=max-1;index>=0;index--){
|
||||
if(FindTagInSet(aTagStack[index],aTagList.mTags,aTagList.mCount)) {
|
||||
PRBool result=FindTagInSet(aContext[index],aTagList.mTags,aTagList.mCount);
|
||||
if(result) {
|
||||
return index;
|
||||
}
|
||||
}
|
||||
return kNotFound;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @update gess 01/04/99
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
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,16 +147,18 @@ 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;
|
||||
|
||||
/**
|
||||
* Construct a content sink stream.
|
||||
* @update gpk02/03/99
|
||||
* @update gpk02/03/99
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
@ -187,9 +191,10 @@ nsHTMLToTXTSinkStream::nsHTMLToTXTSinkStream()
|
||||
mOLStackIndex = 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @update gpk02/03/99
|
||||
* @update gpk02/03/99
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
@ -206,7 +211,7 @@ nsHTMLToTXTSinkStream::~nsHTMLToTXTSinkStream()
|
||||
|
||||
/**
|
||||
*
|
||||
* @update gpk04/30/99
|
||||
* @update gpk04/30/99
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
@ -224,10 +229,11 @@ nsHTMLToTXTSinkStream::Initialize(nsIOutputStream* aOutStream,
|
||||
|
||||
/**
|
||||
*
|
||||
* @update gpk04/30/99
|
||||
* @update gpk04/30/99
|
||||
* @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.
|
||||
@ -246,10 +254,9 @@ nsHTMLToTXTSinkStream::SetCharsetOverride(const nsString* aCharset)
|
||||
* @update gpk02/03/99
|
||||
* @param nsString reference to new title value
|
||||
* @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,12 +440,14 @@ 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) ||
|
||||
(mFlags & nsIDocumentEncoder::OutputWrap))) {
|
||||
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);
|
||||
char cbuf[40];
|
||||
PR_snprintf(cbuf, sizeof(cbuf), "%ld.", (mOLStack[mOLStackIndex-1])++);
|
||||
temp = cbuf;
|
||||
}
|
||||
else
|
||||
number += "#";
|
||||
temp += Spaces(gOLNumberWidth - number.Length()) + number + '.';
|
||||
temp = "#";
|
||||
}
|
||||
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;
|
||||
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)
|
||||
{
|
||||
nsAutoString url;
|
||||
if (NS_SUCCEEDED(GetValueOfAttribute(aNode, "src", url)))
|
||||
case eHTMLTag_table:
|
||||
case eHTMLTag_ul:
|
||||
case eHTMLTag_ol:
|
||||
case eHTMLTag_p:
|
||||
{
|
||||
nsAutoString temp, desc;
|
||||
if (NS_SUCCEEDED(GetValueOfAttribute(aNode, "alt", desc)))
|
||||
{
|
||||
temp += " (";
|
||||
temp += desc;
|
||||
temp += " <URL:";
|
||||
temp += url;
|
||||
temp += ">) ";
|
||||
}
|
||||
else
|
||||
{
|
||||
temp += " <URL:";
|
||||
temp += url;
|
||||
temp += "> ";
|
||||
}
|
||||
Write(temp);
|
||||
EnsureVerticalSpace((mFlags & nsIDocumentEncoder::OutputFormatted) ? 1 : 0);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
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,23 +712,13 @@ 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;
|
||||
}
|
||||
|
||||
void nsHTMLToTXTSinkStream::EnsureBufferSize(PRInt32 aNewSize)
|
||||
{
|
||||
if (mBufferSize < aNewSize)
|
||||
if (mBufferSize < aNewSize)
|
||||
{
|
||||
nsAllocator::Free(mBuffer);
|
||||
mBufferSize = 2*aNewSize+1; // make the twice as large
|
||||
@ -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(mCurrentLine);
|
||||
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;
|
||||
// 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;
|
||||
}
|
||||
|
||||
tempstr.Append(" ");
|
||||
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,16 +507,20 @@ 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);
|
||||
CToken* textToken=theRecycler->CreateTokenOfType(eToken_text,theTag);
|
||||
result=((CTextToken*)textToken)->ConsumeUntil(0,PR_TRUE,aScanner,endTag,mParseMode); //tell new token to finish consuming text...
|
||||
//endTag.Append(">");
|
||||
CToken* endToken=theRecycler->CreateTokenOfType(eToken_end,theTag,endTag);
|
||||
AddToken(textToken,result,mTokenDeque,theRecycler);
|
||||
AddToken(endToken,result,mTokenDeque,theRecycler);
|
||||
nsAutoString endTag(nsHTMLTags::GetStringValue(theTag));
|
||||
endTag.Insert("</",0,2);
|
||||
CToken* textToken=theRecycler->CreateTokenOfType(eToken_text,theTag);
|
||||
result=((CTextToken*)textToken)->ConsumeUntil(0,PR_TRUE,aScanner,endTag,mParseMode); //tell new token to finish consuming text...
|
||||
//endTag.Append(">");
|
||||
CToken* endToken=theRecycler->CreateTokenOfType(eToken_end,theTag,endTag);
|
||||
AddToken(textToken,result,mTokenDeque,theRecycler);
|
||||
AddToken(endToken,result,mTokenDeque,theRecycler);
|
||||
}
|
||||
}
|
||||
|
||||
//EEEEECCCCKKKK!!!
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
@ -88,6 +88,8 @@ protected:
|
||||
virtual nsresult ConsumeText(const nsString& aString,CToken*& aToken,nsScanner& aScanner);
|
||||
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);
|
||||
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
/*
|
||||
@ -217,8 +222,10 @@ nsresult CStartToken::Consume(PRUnichar aChar, nsScanner& aScanner,PRInt32 aMode
|
||||
//Good. Now, let's skip whitespace after the identifier,
|
||||
//and see if the next char is ">". If so, we have a complete
|
||||
//tag without attributes.
|
||||
if(NS_OK==result) {
|
||||
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) {
|
||||
|
@ -113,25 +113,27 @@ protected:
|
||||
*/
|
||||
class CStartToken: public CHTMLToken {
|
||||
public:
|
||||
CStartToken(eHTMLTags aTag);
|
||||
CStartToken(nsString& aName,eHTMLTags aTag=eHTMLTag_unknown);
|
||||
virtual nsresult Consume(PRUnichar aChar,nsScanner& aScanner,PRInt32 aMode);
|
||||
virtual PRInt32 GetTypeID(void);
|
||||
virtual const char* GetClassName(void);
|
||||
virtual PRInt32 GetTokenType(void);
|
||||
CStartToken(eHTMLTags aTag);
|
||||
CStartToken(nsString& aName,eHTMLTags aTag=eHTMLTag_unknown);
|
||||
virtual nsresult Consume(PRUnichar aChar,nsScanner& aScanner,PRInt32 aMode);
|
||||
virtual PRInt32 GetTypeID(void);
|
||||
virtual const char* GetClassName(void);
|
||||
virtual PRInt32 GetTokenType(void);
|
||||
|
||||
PRBool IsAttributed(void);
|
||||
void SetAttributed(PRBool aValue);
|
||||
PRBool IsEmpty(void);
|
||||
void SetEmpty(PRBool aValue);
|
||||
virtual void DebugDumpSource(nsOutputStream& out);
|
||||
virtual void GetSource(nsString& anOutputString);
|
||||
PRBool IsAttributed(void);
|
||||
void SetAttributed(PRBool aValue);
|
||||
PRBool IsEmpty(void);
|
||||
void SetEmpty(PRBool aValue);
|
||||
virtual void DebugDumpSource(nsOutputStream& out);
|
||||
virtual void GetSource(nsString& anOutputString);
|
||||
|
||||
virtual void Reinitialize(PRInt32 aTag, const nsString& aString);
|
||||
virtual void Reinitialize(PRInt32 aTag, const nsString& aString);
|
||||
|
||||
nsAutoString mTrailingContent;
|
||||
PRInt32 mOrigin;
|
||||
protected:
|
||||
PRBool mAttributed;
|
||||
PRBool mEmpty;
|
||||
PRBool mAttributed;
|
||||
PRBool mEmpty;
|
||||
};
|
||||
|
||||
|
||||
@ -272,9 +274,10 @@ class CAttributeToken: public CHTMLToken {
|
||||
PRBool mLastAttribute;
|
||||
virtual void Reinitialize(PRInt32 aTag, const nsString& aString);
|
||||
|
||||
protected:
|
||||
nsString mTextKey;
|
||||
};
|
||||
PRBool mHasEqualWithoutValue;
|
||||
nsString mTextKey;
|
||||
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
|
@ -106,10 +106,11 @@ class nsIDTD : public nsISupports {
|
||||
* @param aFilename--string that contains name of file being parsed (if applicable)
|
||||
* @return
|
||||
*/
|
||||
NS_IMETHOD WillBuildModel( nsString& aFilename,
|
||||
PRBool aNotifySink,
|
||||
nsString& aSourceType,
|
||||
NS_IMETHOD WillBuildModel( nsString& aFilename,
|
||||
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
|
||||
(*gDumpFile) << theHeader << endl;
|
||||
(*gDumpFile) << "<viewsource xmlns=\"viewsource\">" << endl;
|
||||
#endif
|
||||
#ifdef rickgdebug
|
||||
(*gDumpFile) << theHeader << endl;
|
||||
(*gDumpFile) << "<viewsource xmlns=\"viewsource\">" << endl;
|
||||
#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
|
||||
|
||||
//now let's automatically close the root container...
|
||||
CToken theToken("viewsource");
|
||||
nsCParserNode theNode(&theToken,0);
|
||||
mSink->CloseContainer(theNode);
|
||||
|
||||
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;
|
||||
|
||||
mParser->GetDocumentCharset(charsetValue,charsetSource);
|
||||
eHTMLTags theTag = (eHTMLTags)aToken->GetTypeID();
|
||||
result=theService.Notify(theTag,theContext.mTokenNode,(PRUint32)theDocID,
|
||||
kViewSourceCommand,charsetValue,charsetSource);
|
||||
eHTMLTags theTag=(eHTMLTags)theToken->GetTypeID();
|
||||
|
||||
result=theService.Notify(theTag,theContext.mTokenNode,(PRUint32)theDocID,kViewSourceCommand,mParser);
|
||||
}
|
||||
theContext.mTokenNode.Init(0,0,gTokenRecycler); //now recycle.
|
||||
break;
|
||||
|
@ -108,11 +108,12 @@ 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,
|
||||
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
|
||||
@ -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,11 +156,12 @@ class nsXIFDTD : public nsIDTD {
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
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
|
||||
|
Loading…
Reference in New Issue
Block a user