# HG changeset patch # User Emmanuel Gil Peyrot # Date 1320363720 25200 # Node ID 03be0717d3f8f3abe65975537ee46bc91c98cd11 # Parent 161d4ea1c3f8b421ca0fa34ae96d1fb3c3d826dc Use the same code for client- and server-side Atom parsing. diff --git a/atom.js b/atom.js --- a/atom.js +++ b/atom.js @@ -1,19 +1,61 @@ 'use strict'; -if (!document) +if (typeof window === 'undefined') { + var Element = require('ltx').Element; + var JID = require('./jid'); + var ns = require('./ns'); + var config = require('./configuration'); + var document = {}; -if (!document.createElementNS) document.createElementNS = function(ns, name) { return new Element(name, {xmlns: ns}); }; -if (!document.createTextNode) document.createTextNode = function(text) { return text; }; -parsers[ns.atom] = function(item) { + Element.prototype.getAttributeNS = function(ns, name) { + // TODO: use the namespace. + return this.attrs[name]; + }; + + Element.prototype.setAttributeNS = function(ns, name, value) { + // TODO: use the namespace. + this.attrs[name] = value; + }; + + Element.prototype.cloneNode = function(depth) { + // XXX + return this; + }; + + Element.prototype.appendChild = function(child) { + if (typeof child === 'string') + this.t(child); + else + this.cnode(child); + }; + + Element.prototype.getElementsByTagNameNS = function(ns, name) { + return this.getChildren(name, ns); + }; + + Element.prototype.__defineGetter__('textContent', function() { + return this.getText(); + }); + + Element.prototype.__defineGetter__('firstChild', function() { + return this.children[0]; + }); + + Element.prototype.__defineGetter__('childNodes', function() { + return this.children; + }); +} + +var atomParser = function(item) { var toDate = function(atom) { var d = new Date; @@ -38,11 +80,10 @@ parsers[ns.atom] = function(item) { var toHTML = function(item, date) { var atom = item.payload; - var id = item.id; var article = document.createElementNS(ns.xhtml, 'article'); - article.setAttributeNS(ns.e, 'id', id); + article.setAttributeNS(ns.e, 'id', item.id); var d8601 = date.to8601(); article.setAttributeNS(ns.e, 'date', d8601); @@ -70,7 +111,7 @@ parsers[ns.atom] = function(item) { try { var atomURI = atomAuthor.getElementsByTagNameNS(ns.atom, 'uri')[0].textContent; var a = document.createElementNS(ns.xhtml, 'a'); - a.href = atomURI; + a.setAttributeNS(null, 'href', atomURI); var atomJID = new JID; atomJID.uri = atomURI; @@ -78,7 +119,7 @@ parsers[ns.atom] = function(item) { cite.appendChild(a); var img = document.createElementNS(ns.xhtml, 'img'); - img.src = config.avatarRoot + atomJID.bare; + img.setAttributeNS(null, 'src', config.avatarRoot + atomJID.bare); aside.appendChild(img); } catch (e) { cite.appendChild(document.createTextNode(atomName)); @@ -91,7 +132,7 @@ parsers[ns.atom] = function(item) { var atomEmail = atomAuthor.getElementsByTagNameNS(ns.atom, 'email')[0].textContent; footer.appendChild(document.createTextNode(' (')); var a = document.createElementNS(ns.xhtml, 'a'); - a.href = 'mailto:' + atomEmail; + a.setAttributeNS(null, 'href', 'mailto:' + atomEmail); a.appendChild(document.createTextNode('email')); footer.appendChild(a); footer.appendChild(document.createTextNode(')')); @@ -102,7 +143,11 @@ parsers[ns.atom] = function(item) { } catch (e) { } - footer.innerHTML += ', '; + var time = document.createElementNS(ns.xhtml, 'time'); + time.setAttributeNS(null, 'datetime', d8601); + time.appendChild(document.createTextNode(date.getRelative())); + footer.appendChild(document.createTextNode(', ')); + footer.appendChild(time); try { var atomSummary = atomAuthor.getElementsByTagNameNS(ns.atom, 'summary')[0].textContent; @@ -120,12 +165,20 @@ parsers[ns.atom] = function(item) { p.appendChild(document.createTextNode(atomContent.textContent)); article.appendChild(p); } else if (/^html$/.test(contentType)) { - article.insertAdjacentHTML('beforeend', atomContent.textContent); // FIXME: could be not-well-formed. + if (!article.insertAdjacentHTML) + article.appendChild(document.createTextNode('Inline HTML inclusion not yet supported server-side.')); + else + article.insertAdjacentHTML('beforeend', atomContent.textContent); // FIXME: could be not-well-formed. } else if (/^xhtml$/.test(contentType)) { var div = atomContent.firstChild; var children = div.childNodes; - for (var i=0; iComments !'; + var a = document.createElementNS(ns.xhtml, 'a'); + a.setAttributeNS(null, 'href', '?jid=' + href.bare + ';node=' + href.query.node); + a.appendChild(document.createTextNode('Comments')); + article.appendChild(a); } return article; @@ -175,4 +231,9 @@ parsers[ns.atom] = function(item) { this.xml = item.payload; this.date = toDate(item.payload); this.html = toHTML(item, this.date); -} +}; + +if (typeof parsers !== 'undefined') + parsers[ns.atom] = atomParser; +else if (typeof module !== 'undefined') + module.exports = atomParser; diff --git a/nothing.js b/nothing.js --- a/nothing.js +++ b/nothing.js @@ -7,7 +7,7 @@ parsers[''] = function(item) { var toHTML = function(item, date) { var article = document.createElementNS(ns.xhtml, 'article'); - article.setAttributeNS(ns.e, 'id', id); + article.setAttributeNS(ns.e, 'id', item.id); article.setAttributeNS(ns.e, 'date', date.to8601()); article.appendChild(document.createElementNS(ns.xhtml, 'h2').appendChild(document.createTextNode('This post is in an unknown namespace.'))); return article; diff --git a/server.js b/server.js --- a/server.js +++ b/server.js @@ -14,6 +14,7 @@ var JID = require('./jid'); var ns = require('./ns'); var forms = require('./forms'); require('./date'); +var Atom = require('./atom'); var received = {}; @@ -148,89 +149,6 @@ cl.on('stanza', function(stanza) { } }); -var parseAtom = function(atom, id, jid) { - var article = new Element('article', {'e:id': id}); - - var avatar = article.c('aside').c('img') - article.up(); - - try { - var title = atom.getChild('title', ns.atom).getText(); - if (title) - article.c('h2').t(title).up(); - } catch (e) { } - - var footer = article.c('footer'); - article.up(); - - var author = atom.getChild('author', ns.atom); - if (author) { - footer.t('By '); - var name = author.getChild('name', ns.atom).getText(); - - try{ - var uri = author.getChild('uri', ns.atom).getText(); - footer.c('cite').c('a', {href: uri}).t(name).up(); - avatar.attrs.src = config.avatarRoot + uri.substring(5); - avatar.attrs.alt = uri.substring(5); - } catch (e) { - footer.c('cite').t(name); - } - - try { - var email = author.getChild('email', ns.atom).getText(); - footer.t(' (').c('a', {href: 'mailto:' + email}).t('email').up().t(')'); - } catch (e) { } - footer.up(); - } - - var published = (function() { - try { - var elem = atom.getChild('published', ns.atom); - var iso8601 = elem.getText(); - var d = (new Date).set8601(iso8601); - var relative = d.getRelative(); - - return {iso8601: iso8601, relative: relative}; - } catch (e) { - var d = new Date; - return {iso8601: d.to8601(), relative: d.getRelative()}; - } - })(); - - if (author) - footer.t(', '); - footer.c('time', {datetime: published.iso8601}).t(published.relative).up(); - article.attrs['e:date'] = published.iso8601; - - try { - var summary = atom.getChild('summary', ns.atom).getText(); - if (summary) - article.c('p').t(summary).up(); - } catch (e) { } - - try { - var links = atom.getChildren('link'); - for (var i in links) { - var link = links[i]; - - if (link.attrs.rel !== 'replies') - continue; - - if (link.attrs.title !== 'comments') - continue; - - var href = new JID; - href.uri = link.attrs.href; - - article.c('a', {href: '?jid=' + href.bare + ';node=' + href.query.node + ';origjid=' + jid.bare + ';orignode=' + jid.resource + ';origitem=' + id}).t('Comments !'); - break; - } - } catch (e) { } - - return article; -}; - var generatePage = function(jid) { var r = received[jid.full]; var s = r.wait; @@ -251,9 +169,9 @@ var makePage = function(res, jid, form, var body = ''; for (var id in data) { - var item = data[id]; - var article = parseAtom(item, id, jid); - body = article + body; + var payload = data[id]; + var article = new Atom({id: id, ns: payload.attrs['xmlns'], payload: payload}); // , jid ? + body = article.html + body; } body = '
' + body;