# Author:: Nicolas Pouillard . # Copyright:: Copyright (c) 2005 Uttk Team. All rights reserved. # License:: LGPL # Revision:: $Id: /w/fey/uttk/trunk/lib/uttk/dumpers/Html.rb 21970 2006-02-19T22:15:36.271512Z pouillar $ require 'stringio' HtmlEncode.import! module Uttk module Dumpers # # Use me at least with the Compact filter: # Compact: [NodeCut: [!skip ^contents$, [Html: [log.html]]]] # class Html < Dumper include Concrete cattr_reader :base_url @@base_url = 'http://api.uttk.org/' # Use this one when you have made changes in lib/www # @@base_url = "file://#{Uttk.dir.parent.expand_path}/www/" class XmlMarkup < Builder::XmlMarkup #:nodoc: def initialize ( *a, &b ) @self = nil super end def itext! ( str ) _indent text! str.to_s.chomp _newline end alias_method :html!, :<< def ihtml! ( str ) _indent self << str.to_s.chomp _newline end def expand_and_collapse ( type, name ) td do a :onClick => "uttk_expand_all(#{type});" do itext! "Expand all #{name}" end end td do a :onClick => "uttk_collapse_all(#{type});" do itext! "Collapse all #{name}" end end end end class BaseNode # :nodoc: attr_reader :father, :name, :status, :id, :contents, :state @@template_images = Html.base_url + 'images/%%%IMAGE_SPLIT%%%triangle.gif' def initialize ( h ) @father, @status, @id = h[:father], h[:status], h[:id] @name, @contents, @state = h[:name], h[:contents], h[:state] end def unquote ( s ) s.gsub('"', '') end def html @status ||= '' x = XmlMarkup.new x.div :class => self.class.name.demodulize.underscore do x.table :class => 'title', :id => unquote(status).sub(/\(.+\)/, '') do x.tr do if state == 2 x.td { x.text!(name.to_s + ': ') } x.td { x.pre clean_yaml_str(contents), :class => 'attribute_alone' } else x.td :width => '11px', :onClick => "uttk_toggle_state(#{id.gsub('"', "'")})" do x.img :src => @@template_images end x.td { x.text!(name.to_s) } x.td(:width => '20px') { x.text!(unquote(status).gsub('NONE', '')) } end end end end result = x.target! raise unless result =~ /<\/div>\Z/ result.sub!(/<\/div>\Z/, '') result.split('%%%IMAGE_SPLIT%%%').map do |x| x.dump end.join(', ') end def clean_yaml_str ( anObject ) str = '' io = StringIO.new str log = Logger.new(Dumpers::Yaml.new(io)) log << anObject log.close io.close str.sub!(/^---\s*/, '') str.chomp! str end private :clean_yaml_str end class Node < BaseNode # :nodoc: def to_html_uttk_js ( status_h ) @status = status_h[@status] "uttk_add_node(#@id, #@father, #@state, #{html});" end end class Leaf < BaseNode # :nodoc: def to_html_uttk_js ( status_h ) "uttk_add_leaf(#@id, #@father, #@state, #{html}, #{html_contents});" end def html_contents return '""' if state == 2 x = XmlMarkup.new x.table :class => 'attribute' do contents.each do |k, v| x.tr do x.td "#{k}:", :class => 'key' x.td :class => 'value' do x.pre clean_yaml_str(v), :class => 'attribute' end end end end x.target!.dump end end def initialize ( *a, &b ) @uttk_js = base_url + 'javascripts/uttk.js' @uttk_css = base_url + 'stylesheets/uttk.css' super reset end def reset @current_ids = Hash.new(0) @ids = {} @ids[:node] = { '/' => 'null' } @elts = [] @status = Hash.new('"NONE"') @x = Builder::XmlMarkup.new(:target => self, :indent => 2) end protected :reset def new_node ( path, node ) super father = id_of :node, path path << node id = id_of :node, path path << :status status = id_of :status, path @elts << Node.new(:father => father, :name => node.segment, :id => id, :status => status, :state => 1) end protected :new_node def new_leaf ( path, leaf ) super if path.last.segment == :status @status[id_of(:status, path)] = leaf @elts.pop else father = id_of :node, path path << leaf id = id_of :leaf, path contents = leaf n = @elts.pop father, leaf, id, status = n.father, n.name, n.id, n.status state, status = 0, '' if contents.is_a? Hash status = contents[:status] [:status].each do |k| contents.delete k if contents.has_key? k end else state = 2 end @elts << Leaf.new(:father => father, :id => id, :name => leaf, :status => status, :state => state, :contents => contents) end end protected :new_leaf def close super x = XmlMarkup.new(:indent => 2, :target => self) x.html do x.head do x.script '', :language => 'javascript', :src => @uttk_js x.style :type => 'text/css' do x.itext! "@import url('#@uttk_css');" end x.script :language => 'javascript' do @elts.each do |elt| x << elt.to_html_uttk_js(@status) << "\n" end end end x.body :onLoad => 'uttk_main()' do x.table :class => 'uttk_infos' do x.tr :class => 'uttk_infos_box' do x.expand_and_collapse 'null', '' x.expand_and_collapse "'node'", 'nodes' x.expand_and_collapse "'leaf'", 'leaves' end end x.div '', :id => 'uttk_contents' end end reset end protected :close def id_of ( prefix, path ) path = path.inspect @ids[prefix] ||= {} result = @ids[prefix][path] if result.nil? result = @ids[prefix][path] = new_id(prefix) end result end protected :id_of def new_id ( prefix ) id = "#{prefix}#{@current_ids[prefix]}" @current_ids[prefix] += 1 id.dump end protected :new_id def self.clean_js_str ( str ) res = str.to_s.html_encode.dump res.gsub!(/([^\\])\\n/, '\1
\n') res end end # class Html end # module Dumpers end # module Uttk