зеркало из https://github.com/mozilla/pjs.git
Make CreateContextualFragment know what document the fragment is destined for.
Fixes some issues with images and innerHTML. Bugs 198486, 198989, 201865. r=jfrancis, sr=jst
This commit is contained in:
Родитель
0831c7e659
Коммит
5df3b30a3b
|
@ -365,14 +365,12 @@ nsImageLoadingContent::ImageURIChanged(const nsACString& aNewURI)
|
|||
nsresult rv; // XXXbz Should failures in this method fire onerror?
|
||||
|
||||
// First, get a document (needed for security checks, base URI and the like)
|
||||
// Even if we do not have a document, we want to keep going here. The
|
||||
// reason is that nodes created by the HTMLFragmentContentSink have no
|
||||
// document (not even in the nodeinfo) and are used when cutting and
|
||||
// pasting, as well as for drag&drop. So if we are to have composer sorta
|
||||
// working.... Once bug 198486 is fixed, we can go back to just bailing on
|
||||
// a null document.
|
||||
nsCOMPtr<nsIDocument> doc;
|
||||
rv = GetOurDocument(getter_AddRefs(doc));
|
||||
if (!doc) {
|
||||
// No reason to bother, I think...
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIURI> imageURI;
|
||||
rv = StringToURI(aNewURI, doc, getter_AddRefs(imageURI));
|
||||
|
@ -390,11 +388,7 @@ nsImageLoadingContent::ImageURIChanged(const nsACString& aNewURI)
|
|||
// not to show the broken image icon. If the load is blocked by the
|
||||
// content policy or security manager, we will want to cancel with
|
||||
// the error code from those.
|
||||
nsresult cancelResult = NS_OK;
|
||||
if (doc) {
|
||||
// Can't do security or content policy checks without a document
|
||||
cancelResult = CanLoadImage(imageURI, doc);
|
||||
}
|
||||
nsresult cancelResult = CanLoadImage(imageURI, doc);
|
||||
if (NS_SUCCEEDED(cancelResult)) {
|
||||
cancelResult = NS_ERROR_IMAGE_SRC_CHANGED;
|
||||
}
|
||||
|
@ -409,15 +403,11 @@ nsImageLoadingContent::ImageURIChanged(const nsACString& aNewURI)
|
|||
}
|
||||
|
||||
nsCOMPtr<nsILoadGroup> loadGroup;
|
||||
if (doc) {
|
||||
doc->GetDocumentLoadGroup(getter_AddRefs(loadGroup));
|
||||
NS_WARN_IF_FALSE(loadGroup, "Could not get loadgroup; onload may fire too early");
|
||||
}
|
||||
doc->GetDocumentLoadGroup(getter_AddRefs(loadGroup));
|
||||
NS_WARN_IF_FALSE(loadGroup, "Could not get loadgroup; onload may fire too early");
|
||||
|
||||
nsCOMPtr<nsIURI> documentURI;
|
||||
if (doc) {
|
||||
doc->GetDocumentURL(getter_AddRefs(documentURI));
|
||||
}
|
||||
doc->GetDocumentURL(getter_AddRefs(documentURI));
|
||||
|
||||
nsCOMPtr<imgIRequest> & req = mCurrentRequest ? mPendingRequest : mCurrentRequest;
|
||||
|
||||
|
@ -513,18 +503,17 @@ nsImageLoadingContent::StringToURI(const nsACString& aSpec,
|
|||
nsIDocument* aDocument,
|
||||
nsIURI** aURI)
|
||||
{
|
||||
// XXXbz Commented out precondition pending fix for bug 198486
|
||||
// NS_PRECONDITION(aDocument, "Must have a document");
|
||||
NS_PRECONDITION(aDocument, "Must have a document");
|
||||
NS_PRECONDITION(aURI, "Null out param");
|
||||
|
||||
nsresult rv = NS_OK;
|
||||
nsresult rv;
|
||||
|
||||
// (1) Get the base URI
|
||||
nsCOMPtr<nsIURI> baseURL;
|
||||
nsCOMPtr<nsIHTMLContent> thisContent = do_QueryInterface(this);
|
||||
if (thisContent) {
|
||||
rv = thisContent->GetBaseURL(*getter_AddRefs(baseURL));
|
||||
} else if (aDocument) {
|
||||
} else {
|
||||
rv = aDocument->GetBaseURL(*getter_AddRefs(baseURL));
|
||||
if (!baseURL) {
|
||||
rv = aDocument->GetDocumentURL(getter_AddRefs(baseURL));
|
||||
|
@ -534,9 +523,7 @@ nsImageLoadingContent::StringToURI(const nsACString& aSpec,
|
|||
|
||||
// (2) Get the charset
|
||||
nsAutoString charset;
|
||||
if (aDocument) {
|
||||
aDocument->GetDocumentCharacterSet(charset);
|
||||
}
|
||||
aDocument->GetDocumentCharacterSet(charset);
|
||||
|
||||
// (3) Construct the silly thing
|
||||
return NS_NewURI(aURI,
|
||||
|
@ -549,13 +536,22 @@ nsImageLoadingContent::StringToURI(const nsACString& aSpec,
|
|||
/**
|
||||
* Struct used to dispatch events
|
||||
*/
|
||||
MOZ_DECL_CTOR_COUNTER(ImageEvent)
|
||||
|
||||
struct ImageEvent : PLEvent {
|
||||
ImageEvent(nsIPresContext* aPresContext, nsIContent* aContent,
|
||||
const nsAString& aMessage)
|
||||
: mPresContext(aPresContext),
|
||||
mContent(aContent),
|
||||
mMessage(aMessage)
|
||||
{}
|
||||
{
|
||||
MOZ_COUNT_CTOR(ImageEvent);
|
||||
}
|
||||
~ImageEvent()
|
||||
{
|
||||
MOZ_COUNT_DTOR(ImageEvent);
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIPresContext> mPresContext;
|
||||
nsCOMPtr<nsIContent> mContent;
|
||||
nsString mMessage;
|
||||
|
@ -610,11 +606,6 @@ nsImageLoadingContent::FireEvent(const nsAString& aEventType)
|
|||
nsCOMPtr<nsIDocument> document;
|
||||
rv = GetOurDocument(getter_AddRefs(document));
|
||||
|
||||
if (!document) {
|
||||
// no use to fire events if there is no document....
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIPresShell> shell;
|
||||
document->GetShellAt(0, getter_AddRefs(shell));
|
||||
NS_ENSURE_TRUE(shell, NS_ERROR_FAILURE);
|
||||
|
|
|
@ -85,11 +85,19 @@ private:
|
|||
* Struct used to manage the image observers.
|
||||
*/
|
||||
struct ImageObserver {
|
||||
MOZ_DECL_CTOR_COUNTER(ImageObserver)
|
||||
|
||||
ImageObserver(imgIDecoderObserver* aObserver) :
|
||||
mObserver(aObserver),
|
||||
mNext(nsnull)
|
||||
{}
|
||||
~ImageObserver() { delete mNext; }
|
||||
{
|
||||
MOZ_COUNT_CTOR(ImageObserver);
|
||||
}
|
||||
~ImageObserver()
|
||||
{
|
||||
MOZ_COUNT_DTOR(ImageObserver);
|
||||
delete mNext;
|
||||
}
|
||||
|
||||
nsCOMPtr<imgIDecoderObserver> mObserver;
|
||||
ImageObserver* mNext;
|
||||
|
|
|
@ -971,7 +971,7 @@ nsresult nsRange::GetStartContainer(nsIDOMNode** aStartParent)
|
|||
return NS_ERROR_NOT_INITIALIZED;
|
||||
if (!aStartParent)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
//NS_IF_RELEASE(*aStartParent); don't think we should be doing this
|
||||
|
||||
*aStartParent = mStartParent;
|
||||
NS_IF_ADDREF(*aStartParent);
|
||||
return NS_OK;
|
||||
|
@ -2532,15 +2532,12 @@ nsRange::CreateContextualFragment(const nsAString& aFragment,
|
|||
nsCOMPtr<nsIParser> parser = do_CreateInstance(kCParserCID, &result);
|
||||
NS_ENSURE_SUCCESS(result, result);
|
||||
|
||||
nsCOMPtr<nsIContent> content = do_QueryInterface(mStartParent, &result);
|
||||
NS_ENSURE_SUCCESS(result, result);
|
||||
|
||||
nsCOMPtr<nsIDocument> document;
|
||||
nsCOMPtr<nsIDOMDocument> domDocument;
|
||||
|
||||
result = content->GetDocument(*getter_AddRefs(document));
|
||||
if (document && NS_SUCCEEDED(result)) {
|
||||
domDocument = do_QueryInterface(document, &result);
|
||||
result = mStartParent->GetOwnerDocument(getter_AddRefs(domDocument));
|
||||
if (domDocument && NS_SUCCEEDED(result)) {
|
||||
document = do_QueryInterface(domDocument, &result);
|
||||
}
|
||||
|
||||
nsVoidArray tagStack;
|
||||
|
@ -2577,6 +2574,7 @@ nsRange::CreateContextualFragment(const nsAString& aFragment,
|
|||
|
||||
result = NS_NewHTMLFragmentContentSink(getter_AddRefs(sink));
|
||||
if (NS_SUCCEEDED(result)) {
|
||||
sink->SetTargetDocument(document);
|
||||
parser->SetContentSink(sink);
|
||||
nsCOMPtr<nsIDOMNSDocument> domnsDocument(do_QueryInterface(document));
|
||||
if (domnsDocument) {
|
||||
|
@ -2631,9 +2629,7 @@ nsRange::CreateContextualFragment(const nsAString& aFragment,
|
|||
}
|
||||
|
||||
nsDTDMode mode = eDTDMode_autodetect;
|
||||
nsCOMPtr<nsIDOMDocument> ownerDoc;
|
||||
mStartParent->GetOwnerDocument(getter_AddRefs(ownerDoc));
|
||||
nsCOMPtr<nsIHTMLDocument> htmlDoc(do_QueryInterface(ownerDoc));
|
||||
nsCOMPtr<nsIHTMLDocument> htmlDoc(do_QueryInterface(domDocument));
|
||||
if (htmlDoc) {
|
||||
nsCompatibility compatMode;
|
||||
htmlDoc->GetCompatibilityMode(compatMode);
|
||||
|
|
|
@ -117,6 +117,7 @@ public:
|
|||
|
||||
// nsIHTMLFragmentContentSink
|
||||
NS_IMETHOD GetFragment(nsIDOMDocumentFragment** aFragment);
|
||||
NS_IMETHOD SetTargetDocument(nsIDocument* aDocument);
|
||||
|
||||
nsIContent* GetCurrentContent();
|
||||
PRInt32 PushContent(nsIContent *aContent);
|
||||
|
@ -167,31 +168,27 @@ public:
|
|||
nsresult
|
||||
NS_NewHTMLFragmentContentSink2(nsIHTMLFragmentContentSink** aResult)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aResult);
|
||||
NS_PRECONDITION(aResult, "Null out ptr");
|
||||
|
||||
nsCOMPtr<nsHTMLFragmentContentSink2> it;
|
||||
NS_NEWXPCOM(it, nsHTMLFragmentContentSink2);
|
||||
NS_ENSURE_TRUE(it, NS_ERROR_OUT_OF_MEMORY);
|
||||
*aResult = new nsHTMLFragmentContentSink2();
|
||||
NS_ENSURE_TRUE(*aResult, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
nsresult rv = it->Init();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
NS_ADDREF(*aResult);
|
||||
|
||||
return CallQueryInterface(it, aResult);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
NS_NewHTMLFragmentContentSink(nsIHTMLFragmentContentSink** aResult)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aResult);
|
||||
NS_PRECONDITION(aResult, "Null out ptr");
|
||||
|
||||
nsCOMPtr<nsHTMLFragmentContentSink> it;
|
||||
NS_NEWXPCOM(it, nsHTMLFragmentContentSink);
|
||||
NS_ENSURE_TRUE(it, NS_ERROR_OUT_OF_MEMORY);
|
||||
*aResult = new nsHTMLFragmentContentSink();
|
||||
NS_ENSURE_TRUE(*aResult, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
nsresult rv = it->Init();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
NS_ADDREF(*aResult);
|
||||
|
||||
return CallQueryInterface(it, aResult);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsHTMLFragmentContentSink::nsHTMLFragmentContentSink()
|
||||
|
@ -271,15 +268,6 @@ nsHTMLFragmentContentSink::QueryInterface(REFNSIID aIID, void** aInstancePtr)
|
|||
}
|
||||
|
||||
|
||||
nsresult nsHTMLFragmentContentSink::Init()
|
||||
{
|
||||
nsresult rv = NS_NewNodeInfoManager(getter_AddRefs(mNodeInfoManager));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return mNodeInfoManager->Init(nsnull);
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLFragmentContentSink::WillBuildModel(void)
|
||||
{
|
||||
|
@ -343,6 +331,8 @@ nsHTMLFragmentContentSink::EndContext(PRInt32 aID)
|
|||
NS_IMETHODIMP
|
||||
nsHTMLFragmentContentSink::SetTitle(const nsString& aValue)
|
||||
{
|
||||
NS_ENSURE_TRUE(mNodeInfoManager, NS_ERROR_NOT_INITIALIZED);
|
||||
|
||||
nsresult result=NS_OK;
|
||||
|
||||
nsCOMPtr<nsINodeInfo> nodeInfo;
|
||||
|
@ -481,6 +471,8 @@ static const char kSentinelStr[] = "endnote";
|
|||
NS_IMETHODIMP
|
||||
nsHTMLFragmentContentSink::OpenContainer(const nsIParserNode& aNode)
|
||||
{
|
||||
NS_ENSURE_TRUE(mNodeInfoManager, NS_ERROR_NOT_INITIALIZED);
|
||||
|
||||
nsAutoString tag;
|
||||
nsresult result = NS_OK;
|
||||
|
||||
|
@ -571,6 +563,8 @@ nsHTMLFragmentContentSink::AddHeadContent(const nsIParserNode& aNode)
|
|||
NS_IMETHODIMP
|
||||
nsHTMLFragmentContentSink::AddLeaf(const nsIParserNode& aNode)
|
||||
{
|
||||
NS_ENSURE_TRUE(mNodeInfoManager, NS_ERROR_NOT_INITIALIZED);
|
||||
|
||||
nsresult result = NS_OK;
|
||||
|
||||
switch (aNode.GetTokenType()) {
|
||||
|
@ -730,6 +724,28 @@ nsHTMLFragmentContentSink::GetFragment(nsIDOMDocumentFragment** aFragment)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLFragmentContentSink::SetTargetDocument(nsIDocument* aTargetDocument)
|
||||
{
|
||||
if (aTargetDocument) {
|
||||
aTargetDocument->GetNodeInfoManager(*getter_AddRefs(mNodeInfoManager));
|
||||
}
|
||||
|
||||
if (mNodeInfoManager) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult rv = NS_NewNodeInfoManager(getter_AddRefs(mNodeInfoManager));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = mNodeInfoManager->Init(nsnull);
|
||||
if (NS_FAILED(rv)) {
|
||||
mNodeInfoManager = nsnull;
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsIContent*
|
||||
nsHTMLFragmentContentSink::GetCurrentContent()
|
||||
{
|
||||
|
|
|
@ -2133,6 +2133,16 @@ nsresult nsHTMLEditor::CreateDOMFragmentFromPaste(nsIDOMNSRange *aNSRange,
|
|||
nsCOMPtr<nsIDOMDocumentFragment> docfrag;
|
||||
nsCOMPtr<nsIDOMNode> contextAsNode, tmp;
|
||||
nsresult res = NS_OK;
|
||||
|
||||
nsCOMPtr<nsIDOMElement> rootElement;
|
||||
GetRootElement(getter_AddRefs(rootElement));
|
||||
|
||||
nsCOMPtr<nsIDocument> doc;
|
||||
if (rootElement) {
|
||||
nsCOMPtr<nsIDOMDocument> domDoc;
|
||||
rootElement->GetOwnerDocument(getter_AddRefs(domDoc));
|
||||
doc = do_QueryInterface(domDoc);
|
||||
}
|
||||
|
||||
// if we have context info, create a fragment for that
|
||||
nsVoidArray tagStack;
|
||||
|
@ -2141,7 +2151,7 @@ nsresult nsHTMLEditor::CreateDOMFragmentFromPaste(nsIDOMNSRange *aNSRange,
|
|||
PRInt32 contextDepth = 0;
|
||||
if (aContextStr.Length())
|
||||
{
|
||||
res = ParseFragment(aContextStr, tagStack, address_of(contextAsNode));
|
||||
res = ParseFragment(aContextStr, tagStack, doc, address_of(contextAsNode));
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
NS_ENSURE_TRUE(contextAsNode, NS_ERROR_FAILURE);
|
||||
|
||||
|
@ -2168,7 +2178,7 @@ nsresult nsHTMLEditor::CreateDOMFragmentFromPaste(nsIDOMNSRange *aNSRange,
|
|||
return res;
|
||||
}
|
||||
// create fragment for pasted html
|
||||
res = ParseFragment(aInputString, tagStack, outFragNode);
|
||||
res = ParseFragment(aInputString, tagStack, doc, outFragNode);
|
||||
FreeTagStackStrings(tagStack);
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
NS_ENSURE_TRUE(*outFragNode, NS_ERROR_FAILURE);
|
||||
|
@ -2207,7 +2217,10 @@ nsresult nsHTMLEditor::CreateDOMFragmentFromPaste(nsIDOMNSRange *aNSRange,
|
|||
}
|
||||
|
||||
|
||||
nsresult nsHTMLEditor::ParseFragment(const nsAString & aFragStr, nsVoidArray &aTagStack, nsCOMPtr<nsIDOMNode> *outNode)
|
||||
nsresult nsHTMLEditor::ParseFragment(const nsAString & aFragStr,
|
||||
nsVoidArray &aTagStack,
|
||||
nsIDocument* aTargetDocument,
|
||||
nsCOMPtr<nsIDOMNode> *outNode)
|
||||
{
|
||||
// figure out if we are parsing full context or not
|
||||
PRBool bContext = (aTagStack.Count()==0);
|
||||
|
@ -2230,6 +2243,8 @@ nsresult nsHTMLEditor::ParseFragment(const nsAString & aFragStr, nsVoidArray &aT
|
|||
nsCOMPtr<nsIHTMLFragmentContentSink> fragSink(do_QueryInterface(sink));
|
||||
NS_ENSURE_TRUE(fragSink, NS_ERROR_FAILURE);
|
||||
|
||||
fragSink->SetTargetDocument(aTargetDocument);
|
||||
|
||||
// parse the fragment
|
||||
parser->SetContentSink(sink);
|
||||
if (bContext)
|
||||
|
|
|
@ -683,7 +683,9 @@ protected:
|
|||
nsCOMPtr<nsIDOMNode> *outFragNode,
|
||||
PRInt32 *outRangeStartHint,
|
||||
PRInt32 *outRangeEndHint);
|
||||
nsresult ParseFragment(const nsAString & aStr, nsVoidArray &aTagStack, nsCOMPtr<nsIDOMNode> *outNode);
|
||||
nsresult ParseFragment(const nsAString & aStr, nsVoidArray &aTagStack,
|
||||
nsIDocument* aTargetDoc,
|
||||
nsCOMPtr<nsIDOMNode> *outNode);
|
||||
nsresult CreateListOfNodesToPaste(nsIDOMNode *aFragmentAsNode,
|
||||
nsCOMArray<nsIDOMNode>& outNodeList,
|
||||
PRInt32 aRangeStartHint,
|
||||
|
|
|
@ -44,6 +44,7 @@
|
|||
#define NS_HTMLFRAGMENTSINK2_CONTRACTID "@mozilla.org/layout/htmlfragmentsink;2"
|
||||
|
||||
class nsIDOMDocumentFragment;
|
||||
class nsIDocument;
|
||||
|
||||
#define NS_IHTML_FRAGMENT_CONTENT_SINK_IID \
|
||||
{0xa6cf9102, 0x15b3, 0x11d2, \
|
||||
|
@ -58,6 +59,18 @@ public:
|
|||
*
|
||||
*/
|
||||
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.
|
||||
*
|
||||
* If aDocument is null or has no nodeinfo manager, the sink will
|
||||
* create a brand-new nodeinfo manager.
|
||||
*
|
||||
* @param aDocument the document the new nodes will belong to
|
||||
*/
|
||||
NS_IMETHOD SetTargetDocument(nsIDocument* aDocument) = 0;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -44,6 +44,7 @@
|
|||
#define NS_HTMLFRAGMENTSINK2_CONTRACTID "@mozilla.org/layout/htmlfragmentsink;2"
|
||||
|
||||
class nsIDOMDocumentFragment;
|
||||
class nsIDocument;
|
||||
|
||||
#define NS_IHTML_FRAGMENT_CONTENT_SINK_IID \
|
||||
{0xa6cf9102, 0x15b3, 0x11d2, \
|
||||
|
@ -58,6 +59,18 @@ public:
|
|||
*
|
||||
*/
|
||||
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.
|
||||
*
|
||||
* If aDocument is null or has no nodeinfo manager, the sink will
|
||||
* create a brand-new nodeinfo manager.
|
||||
*
|
||||
* @param aDocument the document the new nodes will belong to
|
||||
*/
|
||||
NS_IMETHOD SetTargetDocument(nsIDocument* aDocument) = 0;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
Загрузка…
Ссылка в новой задаче