From c5b56564667194b179ebfcc87608d38e9969fade Mon Sep 17 00:00:00 2001 From: Kent Hansen Date: Thu, 11 Aug 2011 13:58:53 +0200 Subject: [PATCH] Improve the Qt/JavaScript (QJS) documentation Make sure all public classes and functions are documented. Fix/remove broken references. Add code snippets. Add a minimal "Making Applications Scriptable" page based on the QtScript docs. Change-Id: I76a32bff776b478f01ff08b3276a0a020a1fa81f Reviewed-on: http://codereview.qt.nokia.com/2863 Reviewed-by: Qt Sanity Bot Reviewed-by: Simon Hausmann --- doc/src/declarative/qtjavascript.qdoc | 92 ++++++++++ doc/src/snippets/code/src_script_qjsengine.cpp | 90 ++++++++++ doc/src/snippets/code/src_script_qjsvalue.cpp | 65 +++++++ .../snippets/code/src_script_qjsvalueiterator.cpp | 72 ++++++++ doc/src/snippets/qtjavascript/evaluation/main.cpp | 51 ++++++ .../qtjavascript/registeringobjects/main.cpp | 57 +++++++ .../qtjavascript/registeringvalues/main.cpp | 53 ++++++ src/declarative/qml/v8/qjsengine.cpp | 178 ++++++++++++++++++- src/declarative/qml/v8/qjsvalue.cpp | 115 +++++++++---- src/declarative/qml/v8/qjsvalueiterator.cpp | 31 ++-- 10 files changed, 744 insertions(+), 60 deletions(-) create mode 100644 doc/src/declarative/qtjavascript.qdoc create mode 100644 doc/src/snippets/code/src_script_qjsengine.cpp create mode 100644 doc/src/snippets/code/src_script_qjsvalue.cpp create mode 100644 doc/src/snippets/code/src_script_qjsvalueiterator.cpp create mode 100644 doc/src/snippets/qtjavascript/evaluation/main.cpp create mode 100644 doc/src/snippets/qtjavascript/registeringobjects/main.cpp create mode 100644 doc/src/snippets/qtjavascript/registeringvalues/main.cpp diff --git a/doc/src/declarative/qtjavascript.qdoc b/doc/src/declarative/qtjavascript.qdoc new file mode 100644 index 0000000..6d5e237 --- /dev/null +++ b/doc/src/declarative/qtjavascript.qdoc @@ -0,0 +1,92 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** GNU Free Documentation License +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms +** and conditions contained in a signed written agreement between you +** and Nokia. +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \group qtjavascript + \title Scripting Classes and Overviews + + \brief Classes for embedding JavaScript in Qt/C++ applications. +*/ + +/*! + \page qtjavascript.html + \title Making Applications Scriptable + \ingroup frameworks-technologies + + Qt provides support for application scripting with JavaScript. + The following guides and references cover aspects of programming with + JavaScript and Qt. + + \tableofcontents + + \section1 Scripting Classes + + The following classes add scripting capabilities to Qt applications. + + \annotatedlist qtjavascript + + \section1 Basic Usage + + To evaluate script code, you create a QJSEngine and call its + evaluate() function, passing the script code (text) to evaluate + as argument. + + \snippet doc/src/snippets/qtjavascript/evaluation/main.cpp 0 + + The return value will be the result of the evaluation (represented + as a QJSValue object); this can be converted to standard C++ + and Qt types. + + Custom properties can be made available to scripts by registering + them with the script engine. This is most easily done by setting + properties of the script engine's \e{Global Object}: + + \snippet doc/src/snippets/qtjavascript/registeringvalues/main.cpp 0 + + This places the properties in the script environment, thus making them + available to script code. + + \section1 Making a QObject Available to the Script Engine + + Any QObject-based instance can be made available for use with scripts. + + When a QObject is passed to the QJSEngine::newQObject() function, + a Qt Script wrapper object is created that can be used to make the + QObject's signals, slots, properties, and child objects available + to scripts. + + Here's an example of making an instance of a QObject subclass + available to script code under the name \c{"myObject"}: + + \snippet doc/src/snippets/qtjavascript/registeringobjects/main.cpp 0 + + This will create a global variable called \c{myObject} in the + script environment. The variable serves as a proxy to the + underlying C++ object. Note that the name of the script variable + can be anything; i.e., it is not dependent upon QObject::objectName(). + + */ diff --git a/doc/src/snippets/code/src_script_qjsengine.cpp b/doc/src/snippets/code/src_script_qjsengine.cpp new file mode 100644 index 0000000..56c3d6b --- /dev/null +++ b/doc/src/snippets/code/src_script_qjsengine.cpp @@ -0,0 +1,90 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +QJSEngine myEngine; +QJSValue three = myEngine.evaluate("1 + 2"); +//! [0] + + +//! [1] +QJSValue fun = myEngine.evaluate("(function(a, b) { return a + b; })"); +QJSValueList args; +args << 1 << 2; +QJSValue threeAgain = fun.call(QJSValue(), args); +//! [1] + + +//! [2] +QString fileName = "helloworld.qs"; +QFile scriptFile(fileName); +if (!scriptFile.open(QIODevice::ReadOnly)) + // handle error +QTextStream stream(&scriptFile); +QString contents = stream.readAll(); +scriptFile.close(); +myEngine.evaluate(contents, fileName); +//! [2] + + +//! [3] +myEngine.globalObject().setProperty("myNumber", 123); +... +QJSValue myNumberPlusOne = myEngine.evaluate("myNumber + 1"); +//! [3] + + +//! [4] +QJSValue result = myEngine.evaluate(...); +if (myEngine.hasUncaughtException()) + qDebug() << "uncaught exception:" << result.toString(); +//! [4] + + +//! [5] +QPushButton button; +QJSValue scriptButton = myEngine.newQObject(&button); +myEngine.globalObject().setProperty("button", scriptButton); + +myEngine.evaluate("button.checkable = true"); + +qDebug() << scriptButton.property("checkable").toBoolean(); +scriptButton.property("show").call(); // call the show() slot +//! [5] diff --git a/doc/src/snippets/code/src_script_qjsvalue.cpp b/doc/src/snippets/code/src_script_qjsvalue.cpp new file mode 100644 index 0000000..c64c4c0 --- /dev/null +++ b/doc/src/snippets/code/src_script_qjsvalue.cpp @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +QJSEngine myEngine; +QJSValue myObject = myEngine.newObject(); +QJSValue myOtherObject = myEngine.newObject(); +myObject.setProperty("myChild", myOtherObject); +myObject.setProperty("name", "John Doe"); +//! [0] + + +//! [1] +QJSEngine engine; +engine.evaluate("function fullName() { return this.firstName + ' ' + this.lastName; }"); +engine.evaluate("somePerson = { firstName: 'John', lastName: 'Doe' }"); + +QJSValue global = engine.globalObject(); +QJSValue fullName = global.property("fullName"); +QJSValue who = global.property("somePerson"); +qDebug() << fullName.call(who).toString(); // "John Doe" + +engine.evaluate("function cube(x) { return x * x * x; }"); +QJSValue cube = global.property("cube"); +QJSValueList args; +args << 3; +qDebug() << cube.call(QJSValue(), args).toNumber(); // 27 +//! [1] diff --git a/doc/src/snippets/code/src_script_qjsvalueiterator.cpp b/doc/src/snippets/code/src_script_qjsvalueiterator.cpp new file mode 100644 index 0000000..f72e918 --- /dev/null +++ b/doc/src/snippets/code/src_script_qjsvalueiterator.cpp @@ -0,0 +1,72 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +QScriptValue object; +... +QScriptValueIterator it(object); +while (it.hasNext()) { + it.next(); + qDebug() << it.name() << ": " << it.value().toString(); +} +//! [0] + + +//! [1] +QScriptValue obj = ...; // the object to iterate over +while (obj.isObject()) { + QScriptValueIterator it(obj); + while (it.hasNext()) { + it.next(); + qDebug() << it.name(); + } + obj = obj.prototype(); +} +//! [1] + + +//! [2] +while (it.hasNext()) { + it.next(); + if (it.flags() & QScriptValue::SkipInEnumeration) + continue; + qDebug() << "found enumerated property:" << it.name(); +} +//! [2] diff --git a/doc/src/snippets/qtjavascript/evaluation/main.cpp b/doc/src/snippets/qtjavascript/evaluation/main.cpp new file mode 100644 index 0000000..7782566 --- /dev/null +++ b/doc/src/snippets/qtjavascript/evaluation/main.cpp @@ -0,0 +1,51 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include + +int main(int argc, char *argv[]) +{ + QCoreApplication app(argc, argv); + //! [0] + QJSEngine engine; + qDebug() << "the magic number is:" << engine.evaluate("1 + 2").toNumber(); + //! [0] + return 0; +} diff --git a/doc/src/snippets/qtjavascript/registeringobjects/main.cpp b/doc/src/snippets/qtjavascript/registeringobjects/main.cpp new file mode 100644 index 0000000..25c0f14 --- /dev/null +++ b/doc/src/snippets/qtjavascript/registeringobjects/main.cpp @@ -0,0 +1,57 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include +#include "myobject.h" + +int main(int argc, char *argv[]) +{ + QCoreApplication app(argc, argv); + //! [0] + QJSEngine engine; + QObject *someObject = new MyObject; + QJSValue objectValue = engine.newQObject(someObject); + engine.globalObject().setProperty("myObject", objectValue); + //! [0] + qDebug() << "myObject's calculate() function returns" + << engine.evaluate("myObject.calculate(10)").toNumber(); + return 0; +} diff --git a/doc/src/snippets/qtjavascript/registeringvalues/main.cpp b/doc/src/snippets/qtjavascript/registeringvalues/main.cpp new file mode 100644 index 0000000..fe32f70 --- /dev/null +++ b/doc/src/snippets/qtjavascript/registeringvalues/main.cpp @@ -0,0 +1,53 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include + +int main(int argc, char *argv[]) +{ + QCoreApplication app(argc, argv); + QJSEngine engine; + //! [0] + engine.globalObject().setProperty("foo", 123); + qDebug() << "foo times two is:" << engine.evaluate("foo * 2").toNumber(); + //! [0] + return 0; +} + diff --git a/src/declarative/qml/v8/qjsengine.cpp b/src/declarative/qml/v8/qjsengine.cpp index e80fcb4..3db7fc4 100644 --- a/src/declarative/qml/v8/qjsengine.cpp +++ b/src/declarative/qml/v8/qjsengine.cpp @@ -52,6 +52,97 @@ Q_DECLARE_METATYPE(QJSValue) Q_DECLARE_METATYPE(QObjectList) Q_DECLARE_METATYPE(QList) +/*! + \since 5.0 + \class QJSEngine + + \brief The QJSEngine class provides an environment for evaluating JavaScript code. + + \ingroup qtjavascript + \mainclass + + \section1 Evaluating Scripts + + Use evaluate() to evaluate script code. + + \snippet doc/src/snippets/code/src_script_qjsengine.cpp 0 + + evaluate() returns a QJSValue that holds the result of the + evaluation. The QJSValue class provides functions for converting + the result to various C++ types (e.g. QJSValue::toString() + and QJSValue::toNumber()). + + The following code snippet shows how a script function can be + defined and then invoked from C++ using QJSValue::call(): + + \snippet doc/src/snippets/code/src_script_qjsengine.cpp 1 + + As can be seen from the above snippets, a script is provided to the + engine in the form of a string. One common way of loading scripts is + by reading the contents of a file and passing it to evaluate(): + + \snippet doc/src/snippets/code/src_script_qjsengine.cpp 2 + + Here we pass the name of the file as the second argument to + evaluate(). This does not affect evaluation in any way; the second + argument is a general-purpose string that is used to identify the + script for debugging purposes (for example, our filename will now + show up in any uncaughtExceptionBacktrace() involving the script). + + \section1 Engine Configuration + + The globalObject() function returns the \bold {Global Object} + associated with the script engine. Properties of the Global Object + are accessible from any script code (i.e. they are global + variables). Typically, before evaluating "user" scripts, you will + want to configure a script engine by adding one or more properties + to the Global Object: + + \snippet doc/src/snippets/code/src_script_qjsengine.cpp 3 + + Adding custom properties to the scripting environment is one of the + standard means of providing a scripting API that is specific to your + application. Usually these custom properties are objects created by + the newQObject() or newObject() functions. + + \section1 Script Exceptions + + evaluate() can throw a script exception (e.g. due to a syntax + error); in that case, the return value is the value that was thrown + (typically an \c{Error} object). You can check whether the + evaluation caused an exception by calling hasUncaughtException(). In + that case, you can call toString() on the error object to obtain an + error message. The current uncaught exception is also available + through uncaughtException(). + Calling clearExceptions() will cause any uncaught exceptions to be + cleared. + + \snippet doc/src/snippets/code/src_script_qjsengine.cpp 4 + + \section1 Script Object Creation + + Use newObject() to create a JavaScript object; this is the + C++ equivalent of the script statement \c{new Object()}. You can use + the object-specific functionality in QJSValue to manipulate the + script object (e.g. QJSValue::setProperty()). Similarly, use + newArray() to create a JavaScript array object. Use newDate() to + create a \c{Date} object, and newRegExp() to create a \c{RegExp} + object. + + \section1 QObject Integration + + Use newQObject() to wrap a QObject (or subclass) + pointer. newQObject() returns a proxy script object; properties, + children, and signals and slots of the QObject are available as + properties of the proxy object. No binding code is needed because it + is done dynamically using the Qt meta object system. + + \snippet doc/src/snippets/code/src_script_qjsengine.cpp 5 + + \sa QJSValue, {Making Applications Scriptable} + +*/ + QT_BEGIN_NAMESPACE @@ -102,6 +193,11 @@ QJSEngine::~QJSEngine() } /*! + \fn QV8Engine *QJSEngine::handle() const + \internal +*/ + +/*! Returns true if the last script evaluation resulted in an uncaught exception; otherwise returns false. @@ -201,6 +297,11 @@ QJSValue QJSEngine::evaluate(const QString& program, const QString& fileName, in return QJSValuePrivate::get(d->evaluate(program, fileName, lineNumber)); } +/*! + Returns a QJSValue of the primitive type Null. + + \sa nullValue() +*/ QJSValue QJSEngine::nullValue() { Q_D(QJSEngine); @@ -209,6 +310,11 @@ QJSValue QJSEngine::nullValue() return QJSValuePrivate::get(new QJSValuePrivate(d, v8::Null())); } +/*! + Returns a QJSValue of the primitive type Undefined. + + \sa nullValue() +*/ QJSValue QJSEngine::undefinedValue() { Q_D(QJSEngine); @@ -217,6 +323,14 @@ QJSValue QJSEngine::undefinedValue() return QJSValuePrivate::get(new QJSValuePrivate(d, v8::Undefined())); } +/*! + Creates a JavaScript object of class Object. + + The prototype of the created object will be the Object + prototype object. + + \sa newArray(), QJSValue::setProperty() +*/ QJSValue QJSEngine::newObject() { Q_D(QJSEngine); @@ -225,6 +339,11 @@ QJSValue QJSEngine::newObject() return QJSValuePrivate::get(new QJSValuePrivate(d, v8::Object::New())); } +/*! + Creates a JavaScript object of class Array with the given \a length. + + \sa newObject() +*/ QJSValue QJSEngine::newArray(uint length) { Q_D(QJSEngine); @@ -234,13 +353,12 @@ QJSValue QJSEngine::newArray(uint length) } /*! - Creates a QtScript object that wraps the given QObject \a + Creates a JavaScript object that wraps the given QObject \a object, using the given \a ownership. The given \a options control various aspects of the interaction with the resulting script object. Signals and slots, properties and children of \a object are - available as properties of the created QJSValue. For more - information, see the \l{QtScript} documentation. + available as properties of the created QJSValue. If \a object is a null pointer, this function returns nullValue(). @@ -248,8 +366,8 @@ QJSValue QJSEngine::newArray(uint length) (or its superclass, recursively), the prototype of the new script object will be set to be that default prototype. - If the given \a object is deleted outside of QtScript's control, any - attempt to access the deleted QObject's members through the QtScript + If the given \a object is deleted outside of the engine's control, any + attempt to access the deleted QObject's members through the JavaScript wrapper object (either by script code or C++) will result in a script exception. @@ -264,7 +382,7 @@ QJSValue QJSEngine::newQObject(QObject *object) } /*! - Creates a QtScript object holding the given variant \a value. + Creates a JavaScript object holding the given variant \a value. If a default prototype has been registered with the meta type id of \a value, then the prototype of the created object will be that @@ -282,6 +400,16 @@ QJSValue QJSEngine::newVariant(const QVariant &value) } +/*! + Returns this engine's Global Object. + + By default, the Global Object contains the built-in objects that are + part of \l{ECMA-262}, such as Math, Date and String. Additionally, + you can set properties of the Global Object to make your own + extensions available to all script code. Non-local variables in + script code will be created as properties of the Global Object, as + well as local variables in global code. +*/ QJSValue QJSEngine::globalObject() const { Q_D(const QJSEngine); @@ -290,6 +418,23 @@ QJSValue QJSEngine::globalObject() const return d->scriptValueFromInternal(d->global()); } +/*! + Converts the given \a value to an object, if such a conversion is + possible; otherwise returns an invalid QJSValue. The conversion + is performed according to the following table: + + \table + \header \o Input Type \o Result + \row \o Undefined \o An invalid QJSValue. + \row \o Null \o An invalid QJSValue. + \row \o Boolean \o A new Boolean object whose internal value is set to the value of the boolean. + \row \o Number \o A new Number object whose internal value is set to the value of the number. + \row \o String \o A new String object whose internal value is set to the value of the string. + \row \o Object \o The result is the object itself (no conversion). + \endtable + + \sa newObject() +*/ QJSValue QJSEngine::toObject(const QJSValue& value) { Q_D(QJSEngine); @@ -299,7 +444,7 @@ QJSValue QJSEngine::toObject(const QJSValue& value) } /*! - Creates a QtScript object of class Date from the given \a value. + Creates a JavaScript object of class Date from the given \a value. \sa QJSValue::toDateTime() */ @@ -312,7 +457,7 @@ QJSValue QJSEngine::newDate(const QDateTime &dt) } /*! - Creates a QtScript object of class Date with the given + Creates a JavaScript object of class Date with the given \a value (the number of milliseconds since 01 January 1970, UTC). */ @@ -325,7 +470,7 @@ QJSValue QJSEngine::newDate(double date) } /*! - Creates a QtScript object of class RegExp with the given + Creates a JavaScript object of class RegExp with the given \a regexp. \sa QJSValue::toRegExp() @@ -339,7 +484,7 @@ QJSValue QJSEngine::newRegExp(const QRegExp ®exp) } /*! - Creates a QtScript object of class RegExp with the given + Creates a JavaScript object of class RegExp with the given \a pattern and \a flags. The legal flags are 'g' (global), 'i' (ignore case), and 'm' @@ -425,6 +570,19 @@ bool QJSEngine::convertV2(const QJSValue &value, int type, void *ptr) } } +/*! \fn QJSValue QJSEngine::toScriptValue(const T &value) + + Creates a QJSValue with the given \a value. + + \sa fromScriptValue() +*/ + +/*! \fn T QJSEngine::fromScriptValue(const QJSValue &value) + + Returns the given \a value converted to the template type \c{T}. + + \sa toScriptValue() +*/ QT_END_NAMESPACE diff --git a/src/declarative/qml/v8/qjsvalue.cpp b/src/declarative/qml/v8/qjsvalue.cpp index eff7b43..bbfae89 100644 --- a/src/declarative/qml/v8/qjsvalue.cpp +++ b/src/declarative/qml/v8/qjsvalue.cpp @@ -31,23 +31,71 @@ #include #include -QT_BEGIN_NAMESPACE - /*! - Constructs an invalid value. + \since 5.0 + \class QJSValue + + \brief The QJSValue class acts as a container for Qt/JavaScript data types. + + \ingroup qtjavascript + \mainclass + + QJSValue supports the types defined in the \l{ECMA-262} + standard: The primitive types, which are Undefined, Null, Boolean, + Number, and String; and the Object type. Additionally, built-in + support is provided for Qt/C++ types such as QVariant and QObject. + + For the object-based types (including Date and RegExp), use the + newT() functions in QJSEngine (e.g. QJSEngine::newObject()) + to create a QJSValue of the desired type. For the primitive types, + use one of the QJSValue constructor overloads. + + The methods named isT() (e.g. isBool(), isUndefined()) can be + used to test if a value is of a certain type. The methods named + toT() (e.g. toBool(), toString()) can be used to convert a + QJSValue to another type. You can also use the generic + QJSValue_cast() function. + + Object values have zero or more properties which are themselves + QJSValues. Use setProperty() to set a property of an object, and + call property() to retrieve the value of a property. + + \snippet doc/src/snippets/code/src_script_qjsvalue.cpp 0 + + The attributes of a property can be queried by calling the + propertyFlags() function. + + If you want to iterate over the properties of a script object, use + the QJSValueIterator class. + + Object values have an internal \c{prototype} property, which can be + accessed with prototype() and setPrototype(). + + Function objects (objects for which isFunction() returns true) can + be invoked by calling call(). Constructor functions can be used to + construct new objects by calling construct(). + + Use equals() or strictlyEquals() to compare a QJSValue to another. + + Note that a QJSValue for which isObject() is true only carries a + reference to an actual object; copying the QJSValue will only + copy the object reference, not the object itself. If you want to + clone an object (i.e. copy an object's properties to another + object), you can do so with the help of a \c{for-in} statement in + script code, or QJSValueIterator in C++. + + \sa QJSEngine, QJSValueIterator */ -QJSValue::QJSValue() - : d_ptr(InvalidValue()) -{ -} /*! - Constructs a new QJSValue with a boolean \a value. + \enum QJSValue::SpecialValue + + This enum is used to specify a single-valued type. + + \value UndefinedValue An undefined value. + + \value NullValue A null value. */ -QJSValue::QJSValue(bool value) - : d_ptr(new QJSValuePrivate(value)) -{ -} /*! \enum QJSValue::PropertyFlag @@ -59,17 +107,25 @@ QJSValue::QJSValue(bool value) \value Undeletable Attempts by Qt Script code to \c{delete} the property will be ignored. \value SkipInEnumeration The property is not to be enumerated by a \c{for-in} enumeration. +*/ - \value PropertyGetter The property is defined by a function which will be called to get the property value. - - \value PropertySetter The property is defined by a function which will be called to set the property value. - - \omitvalue QObjectMember This flag is used to indicate that an existing property is a QObject member (a property or method). +QT_BEGIN_NAMESPACE - \value KeepExistingFlags This value is used to indicate to setProperty() that the property's flags should be left unchanged. If the property doesn't exist, the default flags (0) will be used. +/*! + Constructs an invalid value. +*/ +QJSValue::QJSValue() + : d_ptr(InvalidValue()) +{ +} - \omitvalue UserRange Flags in this range are not used by Qt Script, and can be used for custom purposes. +/*! + Constructs a new QJSValue with a boolean \a value. */ +QJSValue::QJSValue(bool value) + : d_ptr(new QJSValuePrivate(value)) +{ +} /*! Constructs a new QJSValue with a number \a value. @@ -120,8 +176,6 @@ QJSValue::QJSValue(const QLatin1String &value) } /*! - \fn QJSValue::QJSValue(const QLatin1String &value) - Constructs a new QJSValue with a string \a value. */ #ifndef QT_NO_CAST_FROM_ASCII @@ -383,8 +437,6 @@ bool QJSValue::isUndefined() const /*! Returns true if this QJSValue is an object of the Error class; otherwise returns false. - - \sa QScriptContext::throwError() */ bool QJSValue::isError() const { @@ -654,7 +706,7 @@ QVariant QJSValue::toVariant() const QJSEngine::hasUncaughtException() to determine if an exception occurred. - \snippet doc/src/snippets/code/src_script_qscriptvalue.cpp 2 + \snippet doc/src/snippets/code/src_script_qjsvalue.cpp 1 \sa construct() */ @@ -773,7 +825,7 @@ QJSValue& QJSValue::operator=(const QJSValue& other) toString()) in an attempt to convert the object to a primitive value (possibly resulting in an uncaught script exception). - \sa strictlyEquals(), lessThan() + \sa strictlyEquals() */ bool QJSValue::equals(const QJSValue& other) const { @@ -830,9 +882,7 @@ bool QJSValue::instanceOf(const QJSValue &other) const } /*! - Returns the value of this QJSValue's property with the given \a name, - using the given \a mode to resolve the property. - + Returns the value of this QJSValue's property with the given \a name. If no such property exists, an invalid QJSValue is returned. If the property is implemented using a getter function (i.e. has the @@ -854,8 +904,7 @@ QJSValue QJSValue::property(const QString& name) const /*! \overload - Returns the property at the given \a arrayIndex, using the given \a - mode to resolve the property. + Returns the property at the given \a arrayIndex. This function is provided for convenience and performance when working with array objects. @@ -878,8 +927,7 @@ QJSValue QJSValue::property(quint32 arrayIndex) const If this QJSValue is not an object, this function does nothing. If this QJSValue does not already have a property with name \a name, - a new property is created; the given \a flags then specify how this - property may be accessed by script code. + a new property is created. If \a value is invalid, the property is removed. @@ -922,8 +970,7 @@ void QJSValue::setProperty(quint32 arrayIndex, const QJSValue& value) } /*! - Returns the flags of the property with the given \a name, using the - given \a mode to resolve the property. + Returns the flags of the property with the given \a name. \sa property() */ diff --git a/src/declarative/qml/v8/qjsvalueiterator.cpp b/src/declarative/qml/v8/qjsvalueiterator.cpp index 42bfd34..76a43c9 100644 --- a/src/declarative/qml/v8/qjsvalueiterator.cpp +++ b/src/declarative/qml/v8/qjsvalueiterator.cpp @@ -36,7 +36,7 @@ QT_BEGIN_NAMESPACE \brief The QJSValueIterator class provides a Java-style iterator for QJSValue. - \ingroup script + \ingroup qtjavascript The QJSValueIterator constructor takes a QJSValue as @@ -44,28 +44,24 @@ QT_BEGIN_NAMESPACE beginning of the sequence of properties. Here's how to iterate over all the properties of a QJSValue: - \snippet doc/src/snippets/code/src_script_QJSValueIterator.cpp 0 + \snippet doc/src/snippets/code/src_script_qjsvalueiterator.cpp 0 - The next() advances the iterator. The name(), value() and flags() - functions return the name, value and flags of the last item that was + The next() advances the iterator. The name() and value() + functions return the name and value of the last item that was jumped over. - If you want to remove properties as you iterate over the - QJSValue, use remove(). If you want to modify the value of a - property, use setValue(). - Note that QJSValueIterator only iterates over the QJSValue's own properties; i.e. it does not follow the prototype chain. You can use a loop like this to follow the prototype chain: - \snippet doc/src/snippets/code/src_script_QJSValueIterator.cpp 1 + \snippet doc/src/snippets/code/src_script_qjsvalueiterator.cpp 1 Note that QJSValueIterator will not automatically skip over properties that have the QJSValue::SkipInEnumeration flag set; that flag only affects iteration in script code. If you want, you can skip over such properties with code like the following: - \snippet doc/src/snippets/code/src_script_QJSValueIterator.cpp 2 + \snippet doc/src/snippets/code/src_script_qjsvalueiterator.cpp 2 \sa QJSValue::property() */ @@ -90,7 +86,7 @@ QJSValueIterator::~QJSValueIterator() (i.e. the iterator is \e not at the back of the property sequence); otherwise returns false. - \sa next(), hasPrevious() + \sa next() */ bool QJSValueIterator::hasNext() const { @@ -101,11 +97,14 @@ bool QJSValueIterator::hasNext() const /*! Advances the iterator by one position. + Returns true if there is at least one item ahead of the iterator + (i.e. the iterator is \e not at the back of the property sequence); + otherwise returns false. Calling this function on an iterator located at the back of the container leads to undefined results. - \sa hasNext(), previous(), name() + \sa hasNext(), name() */ bool QJSValueIterator::next() { @@ -116,9 +115,9 @@ bool QJSValueIterator::next() /*! Returns the name of the last property that was jumped over using - next() or previous(). + next(). - \sa value(), flags() + \sa value() */ QString QJSValueIterator::name() const { @@ -130,9 +129,9 @@ QString QJSValueIterator::name() const /*! Returns the value of the last property that was jumped over using - next() or previous(). + next(). - \sa setValue(), name() + \sa name() */ QJSValue QJSValueIterator::value() const { -- 1.7.2.5