view forms.js @ 15:60c80751cfa5

JID handling conforming to the RFC.
author Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
date Tue, 19 Oct 2010 17:48:45 +0200
parents efe8dbd34780
children 5fc4ee90c1bc
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('xmpp')
var service_configuration = require('./configuration').service_configuration;

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 (typeof desc == 'string')
		desc = service_configuration[desc];

	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 (type == 'jid-multi' || type == 'list-multi' || type == 'text-multi') {
				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());
				}
			} else if (type == 'boolean') {
				var value = field.getChild('value');
				if (value)
					form.fields[name].value = parseBoolean(value.getText());
			} else {
				var value = field.getChild('value');
				if (value)
					form.fields[name].value = value.getText();
			}
		}
	}
	return form;
}