// Gmail Filter Assistant
// Copyright (c) 2007, Ming Zhang (kfkming@gmail.com)
// Released under the GPL license
// http://www.gnu.org/copyleft/gpl.html
// GUID: {bffc3178-2849-4727-a62c-866b8ec0523d}
// --------------------------------------------------------------------
//
// This is a Greasemonkey user script.
//
// To install, you need Greasemonkey: http://greasemonkey.mozdev.org/
// Then restart Firefox and revisit this script.
// Under Tools, there will be a new menu item to "Install User Script".
// Accept the default configuration and install.
//
// To uninstall, go to Tools/Manage User Scripts,
// select "Gmail Filter Assistant", and click Uninstall.
//
// --------------------------------------------------------------------
// ==UserScript==
// @name Gmail Filter Assistant
// @description Help to manage the Gmail filters more efficiently
// @source http://userscripts.org/scripts/show/7997
// @identifier http://userscripts.org/scripts/source/7997.user.js
// @author Ming (Amos) Zhang
// @date 2007-03-17
// @namespace http://www.amoszhang.com/GmailFilterAssistant
// @include https://mail.google.com/*
// @include http://mail.google.com/*
// ==/UserScript==
//
const Version = 0.16; // the ';' at the end is necessary
const SCRIPT_SHOW_URL = 'http://userscripts.org/scripts/show/7997';
const NUM_FILTER_ITEMS = 13;
var DEBUG = false;
var FILTER_REF_URL = '?&view=pr&pnl=f';
var FILTER_SET_URL = '?';
const FILTERASST_STYLES =
"table._gfa_ {"+
" width: 100%;"+
" border-width: 3;"+
" border-style: solid;" +
" border-color:#FAD163;" +
" background: #FFF7D7;"+
" cellspacing: 0px;"+
" cellpadding: 0px;"+
"}"+
"td._gfa_label {" +
" font-weight: bold;" +
" text-align: right;" +
" vertical-align: middle;" +
" padding-top: 4px;" +
" white-space: nowrap;"+
" font-family: arial,sans-serif;" +
" font-size: 80%;" +
"}" +
"span._gfa_navLink {" +
" background: #FAD163;"+
" border-color: #FAD163;"+
" border-width: 3;"+
" border-style: solid;" +
" font-weight: bold;" +
" text-align: middle;" +
" vertical-align: bottom;" +
" padding-top: 2px;" +
" padding-left: 4px;" +
" padding-bottom: 2px;" +
" padding-right: 4px;" +
" font-family: arial,sans-serif;" +
" font-size: 80%;" +
" white-space: nowrap;"+
" cursor: pointer;"+
" float: right;"+
" -moz-border-radius-topleft: 4px;"+
" -moz-border-radius-topright: 4px;"+
"}" +
"input._gfa_inputbox {" +
" font-weight: normal;" +
" text-align: left;" +
" vertical-align: middle;" +
" padding-top: 4px;" +
" width : 100%;"+
" font-family: arial,sans-serif;" +
" font-size: 80%;" +
"}" +
"span.hovereffect:hover{background-color:#d0dbeb;}";
const RSC_LANG={
'en' :{
title: "Filter Assistant",
loading:"Loading...",
running:'Running...',
createfilter:"Create Filter",
newversion:"New version of Gmail Filter Assistant available, install it ",
here:"here",
from: "From:",
to: "To:",
subject:"Subject:",
hasword:"Hasword:",
doesnthave:"Doesn't have:",
hasattachment:"Has attachment:",
skipinbox:"Skip the inbox(Archive it)",
starit:"Star it",
applylabel:"Apply the label",
forward:"Forward it to",
deleteit:"Delete it",
applytoexistingconvs:"Apply the filter to existing conversations",
moreactions:"More actions...",
newlabel:"New label...",
backup:"Backup filter&label",
restore:"Restore filter&label",
consolidate:"Consolidate filters",
hidenavtag:'Hide the navigation tag',
popuplabel:'Your filter & label data',
close:'Close',
cancel:'Cancel',
readingfilterlabeldataerror:"Reading filter and label data error, please try again later",
popuptitlebackup:'Javascript doesn\'t have the capability to write disk file, please copy/paste the content in the textbox to a .txt file, and keep this file in a safe place.',
popuptitlerestore:'Please copy/paste Filter & Label data from where you saved them to the text box below and click "Close"',
popuprestorewarning:'WARNING!!\n\Restoring filter data will overwrite existing filters and may take several seconds to several minutes, depending on your connection speed. \n\nAre you sure you want to continue?',
inputlabeltitle:'Please input the label name (maximal length 100):',
failtoretrieveresult:'Fail to retrieve the result, the action may not be completed',
emptycriteriawarning:'Warning: "From", "To", "Subject", "Hasword" and "Doesn\'t have" are all empty, are you sure you want to proceed?',
selectatleastoneaction:'Please select at least one action',
selectalabelorcreateone:'Please select a label or create a new one',
itemintrashwarning:'Warning: Items in the Trash are not displayed in label views or the starred view.\nDo you still wish to create the filter?',
foundduplicatefilterwarning:'Found a filter having the same criteria, overwrite it?',
},
'zh-CN' :{
title: "过滤器助手",
loading:"载入中...",
running:"正在运行...",
createfilter:"创建过滤器",
newversion:"发现新版本的 Gmail Filter Assistant, 安装请点",
here:"这里",
from: "来自:",
to: "发往:",
subject:"标题:",
hasword:"含有:",
doesnthave:"没有:",
hasattachment:"带附件:",
skipinbox:"跳过收件箱(直接存档)",
starit:"标星",
applylabel:"标记为",
forward:"转发至",
deleteit:"删除",
applytoexistingconvs:"将本过滤器作用于已有对话",
moreactions:"其他操作...",
newlabel:"新建标签...",
backup:"备份过滤器及标签",
restore:"恢复过滤器及标签",
consolidate:"整合过滤器",
hidenavtag:'隐藏导航标签',
popuplabel:'您的过滤器及标签数据',
close:'关闭',
cancel:'取消',
readingfilterlabeldataerror:"读取过滤器及标签数据过程中发生错误,请迟些时候再试",
popuptitlebackup:"Javascript 无法读写磁盘文件,请将文本框内的数据拷贝/粘贴至一个文本文件并妥善保存",
popuptitlerestore:"请将保存的过滤器及标签数据拷贝/粘贴至文本框然后点击“关闭”",
popuprestorewarning:"警告!恢复操作将覆盖已有的过滤器及标签数据!而且根据您的网络速度,整个过程可能持续几秒钟至几分钟不等。\n\n确定要进行恢复操作么?",
inputlabeltitle:"请输入标签名(最长100字符):",
failtoretrieveresult:"读取结果失败,此项操作可能未顺利完成",
emptycriteriawarning:"请填写搜索条件",
selectatleastoneaction:"请选择至少一项操作",
selectalabelorcreateone:"请选择一个标签或创建一个新标签",
itemintrashwarning:"警告:标签视图或已加注星标的邮件视图中不显示已删除邮件中的内容。\n 是否仍要创建过滤器?",
foundduplicatefilterwarning:"发现一个已有过滤器含有相同的搜索条件,是否覆盖?",
},
'de' :{
title: "Filter Assistent",
loading:"Lade...",
running:'Läuft...',
createfilter:"Filter erstellen",
newversion:"Eine neue Version von Gmail Filter Assistant ist verfügbar, installieren Sie es von",
here:"hier",
from: "Von:",
to: "An:", subject:"Betreff:",
hasword:"Mit diesen Worten:",
doesnthave:"Ohne:",
hasattachment:"Mit Anhang",
skipinbox:"Posteingang überspringen (Archivieren)",
starit:"Markierung hinzufügen", applylabel:"Label anwenden",
forward:"Weiterleiten an",
deleteit:"Löschen",
applytoexistingconvs:"Filter auf existierende Konversationen anwenden",
moreactions:"Weitere Aktionen...",
newlabel:"Neues Label...",
backup:"Filter&Label sichern",
restore:"Filter&Label wiederherstellen",
consolidate:"Filter konsolidieren",
hidenavtag:'Navigationslink verstecken',
popuplabel:'Ihre Filter & Label Daten',
close:'Schließen',
cancel:'Abbrechen',
readingfilterlabeldataerror:"Fehler beim lesen der Filter und Label Daten. Bitte später noch einmal versuchen",
popuptitlebackup:'Javascript kann nicht auf die Festplatte schreiben. Bitte den Inhalt der Textbox in eine Text-Datei sichern.',
popuptitlerestore:'Bitte kopieren (kopieren/einfügen) Sie die Filter & Label Daten aus Ihrer Sicherung in die Textbox unten und klicken Sie "Schlieéen"',
popuprestorewarning:'WARNUNG!! Wiederherstellen der Filterdaten wird existierende Filter überschreiben und kann (abhängig von Iherer Verbindungsgeschwindigkeit) mehrere Minuten dauern. Sind Sie sicher, dass sie fortfahren wollen?',
inputlabeltitle:'Bitte den neuen Label-Namen eingeben (maximal 100 Zeichen):',
failtoretrieveresult:'Fehler das Ergebnis zu empfangen. Die aktion konnte evtl. nicht durchgeführt werden',
emptycriteriawarning:'Warnung: "Von", "An", "Betreff", "Mit diesen Worten" und "Ohne" sind alle leer. Sind Sie sicher, dass sie weitermachen wollen?',
selectatleastoneaction:'Bitte wählen Sie mindestens eine Aktion',
selectalabelorcreateone:'Bitte wählen Sie ein Label oder erstellen Sie ein neues',
itemintrashwarning:'Warnung: Dinge im Papierkorb, oder markierte Nachrichten werden nicht in der Markiert oder Papierporb-Anschicht angezeigt.\nWollen Sie den Filter immer noch erstellen?',
foundduplicatefilterwarning:'Ein Filter mit gleichen Kriterien wurde gefunden. Soll er überschrieben werden?',
},
};
//=========================
// Definition of variables
//=========================
var baseURI=document.baseURI;
var LabelData, FilterData;
var titleBoxHeight;
var FilterAsstVisibile=false;
var DataReady=false;
var CurrentLabel="";
var CurrentFilterData=null;
var at, ik;
var rawFilterLabelData='';
var lang='en'; // default language: English
var base_url='';
var isHidingNavTag = false;
var msg_idx=-1; // the index of the message on which GFA is called, only one GFA instance is allowed at any time
var FloatingMsg='';
//=======================
// Definition of objects
//=======================
function ParamParsingData()
{
this.curr_pos = 0;
}
function Filter()
{
this.id='';
this.name='';
this.from = '';
this.to = '';
this.subject = '';
this.hasword = '';
this.doesnthave = '';
this.hasattachment = false;
this.skipinbox = false;
this.starit = false;
this.applylabel = false;
this.labeltoapply = '';
this.forward = false;
this.forwardto = '';
this.deleteit = false;
this.applyonexistingconvs = false;
}
var tmpdiv = newNode('div');
function myUnescape(s)
{
s=s.replace(/\\u/g, '%u');
tmpdiv.innerHTML = unescape(s);
return tmpdiv.innerHTML;
}
function getWord(s)
{
if (lang && RSC_LANG[lang] && RSC_LANG[lang][s])
s= RSC_LANG[lang][s];
else
{
debug('[getWord]: retrieve resource fail: RSC_LANG['+lang+']['+s+'] return null');
s= RSC_LANG['en'][s];
lang='en';
}
return myUnescape(s);
}
autoupdate();
// autoupdate function credit to Bjorn Rosell http://userscripts.org/scripts/show/7715
function autoupdate() {
// get base URL
base_url=baseURI.match(/http[s]{0,1}:\/\/mail.google.com\/a\/[^\.].*\.[a-z]{2,}\//); // google App for Your Domain mailbox
if (!base_url) //not found
base_url=baseURI.match(/http[s]{0,1}:\/\/mail.google.com\/mail\//); // gmail
if (base_url)
{
FILTER_REF_URL = base_url + FILTER_REF_URL;
FILTER_SET_URL = base_url + FILTER_SET_URL;
}
else
return; // not a proper page
// only check for updates one time a day
var d = new Date();
at = getDataItem(document.cookie,'GMAIL_AT=', ';');
ik = GM_getValue('_gfa_'+base_url+'ik', null);
lang = GM_getValue('_gfa_'+base_url+'lang', 'en');
isHidingNavTag = GM_getValue('_gfa_'+base_url+'HideNavTag', false);
var node=document.getElementsByTagName ('SCRIPT');
for (var obj in node)
{
if (typeof node[obj]=='object' && node[obj].innerHTML.match(/D\(\[/))
{
var data=getReturnValue(node[obj].innerHTML, 'D([\"ud\"');
if (data!=null)
{
ik=data[2];
GM_setValue('_gfa_'+base_url+'ik', ik);
debug('ik='+ik);
try
{
var t=getDataItem(myUnescape(data[8]), 'hl=', '&');
if (t==null)
lang='en';
else
lang=t;
debug('lang='+lang);
GM_setValue('_gfa_'+base_url+'lang', lang);
}
catch(e){};
}
}
}
if (getNode('msgs')==null || getNode('tt')==null || getNode('mh_0')==null) // only add the link on mail content display page
{
debug('[autoupdate]: Not the msg display page. Leaving...');
// the control of the script falls out to a new page, let's set a mark for recheck everything
GM_setValue('_gfa_recheck',true);
return 0;
}
window.setInterval(function()
{
drawFilterAsstBtn();
}, 1000);
GM_addStyle(FILTERASST_STYLES);
if (GM_getValue('_gfa_lastcheck') == d.getDate()) {
return;
}
// check for update
GM_xmlhttpRequest({
method:"GET",
headers:{ 'Accept': 'text/plain'},
url: SCRIPT_SHOW_URL,
onload:function(result) {
var data = result.responseText ;
var ver = parseFloat(getDataItem(data, 'Gmail Filter Assistant v', ';')); // get version number
debug('The latest version=['+ver+'], and current version=['+Version+']');
if ( ver > Version ) { // current version is an old one
FloatingMsg=getWord('newversion')+''+getWord('here')+''
}
// getting new version info successfully, set the lastcheck flag to prevent more than one checking every day.
var d = new Date();
GM_setValue('_gfa_lastcheck', d.getDate());
}
});
}
function getLabel_n_FilterData(callbackfunc, argument)
{
if (typeof callbackfunc!='function')
{
debug('[getLabel_n_FilterData]: Invalid callback function. Leaving...');
return;
}
if (DataReady)
{
callbackfunc(argument);
debug('[getLabel_n_FilterData]: Data is ready, no need to read again. Leaving...');
return;
}
debug('[getLabel_n_FilterData]: Entering...');
var navfilter=null;
if (msg_idx!=-1)
navfilter=getNode('_gfa_navlink_'+msg_idx+'_text');
if (navfilter) navfilter.innerHTML=''+getWord('loading')+'';
GM_xmlhttpRequest({
method:'GET',
url: FILTER_REF_URL,
onload: function(responseDetails) {
if (navfilter) navfilter.innerHTML=getWord('title');
debug('[getLabel_n_FilterData]: Reading label data....');
var data;
var status;
status = responseDetails.status;
data = responseDetails.responseText;
rawFilterLabelData=data;
//debug('Response Text='+data);
if (status!=200) // not OK
return;
LabelData = getReturnValue(data, 'D([\"cta\"');
LabelData = LabelData[0];
debug('[getLabel_n_FilterData]: LabelData='+LabelData.toString());
debug('[getLabel_n_FilterData]: Reading filter data....');
FilterData = null;
FilterData = getReturnValue(data, 'D([\"fi\"');
debug('[getLabel_n_FilterData]: FilterData='+FilterData.toString());
FilterData = FilterData[0];
if (!FilterData)
{
debug('[getLabel_n_FilterData]: FilterData='+FilterData.toString());
}
DataReady=true;
debug('[getLabel_n_FilterData]: All data ready');
if (CurrentFilterData!=null) // recover the status before refreshing
{
if (CurrentLabel!="")
CurrentFilterData.labeltoapply=CurrentLabel;
}
if (CurrentFilterData!=null) // recover the status before refreshing
{
restoreUserChanges(CurrentFilterData);
CurrentFilterData=null;
}
callbackfunc(argument);
debug('[getLabel_n_FilterData]: Leaving...');
},
onerror: function(responseDetails){
if (navfilter) navfilter.innerHTML=getWord('title');
debug('[getLabel_n_FilterData]: Leaving...');
}
});
}
function drawFilterAsstBtn()
{
//debug("[drawFilterAssistantBtn]: Entering...");
var msgs=getNode("msgs");
var node, ws;
var j=-1;
ws = getNode('_gfa_ws');
for (var i=0;;i++)
{
node=getNode('msg_'+i);
if (!node)
{
break;
}
//debug('find message['+i+']');
j=i+1;
node=getNode('_cbt_'+j+'_l');
if (!node)
{
if (ws && ws.getAttribute('idx')==i)
{
ws.parentNode.removeChild(ws);
}
continue;
}
// debug('find dropdown box for message['+i+']');
if (getNode('_gfa_navlink_'+i))
{
//debug('nav link already exists. skip...');
continue;
}
var link=newNode('TD');
link.id='_gfa_navlink_'+i;
link.className="cbum";
link.setAttribute("style", "padding-top: 5px;visibility: visible !important;");
link.innerHTML= ' Filter Assistant ';
link.addEventListener('click', OnFilterAsstBtnClicked, false);
link.style.cursor="pointer";
node.parentNode.insertBefore(link, node.nextSibling);
debug('insert GFA link');
var separator=newNode('TD');
separator.className='cbus';
node.parentNode.insertBefore(separator, link.nextSibling);
//debug('insert separator');
}
//debug("[drawFilterAssistantBtn]: Leaving...");
}
function OnFilterAsstBtnClicked(e)
{
debug('[OnFilterAsstBtnClicked]: Entering...');
var old_msg_idx=msg_idx;
var s=this.id;
debug("this.id="+this.id);
if (!s || !s.match(/^_gfa_navlink_[a-zA-Z]*[0-9]+$/)) return;
msg_idx= s.substr(13);
if (old_msg_idx!=msg_idx)
{
var node=getNode('_gfa_ws');
if (node) node.parentNode.removeChild(node);
}
getLabel_n_FilterData(drawFilterAsstWorkspace, (getNode('_gfa_ws_div')==null));
debug('[OnFilterAsstBtnClicked]: Leaving...');
}
//=================================
// Draw Filter Assistant Workspace
//=================================
function createTitlebox()
{
var titlebox=getNode('_gfa_ws'); // the whole workspace
var msg=getNode('msg_'+msg_idx);
if (!titlebox) // create the titlebox if it's not there.
{
titlebox=newNode('table');
titlebox.id='_gfa_ws';
titlebox.setAttribute('idx',msg_idx);
msg.insertBefore(titlebox, msg.firstChild.nextSibling);
titlebox.setAttribute('cellspacing','0');
titlebox.setAttribute('cellpadding','0');
titlebox.setAttribute('style','width: 100%');
}
return titlebox;
}
function drawFilterAsstWorkspace(show_boxes) // show_boxes: show the "criteria" and "action" boxes?
{
debug('[drawFilterAsstWorkspace]: Entering... show_boxes = '+show_boxes);
var titlebox=createTitlebox();
// check if the workspace has already been drawn
var node=getNode('_gfa_ws_div');
if (node) // the workspace is there, hide it.
node.parentNode.removeChild(node);
debug('[drawFilterAsstWorkspace]: FloatingMsg = '+FloatingMsg);
titlebox.innerHTML=
'
'
+ (FloatingMsg!=''?
(''
+ ''
+ ' '+myUnescape(FloatingMsg)+' '
+ ' | '
+ ' |
'):'')
+ '';
if (FloatingMsg!='')
{
window.setTimeout(function(){
var node=getNode('_gfa_FloatingMsg');
if (node)
node.parentNode.removeChild(node);
}, 5000); // delete the msg
}
FloatingMsg='';
if (!show_boxes) return;
node=newNode('tr');
titlebox.firstChild.appendChild(node);
node.innerHTML=
''
+ ' '
var div=getNode('_gfa_ws_div');
if (!div) return;
var LabelsCombBox = newNode('select');
LabelsCombBox.id = "cbBoxLabels";
var i;
var opList;
for (i=0; i6) // remove _upro_
recver += t.firstChild.id.substr(6) + " OR ";
}
}
if (recver.length>0)
recver = recver.substr(0, recver.length-4);
}
}catch(e)
{
GM_log('Error occurred: Getting sender/receiver fail. \n\nDetailed error msg:\n\n['+e.name+']:'+e.message);
}
// ======================= add "Characteristic" part =============================
div.innerHTML=
''
+ ''
+' | ';
getNode('opBackupFilters').addEventListener('click', onBackupFilters, false);
getNode('opRestoreFilters').addEventListener('click', onRestoreFilters, false);
getNode('opConsolidateFilters').addEventListener('click', onConsolidateFilters, false);
node = getNode('lblCreateFilter');
node.addEventListener('click', onCreateFilter, false);
node = getNode('_gfa_navlink_lblCancel'+msg_idx);
node.addEventListener('click', OnFilterAsstBtnClicked, false);
node = getNode('chkBoxApplyLabel');
node.parentNode.appendChild(LabelsCombBox);
debug('[drawFilterAsstWorkspace]: Leaving...');
}
function checkApplyTheLabel()
{
try{getNode('chkBoxApplyLabel').checked=true;}catch(e){};
}
//=======================
// Draw the popup window
//=======================
function drawPopup(title, callback)
{
if (callback==null || typeof callback!='function') return;
var popup = newNode('div');
popup.id='_gfa_popup';
popup.setAttribute("style", "z-index:1102;position:fixed;overflow:auto;width:470px;left:20px;top:20px;background-color:#FFF7D7;padding:15px;border:2px solid #FAD163");
document.body.appendChild(popup);
if (typeof title!='string' || title==null) title='';
popup.innerHTML=
''+title+' '
+ ' '+getWord('popuplabel')+': '
+ '
'
+ '';
getNode('btnClosePopup').addEventListener('click', callback, false);
}
//===========================
// Close popup event handler
//===========================
function onClosePopup()
{
var node=getNode('_gfa_popup');
if (node) node.parentNode.removeChild(node);
}
//=============================
// Backup filter event handler
//=============================
function onBackupFilters()
{
if (rawFilterLabelData=='')
{
alert(getWord('readingfilterlabeldataerror'));
return;
}
drawPopup( getWord('popuptitlebackup'),
onClosePopup);
var node=getNode('txtBoxFilters');
var s='';
var header = 'D([\"fi\"';
s=s+header+getRawData(rawFilterLabelData, header)+');';
s+='\n\n';
header = 'D([\"cta\"';
s=s+header+getRawData(rawFilterLabelData, header)+');';
node.innerHTML=s;
}
//=============================
// Restore filter event handler
//=============================
function onRestoreFilters()
{
drawPopup(getWord('popuptitlerestore'),
RestoreFilters );
}
function RestoreFilters()
{
var node=getNode('txtBoxFilters');
var s='';
if (node)
s = node.value;
onClosePopup();
if (s=='')
{
return;
}
var fd, ld; //filter data, label data
f=getReturnValue(s, 'D(["fi"');
l=getReturnValue(s, 'D(["cta"');
var node=getNode('_gfa_navlink_'+msg_idx);
if (node) node.innerHTML=' '+getWord('running')+'';
if (f)
{
if (!confirm(getWord('popuprestorewarning')))
{
node.innerHTML=getWord('title');
return;
}
var nHasInvalidData=0;
var nEdit=0, nAdd=0;
for (var i=0;i=0) // found a filter having the same criteria
{
// check if actions are same, too
var same=true;
for (var j=6;j<13;j++)
if (same)
same = same && (f[i][2][j]!=FilterData[k][2][j]);
else
break;
// the two filters are the same, skip it
if (same) continue;
fd.id = FilterData[k][0]; // store the ID
fd.name = FilterData[k][1]; // store the name
var old_fd=clone(fd);
old_fd.skipinbox = FilterData[k][2][6];
old_fd.starit = FilterData[k][2][7];
old_fd.applylabel = FilterData[k][2][8];
old_fd.labeltoapply = FilterData[k][2][9];
old_fd.forward = FilterData[k][2][10];
old_fd.forwardto = FilterData[k][2][11];
old_fd.deleteit = FilterData[k][2][12];
nEdit++;
editFilter(old_fd, fd, i==(f.length-1));
}
else
{
nAdd++;
addFilter(fd,i==(f.length-1));
}
}
//if (nHasInvalidData + nEdit + nAdd > 0)
// alert('Restoring filter data'Some filter data is invalid and was ignored in the restoring procedure');
}
}
function isBoolValue(v)
{
return (v=='true' || v=='false' || v=='');
}
//==================================
// Consolidate filter event handler
//==================================
function onConsolidateFilters()
{
// in progress
}
//==================
// Add Label
//==================
function addLabel(refresh)
{
debug('[addLabel]: Entering...');
CurrentFilterData = getUserChanges();
CurrentLabel=prompt(getWord('inputlabeltitle'),'');
if (CurrentLabel.length<0)
{
debug('[addLabel]: Empty label. Leaving...');
return;
}
else if (CurrentLabel.length>100)
CurrentLabel=CurrentLabel.substr(0,100);
debug("CurrentLabel="+CurrentLabel);
var postdata='act=cc_'+encodeURIComponent(CurrentLabel)+'&at='+at;
var add_lbl_url=base_url+'?&ik=&view=up';
var referer=base_url+'?&view=pr&pnl=l&ik='+ik+'&zx='+UniqueURL();
GM_xmlhttpRequest({
method:'POST',
url: add_lbl_url,
headers:{
'Referer': referer,
'Content-type' : 'application/x-www-form-urlencoded'
},
data : postdata,
onload: function(responseDetails) {
debug(responseDetails.responseText);
if (refresh)
{
var ret=getReturnValue( responseDetails.responseText, 'D([\"ar\"');
if (ret!=null)
{
debug('< D(["ar" > returns : '+ret.toString());
}
if(ret && ret[1])
{
FloatingMsg = ret[1];
CurrentFilterData.applylabel=true;
}
else
FloatingMsg = getWord('failtoretrieveresult');
DataReady=false;
getLabel_n_FilterData(drawFilterAsstWorkspace, true);
}
debug('[addLabel]: Leaving...');
},
onerror: function(responseDetails){
GM_log("ERROR: "+responseDetailsText);
debug('[addLabel]: Leaving...');
}
});
}
//==========================================
// Save user change to the workspace
//==========================================
function getUserChanges()
{
f=new Filter();
f.id = '';
f.name = '';
f.from = getNode('txtBoxFrom').value;
f.to=getNode('txtBoxTo').value;
f.subject=getNode('txtBoxSubject').value;
f.hasword=getNode('txtBoxHasWord').value;
f.doesnthave=getNode ('txtBoxDoesntHave').value;
f.hasattachment=getNode('chkBoxHasAttachment').checked;
f.skipinbox=getNode('chkBoxSkipInbox').checked;
f.starit=getNode('chkBoxStarIt').checked;
f.applylabel=getNode('chkBoxApplyLabel').checked;
f.labeltoapply=getNode('cbBoxLabels').value;
f.forward=getNode('chkBoxForwardTo').checked;
f.forwardto=getNode('txtBoxForwardTo').value;
f.deleteit=getNode('chkBoxDeleteIt').checked;
f.applyonexistingconvs=getNode('chkBoxApplyToExistingConvs').checked;
return f;
}
//==========================================
// Restore the user change to the workspace
//==========================================
function restoreUserChanges(f)
{
try
{
getNode('txtBoxFrom').value=f.from;
getNode('txtBoxTo').value= f.to;
getNode('txtBoxSubject').value=f.subject;
getNode('txtBoxHasWord').value=f.hasword;
getNode('txtBoxDoesntHave').value=f.doesnthave;
getNode('chkBoxHasAttachment').checked=f.hasattachment;
getNode('chkBoxSkipInbox').checked=f.skipinbox;
getNode('chkBoxStarIt').checked=f.starit;
getNode('chkBoxApplyLabel').checked= f.applylabel;
getNode('cbBoxLabels').value=f.labeltoapply;
getNode('chkBoxForwardTo').checked=f.forward;
getNode('txtBoxForwardTo').value=f.forwardto;
getNode('chkBoxDeleteIt').checked= f.deleteit;
getNode('chkBoxApplyToExistingConvs').checked=f.applyonexistingconvs;
}catch(e)
{
GM_log('Error occured: Setting current filter data failed. \n\nDetailed error msg:\n\n['+e.name+']:'+e.message);
}
}
function hasFilter(fd)
{
if (FilterData!=null) //check existing filters to see if the rule has already been there
{
var len=FilterData.length;
for (var i=0;i returns : '+ret.toString());
}
if(ret && ret[1])
FloatingMsg = ret[1];
else
FloatingMsg = getWord('failtoretrieveresult');
DataReady=false;
getLabel_n_FilterData(drawFilterAsstWorkspace, false);
node.innerHTML = ''+getWord('createfilter')+'';
}
debug('[addFilter]: Leaving...');
},
onerror: function(responseDetails){
GM_log("ERROR: \nstatus="+responseDetails.status+"\nHeaders="+responseDetails.responseHeaders+"\nFeed data="+ responseDetails.responseText);
debug('[addFilter]: Leaving...');
}
});
}
//==================
// Edit Filter
//==================
function editFilter(old_fd, new_fd, refresh)
{
debug('[editFilter]: Entering...');
// ==== add the filter ====
// The following code is based on :
// Gmail Agent API
// Copyright (C) 2005 Johnvey Hwang, Eric Larson
// http://sourceforge.net/projects/gmail-api/
// Generate the URL
var add_flt_url = FILTER_SET_URL
+ 'ik=' + ik
+ '&view=pr'
+ '&pnl=f'
+ '&at='+ at
+ '&act=rf' // action = refine filter
+ '&search=cf'
+ '&cf_t=rf'
+ '&cf1_from=' + encodeURIComponent(new_fd.from)
+ '&cf1_to=' + encodeURIComponent(new_fd.to)
+ '&cf1_subj=' + encodeURIComponent(new_fd.subject)
+ '&cf1_has=' + encodeURIComponent(new_fd.hasword)
+ '&cf1_hasnot=' + encodeURIComponent(new_fd.doesnthave)
+ '&cf1_attach=' + encodeURIComponent(new_fd.hasattachment)
+ '&cf2_ar=' + encodeURIComponent(new_fd.skipinbox)
+ '&cf2_st=' + encodeURIComponent(new_fd.starit)
+ '&cf2_cat=' + encodeURIComponent(new_fd.applylabel)
+ '&cf2_sel=' + encodeURIComponent(new_fd.labeltoapply)
+ '&cf2_emc=' + encodeURIComponent(new_fd.forward)
+ '&cf2_email=' + encodeURIComponent(new_fd.forwardto)
+ '&cf2_tr=' + encodeURIComponent(new_fd.deleteit)
+ '&ofid=' + encodeURIComponent(new_fd.id)
+ '&irf=' + encodeURIComponent(new_fd.applyonexistingconvs) //whether to apply the filter to all existing mails
+ '&zx=' + UniqueURL();
// Generate referrer
var referer = FILTER_SET_URL
+ 'ik=' + ik
+ '&search=cf'
+ '&view=tl'
+ '&start=0'
+ '&cf_f=cf1'
+ '&cf_t=cf2'
+ '&cf1_from=' + encodeURIComponent(old_fd.from)
+ '&cf1_to=' + encodeURIComponent(old_fd.to)
+ '&cf1_subj=' + encodeURIComponent(old_fd.subject)
+ '&cf1_has=' + encodeURIComponent(old_fd.hasword)
+ '&cf1_hasnot=' + encodeURIComponent(old_fd.doesnthave)
+ '&cf1_attach=' + encodeURIComponent(old_fd.hasattachment)
+ '&cf2_ar=' + encodeURIComponent(old_fd.skipinbox)
+ '&cf2_st=' + encodeURIComponent(old_fd.starit)
+ '&cf2_cat=' + encodeURIComponent(old_fd.applylabel)
+ '&cf2_sel=' + encodeURIComponent(old_fd.labeltoapply)
+ '&cf2_emc=' + encodeURIComponent(old_fd.forward)
+ '&cf2_email=' + encodeURIComponent(old_fd.forwardto)
+ '&cf2_tr=' + encodeURIComponent(old_fd.deleteit)
+ '&ofid=' + encodeURIComponent(old_fd.id)
+ '&zx=' + UniqueURL();
var node=getNode('lblCreateFilter');
if (refresh)
{
node.innerHTML = ''+getWord('running')+'';
node.removeEventListener('click', onCreateFilter, false);
}
GM_xmlhttpRequest({
method:'GET',
url: add_flt_url,
headers:{'Referer': referer},
onload: function(responseDetails) {
debug(responseDetails.responseText );
if (refresh)
{
var ret=getReturnValue(responseDetails.responseText, 'D([\"ar\"');
if (ret!=null)
{
debug('< D(["ar" > returns : '+ret.toString());
}
if(ret && ret[1])
FloatingMsg = ret[1];
else
FloatingMsg = getWord('failtoretrieveresult');
DataReady=false;
getLabel_n_FilterData(drawFilterAsstWorkspace, false);
node.innerHTML = ''+getWord('createfilter')+'';
}
debug('[editFilter]: Leaving...');
},
onerror: function(responseDetails){
GM_log("ERROR: \nstatus="+responseDetails.status+"\nHeaders="+responseDetails.responseHeaders+"\nFeed data="+ responseDetails.responseText);
debug('[editFilter]: Leaving...');
}
});
}
//======================================
// Get data item value given the header
//======================================
function getReturnValue(data, header)
{
//debug('[getReturnValue]: Entering...');
data = data.replace(/[\r\n\t\v\f\b\0]/g,""); // remove some escaped characters which doesn't affect the result
data = data.replace(/\\\\/g, "\\"); // replace \\ with \
// header is the data header like < D(["ar" >
var s;
var param;
var ret=null;
param=new ParamParsingData();
param.curr_pos=0;
s=getRawData(data, header);
// debug('[getReturnValue]: getRawData() returns <'+s+'>');
if (s!='')
ret = parseData(s, 0, s.length-1, param); // parse the block data, data is the data string,
else
ret = null;
//debug('[getReturnValue]: Leaving...');
return ret;
}
function getRawData(data, header)
{
// header is the data header like < D(["ar" >
var sp = data.indexOf(header), ep;
if (sp!=-1) // the labels found
{
sp = sp + header.length + 1; // the starting point of this data block
ep = data.indexOf(');', sp); // the ending point of this data block
return data.substring(sp, ep-1);
}
return '';
}
//=================================
// Parse raw data read from google
//=================================
function parseData(data, sp, ep, param)
{
var i;
var quoted=false;
var s="";
var arr = new Array();
//GM_log(data.substring(sp,ep));
i = sp; // skip the starting '['
while (i<=ep)
{
switch (data[i])
{
case '[': // found an inner block
{
if (!quoted)
{
arr.push(parseData(data, i+1, ep, param));
i = param.curr_pos;
}
else
s=s+data[i];
break;
}
case '"': // find an element
{
if (!quoted) // left quote in a pair is found
{
quoted=true;
s="";
}
else // right quote in a pair is found
{
arr.push(myUnescape(s)); // push the current element into array
s="";
quoted = false;
}
break;
}
case '\\': // take care of the escaped character
{
switch (data[i+1]) // check the next character
{
case '"': // \"
case '\'':
case '\<':
case '\>':
{
s=s+data[i+1];
i++;
break;
}
default: // error, I don't do anything here, assuming Google doesn't make mistake in the data :)
{
s=s+data[i];
break;
}
}
break;
}
case ',': // delimiter
{
if (!quoted) // not quoted
{
if (data[i-1]!='"' && data[i-1]!=']')
arr.push(s);
s = ""; // clear the current element
}
else
s = s + ',';
break;
}
case ']': // finish processing current array
{
if (!quoted)
{
if (s!="")
arr.push(myUnescape(s));
s = "";
param.curr_pos = i;
return arr; // I assume the brackets are well paired
}
else
s = s + ']';
break;
}
default:
s = s + data[i];
}
param.curr_pos = ++i;
}
return arr;
}
var charset='abcdefghijklmnopqrstuvwxyz0123456789';
//====================
// Make a unique URL
//====================
function UniqueURL()
{
var s='';
for (i=0;i<12;i++)
{
s=s+charset[Math.floor(Math.random()*36)];
}
return s;
}
//====================
// show debug message
//====================
function debug(msg)
{
if (DEBUG) GM_log(msg);
}
//============================
// trim space around a string
//============================
function trim(s)
{
var i, len=s.length, sp=0, ep=len-1;
for (i=0;i=sp;i--)
if (s[i]==' ') ep--;
else break;
return s.subString(sp, ep+1);
}
// Following function credited to RoBorg, http://javascript.geniusbug.com/
function clone(obj)
{
if(typeof(obj) != 'object') return obj;
if(obj == null) return obj;
var newobj = new Object();
for(var i in obj)
newobj[i] = clone(obj[i]);
return newobj;
}
// Following functions credited to Mihai @ http://persistent.info/
function newNode(type) {
return unsafeWindow.document.createElement(type);
}
function getNode(id) {
return unsafeWindow.document.getElementById (id);
}
function getDataItem(data, header, endchar) {
var re = new RegExp(header + "([^"+endchar+"]+)");
var value = re.exec(data);
return (value != null) ? myUnescape(value[1]) : null;
}
|