8000 Add macOS find pasteboard support by kevinsawicki · Pull Request #7719 · electron/electron · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Add macOS find pasteboard support #7719

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Oct 26, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
101 changes: 55 additions & 46 deletions atom/common/api/atom_api_clipboard.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2,47 +2,43 @@
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.

#include <string>
#include <vector>
#include "atom/common/api/atom_api_clipboard.h"

#include "atom/common/native_mate_converters/image_converter.h"
#include "atom/common/native_mate_converters/string16_converter.h"
#include "base/strings/utf_string_conversions.h"
#include "native_mate/arguments.h"
#include "native_mate/dictionary.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "ui/base/clipboard/clipboard.h"
#include "ui/base/clipboard/scoped_clipboard_writer.h"
#include "ui/gfx/image/image.h"

#include "atom/common/node_includes.h"

namespace {
namespace atom {

namespace api {

ui::ClipboardType GetClipboardType(mate::Arguments* args) {
ui::ClipboardType Clipboard::GetClipboardType(mate::Arguments* args) {
std::string type;
if (args->GetNext(&type) && type == "selection")
return ui::CLIPBOARD_TYPE_SELECTION;
else
return ui::CLIPBOARD_TYPE_COPY_PASTE;
}

std::vector<base::string16> AvailableFormats(mate::Arguments* args) {
std::vector<base::string16> Clipboard::AvailableFormats(mate::Arguments* args) {
std::vector<base::string16> format_types;
bool ignore;
ui::Clipboard* clipboard = ui::Clipboard::GetForCurrentThread();
clipboard->ReadAvailableTypes(GetClipboardType(args), &format_types, &ignore);
return format_types;
}

bool Has(const std::string& format_string, mate::Arguments* args) {
bool Clipboard::Has(const std::string& format_string, mate::Arguments* args) {
ui::Clipboard* clipboard = ui::Clipboard::GetForCurrentThread();
ui::Clipboard::FormatType format(ui::Clipboard::GetFormatType(format_string));
return clipboard->IsFormatAvailable(format, GetClipboardType(args));
}

std::string Read(const std::string& format_string,
mate::Arguments* args) {
std::string Clipboard::Read(const std::string& format_string,
mate::Arguments* args) {
ui::Clipboard* clipboard = ui::Clipboard::GetForCurrentThread();
ui::Clipboard::FormatType format(ui::Clipboard::GetFormatType(format_string));

Expand All @@ -51,8 +47,7 @@ std::string Read(const std::string& format_string,
return data;
}

void Write(const mate::Dictionary& data,
mate::Arguments* args) {
void Clipboard::Write(const mate::Dictionary& data, mate::Arguments* args) {
ui::ScopedClipboardWriter writer(GetClipboardType(args));
base::string16 text, html, bookmark;
gfx::Image image;
Expand All @@ -76,7 +71,7 @@ void Write(const mate::Dictionary& data,
writer.WriteImage(image.AsBitmap());
}

base::string16 ReadText(mate::Arguments* args) {
base::string16 Clipboard::ReadText(mate::Arguments* args) {
base::string16 data;
ui::Clipboard* clipboard = ui::Clipboard::GetForCurrentThread();
auto type = GetClipboardType(args);
Expand All @@ -92,24 +87,24 @@ base::string16 ReadText(mate::Arguments* args) {
return data;
}

void WriteText(const base::string16& text, mate::Arguments* args) {
void Clipboard::WriteText(const base::string16& text, mate::Arguments* args) {
ui::ScopedClipboardWriter writer(GetClipboardType(args));
writer.WriteText(text);
}

base::string16 ReadRtf(mate::Arguments* args) {
base::string16 Clipboard::ReadRtf(mate::Arguments* args) {
std::string data;
ui::Clipboard* clipboard = ui::Clipboard::GetForCurrentThread();
clipboard->ReadRTF(GetClipboardType(args), &data);
return base::UTF8ToUTF16(data);
}

void WriteRtf(const std::string& text, mate::Arguments* args) {
void Clipboard::WriteRtf(const std::string& text, mate::Arguments* args) {
ui::ScopedClipboardWriter writer(GetClipboardType(args));
writer.WriteRTF(text);
}

base::string16 ReadHtml(mate::Arguments* args) {
base::string16 Clipboard::ReadHtml(mate::Arguments* args) {
base::string16 data;
base::string16 html;
std::string url;
Expand All @@ -121,12 +116,12 @@ base::string16 ReadHtml(mate::Arguments* args) {
return data;
}

void WriteHtml(const base::string16& html, mate::Arguments* args) {
void Clipboard::WriteHtml(const base::string16& html, mate::Arguments* args) {
ui::ScopedClipboardWriter writer(GetClipboardType(args));
writer.WriteHTML(html, std::string());
}

v8::Local<v8::Value> ReadBookmark(mate::Arguments* args) {
v8::Local<v8::Value> Clipboard::ReadBookmark(mate::Arguments* args) {
base::string16 title;
std::string url;
mate::Dictionary dict = mate::Dictionary::CreateEmpty(args->isolate());
Expand All @@ -137,51 +132,65 @@ v8::Local<v8::Value> ReadBookmark(mate::Arguments* args) {
return dict.GetHandle();
}

void WriteBookmark(const base::string16& title, const std::string& url,
mate::Arguments* args) {
void Clipboard::WriteBookmark(const base::string16& title,
const std::string& url,
mate::Arguments* args) {
ui::ScopedClipboardWriter writer(GetClipboardType(args));
writer.WriteBookmark(title, url);
}

gfx::Image ReadImage(mate::Arguments* args) {
gfx::Image Clipboard::ReadImage(mate::Arguments* args) {
ui::Clipboard* clipboard = ui::Clipboard::GetForCurrentThread();
SkBitmap bitmap = clipboard->ReadImage(GetClipboardType(args));
return gfx::Image::CreateFrom1xBitmap(bitmap);
}

void WriteImage(const gfx::Image& image, mate::Arguments* args) {
void Clipboard::WriteImage(const gfx::Image& image, mate::Arguments* args) {
ui::ScopedClipboardWriter writer(GetClipboardType(args));
writer.WriteImage(image.AsBitmap());
}

void Clear(mate::Arguments* args) {
#if !defined(OS_MACOSX)
void Clipboard::WriteFindText(const base::string16& text) {}
base::string16 Clipboard::ReadFindText() { return base::string16(); }
#endif

void Clipboard::Clear(mate::Arguments* args) {
ui::Clipboard::GetForCurrentThread()->Clear(GetClipboardType(args));
}

} // namespace api

} // namespace atom

namespace {

void Initialize(v8::Local<v8::Object> exports, v8::Local<v8::Value> unused,
v8::Local<v8::Context> context, void* priv) {
mate::Dictionary dict(context->GetIsolate(), exports);
dict.SetMethod("availableFormats", &AvailableFormats);
dict.SetMethod("has", &Has);
dict.SetMethod("read", &Read);
dict.SetMethod("write", &Write);
dict.SetMethod("readText", &ReadText);
dict.SetMethod("writeText", &WriteText);
dict.SetMethod("readRTF", &ReadRtf);
dict.SetMethod("writeRTF", &WriteRtf);
dict.SetMethod("readHTML", &ReadHtml);
dict.SetMethod("writeHTML", &WriteHtml);
dict.SetMethod("readBookmark", &ReadBookmark);
dict.SetMethod("writeBookmark", &WriteBookmark);
dict.SetMethod("readImage", &ReadImage);
dict.SetMethod("writeImage", &WriteImage);
dict.SetMethod("clear", &Clear);
dict.SetMethod("availableFormats", &atom::api::Clipboard::AvailableFormats);
dict.SetMethod("has", &atom::api::Clipboard::Has);
dict.SetMethod("read", &atom::api::Clipboard::Read);
dict.SetMethod("write", &atom::api::Clipboard::Write);
dict.SetMethod("readText", &atom::api::Clipboard::ReadText);
dict.SetMethod("writeText", &atom::api::Clipboard::WriteText);
dict.SetMethod("readRTF", &atom::api::Clipboard::ReadRtf);
dict.SetMethod("writeRTF", &atom::api::Clipboard::WriteRtf);
dict.SetMethod("readHTML", &atom::api::Clipboard::ReadHtml);
dict.SetMethod("writeHTML", &atom::api::Clipboard::WriteHtml);
dict.SetMethod("readBookmark", &atom::api::Clipboard::ReadBookmark);
dict.SetMethod("writeBookmark", &atom::api::Clipboard::WriteBookmark);
dict.SetMethod("readImage", &atom::api::Clipboard::ReadImage);
dict.SetMethod("writeImage", &atom::api::Clipboard::WriteImage);
dict.SetMethod("readFindText", &atom::api::Clipboard::ReadFindText);
dict.SetMethod("writeFindText", &atom::api::Clipboard::WriteFindText);
dict.SetMethod("clear", &atom::api::Clipboard::Clear);

// TODO(kevinsawicki): Remove in 2.0, deprecate before then with warnings
dict.SetMethod("readRtf", &ReadRtf);
dict.SetMethod("writeRtf", &WriteRtf);
dict.SetMethod("readHtml", &ReadHtml);
dict.SetMethod("writeHtml", &WriteHtml);
dict.SetMethod("readRtf", &atom::api::Clipboard::ReadRtf);
dict.SetMethod("writeRtf", &atom::api::Clipboard::WriteRtf);
dict.SetMethod("readHtml", &atom::api::Clipboard::ReadHtml);
dict.SetMethod("writeHtml", &atom::api::Clipboard::WriteHtml);
}

} // namespace
Expand Down
59 changes: 59 additions & 0 deletions atom/common/api/atom_api_clipboard.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
// Copyright (c) 2016 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.

#ifndef ATOM_COMMON_API_ATOM_API_CLIPBOARD_H_
#define ATOM_COMMON_API_ATOM_API_CLIPBOARD_H_

#include <string>
#include <vector>

#include "native_mate/arguments.h"
#include "native_mate/dictionary.h"
#include "ui/base/clipboard/clipboard.h"
#include "ui/gfx/image/image.h"

namespace atom {

namespace api {

class Clipboard {
public:
static ui::ClipboardType GetClipboardType(mate::Arguments* args);
static std::vector<base::string16> AvailableFormats(mate::Arguments* args);
static bool Has(const std::string& format_string, mate::Arguments* args);
static void Clear(mate::Arguments* args);

static std::string Read(const std::string& format_string,
mate::Arguments* args);
static void Write(const mate::Dictionary& data, mate::Arguments* args);

static base::string16 ReadText(mate::Arguments* args);
static void WriteText(const base::string16& text, mate::Arguments* args);

static base::string16 ReadRtf(mate::Arguments* args);
static void WriteRtf(const std::string& text, mate::Arguments* args);

static base::string16 ReadHtml(mate::Arguments* args);
static void WriteHtml(const base::string16& html, mate::Arguments* args);

static v8::Local<v8::Value> ReadBookmark(mate::Arguments* args);
static void WriteBookmark(const base::string16& title,
const std::string& url,
mate::Arguments* args);

static gfx::Image ReadImage(mate::Arguments* args);
static void WriteImage(const gfx::Image& image, mate::Arguments* args);

static base::string16 ReadFindText();
static void WriteFindText(const base::string16& text);

private:
DISALLOW_COPY_AND_ASSIGN(Clipboard);
};

} // namespace api

} // namespace atom

#endif // ATOM_COMMON_API_ATOM_API_CLIPBOARD_H_
24 changes: 24 additions & 0 deletions atom/common/api/atom_api_clipboard_mac.mm
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// Copyright (c) 2016 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.

#include "atom/common/api/atom_api_clipboard.h"
#include "base/strings/sys_string_conversions.h"
#include "ui/base/cocoa/find_pasteboard.h"

namespace atom {

namespace api {

void Clipboard::WriteFindText(const base::string16& text) {
NSString* text_ns = base::SysUTF16ToNSString(text);
[[FindPasteboard sharedInstance] setFindText:text_ns];
}

base::string16 Clipboard::ReadFindText() {
return GetFindPboardText();
}

} // namespace api

} // namespace atom
13 changes: 13 additions & 0 deletions docs/api/clipboard.md
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,19 @@ clipboard.write({
})
```

### `clipboard.readFindText()` _macOS_

Returns `String` - The text on the find pasteboard. This method uses synchronous
IPC when called from the renderer process. The cached value is reread from the
find pasteboard whenever the application is activated.

### `clipboard.writeFindText(text)` _macOS_

* `text` String

Writes the `text` into the find pasteboard as plain text. This method uses
synchronous IPC when called from the renderer process.

### `clipboard.clear([type])`

* `type` String (optional)
Expand Down
2 changes: 2 additions & 0 deletions filenames.gypi
Original file line number Diff line number Diff line change
Expand Up @@ -340,6 +340,8 @@
'atom/common/api/api_messages.h',
'atom/common/api/atom_api_asar.cc',
'atom/common/api/atom_api_clipboard.cc',
'atom/common/api/atom_api_clipboard.h',
'atom/common/api/atom_api_clipboard_mac.mm',
'atom/common/api/atom_api_crash_reporter.cc',
'atom/common/api/atom_api_key_weak_map.h',
'atom/common/api/atom_api_native_image.cc',
Expand Down
11 changes: 10 additions & 1 deletion lib/common/api/clipboard.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,14 @@ if (process.platform === 'linux' && process.type === 'renderer') {
// On Linux we could not access clipboard in renderer process.
module.exports = require('electron').remote.clipboard
} else {
module.exports = process.atomBinding('clipboard')
const clipboard = process.atomBinding('clipboard')

// Read/write to find pasteboard over IPC since only main process is notified
// of changes
if (process.platform === 'darwin' && process.type === 'renderer') {
clipboard.readFindText = require('electron').remote.clipboard.readFindText
clipboard.writeFindText = require('electron').remote.clipboard.writeFindText
}

module.exports = clipboard
}
9 changes: 9 additions & 0 deletions spec/api-clipboard-spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -84,4 +84,13 @@ describe('clipboard module', function () {
}
})
})

describe('clipboard.read/writeFindText(text)', function () {
it('reads and write text to the find pasteboard', function () {
if (process.platform !== 'darwin') return this.skip()

clipboard.writeFindText('find this')
assert.equal(clipboard.readFindText(), 'find this')
})
})
})
0