view blog.js @ 1:82905edac9d8

Fix some things.
author Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
date Tue, 12 Jul 2011 17:47:32 +0200
parents f62b5c395a48
children f630f4b90564
line wrap: on
line source

//'use strict';

const BOSH_SERVICE = 'http://linkmauve.fr/http-bind/';
var conn = null;
var jid = 'blog@linkmauve.fr'; // FIXME: Strophe should accept anonymous connections.
var password = 'blog';
var service = 'psgxs.linkmauve.fr';
var node = 'blog';
var re = true;

var params = (function() {
	var vars = {};
	var hashes = window.location.href.slice(window.location.href.indexOf('?') + 1).split(';');

	for(var i = 0; i < hashes.length; i++) {
		var s = hashes[i].indexOf('=');
		var key = hashes[i].substring(0, s);
		var value = hashes[i].substring(s+1);
		vars[key] = value;
	}

	return vars;
})();

if (params.jid)
	service = params.jid;

if (params.node)
	node = params.node;

var logs = document.getElementById('log');
if (params.debug)
	logs.parentNode.hidden = false;

var received = {};
var messages = document.getElementById('messages');

function log(msg, error) {
	var p = document.createElementNS(ns.xhtml, 'p');
	p.appendChild(document.createTextNode(msg));

	if (!error)
		p.setAttributeNS(null, 'class', 'error');

	logs.appendChild(p);
}

function rawInput(data) {
	log('RECV: ' + data, 1);
}

function rawOutput(data) {
	log('SENT: ' + data, 1);
}

var html = function(name, id) {
	return received[name][id].html;
}

var date = function(name, id) {
	return received[name][id].date;
}

var updateMessage = function(name, id) {
	var divs = messages.getElementsByTagNameNS(ns.xhtml, 'div');
	var container = null;

	for (var i in divs) {
		var div = divs[i]
		if (typeof div != 'object')
			continue;

		if (div.getAttributeNS(ns.e, 'jid') === name) {
			container = div;
			break;
		}
	}

	if (!container) {
		var container = document.createElementNS(ns.xhtml, 'div');
		container.setAttributeNS(ns.e, 'jid', name);
		messages.appendChild(container);
	}

	var articles = container.getElementsByTagNameNS(ns.xhtml, 'article');
	for (var i in articles) {
		var article = articles[i];
		if (typeof article != 'object')
			continue;

		if (article.getAttributeNS(ns.e, 'id') === id) {
			container.replaceChild(html(name, id), article);
			return;
		}
	}

	var article = html(name, id);

	if (!container.firstChild)
		container.appendChild(article);
	else {
		var d = date(name, id);
		var toInsert;
		for (var i in articles) {
			var a = articles[i];
			if (typeof a != 'object')
				continue;

			var ad = new Date();
			ad.set8601(a.getAttributeNS(ns.e, 'date'));

			if (ad < d) {
				toInsert = a;
				break;
			}
		}

		if (toInsert)
			container.insertBefore(article, toInsert);
		else
			container.appendChild(article);
	}
}

var convert = function(id, xml) {
	var ns = xml['@xmlns'];
	if (ns in parsers)
		return new parsers[ns](id, xml);
	return new parsers[''](id, xml);
};

var parsePubSubEvent = function(stanza) {
	var e = {};

	e.service = stanza.getAttribute('from');

	var pubsub = stanza.getChild('event', ns.pse);
	if (!pubsub) {
		pubsub = stanza.getChild('pubsub', ns.ps);
		if (!pubsub)
			return;
	}
	e.ns = pubsub.getAttribute('xmlns');

	var items = pubsub.getChild('items', e.ns);
	if (!items)
		return;

	e.node = items.getAttribute('node');
	items = items.getChildren('item', e.ns);
	if (!items)
		return;

	e.name = e.service + '/' + e.node;

	e.items = {};
	for (var i in items) {
		var item = items[i];
		if (!item.getAttribute)
			continue;

		var pl = item.getChild();
		if (!pl)
			continue;

		var id = item.getAttribute('id');

		e.items[id] = pl;
	}

	return e;
}

var onMessages = function(stanza) {
	conn.addHandler(onMessages, null, 'message', null, null, null);

	log('message');
	stanza = xml2json(stanza);
	var e = parsePubSubEvent(stanza);

	if (!received[e.name])
		received[e.name] = {};

	for (var id in e.items) {
		received[e.name][id] = convert(id, e.items[id]);
		updateMessage(e.name, id);
	}
}

var onInfo = function(stanza) {
	log('info');
	/*var query = stanza.getElementsByTagNameNS(ns.info, 'query')[0];
	var x = query.getElementsByTagNameNS(ns.data, 'x')[0];
	var form = forms.parse(x);*/
}

var onSubscribed = function(stanza) {
	log('subscribed');
	var type = stanza.getAttribute('type');
	if (type !== 'result') {
		messages.innerHTML = 'Error, impossible to retrieve messages.';
		conn.disconnect();
	}
}

function onConnect(status) {
	if (status == Strophe.Status.CONNECTING) {
		log('Strophe is connecting.');
	} else if (status == Strophe.Status.CONNFAIL) {
		log('Strophe failed to connect.');
	} else if (status == Strophe.Status.AUTHENTICATING) {
		log('Strophe is authenticating.');
	} else if (status == Strophe.Status.DISCONNECTING) {
		log('Strophe is disconnecting.');
	} else if (status == Strophe.Status.DISCONNECTED) {
		log('Strophe is disconnected.');
		if (re)
			conn.connect(jid, password, onConnect);
	} else if (status == Strophe.Status.CONNECTED) {
		log('Strophe is connected.');
		conn.addHandler(onMessages, null, 'message', null, null, null);
		conn.send($pres().tree());
		conn.pubsub.subscribe(jid, service, node, undefined, onMessages, onSubscribed);
		if (params.no === 'server') {
			conn.pubsub.items(jid, service, node, onMessages);
			conn.pubsub.info(jid, service, node, onInfo);
		}
	} else
		log('Strophe is '+status+'.');
}

window.addEventListener('load', function () {
	conn = new Strophe.Connection(BOSH_SERVICE);
	conn.rawInput = rawInput;
	conn.rawOutput = rawOutput;
	conn.connect(jid, password, onConnect);
}, false);

window.addEventListener('unload', function (e) {
	re = false;
	conn.disconnect();
	e.preventDefault();
}, false);