10#include <private/qstdweb_p.h>
12#include <QCoreApplication>
13#include <qpa/qwindowsysteminterface.h>
17#include <emscripten/val.h>
20using namespace emscripten;
24 QMimeData *_mimes = QWasmIntegration::get()->getWasmClipboard()->mimeData(QClipboard::Clipboard);
29 if (_mimes->hasText()) {
30 event[
"clipboardData"].call<
void>(
"setData", val(
"text/plain"),
31 _mimes->text().toEcmaString());
33 if (_mimes->hasHtml()) {
34 event[
"clipboardData"].call<
void>(
"setData", val(
"text/html"), _mimes->html().toEcmaString());
37 for (
auto mimetype : _mimes->formats()) {
38 if (mimetype.contains(
"text/"))
40 QByteArray ba = _mimes->data(mimetype);
42 event[
"clipboardData"].call<
void>(
"setData", mimetype.toEcmaString(),
46 event.call<
void>(
"preventDefault");
52 if (wasmInput && wasmInput->usingTextInput())
57 QWindowSystemInterface::handleKeyEvent(
58 0, QEvent::KeyPress, Qt::Key_X, Qt::ControlModifier,
"X");
61 commonCopyEvent(event);
67 if (wasmInput && wasmInput->usingTextInput())
72 QWindowSystemInterface::handleKeyEvent(
73 0, QEvent::KeyPress, Qt::Key_C, Qt::ControlModifier,
"C");
75 commonCopyEvent(event);
81 if (wasmInput && wasmInput->usingTextInput())
84 event.call<
void>(
"preventDefault");
90 function(
"qtClipboardCutTo", &qClipboardCutTo);
91 function(
"qtClipboardCopyTo", &qClipboardCopyTo);
92 function(
"qtClipboardPasteTo", &qClipboardPasteTo);
97 val clipboard = val::global(
"navigator")[
"clipboard"];
99 const bool hasPermissionsApi = !val::global(
"navigator")[
"permissions"].isUndefined();
100 m_hasClipboardApi = !clipboard.isUndefined() && !clipboard[
"readText"].isUndefined();
102 if (m_hasClipboardApi && hasPermissionsApi)
103 initClipboardPermissions();
112 if (mode != QClipboard::Clipboard)
115 return QPlatformClipboard::mimeData(mode);
121 QPlatformClipboard::setMimeData(mimeData, mode);
122 if (m_hasClipboardApi)
123 writeToClipboardApi();
130 if (event.type != EventType::KeyDown || !event.modifiers.testFlag(Qt::ControlModifier))
133 if (event.key != Qt::Key_C && event.key != Qt::Key_V && event.key != Qt::Key_X)
136 const bool isPaste = event.key == Qt::Key_V;
138 return m_hasClipboardApi && !isPaste
145 return mode == QClipboard::Clipboard;
156 val permissions = val::global(
"navigator")[
"permissions"];
158 qstdweb::Promise::make(permissions,
"query", { .catchFunc = [](emscripten::val) {} }, ([]() {
159 val readPermissionsMap = val::object();
160 readPermissionsMap.set(
"name", val(
"clipboard-read"));
161 return readPermissionsMap;
163 qstdweb::Promise::make(permissions,
"query", { .catchFunc = [](emscripten::val) {} }, ([]() {
164 val readPermissionsMap = val::object();
165 readPermissionsMap.set(
"name", val(
"clipboard-write"));
166 return readPermissionsMap;
173 emscripten::val isChromium = val::global(
"window")[
"chrome"];
174 if (!isChromium.isUndefined()) {
175 cContext = val::global(
"document");
180 cContext.call<
void>(
"addEventListener", val(
"cut"),
181 val::module_property(
"qtClipboardCutTo"),
true);
182 cContext.call<
void>(
"addEventListener", val(
"copy"),
183 val::module_property(
"qtClipboardCopyTo"),
true);
184 cContext.call<
void>(
"addEventListener", val(
"paste"),
185 val::module_property(
"qtClipboardPasteTo"),
true);
190 return m_hasClipboardApi;
195 Q_ASSERT(m_hasClipboardApi);
201 QMimeData *_mimes = mimeData(QClipboard::Clipboard);
205 emscripten::val clipboardWriteArray = emscripten::val::array();
208 for (
auto mimetype : _mimes->formats()) {
213 if (mimetype.contains(
"STRING", Qt::CaseSensitive) || mimetype.contains(
"TEXT", Qt::CaseSensitive))
216 if (_mimes->hasHtml()) {
217 ba = _mimes->html().toLocal8Bit();
219 mimetype =
"text/html";
220 }
else if (mimetype.contains(
"text/plain")) {
221 ba = _mimes->text().toLocal8Bit();
222 }
else if (mimetype.contains(
"image")) {
223 QImage img = qvariant_cast<QImage>( _mimes->imageData());
225 buffer.open(QIODevice::WriteOnly);
226 img.save(&buffer,
"PNG");
227 mimetype =
"image/png";
233 ba = _mimes->data(mimetype);
237 const char *content = ba.data();
238 int dataLength = ba.length();
239 if (dataLength < 1) {
240 qDebug() <<
"no content found";
244 emscripten::val document = emscripten::val::global(
"document");
245 emscripten::val window = emscripten::val::global(
"window");
247 emscripten::val fileContentView =
248 emscripten::val(emscripten::typed_memory_view(dataLength, content));
249 emscripten::val fileContentCopy = emscripten::val::global(
"ArrayBuffer").new_(dataLength);
250 emscripten::val fileContentCopyView =
251 emscripten::val::global(
"Uint8Array").new_(fileContentCopy);
252 fileContentCopyView.call<
void>(
"set", fileContentView);
254 emscripten::val contentArray = emscripten::val::array();
255 contentArray.call<
void>(
"push", fileContentCopyView);
258 emscripten::val type = emscripten::val::array();
259 type.set(
"type", mimetype.toEcmaString());
261 emscripten::val contentBlob = emscripten::val::global(
"Blob").new_(contentArray, type);
263 emscripten::val clipboardItemObject = emscripten::val::object();
264 clipboardItemObject.set(mimetype.toEcmaString(), contentBlob);
266 val clipboardItemData = val::global(
"ClipboardItem").new_(clipboardItemObject);
268 clipboardWriteArray.call<
void>(
"push", clipboardItemData);
275 val navigator = val::global(
"navigator");
277 qstdweb::Promise::make(
278 navigator[
"clipboard"],
"write",
280 .catchFunc = [](emscripten::val error) {
281 qWarning() <<
"clipboard error"
282 << QString::fromStdString(error[
"name"].as<std::string>())
283 << QString::fromStdString(error[
"message"].as<std::string>());
286 clipboardWriteArray);
295 val document = val::global(
"document");
296 document.call<val>(
"execCommand", val(
"copy"));
301 qDebug() <<
"sendClipboardData";
304 const auto mimeCallback = std::function([transfer](QMimeData *data) {
307 QWasmIntegration::get()->clipboard()->QPlatformClipboard::setMimeData(data, QClipboard::Clipboard);
308 QWindowSystemInterface::handleKeyEvent(0, QEvent::KeyPress, Qt::Key_V,
309 Qt::ControlModifier,
"V");
310 QWindowSystemInterface::handleKeyEvent(0, QEvent::KeyRelease, Qt::Key_V,
311 Qt::ControlModifier,
"V");
315 transfer->toMimeDataWithFile(mimeCallback);
virtual ~QWasmClipboard()
void setMimeData(QMimeData *data, QClipboard::Mode mode=QClipboard::Clipboard) override
@ NativeClipboardEventNeeded
@ NativeClipboardEventAndCopiedDataNeeded
bool supportsMode(QClipboard::Mode mode) const override
QMimeData * mimeData(QClipboard::Mode mode=QClipboard::Clipboard) override
ProcessKeyboardResult processKeyboard(const KeyEvent &event)
bool ownsMode(QClipboard::Mode mode) const override
static QWasmIntegration * get()
QWasmClipboard * getWasmClipboard()
Combined button and popup list for selecting options.
static void qClipboardCutTo(val event)
static void qClipboardPasteTo(val event)
static void commonCopyEvent(val event)
static void qClipboardCopyTo(val event)
EMSCRIPTEN_BINDINGS(qtClipboardModule)