97769 - Replace nsITagStack with a simple nsVoidArray. Also, nuked nsITagStack since it is not of a big help.r=heikki, sr=jst.

99282  - Make sure only HEAD attributes get added to the attribute list in ::OpenHead(). r=heikki, sr=jst.
100466 - Stop DT from containing DL.r=heikki,sr=jst.
102370 - DT should not close DD and vice versa.r=heikki,sr=jst.
100397 - In order for residual style to kick in...disable the check for wellformedness in quirks mode.r=alexandru,sr=attinasi.
102376 - Release nsIRequest in nsParser::DidBuildModel() since nsIRequest is not required past DidBuildModel.r=heikki,sr=darin.
This commit is contained in:
harishd%netscape.com 2001-10-19 20:48:18 +00:00
Родитель ac09dc9ddc
Коммит ac2e3f5bc1
40 изменённых файлов: 270 добавлений и 437 удалений

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

@ -2261,7 +2261,7 @@ nsRange::CreateContextualFragment(const nsAReadableString& aFragment,
{
nsresult result = NS_OK;
nsCOMPtr<nsIParser> parser;
nsITagStack* tagStack;
nsVoidArray tagStack;
if (!mIsPositioned) {
return NS_ERROR_FAILURE;
@ -2273,135 +2273,130 @@ nsRange::CreateContextualFragment(const nsAReadableString& aFragment,
NS_GET_IID(nsIParser),
(void **)getter_AddRefs(parser));
if (NS_SUCCEEDED(result)) {
result = parser->CreateTagStack(&tagStack);
nsCOMPtr<nsIDOMNode> parent;
nsCOMPtr<nsIContent> content(do_QueryInterface(mStartParent, &result));
if (NS_SUCCEEDED(result)) {
nsCOMPtr<nsIDOMNode> parent;
nsCOMPtr<nsIContent> content(do_QueryInterface(mStartParent, &result));
nsCOMPtr<nsIDocument> document;
nsCOMPtr<nsIDOMDocument> domDocument;
result = content->GetDocument(*getter_AddRefs(document));
if (document && NS_SUCCEEDED(result)) {
domDocument = do_QueryInterface(document, &result);
}
if (NS_SUCCEEDED(result)) {
nsCOMPtr<nsIDocument> document;
nsCOMPtr<nsIDOMDocument> domDocument;
parent = mStartParent;
while (parent &&
(parent != domDocument) &&
NS_SUCCEEDED(result)) {
nsCOMPtr<nsIDOMNode> temp;
nsAutoString tagName;
PRUnichar* name = nsnull;
PRUint16 nodeType;
result = content->GetDocument(*getter_AddRefs(document));
if (document && NS_SUCCEEDED(result)) {
domDocument = do_QueryInterface(document, &result);
}
parent = mStartParent;
while (parent &&
(parent != domDocument) &&
NS_SUCCEEDED(result)) {
nsCOMPtr<nsIDOMNode> temp;
nsAutoString tagName;
PRUnichar* name = nsnull;
PRUint16 nodeType;
parent->GetNodeType(&nodeType);
if (nsIDOMNode::ELEMENT_NODE == nodeType) {
parent->GetNodeName(tagName);
// XXX Wish we didn't have to allocate here
name = ToNewUnicode(tagName);
if (name) {
tagStack->Push(name);
temp = parent;
result = temp->GetParentNode(getter_AddRefs(parent));
}
else {
result = NS_ERROR_OUT_OF_MEMORY;
}
}
else {
parent->GetNodeType(&nodeType);
if (nsIDOMNode::ELEMENT_NODE == nodeType) {
parent->GetNodeName(tagName);
// XXX Wish we didn't have to allocate here
name = ToNewUnicode(tagName);
if (name) {
tagStack.AppendElement(name);
temp = parent;
result = temp->GetParentNode(getter_AddRefs(parent));
}
else {
result = NS_ERROR_OUT_OF_MEMORY;
}
}
else {
temp = parent;
result = temp->GetParentNode(getter_AddRefs(parent));
}
}
if (NS_SUCCEEDED(result)) {
nsAutoString contentType;
nsIHTMLFragmentContentSink* sink;
result = NS_NewHTMLFragmentContentSink(&sink);
if (NS_SUCCEEDED(result)) {
nsAutoString contentType;
nsIHTMLFragmentContentSink* sink;
result = NS_NewHTMLFragmentContentSink(&sink);
if (NS_SUCCEEDED(result)) {
parser->SetContentSink(sink);
nsCOMPtr<nsIDOMNSDocument> domnsDocument(do_QueryInterface(document));
if (domnsDocument) {
domnsDocument->GetContentType(contentType);
}
else {
// Who're we kidding. This only works for html.
contentType.Assign(NS_LITERAL_STRING("text/html"));
}
parser->SetContentSink(sink);
nsCOMPtr<nsIDOMNSDocument> domnsDocument(do_QueryInterface(document));
if (domnsDocument) {
domnsDocument->GetContentType(contentType);
}
else {
// Who're we kidding. This only works for html.
contentType.Assign(NS_LITERAL_STRING("text/html"));
}
// If there's no JS or system JS running,
// push the current document's context on the JS context stack
// so that event handlers in the fragment do not get
// compiled with the system principal.
nsCOMPtr<nsIJSContextStack> ContextStack;
nsCOMPtr<nsIScriptSecurityManager> secMan;
secMan = do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, &result);
if (document && NS_SUCCEEDED(result)) {
nsCOMPtr<nsIPrincipal> sysPrin;
nsCOMPtr<nsIPrincipal> subjectPrin;
// If there's no JS or system JS running,
// push the current document's context on the JS context stack
// so that event handlers in the fragment do not get
// compiled with the system principal.
nsCOMPtr<nsIJSContextStack> ContextStack;
nsCOMPtr<nsIScriptSecurityManager> secMan;
secMan = do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, &result);
if (document && NS_SUCCEEDED(result)) {
nsCOMPtr<nsIPrincipal> sysPrin;
nsCOMPtr<nsIPrincipal> subjectPrin;
// Just to compare, not to use!
result = secMan->GetSystemPrincipal(getter_AddRefs(sysPrin));
if (NS_SUCCEEDED(result))
result = secMan->GetSubjectPrincipal(getter_AddRefs(subjectPrin));
// If there's no subject principal, there's no JS running, so we're in system code.
// (just in case...null subject principal will probably never happen)
if (NS_SUCCEEDED(result) &&
(!subjectPrin || sysPrin.get() == subjectPrin.get())) {
nsCOMPtr<nsIScriptGlobalObject> globalObj;
result = document->GetScriptGlobalObject(getter_AddRefs(globalObj));
// Just to compare, not to use!
result = secMan->GetSystemPrincipal(getter_AddRefs(sysPrin));
if (NS_SUCCEEDED(result))
result = secMan->GetSubjectPrincipal(getter_AddRefs(subjectPrin));
// If there's no subject principal, there's no JS running, so we're in system code.
// (just in case...null subject principal will probably never happen)
if (NS_SUCCEEDED(result) &&
(!subjectPrin || sysPrin.get() == subjectPrin.get())) {
nsCOMPtr<nsIScriptGlobalObject> globalObj;
result = document->GetScriptGlobalObject(getter_AddRefs(globalObj));
nsCOMPtr<nsIScriptContext> scriptContext;
if (NS_SUCCEEDED(result) && globalObj) {
result = globalObj->GetContext(getter_AddRefs(scriptContext));
}
nsCOMPtr<nsIScriptContext> scriptContext;
if (NS_SUCCEEDED(result) && globalObj) {
result = globalObj->GetContext(getter_AddRefs(scriptContext));
}
JSContext* cx = nsnull;
if (NS_SUCCEEDED(result) && scriptContext) {
cx = (JSContext*)scriptContext->GetNativeContext();
}
JSContext* cx = nsnull;
if (NS_SUCCEEDED(result) && scriptContext) {
cx = (JSContext*)scriptContext->GetNativeContext();
}
if(cx) {
ContextStack = do_GetService("@mozilla.org/js/xpc/ContextStack;1", &result);
if(NS_SUCCEEDED(result)) {
result = ContextStack->Push(cx);
}
if(cx) {
ContextStack = do_GetService("@mozilla.org/js/xpc/ContextStack;1", &result);
if(NS_SUCCEEDED(result)) {
result = ContextStack->Push(cx);
}
}
}
result = parser->ParseFragment(aFragment, (void*)0,
*tagStack,
0, contentType);
if (ContextStack) {
JSContext *notused;
ContextStack->Pop(&notused);
}
if (NS_SUCCEEDED(result)) {
sink->GetFragment(aReturn);
}
NS_RELEASE(sink);
}
result = parser->ParseFragment(aFragment, (void*)0,
tagStack,
0, contentType);
if (ContextStack) {
JSContext *notused;
ContextStack->Pop(&notused);
}
if (NS_SUCCEEDED(result)) {
sink->GetFragment(aReturn);
}
NS_RELEASE(sink);
}
}
// XXX Ick! Delete strings we allocated above.
PRUnichar* str = nsnull;
str = tagStack->Pop();
while (str) {
nsCRT::free(str);
str = tagStack->Pop();
}
}
// XXX Double Ick! Deleting something that someone else newed.
delete tagStack;
// XXX Ick! Delete strings we allocated above.
PRInt32 count = tagStack.Count();
for (PRInt32 i = 0; i < count; i++) {
PRUnichar* str = (PRUnichar*)tagStack.ElementAt(i);
if (str) {
nsCRT::free(str);
}
}
}

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

@ -3133,7 +3133,7 @@ HTMLContentSink::OpenHead(const nsIParserNode& aNode)
mContextStack.AppendElement(mCurrentContext);
mCurrentContext = mHeadContext;
if (nsnull != mHead) {
if (mHead && aNode.GetNodeType() == eHTMLTag_head) {
rv = AddAttributes(aNode, mHead);
}

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

@ -53,7 +53,7 @@
#include "nsIDTD.h"
#include "nsIInputStream.h"
#include "nsHashtable.h"
#include "nsVoidArray.h"
#define NS_IPARSER_IID \
{0x355cbba0, 0xbf7d, 0x11d1, \
@ -111,15 +111,6 @@ typedef enum {
enum eStreamState {eNone,eOnStart,eOnDataAvail,eOnStop};
class nsITagStack {
public:
virtual void Push(PRUnichar* aTag)=0;
virtual PRUnichar* Pop(void)=0;
virtual PRUnichar* TagAt(PRUint32 anIndex)=0;
virtual PRUint32 GetSize(void)=0;
};
/**
* FOR DEBUG PURPOSE ONLY
*
@ -200,14 +191,6 @@ class nsIParser : public nsISupports {
virtual nsIParserFilter* SetParserFilter(nsIParserFilter* aFilter) = 0;
/**
* Call this to get a newly constructed tagstack
* @update gess 5/05/99
* @param aTagStack is an out parm that will contain your result
* @return NS_OK if successful, or NS_HTMLPARSER_MEMORY_ERROR on error
*/
virtual nsresult CreateTagStack(nsITagStack** aTagStack)=0;
/**
* Get the channel associated with this parser
* @update harishd,gagan 07/17/01
@ -251,7 +234,12 @@ class nsIParser : public nsISupports {
virtual nsresult Terminate(void) = 0;
virtual nsresult ParseFragment(const nsAReadableString& aSourceBuffer,void* aKey,nsITagStack& aStack,PRUint32 anInsertPos,const nsString& aContentType,nsDTDMode aMode=eDTDMode_autodetect)=0;
virtual nsresult ParseFragment(const nsAReadableString& aSourceBuffer,
void* aKey,
nsVoidArray& aTagStack,
PRUint32 anInsertPos,
const nsString& aContentType,
nsDTDMode aMode=eDTDMode_autodetect) = 0;
/**
* This method gets called when the tokens have been consumed, and it's time

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

@ -48,10 +48,11 @@
#include "nsIParser.h"
#include "nsIURL.h"
#include "nsIDTD.h"
#include "nsScanner.h"
#include "nsIStreamListener.h"
#include "nsString.h"
#include "nsIRequest.h"
#include "nsScanner.h"
#include "nsString.h"
#include "nsCOMPtr.h"
/**
* Note that the parser is given FULL access to all
@ -78,30 +79,28 @@ public:
void SetMimeType(nsAReadableString& aMimeType);
CParserContext* mPrevContext;
nsDTDMode mDTDMode;
eParserDocType mDocType;
nsAutoString mMimeType;
eStreamState mStreamListenerState; //this is really only here for debug purposes.
PRBool mMultipart;
eContextType mContextType;
eAutoDetectResult mAutoDetectStatus;
eParserCommands mParserCommand; //tells us to viewcontent/viewsource/viewerrors...
// Why is mRequest a strong reference? Refer to bug 102376
nsCOMPtr<nsIRequest> mRequest; // provided by necko to differnciate different input streams
nsScanner* mScanner;
nsIDTD* mDTD;
nsIDTD* mValidator;
char* mTransferBuffer;
// why is mRequest strongly referenced? see bug 102376.
nsIDTD* mDTD;
nsIDTD* mValidator;
nsIRequestObserver* mListener;
void* mKey;
PRUint32 mTransferBufferSize;
PRBool mCopyUnused;
char* mTransferBuffer;
void* mKey;
CParserContext* mPrevContext;
nsScanner* mScanner;
nsAutoString mMimeType;
nsDTDMode mDTDMode;
eParserDocType mDocType;
eStreamState mStreamListenerState; //this is really only here for debug purposes.
eContextType mContextType;
eAutoDetectResult mAutoDetectStatus;
eParserCommands mParserCommand; //tells us to viewcontent/viewsource/viewerrors...
PRBool mMultipart;
PRBool mCopyUnused;
PRUint32 mTransferBufferSize;
};

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

@ -147,7 +147,7 @@ TagList gHeadingTags={6,{eHTMLTag_h1,eHTMLTag_h2,eHTMLTag_h3,eHTMLTag_h4,eHTMLT
TagList gTableCloseTags={6,{eHTMLTag_td,eHTMLTag_tr,eHTMLTag_th,eHTMLTag_tbody,eHTMLTag_thead,eHTMLTag_tfoot}};
TagList gTRCloseTags={3,{eHTMLTag_tr,eHTMLTag_td,eHTMLTag_th}};
TagList gTDCloseTags={2,{eHTMLTag_td,eHTMLTag_th}};
TagList gDTCloseTags={3,{eHTMLTag_dt,eHTMLTag_dd,eHTMLTag_p}};
TagList gDTCloseTags={1,{eHTMLTag_p}};
TagList gULCloseTags={1,{eHTMLTag_li}};
TagList gULAutoClose={2,{eHTMLTag_p,eHTMLTag_ul}}; //fix bug 50261..
@ -454,7 +454,7 @@ void InitializeElementTable(void) {
/*req-parent excl-parent*/ eHTMLTag_unknown,eHTMLTag_unknown,
/*rootnodes,endrootnodes*/ &gRootTags, &gRootTags,
/*autoclose starttags and endtags*/ &gDTCloseTags,0,0,0,
/*parent,incl,exclgroups*/ kDLChild, kFlowEntity, kNone,
/*parent,incl,exclgroups*/ kDLChild|kInlineEntity, kFlowEntity|kDLChild, kNone, // added kDLChild to the inclusion bit - Refer bug 102370
/*special props, prop-range*/ kNoPropagate|kMustCloseSelf|kVerifyHierarchy,kDefaultPropRange,
/*special parents,kids,skip*/ &gInDL,0,eHTMLTag_unknown);
@ -498,7 +498,7 @@ void InitializeElementTable(void) {
/*tag*/ eHTMLTag_dl,
/*req-parent excl-parent*/ eHTMLTag_unknown,eHTMLTag_unknown,
/*rootnodes,endrootnodes*/ &gDLRootTags,&gRootTags, //fix bug 57634
/*autoclose starttags and endtags*/ 0,0,0,0,
/*autoclose starttags and endtags*/ 0,0,0,&gDLKids, // DT/DD should not contain DL - bug 100466
/*parent,incl,exclgroups*/ kBlock, kSelf|kFlowEntity, kNone,
/*special props, prop-range*/ kOmitWS, kNoPropRange,
/*special parents,kids,skip*/ 0,&gDLKids,eHTMLTag_unknown);
@ -508,8 +508,8 @@ void InitializeElementTable(void) {
/*req-parent excl-parent*/ eHTMLTag_unknown,eHTMLTag_unknown,
/*rootnodes,endrootnodes*/ &gRootTags, &gRootTags,
/*autoclose starttags and endtags*/ &gDTCloseTags,0,0,0,
/*parent,incl,exclgroups*/ kDLChild|kInlineEntity, kFlowEntity-kHeading, kNone, // dt's parent group is inline - bug 65467
/*special props, prop-range*/ (kNoPropagate|kMustCloseSelf),kDefaultPropRange,
/*parent,incl,exclgroups*/ kDLChild|kInlineEntity, (kFlowEntity-kHeading)|kDLChild, kNone, // dt's parent group is inline - bug 65467
/*special props, prop-range*/ (kNoPropagate|kMustCloseSelf),kDefaultPropRange, // // added kDLChild to the inclusion bit - Refer bug 102370
/*special parents,kids,skip*/ &gInDL,0,eHTMLTag_unknown);
Initialize(
@ -1940,13 +1940,15 @@ PRBool nsHTMLElement::IsResidualStyleTag(eHTMLTags aChild) {
case eHTMLTag_bdo:
case eHTMLTag_big:
case eHTMLTag_blink:
case eHTMLTag_del:
case eHTMLTag_del:
case eHTMLTag_em:
case eHTMLTag_font:
case eHTMLTag_i:
case eHTMLTag_ins:
case eHTMLTag_q:
case eHTMLTag_s:
case eHTMLTag_small:
case eHTMLTag_strong:
case eHTMLTag_strike:
case eHTMLTag_sub:
case eHTMLTag_sup:
@ -1961,11 +1963,9 @@ PRBool nsHTMLElement::IsResidualStyleTag(eHTMLTags aChild) {
case eHTMLTag_cite:
case eHTMLTag_code:
case eHTMLTag_dfn:
case eHTMLTag_em:
case eHTMLTag_kbd:
case eHTMLTag_samp:
case eHTMLTag_span:
case eHTMLTag_strong:
case eHTMLTag_var:
result=PR_FALSE;
default:

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

@ -460,7 +460,10 @@ nsresult nsHTMLTokenizer::ScanDocStructure(PRBool aFinalChunk) {
}
nsresult nsHTMLTokenizer::DidTokenize(PRBool aFinalChunk) {
return ScanDocStructure(aFinalChunk);
// Bug 100397
// In quirks mode we want residual style, in NavDTD, to kick
// in regardless of whether the document is wellformed or not.
return (mFlags & NS_IPARSER_FLAG_STRICT_MODE)? ScanDocStructure(aFinalChunk):NS_OK;
}
/**

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

@ -265,43 +265,6 @@ static CSharedParserObjects* gSharedParserObjects=0;
//-------------------------------------------------------------------------
/**********************************************************************************
This class is used as an interface between an external agent (like the DOM) and
the parser. It will contain a stack full of tagnames, which is used in our
parser/paste API's.
**********************************************************************************/
class nsTagStack : public nsITagStack {
public:
nsTagStack() : nsITagStack(), mTags(0) {
}
virtual ~nsTagStack() {
}
virtual void Push(PRUnichar* aTag){
mTags.Push(aTag);
}
virtual PRUnichar* Pop(void){
PRUnichar* result=(PRUnichar*)mTags.Pop();
return result;
}
virtual PRUnichar* TagAt(PRUint32 anIndex){
PRUnichar* result=0;
if(anIndex<(PRUint32)mTags.GetSize())
result=(PRUnichar*)mTags.ObjectAt(anIndex);
return result;
}
virtual PRUint32 GetSize(void){
return mTags.GetSize();
}
nsDeque mTags; //will hold a deque of prunichars...
};
CSharedParserObjects& GetSharedObjects() {
if (!gSharedParserObjects) {
gSharedParserObjects = new CSharedParserObjects();
@ -1418,6 +1381,7 @@ nsresult nsParser::DidBuildModel(nsresult anErrorCode) {
result = mParserContext->mDTD->DidBuildModel(anErrorCode,PRBool(0==mParserContext->mPrevContext),this,mSink);
}
//Ref. to bug 61462.
mParserContext->mRequest = 0;
}//if
}
@ -1778,55 +1742,31 @@ nsresult nsParser::Parse(const nsAReadableString& aSourceBuffer, void* aKey,
* @param
* @return
*/
nsresult nsParser::ParseFragment(const nsAReadableString& aSourceBuffer,void* aKey,nsITagStack& aStack,PRUint32 anInsertPos,const nsString& aMimeType,nsDTDMode aMode){
nsresult nsParser::ParseFragment(const nsAReadableString& aSourceBuffer,
void* aKey,
nsVoidArray& aTagStack,
PRUint32 anInsertPos,
const nsString& aMimeType,
nsDTDMode aMode){
nsresult result=NS_OK;
nsresult result = NS_OK;
nsAutoString theContext;
PRUint32 theCount=aStack.GetSize();
PRUint32 theIndex=0;
while(theIndex++<theCount){
PRUint32 theCount = aTagStack.Count();
PRUint32 theIndex = 0;
while (theIndex++ < theCount){
theContext.AppendWithConversion("<");
theContext.Append(aStack.TagAt(theCount-theIndex));
theContext.Append((PRUnichar*)aTagStack.ElementAt(theCount - theIndex));
theContext.AppendWithConversion(">");
}
theContext.AppendWithConversion("<endnote>"); //XXXHack! I'll make this better later.
nsAutoString theBuffer(theContext);
//now it's time to try to build the model from this fragment
#if 0
//use this to force a buffer-full of content as part of a paste operation...
theBuffer.Append("<title>title</title><a href=\"one\">link</a>");
#else
//#define USEFILE
#ifdef USEFILE
const char* theFile="c:/temp/rhp.html";
fstream input(theFile,ios::in);
char buffer[1024];
int count=1;
while(count) {
input.getline(buffer,sizeof(buffer));
count=input.gcount();
if(0<count) {
buffer[count-1]=0;
theBuffer.Append(buffer,count-1);
}
}
#else
//this is the normal code path for paste...
theBuffer.Append(aSourceBuffer);
#endif
#endif
if(theBuffer.Length()){
//now it's time to try to build the model from this fragment
mObserversEnabled=PR_FALSE; //disable observers for fragments
result=Parse(theBuffer,(void*)&theBuffer,aMimeType,PR_FALSE,PR_TRUE);
mObserversEnabled=PR_TRUE; //now reenable.
}
mObserversEnabled = PR_FALSE; //disable observers for fragments
result = Parse(theContext + aSourceBuffer,(void*)&theContext,aMimeType,PR_FALSE,PR_TRUE);
mObserversEnabled = PR_TRUE; //now reenable.
return result;
}
@ -2108,10 +2048,11 @@ nsresult nsParser::OnStartRequest(nsIRequest *request, nsISupports* aContext) {
if (nsnull != mObserver) {
mObserver->OnStartRequest(request, aContext);
}
mParserContext->mStreamListenerState=eOnStart;
mParserContext->mAutoDetectStatus=eUnknownDetect;
mParserContext->mRequest=request;
mParserContext->mDTD=0;
mParserContext->mStreamListenerState = eOnStart;
mParserContext->mAutoDetectStatus = eUnknownDetect;
mParserContext->mDTD = 0;
mParserContext->mRequest = request;
nsresult rv;
char* contentType = nsnull;
nsCOMPtr<nsIChannel> channel = do_QueryInterface(request);
@ -2724,20 +2665,6 @@ void nsParser::DebugDumpSource(nsOutputStream& aStream) {
}
#endif
/**
* Call this to get a newly constructed tagstack
* @update gess 5/05/99
* @param aTagStack is an out parm that will contain your result
* @return NS_OK if successful, or NS_HTMLPARSER_MEMORY_ERROR on error
*/
nsresult nsParser::CreateTagStack(nsITagStack** aTagStack){
*aTagStack=new nsTagStack();
if(*aTagStack)
return NS_OK;
return NS_ERROR_OUT_OF_MEMORY;
}
/**
* Get the channel associated with this parser
* @update harishd,gagan 07/17/01

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

@ -215,7 +215,12 @@ class nsParser : public nsIParser,
*/
virtual nsresult Parse(const nsAReadableString& aSourceBuffer,void* aKey,const nsAReadableString& aContentType,PRBool aEnableVerify=PR_FALSE,PRBool aLastCall=PR_FALSE,nsDTDMode aMode=eDTDMode_autodetect);
virtual nsresult ParseFragment(const nsAReadableString& aSourceBuffer,void* aKey,nsITagStack& aStack,PRUint32 anInsertPos,const nsString& aContentType,nsDTDMode aMode=eDTDMode_autodetect);
virtual nsresult ParseFragment(const nsAReadableString& aSourceBuffer,
void* aKey,
nsVoidArray& aTagStack,
PRUint32 anInsertPos,
const nsString& aContentType,
nsDTDMode aMode=eDTDMode_autodetect);
/**
@ -295,14 +300,6 @@ class nsParser : public nsIParser,
*/
virtual nsITokenizer* GetTokenizer(void);
/**
* Call this to get a newly constructed tagstack
* @update gess 5/05/99
* @param aTagStack is an out parm that will contain your result
* @return NS_OK if successful, or NS_HTMLPARSER_MEMORY_ERROR on error
*/
virtual nsresult CreateTagStack(nsITagStack** aTagStack);
/**
* Get the channel associated with this parser
* @update harishd,gagan 07/17/01

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

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

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

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

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

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

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

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

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

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

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

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

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

@ -19,19 +19,24 @@
#
# Contributor(s):
DEPTH=..\..\..
DEPTH =..\..\..
REQUIRES = \
xpcom \
htmlparser\
necko \
string \
$NULL
MAKE_OBJ_TYPE = EXE
MAKE_OBJ_TYPE = EXE
PROGRAM = .\$(OBJDIR)\TestParser.exe
OBJS = \
.\$(OBJDIR)\TestParser.obj \
OBJS = \
.\$(OBJDIR)\TestParser.obj\
$(NULL)
LLIBS= \
$(DIST)\lib\xpcom.lib \
LLIBS = \
$(DIST)\lib\xpcom.lib \
$(LIBNSPR) \
$(NULL)

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

@ -53,7 +53,7 @@
#include "nsIDTD.h"
#include "nsIInputStream.h"
#include "nsHashtable.h"
#include "nsVoidArray.h"
#define NS_IPARSER_IID \
{0x355cbba0, 0xbf7d, 0x11d1, \
@ -111,15 +111,6 @@ typedef enum {
enum eStreamState {eNone,eOnStart,eOnDataAvail,eOnStop};
class nsITagStack {
public:
virtual void Push(PRUnichar* aTag)=0;
virtual PRUnichar* Pop(void)=0;
virtual PRUnichar* TagAt(PRUint32 anIndex)=0;
virtual PRUint32 GetSize(void)=0;
};
/**
* FOR DEBUG PURPOSE ONLY
*
@ -200,14 +191,6 @@ class nsIParser : public nsISupports {
virtual nsIParserFilter* SetParserFilter(nsIParserFilter* aFilter) = 0;
/**
* Call this to get a newly constructed tagstack
* @update gess 5/05/99
* @param aTagStack is an out parm that will contain your result
* @return NS_OK if successful, or NS_HTMLPARSER_MEMORY_ERROR on error
*/
virtual nsresult CreateTagStack(nsITagStack** aTagStack)=0;
/**
* Get the channel associated with this parser
* @update harishd,gagan 07/17/01
@ -251,7 +234,12 @@ class nsIParser : public nsISupports {
virtual nsresult Terminate(void) = 0;
virtual nsresult ParseFragment(const nsAReadableString& aSourceBuffer,void* aKey,nsITagStack& aStack,PRUint32 anInsertPos,const nsString& aContentType,nsDTDMode aMode=eDTDMode_autodetect)=0;
virtual nsresult ParseFragment(const nsAReadableString& aSourceBuffer,
void* aKey,
nsVoidArray& aTagStack,
PRUint32 anInsertPos,
const nsString& aContentType,
nsDTDMode aMode=eDTDMode_autodetect) = 0;
/**
* This method gets called when the tokens have been consumed, and it's time

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

@ -48,10 +48,11 @@
#include "nsIParser.h"
#include "nsIURL.h"
#include "nsIDTD.h"
#include "nsScanner.h"
#include "nsIStreamListener.h"
#include "nsString.h"
#include "nsIRequest.h"
#include "nsScanner.h"
#include "nsString.h"
#include "nsCOMPtr.h"
/**
* Note that the parser is given FULL access to all
@ -78,30 +79,28 @@ public:
void SetMimeType(nsAReadableString& aMimeType);
CParserContext* mPrevContext;
nsDTDMode mDTDMode;
eParserDocType mDocType;
nsAutoString mMimeType;
eStreamState mStreamListenerState; //this is really only here for debug purposes.
PRBool mMultipart;
eContextType mContextType;
eAutoDetectResult mAutoDetectStatus;
eParserCommands mParserCommand; //tells us to viewcontent/viewsource/viewerrors...
// Why is mRequest a strong reference? Refer to bug 102376
nsCOMPtr<nsIRequest> mRequest; // provided by necko to differnciate different input streams
nsScanner* mScanner;
nsIDTD* mDTD;
nsIDTD* mValidator;
char* mTransferBuffer;
// why is mRequest strongly referenced? see bug 102376.
nsIDTD* mDTD;
nsIDTD* mValidator;
nsIRequestObserver* mListener;
void* mKey;
PRUint32 mTransferBufferSize;
PRBool mCopyUnused;
char* mTransferBuffer;
void* mKey;
CParserContext* mPrevContext;
nsScanner* mScanner;
nsAutoString mMimeType;
nsDTDMode mDTDMode;
eParserDocType mDocType;
eStreamState mStreamListenerState; //this is really only here for debug purposes.
eContextType mContextType;
eAutoDetectResult mAutoDetectStatus;
eParserCommands mParserCommand; //tells us to viewcontent/viewsource/viewerrors...
PRBool mMultipart;
PRBool mCopyUnused;
PRUint32 mTransferBufferSize;
};

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

@ -147,7 +147,7 @@ TagList gHeadingTags={6,{eHTMLTag_h1,eHTMLTag_h2,eHTMLTag_h3,eHTMLTag_h4,eHTMLT
TagList gTableCloseTags={6,{eHTMLTag_td,eHTMLTag_tr,eHTMLTag_th,eHTMLTag_tbody,eHTMLTag_thead,eHTMLTag_tfoot}};
TagList gTRCloseTags={3,{eHTMLTag_tr,eHTMLTag_td,eHTMLTag_th}};
TagList gTDCloseTags={2,{eHTMLTag_td,eHTMLTag_th}};
TagList gDTCloseTags={3,{eHTMLTag_dt,eHTMLTag_dd,eHTMLTag_p}};
TagList gDTCloseTags={1,{eHTMLTag_p}};
TagList gULCloseTags={1,{eHTMLTag_li}};
TagList gULAutoClose={2,{eHTMLTag_p,eHTMLTag_ul}}; //fix bug 50261..
@ -454,7 +454,7 @@ void InitializeElementTable(void) {
/*req-parent excl-parent*/ eHTMLTag_unknown,eHTMLTag_unknown,
/*rootnodes,endrootnodes*/ &gRootTags, &gRootTags,
/*autoclose starttags and endtags*/ &gDTCloseTags,0,0,0,
/*parent,incl,exclgroups*/ kDLChild, kFlowEntity, kNone,
/*parent,incl,exclgroups*/ kDLChild|kInlineEntity, kFlowEntity|kDLChild, kNone, // added kDLChild to the inclusion bit - Refer bug 102370
/*special props, prop-range*/ kNoPropagate|kMustCloseSelf|kVerifyHierarchy,kDefaultPropRange,
/*special parents,kids,skip*/ &gInDL,0,eHTMLTag_unknown);
@ -498,7 +498,7 @@ void InitializeElementTable(void) {
/*tag*/ eHTMLTag_dl,
/*req-parent excl-parent*/ eHTMLTag_unknown,eHTMLTag_unknown,
/*rootnodes,endrootnodes*/ &gDLRootTags,&gRootTags, //fix bug 57634
/*autoclose starttags and endtags*/ 0,0,0,0,
/*autoclose starttags and endtags*/ 0,0,0,&gDLKids, // DT/DD should not contain DL - bug 100466
/*parent,incl,exclgroups*/ kBlock, kSelf|kFlowEntity, kNone,
/*special props, prop-range*/ kOmitWS, kNoPropRange,
/*special parents,kids,skip*/ 0,&gDLKids,eHTMLTag_unknown);
@ -508,8 +508,8 @@ void InitializeElementTable(void) {
/*req-parent excl-parent*/ eHTMLTag_unknown,eHTMLTag_unknown,
/*rootnodes,endrootnodes*/ &gRootTags, &gRootTags,
/*autoclose starttags and endtags*/ &gDTCloseTags,0,0,0,
/*parent,incl,exclgroups*/ kDLChild|kInlineEntity, kFlowEntity-kHeading, kNone, // dt's parent group is inline - bug 65467
/*special props, prop-range*/ (kNoPropagate|kMustCloseSelf),kDefaultPropRange,
/*parent,incl,exclgroups*/ kDLChild|kInlineEntity, (kFlowEntity-kHeading)|kDLChild, kNone, // dt's parent group is inline - bug 65467
/*special props, prop-range*/ (kNoPropagate|kMustCloseSelf),kDefaultPropRange, // // added kDLChild to the inclusion bit - Refer bug 102370
/*special parents,kids,skip*/ &gInDL,0,eHTMLTag_unknown);
Initialize(
@ -1940,13 +1940,15 @@ PRBool nsHTMLElement::IsResidualStyleTag(eHTMLTags aChild) {
case eHTMLTag_bdo:
case eHTMLTag_big:
case eHTMLTag_blink:
case eHTMLTag_del:
case eHTMLTag_del:
case eHTMLTag_em:
case eHTMLTag_font:
case eHTMLTag_i:
case eHTMLTag_ins:
case eHTMLTag_q:
case eHTMLTag_s:
case eHTMLTag_small:
case eHTMLTag_strong:
case eHTMLTag_strike:
case eHTMLTag_sub:
case eHTMLTag_sup:
@ -1961,11 +1963,9 @@ PRBool nsHTMLElement::IsResidualStyleTag(eHTMLTags aChild) {
case eHTMLTag_cite:
case eHTMLTag_code:
case eHTMLTag_dfn:
case eHTMLTag_em:
case eHTMLTag_kbd:
case eHTMLTag_samp:
case eHTMLTag_span:
case eHTMLTag_strong:
case eHTMLTag_var:
result=PR_FALSE;
default:

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

@ -460,7 +460,10 @@ nsresult nsHTMLTokenizer::ScanDocStructure(PRBool aFinalChunk) {
}
nsresult nsHTMLTokenizer::DidTokenize(PRBool aFinalChunk) {
return ScanDocStructure(aFinalChunk);
// Bug 100397
// In quirks mode we want residual style, in NavDTD, to kick
// in regardless of whether the document is wellformed or not.
return (mFlags & NS_IPARSER_FLAG_STRICT_MODE)? ScanDocStructure(aFinalChunk):NS_OK;
}
/**

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

@ -265,43 +265,6 @@ static CSharedParserObjects* gSharedParserObjects=0;
//-------------------------------------------------------------------------
/**********************************************************************************
This class is used as an interface between an external agent (like the DOM) and
the parser. It will contain a stack full of tagnames, which is used in our
parser/paste API's.
**********************************************************************************/
class nsTagStack : public nsITagStack {
public:
nsTagStack() : nsITagStack(), mTags(0) {
}
virtual ~nsTagStack() {
}
virtual void Push(PRUnichar* aTag){
mTags.Push(aTag);
}
virtual PRUnichar* Pop(void){
PRUnichar* result=(PRUnichar*)mTags.Pop();
return result;
}
virtual PRUnichar* TagAt(PRUint32 anIndex){
PRUnichar* result=0;
if(anIndex<(PRUint32)mTags.GetSize())
result=(PRUnichar*)mTags.ObjectAt(anIndex);
return result;
}
virtual PRUint32 GetSize(void){
return mTags.GetSize();
}
nsDeque mTags; //will hold a deque of prunichars...
};
CSharedParserObjects& GetSharedObjects() {
if (!gSharedParserObjects) {
gSharedParserObjects = new CSharedParserObjects();
@ -1418,6 +1381,7 @@ nsresult nsParser::DidBuildModel(nsresult anErrorCode) {
result = mParserContext->mDTD->DidBuildModel(anErrorCode,PRBool(0==mParserContext->mPrevContext),this,mSink);
}
//Ref. to bug 61462.
mParserContext->mRequest = 0;
}//if
}
@ -1778,55 +1742,31 @@ nsresult nsParser::Parse(const nsAReadableString& aSourceBuffer, void* aKey,
* @param
* @return
*/
nsresult nsParser::ParseFragment(const nsAReadableString& aSourceBuffer,void* aKey,nsITagStack& aStack,PRUint32 anInsertPos,const nsString& aMimeType,nsDTDMode aMode){
nsresult nsParser::ParseFragment(const nsAReadableString& aSourceBuffer,
void* aKey,
nsVoidArray& aTagStack,
PRUint32 anInsertPos,
const nsString& aMimeType,
nsDTDMode aMode){
nsresult result=NS_OK;
nsresult result = NS_OK;
nsAutoString theContext;
PRUint32 theCount=aStack.GetSize();
PRUint32 theIndex=0;
while(theIndex++<theCount){
PRUint32 theCount = aTagStack.Count();
PRUint32 theIndex = 0;
while (theIndex++ < theCount){
theContext.AppendWithConversion("<");
theContext.Append(aStack.TagAt(theCount-theIndex));
theContext.Append((PRUnichar*)aTagStack.ElementAt(theCount - theIndex));
theContext.AppendWithConversion(">");
}
theContext.AppendWithConversion("<endnote>"); //XXXHack! I'll make this better later.
nsAutoString theBuffer(theContext);
//now it's time to try to build the model from this fragment
#if 0
//use this to force a buffer-full of content as part of a paste operation...
theBuffer.Append("<title>title</title><a href=\"one\">link</a>");
#else
//#define USEFILE
#ifdef USEFILE
const char* theFile="c:/temp/rhp.html";
fstream input(theFile,ios::in);
char buffer[1024];
int count=1;
while(count) {
input.getline(buffer,sizeof(buffer));
count=input.gcount();
if(0<count) {
buffer[count-1]=0;
theBuffer.Append(buffer,count-1);
}
}
#else
//this is the normal code path for paste...
theBuffer.Append(aSourceBuffer);
#endif
#endif
if(theBuffer.Length()){
//now it's time to try to build the model from this fragment
mObserversEnabled=PR_FALSE; //disable observers for fragments
result=Parse(theBuffer,(void*)&theBuffer,aMimeType,PR_FALSE,PR_TRUE);
mObserversEnabled=PR_TRUE; //now reenable.
}
mObserversEnabled = PR_FALSE; //disable observers for fragments
result = Parse(theContext + aSourceBuffer,(void*)&theContext,aMimeType,PR_FALSE,PR_TRUE);
mObserversEnabled = PR_TRUE; //now reenable.
return result;
}
@ -2108,10 +2048,11 @@ nsresult nsParser::OnStartRequest(nsIRequest *request, nsISupports* aContext) {
if (nsnull != mObserver) {
mObserver->OnStartRequest(request, aContext);
}
mParserContext->mStreamListenerState=eOnStart;
mParserContext->mAutoDetectStatus=eUnknownDetect;
mParserContext->mRequest=request;
mParserContext->mDTD=0;
mParserContext->mStreamListenerState = eOnStart;
mParserContext->mAutoDetectStatus = eUnknownDetect;
mParserContext->mDTD = 0;
mParserContext->mRequest = request;
nsresult rv;
char* contentType = nsnull;
nsCOMPtr<nsIChannel> channel = do_QueryInterface(request);
@ -2724,20 +2665,6 @@ void nsParser::DebugDumpSource(nsOutputStream& aStream) {
}
#endif
/**
* Call this to get a newly constructed tagstack
* @update gess 5/05/99
* @param aTagStack is an out parm that will contain your result
* @return NS_OK if successful, or NS_HTMLPARSER_MEMORY_ERROR on error
*/
nsresult nsParser::CreateTagStack(nsITagStack** aTagStack){
*aTagStack=new nsTagStack();
if(*aTagStack)
return NS_OK;
return NS_ERROR_OUT_OF_MEMORY;
}
/**
* Get the channel associated with this parser
* @update harishd,gagan 07/17/01

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

@ -215,7 +215,12 @@ class nsParser : public nsIParser,
*/
virtual nsresult Parse(const nsAReadableString& aSourceBuffer,void* aKey,const nsAReadableString& aContentType,PRBool aEnableVerify=PR_FALSE,PRBool aLastCall=PR_FALSE,nsDTDMode aMode=eDTDMode_autodetect);
virtual nsresult ParseFragment(const nsAReadableString& aSourceBuffer,void* aKey,nsITagStack& aStack,PRUint32 anInsertPos,const nsString& aContentType,nsDTDMode aMode=eDTDMode_autodetect);
virtual nsresult ParseFragment(const nsAReadableString& aSourceBuffer,
void* aKey,
nsVoidArray& aTagStack,
PRUint32 anInsertPos,
const nsString& aContentType,
nsDTDMode aMode=eDTDMode_autodetect);
/**
@ -295,14 +300,6 @@ class nsParser : public nsIParser,
*/
virtual nsITokenizer* GetTokenizer(void);
/**
* Call this to get a newly constructed tagstack
* @update gess 5/05/99
* @param aTagStack is an out parm that will contain your result
* @return NS_OK if successful, or NS_HTMLPARSER_MEMORY_ERROR on error
*/
virtual nsresult CreateTagStack(nsITagStack** aTagStack);
/**
* Get the channel associated with this parser
* @update harishd,gagan 07/17/01

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

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

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

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

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

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

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

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

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

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

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

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

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

@ -19,19 +19,24 @@
#
# Contributor(s):
DEPTH=..\..\..
DEPTH =..\..\..
REQUIRES = \
xpcom \
htmlparser\
necko \
string \
$NULL
MAKE_OBJ_TYPE = EXE
MAKE_OBJ_TYPE = EXE
PROGRAM = .\$(OBJDIR)\TestParser.exe
OBJS = \
.\$(OBJDIR)\TestParser.obj \
OBJS = \
.\$(OBJDIR)\TestParser.obj\
$(NULL)
LLIBS= \
$(DIST)\lib\xpcom.lib \
LLIBS = \
$(DIST)\lib\xpcom.lib \
$(LIBNSPR) \
$(NULL)