# encoding: utf-8 module Watir module HTML class Generator IGNORED_ATTRIBUTES = %w(cells elements hash rows span text) def generate(spec_url, io = StringIO.new) @spec_url, @io = spec_url, io extract_spec cleanup_spec write_header write_class_defs write_container_methods write_footer io end private def generator @generator ||= WebIDL::Generator.new(visitor) end def visitor @visitor ||= Visitor.new end def extractor @extractor ||= SpecExtractor.new(@spec_url) end def extract_spec @tag2interfaces = extractor.process @sorted_interfaces = extractor.sorted_interfaces if extractor.errors.any? raise "error extracting spec: #{extractor.errors.join("\n")}" end end def cleanup_spec # ignore the link element for now @tag2interfaces.delete("link") @sorted_interfaces.reject! { |intf| intf.name == "HTMLLinkElement" } # frame is implemented manually, see https://github.com/watir/watir-webdriver/issues/204 @sorted_interfaces.reject! { |intf| intf.name == "HTMLFrameElement" } # cleanup attributes @sorted_interfaces.each do |intf| intf.members.delete_if { |member| IGNORED_ATTRIBUTES.include?(member.name) } end end def write_header @io.puts "# Autogenerated from the HTML5 specification. Edits may be lost." @io.puts "module Watir" end def write_class_defs @sorted_interfaces.each do |interface| interface = generator.generate(interface) unless interface.empty? interface.gsub!(/^\s+\n/, '') # remove empty lines @io.puts indent(interface) end end end def write_container_methods @io.puts "\n\n" @io.puts indent("module Container") @tag2interfaces.sort.each do |tag, interfaces| raise "multiple interfaces for tag #{tag.inspect}" unless interfaces.map { |e| e.name }.uniq.size == 1 tag_string = tag.inspect singular = Util.paramify(tag) plural = singular.pluralize element_class = Util.classify(interfaces.first.name) collection_class = "#{element_class}Collection" # visitor.visit_tag(tag, interfaces.first.name) !? @io.puts indent(<<-CODE, 3) # # @return [#{element_class}] # def #{singular}(*args) #{element_class}.new(self, extract_selector(args).merge(:tag_name => #{tag_string})) end # # @return [#{collection_class}] # def #{plural}(*args) #{collection_class}.new(self, extract_selector(args).merge(:tag_name => #{tag_string})) end Watir.tag_to_class[#{tag.to_sym.inspect}] = #{element_class} CODE end @io.puts indent("end # Container") end def write_footer @io.puts "end # Watir" end def indent(code, indent = 1) indent_string = " " * indent code.split("\n").map { |line| line.empty? ? line : indent_string + line }.join("\n") end end # Generator end # HTML5 end # Watir