class JsMenuBuilder

Constants

ACCORDION_CSS
ACCORDION_JS
FIXED_MENU_CSS
FIXED_MENU_JS
FULL_PAGE_TABS_CSS
FULL_PAGE_TABS_JS
TABS_CSS
TABS_JS
VERTICAL_MENU_CSS
VERTICAL_MENU_JS

Attributes

css[R]
html[R]
js[R]

Public Class Methods

new(unknown=nil, options={}) click to toggle source
# File lib/jsmenubuilder.rb, line 379
def initialize(unknown=nil, options={})
  
  @debug = options[:debug]
  puts 'options: ' + options.inspect if @debug    
  
  if unknown.is_a? Symbol
    type = unknown.to_sym
    
  elsif unknown.is_a? String then
    
    s, _ = RXFHelper.read unknown
    if s =~ /^<tags/ then
      options = parse_xml(s)
      type = options.keys.first
    else
      type = unknown.to_sym
    end

  elsif unknown.is_a? Hash
    options = unknown
  end    

  @types = %i(tabs full_page_tabs accordion sticky_navbar 
                    vertical_menu fixed_menu breadcrumb)
  
  build(type, options) if type

end

Public Instance Methods

import(xml) click to toggle source
# File lib/jsmenubuilder.rb, line 408
def import(xml)
  
  puts 'inside import'.info if @debug
  doc = Rexle.new(xml)
  type = doc.root.attributes[:mode]
  
  type = if type == 'fullpage' then
  'full_page_tabs'
  elsif type.nil?
    doc.root.name unless type
  end
  
  tabs = doc.root.xpath('tab').inject({}) do |r, tab|
    r.merge(tab.attributes[:title] => tab.children.join.strip)
  end
  
  e = doc.root.element('tab[@mode="active"]')
  
  default_tab = if e then
    title = e.attributes[:title]
    (tabs.keys.index(title) + 1).to_s
  else
    '1'
  end

  h = { active: default_tab, tabs: tabs}
  build(type, h)
  self
  
end
to_css() click to toggle source
# File lib/jsmenubuilder.rb, line 439
def to_css()
  @css
end
to_h() click to toggle source
# File lib/jsmenubuilder.rb, line 443
def to_h()
  @h
end
to_html() click to toggle source
# File lib/jsmenubuilder.rb, line 447
def to_html()
  @html
end
to_js() click to toggle source
# File lib/jsmenubuilder.rb, line 451
def to_js()
  @js
end
to_webpage() { |css, html, js| ... } click to toggle source
# File lib/jsmenubuilder.rb, line 455
def to_webpage()

  r = block_given? ? yield(@css, @html, @js) : @css, @html, @js
  css, html, js = *r.flatten
  puts 'css: ' + css.inspect if @debug
  
  a = RexleBuilder.build do |xml|
    xml.html do 
      xml.head do
        xml.meta name: "viewport", content: \
            "width=device-width, initial-scale=1"
        xml.style "\nbody {font-family: Arial;}\n\n" + css
      end
      xml.body
    end
  end

  doc = Rexle.new(a)
  e = Rexle.new("<html>%s</html>" % html).root
  
  e.children.each {|child| doc.root.element('body').add child }
  
  doc.root.element('body').add \
      Rexle::Element.new('script').add_text "\n" + 
      js.gsub(/^ +\/\/[^\n]+\n/,'')
  
  "<!DOCTYPE html>\n" + doc.xml(pretty: true, declaration: false)\
      .gsub(/<\/div>/,'\0' + "\n").gsub(/\n *<!--[^>]+>/,'')
  
end
to_xml() click to toggle source
# File lib/jsmenubuilder.rb, line 486
def to_xml()
  @xml
end

Private Instance Methods

accordion(opt={}) click to toggle source
# File lib/jsmenubuilder.rb, line 652
def accordion(opt={})

  puts ('opt: ' + opt.inspect).debug if @debug
  
  panels = opt[:accordion]    

  @h = h = panels.group_by {|key, value| key.upcase[0]}

  debug = @debug
  
  puts ('panels: ' + panels.inspect).debug if @debug

  a = RexleBuilder.build do |xml|
    
    xml.html do
            
      h.sort.each do |char, rows|
        
        xml.h2({class: 'anchor', id: char.downcase}, char)
        
        rows.each do |heading, value|
          
          puts 'value: ' + value.inspect if @debug
          inner_html, attrclass = value
          
          puts 'inner_html: ' + inner_html.inspect if debug
          xml.a({class: 'anchor', name: heading.downcase.gsub(/\W/,'-')\
                 .gsub(/-{2,}/,'-').gsub(/^-|-$/,'')})
          xml.button({class:'accordion'}, heading.to_s)
          
          s = 'panel'
          s += ' ' + attrclass if attrclass
          xml.div({class: s}, inner_html)
          
        end
      end

    end
  end

  doc = Rexle.new(a)
  puts 'doc: ' + doc.xml.inspect if @debug
  return doc
  
end
breadcrumb(opt={}) click to toggle source
build(type, options) click to toggle source
# File lib/jsmenubuilder.rb, line 493
def build(type, options)
  
  puts 'inside build'.info if @debug
  puts "type: %s\noptions: %s".debug % [type, options] if @debug
  
  type = :full_page_tabs if type.to_sym == :fullpage
  
  return unless @types.include? type.to_sym
  
  doc = method(type.to_sym).call(options)
  puts 'doc: ' + doc.inspect if @debug
  
  @html = doc.xml(pretty: true, declaration: false)\
    .gsub(/<\/div>/,'\0' + "\n").strip.lines[1..-2]\
    .map {|x| x.sub(/^  /,'') }.join
  
  @css = Object.const_get self.class.to_s + '::' + type.to_s.upcase + '_CSS'
  @js = Object.const_get self.class.to_s + '::' + type.to_s.upcase + '_JS'    
  
  @xml = build_xml(type.to_sym, options)
  
