class Wunderbar::HtmlMarkup
Constants
- HEAD
- HTML5_BLOCK
- VOID
Public Class Methods
flatten?(children)
click to toggle source
# File lib/wunderbar/html-methods.rb, line 420 def self.flatten?(children) # do any of the text nodes need special processing to preserve spacing? flatten = false space = true if children.any? {|child| child.text? and !child.text.strip.empty?} children.each do |child| if child.text? or child.element? unless child.text == '' flatten = true if not space and not child.text =~ /\A\s/ space = (child.text =~ /\s\Z/) end space = true if child.element? and HTML5_BLOCK.include? child.name end end end flatten end
new(scope)
click to toggle source
# File lib/wunderbar/html-methods.rb, line 40 def initialize(scope) @_scope = scope @_x = XmlMarkup.new :scope => scope end
Public Instance Methods
_(text=nil, &block)
click to toggle source
# File lib/wunderbar/html-methods.rb, line 353 def _(text=nil, &block) unless block if text @_x.indented_text! text.to_s end return @_x end children = instance_eval(&block) if String === children ok = defined? Nokogiri if ok and (children.include? '<' or children.include? '&') if defined? Nokogiri::HTML5.fragment doc = Nokogiri::HTML5.fragment(children.to_s) else doc = Nokogiri::HTML.fragment(children.to_s) end children = doc.children.to_a # ignore leading whitespace while not children.empty? and children.first.text? break unless children.first.text.strip.empty? children.shift end # gather up candidate head elements pending_head = [] while not children.empty? and children.first.element? break unless (HEAD+['script']).include? children.first.name pending_head << children.shift end # rebuild head element if any candidates were found unless pending_head.empty? head = Nokogiri::XML::Node.new('head', pending_head.first.document) pending_head.each {|child| head << child} children.unshift head end else return @_x.indented_text! children end elsif children.nil? or Wunderbar::Node === children return children end @_x[*children] end
_!(text)
click to toggle source
# File lib/wunderbar/html-methods.rb, line 349 def _!(text) @_x.text! text.to_s.chomp end
__(text=nil, &block)
click to toggle source
# File lib/wunderbar/html-methods.rb, line 404 def __(text=nil, &block) if text @_x.spaced! @_x.indented_text! text elsif block @_x.spaced! _(&block) else @_x.text! "" end end
_coderay(*args)
click to toggle source
# File lib/wunderbar/coderay.rb, line 7 def _coderay(*args) # allow arguments in any order, disambiguate based on type lang, string, attrs = :ruby, '', {} args.each do |arg| case arg when Symbol; lang = arg when String; string = arg when Hash; attrs = arg end end base = _{ CodeRay.scan(CDATANode.normalize(string), lang).div } # remove wrapping divs while base.length == 1 and base.first.name == 'div' div = base.first.parent.children.pop div.children.each {|child| child.parent = base.first.parent} base.first.parent.children += base.first.children base = div.children end # add attrs provided to pre element if base.length == 1 and base.first.name == 'pre' base.first.attrs.merge! attrs end end
_coffeescript(text)
click to toggle source
# File lib/wunderbar/coffeescript.rb, line 6 def _coffeescript(text) _script CoffeeScript.compile(text) end
_exception(*args)
click to toggle source
Calls superclass method
# File lib/wunderbar/html-methods.rb, line 245 def _exception(*args) exception = args.first if exception.respond_to? :backtrace options = (Hash === args.last)? args.last : {} traceback_class = options.delete(:traceback_class) traceback_style = options.delete(:traceback_style) traceback_style ||= 'background-color:#ff0; margin: 1em 0; ' + 'padding: 1em; border: 4px solid red; border-radius: 1em' text = exception.inspect log_level = options.delete(:log_level) || :error Wunderbar.send log_level, text exception.backtrace.each do |frame| next if Wunderbar::CALLERS_TO_IGNORE.any? {|re| frame =~ re} Wunderbar.send log_level, " #{frame}" text += "\n #{frame}" end if traceback_class tag! :pre, text, :class=>traceback_class else tag! :pre, text, :style=>traceback_style end else super end end
_head(*args, &block)
click to toggle source
# File lib/wunderbar/html-methods.rb, line 273 def _head(*args, &block) tag!('head', *args) do tag! :meta, :charset => 'utf-8' block.call if block end end
_html(*args, &block)
click to toggle source
# File lib/wunderbar/html-methods.rb, line 167 def _html(*args, &block) html(*args, &block) end
_markdown(string)
click to toggle source
# File lib/wunderbar/markdown.rb, line 7 def _markdown(string) _{ Kramdown::Document.new(CDATANode.normalize(string)).to_html } end
_math(*args, &block)
click to toggle source
# File lib/wunderbar/html-methods.rb, line 297 def _math(*args, &block) args << {} if args.empty? if Hash === args.first args.first['xmlns'] = 'http://www.w3.org/1998/Math/MathML' end proxiable_tag! :math, *args, &block end
_ol(*args, &block)
click to toggle source
Calls superclass method
# File lib/wunderbar/html-methods.rb, line 327 def _ol(*args, &block) return super if block iterable = args.first.respond_to? :each if iterable and (args.length > 1 or not args.first.respond_to? :to_hash) list = args.shift tag!(:ol, *args) {list.each {|arg| _li arg }} else super end end
_p(*args, &block)
click to toggle source
Calls superclass method
# File lib/wunderbar/html-methods.rb, line 280 def _p(*args, &block) if args.length >= 1 and String === args.first and args.first.include? "\n" text = args.shift tag! :p, *args do @_x.indented_text! text end else super end end
_pre(*args, &block)
click to toggle source
# File lib/wunderbar/html-methods.rb, line 305 def _pre(*args, &block) args.first.chomp! if String === args.first and args.first.end_with? "\n" @_x.compact! do proxiable_tag! :pre, PreformattedNode, *args, &block end end
_script(*args, &block)
click to toggle source
Calls superclass method
Wunderbar::Overridable#_script
# File lib/wunderbar/script.rb, line 25 def _script(*args, &block) if block node = super(*args, &nil).node? node.block = block if binding.respond_to? :of_caller # provided by require 'binding_of_caller' node.binding = binding.of_caller(1) else node.binding = binding end node else super end end
_svg(*args, &block)
click to toggle source
# File lib/wunderbar/html-methods.rb, line 291 def _svg(*args, &block) args << {} if args.empty? args.first['xmlns'] = 'http://www.w3.org/2000/svg' if Hash === args.first proxiable_tag! :svg, *args, &block end
_textarea(*args, &block)
click to toggle source
# File lib/wunderbar/html-methods.rb, line 312 def _textarea(*args, &block) proxiable_tag! :textarea, PreformattedNode, *args, &block end
_tr(*args, &block)
click to toggle source
Calls superclass method
# File lib/wunderbar/html-methods.rb, line 338 def _tr(*args, &block) return super if block iterable = args.first.respond_to? :each if iterable and (args.length > 1 or not args.first.respond_to? :to_hash) list = args.shift tag!(:tr, *args) {list.each {|arg| _td arg }} else super end end
_ul(*args, &block)
click to toggle source
Calls superclass method
# File lib/wunderbar/html-methods.rb, line 316 def _ul(*args, &block) return super if block iterable = args.first.respond_to? :each if iterable and (args.length > 1 or not args.first.respond_to? :to_hash) list = args.shift.dup tag!(:ul, *args) {list.each {|arg| _li arg }} else super end end
`(input)
click to toggle source
# File lib/wunderbar/backtick.rb, line 7 def `(input) Ruby2JS.convert(input) end
clear!()
click to toggle source
# File lib/wunderbar/html-methods.rb, line 416 def clear! @_x.clear! end
html(*args, &block)
click to toggle source
# File lib/wunderbar/html-methods.rb, line 45 def html(*args, &block) # default namespace args << {} if args.empty? if Hash === args.first args.first[:xmlns] ||= 'http://www.w3.org/1999/xhtml' @_x._width = args.first.delete(:_width).to_i if args.first[:_width] end bom = "\ufeff" title = args.shift if String === args.first @_x.declare! :DOCTYPE, :html html = tag! :html, *args do set_variables_from_params _title title if title instance_eval(&block) end pending_head = [] pending_body = [] head = nil body = nil html.children.each do |child| next unless child if String === child pending_body << child elsif child.name == 'head' head = child elsif child.name == 'body' body = child elsif HEAD.include? child.name pending_head << child elsif child.name == 'script' if pending_body.empty? pending_head << child else pending_body << child end else pending_body << child end end if pending_body.length == 1 and pending_body[0].name.to_s == 'frameset' body = pending_body.shift end @_x.instance_eval {@node = html} head = _head_ if not head body = _body nil if not body html.children.unshift(head.parent.children.delete(head)) html.children.push(body.parent.children.delete(body)) head.parent = body.parent = html head.children.compact! body.children.compact! [ [pending_head, head], [pending_body, body] ].each do |list, node| list.each do |child| html.children.delete(child) node.add_child child end end if not head.at('title') h1 = body.at('h1') head.add_child Node.new('title', h1.text) if h1 and h1.text end prefix = nil base = head.children.index(head.at('base')) if base head.children.insert 1, head.children.delete_at(base) if base > 1 # compute relative path from base to the current working directory # # current working directory can be something like /a/b/c/d/e; # document root may be /a/b, document base may be c/ and the href # may be d/. In such a case, a prefix of '..' would be in order. # # Note: there are three basic use cases that need to be handled: # # * Native Rack server (typically puma). Document base is defined # by the application. # # * Passenger server (typically Apache httpd). Document base may # be relative to the PassengerBaseURI. # # * Proxied Rack server. Document base may be relate to the # HTTP_X_WUNDERBAR_BASE # cwd = File.realpath(Dir.pwd) base = @_scope.env['DOCUMENT_ROOT'] if @_scope.env.respond_to? :[] base ||= cwd href = (head.children[1].attrs[:href] || '') _base = @_scope.env['HTTP_X_WUNDERBAR_BASE'] || @_scope.env['SCRIPT_NAME'] if _base and not _base.empty? and href.start_with? _base href = href[_base.length-1..-1] end base += href base += 'index.html' if base.end_with? '/' base = Pathname.new(base).parent prefix = Pathname.new(cwd).relative_path_from(base).to_s + '/' prefix = nil unless prefix.start_with? '..' elsif @_scope.respond_to? :env and @_scope.env['PATH_INFO'].to_s.length>1 prefix = '../' * (@_scope.env['PATH_INFO'].count('/') - 1) end Asset.declarations(html, prefix) title = head.children.index do |child| child.respond_to? :name and child.name == 'title' end if title and title > 1 head.children.insert 1, head.children.delete_at(title) end bom + @_x.target! end
method_missing(name, *args, &block)
click to toggle source
# File lib/wunderbar/html-methods.rb, line 171 def method_missing(name, *args, &block) if name =~ /^_(\w+)(!|\?|)$/ name, flag = $1, $2 elsif @_scope and @_scope.respond_to? name return @_scope.__send__ name, *args, &block else err = NameError.new "undefined local variable or method `#{name}'", name err.set_backtrace caller raise err end if name.sub!(/_$/,'') @_x.spaced! if flag != '!' and respond_to? "_#{name}" return __send__ "_#{name}#{flag}", *args, &block end end name = name.to_s.gsub('_', '-') if flag == '!' @_x.compact! { tag! name, *args, &block } elsif flag == '?' # capture exceptions, produce filtered tracebacks tag!(name, *args) do begin block.call rescue ::Exception => exception options = (Hash === args.last)? args.last : {} options[:log_level] = 'warn' _exception exception, options end end elsif Wunderbar.templates.include? name x = self.class.new({}) instance_variables.each do |ivar| x.instance_variable_set ivar, instance_variable_get(ivar) end if Hash === args.last args.last.each do |attrname, value| x.instance_variable_set "@#{attrname}", value end end save_yield = Wunderbar.templates['yield'] begin Wunderbar.templates['yield'] = block if block x.instance_eval(&Wunderbar.templates[name]) ensure Wunderbar.templates['yield'] = save_yield Wunderbar.templates.delete 'yield' unless save_yield end else tag! name, *args, &block end end
proxiable_tag!(name, *args, &block)
click to toggle source
# File lib/wunderbar/html-methods.rb, line 236 def proxiable_tag!(name, *args, &block) node = @_x.tag! name, *args, &block if !block CssProxy.new(self, node) else node end end
tag!(name, *args, &block)
click to toggle source
# File lib/wunderbar/html-methods.rb, line 227 def tag!(name, *args, &block) node = @_x.tag! name, *args, &block if !block and args.empty? CssProxy.new(self, node) else node end end