Mercurial > eldonilo > blog
diff blog.js @ 0:f62b5c395a48
Initial commit.
author | Emmanuel Gil Peyrot <linkmauve@linkmauve.fr> |
---|---|
date | Sat, 04 Jun 2011 05:02:47 +0200 |
parents | |
children | 82905edac9d8 |
line wrap: on
line diff
new file mode 100644 --- /dev/null +++ b/blog.js @@ -0,0 +1,243 @@ +//'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.idq, 'jid') === name) { + container = div; + break; + } + } + + if (!container) { + var container = document.createElementNS(ns.xhtml, 'div'); + container.setAttributeNS(ns.idq, '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.idq, '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.idq, '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);