end
build_h(doc) click to toggle source
# File lib/jsmenubuilder.rb, line 516
def build_h(doc)
  
  puts 'inside build_h'.info if @debug
  
  h = doc.root.xpath('tag').inject({}) do |r,e|
    r.merge(e.attributes[:title] => [e.children.join.strip, e.attributes[:class].join(' ')])
  end
  
  puts ('build_h: ' + h.inspect).debug if @debug
  
  {doc.root.attributes[:mode].to_s.to_sym => h}
  
end
build_xml(type, opt={}) click to toggle source
# File lib/jsmenubuilder.rb, line 530
def build_xml(type, opt={})

  puts 'inside build_xml'.info if @debug
  puts 'type: ' + type.inspect if @debug
  
  options = if type.to_s =~ /tabs\b/ then
    {active: '1'}.merge(opt)
  else
    opt
  end    

  entries = if options[:headings] then
    headings = options[:headings]
    headings.zip(headings.map {|heading| ['h3', {}, heading]}).to_h
  else
    return unless options.has_key?(type.to_sym)
    options[type.to_sym]
  end
  
  puts 'entries: ' + entries.inspect if @debug

  a = RexleBuilder.build do |xml|
    xml.tags({mode: type}) do 
      entries.each do |heading, value|
        content, klass = value
        xml.tag({title: heading, class: klass}, content )
      end
    end
  end

  doc = Rexle.new(a)
 
  if options[:active] then
    e = doc.root.element("tag[#{options[:active]}]")
    e.attributes[:mode] = 'active' if e
  end

  return doc.xml(pretty: true)

end
fixed_menu(opt={}) click to toggle source
# File lib/jsmenubuilder.rb, line 766
def fixed_menu(opt={})

  puts 'inside fixed_menu' if @debug
  
  navhtml = if opt[:html] then
  
    opt[:html]
    
  elsif opt[:items]
    
    RexleBuilder.build do |xml|
      
      xml.html do
        
        xml.div(class: 'navbar') do
          
          opt[:items].each do |title, href|
            xml.a({href: href}, title)
          end
          
        end
        
        xml.div(class: 'main') do
          
        end

      end
    end
  end
  
  doc = Rexle.new(navhtml)
  puts 'doc: ' + doc.xml.inspect if @debug           

  return doc

  
end
full_page_tabs(opt={}) click to toggle source
# File lib/jsmenubuilder.rb, line 616
def full_page_tabs(opt={})

  options = {active: '1'}.merge(opt)

  tabs = if options[:headings] then
    headings = options[:headings]
    headings.zip(headings.map {|heading| ['h3', {}, heading]}).to_h
  else
    options[:tabs]
  end                                                     

  a = RexleBuilder.build do |xml|
    xml.html do 

      tabs.keys.each do |heading|
        xml.button({class:'tablink', 
                    onclick: %Q(openPage("#{heading}", this))}, heading.to_s)
      end

      tabs.each do |heading, content|
        puts 'content: ' + content.inspect
        xml.div({id: heading, class: 'tabcontent'}, content )
      end
    end
  end

  doc = Rexle.new(a)
 
  e = doc.root.element("button[#{options[:active]}]")
  e.attributes[:id] = 'defaultOpen' if e

  return doc

  
end
parse_xml(s) click to toggle source
# File lib/jsmenubuilder.rb, line 571
def parse_xml(s)
  doc = Rexle.new(s)
  build_h(doc)
end
sticky_navbar(opt={}) click to toggle source
tabs(opt={}) click to toggle source
# File lib/jsmenubuilder.rb, line 576
def tabs(opt={})

  options = {active: '1'}.merge(opt)

  tabs = if options[:headings] then
    headings = options[:headings]
    headings.zip(headings.map {|heading| ['h3', {}, heading]}).to_h
  else
    options[:tabs]
  end

  a = RexleBuilder.build do |xml|
    xml.html do 

      xml.comment!(' Tab links ')
      xml.div(class: 'tab' ) do
        tabs.keys.each do |heading|
          xml.button({class:'tablinks', 
                      onclick: %Q(openTab(event, "#{heading}"))}, heading.to_s)
        end
      end

      xml.comment!(' Tab content ')

      tabs.each do |heading, content|
        puts 'content: ' + content.inspect
        xml.div({id: heading, class: 'tabcontent'}, content )
      end
    end
  end

  doc = Rexle.new(a)
 
  e = doc.root.element("div/button[#{options[:active]}]")
  e.attributes[:id] = 'defaultOpen' if e

  return doc

end
vertical_menu(opt={}) click to toggle source
# File lib/jsmenubuilder.rb, line 732
def vertical_menu(opt={})

  puts 'inside vertical_navbar' if @debug
  
  navhtml = if opt[:html] then
  
    opt[:html]
    
  elsif opt[:items]
    
    RexleBuilder.build do |xml|
      
      xml.html do
        
        xml.div(class: 'vertical-menu') do
          
          opt[:items].each do |title, href|
            xml.a({href: href}, title)
          end
          
        end

      end
    end
  end
  
  doc = Rexle.new(navhtml)
  puts 'doc: ' + doc.xml.inspect if @debug           

  return doc

  
end