Skip to content

Instantly share code, notes, and snippets.

@anekos
Last active August 29, 2015 14:07
Show Gist options
  • Save anekos/d0f80263bc3def842ddb to your computer and use it in GitHub Desktop.
Save anekos/d0f80263bc3def842ddb to your computer and use it in GitHub Desktop.
feedeen.com for vimperator
(function () {
let A = Array.slice;
const selectors = {
selectedEntry: '.fd_focus',
currentFeedTitle: '.fd_current_feed_title',
feeds: '.fd_feed',
feedTitle: '.fd_feed_title',
feedEntryCount: '.fd_feed_count'
};
function httpRequest (uri, data, onComplete) {
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function () {
if (xhr.readyState == 4) {
if (xhr.status == 200)
onComplete && onComplete(xhr);
else
liberator.echoerr(xhr.statusText);
}
};
xhr.open(data ? 'POST' : 'GET', uri, !!onComplete);
xhr.send(data || null); // XXX undefined を渡すのはまずいのかな
return xhr;
}
const api = {
matchingUrls: new RegExp('^https?://www\.feedeen\.com/'),
get doc () content.document,
get selectedEntry () api.doc.querySelector(selectors.selectedEntry),
get selectedEntryInfo () {
// let entry = api.doc.querySelector('.fd_expanded');
let entry = api.selectedEntry;
return {
url: entry.querySelector('.fd_url').href,
title: entry.querySelector('.fd_title').textContent,
siteurl: entry.querySelector('.fd_siteurl').href,
sitename: entry.querySelector('.fd_sitename').textContent
};
},
get currentFeedTitle () api.doc.querySelector(selectors.currentFeedTitle).textContent,
getFeeds: function (unread) {
function extractFeedInfo (feed, i) {
return feed && {
id:
let (id = feed.querySelector('[spin-action-data]'))
(id && parseInt(id.getAttribute('spin-action-data').replace(/^.*?:/, ''), 10)),
element: feed,
title: feed.querySelector(selectors.feedTitle).textContent,
count:
let (count = feed.querySelector(selectors.feedEntryCount))
((count && !count.getAttribute('style', '').match(/none/i)) ? parseInt(count.textContent, 10) : 0)
};
}
function bindIndex (info, i) {
info.index = i;
}
let title = api.currentFeedTitle;
let result = A(api.doc.querySelectorAll(selectors.feeds)).map(extractFeedInfo);
if (unread)
result = result.filter(function (it) (it.title == title || it.count > 0));
result.forEach(bindIndex);
return result;
},
getCurrentFeedInfo: function (unread) {
let title = api.currentFeedTitle;
return api.getFeeds(unread).filter(function (it) it.title === title)[0];
},
get groups () {
return A(api.doc.querySelectorAll('[data-node-id^=g]')).map(function(it) {
return {
id: it.getAttribute('data-node-id').replace(/^g/, ''),
name: it.previousSibling.textContent
}
});
},
openSelectedEntry: function () {
liberator.open(api.selectedEntryInfo.url, liberator.NEW_BACKGROUND_TAB);
},
switchFeed: function (feed) {
feed.element.scrollIntoView();
return buffer.followLink(feed.element.querySelector('span'), liberator.CURRENT_TAB);
},
goNextFeed: function (unread) {
let current = api.getCurrentFeedInfo(unread);
let feeds = api.getFeeds(unread);
let next = feeds[current.index + 1];
if (next)
api.switchFeed(next);
},
goPreviousFeed: function (unread) {
let current = api.getCurrentFeedInfo(unread);
let feeds = api.getFeeds(unread);
let previous = feeds[current.index - 1];
if (previous)
api.switchFeed(previous);
},
readItLater: function () {
let info = api.selectedEntryInfo;
plugins.readitlater.API.add(
info.url,
info.title,
function () {
liberator.echomsg('Read it later: ' + info.title + ' - ' + info.url);
}
);
},
changeFeedGroups: function (feed, groupIds) {
window.alert('https://www.feedeen.com/subscriptions/' + feed.id);
httpRequest(
'https://www.feedeen.com/subscriptions/' + feed.id,
JSON.stringify({
name: 's' + feed.title,
favicon: "shttp://subtech.g.hatena.ne.jp/images/group/subtech/favicon.ico",
groups: {
'29517': {position: 's0'}
}
}),
function (e) {
window.alert('onComplet: ' + e);
}
);
}
};
liberator._feedeen = __context__.api = api;
let subCommands = [
{name: 'nextfeed', actionName: 'goNextFeed'},
{name: 'prevfeed', actionName: 'goPreviousFeed'},
{name: 'readitlater', actionName: 'readItLater'},
{name: 'open', actionName: 'openSelectedEntry'},
{
name: 'go',
action: function (args) {
for (let [, feed] in Iterator(api.getFeeds()))
if (args.literalArg == feed.title)
return api.switchFeed(feed);
},
completer: function (context) {
context.title = ['Feed name', 'Feed name'];
context.completions = [
[feed.title, feed.title]
for ([, feed] in Iterator(api.getFeeds(true)))
];
}
}
];
commands.addUserCommand(
['feedeen'],
'feedeen.com',
function () {
},
{
subCommands: [
(function (cmd)
new Command(
[cmd.name],
cmd.description || cmd.name,
cmd.actionName ? function (args) api[cmd.actionName](args.bang) : cmd.action,
{completer: cmd.completer, literal: 0, bang: true}
)
)(cmd)
for ([, cmd] in Iterator(subCommands))
]
},
true // replace
);
})();
" feedSomeKeys_3.js
fmaps -u='https?://www.feedeen.com/d' -events=vkeydown j k
fmaps -u='https?://www.feedeen.com/d' -events=keydown,keypress J,<Space> K,<S-Space>
nnoremap -urls='^https?:\/\/www.feedeen.com\/' s :<C-u>feedeen nextfeed!<CR>
nnoremap -urls='^https?:\/\/www.feedeen.com\/' a :<C-u>feedeen prevfeed!<CR>
nnoremap -urls='^https?:\/\/www.feedeen.com\/' S :<C-u>feedeen nextfeed<CR>
nnoremap -urls='^https?:\/\/www.feedeen.com\/' A :<C-u>feedeen prevfeed<CR>
nnoremap -urls='^https?:\/\/www.feedeen.com\/' p :<C-u>feedeen readitlater<CR>
nnoremap -urls='^https?:\/\/www.feedeen.com\/' v :<C-u>feedeen open<CR>
nnoremap -urls='^https?:\/\/www.feedeen.com\/' b :<C-u>feedeen go<Space>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment