diff options
Diffstat (limited to 'src/qml/jsapi')
-rw-r--r-- | src/qml/jsapi/qjsengine.cpp | 139 | ||||
-rw-r--r-- | src/qml/jsapi/qjsengine.h | 16 | ||||
-rw-r--r-- | src/qml/jsapi/qjsvalue.cpp | 33 | ||||
-rw-r--r-- | src/qml/jsapi/qjsvalue_p.h | 2 | ||||
-rw-r--r-- | src/qml/jsapi/qjsvalueiterator.cpp | 39 | ||||
-rw-r--r-- | src/qml/jsapi/qjsvalueiterator_p.h | 21 |
6 files changed, 181 insertions, 69 deletions
diff --git a/src/qml/jsapi/qjsengine.cpp b/src/qml/jsapi/qjsengine.cpp index ee27c21aed..5ccbccebad 100644 --- a/src/qml/jsapi/qjsengine.cpp +++ b/src/qml/jsapi/qjsengine.cpp @@ -77,7 +77,6 @@ Q_DECLARE_METATYPE(QList<int>) \ingroup qtjavascript \inmodule QtQml - \mainclass \section1 Evaluating Scripts @@ -161,8 +160,82 @@ Q_DECLARE_METATYPE(QList<int>) \snippet code/src_script_qjsengine.cpp 5 - \sa QJSValue, {Making Applications Scriptable} + \section1 Extensions + QJSEngine provides a compliant ECMAScript implementation. By default, + familiar utilities like logging are not available, but they can can be + installed via the \l installExtensions() function. + + \sa QJSValue, {Making Applications Scriptable}, + {List of JavaScript Objects and Functions} + +*/ + +/*! + \enum QJSEngine::Extension + + This enum is used to specify extensions to be installed via + \l installExtensions(). + + \value TranslationExtension Indicates that translation functions (\c qsTr(), + for example) should be installed. + + \value ConsoleExtension Indicates that console functions (\c console.log(), + for example) should be installed. + + \value GarbageCollectionExtension Indicates that garbage collection + functions (\c gc(), for example) should be installed. + + \value AllExtensions Indicates that all extension should be installed. + + \b TranslationExtension + + The relation between script translation functions and C++ translation + functions is described in the following table: + + \table + \header \li Script Function \li Corresponding C++ Function + \row \li qsTr() \li QObject::tr() + \row \li QT_TR_NOOP() \li QT_TR_NOOP() + \row \li qsTranslate() \li QCoreApplication::translate() + \row \li QT_TRANSLATE_NOOP() \li QT_TRANSLATE_NOOP() + \row \li qsTrId() \li qtTrId() + \row \li QT_TRID_NOOP() \li QT_TRID_NOOP() + \endtable + + This flag also adds an \c arg() function to the string prototype. + + For more information, see the \l {Internationalization with Qt} + documentation. + + \b ConsoleExtension + + The \l {Console API}{console} object implements a subset of the + \l {https://developer.mozilla.org/en-US/docs/Web/API/Console}{Console API}, + which provides familiar logging functions, such as \c console.log(). + + The list of functions added is as follows: + + \list + \li \c console.assert() + \li \c console.debug() + \li \c console.exception() + \li \c console.info() + \li \c console.log() (equivalent to \c console.debug()) + \li \c console.error() + \li \c console.time() + \li \c console.timeEnd() + \li \c console.trace() + \li \c console.count() + \li \c console.warn() + \li \c {print()} (equivalent to \c console.debug()) + \endlist + + For more information, see the \l {Console API} documentation. + + \b GarbageCollectionExtension + + The \c gc() function is equivalent to calling \l collectGarbage(). */ QT_BEGIN_NAMESPACE @@ -235,8 +308,11 @@ void QJSEngine::collectGarbage() d->m_v4Engine->memoryManager->runGC(); } +#if QT_DEPRECATED_SINCE(5, 6) + /*! \since 5.4 + \obsolete Installs translator functions on the given \a object, or on the Global Object if no object is specified. @@ -260,30 +336,46 @@ void QJSEngine::collectGarbage() */ void QJSEngine::installTranslatorFunctions(const QJSValue &object) { + installExtensions(TranslationExtension, object); +} + +#endif // QT_DEPRECATED_SINCE(5, 6) + + +/*! + \since 5.6 + + Installs JavaScript \a extensions to add functionality that is not + available in a standard ECMAScript implementation. + + The extensions are installed on the given \a object, or on the + \l {globalObject()}{Global Object} if no object is specified. + + Several extensions can be installed at once by \c {OR}-ing the enum values: + + \code + installExtensions(QJSEngine::TranslationExtension | QJSEngine::ConsoleExtension); + \endcode + + \sa Extension +*/ +void QJSEngine::installExtensions(QJSEngine::Extensions extensions, const QJSValue &object) +{ QV4::ExecutionEngine *otherEngine = QJSValuePrivate::engine(&object); if (otherEngine && otherEngine != d->m_v4Engine) { - qWarning("QJSEngine: Trying to install a translator function from a different engine"); + qWarning("QJSEngine: Trying to install extensions from a different engine"); return; } + QV4::Scope scope(d->m_v4Engine); QV4::ScopedObject obj(scope); QV4::Value *val = QJSValuePrivate::getValue(&object); if (val) obj = val; if (!obj) - obj = scope.engine->globalObject(); -#ifndef QT_NO_TRANSLATION - obj->defineDefaultProperty(QStringLiteral("qsTranslate"), QV4::GlobalExtensions::method_qsTranslate); - obj->defineDefaultProperty(QStringLiteral("QT_TRANSLATE_NOOP"), QV4::GlobalExtensions::method_qsTranslateNoOp); - obj->defineDefaultProperty(QStringLiteral("qsTr"), QV4::GlobalExtensions::method_qsTr); - obj->defineDefaultProperty(QStringLiteral("QT_TR_NOOP"), QV4::GlobalExtensions::method_qsTrNoOp); - obj->defineDefaultProperty(QStringLiteral("qsTrId"), QV4::GlobalExtensions::method_qsTrId); - obj->defineDefaultProperty(QStringLiteral("QT_TRID_NOOP"), QV4::GlobalExtensions::method_qsTrIdNoOp); - - // string prototype extension - scope.engine->stringPrototype.asObject()->defineDefaultProperty(QStringLiteral("arg"), - QV4::GlobalExtensions::method_string_arg); -#endif + obj = scope.engine->globalObject; + + QV4::GlobalExtensions::init(obj, extensions); } /*! @@ -318,8 +410,10 @@ QJSValue QJSEngine::evaluate(const QString& program, const QString& fileName, in { QV4::ExecutionEngine *v4 = d->m_v4Engine; QV4::Scope scope(v4); - QV4::ScopedContext ctx(scope, v4->currentContext()); - if (ctx->d() != v4->rootContext()) + QV4::ExecutionContextSaver saver(scope); + + QV4::ExecutionContext *ctx = v4->currentContext; + if (ctx->d() != v4->rootContext()->d()) ctx = v4->pushGlobalContext(); QV4::ScopedValue result(scope); @@ -331,8 +425,7 @@ QJSValue QJSEngine::evaluate(const QString& program, const QString& fileName, in result = script.run(); if (scope.engine->hasException) result = v4->catchException(); - if (ctx->d() != v4->rootContext()) - v4->popContext(); + return QJSValue(v4, result->asReturnedValue()); } @@ -414,7 +507,7 @@ QJSValue QJSEngine::globalObject() const { Q_D(const QJSEngine); QV4::Scope scope(d->m_v4Engine); - QV4::ScopedValue v(scope, d->m_v4Engine->globalObject()); + QV4::ScopedValue v(scope, d->m_v4Engine->globalObject); return QJSValue(d->m_v4Engine, v->asReturnedValue()); } @@ -554,7 +647,7 @@ bool QJSEngine::convertV2(const QJSValue &value, int type, void *ptr) Creates a QJSValue with the given \a value. - \sa fromScriptValue(), newVariant() + \sa fromScriptValue() */ /*! \fn T QJSEngine::fromScriptValue(const QJSValue &value) @@ -581,7 +674,7 @@ QJSEnginePrivate::~QJSEnginePrivate() QQmlPropertyCache *QJSEnginePrivate::createCache(const QMetaObject *mo) { if (!mo->superClass()) { - QQmlPropertyCache *rv = new QQmlPropertyCache(q_func(), mo); + QQmlPropertyCache *rv = new QQmlPropertyCache(QV8Engine::getV4(q_func()), mo); propertyCache.insert(mo, rv); return rv; } else { diff --git a/src/qml/jsapi/qjsengine.h b/src/qml/jsapi/qjsengine.h index 123eb727df..40b0a60369 100644 --- a/src/qml/jsapi/qjsengine.h +++ b/src/qml/jsapi/qjsengine.h @@ -81,7 +81,19 @@ public: void collectGarbage(); - void installTranslatorFunctions(const QJSValue &object = QJSValue()); +#if QT_DEPRECATED_SINCE(5, 6) + QT_DEPRECATED void installTranslatorFunctions(const QJSValue &object = QJSValue()); +#endif + + enum Extension { + TranslationExtension = 0x1, + ConsoleExtension = 0x2, + GarbageCollectionExtension = 0x4, + AllExtensions = 0xffffffff + }; + Q_DECLARE_FLAGS(Extensions, Extension) + + void installExtensions(Extensions extensions, const QJSValue &object = QJSValue()); QV8Engine *handle() const { return d; } @@ -102,6 +114,8 @@ private: friend class QV8Engine; }; +Q_DECLARE_OPERATORS_FOR_FLAGS(QJSEngine::Extensions) + inline bool qjsvalue_cast_helper(const QJSValue &value, int type, void *ptr) { return QJSEngine::convertV2(value, type, ptr); diff --git a/src/qml/jsapi/qjsvalue.cpp b/src/qml/jsapi/qjsvalue.cpp index 1d9dc2b6db..a49b98c921 100644 --- a/src/qml/jsapi/qjsvalue.cpp +++ b/src/qml/jsapi/qjsvalue.cpp @@ -37,13 +37,14 @@ #include "qjsengine.h" #include "qjsvalue.h" #include "qjsvalue_p.h" -#include "qv4value_inl_p.h" +#include "qv4value_p.h" #include "qv4object_p.h" #include "qv4functionobject_p.h" #include "qv4dateobject_p.h" #include "qv4runtime_p.h" #include "qv4variantobject_p.h" #include "qv4regexpobject_p.h" +#include "qv4errorobject_p.h" #include "private/qv8engine_p.h" #include <private/qv4mm_p.h> #include <private/qv4scopedvalue_p.h> @@ -57,7 +58,6 @@ \ingroup qtjavascript \inmodule QtQml - \mainclass QJSValue supports the types defined in the \l{ECMA-262} standard: The primitive types, which are Undefined, Null, Boolean, @@ -329,8 +329,7 @@ bool QJSValue::isError() const QV4::Value *val = QJSValuePrivate::getValue(this); if (!val) return false; - Object *o = val->asObject(); - return o && o->asErrorObject(); + return val->as<ErrorObject>(); } /*! @@ -344,7 +343,7 @@ bool QJSValue::isArray() const QV4::Value *val = QJSValuePrivate::getValue(this); if (!val) return false; - return val->asArrayObject(); + return val->as<ArrayObject>(); } /*! @@ -361,7 +360,7 @@ bool QJSValue::isObject() const QV4::Value *val = QJSValuePrivate::getValue(this); if (!val) return false; - return val->asObject(); + return val->as<Object>(); } /*! @@ -375,7 +374,7 @@ bool QJSValue::isCallable() const QV4::Value *val = QJSValuePrivate::getValue(this); if (!val) return false; - return val->asFunctionObject(); + return val->as<FunctionObject>(); } /*! @@ -601,7 +600,7 @@ QVariant QJSValue::toVariant() const QV4::Value *val = QJSValuePrivate::valueForData(this, &scratch); Q_ASSERT(val); - if (Object *o = val->asObject()) + if (Object *o = val->as<Object>()) return o->engine()->toVariant(*val, /*typeHint*/ -1, /*createJSValueForObjects*/ false); if (val->isString()) @@ -640,7 +639,7 @@ QJSValue QJSValue::call(const QJSValueList &args) if (!val) return QJSValue(); - FunctionObject *f = val->asFunctionObject(); + FunctionObject *f = val->as<FunctionObject>(); if (!f) return QJSValue(); @@ -649,7 +648,7 @@ QJSValue QJSValue::call(const QJSValueList &args) Scope scope(engine); ScopedCallData callData(scope, args.length()); - callData->thisObject = engine->globalObject()->asReturnedValue(); + callData->thisObject = engine->globalObject; for (int i = 0; i < args.size(); ++i) { if (!QJSValuePrivate::checkEngine(engine, args.at(i))) { qWarning("QJSValue::call() failed: cannot call function with argument created in a different engine"); @@ -691,7 +690,7 @@ QJSValue QJSValue::callWithInstance(const QJSValue &instance, const QJSValueList if (!val) return QJSValue(); - FunctionObject *f = val->asFunctionObject(); + FunctionObject *f = val->as<FunctionObject>(); if (!f) return QJSValue(); @@ -745,7 +744,7 @@ QJSValue QJSValue::callAsConstructor(const QJSValueList &args) if (!val) return QJSValue(); - FunctionObject *f = val->asFunctionObject(); + FunctionObject *f = val->as<FunctionObject>(); if (!f) return QJSValue(); @@ -801,7 +800,7 @@ QJSValue QJSValue::prototype() const if (!engine) return QJSValue(); QV4::Scope scope(engine); - ScopedObject o(scope, QJSValuePrivate::getValue(this)->asObject()); + ScopedObject o(scope, QJSValuePrivate::getValue(this)->as<Object>()); if (!o) return QJSValue(); ScopedObject p(scope, o->prototype()); @@ -1041,7 +1040,7 @@ QJSValue QJSValue::property(quint32 arrayIndex) const if (!o) return QJSValue(); - QV4::ScopedValue result(scope, arrayIndex == UINT_MAX ? o->get(engine->id_uintMax) : o->getIndexed(arrayIndex)); + QV4::ScopedValue result(scope, arrayIndex == UINT_MAX ? o->get(engine->id_uintMax()) : o->getIndexed(arrayIndex)); if (engine->hasException) engine->catchException(); return QJSValue(engine, result->asReturnedValue()); @@ -1120,7 +1119,7 @@ void QJSValue::setProperty(quint32 arrayIndex, const QJSValue& value) if (arrayIndex != UINT_MAX) o->putIndexed(arrayIndex, v); else - o->put(engine->id_uintMax, v); + o->put(engine->id_uintMax(), v); if (engine->hasException) engine->catchException(); } @@ -1236,7 +1235,7 @@ QDateTime QJSValue::toDateTime() const { QV4::Value *val = QJSValuePrivate::getValue(this); if (val) { - QV4::DateObject *date = val->asDateObject(); + QV4::DateObject *date = val->as<DateObject>(); if (date) return date->toQDateTime(); } @@ -1250,7 +1249,7 @@ QDateTime QJSValue::toDateTime() const bool QJSValue::isDate() const { QV4::Value *val = QJSValuePrivate::getValue(this); - return val && val->asDateObject(); + return val && val->as<DateObject>(); } /*! diff --git a/src/qml/jsapi/qjsvalue_p.h b/src/qml/jsapi/qjsvalue_p.h index 93a28a4a5f..08dc184412 100644 --- a/src/qml/jsapi/qjsvalue_p.h +++ b/src/qml/jsapi/qjsvalue_p.h @@ -47,7 +47,7 @@ #include <qjsvalue.h> #include <private/qtqmlglobal_p.h> -#include <private/qv4value_inl_p.h> +#include <private/qv4value_p.h> #include <private/qv4string_p.h> #include <private/qv4engine_p.h> #include <private/qv4object_p.h> diff --git a/src/qml/jsapi/qjsvalueiterator.cpp b/src/qml/jsapi/qjsvalueiterator.cpp index 1ee4121f5c..a24953ae3f 100644 --- a/src/qml/jsapi/qjsvalueiterator.cpp +++ b/src/qml/jsapi/qjsvalueiterator.cpp @@ -52,9 +52,6 @@ QJSValueIteratorPrivate::QJSValueIteratorPrivate(const QJSValue &v) QV4::Scope scope(e); QV4::ScopedObject o(scope, QJSValuePrivate::getValue(&v)); iterator.set(e, e->newForEachIteratorObject(o)); - - currentName = (QV4::String *)0; - nextName = (QV4::String *)0; } @@ -102,8 +99,10 @@ QJSValueIterator::QJSValueIterator(const QJSValue& object) QV4::Scoped<QV4::ForEachIteratorObject> it(scope, d_ptr->iterator.value()); it->d()->it.flags = QV4::ObjectIterator::NoFlags; QV4::ScopedString nm(scope); - it->d()->it.next(nm.getRef(), &d_ptr->nextIndex, &d_ptr->nextProperty, &d_ptr->nextAttributes); - d_ptr->nextName = nm; + QV4::Property nextProperty; + QV4::PropertyAttributes nextAttributes; + it->d()->it.next(nm.getRef(), &d_ptr->nextIndex, &nextProperty, &nextAttributes); + d_ptr->nextName.set(v4, nm.asReturnedValue()); } /*! @@ -125,7 +124,7 @@ bool QJSValueIterator::hasNext() const QV4::Value *val = QJSValuePrivate::getValue(&d_ptr->value); if (!val || !val->isObject()) return false; - return !!d_ptr->nextName || d_ptr->nextIndex != UINT_MAX; + return d_ptr->nextName.as<QV4::String>() || d_ptr->nextIndex != UINT_MAX; } /*! @@ -143,8 +142,6 @@ bool QJSValueIterator::next() return false; d_ptr->currentName = d_ptr->nextName; d_ptr->currentIndex = d_ptr->nextIndex; - d_ptr->currentProperty.copy(&d_ptr->nextProperty, d_ptr->nextAttributes); - d_ptr->currentAttributes = d_ptr->nextAttributes; QV4::ExecutionEngine *v4 = d_ptr->iterator.engine(); if (!v4) @@ -152,9 +149,11 @@ bool QJSValueIterator::next() QV4::Scope scope(v4); QV4::Scoped<QV4::ForEachIteratorObject> it(scope, d_ptr->iterator.value()); QV4::ScopedString nm(scope); - it->d()->it.next(nm.getRef(), &d_ptr->nextIndex, &d_ptr->nextProperty, &d_ptr->nextAttributes); - d_ptr->nextName = nm; - return !!d_ptr->currentName || d_ptr->currentIndex != UINT_MAX; + QV4::Property nextProperty; + QV4::PropertyAttributes nextAttributes; + it->d()->it.next(nm.getRef(), &d_ptr->nextIndex, &nextProperty, &nextAttributes); + d_ptr->nextName.set(v4, nm.asReturnedValue()); + return d_ptr->currentName.as<QV4::String>() || d_ptr->currentIndex != UINT_MAX; } /*! @@ -168,8 +167,8 @@ QString QJSValueIterator::name() const QV4::Value *val = QJSValuePrivate::getValue(&d_ptr->value); if (!val || !val->isObject()) return QString(); - if (!!d_ptr->currentName) - return d_ptr->currentName->toQString(); + if (QV4::String *s = d_ptr->currentName.as<QV4::String>()) + return s->toQString(); if (d_ptr->currentIndex < UINT_MAX) return QString::number(d_ptr->currentIndex); return QString(); @@ -192,10 +191,10 @@ QJSValue QJSValueIterator::value() const if (!obj) return QJSValue(); - if (!d_ptr->currentName && d_ptr->currentIndex == UINT_MAX) + if (!d_ptr->currentName.as<QV4::String>() && d_ptr->currentIndex == UINT_MAX) return QJSValue(); - QV4::ScopedValue v(scope, obj->getValue(*obj, &d_ptr->currentProperty, d_ptr->currentAttributes)); + QV4::ScopedValue v(scope, d_ptr->currentIndex == UINT_MAX ? obj->get(d_ptr->currentName.as<QV4::String>()) : obj->getIndexed(d_ptr->currentIndex)); if (scope.hasException()) { engine->catchException(); return QJSValue(); @@ -214,8 +213,8 @@ QJSValueIterator& QJSValueIterator::operator=(QJSValue& object) d_ptr->value = object; d_ptr->currentIndex = UINT_MAX; d_ptr->nextIndex = UINT_MAX; - d_ptr->currentName = (QV4::String *)0; - d_ptr->nextName = (QV4::String *)0; + d_ptr->currentName.clear(); + d_ptr->nextName.clear(); QV4::ExecutionEngine *v4 = d_ptr->iterator.engine(); if (!v4) { d_ptr->iterator.clear(); @@ -228,8 +227,10 @@ QJSValueIterator& QJSValueIterator::operator=(QJSValue& object) QV4::Scoped<QV4::ForEachIteratorObject> it(scope, d_ptr->iterator.value()); it->d()->it.flags = QV4::ObjectIterator::NoFlags; QV4::ScopedString nm(scope); - it->d()->it.next(nm.getRef(), &d_ptr->nextIndex, &d_ptr->nextProperty, &d_ptr->nextAttributes); - d_ptr->nextName = nm; + QV4::Property nextProperty; + QV4::PropertyAttributes nextAttributes; + it->d()->it.next(nm.getRef(), &d_ptr->nextIndex, &nextProperty, &nextAttributes); + d_ptr->nextName.set(v4, nm.asReturnedValue()); return *this; } diff --git a/src/qml/jsapi/qjsvalueiterator_p.h b/src/qml/jsapi/qjsvalueiterator_p.h index c17fedf73e..dfc5e18cd6 100644 --- a/src/qml/jsapi/qjsvalueiterator_p.h +++ b/src/qml/jsapi/qjsvalueiterator_p.h @@ -34,6 +34,17 @@ #ifndef QJSVALUEITERATOR_P_H #define QJSVALUEITERATOR_P_H +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + #include "qjsvalue.h" #include "private/qv4objectiterator_p.h" @@ -48,15 +59,9 @@ public: QJSValue value; QV4::PersistentValue iterator; - // ### GC - QV4::Property currentProperty; - QV4::PropertyAttributes currentAttributes; - QV4::StringValue currentName; + QV4::PersistentValue currentName; uint currentIndex; - // ### GC - QV4::Property nextProperty; - QV4::PropertyAttributes nextAttributes; - QV4::StringValue nextName; + QV4::PersistentValue nextName; uint nextIndex; }; |