зеркало из 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 \
|
||||
{ 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}
|
||||
#define NS_XULPOPUPLISTENER_CID \
|
||||
{ 0x3986b301, 0x97c, 0x11d3, { 0xbf, 0x87, 0x0, 0x10, 0x5a, 0x1b, 0x6, 0x27 } }
|
||||
|
|
|
@ -58,7 +58,8 @@
|
|||
#include "nsIParser.h"
|
||||
#include "nsIComponentManager.h"
|
||||
#include "nsParserCIID.h"
|
||||
#include "nsIHTMLFragmentContentSink.h"
|
||||
#include "nsIFragmentContentSink.h"
|
||||
#include "nsIContentSink.h"
|
||||
#include "nsIEnumerator.h"
|
||||
#include "nsIScriptSecurityManager.h"
|
||||
#include "nsIScriptGlobalObject.h"
|
||||
|
@ -2366,8 +2367,40 @@ nsRange::CreateContextualFragment(const nsAString& aFragment,
|
|||
|
||||
parent->GetNodeType(&nodeType);
|
||||
if (nsIDOMNode::ELEMENT_NODE == nodeType) {
|
||||
nsAutoString tagName;
|
||||
PRInt32 namespaceID;
|
||||
nsAutoString tagName, uriStr;
|
||||
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
|
||||
PRUnichar* name = ToNewUnicode(tagName);
|
||||
if (name) {
|
||||
|
@ -2387,23 +2420,30 @@ nsRange::CreateContextualFragment(const nsAString& aFragment,
|
|||
|
||||
if (NS_SUCCEEDED(result)) {
|
||||
nsCAutoString contentType;
|
||||
nsCOMPtr<nsIHTMLFragmentContentSink> sink;
|
||||
|
||||
result = NS_NewHTMLFragmentContentSink(getter_AddRefs(sink));
|
||||
if (NS_SUCCEEDED(result)) {
|
||||
sink->SetTargetDocument(document);
|
||||
parser->SetContentSink(sink);
|
||||
nsCOMPtr<nsIDOMNSDocument> domnsDocument(do_QueryInterface(document));
|
||||
if (domnsDocument) {
|
||||
PRBool bCaseSensitive = PR_TRUE;
|
||||
if (document) {
|
||||
nsAutoString buf;
|
||||
domnsDocument->GetContentType(buf);
|
||||
document->GetContentType(buf);
|
||||
CopyUCS2toASCII(buf, contentType);
|
||||
bCaseSensitive = document->IsCaseSensitive();
|
||||
}
|
||||
else {
|
||||
// Who're we kidding. This only works for html.
|
||||
contentType.AssignLiteral("text/html");
|
||||
contentType.AssignLiteral("text/xml");
|
||||
}
|
||||
|
||||
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)) {
|
||||
sink->SetTargetDocument(document);
|
||||
nsCOMPtr<nsIContentSink> contentsink( do_QueryInterface(sink) );
|
||||
parser->SetContentSink(contentsink);
|
||||
|
||||
// If there's no JS or system JS running,
|
||||
// push the current document's context on the JS context stack
|
||||
// so that event handlers in the fragment do not get
|
||||
|
@ -2445,7 +2485,7 @@ nsRange::CreateContextualFragment(const nsAString& aFragment,
|
|||
|
||||
nsDTDMode mode = eDTDMode_autodetect;
|
||||
nsCOMPtr<nsIHTMLDocument> htmlDoc(do_QueryInterface(domDocument));
|
||||
if (htmlDoc) {
|
||||
if (bHTML) {
|
||||
switch (htmlDoc->GetCompatibilityMode()) {
|
||||
case eCompatibility_NavQuirks:
|
||||
mode = eDTDMode_quirks;
|
||||
|
@ -2460,10 +2500,12 @@ nsRange::CreateContextualFragment(const nsAString& aFragment,
|
|||
NS_NOTREACHED("unknown mode");
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
mode = eDTDMode_full_standards;
|
||||
}
|
||||
result = parser->ParseFragment(aFragment, (void*)0,
|
||||
tagStack,
|
||||
0, contentType, mode);
|
||||
!bHTML, contentType, mode);
|
||||
|
||||
if (ContextStack) {
|
||||
JSContext *notused;
|
||||
|
|
|
@ -134,6 +134,7 @@ HTML_ATOM(em, "em")
|
|||
HTML_ATOM(embed, "embed")
|
||||
HTML_ATOM(encoding, "encoding")
|
||||
HTML_ATOM(enctype, "enctype")
|
||||
HTML_ATOM(endnote, "endnote") // contextual fragments
|
||||
HTML_ATOM(_event, "event")
|
||||
HTML_ATOM(face, "face")
|
||||
HTML_ATOM(fieldset, "fieldset")
|
||||
|
|
|
@ -36,7 +36,8 @@
|
|||
* ***** END LICENSE BLOCK ***** */
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsIHTMLFragmentContentSink.h"
|
||||
#include "nsIFragmentContentSink.h"
|
||||
#include "nsIHTMLContentSink.h"
|
||||
#include "nsIParser.h"
|
||||
#include "nsIParserService.h"
|
||||
#include "nsIHTMLContent.h"
|
||||
|
@ -68,9 +69,10 @@
|
|||
// at some pointe really soon!
|
||||
//
|
||||
|
||||
class nsHTMLFragmentContentSink : public nsIHTMLFragmentContentSink {
|
||||
class nsHTMLFragmentContentSink : public nsIFragmentContentSink,
|
||||
public nsIHTMLContentSink {
|
||||
public:
|
||||
nsHTMLFragmentContentSink();
|
||||
nsHTMLFragmentContentSink(PRBool aAllContent = PR_FALSE);
|
||||
virtual ~nsHTMLFragmentContentSink();
|
||||
|
||||
// nsISupports
|
||||
|
@ -119,7 +121,7 @@ public:
|
|||
NS_IMETHOD AddProcessingInstruction(const nsIParserNode& aNode);
|
||||
NS_IMETHOD AddDocTypeDecl(const nsIParserNode& aNode);
|
||||
|
||||
// nsIHTMLFragmentContentSink
|
||||
// nsIFragmentContentSink
|
||||
NS_IMETHOD GetFragment(nsIDOMDocumentFragment** aFragment);
|
||||
NS_IMETHOD SetTargetDocument(nsIDocument* aDocument);
|
||||
|
||||
|
@ -160,43 +162,45 @@ public:
|
|||
nsRefPtr<nsNodeInfoManager> mNodeInfoManager;
|
||||
};
|
||||
|
||||
class nsHTMLFragmentContentSink2 : public nsHTMLFragmentContentSink
|
||||
{
|
||||
public:
|
||||
nsHTMLFragmentContentSink2() { mHitSentinel = PR_TRUE; mSeenBody = PR_FALSE;}
|
||||
virtual ~nsHTMLFragmentContentSink2() {}
|
||||
};
|
||||
|
||||
nsresult
|
||||
NS_NewHTMLFragmentContentSink2(nsIHTMLFragmentContentSink** aResult)
|
||||
static nsresult
|
||||
NewHTMLFragmentContentSinkHelper(PRBool aAllContent, nsIFragmentContentSink** aResult)
|
||||
{
|
||||
NS_PRECONDITION(aResult, "Null out ptr");
|
||||
if (nsnull == aResult) {
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
|
||||
*aResult = new nsHTMLFragmentContentSink2();
|
||||
NS_ENSURE_TRUE(*aResult, NS_ERROR_OUT_OF_MEMORY);
|
||||
nsHTMLFragmentContentSink* it = new nsHTMLFragmentContentSink(aAllContent);
|
||||
if (nsnull == it) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
NS_ADDREF(*aResult);
|
||||
NS_ADDREF(*aResult = it);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
NS_NewHTMLFragmentContentSink(nsIHTMLFragmentContentSink** aResult)
|
||||
NS_NewHTMLFragmentContentSink2(nsIFragmentContentSink** aResult)
|
||||
{
|
||||
NS_PRECONDITION(aResult, "Null out ptr");
|
||||
|
||||
*aResult = new nsHTMLFragmentContentSink();
|
||||
NS_ENSURE_TRUE(*aResult, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
NS_ADDREF(*aResult);
|
||||
|
||||
return NS_OK;
|
||||
return NewHTMLFragmentContentSinkHelper(PR_TRUE,aResult);
|
||||
}
|
||||
|
||||
nsHTMLFragmentContentSink::nsHTMLFragmentContentSink()
|
||||
nsresult
|
||||
NS_NewHTMLFragmentContentSink(nsIFragmentContentSink** aResult)
|
||||
{
|
||||
return NewHTMLFragmentContentSinkHelper(PR_FALSE,aResult);
|
||||
}
|
||||
|
||||
nsHTMLFragmentContentSink::nsHTMLFragmentContentSink(PRBool aAllContent)
|
||||
{
|
||||
if (aAllContent) {
|
||||
mHitSentinel = PR_TRUE;
|
||||
mSeenBody = PR_FALSE;
|
||||
} else {
|
||||
mHitSentinel = PR_FALSE;
|
||||
mSeenBody = PR_TRUE;
|
||||
}
|
||||
mRoot = nsnull;
|
||||
mParser = nsnull;
|
||||
mCurrentForm = nsnull;
|
||||
|
@ -233,10 +237,10 @@ NS_IMPL_ADDREF(nsHTMLFragmentContentSink)
|
|||
NS_IMPL_RELEASE(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(nsIContentSink)
|
||||
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIHTMLFragmentContentSink)
|
||||
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIFragmentContentSink)
|
||||
NS_INTERFACE_MAP_END
|
||||
|
||||
|
||||
|
@ -441,8 +445,6 @@ nsHTMLFragmentContentSink::AddBaseTagInfo(nsIContent* aContent)
|
|||
}
|
||||
}
|
||||
|
||||
static const char kSentinelStr[] = "endnote";
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLFragmentContentSink::OpenContainer(const nsIParserNode& aNode)
|
||||
{
|
||||
|
@ -452,7 +454,8 @@ nsHTMLFragmentContentSink::OpenContainer(const nsIParserNode& aNode)
|
|||
nsresult result = NS_OK;
|
||||
|
||||
tag.Assign(aNode.GetText());
|
||||
if (tag.EqualsIgnoreCase(kSentinelStr)) {
|
||||
|
||||
if (nsHTMLAtoms::endnote->Equals(tag)) {
|
||||
mHitSentinel = PR_TRUE;
|
||||
}
|
||||
else if (mHitSentinel) {
|
||||
|
|
|
@ -134,6 +134,7 @@ HTML_ATOM(em, "em")
|
|||
HTML_ATOM(embed, "embed")
|
||||
HTML_ATOM(encoding, "encoding")
|
||||
HTML_ATOM(enctype, "enctype")
|
||||
HTML_ATOM(endnote, "endnote") // contextual fragments
|
||||
HTML_ATOM(_event, "event")
|
||||
HTML_ATOM(face, "face")
|
||||
HTML_ATOM(fieldset, "fieldset")
|
||||
|
|
|
@ -72,6 +72,7 @@ REQUIRES = xpcom \
|
|||
|
||||
CPPSRCS = \
|
||||
nsXMLContentSink.cpp \
|
||||
nsXMLFragmentContentSink.cpp \
|
||||
nsXMLDocument.cpp \
|
||||
nsXMLPrettyPrinter.cpp \
|
||||
$(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
|
||||
nsXMLContentSink::HandleStartElement(const PRUnichar *aName,
|
||||
const PRUnichar **aAtts,
|
||||
|
@ -967,44 +1004,17 @@ nsXMLContentSink::HandleStartElement(const PRUnichar *aName,
|
|||
getter_AddRefs(content), &appendContent);
|
||||
NS_ENSURE_SUCCESS(result, result);
|
||||
|
||||
if (mDocument) {
|
||||
content->SetContentID(mDocument->GetAndIncrementContentID());
|
||||
}
|
||||
content->SetDocument(mDocument, PR_FALSE, PR_TRUE);
|
||||
|
||||
// Set the attributes on the new content element
|
||||
result = AddAttributes(aAtts, content);
|
||||
|
||||
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;
|
||||
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) {
|
||||
// Store the element
|
||||
if (!SetDocElement(nameSpaceID,tagAtom,content) && appendContent) {
|
||||
nsCOMPtr<nsIContent> parent = GetCurrentContent();
|
||||
NS_ENSURE_TRUE(parent, NS_ERROR_UNEXPECTED);
|
||||
|
||||
|
@ -1265,6 +1275,15 @@ nsXMLContentSink::HandleXMLDeclaration(const PRUnichar *aData,
|
|||
NS_IMETHODIMP
|
||||
nsXMLContentSink::ReportError(const PRUnichar* aErrorText,
|
||||
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;
|
||||
|
||||
|
@ -1278,14 +1297,13 @@ nsXMLContentSink::ReportError(const PRUnichar* aErrorText,
|
|||
|
||||
// Clear the current content and
|
||||
// prepare to set <parsererror> as the document root
|
||||
nsCOMPtr<nsIDOMNode> node(do_QueryInterface(mDocument));
|
||||
if (node) {
|
||||
if (aNode) {
|
||||
for (;;) {
|
||||
nsCOMPtr<nsIDOMNode> child, dummy;
|
||||
node->GetLastChild(getter_AddRefs(child));
|
||||
aNode->GetLastChild(getter_AddRefs(child));
|
||||
if (!child)
|
||||
break;
|
||||
node->RemoveChild(child, getter_AddRefs(dummy));
|
||||
aNode->RemoveChild(child, getter_AddRefs(dummy));
|
||||
}
|
||||
}
|
||||
NS_IF_RELEASE(mDocElement);
|
||||
|
|
|
@ -107,6 +107,12 @@ protected:
|
|||
PRInt32 aNameSpaceID,
|
||||
nsIAtom* aTagName,
|
||||
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,
|
||||
nsINodeInfo* aNodeInfo, PRUint32 aLineNumber,
|
||||
nsIContent** aResult, PRBool* aAppendContent);
|
||||
|
@ -125,6 +131,11 @@ protected:
|
|||
PRInt32 PushContent(nsIContent *aContent);
|
||||
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);
|
||||
|
||||
|
|
|
@ -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 "nsISupportsPrimitives.h"
|
||||
#include "nsLinebreakConverter.h"
|
||||
#include "nsIHTMLFragmentContentSink.h"
|
||||
#include "nsIFragmentContentSink.h"
|
||||
#include "nsIContentSink.h"
|
||||
|
||||
// netwerk
|
||||
#include "nsIURI.h"
|
||||
|
@ -2529,7 +2530,7 @@ nsresult nsHTMLEditor::ParseFragment(const nsAString & aFragStr,
|
|||
sink = do_CreateInstance(NS_HTMLFRAGMENTSINK_CONTRACTID);
|
||||
|
||||
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);
|
||||
|
||||
fragSink->SetTargetDocument(aTargetDocument);
|
||||
|
@ -2539,7 +2540,7 @@ nsresult nsHTMLEditor::ParseFragment(const nsAString & aFragStr,
|
|||
if (bContext)
|
||||
parser->Parse(aFragStr, (void*)0, NS_LITERAL_CSTRING("text/html"), PR_FALSE, PR_TRUE, eDTDMode_fragment);
|
||||
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
|
||||
nsCOMPtr<nsIDOMDocumentFragment> contextfrag;
|
||||
res = fragSink->GetFragment(getter_AddRefs(contextfrag));
|
||||
|
|
|
@ -83,7 +83,7 @@
|
|||
#include "nsIGenericFactory.h"
|
||||
#include "nsIHTMLCSSStyleSheet.h"
|
||||
#include "nsIHTMLContent.h"
|
||||
#include "nsIHTMLFragmentContentSink.h"
|
||||
#include "nsIFragmentContentSink.h"
|
||||
#include "nsHTMLStyleSheet.h"
|
||||
#include "nsIHTMLToTextSink.h"
|
||||
#include "nsILayoutDebugger.h"
|
||||
|
@ -575,8 +575,10 @@ MAKE_CTOR(CreateHTMLCopyTextEncoder, nsIDocumentEncoder, NS_NewHTM
|
|||
MAKE_CTOR(CreateXMLContentSerializer, nsIContentSerializer, NS_NewXMLContentSerializer)
|
||||
MAKE_CTOR(CreateHTMLContentSerializer, nsIContentSerializer, NS_NewHTMLContentSerializer)
|
||||
MAKE_CTOR(CreatePlainTextSerializer, nsIContentSerializer, NS_NewPlainTextSerializer)
|
||||
MAKE_CTOR(CreateHTMLFragmentSink, nsIHTMLFragmentContentSink, NS_NewHTMLFragmentContentSink)
|
||||
MAKE_CTOR(CreateHTMLFragmentSink2, nsIHTMLFragmentContentSink, NS_NewHTMLFragmentContentSink2)
|
||||
MAKE_CTOR(CreateHTMLFragmentSink, nsIFragmentContentSink, NS_NewHTMLFragmentContentSink)
|
||||
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(CreateXBLService, nsIXBLService, NS_NewXBLService)
|
||||
MAKE_CTOR(CreateBindingManager, nsIBindingManager, NS_NewBindingManager)
|
||||
|
@ -1144,6 +1146,16 @@ static const nsModuleComponentInfo gComponents[] = {
|
|||
MOZ_SANITIZINGHTMLSERIALIZER_CONTRACTID,
|
||||
CreateSanitizingHTMLSerializer },
|
||||
|
||||
{ "xml fragment sink",
|
||||
NS_XMLFRAGMENTSINK_CID,
|
||||
NS_XMLFRAGMENTSINK_CONTRACTID,
|
||||
CreateXMLFragmentSink },
|
||||
|
||||
{ "xml fragment sink 2",
|
||||
NS_XMLFRAGMENTSINK2_CID,
|
||||
NS_XMLFRAGMENTSINK2_CONTRACTID,
|
||||
CreateXMLFragmentSink2 },
|
||||
|
||||
{ "XBL Service",
|
||||
NS_XBLSERVICE_CID,
|
||||
"@mozilla.org/xbl;1",
|
||||
|
|
|
@ -49,7 +49,7 @@ class nsIDocument;
|
|||
class nsIFrame;
|
||||
class nsIHTMLContent;
|
||||
class nsIHTMLContentSink;
|
||||
class nsIHTMLFragmentContentSink;
|
||||
class nsIFragmentContentSink;
|
||||
class nsPresContext;
|
||||
class nsITextContent;
|
||||
class nsIURI;
|
||||
|
@ -253,9 +253,9 @@ NS_NewHTMLContentSink(nsIHTMLContentSink** aInstancePtrResult,
|
|||
nsISupports* aContainer, // e.g. docshell
|
||||
nsIChannel* aChannel);
|
||||
nsresult
|
||||
NS_NewHTMLFragmentContentSink(nsIHTMLFragmentContentSink** aInstancePtrResult);
|
||||
NS_NewHTMLFragmentContentSink(nsIFragmentContentSink** aInstancePtrResult);
|
||||
nsresult
|
||||
NS_NewHTMLFragmentContentSink2(nsIHTMLFragmentContentSink** aInstancePtrResult);
|
||||
NS_NewHTMLFragmentContentSink2(nsIFragmentContentSink** aInstancePtrResult);
|
||||
|
||||
/** Create a new HTML reflow command */
|
||||
nsresult
|
||||
|
|
|
@ -49,7 +49,7 @@ class nsIDocument;
|
|||
class nsIFrame;
|
||||
class nsIHTMLContent;
|
||||
class nsIHTMLContentSink;
|
||||
class nsIHTMLFragmentContentSink;
|
||||
class nsIFragmentContentSink;
|
||||
class nsPresContext;
|
||||
class nsITextContent;
|
||||
class nsIURI;
|
||||
|
@ -253,9 +253,9 @@ NS_NewHTMLContentSink(nsIHTMLContentSink** aInstancePtrResult,
|
|||
nsISupports* aContainer, // e.g. docshell
|
||||
nsIChannel* aChannel);
|
||||
nsresult
|
||||
NS_NewHTMLFragmentContentSink(nsIHTMLFragmentContentSink** aInstancePtrResult);
|
||||
NS_NewHTMLFragmentContentSink(nsIFragmentContentSink** aInstancePtrResult);
|
||||
nsresult
|
||||
NS_NewHTMLFragmentContentSink2(nsIHTMLFragmentContentSink** aInstancePtrResult);
|
||||
NS_NewHTMLFragmentContentSink2(nsIFragmentContentSink** aInstancePtrResult);
|
||||
|
||||
/** Create a new HTML reflow command */
|
||||
nsresult
|
||||
|
|
|
@ -53,7 +53,7 @@ EXPORTS = \
|
|||
nsIContentSink.h \
|
||||
nsITokenizer.h \
|
||||
nsIHTMLContentSink.h \
|
||||
nsIHTMLFragmentContentSink.h\
|
||||
nsIFragmentContentSink.h \
|
||||
nsIParserNode.h \
|
||||
nsIParser.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,
|
||||
void* aKey,
|
||||
nsVoidArray& aTagStack,
|
||||
PRUint32 anInsertPos,
|
||||
PRBool aXMLMode,
|
||||
const nsACString& aContentType,
|
||||
nsDTDMode aMode = eDTDMode_autodetect) = 0;
|
||||
|
||||
|
|
|
@ -1672,27 +1672,47 @@ NS_IMETHODIMP
|
|||
nsParser::ParseFragment(const nsAString& aSourceBuffer,
|
||||
void* aKey,
|
||||
nsVoidArray& aTagStack,
|
||||
PRUint32 anInsertPos,
|
||||
PRBool aXMLMode,
|
||||
const nsACString& aMimeType,
|
||||
nsDTDMode aMode)
|
||||
{
|
||||
nsresult result = NS_OK;
|
||||
nsAutoString theContext;
|
||||
nsAutoString theContext, endContext;
|
||||
PRUint32 theCount = aTagStack.Count();
|
||||
PRUint32 theIndex = 0;
|
||||
|
||||
while (theIndex++ < theCount){
|
||||
for (theIndex = 0; theIndex < theCount; theIndex++) {
|
||||
theContext.AppendLiteral("<");
|
||||
theContext.Append((PRUnichar*)aTagStack.ElementAt(theCount - theIndex));
|
||||
theContext.Append((PRUnichar*)aTagStack.ElementAt(theCount - theIndex - 1));
|
||||
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
|
||||
|
||||
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.
|
||||
|
||||
return result;
|
||||
|
|
|
@ -218,10 +218,13 @@ class nsParser : public nsIParser,
|
|||
PRBool aLastCall,
|
||||
nsDTDMode aMode = eDTDMode_autodetect);
|
||||
|
||||
/**
|
||||
* This method needs documentation
|
||||
*/
|
||||
NS_IMETHOD ParseFragment(const nsAString& aSourceBuffer,
|
||||
void* aKey,
|
||||
nsVoidArray& aTagStack,
|
||||
PRUint32 anInsertPos,
|
||||
PRBool aXMLMode,
|
||||
const nsACString& aContentType,
|
||||
nsDTDMode aMode = eDTDMode_autodetect);
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче