[GTK] Fix layering violations in PasteboardGtk
authorcarlosgc@webkit.org <carlosgc@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 17 Sep 2014 07:05:45 +0000 (07:05 +0000)
committercarlosgc@webkit.org <carlosgc@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 17 Sep 2014 07:05:45 +0000 (07:05 +0000)
https://bugs.webkit.org/show_bug.cgi?id=136802

Reviewed by Darin Adler.

Source/WebCore:

Refactor the Pasteboard code moving the WebCore parts to the Editor.

* PlatformGTK.cmake: Add new file to compilation.
* editing/Editor.cpp:
(WebCore::Editor::performCutOrCopy):
(WebCore::Editor::copyImage):
* editing/Editor.h:
* editing/gtk/EditorGtk.cpp: Added.
(WebCore::createFragmentFromPasteBoardData):
(WebCore::Editor::pasteWithPasteboard):
(WebCore::getImageAndURLForElement):
(WebCore::Editor::writeImageToPasteboard):
(WebCore::Editor::writeSelectionToPasteboard):
* page/DragController.cpp:
(WebCore::DragController::startDrag):
* page/gtk/DragControllerGtk.cpp:
(WebCore::DragController::declareAndWriteDragImage):
* platform/Pasteboard.h:
* platform/gtk/DataObjectGtk.cpp: Remove range member, the caller
should call setText() + setMarkup() intead.
(WebCore::DataObjectGtk::setText):
(WebCore::DataObjectGtk::setMarkup):
(WebCore::DataObjectGtk::clearText):
(WebCore::DataObjectGtk::clearMarkup):
(WebCore::DataObjectGtk::clearAllExceptFilenames):
* platform/gtk/DataObjectGtk.h:
(WebCore::DataObjectGtk::hasText):
(WebCore::DataObjectGtk::hasMarkup):
(WebCore::DataObjectGtk::clearImage):
(WebCore::DataObjectGtk::text):
(WebCore::DataObjectGtk::markup):
(WebCore::DataObjectGtk::setRange): Deleted.
* platform/gtk/GtkDragAndDropHelper.h:
* platform/gtk/PasteboardGtk.cpp:
(WebCore::PasteboardImage::PasteboardImage):
(WebCore::PasteboardImage::~PasteboardImage):
(WebCore::Pasteboard::write):
(WebCore::Pasteboard::writeSelection): Deleted.
(WebCore::getURLForImageElement): Deleted.
(WebCore::Pasteboard::writeImage): Deleted.
(WebCore::Pasteboard::documentFragment): Deleted.
* platform/gtk/PasteboardHelper.cpp:
(WebCore::displayFromFrame): Deleted.
(WebCore::PasteboardHelper::getPrimarySelectionClipboard): Deleted.
* platform/gtk/PasteboardHelper.h:

Source/WebKit2:

* WebProcess/WebCoreSupport/gtk/WebEditorClientGtk.cpp:
(WebKit::WebEditorClient::updateGlobalSelection): Use new API to
update the global selection.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@173687 268f45cc-cd09-0410-ab3c-d52691b4dbfc

16 files changed:
Source/WebCore/ChangeLog
Source/WebCore/PlatformGTK.cmake
Source/WebCore/editing/Editor.cpp
Source/WebCore/editing/Editor.h
Source/WebCore/editing/gtk/EditorGtk.cpp [new file with mode: 0644]
Source/WebCore/page/DragController.cpp
Source/WebCore/page/gtk/DragControllerGtk.cpp
Source/WebCore/platform/Pasteboard.h
Source/WebCore/platform/gtk/DataObjectGtk.cpp
Source/WebCore/platform/gtk/DataObjectGtk.h
Source/WebCore/platform/gtk/GtkDragAndDropHelper.h
Source/WebCore/platform/gtk/PasteboardGtk.cpp
Source/WebCore/platform/gtk/PasteboardHelper.cpp
Source/WebCore/platform/gtk/PasteboardHelper.h
Source/WebKit2/ChangeLog
Source/WebKit2/WebProcess/WebCoreSupport/gtk/WebEditorClientGtk.cpp

index 52ea6d8..250bb17 100644 (file)
@@ -1,5 +1,58 @@
 2014-09-16  Carlos Garcia Campos  <cgarcia@igalia.com>
 
