Support for goo.gl api key
* option lua_shorten_googl_key
* better error parsing
-- DATA FORMS (XEP-0004)
-- library
local form_field = require 'lm.form_field'
--
local F = { }
local M = { }
M.__index = M
-- form.new -- new form
-- form.parse -- parse existing form -- according to form type!
-- form:type -- get type
-- form:desc -- get title, instructions
-- form:format -- format form -- according to form type!
-- form:fields -- iterator, returns field objects
-- form:add -- create field
-- form:field -- get field
-- ?? form:del -- delete field
-- field.new -- create field
-- field:index -- get index
-- field:type -- get type
-- field:name -- get var
-- field:desc -- get label, desc
-- field:value -- get/set value
-- field:values -- get values
-- field:clear -- clear value
-- field:options -- get options
-- field:required -- get required
-- form may have 'fixed' fields and should be ordered
-- submit must not have 'fixed' fields and may be not ordered
-- cancel must not have anything
-- result should not have 'fixed', may be not ordered and can contain reported/item... multiple instances.
function F.new ( args )
local form = {
xmlns = 'jabber:x:data',
ftype = args.type or 'form',
title = args.title,
instructions = args.instructions,
f = { },
}
setmetatable ( form, M )
return form
end
function F.parse ( x )
local title = x:child ( 'title' )
if title then
title = title:value ()
end
local instructions = x:child ( 'instructions' )
if instructions then
instructions = instructions:value ()
end
local f = F.new { type = x:attribute ( 'type' ), title = title, instructions = instructions }
local field = x:child ()
while field do
local name = field:name ()
if name == 'field' then
local ftype = field:attribute ( 'type' ) or 'text-single'
local var = field:attribute ( 'var' )
local r = {
type = ftype,
label = field:attribute ( 'label' ),
}
local desc = field:child ( 'desc' )
if desc then
r.desc = desc:value ()
end
if field:child ( 'required' ) then
r.required = true
end
if ftype == 'jid-multi' or ftype == 'list-multi' or ftype == 'text-multi' or ftype == 'list-single' then
local values = { }
local options = { }
local item = field:child ()
while item do
local name = item:name ()
if name == 'value' then
table.insert ( values, item:value () )
elseif name == 'option' then
options[item:child( 'value' ):value ()] = item:attribute ( 'label' ) or ''
end
item = item:next ()
end
if ftype == 'list-single' then
local value = field:child ( 'value' )
if value then
r.value = value:value ()
end
else
r.value = values
end
if ftype == 'list-multi' or ftype == 'list-single' then
r.options = options
end
else
local value = field:child ( 'value' )
if value then
r.value = value:value ()
end
end
f:add ( var, r )
end
field = field:next ()
end
return f
end
function M.type ( form )
return form.ftype
end
function M.desc ( form )
return form.title, form.instructions
end
function M.format ( form, root, format_as )
local ft = format_as or form:type ()
root.x = { xmlns = 'jabber:x:data', type = ft }
if ft == 'cancel' then
return root
end
if ft == 'form' then
local title, instructions = form:desc ()
if title then
root.x.title = { title }
end
if instructions then
root.x.instructions = { instructions }
end
end
local fields = { }
for i, field in form:fields () do
local ftype = field:type ()
local options, label, desc, required
if ft == 'form' then
label, desc = field:desc ()
if desc then
desc = { desc }
end
if field:required () then
required = { }
end
for option, label in field:options () do
table.insert ( options, { label = label, value = { option } } )
end
end
local value
if ftype == 'list-multi' or ftype == 'text-multi' or ftype == 'jid-multi' then
if ft == 'form' then
for option, label in field:options () do
table.insert ( options, { label = label, value = { option } } )
end
end
value = { }
for j, v in field:values () do
table.insert ( value, { v } )
end
else
value = { field:value () }
end
if ftype ~= 'fixed' or ft == 'form' then
table.insert ( fields, {
type = ftype,
var = field:name (),
label = label,
desc = desc,
value = value,
option = options
} )
end
end
root.x.field = fields
return root
end
function M.fields ( form )
return ipairs ( form.f )
end
function M.add ( form, var, fld )
fld.var = var
fld.index = #form.f + 1 -- XXX
if not fld.type then
fld.type = 'text-single'
end
local obj = form_field.new ( fld )
table.insert ( form.f, obj )
form.f[var] = obj
return obj
end
function M.field ( form, var )
-- works well on indices
return form.f[var]
end
return F
-- vim: se ts=4: --