view 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 source

/*
 *  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;
}