/**************************************************************************** ** ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** ** This file is part of the documentation of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions ** contained in the either Technology Preview License Agreement or the ** Beta Release License Agreement. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain ** additional rights. These rights are described in the Nokia Qt LGPL ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this ** package. ** ** GNU General Public License Usage ** Alternatively, this file may be used under the terms of the GNU ** General Public License version 3.0 as published by the Free Software ** Foundation and appearing in the file LICENSE.GPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU General Public License version 3.0 requirements will be ** met: http://www.gnu.org/copyleft/gpl.html. ** ** If you are unsure which license is appropriate for your use, please ** contact the sales department at qt-sales@nokia.com. ** $QT_END_LICENSE$ ** ****************************************************************************/ /*! \page qmlecmascript.html \title ECMAScript Blocks QML encourages building UIs declaratively, using \l {Property Binding} and the composition of existing \l {QML Elements}. If imperative code is required to implement more advanced behavior, the \l Script element can be used to add ECMAScript code directly to a QML file, or to include an external ECMAScript file. The \l Script element is a QML language \e intrinsic. It can be used anywhere in a QML file, \e except as the root element of a file or sub-component, but cannot be assigned to an object property or given an id. The included ECMAScript is evaluated in a scope chain. The \l {QML Scope} documentation covers the specifics of scoping in QML. \section1 Inline Script Small blocks of ECMAScript can be included directly inside a \l {QML Document} as the body of the \l Script element. \code Rectangle { Script { function factorial(var a) { a = Integer(a); if (a <= 0) return 1; else return a * factorial(a - 1); } } } \endcode Good programming practice dictates that only small script snippets should be written inline. QML prohibits the declaration of anything other than functions in an inline script block. For example, the following script is illegal as an inline script block as it declares the non-function variable \c lastResult. \code // Illegal inline code block var lastResult = 0 function factorial(var a) { a = Integer(a); if (a <= 0) lastResult = 1; else lastResult = a * factorial(a - 1); return lastResult; } \endcode \section1 Including an External File To avoid cluttering the QML file, large script blocks should be in a separate file. The \l Script element's \c source property is used to load script from an external file. If the previous factorial code that was illegal as an inline script block was saved into a "factorial.js" file, it could be included like this. \code Rectangle { Script { source: "factorial.js" } } \endcode The \c source property may reference a relative file, or an absolute path. In the case of a relative file, the location is resolved relative to the location of the \l {QML Document} that contains the \l Script element. If the script file is not accessible, an error will occur. If the source is on a network resource, the enclosing QML document will remain in the \l {QmlComponent::status()}{waiting state} until the script has been retrieved. \section1 Running Script at Startup It is occasionally necessary to run a block of ECMAScript code at application (or component instance) "startup". While it is tempting to just include the startup script as \e {global code} in an external script file, this can have sever limitations as the QML environment may not have been fully established. For example, some objects might not have been created or some \l {Property Binding}s may not have been run. \l {QML Script Restrictions} covers the exact limitations of global script code. The QML \l Component element provides an \e attached \c onCompleted property that can be used to trigger the execution of script code at startup after the QML environment has been completely established. The following QML code shows how to use the \c Component::onCompleted property. \code Rectangle { Script { function startupFunction() { // ... startup code } } Component.onCompleted: startupFunction(); } \endcode Any element in a QML file - including nested elements and nested QML component instances - can use this attached property. If there is more than one script to execute at startup, they are run sequentially in an undefined order. \section1 QML Script Restrictions QML \l Script blocks contain standard ECMAScript code. QML introduces the following restrictions. \list \o Script code cannot modify the global object. In QML, the global object is constant - existing properties cannot be modified or deleted, and no new properties may be created. Most ECMAScript programs do not explicitly modify the global object. However, ECMAScript's automatic creation of undeclared variables is an implicit modification of the global object, and is prohibited in QML. Assuming that the \c a variable does not exist in the scope chain, the following code is illegal in QML. \code // Illegal modification of undeclared variable a = 1; for (var ii = 1; ii < 10; ++ii) a = a * ii; print("Result: " + a); \endcode It can be trivially modified to this legal code. \code var a = 1; for (var ii = 1; ii < 10; ++ii) a = a * ii; print("Result: " + a); \endcode Any attempt to modify the global object - either implicitly or explicitly - will cause an exception. If uncaught, this will result in an warning being printed, that includes the file and line number of the offending code. \o Global code is run in a reduced scope During startup, if a \l Script block includes an external file with "global" code, it is executed in a scope that contains only the external file itself and the global object. That is, it will not have access to the QML objects and properties it \l {QML Scope}{normally would}. Global code that only accesses script local variable is permitted. This is an example of valid global code. \code var colors = [ "red", "blue", "green", "orange", "purple" ]; \endcode Global code that accesses QML objects will not run correctly. \code // Invalid global code - the "rootObject" variable is undefined var initialPosition = { rootObject.x, rootObject.y } \endcode This restriction exists as the QML environment is not yet fully established. To run code after the environment setup has completed, refer to \l {Running Script at Startup}. \endlist */