There are 12 previous versions of this script.
Add Syntax Highlighting (this will take a few seconds, probably freezing your browser while it works)
// ==UserScript==
// @name Gmail Template Switcher - v 2.0
// @namespace http://ishikawa.r-stone.net/
// @description Append the function to apply the mail template, when writing a mail. Modify source code of [Gmail Template Switch] from http://d.hatena.ne.jp/re_guzy by re_guzy
// @version 0.2.20111104.0
// @include http://mail.google.com/*
// @include https://mail.google.com/*
// @exclude http://mail.google.com/mail/help/*
// @exclude https://mail.google.com/mail/help/*
// @match http://mail.google.com/*
// @match https://mail.google.com/*
//
// Copyright (c) 2007-2008, re_guzy <goodspeed.xii@gmail.com>
// Distributed under the MIT license
// http://opensource.org/licenses/mit-license.php
// http://sourceforge.jp/projects/opensource/wiki/licenses%2FMIT_license
//
// Notice : To Uninstall this script, remove "gtssettings0-9" from Gmail contact list.
// Thanks : This script uses jQuery 1.2 .
// Feature: When writing a mail, append a combobox to action. By selecting action,
// apply template to mail, or add template or remove template. Template
// is saved to "contact list" named starting with "gtssettings".
// Require: Greasemonkey 0.7.20080121.0
// Change : 0.2.20111104.0 - fix for new design
// 0.2.20110628.0 - support multi account
// 0.2.20100202.0 - corresponded provisionally with this Google Gmail Greasemonkey API problem
// 0.2.20091126.0 - fix for new button design
// 0.2.20090810.0 - fix for Google Chrome 3.0.197.11
// 0.2.20090730.0 - fix for can not add a template
// 0.2.20090716.0 - support Rich Text formatting
// 0.2.20090626.0 - support google chrome user scripts
// 0.2.20090204.0 - fix for new button design
// 0.2.20081129.0 - body setting bug fix
// 0.2.20081128.0 - support Greasekit for Safari
// support Opera
// uses jQuery
// change GM API call
// 0.1.20080526.0 - bug fix for Firefox 3 RC1
// 0.1.20080519.0 - bug fix for Google Apps
// 0.1.20080515.0 - change msg selector
// 0.1.20080514.0 - change msg selector
// 0.1.20080509.0 - Initial release
// ==/UserScript==
(function(contentWindow) {
var DEBUG_MODE = false;
var KEY_TOKEN = 'gts_token';
var KEY_CACHE = 'gts_cache';
var CONTACT_NAME = 'gtssettings';
var CONTACT_ID_RE = /,"Id":"(\w+)","MailsSent":\d,"Name":"gtssettings\d","Notes":/;
var MSGBODY_RE = /([\s\S]*)\n?(?:^---)(\n[\s\S]+)/m;
var MSGBODY_RT_RE = /([\s\S]*)[<br>]?---([<br>][\s\S]+)/m;
var LOCATION_RE = /(https?:\/\/[^\/]+\/a\/[^\/]+\/?).*/;
var USER_NUMBER_RE = /mail\/u\/([0-9])\//;
var SELECTOR = {
'msgbody' : 'textarea[@name=body]',
'rt_msgbody' : 'iframe',
'subject' : 'input[@name=subject]',
'to' : 'textarea[@name=to]',
'from' : 'select[@name=from], input[@name=from]',
'cc' : 'textarea[@name=cc]',
'bcc' : 'textarea[@name=bcc]'
};
// Add jQuery
var $ = null;
var GM_JQuery = null;
// self.location.href?
/*try {
if (document.location.href!=top.location.href) return;
} catch(err) {
debugLog(err);
return;
}*/
GM_JQuery = document.getElementById('gts_jquery');
if (GM_JQuery) {
debugLog('appended script element on '+document.location.href);
return;
}
GM_JQuery = document.createElement('script');
GM_JQuery.src = document.location.protocol + '//ajax.googleapis.com/ajax/libs/jquery/1.2/jquery.min.js';
GM_JQuery.type = 'text/javascript';
GM_JQuery.id = 'gts_jquery';
document.getElementsByTagName('head')[0].appendChild(GM_JQuery);
// Check if jQuery's loaded
function GM_wait(jQeuryLoadLimit) {
try {
$ = contentWindow.jQuery || this.jQuery;
} catch(err) {
debugLog(err);
}
if ($ == null || typeof $ == 'undefined') {
debugLog('jquery load check at '+jQeuryLoadLimit+'...');
if (jQeuryLoadLimit <= 0) return;
jQeuryLoadLimit--;
window.setTimeout(GM_wait, 1000, jQeuryLoadLimit);
} else {
debugLog('jquery loaded at '+jQeuryLoadLimit+' times');
gtsInit();
}
}
GM_wait(8);
// Add Missing GM_ API functions for GreaseKit
if (typeof(GM_setValue) != 'function' && typeof(GM_getValue) != 'function') {
function GM_setValue(name, value) {
document.cookie = [
name, '=', escape(value),
';expires=', (new Date(new Date().getTime() + 365 * 1000 * 60 * 60 * 24)).toGMTString()
].join('');
}
function GM_getValue(name, value) {
var r = new RegExp(name + '=([^;]*)'), m;
if (m = document.cookie.match(r)) {
return unescape(m[1]);
}
return value;
}
function GM_delValue(name, value) {
if (GM_getValue(name, false))
document.cookie = name + '=;expires=Thu, 01-Jan-1970 00:00:01 GMT';
}
} else {
var GM_delValue = GM_setValue;
}
/*
*
*/
var gmail = null;
var T = new Array(10);
var Ja = false;
var recentView;
/*
* get gmail elements
*/
function getViewType() {
var str = '';
switch (gmail.getActiveViewType()) {
case 'tl': str = 'Threadlist'; break;
case 'cv': str = 'Conversation'; break;
case 'co': str = 'Compose'; break;
case 'ct': str = 'Contacts'; break;
case 's': str = 'Settings'; break;
default: str = 'Unknown';
}
return str;
}
function getView() {
return document;
}
function getLabel(regstr) {
var returnValue = null;
$('form > table', getView()).each(function() {
$('span', this).each(function(i) {
var l = $(this).html();
var reg = new RegExp(regstr);
if (l.match(reg)) {
returnValue = $(this).get(0);
return;
}
});
});
return returnValue;
}
//
function gtsInit() {
debugLog("gtsInit");
window.setTimeout(function() {
initT();
document.addEventListener('focus', function(event) {
if (event.target.name != 'to' && event.target.name != 'body') {
debugLog(event.target);
return;
}
debugLog('focus to to or body element');
initialize();
}, true);
// for Richtext format mode
getView().addEventListener('DOMNodeInserted', nodeInsertedHandler, false);
}, 100);
}
//
function initT() {
T[0] = { 'id' : -1, 'num' : 0 };
for (var i=1;i < T.length;i++) {
T[i] = {
'id' : -1,
'num' : i,
'from' : '',
'to' : '',
'cc' : '',
'bcc' : '',
'subject' : '',
'body' : '',
'body_latter' : '',
'body_rt' : '',
'body_rt_latter' : ''
}
}
}
function viewChanged() {
debugLog('viewChanged');
str = getViewType();
if (str != "Compose" && str != "Conversation") {
if (recentView) {
recentView.removeEventListener('DOMNodeInserted', nodeInsertedHandler, false);
}
return;
}
recentView = getView();
window.setTimeout(function() {
initialize();
}, 600);
}
function nodeInsertedHandler(event) {
var target = event.target;
if (target.nodeType == 1) {
tagName = target.tagName.toLowerCase();
if (tagName == 'form') {
debugLog('form inserted');
window.setTimeout(function() {
initialize();
}, 100);
} else if (tagName == 'table') {
debugLog('table inserted');
window.setTimeout(function() {
initialize();
}, 100);
} else if (tagName == 'iframe') {
debugLog('iframe inserted');
$('form', getView()).each(function() {
$(x('r'), this).each(function(i) {
$(this).ready(function() {
window.setTimeout(function() {
initialize();
}, 100);
});
});
});
}
}
}
function initialize() {
debugLog('initialize');
try {
if ($('#id_gts_template', getView()).is('select')) {
debugLog('already initialized');
return;
}
$('form', getView()).each(function() {
var label = $('div[role=navigation] div[role=button]:eq(0)', $(this).parent().parent().parent()).text();
Ja = (label.indexOf('送信')>=0);
$(this).prepend(createSelectElement());
composeCommand(this);
});
} catch(e) {
debugLog('initialize failure because : ' + e);
return;
}
}
function createSelectElement() {
var content = $('<select id="id_gts_template" style="margin-left:6px;font-size:.8em;">').append(toOption('please wait...' , false , true)).change(function(event) {
doCommand(event.target);
});
return content;
}
function toOption(text, value, selected, cls) {
var a = []
$.each({
'style' : value ? null : '"color: rgb(119, 119, 119);"',
'disabled' : value ? null : '"disabled"',
'selected' : selected ? '"selected"' : null,
'value' : value ? '"' + value + '"' : null,
'class' : cls ? cls : null
}, function(i,v) {
if (v) {a.push(i + "=" + v);}
});
return "<option " + a.join(' ') + ">" + text + "</option>";
}
function doCommand(selectNode) {
$('form', getView()).each(function() {
if (selectNode.value == 'add') {
addTemplate(this, true);
} else if (selectNode.value == 'add_ignore_from') {
addTemplate(this, false);
} else if (selectNode.value.match(/apply_(\d+)/)) {
applyTemplate(RegExp.$1 , this);
} else if (selectNode.value.match(/delete_(\d+)/)) {
deleteTemplate(RegExp.$1 , this);
} else if (selectNode.value == 'undo') {
//var w = typeof unsafeWindow != "undefined" && unsafeWindow || window;
//if (w.gts_undo) { w.gts_undo(); }
if (contentWindow.gts_undo) { contentWindow.gts_undo(); }
}
selectNode.value = 'init';
});
}
function composeCommand(form) {
debugLog('call composeCommand');
getTemplates(function /*parseTemplate*/(notes, use_cache) {
$.each(notes, function(i, data) {
if (use_cache) {
T[i] = notes[i];
} else {
var note = data.note ? decode(data.note, false) : "{}";
try {
T[data.num] = eval(note);
T[data.num].id = data.id;
T[data.num] = decode(T[data.num], true);
} catch(e) {
debugLog('eval failed : ' + e);
}
}
});
recomposeSelectElement(form);
applyDefault(form);
if (notes.length == 0) {
save();
} else if (!use_cache) {
var caches = [];
$.each(T, function(i, v) {
//caches.push(encode(v, true).toSource());
caches.push(toSource(encode(v, true)));
});
window.setTimeout(function() {
GM_setValue(KEY_CACHE, "[" + caches.join(", ") + "]");
}, 0);
}
});
}
function applyDefault(form) {
debugLog('call applyDefault');
$(x('f'), form).each(function(k, v) {
var fromvalue = this.value;
matched = $.grep(T, function(i) {
return (i.name + '').indexOf('#') == 0 && i.from == fromvalue;
});
if (matched.length > 0) {
applyTemplate(matched[0].num, form);
}
});
}
function recomposeSelectElement(form) {
debugLog('call recomposeSelectElement');
var options = [];
options.push(toOption(trans('Template actions...'), 'init', true, 'gts_option_first'));
var enables = $.grep(T, function(o) {return (o.name && o.num != 0);});
var expand = function(arrays, cmd) {
var hash = {};
$.each(enables, function(i, v) {
hash[v.from] = hash[v.from] || [];
hash[v.from].push(v);
});
$.each(hash, function(i, v) {
arrays.push(toOption(' <' + (i || trans('No from')) + '>'));
$.each(v, function(j, t) {
arrays.push(toOption(' ' + t.name , cmd + '_' + t.num));
});
});
};
$.each([
{'cmd':'apply', 'exp':trans("Apply"), 'func':expand},
{'cmd':'add','exp':trans("Append"), 'func':function(arrays, cmd) {
var used = $.grep(T , function(o) { return (o.name && o.num != 0) });
if (used.length < 9) {
arrays.push(toOption(' ' + trans("Includes from") , cmd));
arrays.push(toOption(' ' + trans("Excludes from") , cmd + '_ignore_from'));
} else {
arrays.push(toOption(' ' + trans('Quantity limit is 9')));
}
}},
{'cmd':'delete','exp':trans('Remove'), 'func':expand}
], function(i, v) {
if (v.func == expand && enables.length ==0) { return; }
options.push(toOption('-------'));
options.push(toOption(trans('verbs', v.exp) + ':'));
v.func(options, v.cmd);
});
$('#id_gts_template', getView()).empty().append(options.join('')).each(function(){
this.value = 'init';
});
}
function addTemplate(form, contain_from) {
debugLog('call addTemplate');
var m = trans('Please input the template name.');
if (contain_from) {
m += '\n';
m += trans('If the name is started from "#", it becomes default of the corresponding "from".');
}
var name = window.prompt(m, "");
if (!name) {return;}
if ($.grep(T , function(o) { return (o.name == name) }).length > 0) {
alert(trans('The name already exists.'));
return;
}
var empties = $.grep(T , function(o) { return (o.name || o.num == 0) }, true);
var t = empties[0];
var body_rt_content = '';
try {
body_rt_content = $(x('r') , form).contents().find("body")[0].innerHTML || "";
} catch(e) {
debugLog('body_rt iframe not found.');
}
$.extend(T[t.num], {
'num' : t.num,
'id' : t.id,
'name' : name,
'from' : contain_from ? $(x('f') , form).val() : "",
'to' : $(x('t') , form).val(),
'cc' : $(x('c') , form).val(),
'bcc' : $(x('b') , form).val(),
'subject' : $(x('s') , form).val(),
'body' : $(x('m') , form).val(),
'body_rt' : body_rt_content
});
if (MSGBODY_RE.exec(T[t.num].body)) {
T[t.num].body = RegExp.$1;
T[t.num].body_latter = RegExp.$2;
}
if (MSGBODY_RT_RE.exec(T[t.num].body_rt)) {
T[t.num].body_rt = RegExp.$1;
T[t.num].body_rt_latter = RegExp.$2;
}
editContact(T[t.num], function() {
recomposeSelectElement(form);
msg(trans('appended', name));
});
}
function applyTemplate(num , form) {
debugLog('request apply : ' + num);
var span = {'from':'change|変更', 'subject':'Subject|件名', 'cc':'Cc', 'bcc':'Bcc'};
if (typeof T[0]._init == 'undefined') {
T[0]._init = {};
$(x('f,s,t,c,b,m'), form).each(function(i) { T[0]._init[this.name] = $.trim(this.value); });
$(x('r'), form).each(function(i) { T[0]._init["body_rt"] = $.trim($(this).contents().find("body")[0].innerHTML); });
}
$(x('f,s,t,c,b'), form).each(function(i) {
if (span[this.name] && T[num][this.name]) {
var target = getLabel(span[this.name]);
if (target) emulate_click(target, null);
}
var tmp = T[0]._init[this.name];
if (this.type == 'textarea') {
var targetaddrs = tmp || '';
//既に含まれているものは追加しない
var notcontains = $.grep(T[num][this.name].split(','), function(i) {
if ($.trim(i).length == 0) { return; }//空白は無視
if (/([\w\.+-]+@[\w+-]+(\.[\w+-]+)+)/.exec(i)) {
return targetaddrs.indexOf(RegExp.$1) < 0;
} else {
return targetaddrs.indexOf(i) < 0;
}
});
if (tmp) { notcontains.unshift(tmp); }
this.value = notcontains.join(', ');
} else if (this.name == 'from' && this.value == T[num][this.name]) {
return;
} else {
this.value = (this.name == 'subject' && tmp) ? tmp : T[num][this.name];
}
});
$(x('m'), form).each(function(i, v) {
this.value = $.grep([
T[num].body, T[0]._init.body, T[num].body_latter
], function(i) { return i; }).join("\n\n");
});
$(x('r'), form).each(function(i, v) {
var b = $(this).contents().find("body")[0];
if (!T[num].body_rt && !T[num].body_rt_latter) {
var tmp_body = (T[num].body || "").replace(/\r\n/g,"<br>").replace(/(\n|\r)/g,"<br>");
var tmp_body_latter = (T[num].body_latter || "").replace(/\r\n/g,"<br>").replace(/(\n|\r)/g,"<br>");
$(b).html($.grep([
tmp_body, T[0]._init.body_rt, tmp_body_latter
], function(i) { return i; }).join("<br>"));
} else {
$(b).html($.grep([
T[num].body_rt, T[0]._init.body_rt, T[num].body_rt_latter
], function(i) { return i; }).join("<br>"));
}
});
$(x('s,t'), form).each(function() {
if (!this.value) {
//$(this).focus();
this.selectionStart = 0;
this.selectionEnd = 0;
}
});
$(x('m'), form).each(function() {
if ((this.name == 'body') && $(this).parent().parent().css("display") != "none") {
//$(this).focus();
this.selectionStart = 0;
this.selectionEnd = 0;
} else {
$(x('r'), form).each(function() {
$(this).contents().find("body")[0].selectionStart = 0;
$(this).contents().find("body")[0].selectionEnd = 0;
});
}
});
var undos = [
toOption('-------', null, null, "gts_undo_option"),
toOption(' ' + trans("Undo"), 'undo', null, "gts_undo_option")
];
$('#id_gts_template .gts_undo_option', getView()).remove();
$('#id_gts_template .gts_option_first', getView()).after(undos.join(''));
msg(trans('applied', T[num].name), function() {
undo(form);
msg(trans("To apply template was canceled."));
return false;
}, true);
}
function undo(form) {
debugLog('undo');
if (typeof T[0]._init != 'undefined') {
$(x('t,c,b,m'), form).each(function() { this.value = T[0]._init[this.name]; });
$(x('r'), form).each(function() { $(this).contents().find("body")[0].innerHTML = T[0]._init["body_rt"]; });
}
delete T[0]._init;
$('#id_gts_template .gts_undo_option', getView()).remove();
}
function emulate_click(target, form) {
$(target, form).each(function(i) {
if (this.dispatchEvent) {
var e = document.createEvent('MouseEvents');
e.initEvent("click", true, true);
this.dispatchEvent(e);
}
});
}
function deleteTemplate(num , form) {
var name = T[num].name;
if (confirm(trans('remove confirm', name)) != true) {
return;
}
debugLog('request delete : ' + num);
T[num] = {'id' : T[num].id, 'num' : num};
editContact(T[num], function() {
recomposeSelectElement(form);
msg(trans("removed", name));
});
}
function getTemplates(f_parseTemplate) {
debugLog('call getTemplates');
var queryUrl = 'contacts/u/'+getUserNumber()+'/data/contacts?thumb=false&groups=false&show=ALL&psort=Name&max=300&out=js&rf=&jsx=true';
ajax(queryUrl, function(req){
contactPage = req.replace('while (true); ', '').replace(/&&&START&&&([^&&&]+)&&&END&&&/, "$1");
response = eval("(" + contactPage + ")");
if (response.Success) {
var contacts = response.Body.Contacts;
var notes = [];
for(i=0; i<contacts.length; i++) {
if (contacts[i].Name && /gtssettings(\d)/.exec(contacts[i].Name) ) {
num = RegExp.$1;
note = contacts[i].Notes;
id = contacts[i].Id;
notes.push({'num' : num, 'note' : note, 'id' : id});
}
}
var authtoken = response.Body.AuthToken.Value;
window.setTimeout(function() {
GM_setValue(KEY_TOKEN, authtoken);
}, 0);
f_parseTemplate(notes);
} else {
debugLog("Contacts Request Failed: " + response.Errors[0].Text);
}
});
}
function editContact(tmpl, f_completed) {
window.setTimeout(function() {
var authtoken = GM_getValue(KEY_TOKEN);
if (!authtoken) {
debugLog('token not found');
return;
}
var escaped = encode(tmpl, true);
var post_data = $.param({
'token' : authtoken,
'tok' : authtoken,
'out' : 'js',
'id' : tmpl.id,
'action' : 'SET',
'Name' : CONTACT_NAME + tmpl.num,
'Emails.0.Address' : CONTACT_NAME+tmpl.num+'@gmail.com',
'Notes' : encode(escaped, false)
});
ajax('contacts/u/'+getUserNumber()+'/update/contact', function(req) {
var response = eval("(" + req.replace('while (true); ', '').replace(/&&&START&&&([^&&&]+)&&&END&&&/, "$1") + ")");
if (response.Success) {
if (tmpl.id == -1) {
if (CONTACT_ID_RE.exec(req)) {
tmpl.id = RegExp.$1;
editContact(tmpl, f_completed);
}
} else {
if (tmpl.num != 0) {
save(f_completed);
} else {
f_completed();
}
}
} else {
debugLog('Update Contact Request Failed: '+response.Errors[0].Text);
}
}, 'POST', {'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8'}, post_data);
}, 0);
}
function encode(tmpl, by_escape) {
if (by_escape) {
var escaped = {};
/* encodeURIだと「'」がエンコードされないので、escapeを使う */
$.each(tmpl, function(i, v) {
if (i.indexOf('_') == 0) { return; }
escaped[i] = escape(v);
});
return escaped;
} else {
/* 連絡先は「"」で囲まれるため、JSONデータを表すのに「"」を使えない。
連絡先から復元するときに使うデータを、REGEXでマッチさせるため「"」を「'」に置換しておく。 */
//return tmpl.toSource().replace(/\"/g, "'");
return toSource(tmpl).replace(/\"/g, "'");
}
}
function decode(tmpl, by_unescape) {
if (by_unescape) {
var unescaped = {};
$.each(tmpl, function(k, v) {unescaped[k] = unescape(v);});
return unescaped;
} else {
/* 連絡先に格納するために、「'」に変換しておいた「"」を戻す */
return tmpl.replace(/\\'/g, "\"");
}
}
function getCookie(name) {
var re = new RegExp(name + "=([^;]+)");
var value = re.exec(document.cookie);
return (value != null) ? decodeURI(value[1]) : null;
}
function msg(message, f_clicked, use_undo) {
//var w = typeof unsafeWindow != 'undefined' && unsafeWindow || window;
//w.gts_undo = f_clicked;
contentWindow.gts_undo = f_clicked;
$("table[role='alert']", getView().ownerDocument).each(function() {
$('td:eq(4)', this).html('GTS : '+message);
if (use_undo) {
$('td:eq(4)', this).append($('<span id="link_undo" class="SdKLH Pns21c" >').text(trans('Undo link')).click(f_clicked));
}
$(this).parent().css('visibility', 'visible');
window.setTimeout(function() {
$("table[role='alert']", getView().ownerDocument).each(function() {
var re = new RegExp('GTS : '+message);
if ($('td:eq(4)', this).html().match(re)) {
$(this).parent().css('visibility', 'hidden');
}
});
}, 10000);
});
}
function save(f_saved) {
debugLog('T[0].id: '+T[0].id);
T[0]['num'] = 0;
T[0].date = new Date();
editContact(T[0], f_saved ? f_saved : function() {});
}
function ajax(request_path, f_load, get_or_post, headers, data) {
window.setTimeout(function() {
$.ajax({
'type': get_or_post ? get_or_post : "GET",
'url': getBaseLocation() + request_path,
'data': data,
'headers': headers,
'success': f_load,
'error': function(req) {
debugLog("Request Failed in error code: " + req.status);
}
});
}, 0);
}
function getBaseLocation() {
if (LOCATION_RE.exec(document.location)) {//for Google Apps
return RegExp.$1;
} else {
http = 'http';
if (window.location.toString().charAt(4) == 's') {
http = 'https';
}
return http + '://mail.google.com/mail/';
}
}
function getUserNumber() {
var user_number = 0;
if (USER_NUMBER_RE.exec(document.location)) {
if (RegExp.$1) {
user_number = RegExp.$1;
}
}
debugLog("user number is " + user_number);
return user_number;
}
function trans(msg_id, opt) {
return {
'Template actions...' : Ja ? 'テンプレートの操作...' : msg_id,
'Apply' : Ja ? '適用' : msg_id,
'Append' : Ja ? '追加' : msg_id,
'Includes from' : Ja ? '差出人を含む' : msg_id,
'Excludes from' : Ja ? '差出人を除く' : msg_id,
'Quantity limit is 9' : Ja ? '最大9個です' : msg_id,
'Remove' : Ja ? '削除' : msg_id,
'verbs' : Ja ? (opt + 'するテンプレート') : (opt + ' template'),
'Please input the template name.' : Ja ? 'テンプレート名を入力してください。' : msg_id,
'If the name is started from "#", it becomes default of the corresponding "from".' :
Ja ? '名前を「#」から始めると、対応する差出人のデフォルトになります。' : msg_id,
'The name already exists.' : Ja ? 'その名前は既に存在します。' : msg_id,
'appended' : Ja ? ("テンプレート「" + opt + "」を追加しました。")
: ('Template "' + opt + '" was appended.'),
'applied' : Ja ? ("テンプレート「"+opt+"」を適用しました。")
: ('Template "' + opt + '" was applied. '),
'remove confirm' : Ja ? ("テンプレート「" + opt + "」を削除しますか?")
: ('Is template "' + opt + '" removed?'),
'removed' : Ja ? ("テンプレート「" + opt + "」を削除しました。")
: ('Template "' + opt + '" was removed.'),
'To apply template was canceled.' : Ja ? "テンプレートの適用は取り消されました。" : msg_id,
'Undo' : Ja ? "適用の取り消し" : msg_id,
'Undo link' : Ja ? "適用取り消し" : "Undo applied",
'No from' : Ja ? "差出人なし" : msg_id
}[msg_id] || msg_id;
}
function x(prefix) {
var result = [];
$.each(SELECTOR, function(i, v) {
if (typeof prefix != 'undefined') {
if ($.grep(prefix.split(','), function(j) { return i.indexOf(j) == 0; }).length == 0) {
return;
}
}
result.push(v);
});
return result.join(', ');
}
/*
* Thanks
* http://opera.higeorange.com/misc/jsToSource.html
* http://blog.livedoor.jp/dankogai/archives/50957994.html
*/
function toSource(obj) {
if (typeof obj.toSource != 'undefined') return obj.toSource();
var con = obj.constructor;
if (con == Boolean) {
return obj.toString();
} else if (con == Number) {
return obj.toString();
} else if (con == String) {
return '\"'+obj.toString().replace(/[\\\"\']/g, function(m0) {
return '\\' + m0;
})+'\"';
} else if (con == Date) {
return '(new Date('+obj.valueOf()+'))';
} else if (con == RegExp) {
return obj.toString();
} else if (con == Function) {
return obj.toString();
} else if (con == Array) {
var src = [];
for (var i=0, l=obj.length; i<l; i++) {
src[i] = toSource(obj[i]);
}
return '['+src.toString()+']';
} else if (con == Object) {
var src = [];
for (var p in obj) {
if (!obj.hasOwnProperty(p)) continue;
//src[src.length] = toSource(p) + ':' + (obj[p] ? toSource(obj[p]) : obj[p] === undefined ? 'undefined' : 'null');
src[src.length] = toSource(p) + ':' + toSource(obj[p]);
}
// parens needed to make eval() happy
return '({'+src.toString()+'})';
}
}
function debugLog(str){
if (DEBUG_MODE){
if (typeof(GM_log) != 'function' && typeof(opera) != 'undefined') {
GM_log = opera.postError; // for opera
}
GM_log(str);
}
}
})(this.contentWindow||typeof unsafeWindow != 'undefined' && unsafeWindow||window);