class Gara::Html5Emitter
Public Class Methods
debug(msg)
click to toggle source
# File lib/gara/html5_emitter.rb, line 31 def self.debug(msg) puts msg if ENV['DEBUG'] end
new()
click to toggle source
# File lib/gara/html5_emitter.rb, line 35 def initialize @doc = Nokogiri::HTML::DocumentFragment.parse("") @builder = Nokogiri::HTML::Builder.with(@doc) end
Public Instance Methods
add_methods_to(context)
click to toggle source
Calls superclass method
# File lib/gara/html5_emitter.rb, line 40 def add_methods_to(context) builder = @builder # Open the eigenclass of the passed in context eigenclass_of_context = class << context ; self ; end # add procs as methods for each html5 tag to the context _proc_hash(@builder).each do |method_name, proc| eigenclass_of_context.send(:define_method, method_name, &proc) end # provide a self << on context that delegates to the nokogiri builder # so that we can insert the results of rails helpers eigenclass_of_context.send(:define_method, :<<) do |string| builder << string if string.kind_of?(String) end # override/wrap helper methods that presumably return strings # so that they insert their markup into the nokogiri builder _helper_methods_from(eigenclass_of_context).each do |method| eigenclass_of_context.class_eval do define_method method do |*args, &block_for_helper| result = super(*args, &block_for_helper) if result.kind_of? String # uncomment to see if we are inapproriately wrapping some helper # puts "#{method} returned: #{result}" self << result else result end end end end end
emit()
click to toggle source
# File lib/gara/html5_emitter.rb, line 75 def emit nodes = @doc.children if nodes.length.eql?(1) && nodes.first.name.eql?("html") # necessary to include doctype - TODO: avoid calling to_html twice Nokogiri::HTML::Document.parse( @doc.to_html ).to_xhtml(indent: 2) else @doc.to_html end end
Private Instance Methods
_helper_methods_from(eigenclass_of_context)
click to toggle source
we only want to wrap helpers that return strings which should be inserted as markup into the document so we identify which methods should NOT be wrapped here and exclude them
# File lib/gara/html5_emitter.rb, line 89 def _helper_methods_from(eigenclass_of_context) helpers = ((eigenclass_of_context.instance_methods - HTML5_TAGS) - Object.instance_methods) - [:tag, :_layout_for, :path_to_, :form_authenticity_token, :content_tag] helpers.reject do |method| method.to_s.match(/(_\d+_\d+$)|(lookup_context)|(<<)|(_url$)|(_path$)|(compute_.*$)|(asset)|(path_to_.*)/) end end
_proc_hash(nokogiri)
click to toggle source
# File lib/gara/html5_emitter.rb, line 97 def _proc_hash(nokogiri) proc_hash = HTML5_TAGS.inject({}) do |hash, tag| # nokogiri's builder is now a local binding so we can access it # from inside an instance of Context (procs preserve local bindings) builder = nokogiri hash[tag] = -> (*args, &block) { result = nil begin builder.public_send(tag, *args) do # public send is necessary due to send accessing private method Kernel#p unless block.nil? result = block.call # necessary to make sure block executes in Context not Builder if result.kind_of?(String) self << result # add any string returned to the document so that: p { "works" } yields "<p>works</p>" else result end end end rescue Exception => e binding.pry end } hash end end