#
# Copyright (C) 2007 Mobio Networks, Inc.
#
# This program is free software: you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free Software
# Foundation, either version 3 of the License, or (at your option) any later
# version.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
# details.
#
# You should have received a copy of the GNU General Public License along with
# this program. If not, see .
#
require 'builder/xmlmarkup'
require 'rmobio/rxml/base_transformer'
require 'singleton'
module Rmobio
module Rxml
class XformsTransformer < BaseTransformer
include Singleton
# def self.get_instance
# return @@xf_instance if defined? @@xf_instance
# @@xf_instance = new
# end
# private_class_method :new
def doctype(xml, style_src=nil)
xml << ''
@model_buffer = '
'
#xml << render_to_string(:partial => 'twitter/default_style.xml')
@model_buffer << '' if style_src
@model_buffer << "\n"
yield xml
@model_buffer << "\n"
xml << @model_buffer << @view_buffer
xml << ""
@view_buffer = ""
@model_buffer = ""
end
def body(doc, title, style=nil)
# xforms style is external style
@view_buffer << '' if style
@view_buffer << "\n"
yield doc
@view_buffer << ""
end
def text(doc, txt="", args={})
# If there's id but no xpath, we will create a default instance data for
# the textoutput.
if args[:id] and args[:xpath].nil?
@model_buffer << "\n" << '' << txt << "\n"
end
if args[:xstyle]
@view_buffer << "\n"
else
@view_buffer << ">" << txt << ""
end
end
def textarea(doc, txt="", args={})
# If there's id but no xpath, we will create a default instance data for
# the textoutput.
if args[:id] and args[:xpath].nil?
@model_buffer << "\n" << '' << txt << "\n"
end
@view_buffer << "\n"
else
@view_buffer << ">" << txt << ""
end
end # textarea
#Create an input field for user to enter text
# id: The instance id that will be associated with this input field. An instance data
# will be created in the model as well
# value: initial value that will be displayed when ui is loaded
# type: not used for xforms client
# args: Hash to hold any other attributes. Height, width and style should go into
# :xstyle.
def input(doc, id, value, type, args={})
# Create model instance only when there's no xpath
if args[:xpath].nil?
@model_buffer << "\n" << '' << value << "\n"
end
@view_buffer << "\n"
else
@view_buffer << args[:xpath] << "\"/>"
end
end
def submit_tag(id)
end
#Generate basic form submission in xforms.
# id: the instance id that is referred by submission attribute
# action: the action url that is invoked
# method: http method, 'get' and 'post'
# req_id: the instance id that contains the request xml data to be sent
# replace_id: if we are replacing instance, the instance, this attribute
# specifies the id of the instance that data will be replace.
# attr: any extra attribute
def form(doc, id, action, method, req_id=nil, replace_id=nil, attr=nil)
@model_buffer << "\n'
#yield doc
#@model_buffer << ''
end
#There's no link widget in Mobio widget set so use a button widget instead to
#provide action for html link. If href is provided and there's no block,
# will be used to invoke the 'href' url. Otherwise, the call block
#will be executed and template can provide specifal action using the action tag.
#Default event type is ev:event="DOMActivate" for the button.
def link(doc, href, txt="", args={}, &block)
@view_buffer << "\n' << txt << ''
# If no action provided, default to use xf:load the url
if block
yield doc
else
@view_buffer << ''
end
@view_buffer << ''
end
#Put arbitray stuff in the model buffer. A workaround for any special xforms
#tags that are not supported yet in the transformer.
def plain_model(doc, txt)
@model_buffer << txt
end
#Put arbitray stuff in the view buffer. A workaround for any special xforms
#tags that are not supported yet in the transformer.
def plain_view(doc, txt)
@view_buffer << txt
end
# def action(doc, ev_type, action, url)
# @view_buffer << "\n"
#
#
# <% if @client_version == '0.6' %>
#
#
# <% else %>
#
#
#
# <% end %>
#
# end
def softBr(doc)
@view_buffer << ''
end
# args[:widget] => specify the widget type, can be 'icon' or 'image', default is image
#
def image(doc, id, src, args={})
widget = "image"
widget = args[:widget] if args[:widget]
@view_buffer << "\n"
else
@view_buffer << src << "\">"
end
else
@view_buffer << '>' << src
end
@view_buffer << ""
end
def tag!(sym, *args)
end
# Create an instance in the model
def instance_tag(doc, id)
@model_buffer << "\n"
yield doc
@model_buffer << ''
end
def table(doc, style="", xstyle="")
@view_buffer << "\n"
yield doc
@view_buffer << ''
end
def table_row(doc, style="", xstyle="")
@view_buffer << "\n"
yield doc
@view_buffer << ''
end
def table_cell(doc, style="", xstyle="")
@view_buffer << ""
yield doc
@view_buffer << ''
end
# Beginning overwrite the builder methods and send all output to model_buffer
def method_missing(sym, *args, &block)
text = nil
attrs = nil
sym = "#{sym}:#{args.shift}" if args.first.kind_of?(Symbol)
args.each do |arg|
case arg
when Hash
attrs ||= {}
attrs.merge!(arg)
else
text ||= ''
text << arg.to_s
end
end
if block
unless text.nil?
raise ArgumentError, "XmlMarkup cannot mix a text argument with a block"
end
_indent
_start_tag(sym, attrs)
_newline
_nested_structures(block)
_indent
_end_tag(sym)
_newline
elsif text.nil?
_indent
_start_tag(sym, attrs, true)
_newline
else
_indent
_start_tag(sym, attrs)
text! text
_end_tag(sym)
_newline
end
end
def _text(text)
@model_buffer << text
end
# Start an XML tag. If end_too is true, then the start
# tag is also the end tag (e.g.
def _start_tag(sym, attrs, end_too=false)
@model_buffer << "<#{sym}"
_insert_attributes(attrs)
@model_buffer << "/" if end_too
@model_buffer << ">"
end
# Insert an ending tag.
def _end_tag(sym)
@model_buffer << "#{sym}>"
end
# Insert the attributes (given in the hash).
def _insert_attributes(attrs, order=[])
return if attrs.nil?
order.each do |k|
v = attrs[k]
@model_buffer << %{ #{k}="#{_attr_value(v)}"} if v # " WART
end
attrs.each do |k, v|
@model_buffer << %{ #{k}="#{_attr_value(v)}"} unless order.member?(k) # " WART
end
end
def _attr_value(value)
case value
when Symbol
value.to_s
else
_escape_quote(value.to_s)
end
end
def _nested_structures(block)
@level += 1
block.call(self)
ensure
@level -= 1
end
# End builder methods
end
end
end