Hack 64. Add a Delete Button to Gmail

 < Day Day Up > 

Improve the Gmail interface with the most requested feature that Google doesn't want you to have.

Many netizens have gotten a Gmail account and been wowed with the interface, but noticed one critical missing piece: there is no easy way to delete a message. Deletion in the standard Gmail interface requires opening the drop-down actions box and selecting the last item, which is cumbersome for a frequent activity.

This hack alters the user interface of Gmail to include an extra button that lets the user delete any message with one simple click.

7.6.1. The Code

This script is split into five parts.

  1. The _gd_gmail_delete function performs the actual message deletion. It simply searches for a <select> element within its parent container and then finds the appropriate action within that menu. If it is found, the script triggers the onchange handler of the select box, which launches the standard Gmail code to delete the selected messages.

  2. The _gd_make_dom_button function is notable because it supports multiple languages. There is only one word that the script adds, but this function attempts to autodetect the language in the Gmail interface, and sets the Delete button caption to the proper translation. It also attaches the _gd_gmail_delete function as the onclick event handler for the button.

  3. The _gd_insert_button function does the real magic in this script. It calls the _gd_make_dom_button function to create a new element to be injected into the page, does a little checking for the most attractive place to put it, and injects the element into the page.

  4. The _gd_place_delete_buttons function is the driver function. It calls the _gd_element function to check for the four places where it might be appropriate to place the Delete button. The best thing to look for is the drop-down actions menu, which is tagged with one of four IDs, depending on the page. If we find the drop-down menu, we call the _gd_insert_button function with a reference to the container of that box.

  5. Finally, the main block of the script checks for the document.location.search element. The Gmail interface is split into multiple frames, but the frame where all the user interaction occurs will always contain a search box. If it makes sense to add a Delete button on the current page, we call the _gd_place_delete_buttons function to add it. Because of the way Gmail constantly re-creates parts of its user interface, we also need to register an event handler to re-add our Delete button after all mouse and keyboard actions.

