atom_api_clipboard.cc 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  1. // Copyright (c) 2013 GitHub, Inc.
  2. // Use of this source code is governed by the MIT license that can be
  3. // found in the LICENSE file.
  4. #include "atom/common/api/atom_api_clipboard.h"
  5. #include "atom/common/native_mate_converters/image_converter.h"
  6. #include "atom/common/native_mate_converters/string16_converter.h"
  7. #include "base/strings/utf_string_conversions.h"
  8. #include "third_party/skia/include/core/SkBitmap.h"
  9. #include "third_party/skia/include/core/SkImageInfo.h"
  10. #include "third_party/skia/include/core/SkPixmap.h"
  11. #include "ui/base/clipboard/clipboard_format_type.h"
  12. #include "ui/base/clipboard/scoped_clipboard_writer.h"
  13. #include "atom/common/node_includes.h"
  14. namespace atom {
  15. namespace api {
  16. ui::ClipboardType Clipboard::GetClipboardType(mate::Arguments* args) {
  17. std::string type;
  18. if (args->GetNext(&type) && type == "selection")
  19. return ui::CLIPBOARD_TYPE_SELECTION;
  20. else
  21. return ui::CLIPBOARD_TYPE_COPY_PASTE;
  22. }
  23. std::vector<base::string16> Clipboard::AvailableFormats(mate::Arguments* args) {
  24. std::vector<base::string16> format_types;
  25. bool ignore;
  26. ui::Clipboard* clipboard = ui::Clipboard::GetForCurrentThread();
  27. clipboard->ReadAvailableTypes(GetClipboardType(args), &format_types, &ignore);
  28. return format_types;
  29. }
  30. bool Clipboard::Has(const std::string& format_string, mate::Arguments* args) {
  31. ui::Clipboard* clipboard = ui::Clipboard::GetForCurrentThread();
  32. ui::ClipboardFormatType format(
  33. ui::ClipboardFormatType::GetType(format_string));
  34. return clipboard->IsFormatAvailable(format, GetClipboardType(args));
  35. }
  36. std::string Clipboard::Read(const std::string& format_string) {
  37. ui::Clipboard* clipboard = ui::Clipboard::GetForCurrentThread();
  38. ui::ClipboardFormatType format(
  39. ui::ClipboardFormatType::GetType(format_string));
  40. std::string data;
  41. clipboard->ReadData(format, &data);
  42. return data;
  43. }
  44. v8::Local<v8::Value> Clipboard::ReadBuffer(const std::string& format_string,
  45. mate::Arguments* args) {
  46. std::string data = Read(format_string);
  47. return node::Buffer::Copy(args->isolate(), data.data(), data.length())
  48. .ToLocalChecked();
  49. }
  50. void Clipboard::WriteBuffer(const std::string& format,
  51. const v8::Local<v8::Value> buffer,
  52. mate::Arguments* args) {
  53. if (!node::Buffer::HasInstance(buffer)) {
  54. args->ThrowError("buffer must be a node Buffer");
  55. return;
  56. }
  57. ui::ScopedClipboardWriter writer(GetClipboardType(args));
  58. writer.WriteData(
  59. ui::ClipboardFormatType::GetType(format).Serialize(),
  60. std::string(node::Buffer::Data(buffer), node::Buffer::Length(buffer)));
  61. }
  62. void Clipboard::Write(const mate::Dictionary& data, mate::Arguments* args) {
  63. ui::ScopedClipboardWriter writer(GetClipboardType(args));
  64. base::string16 text, html, bookmark;
  65. gfx::Image image;
  66. if (data.Get("text", &text)) {
  67. writer.WriteText(text);
  68. if (data.Get("bookmark", &bookmark))
  69. writer.WriteBookmark(bookmark, base::UTF16ToUTF8(text));
  70. }
  71. if (data.Get("rtf", &text)) {
  72. std::string rtf = base::UTF16ToUTF8(text);
  73. writer.WriteRTF(rtf);
  74. }
  75. if (data.Get("html", &html))
  76. writer.WriteHTML(html, std::string());
  77. if (data.Get("image", &image))
  78. writer.WriteImage(image.AsBitmap());
  79. }
  80. base::string16 Clipboard::ReadText(mate::Arguments* args) {
  81. base::string16 data;
  82. ui::Clipboard* clipboard = ui::Clipboard::GetForCurrentThread();
  83. auto type = GetClipboardType(args);
  84. if (clipboard->IsFormatAvailable(ui::ClipboardFormatType::GetPlainTextWType(),
  85. type)) {
  86. clipboard->ReadText(type, &data);
  87. } else if (clipboard->IsFormatAvailable(
  88. ui::ClipboardFormatType::GetPlainTextType(), type)) {
  89. std::string result;
  90. clipboard->ReadAsciiText(type, &result);
  91. data = base::ASCIIToUTF16(result);
  92. }
  93. return data;
  94. }
  95. void Clipboard::WriteText(const base::string16& text, mate::Arguments* args) {
  96. ui::ScopedClipboardWriter writer(GetClipboardType(args));
  97. writer.WriteText(text);
  98. }
  99. base::string16 Clipboard::ReadRTF(mate::Arguments* args) {
  100. std::string data;
  101. ui::Clipboard* clipboard = ui::Clipboard::GetForCurrentThread();
  102. clipboard->ReadRTF(GetClipboardType(args), &data);
  103. return base::UTF8ToUTF16(data);
  104. }
  105. void Clipboard::WriteRTF(const std::string& text, mate::Arguments* args) {
  106. ui::ScopedClipboardWriter writer(GetClipboardType(args));
  107. writer.WriteRTF(text);
  108. }
  109. base::string16 Clipboard::ReadHTML(mate::Arguments* args) {
  110. base::string16 data;
  111. base::string16 html;
  112. std::string url;
  113. uint32_t start;
  114. uint32_t end;
  115. ui::Clipboard* clipboard = ui::Clipboard::GetForCurrentThread();
  116. clipboard->ReadHTML(GetClipboardType(args), &html, &url, &start, &end);
  117. data = html.substr(start, end - start);
  118. return data;
  119. }
  120. void Clipboard::WriteHTML(const base::string16& html, mate::Arguments* args) {
  121. ui::ScopedClipboardWriter writer(GetClipboardType(args));
  122. writer.WriteHTML(html, std::string());
  123. }
  124. v8::Local<v8::Value> Clipboard::ReadBookmark(mate::Arguments* args) {
  125. base::string16 title;
  126. std::string url;
  127. mate::Dictionary dict = mate::Dictionary::CreateEmpty(args->isolate());
  128. ui::Clipboard* clipboard = ui::Clipboard::GetForCurrentThread();
  129. clipboard->ReadBookmark(&title, &url);
  130. dict.Set("title", title);
  131. dict.Set("url", url);
  132. return dict.GetHandle();
  133. }
  134. void Clipboard::WriteBookmark(const base::string16& title,
  135. const std::string& url,
  136. mate::Arguments* args) {
  137. ui::ScopedClipboardWriter writer(GetClipboardType(args));
  138. writer.WriteBookmark(title, url);
  139. }
  140. gfx::Image Clipboard::ReadImage(mate::Arguments* args) {
  141. ui::Clipboard* clipboard = ui::Clipboard::GetForCurrentThread();
  142. SkBitmap bitmap = clipboard->ReadImage(GetClipboardType(args));
  143. return gfx::Image::CreateFrom1xBitmap(bitmap);
  144. }
  145. void Clipboard::WriteImage(const gfx::Image& image, mate::Arguments* args) {
  146. ui::ScopedClipboardWriter writer(GetClipboardType(args));
  147. SkBitmap orig = image.AsBitmap();
  148. SkBitmap bmp;
  149. if (bmp.tryAllocPixels(orig.info()) &&
  150. orig.readPixels(bmp.info(), bmp.getPixels(), bmp.rowBytes(), 0, 0)) {
  151. writer.WriteImage(bmp);
  152. }
  153. }
  154. #if !defined(OS_MACOSX)
  155. void Clipboard::WriteFindText(const base::string16& text) {}
  156. base::string16 Clipboard::ReadFindText() {
  157. return base::string16();
  158. }
  159. #endif
  160. void Clipboard::Clear(mate::Arguments* args) {
  161. ui::Clipboard::GetForCurrentThread()->Clear(GetClipboardType(args));
  162. }
  163. } // namespace api
  164. } // namespace atom
  165. namespace {
  166. void Initialize(v8::Local<v8::Object> exports,
  167. v8::Local<v8::Value> unused,
  168. v8::Local<v8::Context> context,
  169. void* priv) {
  170. mate::Dictionary dict(context->GetIsolate(), exports);
  171. dict.SetMethod("availableFormats", &atom::api::Clipboard::AvailableFormats);
  172. dict.SetMethod("has", &atom::api::Clipboard::Has);
  173. dict.SetMethod("read", &atom::api::Clipboard::Read);
  174. dict.SetMethod("write", &atom::api::Clipboard::Write);
  175. dict.SetMethod("readText", &atom::api::Clipboard::ReadText);
  176. dict.SetMethod("writeText", &atom::api::Clipboard::WriteText);
  177. dict.SetMethod("readRTF", &atom::api::Clipboard::ReadRTF);
  178. dict.SetMethod("writeRTF", &atom::api::Clipboard::WriteRTF);
  179. dict.SetMethod("readHTML", &atom::api::Clipboard::ReadHTML);
  180. dict.SetMethod("writeHTML", &atom::api::Clipboard::WriteHTML);
  181. dict.SetMethod("readBookmark", &atom::api::Clipboard::ReadBookmark);
  182. dict.SetMethod("writeBookmark", &atom::api::Clipboard::WriteBookmark);
  183. dict.SetMethod("readImage", &atom::api::Clipboard::ReadImage);
  184. dict.SetMethod("writeImage", &atom::api::Clipboard::WriteImage);
  185. dict.SetMethod("readFindText", &atom::api::Clipboard::ReadFindText);
  186. dict.SetMethod("writeFindText", &atom::api::Clipboard::WriteFindText);
  187. dict.SetMethod("readBuffer", &atom::api::Clipboard::ReadBuffer);
  188. dict.SetMethod("writeBuffer", &atom::api::Clipboard::WriteBuffer);
  189. dict.SetMethod("clear", &atom::api::Clipboard::Clear);
  190. }
  191. } // namespace
  192. NODE_LINKED_MODULE_CONTEXT_AWARE(atom_common_clipboard, Initialize)