зеркало из https://github.com/mozilla/gecko-dev.git
Make createContextualFragment work for XML. Bug 133827, patch by
steve.swanson@mackichan.com, r=bzbarsky, sr=jst
This commit is contained in:
Родитель
72576ab1aa
Коммит
e2c56f9785
|
@ -217,6 +217,14 @@
|
||||||
#define NS_HTMLFRAGMENTSINK2_CID \
|
#define NS_HTMLFRAGMENTSINK2_CID \
|
||||||
{ 0x13111d00, 0xce81, 0x11d6, { 0x80, 0x82, 0xec, 0xf3, 0x66, 0x5a, 0xf6, 0x7c } }
|
{ 0x13111d00, 0xce81, 0x11d6, { 0x80, 0x82, 0xec, 0xf3, 0x66, 0x5a, 0xf6, 0x7c } }
|
||||||
|
|
||||||
|
// {4B664E54-72A2-4bbf-A5C2-66D4DC3066A0}
|
||||||
|
#define NS_XMLFRAGMENTSINK_CID \
|
||||||
|
{ 0x4b664e54, 0x72a2, 0x4bbf, { 0xa5, 0xc2, 0x66, 0xd4, 0xdc, 0x30, 0x66, 0xa0 } }
|
||||||
|
|
||||||
|
// {4DC30689-929D-425e-A709-082C6294E542}
|
||||||
|
#define NS_XMLFRAGMENTSINK2_CID \
|
||||||
|
{ 0x4dc30689, 0x929d, 0x425e, { 0xa7, 0x9, 0x8, 0x2c, 0x62, 0x94, 0xe5, 0x42 } }
|
||||||
|
|
||||||
// {3986B301-097C-11d3-BF87-00105A1B0627}
|
// {3986B301-097C-11d3-BF87-00105A1B0627}
|
||||||
#define NS_XULPOPUPLISTENER_CID \
|
#define NS_XULPOPUPLISTENER_CID \
|
||||||
{ 0x3986b301, 0x97c, 0x11d3, { 0xbf, 0x87, 0x0, 0x10, 0x5a, 0x1b, 0x6, 0x27 } }
|
{ 0x3986b301, 0x97c, 0x11d3, { 0xbf, 0x87, 0x0, 0x10, 0x5a, 0x1b, 0x6, 0x27 } }
|
||||||
|
|
|
@ -58,7 +58,8 @@
|
||||||
#include "nsIParser.h"
|
#include "nsIParser.h"
|
||||||
#include "nsIComponentManager.h"
|
#include "nsIComponentManager.h"
|
||||||
#include "nsParserCIID.h"
|
#include "nsParserCIID.h"
|
||||||
#include "nsIHTMLFragmentContentSink.h"
|
#include "nsIFragmentContentSink.h"
|
||||||
|
#include "nsIContentSink.h"
|
||||||
#include "nsIEnumerator.h"
|
#include "nsIEnumerator.h"
|
||||||
#include "nsIScriptSecurityManager.h"
|
#include "nsIScriptSecurityManager.h"
|
||||||
#include "nsIScriptGlobalObject.h"
|
#include "nsIScriptGlobalObject.h"
|
||||||
|
@ -2366,8 +2367,40 @@ nsRange::CreateContextualFragment(const nsAString& aFragment,
|
||||||
|
|
||||||
parent->GetNodeType(&nodeType);
|
parent->GetNodeType(&nodeType);
|
||||||
if (nsIDOMNode::ELEMENT_NODE == nodeType) {
|
if (nsIDOMNode::ELEMENT_NODE == nodeType) {
|
||||||
nsAutoString tagName;
|
PRInt32 namespaceID;
|
||||||
|
nsAutoString tagName, uriStr;
|
||||||
parent->GetNodeName(tagName);
|
parent->GetNodeName(tagName);
|
||||||
|
|
||||||
|
// see if we need to add xmlns declarations
|
||||||
|
nsCOMPtr<nsIContent> content( do_QueryInterface(parent) );
|
||||||
|
PRUint32 count = content->GetAttrCount();
|
||||||
|
if (count > 0) {
|
||||||
|
PRUint32 index;
|
||||||
|
nsAutoString nameStr, prefixStr, valueStr;
|
||||||
|
nsCOMPtr<nsIAtom> attrName, attrPrefix;
|
||||||
|
|
||||||
|
for (index = 0; index < count; index++) {
|
||||||
|
|
||||||
|
content->GetAttrNameAt(index,
|
||||||
|
&namespaceID,
|
||||||
|
getter_AddRefs(attrName),
|
||||||
|
getter_AddRefs(attrPrefix));
|
||||||
|
|
||||||
|
if (namespaceID == kNameSpaceID_XMLNS) {
|
||||||
|
content->GetAttr(namespaceID, attrName, uriStr);
|
||||||
|
|
||||||
|
// really want something like nsXMLContentSerializer::SerializeAttr()
|
||||||
|
tagName.Append(NS_LITERAL_STRING(" xmlns")); // space important
|
||||||
|
if (attrPrefix) {
|
||||||
|
tagName.Append(PRUnichar(':'));
|
||||||
|
attrName->ToString(nameStr);
|
||||||
|
tagName.Append(nameStr);
|
||||||
|
}
|
||||||
|
tagName.Append(NS_LITERAL_STRING("=\"") + uriStr + NS_LITERAL_STRING("\""));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// XXX Wish we didn't have to allocate here
|
// XXX Wish we didn't have to allocate here
|
||||||
PRUnichar* name = ToNewUnicode(tagName);
|
PRUnichar* name = ToNewUnicode(tagName);
|
||||||
if (name) {
|
if (name) {
|
||||||
|
@ -2387,22 +2420,29 @@ nsRange::CreateContextualFragment(const nsAString& aFragment,
|
||||||
|
|
||||||
if (NS_SUCCEEDED(result)) {
|
if (NS_SUCCEEDED(result)) {
|
||||||
nsCAutoString contentType;
|
nsCAutoString contentType;
|
||||||
nsCOMPtr<nsIHTMLFragmentContentSink> sink;
|
PRBool bCaseSensitive = PR_TRUE;
|
||||||
|
if (document) {
|
||||||
|
nsAutoString buf;
|
||||||
|
document->GetContentType(buf);
|
||||||
|
CopyUCS2toASCII(buf, contentType);
|
||||||
|
bCaseSensitive = document->IsCaseSensitive();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
contentType.AssignLiteral("text/xml");
|
||||||
|
}
|
||||||
|
|
||||||
result = NS_NewHTMLFragmentContentSink(getter_AddRefs(sink));
|
nsCOMPtr<nsIHTMLDocument> htmlDoc(do_QueryInterface(domDocument));
|
||||||
|
PRBool bHTML = htmlDoc && !bCaseSensitive;
|
||||||
|
nsCOMPtr<nsIFragmentContentSink> sink;
|
||||||
|
if (bHTML) {
|
||||||
|
result = NS_NewHTMLFragmentContentSink(getter_AddRefs(sink));
|
||||||
|
} else {
|
||||||
|
result = NS_NewXMLFragmentContentSink(getter_AddRefs(sink));
|
||||||
|
}
|
||||||
if (NS_SUCCEEDED(result)) {
|
if (NS_SUCCEEDED(result)) {
|
||||||
sink->SetTargetDocument(document);
|
sink->SetTargetDocument(document);
|
||||||
parser->SetContentSink(sink);
|
nsCOMPtr<nsIContentSink> contentsink( do_QueryInterface(sink) );
|
||||||
nsCOMPtr<nsIDOMNSDocument> domnsDocument(do_QueryInterface(document));
|
parser->SetContentSink(contentsink);
|
||||||
if (domnsDocument) {
|
|
||||||
nsAutoString buf;
|
|
||||||
domnsDocument->GetContentType(buf);
|
|
||||||
CopyUCS2toASCII(buf, contentType);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// Who're we kidding. This only works for html.
|
|
||||||
contentType.AssignLiteral("text/html");
|
|
||||||
}
|
|
||||||
|
|
||||||
// If there's no JS or system JS running,
|
// If there's no JS or system JS running,
|
||||||
// push the current document's context on the JS context stack
|
// push the current document's context on the JS context stack
|
||||||
|
@ -2445,7 +2485,7 @@ nsRange::CreateContextualFragment(const nsAString& aFragment,
|
||||||
|
|
||||||
nsDTDMode mode = eDTDMode_autodetect;
|
nsDTDMode mode = eDTDMode_autodetect;
|
||||||
nsCOMPtr<nsIHTMLDocument> htmlDoc(do_QueryInterface(domDocument));
|
nsCOMPtr<nsIHTMLDocument> htmlDoc(do_QueryInterface(domDocument));
|
||||||
if (htmlDoc) {
|
if (bHTML) {
|
||||||
switch (htmlDoc->GetCompatibilityMode()) {
|
switch (htmlDoc->GetCompatibilityMode()) {
|
||||||
case eCompatibility_NavQuirks:
|
case eCompatibility_NavQuirks:
|
||||||
mode = eDTDMode_quirks;
|
mode = eDTDMode_quirks;
|
||||||
|
@ -2460,10 +2500,12 @@ nsRange::CreateContextualFragment(const nsAString& aFragment,
|
||||||
NS_NOTREACHED("unknown mode");
|
NS_NOTREACHED("unknown mode");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
mode = eDTDMode_full_standards;
|
||||||
}
|
}
|
||||||
result = parser->ParseFragment(aFragment, (void*)0,
|
result = parser->ParseFragment(aFragment, (void*)0,
|
||||||
tagStack,
|
tagStack,
|
||||||
0, contentType, mode);
|
!bHTML, contentType, mode);
|
||||||
|
|
||||||
if (ContextStack) {
|
if (ContextStack) {
|
||||||
JSContext *notused;
|
JSContext *notused;
|
||||||
|
|
|
@ -134,6 +134,7 @@ HTML_ATOM(em, "em")
|
||||||
HTML_ATOM(embed, "embed")
|
HTML_ATOM(embed, "embed")
|
||||||
HTML_ATOM(encoding, "encoding")
|
HTML_ATOM(encoding, "encoding")
|
||||||
HTML_ATOM(enctype, "enctype")
|
HTML_ATOM(enctype, "enctype")
|
||||||
|
HTML_ATOM(endnote, "endnote") // contextual fragments
|
||||||
HTML_ATOM(_event, "event")
|
HTML_ATOM(_event, "event")
|
||||||
HTML_ATOM(face, "face")
|
HTML_ATOM(face, "face")
|
||||||
HTML_ATOM(fieldset, "fieldset")
|
HTML_ATOM(fieldset, "fieldset")
|
||||||
|
|
|
@ -36,7 +36,8 @@
|
||||||
* ***** END LICENSE BLOCK ***** */
|
* ***** END LICENSE BLOCK ***** */
|
||||||
#include "nsCOMPtr.h"
|
#include "nsCOMPtr.h"
|
||||||
#include "nsIServiceManager.h"
|
#include "nsIServiceManager.h"
|
||||||
#include "nsIHTMLFragmentContentSink.h"
|
#include "nsIFragmentContentSink.h"
|
||||||
|
#include "nsIHTMLContentSink.h"
|
||||||
#include "nsIParser.h"
|
#include "nsIParser.h"
|
||||||
#include "nsIParserService.h"
|
#include "nsIParserService.h"
|
||||||
#include "nsIHTMLContent.h"
|
#include "nsIHTMLContent.h"
|
||||||
|
@ -68,9 +69,10 @@
|
||||||
// at some pointe really soon!
|
// at some pointe really soon!
|
||||||
//
|
//
|
||||||
|
|
||||||
class nsHTMLFragmentContentSink : public nsIHTMLFragmentContentSink {
|
class nsHTMLFragmentContentSink : public nsIFragmentContentSink,
|
||||||
|
public nsIHTMLContentSink {
|
||||||
public:
|
public:
|
||||||
nsHTMLFragmentContentSink();
|
nsHTMLFragmentContentSink(PRBool aAllContent = PR_FALSE);
|
||||||
virtual ~nsHTMLFragmentContentSink();
|
virtual ~nsHTMLFragmentContentSink();
|
||||||
|
|
||||||
// nsISupports
|
// nsISupports
|
||||||
|
@ -119,7 +121,7 @@ public:
|
||||||
NS_IMETHOD AddProcessingInstruction(const nsIParserNode& aNode);
|
NS_IMETHOD AddProcessingInstruction(const nsIParserNode& aNode);
|
||||||
NS_IMETHOD AddDocTypeDecl(const nsIParserNode& aNode);
|
NS_IMETHOD AddDocTypeDecl(const nsIParserNode& aNode);
|
||||||
|
|
||||||
// nsIHTMLFragmentContentSink
|
// nsIFragmentContentSink
|
||||||
NS_IMETHOD GetFragment(nsIDOMDocumentFragment** aFragment);
|
NS_IMETHOD GetFragment(nsIDOMDocumentFragment** aFragment);
|
||||||
NS_IMETHOD SetTargetDocument(nsIDocument* aDocument);
|
NS_IMETHOD SetTargetDocument(nsIDocument* aDocument);
|
||||||
|
|
||||||
|
@ -160,43 +162,45 @@ public:
|
||||||
nsRefPtr<nsNodeInfoManager> mNodeInfoManager;
|
nsRefPtr<nsNodeInfoManager> mNodeInfoManager;
|
||||||
};
|
};
|
||||||
|
|
||||||
class nsHTMLFragmentContentSink2 : public nsHTMLFragmentContentSink
|
static nsresult
|
||||||
{
|
NewHTMLFragmentContentSinkHelper(PRBool aAllContent, nsIFragmentContentSink** aResult)
|
||||||
public:
|
|
||||||
nsHTMLFragmentContentSink2() { mHitSentinel = PR_TRUE; mSeenBody = PR_FALSE;}
|
|
||||||
virtual ~nsHTMLFragmentContentSink2() {}
|
|
||||||
};
|
|
||||||
|
|
||||||
nsresult
|
|
||||||
NS_NewHTMLFragmentContentSink2(nsIHTMLFragmentContentSink** aResult)
|
|
||||||
{
|
{
|
||||||
NS_PRECONDITION(aResult, "Null out ptr");
|
NS_PRECONDITION(aResult, "Null out ptr");
|
||||||
|
if (nsnull == aResult) {
|
||||||
|
return NS_ERROR_NULL_POINTER;
|
||||||
|
}
|
||||||
|
|
||||||
*aResult = new nsHTMLFragmentContentSink2();
|
nsHTMLFragmentContentSink* it = new nsHTMLFragmentContentSink(aAllContent);
|
||||||
NS_ENSURE_TRUE(*aResult, NS_ERROR_OUT_OF_MEMORY);
|
if (nsnull == it) {
|
||||||
|
return NS_ERROR_OUT_OF_MEMORY;
|
||||||
NS_ADDREF(*aResult);
|
}
|
||||||
|
|
||||||
|
NS_ADDREF(*aResult = it);
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
NS_NewHTMLFragmentContentSink(nsIHTMLFragmentContentSink** aResult)
|
NS_NewHTMLFragmentContentSink2(nsIFragmentContentSink** aResult)
|
||||||
{
|
{
|
||||||
NS_PRECONDITION(aResult, "Null out ptr");
|
return NewHTMLFragmentContentSinkHelper(PR_TRUE,aResult);
|
||||||
|
|
||||||
*aResult = new nsHTMLFragmentContentSink();
|
|
||||||
NS_ENSURE_TRUE(*aResult, NS_ERROR_OUT_OF_MEMORY);
|
|
||||||
|
|
||||||
NS_ADDREF(*aResult);
|
|
||||||
|
|
||||||
return NS_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
nsHTMLFragmentContentSink::nsHTMLFragmentContentSink()
|
nsresult
|
||||||
|
NS_NewHTMLFragmentContentSink(nsIFragmentContentSink** aResult)
|
||||||
{
|
{
|
||||||
mHitSentinel = PR_FALSE;
|
return NewHTMLFragmentContentSinkHelper(PR_FALSE,aResult);
|
||||||
mSeenBody = PR_TRUE;
|
}
|
||||||
|
|
||||||
|
nsHTMLFragmentContentSink::nsHTMLFragmentContentSink(PRBool aAllContent)
|
||||||
|
{
|
||||||
|
if (aAllContent) {
|
||||||
|
mHitSentinel = PR_TRUE;
|
||||||
|
mSeenBody = PR_FALSE;
|
||||||
|
} else {
|
||||||
|
mHitSentinel = PR_FALSE;
|
||||||
|
mSeenBody = PR_TRUE;
|
||||||
|
}
|
||||||
mRoot = nsnull;
|
mRoot = nsnull;
|
||||||
mParser = nsnull;
|
mParser = nsnull;
|
||||||
mCurrentForm = nsnull;
|
mCurrentForm = nsnull;
|
||||||
|
@ -233,10 +237,10 @@ NS_IMPL_ADDREF(nsHTMLFragmentContentSink)
|
||||||
NS_IMPL_RELEASE(nsHTMLFragmentContentSink)
|
NS_IMPL_RELEASE(nsHTMLFragmentContentSink)
|
||||||
|
|
||||||
NS_INTERFACE_MAP_BEGIN(nsHTMLFragmentContentSink)
|
NS_INTERFACE_MAP_BEGIN(nsHTMLFragmentContentSink)
|
||||||
NS_INTERFACE_MAP_ENTRY(nsIHTMLFragmentContentSink)
|
NS_INTERFACE_MAP_ENTRY(nsIFragmentContentSink)
|
||||||
NS_INTERFACE_MAP_ENTRY(nsIHTMLContentSink)
|
NS_INTERFACE_MAP_ENTRY(nsIHTMLContentSink)
|
||||||
NS_INTERFACE_MAP_ENTRY(nsIContentSink)
|
NS_INTERFACE_MAP_ENTRY(nsIContentSink)
|
||||||
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIHTMLFragmentContentSink)
|
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIFragmentContentSink)
|
||||||
NS_INTERFACE_MAP_END
|
NS_INTERFACE_MAP_END
|
||||||
|
|
||||||
|
|
||||||
|
@ -441,8 +445,6 @@ nsHTMLFragmentContentSink::AddBaseTagInfo(nsIContent* aContent)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char kSentinelStr[] = "endnote";
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsHTMLFragmentContentSink::OpenContainer(const nsIParserNode& aNode)
|
nsHTMLFragmentContentSink::OpenContainer(const nsIParserNode& aNode)
|
||||||
{
|
{
|
||||||
|
@ -452,7 +454,8 @@ nsHTMLFragmentContentSink::OpenContainer(const nsIParserNode& aNode)
|
||||||
nsresult result = NS_OK;
|
nsresult result = NS_OK;
|
||||||
|
|
||||||
tag.Assign(aNode.GetText());
|
tag.Assign(aNode.GetText());
|
||||||
if (tag.EqualsIgnoreCase(kSentinelStr)) {
|
|
||||||
|
if (nsHTMLAtoms::endnote->Equals(tag)) {
|
||||||
mHitSentinel = PR_TRUE;
|
mHitSentinel = PR_TRUE;
|
||||||
}
|
}
|
||||||
else if (mHitSentinel) {
|
else if (mHitSentinel) {
|
||||||
|
|
|
@ -134,6 +134,7 @@ HTML_ATOM(em, "em")
|
||||||
HTML_ATOM(embed, "embed")
|
HTML_ATOM(embed, "embed")
|
||||||
HTML_ATOM(encoding, "encoding")
|
HTML_ATOM(encoding, "encoding")
|
||||||
HTML_ATOM(enctype, "enctype")
|
HTML_ATOM(enctype, "enctype")
|
||||||
|
HTML_ATOM(endnote, "endnote") // contextual fragments
|
||||||
HTML_ATOM(_event, "event")
|
HTML_ATOM(_event, "event")
|
||||||
HTML_ATOM(face, "face")
|
HTML_ATOM(face, "face")
|
||||||
HTML_ATOM(fieldset, "fieldset")
|
HTML_ATOM(fieldset, "fieldset")
|
||||||
|
|
|
@ -72,6 +72,7 @@ REQUIRES = xpcom \
|
||||||
|
|
||||||
CPPSRCS = \
|
CPPSRCS = \
|
||||||
nsXMLContentSink.cpp \
|
nsXMLContentSink.cpp \
|
||||||
|
nsXMLFragmentContentSink.cpp \
|
||||||
nsXMLDocument.cpp \
|
nsXMLDocument.cpp \
|
||||||
nsXMLPrettyPrinter.cpp \
|
nsXMLPrettyPrinter.cpp \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
|
|
|
@ -911,6 +911,43 @@ NS_NewMathMLElement(nsIContent** aResult, nsINodeInfo* aNodeInfo)
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
PRBool
|
||||||
|
nsXMLContentSink::SetDocElement(PRInt32 aNameSpaceID,
|
||||||
|
nsIAtom* aTagName,
|
||||||
|
nsIContent *aContent)
|
||||||
|
{
|
||||||
|
if (mDocElement)
|
||||||
|
return PR_FALSE;
|
||||||
|
|
||||||
|
// check for root elements that needs special handling for
|
||||||
|
// prettyprinting
|
||||||
|
if ((aNameSpaceID == kNameSpaceID_XBL &&
|
||||||
|
aTagName == nsXBLAtoms::bindings) ||
|
||||||
|
(aNameSpaceID == kNameSpaceID_XSLT &&
|
||||||
|
(aTagName == nsLayoutAtoms::stylesheet ||
|
||||||
|
aTagName == nsLayoutAtoms::transform))) {
|
||||||
|
mPrettyPrintHasSpecialRoot = PR_TRUE;
|
||||||
|
if (mPrettyPrintXML) {
|
||||||
|
// In this case, disable script execution, stylesheet
|
||||||
|
// loading, and auto XLinks since we plan to prettyprint.
|
||||||
|
mAllowAutoXLinks = PR_FALSE;
|
||||||
|
nsIScriptLoader* scriptLoader = mDocument->GetScriptLoader();
|
||||||
|
if (scriptLoader) {
|
||||||
|
scriptLoader->SetEnabled(PR_FALSE);
|
||||||
|
}
|
||||||
|
if (mCSSLoader) {
|
||||||
|
mCSSLoader->SetEnabled(PR_FALSE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mDocElement = aContent;
|
||||||
|
NS_ADDREF(mDocElement);
|
||||||
|
|
||||||
|
mDocument->SetRootContent(mDocElement);
|
||||||
|
return PR_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsXMLContentSink::HandleStartElement(const PRUnichar *aName,
|
nsXMLContentSink::HandleStartElement(const PRUnichar *aName,
|
||||||
const PRUnichar **aAtts,
|
const PRUnichar **aAtts,
|
||||||
|
@ -967,44 +1004,17 @@ nsXMLContentSink::HandleStartElement(const PRUnichar *aName,
|
||||||
getter_AddRefs(content), &appendContent);
|
getter_AddRefs(content), &appendContent);
|
||||||
NS_ENSURE_SUCCESS(result, result);
|
NS_ENSURE_SUCCESS(result, result);
|
||||||
|
|
||||||
content->SetContentID(mDocument->GetAndIncrementContentID());
|
if (mDocument) {
|
||||||
|
content->SetContentID(mDocument->GetAndIncrementContentID());
|
||||||
|
}
|
||||||
content->SetDocument(mDocument, PR_FALSE, PR_TRUE);
|
content->SetDocument(mDocument, PR_FALSE, PR_TRUE);
|
||||||
|
|
||||||
// Set the attributes on the new content element
|
// Set the attributes on the new content element
|
||||||
result = AddAttributes(aAtts, content);
|
result = AddAttributes(aAtts, content);
|
||||||
|
|
||||||
if (NS_OK == result) {
|
if (NS_OK == result) {
|
||||||
// If this is the document element
|
// Store the element
|
||||||
if (!mDocElement) {
|
if (!SetDocElement(nameSpaceID,tagAtom,content) && appendContent) {
|
||||||
|
|
||||||
// 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 (mPrettyPrintXML) {
|
|
||||||
// In this case, disable script execution, stylesheet
|
|
||||||
// loading, and auto XLinks since we plan to prettyprint.
|
|
||||||
mAllowAutoXLinks = PR_FALSE;
|
|
||||||
nsIScriptLoader* scriptLoader = mDocument->GetScriptLoader();
|
|
||||||
if (scriptLoader) {
|
|
||||||
scriptLoader->SetEnabled(PR_FALSE);
|
|
||||||
}
|
|
||||||
if (mCSSLoader) {
|
|
||||||
mCSSLoader->SetEnabled(PR_FALSE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
mDocElement = content;
|
|
||||||
NS_ADDREF(mDocElement);
|
|
||||||
|
|
||||||
mDocument->SetRootContent(mDocElement);
|
|
||||||
}
|
|
||||||
else if (appendContent) {
|
|
||||||
nsCOMPtr<nsIContent> parent = GetCurrentContent();
|
nsCOMPtr<nsIContent> parent = GetCurrentContent();
|
||||||
NS_ENSURE_TRUE(parent, NS_ERROR_UNEXPECTED);
|
NS_ENSURE_TRUE(parent, NS_ERROR_UNEXPECTED);
|
||||||
|
|
||||||
|
@ -1265,6 +1275,15 @@ nsXMLContentSink::HandleXMLDeclaration(const PRUnichar *aData,
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsXMLContentSink::ReportError(const PRUnichar* aErrorText,
|
nsXMLContentSink::ReportError(const PRUnichar* aErrorText,
|
||||||
const PRUnichar* aSourceText)
|
const PRUnichar* aSourceText)
|
||||||
|
{
|
||||||
|
nsCOMPtr<nsIDOMNode> node(do_QueryInterface(mDocument));
|
||||||
|
return ReportErrorFrom( aErrorText, aSourceText, node );
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsXMLContentSink::ReportErrorFrom(const PRUnichar* aErrorText,
|
||||||
|
const PRUnichar* aSourceText,
|
||||||
|
nsIDOMNode* aNode)
|
||||||
{
|
{
|
||||||
nsresult rv = NS_OK;
|
nsresult rv = NS_OK;
|
||||||
|
|
||||||
|
@ -1278,14 +1297,13 @@ nsXMLContentSink::ReportError(const PRUnichar* aErrorText,
|
||||||
|
|
||||||
// Clear the current content and
|
// Clear the current content and
|
||||||
// prepare to set <parsererror> as the document root
|
// prepare to set <parsererror> as the document root
|
||||||
nsCOMPtr<nsIDOMNode> node(do_QueryInterface(mDocument));
|
if (aNode) {
|
||||||
if (node) {
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
nsCOMPtr<nsIDOMNode> child, dummy;
|
nsCOMPtr<nsIDOMNode> child, dummy;
|
||||||
node->GetLastChild(getter_AddRefs(child));
|
aNode->GetLastChild(getter_AddRefs(child));
|
||||||
if (!child)
|
if (!child)
|
||||||
break;
|
break;
|
||||||
node->RemoveChild(child, getter_AddRefs(dummy));
|
aNode->RemoveChild(child, getter_AddRefs(dummy));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
NS_IF_RELEASE(mDocElement);
|
NS_IF_RELEASE(mDocElement);
|
||||||
|
|
|
@ -107,6 +107,12 @@ protected:
|
||||||
PRInt32 aNameSpaceID,
|
PRInt32 aNameSpaceID,
|
||||||
nsIAtom* aTagName,
|
nsIAtom* aTagName,
|
||||||
PRUint32 aLineNumber) { return PR_TRUE; }
|
PRUint32 aLineNumber) { return PR_TRUE; }
|
||||||
|
// Set the given content as the root element for the created document
|
||||||
|
// don't set if root element was already set.
|
||||||
|
// return TRUE if this call set the root element
|
||||||
|
virtual PRBool SetDocElement(PRInt32 aNameSpaceID,
|
||||||
|
nsIAtom *aTagName,
|
||||||
|
nsIContent *aContent);
|
||||||
virtual nsresult CreateElement(const PRUnichar** aAtts, PRUint32 aAttsCount,
|
virtual nsresult CreateElement(const PRUnichar** aAtts, PRUint32 aAttsCount,
|
||||||
nsINodeInfo* aNodeInfo, PRUint32 aLineNumber,
|
nsINodeInfo* aNodeInfo, PRUint32 aLineNumber,
|
||||||
nsIContent** aResult, PRBool* aAppendContent);
|
nsIContent** aResult, PRBool* aAppendContent);
|
||||||
|
@ -125,6 +131,11 @@ protected:
|
||||||
PRInt32 PushContent(nsIContent *aContent);
|
PRInt32 PushContent(nsIContent *aContent);
|
||||||
already_AddRefed<nsIContent> PopContent();
|
already_AddRefed<nsIContent> PopContent();
|
||||||
|
|
||||||
|
// node is the base content which will be cleared out and an error fragment will be inserted
|
||||||
|
// return value indicates whether fragment was successfully created
|
||||||
|
NS_IMETHOD ReportErrorFrom(const PRUnichar* aErrorText,
|
||||||
|
const PRUnichar* aSourceText,
|
||||||
|
nsIDOMNode* aNode);
|
||||||
|
|
||||||
nsresult ProcessBASETag(nsIContent* aContent);
|
nsresult ProcessBASETag(nsIContent* aContent);
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,344 @@
|
||||||
|
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||||
|
/* ***** BEGIN LICENSE BLOCK *****
|
||||||
|
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||||
|
*
|
||||||
|
* The contents of this file are subject to the Mozilla Public License Version
|
||||||
|
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at
|
||||||
|
* http://www.mozilla.org/MPL/
|
||||||
|
*
|
||||||
|
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||||
|
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||||
|
* for the specific language governing rights and limitations under the
|
||||||
|
* License.
|
||||||
|
*
|
||||||
|
* The Original Code is mozilla.org code.
|
||||||
|
*
|
||||||
|
* The Initial Developer of the Original Code is
|
||||||
|
* Steve Swanson steve.swanson@mackichan.com.
|
||||||
|
* Portions created by the Initial Developer are Copyright (C) 2004
|
||||||
|
* the Initial Developer. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Contributor(s):
|
||||||
|
*
|
||||||
|
* Alternatively, the contents of this file may be used under the terms of
|
||||||
|
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||||
|
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||||
|
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||||
|
* of those above. If you wish to allow use of your version of this file only
|
||||||
|
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||||
|
* use your version of this file under the terms of the MPL, indicate your
|
||||||
|
* decision by deleting the provisions above and replace them with the notice
|
||||||
|
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||||
|
* the provisions above, a recipient may use your version of this file under
|
||||||
|
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||||
|
*
|
||||||
|
* ***** END LICENSE BLOCK ***** */
|
||||||
|
#include "nsCOMPtr.h"
|
||||||
|
#include "nsXMLContentSink.h"
|
||||||
|
#include "nsIFragmentContentSink.h"
|
||||||
|
#include "nsIXMLContentSink.h"
|
||||||
|
#include "nsContentSink.h"
|
||||||
|
#include "nsIExpatSink.h"
|
||||||
|
#include "nsIParser.h"
|
||||||
|
#include "nsIDocument.h"
|
||||||
|
#include "nsIDOMDocumentFragment.h"
|
||||||
|
#include "nsIXMLContent.h"
|
||||||
|
#include "nsHTMLAtoms.h"
|
||||||
|
#include "nsINodeInfo.h"
|
||||||
|
#include "nsNodeInfoManager.h"
|
||||||
|
#include "nsContentCreatorFunctions.h"
|
||||||
|
|
||||||
|
|
||||||
|
class nsXMLFragmentContentSink : public nsXMLContentSink,
|
||||||
|
public nsIFragmentContentSink
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
nsXMLFragmentContentSink(PRBool aAllContent = PR_FALSE);
|
||||||
|
virtual ~nsXMLFragmentContentSink();
|
||||||
|
|
||||||
|
// nsISupports
|
||||||
|
NS_DECL_ISUPPORTS_INHERITED
|
||||||
|
|
||||||
|
// nsIExpatSink
|
||||||
|
NS_IMETHOD HandleDoctypeDecl(const nsAString & aSubset,
|
||||||
|
const nsAString & aName,
|
||||||
|
const nsAString & aSystemId,
|
||||||
|
const nsAString & aPublicId,
|
||||||
|
nsISupports* aCatalogData);
|
||||||
|
NS_IMETHOD HandleProcessingInstruction(const PRUnichar *aTarget,
|
||||||
|
const PRUnichar *aData);
|
||||||
|
NS_IMETHOD HandleXMLDeclaration(const PRUnichar *aData,
|
||||||
|
PRUint32 aLength);
|
||||||
|
NS_IMETHOD ReportError(const PRUnichar* aErrorText,
|
||||||
|
const PRUnichar* aSourceText);
|
||||||
|
|
||||||
|
// nsIContentSink
|
||||||
|
NS_IMETHOD WillBuildModel(void);
|
||||||
|
NS_IMETHOD DidBuildModel();
|
||||||
|
NS_IMETHOD SetDocumentCharset(nsACString& aCharset);
|
||||||
|
|
||||||
|
// nsIXMLContentSink
|
||||||
|
|
||||||
|
// nsIFragmentContentSink
|
||||||
|
NS_IMETHOD GetFragment(nsIDOMDocumentFragment** aFragment);
|
||||||
|
NS_IMETHOD SetTargetDocument(nsIDocument* aDocument);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual PRBool SetDocElement(PRInt32 aNameSpaceID,
|
||||||
|
nsIAtom *aTagName,
|
||||||
|
nsIContent *aContent);
|
||||||
|
virtual nsresult CreateElement(const PRUnichar** aAtts, PRUint32 aAttsCount,
|
||||||
|
nsINodeInfo* aNodeInfo, PRUint32 aLineNumber,
|
||||||
|
nsIContent** aResult, PRBool* aAppendContent);
|
||||||
|
virtual nsresult CloseElement(nsIContent* aContent, PRBool* aAppendContent);
|
||||||
|
|
||||||
|
// nsContentSink overrides
|
||||||
|
virtual nsresult ProcessStyleLink(nsIContent* aElement,
|
||||||
|
const nsAString& aHref,
|
||||||
|
PRBool aAlternate,
|
||||||
|
const nsAString& aTitle,
|
||||||
|
const nsAString& aType,
|
||||||
|
const nsAString& aMedia);
|
||||||
|
nsresult LoadXSLStyleSheet(nsIURI* aUrl);
|
||||||
|
void StartLayout();
|
||||||
|
|
||||||
|
nsCOMPtr<nsIDocument> mTargetDocument;
|
||||||
|
// the fragment
|
||||||
|
nsCOMPtr<nsIContent> mRoot;
|
||||||
|
|
||||||
|
// if FALSE, take content inside endnote tag
|
||||||
|
PRBool mAllContent;
|
||||||
|
nsCOMPtr<nsIContent> mEndnote;
|
||||||
|
};
|
||||||
|
|
||||||
|
static nsresult
|
||||||
|
NewXMLFragmentContentSinkHelper(PRBool aAllContent, nsIFragmentContentSink** aResult)
|
||||||
|
{
|
||||||
|
nsXMLFragmentContentSink* it = new nsXMLFragmentContentSink(aAllContent);
|
||||||
|
if (!it) {
|
||||||
|
return NS_ERROR_OUT_OF_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_ADDREF(*aResult = it);
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
NS_NewXMLFragmentContentSink2(nsIFragmentContentSink** aResult)
|
||||||
|
{
|
||||||
|
return NewXMLFragmentContentSinkHelper(PR_TRUE, aResult);
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
NS_NewXMLFragmentContentSink(nsIFragmentContentSink** aResult)
|
||||||
|
{
|
||||||
|
return NewXMLFragmentContentSinkHelper(PR_FALSE, aResult);
|
||||||
|
}
|
||||||
|
|
||||||
|
nsXMLFragmentContentSink::nsXMLFragmentContentSink(PRBool aAllContent)
|
||||||
|
: mAllContent(aAllContent)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
nsXMLFragmentContentSink::~nsXMLFragmentContentSink()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMPL_ISUPPORTS_INHERITED1(nsXMLFragmentContentSink,
|
||||||
|
nsXMLContentSink,
|
||||||
|
nsIFragmentContentSink)
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsXMLFragmentContentSink::WillBuildModel(void)
|
||||||
|
{
|
||||||
|
if (mRoot) {
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
mState = eXMLContentSinkState_InDocumentElement;
|
||||||
|
|
||||||
|
NS_ASSERTION(mTargetDocument, "Need a document!");
|
||||||
|
|
||||||
|
nsCOMPtr<nsIDOMDocumentFragment> frag;
|
||||||
|
nsresult rv = NS_NewDocumentFragment(getter_AddRefs(frag), mTargetDocument);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
mRoot = do_QueryInterface(frag);
|
||||||
|
PushContent(mRoot); // preload content stack because we know all content goes in the fragment
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsXMLFragmentContentSink::DidBuildModel()
|
||||||
|
{
|
||||||
|
PopContent(); // remove mRoot pushed above
|
||||||
|
|
||||||
|
if (!mAllContent) {
|
||||||
|
NS_ASSERTION(mEndnote, "<endnote> missing in fragment string.");
|
||||||
|
if (mEndnote) {
|
||||||
|
NS_ASSERTION(mRoot->GetChildCount() == 1, "contents have too many children!");
|
||||||
|
// move guts
|
||||||
|
for (PRUint32 child = mEndnote->GetChildCount(); child > 0; child--) {
|
||||||
|
nsCOMPtr<nsIContent> firstchild = mEndnote->GetChildAt(0);
|
||||||
|
mEndnote->RemoveChildAt( 0, PR_FALSE );
|
||||||
|
mRoot->AppendChildTo( firstchild, PR_FALSE, PR_FALSE );
|
||||||
|
}
|
||||||
|
// delete outer content
|
||||||
|
mRoot->RemoveChildAt( 0, PR_FALSE );
|
||||||
|
}
|
||||||
|
// else just leave the content in the fragment. or should we fail?
|
||||||
|
}
|
||||||
|
|
||||||
|
nsCOMPtr<nsIParser> kungFuDeathGrip(mParser);
|
||||||
|
|
||||||
|
// Drop our reference to the parser to get rid of a circular
|
||||||
|
// reference.
|
||||||
|
mParser = nsnull;
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsXMLFragmentContentSink::SetDocumentCharset(nsACString& aCharset)
|
||||||
|
{
|
||||||
|
NS_NOTREACHED("fragments shouldn't set charset");
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
PRBool
|
||||||
|
nsXMLFragmentContentSink::SetDocElement(PRInt32 aNameSpaceID,
|
||||||
|
nsIAtom* aTagName,
|
||||||
|
nsIContent *aContent)
|
||||||
|
{
|
||||||
|
// this is a fragment, not a document
|
||||||
|
return PR_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
nsXMLFragmentContentSink::CreateElement(const PRUnichar** aAtts, PRUint32 aAttsCount,
|
||||||
|
nsINodeInfo* aNodeInfo, PRUint32 aLineNumber,
|
||||||
|
nsIContent** aResult, PRBool* aAppendContent)
|
||||||
|
{
|
||||||
|
nsresult rv = nsXMLContentSink::CreateElement(aAtts, aAttsCount,
|
||||||
|
aNodeInfo, aLineNumber,
|
||||||
|
aResult, aAppendContent);
|
||||||
|
*aAppendContent = PR_TRUE; // make sure scripts added immediately, not on close.
|
||||||
|
|
||||||
|
if (NS_SUCCEEDED(rv) && aNodeInfo->Equals(nsHTMLAtoms::endnote))
|
||||||
|
mEndnote = *aResult;
|
||||||
|
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
nsXMLFragmentContentSink::CloseElement(nsIContent* aContent, PRBool* aAppendContent)
|
||||||
|
{
|
||||||
|
// don't do fancy stuff in nsXMLContentSink
|
||||||
|
*aAppendContent = PR_FALSE;
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsXMLFragmentContentSink::HandleDoctypeDecl(const nsAString & aSubset,
|
||||||
|
const nsAString & aName,
|
||||||
|
const nsAString & aSystemId,
|
||||||
|
const nsAString & aPublicId,
|
||||||
|
nsISupports* aCatalogData)
|
||||||
|
{
|
||||||
|
NS_NOTREACHED("fragments shouldn't have doctype declarations");
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsXMLFragmentContentSink::HandleProcessingInstruction(const PRUnichar *aTarget,
|
||||||
|
const PRUnichar *aData)
|
||||||
|
{
|
||||||
|
FlushText();
|
||||||
|
|
||||||
|
nsresult result = NS_OK;
|
||||||
|
const nsDependentString target(aTarget);
|
||||||
|
const nsDependentString data(aData);
|
||||||
|
|
||||||
|
nsCOMPtr<nsIContent> node;
|
||||||
|
|
||||||
|
result = NS_NewXMLProcessingInstruction(getter_AddRefs(node), target, data);
|
||||||
|
if (NS_SUCCEEDED(result)) {
|
||||||
|
// no special processing here. that should happen when the fragment moves into the document
|
||||||
|
result = AddContentAsLeaf(node);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsXMLFragmentContentSink::HandleXMLDeclaration(const PRUnichar *aData,
|
||||||
|
PRUint32 aLength)
|
||||||
|
{
|
||||||
|
NS_NOTREACHED("fragments shouldn't have XML declarations");
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsXMLFragmentContentSink::ReportError(const PRUnichar* aErrorText,
|
||||||
|
const PRUnichar* aSourceText)
|
||||||
|
{
|
||||||
|
nsCOMPtr<nsIDOMNode> node(do_QueryInterface(mRoot));
|
||||||
|
return ReportErrorFrom( aErrorText, aSourceText, node );
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
nsXMLFragmentContentSink::ProcessStyleLink(nsIContent* aElement,
|
||||||
|
const nsAString& aHref,
|
||||||
|
PRBool aAlternate,
|
||||||
|
const nsAString& aTitle,
|
||||||
|
const nsAString& aType,
|
||||||
|
const nsAString& aMedia)
|
||||||
|
{
|
||||||
|
// don't process until moved to document
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
nsXMLFragmentContentSink::LoadXSLStyleSheet(nsIURI* aUrl)
|
||||||
|
{
|
||||||
|
NS_NOTREACHED("fragments shouldn't have XSL style sheets");
|
||||||
|
return NS_ERROR_UNEXPECTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nsXMLFragmentContentSink::StartLayout()
|
||||||
|
{
|
||||||
|
NS_NOTREACHED("fragments shouldn't layout");
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsXMLFragmentContentSink::GetFragment(nsIDOMDocumentFragment** aFragment)
|
||||||
|
{
|
||||||
|
if (mRoot) {
|
||||||
|
return CallQueryInterface(mRoot, aFragment);
|
||||||
|
}
|
||||||
|
|
||||||
|
*aFragment = nsnull;
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsXMLFragmentContentSink::SetTargetDocument(nsIDocument* aTargetDocument)
|
||||||
|
{
|
||||||
|
NS_ENSURE_ARG_POINTER(aTargetDocument);
|
||||||
|
|
||||||
|
mTargetDocument = aTargetDocument;
|
||||||
|
mNodeInfoManager = aTargetDocument->NodeInfoManager();
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
|
@ -93,7 +93,8 @@
|
||||||
#include "nsXPCOM.h"
|
#include "nsXPCOM.h"
|
||||||
#include "nsISupportsPrimitives.h"
|
#include "nsISupportsPrimitives.h"
|
||||||
#include "nsLinebreakConverter.h"
|
#include "nsLinebreakConverter.h"
|
||||||
#include "nsIHTMLFragmentContentSink.h"
|
#include "nsIFragmentContentSink.h"
|
||||||
|
#include "nsIContentSink.h"
|
||||||
|
|
||||||
// netwerk
|
// netwerk
|
||||||
#include "nsIURI.h"
|
#include "nsIURI.h"
|
||||||
|
@ -2529,7 +2530,7 @@ nsresult nsHTMLEditor::ParseFragment(const nsAString & aFragStr,
|
||||||
sink = do_CreateInstance(NS_HTMLFRAGMENTSINK_CONTRACTID);
|
sink = do_CreateInstance(NS_HTMLFRAGMENTSINK_CONTRACTID);
|
||||||
|
|
||||||
NS_ENSURE_TRUE(sink, NS_ERROR_FAILURE);
|
NS_ENSURE_TRUE(sink, NS_ERROR_FAILURE);
|
||||||
nsCOMPtr<nsIHTMLFragmentContentSink> fragSink(do_QueryInterface(sink));
|
nsCOMPtr<nsIFragmentContentSink> fragSink(do_QueryInterface(sink));
|
||||||
NS_ENSURE_TRUE(fragSink, NS_ERROR_FAILURE);
|
NS_ENSURE_TRUE(fragSink, NS_ERROR_FAILURE);
|
||||||
|
|
||||||
fragSink->SetTargetDocument(aTargetDocument);
|
fragSink->SetTargetDocument(aTargetDocument);
|
||||||
|
@ -2539,7 +2540,7 @@ nsresult nsHTMLEditor::ParseFragment(const nsAString & aFragStr,
|
||||||
if (bContext)
|
if (bContext)
|
||||||
parser->Parse(aFragStr, (void*)0, NS_LITERAL_CSTRING("text/html"), PR_FALSE, PR_TRUE, eDTDMode_fragment);
|
parser->Parse(aFragStr, (void*)0, NS_LITERAL_CSTRING("text/html"), PR_FALSE, PR_TRUE, eDTDMode_fragment);
|
||||||
else
|
else
|
||||||
parser->ParseFragment(aFragStr, 0, aTagStack, 0, NS_LITERAL_CSTRING("text/html"), eDTDMode_quirks);
|
parser->ParseFragment(aFragStr, 0, aTagStack, PR_FALSE, NS_LITERAL_CSTRING("text/html"), eDTDMode_quirks);
|
||||||
// get the fragment node
|
// get the fragment node
|
||||||
nsCOMPtr<nsIDOMDocumentFragment> contextfrag;
|
nsCOMPtr<nsIDOMDocumentFragment> contextfrag;
|
||||||
res = fragSink->GetFragment(getter_AddRefs(contextfrag));
|
res = fragSink->GetFragment(getter_AddRefs(contextfrag));
|
||||||
|
|
|
@ -83,7 +83,7 @@
|
||||||
#include "nsIGenericFactory.h"
|
#include "nsIGenericFactory.h"
|
||||||
#include "nsIHTMLCSSStyleSheet.h"
|
#include "nsIHTMLCSSStyleSheet.h"
|
||||||
#include "nsIHTMLContent.h"
|
#include "nsIHTMLContent.h"
|
||||||
#include "nsIHTMLFragmentContentSink.h"
|
#include "nsIFragmentContentSink.h"
|
||||||
#include "nsHTMLStyleSheet.h"
|
#include "nsHTMLStyleSheet.h"
|
||||||
#include "nsIHTMLToTextSink.h"
|
#include "nsIHTMLToTextSink.h"
|
||||||
#include "nsILayoutDebugger.h"
|
#include "nsILayoutDebugger.h"
|
||||||
|
@ -575,8 +575,10 @@ MAKE_CTOR(CreateHTMLCopyTextEncoder, nsIDocumentEncoder, NS_NewHTM
|
||||||
MAKE_CTOR(CreateXMLContentSerializer, nsIContentSerializer, NS_NewXMLContentSerializer)
|
MAKE_CTOR(CreateXMLContentSerializer, nsIContentSerializer, NS_NewXMLContentSerializer)
|
||||||
MAKE_CTOR(CreateHTMLContentSerializer, nsIContentSerializer, NS_NewHTMLContentSerializer)
|
MAKE_CTOR(CreateHTMLContentSerializer, nsIContentSerializer, NS_NewHTMLContentSerializer)
|
||||||
MAKE_CTOR(CreatePlainTextSerializer, nsIContentSerializer, NS_NewPlainTextSerializer)
|
MAKE_CTOR(CreatePlainTextSerializer, nsIContentSerializer, NS_NewPlainTextSerializer)
|
||||||
MAKE_CTOR(CreateHTMLFragmentSink, nsIHTMLFragmentContentSink, NS_NewHTMLFragmentContentSink)
|
MAKE_CTOR(CreateHTMLFragmentSink, nsIFragmentContentSink, NS_NewHTMLFragmentContentSink)
|
||||||
MAKE_CTOR(CreateHTMLFragmentSink2, nsIHTMLFragmentContentSink, NS_NewHTMLFragmentContentSink2)
|
MAKE_CTOR(CreateHTMLFragmentSink2, nsIFragmentContentSink, NS_NewHTMLFragmentContentSink2)
|
||||||
|
MAKE_CTOR(CreateXMLFragmentSink, nsIFragmentContentSink, NS_NewXMLFragmentContentSink)
|
||||||
|
MAKE_CTOR(CreateXMLFragmentSink2, nsIFragmentContentSink, NS_NewXMLFragmentContentSink2)
|
||||||
MAKE_CTOR(CreateSanitizingHTMLSerializer, nsIContentSerializer, NS_NewSanitizingHTMLSerializer)
|
MAKE_CTOR(CreateSanitizingHTMLSerializer, nsIContentSerializer, NS_NewSanitizingHTMLSerializer)
|
||||||
MAKE_CTOR(CreateXBLService, nsIXBLService, NS_NewXBLService)
|
MAKE_CTOR(CreateXBLService, nsIXBLService, NS_NewXBLService)
|
||||||
MAKE_CTOR(CreateBindingManager, nsIBindingManager, NS_NewBindingManager)
|
MAKE_CTOR(CreateBindingManager, nsIBindingManager, NS_NewBindingManager)
|
||||||
|
@ -1144,6 +1146,16 @@ static const nsModuleComponentInfo gComponents[] = {
|
||||||
MOZ_SANITIZINGHTMLSERIALIZER_CONTRACTID,
|
MOZ_SANITIZINGHTMLSERIALIZER_CONTRACTID,
|
||||||
CreateSanitizingHTMLSerializer },
|
CreateSanitizingHTMLSerializer },
|
||||||
|
|
||||||
|
{ "xml fragment sink",
|
||||||
|
NS_XMLFRAGMENTSINK_CID,
|
||||||
|
NS_XMLFRAGMENTSINK_CONTRACTID,
|
||||||
|
CreateXMLFragmentSink },
|
||||||
|
|
||||||
|
{ "xml fragment sink 2",
|
||||||
|
NS_XMLFRAGMENTSINK2_CID,
|
||||||
|
NS_XMLFRAGMENTSINK2_CONTRACTID,
|
||||||
|
CreateXMLFragmentSink2 },
|
||||||
|
|
||||||
{ "XBL Service",
|
{ "XBL Service",
|
||||||
NS_XBLSERVICE_CID,
|
NS_XBLSERVICE_CID,
|
||||||
"@mozilla.org/xbl;1",
|
"@mozilla.org/xbl;1",
|
||||||
|
|
|
@ -49,7 +49,7 @@ class nsIDocument;
|
||||||
class nsIFrame;
|
class nsIFrame;
|
||||||
class nsIHTMLContent;
|
class nsIHTMLContent;
|
||||||
class nsIHTMLContentSink;
|
class nsIHTMLContentSink;
|
||||||
class nsIHTMLFragmentContentSink;
|
class nsIFragmentContentSink;
|
||||||
class nsPresContext;
|
class nsPresContext;
|
||||||
class nsITextContent;
|
class nsITextContent;
|
||||||
class nsIURI;
|
class nsIURI;
|
||||||
|
@ -253,9 +253,9 @@ NS_NewHTMLContentSink(nsIHTMLContentSink** aInstancePtrResult,
|
||||||
nsISupports* aContainer, // e.g. docshell
|
nsISupports* aContainer, // e.g. docshell
|
||||||
nsIChannel* aChannel);
|
nsIChannel* aChannel);
|
||||||
nsresult
|
nsresult
|
||||||
NS_NewHTMLFragmentContentSink(nsIHTMLFragmentContentSink** aInstancePtrResult);
|
NS_NewHTMLFragmentContentSink(nsIFragmentContentSink** aInstancePtrResult);
|
||||||
nsresult
|
nsresult
|
||||||
NS_NewHTMLFragmentContentSink2(nsIHTMLFragmentContentSink** aInstancePtrResult);
|
NS_NewHTMLFragmentContentSink2(nsIFragmentContentSink** aInstancePtrResult);
|
||||||
|
|
||||||
/** Create a new HTML reflow command */
|
/** Create a new HTML reflow command */
|
||||||
nsresult
|
nsresult
|
||||||
|
|
|
@ -49,7 +49,7 @@ class nsIDocument;
|
||||||
class nsIFrame;
|
class nsIFrame;
|
||||||
class nsIHTMLContent;
|
class nsIHTMLContent;
|
||||||
class nsIHTMLContentSink;
|
class nsIHTMLContentSink;
|
||||||
class nsIHTMLFragmentContentSink;
|
class nsIFragmentContentSink;
|
||||||
class nsPresContext;
|
class nsPresContext;
|
||||||
class nsITextContent;
|
class nsITextContent;
|
||||||
class nsIURI;
|
class nsIURI;
|
||||||
|
@ -253,9 +253,9 @@ NS_NewHTMLContentSink(nsIHTMLContentSink** aInstancePtrResult,
|
||||||
nsISupports* aContainer, // e.g. docshell
|
nsISupports* aContainer, // e.g. docshell
|
||||||
nsIChannel* aChannel);
|
nsIChannel* aChannel);
|
||||||
nsresult
|
nsresult
|
||||||
NS_NewHTMLFragmentContentSink(nsIHTMLFragmentContentSink** aInstancePtrResult);
|
NS_NewHTMLFragmentContentSink(nsIFragmentContentSink** aInstancePtrResult);
|
||||||
nsresult
|
nsresult
|
||||||
NS_NewHTMLFragmentContentSink2(nsIHTMLFragmentContentSink** aInstancePtrResult);
|
NS_NewHTMLFragmentContentSink2(nsIFragmentContentSink** aInstancePtrResult);
|
||||||
|
|
||||||
/** Create a new HTML reflow command */
|
/** Create a new HTML reflow command */
|
||||||
nsresult
|
nsresult
|
||||||
|
|
|
@ -53,7 +53,7 @@ EXPORTS = \
|
||||||
nsIContentSink.h \
|
nsIContentSink.h \
|
||||||
nsITokenizer.h \
|
nsITokenizer.h \
|
||||||
nsIHTMLContentSink.h \
|
nsIHTMLContentSink.h \
|
||||||
nsIHTMLFragmentContentSink.h\
|
nsIFragmentContentSink.h \
|
||||||
nsIParserNode.h \
|
nsIParserNode.h \
|
||||||
nsIParser.h \
|
nsIParser.h \
|
||||||
nsIDTD.h \
|
nsIDTD.h \
|
||||||
|
|
|
@ -0,0 +1,88 @@
|
||||||
|
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||||
|
/* ***** BEGIN LICENSE BLOCK *****
|
||||||
|
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||||
|
*
|
||||||
|
* The contents of this file are subject to the Mozilla Public License Version
|
||||||
|
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at
|
||||||
|
* http://www.mozilla.org/MPL/
|
||||||
|
*
|
||||||
|
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||||
|
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||||
|
* for the specific language governing rights and limitations under the
|
||||||
|
* License.
|
||||||
|
*
|
||||||
|
* The Original Code is Mozilla Communicator client code.
|
||||||
|
*
|
||||||
|
* The Initial Developer of the Original Code is
|
||||||
|
* Netscape Communications Corporation.
|
||||||
|
* Portions created by the Initial Developer are Copyright (C) 1998
|
||||||
|
* the Initial Developer. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Contributor(s):
|
||||||
|
*
|
||||||
|
* Alternatively, the contents of this file may be used under the terms of
|
||||||
|
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||||
|
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||||
|
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||||
|
* of those above. If you wish to allow use of your version of this file only
|
||||||
|
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||||
|
* use your version of this file under the terms of the MPL, indicate your
|
||||||
|
* decision by deleting the provisions above and replace them with the notice
|
||||||
|
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||||
|
* the provisions above, a recipient may use your version of this file under
|
||||||
|
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||||
|
*
|
||||||
|
* ***** END LICENSE BLOCK ***** */
|
||||||
|
#ifndef nsIFragmentContentSink_h___
|
||||||
|
#define nsIFragmentContentSink_h___
|
||||||
|
|
||||||
|
#include "nsISupports.h"
|
||||||
|
|
||||||
|
class nsIDOMDocumentFragment;
|
||||||
|
class nsIDocument;
|
||||||
|
|
||||||
|
#define NS_I_FRAGMENT_CONTENT_SINK_IID \
|
||||||
|
{ 0x2b23c1fb, 0xb83c, 0x436b, \
|
||||||
|
{ 0xb7, 0x2a, 0x9c, 0xbe, 0xf1, 0xe9, 0x9b, 0x20 } };
|
||||||
|
|
||||||
|
class nsIFragmentContentSink : public nsISupports {
|
||||||
|
public:
|
||||||
|
NS_DEFINE_STATIC_IID_ACCESSOR(NS_I_FRAGMENT_CONTENT_SINK_IID)
|
||||||
|
/**
|
||||||
|
* This method is used to obtain the fragment created by
|
||||||
|
* a fragment content sink. The value returned will be null
|
||||||
|
* if the content sink hasn't yet received parser notifications.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
NS_IMETHOD GetFragment(nsIDOMDocumentFragment** aFragment) = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method is used to set the target document for this fragment
|
||||||
|
* sink. This document's nodeinfo manager will be used to create
|
||||||
|
* the content objects. This MUST be called before the sink is used.
|
||||||
|
*
|
||||||
|
* @param aDocument the document the new nodes will belong to
|
||||||
|
* (should not be null)
|
||||||
|
*/
|
||||||
|
NS_IMETHOD SetTargetDocument(nsIDocument* aDocument) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base version takes string nested in context, context ends with <endnote>.
|
||||||
|
* 2 version just loads whole string.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define NS_HTMLFRAGMENTSINK_CONTRACTID "@mozilla.org/layout/htmlfragmentsink;1"
|
||||||
|
#define NS_HTMLFRAGMENTSINK2_CONTRACTID "@mozilla.org/layout/htmlfragmentsink;2"
|
||||||
|
|
||||||
|
#define NS_XMLFRAGMENTSINK_CONTRACTID "@mozilla.org/layout/xmlfragmentsink;1"
|
||||||
|
#define NS_XMLFRAGMENTSINK2_CONTRACTID "@mozilla.org/layout/xmlfragmentsink;2"
|
||||||
|
|
||||||
|
// the HTML versions are in nsHTMLParts.h
|
||||||
|
nsresult
|
||||||
|
NS_NewXMLFragmentContentSink(nsIFragmentContentSink** aInstancePtrResult);
|
||||||
|
nsresult
|
||||||
|
NS_NewXMLFragmentContentSink2(nsIFragmentContentSink** aInstancePtrResult);
|
||||||
|
|
||||||
|
#endif
|
|
@ -251,7 +251,7 @@ class nsIParser : public nsISupports {
|
||||||
NS_IMETHOD ParseFragment(const nsAString& aSourceBuffer,
|
NS_IMETHOD ParseFragment(const nsAString& aSourceBuffer,
|
||||||
void* aKey,
|
void* aKey,
|
||||||
nsVoidArray& aTagStack,
|
nsVoidArray& aTagStack,
|
||||||
PRUint32 anInsertPos,
|
PRBool aXMLMode,
|
||||||
const nsACString& aContentType,
|
const nsACString& aContentType,
|
||||||
nsDTDMode aMode = eDTDMode_autodetect) = 0;
|
nsDTDMode aMode = eDTDMode_autodetect) = 0;
|
||||||
|
|
||||||
|
|
|
@ -1672,27 +1672,47 @@ NS_IMETHODIMP
|
||||||
nsParser::ParseFragment(const nsAString& aSourceBuffer,
|
nsParser::ParseFragment(const nsAString& aSourceBuffer,
|
||||||
void* aKey,
|
void* aKey,
|
||||||
nsVoidArray& aTagStack,
|
nsVoidArray& aTagStack,
|
||||||
PRUint32 anInsertPos,
|
PRBool aXMLMode,
|
||||||
const nsACString& aMimeType,
|
const nsACString& aMimeType,
|
||||||
nsDTDMode aMode)
|
nsDTDMode aMode)
|
||||||
{
|
{
|
||||||
nsresult result = NS_OK;
|
nsresult result = NS_OK;
|
||||||
nsAutoString theContext;
|
nsAutoString theContext, endContext;
|
||||||
PRUint32 theCount = aTagStack.Count();
|
PRUint32 theCount = aTagStack.Count();
|
||||||
PRUint32 theIndex = 0;
|
PRUint32 theIndex = 0;
|
||||||
|
|
||||||
while (theIndex++ < theCount){
|
for (theIndex = 0; theIndex < theCount; theIndex++) {
|
||||||
theContext.AppendLiteral("<");
|
theContext.AppendLiteral("<");
|
||||||
theContext.Append((PRUnichar*)aTagStack.ElementAt(theCount - theIndex));
|
theContext.Append((PRUnichar*)aTagStack.ElementAt(theCount - theIndex - 1));
|
||||||
theContext.AppendLiteral(">");
|
theContext.AppendLiteral(">");
|
||||||
}
|
}
|
||||||
|
|
||||||
theContext.AppendLiteral("<endnote>"); //XXXHack! I'll make this better later.
|
// Note duplication: nsHTMLAtoms::endnote == an atom in nsHTMLTags
|
||||||
|
theContext.AppendLiteral("<");
|
||||||
|
theContext.Append(nsHTMLTags::GetStringValue(eHTMLTag_endnote));
|
||||||
|
theContext.AppendLiteral(">");
|
||||||
|
|
||||||
|
if (aXMLMode) {
|
||||||
|
endContext.AppendLiteral("</");
|
||||||
|
endContext.Append(nsHTMLTags::GetStringValue(eHTMLTag_endnote));
|
||||||
|
endContext.AppendLiteral(">");
|
||||||
|
|
||||||
|
for (theIndex = 0; theIndex < theCount; theIndex++) {
|
||||||
|
endContext.AppendLiteral("</");
|
||||||
|
nsAutoString thisTag( (PRUnichar*)aTagStack.ElementAt(theIndex) );
|
||||||
|
PRInt32 endOfTag = thisTag.FindChar(PRUnichar(' ')); // was there an xmlns=?
|
||||||
|
if (endOfTag == -1)
|
||||||
|
endContext.Append( thisTag );
|
||||||
|
else
|
||||||
|
endContext.Append( Substring(thisTag,0,endOfTag) );
|
||||||
|
endContext.AppendLiteral(">");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//now it's time to try to build the model from this fragment
|
//now it's time to try to build the model from this fragment
|
||||||
|
|
||||||
mFlags &= ~NS_PARSER_FLAG_OBSERVERS_ENABLED; //disable observers for fragments
|
mFlags &= ~NS_PARSER_FLAG_OBSERVERS_ENABLED; //disable observers for fragments
|
||||||
result = Parse(theContext + aSourceBuffer,(void*)&theContext,aMimeType,PR_FALSE,PR_TRUE, aMode);
|
result = Parse(theContext + aSourceBuffer + endContext,(void*)&theContext,aMimeType,PR_FALSE,PR_TRUE, aMode);
|
||||||
mFlags |= NS_PARSER_FLAG_OBSERVERS_ENABLED; //now reenable.
|
mFlags |= NS_PARSER_FLAG_OBSERVERS_ENABLED; //now reenable.
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
|
|
@ -218,10 +218,13 @@ class nsParser : public nsIParser,
|
||||||
PRBool aLastCall,
|
PRBool aLastCall,
|
||||||
nsDTDMode aMode = eDTDMode_autodetect);
|
nsDTDMode aMode = eDTDMode_autodetect);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method needs documentation
|
||||||
|
*/
|
||||||
NS_IMETHOD ParseFragment(const nsAString& aSourceBuffer,
|
NS_IMETHOD ParseFragment(const nsAString& aSourceBuffer,
|
||||||
void* aKey,
|
void* aKey,
|
||||||
nsVoidArray& aTagStack,
|
nsVoidArray& aTagStack,
|
||||||
PRUint32 anInsertPos,
|
PRBool aXMLMode,
|
||||||
const nsACString& aContentType,
|
const nsACString& aContentType,
|
||||||
nsDTDMode aMode = eDTDMode_autodetect);
|
nsDTDMode aMode = eDTDMode_autodetect);
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче