diff options
author | Ulf Hermann <ulf.hermann@qt.io> | 2020-12-07 15:04:44 +0100 |
---|---|---|
committer | Ulf Hermann <ulf.hermann@qt.io> | 2020-12-07 15:53:39 +0100 |
commit | 61a5860599cb2bf770ea3150f8a993d3b08b840a (patch) | |
tree | 266eaafa852e5a95622a8fb0a571d5f3ab2eb39c /src/qml/jsapi | |
parent | e8596de70e46e98a851ac8204e294e5ef4994b96 (diff) |
QJSValue: Add toVariant() overload with conversion behavior
The QJSValue to QVariant conversion is traditionally messy. The recent
addition of a special case for FunctionObject did not make that better.
Rather, we now add a way of specifying that the conversion should be
lossless, which avoids all conversions of JS objects and arrays.
Amends commit 6b08c24297f39f3c67bc5c16f46198b33af66529.
Change-Id: I6d4506b52d3175ed2f2984f8a26d560cf6311ab6
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Diffstat (limited to 'src/qml/jsapi')
-rw-r--r-- | src/qml/jsapi/qjsvalue.cpp | 54 | ||||
-rw-r--r-- | src/qml/jsapi/qjsvalue.h | 8 |
2 files changed, 50 insertions, 12 deletions
diff --git a/src/qml/jsapi/qjsvalue.cpp b/src/qml/jsapi/qjsvalue.cpp index 5c246bf2fd..ad5ab95408 100644 --- a/src/qml/jsapi/qjsvalue.cpp +++ b/src/qml/jsapi/qjsvalue.cpp @@ -184,6 +184,17 @@ provided is malformed. */ +/*! + \enum QJSValue::ObjectConversionBehavior + + This enum is used to specify how JavaScript objects without an equivalent + native Qt type should be treated when converting to QVariant. + + \value ConvertJSObjects A best-effort, possibly lossy, conversion is attempted. + + \value RetainJSObjects The value is retained as QJSValue wrapped in QVariant. +*/ + QT_BEGIN_NAMESPACE using namespace QV4; @@ -549,9 +560,22 @@ quint32 QJSValue::toUInt() const } /*! - Returns the QVariant value of this QJSValue, if it can be - converted to a QVariant; otherwise returns an invalid QVariant. - The conversion is performed according to the following table: + \overload + + Returns toVariant(ConvertJSObjects). + + \sa isVariant() +*/ +QVariant QJSValue::toVariant() const +{ + return toVariant(ConvertJSObjects); +} + +/*! + Returns the QVariant value of this QJSValue, if it can be + converted to a QVariant; otherwise returns an invalid QVariant. + Some JavaScript types and objects have native expressions in Qt. + Those are converted to their native expressions. For example: \table \header \li Input Type \li Result @@ -563,14 +587,22 @@ quint32 QJSValue::toUInt() const \row \li QVariant Object \li The result is the QVariant value of the object (no conversion). \row \li QObject Object \li A QVariant containing a pointer to the QObject. \row \li Date Object \li A QVariant containing the date value (toDateTime()). - \row \li RegExp Object \li A QVariant containing the regular expression value. - \row \li Array Object \li The array is converted to a QVariantList. Each element is converted to a QVariant, recursively; cyclic references are not followed. - \row \li Object \li The object is converted to a QVariantMap. Each property is converted to a QVariant, recursively; cyclic references are not followed. + \row \li RegularExpression Object \li A QVariant containing the regular expression value. \endtable - \sa isVariant() + For other types the \a behavior parameter is relevant. If + \c ConvertJSObjects is given, a best effort but possibly lossy conversion is + attempted. Generic JavaScript objects are converted to QVariantMap. + JavaScript arrays are converted to QVariantList. Each property or element is + converted to a QVariant, recursively; cyclic references are not followed. + JavaScript function objects are dropped. If \c RetainJSObjects is given, the + QJSValue is wrapped into a QVariant via QVariant::fromValue(). The resulting + conversion is lossless but the internal structure of the objects is not + immediately accessible. + + \sa isVariant() */ -QVariant QJSValue::toVariant() const +QVariant QJSValue::toVariant(QJSValue::ObjectConversionBehavior behavior) const { if (const QString *string = QJSValuePrivate::asQString(this)) return QVariant(*string); @@ -591,10 +623,8 @@ QVariant QJSValue::toVariant() const if (val.isString()) return QVariant(val.toQString()); - if (QV4::Managed *m = val.as<QV4::Managed>()) { - return m->engine()->toVariant(val, /*typeHint*/ -1, - /*createJSValueForObjects*/ val.isFunctionObject()); - } + if (QV4::Managed *m = val.as<QV4::Managed>()) + return m->engine()->toVariant(val, /*typeHint*/ -1, behavior == RetainJSObjects); Q_ASSERT(false); return QVariant(); diff --git a/src/qml/jsapi/qjsvalue.h b/src/qml/jsapi/qjsvalue.h index 8a62b974c8..ad3c4ffd4d 100644 --- a/src/qml/jsapi/qjsvalue.h +++ b/src/qml/jsapi/qjsvalue.h @@ -79,6 +79,11 @@ public: URIError }; + enum ObjectConversionBehavior { + ConvertJSObjects, + RetainJSObjects + }; + public: QJSValue(SpecialValue value = UndefinedValue); ~QJSValue(); @@ -121,7 +126,10 @@ public: qint32 toInt() const; quint32 toUInt() const; bool toBool() const; + QVariant toVariant() const; + QVariant toVariant(ObjectConversionBehavior behavior) const; + QObject *toQObject() const; const QMetaObject *toQMetaObject() const; QDateTime toDateTime() const; |