Add QString<->emscripten::val conversion functions
Following the QRect, add functions converting the QString to native emscripten::val and back: fromJsString, toJsString Change-Id: I2d0625ede3bbf7249e2e91b8de298b5b91df8ba2 Reviewed-by: Morten Johan Sørvig <morten.sorvig@qt.io>
This commit is contained in:
parent
4dbb07f614
commit
2e97ccc8d0
@ -42,4 +42,56 @@ emscripten::val QRectF::toDOMRect() const
|
||||
return emscripten::val::global("DOMRect").new_(left(), top(), width(), height());
|
||||
}
|
||||
|
||||
/*!
|
||||
Converts the \l {https://262.ecma-international.org/#sec-string-object}{ECMAScript string} \a
|
||||
jsString to QString. Behavior is undefined if the provided parameter is not a string.
|
||||
|
||||
\since 6.6
|
||||
\ingroup platform-type-conversions
|
||||
|
||||
\sa toJsString()
|
||||
*/
|
||||
QString QString::fromJsString(emscripten::val jsString)
|
||||
{
|
||||
Q_ASSERT_X(jsString.isString(), Q_FUNC_INFO, "Passed object is not a string");
|
||||
|
||||
const double length = jsString["length"].as<double>();
|
||||
|
||||
Q_ASSERT_X((double(uint64_t(length)) != double(uint64_t(length) - 1)
|
||||
&& double(uint64_t(length)) != double(uint64_t(length) + 1))
|
||||
|| !std::numeric_limits<double>::is_iec559,
|
||||
Q_FUNC_INFO, "The floating-point length cannot precisely represent an integer");
|
||||
|
||||
constexpr int zeroTerminatorLength = 1;
|
||||
const auto lengthOfUtf16 = (length + zeroTerminatorLength) * 2;
|
||||
|
||||
Q_ASSERT_X((double(uint64_t(lengthOfUtf16)) != double(uint64_t(lengthOfUtf16) - 1)
|
||||
&& double(uint64_t(lengthOfUtf16)) != double(uint64_t(lengthOfUtf16) + 1))
|
||||
|| !std::numeric_limits<double>::is_iec559,
|
||||
Q_FUNC_INFO,
|
||||
"The floating-point lengthOfUtf16 cannot precisely represent an integer");
|
||||
|
||||
const QString result(uint64_t(length), Qt::Uninitialized);
|
||||
|
||||
static const emscripten::val stringToUTF16(emscripten::val::module_property("stringToUTF16"));
|
||||
stringToUTF16(jsString, emscripten::val(quintptr(result.data())),
|
||||
emscripten::val(lengthOfUtf16));
|
||||
return result;
|
||||
}
|
||||
|
||||
/*!
|
||||
Converts this object to an
|
||||
\l {https://262.ecma-international.org/#sec-string-object}{ECMAScript string}.
|
||||
|
||||
\since 6.6
|
||||
\ingroup platform-type-conversions
|
||||
|
||||
\sa fromJsString()
|
||||
*/
|
||||
emscripten::val QString::toJsString() const
|
||||
{
|
||||
static const emscripten::val UTF16ToString(emscripten::val::module_property("UTF16ToString"));
|
||||
return UTF16ToString(emscripten::val(quintptr(utf16())));
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
@ -806,6 +806,11 @@ public:
|
||||
NSString *toNSString() const Q_DECL_NS_RETURNS_AUTORELEASED;
|
||||
#endif
|
||||
|
||||
#if defined(Q_OS_WASM) || defined(Q_QDOC)
|
||||
static QString fromJsString(emscripten::val jsString);
|
||||
emscripten::val toJsString() const;
|
||||
#endif
|
||||
|
||||
inline bool isNull() const { return d->isNull(); }
|
||||
|
||||
|
||||
|
@ -31,7 +31,6 @@ qt_internal_add_plugin(QWasmIntegrationPlugin
|
||||
qwasmplatform.cpp qwasmplatform.h
|
||||
qwasmscreen.cpp qwasmscreen.h
|
||||
qwasmservices.cpp qwasmservices.h
|
||||
qwasmstring.cpp qwasmstring.h
|
||||
qwasmstylepixmaps_p.h
|
||||
qwasmtheme.cpp qwasmtheme.h
|
||||
qwasmwindow.cpp qwasmwindow.h
|
||||
|
@ -3,7 +3,7 @@
|
||||
|
||||
#include "qwasmclipboard.h"
|
||||
#include "qwasmwindow.h"
|
||||
#include "qwasmstring.h"
|
||||
|
||||
#include <private/qstdweb_p.h>
|
||||
|
||||
#include <emscripten.h>
|
||||
@ -27,12 +27,11 @@ static void commonCopyEvent(val event)
|
||||
|
||||
// doing it this way seems to sanitize the text better that calling data() like down below
|
||||
if (_mimes->hasText()) {
|
||||
event["clipboardData"].call<void>("setData", val("text/plain")
|
||||
, QWasmString::fromQString(_mimes->text()));
|
||||
event["clipboardData"].call<void>("setData", val("text/plain"),
|
||||
_mimes->text().toJsString());
|
||||
}
|
||||
if (_mimes->hasHtml()) {
|
||||
event["clipboardData"].call<void>("setData", val("text/html")
|
||||
, QWasmString::fromQString(_mimes->html()));
|
||||
event["clipboardData"].call<void>("setData", val("text/html"), _mimes->html().toJsString());
|
||||
}
|
||||
|
||||
for (auto mimetype : _mimes->formats()) {
|
||||
@ -40,8 +39,8 @@ static void commonCopyEvent(val event)
|
||||
continue;
|
||||
QByteArray ba = _mimes->data(mimetype);
|
||||
if (!ba.isEmpty())
|
||||
event["clipboardData"].call<void>("setData", QWasmString::fromQString(mimetype)
|
||||
, val(ba.constData()));
|
||||
event["clipboardData"].call<void>("setData", mimetype.toJsString(),
|
||||
val(ba.constData()));
|
||||
}
|
||||
|
||||
event.call<void>("preventDefault");
|
||||
@ -140,7 +139,7 @@ static void qClipboardPasteTo(val dataTransfer)
|
||||
|| itemMimeType.contains("TEXT", Qt::CaseSensitive)) {
|
||||
break;
|
||||
}
|
||||
const QString data = QWasmString::toQString(
|
||||
const QString data = QString::fromJsString(
|
||||
clipboardData.call<val>("getData", val(itemMimeType.toStdString())));
|
||||
|
||||
if (!data.isEmpty()) {
|
||||
@ -329,12 +328,12 @@ void QWasmClipboard::writeToClipboardApi()
|
||||
|
||||
// we have a blob, now create a ClipboardItem
|
||||
emscripten::val type = emscripten::val::array();
|
||||
type.set("type", val(QWasmString::fromQString(mimetype)));
|
||||
type.set("type", mimetype.toJsString());
|
||||
|
||||
emscripten::val contentBlob = emscripten::val::global("Blob").new_(contentArray, type);
|
||||
|
||||
emscripten::val clipboardItemObject = emscripten::val::object();
|
||||
clipboardItemObject.set(val(QWasmString::fromQString(mimetype)), contentBlob);
|
||||
clipboardItemObject.set(mimetype.toJsString(), contentBlob);
|
||||
|
||||
val clipboardItemData = val::global("ClipboardItem").new_(clipboardItemObject);
|
||||
|
||||
|
@ -3,7 +3,6 @@
|
||||
|
||||
#include "qwasmcursor.h"
|
||||
#include "qwasmscreen.h"
|
||||
#include "qwasmstring.h"
|
||||
|
||||
#include <QtCore/qdebug.h>
|
||||
#include <QtGui/qwindow.h>
|
||||
|
@ -6,7 +6,6 @@
|
||||
#include "qwasmcompositor.h"
|
||||
#include "qwasmintegration.h"
|
||||
#include "qwasmclipboard.h"
|
||||
#include "qwasmstring.h"
|
||||
#include "qwasmcursor.h"
|
||||
#include <QtGui/qevent.h>
|
||||
#include <qpa/qwindowsysteminterface.h>
|
||||
|
@ -11,7 +11,6 @@
|
||||
#include "qwasmaccessibility.h"
|
||||
#include "qwasmservices.h"
|
||||
#include "qwasmoffscreensurface.h"
|
||||
#include "qwasmstring.h"
|
||||
|
||||
#include "qwasmwindow.h"
|
||||
#include "qwasmbackingstore.h"
|
||||
@ -287,7 +286,8 @@ void QWasmIntegration::removeScreen(const emscripten::val &element)
|
||||
auto it = std::find_if(m_screens.begin(), m_screens.end(),
|
||||
[&] (const QPair<emscripten::val, QWasmScreen *> &candidate) { return candidate.first.equals(element); });
|
||||
if (it == m_screens.end()) {
|
||||
qWarning() << "Attempting to remove non-existing screen for element" << QWasmString::toQString(element["id"]);;
|
||||
qWarning() << "Attempting to remove non-existing screen for element"
|
||||
<< QString::fromJsString(element["id"]);
|
||||
return;
|
||||
}
|
||||
it->second->deleteScreen();
|
||||
@ -299,7 +299,8 @@ void QWasmIntegration::resizeScreen(const emscripten::val &element)
|
||||
auto it = std::find_if(m_screens.begin(), m_screens.end(),
|
||||
[&] (const QPair<emscripten::val, QWasmScreen *> &candidate) { return candidate.first.equals(element); });
|
||||
if (it == m_screens.end()) {
|
||||
qWarning() << "Attempting to resize non-existing screen for element" << QWasmString::toQString(element["id"]);;
|
||||
qWarning() << "Attempting to resize non-existing screen for element"
|
||||
<< QString::fromJsString(element["id"]);
|
||||
return;
|
||||
}
|
||||
it->second->updateQScreenAndCanvasRenderSize();
|
||||
|
@ -6,7 +6,6 @@
|
||||
#include "qwasmeventtranslator.h"
|
||||
#include "qwasmcompositor.h"
|
||||
#include "qwasmintegration.h"
|
||||
#include "qwasmstring.h"
|
||||
#include "qwasmcssstyle.h"
|
||||
|
||||
#include <emscripten/bind.h>
|
||||
@ -194,7 +193,7 @@ qreal QWasmScreen::devicePixelRatio() const
|
||||
|
||||
QString QWasmScreen::name() const
|
||||
{
|
||||
return QWasmString::toQString(m_shadowContainer["id"]);
|
||||
return QString::fromJsString(m_shadowContainer["id"]);
|
||||
}
|
||||
|
||||
QPlatformCursor *QWasmScreen::cursor() const
|
||||
|
@ -2,7 +2,6 @@
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
|
||||
|
||||
#include "qwasmservices.h"
|
||||
#include "qwasmstring.h"
|
||||
|
||||
#include <QtCore/QUrl>
|
||||
#include <QtCore/QDebug>
|
||||
@ -13,8 +12,8 @@ QT_BEGIN_NAMESPACE
|
||||
|
||||
bool QWasmServices::openUrl(const QUrl &url)
|
||||
{
|
||||
emscripten::val jsUrl = QWasmString::fromQString(url.toString());
|
||||
emscripten::val::global("window").call<void>("open", jsUrl, emscripten::val("_blank"));
|
||||
emscripten::val::global("window").call<void>("open", url.toString().toJsString(),
|
||||
emscripten::val("_blank"));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -1,36 +0,0 @@
|
||||
// Copyright (C) 2020 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
|
||||
|
||||
#include "qwasmstring.h"
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
using namespace emscripten;
|
||||
|
||||
val QWasmString::fromQString(const QString &str)
|
||||
{
|
||||
static const val UTF16ToString(
|
||||
val::module_property("UTF16ToString"));
|
||||
|
||||
auto ptr = quintptr(str.utf16());
|
||||
return UTF16ToString(val(ptr));
|
||||
}
|
||||
|
||||
QString QWasmString::toQString(const val &v)
|
||||
{
|
||||
QString result;
|
||||
if (!v.isString())
|
||||
return result;
|
||||
|
||||
static const val stringToUTF16(
|
||||
val::module_property("stringToUTF16"));
|
||||
static const val length("length");
|
||||
|
||||
int len = v[length].as<int>();
|
||||
result.resize(len);
|
||||
auto ptr = quintptr(result.utf16());
|
||||
stringToUTF16(v, val(ptr), val((len + 1) * 2));
|
||||
return result;
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
@ -1,19 +0,0 @@
|
||||
// Copyright (C) 2020 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <qstring.h>
|
||||
|
||||
#include <emscripten/val.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QWasmString
|
||||
{
|
||||
public:
|
||||
static emscripten::val fromQString(const QString &str);
|
||||
static QString toQString(const emscripten::val &v);
|
||||
};
|
||||
QT_END_NAMESPACE
|
||||
|
@ -18,7 +18,6 @@
|
||||
#include "qwasmcompositor.h"
|
||||
#include "qwasmevent.h"
|
||||
#include "qwasmeventdispatcher.h"
|
||||
#include "qwasmstring.h"
|
||||
#include "qwasmaccessibility.h"
|
||||
|
||||
#include <iostream>
|
||||
|
@ -9,6 +9,9 @@ if(APPLE)
|
||||
list(APPEND tst_qstring_extra_libraries ${FWFoundation})
|
||||
list(APPEND tst_qstring_extra_sources tst_qstring_mac.mm)
|
||||
endif()
|
||||
if(WASM)
|
||||
list(APPEND tst_qstring_extra_sources tst_qstring_wasm.cpp)
|
||||
endif()
|
||||
|
||||
foreach(test tst_qstring tst_qstring_restricted_ascii)
|
||||
qt_internal_add_test(${test}
|
||||
|
@ -541,6 +541,7 @@ private slots:
|
||||
#endif
|
||||
void STL();
|
||||
void macTypes();
|
||||
void wasmTypes();
|
||||
void isEmpty();
|
||||
void isNull();
|
||||
void nullness();
|
||||
@ -1344,6 +1345,16 @@ void tst_QString::macTypes()
|
||||
#endif
|
||||
}
|
||||
|
||||
void tst_QString::wasmTypes()
|
||||
{
|
||||
#ifndef Q_OS_WASM
|
||||
QSKIP("This is a WASM-only test");
|
||||
#else
|
||||
extern void tst_QString_wasmTypes(); // in qcore_wasm.cpp
|
||||
tst_QString_wasmTypes();
|
||||
#endif
|
||||
}
|
||||
|
||||
void tst_QString::truncate()
|
||||
{
|
||||
QString nullStr;
|
||||
|
28
tests/auto/corelib/text/qstring/tst_qstring_wasm.cpp
Normal file
28
tests/auto/corelib/text/qstring/tst_qstring_wasm.cpp
Normal file
@ -0,0 +1,28 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
#include <QtCore/QString>
|
||||
#include <QTest>
|
||||
|
||||
#include <emscripten/val.h>
|
||||
|
||||
void tst_QString_wasmTypes()
|
||||
{
|
||||
// QString <-> emscripten::val
|
||||
{
|
||||
QString qtString("test string");
|
||||
const emscripten::val jsString = qtString.toJsString();
|
||||
QString qtStringCopy(qtString);
|
||||
qtString = qtString.toUpper(); // modify
|
||||
QCOMPARE(QString::fromJsString(jsString), qtStringCopy);
|
||||
}
|
||||
{
|
||||
QString longString;
|
||||
for (uint64_t i = 0; i < 1000; ++i)
|
||||
longString += "Lorem ipsum FTW";
|
||||
const emscripten::val jsString = longString.toJsString();
|
||||
QString qtStringCopy(longString);
|
||||
longString = longString.toUpper(); // modify
|
||||
QCOMPARE(QString::fromJsString(jsString), qtStringCopy);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user