From d9e18b8f8151c65b02fcf2929d14982d2433b693 Mon Sep 17 00:00:00 2001 From: DotMG Date: Fri, 18 Apr 2008 13:33:20 +0000 Subject: GViMail: Make all GMail links clickable by vimperator. first version. git-svn-id: http://svn.coderepos.org/share/lang/javascript/vimperator-plugins/trunk@9722 d0d07461-0603-4401-acd4-de1884942a52 --- gvimail.js | 161 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 161 insertions(+) create mode 100644 gvimail.js (limited to 'gvimail.js') diff --git a/gvimail.js b/gvimail.js new file mode 100644 index 0000000..3fca38c --- /dev/null +++ b/gvimail.js @@ -0,0 +1,161 @@ +/** + * + * ==VimperatorPlugin== + * @name GViMail + * @description Make Gmail behave like Vim + * @author Mahefa Randimbisoa (DotMG) + * @license GPL 2.0 + * @requires Vimperator 0.6pre, Gmail v1 or v2 + * @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 = true; + + // for compatibility with all versions of vimperator >= 0.6pre, + // we use the name viberator to indicate either vimperator or liberator namespace + var viberator = (typeof(liberator) == 'undefined') ? vimperator : liberator; + + + var GViMail = { + modes:viberator.config.browserModes || [viberator.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 (liberator.buffer.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 = viberator.buffer.evaluateXPath('//*[contains(@class, "'+classnamev2+'")] | //img[contains(@src, "'+imgsrcv1+'")]', GViMail.getMainCanvas().contentDocument, null, true).iterateNext(); + // hmm, the code below generates a log: Invalid argument for followLink + viberator.buffer.followLink(elem, viberator.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. + isGmail:function(uri, even) + { + if (/^https?:\/\/mail\.google\.com\//.test(uri)) + { + window.setTimeout(function(){GViMail.focusMainFrame();}, 100); + } + }, + /// 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 (viberator.mode == viberator.modes.NORMAL + && !viberator.mode.isRecording + && !(viberator.modes.extended & viberator.modes.MENU) + && !viberator.modes.passNextKey + && !viberator.modes.passAllKeys) + { + GViMail.focusMainFrame(); + } + } +} + +viberator.mappings.addUserMap(GViMail.modes, ["zM"], + "Closes all fold", + function () { GViMail.clickImage('Dm2exe', 'collapse_icon'); }); +viberator.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 + + " | //span[@role='link']" + // 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(@class,'zWKgkf')]) or (ancestor::div[contains(@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(@class,'IUCKJe')]" + // UnFold messages in thread when no excerpt is displayed (blank line) + // Such
s have a class XoqCub, have another
child having the class YrHFdf, and there is no table il all their descendants + + " | //*[contains(@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']" + // 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(@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]" + //