forked from vimpr/vimperator-plugins
-
Notifications
You must be signed in to change notification settings - Fork 0
/
gvimail.js
165 lines (159 loc) · 8.17 KB
/
gvimail.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
/**
*
* ==VimperatorPlugin==
* @name GViMail
* @description Make Gmail behave like Vim
* @author Mahefa Randimbisoa (DotMG) <dotmg@users.sourceforge.net>
* @license GPL 2.0
* @requires Vimperator 2.3pre
* @url http://code.google.com/p/gvimail/
* @version 0.1
* ==/VimperatorPlugin==
*
* Mappings:
* zf: re-give focus to the main frame.
* zR: Opens all folds.
* zM: Closes all folds.
*/
(function(){
// Set use_gmail_v1 to false if you don't use the older version of Gmail at all.
// Support of the older version of Gmail is very limited.
var use_gmail_v1 = true;
// Set use_gmail_v2 to false if you don't use the version 2 of Gmail.
var use_gmail_v2 = true;
// If you have installed stylechanger.js and want to use the Vimish style, set the option below to true.
// If you didn't yet get the gvimail.css, download it from http://code.google.com/p/gvimail/source/browse/trunk/colors/GVimail.css
// and put it in ~/.vimperator/colors (or %HOMEPATH\vimperator\colors)
var use_gvimail_css = false;
var GViMail = {
modes:config.browserModes || [modes.NORMAL],
/// get the iframe object that contains all the visible items. This should always get focus.
getMainCanvas : function()
{ // It is simpler to find the main canvas in Gmail v2, (id='canvas_frame')
var canvas_frame = window.content.document.getElementById('canvas_frame');
if (canvas_frame) return (canvas_frame);
if (use_gmail_v1)
{// On older versions of Gmail, The main canvas is the iframe that has the attribute left: 0pt
return (util.evaluateXPath('//iframe[contains(@style, "left: 0pt")]', window.content.frames[0].document, null, true).iterateNext());
}
return null;
},
/// Execute an action by simulating a click on an image. It has 2 params: the classname (for Gmail v2)
/// or a part of the src attribute of the img element (for Gmail v1)
clickImage : function (classnamev2, imgsrcv1)
{
var elem = util.evaluateXPath('//*[contains(concat(" ", @class, " "), " '+classnamev2+' ")] | //img[contains(@src, "'+imgsrcv1+'")]', GViMail.getMainCanvas().contentDocument, null, true).iterateNext();
// hmm, the code below generates a log: Invalid argument for followLink.
buffer.followLink(elem, liberator.CURRENT_TAB);
},
/// Gives focus to the main Canvas, to make all keys working well.
focusMainFrame:function ()
{
GViMail.getMainCanvas().contentWindow.focus();
},
/// On TabSelect (if Gmail Tab), we will give focus to the main canvas.
get isGmail () (/^https?:\/\/mail\.google\.com\//.test(buffer.URL)),
/// when you type some key to make an action, habitually, the main canvas looses focus.
/// we will add an EventListener on keypress to avoid this.
preventLooseFocus:function()
{
if (liberator.mode == modes.NORMAL
&& !liberator.mode.isRecording
&& !(modes.extended & modes.MENU)
&& !modes.passNextKey
&& !modes.passAllKeys)
{
GViMail.focusMainFrame();
}
}
};
mappings.addUserMap(GViMail.modes, ["zM"],
"Closes all fold",
function () { GViMail.clickImage('Dm2exe', 'collapse_icon'); });
mappings.addUserMap(GViMail.modes, ["zR"],
"Opens all fold",
function () { GViMail.clickImage('kPoXId', 'expand_icon'); });
// Let's build the Gmail(v2)-custom hinttags. Follow the comments to understand.
var gmail_v2_hinttags =
"//span[@selector]"
// Menu Settings, Older version, Compose Mail, Inbox, Starred .. Contacts, Labels, turn on/off chat
// The [not(ancestor::tr//td[@class='mka4te'])] is to avoid interferring with //td[@class='mka4te']/ancestor::tr/td[5], see Select message in the list below
+ " | //span[@role='link'][not(ancestor::tr//td[@class='mka4te'])]"
// Refresh, Back to "label", Reply to all, Forward, Filter messages like this, ...
// You could just use //div[@act] here, but there appears 4 unwanted hints when first-viewing a message
+ " | //div[@act][not(ancestor::div[contains(concat(' ', @class, ' '), ' zWKgkf ')]) or (ancestor::div[contains(concat(' ', @class, ' '), ' zWKgkf ') and contains(@style, 'visibility')])]"
// More actions, Toolbar buttons on RTE (don't use RTE, plain ascii mails are sexier)
+ " | //*[@unselectable='on']"
// Fold and UnFold messages in thread that has an excerpt displayed in grey
+ " | //div[contains(concat(' ', @class, ' '), ' IUCKJe ')]"
// UnFold messages in thread when no excerpt is displayed (blank line)
// Such <div>s have a class XoqCub, have another <div> child having the class YrHFdf, and there is no table il all their descendants
+ " | //*[contains(concat(' ', @class, ' '), ' XoqCub ')]/div[@class='YrHFdf'][count(descendant-or-self::table)=0]"
// Star on message list
+ " | //td[@class='mka4te']/img"
// Star on thread list (same subject)
+ " | //td/span[starts-with(@class, 'lHQn1d')]/img"
// Delete all spam messages now
+ " | //*[@class='rj1J6b'"
// Invite x@y.z to Gmail.
+ " or @class='YCDlS'"
// When you delete any message in a thread view, there are links saying "n deleted messages in this conversation. View message or delete forever."
+ " or @class='u1T3K' or @class='iVE0ue'"
// Hide filter options (settings)
+ " or @class='u7uAnb']"
// Select message in the list
+ " | //td[@class='mka4te']/ancestor::tr/td[5]"
// Change picture [Settings] ==> next step still not working
+ " | //div[@class='c3pyI']/span"
// Attach a file + Add event invitation + Rich formatting|Plain text
+ " | //*[contains(concat(' ', @class, ' '), ' MRoIub ')]"
// Check spelling
+ " | //span[@class='mrKIf']"
// Everything that is displayed as image (+ Edit labels)
+ " | //img[contains(@src, 'cleardot.gif')]"
// Reply + Reply to all + Forward + show/hide details + Edit labels
// We will not select divs that contains any hintable elements inside
+ " | //*[@idlink][count(descendant-or-self::span[@role='link'])=0 and count(descendant-or-self::a)=0]"
// <label>|x
+ " | //table[@class='Ir5Jyf']//span"
// Settings> Accounts> make_default|edit_info|delete|View_history|Check_mail_now
+ " | //*[contains(concat(' ', @class, ' '), ' GaVz0 ')]"
// Update conversation, Ignore (when someone just posted a message on the thread you're reading & editing)
+ " | //*[contains(concat(' ', @class, ' '), ' Gf76kb ')]"
+ " | //*[contains(concat(' ', @class, ' '), ' GRpVjf ')]" //Recently changed to this ...
// Show|Hide quoted text
+ " | //span[contains(concat(' ', @class, ' '), ' WQ9l9c ')]"
//
+ " | //div[contains(concat(' ', @class), ' goog-menuitem')]";
// We provide limited support for Gmail(v1)
var gmail_v1_hinttags =
"//*[contains(@class, 'lk ') or @class='msc' or @class='ll' or @class='setl' or @class='lkw' or starts-with(@class, 'sc ')] | //tr[@class='rr' or @class='ur']/td[position()=5] | //div/span[contains(@class, 'bz_rbbb')] | //span[@class='l' and contains(@id, 'sl_')]" ;
var gmail_hints = use_gmail_v1 ? gmail_v1_hinttags : "";
if (use_gmail_v2) gmail_hints = gmail_hints + (gmail_hints ? " | " : "") + gmail_v2_hinttags;
gmail_hints = gmail_hints + (gmail_hints ? " | " : "") + options['hinttags'];
// Now: override default hinttags. Override is not the true wording, I'd rather say extend.
/*options.add(["hinttags", "ht"],
"XPath string of hintable elements activated by 'f' and 'F'",
// Gmail uses span[@selector] for labels in the line Select: All, None, Read, Unread, Starred, Unstarred
"string",
gmail_hints);*/
// This is not the most elegant solution to do this, but I don't manage to find the correct one myself...
options.get("hinttags").value=gmail_hints;
// When navigation keys (and others) no longer work, type zf to focus to the main frame
mappings.addUserMap(GViMail.modes, ["zf"],
"Focus main frame",
function () { GViMail.focusMainFrame(); });
getBrowser().mTabBox.addEventListener('TabSelect', function(event){
if (GViMail.isGmail)
window.setTimeout(function(){GViMail.focusMainFrame();}, 100);
}, false);
window.addEventListener('keypress', function () {
if (GViMail.isGmail)
GViMail.preventLooseFocus();
}, true);
if (use_gvimail_css && (typeof liberator.globalVariables.styles == 'undefined' || liberator.globalVariables.styles == ''))
{
liberator.globalVariables.styles = 'style,gvimail';
}
})();
// vim:noet: