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;
+}