Mercurial > psc
diff forms.js @ 0:a2dab4544b2d default tip
Initial commit.
author | Emmanuel Gil Peyrot <linkmauve@linkmauve.fr> |
---|---|
date | Fri, 28 Jan 2011 02:35:04 +0100 |
parents | |
children |
line wrap: on
line diff
new file mode 100644 --- /dev/null +++ b/forms.js @@ -0,0 +1,217 @@ +/* + * Copyright (C) 2010 Emmanuel Gil Peyrot <linkmauve@linkmauve.fr> + * + * This file is part of PSĜS, a PubSub server written in JavaScript. + * + * PSĜS is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License. + * + * PSĜS 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with PSĜS. If not, see <http://www.gnu.org/licenses/>. + */ + +var xmpp = require('clxmpp') + +var parseBoolean = function(b) { + if (b == 'true' || b == 'True' || b == 'TRUE' || b == '1') + return true; + return false; +} + +exports.build = function(type, desc, content, labels, title, instructions) { + var x = xmpp.stanza('x', {xmlns: 'jabber:x:data', type: type}); + + if (desc._TITLE) + x.s('title').t(desc._TITLE); + else if (title) + x.s('title').t(title); + + if (desc._INSTRUCTIONS) + x.s('instructions').t(desc._INSTRUCTIONS); + else if (instructions) + x.s('instructions').t(instructions); + + if (content == 'default') { + content = {}; + for (var i in desc) + content[i] = desc[i].value; + } + + for (var i in desc) { + if (i[0] == '_') + continue; + + var fieldAttr = {'var': i}; + + if (labels) { + if (desc[i].type) + fieldAttr.type = desc[i].type; + if (desc[i].label) + fieldAttr.label = desc[i].label; + } + var field = xmpp.stanza('field', fieldAttr); + + if (labels && + (desc[i].type == 'list-multi' || + desc[i].type == 'list-single')) { + for (var j in desc[i].options) { + var optAttr = {}; + if (desc[i].options[j].label) + optAttr.label = desc[i].options[j].label; + field.s('option', optAttr).c('value').t(j); + } + } + + if (i == 'FORM_TYPE') + field.s('value').t(desc[i].value); + else if (typeof content[i] != 'undefined') { + var md = content[i]; + if (desc[i].type == 'jid-multi' || + desc[i].type == 'list-multi' || + desc[i].type == 'text-multi') { + for (var j=0; j<md.length; j++) + field.s('value') + .t(md[j].toString()); + } else + field.s('value').t(md.toString()); + } + + x.cnode(field); + } + if (field) + return x; + return -1; //FIXME +} + +exports.parse = function(x, params) { + var form = {}; + + if (!params) { + var type = x.getAttribute('type'); + if (type) + form.type = type; + + var title = x.getChild('title'); + if (title) + form.title = title; + + var instructions = x.getChild('instructions'); + if (instructions) + form.instructions = instructions; + } + + form.fields = {}; + for (var i in x.tags) { + var field = x.tags[i]; + var name = field.getAttribute('var'); + if (params && name == 'FORM_TYPE') + continue; + + if (params) { + var type = field.getAttribute('type'); + if (type == 'jid-multi' || type == 'list-multi' || type == 'text-multi') { + form.fields[name] = []; + for (var j in field.tags) { + var elem = field.tags[j]; + if (elem.name == 'value') + form.fields[name].push(elem.getText()); + } + } else if (type == 'boolean') { + var value = field.getChild('value'); + if (value) + form.fields[name] = parseBoolean(value.getText()); + } else { + var value = field.getChild('value'); + if (value) + form.fields[name] = value.getText(); + } + } else { + form.fields[name] = {}; + + var label = field.getAttribute('label'); + if (label) + form.fields[name].label = label; + + var type = field.getAttribute('type'); + if (type) + form.fields[name].type = type; + + if (field.tags.length) { + if (field.tags.length == 1) { + if (field.tags[0].name == 'value') { + var value = field.tags[0]; + if (type == 'boolean') + form.fields[name].value = parseBoolean(value.getText()); + else + form.fields[name].value = value.getText(); + } + } else { + form.fields[name].options = {}; + form.fields[name].values = []; + for (var j in field.tags) { + var elem = field.tags[j]; + if (elem.name == 'option') { + var value = elem.getChild('value'); + if (!value) + continue; + + value = value.getText(); + if (!value) + continue; + + form.fields[name].options[value] = {}; + + label = elem.getAttribute('label') + if (label) + form.fields[name].options[value].label = label; + } else if (elem.name == 'value') + form.fields[name].values.push(elem.getText()); + } + if (form.fields[name].values.length == 1) { + form.fields[name].value = form.fields[name].values[0]; + delete form.fields[name].values; + } + } + } + } + } + return form; +} + +exports.toString = function(form) { + var text = ''; + + var inspect = require('sys').inspect; + + for (var i in form.fields) { + if (i == 'FORM_TYPE') + continue; + + var field = form.fields[i]; + text += '\n\t' + i; + if (field.label) + text += ' (' + field.label + ')'; + if (field.type) + text += ', ' + field.type; + + text += ': '; + if (typeof field.value != 'undefined') + text += inspect(field.value); + else if (field.values) + text += inspect(field.values); + else + text += 'empty'; + + if (typeof field.options == 'object') + for (var j in field.options) + text += '\n\t\t' + j + ': ' + field.options[j].label; + } + return text; +}