зеркало из https://github.com/mozilla/pjs.git
Converted parser into a module. Removed usage of static parser methods and used nsIParserService and nsIDTD methods instead. To be reviewed by RickG.
This commit is contained in:
Родитель
9690a811f2
Коммит
abef968cec
|
@ -49,6 +49,7 @@
|
|||
#include "nsIFormControl.h"
|
||||
|
||||
#include "nsIComponentManager.h"
|
||||
#include "nsIServiceManager.h"
|
||||
|
||||
#include "nsIScrollableView.h"
|
||||
#include "nsHTMLAtoms.h"
|
||||
|
@ -66,6 +67,9 @@
|
|||
#include "nsHTMLIIDs.h"
|
||||
#include "nsTextFragment.h"
|
||||
|
||||
#include "nsIParserService.h"
|
||||
#include "nsParserCIID.h"
|
||||
|
||||
// XXX Go through a factory for this one
|
||||
#include "nsICSSParser.h"
|
||||
|
||||
|
@ -109,29 +113,7 @@ static PRLogModuleInfo* gSinkLogModuleInfo;
|
|||
} \
|
||||
PR_END_MACRO
|
||||
|
||||
#define SINK_TRACE_NODE(_bit,_msg,_node) SinkTraceNode(_bit,_msg,_node,this)
|
||||
|
||||
|
||||
static void
|
||||
SinkTraceNode(PRUint32 aBit,
|
||||
const char* aMsg,
|
||||
const nsIParserNode& aNode,
|
||||
void* aThis)
|
||||
{
|
||||
if (SINK_LOG_TEST(gSinkLogModuleInfo,aBit)) {
|
||||
char cbuf[40];
|
||||
const char* cp;
|
||||
PRInt32 nt = aNode.GetNodeType();
|
||||
if ((nt > PRInt32(eHTMLTag_unknown)) &&
|
||||
(nt < PRInt32(eHTMLTag_text))) {
|
||||
cp = nsHTMLTags::GetStringValue(nsHTMLTag(aNode.GetNodeType()));
|
||||
} else {
|
||||
aNode.GetText().ToCString(cbuf, sizeof(cbuf));
|
||||
cp = cbuf;
|
||||
}
|
||||
PR_LogPrint("%s: this=%p node='%s'", aMsg, aThis, cp);
|
||||
}
|
||||
}
|
||||
#define SINK_TRACE_NODE(_bit,_msg,_node,_obj) _obj->SinkTraceNode(_bit,_msg,_node,this)
|
||||
|
||||
#else
|
||||
#define SINK_TRACE(_bit,_args)
|
||||
|
@ -189,6 +171,27 @@ public:
|
|||
|
||||
NS_IMETHOD DoFragment(PRBool aFlag);
|
||||
|
||||
void ReduceEntities(nsString& aString);
|
||||
void GetAttributeValueAt(const nsIParserNode& aNode,
|
||||
PRInt32 aIndex,
|
||||
nsString& aResult,
|
||||
nsIScriptContextOwner* aScriptContextOwner);
|
||||
nsresult AddAttributes(const nsIParserNode& aNode,
|
||||
nsIHTMLContent* aContent,
|
||||
nsIScriptContextOwner* aScriptContextOwner,
|
||||
PRBool aNotify = PR_FALSE);
|
||||
nsresult CreateContentObject(const nsIParserNode& aNode,
|
||||
nsHTMLTag aNodeType,
|
||||
nsIDOMHTMLFormElement* aForm,
|
||||
nsIWebShell* aWebShell,
|
||||
nsIHTMLContent** aResult);
|
||||
#ifdef NS_DEBUG
|
||||
void SinkTraceNode(PRUint32 aBit,
|
||||
const char* aMsg,
|
||||
const nsIParserNode& aNode,
|
||||
void* aThis);
|
||||
#endif
|
||||
|
||||
nsIDocument* mDocument;
|
||||
nsIHTMLDocument* mHTMLDocument;
|
||||
nsIURI* mDocumentURI;
|
||||
|
@ -346,105 +349,144 @@ public:
|
|||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
static void
|
||||
ReduceEntities(nsString& aString)
|
||||
#ifdef NS_DEBUG
|
||||
void
|
||||
HTMLContentSink::SinkTraceNode(PRUint32 aBit,
|
||||
const char* aMsg,
|
||||
const nsIParserNode& aNode,
|
||||
void* aThis)
|
||||
{
|
||||
// Reduce any entities
|
||||
// XXX Note: as coded today, this will only convert well formed
|
||||
// entities. This may not be compatible enough.
|
||||
// XXX there is a table in navigator that translates some numeric entities
|
||||
// should we be doing that? If so then it needs to live in two places (bad)
|
||||
// so we should add a translate numeric entity method from the parser...
|
||||
char cbuf[100];
|
||||
PRInt32 i = 0;
|
||||
while (i < aString.Length()) {
|
||||
// If we have the start of an entity (and it's not at the end of
|
||||
// our string) then translate the entity into it's unicode value.
|
||||
if ((aString.CharAt(i++) == '&') && (i < aString.Length())) {
|
||||
PRInt32 start = i - 1;
|
||||
PRUnichar e = aString.CharAt(i);
|
||||
if (e == '#') {
|
||||
// Convert a numeric character reference
|
||||
i++;
|
||||
char* cp = cbuf;
|
||||
char* limit = cp + sizeof(cbuf) - 1;
|
||||
PRBool ok = PR_FALSE;
|
||||
PRInt32 slen = aString.Length();
|
||||
while ((i < slen) && (cp < limit)) {
|
||||
e = aString.CharAt(i);
|
||||
if (e == ';') {
|
||||
i++;
|
||||
ok = PR_TRUE;
|
||||
break;
|
||||
}
|
||||
if ((e >= '0') && (e <= '9')) {
|
||||
*cp++ = char(e);
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (!ok || (cp == cbuf)) {
|
||||
continue;
|
||||
}
|
||||
*cp = '\0';
|
||||
if (cp - cbuf > 5) {
|
||||
continue;
|
||||
}
|
||||
PRInt32 ch = PRInt32( ::atoi(cbuf) );
|
||||
if (ch > 65535) {
|
||||
continue;
|
||||
}
|
||||
if (SINK_LOG_TEST(gSinkLogModuleInfo,aBit)) {
|
||||
char cbuf[40];
|
||||
const char* cp;
|
||||
nsAutoString str;
|
||||
PRInt32 nt = aNode.GetNodeType();
|
||||
if ((nt > PRInt32(eHTMLTag_unknown)) &&
|
||||
(nt < PRInt32(eHTMLTag_text)) && mParser) {
|
||||
nsCOMPtr<nsIDTD> dtd;
|
||||
mParser->GetDTD(getter_AddRefs(dtd));
|
||||
dtd->IntTagToStringTag(nsHTMLTag(aNode.GetNodeType()), str);
|
||||
cp = str.ToCString(cbuf, sizeof(cbuf));
|
||||
} else {
|
||||
aNode.GetText().ToCString(cbuf, sizeof(cbuf));
|
||||
cp = cbuf;
|
||||
}
|
||||
PR_LogPrint("%s: this=%p node='%s'", aMsg, aThis, cp);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// Remove entity from string and replace it with the integer
|
||||
// value.
|
||||
aString.Cut(start, i - start);
|
||||
aString.Insert(PRUnichar(ch), start);
|
||||
i = start + 1;
|
||||
}
|
||||
else if (((e >= 'A') && (e <= 'Z')) ||
|
||||
((e >= 'a') && (e <= 'z'))) {
|
||||
// Convert a named entity
|
||||
i++;
|
||||
char* cp = cbuf;
|
||||
char* limit = cp + sizeof(cbuf) - 1;
|
||||
*cp++ = char(e);
|
||||
PRBool ok = PR_FALSE;
|
||||
PRInt32 slen = aString.Length();
|
||||
while ((i < slen) && (cp < limit)) {
|
||||
e = aString.CharAt(i);
|
||||
if (e == ';') {
|
||||
i++;
|
||||
ok = PR_TRUE;
|
||||
break;
|
||||
}
|
||||
if (((e >= '0') && (e <= '9')) ||
|
||||
((e >= 'A') && (e <= 'Z')) ||
|
||||
((e >= 'a') && (e <= 'z'))) {
|
||||
*cp++ = char(e);
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (!ok || (cp == cbuf)) {
|
||||
continue;
|
||||
}
|
||||
*cp = '\0';
|
||||
PRInt32 ch = nsHTMLEntities::EntityToUnicode(nsSubsumeCStr(cbuf, PR_FALSE));
|
||||
if (ch < 0) {
|
||||
continue;
|
||||
}
|
||||
void
|
||||
HTMLContentSink::ReduceEntities(nsString& aString)
|
||||
{
|
||||
if (mParser) {
|
||||
nsCOMPtr<nsIDTD> dtd;
|
||||
|
||||
nsresult rv = mParser->GetDTD(getter_AddRefs(dtd));
|
||||
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
|
||||
// Remove entity from string and replace it with the integer
|
||||
// value.
|
||||
aString.Cut(start, i - start);
|
||||
aString.Insert(PRUnichar(ch), start);
|
||||
i = start + 1;
|
||||
}
|
||||
else if (e == '{') {
|
||||
// Convert a script entity
|
||||
// XXX write me!
|
||||
// Reduce any entities
|
||||
// XXX Note: as coded today, this will only convert well formed
|
||||
// entities. This may not be compatible enough.
|
||||
// XXX there is a table in navigator that translates some numeric entities
|
||||
// should we be doing that? If so then it needs to live in two places (bad)
|
||||
// so we should add a translate numeric entity method from the parser...
|
||||
char cbuf[100];
|
||||
PRInt32 i = 0;
|
||||
while (i < aString.Length()) {
|
||||
// If we have the start of an entity (and it's not at the end of
|
||||
// our string) then translate the entity into it's unicode value.
|
||||
if ((aString.CharAt(i++) == '&') && (i < aString.Length())) {
|
||||
PRInt32 start = i - 1;
|
||||
PRUnichar e = aString.CharAt(i);
|
||||
if (e == '#') {
|
||||
// Convert a numeric character reference
|
||||
i++;
|
||||
char* cp = cbuf;
|
||||
char* limit = cp + sizeof(cbuf) - 1;
|
||||
PRBool ok = PR_FALSE;
|
||||
PRInt32 slen = aString.Length();
|
||||
while ((i < slen) && (cp < limit)) {
|
||||
e = aString.CharAt(i);
|
||||
if (e == ';') {
|
||||
i++;
|
||||
ok = PR_TRUE;
|
||||
break;
|
||||
}
|
||||
if ((e >= '0') && (e <= '9')) {
|
||||
*cp++ = char(e);
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (!ok || (cp == cbuf)) {
|
||||
continue;
|
||||
}
|
||||
*cp = '\0';
|
||||
if (cp - cbuf > 5) {
|
||||
continue;
|
||||
}
|
||||
PRInt32 ch = PRInt32( ::atoi(cbuf) );
|
||||
if (ch > 65535) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Remove entity from string and replace it with the integer
|
||||
// value.
|
||||
aString.Cut(start, i - start);
|
||||
aString.Insert(PRUnichar(ch), start);
|
||||
i = start + 1;
|
||||
}
|
||||
else if (((e >= 'A') && (e <= 'Z')) ||
|
||||
((e >= 'a') && (e <= 'z'))) {
|
||||
// Convert a named entity
|
||||
i++;
|
||||
char* cp = cbuf;
|
||||
char* limit = cp + sizeof(cbuf) - 1;
|
||||
*cp++ = char(e);
|
||||
PRBool ok = PR_FALSE;
|
||||
PRInt32 slen = aString.Length();
|
||||
while ((i < slen) && (cp < limit)) {
|
||||
e = aString.CharAt(i);
|
||||
if (e == ';') {
|
||||
i++;
|
||||
ok = PR_TRUE;
|
||||
break;
|
||||
}
|
||||
if (((e >= '0') && (e <= '9')) ||
|
||||
((e >= 'A') && (e <= 'Z')) ||
|
||||
((e >= 'a') && (e <= 'z'))) {
|
||||
*cp++ = char(e);
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (!ok || (cp == cbuf)) {
|
||||
continue;
|
||||
}
|
||||
*cp = '\0';
|
||||
PRInt32 ch;
|
||||
nsAutoString str(cbuf);
|
||||
dtd->ConvertEntityToUnicode(str, &ch);
|
||||
|
||||
if (ch < 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Remove entity from string and replace it with the integer
|
||||
// value.
|
||||
aString.Cut(start, i - start);
|
||||
aString.Insert(PRUnichar(ch), start);
|
||||
i = start + 1;
|
||||
}
|
||||
else if (e == '{') {
|
||||
// Convert a script entity
|
||||
// XXX write me!
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -452,11 +494,11 @@ ReduceEntities(nsString& aString)
|
|||
|
||||
// Temporary factory code to create content objects
|
||||
|
||||
static void
|
||||
GetAttributeValueAt(const nsIParserNode& aNode,
|
||||
PRInt32 aIndex,
|
||||
nsString& aResult,
|
||||
nsIScriptContextOwner* aScriptContextOwner)
|
||||
void
|
||||
HTMLContentSink::GetAttributeValueAt(const nsIParserNode& aNode,
|
||||
PRInt32 aIndex,
|
||||
nsString& aResult,
|
||||
nsIScriptContextOwner* aScriptContextOwner)
|
||||
{
|
||||
// Copy value
|
||||
const nsString& value = aNode.GetValueAt(aIndex);
|
||||
|
@ -479,11 +521,11 @@ GetAttributeValueAt(const nsIParserNode& aNode,
|
|||
ReduceEntities(aResult);
|
||||
}
|
||||
|
||||
static nsresult
|
||||
AddAttributes(const nsIParserNode& aNode,
|
||||
nsIHTMLContent* aContent,
|
||||
nsIScriptContextOwner* aScriptContextOwner,
|
||||
PRBool aNotify = PR_FALSE)
|
||||
nsresult
|
||||
HTMLContentSink::AddAttributes(const nsIParserNode& aNode,
|
||||
nsIHTMLContent* aContent,
|
||||
nsIScriptContextOwner* aScriptContextOwner,
|
||||
PRBool aNotify)
|
||||
{
|
||||
// Add tag attributes to the content attributes
|
||||
nsAutoString k, v;
|
||||
|
@ -782,13 +824,15 @@ GetOptionText(const nsIParserNode& aNode, nsString& aText)
|
|||
/**
|
||||
* Factory subroutine to create all of the html content objects.
|
||||
*/
|
||||
static nsresult
|
||||
CreateContentObject(const nsIParserNode& aNode,
|
||||
nsHTMLTag aNodeType,
|
||||
nsIDOMHTMLFormElement* aForm,
|
||||
nsIWebShell* aWebShell,
|
||||
nsIHTMLContent** aResult)
|
||||
nsresult
|
||||
HTMLContentSink::CreateContentObject(const nsIParserNode& aNode,
|
||||
nsHTMLTag aNodeType,
|
||||
nsIDOMHTMLFormElement* aForm,
|
||||
nsIWebShell* aWebShell,
|
||||
nsIHTMLContent** aResult)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
// Find/create atom for the tag name
|
||||
nsAutoString tmp;
|
||||
if (eHTMLTag_userdefined == aNodeType) {
|
||||
|
@ -796,41 +840,63 @@ CreateContentObject(const nsIParserNode& aNode,
|
|||
tmp.ToLowerCase();
|
||||
}
|
||||
else {
|
||||
tmp.Append(nsHTMLTags::GetStringValue(aNodeType));
|
||||
}
|
||||
nsIAtom* atom = NS_NewAtom(tmp);
|
||||
if (nsnull == atom) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
nsCOMPtr<nsIDTD> dtd;
|
||||
rv = mParser->GetDTD(getter_AddRefs(dtd));
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
nsAutoString str;
|
||||
dtd->IntTagToStringTag(aNodeType, str);
|
||||
tmp.Append(str);
|
||||
}
|
||||
}
|
||||
|
||||
// Make the content object
|
||||
// XXX why is textarea not a container?
|
||||
nsAutoString content;
|
||||
if (eHTMLTag_textarea == aNodeType) {
|
||||
content = aNode.GetSkippedContent();
|
||||
}
|
||||
nsresult rv = MakeContentObject(aNodeType, atom, aForm, aWebShell,
|
||||
aResult, &content);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
nsIAtom* atom = NS_NewAtom(tmp);
|
||||
if (nsnull == atom) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
NS_RELEASE(atom);
|
||||
// Make the content object
|
||||
// XXX why is textarea not a container?
|
||||
nsAutoString content;
|
||||
if (eHTMLTag_textarea == aNodeType) {
|
||||
content = aNode.GetSkippedContent();
|
||||
}
|
||||
rv = MakeContentObject(aNodeType, atom, aForm, aWebShell,
|
||||
aResult, &content);
|
||||
|
||||
NS_RELEASE(atom);
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
static NS_DEFINE_CID(kParserServiceCID, NS_PARSERSERVICE_CID);
|
||||
|
||||
nsresult
|
||||
NS_CreateHTMLElement(nsIHTMLContent** aResult, const nsString& aTag)
|
||||
{
|
||||
// Find tag in tag table
|
||||
nsHTMLTag id = nsHTMLTags::LookupTag(aTag);
|
||||
if (eHTMLTag_userdefined == id) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
// Create atom for tag and then create content object
|
||||
const nsCString& tag = nsHTMLTags::GetStringValue(id);
|
||||
nsIAtom* atom = NS_NewAtom((const char*)tag);
|
||||
nsresult rv = MakeContentObject(id, atom, nsnull, nsnull, aResult);
|
||||
NS_RELEASE(atom);
|
||||
NS_WITH_SERVICE(nsIParserService,
|
||||
parserService,
|
||||
kParserServiceCID,
|
||||
&rv);
|
||||
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
// Find tag in tag table
|
||||
PRInt32 id;
|
||||
rv = parserService->HTMLStringTagToId(aTag, &id);
|
||||
if (eHTMLTag_userdefined == nsHTMLTag(id)) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
// Create atom for tag and then create content object
|
||||
nsAutoString tag;
|
||||
rv = parserService->HTMLIdToStringTag(id, tag);
|
||||
nsIAtom* atom = NS_NewAtom(tag.GetUnicode());
|
||||
rv = MakeContentObject(nsHTMLTag(id), atom, nsnull, nsnull, aResult);
|
||||
NS_RELEASE(atom);
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
@ -994,7 +1060,7 @@ SinkContext::OpenContainer(const nsIParserNode& aNode)
|
|||
FlushText();
|
||||
|
||||
SINK_TRACE_NODE(SINK_TRACE_CALLS,
|
||||
"SinkContext::OpenContainer", aNode);
|
||||
"SinkContext::OpenContainer", aNode, mSink);
|
||||
|
||||
nsresult rv;
|
||||
if (mStackPos + 1 > mStackSize) {
|
||||
|
@ -1007,10 +1073,10 @@ SinkContext::OpenContainer(const nsIParserNode& aNode)
|
|||
// Create new container content object
|
||||
nsHTMLTag nodeType = nsHTMLTag(aNode.GetNodeType());
|
||||
nsIHTMLContent* content;
|
||||
rv = CreateContentObject(aNode, nodeType,
|
||||
mSink->mCurrentForm,
|
||||
mSink->mFrameset ? mSink->mWebShell : nsnull,
|
||||
&content);
|
||||
rv = mSink->CreateContentObject(aNode, nodeType,
|
||||
mSink->mCurrentForm,
|
||||
mSink->mFrameset ? mSink->mWebShell : nsnull,
|
||||
&content);
|
||||
if (NS_OK != rv) {
|
||||
return rv;
|
||||
}
|
||||
|
@ -1022,7 +1088,7 @@ SinkContext::OpenContainer(const nsIParserNode& aNode)
|
|||
content->SetDocument(mSink->mDocument, PR_FALSE);
|
||||
|
||||
nsIScriptContextOwner* sco = mSink->mDocument->GetScriptContextOwner();
|
||||
rv = AddAttributes(aNode, content, sco);
|
||||
rv = mSink->AddAttributes(aNode, content, sco);
|
||||
NS_IF_RELEASE(sco);
|
||||
|
||||
if (mPreAppend) {
|
||||
|
@ -1073,7 +1139,7 @@ SinkContext::CloseContainer(const nsIParserNode& aNode)
|
|||
FlushText();
|
||||
|
||||
SINK_TRACE_NODE(SINK_TRACE_CALLS,
|
||||
"SinkContext::CloseContainer", aNode);
|
||||
"SinkContext::CloseContainer", aNode, mSink);
|
||||
|
||||
--mStackPos;
|
||||
nsHTMLTag nodeType = mStack[mStackPos].mType;
|
||||
|
@ -1242,7 +1308,7 @@ nsresult
|
|||
SinkContext::AddLeaf(const nsIParserNode& aNode)
|
||||
{
|
||||
SINK_TRACE_NODE(SINK_TRACE_CALLS,
|
||||
"SinkContext::AddLeaf", aNode);
|
||||
"SinkContext::AddLeaf", aNode, mSink);
|
||||
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
|
@ -1254,9 +1320,9 @@ SinkContext::AddLeaf(const nsIParserNode& aNode)
|
|||
// Create new leaf content object
|
||||
nsHTMLTag nodeType = nsHTMLTag(aNode.GetNodeType());
|
||||
nsIHTMLContent* content;
|
||||
rv = CreateContentObject(aNode, nodeType,
|
||||
mSink->mCurrentForm, mSink->mWebShell,
|
||||
&content);
|
||||
rv = mSink->CreateContentObject(aNode, nodeType,
|
||||
mSink->mCurrentForm, mSink->mWebShell,
|
||||
&content);
|
||||
if (NS_OK != rv) {
|
||||
return rv;
|
||||
}
|
||||
|
@ -1266,7 +1332,7 @@ SinkContext::AddLeaf(const nsIParserNode& aNode)
|
|||
content->SetDocument(mSink->mDocument, PR_FALSE);
|
||||
|
||||
nsIScriptContextOwner* sco = mSink->mDocument->GetScriptContextOwner();
|
||||
rv = AddAttributes(aNode, content, sco);
|
||||
rv = mSink->AddAttributes(aNode, content, sco);
|
||||
NS_IF_RELEASE(sco);
|
||||
if (NS_OK != rv) {
|
||||
NS_RELEASE(content);
|
||||
|
@ -1900,7 +1966,7 @@ HTMLContentSink::OpenHTML(const nsIParserNode& aNode)
|
|||
|
||||
NS_START_STOPWATCH(mWatch)
|
||||
SINK_TRACE_NODE(SINK_TRACE_CALLS,
|
||||
"HTMLContentSink::OpenHTML", aNode);
|
||||
"HTMLContentSink::OpenHTML", aNode, this);
|
||||
|
||||
NS_STOP_STOPWATCH(mWatch)
|
||||
return NS_OK;
|
||||
|
@ -1911,7 +1977,7 @@ HTMLContentSink::CloseHTML(const nsIParserNode& aNode)
|
|||
{
|
||||
NS_START_STOPWATCH(mWatch)
|
||||
SINK_TRACE_NODE(SINK_TRACE_CALLS,
|
||||
"HTMLContentSink::CloseHTML", aNode);
|
||||
"HTMLContentSink::CloseHTML", aNode, this);
|
||||
if (nsnull != mHeadContext) {
|
||||
mHeadContext->End();
|
||||
delete mHeadContext;
|
||||
|
@ -1926,7 +1992,7 @@ HTMLContentSink::OpenHead(const nsIParserNode& aNode)
|
|||
{
|
||||
NS_START_STOPWATCH(mWatch)
|
||||
SINK_TRACE_NODE(SINK_TRACE_CALLS,
|
||||
"HTMLContentSink::OpenHead", aNode);
|
||||
"HTMLContentSink::OpenHead", aNode, this);
|
||||
nsresult rv = NS_OK;
|
||||
if (nsnull == mHeadContext) {
|
||||
mHeadContext = new SinkContext(this);
|
||||
|
@ -1959,7 +2025,7 @@ HTMLContentSink::CloseHead(const nsIParserNode& aNode)
|
|||
{
|
||||
NS_START_STOPWATCH(mWatch)
|
||||
SINK_TRACE_NODE(SINK_TRACE_CALLS,
|
||||
"HTMLContentSink::CloseHead", aNode);
|
||||
"HTMLContentSink::CloseHead", aNode, this);
|
||||
PRInt32 n = mContextStack.Count() - 1;
|
||||
mCurrentContext = (SinkContext*) mContextStack.ElementAt(n);
|
||||
mContextStack.RemoveElementAt(n);
|
||||
|
@ -1974,7 +2040,7 @@ HTMLContentSink::OpenBody(const nsIParserNode& aNode)
|
|||
//NS_PRECONDITION(nsnull == mBody, "parser called OpenBody twice");
|
||||
|
||||
SINK_TRACE_NODE(SINK_TRACE_CALLS,
|
||||
"HTMLContentSink::OpenBody", aNode);
|
||||
"HTMLContentSink::OpenBody", aNode, this);
|
||||
// Add attributes, if any, to the current BODY node
|
||||
if(mBody != nsnull){
|
||||
nsIScriptContextOwner* sco = mDocument->GetScriptContextOwner();
|
||||
|
@ -2007,7 +2073,7 @@ HTMLContentSink::CloseBody(const nsIParserNode& aNode)
|
|||
{
|
||||
NS_START_STOPWATCH(mWatch)
|
||||
SINK_TRACE_NODE(SINK_TRACE_CALLS,
|
||||
"HTMLContentSink::CloseBody", aNode);
|
||||
"HTMLContentSink::CloseBody", aNode, this);
|
||||
|
||||
PRBool didFlush;
|
||||
nsresult rv = mCurrentContext->FlushText(&didFlush);
|
||||
|
@ -2036,7 +2102,7 @@ HTMLContentSink::OpenForm(const nsIParserNode& aNode)
|
|||
mCurrentContext->FlushText();
|
||||
|
||||
SINK_TRACE_NODE(SINK_TRACE_CALLS,
|
||||
"HTMLContentSink::OpenForm", aNode);
|
||||
"HTMLContentSink::OpenForm", aNode, this);
|
||||
|
||||
// Close out previous form if it's there. If there is one
|
||||
// around, it's probably because the last one wasn't well-formed.
|
||||
|
@ -2096,7 +2162,7 @@ HTMLContentSink::CloseForm(const nsIParserNode& aNode)
|
|||
|
||||
mCurrentContext->FlushText();
|
||||
SINK_TRACE_NODE(SINK_TRACE_CALLS,
|
||||
"HTMLContentSink::CloseForm", aNode);
|
||||
"HTMLContentSink::CloseForm", aNode, this);
|
||||
|
||||
if (nsnull != mCurrentForm) {
|
||||
// Check if this is a well-formed form
|
||||
|
@ -2125,7 +2191,7 @@ HTMLContentSink::OpenFrameset(const nsIParserNode& aNode)
|
|||
{
|
||||
NS_START_STOPWATCH(mWatch)
|
||||
SINK_TRACE_NODE(SINK_TRACE_CALLS,
|
||||
"HTMLContentSink::OpenFrameset", aNode);
|
||||
"HTMLContentSink::OpenFrameset", aNode, this);
|
||||
|
||||
nsresult rv = mCurrentContext->OpenContainer(aNode);
|
||||
if ((NS_OK == rv) && (nsnull == mFrameset)) {
|
||||
|
@ -2142,7 +2208,7 @@ HTMLContentSink::CloseFrameset(const nsIParserNode& aNode)
|
|||
{
|
||||
NS_START_STOPWATCH(mWatch)
|
||||
SINK_TRACE_NODE(SINK_TRACE_CALLS,
|
||||
"HTMLContentSink::CloseFrameset", aNode);
|
||||
"HTMLContentSink::CloseFrameset", aNode, this);
|
||||
|
||||
SinkContext* sc = mCurrentContext;
|
||||
nsIHTMLContent* fs = sc->mStack[sc->mStackPos-1].mContent;
|
||||
|
@ -2161,7 +2227,7 @@ HTMLContentSink::OpenMap(const nsIParserNode& aNode)
|
|||
NS_START_STOPWATCH(mWatch)
|
||||
nsresult rv = NS_OK;
|
||||
SINK_TRACE_NODE(SINK_TRACE_CALLS,
|
||||
"HTMLContentSink::OpenMap", aNode);
|
||||
"HTMLContentSink::OpenMap", aNode, this);
|
||||
// We used to treat MAP elements specially (i.e. they were
|
||||
// only parent elements for AREAs), but we don't anymore.
|
||||
// HTML 4.0 says that MAP elements can have block content
|
||||
|
@ -2177,7 +2243,7 @@ HTMLContentSink::CloseMap(const nsIParserNode& aNode)
|
|||
NS_START_STOPWATCH(mWatch)
|
||||
nsresult rv = NS_OK;
|
||||
SINK_TRACE_NODE(SINK_TRACE_CALLS,
|
||||
"HTMLContentSink::CloseMap", aNode);
|
||||
"HTMLContentSink::CloseMap", aNode, this);
|
||||
NS_IF_RELEASE(mCurrentMap);
|
||||
NS_IF_RELEASE(mCurrentDOMMap);
|
||||
|
||||
|
|
|
@ -66,6 +66,7 @@
|
|||
#include "nsICookieService.h"
|
||||
#endif // NECKO
|
||||
|
||||
#include "nsIParserService.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsIFormManager.h"
|
||||
#include "nsIComponentManager.h"
|
||||
|
@ -2297,7 +2298,8 @@ IsNamedItem(nsIContent* aContent, nsIAtom *aTag,
|
|||
if ((aTag == nsHTMLAtoms::img) || (aTag == nsHTMLAtoms::form) ||
|
||||
(!aInForm && ((aTag == nsHTMLAtoms::applet) ||
|
||||
(aTag == nsHTMLAtoms::embed)))) {
|
||||
if (NS_CONTENT_ATTR_HAS_VALUE == aContent->GetAttribute(kNameSpaceID_HTML, nsHTMLAtoms::name, aName)) {
|
||||
if ((NS_CONTENT_ATTR_HAS_VALUE == aContent->GetAttribute(kNameSpaceID_HTML, nsHTMLAtoms::name, aName)) ||
|
||||
(NS_CONTENT_ATTR_HAS_VALUE == aContent->GetAttribute(kNameSpaceID_HTML, nsHTMLAtoms::id, aName))) {
|
||||
return PR_TRUE;
|
||||
}
|
||||
}
|
||||
|
@ -2759,6 +2761,8 @@ PRBool nsHTMLDocument::SearchBlock(BlockText & aBlockText,
|
|||
return found;
|
||||
}
|
||||
|
||||
static NS_DEFINE_CID(kParserServiceCID, NS_PARSERSERVICE_CID);
|
||||
|
||||
////////////////////////////////////////////////////
|
||||
// Check to see if a Content node is a block tag
|
||||
////////////////////////////////////////////////////
|
||||
|
@ -2775,7 +2779,19 @@ PRBool nsHTMLDocument::NodeIsBlock(nsIDOMNode * aNode)
|
|||
domElement->GetTagName(tagName);
|
||||
NS_RELEASE(domElement);
|
||||
|
||||
isBlock = IsBlockLevel(nsHTMLTags::LookupTag(tagName), mIsPreTag);
|
||||
// XXX Should be done at a higher level than this routine
|
||||
// since getting the service is not the cheapest operation.
|
||||
// Waiting for mjudge to tell me where since it looks like
|
||||
// this code is still in development.
|
||||
|
||||
NS_WITH_SERVICE(nsIParserService, service, kParserServiceCID, &rv);
|
||||
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
PRInt32 id;
|
||||
|
||||
service->HTMLStringTagToId(tagName, &id);
|
||||
isBlock = IsBlockLevel(nsHTMLTag(id), mIsPreTag);
|
||||
}
|
||||
|
||||
return isBlock;
|
||||
}
|
||||
|
|
|
@ -94,6 +94,9 @@ public:
|
|||
PRInt32 PushContent(nsIContent *aContent);
|
||||
nsIContent* PopContent();
|
||||
|
||||
void GetAttributeValueAt(const nsIParserNode& aNode,
|
||||
PRInt32 aIndex,
|
||||
nsString& aResult);
|
||||
nsresult AddAttributes(const nsIParserNode& aNode,
|
||||
nsIContent* aContent);
|
||||
|
||||
|
@ -636,10 +639,10 @@ nsHTMLFragmentContentSink::FlushText()
|
|||
}
|
||||
|
||||
// XXX Code copied from nsHTMLContentSink. It should be shared.
|
||||
static void
|
||||
GetAttributeValueAt(const nsIParserNode& aNode,
|
||||
PRInt32 aIndex,
|
||||
nsString& aResult)
|
||||
void
|
||||
nsHTMLFragmentContentSink::GetAttributeValueAt(const nsIParserNode& aNode,
|
||||
PRInt32 aIndex,
|
||||
nsString& aResult)
|
||||
{
|
||||
// Copy value
|
||||
const nsString& value = aNode.GetValueAt(aIndex);
|
||||
|
@ -660,102 +663,113 @@ GetAttributeValueAt(const nsIParserNode& aNode,
|
|||
}
|
||||
}
|
||||
|
||||
// Reduce any entities
|
||||
// XXX Note: as coded today, this will only convert well formed
|
||||
// entities. This may not be compatible enough.
|
||||
// XXX there is a table in navigator that translates some numeric entities
|
||||
// should we be doing that? If so then it needs to live in two places (bad)
|
||||
// so we should add a translate numeric entity method from the parser...
|
||||
char cbuf[100];
|
||||
PRInt32 indx = 0;
|
||||
while (indx < aResult.Length()) {
|
||||
// If we have the start of an entity (and it's not at the end of
|
||||
// our string) then translate the entity into it's unicode value.
|
||||
if ((aResult.CharAt(indx++) == '&') && (indx < aResult.Length())) {
|
||||
PRInt32 start = indx - 1;
|
||||
PRUnichar e = aResult.CharAt(indx);
|
||||
if (e == '#') {
|
||||
// Convert a numeric character reference
|
||||
indx++;
|
||||
char* cp = cbuf;
|
||||
char* limit = cp + sizeof(cbuf) - 1;
|
||||
PRBool ok = PR_FALSE;
|
||||
PRInt32 slen = aResult.Length();
|
||||
while ((indx < slen) && (cp < limit)) {
|
||||
e = aResult.CharAt(indx);
|
||||
if (e == ';') {
|
||||
if (mParser) {
|
||||
nsCOMPtr<nsIDTD> dtd;
|
||||
|
||||
nsresult rv = mParser->GetDTD(getter_AddRefs(dtd));
|
||||
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
// Reduce any entities
|
||||
// XXX Note: as coded today, this will only convert well formed
|
||||
// entities. This may not be compatible enough.
|
||||
// XXX there is a table in navigator that translates some numeric entities
|
||||
// should we be doing that? If so then it needs to live in two places (bad)
|
||||
// so we should add a translate numeric entity method from the parser...
|
||||
char cbuf[100];
|
||||
PRInt32 indx = 0;
|
||||
while (indx < aResult.Length()) {
|
||||
// If we have the start of an entity (and it's not at the end of
|
||||
// our string) then translate the entity into it's unicode value.
|
||||
if ((aResult.CharAt(indx++) == '&') && (indx < aResult.Length())) {
|
||||
PRInt32 start = indx - 1;
|
||||
PRUnichar e = aResult.CharAt(indx);
|
||||
if (e == '#') {
|
||||
// Convert a numeric character reference
|
||||
indx++;
|
||||
ok = PR_TRUE;
|
||||
break;
|
||||
char* cp = cbuf;
|
||||
char* limit = cp + sizeof(cbuf) - 1;
|
||||
PRBool ok = PR_FALSE;
|
||||
PRInt32 slen = aResult.Length();
|
||||
while ((indx < slen) && (cp < limit)) {
|
||||
e = aResult.CharAt(indx);
|
||||
if (e == ';') {
|
||||
indx++;
|
||||
ok = PR_TRUE;
|
||||
break;
|
||||
}
|
||||
if ((e >= '0') && (e <= '9')) {
|
||||
*cp++ = char(e);
|
||||
indx++;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (!ok || (cp == cbuf)) {
|
||||
continue;
|
||||
}
|
||||
*cp = '\0';
|
||||
if (cp - cbuf > 5) {
|
||||
continue;
|
||||
}
|
||||
PRInt32 ch = PRInt32( ::atoi(cbuf) );
|
||||
if (ch > 65535) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Remove entity from string and replace it with the integer
|
||||
// value.
|
||||
aResult.Cut(start, indx - start);
|
||||
aResult.Insert(PRUnichar(ch), start);
|
||||
indx = start + 1;
|
||||
}
|
||||
if ((e >= '0') && (e <= '9')) {
|
||||
else if (((e >= 'A') && (e <= 'Z')) ||
|
||||
((e >= 'a') && (e <= 'z'))) {
|
||||
// Convert a named entity
|
||||
indx++;
|
||||
char* cp = cbuf;
|
||||
char* limit = cp + sizeof(cbuf) - 1;
|
||||
*cp++ = char(e);
|
||||
indx++;
|
||||
continue;
|
||||
PRBool ok = PR_FALSE;
|
||||
PRInt32 slen = aResult.Length();
|
||||
while ((indx < slen) && (cp < limit)) {
|
||||
e = aResult.CharAt(indx);
|
||||
if (e == ';') {
|
||||
indx++;
|
||||
ok = PR_TRUE;
|
||||
break;
|
||||
}
|
||||
if (((e >= '0') && (e <= '9')) ||
|
||||
((e >= 'A') && (e <= 'Z')) ||
|
||||
((e >= 'a') && (e <= 'z'))) {
|
||||
*cp++ = char(e);
|
||||
indx++;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (!ok || (cp == cbuf)) {
|
||||
continue;
|
||||
}
|
||||
*cp = '\0';
|
||||
PRInt32 ch;
|
||||
nsAutoString str(cbuf);
|
||||
dtd->ConvertEntityToUnicode(str, &ch);
|
||||
|
||||
if (ch < 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Remove entity from string and replace it with the integer
|
||||
// value.
|
||||
aResult.Cut(start, indx - start);
|
||||
aResult.Insert(PRUnichar(ch), start);
|
||||
indx = start + 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (!ok || (cp == cbuf)) {
|
||||
continue;
|
||||
}
|
||||
*cp = '\0';
|
||||
if (cp - cbuf > 5) {
|
||||
continue;
|
||||
}
|
||||
PRInt32 ch = PRInt32( ::atoi(cbuf) );
|
||||
if (ch > 65535) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Remove entity from string and replace it with the integer
|
||||
// value.
|
||||
aResult.Cut(start, indx - start);
|
||||
aResult.Insert(PRUnichar(ch), start);
|
||||
indx = start + 1;
|
||||
}
|
||||
else if (((e >= 'A') && (e <= 'Z')) ||
|
||||
((e >= 'a') && (e <= 'z'))) {
|
||||
// Convert a named entity
|
||||
indx++;
|
||||
char* cp = cbuf;
|
||||
char* limit = cp + sizeof(cbuf) - 1;
|
||||
*cp++ = char(e);
|
||||
PRBool ok = PR_FALSE;
|
||||
PRInt32 slen = aResult.Length();
|
||||
while ((indx < slen) && (cp < limit)) {
|
||||
e = aResult.CharAt(indx);
|
||||
if (e == ';') {
|
||||
indx++;
|
||||
ok = PR_TRUE;
|
||||
break;
|
||||
else if (e == '{') {
|
||||
// Convert a script entity
|
||||
// XXX write me!
|
||||
}
|
||||
if (((e >= '0') && (e <= '9')) ||
|
||||
((e >= 'A') && (e <= 'Z')) ||
|
||||
((e >= 'a') && (e <= 'z'))) {
|
||||
*cp++ = char(e);
|
||||
indx++;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (!ok || (cp == cbuf)) {
|
||||
continue;
|
||||
}
|
||||
*cp = '\0';
|
||||
PRInt32 ch = nsHTMLEntities::EntityToUnicode(nsSubsumeCStr(cbuf, PR_FALSE));
|
||||
if (ch < 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Remove entity from string and replace it with the integer
|
||||
// value.
|
||||
aResult.Cut(start, indx - start);
|
||||
aResult.Insert(PRUnichar(ch), start);
|
||||
indx = start + 1;
|
||||
}
|
||||
else if (e == '{') {
|
||||
// Convert a script entity
|
||||
// XXX write me!
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -410,10 +410,10 @@ nsXMLContentSink::SetParser(nsIParser* aParser)
|
|||
}
|
||||
|
||||
// XXX Code copied from nsHTMLContentSink. It should be shared.
|
||||
static void
|
||||
GetAttributeValueAt(const nsIParserNode& aNode,
|
||||
PRInt32 aIndex,
|
||||
nsString& aResult)
|
||||
void
|
||||
nsXMLContentSink::GetAttributeValueAt(const nsIParserNode& aNode,
|
||||
PRInt32 aIndex,
|
||||
nsString& aResult)
|
||||
{
|
||||
// Copy value
|
||||
const nsString& value = aNode.GetValueAt(aIndex);
|
||||
|
@ -434,102 +434,113 @@ GetAttributeValueAt(const nsIParserNode& aNode,
|
|||
}
|
||||
}
|
||||
|
||||
// Reduce any entities
|
||||
// XXX Note: as coded today, this will only convert well formed
|
||||
// entities. This may not be compatible enough.
|
||||
// XXX there is a table in navigator that translates some numeric entities
|
||||
// should we be doing that? If so then it needs to live in two places (bad)
|
||||
// so we should add a translate numeric entity method from the parser...
|
||||
char cbuf[100];
|
||||
PRInt32 index = 0;
|
||||
while (index < aResult.Length()) {
|
||||
// If we have the start of an entity (and it's not at the end of
|
||||
// our string) then translate the entity into it's unicode value.
|
||||
if ((aResult.CharAt(index++) == '&') && (index < aResult.Length())) {
|
||||
PRInt32 start = index - 1;
|
||||
PRUnichar e = aResult.CharAt(index);
|
||||
if (e == '#') {
|
||||
// Convert a numeric character reference
|
||||
index++;
|
||||
char* cp = cbuf;
|
||||
char* limit = cp + sizeof(cbuf) - 1;
|
||||
PRBool ok = PR_FALSE;
|
||||
PRInt32 slen = aResult.Length();
|
||||
while ((index < slen) && (cp < limit)) {
|
||||
PRUnichar ch = aResult.CharAt(index);
|
||||
if (ch == ';') {
|
||||
if (mParser) {
|
||||
nsCOMPtr<nsIDTD> dtd;
|
||||
|
||||
nsresult rv = mParser->GetDTD(getter_AddRefs(dtd));
|
||||
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
|
||||
// Reduce any entities
|
||||
// XXX Note: as coded today, this will only convert well formed
|
||||
// entities. This may not be compatible enough.
|
||||
// XXX there is a table in navigator that translates some numeric entities
|
||||
// should we be doing that? If so then it needs to live in two places (bad)
|
||||
// so we should add a translate numeric entity method from the parser...
|
||||
char cbuf[100];
|
||||
PRInt32 index = 0;
|
||||
while (index < aResult.Length()) {
|
||||
// If we have the start of an entity (and it's not at the end of
|
||||
// our string) then translate the entity into it's unicode value.
|
||||
if ((aResult.CharAt(index++) == '&') && (index < aResult.Length())) {
|
||||
PRInt32 start = index - 1;
|
||||
PRUnichar e = aResult.CharAt(index);
|
||||
if (e == '#') {
|
||||
// Convert a numeric character reference
|
||||
index++;
|
||||
ok = PR_TRUE;
|
||||
break;
|
||||
char* cp = cbuf;
|
||||
char* limit = cp + sizeof(cbuf) - 1;
|
||||
PRBool ok = PR_FALSE;
|
||||
PRInt32 slen = aResult.Length();
|
||||
while ((index < slen) && (cp < limit)) {
|
||||
PRUnichar ch = aResult.CharAt(index);
|
||||
if (ch == ';') {
|
||||
index++;
|
||||
ok = PR_TRUE;
|
||||
break;
|
||||
}
|
||||
if ((ch >= '0') && (ch <= '9')) {
|
||||
*cp++ = char(ch);
|
||||
index++;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (!ok || (cp == cbuf)) {
|
||||
continue;
|
||||
}
|
||||
*cp = '\0';
|
||||
if (cp - cbuf > 5) {
|
||||
continue;
|
||||
}
|
||||
PRInt32 ch = PRInt32( ::atoi(cbuf) );
|
||||
if (ch > 65535) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Remove entity from string and replace it with the integer
|
||||
// value.
|
||||
aResult.Cut(start, index - start);
|
||||
aResult.Insert(PRUnichar(ch), start);
|
||||
index = start + 1;
|
||||
}
|
||||
if ((ch >= '0') && (ch <= '9')) {
|
||||
*cp++ = char(ch);
|
||||
else if (((e >= 'A') && (e <= 'Z')) ||
|
||||
((e >= 'a') && (e <= 'z'))) {
|
||||
// Convert a named entity
|
||||
index++;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (!ok || (cp == cbuf)) {
|
||||
continue;
|
||||
}
|
||||
*cp = '\0';
|
||||
if (cp - cbuf > 5) {
|
||||
continue;
|
||||
}
|
||||
PRInt32 ch = PRInt32( ::atoi(cbuf) );
|
||||
if (ch > 65535) {
|
||||
continue;
|
||||
}
|
||||
char* cp = cbuf;
|
||||
char* limit = cp + sizeof(cbuf) - 1;
|
||||
*cp++ = char(e);
|
||||
PRBool ok = PR_FALSE;
|
||||
PRInt32 slen = aResult.Length();
|
||||
while ((index < slen) && (cp < limit)) {
|
||||
PRUnichar ch = aResult.CharAt(index);
|
||||
if (ch == ';') {
|
||||
index++;
|
||||
ok = PR_TRUE;
|
||||
break;
|
||||
}
|
||||
if (((ch >= '0') && (ch <= '9')) ||
|
||||
((ch >= 'A') && (ch <= 'Z')) ||
|
||||
((ch >= 'a') && (ch <= 'z'))) {
|
||||
*cp++ = char(ch);
|
||||
index++;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (!ok || (cp == cbuf)) {
|
||||
continue;
|
||||
}
|
||||
*cp = '\0';
|
||||
PRInt32 ch;
|
||||
nsAutoString str(cbuf);
|
||||
dtd->ConvertEntityToUnicode(str, &ch);
|
||||
if (ch < 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Remove entity from string and replace it with the integer
|
||||
// value.
|
||||
aResult.Cut(start, index - start);
|
||||
aResult.Insert(PRUnichar(ch), start);
|
||||
index = start + 1;
|
||||
}
|
||||
else if (((e >= 'A') && (e <= 'Z')) ||
|
||||
((e >= 'a') && (e <= 'z'))) {
|
||||
// Convert a named entity
|
||||
index++;
|
||||
char* cp = cbuf;
|
||||
char* limit = cp + sizeof(cbuf) - 1;
|
||||
*cp++ = char(e);
|
||||
PRBool ok = PR_FALSE;
|
||||
PRInt32 slen = aResult.Length();
|
||||
while ((index < slen) && (cp < limit)) {
|
||||
PRUnichar ch = aResult.CharAt(index);
|
||||
if (ch == ';') {
|
||||
index++;
|
||||
ok = PR_TRUE;
|
||||
break;
|
||||
// Remove entity from string and replace it with the integer
|
||||
// value.
|
||||
aResult.Cut(start, index - start);
|
||||
aResult.Insert(PRUnichar(ch), start);
|
||||
index = start + 1;
|
||||
}
|
||||
if (((ch >= '0') && (ch <= '9')) ||
|
||||
((ch >= 'A') && (ch <= 'Z')) ||
|
||||
((ch >= 'a') && (ch <= 'z'))) {
|
||||
*cp++ = char(ch);
|
||||
index++;
|
||||
continue;
|
||||
else if (e == '{') {
|
||||
// Convert a script entity
|
||||
// XXX write me!
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (!ok || (cp == cbuf)) {
|
||||
continue;
|
||||
}
|
||||
*cp = '\0';
|
||||
PRInt32 ch = nsHTMLEntities::EntityToUnicode(nsSubsumeCStr(cbuf, PR_FALSE));
|
||||
if (ch < 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Remove entity from string and replace it with the integer
|
||||
// value.
|
||||
aResult.Cut(start, index - start);
|
||||
aResult.Insert(PRUnichar(ch), start);
|
||||
index = start + 1;
|
||||
}
|
||||
else if (e == '{') {
|
||||
// Convert a script entity
|
||||
// XXX write me!
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -102,7 +102,9 @@ protected:
|
|||
|
||||
nsresult FlushText(PRBool aCreateTextNode=PR_TRUE,
|
||||
PRBool* aDidFlush=nsnull);
|
||||
|
||||
void GetAttributeValueAt(const nsIParserNode& aNode,
|
||||
PRInt32 aIndex,
|
||||
nsString& aResult);
|
||||
nsresult AddAttributes(const nsIParserNode& aNode,
|
||||
nsIContent* aContent,
|
||||
PRBool aIsHTML);
|
||||
|
|
|
@ -49,6 +49,7 @@
|
|||
#include "nsIFormControl.h"
|
||||
|
||||
#include "nsIComponentManager.h"
|
||||
#include "nsIServiceManager.h"
|
||||
|
||||
#include "nsIScrollableView.h"
|
||||
#include "nsHTMLAtoms.h"
|
||||
|
@ -66,6 +67,9 @@
|
|||
#include "nsHTMLIIDs.h"
|
||||
#include "nsTextFragment.h"
|
||||
|
||||
#include "nsIParserService.h"
|
||||
#include "nsParserCIID.h"
|
||||
|
||||
// XXX Go through a factory for this one
|
||||
#include "nsICSSParser.h"
|
||||
|
||||
|
@ -109,29 +113,7 @@ static PRLogModuleInfo* gSinkLogModuleInfo;
|
|||
} \
|
||||
PR_END_MACRO
|
||||
|
||||
#define SINK_TRACE_NODE(_bit,_msg,_node) SinkTraceNode(_bit,_msg,_node,this)
|
||||
|
||||
|
||||
static void
|
||||
SinkTraceNode(PRUint32 aBit,
|
||||
const char* aMsg,
|
||||
const nsIParserNode& aNode,
|
||||
void* aThis)
|
||||
{
|
||||
if (SINK_LOG_TEST(gSinkLogModuleInfo,aBit)) {
|
||||
char cbuf[40];
|
||||
const char* cp;
|
||||
PRInt32 nt = aNode.GetNodeType();
|
||||
if ((nt > PRInt32(eHTMLTag_unknown)) &&
|
||||
(nt < PRInt32(eHTMLTag_text))) {
|
||||
cp = nsHTMLTags::GetStringValue(nsHTMLTag(aNode.GetNodeType()));
|
||||
} else {
|
||||
aNode.GetText().ToCString(cbuf, sizeof(cbuf));
|
||||
cp = cbuf;
|
||||
}
|
||||
PR_LogPrint("%s: this=%p node='%s'", aMsg, aThis, cp);
|
||||
}
|
||||
}
|
||||
#define SINK_TRACE_NODE(_bit,_msg,_node,_obj) _obj->SinkTraceNode(_bit,_msg,_node,this)
|
||||
|
||||
#else
|
||||
#define SINK_TRACE(_bit,_args)
|
||||
|
@ -189,6 +171,27 @@ public:
|
|||
|
||||
NS_IMETHOD DoFragment(PRBool aFlag);
|
||||
|
||||
void ReduceEntities(nsString& aString);
|
||||
void GetAttributeValueAt(const nsIParserNode& aNode,
|
||||
PRInt32 aIndex,
|
||||
nsString& aResult,
|
||||
nsIScriptContextOwner* aScriptContextOwner);
|
||||
nsresult AddAttributes(const nsIParserNode& aNode,
|
||||
nsIHTMLContent* aContent,
|
||||
nsIScriptContextOwner* aScriptContextOwner,
|
||||
PRBool aNotify = PR_FALSE);
|
||||
nsresult CreateContentObject(const nsIParserNode& aNode,
|
||||
nsHTMLTag aNodeType,
|
||||
nsIDOMHTMLFormElement* aForm,
|
||||
nsIWebShell* aWebShell,
|
||||
nsIHTMLContent** aResult);
|
||||
#ifdef NS_DEBUG
|
||||
void SinkTraceNode(PRUint32 aBit,
|
||||
const char* aMsg,
|
||||
const nsIParserNode& aNode,
|
||||
void* aThis);
|
||||
#endif
|
||||
|
||||
nsIDocument* mDocument;
|
||||
nsIHTMLDocument* mHTMLDocument;
|
||||
nsIURI* mDocumentURI;
|
||||
|
@ -346,105 +349,144 @@ public:
|
|||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
static void
|
||||
ReduceEntities(nsString& aString)
|
||||
#ifdef NS_DEBUG
|
||||
void
|
||||
HTMLContentSink::SinkTraceNode(PRUint32 aBit,
|
||||
const char* aMsg,
|
||||
const nsIParserNode& aNode,
|
||||
void* aThis)
|
||||
{
|
||||
// Reduce any entities
|
||||
// XXX Note: as coded today, this will only convert well formed
|
||||
// entities. This may not be compatible enough.
|
||||
// XXX there is a table in navigator that translates some numeric entities
|
||||
// should we be doing that? If so then it needs to live in two places (bad)
|
||||
// so we should add a translate numeric entity method from the parser...
|
||||
char cbuf[100];
|
||||
PRInt32 i = 0;
|
||||
while (i < aString.Length()) {
|
||||
// If we have the start of an entity (and it's not at the end of
|
||||
// our string) then translate the entity into it's unicode value.
|
||||
if ((aString.CharAt(i++) == '&') && (i < aString.Length())) {
|
||||
PRInt32 start = i - 1;
|
||||
PRUnichar e = aString.CharAt(i);
|
||||
if (e == '#') {
|
||||
// Convert a numeric character reference
|
||||
i++;
|
||||
char* cp = cbuf;
|
||||
char* limit = cp + sizeof(cbuf) - 1;
|
||||
PRBool ok = PR_FALSE;
|
||||
PRInt32 slen = aString.Length();
|
||||
while ((i < slen) && (cp < limit)) {
|
||||
e = aString.CharAt(i);
|
||||
if (e == ';') {
|
||||
i++;
|
||||
ok = PR_TRUE;
|
||||
break;
|
||||
}
|
||||
if ((e >= '0') && (e <= '9')) {
|
||||
*cp++ = char(e);
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (!ok || (cp == cbuf)) {
|
||||
continue;
|
||||
}
|
||||
*cp = '\0';
|
||||
if (cp - cbuf > 5) {
|
||||
continue;
|
||||
}
|
||||
PRInt32 ch = PRInt32( ::atoi(cbuf) );
|
||||
if (ch > 65535) {
|
||||
continue;
|
||||
}
|
||||
if (SINK_LOG_TEST(gSinkLogModuleInfo,aBit)) {
|
||||
char cbuf[40];
|
||||
const char* cp;
|
||||
nsAutoString str;
|
||||
PRInt32 nt = aNode.GetNodeType();
|
||||
if ((nt > PRInt32(eHTMLTag_unknown)) &&
|
||||
(nt < PRInt32(eHTMLTag_text)) && mParser) {
|
||||
nsCOMPtr<nsIDTD> dtd;
|
||||
mParser->GetDTD(getter_AddRefs(dtd));
|
||||
dtd->IntTagToStringTag(nsHTMLTag(aNode.GetNodeType()), str);
|
||||
cp = str.ToCString(cbuf, sizeof(cbuf));
|
||||
} else {
|
||||
aNode.GetText().ToCString(cbuf, sizeof(cbuf));
|
||||
cp = cbuf;
|
||||
}
|
||||
PR_LogPrint("%s: this=%p node='%s'", aMsg, aThis, cp);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// Remove entity from string and replace it with the integer
|
||||
// value.
|
||||
aString.Cut(start, i - start);
|
||||
aString.Insert(PRUnichar(ch), start);
|
||||
i = start + 1;
|
||||
}
|
||||
else if (((e >= 'A') && (e <= 'Z')) ||
|
||||
((e >= 'a') && (e <= 'z'))) {
|
||||
// Convert a named entity
|
||||
i++;
|
||||
char* cp = cbuf;
|
||||
char* limit = cp + sizeof(cbuf) - 1;
|
||||
*cp++ = char(e);
|
||||
PRBool ok = PR_FALSE;
|
||||
PRInt32 slen = aString.Length();
|
||||
while ((i < slen) && (cp < limit)) {
|
||||
e = aString.CharAt(i);
|
||||
if (e == ';') {
|
||||
i++;
|
||||
ok = PR_TRUE;
|
||||
break;
|
||||
}
|
||||
if (((e >= '0') && (e <= '9')) ||
|
||||
((e >= 'A') && (e <= 'Z')) ||
|
||||
((e >= 'a') && (e <= 'z'))) {
|
||||
*cp++ = char(e);
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (!ok || (cp == cbuf)) {
|
||||
continue;
|
||||
}
|
||||
*cp = '\0';
|
||||
PRInt32 ch = nsHTMLEntities::EntityToUnicode(nsSubsumeCStr(cbuf, PR_FALSE));
|
||||
if (ch < 0) {
|
||||
continue;
|
||||
}
|
||||
void
|
||||
HTMLContentSink::ReduceEntities(nsString& aString)
|
||||
{
|
||||
if (mParser) {
|
||||
nsCOMPtr<nsIDTD> dtd;
|
||||
|
||||
nsresult rv = mParser->GetDTD(getter_AddRefs(dtd));
|
||||
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
|
||||
// Remove entity from string and replace it with the integer
|
||||
// value.
|
||||
aString.Cut(start, i - start);
|
||||
aString.Insert(PRUnichar(ch), start);
|
||||
i = start + 1;
|
||||
}
|
||||
else if (e == '{') {
|
||||
// Convert a script entity
|
||||
// XXX write me!
|
||||
// Reduce any entities
|
||||
// XXX Note: as coded today, this will only convert well formed
|
||||
// entities. This may not be compatible enough.
|
||||
// XXX there is a table in navigator that translates some numeric entities
|
||||
// should we be doing that? If so then it needs to live in two places (bad)
|
||||
// so we should add a translate numeric entity method from the parser...
|
||||
char cbuf[100];
|
||||
PRInt32 i = 0;
|
||||
while (i < aString.Length()) {
|
||||
// If we have the start of an entity (and it's not at the end of
|
||||
// our string) then translate the entity into it's unicode value.
|
||||
if ((aString.CharAt(i++) == '&') && (i < aString.Length())) {
|
||||
PRInt32 start = i - 1;
|
||||
PRUnichar e = aString.CharAt(i);
|
||||
if (e == '#') {
|
||||
// Convert a numeric character reference
|
||||
i++;
|
||||
char* cp = cbuf;
|
||||
char* limit = cp + sizeof(cbuf) - 1;
|
||||
PRBool ok = PR_FALSE;
|
||||
PRInt32 slen = aString.Length();
|
||||
while ((i < slen) && (cp < limit)) {
|
||||
e = aString.CharAt(i);
|
||||
if (e == ';') {
|
||||
i++;
|
||||
ok = PR_TRUE;
|
||||
break;
|
||||
}
|
||||
if ((e >= '0') && (e <= '9')) {
|
||||
*cp++ = char(e);
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (!ok || (cp == cbuf)) {
|
||||
continue;
|
||||
}
|
||||
*cp = '\0';
|
||||
if (cp - cbuf > 5) {
|
||||
continue;
|
||||
}
|
||||
PRInt32 ch = PRInt32( ::atoi(cbuf) );
|
||||
if (ch > 65535) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Remove entity from string and replace it with the integer
|
||||
// value.
|
||||
aString.Cut(start, i - start);
|
||||
aString.Insert(PRUnichar(ch), start);
|
||||
i = start + 1;
|
||||
}
|
||||
else if (((e >= 'A') && (e <= 'Z')) ||
|
||||
((e >= 'a') && (e <= 'z'))) {
|
||||
// Convert a named entity
|
||||
i++;
|
||||
char* cp = cbuf;
|
||||
char* limit = cp + sizeof(cbuf) - 1;
|
||||
*cp++ = char(e);
|
||||
PRBool ok = PR_FALSE;
|
||||
PRInt32 slen = aString.Length();
|
||||
while ((i < slen) && (cp < limit)) {
|
||||
e = aString.CharAt(i);
|
||||
if (e == ';') {
|
||||
i++;
|
||||
ok = PR_TRUE;
|
||||
break;
|
||||
}
|
||||
if (((e >= '0') && (e <= '9')) ||
|
||||
((e >= 'A') && (e <= 'Z')) ||
|
||||
((e >= 'a') && (e <= 'z'))) {
|
||||
*cp++ = char(e);
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (!ok || (cp == cbuf)) {
|
||||
continue;
|
||||
}
|
||||
*cp = '\0';
|
||||
PRInt32 ch;
|
||||
nsAutoString str(cbuf);
|
||||
dtd->ConvertEntityToUnicode(str, &ch);
|
||||
|
||||
if (ch < 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Remove entity from string and replace it with the integer
|
||||
// value.
|
||||
aString.Cut(start, i - start);
|
||||
aString.Insert(PRUnichar(ch), start);
|
||||
i = start + 1;
|
||||
}
|
||||
else if (e == '{') {
|
||||
// Convert a script entity
|
||||
// XXX write me!
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -452,11 +494,11 @@ ReduceEntities(nsString& aString)
|
|||
|
||||
// Temporary factory code to create content objects
|
||||
|
||||
static void
|
||||
GetAttributeValueAt(const nsIParserNode& aNode,
|
||||
PRInt32 aIndex,
|
||||
nsString& aResult,
|
||||
nsIScriptContextOwner* aScriptContextOwner)
|
||||
void
|
||||
HTMLContentSink::GetAttributeValueAt(const nsIParserNode& aNode,
|
||||
PRInt32 aIndex,
|
||||
nsString& aResult,
|
||||
nsIScriptContextOwner* aScriptContextOwner)
|
||||
{
|
||||
// Copy value
|
||||
const nsString& value = aNode.GetValueAt(aIndex);
|
||||
|
@ -479,11 +521,11 @@ GetAttributeValueAt(const nsIParserNode& aNode,
|
|||
ReduceEntities(aResult);
|
||||
}
|
||||
|
||||
static nsresult
|
||||
AddAttributes(const nsIParserNode& aNode,
|
||||
nsIHTMLContent* aContent,
|
||||
nsIScriptContextOwner* aScriptContextOwner,
|
||||
PRBool aNotify = PR_FALSE)
|
||||
nsresult
|
||||
HTMLContentSink::AddAttributes(const nsIParserNode& aNode,
|
||||
nsIHTMLContent* aContent,
|
||||
nsIScriptContextOwner* aScriptContextOwner,
|
||||
PRBool aNotify)
|
||||
{
|
||||
// Add tag attributes to the content attributes
|
||||
nsAutoString k, v;
|
||||
|
@ -782,13 +824,15 @@ GetOptionText(const nsIParserNode& aNode, nsString& aText)
|
|||
/**
|
||||
* Factory subroutine to create all of the html content objects.
|
||||
*/
|
||||
static nsresult
|
||||
CreateContentObject(const nsIParserNode& aNode,
|
||||
nsHTMLTag aNodeType,
|
||||
nsIDOMHTMLFormElement* aForm,
|
||||
nsIWebShell* aWebShell,
|
||||
nsIHTMLContent** aResult)
|
||||
nsresult
|
||||
HTMLContentSink::CreateContentObject(const nsIParserNode& aNode,
|
||||
nsHTMLTag aNodeType,
|
||||
nsIDOMHTMLFormElement* aForm,
|
||||
nsIWebShell* aWebShell,
|
||||
nsIHTMLContent** aResult)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
// Find/create atom for the tag name
|
||||
nsAutoString tmp;
|
||||
if (eHTMLTag_userdefined == aNodeType) {
|
||||
|
@ -796,41 +840,63 @@ CreateContentObject(const nsIParserNode& aNode,
|
|||
tmp.ToLowerCase();
|
||||
}
|
||||
else {
|
||||
tmp.Append(nsHTMLTags::GetStringValue(aNodeType));
|
||||
}
|
||||
nsIAtom* atom = NS_NewAtom(tmp);
|
||||
if (nsnull == atom) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
nsCOMPtr<nsIDTD> dtd;
|
||||
rv = mParser->GetDTD(getter_AddRefs(dtd));
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
nsAutoString str;
|
||||
dtd->IntTagToStringTag(aNodeType, str);
|
||||
tmp.Append(str);
|
||||
}
|
||||
}
|
||||
|
||||
// Make the content object
|
||||
// XXX why is textarea not a container?
|
||||
nsAutoString content;
|
||||
if (eHTMLTag_textarea == aNodeType) {
|
||||
content = aNode.GetSkippedContent();
|
||||
}
|
||||
nsresult rv = MakeContentObject(aNodeType, atom, aForm, aWebShell,
|
||||
aResult, &content);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
nsIAtom* atom = NS_NewAtom(tmp);
|
||||
if (nsnull == atom) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
NS_RELEASE(atom);
|
||||
// Make the content object
|
||||
// XXX why is textarea not a container?
|
||||
nsAutoString content;
|
||||
if (eHTMLTag_textarea == aNodeType) {
|
||||
content = aNode.GetSkippedContent();
|
||||
}
|
||||
rv = MakeContentObject(aNodeType, atom, aForm, aWebShell,
|
||||
aResult, &content);
|
||||
|
||||
NS_RELEASE(atom);
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
static NS_DEFINE_CID(kParserServiceCID, NS_PARSERSERVICE_CID);
|
||||
|
||||
nsresult
|
||||
NS_CreateHTMLElement(nsIHTMLContent** aResult, const nsString& aTag)
|
||||
{
|
||||
// Find tag in tag table
|
||||
nsHTMLTag id = nsHTMLTags::LookupTag(aTag);
|
||||
if (eHTMLTag_userdefined == id) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
// Create atom for tag and then create content object
|
||||
const nsCString& tag = nsHTMLTags::GetStringValue(id);
|
||||
nsIAtom* atom = NS_NewAtom((const char*)tag);
|
||||
nsresult rv = MakeContentObject(id, atom, nsnull, nsnull, aResult);
|
||||
NS_RELEASE(atom);
|
||||
NS_WITH_SERVICE(nsIParserService,
|
||||
parserService,
|
||||
kParserServiceCID,
|
||||
&rv);
|
||||
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
// Find tag in tag table
|
||||
PRInt32 id;
|
||||
rv = parserService->HTMLStringTagToId(aTag, &id);
|
||||
if (eHTMLTag_userdefined == nsHTMLTag(id)) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
// Create atom for tag and then create content object
|
||||
nsAutoString tag;
|
||||
rv = parserService->HTMLIdToStringTag(id, tag);
|
||||
nsIAtom* atom = NS_NewAtom(tag.GetUnicode());
|
||||
rv = MakeContentObject(nsHTMLTag(id), atom, nsnull, nsnull, aResult);
|
||||
NS_RELEASE(atom);
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
@ -994,7 +1060,7 @@ SinkContext::OpenContainer(const nsIParserNode& aNode)
|
|||
FlushText();
|
||||
|
||||
SINK_TRACE_NODE(SINK_TRACE_CALLS,
|
||||
"SinkContext::OpenContainer", aNode);
|
||||
"SinkContext::OpenContainer", aNode, mSink);
|
||||
|
||||
nsresult rv;
|
||||
if (mStackPos + 1 > mStackSize) {
|
||||
|
@ -1007,10 +1073,10 @@ SinkContext::OpenContainer(const nsIParserNode& aNode)
|
|||
// Create new container content object
|
||||
nsHTMLTag nodeType = nsHTMLTag(aNode.GetNodeType());
|
||||
nsIHTMLContent* content;
|
||||
rv = CreateContentObject(aNode, nodeType,
|
||||
mSink->mCurrentForm,
|
||||
mSink->mFrameset ? mSink->mWebShell : nsnull,
|
||||
&content);
|
||||
rv = mSink->CreateContentObject(aNode, nodeType,
|
||||
mSink->mCurrentForm,
|
||||
mSink->mFrameset ? mSink->mWebShell : nsnull,
|
||||
&content);
|
||||
if (NS_OK != rv) {
|
||||
return rv;
|
||||
}
|
||||
|
@ -1022,7 +1088,7 @@ SinkContext::OpenContainer(const nsIParserNode& aNode)
|
|||
content->SetDocument(mSink->mDocument, PR_FALSE);
|
||||
|
||||
nsIScriptContextOwner* sco = mSink->mDocument->GetScriptContextOwner();
|
||||
rv = AddAttributes(aNode, content, sco);
|
||||
rv = mSink->AddAttributes(aNode, content, sco);
|
||||
NS_IF_RELEASE(sco);
|
||||
|
||||
if (mPreAppend) {
|
||||
|
@ -1073,7 +1139,7 @@ SinkContext::CloseContainer(const nsIParserNode& aNode)
|
|||
FlushText();
|
||||
|
||||
SINK_TRACE_NODE(SINK_TRACE_CALLS,
|
||||
"SinkContext::CloseContainer", aNode);
|
||||
"SinkContext::CloseContainer", aNode, mSink);
|
||||
|
||||
--mStackPos;
|
||||
nsHTMLTag nodeType = mStack[mStackPos].mType;
|
||||
|
@ -1242,7 +1308,7 @@ nsresult
|
|||
SinkContext::AddLeaf(const nsIParserNode& aNode)
|
||||
{
|
||||
SINK_TRACE_NODE(SINK_TRACE_CALLS,
|
||||
"SinkContext::AddLeaf", aNode);
|
||||
"SinkContext::AddLeaf", aNode, mSink);
|
||||
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
|
@ -1254,9 +1320,9 @@ SinkContext::AddLeaf(const nsIParserNode& aNode)
|
|||
// Create new leaf content object
|
||||
nsHTMLTag nodeType = nsHTMLTag(aNode.GetNodeType());
|
||||
nsIHTMLContent* content;
|
||||
rv = CreateContentObject(aNode, nodeType,
|
||||
mSink->mCurrentForm, mSink->mWebShell,
|
||||
&content);
|
||||
rv = mSink->CreateContentObject(aNode, nodeType,
|
||||
mSink->mCurrentForm, mSink->mWebShell,
|
||||
&content);
|
||||
if (NS_OK != rv) {
|
||||
return rv;
|
||||
}
|
||||
|
@ -1266,7 +1332,7 @@ SinkContext::AddLeaf(const nsIParserNode& aNode)
|
|||
content->SetDocument(mSink->mDocument, PR_FALSE);
|
||||
|
||||
nsIScriptContextOwner* sco = mSink->mDocument->GetScriptContextOwner();
|
||||
rv = AddAttributes(aNode, content, sco);
|
||||
rv = mSink->AddAttributes(aNode, content, sco);
|
||||
NS_IF_RELEASE(sco);
|
||||
if (NS_OK != rv) {
|
||||
NS_RELEASE(content);
|
||||
|
@ -1900,7 +1966,7 @@ HTMLContentSink::OpenHTML(const nsIParserNode& aNode)
|
|||
|
||||
NS_START_STOPWATCH(mWatch)
|
||||
SINK_TRACE_NODE(SINK_TRACE_CALLS,
|
||||
"HTMLContentSink::OpenHTML", aNode);
|
||||
"HTMLContentSink::OpenHTML", aNode, this);
|
||||
|
||||
NS_STOP_STOPWATCH(mWatch)
|
||||
return NS_OK;
|
||||
|
@ -1911,7 +1977,7 @@ HTMLContentSink::CloseHTML(const nsIParserNode& aNode)
|
|||
{
|
||||
NS_START_STOPWATCH(mWatch)
|
||||
SINK_TRACE_NODE(SINK_TRACE_CALLS,
|
||||
"HTMLContentSink::CloseHTML", aNode);
|
||||
"HTMLContentSink::CloseHTML", aNode, this);
|
||||
if (nsnull != mHeadContext) {
|
||||
mHeadContext->End();
|
||||
delete mHeadContext;
|
||||
|
@ -1926,7 +1992,7 @@ HTMLContentSink::OpenHead(const nsIParserNode& aNode)
|
|||
{
|
||||
NS_START_STOPWATCH(mWatch)
|
||||
SINK_TRACE_NODE(SINK_TRACE_CALLS,
|
||||
"HTMLContentSink::OpenHead", aNode);
|
||||
"HTMLContentSink::OpenHead", aNode, this);
|
||||
nsresult rv = NS_OK;
|
||||
if (nsnull == mHeadContext) {
|
||||
mHeadContext = new SinkContext(this);
|
||||
|
@ -1959,7 +2025,7 @@ HTMLContentSink::CloseHead(const nsIParserNode& aNode)
|
|||
{
|
||||
NS_START_STOPWATCH(mWatch)
|
||||
SINK_TRACE_NODE(SINK_TRACE_CALLS,
|
||||
"HTMLContentSink::CloseHead", aNode);
|
||||
"HTMLContentSink::CloseHead", aNode, this);
|
||||
PRInt32 n = mContextStack.Count() - 1;
|
||||
mCurrentContext = (SinkContext*) mContextStack.ElementAt(n);
|
||||
mContextStack.RemoveElementAt(n);
|
||||
|
@ -1974,7 +2040,7 @@ HTMLContentSink::OpenBody(const nsIParserNode& aNode)
|
|||
//NS_PRECONDITION(nsnull == mBody, "parser called OpenBody twice");
|
||||
|
||||
SINK_TRACE_NODE(SINK_TRACE_CALLS,
|
||||
"HTMLContentSink::OpenBody", aNode);
|
||||
"HTMLContentSink::OpenBody", aNode, this);
|
||||
// Add attributes, if any, to the current BODY node
|
||||
if(mBody != nsnull){
|
||||
nsIScriptContextOwner* sco = mDocument->GetScriptContextOwner();
|
||||
|
@ -2007,7 +2073,7 @@ HTMLContentSink::CloseBody(const nsIParserNode& aNode)
|
|||
{
|
||||
NS_START_STOPWATCH(mWatch)
|
||||
SINK_TRACE_NODE(SINK_TRACE_CALLS,
|
||||
"HTMLContentSink::CloseBody", aNode);
|
||||
"HTMLContentSink::CloseBody", aNode, this);
|
||||
|
||||
PRBool didFlush;
|
||||
nsresult rv = mCurrentContext->FlushText(&didFlush);
|
||||
|
@ -2036,7 +2102,7 @@ HTMLContentSink::OpenForm(const nsIParserNode& aNode)
|
|||
mCurrentContext->FlushText();
|
||||
|
||||
SINK_TRACE_NODE(SINK_TRACE_CALLS,
|
||||
"HTMLContentSink::OpenForm", aNode);
|
||||
"HTMLContentSink::OpenForm", aNode, this);
|
||||
|
||||
// Close out previous form if it's there. If there is one
|
||||
// around, it's probably because the last one wasn't well-formed.
|
||||
|
@ -2096,7 +2162,7 @@ HTMLContentSink::CloseForm(const nsIParserNode& aNode)
|
|||
|
||||
mCurrentContext->FlushText();
|
||||
SINK_TRACE_NODE(SINK_TRACE_CALLS,
|
||||
"HTMLContentSink::CloseForm", aNode);
|
||||
"HTMLContentSink::CloseForm", aNode, this);
|
||||
|
||||
if (nsnull != mCurrentForm) {
|
||||
// Check if this is a well-formed form
|
||||
|
@ -2125,7 +2191,7 @@ HTMLContentSink::OpenFrameset(const nsIParserNode& aNode)
|
|||
{
|
||||
NS_START_STOPWATCH(mWatch)
|
||||
SINK_TRACE_NODE(SINK_TRACE_CALLS,
|
||||
"HTMLContentSink::OpenFrameset", aNode);
|
||||
"HTMLContentSink::OpenFrameset", aNode, this);
|
||||
|
||||
nsresult rv = mCurrentContext->OpenContainer(aNode);
|
||||
if ((NS_OK == rv) && (nsnull == mFrameset)) {
|
||||
|
@ -2142,7 +2208,7 @@ HTMLContentSink::CloseFrameset(const nsIParserNode& aNode)
|
|||
{
|
||||
NS_START_STOPWATCH(mWatch)
|
||||
SINK_TRACE_NODE(SINK_TRACE_CALLS,
|
||||
"HTMLContentSink::CloseFrameset", aNode);
|
||||
"HTMLContentSink::CloseFrameset", aNode, this);
|
||||
|
||||
SinkContext* sc = mCurrentContext;
|
||||
nsIHTMLContent* fs = sc->mStack[sc->mStackPos-1].mContent;
|
||||
|
@ -2161,7 +2227,7 @@ HTMLContentSink::OpenMap(const nsIParserNode& aNode)
|
|||
NS_START_STOPWATCH(mWatch)
|
||||
nsresult rv = NS_OK;
|
||||
SINK_TRACE_NODE(SINK_TRACE_CALLS,
|
||||
"HTMLContentSink::OpenMap", aNode);
|
||||
"HTMLContentSink::OpenMap", aNode, this);
|
||||
// We used to treat MAP elements specially (i.e. they were
|
||||
// only parent elements for AREAs), but we don't anymore.
|
||||
// HTML 4.0 says that MAP elements can have block content
|
||||
|
@ -2177,7 +2243,7 @@ HTMLContentSink::CloseMap(const nsIParserNode& aNode)
|
|||
NS_START_STOPWATCH(mWatch)
|
||||
nsresult rv = NS_OK;
|
||||
SINK_TRACE_NODE(SINK_TRACE_CALLS,
|
||||
"HTMLContentSink::CloseMap", aNode);
|
||||
"HTMLContentSink::CloseMap", aNode, this);
|
||||
NS_IF_RELEASE(mCurrentMap);
|
||||
NS_IF_RELEASE(mCurrentDOMMap);
|
||||
|
||||
|
|
|
@ -66,6 +66,7 @@
|
|||
#include "nsICookieService.h"
|
||||
#endif // NECKO
|
||||
|
||||
#include "nsIParserService.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsIFormManager.h"
|
||||
#include "nsIComponentManager.h"
|
||||
|
@ -2297,7 +2298,8 @@ IsNamedItem(nsIContent* aContent, nsIAtom *aTag,
|
|||
if ((aTag == nsHTMLAtoms::img) || (aTag == nsHTMLAtoms::form) ||
|
||||
(!aInForm && ((aTag == nsHTMLAtoms::applet) ||
|
||||
(aTag == nsHTMLAtoms::embed)))) {
|
||||
if (NS_CONTENT_ATTR_HAS_VALUE == aContent->GetAttribute(kNameSpaceID_HTML, nsHTMLAtoms::name, aName)) {
|
||||
if ((NS_CONTENT_ATTR_HAS_VALUE == aContent->GetAttribute(kNameSpaceID_HTML, nsHTMLAtoms::name, aName)) ||
|
||||
(NS_CONTENT_ATTR_HAS_VALUE == aContent->GetAttribute(kNameSpaceID_HTML, nsHTMLAtoms::id, aName))) {
|
||||
return PR_TRUE;
|
||||
}
|
||||
}
|
||||
|
@ -2759,6 +2761,8 @@ PRBool nsHTMLDocument::SearchBlock(BlockText & aBlockText,
|
|||
return found;
|
||||
}
|
||||
|
||||
static NS_DEFINE_CID(kParserServiceCID, NS_PARSERSERVICE_CID);
|
||||
|
||||
////////////////////////////////////////////////////
|
||||
// Check to see if a Content node is a block tag
|
||||
////////////////////////////////////////////////////
|
||||
|
@ -2775,7 +2779,19 @@ PRBool nsHTMLDocument::NodeIsBlock(nsIDOMNode * aNode)
|
|||
domElement->GetTagName(tagName);
|
||||
NS_RELEASE(domElement);
|
||||
|
||||
isBlock = IsBlockLevel(nsHTMLTags::LookupTag(tagName), mIsPreTag);
|
||||
// XXX Should be done at a higher level than this routine
|
||||
// since getting the service is not the cheapest operation.
|
||||
// Waiting for mjudge to tell me where since it looks like
|
||||
// this code is still in development.
|
||||
|
||||
NS_WITH_SERVICE(nsIParserService, service, kParserServiceCID, &rv);
|
||||
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
PRInt32 id;
|
||||
|
||||
service->HTMLStringTagToId(tagName, &id);
|
||||
isBlock = IsBlockLevel(nsHTMLTag(id), mIsPreTag);
|
||||
}
|
||||
|
||||
return isBlock;
|
||||
}
|
||||
|
|
|
@ -94,6 +94,9 @@ public:
|
|||
PRInt32 PushContent(nsIContent *aContent);
|
||||
nsIContent* PopContent();
|
||||
|
||||
void GetAttributeValueAt(const nsIParserNode& aNode,
|
||||
PRInt32 aIndex,
|
||||
nsString& aResult);
|
||||
nsresult AddAttributes(const nsIParserNode& aNode,
|
||||
nsIContent* aContent);
|
||||
|
||||
|
@ -636,10 +639,10 @@ nsHTMLFragmentContentSink::FlushText()
|
|||
}
|
||||
|
||||
// XXX Code copied from nsHTMLContentSink. It should be shared.
|
||||
static void
|
||||
GetAttributeValueAt(const nsIParserNode& aNode,
|
||||
PRInt32 aIndex,
|
||||
nsString& aResult)
|
||||
void
|
||||
nsHTMLFragmentContentSink::GetAttributeValueAt(const nsIParserNode& aNode,
|
||||
PRInt32 aIndex,
|
||||
nsString& aResult)
|
||||
{
|
||||
// Copy value
|
||||
const nsString& value = aNode.GetValueAt(aIndex);
|
||||
|
@ -660,102 +663,113 @@ GetAttributeValueAt(const nsIParserNode& aNode,
|
|||
}
|
||||
}
|
||||
|
||||
// Reduce any entities
|
||||
// XXX Note: as coded today, this will only convert well formed
|
||||
// entities. This may not be compatible enough.
|
||||
// XXX there is a table in navigator that translates some numeric entities
|
||||
// should we be doing that? If so then it needs to live in two places (bad)
|
||||
// so we should add a translate numeric entity method from the parser...
|
||||
char cbuf[100];
|
||||
PRInt32 indx = 0;
|
||||
while (indx < aResult.Length()) {
|
||||
// If we have the start of an entity (and it's not at the end of
|
||||
// our string) then translate the entity into it's unicode value.
|
||||
if ((aResult.CharAt(indx++) == '&') && (indx < aResult.Length())) {
|
||||
PRInt32 start = indx - 1;
|
||||
PRUnichar e = aResult.CharAt(indx);
|
||||
if (e == '#') {
|
||||
// Convert a numeric character reference
|
||||
indx++;
|
||||
char* cp = cbuf;
|
||||
char* limit = cp + sizeof(cbuf) - 1;
|
||||
PRBool ok = PR_FALSE;
|
||||
PRInt32 slen = aResult.Length();
|
||||
while ((indx < slen) && (cp < limit)) {
|
||||
e = aResult.CharAt(indx);
|
||||
if (e == ';') {
|
||||
if (mParser) {
|
||||
nsCOMPtr<nsIDTD> dtd;
|
||||
|
||||
nsresult rv = mParser->GetDTD(getter_AddRefs(dtd));
|
||||
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
// Reduce any entities
|
||||
// XXX Note: as coded today, this will only convert well formed
|
||||
// entities. This may not be compatible enough.
|
||||
// XXX there is a table in navigator that translates some numeric entities
|
||||
// should we be doing that? If so then it needs to live in two places (bad)
|
||||
// so we should add a translate numeric entity method from the parser...
|
||||
char cbuf[100];
|
||||
PRInt32 indx = 0;
|
||||
while (indx < aResult.Length()) {
|
||||
// If we have the start of an entity (and it's not at the end of
|
||||
// our string) then translate the entity into it's unicode value.
|
||||
if ((aResult.CharAt(indx++) == '&') && (indx < aResult.Length())) {
|
||||
PRInt32 start = indx - 1;
|
||||
PRUnichar e = aResult.CharAt(indx);
|
||||
if (e == '#') {
|
||||
// Convert a numeric character reference
|
||||
indx++;
|
||||
ok = PR_TRUE;
|
||||
break;
|
||||
char* cp = cbuf;
|
||||
char* limit = cp + sizeof(cbuf) - 1;
|
||||
PRBool ok = PR_FALSE;
|
||||
PRInt32 slen = aResult.Length();
|
||||
while ((indx < slen) && (cp < limit)) {
|
||||
e = aResult.CharAt(indx);
|
||||
if (e == ';') {
|
||||
indx++;
|
||||
ok = PR_TRUE;
|
||||
break;
|
||||
}
|
||||
if ((e >= '0') && (e <= '9')) {
|
||||
*cp++ = char(e);
|
||||
indx++;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (!ok || (cp == cbuf)) {
|
||||
continue;
|
||||
}
|
||||
*cp = '\0';
|
||||
if (cp - cbuf > 5) {
|
||||
continue;
|
||||
}
|
||||
PRInt32 ch = PRInt32( ::atoi(cbuf) );
|
||||
if (ch > 65535) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Remove entity from string and replace it with the integer
|
||||
// value.
|
||||
aResult.Cut(start, indx - start);
|
||||
aResult.Insert(PRUnichar(ch), start);
|
||||
indx = start + 1;
|
||||
}
|
||||
if ((e >= '0') && (e <= '9')) {
|
||||
else if (((e >= 'A') && (e <= 'Z')) ||
|
||||
((e >= 'a') && (e <= 'z'))) {
|
||||
// Convert a named entity
|
||||
indx++;
|
||||
char* cp = cbuf;
|
||||
char* limit = cp + sizeof(cbuf) - 1;
|
||||
*cp++ = char(e);
|
||||
indx++;
|
||||
continue;
|
||||
PRBool ok = PR_FALSE;
|
||||
PRInt32 slen = aResult.Length();
|
||||
while ((indx < slen) && (cp < limit)) {
|
||||
e = aResult.CharAt(indx);
|
||||
if (e == ';') {
|
||||
indx++;
|
||||
ok = PR_TRUE;
|
||||
break;
|
||||
}
|
||||
if (((e >= '0') && (e <= '9')) ||
|
||||
((e >= 'A') && (e <= 'Z')) ||
|
||||
((e >= 'a') && (e <= 'z'))) {
|
||||
*cp++ = char(e);
|
||||
indx++;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (!ok || (cp == cbuf)) {
|
||||
continue;
|
||||
}
|
||||
*cp = '\0';
|
||||
PRInt32 ch;
|
||||
nsAutoString str(cbuf);
|
||||
dtd->ConvertEntityToUnicode(str, &ch);
|
||||
|
||||
if (ch < 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Remove entity from string and replace it with the integer
|
||||
// value.
|
||||
aResult.Cut(start, indx - start);
|
||||
aResult.Insert(PRUnichar(ch), start);
|
||||
indx = start + 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (!ok || (cp == cbuf)) {
|
||||
continue;
|
||||
}
|
||||
*cp = '\0';
|
||||
if (cp - cbuf > 5) {
|
||||
continue;
|
||||
}
|
||||
PRInt32 ch = PRInt32( ::atoi(cbuf) );
|
||||
if (ch > 65535) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Remove entity from string and replace it with the integer
|
||||
// value.
|
||||
aResult.Cut(start, indx - start);
|
||||
aResult.Insert(PRUnichar(ch), start);
|
||||
indx = start + 1;
|
||||
}
|
||||
else if (((e >= 'A') && (e <= 'Z')) ||
|
||||
((e >= 'a') && (e <= 'z'))) {
|
||||
// Convert a named entity
|
||||
indx++;
|
||||
char* cp = cbuf;
|
||||
char* limit = cp + sizeof(cbuf) - 1;
|
||||
*cp++ = char(e);
|
||||
PRBool ok = PR_FALSE;
|
||||
PRInt32 slen = aResult.Length();
|
||||
while ((indx < slen) && (cp < limit)) {
|
||||
e = aResult.CharAt(indx);
|
||||
if (e == ';') {
|
||||
indx++;
|
||||
ok = PR_TRUE;
|
||||
break;
|
||||
else if (e == '{') {
|
||||
// Convert a script entity
|
||||
// XXX write me!
|
||||
}
|
||||
if (((e >= '0') && (e <= '9')) ||
|
||||
((e >= 'A') && (e <= 'Z')) ||
|
||||
((e >= 'a') && (e <= 'z'))) {
|
||||
*cp++ = char(e);
|
||||
indx++;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (!ok || (cp == cbuf)) {
|
||||
continue;
|
||||
}
|
||||
*cp = '\0';
|
||||
PRInt32 ch = nsHTMLEntities::EntityToUnicode(nsSubsumeCStr(cbuf, PR_FALSE));
|
||||
if (ch < 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Remove entity from string and replace it with the integer
|
||||
// value.
|
||||
aResult.Cut(start, indx - start);
|
||||
aResult.Insert(PRUnichar(ch), start);
|
||||
indx = start + 1;
|
||||
}
|
||||
else if (e == '{') {
|
||||
// Convert a script entity
|
||||
// XXX write me!
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -410,10 +410,10 @@ nsXMLContentSink::SetParser(nsIParser* aParser)
|
|||
}
|
||||
|
||||
// XXX Code copied from nsHTMLContentSink. It should be shared.
|
||||
static void
|
||||
GetAttributeValueAt(const nsIParserNode& aNode,
|
||||
PRInt32 aIndex,
|
||||
nsString& aResult)
|
||||
void
|
||||
nsXMLContentSink::GetAttributeValueAt(const nsIParserNode& aNode,
|
||||
PRInt32 aIndex,
|
||||
nsString& aResult)
|
||||
{
|
||||
// Copy value
|
||||
const nsString& value = aNode.GetValueAt(aIndex);
|
||||
|
@ -434,102 +434,113 @@ GetAttributeValueAt(const nsIParserNode& aNode,
|
|||
}
|
||||
}
|
||||
|
||||
// Reduce any entities
|
||||
// XXX Note: as coded today, this will only convert well formed
|
||||
// entities. This may not be compatible enough.
|
||||
// XXX there is a table in navigator that translates some numeric entities
|
||||
// should we be doing that? If so then it needs to live in two places (bad)
|
||||
// so we should add a translate numeric entity method from the parser...
|
||||
char cbuf[100];
|
||||
PRInt32 index = 0;
|
||||
while (index < aResult.Length()) {
|
||||
// If we have the start of an entity (and it's not at the end of
|
||||
// our string) then translate the entity into it's unicode value.
|
||||
if ((aResult.CharAt(index++) == '&') && (index < aResult.Length())) {
|
||||
PRInt32 start = index - 1;
|
||||
PRUnichar e = aResult.CharAt(index);
|
||||
if (e == '#') {
|
||||
// Convert a numeric character reference
|
||||
index++;
|
||||
char* cp = cbuf;
|
||||
char* limit = cp + sizeof(cbuf) - 1;
|
||||
PRBool ok = PR_FALSE;
|
||||
PRInt32 slen = aResult.Length();
|
||||
while ((index < slen) && (cp < limit)) {
|
||||
PRUnichar ch = aResult.CharAt(index);
|
||||
if (ch == ';') {
|
||||
if (mParser) {
|
||||
nsCOMPtr<nsIDTD> dtd;
|
||||
|
||||
nsresult rv = mParser->GetDTD(getter_AddRefs(dtd));
|
||||
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
|
||||
// Reduce any entities
|
||||
// XXX Note: as coded today, this will only convert well formed
|
||||
// entities. This may not be compatible enough.
|
||||
// XXX there is a table in navigator that translates some numeric entities
|
||||
// should we be doing that? If so then it needs to live in two places (bad)
|
||||
// so we should add a translate numeric entity method from the parser...
|
||||
char cbuf[100];
|
||||
PRInt32 index = 0;
|
||||
while (index < aResult.Length()) {
|
||||
// If we have the start of an entity (and it's not at the end of
|
||||
// our string) then translate the entity into it's unicode value.
|
||||
if ((aResult.CharAt(index++) == '&') && (index < aResult.Length())) {
|
||||
PRInt32 start = index - 1;
|
||||
PRUnichar e = aResult.CharAt(index);
|
||||
if (e == '#') {
|
||||
// Convert a numeric character reference
|
||||
index++;
|
||||
ok = PR_TRUE;
|
||||
break;
|
||||
char* cp = cbuf;
|
||||
char* limit = cp + sizeof(cbuf) - 1;
|
||||
PRBool ok = PR_FALSE;
|
||||
PRInt32 slen = aResult.Length();
|
||||
while ((index < slen) && (cp < limit)) {
|
||||
PRUnichar ch = aResult.CharAt(index);
|
||||
if (ch == ';') {
|
||||
index++;
|
||||
ok = PR_TRUE;
|
||||
break;
|
||||
}
|
||||
if ((ch >= '0') && (ch <= '9')) {
|
||||
*cp++ = char(ch);
|
||||
index++;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (!ok || (cp == cbuf)) {
|
||||
continue;
|
||||
}
|
||||
*cp = '\0';
|
||||
if (cp - cbuf > 5) {
|
||||
continue;
|
||||
}
|
||||
PRInt32 ch = PRInt32( ::atoi(cbuf) );
|
||||
if (ch > 65535) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Remove entity from string and replace it with the integer
|
||||
// value.
|
||||
aResult.Cut(start, index - start);
|
||||
aResult.Insert(PRUnichar(ch), start);
|
||||
index = start + 1;
|
||||
}
|
||||
if ((ch >= '0') && (ch <= '9')) {
|
||||
*cp++ = char(ch);
|
||||
else if (((e >= 'A') && (e <= 'Z')) ||
|
||||
((e >= 'a') && (e <= 'z'))) {
|
||||
// Convert a named entity
|
||||
index++;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (!ok || (cp == cbuf)) {
|
||||
continue;
|
||||
}
|
||||
*cp = '\0';
|
||||
if (cp - cbuf > 5) {
|
||||
continue;
|
||||
}
|
||||
PRInt32 ch = PRInt32( ::atoi(cbuf) );
|
||||
if (ch > 65535) {
|
||||
continue;
|
||||
}
|
||||
char* cp = cbuf;
|
||||
char* limit = cp + sizeof(cbuf) - 1;
|
||||
*cp++ = char(e);
|
||||
PRBool ok = PR_FALSE;
|
||||
PRInt32 slen = aResult.Length();
|
||||
while ((index < slen) && (cp < limit)) {
|
||||
PRUnichar ch = aResult.CharAt(index);
|
||||
if (ch == ';') {
|
||||
index++;
|
||||
ok = PR_TRUE;
|
||||
break;
|
||||
}
|
||||
if (((ch >= '0') && (ch <= '9')) ||
|
||||
((ch >= 'A') && (ch <= 'Z')) ||
|
||||
((ch >= 'a') && (ch <= 'z'))) {
|
||||
*cp++ = char(ch);
|
||||
index++;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (!ok || (cp == cbuf)) {
|
||||
continue;
|
||||
}
|
||||
*cp = '\0';
|
||||
PRInt32 ch;
|
||||
nsAutoString str(cbuf);
|
||||
dtd->ConvertEntityToUnicode(str, &ch);
|
||||
if (ch < 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Remove entity from string and replace it with the integer
|
||||
// value.
|
||||
aResult.Cut(start, index - start);
|
||||
aResult.Insert(PRUnichar(ch), start);
|
||||
index = start + 1;
|
||||
}
|
||||
else if (((e >= 'A') && (e <= 'Z')) ||
|
||||
((e >= 'a') && (e <= 'z'))) {
|
||||
// Convert a named entity
|
||||
index++;
|
||||
char* cp = cbuf;
|
||||
char* limit = cp + sizeof(cbuf) - 1;
|
||||
*cp++ = char(e);
|
||||
PRBool ok = PR_FALSE;
|
||||
PRInt32 slen = aResult.Length();
|
||||
while ((index < slen) && (cp < limit)) {
|
||||
PRUnichar ch = aResult.CharAt(index);
|
||||
if (ch == ';') {
|
||||
index++;
|
||||
ok = PR_TRUE;
|
||||
break;
|
||||
// Remove entity from string and replace it with the integer
|
||||
// value.
|
||||
aResult.Cut(start, index - start);
|
||||
aResult.Insert(PRUnichar(ch), start);
|
||||
index = start + 1;
|
||||
}
|
||||
if (((ch >= '0') && (ch <= '9')) ||
|
||||
((ch >= 'A') && (ch <= 'Z')) ||
|
||||
((ch >= 'a') && (ch <= 'z'))) {
|
||||
*cp++ = char(ch);
|
||||
index++;
|
||||
continue;
|
||||
else if (e == '{') {
|
||||
// Convert a script entity
|
||||
// XXX write me!
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (!ok || (cp == cbuf)) {
|
||||
continue;
|
||||
}
|
||||
*cp = '\0';
|
||||
PRInt32 ch = nsHTMLEntities::EntityToUnicode(nsSubsumeCStr(cbuf, PR_FALSE));
|
||||
if (ch < 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Remove entity from string and replace it with the integer
|
||||
// value.
|
||||
aResult.Cut(start, index - start);
|
||||
aResult.Insert(PRUnichar(ch), start);
|
||||
index = start + 1;
|
||||
}
|
||||
else if (e == '{') {
|
||||
// Convert a script entity
|
||||
// XXX write me!
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -102,7 +102,9 @@ protected:
|
|||
|
||||
nsresult FlushText(PRBool aCreateTextNode=PR_TRUE,
|
||||
PRBool* aDidFlush=nsnull);
|
||||
|
||||
void GetAttributeValueAt(const nsIParserNode& aNode,
|
||||
PRInt32 aIndex,
|
||||
nsString& aResult);
|
||||
nsresult AddAttributes(const nsIParserNode& aNode,
|
||||
nsIContent* aContent,
|
||||
PRBool aIsHTML);
|
||||
|
|
Загрузка…
Ссылка в новой задаче