mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-25 13:51:41 +00:00
bug 50497: plaintext copy loses newlines on paste
This commit is contained in:
parent
d4b459cfee
commit
fed9703e2b
33
content/base/public/nsCopySupport.h
Normal file
33
content/base/public/nsCopySupport.h
Normal file
@ -0,0 +1,33 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape 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/NPL/
|
||||
*
|
||||
* 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 Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "nscore.h"
|
||||
#include "nsCOMPtr.h"
|
||||
|
||||
class nsISelection;
|
||||
class nsIDocument;
|
||||
|
||||
class nsCopySupport
|
||||
{
|
||||
// class of static helper functions for copy support
|
||||
public:
|
||||
static nsresult HTMLCopy(nsISelection *aSel, nsIDocument *aDoc, PRInt16 aClipboardID);
|
||||
};
|
@ -171,6 +171,14 @@ public:
|
||||
*/
|
||||
NS_IMETHOD SetWrapColumn(PRUint32 aWC) = 0;
|
||||
|
||||
/**
|
||||
* Get the mime type preferred by the encoder. This piece of api was
|
||||
* added because the copy encoder may need to switch mime types on you
|
||||
* if you ask it to copy html that really represents plaintext content.
|
||||
* Call this AFTER Init() and SetSelection() have both been called.
|
||||
*/
|
||||
NS_IMETHOD GetMimeType(nsAWritableString& aMimeType) = 0;
|
||||
|
||||
/**
|
||||
* The document is encoded, the result is sent to the
|
||||
* to nsIOutputStream.
|
||||
|
154
content/base/src/nsCopySupport.cpp
Normal file
154
content/base/src/nsCopySupport.cpp
Normal file
@ -0,0 +1,154 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape 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/NPL/
|
||||
*
|
||||
* 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 Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "nsCopySupport.h"
|
||||
#include "nsIDocumentEncoder.h"
|
||||
#include "nsISupports.h"
|
||||
#include "nsIContent.h"
|
||||
#include "nsIComponentManager.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsIClipboard.h"
|
||||
#include "nsWidgetsCID.h"
|
||||
#include "nsIEventStateManager.h"
|
||||
#include "nsIPresContext.h"
|
||||
#include "nsIDOMNSHTMLInputElement.h"
|
||||
#include "nsIDOMNSHTMLTextAreaElement.h"
|
||||
#include "nsISupportsPrimitives.h"
|
||||
|
||||
static NS_DEFINE_CID(kCClipboardCID, NS_CLIPBOARD_CID);
|
||||
static NS_DEFINE_CID(kCTransferableCID, NS_TRANSFERABLE_CID);
|
||||
static NS_DEFINE_CID(kHTMLConverterCID, NS_HTMLFORMATCONVERTER_CID);
|
||||
static NS_DEFINE_CID(kTextEncoderCID, NS_TEXT_ENCODER_CID);
|
||||
|
||||
// private clipboard data flavors for html copy, used by editor when pasting
|
||||
#define kHTMLContext "text/_moz_htmlcontext"
|
||||
#define kHTMLInfo "text/_moz_htmlinfo"
|
||||
|
||||
|
||||
nsresult nsCopySupport::HTMLCopy(nsISelection *aSel, nsIDocument *aDoc, PRInt16 aClipboardID)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
nsCOMPtr<nsIDocumentEncoder> docEncoder;
|
||||
|
||||
docEncoder = do_CreateInstance(NS_HTMLCOPY_ENCODER_CONTRACTID);
|
||||
NS_ENSURE_TRUE(docEncoder, NS_ERROR_FAILURE);
|
||||
|
||||
rv = docEncoder->Init(aDoc, NS_LITERAL_STRING("text/html"), 0);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
rv = docEncoder->SetSelection(aSel);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
nsAutoString mimeType;
|
||||
rv = docEncoder->GetMimeType(mimeType);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
nsAutoString buffer, parents, info;
|
||||
PRBool bIsHTMLCopy = PR_FALSE;
|
||||
if (mimeType.EqualsWithConversion("text/html"))
|
||||
bIsHTMLCopy = PR_TRUE;
|
||||
|
||||
if (bIsHTMLCopy)
|
||||
{
|
||||
// encode the selection as html with contextual info
|
||||
rv = docEncoder->EncodeToStringWithContext(buffer, parents, info);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
}
|
||||
else
|
||||
{
|
||||
// encode the selection
|
||||
rv = docEncoder->EncodeToString(buffer);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
}
|
||||
|
||||
// Get the Clipboard
|
||||
NS_WITH_SERVICE(nsIClipboard, clipboard, kCClipboardCID, &rv);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
if ( clipboard )
|
||||
{
|
||||
// Create a transferable for putting data on the Clipboard
|
||||
nsCOMPtr<nsITransferable> trans = do_CreateInstance(kCTransferableCID);
|
||||
if ( trans )
|
||||
{
|
||||
if (bIsHTMLCopy)
|
||||
{
|
||||
// set up the data converter
|
||||
nsCOMPtr<nsIFormatConverter> htmlConverter = do_CreateInstance(kHTMLConverterCID);
|
||||
NS_ENSURE_TRUE(htmlConverter, NS_ERROR_FAILURE);
|
||||
trans->SetConverter(htmlConverter);
|
||||
|
||||
// Add the html DataFlavor to the transferable
|
||||
trans->AddDataFlavor(kHTMLMime);
|
||||
// Add the htmlcontext DataFlavor to the transferable
|
||||
trans->AddDataFlavor(kHTMLContext);
|
||||
// Add the htmlinfo DataFlavor to the transferable
|
||||
trans->AddDataFlavor(kHTMLInfo);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Add the unicode DataFlavor to the transferable
|
||||
trans->AddDataFlavor(kUnicodeMime);
|
||||
}
|
||||
|
||||
// get wStrings to hold clip data
|
||||
nsCOMPtr<nsISupportsWString> dataWrapper, contextWrapper, infoWrapper;
|
||||
dataWrapper = do_CreateInstance(NS_SUPPORTS_WSTRING_CONTRACTID);
|
||||
NS_ENSURE_TRUE(dataWrapper, NS_ERROR_FAILURE);
|
||||
if (bIsHTMLCopy)
|
||||
{
|
||||
contextWrapper = do_CreateInstance(NS_SUPPORTS_WSTRING_CONTRACTID);
|
||||
NS_ENSURE_TRUE(contextWrapper, NS_ERROR_FAILURE);
|
||||
infoWrapper = do_CreateInstance(NS_SUPPORTS_WSTRING_CONTRACTID);
|
||||
NS_ENSURE_TRUE(infoWrapper, NS_ERROR_FAILURE);
|
||||
}
|
||||
|
||||
// populate the strings
|
||||
dataWrapper->SetData ( NS_CONST_CAST(PRUnichar*,buffer.GetUnicode()) );
|
||||
if (bIsHTMLCopy)
|
||||
{
|
||||
contextWrapper->SetData ( NS_CONST_CAST(PRUnichar*,parents.GetUnicode()) );
|
||||
infoWrapper->SetData ( NS_CONST_CAST(PRUnichar*,info.GetUnicode()) );
|
||||
}
|
||||
|
||||
// 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) );
|
||||
if (bIsHTMLCopy)
|
||||
{
|
||||
trans->SetTransferData(kHTMLMime, genericDataObj, buffer.Length()*2);
|
||||
genericDataObj = do_QueryInterface(contextWrapper);
|
||||
trans->SetTransferData(kHTMLContext, genericDataObj, parents.Length()*2);
|
||||
genericDataObj = do_QueryInterface(infoWrapper);
|
||||
trans->SetTransferData(kHTMLInfo, genericDataObj, info.Length()*2);
|
||||
}
|
||||
else
|
||||
{
|
||||
trans->SetTransferData(kUnicodeMime, genericDataObj, buffer.Length()*2);
|
||||
}
|
||||
// put the transferable on the clipboard
|
||||
clipboard->SetData(trans, nsnull, aClipboardID);
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
}
|
@ -92,6 +92,7 @@ public:
|
||||
NS_IMETHOD SetRange(nsIDOMRange* aRange);
|
||||
NS_IMETHOD SetWrapColumn(PRUint32 aWC);
|
||||
NS_IMETHOD SetCharset(const nsAReadableString& aCharset);
|
||||
NS_IMETHOD GetMimeType(nsAWritableString& aMimeType);
|
||||
NS_IMETHOD EncodeToStream(nsIOutputStream* aStream);
|
||||
NS_IMETHOD EncodeToString(nsAWritableString& aOutputString);
|
||||
NS_IMETHOD EncodeToStringWithContext(nsAWritableString& aEncodedString,
|
||||
@ -224,6 +225,14 @@ nsDocumentEncoder::SetCharset(const nsAReadableString& aCharset)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDocumentEncoder::GetMimeType(nsAWritableString& aMimeType)
|
||||
{
|
||||
aMimeType = mMimeType;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
PRBool
|
||||
nsDocumentEncoder::IncludeInContext(nsIDOMNode *aNode)
|
||||
{
|
||||
@ -803,9 +812,7 @@ nsDocumentEncoder::SerializeRangeToString(nsIDOMRange *aRange,
|
||||
|
||||
if (!mCommonParent)
|
||||
return NS_OK;
|
||||
|
||||
AdjustCommonParent(address_of(mCommonParent));
|
||||
|
||||
|
||||
aRange->GetStartContainer(getter_AddRefs(startParent));
|
||||
NS_ENSURE_TRUE(startParent, NS_ERROR_FAILURE);
|
||||
aRange->GetStartOffset(&startOffset);
|
||||
@ -1061,12 +1068,34 @@ nsHTMLCopyEncoder::SetSelection(nsISelection* aSelection)
|
||||
// check for text widgets: we need to recognize these so that
|
||||
// we don't tweak the selection to be outside of the magic
|
||||
// div that ender-lite text widgets are embedded in.
|
||||
nsCOMPtr<nsIDOMNode> selNode;
|
||||
nsresult rv = aSelection->GetFocusNode(getter_AddRefs(selNode));
|
||||
|
||||
if (!aSelection)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
nsCOMPtr<nsIDOMRange> range;
|
||||
nsCOMPtr<nsIDOMNode> commonParent;
|
||||
PRInt32 count = 0;
|
||||
|
||||
nsresult rv = aSelection->GetRangeCount(&count);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
nsCOMPtr<nsIContent> tmp, selContent( do_QueryInterface(selNode) );
|
||||
|
||||
// if selection is uninitialized return
|
||||
if (!count)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
// we'll just use the common parent of the first range. Implicit assumption
|
||||
// here that multi-range selections are table cell selections, in which case
|
||||
// the common parent is somewhere in the table and we don't really care where.
|
||||
rv = aSelection->GetRangeAt(0, getter_AddRefs(range));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (!range)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
range->GetCommonAncestorContainer(getter_AddRefs(commonParent));
|
||||
|
||||
nsCOMPtr<nsIContent> tmp, selContent( do_QueryInterface(commonParent) );
|
||||
while (selContent)
|
||||
{
|
||||
// checking for selection inside a plaintext form widget
|
||||
nsCOMPtr<nsIAtom> atom;
|
||||
selContent->GetTag(*getter_AddRefs(atom));
|
||||
if (atom.get() == nsHTMLAtoms::input ||
|
||||
@ -1214,15 +1243,28 @@ nsHTMLCopyEncoder::IncludeInContext(nsIDOMNode *aNode)
|
||||
|
||||
content->GetTag(*getter_AddRefs(tag));
|
||||
|
||||
if (tag.get() == nsHTMLAtoms::b ||
|
||||
tag.get() == nsHTMLAtoms::i ||
|
||||
tag.get() == nsHTMLAtoms::u ||
|
||||
tag.get() == nsHTMLAtoms::pre ||
|
||||
tag.get() == nsHTMLAtoms::h1 ||
|
||||
tag.get() == nsHTMLAtoms::h2 ||
|
||||
tag.get() == nsHTMLAtoms::h3 ||
|
||||
tag.get() == nsHTMLAtoms::h4 ||
|
||||
tag.get() == nsHTMLAtoms::h5 ||
|
||||
if (tag.get() == nsHTMLAtoms::b ||
|
||||
tag.get() == nsHTMLAtoms::i ||
|
||||
tag.get() == nsHTMLAtoms::u ||
|
||||
tag.get() == nsHTMLAtoms::tt ||
|
||||
tag.get() == nsHTMLAtoms::s ||
|
||||
tag.get() == nsHTMLAtoms::strike ||
|
||||
tag.get() == nsHTMLAtoms::em ||
|
||||
tag.get() == nsHTMLAtoms::strong ||
|
||||
tag.get() == nsHTMLAtoms::dfn ||
|
||||
tag.get() == nsHTMLAtoms::code ||
|
||||
tag.get() == nsHTMLAtoms::cite ||
|
||||
tag.get() == nsHTMLAtoms::variable ||
|
||||
tag.get() == nsHTMLAtoms::abbr ||
|
||||
tag.get() == nsHTMLAtoms::font ||
|
||||
tag.get() == nsHTMLAtoms::script ||
|
||||
tag.get() == nsHTMLAtoms::span ||
|
||||
tag.get() == nsHTMLAtoms::pre ||
|
||||
tag.get() == nsHTMLAtoms::h1 ||
|
||||
tag.get() == nsHTMLAtoms::h2 ||
|
||||
tag.get() == nsHTMLAtoms::h3 ||
|
||||
tag.get() == nsHTMLAtoms::h4 ||
|
||||
tag.get() == nsHTMLAtoms::h5 ||
|
||||
tag.get() == nsHTMLAtoms::h6) {
|
||||
return PR_TRUE;
|
||||
}
|
||||
@ -1515,7 +1557,9 @@ nsHTMLCopyEncoder::IsRoot(nsIDOMNode* aNode)
|
||||
if (mIsTextWidget)
|
||||
return (IsTag(aNode, nsHTMLAtoms::div));
|
||||
else
|
||||
return (IsTag(aNode, nsHTMLAtoms::body));
|
||||
return (IsTag(aNode, nsHTMLAtoms::body) ||
|
||||
IsTag(aNode, nsHTMLAtoms::td) ||
|
||||
IsTag(aNode, nsHTMLAtoms::th));
|
||||
}
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
@ -119,6 +119,8 @@ HTML_ATOM(dt, "dt")
|
||||
|
||||
HTML_ATOM(datetime, "datetime")
|
||||
HTML_ATOM(data, "data")
|
||||
HTML_ATOM(dfn, "dfn")
|
||||
HTML_ATOM(em, "em")
|
||||
HTML_ATOM(embed, "embed")
|
||||
HTML_ATOM(encoding, "encoding")
|
||||
HTML_ATOM(enctype, "enctype")
|
||||
@ -224,6 +226,7 @@ HTML_ATOM(rightpadding, "rightpadding")
|
||||
HTML_ATOM(rows, "rows")
|
||||
HTML_ATOM(rowspan, "rowspan")
|
||||
HTML_ATOM(rules, "rules")
|
||||
HTML_ATOM(s, "s")
|
||||
HTML_ATOM(scheme, "scheme")
|
||||
HTML_ATOM(scope, "scope")
|
||||
HTML_ATOM(script, "script")
|
||||
@ -238,6 +241,8 @@ HTML_ATOM(span, "span")
|
||||
HTML_ATOM(src, "src")
|
||||
HTML_ATOM(standby, "standby")
|
||||
HTML_ATOM(start, "start")
|
||||
HTML_ATOM(strike, "strike")
|
||||
HTML_ATOM(strong, "strong")
|
||||
HTML_ATOM(style, "style")
|
||||
HTML_ATOM(summary, "summary")
|
||||
HTML_ATOM(suppress, "suppress")
|
||||
@ -264,6 +269,7 @@ HTML_ATOM(title, "title")
|
||||
HTML_ATOM(top, "top")
|
||||
HTML_ATOM(toppadding, "toppadding")
|
||||
HTML_ATOM(tr, "tr")
|
||||
HTML_ATOM(tt, "tt")
|
||||
HTML_ATOM(type, "type")
|
||||
HTML_ATOM(u, "u")
|
||||
HTML_ATOM(ul, "ul")
|
||||
|
@ -119,6 +119,8 @@ HTML_ATOM(dt, "dt")
|
||||
|
||||
HTML_ATOM(datetime, "datetime")
|
||||
HTML_ATOM(data, "data")
|
||||
HTML_ATOM(dfn, "dfn")
|
||||
HTML_ATOM(em, "em")
|
||||
HTML_ATOM(embed, "embed")
|
||||
HTML_ATOM(encoding, "encoding")
|
||||
HTML_ATOM(enctype, "enctype")
|
||||
@ -224,6 +226,7 @@ HTML_ATOM(rightpadding, "rightpadding")
|
||||
HTML_ATOM(rows, "rows")
|
||||
HTML_ATOM(rowspan, "rowspan")
|
||||
HTML_ATOM(rules, "rules")
|
||||
HTML_ATOM(s, "s")
|
||||
HTML_ATOM(scheme, "scheme")
|
||||
HTML_ATOM(scope, "scope")
|
||||
HTML_ATOM(script, "script")
|
||||
@ -238,6 +241,8 @@ HTML_ATOM(span, "span")
|
||||
HTML_ATOM(src, "src")
|
||||
HTML_ATOM(standby, "standby")
|
||||
HTML_ATOM(start, "start")
|
||||
HTML_ATOM(strike, "strike")
|
||||
HTML_ATOM(strong, "strong")
|
||||
HTML_ATOM(style, "style")
|
||||
HTML_ATOM(summary, "summary")
|
||||
HTML_ATOM(suppress, "suppress")
|
||||
@ -264,6 +269,7 @@ HTML_ATOM(title, "title")
|
||||
HTML_ATOM(top, "top")
|
||||
HTML_ATOM(toppadding, "toppadding")
|
||||
HTML_ATOM(tr, "tr")
|
||||
HTML_ATOM(tt, "tt")
|
||||
HTML_ATOM(type, "type")
|
||||
HTML_ATOM(u, "u")
|
||||
HTML_ATOM(ul, "ul")
|
||||
|
@ -29,18 +29,13 @@
|
||||
#include "nsISelectionPrivate.h"
|
||||
#include "nsISelectionListener.h"
|
||||
#include "nsWidgetsCID.h"
|
||||
#include "nsIClipboard.h"
|
||||
#include "nsIDOMDocument.h"
|
||||
#include "nsIDocumentEncoder.h"
|
||||
#include "nsCopySupport.h"
|
||||
#include "nsIClipboard.h"
|
||||
|
||||
#include "nsIDocument.h"
|
||||
#include "nsSupportsPrimitives.h"
|
||||
|
||||
// private clipboard data flavors for html copy, used by editor when pasting
|
||||
#define kHTMLContext "text/_moz_htmlcontext"
|
||||
#define kHTMLInfo "text/_moz_htmlinfo"
|
||||
|
||||
|
||||
class nsAutoCopyService : public nsIAutoCopyService , public nsISelectionListener
|
||||
{
|
||||
public:
|
||||
@ -56,10 +51,6 @@ public:
|
||||
//nsISelectionListener interfaces
|
||||
NS_IMETHOD NotifySelectionChanged(nsIDOMDocument *aDoc, nsISelection *aSel, short aReason);
|
||||
//end nsISelectionListener
|
||||
protected:
|
||||
nsCOMPtr<nsIClipboard> mClipboard;
|
||||
nsCOMPtr<nsITransferable> mTransferable;
|
||||
nsCOMPtr<nsIFormatConverter> mConverter;
|
||||
};
|
||||
|
||||
// Implement our nsISupports methods
|
||||
@ -125,14 +116,8 @@ nsAutoCopyService::NotifySelectionChanged(nsIDOMDocument *aDoc, nsISelection *aS
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
if (!mClipboard) {
|
||||
static NS_DEFINE_CID(kCClipboardCID, NS_CLIPBOARD_CID);
|
||||
mClipboard = do_GetService(kCClipboardCID, &rv);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
}
|
||||
if (!(aReason & nsISelectionListener::MOUSEUP_REASON))
|
||||
return NS_OK;//dont care if we are still dragging. or if its not from a mouseup
|
||||
return NS_OK; //dont care if we are still dragging. or if its not from a mouseup
|
||||
PRBool collapsed;
|
||||
if (!aDoc || !aSel || NS_FAILED(aSel->GetIsCollapsed(&collapsed)) || collapsed) {
|
||||
#ifdef DEBUG_CLIPBOARD
|
||||
@ -144,82 +129,13 @@ nsAutoCopyService::NotifySelectionChanged(nsIDOMDocument *aDoc, nsISelection *aS
|
||||
|
||||
nsCOMPtr<nsIDocument> doc;
|
||||
doc = do_QueryInterface(NS_REINTERPRET_CAST(nsISupports *,aDoc),&rv);
|
||||
nsAutoString buffer, parents, info;
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
if (!doc)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
nsCOMPtr<nsIDocumentEncoder> docEncoder;
|
||||
|
||||
docEncoder = do_CreateInstance(NS_HTMLCOPY_ENCODER_CONTRACTID);
|
||||
NS_ENSURE_TRUE(docEncoder, NS_ERROR_FAILURE);
|
||||
|
||||
docEncoder->Init(doc, NS_LITERAL_STRING("text/html"), 0);
|
||||
docEncoder->SetSelection(aSel);
|
||||
|
||||
rv = docEncoder->EncodeToStringWithContext(buffer, parents, info);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
/* create a transferable */
|
||||
static NS_DEFINE_CID(kCTransferableCID, NS_TRANSFERABLE_CID);
|
||||
nsCOMPtr<nsITransferable> trans;
|
||||
trans = do_CreateInstance(kCTransferableCID);
|
||||
if (!trans)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
if (!mConverter) {
|
||||
static NS_DEFINE_CID(kHTMLConverterCID, NS_HTMLFORMATCONVERTER_CID);
|
||||
mConverter = do_CreateInstance(kHTMLConverterCID);
|
||||
if (!mConverter)
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
trans->AddDataFlavor(kHTMLMime);
|
||||
trans->SetConverter(mConverter);
|
||||
|
||||
// Add the html DataFlavor to the transferable
|
||||
trans->AddDataFlavor(kHTMLMime);
|
||||
// Add the htmlcontext DataFlavor to the transferable
|
||||
trans->AddDataFlavor(kHTMLContext);
|
||||
// Add the htmlinfo DataFlavor to the transferable
|
||||
trans->AddDataFlavor(kHTMLInfo);
|
||||
|
||||
// get wStrings to hold clip data
|
||||
nsCOMPtr<nsISupportsWString> dataWrapper, contextWrapper, infoWrapper;
|
||||
dataWrapper = do_CreateInstance(NS_SUPPORTS_WSTRING_CONTRACTID);
|
||||
NS_ENSURE_TRUE(dataWrapper, NS_ERROR_FAILURE);
|
||||
contextWrapper = do_CreateInstance(NS_SUPPORTS_WSTRING_CONTRACTID);
|
||||
NS_ENSURE_TRUE(contextWrapper, NS_ERROR_FAILURE);
|
||||
infoWrapper = do_CreateInstance(NS_SUPPORTS_WSTRING_CONTRACTID);
|
||||
NS_ENSURE_TRUE(infoWrapper, NS_ERROR_FAILURE);
|
||||
|
||||
// populate the strings
|
||||
dataWrapper->SetData ( NS_CONST_CAST(PRUnichar*,buffer.GetUnicode()) );
|
||||
contextWrapper->SetData ( NS_CONST_CAST(PRUnichar*,parents.GetUnicode()) );
|
||||
infoWrapper->SetData ( NS_CONST_CAST(PRUnichar*,info.GetUnicode()) );
|
||||
|
||||
// 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) );
|
||||
trans->SetTransferData(kHTMLMime, genericDataObj, buffer.Length()*2);
|
||||
genericDataObj = do_QueryInterface(contextWrapper);
|
||||
trans->SetTransferData(kHTMLContext, genericDataObj, parents.Length()*2);
|
||||
genericDataObj = do_QueryInterface(infoWrapper);
|
||||
trans->SetTransferData(kHTMLInfo, genericDataObj, info.Length()*2);
|
||||
|
||||
// put the transferable on the clipboard
|
||||
mClipboard->SetData(trans, nsnull, nsIClipboard::kSelectionClipboard);
|
||||
|
||||
#ifdef DEBUG_CLIPBOARD
|
||||
static char *reasons[] = {
|
||||
"UNKNOWN", "NEW", "REMOVED", "ALTERED",
|
||||
"BOGUS4", "BOGUS5", "BOGUS6", "BOGUS7", "BOGUS8"
|
||||
};
|
||||
|
||||
nsAutoString str;
|
||||
aSel->ToString(str);
|
||||
char *selStr = str.ToNewCString();
|
||||
fprintf(stderr, "SELECTION: %s, %p, %p [%s]\n", reasons[reason], doc, aSel,
|
||||
selStr);
|
||||
nsMemory::Free(selStr);
|
||||
#endif
|
||||
return NS_OK;
|
||||
// call the copy code
|
||||
rv = nsCopySupport::HTMLCopy(aSel, doc, nsIClipboard::kSelectionClipboard);
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
@ -117,8 +117,6 @@
|
||||
// Drag & Drop, Clipboard
|
||||
#include "nsWidgetsCID.h"
|
||||
#include "nsIClipboard.h"
|
||||
#include "nsITransferable.h"
|
||||
#include "nsIFormatConverter.h"
|
||||
#include "nsIDocShellTreeItem.h"
|
||||
#include "nsIURI.h"
|
||||
#include "nsIEventQueue.h"
|
||||
@ -126,8 +124,8 @@
|
||||
#include "nsIScrollableFrame.h"
|
||||
#include "prtime.h"
|
||||
#include "prlong.h"
|
||||
#include "nsIDocumentEncoder.h"
|
||||
#include "nsIDragService.h"
|
||||
#include "nsCopySupport.h"
|
||||
|
||||
// Dummy layout request
|
||||
#include "nsIChannel.h"
|
||||
@ -168,10 +166,6 @@ static nsresult CtlStyleWatch(PRUint32 aCtlValue, nsIStyleSet *aStyleSet);
|
||||
#define kStyleWatchStop 16
|
||||
#define kStyleWatchReset 32
|
||||
|
||||
// private clipboard data flavors for html copy, used by editor when pasting
|
||||
#define kHTMLContext "text/_moz_htmlcontext"
|
||||
#define kHTMLInfo "text/_moz_htmlinfo"
|
||||
|
||||
// Class ID's
|
||||
static NS_DEFINE_CID(kFrameSelectionCID, NS_FRAMESELECTION_CID);
|
||||
static NS_DEFINE_CID(kCRangeCID, NS_RANGE_CID);
|
||||
@ -3572,9 +3566,7 @@ PresShell::DoCopy()
|
||||
if (!doc) return NS_ERROR_FAILURE;
|
||||
|
||||
nsresult rv;
|
||||
|
||||
nsCOMPtr<nsISelection> sel;
|
||||
|
||||
nsCOMPtr<nsIEventStateManager> manager;
|
||||
nsCOMPtr<nsIContent> content;
|
||||
rv = mPresContext->GetEventStateManager(getter_AddRefs(manager));
|
||||
@ -3612,74 +3604,11 @@ PresShell::DoCopy()
|
||||
if (isCollapsed)
|
||||
return NS_OK;
|
||||
|
||||
nsCOMPtr<nsIDocumentEncoder> docEncoder;
|
||||
|
||||
docEncoder = do_CreateInstance(NS_HTMLCOPY_ENCODER_CONTRACTID);
|
||||
NS_ENSURE_TRUE(docEncoder, NS_ERROR_FAILURE);
|
||||
|
||||
docEncoder->Init(doc, NS_LITERAL_STRING("text/html"), 0);
|
||||
docEncoder->SetSelection(sel);
|
||||
|
||||
nsAutoString buffer, parents, info;
|
||||
|
||||
rv = docEncoder->EncodeToStringWithContext(buffer, parents, info);
|
||||
if (NS_FAILED(rv))
|
||||
// call the copy code
|
||||
rv = nsCopySupport::HTMLCopy(sel, doc, nsIClipboard::kGlobalClipboard);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
// Get the Clipboard
|
||||
NS_WITH_SERVICE(nsIClipboard, clipboard, kCClipboardCID, &rv);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
if ( clipboard )
|
||||
{
|
||||
// Create a transferable for putting data on the Clipboard
|
||||
nsCOMPtr<nsITransferable> trans;
|
||||
rv = nsComponentManager::CreateInstance(kCTransferableCID, nsnull,
|
||||
NS_GET_IID(nsITransferable),
|
||||
getter_AddRefs(trans));
|
||||
if ( trans )
|
||||
{
|
||||
// set up the data converter
|
||||
nsCOMPtr<nsIFormatConverter> htmlConverter = do_CreateInstance(kHTMLConverterCID);
|
||||
NS_ENSURE_TRUE(htmlConverter, NS_ERROR_FAILURE);
|
||||
trans->SetConverter(htmlConverter);
|
||||
|
||||
// Add the html DataFlavor to the transferable
|
||||
trans->AddDataFlavor(kHTMLMime);
|
||||
// Add the htmlcontext DataFlavor to the transferable
|
||||
trans->AddDataFlavor(kHTMLContext);
|
||||
// Add the htmlinfo DataFlavor to the transferable
|
||||
trans->AddDataFlavor(kHTMLInfo);
|
||||
|
||||
// get wStrings to hold clip data
|
||||
nsCOMPtr<nsISupportsWString> dataWrapper, contextWrapper, infoWrapper;
|
||||
dataWrapper = do_CreateInstance(NS_SUPPORTS_WSTRING_CONTRACTID);
|
||||
NS_ENSURE_TRUE(dataWrapper, NS_ERROR_FAILURE);
|
||||
contextWrapper = do_CreateInstance(NS_SUPPORTS_WSTRING_CONTRACTID);
|
||||
NS_ENSURE_TRUE(contextWrapper, NS_ERROR_FAILURE);
|
||||
infoWrapper = do_CreateInstance(NS_SUPPORTS_WSTRING_CONTRACTID);
|
||||
NS_ENSURE_TRUE(infoWrapper, NS_ERROR_FAILURE);
|
||||
|
||||
// populate the strings
|
||||
dataWrapper->SetData ( NS_CONST_CAST(PRUnichar*,buffer.GetUnicode()) );
|
||||
contextWrapper->SetData ( NS_CONST_CAST(PRUnichar*,parents.GetUnicode()) );
|
||||
infoWrapper->SetData ( NS_CONST_CAST(PRUnichar*,info.GetUnicode()) );
|
||||
|
||||
// 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) );
|
||||
trans->SetTransferData(kHTMLMime, genericDataObj, buffer.Length()*2);
|
||||
genericDataObj = do_QueryInterface(contextWrapper);
|
||||
trans->SetTransferData(kHTMLContext, genericDataObj, parents.Length()*2);
|
||||
genericDataObj = do_QueryInterface(infoWrapper);
|
||||
trans->SetTransferData(kHTMLInfo, genericDataObj, info.Length()*2);
|
||||
|
||||
// put the transferable on the clipboard
|
||||
clipboard->SetData(trans, nsnull, nsIClipboard::kGlobalClipboard);
|
||||
}
|
||||
}
|
||||
|
||||
// Now that we have copied, update the Paste menu item
|
||||
nsCOMPtr<nsIScriptGlobalObject> globalObject;
|
||||
doc->GetScriptGlobalObject(getter_AddRefs(globalObject));
|
||||
|
@ -171,6 +171,14 @@ public:
|
||||
*/
|
||||
NS_IMETHOD SetWrapColumn(PRUint32 aWC) = 0;
|
||||
|
||||
/**
|
||||
* Get the mime type preferred by the encoder. This piece of api was
|
||||
* added because the copy encoder may need to switch mime types on you
|
||||
* if you ask it to copy html that really represents plaintext content.
|
||||
* Call this AFTER Init() and SetSelection() have both been called.
|
||||
*/
|
||||
NS_IMETHOD GetMimeType(nsAWritableString& aMimeType) = 0;
|
||||
|
||||
/**
|
||||
* The document is encoded, the result is sent to the
|
||||
* to nsIOutputStream.
|
||||
|
@ -37,6 +37,7 @@ CPPSRCS = \
|
||||
nsContentIterator.cpp \
|
||||
nsContentList.cpp \
|
||||
nsContentPolicy.cpp \
|
||||
nsCopySupport.cpp \
|
||||
nsDocument.cpp \
|
||||
nsDocumentEncoder.cpp \
|
||||
nsDocumentFragment.cpp \
|
||||
|
@ -36,6 +36,7 @@ CPPSRCS = \
|
||||
nsContentList.cpp \
|
||||
nsContentIterator.cpp \
|
||||
nsContentPolicy.cpp \
|
||||
nsCopySupport.cpp \
|
||||
nsDocument.cpp \
|
||||
nsDocumentEncoder.cpp \
|
||||
nsDocumentFragment.cpp \
|
||||
@ -87,6 +88,7 @@ CPP_OBJS= \
|
||||
.\$(OBJDIR)\nsContentList.obj \
|
||||
.\$(OBJDIR)\nsContentIterator.obj \
|
||||
.\$(OBJDIR)\nsContentPolicy.obj \
|
||||
.\$(OBJDIR)\nsCopySupport.obj \
|
||||
.\$(OBJDIR)\nsDocument.obj \
|
||||
.\$(OBJDIR)\nsDocumentEncoder.obj \
|
||||
.\$(OBJDIR)\nsDocumentFragment.obj \
|
||||
|
@ -29,18 +29,13 @@
|
||||
#include "nsISelectionPrivate.h"
|
||||
#include "nsISelectionListener.h"
|
||||
#include "nsWidgetsCID.h"
|
||||
#include "nsIClipboard.h"
|
||||
#include "nsIDOMDocument.h"
|
||||
#include "nsIDocumentEncoder.h"
|
||||
#include "nsCopySupport.h"
|
||||
#include "nsIClipboard.h"
|
||||
|
||||
#include "nsIDocument.h"
|
||||
#include "nsSupportsPrimitives.h"
|
||||
|
||||
// private clipboard data flavors for html copy, used by editor when pasting
|
||||
#define kHTMLContext "text/_moz_htmlcontext"
|
||||
#define kHTMLInfo "text/_moz_htmlinfo"
|
||||
|
||||
|
||||
class nsAutoCopyService : public nsIAutoCopyService , public nsISelectionListener
|
||||
{
|
||||
public:
|
||||
@ -56,10 +51,6 @@ public:
|
||||
//nsISelectionListener interfaces
|
||||
NS_IMETHOD NotifySelectionChanged(nsIDOMDocument *aDoc, nsISelection *aSel, short aReason);
|
||||
//end nsISelectionListener
|
||||
protected:
|
||||
nsCOMPtr<nsIClipboard> mClipboard;
|
||||
nsCOMPtr<nsITransferable> mTransferable;
|
||||
nsCOMPtr<nsIFormatConverter> mConverter;
|
||||
};
|
||||
|
||||
// Implement our nsISupports methods
|
||||
@ -125,14 +116,8 @@ nsAutoCopyService::NotifySelectionChanged(nsIDOMDocument *aDoc, nsISelection *aS
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
if (!mClipboard) {
|
||||
static NS_DEFINE_CID(kCClipboardCID, NS_CLIPBOARD_CID);
|
||||
mClipboard = do_GetService(kCClipboardCID, &rv);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
}
|
||||
if (!(aReason & nsISelectionListener::MOUSEUP_REASON))
|
||||
return NS_OK;//dont care if we are still dragging. or if its not from a mouseup
|
||||
return NS_OK; //dont care if we are still dragging. or if its not from a mouseup
|
||||
PRBool collapsed;
|
||||
if (!aDoc || !aSel || NS_FAILED(aSel->GetIsCollapsed(&collapsed)) || collapsed) {
|
||||
#ifdef DEBUG_CLIPBOARD
|
||||
@ -144,82 +129,13 @@ nsAutoCopyService::NotifySelectionChanged(nsIDOMDocument *aDoc, nsISelection *aS
|
||||
|
||||
nsCOMPtr<nsIDocument> doc;
|
||||
doc = do_QueryInterface(NS_REINTERPRET_CAST(nsISupports *,aDoc),&rv);
|
||||
nsAutoString buffer, parents, info;
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
if (!doc)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
nsCOMPtr<nsIDocumentEncoder> docEncoder;
|
||||
|
||||
docEncoder = do_CreateInstance(NS_HTMLCOPY_ENCODER_CONTRACTID);
|
||||
NS_ENSURE_TRUE(docEncoder, NS_ERROR_FAILURE);
|
||||
|
||||
docEncoder->Init(doc, NS_LITERAL_STRING("text/html"), 0);
|
||||
docEncoder->SetSelection(aSel);
|
||||
|
||||
rv = docEncoder->EncodeToStringWithContext(buffer, parents, info);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
/* create a transferable */
|
||||
static NS_DEFINE_CID(kCTransferableCID, NS_TRANSFERABLE_CID);
|
||||
nsCOMPtr<nsITransferable> trans;
|
||||
trans = do_CreateInstance(kCTransferableCID);
|
||||
if (!trans)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
if (!mConverter) {
|
||||
static NS_DEFINE_CID(kHTMLConverterCID, NS_HTMLFORMATCONVERTER_CID);
|
||||
mConverter = do_CreateInstance(kHTMLConverterCID);
|
||||
if (!mConverter)
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
trans->AddDataFlavor(kHTMLMime);
|
||||
trans->SetConverter(mConverter);
|
||||
|
||||
// Add the html DataFlavor to the transferable
|
||||
trans->AddDataFlavor(kHTMLMime);
|
||||
// Add the htmlcontext DataFlavor to the transferable
|
||||
trans->AddDataFlavor(kHTMLContext);
|
||||
// Add the htmlinfo DataFlavor to the transferable
|
||||
trans->AddDataFlavor(kHTMLInfo);
|
||||
|
||||
// get wStrings to hold clip data
|
||||
nsCOMPtr<nsISupportsWString> dataWrapper, contextWrapper, infoWrapper;
|
||||
dataWrapper = do_CreateInstance(NS_SUPPORTS_WSTRING_CONTRACTID);
|
||||
NS_ENSURE_TRUE(dataWrapper, NS_ERROR_FAILURE);
|
||||
contextWrapper = do_CreateInstance(NS_SUPPORTS_WSTRING_CONTRACTID);
|
||||
NS_ENSURE_TRUE(contextWrapper, NS_ERROR_FAILURE);
|
||||
infoWrapper = do_CreateInstance(NS_SUPPORTS_WSTRING_CONTRACTID);
|
||||
NS_ENSURE_TRUE(infoWrapper, NS_ERROR_FAILURE);
|
||||
|
||||
// populate the strings
|
||||
dataWrapper->SetData ( NS_CONST_CAST(PRUnichar*,buffer.GetUnicode()) );
|
||||
contextWrapper->SetData ( NS_CONST_CAST(PRUnichar*,parents.GetUnicode()) );
|
||||
infoWrapper->SetData ( NS_CONST_CAST(PRUnichar*,info.GetUnicode()) );
|
||||
|
||||
// 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) );
|
||||
trans->SetTransferData(kHTMLMime, genericDataObj, buffer.Length()*2);
|
||||
genericDataObj = do_QueryInterface(contextWrapper);
|
||||
trans->SetTransferData(kHTMLContext, genericDataObj, parents.Length()*2);
|
||||
genericDataObj = do_QueryInterface(infoWrapper);
|
||||
trans->SetTransferData(kHTMLInfo, genericDataObj, info.Length()*2);
|
||||
|
||||
// put the transferable on the clipboard
|
||||
mClipboard->SetData(trans, nsnull, nsIClipboard::kSelectionClipboard);
|
||||
|
||||
#ifdef DEBUG_CLIPBOARD
|
||||
static char *reasons[] = {
|
||||
"UNKNOWN", "NEW", "REMOVED", "ALTERED",
|
||||
"BOGUS4", "BOGUS5", "BOGUS6", "BOGUS7", "BOGUS8"
|
||||
};
|
||||
|
||||
nsAutoString str;
|
||||
aSel->ToString(str);
|
||||
char *selStr = str.ToNewCString();
|
||||
fprintf(stderr, "SELECTION: %s, %p, %p [%s]\n", reasons[reason], doc, aSel,
|
||||
selStr);
|
||||
nsMemory::Free(selStr);
|
||||
#endif
|
||||
return NS_OK;
|
||||
// call the copy code
|
||||
rv = nsCopySupport::HTMLCopy(aSel, doc, nsIClipboard::kSelectionClipboard);
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
154
layout/base/src/nsCopySupport.cpp
Normal file
154
layout/base/src/nsCopySupport.cpp
Normal file
@ -0,0 +1,154 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape 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/NPL/
|
||||
*
|
||||
* 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 Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "nsCopySupport.h"
|
||||
#include "nsIDocumentEncoder.h"
|
||||
#include "nsISupports.h"
|
||||
#include "nsIContent.h"
|
||||
#include "nsIComponentManager.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsIClipboard.h"
|
||||
#include "nsWidgetsCID.h"
|
||||
#include "nsIEventStateManager.h"
|
||||
#include "nsIPresContext.h"
|
||||
#include "nsIDOMNSHTMLInputElement.h"
|
||||
#include "nsIDOMNSHTMLTextAreaElement.h"
|
||||
#include "nsISupportsPrimitives.h"
|
||||
|
||||
static NS_DEFINE_CID(kCClipboardCID, NS_CLIPBOARD_CID);
|
||||
static NS_DEFINE_CID(kCTransferableCID, NS_TRANSFERABLE_CID);
|
||||
static NS_DEFINE_CID(kHTMLConverterCID, NS_HTMLFORMATCONVERTER_CID);
|
||||
static NS_DEFINE_CID(kTextEncoderCID, NS_TEXT_ENCODER_CID);
|
||||
|
||||
// private clipboard data flavors for html copy, used by editor when pasting
|
||||
#define kHTMLContext "text/_moz_htmlcontext"
|
||||
#define kHTMLInfo "text/_moz_htmlinfo"
|
||||
|
||||
|
||||
nsresult nsCopySupport::HTMLCopy(nsISelection *aSel, nsIDocument *aDoc, PRInt16 aClipboardID)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
nsCOMPtr<nsIDocumentEncoder> docEncoder;
|
||||
|
||||
docEncoder = do_CreateInstance(NS_HTMLCOPY_ENCODER_CONTRACTID);
|
||||
NS_ENSURE_TRUE(docEncoder, NS_ERROR_FAILURE);
|
||||
|
||||
rv = docEncoder->Init(aDoc, NS_LITERAL_STRING("text/html"), 0);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
rv = docEncoder->SetSelection(aSel);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
nsAutoString mimeType;
|
||||
rv = docEncoder->GetMimeType(mimeType);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
nsAutoString buffer, parents, info;
|
||||
PRBool bIsHTMLCopy = PR_FALSE;
|
||||
if (mimeType.EqualsWithConversion("text/html"))
|
||||
bIsHTMLCopy = PR_TRUE;
|
||||
|
||||
if (bIsHTMLCopy)
|
||||
{
|
||||
// encode the selection as html with contextual info
|
||||
rv = docEncoder->EncodeToStringWithContext(buffer, parents, info);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
}
|
||||
else
|
||||
{
|
||||
// encode the selection
|
||||
rv = docEncoder->EncodeToString(buffer);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
}
|
||||
|
||||
// Get the Clipboard
|
||||
NS_WITH_SERVICE(nsIClipboard, clipboard, kCClipboardCID, &rv);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
if ( clipboard )
|
||||
{
|
||||
// Create a transferable for putting data on the Clipboard
|
||||
nsCOMPtr<nsITransferable> trans = do_CreateInstance(kCTransferableCID);
|
||||
if ( trans )
|
||||
{
|
||||
if (bIsHTMLCopy)
|
||||
{
|
||||
// set up the data converter
|
||||
nsCOMPtr<nsIFormatConverter> htmlConverter = do_CreateInstance(kHTMLConverterCID);
|
||||
NS_ENSURE_TRUE(htmlConverter, NS_ERROR_FAILURE);
|
||||
trans->SetConverter(htmlConverter);
|
||||
|
||||
// Add the html DataFlavor to the transferable
|
||||
trans->AddDataFlavor(kHTMLMime);
|
||||
// Add the htmlcontext DataFlavor to the transferable
|
||||
trans->AddDataFlavor(kHTMLContext);
|
||||
// Add the htmlinfo DataFlavor to the transferable
|
||||
trans->AddDataFlavor(kHTMLInfo);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Add the unicode DataFlavor to the transferable
|
||||
trans->AddDataFlavor(kUnicodeMime);
|
||||
}
|
||||
|
||||
// get wStrings to hold clip data
|
||||
nsCOMPtr<nsISupportsWString> dataWrapper, contextWrapper, infoWrapper;
|
||||
dataWrapper = do_CreateInstance(NS_SUPPORTS_WSTRING_CONTRACTID);
|
||||
NS_ENSURE_TRUE(dataWrapper, NS_ERROR_FAILURE);
|
||||
if (bIsHTMLCopy)
|
||||
{
|
||||
contextWrapper = do_CreateInstance(NS_SUPPORTS_WSTRING_CONTRACTID);
|
||||
NS_ENSURE_TRUE(contextWrapper, NS_ERROR_FAILURE);
|
||||
infoWrapper = do_CreateInstance(NS_SUPPORTS_WSTRING_CONTRACTID);
|
||||
NS_ENSURE_TRUE(infoWrapper, NS_ERROR_FAILURE);
|
||||
}
|
||||
|
||||
// populate the strings
|
||||
dataWrapper->SetData ( NS_CONST_CAST(PRUnichar*,buffer.GetUnicode()) );
|
||||
if (bIsHTMLCopy)
|
||||
{
|
||||
contextWrapper->SetData ( NS_CONST_CAST(PRUnichar*,parents.GetUnicode()) );
|
||||
infoWrapper->SetData ( NS_CONST_CAST(PRUnichar*,info.GetUnicode()) );
|
||||
}
|
||||
|
||||
// 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) );
|
||||
if (bIsHTMLCopy)
|
||||
{
|
||||
trans->SetTransferData(kHTMLMime, genericDataObj, buffer.Length()*2);
|
||||
genericDataObj = do_QueryInterface(contextWrapper);
|
||||
trans->SetTransferData(kHTMLContext, genericDataObj, parents.Length()*2);
|
||||
genericDataObj = do_QueryInterface(infoWrapper);
|
||||
trans->SetTransferData(kHTMLInfo, genericDataObj, info.Length()*2);
|
||||
}
|
||||
else
|
||||
{
|
||||
trans->SetTransferData(kUnicodeMime, genericDataObj, buffer.Length()*2);
|
||||
}
|
||||
// put the transferable on the clipboard
|
||||
clipboard->SetData(trans, nsnull, aClipboardID);
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
}
|
33
layout/base/src/nsCopySupport.h
Normal file
33
layout/base/src/nsCopySupport.h
Normal file
@ -0,0 +1,33 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape 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/NPL/
|
||||
*
|
||||
* 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 Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "nscore.h"
|
||||
#include "nsCOMPtr.h"
|
||||
|
||||
class nsISelection;
|
||||
class nsIDocument;
|
||||
|
||||
class nsCopySupport
|
||||
{
|
||||
// class of static helper functions for copy support
|
||||
public:
|
||||
static nsresult HTMLCopy(nsISelection *aSel, nsIDocument *aDoc, PRInt16 aClipboardID);
|
||||
};
|
@ -92,6 +92,7 @@ public:
|
||||
NS_IMETHOD SetRange(nsIDOMRange* aRange);
|
||||
NS_IMETHOD SetWrapColumn(PRUint32 aWC);
|
||||
NS_IMETHOD SetCharset(const nsAReadableString& aCharset);
|
||||
NS_IMETHOD GetMimeType(nsAWritableString& aMimeType);
|
||||
NS_IMETHOD EncodeToStream(nsIOutputStream* aStream);
|
||||
NS_IMETHOD EncodeToString(nsAWritableString& aOutputString);
|
||||
NS_IMETHOD EncodeToStringWithContext(nsAWritableString& aEncodedString,
|
||||
@ -224,6 +225,14 @@ nsDocumentEncoder::SetCharset(const nsAReadableString& aCharset)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDocumentEncoder::GetMimeType(nsAWritableString& aMimeType)
|
||||
{
|
||||
aMimeType = mMimeType;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
PRBool
|
||||
nsDocumentEncoder::IncludeInContext(nsIDOMNode *aNode)
|
||||
{
|
||||
@ -803,9 +812,7 @@ nsDocumentEncoder::SerializeRangeToString(nsIDOMRange *aRange,
|
||||
|
||||
if (!mCommonParent)
|
||||
return NS_OK;
|
||||
|
||||
AdjustCommonParent(address_of(mCommonParent));
|
||||
|
||||
|
||||
aRange->GetStartContainer(getter_AddRefs(startParent));
|
||||
NS_ENSURE_TRUE(startParent, NS_ERROR_FAILURE);
|
||||
aRange->GetStartOffset(&startOffset);
|
||||
@ -1061,12 +1068,34 @@ nsHTMLCopyEncoder::SetSelection(nsISelection* aSelection)
|
||||
// check for text widgets: we need to recognize these so that
|
||||
// we don't tweak the selection to be outside of the magic
|
||||
// div that ender-lite text widgets are embedded in.
|
||||
nsCOMPtr<nsIDOMNode> selNode;
|
||||
nsresult rv = aSelection->GetFocusNode(getter_AddRefs(selNode));
|
||||
|
||||
if (!aSelection)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
nsCOMPtr<nsIDOMRange> range;
|
||||
nsCOMPtr<nsIDOMNode> commonParent;
|
||||
PRInt32 count = 0;
|
||||
|
||||
nsresult rv = aSelection->GetRangeCount(&count);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
nsCOMPtr<nsIContent> tmp, selContent( do_QueryInterface(selNode) );
|
||||
|
||||
// if selection is uninitialized return
|
||||
if (!count)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
// we'll just use the common parent of the first range. Implicit assumption
|
||||
// here that multi-range selections are table cell selections, in which case
|
||||
// the common parent is somewhere in the table and we don't really care where.
|
||||
rv = aSelection->GetRangeAt(0, getter_AddRefs(range));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (!range)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
range->GetCommonAncestorContainer(getter_AddRefs(commonParent));
|
||||
|
||||
nsCOMPtr<nsIContent> tmp, selContent( do_QueryInterface(commonParent) );
|
||||
while (selContent)
|
||||
{
|
||||
// checking for selection inside a plaintext form widget
|
||||
nsCOMPtr<nsIAtom> atom;
|
||||
selContent->GetTag(*getter_AddRefs(atom));
|
||||
if (atom.get() == nsHTMLAtoms::input ||
|
||||
@ -1214,15 +1243,28 @@ nsHTMLCopyEncoder::IncludeInContext(nsIDOMNode *aNode)
|
||||
|
||||
content->GetTag(*getter_AddRefs(tag));
|
||||
|
||||
if (tag.get() == nsHTMLAtoms::b ||
|
||||
tag.get() == nsHTMLAtoms::i ||
|
||||
tag.get() == nsHTMLAtoms::u ||
|
||||
tag.get() == nsHTMLAtoms::pre ||
|
||||
tag.get() == nsHTMLAtoms::h1 ||
|
||||
tag.get() == nsHTMLAtoms::h2 ||
|
||||
tag.get() == nsHTMLAtoms::h3 ||
|
||||
tag.get() == nsHTMLAtoms::h4 ||
|
||||
tag.get() == nsHTMLAtoms::h5 ||
|
||||
if (tag.get() == nsHTMLAtoms::b ||
|
||||
tag.get() == nsHTMLAtoms::i ||
|
||||
tag.get() == nsHTMLAtoms::u ||
|
||||
tag.get() == nsHTMLAtoms::tt ||
|
||||
tag.get() == nsHTMLAtoms::s ||
|
||||
tag.get() == nsHTMLAtoms::strike ||
|
||||
tag.get() == nsHTMLAtoms::em ||
|
||||
tag.get() == nsHTMLAtoms::strong ||
|
||||
tag.get() == nsHTMLAtoms::dfn ||
|
||||
tag.get() == nsHTMLAtoms::code ||
|
||||
tag.get() == nsHTMLAtoms::cite ||
|
||||
tag.get() == nsHTMLAtoms::variable ||
|
||||
tag.get() == nsHTMLAtoms::abbr ||
|
||||
tag.get() == nsHTMLAtoms::font ||
|
||||
tag.get() == nsHTMLAtoms::script ||
|
||||
tag.get() == nsHTMLAtoms::span ||
|
||||
tag.get() == nsHTMLAtoms::pre ||
|
||||
tag.get() == nsHTMLAtoms::h1 ||
|
||||
tag.get() == nsHTMLAtoms::h2 ||
|
||||
tag.get() == nsHTMLAtoms::h3 ||
|
||||
tag.get() == nsHTMLAtoms::h4 ||
|
||||
tag.get() == nsHTMLAtoms::h5 ||
|
||||
tag.get() == nsHTMLAtoms::h6) {
|
||||
return PR_TRUE;
|
||||
}
|
||||
@ -1515,7 +1557,9 @@ nsHTMLCopyEncoder::IsRoot(nsIDOMNode* aNode)
|
||||
if (mIsTextWidget)
|
||||
return (IsTag(aNode, nsHTMLAtoms::div));
|
||||
else
|
||||
return (IsTag(aNode, nsHTMLAtoms::body));
|
||||
return (IsTag(aNode, nsHTMLAtoms::body) ||
|
||||
IsTag(aNode, nsHTMLAtoms::td) ||
|
||||
IsTag(aNode, nsHTMLAtoms::th));
|
||||
}
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
@ -119,6 +119,8 @@ HTML_ATOM(dt, "dt")
|
||||
|
||||
HTML_ATOM(datetime, "datetime")
|
||||
HTML_ATOM(data, "data")
|
||||
HTML_ATOM(dfn, "dfn")
|
||||
HTML_ATOM(em, "em")
|
||||
HTML_ATOM(embed, "embed")
|
||||
HTML_ATOM(encoding, "encoding")
|
||||
HTML_ATOM(enctype, "enctype")
|
||||
@ -224,6 +226,7 @@ HTML_ATOM(rightpadding, "rightpadding")
|
||||
HTML_ATOM(rows, "rows")
|
||||
HTML_ATOM(rowspan, "rowspan")
|
||||
HTML_ATOM(rules, "rules")
|
||||
HTML_ATOM(s, "s")
|
||||
HTML_ATOM(scheme, "scheme")
|
||||
HTML_ATOM(scope, "scope")
|
||||
HTML_ATOM(script, "script")
|
||||
@ -238,6 +241,8 @@ HTML_ATOM(span, "span")
|
||||
HTML_ATOM(src, "src")
|
||||
HTML_ATOM(standby, "standby")
|
||||
HTML_ATOM(start, "start")
|
||||
HTML_ATOM(strike, "strike")
|
||||
HTML_ATOM(strong, "strong")
|
||||
HTML_ATOM(style, "style")
|
||||
HTML_ATOM(summary, "summary")
|
||||
HTML_ATOM(suppress, "suppress")
|
||||
@ -264,6 +269,7 @@ HTML_ATOM(title, "title")
|
||||
HTML_ATOM(top, "top")
|
||||
HTML_ATOM(toppadding, "toppadding")
|
||||
HTML_ATOM(tr, "tr")
|
||||
HTML_ATOM(tt, "tt")
|
||||
HTML_ATOM(type, "type")
|
||||
HTML_ATOM(u, "u")
|
||||
HTML_ATOM(ul, "ul")
|
||||
|
@ -117,8 +117,6 @@
|
||||
// Drag & Drop, Clipboard
|
||||
#include "nsWidgetsCID.h"
|
||||
#include "nsIClipboard.h"
|
||||
#include "nsITransferable.h"
|
||||
#include "nsIFormatConverter.h"
|
||||
#include "nsIDocShellTreeItem.h"
|
||||
#include "nsIURI.h"
|
||||
#include "nsIEventQueue.h"
|
||||
@ -126,8 +124,8 @@
|
||||
#include "nsIScrollableFrame.h"
|
||||
#include "prtime.h"
|
||||
#include "prlong.h"
|
||||
#include "nsIDocumentEncoder.h"
|
||||
#include "nsIDragService.h"
|
||||
#include "nsCopySupport.h"
|
||||
|
||||
// Dummy layout request
|
||||
#include "nsIChannel.h"
|
||||
@ -168,10 +166,6 @@ static nsresult CtlStyleWatch(PRUint32 aCtlValue, nsIStyleSet *aStyleSet);
|
||||
#define kStyleWatchStop 16
|
||||
#define kStyleWatchReset 32
|
||||
|
||||
// private clipboard data flavors for html copy, used by editor when pasting
|
||||
#define kHTMLContext "text/_moz_htmlcontext"
|
||||
#define kHTMLInfo "text/_moz_htmlinfo"
|
||||
|
||||
// Class ID's
|
||||
static NS_DEFINE_CID(kFrameSelectionCID, NS_FRAMESELECTION_CID);
|
||||
static NS_DEFINE_CID(kCRangeCID, NS_RANGE_CID);
|
||||
@ -3572,9 +3566,7 @@ PresShell::DoCopy()
|
||||
if (!doc) return NS_ERROR_FAILURE;
|
||||
|
||||
nsresult rv;
|
||||
|
||||
nsCOMPtr<nsISelection> sel;
|
||||
|
||||
nsCOMPtr<nsIEventStateManager> manager;
|
||||
nsCOMPtr<nsIContent> content;
|
||||
rv = mPresContext->GetEventStateManager(getter_AddRefs(manager));
|
||||
@ -3612,74 +3604,11 @@ PresShell::DoCopy()
|
||||
if (isCollapsed)
|
||||
return NS_OK;
|
||||
|
||||
nsCOMPtr<nsIDocumentEncoder> docEncoder;
|
||||
|
||||
docEncoder = do_CreateInstance(NS_HTMLCOPY_ENCODER_CONTRACTID);
|
||||
NS_ENSURE_TRUE(docEncoder, NS_ERROR_FAILURE);
|
||||
|
||||
docEncoder->Init(doc, NS_LITERAL_STRING("text/html"), 0);
|
||||
docEncoder->SetSelection(sel);
|
||||
|
||||
nsAutoString buffer, parents, info;
|
||||
|
||||
rv = docEncoder->EncodeToStringWithContext(buffer, parents, info);
|
||||
if (NS_FAILED(rv))
|
||||
// call the copy code
|
||||
rv = nsCopySupport::HTMLCopy(sel, doc, nsIClipboard::kGlobalClipboard);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
// Get the Clipboard
|
||||
NS_WITH_SERVICE(nsIClipboard, clipboard, kCClipboardCID, &rv);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
if ( clipboard )
|
||||
{
|
||||
// Create a transferable for putting data on the Clipboard
|
||||
nsCOMPtr<nsITransferable> trans;
|
||||
rv = nsComponentManager::CreateInstance(kCTransferableCID, nsnull,
|
||||
NS_GET_IID(nsITransferable),
|
||||
getter_AddRefs(trans));
|
||||
if ( trans )
|
||||
{
|
||||
// set up the data converter
|
||||
nsCOMPtr<nsIFormatConverter> htmlConverter = do_CreateInstance(kHTMLConverterCID);
|
||||
NS_ENSURE_TRUE(htmlConverter, NS_ERROR_FAILURE);
|
||||
trans->SetConverter(htmlConverter);
|
||||
|
||||
// Add the html DataFlavor to the transferable
|
||||
trans->AddDataFlavor(kHTMLMime);
|
||||
// Add the htmlcontext DataFlavor to the transferable
|
||||
trans->AddDataFlavor(kHTMLContext);
|
||||
// Add the htmlinfo DataFlavor to the transferable
|
||||
trans->AddDataFlavor(kHTMLInfo);
|
||||
|
||||
// get wStrings to hold clip data
|
||||
nsCOMPtr<nsISupportsWString> dataWrapper, contextWrapper, infoWrapper;
|
||||
dataWrapper = do_CreateInstance(NS_SUPPORTS_WSTRING_CONTRACTID);
|
||||
NS_ENSURE_TRUE(dataWrapper, NS_ERROR_FAILURE);
|
||||
contextWrapper = do_CreateInstance(NS_SUPPORTS_WSTRING_CONTRACTID);
|
||||
NS_ENSURE_TRUE(contextWrapper, NS_ERROR_FAILURE);
|
||||
infoWrapper = do_CreateInstance(NS_SUPPORTS_WSTRING_CONTRACTID);
|
||||
NS_ENSURE_TRUE(infoWrapper, NS_ERROR_FAILURE);
|
||||
|
||||
// populate the strings
|
||||
dataWrapper->SetData ( NS_CONST_CAST(PRUnichar*,buffer.GetUnicode()) );
|
||||
contextWrapper->SetData ( NS_CONST_CAST(PRUnichar*,parents.GetUnicode()) );
|
||||
infoWrapper->SetData ( NS_CONST_CAST(PRUnichar*,info.GetUnicode()) );
|
||||
|
||||
// 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) );
|
||||
trans->SetTransferData(kHTMLMime, genericDataObj, buffer.Length()*2);
|
||||
genericDataObj = do_QueryInterface(contextWrapper);
|
||||
trans->SetTransferData(kHTMLContext, genericDataObj, parents.Length()*2);
|
||||
genericDataObj = do_QueryInterface(infoWrapper);
|
||||
trans->SetTransferData(kHTMLInfo, genericDataObj, info.Length()*2);
|
||||
|
||||
// put the transferable on the clipboard
|
||||
clipboard->SetData(trans, nsnull, nsIClipboard::kGlobalClipboard);
|
||||
}
|
||||
}
|
||||
|
||||
// Now that we have copied, update the Paste menu item
|
||||
nsCOMPtr<nsIScriptGlobalObject> globalObject;
|
||||
doc->GetScriptGlobalObject(getter_AddRefs(globalObject));
|
||||
|
Binary file not shown.
Loading…
Reference in New Issue
Block a user