зеркало из https://github.com/mozilla/gecko-dev.git
Bug 169124: Make the XSLT contentsink create generic xml-elements for all elements to get around limitations with xhtml elements. Also do some cleaning in the XML contentsink.
r=harishd sr=peterv
This commit is contained in:
Родитель
2fd32d5576
Коммит
4ef08f6409
|
@ -720,46 +720,43 @@ nsXBLContentSink::ConstructParameter(const PRUnichar **aAtts)
|
|||
}
|
||||
|
||||
nsresult
|
||||
nsXBLContentSink::CreateElement(const PRUnichar** aAtts,
|
||||
PRUint32 aAttsCount,
|
||||
PRInt32 aNameSpaceID,
|
||||
nsINodeInfo* aNodeInfo,
|
||||
nsIContent** aResult)
|
||||
nsXBLContentSink::CreateElement(const PRUnichar** aAtts, PRUint32 aAttsCount,
|
||||
nsINodeInfo* aNodeInfo, PRUint32 aLineNumber,
|
||||
nsIContent** aResult, PRBool* aAppendContent)
|
||||
{
|
||||
if (aNameSpaceID == kNameSpaceID_XUL) {
|
||||
nsXULPrototypeElement* prototype = new nsXULPrototypeElement();
|
||||
if (!prototype)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
prototype->mNodeInfo = aNodeInfo;
|
||||
|
||||
// Reset the refcnt to 0. Normally XUL prototype elements get a refcnt of 1
|
||||
// to represent ownership by the XUL prototype document. In our case we have
|
||||
// no prototype document, and our initial ref count of 1 will come from being
|
||||
// wrapped by a real XUL element in the Create call below.
|
||||
prototype->mRefCnt = 0;
|
||||
|
||||
AddAttributesToXULPrototype(aAtts, aAttsCount, prototype);
|
||||
|
||||
// Following this function call, the prototype's ref count will be 1.
|
||||
nsresult rv = nsXULElement::Create(prototype, mDocument, PR_FALSE, aResult);
|
||||
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
return NS_OK;
|
||||
if (!aNodeInfo->NamespaceEquals(kNameSpaceID_XUL)) {
|
||||
return nsXMLContentSink::CreateElement(aAtts, aAttsCount, aNodeInfo,
|
||||
aLineNumber, aResult,
|
||||
aAppendContent);
|
||||
}
|
||||
else
|
||||
return nsXMLContentSink::CreateElement(aAtts, aAttsCount, aNameSpaceID, aNodeInfo, aResult);
|
||||
|
||||
*aAppendContent = PR_TRUE;
|
||||
nsXULPrototypeElement* prototype = new nsXULPrototypeElement();
|
||||
if (!prototype)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
prototype->mNodeInfo = aNodeInfo;
|
||||
|
||||
// Reset the refcnt to 0. Normally XUL prototype elements get a refcnt of 1
|
||||
// to represent ownership by the XUL prototype document. In our case we have
|
||||
// no prototype document, and our initial ref count of 1 will come from being
|
||||
// wrapped by a real XUL element in the Create call below.
|
||||
prototype->mRefCnt = 0;
|
||||
|
||||
AddAttributesToXULPrototype(aAtts, aAttsCount, prototype);
|
||||
|
||||
// Following this function call, the prototype's ref count will be 1.
|
||||
return nsXULElement::Create(prototype, mDocument, PR_FALSE, aResult);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsXBLContentSink::AddAttributes(const PRUnichar** aAtts,
|
||||
nsIContent* aContent,
|
||||
PRBool aIsHTML)
|
||||
nsIContent* aContent)
|
||||
{
|
||||
if (aContent->IsContentOfType(nsIContent::eXUL))
|
||||
return NS_OK; // Nothing to do, since the proto already has the attrs.
|
||||
else
|
||||
return nsXMLContentSink::AddAttributes(aAtts, aContent, aIsHTML);
|
||||
|
||||
return nsXMLContentSink::AddAttributes(aAtts, aContent);
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
|
|
@ -106,15 +106,12 @@ protected:
|
|||
PRInt32 aNameSpaceID,
|
||||
nsIAtom* aTagName);
|
||||
|
||||
nsresult CreateElement(const PRUnichar** aAtts,
|
||||
PRUint32 aAttsCount,
|
||||
PRInt32 aNameSpaceID,
|
||||
nsINodeInfo* aNodeInfo,
|
||||
nsIContent** aResult);
|
||||
nsresult CreateElement(const PRUnichar** aAtts, PRUint32 aAttsCount,
|
||||
nsINodeInfo* aNodeInfo, PRUint32 aLineNumber,
|
||||
nsIContent** aResult, PRBool* aAppendContent);
|
||||
|
||||
nsresult AddAttributes(const PRUnichar** aAtts,
|
||||
nsIContent* aContent,
|
||||
PRBool aIsHTML);
|
||||
nsIContent* aContent);
|
||||
|
||||
nsresult AddAttributesToXULPrototype(const PRUnichar **aAtts,
|
||||
PRUint32 aAttsCount,
|
||||
|
|
|
@ -176,6 +176,7 @@ nsXMLContentSink::nsXMLContentSink()
|
|||
mPrettyPrintXML = PR_TRUE;
|
||||
mPrettyPrintHasSpecialRoot = PR_FALSE;
|
||||
mPrettyPrintHasFactoredElements = PR_FALSE;
|
||||
mHasProcessedBase = PR_FALSE;
|
||||
}
|
||||
|
||||
nsXMLContentSink::~nsXMLContentSink()
|
||||
|
@ -577,37 +578,133 @@ nsXMLContentSink::SplitXMLName(const nsAString& aString, nsIAtom **aPrefix,
|
|||
}
|
||||
|
||||
nsresult
|
||||
nsXMLContentSink::CreateElement(const PRUnichar** aAtts, PRUint32 aAttsCount, PRInt32 aNameSpaceID,
|
||||
nsINodeInfo* aNodeInfo, nsIContent** aResult)
|
||||
nsXMLContentSink::CreateElement(const PRUnichar** aAtts, PRUint32 aAttsCount,
|
||||
nsINodeInfo* aNodeInfo, PRUint32 aLineNumber,
|
||||
nsIContent** aResult, PRBool* aAppendContent)
|
||||
{
|
||||
NS_ASSERTION(aNodeInfo, "can't create element without nodeinfo");
|
||||
|
||||
*aAppendContent = PR_TRUE;
|
||||
nsresult rv = NS_OK;
|
||||
// The first step here is to see if someone has provided their
|
||||
// own content element implementation (e.g., XUL or MathML).
|
||||
// This is done based off a contractid/namespace scheme.
|
||||
nsCOMPtr<nsIElementFactory> elementFactory;
|
||||
nsContentUtils::GetNSManagerWeakRef()->GetElementFactory(aNameSpaceID,
|
||||
getter_AddRefs(elementFactory));
|
||||
if (elementFactory) {
|
||||
// Create the content element using the element factory.
|
||||
|
||||
PRInt32 nameSpaceID;
|
||||
aNodeInfo->GetNamespaceID(nameSpaceID);
|
||||
|
||||
// XHTML needs some special attention
|
||||
if (nameSpaceID != kNameSpaceID_XHTML) {
|
||||
// The first step here is to see if someone has provided their
|
||||
// own content element implementation (e.g., XUL or MathML).
|
||||
// This is done based off a contractid/namespace scheme.
|
||||
nsCOMPtr<nsIElementFactory> elementFactory;
|
||||
rv = nsContentUtils::GetNSManagerWeakRef()->
|
||||
GetElementFactory(nameSpaceID, getter_AddRefs(elementFactory));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
elementFactory->CreateInstanceByTag(aNodeInfo, aResult);
|
||||
}
|
||||
else {
|
||||
NS_NewXMLElement(aResult, aNodeInfo);
|
||||
|
||||
// If we care, find out if we just used a special factory.
|
||||
if (!mPrettyPrintHasFactoredElements && !mPrettyPrintHasSpecialRoot &&
|
||||
mPrettyPrintXML) {
|
||||
PRBool hasFactory = PR_FALSE;
|
||||
rv = nsContentUtils::GetNSManagerWeakRef()->HasRegisteredFactory(nameSpaceID, &hasFactory);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
mPrettyPrintHasFactoredElements = hasFactory;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// If we care, find out if we just used a special factory.
|
||||
if (!mPrettyPrintHasFactoredElements && !mPrettyPrintHasSpecialRoot &&
|
||||
mPrettyPrintXML) {
|
||||
PRBool hasFactory = PR_FALSE;
|
||||
rv = nsContentUtils::GetNSManagerWeakRef()->HasRegisteredFactory(aNameSpaceID,
|
||||
&hasFactory);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
mPrettyPrintHasFactoredElements = hasFactory;
|
||||
mPrettyPrintHasFactoredElements = PR_TRUE;
|
||||
nsCOMPtr<nsIHTMLContent> htmlContent;
|
||||
rv = NS_CreateHTMLElement(getter_AddRefs(htmlContent), aNodeInfo, PR_TRUE);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = CallQueryInterface(htmlContent, aResult);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsIAtom> tagAtom;
|
||||
aNodeInfo->GetNameAtom(*getter_AddRefs(tagAtom));
|
||||
|
||||
if (tagAtom == nsHTMLAtoms::script) {
|
||||
// Don't append the content to the tree until we're all
|
||||
// done collecting its contents
|
||||
mConstrainSize = PR_FALSE;
|
||||
mScriptLineNo = aLineNumber;
|
||||
*aAppendContent = PR_FALSE;
|
||||
}
|
||||
else if (tagAtom == nsHTMLAtoms::title) {
|
||||
if (mTitleText.IsEmpty()) {
|
||||
mInTitle = PR_TRUE; // The first title wins
|
||||
}
|
||||
}
|
||||
else if (tagAtom == nsHTMLAtoms::link || tagAtom == nsHTMLAtoms::style) {
|
||||
nsCOMPtr<nsIStyleSheetLinkingElement> ssle(do_QueryInterface(htmlContent));
|
||||
|
||||
if (ssle) {
|
||||
ssle->InitStyleLinkElement(mParser, PR_FALSE);
|
||||
ssle->SetEnableUpdates(PR_FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
nsresult
|
||||
nsXMLContentSink::CloseElement(nsIContent* aContent, PRBool* aAppendContent)
|
||||
{
|
||||
NS_ASSERTION(aContent, "missing element to close");
|
||||
|
||||
*aAppendContent = PR_FALSE;
|
||||
if (!aContent->IsContentOfType(nsIContent::eHTML)) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIAtom> tagAtom;
|
||||
aContent->GetTag(*getter_AddRefs(tagAtom));
|
||||
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
if (tagAtom == nsHTMLAtoms::script) {
|
||||
rv = ProcessEndSCRIPTTag(aContent);
|
||||
*aAppendContent = PR_TRUE;
|
||||
}
|
||||
else if (tagAtom == nsHTMLAtoms::title && mInTitle) {
|
||||
// The first title wins
|
||||
nsCOMPtr<nsIDOMNSDocument> dom_doc(do_QueryInterface(mDocument));
|
||||
if (dom_doc) {
|
||||
mTitleText.CompressWhitespace();
|
||||
dom_doc->SetTitle(mTitleText);
|
||||
}
|
||||
mInTitle = PR_FALSE;
|
||||
}
|
||||
else if (tagAtom == nsHTMLAtoms::base && !mHasProcessedBase) {
|
||||
// The first base wins
|
||||
rv = ProcessBASETag(aContent);
|
||||
mHasProcessedBase = PR_TRUE;
|
||||
}
|
||||
else if (tagAtom == nsHTMLAtoms::meta) {
|
||||
rv = ProcessMETATag(aContent);
|
||||
}
|
||||
else if (tagAtom == nsHTMLAtoms::link || tagAtom == nsHTMLAtoms::style) {
|
||||
nsCOMPtr<nsIStyleSheetLinkingElement> ssle(do_QueryInterface(aContent));
|
||||
|
||||
if (ssle) {
|
||||
ssle->SetEnableUpdates(PR_TRUE);
|
||||
rv = ssle->UpdateStyleSheet(nsnull, mStyleSheetCount);
|
||||
if (NS_SUCCEEDED(rv) || (rv == NS_ERROR_HTMLPARSER_BLOCK)) {
|
||||
if (rv == NS_ERROR_HTMLPARSER_BLOCK && mParser) {
|
||||
mParser->BlockParser();
|
||||
}
|
||||
++mStyleSheetCount;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsXMLContentSink::AddContentAsLeaf(nsIContent *aContent)
|
||||
{
|
||||
|
@ -761,18 +858,22 @@ nsXMLContentSink::StyleSheetLoaded(nsICSSStyleSheet* aSheet,
|
|||
}
|
||||
|
||||
nsresult
|
||||
nsXMLContentSink::ProcessBASETag()
|
||||
nsXMLContentSink::ProcessBASETag(nsIContent* aContent)
|
||||
{
|
||||
NS_ASSERTION(aContent, "missing base-element");
|
||||
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
if (mDocument) {
|
||||
nsAutoString value;
|
||||
|
||||
if (NS_CONTENT_ATTR_HAS_VALUE == mBaseElement->GetAttr(kNameSpaceID_None, nsHTMLAtoms::target, value)) {
|
||||
if (aContent->GetAttr(kNameSpaceID_None, nsHTMLAtoms::target, value) ==
|
||||
NS_CONTENT_ATTR_HAS_VALUE) {
|
||||
mDocument->SetBaseTarget(value);
|
||||
}
|
||||
|
||||
if (NS_CONTENT_ATTR_HAS_VALUE == mBaseElement->GetAttr(kNameSpaceID_None, nsHTMLAtoms::href, value)) {
|
||||
if (aContent->GetAttr(kNameSpaceID_None, nsHTMLAtoms::href, value) ==
|
||||
NS_CONTENT_ATTR_HAS_VALUE) {
|
||||
nsCOMPtr<nsIURI> baseURI;
|
||||
rv = NS_NewURI(getter_AddRefs(baseURI), value);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
|
@ -809,7 +910,7 @@ static const PRUnichar kLessThanCh = PRUnichar('<');
|
|||
static const PRUnichar kGreaterThanCh = PRUnichar('>');
|
||||
|
||||
nsresult
|
||||
nsXMLContentSink::ProcessLink(nsIHTMLContent* aElement,
|
||||
nsXMLContentSink::ProcessLink(nsIContent* aElement,
|
||||
const nsAString& aLinkData)
|
||||
{
|
||||
nsresult result = NS_OK;
|
||||
|
@ -964,7 +1065,7 @@ nsXMLContentSink::ProcessLink(nsIHTMLContent* aElement,
|
|||
|
||||
// XXX Copied from HTML, should be shared
|
||||
nsresult
|
||||
nsXMLContentSink::ProcessHeaderData(nsIAtom* aHeader,const nsAString& aValue,nsIHTMLContent* aContent)
|
||||
nsXMLContentSink::ProcessHeaderData(nsIAtom* aHeader,const nsAString& aValue,nsIContent* aContent)
|
||||
{
|
||||
nsresult rv=NS_OK;
|
||||
// XXX necko isn't going to process headers coming in from the parser
|
||||
|
@ -1112,20 +1213,22 @@ nsXMLContentSink::ProcessHTTPHeaders(nsIChannel* aChannel) {
|
|||
}
|
||||
|
||||
nsresult
|
||||
nsXMLContentSink::ProcessMETATag()
|
||||
nsXMLContentSink::ProcessMETATag(nsIContent* aContent)
|
||||
{
|
||||
NS_ASSERTION(aContent, "missing base-element");
|
||||
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
// set any HTTP-EQUIV data into document's header data as well as url
|
||||
nsAutoString header;
|
||||
mMetaElement->GetAttr(kNameSpaceID_None, nsHTMLAtoms::httpEquiv, header);
|
||||
aContent->GetAttr(kNameSpaceID_None, nsHTMLAtoms::httpEquiv, header);
|
||||
if (!header.IsEmpty()) {
|
||||
nsAutoString result;
|
||||
mMetaElement->GetAttr(kNameSpaceID_None, nsHTMLAtoms::content, result);
|
||||
aContent->GetAttr(kNameSpaceID_None, nsHTMLAtoms::content, result);
|
||||
if (!result.IsEmpty()) {
|
||||
ToLowerCase(header);
|
||||
nsCOMPtr<nsIAtom> fieldAtom(dont_AddRef(NS_NewAtom(header)));
|
||||
rv=ProcessHeaderData(fieldAtom,result,mMetaElement);
|
||||
rv = ProcessHeaderData(fieldAtom, result, aContent);
|
||||
}//if (!result.IsEmpty())
|
||||
}//if (!header.IsEmpty())
|
||||
|
||||
|
@ -1633,97 +1736,58 @@ nsXMLContentSink::HandleStartElement(const PRUnichar *aName,
|
|||
mNodeInfoManager->GetNodeInfo(tagAtom, nameSpacePrefix, nameSpaceID,
|
||||
*getter_AddRefs(nodeInfo));
|
||||
|
||||
const PRBool isXHTML = nameSpaceID == kNameSpaceID_XHTML;
|
||||
result = CreateElement(aAtts, aAttsCount, nodeInfo, aLineNumber,
|
||||
getter_AddRefs(content), &appendContent);
|
||||
NS_ENSURE_SUCCESS(result, result);
|
||||
|
||||
if (isXHTML) {
|
||||
mPrettyPrintHasFactoredElements = PR_TRUE;
|
||||
if (tagAtom.get() == nsHTMLAtoms::script) {
|
||||
result = ProcessStartSCRIPTTag(aLineNumber);
|
||||
// Don't append the content to the tree until we're all
|
||||
// done collecting its contents
|
||||
appendContent = PR_FALSE;
|
||||
} else if (tagAtom.get() == nsHTMLAtoms::title) {
|
||||
if (mTitleText.IsEmpty())
|
||||
mInTitle = PR_TRUE; // The first title wins
|
||||
}
|
||||
PRInt32 id;
|
||||
mDocument->GetAndIncrementContentID(&id);
|
||||
content->SetContentID(id);
|
||||
|
||||
nsCOMPtr<nsIHTMLContent> htmlContent;
|
||||
result = NS_CreateHTMLElement(getter_AddRefs(htmlContent), nodeInfo, PR_TRUE);
|
||||
content = do_QueryInterface(htmlContent);
|
||||
content->SetDocument(mDocument, PR_FALSE, PR_TRUE);
|
||||
|
||||
if (tagAtom == nsHTMLAtoms::base) {
|
||||
if (!mBaseElement) {
|
||||
mBaseElement = htmlContent; // The first base wins
|
||||
}
|
||||
} else if (tagAtom.get() == nsHTMLAtoms::meta) {
|
||||
if (!mMetaElement) {
|
||||
mMetaElement = htmlContent;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
CreateElement(aAtts, aAttsCount, nameSpaceID, nodeInfo, getter_AddRefs(content));
|
||||
// Set the attributes on the new content element
|
||||
result = AddAttributes(aAtts, content);
|
||||
|
||||
if (NS_OK == result) {
|
||||
PRInt32 id;
|
||||
mDocument->GetAndIncrementContentID(&id);
|
||||
content->SetContentID(id);
|
||||
// If this is the document element
|
||||
if (!mDocElement) {
|
||||
|
||||
if (isXHTML &&
|
||||
((tagAtom == nsHTMLAtoms::link) ||
|
||||
(tagAtom == nsHTMLAtoms::style))) {
|
||||
nsCOMPtr<nsIStyleSheetLinkingElement> ssle(do_QueryInterface(content));
|
||||
// check for root elements that needs special handling for
|
||||
// prettyprinting
|
||||
if ((nameSpaceID == kNameSpaceID_XBL &&
|
||||
tagAtom == nsXBLAtoms::bindings) ||
|
||||
(nameSpaceID == kNameSpaceID_XSLT &&
|
||||
(tagAtom == nsLayoutAtoms::stylesheet ||
|
||||
tagAtom == nsLayoutAtoms::transform))) {
|
||||
mPrettyPrintHasSpecialRoot = PR_TRUE;
|
||||
}
|
||||
|
||||
if (ssle) {
|
||||
ssle->InitStyleLinkElement(mParser, PR_FALSE);
|
||||
ssle->SetEnableUpdates(PR_FALSE);
|
||||
mDocElement = content;
|
||||
NS_ADDREF(mDocElement);
|
||||
|
||||
// For XSLT, we need to wait till after the transform
|
||||
// to set the root content object.
|
||||
if (!mXSLTransformMediator) {
|
||||
mDocument->SetRootContent(mDocElement);
|
||||
}
|
||||
}
|
||||
else if (appendContent) {
|
||||
nsCOMPtr<nsIContent> parent = dont_AddRef(GetCurrentContent());
|
||||
NS_ENSURE_TRUE(parent, NS_ERROR_UNEXPECTED);
|
||||
|
||||
content->SetDocument(mDocument, PR_FALSE, PR_TRUE);
|
||||
|
||||
// Set the attributes on the new content element
|
||||
result = AddAttributes(aAtts, content, isXHTML);
|
||||
|
||||
if (NS_OK == result) {
|
||||
// If this is the document element
|
||||
if (!mDocElement) {
|
||||
|
||||
// check for root elements that needs special handling for
|
||||
// prettyprinting
|
||||
if ((nameSpaceID == kNameSpaceID_XBL &&
|
||||
tagAtom == nsXBLAtoms::bindings) ||
|
||||
(nameSpaceID == kNameSpaceID_XSLT &&
|
||||
(tagAtom == nsLayoutAtoms::stylesheet ||
|
||||
tagAtom == nsLayoutAtoms::transform))) {
|
||||
mPrettyPrintHasSpecialRoot = PR_TRUE;
|
||||
}
|
||||
|
||||
mDocElement = content;
|
||||
NS_ADDREF(mDocElement);
|
||||
|
||||
// For XSL, we need to wait till after the transform
|
||||
// to set the root content object.
|
||||
if (!mXSLTransformMediator)
|
||||
mDocument->SetRootContent(mDocElement);
|
||||
}
|
||||
else if (appendContent) {
|
||||
nsCOMPtr<nsIContent> parent = getter_AddRefs(GetCurrentContent());
|
||||
|
||||
parent->AppendChildTo(content, PR_FALSE, PR_FALSE);
|
||||
}
|
||||
|
||||
PushContent(content);
|
||||
parent->AppendChildTo(content, PR_FALSE, PR_FALSE);
|
||||
}
|
||||
|
||||
// Set the ID attribute atom on the node info object for this node
|
||||
if ((aIndex != (PRUint32)-1) && NS_SUCCEEDED(result)) {
|
||||
nsCOMPtr<nsIAtom> IDAttr =
|
||||
dont_AddRef(NS_NewAtom((const PRUnichar *)aAtts[aIndex]));
|
||||
PushContent(content);
|
||||
}
|
||||
|
||||
if (IDAttr) {
|
||||
result = nodeInfo->SetIDAttributeAtom(IDAttr);
|
||||
}
|
||||
// Set the ID attribute atom on the node info object for this node
|
||||
if ((aIndex != (PRUint32)-1) && NS_SUCCEEDED(result)) {
|
||||
nsCOMPtr<nsIAtom> IDAttr = do_GetAtom(aAtts[aIndex]);
|
||||
|
||||
if (IDAttr) {
|
||||
result = nodeInfo->SetIDAttributeAtom(IDAttr);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1734,7 +1798,6 @@ NS_IMETHODIMP
|
|||
nsXMLContentSink::HandleEndElement(const PRUnichar *aName)
|
||||
{
|
||||
nsresult result = NS_OK;
|
||||
PRBool popContent = PR_TRUE;
|
||||
PRBool appendContent = PR_FALSE;
|
||||
|
||||
// XXX Hopefully the parser will flag this before we get
|
||||
|
@ -1744,76 +1807,25 @@ nsXMLContentSink::HandleEndElement(const PRUnichar *aName)
|
|||
|
||||
FlushText();
|
||||
|
||||
nsCOMPtr<nsIContent> currentContent(dont_AddRef(GetCurrentContent()));
|
||||
nsCOMPtr<nsIAtom> tagAtom;
|
||||
nsCOMPtr<nsIContent> content = dont_AddRef(PopContent());
|
||||
NS_ASSERTION(content, "failed to pop content");
|
||||
|
||||
if (currentContent && currentContent->IsContentOfType(nsIContent::eHTML)) {
|
||||
currentContent->GetTag(*getter_AddRefs(tagAtom));
|
||||
result = CloseElement(content, &appendContent);
|
||||
NS_ENSURE_SUCCESS(result, result);
|
||||
|
||||
if (tagAtom.get() == nsHTMLAtoms::script) {
|
||||
result = ProcessEndSCRIPTTag();
|
||||
appendContent = PR_TRUE;
|
||||
} else if (tagAtom.get() == nsHTMLAtoms::title) {
|
||||
if (mInTitle) { // The first title wins
|
||||
nsCOMPtr<nsIDOMNSDocument> dom_doc(do_QueryInterface(mDocument));
|
||||
if (dom_doc) {
|
||||
mTitleText.CompressWhitespace();
|
||||
dom_doc->SetTitle(mTitleText);
|
||||
}
|
||||
mInTitle = PR_FALSE;
|
||||
}
|
||||
} else if (tagAtom == nsHTMLAtoms::base) {
|
||||
if (mBaseElement) {
|
||||
result = ProcessBASETag();
|
||||
}
|
||||
} else if (tagAtom.get() == nsHTMLAtoms::meta) {
|
||||
if (mMetaElement) {
|
||||
result = ProcessMETATag();
|
||||
mMetaElement = nsnull; // HTML can have more than one meta so clear this now
|
||||
}
|
||||
}
|
||||
if (mDocElement == content) {
|
||||
mState = eXMLContentSinkState_InEpilog;
|
||||
}
|
||||
else if (appendContent) {
|
||||
nsCOMPtr<nsIContent> parent = getter_AddRefs(GetCurrentContent());
|
||||
NS_ENSURE_TRUE(parent, NS_ERROR_UNEXPECTED);
|
||||
|
||||
parent->AppendChildTo(content, PR_FALSE, PR_FALSE);
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIContent> content;
|
||||
if (popContent) {
|
||||
content = getter_AddRefs(PopContent());
|
||||
if (content) {
|
||||
if (mDocElement == content.get()) {
|
||||
mState = eXMLContentSinkState_InEpilog;
|
||||
}
|
||||
else if (appendContent) {
|
||||
nsCOMPtr<nsIContent> parent = getter_AddRefs(GetCurrentContent());
|
||||
|
||||
parent->AppendChildTo(content, PR_FALSE, PR_FALSE);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// XXX Again, the parser should catch unmatched tags and
|
||||
// we should never get here.
|
||||
PR_ASSERT(0);
|
||||
}
|
||||
}
|
||||
nsINameSpace* nameSpace = PopNameSpaces();
|
||||
NS_IF_RELEASE(nameSpace);
|
||||
|
||||
if (currentContent &&
|
||||
currentContent->IsContentOfType(nsIContent::eHTML) &&
|
||||
((tagAtom == nsHTMLAtoms::link) ||
|
||||
(tagAtom == nsHTMLAtoms::style))) {
|
||||
nsCOMPtr<nsIStyleSheetLinkingElement> ssle(do_QueryInterface(content));
|
||||
|
||||
if (ssle) {
|
||||
ssle->SetEnableUpdates(PR_TRUE);
|
||||
result = ssle->UpdateStyleSheet(nsnull, mStyleSheetCount);
|
||||
if (NS_SUCCEEDED(result) || (result == NS_ERROR_HTMLPARSER_BLOCK)) {
|
||||
if (result == NS_ERROR_HTMLPARSER_BLOCK && mParser) {
|
||||
mParser->BlockParser();
|
||||
}
|
||||
mStyleSheetCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (mNeedToBlockParser || (mParser && !mParser->IsParserEnabled())) {
|
||||
if (mParser) mParser->BlockParser();
|
||||
result = NS_ERROR_HTMLPARSER_BLOCK;
|
||||
|
@ -2167,8 +2179,7 @@ nsXMLContentSink::PushNameSpacesFrom(const PRUnichar** aAtts)
|
|||
|
||||
nsresult
|
||||
nsXMLContentSink::AddAttributes(const PRUnichar** aAtts,
|
||||
nsIContent* aContent,
|
||||
PRBool aIsHTML)
|
||||
nsIContent* aContent)
|
||||
{
|
||||
// Add tag attributes to the content attributes
|
||||
nsCOMPtr<nsIAtom> nameSpacePrefix, nameAtom;
|
||||
|
@ -2283,16 +2294,15 @@ nsXMLContentSink::AddText(const PRUnichar* aText,
|
|||
}
|
||||
|
||||
nsresult
|
||||
nsXMLContentSink::ProcessEndSCRIPTTag()
|
||||
nsXMLContentSink::ProcessEndSCRIPTTag(nsIContent* aContent)
|
||||
{
|
||||
nsresult result = NS_OK;
|
||||
|
||||
nsCOMPtr<nsIContent> element(dont_AddRef(GetCurrentContent()));
|
||||
nsCOMPtr<nsIDOMHTMLScriptElement> scriptElement(do_QueryInterface(element));
|
||||
nsCOMPtr<nsIDOMHTMLScriptElement> scriptElement(do_QueryInterface(aContent));
|
||||
NS_ASSERTION(scriptElement, "null script element in XML content sink");
|
||||
mScriptElements.AppendElement(scriptElement);
|
||||
|
||||
nsCOMPtr<nsIScriptElement> sele(do_QueryInterface(element));
|
||||
nsCOMPtr<nsIScriptElement> sele(do_QueryInterface(aContent));
|
||||
if (sele) {
|
||||
sele->SetLineNumber(mScriptLineNo);
|
||||
}
|
||||
|
@ -2305,13 +2315,3 @@ nsXMLContentSink::ProcessEndSCRIPTTag()
|
|||
|
||||
return result;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsXMLContentSink::ProcessStartSCRIPTTag(PRUint32 aLineNo)
|
||||
{
|
||||
// Wait until we get the script content
|
||||
mConstrainSize = PR_FALSE;
|
||||
mScriptLineNo = aLineNo;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -120,20 +120,19 @@ protected:
|
|||
void StartLayout();
|
||||
|
||||
nsresult PushNameSpacesFrom(const PRUnichar** aAttributes);
|
||||
nsresult AddAttributes(const PRUnichar** aNode, nsIContent* aContent,PRBool aIsHTML);
|
||||
nsresult AddAttributes(const PRUnichar** aNode, nsIContent* aContent);
|
||||
nsresult AddText(const PRUnichar* aString, PRInt32 aLength);
|
||||
nsresult ProcessStartSCRIPTTag(PRUint32 aLineNo);
|
||||
nsresult ProcessEndSCRIPTTag();
|
||||
nsresult ProcessEndSCRIPTTag(nsIContent* aContent);
|
||||
|
||||
virtual PRBool OnOpenContainer(const PRUnichar **aAtts,
|
||||
PRUint32 aAttsCount,
|
||||
PRInt32 aNameSpaceID,
|
||||
nsIAtom* aTagName) { return PR_TRUE; }
|
||||
virtual nsresult CreateElement(const PRUnichar** aAtts,
|
||||
PRUint32 aAttsCount,
|
||||
PRInt32 aNameSpaceID,
|
||||
nsINodeInfo* aNodeInfo,
|
||||
nsIContent** aResult);
|
||||
virtual nsresult CreateElement(const PRUnichar** aAtts, PRUint32 aAttsCount,
|
||||
nsINodeInfo* aNodeInfo, PRUint32 aLineNumber,
|
||||
nsIContent** aResult, PRBool* aAppendContent);
|
||||
|
||||
virtual nsresult CloseElement(nsIContent* aContent, PRBool* aAppendContent);
|
||||
|
||||
virtual nsresult FlushText(PRBool aCreateTextNode=PR_TRUE,
|
||||
PRBool* aDidFlush=nsnull);
|
||||
|
@ -150,13 +149,12 @@ protected:
|
|||
nsIContent* PopContent();
|
||||
|
||||
|
||||
nsresult ProcessBASETag();
|
||||
nsresult ProcessMETATag();
|
||||
nsresult ProcessLINKTag();
|
||||
nsresult ProcessBASETag(nsIContent* aContent);
|
||||
nsresult ProcessMETATag(nsIContent* aContent);
|
||||
nsresult ProcessHeaderData(nsIAtom* aHeader, const nsAString& aValue,
|
||||
nsIHTMLContent* aContent);
|
||||
nsIContent* aContent);
|
||||
nsresult ProcessHTTPHeaders(nsIChannel* aChannel);
|
||||
nsresult ProcessLink(nsIHTMLContent* aElement, const nsAString& aLinkData);
|
||||
nsresult ProcessLink(nsIContent* aElement, const nsAString& aLinkData);
|
||||
|
||||
nsresult RefreshIfEnabled(nsIViewManager* vm);
|
||||
|
||||
|
@ -204,13 +202,11 @@ protected:
|
|||
PRPackedBool mPrettyPrintXML;
|
||||
PRPackedBool mPrettyPrintHasSpecialRoot;
|
||||
PRPackedBool mPrettyPrintHasFactoredElements;
|
||||
PRPackedBool mHasProcessedBase;
|
||||
|
||||
nsCOMPtr<nsISupportsArray> mContentStack;
|
||||
nsCOMPtr<nsINodeInfoManager> mNodeInfoManager;
|
||||
nsCOMPtr<nsITransformMediator> mXSLTransformMediator;
|
||||
nsCOMPtr<nsIHTMLContent> mBaseElement;
|
||||
nsCOMPtr<nsIHTMLContent> mMetaElement;
|
||||
nsCOMPtr<nsIHTMLContent> mLinkElement;
|
||||
};
|
||||
|
||||
#endif // nsXMLContentSink_h__
|
||||
|
|
|
@ -175,3 +175,19 @@ nsXSLContentSink::ReportError(const PRUnichar* aErrorText,
|
|||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsXSLContentSink::CreateElement(const PRUnichar** aAtts, PRUint32 aAttsCount,
|
||||
nsINodeInfo* aNodeInfo, PRUint32 aLineNumber,
|
||||
nsIContent** aResult, PRBool* aAppendContent)
|
||||
{
|
||||
*aAppendContent = PR_TRUE;
|
||||
return NS_NewXMLElement(aResult, aNodeInfo);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsXSLContentSink::CloseElement(nsIContent* aContent, PRBool* aAppendContent)
|
||||
{
|
||||
*aAppendContent = PR_FALSE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -64,6 +64,13 @@ public:
|
|||
const PRUnichar *aSourceText);
|
||||
|
||||
protected:
|
||||
// override nsXMLContentSink hooks
|
||||
nsresult CreateElement(const PRUnichar** aAtts, PRUint32 aAttsCount,
|
||||
nsINodeInfo* aNodeInfo, PRUint32 aLineNumber,
|
||||
nsIContent** aResult, PRBool* aAppendContent);
|
||||
|
||||
nsresult CloseElement(nsIContent* aContent, PRBool* aAppendContent);
|
||||
|
||||
NS_IMETHOD ProcessStyleLink(nsIContent* aElement,
|
||||
const nsString& aHref,
|
||||
PRBool aAlternate,
|
||||
|
|
Загрузка…
Ссылка в новой задаче