diff --git a/content/base/public/nsCopySupport.h b/content/base/public/nsCopySupport.h new file mode 100644 index 000000000000..5413afb47a25 --- /dev/null +++ b/content/base/public/nsCopySupport.h @@ -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); +}; \ No newline at end of file diff --git a/content/base/public/nsIDocumentEncoder.h b/content/base/public/nsIDocumentEncoder.h index dc19df81f7d1..d36f53b2715d 100644 --- a/content/base/public/nsIDocumentEncoder.h +++ b/content/base/public/nsIDocumentEncoder.h @@ -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. diff --git a/content/base/src/nsCopySupport.cpp b/content/base/src/nsCopySupport.cpp new file mode 100644 index 000000000000..3d1f013acc5d --- /dev/null +++ b/content/base/src/nsCopySupport.cpp @@ -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 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 trans = do_CreateInstance(kCTransferableCID); + if ( trans ) + { + if (bIsHTMLCopy) + { + // set up the data converter + nsCOMPtr 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 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 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; +} diff --git a/content/base/src/nsDocumentEncoder.cpp b/content/base/src/nsDocumentEncoder.cpp index d985b0ee2aa1..5f18a6b3750f 100644 --- a/content/base/src/nsDocumentEncoder.cpp +++ b/content/base/src/nsDocumentEncoder.cpp @@ -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 selNode; - nsresult rv = aSelection->GetFocusNode(getter_AddRefs(selNode)); + + if (!aSelection) + return NS_ERROR_NULL_POINTER; + + nsCOMPtr range; + nsCOMPtr commonParent; + PRInt32 count = 0; + + nsresult rv = aSelection->GetRangeCount(&count); NS_ENSURE_SUCCESS(rv, rv); - nsCOMPtr 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 tmp, selContent( do_QueryInterface(commonParent) ); while (selContent) { + // checking for selection inside a plaintext form widget nsCOMPtr 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; } diff --git a/content/html/content/src/nsHTMLAtomList.h b/content/html/content/src/nsHTMLAtomList.h index ae48edf0a086..2c111301b75d 100644 --- a/content/html/content/src/nsHTMLAtomList.h +++ b/content/html/content/src/nsHTMLAtomList.h @@ -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") diff --git a/content/shared/public/nsHTMLAtomList.h b/content/shared/public/nsHTMLAtomList.h index ae48edf0a086..2c111301b75d 100644 --- a/content/shared/public/nsHTMLAtomList.h +++ b/content/shared/public/nsHTMLAtomList.h @@ -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") diff --git a/layout/base/nsAutoCopy.cpp b/layout/base/nsAutoCopy.cpp index e19b0a5c10fd..d20491b58fec 100644 --- a/layout/base/nsAutoCopy.cpp +++ b/layout/base/nsAutoCopy.cpp @@ -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 mClipboard; - nsCOMPtr mTransferable; - nsCOMPtr 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 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 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 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 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 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; } diff --git a/layout/base/nsPresShell.cpp b/layout/base/nsPresShell.cpp index 9e4fd957de0d..fe253ae61434 100644 --- a/layout/base/nsPresShell.cpp +++ b/layout/base/nsPresShell.cpp @@ -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 sel; - nsCOMPtr manager; nsCOMPtr content; rv = mPresContext->GetEventStateManager(getter_AddRefs(manager)); @@ -3612,74 +3604,11 @@ PresShell::DoCopy() if (isCollapsed) return NS_OK; - nsCOMPtr 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 trans; - rv = nsComponentManager::CreateInstance(kCTransferableCID, nsnull, - NS_GET_IID(nsITransferable), - getter_AddRefs(trans)); - if ( trans ) - { - // set up the data converter - nsCOMPtr 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 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 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 globalObject; doc->GetScriptGlobalObject(getter_AddRefs(globalObject)); diff --git a/layout/base/public/nsIDocumentEncoder.h b/layout/base/public/nsIDocumentEncoder.h index dc19df81f7d1..d36f53b2715d 100644 --- a/layout/base/public/nsIDocumentEncoder.h +++ b/layout/base/public/nsIDocumentEncoder.h @@ -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. diff --git a/layout/base/src/Makefile.in b/layout/base/src/Makefile.in index d301c3422b4c..125641becb99 100644 --- a/layout/base/src/Makefile.in +++ b/layout/base/src/Makefile.in @@ -37,6 +37,7 @@ CPPSRCS = \ nsContentIterator.cpp \ nsContentList.cpp \ nsContentPolicy.cpp \ + nsCopySupport.cpp \ nsDocument.cpp \ nsDocumentEncoder.cpp \ nsDocumentFragment.cpp \ diff --git a/layout/base/src/makefile.win b/layout/base/src/makefile.win index 31747e4bf129..23d38c5cbb15 100644 --- a/layout/base/src/makefile.win +++ b/layout/base/src/makefile.win @@ -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 \ diff --git a/layout/base/src/nsAutoCopy.cpp b/layout/base/src/nsAutoCopy.cpp index e19b0a5c10fd..d20491b58fec 100644 --- a/layout/base/src/nsAutoCopy.cpp +++ b/layout/base/src/nsAutoCopy.cpp @@ -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 mClipboard; - nsCOMPtr mTransferable; - nsCOMPtr 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 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 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 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 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 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; } diff --git a/layout/base/src/nsCopySupport.cpp b/layout/base/src/nsCopySupport.cpp new file mode 100644 index 000000000000..3d1f013acc5d --- /dev/null +++ b/layout/base/src/nsCopySupport.cpp @@ -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 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 trans = do_CreateInstance(kCTransferableCID); + if ( trans ) + { + if (bIsHTMLCopy) + { + // set up the data converter + nsCOMPtr 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 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 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; +} diff --git a/layout/base/src/nsCopySupport.h b/layout/base/src/nsCopySupport.h new file mode 100644 index 000000000000..5413afb47a25 --- /dev/null +++ b/layout/base/src/nsCopySupport.h @@ -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); +}; \ No newline at end of file diff --git a/layout/base/src/nsDocumentEncoder.cpp b/layout/base/src/nsDocumentEncoder.cpp index d985b0ee2aa1..5f18a6b3750f 100644 --- a/layout/base/src/nsDocumentEncoder.cpp +++ b/layout/base/src/nsDocumentEncoder.cpp @@ -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 selNode; - nsresult rv = aSelection->GetFocusNode(getter_AddRefs(selNode)); + + if (!aSelection) + return NS_ERROR_NULL_POINTER; + + nsCOMPtr range; + nsCOMPtr commonParent; + PRInt32 count = 0; + + nsresult rv = aSelection->GetRangeCount(&count); NS_ENSURE_SUCCESS(rv, rv); - nsCOMPtr 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 tmp, selContent( do_QueryInterface(commonParent) ); while (selContent) { + // checking for selection inside a plaintext form widget nsCOMPtr 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; } diff --git a/layout/html/base/src/nsHTMLAtomList.h b/layout/html/base/src/nsHTMLAtomList.h index ae48edf0a086..2c111301b75d 100644 --- a/layout/html/base/src/nsHTMLAtomList.h +++ b/layout/html/base/src/nsHTMLAtomList.h @@ -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") diff --git a/layout/html/base/src/nsPresShell.cpp b/layout/html/base/src/nsPresShell.cpp index 9e4fd957de0d..fe253ae61434 100644 --- a/layout/html/base/src/nsPresShell.cpp +++ b/layout/html/base/src/nsPresShell.cpp @@ -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 sel; - nsCOMPtr manager; nsCOMPtr content; rv = mPresContext->GetEventStateManager(getter_AddRefs(manager)); @@ -3612,74 +3604,11 @@ PresShell::DoCopy() if (isCollapsed) return NS_OK; - nsCOMPtr 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 trans; - rv = nsComponentManager::CreateInstance(kCTransferableCID, nsnull, - NS_GET_IID(nsITransferable), - getter_AddRefs(trans)); - if ( trans ) - { - // set up the data converter - nsCOMPtr 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 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 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 globalObject; doc->GetScriptGlobalObject(getter_AddRefs(globalObject)); diff --git a/layout/macbuild/layout.mcp b/layout/macbuild/layout.mcp index 496950c01371..e3e1b73588d6 100644 Binary files a/layout/macbuild/layout.mcp and b/layout/macbuild/layout.mcp differ