aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/jsapi
diff options
context:
space:
mode:
Diffstat (limited to 'src/qml/jsapi')
-rw-r--r--src/qml/jsapi/qjsengine.cpp139
-rw-r--r--src/qml/jsapi/qjsengine.h16
-rw-r--r--src/qml/jsapi/qjsvalue.cpp33
-rw-r--r--src/qml/jsapi/qjsvalue_p.h2
-rw-r--r--src/qml/jsapi/qjsvalueiterator.cpp39
-rw-r--r--src/qml/jsapi/qjsvalueiterator_p.h21
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;
};