• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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