|
|
|
@ -103,6 +103,8 @@
|
|
|
|
|
#include "nsInternetCiter.h"
|
|
|
|
|
#include "nsXPCOM.h"
|
|
|
|
|
#include "nsISupportsPrimitives.h"
|
|
|
|
|
#include "nsLinebreakConverter.h"
|
|
|
|
|
#include "nsIHTMLFragmentContentSink.h"
|
|
|
|
|
|
|
|
|
|
// netwerk
|
|
|
|
|
#include "nsIURI.h"
|
|
|
|
@ -123,6 +125,7 @@ const PRUnichar nbsp = 160;
|
|
|
|
|
|
|
|
|
|
static NS_DEFINE_CID(kCRangeCID, NS_RANGE_CID);
|
|
|
|
|
static NS_DEFINE_CID(kPrefServiceCID, NS_PREF_CID);
|
|
|
|
|
static NS_DEFINE_CID(kCParserCID, NS_PARSER_CID);
|
|
|
|
|
|
|
|
|
|
// Drag & Drop, Clipboard Support
|
|
|
|
|
static NS_DEFINE_CID(kCClipboardCID, NS_CLIPBOARD_CID);
|
|
|
|
@ -132,6 +135,10 @@ static NS_DEFINE_CID(kCHTMLFormatConverterCID, NS_HTMLFORMATCONVERTER_CID);
|
|
|
|
|
#define kHTMLContext "text/_moz_htmlcontext"
|
|
|
|
|
#define kHTMLInfo "text/_moz_htmlinfo"
|
|
|
|
|
|
|
|
|
|
// some little helpers
|
|
|
|
|
static PRInt32 FindPositiveIntegerAfterString(const char *aLeadingString, nsCString &aCStr);
|
|
|
|
|
static nsresult RemoveFragComments(nsCString &theStr);
|
|
|
|
|
static void RemoveBodyAndHead(nsIDOMNode *aNode);
|
|
|
|
|
|
|
|
|
|
#if defined(NS_DEBUG) && defined(DEBUG_buster)
|
|
|
|
|
static PRBool gNoisy = PR_FALSE;
|
|
|
|
@ -381,7 +388,7 @@ nsHTMLEditor::InsertHTMLWithCharsetAndContext(const nsAString & aInputString,
|
|
|
|
|
// this is because if there is a br at end of what we paste, it will make
|
|
|
|
|
// the invisible br visible.
|
|
|
|
|
nsWSRunObject wsObj(this, parentNode, offsetOfNewNode);
|
|
|
|
|
if ( nsTextEditUtils::IsBreak(wsObj.mEndReasonNode) &&
|
|
|
|
|
if (nsTextEditUtils::IsBreak(wsObj.mEndReasonNode) &&
|
|
|
|
|
!IsVisBreak(wsObj.mEndReasonNode) )
|
|
|
|
|
{
|
|
|
|
|
res = DeleteNode(wsObj.mEndReasonNode);
|
|
|
|
@ -758,31 +765,136 @@ nsHTMLEditor::StripFormattingNodes(nsIDOMNode *aNode, PRBool aListOnly)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
NS_IMETHODIMP nsHTMLEditor::PrepareTransferable(nsITransferable **transferable)
|
|
|
|
|
{
|
|
|
|
|
return NS_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
NS_IMETHODIMP nsHTMLEditor::PrepareHTMLTransferable(nsITransferable **aTransferable,
|
|
|
|
|
PRBool aHavePrivFlavor)
|
|
|
|
|
{
|
|
|
|
|
// Create generic Transferable for getting the data
|
|
|
|
|
nsresult rv = nsComponentManager::CreateInstance(kCTransferableCID, nsnull,
|
|
|
|
|
NS_GET_IID(nsITransferable),
|
|
|
|
|
(void**)transferable);
|
|
|
|
|
(void**)aTransferable);
|
|
|
|
|
if (NS_FAILED(rv))
|
|
|
|
|
return rv;
|
|
|
|
|
|
|
|
|
|
// Get the nsITransferable interface for getting the data from the clipboard
|
|
|
|
|
if (transferable)
|
|
|
|
|
if (aTransferable)
|
|
|
|
|
{
|
|
|
|
|
// Create the desired DataFlavor for the type of data
|
|
|
|
|
// we want to get out of the transferable
|
|
|
|
|
if ((mFlags & eEditorPlaintextMask) == 0) // This should only happen in html editors, not plaintext
|
|
|
|
|
{
|
|
|
|
|
(*transferable)->AddDataFlavor(kHTMLMime);
|
|
|
|
|
(*transferable)->AddDataFlavor(kFileMime);
|
|
|
|
|
if (!aHavePrivFlavor)
|
|
|
|
|
{
|
|
|
|
|
(*aTransferable)->AddDataFlavor(kNativeHTMLMime);
|
|
|
|
|
}
|
|
|
|
|
(*aTransferable)->AddDataFlavor(kHTMLMime);
|
|
|
|
|
(*aTransferable)->AddDataFlavor(kFileMime);
|
|
|
|
|
//(*transferable)->AddDataFlavor(kJPEGImageMime);
|
|
|
|
|
}
|
|
|
|
|
(*transferable)->AddDataFlavor(kUnicodeMime);
|
|
|
|
|
(*aTransferable)->AddDataFlavor(kUnicodeMime);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
PRInt32
|
|
|
|
|
FindPositiveIntegerAfterString(const char *aLeadingString, nsCString &aCStr)
|
|
|
|
|
{
|
|
|
|
|
// first obtain offsets from cfhtml str
|
|
|
|
|
PRInt32 numFront = aCStr.Find(aLeadingString);
|
|
|
|
|
if (numFront == -1)
|
|
|
|
|
return -1;
|
|
|
|
|
numFront += nsCRT::strlen(aLeadingString);
|
|
|
|
|
|
|
|
|
|
PRInt32 numBack = aCStr.FindCharInSet(CRLF, numFront);
|
|
|
|
|
if (numBack == -1)
|
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
|
|
nsCAutoString numStr(Substring(aCStr, numFront, numBack-numFront));
|
|
|
|
|
PRInt32 errorCode;
|
|
|
|
|
return numStr.ToInteger(&errorCode);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
|
RemoveFragComments(nsCString & aStr)
|
|
|
|
|
{
|
|
|
|
|
// remove the StartFragment/EndFragment comments from the str, if present
|
|
|
|
|
PRInt32 startCommentIndx = aStr.Find("<!--StartFragment");
|
|
|
|
|
if (startCommentIndx >= 0)
|
|
|
|
|
{
|
|
|
|
|
PRInt32 startCommentEnd = aStr.Find("-->", PR_FALSE, startCommentIndx);
|
|
|
|
|
if (startCommentEnd > startCommentIndx)
|
|
|
|
|
aStr.Cut(startCommentIndx, (startCommentEnd+3)-startCommentIndx);
|
|
|
|
|
}
|
|
|
|
|
PRInt32 endCommentIndx = aStr.Find("<!--EndFragment");
|
|
|
|
|
if (endCommentIndx >= 0)
|
|
|
|
|
{
|
|
|
|
|
PRInt32 endCommentEnd = aStr.Find("-->", PR_FALSE, endCommentIndx);
|
|
|
|
|
if (endCommentEnd > endCommentIndx)
|
|
|
|
|
aStr.Cut(endCommentIndx, (endCommentEnd+3)-endCommentIndx);
|
|
|
|
|
}
|
|
|
|
|
return NS_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
|
nsHTMLEditor::ParseCFHTML(nsCString & aCfhtml, PRUnichar **aStuffToPaste, PRUnichar **aCfcontext)
|
|
|
|
|
{
|
|
|
|
|
// first obtain offsets from cfhtml str
|
|
|
|
|
PRInt32 startHTML = FindPositiveIntegerAfterString("StartHTML:", aCfhtml);
|
|
|
|
|
PRInt32 endHTML = FindPositiveIntegerAfterString("EndHTML:", aCfhtml);
|
|
|
|
|
PRInt32 startFragment = FindPositiveIntegerAfterString("StartFragment:", aCfhtml);
|
|
|
|
|
PRInt32 endFragment = FindPositiveIntegerAfterString("EndFragment:", aCfhtml);
|
|
|
|
|
|
|
|
|
|
if ((startHTML<0) || (endHTML<0) || (startFragment<0) || (endFragment<0))
|
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
|
|
|
|
|
|
// create context string
|
|
|
|
|
nsCAutoString contextUTF8(Substring(aCfhtml, startHTML, startFragment - startHTML) +
|
|
|
|
|
Substring(aCfhtml, endFragment, endHTML - endFragment));
|
|
|
|
|
|
|
|
|
|
// create fragment string
|
|
|
|
|
nsCAutoString fragmentUTF8(Substring(aCfhtml, startFragment, endFragment-startFragment));
|
|
|
|
|
|
|
|
|
|
// remove the StartFragment/EndFragment comments from the fragment, if present
|
|
|
|
|
RemoveFragComments(fragmentUTF8);
|
|
|
|
|
|
|
|
|
|
// remove the StartFragment/EndFragment comments from the context, if present
|
|
|
|
|
RemoveFragComments(contextUTF8);
|
|
|
|
|
|
|
|
|
|
// convert both strings to usc2
|
|
|
|
|
const nsAFlatString& fragUcs2Str = NS_ConvertUTF8toUCS2(fragmentUTF8);
|
|
|
|
|
const nsAFlatString& cntxtUcs2Str = NS_ConvertUTF8toUCS2(contextUTF8);
|
|
|
|
|
|
|
|
|
|
// translate platform linebreaks for fragment
|
|
|
|
|
PRUnichar* newStr = 0;
|
|
|
|
|
PRInt32 oldLengthInChars = fragUcs2Str.Length() + 1; // +1 to include null terminator
|
|
|
|
|
PRInt32 newLengthInChars = 0;
|
|
|
|
|
*aStuffToPaste = nsLinebreakConverter::ConvertUnicharLineBreaks(fragUcs2Str.get(),
|
|
|
|
|
nsLinebreakConverter::eLinebreakAny,
|
|
|
|
|
nsLinebreakConverter::eLinebreakContent,
|
|
|
|
|
oldLengthInChars, &newLengthInChars);
|
|
|
|
|
if (!aStuffToPaste)
|
|
|
|
|
{
|
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// translate platform linebreaks for context
|
|
|
|
|
newStr = 0;
|
|
|
|
|
oldLengthInChars = cntxtUcs2Str.Length(); // +1 to include null terminator
|
|
|
|
|
newLengthInChars = 0;
|
|
|
|
|
*aCfcontext = nsLinebreakConverter::ConvertUnicharLineBreaks(cntxtUcs2Str.get(),
|
|
|
|
|
nsLinebreakConverter::eLinebreakAny,
|
|
|
|
|
nsLinebreakConverter::eLinebreakContent,
|
|
|
|
|
oldLengthInChars, &newLengthInChars);
|
|
|
|
|
// it's ok for context to be empty. frag might be whole doc and contain all it's context.
|
|
|
|
|
|
|
|
|
|
// we're done!
|
|
|
|
|
return NS_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
NS_IMETHODIMP nsHTMLEditor::InsertFromTransferable(nsITransferable *transferable,
|
|
|
|
|
const nsAString & aContextStr,
|
|
|
|
|
const nsAString & aInfoStr)
|
|
|
|
@ -795,41 +907,59 @@ NS_IMETHODIMP nsHTMLEditor::InsertFromTransferable(nsITransferable *transferable
|
|
|
|
|
{
|
|
|
|
|
nsAutoTxnsConserveSelection dontSpazMySelection(this);
|
|
|
|
|
nsAutoString flavor, stuffToPaste;
|
|
|
|
|
flavor.AssignWithConversion( bestFlavor ); // just so we can use flavor.Equals()
|
|
|
|
|
flavor.AssignWithConversion(bestFlavor); // just so we can use flavor.Equals()
|
|
|
|
|
#ifdef DEBUG_clipboard
|
|
|
|
|
printf("Got flavor [%s]\n", bestFlavor);
|
|
|
|
|
#endif
|
|
|
|
|
if (flavor.Equals(NS_LITERAL_STRING(kHTMLMime)))
|
|
|
|
|
|
|
|
|
|
if (flavor.Equals(NS_LITERAL_STRING(kNativeHTMLMime)))
|
|
|
|
|
{
|
|
|
|
|
nsCOMPtr<nsISupportsString> textDataObj ( do_QueryInterface(genericDataObj) );
|
|
|
|
|
// note cf_html uses utf8, hence use length = len, not len/2 as in flavors below
|
|
|
|
|
nsCOMPtr<nsISupportsCString> textDataObj(do_QueryInterface(genericDataObj));
|
|
|
|
|
if (textDataObj && len > 0)
|
|
|
|
|
{
|
|
|
|
|
nsCAutoString cfhtml;
|
|
|
|
|
textDataObj->GetData(cfhtml);
|
|
|
|
|
NS_ASSERTION(cfhtml.Length() <= (len), "Invalid length!");
|
|
|
|
|
nsXPIDLString cfcontext, cffragment, cfselection; // cfselection left emtpy for now
|
|
|
|
|
|
|
|
|
|
rv = ParseCFHTML(cfhtml, getter_Copies(cffragment), getter_Copies(cfcontext));
|
|
|
|
|
if (NS_SUCCEEDED(rv) && !cffragment.IsEmpty())
|
|
|
|
|
{
|
|
|
|
|
nsAutoEditBatch beginBatching(this);
|
|
|
|
|
rv = InsertHTMLWithContext(cffragment, cfcontext, cfselection);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (flavor.Equals(NS_LITERAL_STRING(kHTMLMime)))
|
|
|
|
|
{
|
|
|
|
|
nsCOMPtr<nsISupportsString> textDataObj(do_QueryInterface(genericDataObj));
|
|
|
|
|
if (textDataObj && len > 0)
|
|
|
|
|
{
|
|
|
|
|
nsAutoString text;
|
|
|
|
|
|
|
|
|
|
textDataObj->GetData ( text );
|
|
|
|
|
|
|
|
|
|
textDataObj->GetData(text);
|
|
|
|
|
NS_ASSERTION(text.Length() <= (len/2), "Invalid length!");
|
|
|
|
|
stuffToPaste.Assign ( text.get(), len / 2 );
|
|
|
|
|
stuffToPaste.Assign(text.get(), len / 2);
|
|
|
|
|
nsAutoEditBatch beginBatching(this);
|
|
|
|
|
rv = InsertHTMLWithContext(stuffToPaste, aContextStr, aInfoStr);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (flavor.Equals(NS_LITERAL_STRING(kUnicodeMime)))
|
|
|
|
|
{
|
|
|
|
|
nsCOMPtr<nsISupportsString> textDataObj ( do_QueryInterface(genericDataObj) );
|
|
|
|
|
nsCOMPtr<nsISupportsString> textDataObj(do_QueryInterface(genericDataObj));
|
|
|
|
|
if (textDataObj && len > 0)
|
|
|
|
|
{
|
|
|
|
|
nsAutoString text;
|
|
|
|
|
textDataObj->GetData ( text );
|
|
|
|
|
textDataObj->GetData(text);
|
|
|
|
|
NS_ASSERTION(text.Length() <= (len/2), "Invalid length!");
|
|
|
|
|
stuffToPaste.Assign ( text.get(), len / 2 );
|
|
|
|
|
stuffToPaste.Assign(text.get(), len / 2);
|
|
|
|
|
nsAutoEditBatch beginBatching(this);
|
|
|
|
|
rv = InsertText(stuffToPaste);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (flavor.Equals(NS_LITERAL_STRING(kFileMime)))
|
|
|
|
|
{
|
|
|
|
|
nsCOMPtr<nsIFile> fileObj ( do_QueryInterface(genericDataObj) );
|
|
|
|
|
nsCOMPtr<nsIFile> fileObj(do_QueryInterface(genericDataObj));
|
|
|
|
|
if (fileObj && len > 0)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
@ -839,27 +969,27 @@ NS_IMETHODIMP nsHTMLEditor::InsertFromTransferable(nsITransferable *transferable
|
|
|
|
|
return rv;
|
|
|
|
|
|
|
|
|
|
nsCOMPtr<nsIURL> fileURL(do_QueryInterface(uri));
|
|
|
|
|
if ( fileURL )
|
|
|
|
|
if (fileURL)
|
|
|
|
|
{
|
|
|
|
|
PRBool insertAsImage = PR_FALSE;
|
|
|
|
|
nsCAutoString fileextension;
|
|
|
|
|
rv = fileURL->GetFileExtension( fileextension );
|
|
|
|
|
if ( NS_SUCCEEDED(rv) && !fileextension.IsEmpty() )
|
|
|
|
|
rv = fileURL->GetFileExtension(fileextension);
|
|
|
|
|
if (NS_SUCCEEDED(rv) && !fileextension.IsEmpty())
|
|
|
|
|
{
|
|
|
|
|
if ( (nsCRT::strcasecmp( fileextension.get(), "jpg" ) == 0 )
|
|
|
|
|
|| (nsCRT::strcasecmp( fileextension.get(), "jpeg" ) == 0 )
|
|
|
|
|
|| (nsCRT::strcasecmp( fileextension.get(), "gif" ) == 0 )
|
|
|
|
|
|| (nsCRT::strcasecmp( fileextension.get(), "png" ) == 0 ) )
|
|
|
|
|
if ( (nsCRT::strcasecmp(fileextension.get(), "jpg") == 0 )
|
|
|
|
|
|| (nsCRT::strcasecmp(fileextension.get(), "jpeg") == 0 )
|
|
|
|
|
|| (nsCRT::strcasecmp(fileextension.get(), "gif") == 0 )
|
|
|
|
|
|| (nsCRT::strcasecmp(fileextension.get(), "png") == 0 ) )
|
|
|
|
|
{
|
|
|
|
|
insertAsImage = PR_TRUE;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
nsCAutoString urltext;
|
|
|
|
|
rv = fileURL->GetSpec( urltext );
|
|
|
|
|
if ( NS_SUCCEEDED(rv) && !urltext.IsEmpty() )
|
|
|
|
|
rv = fileURL->GetSpec(urltext);
|
|
|
|
|
if (NS_SUCCEEDED(rv) && !urltext.IsEmpty())
|
|
|
|
|
{
|
|
|
|
|
if ( insertAsImage )
|
|
|
|
|
if (insertAsImage)
|
|
|
|
|
{
|
|
|
|
|
stuffToPaste.Assign(NS_LITERAL_STRING("<IMG src=\""));
|
|
|
|
|
stuffToPaste.Append(NS_ConvertUTF8toUCS2(urltext));
|
|
|
|
@ -910,9 +1040,15 @@ NS_IMETHODIMP nsHTMLEditor::InsertFromDrop(nsIDOMEvent* aDropEvent)
|
|
|
|
|
dragService->GetCurrentSession(getter_AddRefs(dragSession));
|
|
|
|
|
if (!dragSession) return NS_OK;
|
|
|
|
|
|
|
|
|
|
// find out if we have our internal html flavor on the clipboard. We don't want to mess
|
|
|
|
|
// around with cfhtml if we do.
|
|
|
|
|
PRBool bHavePrivateHTMLFlavor = PR_FALSE;
|
|
|
|
|
rv = dragSession->IsDataFlavorSupported(kHTMLContext, &bHavePrivateHTMLFlavor);
|
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
|
|
// Get the nsITransferable interface for getting the data from the drop
|
|
|
|
|
nsCOMPtr<nsITransferable> trans;
|
|
|
|
|
rv = PrepareTransferable(getter_AddRefs(trans));
|
|
|
|
|
rv = PrepareHTMLTransferable(getter_AddRefs(trans), bHavePrivateHTMLFlavor);
|
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
if (!trans) return NS_OK; // NS_ERROR_FAILURE; SHOULD WE FAIL?
|
|
|
|
|
|
|
|
|
@ -953,30 +1089,30 @@ NS_IMETHODIMP nsHTMLEditor::InsertFromDrop(nsIDOMEvent* aDropEvent)
|
|
|
|
|
{
|
|
|
|
|
nsAutoString text;
|
|
|
|
|
textDataObj = do_QueryInterface(contextDataObj);
|
|
|
|
|
textDataObj->GetData ( text );
|
|
|
|
|
textDataObj->GetData(text);
|
|
|
|
|
NS_ASSERTION(text.Length() <= (contextLen/2), "Invalid length!");
|
|
|
|
|
contextStr.Assign ( text.get(), contextLen / 2 );
|
|
|
|
|
contextStr.Assign(text.get(), contextLen / 2);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (infoDataObj)
|
|
|
|
|
{
|
|
|
|
|
nsAutoString text;
|
|
|
|
|
textDataObj = do_QueryInterface(infoDataObj);
|
|
|
|
|
textDataObj->GetData ( text );
|
|
|
|
|
textDataObj->GetData(text);
|
|
|
|
|
NS_ASSERTION(text.Length() <= (infoLen/2), "Invalid length!");
|
|
|
|
|
infoStr.Assign ( text.get(), infoLen / 2 );
|
|
|
|
|
infoStr.Assign(text.get(), infoLen / 2);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ( doPlaceCaret )
|
|
|
|
|
if (doPlaceCaret)
|
|
|
|
|
{
|
|
|
|
|
// check if the user pressed the key to force a copy rather than a move
|
|
|
|
|
// if we run into problems here, we'll just assume the user doesn't want a copy
|
|
|
|
|
PRBool userWantsCopy = PR_FALSE;
|
|
|
|
|
|
|
|
|
|
nsCOMPtr<nsIDOMNSUIEvent> nsuiEvent (do_QueryInterface(aDropEvent));
|
|
|
|
|
nsCOMPtr<nsIDOMNSUIEvent> nsuiEvent(do_QueryInterface(aDropEvent));
|
|
|
|
|
if (!nsuiEvent) return NS_ERROR_FAILURE;
|
|
|
|
|
|
|
|
|
|
nsCOMPtr<nsIDOMMouseEvent> mouseEvent ( do_QueryInterface(aDropEvent) );
|
|
|
|
|
nsCOMPtr<nsIDOMMouseEvent> mouseEvent(do_QueryInterface(aDropEvent));
|
|
|
|
|
if (mouseEvent)
|
|
|
|
|
|
|
|
|
|
#ifdef XP_MAC
|
|
|
|
@ -1141,24 +1277,26 @@ NS_IMETHODIMP nsHTMLEditor::CanDrag(nsIDOMEvent *aDragEvent, PRBool *aCanDrag)
|
|
|
|
|
if (NS_FAILED(res)) return res;
|
|
|
|
|
|
|
|
|
|
// if we are collapsed, we have no selection so nothing to drag
|
|
|
|
|
if ( isCollapsed )
|
|
|
|
|
if (isCollapsed)
|
|
|
|
|
return NS_OK;
|
|
|
|
|
|
|
|
|
|
nsCOMPtr<nsIDOMEventTarget> eventTarget;
|
|
|
|
|
|
|
|
|
|
nsCOMPtr<nsIDOMNSEvent> nsevent(do_QueryInterface(aDragEvent));
|
|
|
|
|
|
|
|
|
|
if (nsevent) {
|
|
|
|
|
if (nsevent)
|
|
|
|
|
{
|
|
|
|
|
res = nsevent->GetOriginalTarget(getter_AddRefs(eventTarget));
|
|
|
|
|
if (NS_FAILED(res)) {
|
|
|
|
|
if (NS_FAILED(res))
|
|
|
|
|
{
|
|
|
|
|
return res;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ( eventTarget )
|
|
|
|
|
if (eventTarget)
|
|
|
|
|
{
|
|
|
|
|
nsCOMPtr<nsIDOMNode> eventTargetDomNode = do_QueryInterface(eventTarget);
|
|
|
|
|
if ( eventTargetDomNode )
|
|
|
|
|
if (eventTargetDomNode)
|
|
|
|
|
{
|
|
|
|
|
PRBool isTargetedCorrectly = PR_FALSE;
|
|
|
|
|
res = selection->ContainsNode(eventTargetDomNode, PR_FALSE, &isTargetedCorrectly);
|
|
|
|
@ -1252,7 +1390,7 @@ NS_IMETHODIMP nsHTMLEditor::DoDrag(nsIDOMEvent *aDragEvent)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// if we have an empty string, we're done; otherwise continue
|
|
|
|
|
if ( !buffer.IsEmpty() )
|
|
|
|
|
if (!buffer.IsEmpty())
|
|
|
|
|
{
|
|
|
|
|
nsCOMPtr<nsISupportsString> dataWrapper, contextWrapper, infoWrapper;
|
|
|
|
|
|
|
|
|
@ -1269,7 +1407,7 @@ NS_IMETHODIMP nsHTMLEditor::DoDrag(nsIDOMEvent *aDragEvent)
|
|
|
|
|
|
|
|
|
|
// QI the data object an |nsISupports| so that when the transferable holds
|
|
|
|
|
// onto it, it will addref the correct interface.
|
|
|
|
|
nsCOMPtr<nsISupports> genericDataObj ( do_QueryInterface(dataWrapper) );
|
|
|
|
|
nsCOMPtr<nsISupports> genericDataObj(do_QueryInterface(dataWrapper));
|
|
|
|
|
rv = trans->SetTransferData(kUnicodeMime, genericDataObj, buffer.Length() * 2);
|
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
}
|
|
|
|
@ -1280,8 +1418,8 @@ NS_IMETHODIMP nsHTMLEditor::DoDrag(nsIDOMEvent *aDragEvent)
|
|
|
|
|
infoWrapper = do_CreateInstance(NS_SUPPORTS_STRING_CONTRACTID);
|
|
|
|
|
NS_ENSURE_TRUE(infoWrapper, NS_ERROR_FAILURE);
|
|
|
|
|
|
|
|
|
|
contextWrapper->SetData ( parents );
|
|
|
|
|
infoWrapper->SetData ( info );
|
|
|
|
|
contextWrapper->SetData(parents);
|
|
|
|
|
infoWrapper->SetData(info);
|
|
|
|
|
|
|
|
|
|
rv = trans->AddDataFlavor(kHTMLMime);
|
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
@ -1292,7 +1430,7 @@ NS_IMETHODIMP nsHTMLEditor::DoDrag(nsIDOMEvent *aDragEvent)
|
|
|
|
|
rv = trans->SetConverter(htmlConverter);
|
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
|
|
nsCOMPtr<nsISupports> genericDataObj ( do_QueryInterface(dataWrapper) );
|
|
|
|
|
nsCOMPtr<nsISupports> genericDataObj(do_QueryInterface(dataWrapper));
|
|
|
|
|
rv = trans->SetTransferData(kHTMLMime, genericDataObj, buffer.Length() * 2);
|
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
|
@ -1321,12 +1459,13 @@ NS_IMETHODIMP nsHTMLEditor::DoDrag(nsIDOMEvent *aDragEvent)
|
|
|
|
|
// in some cases we'll want to cut rather than copy... hmmmmm...
|
|
|
|
|
flags = nsIDragService::DRAGDROP_ACTION_COPY + nsIDragService::DRAGDROP_ACTION_MOVE;
|
|
|
|
|
|
|
|
|
|
rv = dragService->InvokeDragSession( domnode, transferableArray, nsnull, flags);
|
|
|
|
|
rv = dragService->InvokeDragSession(domnode, transferableArray, nsnull, flags);
|
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
|
|
nsCOMPtr<nsIDOMNSEvent> nsevent(do_QueryInterface(aDragEvent));
|
|
|
|
|
|
|
|
|
|
if (nsevent) {
|
|
|
|
|
if (nsevent)
|
|
|
|
|
{
|
|
|
|
|
nsevent->PreventBubble();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -1335,19 +1474,50 @@ NS_IMETHODIMP nsHTMLEditor::DoDrag(nsIDOMEvent *aDragEvent)
|
|
|
|
|
return rv;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
PRBool nsHTMLEditor::HavePrivateHTMLFlavor(nsIClipboard *aClipboard)
|
|
|
|
|
{
|
|
|
|
|
// check the clipboard for our special kHTMLContext flavor. If that is there, we know
|
|
|
|
|
// we have our own internal html format on clipboard.
|
|
|
|
|
|
|
|
|
|
if (!aClipboard) return PR_FALSE;
|
|
|
|
|
PRBool bHavePrivateHTMLFlavor = PR_FALSE;
|
|
|
|
|
nsCOMPtr<nsISupportsArray> flavArray;
|
|
|
|
|
|
|
|
|
|
nsresult res = NS_NewISupportsArray(getter_AddRefs(flavArray));
|
|
|
|
|
if (NS_FAILED(res)) return PR_FALSE;
|
|
|
|
|
|
|
|
|
|
nsCOMPtr<nsISupportsCString> contextString = do_CreateInstance(NS_SUPPORTS_CSTRING_CONTRACTID);
|
|
|
|
|
if (!contextString) return PR_FALSE;
|
|
|
|
|
|
|
|
|
|
contextString->SetData(NS_LITERAL_CSTRING(kHTMLContext));
|
|
|
|
|
|
|
|
|
|
flavArray->AppendElement(contextString);
|
|
|
|
|
|
|
|
|
|
if (NS_SUCCEEDED(aClipboard->HasDataMatchingFlavors (flavArray, nsIClipboard::kGlobalClipboard, &bHavePrivateHTMLFlavor )))
|
|
|
|
|
return bHavePrivateHTMLFlavor;
|
|
|
|
|
|
|
|
|
|
return PR_FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
NS_IMETHODIMP nsHTMLEditor::Paste(PRInt32 aSelectionType)
|
|
|
|
|
{
|
|
|
|
|
ForceCompositionEnd();
|
|
|
|
|
|
|
|
|
|
// Get Clipboard Service
|
|
|
|
|
nsresult rv;
|
|
|
|
|
nsCOMPtr<nsIClipboard> clipboard( do_GetService( kCClipboardCID, &rv ) );
|
|
|
|
|
if ( NS_FAILED(rv) )
|
|
|
|
|
nsCOMPtr<nsIClipboard> clipboard(do_GetService(kCClipboardCID, &rv));
|
|
|
|
|
if (NS_FAILED(rv))
|
|
|
|
|
return rv;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// find out if we have our internal html flavor on the clipboard. We don't want to mess
|
|
|
|
|
// around with cfhtml if we do.
|
|
|
|
|
PRBool bHavePrivateHTMLFlavor = HavePrivateHTMLFlavor(clipboard);
|
|
|
|
|
|
|
|
|
|
// Get the nsITransferable interface for getting the data from the clipboard
|
|
|
|
|
nsCOMPtr<nsITransferable> trans;
|
|
|
|
|
rv = PrepareTransferable(getter_AddRefs(trans));
|
|
|
|
|
rv = PrepareHTMLTransferable(getter_AddRefs(trans), bHavePrivateHTMLFlavor);
|
|
|
|
|
if (NS_SUCCEEDED(rv) && trans)
|
|
|
|
|
{
|
|
|
|
|
// Get the Data from the clipboard
|
|
|
|
@ -1355,38 +1525,43 @@ NS_IMETHODIMP nsHTMLEditor::Paste(PRInt32 aSelectionType)
|
|
|
|
|
{
|
|
|
|
|
// also get additional html copy hints, if present
|
|
|
|
|
nsAutoString contextStr, infoStr;
|
|
|
|
|
nsCOMPtr<nsISupports> contextDataObj, infoDataObj;
|
|
|
|
|
PRUint32 contextLen, infoLen;
|
|
|
|
|
nsCOMPtr<nsISupportsString> textDataObj;
|
|
|
|
|
|
|
|
|
|
nsCOMPtr<nsITransferable> contextTrans = do_CreateInstance(kCTransferableCID);
|
|
|
|
|
NS_ENSURE_TRUE(contextTrans, NS_ERROR_NULL_POINTER);
|
|
|
|
|
contextTrans->AddDataFlavor(kHTMLContext);
|
|
|
|
|
clipboard->GetData(contextTrans, aSelectionType);
|
|
|
|
|
contextTrans->GetTransferData(kHTMLContext, getter_AddRefs(contextDataObj), &contextLen);
|
|
|
|
|
|
|
|
|
|
nsCOMPtr<nsITransferable> infoTrans = do_CreateInstance(kCTransferableCID);
|
|
|
|
|
NS_ENSURE_TRUE(infoTrans, NS_ERROR_NULL_POINTER);
|
|
|
|
|
infoTrans->AddDataFlavor(kHTMLInfo);
|
|
|
|
|
clipboard->GetData(infoTrans, aSelectionType);
|
|
|
|
|
infoTrans->GetTransferData(kHTMLInfo, getter_AddRefs(infoDataObj), &infoLen);
|
|
|
|
|
|
|
|
|
|
if (contextDataObj)
|
|
|
|
|
// also get additional html copy hints, if present
|
|
|
|
|
if (bHavePrivateHTMLFlavor)
|
|
|
|
|
{
|
|
|
|
|
nsAutoString text;
|
|
|
|
|
textDataObj = do_QueryInterface(contextDataObj);
|
|
|
|
|
textDataObj->GetData ( text );
|
|
|
|
|
NS_ASSERTION(text.Length() <= (contextLen/2), "Invalid length!");
|
|
|
|
|
contextStr.Assign ( text.get(), contextLen / 2 );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (infoDataObj)
|
|
|
|
|
{
|
|
|
|
|
nsAutoString text;
|
|
|
|
|
textDataObj = do_QueryInterface(infoDataObj);
|
|
|
|
|
textDataObj->GetData ( text );
|
|
|
|
|
NS_ASSERTION(text.Length() <= (infoLen/2), "Invalid length!");
|
|
|
|
|
infoStr.Assign ( text.get(), infoLen / 2 );
|
|
|
|
|
nsCOMPtr<nsISupports> contextDataObj, infoDataObj;
|
|
|
|
|
PRUint32 contextLen, infoLen;
|
|
|
|
|
nsCOMPtr<nsISupportsString> textDataObj;
|
|
|
|
|
|
|
|
|
|
nsCOMPtr<nsITransferable> contextTrans = do_CreateInstance(kCTransferableCID);
|
|
|
|
|
NS_ENSURE_TRUE(contextTrans, NS_ERROR_NULL_POINTER);
|
|
|
|
|
contextTrans->AddDataFlavor(kHTMLContext);
|
|
|
|
|
clipboard->GetData(contextTrans, aSelectionType);
|
|
|
|
|
contextTrans->GetTransferData(kHTMLContext, getter_AddRefs(contextDataObj), &contextLen);
|
|
|
|
|
|
|
|
|
|
nsCOMPtr<nsITransferable> infoTrans = do_CreateInstance(kCTransferableCID);
|
|
|
|
|
NS_ENSURE_TRUE(infoTrans, NS_ERROR_NULL_POINTER);
|
|
|
|
|
infoTrans->AddDataFlavor(kHTMLInfo);
|
|
|
|
|
clipboard->GetData(infoTrans, aSelectionType);
|
|
|
|
|
infoTrans->GetTransferData(kHTMLInfo, getter_AddRefs(infoDataObj), &infoLen);
|
|
|
|
|
|
|
|
|
|
if (contextDataObj)
|
|
|
|
|
{
|
|
|
|
|
nsAutoString text;
|
|
|
|
|
textDataObj = do_QueryInterface(contextDataObj);
|
|
|
|
|
textDataObj->GetData(text);
|
|
|
|
|
NS_ASSERTION(text.Length() <= (contextLen/2), "Invalid length!");
|
|
|
|
|
contextStr.Assign(text.get(), contextLen / 2);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (infoDataObj)
|
|
|
|
|
{
|
|
|
|
|
nsAutoString text;
|
|
|
|
|
textDataObj = do_QueryInterface(infoDataObj);
|
|
|
|
|
textDataObj->GetData(text);
|
|
|
|
|
NS_ASSERTION(text.Length() <= (infoLen/2), "Invalid length!");
|
|
|
|
|
infoStr.Assign(text.get(), infoLen / 2);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
rv = InsertFromTransferable(trans, contextStr, infoStr);
|
|
|
|
|
}
|
|
|
|
@ -1404,8 +1579,8 @@ NS_IMETHODIMP nsHTMLEditor::PasteNoFormatting(PRInt32 aSelectionType)
|
|
|
|
|
|
|
|
|
|
// Get Clipboard Service
|
|
|
|
|
nsresult rv;
|
|
|
|
|
nsCOMPtr<nsIClipboard> clipboard( do_GetService( kCClipboardCID, &rv ) );
|
|
|
|
|
if ( NS_FAILED(rv) )
|
|
|
|
|
nsCOMPtr<nsIClipboard> clipboard(do_GetService(kCClipboardCID, &rv));
|
|
|
|
|
if (NS_FAILED(rv))
|
|
|
|
|
return rv;
|
|
|
|
|
|
|
|
|
|
// Get the nsITransferable interface for getting the data from the clipboard.
|
|
|
|
@ -1454,9 +1629,7 @@ NS_IMETHODIMP nsHTMLEditor::CanPaste(PRInt32 aSelectionType, PRBool *aCanPaste)
|
|
|
|
|
// add the flavors for all editors
|
|
|
|
|
for (const char* const* flavor = textEditorFlavors; *flavor; flavor++)
|
|
|
|
|
{
|
|
|
|
|
nsCOMPtr<nsISupportsCString> flavorString;
|
|
|
|
|
nsComponentManager::CreateInstance(NS_SUPPORTS_CSTRING_CONTRACTID, nsnull,
|
|
|
|
|
NS_GET_IID(nsISupportsCString), getter_AddRefs(flavorString));
|
|
|
|
|
nsCOMPtr<nsISupportsCString> flavorString = do_CreateInstance(NS_SUPPORTS_CSTRING_CONTRACTID);
|
|
|
|
|
if (flavorString)
|
|
|
|
|
{
|
|
|
|
|
flavorString->SetData(nsDependentCString(*flavor));
|
|
|
|
@ -1471,9 +1644,7 @@ NS_IMETHODIMP nsHTMLEditor::CanPaste(PRInt32 aSelectionType, PRBool *aCanPaste)
|
|
|
|
|
*htmlFlavor;
|
|
|
|
|
htmlFlavor++)
|
|
|
|
|
{
|
|
|
|
|
nsCOMPtr<nsISupportsCString> flavorString;
|
|
|
|
|
nsComponentManager::CreateInstance(NS_SUPPORTS_CSTRING_CONTRACTID, nsnull,
|
|
|
|
|
NS_GET_IID(nsISupportsCString), getter_AddRefs(flavorString));
|
|
|
|
|
nsCOMPtr<nsISupportsCString> flavorString = do_CreateInstance(NS_SUPPORTS_CSTRING_CONTRACTID);
|
|
|
|
|
if (flavorString)
|
|
|
|
|
{
|
|
|
|
|
flavorString->SetData(nsDependentCString(*htmlFlavor));
|
|
|
|
@ -1595,13 +1766,13 @@ NS_IMETHODIMP nsHTMLEditor::PasteAsPlaintextQuotation(PRInt32 aSelectionType)
|
|
|
|
|
nsAutoString stuffToPaste;
|
|
|
|
|
if (flavor.Equals(NS_LITERAL_STRING(kUnicodeMime)))
|
|
|
|
|
{
|
|
|
|
|
nsCOMPtr<nsISupportsString> textDataObj ( do_QueryInterface(genericDataObj) );
|
|
|
|
|
nsCOMPtr<nsISupportsString> textDataObj(do_QueryInterface(genericDataObj));
|
|
|
|
|
if (textDataObj && len > 0)
|
|
|
|
|
{
|
|
|
|
|
nsAutoString text;
|
|
|
|
|
textDataObj->GetData ( text );
|
|
|
|
|
textDataObj->GetData(text);
|
|
|
|
|
NS_ASSERTION(text.Length() <= (len/2), "Invalid length!");
|
|
|
|
|
stuffToPaste.Assign ( text.get(), len / 2 );
|
|
|
|
|
stuffToPaste.Assign(text.get(), len / 2);
|
|
|
|
|
nsAutoEditBatch beginBatching(this);
|
|
|
|
|
rv = InsertAsPlaintextQuotation(stuffToPaste, PR_TRUE, 0);
|
|
|
|
|
}
|
|
|
|
@ -1903,6 +2074,46 @@ nsHTMLEditor::InsertAsCitedQuotation(const nsAString & aQuotedText,
|
|
|
|
|
return res;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void RemoveBodyAndHead(nsIDOMNode *aNode)
|
|
|
|
|
{
|
|
|
|
|
if (!aNode)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
nsCOMPtr<nsIDOMNode> tmp, child, body, head;
|
|
|
|
|
// find the body and head nodes if any.
|
|
|
|
|
// look only at immediate children of aNode.
|
|
|
|
|
aNode->GetFirstChild(getter_AddRefs(child));
|
|
|
|
|
while (child)
|
|
|
|
|
{
|
|
|
|
|
if (nsTextEditUtils::IsBody(child))
|
|
|
|
|
{
|
|
|
|
|
body = child;
|
|
|
|
|
}
|
|
|
|
|
else if (nsEditor::NodeIsType(child, NS_LITERAL_STRING("head")))
|
|
|
|
|
{
|
|
|
|
|
head = child;
|
|
|
|
|
}
|
|
|
|
|
child->GetNextSibling(getter_AddRefs(tmp));
|
|
|
|
|
child = tmp;
|
|
|
|
|
}
|
|
|
|
|
if (head)
|
|
|
|
|
{
|
|
|
|
|
aNode->RemoveChild(head, getter_AddRefs(tmp));
|
|
|
|
|
}
|
|
|
|
|
if (body)
|
|
|
|
|
{
|
|
|
|
|
body->GetFirstChild(getter_AddRefs(child));
|
|
|
|
|
while (child)
|
|
|
|
|
{
|
|
|
|
|
aNode->InsertBefore(child, body, getter_AddRefs(tmp));
|
|
|
|
|
body->GetFirstChild(getter_AddRefs(child));
|
|
|
|
|
}
|
|
|
|
|
aNode->RemoveChild(body, getter_AddRefs(tmp));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
nsresult nsHTMLEditor::CreateDOMFragmentFromPaste(nsIDOMNSRange *aNSRange,
|
|
|
|
|
const nsAString & aInputString,
|
|
|
|
|
const nsAString & aContextStr,
|
|
|
|
@ -1914,46 +2125,43 @@ nsresult nsHTMLEditor::CreateDOMFragmentFromPaste(nsIDOMNSRange *aNSRange,
|
|
|
|
|
if (!outFragNode || !outRangeStartHint || !outRangeEndHint || !aNSRange)
|
|
|
|
|
return NS_ERROR_NULL_POINTER;
|
|
|
|
|
nsCOMPtr<nsIDOMDocumentFragment> docfrag;
|
|
|
|
|
nsCOMPtr<nsIDOMNode> contextAsNode;
|
|
|
|
|
nsCOMPtr<nsIDOMNode> contextAsNode, tmp;
|
|
|
|
|
nsresult res = NS_OK;
|
|
|
|
|
|
|
|
|
|
// if we have context info, create a fragment for that
|
|
|
|
|
nsCOMPtr<nsIDOMDocumentFragment> contextfrag;
|
|
|
|
|
nsCOMPtr<nsIDOMNode> contextLeaf;
|
|
|
|
|
nsCOMPtr<nsIDOMNode> contextLeaf, junk;
|
|
|
|
|
PRInt32 contextDepth = 0;
|
|
|
|
|
if (aContextStr.Length())
|
|
|
|
|
{
|
|
|
|
|
res = aNSRange->CreateContextualFragment(aContextStr, getter_AddRefs(contextfrag));
|
|
|
|
|
res = ParseFragment(aContextStr, address_of(contextAsNode));
|
|
|
|
|
NS_ENSURE_SUCCESS(res, res);
|
|
|
|
|
contextAsNode = do_QueryInterface(contextfrag);
|
|
|
|
|
NS_ENSURE_TRUE(contextAsNode, NS_ERROR_FAILURE);
|
|
|
|
|
|
|
|
|
|
res = StripFormattingNodes(contextAsNode);
|
|
|
|
|
NS_ENSURE_SUCCESS(res, res);
|
|
|
|
|
|
|
|
|
|
RemoveBodyAndHead(contextAsNode);
|
|
|
|
|
|
|
|
|
|
// cache the deepest leaf in the context
|
|
|
|
|
nsCOMPtr<nsIDOMNode> junk, child, tmp = contextAsNode;
|
|
|
|
|
tmp = contextAsNode;
|
|
|
|
|
while (tmp)
|
|
|
|
|
{
|
|
|
|
|
contextDepth++;
|
|
|
|
|
contextLeaf = tmp;
|
|
|
|
|
contextLeaf->GetFirstChild(getter_AddRefs(tmp));
|
|
|
|
|
}
|
|
|
|
|
// tweak aNSRange to point inside contextAsNode
|
|
|
|
|
nsCOMPtr<nsIDOMRange> range(do_QueryInterface(aNSRange));
|
|
|
|
|
if (range)
|
|
|
|
|
{
|
|
|
|
|
aNSRange->NSDetach();
|
|
|
|
|
range->SetStart(contextLeaf,0);
|
|
|
|
|
range->SetEnd(contextLeaf,0);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// create fragment for pasted html
|
|
|
|
|
res = aNSRange->CreateContextualFragment(aInputString, getter_AddRefs(docfrag));
|
|
|
|
|
res = ParseFragment(aInputString, outFragNode);
|
|
|
|
|
NS_ENSURE_SUCCESS(res, res);
|
|
|
|
|
*outFragNode = do_QueryInterface(docfrag);
|
|
|
|
|
|
|
|
|
|
if (contextfrag)
|
|
|
|
|
NS_ENSURE_TRUE(*outFragNode, NS_ERROR_FAILURE);
|
|
|
|
|
|
|
|
|
|
RemoveBodyAndHead(*outFragNode);
|
|
|
|
|
|
|
|
|
|
if (contextAsNode)
|
|
|
|
|
{
|
|
|
|
|
nsCOMPtr<nsIDOMNode> junk;
|
|
|
|
|
// unite the two trees
|
|
|
|
|
contextLeaf->AppendChild(*outFragNode, getter_AddRefs(junk));
|
|
|
|
|
*outFragNode = contextAsNode;
|
|
|
|
@ -1983,6 +2191,36 @@ nsresult nsHTMLEditor::CreateDOMFragmentFromPaste(nsIDOMNSRange *aNSRange,
|
|
|
|
|
return res;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
nsresult nsHTMLEditor::ParseFragment(const nsAString &aFragStr, nsCOMPtr<nsIDOMNode> *outNode)
|
|
|
|
|
{
|
|
|
|
|
// create the parser to do the conversion.
|
|
|
|
|
nsCOMPtr<nsIParser> parser;
|
|
|
|
|
nsresult res = nsComponentManager::CreateInstance(kCParserCID, nsnull, NS_GET_IID(nsIParser),
|
|
|
|
|
getter_AddRefs(parser));
|
|
|
|
|
NS_ENSURE_SUCCESS(res, res);
|
|
|
|
|
NS_ENSURE_TRUE(parser, NS_ERROR_FAILURE);
|
|
|
|
|
|
|
|
|
|
// create the html fragment sink
|
|
|
|
|
nsCOMPtr<nsIContentSink> sink;
|
|
|
|
|
sink = do_CreateInstance(NS_HTMLFRAGMENTSINK2_CONTRACTID);
|
|
|
|
|
NS_ENSURE_TRUE(sink, NS_ERROR_FAILURE);
|
|
|
|
|
nsCOMPtr<nsIHTMLFragmentContentSink> fragSink(do_QueryInterface(sink));
|
|
|
|
|
NS_ENSURE_TRUE(fragSink, NS_ERROR_FAILURE);
|
|
|
|
|
|
|
|
|
|
// parse the fragment
|
|
|
|
|
parser->SetContentSink(sink);
|
|
|
|
|
parser->Parse(aFragStr, 0, NS_LITERAL_CSTRING("text/html"), PR_FALSE, PR_TRUE, eDTDMode_fragment);
|
|
|
|
|
|
|
|
|
|
// get the fragment node
|
|
|
|
|
nsCOMPtr<nsIDOMDocumentFragment> contextfrag;
|
|
|
|
|
res = fragSink->GetFragment(getter_AddRefs(contextfrag));
|
|
|
|
|
NS_ENSURE_SUCCESS(res, res);
|
|
|
|
|
*outNode = do_QueryInterface(contextfrag);
|
|
|
|
|
|
|
|
|
|
return res;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
nsresult nsHTMLEditor::CreateListOfNodesToPaste(nsIDOMNode *aFragmentAsNode,
|
|
|
|
|
nsCOMArray<nsIDOMNode>& outNodeList,
|
|
|
|
|
PRInt32 aRangeStartHint,
|
|
|
|
|