Table of Contents

  1. Name
  2. Synopsis
  3. Widget-Specific Options
  4. Description
  5. Widget Command
  6. Node Command
  7. Replaced Objects
  8. Image Loading
  9. Stylesheet Loading
  10. Incremental Document Loading
  11. HTML Specific Processing
  12. References

tkhtml

 ./images/wallpaper_green.png wallpaper_green  ./images/wallpaper_red.png wallpaper_red  ./images/wallpaper_yellow.png wallpaper_yellow

Name

tkhtml - Widget to render html documents.

Synopsis

html pathName ?options?

Standard Options

-exportselection
-height
-width
-xscrollcommand   
-xscrollincrement
-yscrollcommand   
-yscrollincrement

Widget-Specific Options

Description

The [html] command creates a new window (given by the pathName argument) and makes it into an html widget. The html command returns its pathName argument. At the time this command is invoked, there must not exist a window named pathName, but pathName's parent must exist.

Widget Command

The [html] command creates a new Tcl command whose name is pathName. This command may be used to invoke various operations on the widget as follows:

Node Command

There are several interfaces by which a script can obtain a "node handle". Each node handle is a Tcl command that may be used to access the document node that it represents. A node handle is valid from the time it is obtained until the next call to [pathName reset]. The node handle may be used to query and manipulate the document node via the following subcommands:

Replaced Objects

Replaced objects are html document nodes that are replaced by either a Tk image or a Tk window. For example <IMG> or <INPUT> tags. To implement replaced objects in Tkhtml the user supplies the widget with a Tcl script to create and return the name of the image or window, and the widget maps, manages and eventually destroys the image or window.

TODO: Finish this section.

Image Loading

As well as for replaced objects, images are used in several other contexts in CSS formatted documents, for example as list markers or backgrounds. If the -imagecmd option is not set to an empty string (the default), then each time an image URI is encountered in the document, it is appended to the -imagecmd script and the resulting list evaluated.

The command should return either an empty string, the name of a Tk image, or a list of exactly two elements, the name of a Tk image and a script. If the result is an empty string, then no image can be displayed. If the result is a Tk image name, then the image is displayed in the widget. When the image is no longer required, it is deleted. If the result of the command is a list containing a Tk image name and a script, then instead of deleting the image when it is no longer required, the script is evaluated.

Stylesheet Loading

Apart from the default stylesheet that is always loaded (see the description of the -defaultstyle option above), a script may configure the widget with extra style information in the form of CSS stylesheet documents. Complete stylesheet documents (it is not possible to incrementally parse stylesheets as it is HTML document files) are passed to the widget using the [pathName style] command.

As well as any stylesheets specified by the application, stylesheets may be included in HTML documents by document authors in several ways:

# Implementations of application callbacks to load
# stylesheets from the various sources enumerated above.
# ".html" is the name of the applications tkhtml widget.
# The variable $document contains an entire HTML document.
# The pseudo-code <LOAD URI CONTENTS> is used to indicate
# code to load and return the content located at $URI.


proc script_handler {tagcontents} {
    incr ::stylecount
    set id "author.[format %.4d $::stylecount]"
    set handler "import_handler $id"
    .html style -id $id.9999 -importcmd $handler $tagcontents
}


proc link_handler {node} {
    if {[node attr rel] == "stylesheet"} {
        set URI [node attr href]
        set stylesheet [<LOAD URI CONTENTS>]

        incr ::stylecount
        set id "author.[format %.4d $::stylecount]"
        set handler "import_handler $id"
        .html style -id $id.9999 -importcmd $handler $stylesheet
    }
}


proc import_handler {parentid URI} {
    set stylesheet [<LOAD URI CONTENTS>]

    incr ::stylecount
    set id "$parentid.[format %.4d $::stylecount]"
    set handler "import_handler $id"
    .html style -id $id.9999 -importcmd $handler $stylesheet
}


.html handler script style script_handler
.html handler node link link_handler

set ::stylecount 0

.html parse -final $document

The complicated part of the example code above is the generation of stylesheet-ids, the values passed to the -id option of the [.html style] command. Stylesheet-ids are used to determine the precedence of each stylesheet passed to the widget, and the role it plays in the CSS cascade algorithm used to assign properties to document nodes. The first part of each stylesheet-id, which must be either "user", "author" or "agent", determines the role the stylesheet plays in the cascade algorithm. In general, author stylesheets take precedence over user stylesheets which take precedence over agent stylesheets. An author stylesheet is one supplied or linked by the author of the document. A user stylesheet is supplied by the user of the viewing application, possibly by configuring a preferences dialog or similar. An agent stylesheet is supplied by the viewing application, for example the default stylesheet configured using the -defaultstyle option.

The stylesheet id mechanism is designed so that the cascade can be correctly implemented even when the various stylesheets are passed to the widget asynchronously and out of order (as may be the case if they are being downloaded from a network server or servers).

#
# Contents of HTML document
#

<html><head>
    <link rel="stylesheet" href="A.css">
    <style>
        @import uri("B.css")
        @import uri("C.css")
        ... rules ...
    </style>
    <link rel="stylesheet" href="D.css">
... remainder of document ...

#
# Contents of B.css
#



@import "E.css"
... rules ...

In the example above, the stylesheet documents A.css, B.css, C.css, D.css, E.css and the stylesheet embedded in the <style> tag are all author stylesheets. CSS states that the relative precedences of the stylesheets in this case is governed by the following rules:

Applying the above two rules to the example documents indicates that the order of the stylesheets from least to most important is: A.css, E.css, B.css, C.css, embedded <stylesheet>, D.css. For the widget to implement the cascade correctly, the stylesheet-ids passed to the six [pathName style] commands must sort lexigraphically in the same order as the stylesheet precedence determined by the above two rules. The example code above shows one approach to this. Using the example code, stylesheets would be associated with stylesheet-ids as follows:

Stylesheet         Stylesheet-id
-------------------------------
A.css              author.0001.9999
<embedded style>   author.0002.9999
B.css              author.0002.0003.9999
E.css              author.0002.0003.0004.9999
C.css              author.0002.0005.9999
D.css              author.0006.9999

Entries are specified in the above table in the order in which the calls to [html style] would be made. Of course, the example code fails if 10000 or more individual stylesheet documents are loaded. More inventive solutions that avoid this kind of limitation are possible.

Other factors, namely rule specificity and the !IMPORTANT directive are involved in determining the precedence of individual stylesheet rules. These are completely encapsulated by the widget, so are not described here. For complete details of the CSS cascade algorithm, refer to [1].

Incremental Document Loading

This section discusses the widget API in the context of loading a document incrementally, for example from a network server. We assume both remote stylesheets and image files are retrieved as well as the document.

Before a new document (html file) is loaded, any previous document should be purged from memory using the [pathName reset] command. The portion of the new document that is read is passed to the widget using the [pathName parse] command. As new chunks of the document are downloaded, they should also be passed to [pathName parse]. When the final chunk of the document file is passed to the [pathName parse] command the -final option should be specified. This ensures node-handler callbacks (see the description of the [pathName handler] command above) are made for tags that are closed implicitly by the end of the document.

The widget display is updated in an idle callback scheduled after each invocation of the [pathName parse] command.

HTML Specific Processing

TODO: Detail implicit opening and closing tag rules here.

References

[1] CSS2 specification.

tkhtml (n) - Table Of Contents

Name Synopsis Standard Options Widget-Specific Options Description Widget Command Node Command Replaced Objects Image Loading Stylesheet Loading Incremental Document Loading HTML Specific Processing References