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 26namespace WebCore { 27 28static void replaceNonBreakingSpaceWithSpace(String& str) 29{ 30 static const UChar NonBreakingSpaceCharacter = 0xA0; 31 static const UChar SpaceCharacter = ' '; 32 str.replace(NonBreakingSpaceCharacter, SpaceCharacter); 33} 34 35String DataObjectGtk::text() 36{ 37 if (m_range) 38 return m_range->text(); 39 return m_text; 40} 41 42String DataObjectGtk::markup() 43{ 44 if (m_range) 45 return createMarkup(m_range.get(), 0, AnnotateForInterchange, false, AbsoluteURLs); 46 return m_markup; 47} 48 49void DataObjectGtk::setText(const String& newText) 50{ 51 m_range = 0; 52 m_text = newText; 53 replaceNonBreakingSpaceWithSpace(m_text); 54} 55 56void DataObjectGtk::setMarkup(const String& newMarkup) 57{ 58 m_range = 0; 59 m_markup = newMarkup; 60} 61 62void 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 103void 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 123void DataObjectGtk::clearText() 124{ 125 m_range = 0; 126 m_text = ""; 127} 128 129void DataObjectGtk::clearMarkup() 130{ 131 m_range = 0; 132 m_markup = ""; 133} 134 135String DataObjectGtk::urlLabel() 136{ 137 if (hasText()) 138 return text(); 139 140 if (hasURL()) 141 return url(); 142 143 return String(); 144} 145 146void 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 161DataObjectGtk* 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