source: trunk/src/3rdparty/webkit/WebKit/qt/docs/qtwebkit-bridge.qdoc@ 846

Last change on this file since 846 was 846, checked in by Dmitry A. Kuminov, 14 years ago

trunk: Merged in qt 4.7.2 sources from branches/vendor/nokia/qt.

File size: 20.7 KB
Line 
1/*!
2 \inmodule QtWebKit
3 \page qtwebkit-bridge.html
4 \title The QtWebKit Bridge
5 \contentspage QtWebKit
6 \section1 Overview
7 \section2 The technology
8
9 The QtWebKit bridge is a mechanism that extends WebKit's JavaScript environment to access native
10 objects that are represented as \l{QObject}s. It takes advantage of the \l{QObject} introspection,
11 a part of the \l{Object Model}, which makes it easy to integrate with the dynamic JavaScript environment,
12 for example \l{QObject} properties map directly to JavaScript properties.
13
14 For example, both JavaScript and QObjects have properties: a construct that represent a getter/setter
15 pair under one name.
16
17 \section2 Use Cases
18
19 There are two main use cases for the QtWebKit bridge. Web content in a native application, and Thin Clients.
20
21 \section3 Web Content in a Native Application
22
23 This is a common use case in classic Qt application, and a design pattern used by several modern
24 applications. For example, an application that contains a media-player, playlist manager, and music store.
25 The playlist manager is usually best authored as a classic desktop application,
26 with the native-looking robust \l{QWidget}s helping with producing that application.
27 The media-player control, which usually looks custom, can be written using the \l{Graphics View framework}
28 or with in a declarative way with \l{QtDeclarative}. The music store, which shows dynamic content
29 from the internet and gets modified rapidly, is best authored in HTML and maintained on the server.
30
31 With the QtWebKit bridge, that music store component can interact with native parts of the application,
32 for example, if a file needs to be saved to a specific location.
33
34 \section3 Thin Client
35
36 Another use case is using Qt as a native backend to a full web application,
37 referred to here as a thin client. In this use-case, the entire UI is driven by
38 HTML, JavaScript and CSS, and native Qt-based components are used to allow that application
39 access to native features not usually exposed to the web, or to enable helper components that
40 are best written with C++.
41
42 An example for such a client is a UI for a video-on-demand service on a TV. The entire content and
43 UI can be kept on the server, served dynamically through HTTP and rendered with WebKit, with additional
44 native components for accessing hardware-specific features like extracting the list of images
45 out of the video.
46
47 \section2 Difference from Other Bridge Technologies
48
49 Of course QtWebKit is not the only bridge technology out there. NPAPI, for example,
50 is a long-time standard or web-native bridging. Due to Qt's meta-object system, full applications
51 built partially with web-technologies are much easier to develop. NPAPI, however, is more geared
52 towards cross-browser plugins, due to it being an accepted standard.
53
54 When developing a plugin for a browser, NPAPI is recommended. When developing a full application
55 that utilizes HTML-rendering, the QtWebKit bridge is recommended.
56
57 \section2 Relationship with QtScript
58
59 The QtWebKit bridge is similar to \l{QtScript}, especially to some of the features described in the
60 \l{Making Applications Scriptable} page. However, as of Qt 4.7, full QtScript API is not supported for web applications.
61 That is planned as an enhancement for future versions. You might notice that some of the features
62 described here are an exact copy of the ones described in the \l{Making Applications Scriptable} page. That is because
63 the QtWebKit bridge is a subset of that functionality, and this page tries to capture the full
64 capabilities available through the QtWebKit bridge specifically.
65
66 \section1 Accessing QObjects
67
68 \section2 Creating the link via QWebFrame
69
70 By default, no QObjects are accessible through the web environment, for security reasons.
71 To enable web content access for a native QObject, the application must explicitly grant it access,
72 using the following call:
73
74 \snippet webkitsnippets/qtwebkit_bridge_snippets.cpp 0
75
76 See \l{QWebFrame::addToJavaScriptWindowObject()} for more information.
77
78 \section2 Using Signals and Slots
79
80 The QtWebKit bridge adapts Qt's central \l{Signals and Slots} feature for
81 scripting. There are three principal ways to use signals and slots
82 with the QtWebKit bridge:
83
84 \list
85 \i \bold{Hybrid C++/script}: C++ application code connects a
86 signal to a script function. For example, the script function can be
87 a function that the user has typed in, or one that you have read from a
88 file. This approach is useful if you have a QObject but don't want
89 to expose the object itself to the scripting environment; you just
90 want a script to be able to define how a signal should be reacted
91 to, and leave it up to the C++ side of your application to establish
92 the connection.
93
94 \i \bold{Hybrid script/C++}: A script can connect signals and slots
95 to establish connections between pre-defined objects that the
96 application exposes to the scripting environment. In this scenario,
97 the slots themselves are still written in C++, but the definition of
98 the connections is fully dynamic (script-defined).
99
100 \i \bold{Purely script-defined}: A script can both define signal
101 handler functions (effectively "slots written in JavaScript"),
102 \e{and} set up the connections that utilize those handlers. For
103 example, a script can define a function that will handle the
104 QLineEdit::returnPressed() signal, and then connect that signal to the
105 script function.
106 \endlist
107
108 Note that QtScript functions such as qScriptConnect are unavilable in the web environment.
109
110 \section3 Signal to Function Connections
111
112 \snippet webkitsnippets/qtwebkit_bridge_snippets.cpp 6
113
114 In this form of connection, the argument to \c{connect()} is the
115 function to connect to the signal.
116
117 \snippet webkitsnippets/qtwebkit_bridge_snippets.cpp 7
118
119 The argument can be a JavaScript function, as in the above
120 example, or it can be a QObject slot, as in
121 the following example:
122
123 \snippet webkitsnippets/qtwebkit_bridge_snippets.cpp 8
124
125 When the argument is a QObject slot, the argument types of the
126 signal and slot do not necessarily have to be compatible;
127 If necessary, the QtWebKit bridge will, perform conversion of the signal
128 arguments to match the argument types of the slot.
129
130 To disconnect from a signal, you invoke the signal's
131 \c{disconnect()} function, passing the function to disconnect
132 as argument:
133
134 \snippet webkitsnippets/qtwebkit_bridge_snippets.cpp 9
135
136 When a script function is invoked in response to a signal, the
137 \c this object will be the Global Object.
138
139 \section3 Signal to Member Function Connections
140
141 \snippet webkitsnippets/qtwebkit_bridge_snippets.cpp 10
142
143 In this form of the \c{connect()} function, the first argument
144 is the object that will be bound to the variable, \c this, when
145 the function specified using the second argument is invoked.
146
147 If you have a push button in a form, you typically want to do
148 something involving the form in response to the button's
149 \c{clicked} signal; passing the form as the \c this object
150 makes sense in such a case.
151
152 \snippet webkitsnippets/qtwebkit_bridge_snippets.cpp 11
153
154 To disconnect from the signal, pass the same arguments to \c{disconnect()}:
155
156 \snippet webkitsnippets/qtwebkit_bridge_snippets.cpp 12
157
158 \section3 Signal to Named Member Function Connections
159
160 \snippet webkitsnippets/qtwebkit_bridge_snippets.cpp 14
161
162 This form of the \c{connect()} function requires that the first argument is
163 the object that will be bound to the variable \c{this} when a function is
164 invoked in response to the signal. The second argument specifies the
165 name of a function that is connected to the signal, and this refers to a
166 member function of the object passed as the first argument (thisObject
167 in the above scheme).
168
169 Note that the function is resolved when the connection is made, not
170 when the signal is emitted.
171
172 \snippet webkitsnippets/qtwebkit_bridge_snippets.cpp 15
173
174 To disconnect from the signal, pass the same arguments to \c{disconnect()}:
175
176 \snippet webkitsnippets/qtwebkit_bridge_snippets.cpp 17
177
178 \section3 Error Handling
179
180 When \c{connect()} or \c{disconnect()} succeeds, the function will
181 return \c{undefined}; otherwise, it will throw a script exception.
182 You can obtain an error message from the resulting \c{Error} object.
183 Example:
184
185 \snippet webkitsnippets/qtwebkit_bridge_snippets.cpp 18
186
187 \section3 Emitting Signals from Scripts
188
189 To emit a signal from script code, you simply invoke the signal
190 function, passing the relevant arguments:
191
192 \snippet webkitsnippets/qtwebkit_bridge_snippets.cpp 19
193
194 It is currently not possible to define a new signal in a script;
195 i.e., all signals must be defined by C++ classes.
196
197 \section3 Overloaded Signals and Slots
198
199 When a signal or slot is overloaded, the QtWebKit bridge will attempt to
200 pick the right overload based on the actual types of the QScriptValue arguments
201 involved in the function invocation. For example, if your class has slots
202 \c{myOverloadedSlot(int)} and \c{myOverloadedSlot(QString)}, the following
203 script code will behave reasonably:
204
205 \snippet webkitsnippets/qtwebkit_bridge_snippets.cpp 20
206
207 You can specify a particular overload by using array-style property access
208 with the \l{QMetaObject::normalizedSignature()}{normalized signature} of
209 the C++ function as the property name:
210
211 \snippet webkitsnippets/qtwebkit_bridge_snippets.cpp 21
212
213 If the overloads have different number of arguments, the QtWebKit bridge will
214 pick the overload with the argument count that best matches the
215 actual number of arguments passed to the slot.
216
217 For overloaded signals, JavaScript will throw an error if you try to connect
218 to the signal by name; you have to refer to the signal with the full
219 normalized signature of the particular overload you want to connect to.
220
221 \section3 Invokable Methods
222
223 Both slots and signals are invokable from script by default. In addition, it's also
224 possible to define a method that's invokable from script without it being a signal or a slot.
225 This is especially useful for functions with return types, as slots normally do not return anything
226 (it would be meaningless to return values from a slot, as the connected signals don't handle the returned data).
227 To make a non-slot method invokable, simply add the Q_INVOKABLE macro before its definition:
228
229 \snippet webkitsnippets/qtwebkit_bridge_snippets.cpp 22
230
231 \section2 Accessing Properties
232
233 The properties of the QObject are available as properties
234 of the corresponding JavaScript object. When you manipulate
235 a property in script code, the C++ get/set method for that
236 property will automatically be invoked. For example, if your
237 C++ class has a property declared as follows:
238
239 \snippet webkitsnippets/qtwebkit_bridge_snippets.cpp 23
240
241 then script code can do things like the following:
242
243 \snippet webkitsnippets/qtwebkit_bridge_snippets.cpp 24
244
245 \section2 Accessing Child QObjects
246
247 Every named child of the QObject (that is, for which
248 QObject::objectName() is not an empty string) is by default available as
249 a property of the JavaScript wrapper object. For example,
250 if you have a QDialog with a child widget whose \c{objectName} property is
251 \c{"okButton"}, you can access this object in script code through
252 the expression
253
254 \snippet webkitsnippets/qtwebkit_bridge_snippets.cpp 25
255
256 Since \c{objectName} is itself a Q_PROPERTY, you can manipulate
257 the name in script code to, for example, rename an object:
258
259 \snippet webkitsnippets/qtwebkit_bridge_snippets.cpp 26
260
261 \section2 Data types
262
263 When calling slots, receiving signals or accessing properties, usually some payload is involved.
264 For example, a property "text" might return a \l{QString} parameter.
265 The QtWebKit bridge does the job of converting between a given JavaScript data-type, and the
266 expected or given Qt type. Each Qt type has a coresponding set of rules of how JavaScript treats it.
267
268 The data type conversions are also applicable for the data returned from non-void invokable methods.
269
270 \section3 Numbers
271
272 All Qt numeric data types are converted to or from a JavaScript number. These include int, short, float,
273 double, and the porable Qt types (qreal, qint etc). A special case is \l{QChar};
274 If a slot expects a QChar, the QtWebKit bridge would use the unicode value in case of a number,
275 or the first character in a string.
276
277 Note that non-standard (typedefed) number types are not automatically converted to
278 or from a JavaScript number - it's advised to use standard number types for signal, slots
279 and properties.
280
281 When a non-number is passed as an argument to a method or property that expects a number,
282 the appropriate JavaScript conversion function (parseInt / parseFloat) would be used.
283
284 \section3 Strings
285
286 When JavaScript accesses methods or properties that expect a \l{QString}, the QtWebKit bridge
287 will automatically convert the value to a string (if it is not already a string), using the
288 built-in JavaScript toString method.
289
290 When a QString is passed to JavaScript from a signal or a property, The QtWebKit bridge will
291 convert it into a JavaScript string.
292
293 \section3 Date & Time
294
295 Both \l{QDate}, \l{QTime} and \l{QDateTime} are automatically translated to or from the JavaScript
296 Date object. If a number were passed as an argument to a method that expects one of the date/time
297 types, the QtWebKit bridge would treat it as a timestamp. If a sting is passed, QtWebKit would
298 try different Qt date parsing functions to find the right one.
299
300 \section3 Regular Expressions
301
302 The QtWebKit bridge would automatically convert JavaScript RegEx object to a \l{QRegExp}.
303 If a string is passed to a method expecting a \l{QRegExp}, the string would be converted
304 to that \l{QRegExp}.
305
306 \section3 Lists
307
308 The QtWebKit bridge treats several types of lists in a special way: \l{QVariantList}, \l{QStringList},
309 \l{QObjectList} and \l{QList}<int>. When a slot or property expects one of those list types,
310 the QtWebKit bridge would try to convert a JavaScript array into that type, converting each of
311 the array's elements to the single-element type of the list.
312
313 The most useful type of list is perhaps \l{QVariantList}, which can be converted to from any
314 JavaScript array.
315
316 \section3 Compound (JSON) objects
317
318 JavaScript compound objects, also known as JSON objects, are variables that hold a list
319 of key-value pairs, where all the keys are strings and the values can have any type.
320 This translates very well to \l{QVariantMap}, which is nothing more than a \l{QMap} of \l{QString}
321 to \l{QVariant}.
322
323 The seamless conversion between JSON objects and \l{QVariantMap} allows for a very convenient
324 way of passing arbitrary structured data between C++ and the JavaScript environment. The native \l{QObject} has
325 to make sure that compound values are converted to \l{QVariantMap}s and \l{QVariantList}s, and JavaScript is
326 guaranteed to receive them in a meaningful way.
327
328 Note that types that are not supported by JSON, such as JavaScript functions and getters/setters,
329 are not converted.
330
331 \section3 QVariants
332
333 When a slot or property accepts a \l{QVariant}, the QtWebKit bridge would create a \l{QVariant} that best
334 matches the argument passed by JavaScript. A string, for example, would become a \l{QVariant} holding a \l{QString},
335 a normal JSON object would become a \l{QVariantMap}, and a JavaScript array would become a \l{QVariantList}.
336
337 Using \l{QVariant}s generously in C++ in that way makes C++ programming feel a bit more like JavaScript programming,
338 as it adds another level of indirection. Passing \l{QVariant}s around like this q is very flexible, as the program can figure out
339 the type of argument in runtime just like JavaScript would do, but it also takes away from the type-safety and robust
340 nature of C++. It's recommended to use \l{QVariant}s only for convenience high-level functions, and to keep most of your
341 \l{QObject}s somewhat type-safe.
342
343 \section3 QObjects
344
345 A pointer to a \l{QObject} or a \l{QWidget} can be passed as payload in signals, slots and properties. That object
346 can then be used like an object that's exposed directly; i.e. its slots can be invoked, its signals connected to etc.
347 However, this functionality is fairly limited - the type used has to be \l{QObject}* or \l{QWidget}*. If the type
348 specified is a pointer to a non-\l{QWidget} subclass of \l{QObject}, the QtWebKit bridge would not recognize it to be
349 a \l{QObject}.
350
351 In general its advised to use care when passing \l{QObject}s as arguments, as those objects don't become owned by
352 the JavaScript engine; That means that the application developer has to be extra careful not to try to access
353 \l{QObject}s that have already been deleted by the native environment.
354
355 \section3 Pixmaps and Images
356
357 \since 4.7
358
359 The QtWebKit bridge handles \l{QPixmap}s and \l{QImage}s in a special way. Since QtWebKit stores \l{QPixmap}s to
360 represent HTML images, \l{QPixmap}s coming from the native environment can be used directly inside WebKit.
361 A \l{QImage} or a \l{QPixmap} coming from the Qt environment would convert to an intermediate JavaScript object,
362 that can be represented like this:
363
364 \snippet webkitsnippets/qtwebkit_bridge_snippets.cpp 1
365
366 The JavaScript environment can then use the pixmap it gets from Qt and display it inside the HTML environment,
367 by assigning it to an existing <img /> element using assignToHTMLImageElement. It can also use the toDataURL() function,
368 which allows using the pixmap as the src attribute of an image or as a background-image url. Note that the toDataURL()
369 function is costly and should be used with caution.
370
371 Example code:
372
373 C++:
374 \snippet webkitsnippets/qtwebkit_bridge_snippets.cpp 2
375
376 HTML:
377 \snippet webkitsnippets/qtwebkit_bridge_snippets.cpp 3
378
379 When a Qt object expects a \l{QImage} or a \l{QPixmap} as input, and the argument passed is an HTML image element,
380 the QtWebKit bridge would convert the pixmap assigned to that image element into a \l{QPixmap} or a \l{QImage}.
381
382 \since 4.7
383
384 \section3 QWebElement
385
386 A signal, slot or property that expects or returns a \l{QWebElement} can work seamlessly with JavaScript references
387 to DOM elements. The JavaScript environment can select DOM elements, keep them in variables, then pass them to Qt as
388 a \l{QWebElement}, and receive them back. Example:
389
390 C++:
391 \snippet webkitsnippets/qtwebkit_bridge_snippets.cpp 4
392
393 HTML:
394 \snippet webkitsnippets/qtwebkit_bridge_snippets.cpp 5
395
396 This is specifically useful to create custom renderers or extensions to the web environment. Instead of forcing Qt
397 to select the element, the web environment already selects the element and then send the selected element directly to Qt.
398
399 Note that \l{QWebElement}s are not thread safe - an object handling them has to live in the UI thread.
400
401 \section1 Architecture issues
402
403 \section2 Limiting the Scope of the Hybrid Layer
404
405 When using QtWebKit's hybrid features, it is a common pitfall to make the API exposed to JavaScript very rich and
406 use all its features. This, however, leads to complexity and can create bugs that are hard to trace.
407 Instead, it is advisable to keep the hybrid layer small and manageable: create a gate only when
408 there's an actual need for it, i.e. there's a new native enabler that requires a direct interface
409 to the application layer. Sometimes new functionality is better handled internally in the native layer
410 or in the web layer; simplicity is your friend.
411
412 This usually becomes more apparent when the hybrid layer can create or destroy objects, or uses
413 signals slots or properties with a \l{QObject}* argument. It is advised to be very careful and to treat
414 an exposed \l{QObject} as a system - with careful attention to memory management and object ownership.
415
416 \section2 Internet Security
417
418 When exposing native object to an open web environment, it is importwhichant to understand the security
419 implications. Think whether the exposed object enables the web environment access to things that
420 shouldn't be open, and whether the web content loaded by that web page comes from a trusted. In general, when
421 exposing native QObjects that give the web environment access to private information or to functionality
422 that's potentially harmful to the client, such exposure should be balanced by limiting the web page's
423 access to trusted URLs only with HTTPS, and by utilizing other measures as part of a security strategy.
424
425
426
427*/
Note: See TracBrowser for help on using the repository browser.