'use strict'; /*@ Ox.parseEmailAddresses Takes HTML and turns e-mail addresses into links > Ox.parseEmailAddresses('test@pad.ma') 'test@pad.ma' > Ox.parseEmailAddresses('foo bar ') 'foo bar <foo@bar.com>' > Ox.parseEmailAddresses('foo bar <foo@bar.com>') 'foo bar <foo@bar.com>' @*/ // fixme: shouldn't this be formatEmailAddresses? // fixme: fails for linked emails Ox.parseEmailAddresses = function(html) { return html.replace( /\b([0-9A-Z\.\+\-_]+@(?:[0-9A-Z\-]+\.)+[A-Z]{2,6})\b/gi, '$1' ); }; /*@ Ox.parseHTML Takes HTML from an untrusted source and returns something sane > Ox.parseHTML('http://foo.com, bar') 'http://foo.com, bar' > Ox.parseHTML('http://foo.com/foobar?foo, bar') 'http://foo.com/foobar?foo, bar' > Ox.parseHTML('(see: www.foo.com)') '(see: www.foo.com)' > Ox.parseHTML('foo@bar.com') 'foo@bar.com' > Ox.parseHTML('foo') 'foo' > Ox.parseHTML('foo') '<a href="javascript:alert()">foo' > Ox.parseHTML('[http://foo.com foo]') 'foo' > Ox.parseHTML('foo') '
foo
' > Ox.parseHTML('') '<script>alert()</script>' > Ox.parseHTML('\'foo\' < \'bar\' && "foo" > "bar"') '\'foo\' < \'bar\' && "foo" > "bar"' > Ox.parseHTML('foo') 'foo' > Ox.parseHTML('foo') 'foo' @*/ Ox.parseHTML = (function() { var defaultTags = [ // inline formatting 'b', 'code', 'i', 's', 'sub', 'sup', 'u', // block formatting 'blockquote', 'h1', 'h2', 'h3', 'p', 'pre', // lists 'li', 'ol', 'ul', // tables 'table', 'tbody', 'td', 'tfoot', 'th', 'thead', 'tr', // other 'a', 'br', 'img', // special 'rtl', '[]' ], parse = { a: { ']*?href="((https?:\/\/|\/).+?)".*?>': '', '<\/a>': '' }, img: { ']*?src="((https?:\/\/|\/).+?)".*?>': '' }, rtl: { '': '
', '<\/rtl>': '
' }, '*': function(tag) { var ret = {}; ret['<(/?' + tag + ') ?/?>'] = '<{1}>'; return ret; } }, tab = '\t'; return function(html, tags, wikilinks) { var matches = []; tags = tags || defaultTags; // html = Ox.clean(html); fixme: can this be a parameter? if (tags.indexOf('[]') > -1) { html = html.replace(/\[((https?:\/\/|\/).+?) (.+?)\]/gi, '$3'); tags = tags.filter(function(tag) { return tag != '[]'; }); } tags.forEach(function(tag) { var p = parse[tag] || parse['*'](tag); Ox.forEach(p, function(replace, regexp) { html = html.replace(new RegExp(regexp, 'gi'), function() { matches.push(Ox.formatString(replace, arguments)); return tab + (matches.length - 1) + tab; }); }); }); html = Ox.encodeHTML(html); //fixme: both fail if urls/emails are already links //html = Ox.parseURLs(html); //html = Ox.parseEmailAddresses(html); matches.forEach(function(match, i) { html = html.replace(new RegExp(tab + i + tab), match); }); html = html.replace(/\n\n/g, '

'); // close extra opening (and remove extra closing) tags // note: this converts '"' to '"' return Ox.element('
').html(html).html(); }; }()); /*@ Ox.parseURL Takes a URL, returns its components (url) -> URL components url URL > Ox.test.object.hash '#c' > Ox.test.object.host 'www.foo.com:8080' > Ox.test.object.hostname 'www.foo.com' > Ox.test.object.origin 'http://www.foo.com:8080' > Ox.test.object.pathname '/bar/index.html' > Ox.test.object.port '8080' > Ox.test.object.protocol 'http:' > Ox.test.object.search '?a=0&b=1' @*/ Ox.parseURL = (function() { var a = document.createElement('a'), keys = ['hash', 'host', 'hostname', 'origin', 'pathname', 'port', 'protocol', 'search']; return function(string) { var ret = {}; a.href = string; keys.forEach(function(key) { ret[key] = a[key]; }); return ret; }; }()); /*@ Ox.parseURLs Takes HTML and turns URLs into links > Ox.parseURLs('http://foo.com, bar') 'http://foo.com, bar' > Ox.parseURLs('http://foo.com/foobar?foo, bar') 'http://foo.com/foobar?foo, bar' > Ox.parseURLs('www.foo.com, bar') 'www.foo.com, bar' > Ox.parseURLs('http://foo.com etc') 'http://foo.com etc' @*/ // fixme: shouldn't this be formatURLs? // fixme: fails for urls inside links Ox.parseURLs = function(html) { return html.replace( /\b((https?:\/\/|www\.).+?)([\.,:;!\?\)\]]*?(\s|$))/gi, function(string, url, prefix, end) { url = (prefix == 'www.' ? 'http://' : '') + url; return Ox.formatString( '{url}{end}', {end: end, url: url} ); } ); };