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
26 namespace WebCore {
27
replaceNonBreakingSpaceWithSpace(String & str)28 static void replaceNonBreakingSpaceWithSpace(String& str)
29 {
30 static const UChar NonBreakingSpaceCharacter = 0xA0;
31 static const UChar SpaceCharacter = ' ';
32 str.replace(NonBreakingSpaceCharacter, SpaceCharacter);
33 }
34
text()35 String DataObjectGtk::text()
36 {
37 if (m_range)
38 return m_range->text();
39 return m_text;
40 }
41
markup()42 String DataObjectGtk::markup()
43 {
44 if (m_range)
45 return createMarkup(m_range.get(), 0, AnnotateForInterchange, false, AbsoluteURLs);
46 return m_markup;
47 }
48
setText(const String & newText)49 void DataObjectGtk::setText(const String& newText)
50 {
51 m_range = 0;
52 m_text = newText;
53 replaceNonBreakingSpaceWithSpace(m_text);
54 }
55
setMarkup(const String & newMarkup)56 void DataObjectGtk::setMarkup(const String& newMarkup)
57 {
58 m_range = 0;
59 m_markup = newMarkup;
60 }
61
setURIList(const String & uriListString)62 void DataObjectGtk::setURIList(const String& uriListString)
63 {
64 m_uriList = uriListString;
65
66 // This code is originally from: platform/chromium/ChromiumDataObject.cpp.
67 // FIXME: We should make this code cross-platform eventually.
68
69 // Line separator is \r\n per RFC 2483 - however, for compatibility
70 // reasons we also allow just \n here.
71 Vector<String> uriList;
72 uriListString.split('\n', uriList);
73
74 // Process the input and copy the first valid URL into the url member.
75 // In case no URLs can be found, subsequent calls to getData("URL")
76 // will get an empty string. This is in line with the HTML5 spec (see
77 // "The DragEvent and DataTransfer interfaces"). Also extract all filenames
78 // from the URI list.
79 bool setURL = false;
80 for (size_t i = 0; i < uriList.size(); ++i) {
81 String& line = uriList[i];
82 line = line.stripWhiteSpace();
83 if (line.isEmpty())
84 continue;
85 if (line[0] == '#')
86 continue;
87
88 KURL url = KURL(KURL(), line);
89 if (url.isValid()) {
90 if (!setURL) {
91 m_url = url;
92 setURL = true;
93 }
94
95 GOwnPtr<GError> error;
96 GOwnPtr<gchar> filename(g_filename_from_uri(line.utf8().data(), 0, &error.outPtr()));
97 if (!error && filename)
98 m_filenames.append(String::fromUTF8(filename.get()));
99 }
100 }
101 }
102
setURL(const KURL & url,const String & label)103 void DataObjectGtk::setURL(const KURL& url, const String& label)
104 {
105 m_url = url;
106 m_uriList = url;
107 setText(url.string());
108
109 String actualLabel(label);
110 if (actualLabel.isEmpty())
111 actualLabel = url;
112
113 Vector<UChar> markup;
114 append(markup, "<a href=\"");
115 append(markup, url.string());
116 append(markup, "\">");
117 GOwnPtr<gchar> escaped(g_markup_escape_text(actualLabel.utf8().data(), -1));
118 append(markup, String::fromUTF8(escaped.get()));
119 append(markup, "</a>");
120 setMarkup(String::adopt(markup));
121 }
122
clearText()123 void DataObjectGtk::clearText()
124 {
125 m_range = 0;
126 m_text = "";
127 }
128
clearMarkup()129 void DataObjectGtk::clearMarkup()
130 {
131 m_range = 0;
132 m_markup = "";
133 }
134
urlLabel()135 String DataObjectGtk::urlLabel()
136 {
137 if (hasText())
138 return text();
139
140 if (hasURL())
141 return url();
142
143 return String();
144 }
145
clear()146 void DataObjectGtk::clear()
147 {
148 m_text = "";
149 m_markup = "";
150 m_uriList = "";
151 m_url = KURL();
152 m_image = 0;
153 m_range = 0;
154
155 // We do not clear filenames. According to the spec: "The clearData() method
156 // does not affect whether any files were included in the drag, so the types
157 // attribute's list might still not be empty after calling clearData() (it would
158 // still contain the "Files" string if any files were included in the drag)."
159 }
160
forClipboard(GtkClipboard * clipboard)161 DataObjectGtk* DataObjectGtk::forClipboard(GtkClipboard* clipboard)
162 {
163 static HashMap<GtkClipboard*, RefPtr<DataObjectGtk> > objectMap;
164
165 if (!objectMap.contains(clipboard)) {
166 RefPtr<DataObjectGtk> dataObject = DataObjectGtk::create();
167 objectMap.set(clipboard, dataObject);
168 return dataObject.get();
169 }
170
171 HashMap<GtkClipboard*, RefPtr<DataObjectGtk> >::iterator it = objectMap.find(clipboard);
172 return it->second.get();
173 }
174
175 }
176