4
hv3 - Mega-widget building on Tkhtml.
6
THIS IS A WORK IN PROGRESS. IT IS POSSIBLE TO USE THE HV3 WIDGET, BUT
7
IT IS NOT YET PROPERLY PACKAGED. POST ON THE MAILING LIST IF YOU WISH
10
Comments and feedback also welcome.
16
::hv3::hv3 pathName ?options?
21
The [SQ hv3] command creates a new window (given by the pathName
22
argument) and makes it into hv3 widget. The hv3 command
23
returns its pathName argument. At the time this command is invoked,
24
there must not exist a window named pathName, but pathName's parent
25
must exist. Hv3 is a pure Tcl widget implemented using Tkhtml3 and
26
the excellent mega-widget framework Snit.
28
An [SQ hv3] widget is not a web-browser. If it were to be used as
29
a component in a web-browser application it would represent a single
30
browser frame (or iframe). The API described in this document is
31
not the whole API offered by the snit object ::hv3::hv3. Instead,
32
it is the subset of that API that is expected not to change. No
35
There are two 'objects' involved in using the [SQ hv3] widget. One
36
is the widget itself ([SQ ::hv3::hv3]). The other is the
37
request-handle ([SQ ::hv3::request]). A request-handle is the
38
interface between the hv3 widget and wherever it is getting its
39
data from (i.e. your implementation of http://, https:// etc.).
40
Many users will also wish to understand the Tkhtml3 "node-handle"
41
interface, documented as part of the Tkhtml3 manpage.
43
An [SQ hv3] widget provides the following features on top of the
49
Support for selecting text with the pointer.
51
Support for loading linked images and stylesheets from URIs.
53
Support for HTML forms and submission thereof.
55
Support for CSS configured hover (mouseover) effects.
57
Support for loading a new document by clicking on a hyper-link.
60
The two most important interfaces are the [SQ goto] method and the
61
_-requestcmd_ option. The [SQ goto] method tells the widget to
62
load the document identified by the specified absolute or relative
65
The _-requestcmd_ option must be configured with a callback script that
66
the widget invokes to request the requested document. It is the
67
users responsibility to retrieve the document and pass it back to
68
the widget. If the document contains links to external resources
69
(images or CSS stylesheets), then the widget invokes the
70
_-requestcmd_ script to request these. The _-requestcmd_ callback may
71
choose to implement handling for one or more of http:// URIs,
72
file:// URIs or any other existing or invented URI scheme. See
73
the "Example Usage" section below for an example.
75
[Section Standard Options]
81
[Section Html Options]
82
The following Tkhtml options are exposed as public options of
92
[Section Html Commands]
93
The following Tkhtml commands are exposed as public options of
97
node ? ?-index? _x_ _y_?
100
[Section Widget-Specific Options]
102
[Option enableimages {
103
Boolean option (default true). True for image support, false
104
otherwise. If this option is set to false, then the
105
_-requestcmd_ script will never be invoked to request an
108
[Option isvisitedcmd {
109
If not an empty string, this option specifies a script for
110
the widget to invoke to determine if a hyperlink (<A>)
111
node should be styled with the :link or :visited
112
pseudo-class. The script is invoked with the node handle
113
appended to it. If true is returned, :visited is used,
117
If this option is not set by the user code, then the Hv3
118
widget will be unable to display anything.
120
It should be set to a script that may be invoked by the hv3
121
widget to request a resource required to display a URI
122
requested via the [SQ goto] method. Each time a resource
123
is required, the _-requestcmd_ script is invoked with
124
a single argument appended to it, the name of a request
125
handle object. See section "Request Handles" for details.
128
If this option is not set to an empty string (the default),
129
it should be set to a script that will be invoked each time
130
a hyper-link is clicked or a form submitted in the hv3 widget
131
by the end-user. A single argument is appended to the script
132
before it is evaluated, the Tkhtml3 node-handle for the
133
relevant <FORM> (in the case of form submittal) or
134
<A> (if the end user clicked a hyperlink) node. The
135
script should return the path of an hv3 widget into which
136
the new resource should be loaded. This is useful for
137
implementing browsers that support HTML frames and iframes.
139
If the script returns an empty string the request is
140
abandoned and the new resource never loaded and the
141
form data (if any) not submitted.
143
If the option is set to an empty string the new resource is
144
always loaded into the hv3 widget itself.
147
[Section Widget Command]
148
The [SQ hv3] command creates a new Tcl command whose name is
149
pathName. This command may be used to invoke various operations on
150
the widget as follows:
153
pathName cget _option_
154
Returns the current value of the configuration option given
155
by option. Option may have any of the values accepted by
156
the [SQ hv3] command.
160
pathName configure _?option?_ _?value?_
161
Query or modify the configuration options of the widget. If
162
no option is specified, returns a list describing all of
163
the available options for pathName (see Tk_ConfigureInfo
164
for information on the format of this list). If option is
165
specified with no value, then the command returns a list
166
describing the one named option (this list will be
167
identical to the corresponding sublist of the value
168
returned if no option is specified). If one or more
169
option-value pairs are specified, then the command modifies
170
the given widget option(s) to have the given value(s); in
171
this case the command returns an empty string. Option may
172
have any of the values accepted by the [SQ hv3] command.
177
Load the resource at _uri_ into the widget. If _uri_ is
178
not an absolute URI, it is resolved with respect to
179
the widget's current document URI (or <BASE> element
180
contents, if present).
185
Abandon all pending requests. All request handle objects
186
that are still outstanding are destroyed (it is an error
187
to use such a request handle after calling [SQ stop]).
190
[Section Request Handles]
191
To be useful, the user must provide the hv3 with some way to
192
request resources ((X)HTML documents, CSS stylesheets and binary
193
image files) identified by URI for display. To this end, the
194
user configures a _-requestcmd_ script with the hv3 widget.
195
Each time a resource is required, the _-requestcmd_ script
196
is evaluated with a single argument, a request handle object
197
identifier, appended to it.
199
A request handle object is a snit object. The _-requestcmd_
200
script can query the object to determine the parameters of the
201
request and then invoke object methods to return data and
202
meta data. The key APIs are the _-uri_ option and the
205
Data may be returned asynchronously. That is, it is not necessary
206
to return data from within the _-requestcmd_ evaluation, the
207
request handle may be stored and data returned at some later time.
209
[Subsection Request Handle Options]
212
This option is used by "POST" requests, which may be made by an
213
hv3 widget if the loaded document contains a form and the end-user
214
submits it. For a "GET" request (all other requests, the usual
215
case) it is set to an empty string.
217
The cannonical test to check if a given request is a POST or GET
221
if {[$handle cget -postdata] ne ""} {
222
# This is a POST request.
224
# This is a GET request.
228
For POST requests, this option may be set by the Hv3 widget to
229
contain the Content-Type of the data stored in the _-postdata_
230
option. For example "application/x-www-form-urlencoded".
234
The Hv3 widget sets this option to an empty string before passing
235
the request handle to the user code.
237
The user code may set this option to a list containing data to
238
be handled by the hv3 widget as if it had been returned as the
239
HTTP header for an HTTP request. The list consists of alternating
240
HTTP header-names and values. This is the same format as the
241
"meta" element of the "state array" interface used by Tcl's
242
built-in http package.
244
The Hv3 widget interprets the following HTTP headers:
251
The Hv3 widget sets this option to the expected mime type of the
254
If the user code knows the mime type of the resource being returned,
255
it should set this option before the first invocation of the
256
[SQ append] method. Useful values recognized by the hv3 widget
257
include "text/xhtml" and "image/gif".
260
This option is used by "POST" requests, which may be made by an
261
hv3 widget if the loaded document contains a form and the end-user
264
It contains the data to be posted.
266
[Option requestheader {
267
The Hv3 widget sets this option to a list of HTTP header-names and
268
values to be handled as request parameters for an HTTP request (i.e.
269
the "referrer" header).
271
The user code should not change the value of this option.
274
This option is always set by the Hv3 widget before passing the
275
request handle to the user code. It contains the absolute URI
276
of the resource required by the widget.
278
The user code should not change the value of this option.
281
[Subsection Request Handle Methods]
284
requestHandle append _data_
285
This method should be invoked one or more times to return
286
data to the hv3 widget.
288
The data passed to this method should always be binary data.
289
If the data is actually text data for a document or stylesheet,
290
it's encoding is determined based on either a HTTP header
291
returned via the [SQ header] option, or a <meta>
292
element in the header section of an HTML or XHTML document.
293
If neither of these are present, the assumed encoding is
294
either the document encoding in the case of linked CSS
295
stylesheet, or the value returned by [SQ encoding system] for
296
an HTML or XHTML document.
301
This method should be called after all data has been
302
obtained. The request handle object is deleted by the
303
system from within this call, so the object may not be used
304
after this method has been invoked.
309
[Subsection Custom URI Schemes]
311
The hv3 widget may seem a little unusual at first in that there
312
is no interface to feed data directly from the users script to
313
the widget. Instead, the widget requests the required data by
314
invoking the _-requestcmd_ script. Data is identified by
315
the _-uri_ option of the request handle passed as an argument.
317
The reason for this is that the widget often deals with documents
318
that contain linked resources (external CSS stylesheets or images).
319
The resources are not always known when the user script initiates
320
loading the document. For example, if the following document is
321
to be loaded from URI "http://tkhtml.tcl.tk":
326
<IMG src="image.gif">
331
then the _-requestcmd_ must implement the HTTP protocol. The
335
$hv3 goto http://tkhtml.tcl.tk
338
which causes the _-requestcmd_ script to be invoked with a
339
request handle argument specifying the URI "http://tkhtml.tcl.tk".
341
When the _-requestcmd_ returns the data for the URI
342
"http://tkhtml.tcl.tk", the widget invokes the _-requestcmd_ a
343
second time, with a request handle argument specifying the URI
344
"http://tkhtml.tcl.tk/image.gif". If the document contained links
345
to CSS stylesheets or other images, the _-requestcmd- script would
346
be invoked for each of these also.
348
All this is fine if you are fetching data from http servers, but
349
a little inconvenient if the user script already has the document
350
to display ready in a Tcl variable (or variables). The solution
351
here is to invent a custom URI scheme to use within the
352
application. For example, the following example demonstrates a
353
_-requestcmd_ script that implements the "tclvar:", URI scheme
354
for refering to global Tcl variables.
357
proc tclvar_requestcmd {R} {
358
# Get the URI from the request handle. The URI should look
361
# tclvar:///<global varname>
363
set uri \[$R cget -uri]
365
# Strip "tclvar:///" from the start of the URI.
366
set var \[string range $uri 10 end]
368
# Return the data in the global variable $var to the widget.
370
$R finish \[set $var]
374
And a simple script for using this _-requestcmd_:
379
<LINK rel="stylesheet" href="my_stylesheet">
381
<P>Some red text.</P>
390
pack .hv3 -fill both -expand true
392
.hv3 configure -requestcmd tclvar_requestcmd
393
.hv3 goto tclvar:///my_document
396
Note the complication in the code above - the string "tclvar:///" is
397
found at the start of each URI passed to [SQ tclvar_requestcmd]. This
398
is because Hv3 resolves and escapes all URIs against the base URI
399
of the currently loaded document before passing them to the
400
_-requestcmd_. This means you need to be careful with special
401
characters. If the name of the variable storing the stylesheet
402
document in the above example were _::css::my_stylesheet_, then
406
<LINK rel="stylesheet" href="::css::my_stylesheet">
409
would not work. The string "::css::my_stylesheet" is not a valid
410
relative or absolute URI, so the results of resolving it against
411
the base URI of the document, "tclvar:///my_document", are not
412
defined. The solution is to escape the variable names using URI
413
escapes. The Tkhtml3 package provides the [SQ ::tkhtml::encode]
414
and [SQ ::tkhtml::decode] commands for escaping and unescaping
415
strings, respectively. After modifying the _-requestcmd_ proc
416
to support escaped strings, it looks like this:
419
proc tclvar_requestcmd {R} {
420
# Get the URI from the request handle. The URI should look
423
# tclvar:///<global varname>
425
set uri \[$R cget -uri]
427
# Strip "tclvar:///" from the start of the URI.
428
set var \[::thtml::decode \[string range $uri 10 end]]
430
# Return the data in the global variable $var to the widget.
432
$R finish \[set $var]
436
This could be used with a script like this:
441
<LINK rel="stylesheet" href="%3A%3Acss%3A%3Amy_stylesheet">
443
<P>Some red text.</P>
447
namespace eval ::css {
454
pack .hv3 -fill both -expand true
456
.hv3 configure -requestcmd tclvar_requestcmd
457
.hv3 goto tclvar:///\[::tkhtml::encode my/document]
460
In this case the two invocation of tclvar_requestcmd are made with
461
request handle arguments with the following _-uri_ option values:
464
tclvar:///my%2Fdocument
465
tclvar:///%3A%3Acss%3A%3Amy_stylesheet
468
Other custom URI scheme handlers could retrieve data by evaluating
469
Tcl scripts, querying a database or accessing any other part of the