1/****************************************************************************
2**
3** Copyright (C) 2017 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the documentation of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:FDL$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** GNU Free Documentation License Usage
18** Alternatively, this file may be used under the terms of the GNU Free
19** Documentation License version 1.3 as published by the Free Software
20** Foundation and appearing in the file included in the packaging of
21** this file. Please review the following information to ensure
22** the GNU Free Documentation License version 1.3 requirements
23** will be met: https://www.gnu.org/licenses/fdl-1.3.html.
24** $QT_END_LICENSE$
25**
26****************************************************************************/
27/*!
28\page qtqml-javascript-resources.html
29\title Defining JavaScript Resources in QML
30\brief Description of how JavaScript files may be defined for use in QML
31
32The program logic for a QML application may be defined in JavaScript.  The
33JavaScript code may either be defined in-line in QML documents, or separated
34into JavaScript files (known as \c {JavaScript Resources} in QML).
35
36There are two different kinds of JavaScript resources which are supported in
37QML: code-behind implementation files, and shared (library) files.  Both kinds
38of JavaScript resource may be \l{qtqml-javascript-imports.html}{imported} by
39other JavaScript resources, or included in \l{qtqml-modules-topic.html}
40{QML modules}.
41
42\section1 Code-Behind Implementation Resource
43
44Most JavaScript files imported into a QML document are stateful implementations
45for the QML document importing them.  In these cases, each instance of the QML
46object type defined in the document requires a separate copy of the JavaScript
47objects and state in order to behave correctly.
48
49The default behavior when importing JavaScript files is to provide a unique,
50isolated copy for each QML component instance.  If that JavaScript file does
51not import any resources or modules with a \c{.import} statement, its code will
52run in the same scope as the QML component instance and consequently can access
53and manipulate the objects and properties declared in that QML component.
54Otherwise, it will have its own unique scope, and objects and properties of the
55QML component should be passed to the functions of the JavaScript file as
56parameters if they are required.
57
58An example of a code-behind implementation resource follows:
59
60\code
61// MyButton.qml
62import QtQuick 2.0
63import "my_button_impl.js" as Logic // A new instance of this JavaScript resource
64                                    // is loaded for each instance of Button.qml.
65
66Rectangle {
67    id: rect
68    width: 200
69    height: 100
70    color: "red"
71
72    MouseArea {
73        id: mousearea
74        anchors.fill: parent
75        onClicked: Logic.onClicked(rect)
76    }
77}
78\endcode
79
80\code
81// my_button_impl.js
82var clickCount = 0;   // this state is separate for each instance of MyButton
83function onClicked(button) {
84    clickCount += 1;
85    if ((clickCount % 5) == 0) {
86        button.color = Qt.rgba(1,0,0,1);
87    } else {
88        button.color = Qt.rgba(0,1,0,1);
89    }
90}
91\endcode
92
93In general, simple logic should be defined in-line in the QML file, but more
94complex logic should be separated into code-behind implementation resources
95for maintainability and readability.
96
97\section1 Shared JavaScript Resources (Libraries)
98
99By default, JavaScript files imported from QML share their context with the QML
100component. That means the JavaScript files have access to the same QML objects
101and can modify them. As a consequence, each import must have a unique copy of
102these files.
103
104\l {Defining JavaScript Resources in QML#Code-Behind Implementation Resource}
105{The previous section} covers stateful imports of JavaScript files. However,
106some JavaScript files are stateless and act more like reusable libraries, in
107the sense that they provide a set of helper functions that do not require
108anything from where they were imported from. You can save significant amounts
109of memory and speed up the instantiation of QML components if you mark such
110libraries with a special pragma, as shown in the following example.
111
112\code
113// factorial.js
114.pragma library
115
116var factorialCount = 0;
117
118function factorial(a) {
119    a = parseInt(a);
120
121    // factorial recursion
122    if (a > 0)
123        return a * factorial(a - 1);
124
125    // shared state
126    factorialCount += 1;
127
128    // recursion base-case.
129    return 1;
130}
131
132function factorialCallCount() {
133    return factorialCount;
134}
135\endcode
136
137The pragma declaration must appear before any JavaScript code excluding comments.
138
139Note that multiple QML documents can import \c{"factorial.js"} and call the
140factorial and factorialCallCount functions that it provides.  The state of the
141JavaScript import is shared across the QML documents which import it, and thus
142the return value of the factorialCallCount function may be non-zero when called
143within a QML document which never calls the factorial function.
144
145For example:
146
147\code
148// Calculator.qml
149import QtQuick 2.0
150import "factorial.js" as FactorialCalculator // This JavaScript resource is only
151                                             // ever loaded once by the engine,
152                                             // even if multiple instances of
153                                             // Calculator.qml are created.
154
155Text {
156    width: 500
157    height: 100
158    property int input: 17
159    text: "The factorial of " + input + " is: " + FactorialCalculator.factorial(input)
160}
161\endcode
162
163As they are shared, .pragma library files cannot access QML component instance
164objects or properties directly, although QML values can be passed as function
165parameters.
166
167*/
168