+        [GTK] Fix layering violations in PasteboardGtk
+        https://bugs.webkit.org/show_bug.cgi?id=136802
+
+        Reviewed by Darin Adler.
+
+        Refactor the Pasteboard code moving the WebCore parts to the Editor.
+
+        * PlatformGTK.cmake: Add new file to compilation.
+        * editing/Editor.cpp:
+        (WebCore::Editor::performCutOrCopy):
+        (WebCore::Editor::copyImage):
+        * editing/Editor.h:
+        * editing/gtk/EditorGtk.cpp: Added.
+        (WebCore::createFragmentFromPasteBoardData):
+        (WebCore::Editor::pasteWithPasteboard):
+        (WebCore::getImageAndURLForElement):
+        (WebCore::Editor::writeImageToPasteboard):
+        (WebCore::Editor::writeSelectionToPasteboard):
+        * page/DragController.cpp:
+        (WebCore::DragController::startDrag):
+        * page/gtk/DragControllerGtk.cpp:
+        (WebCore::DragController::declareAndWriteDragImage):
+        * platform/Pasteboard.h:
+        * platform/gtk/DataObjectGtk.cpp: Remove range member, the caller
+        should call setText() + setMarkup() intead.
+        (WebCore::DataObjectGtk::setText):
+        (WebCore::DataObjectGtk::setMarkup):
+        (WebCore::DataObjectGtk::clearText):
+        (WebCore::DataObjectGtk::clearMarkup):
+        (WebCore::DataObjectGtk::clearAllExceptFilenames):
+        * platform/gtk/DataObjectGtk.h:
+        (WebCore::DataObjectGtk::hasText):
+        (WebCore::DataObjectGtk::hasMarkup):
+        (WebCore::DataObjectGtk::clearImage):
+        (WebCore::DataObjectGtk::text):
+        (WebCore::DataObjectGtk::markup):
+        (WebCore::DataObjectGtk::setRange): Deleted.
+        * platform/gtk/GtkDragAndDropHelper.h:
+        * platform/gtk/PasteboardGtk.cpp:
+        (WebCore::PasteboardImage::PasteboardImage):
+        (WebCore::PasteboardImage::~PasteboardImage):
+        (WebCore::Pasteboard::write):
+        (WebCore::Pasteboard::writeSelection): Deleted.
+        (WebCore::getURLForImageElement): Deleted.
+        (WebCore::Pasteboard::writeImage): Deleted.
+        (WebCore::Pasteboard::documentFragment): Deleted.
+        * platform/gtk/PasteboardHelper.cpp:
+        (WebCore::displayFromFrame): Deleted.
+        (WebCore::PasteboardHelper::getPrimarySelectionClipboard): Deleted.
+        * platform/gtk/PasteboardHelper.h:
+
+2014-09-16  Carlos Garcia Campos  <cgarcia@igalia.com>
+
         DragData should not depend on Clipboard, DocumentFragment, and Document
         https://bugs.webkit.org/show_bug.cgi?id=21358
 
