[Gtk] NBSP are not replaced when using X clipboard
[WebKit-https.git] / Source / WebCore / platform / gtk / DataObjectGtk.cpp
1 /*
2  * Copyright (C) 2009, Martin Robinson
3  *
4  *  This library is free software; you can redistribute it and/or
5  *  modify it under the terms of the GNU Lesser General Public
6  *  License as published by the Free Software Foundation; either
7  *  version 2 of the License, or (at your option) any later version.
8  *
9  *  This library is distributed in the hope that it will be useful,
10  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  *  Lesser General Public License for more details.
13  *
14  *  You should have received a copy of the GNU Lesser General Public
15  *  License along with this library; if not, write to the Free Software
16  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
17  */
18
19 #include "config.h"
20 #include "DataObjectGtk.h"
21
22 #include "markup.h"
23 #include <gtk/gtk.h>
24 #include <wtf/gobject/GOwnPtr.h>
25 #include <wtf/text/StringBuilder.h>
26
27 namespace WebCore {
28
29 static void replaceNonBreakingSpaceWithSpace(String& str)
30 {
31     static const UChar NonBreakingSpaceCharacter = 0xA0;
32     static const UChar SpaceCharacter = ' ';
33     str.replace(NonBreakingSpaceCharacter, SpaceCharacter);
34 }
35
36 String DataObjectGtk::text() const
37 {
38     if (m_range) {
39         String text = m_range->text();
40         replaceNonBreakingSpaceWithSpace(text);
41         return text;
42     }
43     return m_text;
44 }
45
46 String DataObjectGtk::markup() const
47 {
48     if (m_range)
49         return createMarkup(m_range.get(), 0, AnnotateForInterchange, false, ResolveNonLocalURLs);
50     return m_markup;
51 }
52
53 void DataObjectGtk::setText(const String& newText)
54 {
55     m_range = 0;
56     m_text = newText;
57     replaceNonBreakingSpaceWithSpace(m_text);
58 }
59
60 void DataObjectGtk::setMarkup(const String& newMarkup)
61 {
62     m_range = 0;
63     m_markup = newMarkup;
64 }
65
66 void DataObjectGtk::setURIList(const String& uriListString)
67 {
68     m_uriList = uriListString;
69
70     // This code is originally from: platform/chromium/ChromiumDataObject.cpp.
71     // FIXME: We should make this code cross-platform eventually.
72
73     // Line separator is \r\n per RFC 2483 - however, for compatibility
74     // reasons we also allow just \n here.
75     Vector<String> uriList;
76     uriListString.split('\n', uriList);
77
78     // Process the input and copy the first valid URL into the url member.
79     // In case no URLs can be found, subsequent calls to getData("URL")
80     // will get an empty string. This is in line with the HTML5 spec (see
81     // "The DragEvent and DataTransfer interfaces"). Also extract all filenames
82     // from the URI list.
83     bool setURL = false;
84     for (size_t i = 0; i < uriList.size(); ++i) {
85         String& line = uriList[i];
86         line = line.stripWhiteSpace();
87         if (line.isEmpty())
88             continue;
89         if (line[0] == '#')
90             continue;
91
92         KURL url = KURL(KURL(), line);
93         if (url.isValid()) {
94             if (!setURL) {
95                 m_url = url;
96                 setURL = true;
97             }
98
99             GOwnPtr<GError> error;
100             GOwnPtr<gchar> filename(g_filename_from_uri(line.utf8().data(), 0, &error.outPtr()));
101             if (!error && filename)
102                 m_filenames.append(String::fromUTF8(filename.get()));
103         }
104     }
105 }
106
107 void DataObjectGtk::setURL(const KURL& url, const String& label)
108 {
109     m_url = url;
110     m_uriList = url;
111     setText(url.string());
112
113     String actualLabel(label);
114     if (actualLabel.isEmpty())
115         actualLabel = url;
116
117     StringBuilder markup;
118     markup.append("<a href=\"");
119     markup.append(url.string());
120     markup.append("\">");
121     GOwnPtr<gchar> escaped(g_markup_escape_text(actualLabel.utf8().data(), -1));
122     markup.append(String::fromUTF8(escaped.get()));
123     markup.append("</a>");
124     setMarkup(markup.toString());
125 }
126
127 void DataObjectGtk::clearText()
128 {
129     m_range = 0;
130     m_text = "";
131 }
132
133 void DataObjectGtk::clearMarkup()
134 {
135     m_range = 0;
136     m_markup = "";
137 }
138
139 String DataObjectGtk::urlLabel() const
140 {
141     if (hasText())
142         return text();
143
144     if (hasURL())
145         return url();
146
147     return String();
148 }
149
150 void DataObjectGtk::clearAllExceptFilenames()
151 {
152     m_text = "";
153     m_markup = "";
154     m_uriList = "";
155     m_url = KURL();
156     m_image = 0;
157     m_range = 0;
158 }
159
160 void DataObjectGtk::clearAll()
161 {
162     clearAllExceptFilenames();
163     m_filenames.clear();
164 }
165
166 DataObjectGtk* DataObjectGtk::forClipboard(GtkClipboard* clipboard)
167 {
168     static HashMap<GtkClipboard*, RefPtr<DataObjectGtk> > objectMap;
169
170     if (!objectMap.contains(clipboard)) {
171         RefPtr<DataObjectGtk> dataObject = DataObjectGtk::create();
172         objectMap.set(clipboard, dataObject);
173         return dataObject.get();
174     }
175
176     HashMap<GtkClipboard*, RefPtr<DataObjectGtk> >::iterator it = objectMap.find(clipboard);
177     return it->value.get();
178 }
179
180 }