Save the following user script as gmail-delete-button.user.js:

 // ==UserScript== // @name  Gmail Delete Button // @namespace    http://www.arantius.com/ // @description  Add a "Delete" button to Gmail's interface // @include      http*://mail.google.com/*mail*?* // ==/UserScript== // based on code by Anthony Lieuallen // and included here with his gracious permission // http://www.arantius.com/article/arantius/gmail+delete+button/ function _gd_element(id) { try { var el=document.getElementById(id); } catch (e) { GM_log( "Gmail Delete Button:\nThere was an error!\n\n"+ "Line: "+e.lineNumber+"\n"+ e.name+": "+e.message+"\n" ); return false; } if (el) return el; return false; } function _gd_gmail_delete(delete_button) { //find the command box var command_box = delete_button.parentNode. getElementsByTagName('select')[0]; var real_command_box = command_box.wrappedJSObject || command_box; real_command_box.onfocus( ); //find the command index for 'move to trash' var delete_index=-1; for (var i=0; i<command_box.options.length; i++) { if ('tr'==command_box.options[i].value && !command_box.options[i].disabled ) { delete_index=i; break; } } //don't try to continue if we can't move to trash now if (-1==delete_index) { var box=_gd_element('nt1'); if (box) { try { //if we find the box put an error message in it box.firstChild.style.visibility='visible'; box.getElementsByTagName('td')[1].innerHTML= '' + 'Could not delete. Make sure at least one ' + 'conversation is selected.'; } catch (e) {} } return; } //set the command index and fire the change event command_box.selectedIndex=delete_index; real_command_box = command_box.wrappedJSObject || command_box; real_command_box.onchange( ); } function _gd_make_dom_button(id) { var delete_button= document.createElement('button'); delete_button.setAttribute('class', 'ab'); delete_button.setAttribute('id', '_gd_delete_button'+id); delete_button.addEventListener('click', function( ) { _gd_gmail_delete(delete_button); }, true); //this is a little hack-y, but we can find the language code here var lang=''; try { var urlToTest=window.top.document.getElementsByTagName('frame')[1]. src; lang=urlToTest.match(/html\/([^\/]*)\/loading.html$/)[1]; } catch (e) {} //now check that language, and set the button text var buttonText='Delete'; switch (lang) { case 'it': buttonText='Elimina'; break; case 'es': buttonText='Borrar'; break; case 'fr': buttonText='Supprimer'; break; case 'pt-BR': buttonText='Supressão'; break; case 'de': buttonText='Löschen'; break; } delete_button.innerHTML='<b>'+buttonText+'</b>'; return delete_button; } function _gd_insert_button(insert_container, id) { if (!insert_container) return false; if (_gd_element('_gd_delete_button'+id)) { return false; } //get the elements var spacer, delete_button; delete_button=_gd_make_dom_button(id); spacer=insert_container.firstChild.nextSibling.cloneNode(false); //pick the right place to put them, depending on which page we're on var insert_point=insert_container.firstChild; if (2==id || 3==id) { // 2 and 3 are inside the message and go at a different place insert_point=insert_point.nextSibling.nextSibling; } if (document.location.search.match(/search=query/)) { //inside the search page the button goes in a different place if (0==id) { spacer=insert_container.firstChild.nextSibling.nextSibling. cloneNode(false); insert_point=insert_container.firstChild.nextSibling. nextSibling.nextSibling; } if (1==id) spacer=document.createElement('span'); } else if (document.location.search.match(/search=sent/)) { //inside the sent page the button goes in yet another place if (0==id) { spacer=document.createTextNode(' '); insert_point=insert_container.firstChild.nextSibling. nextSibling; } if (1==id) spacer=document.createElement('span'); } insert_container.insertBefore(spacer, insert_point); insert_container.insertBefore(delete_button, spacer); } function _gd_place_delete_buttons( ) { if (!window || ! document || ! document.body) return; var top_menu=_gd_element('tamu'); if (top_menu) _gd_insert_button(top_menu.parentNode, 0); var bot_menu=_gd_element('bamu'); if (bot_menu) _gd_insert_button(bot_menu.parentNode, 1); var mtp_menu=_gd_element('ctamu'); if (mtp_menu) _gd_insert_button(mtp_menu.parentNode, 2); var mbt_menu=_gd_element('cbamu'); if (mbt_menu) _gd_insert_button(mbt_menu.parentNode, 3); } if (document.location.search) { var s=document.location.search; if (s.match(/\bsearch=(inbox|query|cat|all|starred|sent)\b/) || ( s.match(/view=cv/) && !s.match(/search=(trash|spam)/) ) ) { // Insert the main button try { _gd_place_delete_buttons( ); } catch (e) { GM_log(e.message); } // Set events to try adding buttons after user actions var buttonsInAMoment = function( ) { try { _gd_place_delete_buttons( ); } catch (e) { GM_log(e.message); } }; window.addEventListener('mouseup', buttonsInAMoment, false); window.addEventListener('keyup', buttonsInAMoment, false); } } 

7.6.2. Running the Hack

Before installing the user script, log into Gmail at http://mail.google.com. The default view is your inbox, as shown in Figure 7-7.

Figure 7-7. Unmodified Gmail interface


Now, install the script (Tools Install This User Script) and refresh the page. You will see a Delete button next to the Archive button, as shown in Figure 7-8.

Figure 7-8. Gmail with added Delete button


You can select one or more messages and click Delete, and Gmail will move the messages directly to the Trash folder.

Certain actions within Gmail will completely rebuild the page. This is most obvious when deleting or archiving a previously unread message. Our Delete button will momentarily disappear from the interface when this happens. Don't worry, though; your next mouse click or key press will restore it in time to delete your next message.

Anthony Lieuallen

     < Day Day Up > 


    Greasemonkey Hacks
    Greasemonkey Hacks: Tips & Tools for Remixing the Web with Firefox
    ISBN: 0596101651
    EAN: 2147483647
    Year: 2005
    Pages: 168
    Authors: Mark Pilgrim

    flylib.com © 2008-2017.
    If you may any questions please contact us: flylib@qtcs.net