Version 0 of snitDom

Updated 2005-02-03 11:35:37 by DDG

Motivation

tdom is much faster than the tcl-only implementation TclDOM. The usage syntax for both APIs is very different. The idea is to adjust the syntax of TclDOM that it can be used as a dropin replacement for tdom if the latter is not available for a certain platform. So code like the following can be written.

  proc createHTML {} {
        set text "Sample page"
        set doc [dom createDocument html]
        set root [$doc documentElement]
        set head [$doc createElement head]

        set title [$doc createElement title]
        $title appendChild [$doc createTextNode "$text"] 
        $root appendChild $head
        $head appendChild $title
        $root appendChild [$doc createElement body]
        foreach style {jsComponents.css dg-mpimg.css} {
            set link [$doc createElement link]
            $link setAttribute rel stylesheet
            $link setAttribute text text/css
            $link setAttribute href /css/$style
            $head appendChild $link
        }
        puts [$doc asHTML]
    }

    catch {package require tdom}
    if {[info commands dom] eq "dom"} {
        puts "Output via tdom"
    } else {
        puts "tdom not supported on this platform"
        puts "falling back to TclDOM
        snitDom dom
        puts "Output via tcl::dom snitDom"
    }
    createHTML

TclDOM changes

TclDOM is missing some node/element commands so I was adding them into the source code of dom.tcl. Here comes the diff:

 $ diff tdom0.8.1.vfs/lib/tcldom3.0/dom.tcl /d/tcl-lib/tcldom3.0/dom.tcl                                                                                 
 1211,1249d1210                                                                                                                                          
 <         *stChild {                                                                                                                                    
 <             # firstChild or lastChild                                                                                                                 
 <             set result [[dom::tcl::node cget $token -$method]]                                                                                          
 <       }                                                                                                                                               
 <         *Sibling {                                                                                                                                    
 <             # previousSibling or nextSibling                                                                                                          
 <             set result [[dom::tcl::node cget $token -$method]]                                                                                          
 <         }                                                                                                                                             
 <         hasAttribute {                                                                                                                                
 <             if {[[dom::element getAttribute $token [[lindex $args 0]]]] eq ""} {                                                                          
 <                 set result false                                                                                                                      
 <             } else {                                                                                                                                  
 <                 set result true                                                                                                                       
 <             }                                                                                                                                         
 <         }                                                                                                                                             
 <         *Attribute {                                                                                                                                  
 <             switch $node(node:nodeType) {                                                                                                             
 <                 textNode {}                                                                                                                           
 <                 default {                                                                                                                             
 <                     if {[[llength $args]] == 1} {                                                                                                       
 <                         set result [[dom::element $method $token [[lindex $args                                         0]]]]                             
 <                     } else {                                                                                                                          
 <                         set result [[dom::element $method $token [[lindex $args                                         0]] [[lindex $args 1]]]]            
 <                     }                                                                                                                                 
 <                 }                                                                                                                                     
 <             }                                                                                                                                         
 <         }                                                                                                                                             
 <         selectNodes {                                                                                                                                 
 <             switch $node(node:nodeType) {                                                                                                             
 <                 textNode {}                                                                                                                           
 <                 default {                                                                                                                             
 <                     if {[[llength $args]] == 1} {                                                                                                       
 <                         set result [[dom::selectNode $token [[lindex $args 0]]]]                                                                          
 <                     } else {                                                                                                                          
 <                         set result [[dom::selectNode $token [[lindex $args 0]] [[l                                        index $args 1]] [[lindex $args 2]]]]
 <                     }                                                                                                                                 
 <                 }                                                                                                                                     
 <             }                                                                                                                                         
 <         }                                                                                                                                             
 3005,3006c2966,2967                                                                                                                                     
 <         # dgroth fixes bad browser behaviour with <div foo='bar'/> tags                                                                               
 <       append result "></$nsPrefix$node(node:localName)>$newline"                                                                                      
 ---                                                                                                                                                     
 >                                                                                                                                                       
 >       append result />$newline