Add a FrameHostMsg_BeginNavigation IPC
[chromium-blink-merge.git] / ui / base / x / selection_utils.cc
blobd5ce1c03cf283e7ba0c13554fdb47e915f246264
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "ui/base/x/selection_utils.h"
7 #include <set>
9 #include "base/i18n/icu_string_conversions.h"
10 #include "base/logging.h"
11 #include "base/strings/string_util.h"
12 #include "base/strings/utf_string_conversions.h"
13 #include "ui/base/clipboard/clipboard.h"
14 #include "ui/base/x/x11_util.h"
15 #include "ui/gfx/x/x11_atom_cache.h"
17 namespace ui {
19 const char kMimeTypeMozillaURL[] = "text/x-moz-url";
20 const char kString[] = "STRING";
21 const char kText[] = "TEXT";
22 const char kTextPlain[] = "text/plain";
23 const char kTextPlainUtf8[] = "text/plain;charset=utf-8";
24 const char kUtf8String[] = "UTF8_STRING";
26 const char* kSelectionDataAtoms[] = {
27 Clipboard::kMimeTypeHTML,
28 kString,
29 kText,
30 kTextPlain,
31 kTextPlainUtf8,
32 kUtf8String,
33 NULL
36 std::vector< ::Atom> GetTextAtomsFrom(const X11AtomCache* atom_cache) {
37 std::vector< ::Atom> atoms;
38 atoms.push_back(atom_cache->GetAtom(kUtf8String));
39 atoms.push_back(atom_cache->GetAtom(kString));
40 atoms.push_back(atom_cache->GetAtom(kText));
41 atoms.push_back(atom_cache->GetAtom(kTextPlain));
42 atoms.push_back(atom_cache->GetAtom(kTextPlainUtf8));
43 return atoms;
46 std::vector< ::Atom> GetURLAtomsFrom(const X11AtomCache* atom_cache) {
47 std::vector< ::Atom> atoms;
48 atoms.push_back(atom_cache->GetAtom(Clipboard::kMimeTypeURIList));
49 atoms.push_back(atom_cache->GetAtom(kMimeTypeMozillaURL));
50 return atoms;
53 std::vector< ::Atom> GetURIListAtomsFrom(const X11AtomCache* atom_cache) {
54 std::vector< ::Atom> atoms;
55 atoms.push_back(atom_cache->GetAtom(Clipboard::kMimeTypeURIList));
56 return atoms;
59 void GetAtomIntersection(const std::vector< ::Atom>& desired,
60 const std::vector< ::Atom>& offered,
61 std::vector< ::Atom>* output) {
62 for (std::vector< ::Atom>::const_iterator it = desired.begin();
63 it != desired.end(); ++it) {
64 std::vector< ::Atom>::const_iterator jt =
65 std::find(offered.begin(), offered.end(), *it);
66 if (jt != offered.end())
67 output->push_back(*it);
71 void AddString16ToVector(const base::string16& str,
72 std::vector<unsigned char>* bytes) {
73 const unsigned char* front =
74 reinterpret_cast<const unsigned char*>(str.data());
75 bytes->insert(bytes->end(), front, front + (str.size() * 2));
78 std::vector<std::string> ParseURIList(const SelectionData& data) {
79 // uri-lists are newline separated file lists in URL encoding.
80 std::string unparsed;
81 data.AssignTo(&unparsed);
83 std::vector<std::string> tokens;
84 Tokenize(unparsed, "\n", &tokens);
85 return tokens;
88 std::string RefCountedMemoryToString(
89 const scoped_refptr<base::RefCountedMemory>& memory) {
90 if (!memory.get()) {
91 NOTREACHED();
92 return std::string();
95 size_t size = memory->size();
96 if (!size)
97 return std::string();
99 const unsigned char* front = memory->front();
100 return std::string(reinterpret_cast<const char*>(front), size);
103 base::string16 RefCountedMemoryToString16(
104 const scoped_refptr<base::RefCountedMemory>& memory) {
105 if (!memory.get()) {
106 NOTREACHED();
107 return base::string16();
110 size_t size = memory->size();
111 if (!size)
112 return base::string16();
114 const unsigned char* front = memory->front();
115 return base::string16(reinterpret_cast<const base::char16*>(front), size / 2);
118 ///////////////////////////////////////////////////////////////////////////////
120 SelectionFormatMap::SelectionFormatMap() {}
122 SelectionFormatMap::~SelectionFormatMap() {}
124 void SelectionFormatMap::Insert(
125 ::Atom atom,
126 const scoped_refptr<base::RefCountedMemory>& item) {
127 data_.erase(atom);
128 data_.insert(std::make_pair(atom, item));
131 ui::SelectionData SelectionFormatMap::GetFirstOf(
132 const std::vector< ::Atom>& requested_types) const {
133 for (std::vector< ::Atom>::const_iterator it = requested_types.begin();
134 it != requested_types.end(); ++it) {
135 const_iterator data_it = data_.find(*it);
136 if (data_it != data_.end()) {
137 return SelectionData(data_it->first, data_it->second);
141 return SelectionData();
144 std::vector< ::Atom> SelectionFormatMap::GetTypes() const {
145 std::vector< ::Atom> atoms;
146 for (const_iterator it = data_.begin(); it != data_.end(); ++it)
147 atoms.push_back(it->first);
149 return atoms;
152 ///////////////////////////////////////////////////////////////////////////////
154 SelectionData::SelectionData()
155 : type_(None),
156 atom_cache_(gfx::GetXDisplay(), kSelectionDataAtoms) {
159 SelectionData::SelectionData(
160 ::Atom type,
161 const scoped_refptr<base::RefCountedMemory>& memory)
162 : type_(type),
163 memory_(memory),
164 atom_cache_(gfx::GetXDisplay(), kSelectionDataAtoms) {
167 SelectionData::SelectionData(const SelectionData& rhs)
168 : type_(rhs.type_),
169 memory_(rhs.memory_),
170 atom_cache_(gfx::GetXDisplay(), kSelectionDataAtoms) {
173 SelectionData::~SelectionData() {}
175 SelectionData& SelectionData::operator=(const SelectionData& rhs) {
176 type_ = rhs.type_;
177 memory_ = rhs.memory_;
178 // TODO(erg): In some future where we have to support multiple X Displays,
179 // the following will also need to deal with the display.
180 return *this;
183 bool SelectionData::IsValid() const {
184 return type_ != None;
187 ::Atom SelectionData::GetType() const {
188 return type_;
191 const unsigned char* SelectionData::GetData() const {
192 return memory_.get() ? memory_->front() : NULL;
195 size_t SelectionData::GetSize() const {
196 return memory_.get() ? memory_->size() : 0;
199 std::string SelectionData::GetText() const {
200 if (type_ == atom_cache_.GetAtom(kUtf8String) ||
201 type_ == atom_cache_.GetAtom(kText) ||
202 type_ == atom_cache_.GetAtom(kTextPlainUtf8)) {
203 return RefCountedMemoryToString(memory_);
204 } else if (type_ == atom_cache_.GetAtom(kString) ||
205 type_ == atom_cache_.GetAtom(kTextPlain)) {
206 std::string result;
207 base::ConvertToUtf8AndNormalize(RefCountedMemoryToString(memory_),
208 base::kCodepageLatin1,
209 &result);
210 return result;
211 } else {
212 // BTW, I looked at COMPOUND_TEXT, and there's no way we're going to
213 // support that. Yuck.
214 NOTREACHED();
215 return std::string();
219 base::string16 SelectionData::GetHtml() const {
220 base::string16 markup;
222 if (type_ == atom_cache_.GetAtom(Clipboard::kMimeTypeHTML)) {
223 const unsigned char* data = GetData();
224 size_t size = GetSize();
226 // If the data starts with 0xFEFF, i.e., Byte Order Mark, assume it is
227 // UTF-16, otherwise assume UTF-8.
228 if (size >= 2 &&
229 reinterpret_cast<const uint16_t*>(data)[0] == 0xFEFF) {
230 markup.assign(reinterpret_cast<const uint16_t*>(data) + 1,
231 (size / 2) - 1);
232 } else {
233 base::UTF8ToUTF16(reinterpret_cast<const char*>(data), size, &markup);
236 // If there is a terminating NULL, drop it.
237 if (!markup.empty() && markup.at(markup.length() - 1) == '\0')
238 markup.resize(markup.length() - 1);
240 return markup;
241 } else {
242 NOTREACHED();
243 return markup;
247 void SelectionData::AssignTo(std::string* result) const {
248 *result = RefCountedMemoryToString(memory_);
251 void SelectionData::AssignTo(base::string16* result) const {
252 *result = RefCountedMemoryToString16(memory_);
255 } // namespace ui