diff --git a/popup.css b/popup.css
new file mode 100644
index 0000000..9581fb1
--- /dev/null
+++ b/popup.css
@@ -0,0 +1,155 @@
+body {
+ min-width: 700px;
+ overflow-x: hidden;
+ overflow-y: auto;
+ font: normal x-small verdana, arial, helvetica, sans-serif;
+ }
+ a {
+ text-decoration: none;
+ }
+ a:hover {
+ text-decoration: underline;
+ }
+ #posts {
+ list-style-type: none;
+ margin:0;
+ padding:0;
+ }
+ #posts > li:before {
+ content: counter(postCount) " ";
+ counter-increment: postCount;
+ float: left;
+ margin-top: 15px;
+ color: #C6C6C6;
+ font-size: medium;
+ text-align: right;
+ font-family: arial;
+}
+#posts:first-child {
+ counter-reset: postCount;
+}
+#posts li {
+ margin: 0;
+ padding: 0;
+ padding-left: 3px;
+ margin-bottom: 8px;
+ clear:both;
+ overflow:auto;
+}
+li.hidden .votes, li.hidden .thumblink, li.hidden .link, li.hidden .domain, li.hidden .meta, li.hidden .actions *:not(.hide){
+ opacity: 0.4;
+}
+.votes {
+ float: left;
+ margin-right: 4px;
+ margin-left: 7px;
+ font-size: small;
+ width: 5ex;
+ overflow: hidden;
+ font-weight: bold;
+}
+.upmod, .downmod {
+ margin: 2px 0px 0px 0px;
+ width: 100%;
+ height: 14px;
+ display: block;
+ cursor: pointer;
+ background-position: center center;
+ background-repeat: no-repeat;
+ width: 15px;
+ margin-left: auto;
+ margin-right: auto;
+ background-image: url('sprite.png');
+}
+.upmod {
+ background-position: -4px -271px;
+}
+li[data-dir='1'] .upmod {
+ background-position: -4px -227px;
+}
+.downmod {
+ background-position: -4px -293px;
+}
+li[data-dir='-1'] .downmod {
+ background-position: -4px -249px;
+}
+.count {
+ text-align: center;
+ color: #C6C6C6;
+ display: block;
+}
+.thumblink {
+ float: left;
+ margin: 0px 5px;
+ overflow: hidden;
+ width: 70px;
+}
+.post {
+ overflow: hidden;
+ margin-left: 3px;
+}
+.link {
+ font-size: medium;
+ font-weight: normal;
+ margin-bottom: 1px;
+}
+.domain {
+ color: #888;
+ font-size: x-small;
+}
+.meta {
+ color: #888;
+ font-size: x-small;
+}
+.meta a {
+ color: #369;
+}
+.actions a {
+ color: #888;
+ font-weight: bold;
+ padding: 0 4px;
+}
+.actions a:first-child {
+ padding-left:0;
+}
+.morelink {
+ display:block;
+ text-align:center;
+ position:relative;
+ -moz-border-radius-topleft:6px;
+ -moz-border-radius-bottomleft:6px;
+ border:1px solid #c4dbf1;
+ background:white none repeat-x scroll center left;
+ background-image:url('gradient-button.png');
+ font-size:150%;
+ font-weight:bold;
+ letter-spacing:-1px;
+ line-height:29px;
+ height:29px;
+}
+.morelink:hover, .mlh {
+ border-color:#879eb4;
+ background-image:url('gradient-button-hover.png');
+}
+.morelink a {
+ display:block;
+ width:100%;
+ color:#369;
+}
+.morelink:hover a {
+ color:white;
+}
+.morelink .nub {
+ position:absolute;
+ top:-1px;
+ right:-1px;
+ height:31px;
+ width:24px;
+ background:white none no-repeat scroll center left;
+ background-image:url('sprite.png');
+ background-position:-4px -4px;
+}
+.morelink:hover .nub, .mlhn {
+ background-image:url('sprite.png');
+ background-position:-4px -43px;
+}
\ No newline at end of file
diff --git a/popup.html b/popup.html
index 630a3a0..7777d0c 100644
--- a/popup.html
+++ b/popup.html
@@ -2,398 +2,8 @@
-
-
+
+
diff --git a/popup.js b/popup.js
new file mode 100644
index 0000000..70a45f1
--- /dev/null
+++ b/popup.js
@@ -0,0 +1,233 @@
+var db = openDatabase('mhdb', '1.0', 'Mostly Harmless Database', 5 * 1024 * 1024);
+var cacheTime;
+var over18;
+init();
+
+function init() {
+ if(window.localStorage.getItem('installed') !== 'true') {
+ installDefaults();
+ }
+ db.transaction(function(tx){
+ tx.executeSql('SELECT * FROM prefs WHERE pref=?', ['cacheTime'], function(tx, results) {
+ cacheTime = results.rows.item(0).choice;
+ });
+ tx.executeSql('SELECT * FROM prefs WHERE pref=?', ['over18'], function(tx, results) {
+ over18 = results.rows.item(0).choice;
+ });
+ });
+}
+chrome.tabs.getSelected(undefined, function(currTab) {
+ buildPage(currTab.url);
+});
+function buildPage(pageUrl) {
+ db.transaction(function(tx){
+ tx.executeSql('SELECT * FROM posts WHERE url=?', [pageUrl], function(tx, results) {
+ document.getElementById('posts').setAttribute('data-modhash',results.rows.item(0).modhash);
+ document.getElementById('posts').setAttribute('data-url',pageUrl);
+ var children = results.rows;
+ var now = new Date();
+ for(var i = 0; i < children.length; i++) {
+ var data = children.item(i);
+ var entry = document.createElement('li');
+ entry.id = data.name;
+ if (data.likes === 'true') entry.setAttribute('data-dir','1');
+ if (data.likes === null) entry.setAttribute('data-dir','0');
+ if (data.likes === 'false') entry.setAttribute('data-dir','-1');
+ var votes = document.createElement('div');
+ votes.className = 'votes';
+ var upmod = document.createElement('a');
+ upmod.className = 'upmod';
+ upmod.addEventListener('click',upmodPost);
+ votes.appendChild(upmod);
+ var count = document.createElement('span');
+ count.className = 'count';
+ count.id = 'count_' + data.name;
+ count.innerHTML = data.score;
+ count.title = data.ups + ' up votes, ' + data.downs + ' down votes';
+ votes.appendChild(count);
+ var downmod = document.createElement('a');
+ downmod.className = 'downmod';
+ downmod.id = 'down_' + data.name;
+ votes.appendChild(downmod);
+ entry.appendChild(votes);
+ var thumblink = document.createElement('a');
+ thumblink.className = 'thumblink';
+ thumblink.href = 'http://www.reddit.com' + data.permalink;
+ thumblink.target = '_blank';
+ thumblink.title = 'View this submission on reddit';
+ var thumb = document.createElement('img');
+ thumb.className = 'thumb';
+ data.thumbnail.indexOf('/') === 0 ? thumb.src = 'http://www.reddit.com' + data.thumbnail : thumb.src = data.thumbnail;
+ thumb.alt = data.title;
+ thumblink.appendChild(thumb);
+ entry.appendChild(thumblink);
+ var post = document.createElement('div');
+ post.className = 'post';
+ var link = document.createElement('a');
+ link.className = 'link';
+ link.href = 'http://www.reddit.com' + data.permalink;
+ link.target = '_blank';
+ link.innerHTML = data.title;
+ link.title = 'View this submission on reddit';
+ post.appendChild(link);
+ var space = document.createTextNode(' ');
+ post.appendChild(space);
+ var domain = document.createElement('a');
+ domain.className = 'domain';
+ domain.href = 'http://www.reddit.com/domain/' + data.domain + '/';
+ domain.target = '_href';
+ domain.innerHTML = '(' + data.domain + ')';
+ post.appendChild(domain);
+ var meta = document.createElement('div');
+ meta.className = 'meta';
+ var timestamp = document.createElement('span');
+ timestamp.className = 'timestamp';
+ timestamp.innerHTML = 'submitted ' + prettyDate(ISODateString(new Date(data.created_utc * 1000)));
+ meta.appendChild(timestamp);
+ var by = document.createTextNode(' by ');
+ meta.appendChild(by);
+ var submitter = document.createElement('a');
+ submitter.className = 'submitter';
+ submitter.href = 'http://www.reddit.com/user/' + data.author + '/';
+ submitter.target = '_blank';
+ submitter.innerHTML = data.author;
+ meta.appendChild(submitter);
+ var to = document.createTextNode(' to ');
+ meta.appendChild(to);
+ var subreddit = document.createElement('a');
+ subreddit.className = 'subreddit';
+ subreddit.href = 'http://www.reddit.com/r/' + data.subreddit + '/';
+ subreddit.target = '_blank';
+ subreddit.innerHTML = data.subreddit;
+ meta.appendChild(subreddit);
+ post.appendChild(meta);
+ var actions = document.createElement('div');
+ actions.className = 'actions';
+ var comments = document.createElement('a');
+ comments.className = 'comments';
+ comments.href = 'http://www.reddit.com' + data.permalink;
+ comments.target = '_blank';
+ comments.innerHTML = data.num_comments + ' comments';
+ actions.appendChild(comments);
+ post.appendChild(actions);
+ var share = document.createElement('a');
+ share.className = 'share';
+ share.innerHTML = 'share';
+ actions.appendChild(share);
+ var save = document.createElement('a');
+ save.className = 'save';
+ save.innerHTML = data.saved === 'true' ? 'saved' : 'save';
+ actions.appendChild(save);
+ var hide = document.createElement('a');
+ hide.className = 'hide';
+ if(data.hidden === 'true') {
+ entry.className += ' hidden';
+ hide.innerHTML = 'unhide'
+ } else {
+ hide.innerHTML = 'hide';
+ }
+ actions.appendChild(hide);
+ var report = document.createElement('a');
+ report.className = 'report';
+ report.innerHTML = 'report';
+ actions.appendChild(report);
+ entry.appendChild(post);
+ document.getElementById('posts').appendChild(entry);
+ }
+ document.getElementById('submit').href = 'http://www.reddit.com/submit?url=' + encodeURI(document.getElementById('posts').getAttribute('data-url'));
+ });
+ });
+}
+
+function upmodPost() {
+ var formData = new FormData();
+ var listItem = this.parentNode.parentNode;
+ formData.append('id',listItem.id);
+ formData.append('uh',document.getElementById('posts').getAttribute('data-modhash'));
+ var voteWas = this.parentNode.parentNode.getAttribute('data-dir');
+ var voteCount = document.getElementById('count_' + listItem.id)
+ if(voteWas === '1') formData.append('dir','0');
+ if(voteWas === '0') formData.append('dir','1');
+ if(voteWas === '-1') formData.append('dir','1');
+ var api = new XMLHttpRequest();
+ api.open('POST','http://www.reddit.com/api/vote',false);
+ api.send(formData);
+ db.transaction(function(tx) {
+ if (api.statusText === 'OK') {
+ if(voteWas === '1') {
+ listItem.setAttribute('data-dir','0');
+ tx.executeSql('UPDATE posts SET likes=? WHERE name=?', [null, listItem.id]);
+ }
+ if(voteWas === '0') {
+ listItem.setAttribute('data-dir','1');
+ tx.executeSql('UPDATE posts SET likes=? WHERE name=?', ['true', listItem.id]);
+ }
+ if(voteWas === '-1') {
+ listItem.setAttribute('data-dir','1');
+ tx.executeSql('UPDATE posts SET likes=? WHERE name=?', ['true', listItem.id]);
+ }
+ voteCount.title = 'Voted!';
+ } else {
+ console.error('Error voting.\n' + api.statusText);
+ console.warn(api);
+ return false;
+ }
+ });
+}
+
+
+/*
+ * JavaScript Pretty Date
+ * Thanks to Dean Landolt's comment on
+ * http://ejohn.org/blog/javascript-pretty-date/#postcomment
+ */
+// Takes an ISO time and returns a string representing how
+// long ago the date represents.
+function prettyDate(date_str){
+ var time = ('' + date_str).replace(/-/g,"/").replace(/[TZ]/g," ");
+ var seconds = (new Date - new Date(time)) / 1000;
+ var token = 'ago', list_choice = 1;
+ if (seconds < 0) {
+ seconds = Math.abs(seconds);
+ token = 'from now';
+ list_choice = 2;
+ }
+ var i = 0, format;
+ while (format = time_formats[i++]) if (seconds < format[0]) {
+ if (typeof format[2] == 'string')
+ return format[list_choice];
+ else
+ return Math.floor(seconds / format[2]) + ' ' + format[1] + ' ' + token;
+ }
+ return time;
+};
+var time_formats = [
+ [60, 'just now', 1], // 60
+ [120, '1 minute ago', '1 minute from now'], // 60*2
+ [3600, 'minutes', 60], // 60*60, 60
+ [7200, '1 hour ago', '1 hour from now'], // 60*60*2
+ [86400, 'hours', 3600], // 60*60*24, 60*60
+ [172800, 'yesterday', 'tomorrow'], // 60*60*24*2
+ [604800, 'days', 86400], // 60*60*24*7, 60*60*24
+ [1209600, 'last week', 'next week'], // 60*60*24*7*4*2
+ [2419200, 'weeks', 604800], // 60*60*24*7*4, 60*60*24*7
+ [4838400, 'last month', 'next month'], // 60*60*24*7*4*2
+ [29030400, 'months', 2419200], // 60*60*24*7*4*12, 60*60*24*7*4
+ [58060800, 'last year', 'next year'], // 60*60*24*7*4*12*2
+ [2903040000, 'years', 29030400], // 60*60*24*7*4*12*100, 60*60*24*7*4*12
+ [5806080000, 'last century', 'next century'], // 60*60*24*7*4*12*100*2
+ [58060800000, 'centuries', 2903040000] // 60*60*24*7*4*12*100*20, 60*60*24*7*4*12*100
+];
+
+/*
+ * ISO 8601 Formatted Dates
+ * Gotten from the Mozilla Developer Center
+ */
+function ISODateString(d){
+ function pad(n){return n<10 ? '0'+n : n}
+ return d.getUTCFullYear()+'-'
+ + pad(d.getUTCMonth()+1)+'-'
+ + pad(d.getUTCDate())+'T'
+ + pad(d.getUTCHours())+':'
+ + pad(d.getUTCMinutes())+':'
+ + pad(d.getUTCSeconds())+'Z'}
\ No newline at end of file