index 48d34ed..1bb1d65 100644 (file)
@@ -180,6 +180,7 @@ list(APPEND WebCorePlatformGTK_SOURCES
     accessibility/atk/WebKitAccessibleWrapperAtk.cpp
 
     editing/atk/FrameSelectionAtk.cpp
+    editing/gtk/EditorGtk.cpp
 
     page/gtk/DragControllerGtk.cpp
     page/gtk/EventHandlerGtk.cpp
index 20f8219..b2e5d3a 100644 (file)
@@ -562,7 +562,7 @@ String Editor::plainTextFromPasteboard(const PasteboardPlainText& text)
 
 #endif
 
-#if !PLATFORM(COCOA) && !PLATFORM(EFL)
+#if !PLATFORM(COCOA) && !PLATFORM(EFL) && !PLATFORM(GTK)
 void Editor::pasteWithPasteboard(Pasteboard* pasteboard, bool allowPlainText, MailBlockquoteHandling mailBlockquoteHandling)
 {
     RefPtr<Range> range = selectedRange();
@@ -1324,13 +1324,13 @@ void Editor::performCutOrCopy(EditorActionSpecifier action)
             imageElement = imageElementFromImageDocument(document());
 
         if (imageElement) {
-#if PLATFORM(COCOA) || PLATFORM(EFL)
+#if PLATFORM(COCOA) || PLATFORM(EFL) || PLATFORM(GTK)
             writeImageToPasteboard(*Pasteboard::createForCopyAndPaste(), *imageElement, document().url(), document().title());
 #else
             Pasteboard::createForCopyAndPaste()->writeImage(*imageElement, document().url(), document().title());
 #endif
         } else {
-#if PLATFORM(COCOA) || PLATFORM(EFL)
+#if PLATFORM(COCOA) || PLATFORM(EFL) || PLATFORM(GTK)
             writeSelectionToPasteboard(*Pasteboard::createForCopyAndPaste());
 #else
             // FIXME: Convert all other platforms to match Mac and delete this.
@@ -1436,7 +1436,7 @@ void Editor::copyImage(const HitTestResult& result)
     if (url.isEmpty())
         url = result.absoluteImageURL();
 
-#if PLATFORM(COCOA) || PLATFORM(EFL)
+#if PLATFORM(COCOA) || PLATFORM(EFL) || PLATFORM(GTK)
     writeImageToPasteboard(*Pasteboard::createForCopyAndPaste(), *element, url, result.altDisplayString());
 #else
     Pasteboard::createForCopyAndPaste()->writeImage(*element, url, result.altDisplayString());
index 280163e..4b7195c 100644 (file)
@@ -443,7 +443,7 @@ public:
 #endif // !PLATFORM(IOS)
 #endif
 
-#if PLATFORM(COCOA) || PLATFORM(EFL)
+#if PLATFORM(COCOA) || PLATFORM(EFL) || PLATFORM(GTK)
     WEBCORE_EXPORT void writeSelectionToPasteboard(Pasteboard&);
     WEBCORE_EXPORT void writeImageToPasteboard(Pasteboard&, Element& imageElement, const URL&, const String& title);
 #endif
diff --git a/Source/WebCore/editing/gtk/EditorGtk.cpp b/Source/WebCore/editing/gtk/EditorGtk.cpp
new file mode 100644 (file)
index 0000000..c772ec6
--- /dev/null
@@ -0,0 +1,132 @@
+/*
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 Igalia S.L.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "Editor.h"
+
+#include "CachedImage.h"
+#include "DataObjectGtk.h"
+#include "DocumentFragment.h"
+#include "Frame.h"
+#include "HTMLImageElement.h"
+#include "HTMLInputElement.h"
+#include "HTMLNames.h"
+#include "HTMLParserIdioms.h"
+#include "Pasteboard.h"
+#include "RenderImage.h"
+#include "SVGElement.h"
+#include "XLinkNames.h"
+#include "markup.h"
+
+namespace WebCore {
+
+static PassRefPtr<DocumentFragment> createFragmentFromPasteboardData(Pasteboard& pasteboard, Frame& frame, Range& range, bool allowPlainText, bool& chosePlainText)
+{
+    chosePlainText = false;
+
+    if (!pasteboard.hasData())
+        return nullptr;
+
+    RefPtr<DataObjectGtk> dataObject = pasteboard.dataObject();
+    if (dataObject->hasMarkup() && frame.document()) {
+        if (RefPtr<DocumentFragment> fragment = createFragmentFromMarkup(*frame.document(), dataObject->markup(), emptyString(), DisallowScriptingAndPluginContent))
+            return fragment.release();
+    }
+
+    if (!allowPlainText)
+        return nullptr;
+
+    if (dataObject->hasText()) {
+        chosePlainText = true;
+        if (RefPtr<DocumentFragment> fragment = createFragmentFromText(range, dataObject->text()))
+            return fragment.release();
+    }
+
+    return nullptr;
+}
+
+void Editor::pasteWithPasteboard(Pasteboard* pasteboard, bool allowPlainText, MailBlockquoteHandling mailBlockquoteHandling)
+{
+    RefPtr<Range> range = selectedRange();
+    if (!range)
+        return;
+
+    bool chosePlainText;
+    RefPtr<DocumentFragment> fragment = createFragmentFromPasteboardData(*pasteboard, m_frame, *range, allowPlainText, chosePlainText);
+    if (fragment && shouldInsertFragment(fragment, range, EditorInsertActionPasted))
+        pasteAsFragment(fragment, canSmartReplaceWithPasteboard(*pasteboard), chosePlainText, mailBlockquoteHandling);
+}
+
+static const AtomicString& elementURL(Element& element)
+{
+    if (isHTMLImageElement(element) || isHTMLInputElement(element))
+        return element.fastGetAttribute(HTMLNames::srcAttr);
+    if (isSVGImageElement(element))
+        return element.fastGetAttribute(XLinkNames::hrefAttr);
+    if (isHTMLEmbedElement(element) || isHTMLObjectElement(element))
+        return element.imageSourceURL();
+    return nullAtom;
+}
+
+static bool getImageForElement(Element& element, RefPtr<Image>& image)
+{
+    auto renderer = element.renderer();
+    if (!renderer || !renderer->isRenderImage())
+        return false;
+
+    CachedImage* cachedImage = toRenderImage(*renderer).cachedImage();
+    if (!cachedImage || cachedImage->errorOccurred())
+        return false;
+
+    image = cachedImage->imageForRenderer(renderer);
+    return image;
+}
+
+void Editor::writeImageToPasteboard(Pasteboard& pasteboard, Element& imageElement, const URL&, const String& title)
+{
+    PasteboardImage pasteboardImage;
+
+    if (!getImageForElement(imageElement, pasteboardImage.image))
+        return;
+    ASSERT(pasteboardImage.image);
+
+    pasteboardImage.url.url = imageElement.document().completeURL(stripLeadingAndTrailingHTMLSpaces(elementURL(imageElement)));
+    pasteboardImage.url.title = title;
+    pasteboardImage.url.markup = createMarkup(imageElement, IncludeNode, nullptr, ResolveAllURLs);
+    pasteboard.write(pasteboardImage);
+}
+
+void Editor::writeSelectionToPasteboard(Pasteboard& pasteboard)
+{
+    PasteboardWebContent pasteboardContent;
+    pasteboardContent.canSmartCopyOrDelete = canSmartCopyOrDelete();
+    pasteboardContent.text = selectedTextForDataTransfer();
+    pasteboardContent.markup = createMarkup(*selectedRange(), nullptr, AnnotateForInterchange, false, ResolveNonLocalURLs);
+    pasteboardContent.callback = nullptr;
+    pasteboard.write(pasteboardContent);
+}
+
+} // namespace WebCore
index 9542965..034deee 100644 (file)
@@ -783,7 +783,7 @@ bool DragController::startDrag(Frame& src, const DragState& state, DragOperation
             if (enclosingTextFormControl(src.selection().selection().start()))
                 dataTransfer.pasteboard().writePlainText(src.editor().selectedTextForDataTransfer(), Pasteboard::CannotSmartReplace);
             else {
-#if PLATFORM(COCOA) || PLATFORM(EFL)
+#if PLATFORM(COCOA) || PLATFORM(EFL) || PLATFORM(GTK)
                 src.editor().writeSelectionToPasteboard(dataTransfer.pasteboard());
 #else
                 // FIXME: Convert all other platforms to match Mac and delete this.
index 172c5d4..6efc67a 100644 (file)
@@ -31,6 +31,7 @@
 #include "Document.h"
 #include "DocumentFragment.h"
 #include "DragData.h"
+#include "Editor.h"
 #include "Element.h"
 #include "Frame.h"
 #include "FrameView.h"
@@ -75,7 +76,9 @@ void DragController::cleanupAfterSystemDrag()
 
 void DragController::declareAndWriteDragImage(DataTransfer& dataTransfer, Element& element, const URL& url, const String& label)
 {
-    dataTransfer.pasteboard().writeImage(element, url, label);
+    Frame* frame = element.document().frame();
+    ASSERT(frame);
+    frame->editor().writeImageToPasteboard(dataTransfer.pasteboard(), element, url, label);
 }
 
 PassRefPtr<DocumentFragment> DragController::createFragmentFromDragData(DragData& dragData, Frame& frame, Range&, bool /*allowPlainText*/, bool& /*chosePlainText*/)
index fdeff5b..4aaa7be 100644 (file)
@@ -34,6 +34,7 @@
 
 #if PLATFORM(GTK)
 typedef struct _GtkClipboard GtkClipboard;
+#include <wtf/gobject/GRefPtr.h>
 #endif
 
 #if PLATFORM(IOS)
@@ -78,6 +79,12 @@ struct PasteboardWebContent {
     Vector<String> clientTypes;
     Vector<RefPtr<SharedBuffer>> clientData;
 #endif
+#if PLATFORM(GTK)
+    bool canSmartCopyOrDelete;
+    String text;
+    String markup;
+    GRefPtr<GClosure> callback;
+#endif
 };
 
 struct PasteboardURL {
@@ -86,14 +93,19 @@ struct PasteboardURL {
 #if PLATFORM(MAC)
     String userVisibleForm;
 #endif
+#if PLATFORM(GTK)
+    String markup;
+#endif
 };
 
 struct PasteboardImage {
     WEBCORE_EXPORT PasteboardImage();
     WEBCORE_EXPORT ~PasteboardImage();
     RefPtr<Image> image;
-#if !(PLATFORM(EFL) || PLATFORM(GTK) || PLATFORM(WIN))
+#if !(PLATFORM(EFL) || PLATFORM(WIN))
     PasteboardURL url;
+#endif
+#if !(PLATFORM(EFL) || PLATFORM(GTK) || PLATFORM(WIN))
     RefPtr<SharedBuffer> resourceData;
     String resourceMIMEType;
 #endif
@@ -162,7 +174,7 @@ public:
     void setDragImage(DragImageRef, const IntPoint& hotSpot);
 #endif
 
-#if PLATFORM(GTK) || PLATFORM(WIN)
+#if PLATFORM(WIN)
     PassRefPtr<DocumentFragment> documentFragment(Frame&, Range&, bool allowPlainText, bool& chosePlainText); // FIXME: Layering violation.
     void writeImage(Element&, const URL&, const String& title); // FIXME: Layering violation.
     void writeSelection(Range&, bool canSmartCopyOrDelete, Frame&, ShouldSerializeSelectedTextForDataTransfer = DefaultSelectedTextType); // FIXME: Layering violation.
index bc33bb9..f600176 100644 (file)
@@ -19,9 +19,9 @@
 #include "config.h"
 #include "DataObjectGtk.h"
 
-#include "markup.h"
 #include <gtk/gtk.h>
 #include <wtf/gobject/GUniquePtr.h>
+#include <wtf/text/CString.h>
 #include <wtf/text/StringBuilder.h>
 
 namespace WebCore {
@@ -33,23 +33,6 @@ static void replaceNonBreakingSpaceWithSpace(String& str)
     str.replace(NonBreakingSpaceCharacter, SpaceCharacter);
 }
 
-String DataObjectGtk::text() const
-{
-    if (m_range) {
-        String text = m_range->text();
-        replaceNonBreakingSpaceWithSpace(text);
-        return text;
-    }
-    return m_text;
-}
-
-String DataObjectGtk::markup() const
-{
-    if (m_range)
-        return createMarkup(*m_range, 0, AnnotateForInterchange, false, ResolveNonLocalURLs);
-    return m_markup;
-}
-
 HashMap<String, String> DataObjectGtk::unknownTypes() const
 {
     return m_unknownTypeData;
@@ -57,14 +40,12 @@ HashMap<String, String> DataObjectGtk::unknownTypes() const
 
 void DataObjectGtk::setText(const String& newText)
 {
-    m_range = 0;
     m_text = newText;
     replaceNonBreakingSpaceWithSpace(m_text);
 }
 
 void DataObjectGtk::setMarkup(const String& newMarkup)
 {
-    m_range = 0;
     m_markup = newMarkup;
 }
 
@@ -131,14 +112,12 @@ void DataObjectGtk::setURL(const URL& url, const String& label)
 
 void DataObjectGtk::clearText()
 {
-    m_range = 0;
-    m_text = "";
+    m_text = emptyString();
 }
 
 void DataObjectGtk::clearMarkup()
 {
-    m_range = 0;
-    m_markup = "";
+    m_markup = emptyString();
 }
 
 String DataObjectGtk::urlLabel() const
@@ -154,12 +133,11 @@ String DataObjectGtk::urlLabel() const
 
 void DataObjectGtk::clearAllExceptFilenames()
 {
-    m_text = "";
-    m_markup = "";
-    m_uriList = "";
+    m_text = emptyString();
+    m_markup = emptyString();
+    m_uriList = emptyString();
     m_url = URL();
-    m_image = 0;
-    m_range = 0;
+    m_image = nullptr;
     m_unknownTypeData.clear();
 }
 
index ff14249..850d280 100644 (file)
 
 #include "FileList.h"
 #include "URL.h"
-#include "Range.h"
 #include <wtf/RefCounted.h>
 #include <wtf/gobject/GRefPtr.h>
-#include <wtf/text/CString.h>
 #include <wtf/text/StringHash.h>
 
 namespace WebCore {
@@ -40,22 +38,21 @@ public:
     const String& uriList() const { return m_uriList; }
     const Vector<String>& filenames() const { return m_filenames; }
     GdkPixbuf* image() const { return m_image.get(); }
-    void setRange(PassRefPtr<Range> newRange) { m_range = newRange; }
     void setImage(GdkPixbuf* newImage) { m_image = newImage; }
     void setURL(const URL&, const String&);
     bool hasUnknownTypeData() const { return !m_unknownTypeData.isEmpty(); }
-    bool hasText() const { return m_range || !m_text.isEmpty(); }
-    bool hasMarkup() const { return m_range || !m_markup.isEmpty(); }
+    bool hasText() const { return !m_text.isEmpty(); }
+    bool hasMarkup() const { return !m_markup.isEmpty(); }
     bool hasURIList() const { return !m_uriList.isEmpty(); }
     bool hasURL() const { return !m_url.isEmpty() && m_url.isValid(); }
     bool hasFilenames() const { return !m_filenames.isEmpty(); }
     bool hasImage() const { return m_image; }
     void clearURIList() { m_uriList = ""; }
     void clearURL() { m_url = URL(); }
-    void clearImage() { m_image = 0; }
+    void clearImage() { m_image = nullptr; }
 
-    String text() const;
-    String markup() const;
+    String text() const { return m_text; }
+    String markup() const { return m_markup; }
     String unknownTypeData(const String& type) const { return m_unknownTypeData.get(type); }
     HashMap<String, String> unknownTypes() const;
     void setText(const String&);
@@ -78,7 +75,6 @@ private:
     String m_uriList;
     Vector<String> m_filenames;
     GRefPtr<GdkPixbuf> m_image;
-    RefPtr<Range> m_range;
     HashMap<String, String> m_unknownTypeData;
 };
 
index 529e998..a8c6f27 100644 (file)
@@ -27,6 +27,7 @@ namespace WebCore {
 
 struct DroppingContext;
 class DragData;
+class IntPoint;
 
 typedef void (*DragExitedCallback)(GtkWidget*, DragData&, bool dropHappened);
 
index 5b165a8..0aadd5c 100644 (file)
 #include "config.h"
 #include "Pasteboard.h"
 
-#include "CachedImage.h"
 #include "DataObjectGtk.h"
-#include "DocumentFragment.h"
 #include "DragData.h"
-#include "Editor.h"
-#include "Frame.h"
-#include "HTMLImageElement.h"
-#include "HTMLInputElement.h"
-#include "HTMLNames.h"
-#include "HTMLParserIdioms.h"
 #include "Image.h"
 #include "URL.h"
 #include "PasteboardHelper.h"
-#include "RenderImage.h"
-#include "SVGElement.h"
-#include "SVGNames.h"
-#include "XLinkNames.h"
-#include "markup.h"
 #include <gtk/gtk.h>
-
+#include <wtf/PassOwnPtr.h>
 
 namespace WebCore {
 
@@ -89,6 +76,15 @@ PassOwnPtr<Pasteboard> Pasteboard::createForDragAndDrop(const DragData& dragData
 }
 #endif
 
+// Making this non-inline so that WebKit 2's decoding doesn't have to include Image.h.
+PasteboardImage::PasteboardImage()
+{
+}
+
+PasteboardImage::~PasteboardImage()
+{
+}
+
 Pasteboard::Pasteboard(PassRefPtr<DataObjectGtk> dataObject)
     : m_dataObject(dataObject)
     , m_gtkClipboard(0)
@@ -156,16 +152,6 @@ void Pasteboard::writeString(const String& type, const String& data)
     }
 }
 
-void Pasteboard::writeSelection(Range& selectedRange, bool canSmartCopyOrDelete, Frame& frame, ShouldSerializeSelectedTextForDataTransfer shouldSerializeSelectedTextForDataTransfer)
-{
-    m_dataObject->clearAll();
-    m_dataObject->setText(shouldSerializeSelectedTextForDataTransfer == IncludeImageAltTextForDataTransfer ? frame.editor().selectedTextForDataTransfer() : frame.editor().selectedText());
-    m_dataObject->setMarkup(createMarkup(selectedRange, 0, AnnotateForInterchange, false, ResolveNonLocalURLs));
-
-    if (m_gtkClipboard)
-        PasteboardHelper::defaultPasteboardHelper()->writeClipboardContents(m_gtkClipboard, canSmartCopyOrDelete ? PasteboardHelper::IncludeSmartPaste : PasteboardHelper::DoNotIncludeSmartPaste);
-}
-
 void Pasteboard::writePlainText(const String& text, SmartReplaceOption smartReplaceOption)
 {
     m_dataObject->clearAll();
@@ -186,48 +172,32 @@ void Pasteboard::write(const PasteboardURL& pasteboardURL)
         PasteboardHelper::defaultPasteboardHelper()->writeClipboardContents(m_gtkClipboard);
 }
 
-static URL getURLForImageElement(Element& element)
-{
-    // FIXME: Later this code should be shared with Chromium somehow. Chances are all platforms want it.
-    AtomicString urlString;
-    if (isHTMLImageElement(element) || isHTMLInputElement(element))
-        urlString = element.getAttribute(HTMLNames::srcAttr);
-    else if (element.hasTagName(SVGNames::imageTag))
-        urlString = element.getAttribute(XLinkNames::hrefAttr);
-    else if (element.hasTagName(HTMLNames::embedTag) || isHTMLObjectElement(element))
-        urlString = element.imageSourceURL();
-
-    return urlString.isEmpty() ? URL() : element.document().completeURL(stripLeadingAndTrailingHTMLSpaces(urlString));
-}
-
-void Pasteboard::writeImage(Element& element, const URL&, const String& title)
+void Pasteboard::write(const PasteboardImage& pasteboardImage)
 {
-    if (!(element.renderer() && element.renderer()->isRenderImage()))
-        return;
-
-    RenderImage* renderer = toRenderImage(element.renderer());
-    CachedImage* cachedImage = renderer->cachedImage();
-    if (!cachedImage || cachedImage->errorOccurred())
-        return;
-    Image* image = cachedImage->imageForRenderer(renderer);
-    ASSERT(image);
-
     m_dataObject->clearAll();
-
-    URL url = getURLForImageElement(element);
-    if (!url.isEmpty()) {
-        m_dataObject->setURL(url, title);
-
-        m_dataObject->setMarkup(createMarkup(element, IncludeNode, 0, ResolveAllURLs));
+    if (!pasteboardImage.url.url.isEmpty()) {
+        m_dataObject->setURL(pasteboardImage.url.url, pasteboardImage.url.title);
+        m_dataObject->setMarkup(pasteboardImage.url.markup);
     }
 
-    GRefPtr<GdkPixbuf> pixbuf = adoptGRef(image->getGdkPixbuf());
-    m_dataObject->setImage(pixbuf.get());
+    GRefPtr<GdkPixbuf> pixbuf = adoptGRef(pasteboardImage.image->getGdkPixbuf());
+    if (pixbuf)
+        m_dataObject->setImage(pixbuf.get());
 
     if (m_gtkClipboard)
         PasteboardHelper::defaultPasteboardHelper()->writeClipboardContents(m_gtkClipboard);
 }
 
+void Pasteboard::write(const PasteboardWebContent& pasteboardContent)
+{
+    m_dataObject->clearAll();
+    m_dataObject->setText(pasteboardContent.text);
+    m_dataObject->setMarkup(pasteboardContent.markup);
+
+    if (m_gtkClipboard)
+        PasteboardHelper::defaultPasteboardHelper()->writeClipboardContents(m_gtkClipboard, pasteboardContent.canSmartCopyOrDelete ? PasteboardHelper::IncludeSmartPaste : PasteboardHelper::DoNotIncludeSmartPaste, pasteboardContent.callback.get());
+}
+
 void Pasteboard::writePasteboard(const Pasteboard& sourcePasteboard)
 {
     RefPtr<DataObjectGtk> sourceDataObject = sourcePasteboard.dataObject();
@@ -302,34 +272,6 @@ void Pasteboard::setDragImage(DragImageRef, const IntPoint&)
 }
 #endif
 
-PassRefPtr<DocumentFragment> Pasteboard::documentFragment(Frame& frame, Range& context, bool allowPlainText, bool& chosePlainText)
-{
-    if (m_gtkClipboard)
-        PasteboardHelper::defaultPasteboardHelper()->getClipboardContents(m_gtkClipboard);
-
-    chosePlainText = false;
-
-    if (m_dataObject->hasMarkup()) {
-        if (frame.document()) {
-            RefPtr<DocumentFragment> fragment = createFragmentFromMarkup(*frame.document(), m_dataObject->markup(), emptyString(), DisallowScriptingAndPluginContent);
-            if (fragment)
-                return fragment.release();
-        }
-    }
-
-    if (!allowPlainText)
-        return 0;
-
-    if (m_dataObject->hasText()) {
-        chosePlainText = true;
-        RefPtr<DocumentFragment> fragment = createFragmentFromText(context, m_dataObject->text());
-        if (fragment)
-            return fragment.release();
-    }
-
-    return 0;
-}
-
 void Pasteboard::read(PasteboardPlainText& text)
 {
     if (m_gtkClipboard)
index c092227..2869d25 100644 (file)
 #include "config.h"
 #include "PasteboardHelper.h"
 
-#include "Chrome.h"
 #include "DataObjectGtk.h"
-#include "Frame.h"
 #include "GRefPtrGtk.h"
 #include "GtkVersioning.h"
-#include "Page.h"
 #include "Pasteboard.h"
 #include "TextResourceDecoder.h"
 #include <gtk/gtk.h>
 #include <wtf/gobject/GUniquePtr.h>
+#include <wtf/text/CString.h>
 
 namespace WebCore {
 
@@ -95,20 +93,6 @@ PasteboardHelper::~PasteboardHelper()
     gtk_target_list_unref(m_targetList);
 }
 
-static inline GdkDisplay* displayFromFrame(Frame* frame)
-{
-    ASSERT(frame);
-    Page* page = frame->page();
-    ASSERT(page);
-    PlatformPageClient client = page->chrome().platformPageClient();
-    return client ? gtk_widget_get_display(client) : gdk_display_get_default();
-}
-
-GtkClipboard* PasteboardHelper::getPrimarySelectionClipboard(Frame* frame) const
-{
-    return gtk_clipboard_get_for_display(displayFromFrame(frame), GDK_SELECTION_PRIMARY);
-}
-
 GtkTargetList* PasteboardHelper::targetList() const
 {
     return m_targetList;
@@ -309,12 +293,11 @@ static void clearClipboardContentsCallback(GtkClipboard* clipboard, gpointer dat
     if (!data)
         return;
 
-    GClosure* callback = static_cast<GClosure*>(data);
+    GRefPtr<GClosure> callback = adoptGRef(static_cast<GClosure*>(data));
     GValue firstArgument = {0, {{0}}};
     g_value_init(&firstArgument, G_TYPE_POINTER);
     g_value_set_pointer(&firstArgument, clipboard);
-    g_closure_invoke(callback, 0, 1, &firstArgument, 0);
-    g_closure_unref(callback);
+    g_closure_invoke(callback.get(), nullptr, 1, &firstArgument, 0);
 }
 
 void PasteboardHelper::writeClipboardContents(GtkClipboard* clipboard, SmartPasteInclusion includeSmartPaste, GClosure* callback)
@@ -328,11 +311,14 @@ void PasteboardHelper::writeClipboardContents(GtkClipboard* clipboard, SmartPast
     if (numberOfTargets > 0 && table) {
         settingClipboardDataObject = dataObject;
 
-        gtk_clipboard_set_with_data(clipboard, table, numberOfTargets,
-            getClipboardContentsCallback, clearClipboardContentsCallback, callback);
-        gtk_clipboard_set_can_store(clipboard, 0, 0);
+        if (gtk_clipboard_set_with_data(clipboard, table, numberOfTargets, getClipboardContentsCallback, clearClipboardContentsCallback, g_closure_ref(callback)))
+            gtk_clipboard_set_can_store(clipboard, nullptr, 0);
+        else {
+            // When gtk_clipboard_set_with_data fails the callbacks are ignored, so we need to release the reference we were passing to clearClipboardContentsCallback.
+            g_closure_unref(callback);
+        }
 
-        settingClipboardDataObject = 0;
+        settingClipboardDataObject = nullptr;
 
     } else
         gtk_clipboard_clear(clipboard);
index 5eb669e..0d03d10 100644 (file)
@@ -25,8 +25,8 @@
 #ifndef PasteboardHelper_h
 #define PasteboardHelper_h
 
-#include "Frame.h"
 #include <glib-object.h>
+#include <wtf/Vector.h>
 
 namespace WebCore {
 
@@ -40,7 +40,6 @@ public:
 
     enum SmartPasteInclusion { IncludeSmartPaste, DoNotIncludeSmartPaste };
 
-    GtkClipboard* getPrimarySelectionClipboard(Frame*) const;
     GtkTargetList* targetList() const;
     GtkTargetList* targetListForDataObject(DataObjectGtk*, SmartPasteInclusion = DoNotIncludeSmartPaste);
     void fillSelectionData(GtkSelectionData*, guint, DataObjectGtk*);
index 403fde1..0b5cdff 100644 (file)
@@ -1,5 +1,16 @@
 2014-09-16  Carlos Garcia Campos  <cgarcia@igalia.com>
 
+        [GTK] Fix layering violations in PasteboardGtk
+        https://bugs.webkit.org/show_bug.cgi?id=136802
+
+        Reviewed by Darin Adler.
+
+        * WebProcess/WebCoreSupport/gtk/WebEditorClientGtk.cpp:
+        (WebKit::WebEditorClient::updateGlobalSelection): Use new API to
+        update the global selection.
+
+2014-09-16  Carlos Garcia Campos  <cgarcia@igalia.com>
+
         DragData should not depend on Clipboard, DocumentFragment, and Document
         https://bugs.webkit.org/show_bug.cgi?id=21358
 
index 469d956..bca83e9 100644 (file)
 #include "config.h"
 #include "WebEditorClient.h"
 
-#include "Frame.h"
-#include "FrameDestructionObserver.h"
 #include "PlatformKeyboardEvent.h"
 #include "WebPage.h"
 #include "WebPageProxyMessages.h"
 #include "WebProcess.h"
 #include <WebCore/DataObjectGtk.h>
 #include <WebCore/Document.h>
+#include <WebCore/Frame.h>
+#include <WebCore/FrameDestructionObserver.h>
 #include <WebCore/KeyboardEvent.h>
-#include <WebCore/PasteboardHelper.h>
+#include <WebCore/Pasteboard.h>
 #include <WebCore/WindowsKeyboardCodes.h>
+#include <WebCore/markup.h>
+#include <wtf/gobject/GRefPtr.h>
 
 using namespace WebCore;
 
@@ -175,24 +177,25 @@ static void collapseSelection(GtkClipboard*, Frame* frame)
 void WebEditorClient::updateGlobalSelection(Frame* frame)
 {
 #if PLATFORM(X11)
-    GtkClipboard* clipboard = PasteboardHelper::defaultPasteboardHelper()->getPrimarySelectionClipboard(frame);
-    DataObjectGtk* dataObject = DataObjectGtk::forClipboard(clipboard);
-
     if (!frame->selection().isRange())
         return;
 
-    dataObject->clearAll();
-    dataObject->setRange(frame->selection().toNormalizedRange());
-
     frameSettingClipboard = frame;
-    GClosure* callback = g_cclosure_new(G_CALLBACK(collapseSelection), frame, 0);
+    GRefPtr<GClosure> callback = adoptGRef(g_cclosure_new(G_CALLBACK(collapseSelection), frame, nullptr));
     // This observer will be self-destroyed on closure finalization,
     // that will happen either after closure execution or after
     // closure invalidation.
-    new EditorClientFrameDestructionObserver(frame, callback);
-    g_closure_set_marshal(callback, g_cclosure_marshal_VOID__VOID);
-    PasteboardHelper::defaultPasteboardHelper()->writeClipboardContents(clipboard, PasteboardHelper::DoNotIncludeSmartPaste, callback);
-    frameSettingClipboard = 0;
+    new EditorClientFrameDestructionObserver(frame, callback.get());
+    g_closure_set_marshal(callback.get(), g_cclosure_marshal_VOID__VOID);
+
+    RefPtr<Range> range = frame->selection().toNormalizedRange();
+    PasteboardWebContent pasteboardContent;
+    pasteboardContent.canSmartCopyOrDelete = false;
+    pasteboardContent.text = range->text();
+    pasteboardContent.markup = createMarkup(*range, nullptr, AnnotateForInterchange, false, ResolveNonLocalURLs);
+    pasteboardContent.callback = callback;
+    Pasteboard::createForGlobalSelection()->write(pasteboardContent);
+    frameSettingClipboard = nullptr;
 #endif
 }