Skip to content

Instantly share code, notes, and snippets.

@958
Last active September 28, 2015 13:38
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save 958/1446456 to your computer and use it in GitHub Desktop.
Save 958/1446456 to your computer and use it in GitHub Desktop.
[keysnail]gpumnail
// Info
let PLUGIN_INFO =
<KeySnailPlugin>
<name>gpumnail</name>
<description>Manipulate gpum with KeySnail</description>
<updateURL>https://gist.github.com/958/1446456/raw/gpum.ks.js</updateURL>
<author>958</author>
<version>0.0.4</version>
<license>MIT</license>
<include>main</include>
<detail lang="ja"><![CDATA[
=== 使い方 ===
KeySail で gpum を操作したり、未読メールを KeySnail の prompt 上で閲覧したりできます
gpum のプレビューウィンドウを、キーボードで操作することも可能です
ext.exec('gpum-show-unread-list') して、p J K n N O とかしてみてください
gpum - Google mail Popup Unread Manager :: Add-ons for Firefox
https://addons.mozilla.org/ja/firefox/addon/gpum/
]]></detail>
</KeySnailPlugin>;
// Option
let pOptions = plugins.setupOptions("gpum", {
'keymap': {
preset: {
"C-z" : "prompt-toggle-edit-mode",
"SPC" : "prompt-next-page",
"b" : "prompt-previous-page",
"j" : "prompt-next-completion",
"k" : "prompt-previous-completion",
"g" : "prompt-beginning-of-candidates",
"G" : "prompt-end-of-candidates",
"q" : "prompt-cancel",
// gpum specific actions
"p" : "preview-open",
"J" : "preview-scroll-down",
"K" : "preview-scroll-up",
"L" : "preview-scroll-right",
"H" : "preview-scroll-left",
"P" : "preview-close",
"n" : "select-next-link-in-preview",
"N" : "select-prev-link-in-preview",
"O" : "open-selected-link-in-preview",
"r" : "mark-as-read",
"S" : "mark-as-spam",
"D" : "delete",
"a" : "archive",
"s" : "star",
"o" : "open",
"C" : "compose-gmail",
"M" : "gmail",
},
description: M({
ja: "メイン画面の操作用キーマップ",
en: "Local keymap for manipulation"
})
},
"preview_scroll_point": {
preset: 100,
description: M({
ja: "プレビューのスクロール量",
en: "Scroll point in preview window"
})
},
}, PLUGIN_INFO);
function createUnreads() {
if (gpum.gmail.unreads.length == 0) return null;
let unreads = gpum.gmail.unreads;
let collection = unreads.map(function(item) [
gpum.modules.Gmail.getThreadIdFromThreadURI(item.entry.select('link').attr('href')),
item.entry.select('author>name').text,
item.entry.select('title').text,
item.entry.select('summary').text,
item.time.toLocaleDateString(),
item.entry.select('link').attr('href')
]);
function destroy(entry) {
collection.splice(entry.index, 1);
gpum.gmail.removeFromUnreads(unreads[entry.index]);
if (collection.length == 0)
collection.push([null, 'Empty ...', '', '', '', '']);
prompt.refresh();
}
return {
get collection() {
return collection
},
filter: function (aIndex)
(aIndex < 0 || !collection[aIndex][0]) ? [null] : [{
index: aIndex,
id: collection[aIndex][0],
from: collection[aIndex][1],
title: collection[aIndex][2],
summary: collection[aIndex][3],
date: collection[aIndex][4],
link: collection[aIndex][5],
}],
open: function(entry) {
if (!entry) return;
openUILinkIn(entry.link, 'tab');
},
preview: function(entry) {
if (!entry) return;
preview.open(entry);
if (gpum.modules.util.getBoolPref(gpum.modules.util.getPrefKey("markAsReadOnPreview"), false)) {
gpum.gmail.markAsReadThread(entry.id);
destroy(entry);
}
},
markAsRead: function(entry) {
if (!entry) return;
gpum.gmail.markAsReadThread(entry.id);
destroy(entry);
},
markAsSpam: function(entry) {
if (!entry) return;
gpum.gmail.spamThread(entry.id);
destroy(entry);
},
deleteThread: function(entry) {
if (!entry) return;
gpum.gmail.deleteThread(entry.id);
destroy(entry);
},
archiveThread: function(entry) {
if (!entry) return;
gpum.gmail.archiveThread(entry.id);
destroy(entry);
},
starThread: function(entry) {
if (!entry) return;
gpum.gmail.starThread(entry.id);
//destroy(entry);
},
};
};
let preview = (function(){
let popup = document.getElementById('gpum-popup4preview');
let iframe = document.getElementById('gpum-popup4preview-frame');
let title = document.getElementById('gpum-popup4preview-header-title');
function searchLink(win, sel, pos) {
let links = self.links;
if (links.length == 0) return null;
let elem;
if (sel.rangeCount > 0) {
let (range = sel.getRangeAt(0)) {
let beforeElem;
if (range && range.startContainer)
beforeElem = range.startContainer;
if (beforeElem) {
let rect = beforeElem.getBoundingClientRect();
if (rect.top >= -1 && rect.top <= win.innerHeight) {
let cur = links.indexOf(beforeElem);
elem = (links[cur+pos]) ? links[cur+pos] : links[(pos > 0) ? 0 : links.length - 1];
}
}
}
}
if (!elem) {
let result = links.filter(function(link) {
let rect = link.getBoundingClientRect();
return (rect.top >= 0 && rect.top <= win.innerHeight);
});
elem = (pos > 0) ? result[0] : result[result.length - 1];
}
return elem;
}
function scrollToElem(sel, elem) {
let (range = elem.ownerDocument.createRange()) {
range.selectNodeContents(elem);
sel.removeAllRanges();
sel.addRange(range);
}
sel.QueryInterface(Ci.nsISelection2 || Ci.nsISelectionPrivate).scrollIntoView(
Ci.nsISelectionController.SELECTION_ANCHOR_REGION,
true, -1, -1);
}
let self = {
open: function(entry) {
// from gpum.js
let (url = gpum.gmail.getThreadBodyURL(entry.id)) {
iframe.setAttribute("src", "about:blank");
title.textContent = "Loading ... " + entry.title;
gpum.gmail.getPrintPageURLAnd(entry.id, function (url) {
title.textContent = entry.title;
iframe.setAttribute("src", url);
});
title.setAttribute("url", entry.link.toString());
popup.openPopup(null, "bottomcenter topright");
}
},
close: function()
gpum.closePreview(),
scrollDown: function(entry) {
if (popup.state != 'open') return;
iframe.contentWindow.scrollBy(0, pOptions['preview_scroll_point']);
},
scrollUp: function(entry) {
if (popup.state != 'open') return;
iframe.contentWindow.scrollBy(0, -pOptions['preview_scroll_point']);
},
scrollLeft: function(entry) {
if (popup.state != 'open') return;
iframe.contentWindow.scrollBy(-pOptions['preview_scroll_point'], 0);
},
scrollRight: function(entry) {
if (popup.state != 'open') return;
iframe.contentWindow.scrollBy(pOptions['preview_scroll_point'], 0);
},
scrollToTop: function(entry) {
if (popup.state != 'open') return;
iframe.contentWindow.scrollTo(0, 0);
},
scrollToBottom: function(entry) {
if (popup.state != 'open') return;
iframe.contentWindow.scrollTo(0, Math.max(iframe.contentDocument.documentElement.scrollHeight,
iframe.contentDocument.body.scrollHeight));
},
get links() {
return Array.slice(iframe.contentDocument.querySelectorAll('a'));
},
focusNextLink: function() {
if (popup.state != 'open') return;
let win = iframe.contentWindow;
let sel = win.getSelection();
let elem = searchLink(win, sel, 1);
if (elem)
scrollToElem(sel, elem);
},
focusPreviousLink: function() {
if (popup.state != 'open') return;
let win = iframe.contentWindow;
let sel = win.getSelection();
let elem = searchLink(win, sel, -1);
if (elem)
scrollToElem(sel, elem);
},
openLink: function() {
if (popup.state != 'open') return;
let sel = iframe.contentWindow.getSelection();
if (sel.rangeCount > 0) {
let (range = sel.getRangeAt(0)) {
if (range && range.startContainer && range.startContainer.href)
openUILinkIn(range.startContainer.href, 'tabshifted');
}
}
}
};
return self;
})();
// Add ext
plugins.withProvides(function(provide){
provide('gpum-show-unread-list', function(ev, arg){
if (!window.document.getElementById('gpum-popup')) return;
if (!gpum.gmail.isLoggedIn) {
ext.exec('gpum-login');
return;
}
let unreads = createUnreads();
if (!unreads) return;
prompt.selector({
message : 'Unreads :',
collection : unreads.collection,
flags : [HIDDEN | IGNORE, 0, 0, 0, 0, HIDDEN | IGNORE],
header : ['From', 'Title', 'Summary', 'Date'],
style : [0, 0, style.prompt.description, 0],
width : [10, 40, 40, 10],
keymap : pOptions['keymap'],
onFinish : preview.close,
filter : unreads.filter,
actions : [
[unreads.open,
M({ja:"メールを Gmail で開く", en:"Open"}), "open"],
[unreads.preview,
M({ja:"プレビューを開く", en:"Preview"}), "preview-open,c"],
[preview.close,
M({ja:"プレビューを閉じる", en:"Close preview"}), "preview-close,c"],
[preview.scrollDown,
M({ja:"プレビューを下へスクロール", en:"Preview scroll down"}), "preview-scroll-down,c"],
[preview.scrollUp,
M({ja:"プレビューを上へスクロール", en:"Preview scroll up"}), "preview-scroll-up,c"],
[preview.scrollLeft,
M({ja:"プレビューを左へスクロール", en:"Preview scroll left"}), "preview-scroll-left,c"],
[preview.scrollRight,
M({ja:"プレビューを右へスクロール", en:"Preview scroll right"}), "preview-scroll-right,c"],
[preview.scrollToTop,
M({ja:"プレビューを先頭へスクロール", en:"Preview beginning of candidates"}), "preview-beginning-of-candidates,c"],
[preview.scrollToBottom,
M({ja:"プレビューを末尾へスクロール", en:"Preview end of candidates"}), "preview-end-of-candidates,c"],
[function() {
preview.focusNextLink();
}, M({ja:"プレビュー内の次のリンクを選択する", en:"Select next link in the preview"}), "select-next-link-in-preview,c"],
[function() {
preview.focusPreviousLink();
}, M({ja:"プレビュー内の前のリンクを選択する", en:"Select previous link in the preview"}), "select-prev-link-in-preview,c"],
[function() {
preview.openLink();
}, M({ja:"プレビュー内の選択されているリンクを開く", en:"Open selected link in the preview"}), "open-selected-link-in-preview,c"],
[unreads.markAsRead,
M({ja:"既読にする", en:"Mark as read"}), "mark-as-read,c"],
[unreads.markAsSpam,
M({ja:"スパム報告", en:"Mark as spam"}), "mark-as-spam,c"],
[unreads.deleteThread,
M({ja:"削除する", en:"Delete"}), "delete,c"],
[unreads.archiveThread,
M({ja:"アーカイブする", en:"Archive"}), "archive,c"],
[unreads.starThread,
M({ja:"スターを付ける", en:"Star"}), "star,c"],
[function() {
ext.exec('gpum-compose-mail');
preview.close();
}, M({ja:"メールを作成する", en:"Compose mail"}), "compose-gmail"],
[function() {
openUILinkIn(gpum.gmail.mailURL, 'tab');
preview.close();
}, M({ja:"Gmail を開く", en:"Gmail"}), "gmail"],
]
});
}, M({en:'gpum - Show unread list', ja:'gpum - 新着メールを表示'}));
provide('gpum-check-new-mail', function(ev, arg) {
if (!gpum.gmail.isLoggedIn) {
ext.exec('gpum-login');
return;
}
gpum.checkMailNow();
}, M({en:'gpum - Check new mail', ja:'gpum - 新着メールを確認'}));
provide('gpum-compose-mail', function(ev, arg) {
if (!gpum.gmail.isLoggedIn) {
ext.exec('gpum-login');
return;
}
openUILinkIn(gpum.gmail.composeURL, 'tab');
}, M({en:'gpum - Compose mail', ja:'gpum - 新規メールを作成'}));
provide('gpum-login', function(ev, arg) {
// from gpum.js
let logins = gpum.modules.Gmail.getLogins().filter(function (l) l.username && l.password);
if (logins.length <= 0) return;
let collection = [];
for (let [, { username, password }] in Iterator(logins))
collection.push([username, password]);
prompt.selector({
message : 'Select login user :',
collection : collection,
flags : [0, HIDDEN | IGNORE],
callback : function(aIndex) {
if (collection[aIndex][1])
gpum.login(collection[aIndex][0], collection[aIndex][0]);
else
gmail.openLoginPage();
}
});
}, M({en:'gpum - Login', ja:'gpum - ログイン'}));
provide('gpum-logout', function(ev, arg) {
gpum.logout();
}, M({en:'gpum - Logout', ja:'gpum - ログアウト'}));
provide('gpum-open-config', function(ev, arg) {
gpum.openConfig();
}, M({en:'gpum - Open config', ja:'gpum - 設定画面を表示'}));
provide('gpum-close-preview', function(ev, arg) {
preview.close();
}, M({en:'gpum - Close preview', ja:'gpum - プレビューを閉じる'}));
}, PLUGIN_INFO);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment