view atom.js @ 15:5149a856d9dd default tip

Fix hybrid mode.
author Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
date Thu, 03 Nov 2011 17:28:49 -0700
parents 03be0717d3f8
children
line wrap: on
line source

'use strict';

if (typeof window === 'undefined') {
	var Element = require('ltx').Element;
	var JID = require('./jid');
	var ns = require('./ns');
	var config = require('./configuration');

	var document = {};

	document.createElementNS = function(ns, name) {
		return new Element(name, {xmlns: ns});
	};

	document.createTextNode = function(text) {
		return text;
	};

	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;

		if (!atom)
			return d;

		try {
			var last = atom.getElementsByTagNameNS(ns.atom, 'updated')[0].textContent;
		} catch (e) {
			try {
				var last = atom.getElementsByTagNameNS(ns.atom, 'published')[0].textContent;
			} catch (e) {
				return d;
			}
		}

		// var d = new Date(last); // FIXME: don't work in obsolete browsers
		d.set8601(last);

		return d;
	};

	var toHTML = function(item, date) {
		var atom = item.payload;

		var article = document.createElementNS(ns.xhtml, 'article');

		article.setAttributeNS(ns.e, 'id', item.id);
		var d8601 = date.to8601();
		article.setAttributeNS(ns.e, 'date', d8601);

		var aside = document.createElementNS(ns.xhtml, 'aside');
		article.appendChild(aside);

		try {
			var atomTitle = atom.getElementsByTagNameNS(ns.atom, 'title')[0].textContent;
			var title = document.createElementNS(ns.xhtml, 'h2');
			title.appendChild(document.createTextNode(atomTitle));
			article.appendChild(title);
		} catch (e) {
		}

		var footer = document.createElementNS(ns.xhtml, 'footer');

		try {
			var atomAuthor = atom.getElementsByTagNameNS(ns.atom, 'author')[0];
			try {
				var atomName = atomAuthor.getElementsByTagNameNS(ns.atom, 'name')[0].textContent;
			} catch (e) {
			}

			var cite = document.createElementNS(ns.xhtml, 'cite');
			try {
				var atomURI = atomAuthor.getElementsByTagNameNS(ns.atom, 'uri')[0].textContent;
				var a = document.createElementNS(ns.xhtml, 'a');
				a.setAttributeNS(null, 'href', atomURI);
				var atomJID = new JID;
				atomJID.uri = atomURI;

				a.appendChild(document.createTextNode(atomName? atomName: atomJID.bare));
				cite.appendChild(a);

				var img = document.createElementNS(ns.xhtml, 'img');
				img.setAttributeNS(null, 'src', config.avatarRoot + atomJID.bare);
				aside.appendChild(img);
			} catch (e) {
				cite.appendChild(document.createTextNode(atomName));
			}

			footer.appendChild(document.createTextNode('By '));
			footer.appendChild(cite);

			try {
				var atomEmail = atomAuthor.getElementsByTagNameNS(ns.atom, 'email')[0].textContent;
				footer.appendChild(document.createTextNode(' ('));
				var a = document.createElementNS(ns.xhtml, 'a');
				a.setAttributeNS(null, 'href', 'mailto:' + atomEmail);
				a.appendChild(document.createTextNode('email'));
				footer.appendChild(a);
				footer.appendChild(document.createTextNode(')'));
			} catch (e) {
			}

			article.appendChild(footer);
		} catch (e) {
		}

		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;
			var p = document.createElementNS(ns.xhtml, 'p');
			p.appendChild(document.createTextNode(atomSummary));
			article.appendChild(p);
		} catch (e) {
		}

		try {
			var atomContent = atom.getElementsByTagNameNS(ns.atom, 'content')[0];
			var contentType = atomContent.getAttributeNS(null, 'type');
			if (/^text$/.test(contentType)) {
				var p = document.createElementNS(ns.xhtml, 'p');
				p.appendChild(document.createTextNode(atomContent.textContent));
				article.appendChild(p);
			} else if (/^html$/.test(contentType)) {
				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; i<children.length; i++) {
					var child = children[i];
					if (typeof child === 'string')
						article.appendChild(child);
					else
						article.appendChild(child.cloneNode(true));
				}
			} else {
				var contentSrc = atomContent.getAttributeNS(null, 'src');
				if (contentSrc) {
					if (/^image\//.test(contentType)) {
						var img = document.createElementNS(ns.xhtml, 'img');
						img.setAttributeNS(null, 'src', contentSrc);
						article.appendChild(img);
					} else if (/^audio\//.test(contentType)) {
						var audio = document.createElementNS(ns.xhtml, 'audio');
						audio.setAttributeNS(null, 'src', contentSrc);
						audio.setAttributeNS(null, 'controls', '');
						article.appendChild(audio);
					} else if (/^video\//.test(contentType)) {
						var video = document.createElementNS(ns.xhtml, 'video');
						video.setAttributeNS(null, 'src', contentSrc);
						video.setAttributeNS(null, 'controls', '');
						article.appendChild(video);
					} else {
						var a = document.createElementNS(ns.xhtml, 'a');
						a.setAttributeNS(null, 'href', contentSrc);
						article.appendChild(a);
					}
				}
			}
		} catch (e) {
		}

		var atomLinks = atom.getElementsByTagNameNS(ns.atom, 'link');
		for (var i in atomLinks) {
			var atomLink = atomLinks[i];

			if (atomLink.getAttributeNS(null, 'rel') !== 'replies')
				continue;

			if (atomLink.getAttributeNS(null, 'title') !== 'comments')
				continue;

			var href = new JID;
			href.uri = atomLink.getAttributeNS(null, 'href');

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

	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;