| /*! |
| \inmodule QtWebKit |
| \page qtwebkit-bridge.html |
| \title The QtWebKit Bridge |
| \contentspage QtWebKit |
| \section1 Overview |
| \section2 The technology |
| |
| The QtWebKit bridge is a mechanism that extends WebKit's JavaScript environment to access native |
| objects represented as \l{QObject}s. It takes advantage of the \l{QObject} introspection, |
| a part of the \l{Object Model}, which makes it easy to integrate with the dynamic JavaScript environment. |
| For example \l{QObject} properties map directly to JavaScript properties. |
| |
| \section2 Use Cases |
| |
| There are two main use cases for the QtWebKit bridge: web content in native applications and thin clients. |
| |
| \section3 Web Content in Native Applications |
| |
| This is a common use case in classic Qt application, and a design pattern used by several modern |
| applications like an application that contains a media-player, playlist manager, and music store. |
| The playlist manager is usually best authored as a classic desktop application, |
| with the native-looking robust \l{QWidget}s as the application's backbone. |
| The media-player control usually has a custom look and feel and is best written using the \l{Graphics View framework} |
| or \l{QtDeclarative}. The music store, which shows dynamic content |
| from the Internet and gets modified rapidly, is best authored in HTML and maintained on the server. |
| |
| With the QtWebKit bridge, the music store component can interact with native parts of the application, |
| for example, when a file needs to be saved to a specific location. |
| |
| \section3 Thin Clients |
| |
| The use case uses Qt as a native backend of a full web application, |
| a so-called thin client. In this use case, the entire UI is driven by |
| HTML, JavaScript and CSS. Additionally, it uses Qt-based components to |
| access native features usually not exposed to the web, or to enable helper |
| components that are best written in C++. |
| |
| An example for such a client is a UI for a video-on-demand service on a TV. The entire content and |
| UI can be kept on the server, served dynamically through HTTP and rendered with WebKit. Additional |
| native components are used to access hardware-specific features like extracting a list of images |
| out of a video stream. |
| |
| \section2 Difference from Other Bridge Technologies |
| |
| Of course, QtWebKit is not the only bridge technology out there. NPAPI, for example, |
| is a long-time standard for web-native bridging. Due to Qt's meta-object system, full applications |
| leveraging web technologies are much easier to develop with the QtWebKit bridge than with NPAPI. NPAPI, however, is better |
| for cross-browser plugins, due to it being an accepted standard. |
| |
| When developing a plugin for a browser, NPAPI is recommended. When developing a full application |
| utilizing HTML-rendering, the QtWebKit bridge is recommended. |
| |
| \section2 Relationship with QtScript |
| |
| The QtWebKit bridge is similar to \l{QtScript}, especially for some of the features described in the |
| \l{Making Applications Scriptable} page. However, Qt 4.7 does not provide the full QtScript API for web applications. |
| Full support is planned for future versions. You might notice that some of the features |
| described here are an exact copy of the ones described in the \l{Making Applications Scriptable} page. That is because |
| the QtWebKit bridge is a subset of that functionality, and this page tries to capture the full |
| capabilities available through the QtWebKit bridge specifically. |
| |
| \section1 Accessing QObjects |
| |
| \section2 Making QObjects known to JavaScript via QWebFrame |
| |
| By default, no QObjects are accessible through the web environment, for security reasons. |
| When a web application wants to access a native QObject, it must explicitly grant access |
| to this QObject, using the following call: |
| |
| \snippet webkitsnippets/qtwebkit_bridge_snippets.cpp 0 |
| |
| See \l{QWebFrame::addToJavaScriptWindowObject()} for more information. |
| |
| \section2 Using Signals and Slots |
| |
| The QtWebKit bridge adapts Qt's central \l{Signals and Slots} feature for |
| scripting. There are three principal ways to use signals and slots |
| with the QtWebKit bridge: |
| |
| \list |
| \i \bold{Hybrid C++/script}: C++ application code connects a |
| signal to a script function. This approach is useful if you have |
| a QObject but don't want to expose the object itself to the scripting |
| environment. You just want to define how the script responds to a |
| signal and leave it up to the C++ side of your application to establish |
| the connection between the C++ signal and the JavaScript slot. |
| |
| \i \bold{Hybrid script/C++}: A script can connect signals and slots |
| to establish connections between pre-defined objects that the |
| application exposes to the scripting environment. In this scenario, |
| the slots themselves are still written in C++, but the definition of |
| the connections is fully dynamic (script-defined). |
| |
| \i \bold{Purely script-defined}: A script can both define signal |
| handler functions (effectively "slots written in JavaScript"), |
| \e{and} set up the connections that utilize those handlers. For |
| example, a script can define a function that will handle the |
| QLineEdit::returnPressed() signal, and then connect that signal to the |
| script function. |
| \endlist |
| |
| Note that QtScript functions such as qScriptConnect are unavilable in the web environment. |
| |
| \section3 Signal to Function Connections |
| |
| \snippet webkitsnippets/qtwebkit_bridge_snippets.cpp 7 |
| |
| The call to \c{connect()} establishes a connection between the signal |
| \c{somethingChanged} and the slot \c{myInterestingScriptFunction}. |
| Whenever the object \c{myObject} emits the signal \c{somethingChanged}, |
| the slot \c{myInterestingScriptFunction} gets called automatically. |
| |
| The argument of \c{connect()} can be any JavaScript function as in the above |
| example or a slot of a QObject as in the following example: |
| |
| \snippet webkitsnippets/qtwebkit_bridge_snippets.cpp 8 |
| |
| When the argument is a slot of a QObject, the argument types of the |
| signal and the slot do not have to be compatible. If possible, the QtWebKit |
| bridge converts the signal arguments such that they match the slot argument. |
| |
| To disconnect a slot from a signal, you call the signal's |
| \c{disconnect()} function with the slot as its argument: |
| |
| \snippet webkitsnippets/qtwebkit_bridge_snippets.cpp 9 |
| |
| When a script function is invoked in response to a signal, the |
| \c this object will be the Global Object. |
| |
| \section3 Signal to Member Function Connections |
| |
| \snippet webkitsnippets/qtwebkit_bridge_snippets.cpp 10 |
| |
| The call to \c{connect() establishes a connection between the signal |
| \c{somethingChanged} and the slot \c{function}. Whenever the object |
| \c{myObject} emits the signal \c{somethingChanged}, the slot \c{function} |
| of the object \c{thisObject} gets called automatically. Let's illustrate |
| this with an example. |
| |
| If you have a push button in a form, you typically want the form |
| to do something in response to the button's \c{clicked} signal. The |
| call to \c{connect()} makes sure that the function \c{onClicked()} is |
| called whenever you click on the push button, that is, whenever the |
| the signal \c{clicked()} is emitted by \c{myButton}. The slot \c{onClicked()} |
| prints the value of \c{x} as stored in the \c{form}. |
| |
| \snippet webkitsnippets/qtwebkit_bridge_snippets.cpp 11 |
| |
| To disconnect a slot from a signal, you pass the same arguments to |
| \c{disconnect()} as you passed to \c{connect()}. In general, this looks |
| as follows: |
| |
| \snippet webkitsnippets/qtwebkit_bridge_snippets.cpp 12 |
| |
| \section3 Signal to Named Member Function Connections |
| |
| \snippet webkitsnippets/qtwebkit_bridge_snippets.cpp 14 |
| |
| This form of the \c{connect()} function requires that the first argument \c{thisObject} is |
| the object that will be bound to \c{this} when the function \c{functionName} is |
| invoked in response to the signal \c{somethingChanged}. The second argument \c{functionName} specifies the |
| name of a function that is connected to the signal. It refers to a |
| member function of the object \c{thisObject}. |
| |
| Note that the function is resolved when the connection is made, not |
| when the signal is emitted. |
| |
| \snippet webkitsnippets/qtwebkit_bridge_snippets.cpp 15 |
| |
| To disconnect from the signal, pass the same arguments to \c{disconnect()} |
| as you passed to \c{connect}: |
| |
| \snippet webkitsnippets/qtwebkit_bridge_snippets.cpp 17 |
| |
| \section3 Error Handling |
| |
| When \c{connect()} or \c{disconnect()} succeeds, the function will |
| return \c{undefined}; otherwise, it will throw a script exception. |
| You can obtain an error message from the resulting \c{Error} object. |
| Example: |
| |
| \snippet webkitsnippets/qtwebkit_bridge_snippets.cpp 18 |
| |
| \section3 Emitting Signals from Scripts |
| |
| To emit a signal from script code, you simply invoke the signal |
| function, passing the relevant arguments: |
| |
| \snippet webkitsnippets/qtwebkit_bridge_snippets.cpp 19 |
| |
| It is currently not possible to define a new signal in a script; |
| i.e., all signals must be defined by C++ classes. |
| |
| \section3 Overloaded Signals and Slots |
| |
| When a signal or slot is overloaded, the QtWebKit bridge will attempt to |
| pick the right overload based on the actual types of the QScriptValue arguments |
| involved in the function invocation. For example, if your class has slots |
| \c{myOverloadedSlot(int)} and \c{myOverloadedSlot(QString)}, the following |
| script code will behave reasonably: |
| |
| \snippet webkitsnippets/qtwebkit_bridge_snippets.cpp 20 |
| |
| You can specify a particular overload by using array-style property access |
| with the \l{QMetaObject::normalizedSignature()}{normalized signature} of |
| the C++ function as the property name: |
| |
| \snippet webkitsnippets/qtwebkit_bridge_snippets.cpp 21 |
| |
| If the overloads have different number of arguments, the QtWebKit bridge will |
| pick the overload with the argument count that best matches the |
| actual number of arguments passed to the slot. |
| |
| For overloaded signals, JavaScript will throw an error if you try to connect |
| to the signal by name; you have to refer to the signal with the full |
| normalized signature of the particular overload you want to connect to. |
| |
| \section3 Invokable Methods |
| |
| Both slots and signals are invokable from scripts by default. In addition, it is also |
| possible to define a method that is invokable from scripts, although the method is neither a signal nor a slot. |
| This is especially useful for functions with return types, as slots normally do not return anything |
| (it would be meaningless to return a value from a slot, as the connected signals cannot handle return values). |
| To make a non-slot method invokable, simply add the Q_INVOKABLE macro before its definition: |
| |
| \snippet webkitsnippets/qtwebkit_bridge_snippets.cpp 22 |
| |
| \section2 Accessing Properties |
| |
| The properties of a QObject are available as properties |
| of the corresponding JavaScript object. When you manipulate |
| a property in script code, the C++ get/set method for that |
| property will automatically be invoked. For example, if your |
| C++ class has a property declared as follows: |
| |
| \snippet webkitsnippets/qtwebkit_bridge_snippets.cpp 23 |
| |
| then script code can do things like the following: |
| |
| \snippet webkitsnippets/qtwebkit_bridge_snippets.cpp 24 |
| |
| \section2 Accessing Child QObjects |
| |
| Every named child of a QObject (that is, every child for which |
| QObject::objectName() does not return the empty string) is by default available as |
| a property of the JavaScript wrapper object. For example, |
| if you have a QDialog with a child widget whose \c{objectName} property is |
| \c{"okButton"}, you can access this object in script code through |
| the expression |
| |
| \snippet webkitsnippets/qtwebkit_bridge_snippets.cpp 25 |
| |
| Because \c{objectName} is itself a Q_PROPERTY, you can manipulate |
| the name in script code to rename an object. For example: |
| |
| \snippet webkitsnippets/qtwebkit_bridge_snippets.cpp 26 |
| |
| \section2 Data types |
| |
| When calling slots, receiving signals or accessing properties, usually some payload is involved. |
| For example, a property "text" might return a \l{QString} parameter. |
| The QtWebKit bridge does the job of converting between a given JavaScript data-type, and the |
| expected or given Qt type. Each Qt type has a coresponding set of rules of how JavaScript treats it. |
| |
| The data type conversions are also applicable for the data returned from non-void invokable methods. |
| |
| \section3 Numbers |
| |
| All Qt numeric data types are converted to or from a JavaScript number. These include int, short, float, |
| double, and the portable Qt types (qreal, qint etc). A special case is \l{QChar}. |
| If a slot expects a QChar, the QtWebKit bridge uses the Unicode value in case of a number and the first character in case of a string. |
| |
| Note that non-standard (typedef'ed) number types are not automatically converted to |
| or from a JavaScript number - we suggest to use standard number types for signals, slots |
| and properties. |
| |
| When a non-number is passed as an argument to a method or property that expects a number, |
| the appropriate JavaScript conversion function (parseInt / parseFloat) is used. |
| |
| \section3 Strings |
| |
| When JavaScript accesses methods or properties that expect a \l{QString}, the QtWebKit bridge |
| will automatically convert the value to a string (if it is not already a string), using the |
| built-in JavaScript toString method. |
| |
| When a QString is passed to JavaScript from a signal or a property, the QtWebKit bridge |
| converts it into a JavaScript string. |
| |
| \section3 Date & Time |
| |
| Both \l{QDate}, \l{QTime} and \l{QDateTime} are automatically translated to or from the JavaScript |
| Date object. If a number is passed as an argument to a method that expects one of the date/time |
| types, the QtWebKit bridge treats it as a timestamp. If a sting is passed, QtWebKit |
| tries the different Qt date parsing functions to perform the right translation. |
| |
| \section3 Regular Expressions |
| |
| The QtWebKit bridge automatically converts a JavaScript RegEx object to a \l{QRegExp}. |
| If a string is passed to a method expecting a \l{QRegExp}, the string is converted |
| to a \l{QRegExp}. |
| |
| \section3 Lists |
| |
| The QtWebKit bridge treats several types of lists in a special way: \l{QVariantList}, \l{QStringList}, |
| \l{QObjectList} and \l{QList}<int>. When a slot or property expects one of those list types, |
| the QtWebKit bridge tries to convert a JavaScript array into that type, converting each of |
| the array's elements to the single-element type of the list. |
| |
| The most useful type of list is \l{QVariantList}, which can be converted to and from any |
| JavaScript array. |
| |
| \section3 Compound (JSON) objects |
| |
| JavaScript compound objects, also known as JSON objects, are variables that hold a list |
| of key-value pairs, where all the keys are strings and the values can have any type. |
| This translates very well to \l{QVariantMap}, which is nothing more than a \l{QMap} from \l{QString} |
| to \l{QVariant}. |
| |
| The seamless conversion between JSON objects and \l{QVariantMap} allows for a very convenient |
| way of passing arbitrary structured data between C++ and the JavaScript environment. If the native \l{QObject} makes sure that compound values are converted to \l{QVariantMap}s and \l{QVariantList}s, JavaScript is |
| guaranteed to receive them in a meaningful way. |
| |
| Note that types that are not supported by JSON, such as JavaScript functions and getters/setters, |
| are not converted. |
| |
| \section3 QVariants |
| |
| When a slot or property accepts a \l{QVariant}, the QtWebKit bridge creates a \l{QVariant} that best |
| matches the argument passed by JavaScript. A string, for example, becomes a \l{QVariant} holding a \l{QString}, |
| a normal JSON object becomes a \l{QVariantMap}, and a JavaScript array becomes a \l{QVariantList}. |
| |
| Using \l{QVariant}s generously in C++ in that way makes C++ programming feel a bit more like JavaScript programming, |
| as it adds another level of indirection. Passing \l{QVariant}s around like this is very flexible. The program can figure out |
| the type of argument at runtime just like JavaScript would do. But doing so also takes away the type safety and robustness of C++. |
| We recommended to use \l{QVariant}s only for high-level functions, and to keep most of your |
| \l{QObject}s type-safe. |
| |
| \section3 QObjects |
| |
| Pointers to a \l{QObject} or a \l{QWidget} can be used in signals, slots and properties. This object |
| can then be used like an object that is exposed directly. Its slots can be invoked, its signals connected to, etc. |
| However, this functionality is fairly limited - the type used has to be \l{QObject}* or \l{QWidget}*. If the type |
| specified is a pointer to a non-\l{QWidget} subclass of \l{QObject}, the QtWebKit bridge does not recognize it as |
| a \l{QObject}. |
| |
| In general its advised to use care when passing \l{QObject}s as arguments, as those objects don't become owned by |
| the JavaScript engine; That means that the application developer has to be extra careful not to try to access |
| \l{QObject}s that have already been deleted by the native environment. |
| |
| \section3 Pixmaps and Images |
| |
| \since 4.7 |
| |
| The QtWebKit bridge handles \l{QPixmap}s and \l{QImage}s in a special way. Since QtWebKit stores \l{QPixmap}s to |
| represent HTML images, \l{QPixmap}s coming from the native environment can be used directly inside WebKit. |
| A \l{QImage} or a \l{QPixmap} coming from Qt is converted to an intermediate JavaScript object, |
| which can be represented like this: |
| |
| \snippet webkitsnippets/qtwebkit_bridge_snippets.cpp 1 |
| |
| The JavaScript environment can then use the pixmap from Qt and display it inside the HTML environment, |
| by assigning it to an existing \c{<img>} element with \c{assignToHTMLImageElement()}. It can also use the \c{toDataURL()} function, |
| which allows using the pixmap as the \c{src} attribute of an image or as a \c{background-image} URL. Note that the \c{toDataURL()} |
| function is costly and should be used with caution. |
| |
| Example code: |
| |
| C++: |
| \snippet webkitsnippets/qtwebkit_bridge_snippets.cpp 2 |
| |
| HTML: |
| \snippet webkitsnippets/qtwebkit_bridge_snippets.cpp 3 |
| |
| When a Qt object expects a \l{QImage} or a \l{QPixmap} as input, and the argument passed is an HTML image element, |
| the QtWebKit bridge would convert the pixmap assigned to that image element into a \l{QPixmap} or a \l{QImage}. |
| |
| \since 4.7 |
| |
| \section3 QWebElement |
| |
| A signal, slot or property that expects or returns a \l{QWebElement} can work seamlessly with JavaScript references |
| to DOM elements. The JavaScript environment can select DOM elements, keep them in variables, then pass them to Qt as |
| a \l{QWebElement}, and receive them back. Example: |
| |
| C++: |
| \snippet webkitsnippets/qtwebkit_bridge_snippets.cpp 4 |
| |
| HTML: |
| \snippet webkitsnippets/qtwebkit_bridge_snippets.cpp 5 |
| |
| This is specifically useful to create custom renderers or extensions to the web environment. Instead of forcing Qt |
| to select the element, the web environment selects the element and then sends the selected element directly to Qt. |
| |
| Note that \l{QWebElement}s are not thread safe - an object handling them has to live in the UI thread. |
| |
| \section1 Architecture Issues |
| |
| \section2 Limiting the Scope of the Hybrid Layer |
| |
| When using QtWebKit's hybrid features, it is a common pitfall to make the API exposed to JavaScript very rich and |
| use all its features. This, however, leads to complexity and can create bugs that are hard to find. |
| Instead, it is advisable to keep the hybrid layer small and manageable: create a gate only when |
| there's an actual need for it, i.e. there's a new native enabler that requires a direct interface |
| to the application layer. Sometimes new functionality is better handled internally in the native layer |
| or in the web layer; simplicity is your friend. |
| |
| This usually becomes more apparent when the hybrid layer can create or destroy objects, or uses |
| signals, slots or properties with a \l{QObject}* argument. It is advised to be very careful and to treat |
| an exposed \l{QObject} as a system - with careful attention to memory management and object ownership. |
| |
| \section2 Internet Security |
| |
| When exposing native objects to an open web environment, it is important to understand the security |
| implications. Think whether the exposed object enables the web environment access things that |
| shouldn't be open, and whether the web content loaded by that web page comes from a trusted source. In general, when |
| exposing native QObjects that give the web environment access to private information or to functionality |
| that's potentially harmful to the client, such exposure should be balanced by limiting the web page's |
| access to trusted URLs only with HTTPS, and by utilizing other measures as part of a security strategy. |
| |
| |
| |
| */ |