Changeset 64621 in webkit
- Timestamp:
- Aug 3, 2010 8:06:12 PM (14 years ago)
- Location:
- trunk/WebKit/qt
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/WebKit/qt/ChangeLog
r64557 r64621 1 2010-08-03 Noam Rosenthal <noam.rosenthal@nokia.com> 2 3 Reviewed by Kenneth Rohde Christiansen. 4 5 [Qt] Edits to bridge documentation 6 https://bugs.webkit.org/show_bug.cgi?id=43012 7 8 * docs/qtwebkit-bridge.qdoc: 9 * docs/webkitsnippets/qtwebkit_bridge_snippets.cpp: 10 (wrapInFunction): 11 1 12 2010-08-03 Kim Grönholm <kim.1.gronholm@nokia.com> 2 13 -
trunk/WebKit/qt/docs/qtwebkit-bridge.qdoc
r61684 r64621 8 8 9 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. 10 objects 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. 16 13 17 14 \section2 Use Cases 18 15 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 Application16 There are two main use cases for the QtWebKit bridge: web content in native applications and thin clients. 17 18 \section3 Web Content in Native Applications 22 19 23 20 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.21 applications like an application that contains a media-player, playlist manager, and music store. 25 22 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 bewritten using the \l{Graphics View framework}28 or with in a declarative way with\l{QtDeclarative}. The music store, which shows dynamic content29 from the internet and gets modified rapidly, is best authored in HTML and maintained on the server.30 31 With the QtWebKit bridge, th atmusic store component can interact with native parts of the application,32 for example, ifa 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 toa full web application,37 referred to here as a thin client. In this use-case, the entire UI is driven by38 HTML, JavaScript and CSS , and native Qt-based components are used to allow that application39 access to native features not usually exposed to the web, or to enable helper components that40 are best written withC++.23 with the native-looking robust \l{QWidget}s as the application's backbone. 24 The media-player control usually has a custom look and feel and is best written using the \l{Graphics View framework} 25 or \l{QtDeclarative}. The music store, which shows dynamic content 26 from the Internet and gets modified rapidly, is best authored in HTML and maintained on the server. 27 28 With the QtWebKit bridge, the music store component can interact with native parts of the application, 29 for example, when a file needs to be saved to a specific location. 30 31 \section3 Thin Clients 32 33 The use case uses Qt as a native backend of a full web application, 34 a so-called thin client. In this use case, the entire UI is driven by 35 HTML, JavaScript and CSS. Additionally, it uses Qt-based components to 36 access native features usually not exposed to the web, or to enable helper 37 components that are best written in C++. 41 38 42 39 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 additional44 native components for accessing hardware-specific features like extracting thelist of images45 out of the video.40 UI can be kept on the server, served dynamically through HTTP and rendered with WebKit. Additional 41 native components are used to access hardware-specific features like extracting a list of images 42 out of a video stream. 46 43 47 44 \section2 Difference from Other Bridge Technologies 48 45 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 applications51 built partially with web-technologies are much easier to develop. NPAPI, however, is more geared52 towardscross-browser plugins, due to it being an accepted standard.46 Of course, QtWebKit is not the only bridge technology out there. NPAPI, for example, 47 is a long-time standard for web-native bridging. Due to Qt's meta-object system, full applications 48 leveraging web technologies are much easier to develop with the QtWebKit bridge than with NPAPI. NPAPI, however, is better 49 for cross-browser plugins, due to it being an accepted standard. 53 50 54 51 When developing a plugin for a browser, NPAPI is recommended. When developing a full application 55 that utilizesHTML-rendering, the QtWebKit bridge is recommended.52 utilizing HTML-rendering, the QtWebKit bridge is recommended. 56 53 57 54 \section2 Relationship with QtScript 58 55 59 The QtWebKit bridge is similar to \l{QtScript}, especially tosome of the features described in the60 \l{Making Applications Scriptable} page. However, as of Qt 4.7, full QtScript API is not supportedfor web applications.61 That is planned as an enhancementfor future versions. You might notice that some of the features56 The QtWebKit bridge is similar to \l{QtScript}, especially for some of the features described in the 57 \l{Making Applications Scriptable} page. However, Qt 4.7 does not provide the full QtScript API for web applications. 58 Full support is planned for future versions. You might notice that some of the features 62 59 described here are an exact copy of the ones described in the \l{Making Applications Scriptable} page. That is because 63 60 the QtWebKit bridge is a subset of that functionality, and this page tries to capture the full … … 66 63 \section1 Accessing QObjects 67 64 68 \section2 Creating the linkvia QWebFrame65 \section2 Making QObjects known to JavaScript via QWebFrame 69 66 70 67 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:68 When a web application wants to access a native QObject, it must explicitly grant access 69 to this QObject, using the following call: 73 70 74 71 \snippet webkitsnippets/qtwebkit_bridge_snippets.cpp 0 … … 84 81 \list 85 82 \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. 83 signal to a script function. This approach is useful if you have 84 a QObject but don't want to expose the object itself to the scripting 85 environment. You just want to define how the script responds to a 86 signal and leave it up to the C++ side of your application to establish 87 the connection between the C++ signal and the JavaScript slot. 93 88 94 89 \i \bold{Hybrid script/C++}: A script can connect signals and slots … … 110 105 \section3 Signal to Function Connections 111 106 112 \snippet webkitsnippets/qtwebkit_bridge_snippets.cpp 6113 114 In this form of connection, the argument to \c{connect()} is the115 function to connect to the signal.116 117 107 \snippet webkitsnippets/qtwebkit_bridge_snippets.cpp 7 118 108 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: 109 The call to \c{connect()} establishes a connection between the signal 110 \c{somethingChanged} and the slot \c{myInterestingScriptFunction}. 111 Whenever the object \c{myObject} emits the signal \c{somethingChanged}, 112 the slot \c{myInterestingScriptFunction} gets called automatically. 113 114 The argument of \c{connect()} can be any JavaScript function as in the above 115 example or a slot of a QObject as in the following example: 122 116 123 117 \snippet webkitsnippets/qtwebkit_bridge_snippets.cpp 8 124 118 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: 119 When the argument is a slot of a QObject, the argument types of the 120 signal and the slot do not have to be compatible. If possible, the QtWebKit 121 bridge converts the signal arguments such that they match the slot argument. 122 123 To disconnect a slot from a signal, you call the signal's 124 \c{disconnect()} function with the slot as its argument: 133 125 134 126 \snippet webkitsnippets/qtwebkit_bridge_snippets.cpp 9 … … 141 133 \snippet webkitsnippets/qtwebkit_bridge_snippets.cpp 10 142 134 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. 135 The call to \c{connect() establishes a connection between the signal 136 \c{somethingChanged} and the slot \c{function}. Whenever the object 137 \c{myObject} emits the signal \c{somethingChanged}, the slot \c{function} 138 of the object \c{thisObject} gets called automatically. Let's illustrate 139 this with an example. 140 141 If you have a push button in a form, you typically want the form 142 to do something in response to the button's \c{clicked} signal. The 143 call to \c{connect()} makes sure that the function \c{onClicked()} is 144 called whenever you click on the push button, that is, whenever the 145 the signal \c{clicked()} is emitted by \c{myButton}. The slot \c{onClicked()} 146 prints the value of \c{x} as stored in the \c{form}. 151 147 152 148 \snippet webkitsnippets/qtwebkit_bridge_snippets.cpp 11 153 149 154 To disconnect from the signal, pass the same arguments to \c{disconnect()}: 150 To disconnect a slot from a signal, you pass the same arguments to 151 \c{disconnect()} as you passed to \c{connect()}. In general, this looks 152 as follows: 155 153 156 154 \snippet webkitsnippets/qtwebkit_bridge_snippets.cpp 12 … … 160 158 \snippet webkitsnippets/qtwebkit_bridge_snippets.cpp 14 161 159 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). 160 This form of the \c{connect()} function requires that the first argument \c{thisObject} is 161 the object that will be bound to \c{this} when the function \c{functionName} is 162 invoked in response to the signal \c{somethingChanged}. The second argument \c{functionName} specifies the 163 name of a function that is connected to the signal. It refers to a 164 member function of the object \c{thisObject}. 168 165 169 166 Note that the function is resolved when the connection is made, not … … 172 169 \snippet webkitsnippets/qtwebkit_bridge_snippets.cpp 15 173 170 174 To disconnect from the signal, pass the same arguments to \c{disconnect()}: 171 To disconnect from the signal, pass the same arguments to \c{disconnect()} 172 as you passed to \c{connect}: 175 173 176 174 \snippet webkitsnippets/qtwebkit_bridge_snippets.cpp 17 … … 221 219 \section3 Invokable Methods 222 220 223 Both slots and signals are invokable from script by default. In addition, it's also224 possible to define a method that 's invokable from script without it being a signalor a slot.221 Both slots and signals are invokable from scripts by default. In addition, it is also 222 possible to define a method that is invokable from scripts, although the method is neither a signal nor a slot. 225 223 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).224 (it would be meaningless to return a value from a slot, as the connected signals cannot handle return values). 227 225 To make a non-slot method invokable, simply add the Q_INVOKABLE macro before its definition: 228 226 … … 231 229 \section2 Accessing Properties 232 230 233 The properties of theQObject are available as properties231 The properties of a QObject are available as properties 234 232 of the corresponding JavaScript object. When you manipulate 235 233 a property in script code, the C++ get/set method for that … … 245 243 \section2 Accessing Child QObjects 246 244 247 Every named child of the QObject (that is,for which248 QObject::objectName() is not anempty string) is by default available as245 Every named child of a QObject (that is, every child for which 246 QObject::objectName() does not return the empty string) is by default available as 249 247 a property of the JavaScript wrapper object. For example, 250 248 if you have a QDialog with a child widget whose \c{objectName} property is … … 254 252 \snippet webkitsnippets/qtwebkit_bridge_snippets.cpp 25 255 253 256 Since \c{objectName} is itself a Q_PROPERTY, you can manipulate257 the name in script code to , for example, rename an object:254 Because \c{objectName} is itself a Q_PROPERTY, you can manipulate 255 the name in script code to rename an object. For example: 258 256 259 257 \snippet webkitsnippets/qtwebkit_bridge_snippets.cpp 26 … … 271 269 272 270 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 271 double, and the portable Qt types (qreal, qint etc). A special case is \l{QChar}. 272 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. 273 274 Note that non-standard (typedef'ed) number types are not automatically converted to 275 or from a JavaScript number - we suggest to use standard number types for signals, slots 279 276 and properties. 280 277 281 278 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 beused.279 the appropriate JavaScript conversion function (parseInt / parseFloat) is used. 283 280 284 281 \section3 Strings … … 288 285 built-in JavaScript toString method. 289 286 290 When a QString is passed to JavaScript from a signal or a property, The QtWebKit bridge will291 convert it into a JavaScript string.287 When a QString is passed to JavaScript from a signal or a property, the QtWebKit bridge 288 converts it into a JavaScript string. 292 289 293 290 \section3 Date & Time 294 291 295 292 Both \l{QDate}, \l{QTime} and \l{QDateTime} are automatically translated to or from the JavaScript 296 Date object. If a number werepassed as an argument to a method that expects one of the date/time297 types, the QtWebKit bridge would treat it as a timestamp. If a sting is passed, QtWebKit would298 tr y different Qt date parsing functions to find the right one.293 Date object. If a number is passed as an argument to a method that expects one of the date/time 294 types, the QtWebKit bridge treats it as a timestamp. If a sting is passed, QtWebKit 295 tries the different Qt date parsing functions to perform the right translation. 299 296 300 297 \section3 Regular Expressions 301 298 302 The QtWebKit bridge would automatically convertJavaScript RegEx object to a \l{QRegExp}.303 If a string is passed to a method expecting a \l{QRegExp}, the string would beconverted304 to that\l{QRegExp}.299 The QtWebKit bridge automatically converts a JavaScript RegEx object to a \l{QRegExp}. 300 If a string is passed to a method expecting a \l{QRegExp}, the string is converted 301 to a \l{QRegExp}. 305 302 306 303 \section3 Lists … … 308 305 The QtWebKit bridge treats several types of lists in a special way: \l{QVariantList}, \l{QStringList}, 309 306 \l{QObjectList} and \l{QList}<int>. When a slot or property expects one of those list types, 310 the QtWebKit bridge would tryto convert a JavaScript array into that type, converting each of307 the QtWebKit bridge tries to convert a JavaScript array into that type, converting each of 311 308 the array's elements to the single-element type of the list. 312 309 313 The most useful type of list is perhaps \l{QVariantList}, which can be converted tofrom any310 The most useful type of list is \l{QVariantList}, which can be converted to and from any 314 311 JavaScript array. 315 312 … … 318 315 JavaScript compound objects, also known as JSON objects, are variables that hold a list 319 316 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}317 This translates very well to \l{QVariantMap}, which is nothing more than a \l{QMap} from \l{QString} 321 318 to \l{QVariant}. 322 319 323 320 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 321 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 326 322 guaranteed to receive them in a meaningful way. 327 323 … … 331 327 \section3 QVariants 332 328 333 When a slot or property accepts a \l{QVariant}, the QtWebKit bridge would createa \l{QVariant} that best334 matches the argument passed by JavaScript. A string, for example, would becomea \l{QVariant} holding a \l{QString},335 a normal JSON object would become a \l{QVariantMap}, and a JavaScript array would becomea \l{QVariantList}.329 When a slot or property accepts a \l{QVariant}, the QtWebKit bridge creates a \l{QVariant} that best 330 matches the argument passed by JavaScript. A string, for example, becomes a \l{QVariant} holding a \l{QString}, 331 a normal JSON object becomes a \l{QVariantMap}, and a JavaScript array becomes a \l{QVariantList}. 336 332 337 333 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 out339 the type of argument in runtime just like JavaScript would do, but it also takes away from the type-safety and robust340 nature of C++. It's recommended to use \l{QVariant}s only for conveniencehigh-level functions, and to keep most of your341 \l{QObject}s somewhattype-safe.334 as it adds another level of indirection. Passing \l{QVariant}s around like this is very flexible. The program can figure out 335 the type of argument at runtime just like JavaScript would do. But doing so also takes away the type safety and robustness of C++. 336 We recommended to use \l{QVariant}s only for high-level functions, and to keep most of your 337 \l{QObject}s type-safe. 342 338 343 339 \section3 QObjects 344 340 345 A pointer to a \l{QObject} or a \l{QWidget} can be passed as payload in signals, slots and properties. Thatobject346 can then be used like an object that 's exposed directly; i.e. its slots can be invoked, its signals connected toetc.341 Pointers to a \l{QObject} or a \l{QWidget} can be used in signals, slots and properties. This object 342 can then be used like an object that is exposed directly. Its slots can be invoked, its signals connected to, etc. 347 343 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 be344 specified is a pointer to a non-\l{QWidget} subclass of \l{QObject}, the QtWebKit bridge does not recognize it as 349 345 a \l{QObject}. 350 346 … … 359 355 The QtWebKit bridge handles \l{QPixmap}s and \l{QImage}s in a special way. Since QtWebKit stores \l{QPixmap}s to 360 356 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 convertto an intermediate JavaScript object,362 thatcan be represented like this:357 A \l{QImage} or a \l{QPixmap} coming from Qt is converted to an intermediate JavaScript object, 358 which can be represented like this: 363 359 364 360 \snippet webkitsnippets/qtwebkit_bridge_snippets.cpp 1 365 361 366 The JavaScript environment can then use the pixmap it getsfrom 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()362 The JavaScript environment can then use the pixmap from Qt and display it inside the HTML environment, 363 by assigning it to an existing \c{<img>} element with \c{assignToHTMLImageElement()}. It can also use the \c{toDataURL()} function, 364 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()} 369 365 function is costly and should be used with caution. 370 366 … … 395 391 396 392 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 sendthe selected element directly to Qt.393 to select the element, the web environment selects the element and then sends the selected element directly to Qt. 398 394 399 395 Note that \l{QWebElement}s are not thread safe - an object handling them has to live in the UI thread. 400 396 401 \section1 Architecture issues397 \section1 Architecture Issues 402 398 403 399 \section2 Limiting the Scope of the Hybrid Layer 404 400 405 401 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.402 use all its features. This, however, leads to complexity and can create bugs that are hard to find. 407 403 Instead, it is advisable to keep the hybrid layer small and manageable: create a gate only when 408 404 there's an actual need for it, i.e. there's a new native enabler that requires a direct interface … … 411 407 412 408 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 treat409 signals, slots or properties with a \l{QObject}* argument. It is advised to be very careful and to treat 414 410 an exposed \l{QObject} as a system - with careful attention to memory management and object ownership. 415 411 416 412 \section2 Internet Security 417 413 418 When exposing native object to an open web environment, it is importwhichant to understand the security419 implications. Think whether the exposed object enables the web environment access t o things that420 shouldn't be open, and whether the web content loaded by that web page comes from a trusted . In general, when414 When exposing native objects to an open web environment, it is important to understand the security 415 implications. Think whether the exposed object enables the web environment access things that 416 shouldn't be open, and whether the web content loaded by that web page comes from a trusted source. In general, when 421 417 exposing native QObjects that give the web environment access to private information or to functionality 422 418 that's potentially harmful to the client, such exposure should be balanced by limiting the web page's -
trunk/WebKit/qt/docs/webkitsnippets/qtwebkit_bridge_snippets.cpp
r61480 r64621 96 96 //! [9] 97 97 //! [10] 98 connect(thisObject, function)98 myQObject.somethingChanged.connect(thisObject, function) 99 99 //! [10] 100 100 //! [11] 101 var obj= { x: 123 };102 var fun= function() { print(this.x); };103 my QObject.somethingChanged.connect(obj, fun);101 var form = { x: 123 }; 102 var onClicked = function() { print(this.x); }; 103 myButton.clicked.connect(form, onClicked); 104 104 //! [11] 105 105 //! [12] 106 myQObject.somethingChanged.disconnect( obj, fun);106 myQObject.somethingChanged.disconnect(thisObject, function); 107 107 //! [12] 108 108 //! [13] … … 110 110 //! [13] 111 111 //! [14] 112 connect(thisObject, functionName)112 myQObject.somethingChanged.connect(thisObject, "functionName") 113 113 //! [14] 114 114 //! [15] … … 120 120 //! [16] 121 121 //! [17] 122 myQObject.somethingChanged.disconnect( obj, "fun");122 myQObject.somethingChanged.disconnect(thisObject, "functionName"); 123 123 //! [17] 124 124 //! [18] … … 146 146 147 147 public: 148 Q_INVOKABLE void thisMethodIsInvokableIn QtScript();149 void thisMethodIsNotInvokableIn QtScript();148 Q_INVOKABLE void thisMethodIsInvokableInJavaScript(); 149 void thisMethodIsNotInvokableInJavaScript(); 150 150 151 151 ...
Note: See TracChangeset
for help on using the changeset viewer.