Search code examples
domtcltdom

Wrapping and unwrapping HTML content in tDOM


Would you please tell me if these are correct methods of wrapping selections in a new tag and unwrapping the contents of a tag "into" the parent at the same node location? They appear to work in my HTML content but would like to know if this is the correct approach.

Also, when a child node is replaced, is the replaced child node released from memory or should that be coded?

Thank you.

proc wrap {path tag} {
  foreach item [$::doc selectNodes $path] {
    set wrapper [$::doc createElement $tag]
    # This fails if $item has more than one child node.
    # $wrapper appendFromList [[$item childNodes] asList]
    foreach child [$item childNodes] {
      $wrapper appendChild $child
    }
    [$item parentNode] replaceChild $wrapper $item
  }
}

proc unwrap {path} {
  foreach item [$::doc selectNodes $path] {
    foreach child [$item childNodes] {
      [$item parentNode] insertBefore $child $item
    }
    $item delete
  }
}

Solution

  • Your unwrap implementation looks good to me, but does replaceChild really give you a wrapper element?

    I'd expect wrap to work like:

    proc wrap {path tag} {
      set els [$::doc selectNodes $path]
      if {[llength $els]} {
        set el [lindex $els 0]
        set wrapper [$::doc createElement $tag]
        [$el parentNode] insertBefore $wrapper $el
        foreach el $els {
          $wrapper appendChild $el
        }
      }
    }
    

    Some more remarks:

    • Maybe pass around the document explicitly, rather than refer to a globally scoped variable ::doc all over the place?
    • Maybe return the wrapper element as a return value of wrap, or the empty string to signal a no-match?