Diff
Modified: trunk/Source/WebCore/ChangeLog (154835 => 154836)
--- trunk/Source/WebCore/ChangeLog 2013-08-29 20:06:33 UTC (rev 154835)
+++ trunk/Source/WebCore/ChangeLog 2013-08-29 20:09:21 UTC (rev 154836)
@@ -1,3 +1,41 @@
+2013-08-29 Darin Adler <[email protected]>
+
+ Pasteboard::writeSelection violates layering (first step, fixes it for Mac platform only)
+ https://bugs.webkit.org/show_bug.cgi?id=120483
+
+ Reviewed by Anders Carlsson.
+
+ * editing/Editor.cpp:
+ (WebCore::Editor::cut): Added some comments. Use the new writeSelectionToPasteboard
+ function on Mac instead of Pasteboard::writeSelection.
+ (WebCore::Editor::copy): Ditto.
+
+ * editing/Editor.h: Removed an old unused Mac-only writeSelectionToPasteboard function
+ that was a cover that called through to Pasteboard::writeSelectionForTypes. Added a new
+ Mac-only writeSelectionToPasteboard function that is destined to become cross-platform soon.
+
+ * editing/mac/EditorMac.mm:
+ (WebCore::Editor::writeSelectionToPasteboard): Added. Uses a new pattern where the Editor
+ puts all the data into a structure called PasteboardWebContent then calls the Pasteboard to
+ do the work. The platform-specific aspect of PasteboardWebContent is what formats are needed
+ for each platform.
+
+ * page/DragController.cpp:
+ (WebCore::DragController::startDrag): Added some comments. Use the new writeSelectionToPasteboard
+ function on Mac instead of Pasteboard::writeSelection.
+
+ * platform/Pasteboard.h: Remove some unneeded forward declarations. Added comments for all functions
+ that don't belong in this class because they are layering violations; this becomes the to do list for
+ the project we are beginning here. Added the new PasteboardWebContent structure, empty on all platforms
+ except for Mac for now. Removed writeSelectionForTypes, a Mac-only function that is no longer used.
+ Added setTypes and writeAfterSettingTypes, the two halves of the future function named writeWebContent.
+ Put the writeSelection function inside a "not Mac" if statement. Later to be deleted entirely.
+
+ * platform/mac/PasteboardMac.mm: Removed now-unneeded selectionPasteboardTypes,
+ Pasteboard::writeSelectionForTypes, and writeSelection functions.
+ (WebCore::Pasteboard::setTypes): Added. First half of writing web content to the pasteboard.
+ (WebCore::Pasteboard::writeAfterSettingTypes): Added. Second half of writing web content to the pasteboard.
+
2013-08-29 Antti Koivisto <[email protected]>
Remove code behind ENABLE(DIALOG_ELEMENT)
Modified: trunk/Source/WebCore/editing/Editor.cpp (154835 => 154836)
--- trunk/Source/WebCore/editing/Editor.cpp 2013-08-29 20:06:33 UTC (rev 154835)
+++ trunk/Source/WebCore/editing/Editor.cpp 2013-08-29 20:09:21 UTC (rev 154836)
@@ -1037,15 +1037,22 @@
systemBeep();
return;
}
+
+ // FIXME: This should share more code with the copy function; there is a lot of overlap.
RefPtr<Range> selection = selectedRange();
willWriteSelectionToPasteboard(selection);
if (shouldDeleteRange(selection.get())) {
updateMarkersForWordsAffectedByEditing(true);
- if (enclosingTextFormControl(m_frame.selection().start())) {
- Pasteboard::createForCopyAndPaste()->writePlainText(selectedTextForClipboard(),
- canSmartCopyOrDelete() ? Pasteboard::CanSmartReplace : Pasteboard::CannotSmartReplace);
- } else
+ if (enclosingTextFormControl(m_frame.selection().start()))
+ Pasteboard::createForCopyAndPaste()->writePlainText(selectedTextForClipboard(), canSmartCopyOrDelete() ? Pasteboard::CanSmartReplace : Pasteboard::CannotSmartReplace);
+ else {
+#if PLATFORM(MAC) && !PLATFORM(IOS)
+ writeSelectionToPasteboard(*Pasteboard::createForCopyAndPaste());
+#else
+ // FIXME: Convert all other platforms to match Mac and delete this.
Pasteboard::createForCopyAndPaste()->writeSelection(selection.get(), canSmartCopyOrDelete(), &m_frame, IncludeImageAltTextForClipboard);
+#endif
+ }
didWriteSelectionToPasteboard();
deleteSelectionWithSmartDelete(canSmartCopyOrDelete());
}
@@ -1068,8 +1075,14 @@
Document* document = m_frame.document();
if (HTMLImageElement* imageElement = imageElementFromImageDocument(document))
Pasteboard::createForCopyAndPaste()->writeImage(imageElement, document->url(), document->title());
- else
+ else {
+#if PLATFORM(MAC) && !PLATFORM(IOS)
+ writeSelectionToPasteboard(*Pasteboard::createForCopyAndPaste());
+#else
+ // FIXME: Convert all other platforms to match Mac and delete this.
Pasteboard::createForCopyAndPaste()->writeSelection(selectedRange().get(), canSmartCopyOrDelete(), &m_frame, IncludeImageAltTextForClipboard);
+#endif
+ }
}
didWriteSelectionToPasteboard();
@@ -3127,6 +3140,6 @@
{
m_overwriteModeEnabled = !m_overwriteModeEnabled;
m_frame.selection().setShouldShowBlockCursor(m_overwriteModeEnabled);
-};
+}
} // namespace WebCore
Modified: trunk/Source/WebCore/editing/Editor.h (154835 => 154836)
--- trunk/Source/WebCore/editing/Editor.h 2013-08-29 20:06:33 UTC (rev 154835)
+++ trunk/Source/WebCore/editing/Editor.h 2013-08-29 20:09:21 UTC (rev 154836)
@@ -41,18 +41,15 @@
#include "VisibleSelection.h"
#include "WritingDirection.h"
-#if PLATFORM(MAC) && !defined(__OBJC__)
-class NSDictionary;
-typedef int NSWritingDirection;
+#if PLATFORM(MAC)
+OBJC_CLASS NSDictionary;
#endif
namespace WebCore {
class Clipboard;
class CompositeEditCommand;
-#if ENABLE(DELETION_UI)
class DeleteButtonController;
-#endif
class EditCommand;
class EditCommandComposition;
class EditorClient;
@@ -251,6 +248,7 @@
void lowercaseWord();
void capitalizeWord();
#endif
+
#if USE(AUTOMATIC_TEXT_REPLACEMENT)
void showSubstitutionsPanel();
bool substitutionsPanelIsShowing();
@@ -287,7 +285,7 @@
void didEndEditing();
void willWriteSelectionToPasteboard(PassRefPtr<Range>);
void didWriteSelectionToPasteboard();
-
+
void showFontPanel();
void showStylesPanel();
void showColorPanel();
@@ -392,7 +390,7 @@
NSDictionary* fontAttributesForSelectionStart() const;
bool canCopyExcludingStandaloneImages();
void takeFindStringFromSelection();
- void writeSelectionToPasteboard(const String& pasteboardName, const Vector<String>& pasteboardTypes);
+ void writeSelectionToPasteboard(Pasteboard&);
void readSelectionFromPasteboard(const String& pasteboardName);
String stringSelectionForPasteboard();
String stringSelectionForPasteboardWithImageAltText();
@@ -413,6 +411,7 @@
void setDefaultParagraphSeparator(EditorParagraphSeparator separator) { m_defaultParagraphSeparator = separator; }
Vector<String> dictationAlternativesForMarker(const DocumentMarker*);
void applyDictationAlternativelternative(const String& alternativeString);
+
private:
explicit Editor(Frame&);
Modified: trunk/Source/WebCore/editing/mac/EditorMac.mm (154835 => 154836)
--- trunk/Source/WebCore/editing/mac/EditorMac.mm 2013-08-29 20:06:33 UTC (rev 154835)
+++ trunk/Source/WebCore/editing/mac/EditorMac.mm 2013-08-29 20:09:21 UTC (rev 154836)
@@ -243,12 +243,6 @@
platformStrategies()->pasteboardStrategy()->setStringForType(m_frame.displayStringModifiedByEncoding(selectedTextForClipboard()), NSStringPboardType, NSFindPboard);
}
-void Editor::writeSelectionToPasteboard(const String& pasteboardName, const Vector<String>& pasteboardTypes)
-{
- Pasteboard pasteboard(pasteboardName);
- pasteboard.writeSelectionForTypes(pasteboardTypes, true, &m_frame, DefaultSelectedTextType);
-}
-
void Editor::readSelectionFromPasteboard(const String& pasteboardName)
{
Pasteboard pasteboard(pasteboardName);
@@ -279,4 +273,23 @@
return Pasteboard::getDataSelection(&m_frame, pasteboardType);
}
+void Editor::writeSelectionToPasteboard(Pasteboard& pasteboard)
+{
+ PasteboardWebContent content;
+ content.canSmartCopyOrDelete = canSmartCopyOrDelete();
+ if (RefPtr<LegacyWebArchive> webArchive = LegacyWebArchive::createFromSelection(&m_frame))
+ content.dataInWebArchiveFormat = SharedBuffer::wrapCFData(webArchive->rawDataRepresentation().get());
+ if (NSAttributedString *attributedString = [adoptNS([[WebHTMLConverter alloc] initWithDOMRange:kit(selectedRange().get())]) attributedString]) {
+ if ([attributedString containsAttachments])
+ content.dataInRTFDFormat = SharedBuffer::wrapNSData([attributedString RTFDFromRange:NSMakeRange(0, [attributedString length]) documentAttributes:nil]);
+ content.dataInRTFFormat = SharedBuffer::wrapNSData([attributedString RTFFromRange:NSMakeRange(0, [attributedString length]) documentAttributes:nil]);
+ }
+ content.dataInStringFormat = stringSelectionForPasteboardWithImageAltText();
+ client()->getClientPasteboardDataForRange(selectedRange().get(), content.clientTypes, content.clientData);
+
+ pasteboard.setTypes(content);
+ client()->didSetSelectionTypesForPasteboard();
+ pasteboard.writeAfterSettingTypes(content);
+}
+
} // namespace WebCore
Modified: trunk/Source/WebCore/page/DragController.cpp (154835 => 154836)
--- trunk/Source/WebCore/page/DragController.cpp 2013-08-29 20:06:33 UTC (rev 154835)
+++ trunk/Source/WebCore/page/DragController.cpp 2013-08-29 20:09:21 UTC (rev 154836)
@@ -785,6 +785,8 @@
Image* image = getImage(element);
if (state.type == DragSourceActionSelection) {
if (!clipboard->pasteboard().hasData()) {
+ // FIXME: This entire block is almost identical to the code in Editor::copy, and the code should be shared.
+
RefPtr<Range> selectionRange = src->selection().toNormalizedRange();
ASSERT(selectionRange);
@@ -793,8 +795,12 @@
if (enclosingTextFormControl(src->selection().start()))
clipboard->pasteboard().writePlainText(src->editor().selectedTextForClipboard(), Pasteboard::CannotSmartReplace);
else {
- // FIXME: Could this instead be a helper function in Editor?
- clipboard->pasteboard().writeSelection(selectionRange.get(), src->editor().smartInsertDeleteEnabled() && src->selection().granularity() == WordGranularity, src, IncludeImageAltTextForClipboard);
+#if PLATFORM(MAC)
+ src->editor().writeSelectionToPasteboard(clipboard->pasteboard());
+#else
+ // FIXME: Convert all other platforms to match Mac and delete this.
+ clipboard->pasteboard().writeSelection(selectionRange.get(), src->editor().canSmartCopyOrDelete(), src, IncludeImageAltTextForClipboard);
+#endif
}
src->editor().didWriteSelectionToPasteboard();
Modified: trunk/Source/WebCore/platform/Pasteboard.h (154835 => 154836)
--- trunk/Source/WebCore/platform/Pasteboard.h 2013-08-29 20:06:33 UTC (rev 154835)
+++ trunk/Source/WebCore/platform/Pasteboard.h 2013-08-29 20:09:21 UTC (rev 154836)
@@ -66,19 +66,30 @@
extern const char* WebURLsWithTitlesPboardType;
#endif
-class Clipboard;
class DocumentFragment;
class DragData;
class Element;
class Frame;
-class HitTestResult;
class KURL;
class Node;
class Range;
class SharedBuffer;
enum ShouldSerializeSelectedTextForClipboard { DefaultSelectedTextType, IncludeImageAltTextForClipboard };
-
+
+// For writing web content to the pasteboard. Generally sorted with the richest formats on top.
+struct PasteboardWebContent {
+#if PLATFORM(MAC) && !PLATFORM(IOS)
+ bool canSmartCopyOrDelete;
+ RefPtr<SharedBuffer> dataInWebArchiveFormat;
+ RefPtr<SharedBuffer> dataInRTFDFormat;
+ RefPtr<SharedBuffer> dataInRTFFormat;
+ String dataInStringFormat;
+ Vector<String> clientTypes;
+ Vector<RefPtr<SharedBuffer>> clientData;
+#endif
+};
+
class Pasteboard {
WTF_MAKE_NONCOPYABLE(Pasteboard); WTF_MAKE_FAST_ALLOCATED;
public:
@@ -91,9 +102,8 @@
static PassOwnPtr<Pasteboard> create(const String& pasteboardName);
String name() const { return m_pasteboardName; }
- void writeSelectionForTypes(const Vector<String>& pasteboardTypes, bool canSmartCopyOrDelete, Frame*, ShouldSerializeSelectedTextForClipboard);
explicit Pasteboard(const String& pasteboardName);
- static PassRefPtr<SharedBuffer> getDataSelection(Frame*, const String& pasteboardType);
+ static PassRefPtr<SharedBuffer> getDataSelection(Frame*, const String& pasteboardType); // FIXME: Layering violation.
#endif
#if PLATFORM(GTK)
@@ -124,16 +134,23 @@
String readString(const String& type);
Vector<String> readFilenames();
+ // FIXME: It would be nicer if the two functions below were just parts of a single writeWebContent function,
+ // but for now Mac supports an editor client call that happens after setting the types but before writing to the pasteboard.
+ void setTypes(const PasteboardWebContent&);
+ void writeAfterSettingTypes(const PasteboardWebContent&);
+
bool writeString(const String& type, const String& data);
- void writeSelection(Range*, bool canSmartCopyOrDelete, Frame*, ShouldSerializeSelectedTextForClipboard = DefaultSelectedTextType);
+#if !(PLATFORM(MAC) && !PLATFORM(IOS))
+ void writeSelection(Range*, bool canSmartCopyOrDelete, Frame*, ShouldSerializeSelectedTextForClipboard = DefaultSelectedTextType); // FIXME: Layering violation.
+#endif
void writeMarkup(const String& markup);
void writePlainText(const String&, SmartReplaceOption);
#if !PLATFORM(IOS)
- void writeURL(const KURL&, const String&, Frame* = 0);
- void writeImage(Node*, const KURL&, const String& title);
+ void writeURL(const KURL&, const String&, Frame* = 0); // FIXME: Layering violation.
+ void writeImage(Node*, const KURL&, const String& title); // FIXME: Layering violation.
#else
- void writeImage(Node*, Frame*);
- void writePlainText(const String&, Frame*);
+ void writeImage(Node*, Frame*); // FIXME: Layering violation.
+ void writePlainText(const String&, Frame*); // FIXME: Layering violation.
static NSArray* supportedPasteboardTypes();
#endif
void writePasteboard(const Pasteboard& sourcePasteboard);
@@ -147,14 +164,11 @@
void setDragImage(DragImageRef, const IntPoint& hotSpot);
#endif
- // FIXME: Having these functions here is a layering violation.
- // These functions need to move to the editing directory even if they have platform-specific aspects.
- PassRefPtr<DocumentFragment> documentFragment(Frame*, PassRefPtr<Range>, bool allowPlainText, bool& chosePlainText);
- String plainText(Frame* = 0);
+ PassRefPtr<DocumentFragment> documentFragment(Frame*, PassRefPtr<Range>, bool allowPlainText, bool& chosePlainText); // FIXME: Layering violation.
+ String plainText(Frame* = 0); // FIXME: Layering violation.
#if PLATFORM(IOS)
- // FIXME: Remove this once we switch to platform strategies instead of the editor client.
- void setFrame(Frame*);
+ void setFrame(Frame*); // FIXME: Layering violation.
#endif
#if PLATFORM(GTK) || PLATFORM(QT)
@@ -166,7 +180,7 @@
void setExternalDataObject(IDataObject*);
void writeURLToWritableDataObject(const KURL&, const String&);
COMPtr<WCDataObject> writableDataObject() const { return m_writableDataObject; }
- void writeImageToDataObject(Element*, const KURL&);
+ void writeImageToDataObject(Element*, const KURL&); // FIXME: Layering violation.
#endif
#if PLATFORM(GTK) || PLATFORM(QT)
@@ -197,16 +211,16 @@
#endif
#if PLATFORM(IOS)
- PassRefPtr<DocumentFragment> documentFragmentForPasteboardItemAtIndex(Frame*, int index, bool allowPlainText, bool& chosePlainText);
+ PassRefPtr<DocumentFragment> documentFragmentForPasteboardItemAtIndex(Frame*, int index, bool allowPlainText, bool& chosePlainText); // FIXME: Layering violation.
- Frame* m_frame;
+ Frame* m_frame; // FIXME: Layering violation.
long m_changeCount;
#endif
#if PLATFORM(WIN)
void finishCreatingPasteboard();
- void writeRangeToDataObject(Range*, Frame*);
- void writeURLToDataObject(const KURL&, const String&, Frame*);
+ void writeRangeToDataObject(Range*, Frame*); // FIXME: Layering violation.
+ void writeURLToDataObject(const KURL&, const String&, Frame*); // FIXME: Layering violation.
void writePlainTextToDataObject(const String&, SmartReplaceOption);
HWND m_owner;
Modified: trunk/Source/WebCore/platform/mac/PasteboardMac.mm (154835 => 154836)
--- trunk/Source/WebCore/platform/mac/PasteboardMac.mm 2013-08-29 20:06:33 UTC (rev 154835)
+++ trunk/Source/WebCore/platform/mac/PasteboardMac.mm 2013-08-29 20:09:21 UTC (rev 154836)
@@ -72,20 +72,6 @@
const char* WebURLPboardType = "public.url";
const char* WebURLsWithTitlesPboardType = "WebURLsWithTitlesPboardType";
-static Vector<String> selectionPasteboardTypes(bool canSmartCopyOrDelete, bool selectionContainsAttachments)
-{
- Vector<String> types;
- if (canSmartCopyOrDelete)
- types.append(WebSmartPastePboardType);
- types.append(WebArchivePboardType);
- if (selectionContainsAttachments)
- types.append(String(NSRTFDPboardType));
- types.append(String(NSRTFPboardType));
- types.append(String(NSStringPboardType));
-
- return types;
-}
-
static const Vector<String> writableTypesForURL()
{
Vector<String> types;
@@ -185,47 +171,40 @@
return 0;
}
-void Pasteboard::writeSelectionForTypes(const Vector<String>& pasteboardTypes, bool canSmartCopyOrDelete, Frame* frame, ShouldSerializeSelectedTextForClipboard shouldSerializeSelectedTextForClipboard)
+void Pasteboard::setTypes(const PasteboardWebContent& content)
{
- NSAttributedString* attributedString = nil;
- RetainPtr<WebHTMLConverter> converter = adoptNS([[WebHTMLConverter alloc] initWithDOMRange:kit(frame->editor().selectedRange().get())]);
- if (converter)
- attributedString = [converter.get() attributedString];
-
- Vector<String> types = !pasteboardTypes.isEmpty() ? pasteboardTypes : selectionPasteboardTypes(canSmartCopyOrDelete, [attributedString containsAttachments]);
+ Vector<String> types;
- Vector<String> clientTypes;
- Vector<RefPtr<SharedBuffer> > clientData;
- frame->editor().client()->getClientPasteboardDataForRange(frame->editor().selectedRange().get(), clientTypes, clientData);
- types.appendVector(clientTypes);
+ if (content.canSmartCopyOrDelete)
+ types.append(WebSmartPastePboardType);
+ if (content.dataInWebArchiveFormat)
+ types.append(WebArchivePboardType);
+ if (content.dataInRTFDFormat)
+ types.append(String(NSRTFDPboardType));
+ if (content.dataInRTFFormat)
+ types.append(String(NSRTFPboardType));
+ if (!content.dataInStringFormat.isNull())
+ types.append(String(NSStringPboardType));
+ types.appendVector(content.clientTypes);
m_changeCount = platformStrategies()->pasteboardStrategy()->setTypes(types, m_pasteboardName);
- frame->editor().client()->didSetSelectionTypesForPasteboard();
+}
- for (size_t i = 0; i < clientTypes.size(); ++i)
- m_changeCount = platformStrategies()->pasteboardStrategy()->setBufferForType(clientData[i], clientTypes[i], m_pasteboardName);
-
- // Put HTML on the pasteboard.
- if (types.contains(WebArchivePboardType))
- m_changeCount = platformStrategies()->pasteboardStrategy()->setBufferForType(getDataSelection(frame, WebArchivePboardType), WebArchivePboardType, m_pasteboardName);
-
- // Put the attributed string on the pasteboard (RTF/RTFD format).
- if (types.contains(String(NSRTFDPboardType)))
- m_changeCount = platformStrategies()->pasteboardStrategy()->setBufferForType(getDataSelection(frame, NSRTFDPboardType), NSRTFDPboardType, m_pasteboardName);
-
- if (types.contains(String(NSRTFPboardType)))
- m_changeCount = platformStrategies()->pasteboardStrategy()->setBufferForType(getDataSelection(frame, NSRTFPboardType), NSRTFPboardType, m_pasteboardName);
-
- // Put plain string on the pasteboard.
- if (types.contains(String(NSStringPboardType))) {
- String text = shouldSerializeSelectedTextForClipboard == IncludeImageAltTextForClipboard
- ? frame->editor().stringSelectionForPasteboardWithImageAltText()
- : frame->editor().stringSelectionForPasteboard();
- m_changeCount = platformStrategies()->pasteboardStrategy()->setStringForType(text, NSStringPboardType, m_pasteboardName);
- }
-
- if (types.contains(WebSmartPastePboardType))
+void Pasteboard::writeAfterSettingTypes(const PasteboardWebContent& content)
+{
+ ASSERT(content.clientTypes.size() == content.clientData.size());
+ for (size_t i = 0, size = content.clientTypes.size(); i < size; ++i)
+ m_changeCount = platformStrategies()->pasteboardStrategy()->setBufferForType(content.clientData[i], content.clientTypes[i], m_pasteboardName);
+ if (content.canSmartCopyOrDelete)
m_changeCount = platformStrategies()->pasteboardStrategy()->setBufferForType(0, WebSmartPastePboardType, m_pasteboardName);
+ if (content.dataInWebArchiveFormat)
+ m_changeCount = platformStrategies()->pasteboardStrategy()->setBufferForType(content.dataInWebArchiveFormat, WebArchivePboardType, m_pasteboardName);
+ if (content.dataInRTFDFormat)
+ m_changeCount = platformStrategies()->pasteboardStrategy()->setBufferForType(content.dataInRTFDFormat, NSRTFDPboardType, m_pasteboardName);
+ if (content.dataInRTFFormat)
+ m_changeCount = platformStrategies()->pasteboardStrategy()->setBufferForType(content.dataInRTFFormat, NSRTFPboardType, m_pasteboardName);
+ if (!content.dataInStringFormat.isNull())
+ m_changeCount = platformStrategies()->pasteboardStrategy()->setStringForType(content.dataInStringFormat, NSStringPboardType, m_pasteboardName);
}
void Pasteboard::writePlainText(const String& text, SmartReplaceOption smartReplaceOption)
@@ -240,11 +219,6 @@
if (smartReplaceOption == CanSmartReplace)
m_changeCount = platformStrategies()->pasteboardStrategy()->setBufferForType(0, WebSmartPastePboardType, m_pasteboardName);
}
-
-void Pasteboard::writeSelection(Range*, bool canSmartCopyOrDelete, Frame* frame, ShouldSerializeSelectedTextForClipboard shouldSerializeSelectedTextForClipboard)
-{
- writeSelectionForTypes(Vector<String>(), canSmartCopyOrDelete, frame, shouldSerializeSelectedTextForClipboard);
-}
static long writeURLForTypes(const Vector<String>& types, const String& pasteboardName, const KURL& url, const String& titleStr, Frame* frame)
{