module Temple module HTML # @api public class Fast < Filter DOCTYPES = { xml: { '1.1' => '', '5' => '', 'html' => '', 'strict' => '', 'frameset' => '', 'mobile' => '', 'basic' => '', 'transitional' => '', 'svg' => '' }, html: { '5' => '', 'html' => '', 'strict' => '', 'frameset' => '', 'transitional' => '' } } DOCTYPES[:xhtml] = DOCTYPES[:xml] DOCTYPES.freeze # See http://www.w3.org/html/wg/drafts/html/master/single-page.html#void-elements HTML_VOID_ELEMENTS = %w[area base br col embed hr img input keygen link menuitem meta param source track wbr] define_options format: :xhtml, attr_quote: '"', autoclose: HTML_VOID_ELEMENTS, js_wrapper: nil def initialize(opts = {}) super @format = options[:format] unless [:xhtml, :html, :xml].include?(@format) if @format == :html4 || @format == :html5 warn "Format #{@format.inspect} is deprecated, use :html" @format = :html else raise ArgumentError, "Invalid format #{@format.inspect}" end end wrapper = options[:js_wrapper] wrapper = @format == :xml || @format == :xhtml ? :cdata : :comment if wrapper == :guess @js_wrapper = case wrapper when :comment [ "" ] when :cdata [ "\n//\n" ] when :both [ "" ] when nil when Array wrapper else raise ArgumentError, "Invalid JavaScript wrapper #{wrapper.inspect}" end end def on_html_doctype(type) type = type.to_s.downcase if type =~ /^xml(\s+(.+))?$/ raise(FilterError, 'Invalid xml directive in html mode') if @format == :html w = options[:attr_quote] str = "" else str = DOCTYPES[@format][type] || raise(FilterError, "Invalid doctype #{type}") end [:static, str] end def on_html_comment(content) [:multi, [:static, '']] end def on_html_condcomment(condition, content) on_html_comment [:multi, [:static, "[#{condition}]>"], content, [:static, ''] result << compile(content) if content result << [:static, ""] if !closed result end def on_html_attrs(*attrs) [:multi, *attrs.map {|attr| compile(attr) }] end def on_html_attr(name, value) if @format == :html && empty_exp?(value) [:static, " #{name}"] else [:multi, [:static, " #{name}=#{options[:attr_quote]}"], compile(value), [:static, options[:attr_quote]]] end end def on_html_js(content) if @js_wrapper [:multi, [:static, @js_wrapper.first], compile(content), [:static, @js_wrapper.last]] else compile(content) end end end end end