'
].join('');
if (!document.namespaces['v'])
document.namespaces.add('v', 'urn:schemas-microsoft-com:vml', '#default#VML');
}
/**
* Convert HSV representation to RGB HEX string.
* Credits to http://www.raphaeljs.com
*/
function hsv2rgb(hsv) {
var R,
G,
B,
X,
C;
var h = (hsv.h % 360) / 60;
C = hsv.v * hsv.s;
X = C * (1 - Math.abs(h % 2 - 1));
R = G = B = hsv.v - C;
h = ~~h;
R += [C, X, 0, 0, X, C][h];
G += [X, C, C, X, 0, 0][h];
B += [0, 0, X, C, C, X][h];
var r = Math.floor(R * 255);
var g = Math.floor(G * 255);
var b = Math.floor(B * 255);
return {
r : r,
g : g,
b : b,
hex : "#" + (16777216 | b | (g << 8) | (r << 16)).toString(16).slice(1)
};
}
/**
* Convert RGB representation to HSV.
* r, g, b can be either in <0,1> range or <0,255> range.
* Credits to http://www.raphaeljs.com
*/
function rgb2hsv(rgb) {
var r = rgb.r;
var g = rgb.g;
var b = rgb.b;
if (rgb.r > 1 || rgb.g > 1 || rgb.b > 1) {
r /= 255;
g /= 255;
b /= 255;
}
var H,
S,
V,
C;
V = Math.max(r, g, b);
C = V - Math.min(r, g, b);
H = (C == 0 ? null :
V == r ? (g - b) / C + (g < b ? 6 : 0) :
V == g ? (b - r) / C + 2 :
(r - g) / C + 4);
H = (H % 6) * 60;
S = C == 0 ? 0 : C / V;
return {
h : H,
s : S,
v : V
};
}
/**
* Return click event handler for the slider.
* Sets picker background color and calls ctx.callback if provided.
*/
function slideListener(ctx, slideElement, pickerElement) {
return function (evt) {
evt = evt || window.event;
var mouse = mousePosition(evt);
ctx.h = mouse.y / slideElement.offsetHeight * 360 + hueOffset;
var pickerColor = hsv2rgb({
h : ctx.h,
s : 1,
v : 1
});
var c = hsv2rgb({
h : ctx.h,
s : ctx.s,
v : ctx.v
});
pickerElement.style.backgroundColor = pickerColor.hex;
ctx.callback && ctx.callback(c.hex, {
h : ctx.h - hueOffset,
s : ctx.s,
v : ctx.v
}, {
r : c.r,
g : c.g,
b : c.b
}, undefined, mouse);
}
};
/**
* Return click event handler for the picker.
* Calls ctx.callback if provided.
*/
function pickerListener(ctx, pickerElement) {
return function (evt) {
evt = evt || window.event;
var mouse = mousePosition(evt),
width = pickerElement.offsetWidth,
height = pickerElement.offsetHeight;
ctx.s = mouse.x / width;
ctx.v = (height - mouse.y) / height;
var c = hsv2rgb(ctx);
ctx.callback && ctx.callback(c.hex, {
h : ctx.h - hueOffset,
s : ctx.s,
v : ctx.v
}, {
r : c.r,
g : c.g,
b : c.b
}, mouse);
}
};
var uniqID = 0;
/**
* ColorPicker.
* @param {DOMElement} slideElement HSV slide element.
* @param {DOMElement} pickerElement HSV picker element.
* @param {Function} callback Called whenever the color is changed provided chosen color in RGB HEX format as the only argument.
*/
function ColorPicker(slideElement, pickerElement, callback) {
if (!(this instanceof ColorPicker))
return new ColorPicker(slideElement, pickerElement, callback);
this.h = 0;
this.s = 1;
this.v = 1;
if (!callback) {
// call of the form ColorPicker(element, funtion(hex, hsv, rgb) { ... }), i.e. the no-hassle call.
var element = slideElement;
element.innerHTML = colorpickerHTMLSnippet;
this.slideElement = element.getElementsByClassName('slide')[0];
this.pickerElement = element.getElementsByClassName('picker')[0];
var slideIndicator = element.getElementsByClassName('slide-indicator')[0];
var pickerIndicator = element.getElementsByClassName('picker-indicator')[0];
ColorPicker.fixIndicators(slideIndicator, pickerIndicator);
this.callback = function (hex, hsv, rgb, pickerCoordinate, slideCoordinate) {
ColorPicker.positionIndicators(slideIndicator, pickerIndicator, slideCoordinate, pickerCoordinate);
pickerElement(hex, hsv, rgb);
};
} else {
this.callback = callback;
this.pickerElement = pickerElement;
this.slideElement = slideElement;
}
if (type == 'SVG') {
// Generate uniq IDs for linearGradients so that we don't have the same IDs within one document.
// Then reference those gradients in the associated rectangles.
var slideClone = slide.cloneNode(true);
var pickerClone = picker.cloneNode(true);
var hsvGradient = slideClone.getElementById('gradient-hsv');
var hsvRect = slideClone.getElementsByTagName('rect')[0];
hsvGradient.id = 'gradient-hsv-' + uniqID;
hsvRect.setAttribute('fill', 'url(#' + hsvGradient.id + ')');
var blackAndWhiteGradients = [pickerClone.getElementById('gradient-black'), pickerClone.getElementById('gradient-white')];
var whiteAndBlackRects = pickerClone.getElementsByTagName('rect');
blackAndWhiteGradients[0].id = 'gradient-black-' + uniqID;
blackAndWhiteGradients[1].id = 'gradient-white-' + uniqID;
whiteAndBlackRects[0].setAttribute('fill', 'url(#' + blackAndWhiteGradients[1].id + ')');
whiteAndBlackRects[1].setAttribute('fill', 'url(#' + blackAndWhiteGradients[0].id + ')');
this.slideElement.appendChild(slideClone);
this.pickerElement.appendChild(pickerClone);
uniqID++;
} else {
this.slideElement.innerHTML = slide;
this.pickerElement.innerHTML = picker;
}
addEventListener(this.slideElement, 'click', slideListener(this, this.slideElement, this.pickerElement));
addEventListener(this.pickerElement, 'click', pickerListener(this, this.pickerElement));
enableDragging(this, this.slideElement, slideListener(this, this.slideElement, this.pickerElement));
enableDragging(this, this.pickerElement, pickerListener(this, this.pickerElement));
};
function addEventListener(element, event, listener) {
if (element.attachEvent) {
element.attachEvent('on' + event, listener);
} else if (element.addEventListener) {
element.addEventListener(event, listener, false);
}
}
/**
* Enable drag&drop color selection.
* @param {object} ctx ColorPicker instance.
* @param {DOMElement} element HSV slide element or HSV picker element.
* @param {Function} listener Function that will be called whenever mouse is dragged over the element with event object as argument.
*/
function enableDragging(ctx, element, listener) {
var mousedown = false;
addEventListener(element, 'mousedown', function (evt) {
mousedown = true;
});
addEventListener(element, 'mouseup', function (evt) {
mousedown = false;
});
addEventListener(element, 'mouseout', function (evt) {
mousedown = false;
});
addEventListener(element, 'mousemove', function (evt) {
if (mousedown) {
listener(evt);
}
});
}
ColorPicker.hsv2rgb = function (hsv) {
var rgbHex = hsv2rgb(hsv);
delete rgbHex.hex;
return rgbHex;
};
ColorPicker.hsv2hex = function (hsv) {
return hsv2rgb(hsv).hex;
};
ColorPicker.rgb2hsv = rgb2hsv;
ColorPicker.rgb2hex = function (rgb) {
return hsv2rgb(rgb2hsv(rgb)).hex;
};
ColorPicker.hex2hsv = function (hex) {
return rgb2hsv(ColorPicker.hex2rgb(hex));
};
ColorPicker.hex2rgb = function (hex) {
return {
r : parseInt(hex.substr(1, 2), 16),
g : parseInt(hex.substr(3, 2), 16),
b : parseInt(hex.substr(5, 2), 16)
};
};
/**
* Sets color of the picker in hsv/rgb/hex format.
* @param {object} ctx ColorPicker instance.
* @param {object} hsv Object of the form: { h: , s: , v: }.
* @param {object} rgb Object of the form: { r: , g: , b: }.
* @param {string} hex String of the form: #RRGGBB.
*/
function setColor(ctx, hsv, rgb, hex) {
ctx.h = hsv.h % 360;
ctx.s = hsv.s;
ctx.v = hsv.v;
var c = hsv2rgb(ctx);
var mouseSlide = {
y : (ctx.h * ctx.slideElement.offsetHeight) / 360,
x : 0 // not important
};
var pickerHeight = ctx.pickerElement.offsetHeight;
var mousePicker = {
x : ctx.s * ctx.pickerElement.offsetWidth,
y : pickerHeight - ctx.v * pickerHeight
};
ctx.pickerElement.style.backgroundColor = hsv2rgb({
h : ctx.h,
s : 1,
v : 1
}).hex;
ctx.callback && ctx.callback(hex || c.hex, {
h : ctx.h,
s : ctx.s,
v : ctx.v
}, rgb || {
r : c.r,
g : c.g,
b : c.b
}, mousePicker, mouseSlide);
return ctx;
};
/**
* Sets color of the picker in hsv format.
* @param {object} hsv Object of the form: { h: , s: , v: }.
*/
ColorPicker.prototype.setHsv = function (hsv) {
return setColor(this, hsv);
};
/**
* Sets color of the picker in rgb format.
* @param {object} rgb Object of the form: { r: , g: , b: }.
*/
ColorPicker.prototype.setRgb = function (rgb) {
return setColor(this, rgb2hsv(rgb), rgb);
};
/**
* Sets color of the picker in hex format.
* @param {string} hex Hex color format #RRGGBB.
*/
ColorPicker.prototype.setHex = function (hex) {
return setColor(this, ColorPicker.hex2hsv(hex), undefined, hex);
};
/**
* Helper to position indicators.
* @param {HTMLElement} slideIndicator DOM element representing the indicator of the slide area.
* @param {HTMLElement} pickerIndicator DOM element representing the indicator of the picker area.
* @param {object} mouseSlide Coordinates of the mouse cursor in the slide area.
* @param {object} mousePicker Coordinates of the mouse cursor in the picker area.
*/
ColorPicker.positionIndicators = function (slideIndicator, pickerIndicator, mouseSlide, mousePicker) {
if (mouseSlide) {
slideIndicator.style.top = (mouseSlide.y - slideIndicator.offsetHeight / 2) + 'px';
}
if (mousePicker) {
pickerIndicator.style.top = (mousePicker.y - pickerIndicator.offsetHeight / 2) + 'px';
pickerIndicator.style.left = (mousePicker.x - pickerIndicator.offsetWidth / 2) + 'px';
}
};
/**
* Helper to fix indicators - this is recommended (and needed) for dragable color selection (see enabledDragging()).
*/
ColorPicker.fixIndicators = function (slideIndicator, pickerIndicator) {
pickerIndicator.style.pointerEvents = 'none';
slideIndicator.style.pointerEvents = 'none';
};
window.ColorPicker = ColorPicker;
})(window, window.document);
const HREF_NO = 'javascript:void(0)';
initCrossBrowserSupportForGmFunctions();
var languagesGoogle = '';
var body = getTag('body')[0];
var imgLookup;
var txtSel = encodeURIComponent(txtSel); // text selected
var translation2Element = document.createElement('span');
var currentURL;
var initialized = false;
images();
css();
document.addEventListener('mouseup', showLookupIcon, false);
document.addEventListener('mousedown', mousedownCleaning, false);
function mousedownCleaning(evt) {
var divDic = getId('divDic');
var divLookup = getId('divLookup');
if (divDic) {
if (!clickedInsideID(evt.target, 'divDic'))
divDic.parentNode.removeChild(divDic);
}
if (divLookup)
divLookup.parentNode.removeChild(divLookup);
}
function showLookupIcon(evt) {
if (evt.ctrlKey && evt.altKey && (!GM_getValue('ctrl') || !GM_getValue('alt')))
return;
// XOR http://www.howtocreate.co.uk/xor.html
if (evt.ctrlKey ? !GM_getValue('ctrl') : GM_getValue('ctrl'))
return;
if (evt.altKey ? !GM_getValue('alt') : GM_getValue('alt'))
return;
if (!initialized) {
images();
css();
initialized = true;
}
var divDic = getId('divDic');
var divLookup = getId('divLookup');
txtSel = getSelection();
// Exit if no text is selected
if (!txtSel || txtSel == "") {
if (divDic) {
if (!clickedInsideID(evt.target, 'divDic'))
divDic.parentNode.removeChild(divDic);
}
if (divLookup)
divLookup.parentNode.removeChild(divLookup);
return;
}
// Possible cleanup
if (divDic) {
if (!clickedInsideID(evt.target, 'divDic'))
divDic.parentNode.removeChild(divDic);
return;
}
// Remove div if exists
if (divLookup) {
divLookup.parentNode.removeChild(divLookup);
}
// Div container
divLookup = createElement('div', {
id : 'divLookup',
style : 'background-color:transparent; color:#000000; position:absolute; top:' + (evt.clientY + window.pageYOffset + 10) + 'px; left:' + (evt.clientX + window.pageXOffset + 10) + 'px; padding:0px; z-index:10000; border-radius:2px;'
});
divLookup.appendChild(imgLookup.cloneNode(false));
divLookup.addEventListener('mouseover', lookup, false);
body.appendChild(divLookup);
}
// Create the tooltip and launch the Google Translate request to get the translation
function lookup(evt) {
var divResult = null;
var divDic = getId('divDic');
var divLookup = getId('divLookup');
var top = divLookup.style.top;
var left = divLookup.style.left;
// No text selected
if (!txtSel || txtSel == "") {
if (divDic = getId('divDic'))
divDic.parentNode.removeChild(divDic);
return;
}
// Cleanup divs
if (divDic = getId('divDic')) {
divDic.parentNode.removeChild(divDic);
}
divLookup.parentNode.removeChild(divLookup);
// Div container
divDic = createElement('div', {
id : 'divDic',
style : 'opacity: 1; font-family: "Open Sans", Arial, Helvetica, sans-serif !important; font-size: ' + GM_getValue('fontsize', 'small') + '; background-color: ' + GM_getValue('backgroundColor', '#EDF4FC') + '; color: ' + GM_getValue('textcolor', 'Gray') + '; position:absolute; top:' + top + '; left:' + left + '; min-width:250px; min-height:50px; max-width:50%; padding:5px; text-align:left; z-index:10000; border-radius:4px; box-shadow: -2px 0px 9px 5px #898D91'
});
divDic.addEventListener('mousedown', dragHandler, false);
body.appendChild(divDic);
// Div result
// This awfull wall of text is the "+" image
divResult = createElement('div', {
id : 'divResult',
style : 'overflow:auto; padding:3px;'
}, null, ' Loading...');
divDic.appendChild(divResult);
// Options link
var optionLink = createElement('a', {
id : 'optionsLink',
href : HREF_NO,
style : 'opacity:0.2; position:absolute; bottom:3px; right:13px; font-size:18px; text-decoration:none!important;background:#528DDF;padding:1px;color:#fff;border-radius:6px 6px 6px 6px;border:2px solid #EEEEEE;font-weight:bold;width:20px;text-align:center;display:block;'
}, 'click openCloseOptions false', '+');
divDic.appendChild(optionLink);
optionLink.addEventListener('mouseover', function (e) {
e.target.style.opacity = 1.0
});
optionLink.addEventListener('mouseout', function (e) {
e.target.style.opacity = 0.2
});
// Send the Google Translate request
if ((txtSel + " ").search(/^\s*https?:\/\//) > -1) {
divResult.innerHTML = '' + txtSel + '';
} else if ((txtSel + " ").search(/^\s*\S+(\.\S+)+/) > -1) // site.dom
{
divResult.innerHTML = '' + txtSel + '';
} else {
var sl,
tl,
lang;
sl = GM_getValue('from') ? GM_getValue('from') : "auto";
tl = GM_getValue('to') ? GM_getValue('to') : "auto";
lang = sl + "|" + tl;
//currentURL = "http://www.google.com/translate_t?text=" + encodeURIComponent(txtSel) + "&langpair=" + lang; // Basic address, for web page parsing
//currentURL = "http://translate.google.fr/translate_a/t?client=t&text=" + encodeURIComponent(txtSel) + "&langpair=" + lang; // URL for GET request. This adress return an array as answer
currentPostData = "client=t&text=" + encodeURIComponent(txtSel) + "&langpair=" + lang; // Data for a POST request, for handling long requests
GM_xmlhttpRequest({
/*method: 'GET',
url: currentURL,*/
method : 'POST',
url : 'http://translate.google.fr/translate_a/t',
data : currentPostData,
headers : {
'Content-Type' : 'application/x-www-form-urlencoded'
},
onload : function (resp) {
try {
extractResult(resp.responseText);
} catch (e) {
GM_log(e);
}
}
});
if (GM_getValue('to2', 'Disabled') != 'Disabled') {
sl = GM_getValue('from') ? GM_getValue('from') : "auto";
tl = GM_getValue('to2') ? GM_getValue('to2') : "auto";
lang = sl + "|" + tl;
currentPostData = "client=t&text=" + encodeURIComponent(txtSel) + "&langpair=" + lang; // Data for a POST request, for handling long requests
GM_xmlhttpRequest({
method : 'POST',
url : 'http://translate.google.fr/translate_a/t',
data : currentPostData,
headers : {
'Content-Type' : 'application/x-www-form-urlencoded'
},
onload : function (resp) {
try {
extractResult2(resp.responseText);
} catch (e) {
GM_log(e);
}
}
});
} else {
translation2Element.innerHTML = '';
}
}
}
// Lanched when we select an other language in the setup menu
function quickLookup() {
getId('divDic').style.fontSize = getId('optFontSize').value;
getId('divDic').style.color = getId('optTextColor').value;
getId('divResult').innerHTML = 'Loading...';
var sl,
tl,
lang;
sl = getId('optSelLangFrom').value;
tl = getId('optSelLangTo').value;
lang = sl + "|" + tl;
currentPostData = "client=t&text=" + encodeURIComponent(txtSel) + "&langpair=" + lang; // Data for a POST request, for handling long requests
GM_xmlhttpRequest({
method : 'POST',
url : 'http://translate.google.fr/translate_a/t',
data : currentPostData,
headers : {
'Content-Type' : 'application/x-www-form-urlencoded'
},
onload : function (resp) {
try {
extractResult(resp.responseText);
} catch (e) {
GM_log(e);
}
}
});
if (getId('optSelLangTo2').value != 'Disabled') {
var sl,
tl,
lang;
sl = getId('optSelLangFrom').value;
tl = getId('optSelLangTo2').value;
currentPostData = "client=t&text=" + encodeURIComponent(txtSel) + "&langpair=" + lang; // Data for a POST request, for handling long requests
GM_xmlhttpRequest({
method : 'POST',
url : 'http://translate.google.fr/translate_a/t',
data : currentPostData,
headers : {
'Content-Type' : 'application/x-www-form-urlencoded'
},
onload : function (resp) {
try {
extractResult2(resp.responseText);
} catch (e) {
GM_log(e);
}
}
});
} else {
translation2Element.innerHTML = '';
}
}
function extractResult(gTradStringArray) {
var arr = eval(gTradStringArray); // eval is used to transform the string to an array. I alse made a custom parsing function, but it doesn't handle antislashed characters, so I prefer using eval()
/*
Content of the gTrad array :
0 / 0:Translation 1:Source text
1 / i:Grammar / 0:Types (word, verb, ...) 1: Other translations
5 / Array of other translations
*/
var translation = '';
// 0 - Full translation
translation += '[' + arr[2] + '] ';
for (var i = 0; i < arr[0].length; i++)
translation += arr[0][i][1];
translation += ' ';
translation += '[' + GM_getValue('to', 'auto') + '] ';
for (var i = 0; i < arr[0].length; i++)
translation += arr[0][i][0];
translation += '
';
translation += 'Show details';
translation += 'Hide details ';
// 1 - Grammar
if (typeof arr[1] != 'undefined') {
for (var i = 0; i < arr[1].length; i++) {
translation += '' + arr[1][i][0] + ' : ';
for (var j = 0; j < arr[1][i][1].length; j++) {
translation += ((j == 0) ? '' : ', ') + arr[1][i][1][j];
}
translation += ' ';
}
translation += ' ';
}
// 5 - Alternative parts
if (typeof arr[5] != 'undefined') {
for (var i = 0; i < arr[5].length; i++) {
if (typeof arr[5][i][2] != 'undefined') { // 5/i/2 array of alternatives, 5/i/0 the part of the text we are studying
translation += '' + arr[5][i][0] + ' : ';
for (var j = 0; j < arr[5][i][2].length; j++) {
translation += ((j == 0) ? '' : ', ') + arr[5][i][2][j][0];
}
translation += ' ';
}
}
}
translation += ''; // Detail end
getId('divResult').innerHTML = '
' + translation + '
';
getId('translation2Element').appendChild(translation2Element); // Optional second translation
getId('toggleShowDetails').addEventListener('click', function () {
getId('toggleShowDetails').style.display = 'none';
getId('divDetails').style.display = 'block';
}, false);
getId('toggleHideDetails').addEventListener('click', function () {
getId('toggleShowDetails').style.display = 'inline';
getId('divDetails').style.display = 'none';
}, false);
// Create the Text to Speach
var fromText = '';
var toText = '';
for (var i = 0; i < arr[0].length; i++)
fromText += arr[0][i][1];
for (var i = 0; i < arr[0].length; i++)
toText += arr[0][i][0];
addTextToSpeachLink(getId('texttospeachbuttonfrom'), arr[2], fromText); // arr[2] contains the detected input language
addTextToSpeachLink(getId('texttospeachbuttonto'), GM_getValue('to', 'auto') == 'auto' ? 'en' : GM_getValue('to', 'auto'), toText); // I cannot find a way to get the detected destination language, so if the requested destination is 'auto', I use the english Text to Speach language
}
function extractResult2(gTradStringArray) {
var arr = eval(gTradStringArray);
var translation = '';
translation += '#[' + GM_getValue('to2', 'auto') + '] ';
for (var i = 0; i < arr[0].length; i++)
translation += arr[0][i][0];
translation += '# ';
translation2Element.innerHTML = translation;
var toText2 = '';
for (var i = 0; i < arr[0].length; i++)
toText2 += arr[0][i][0];
addTextToSpeachLink(getId('texttospeachbuttonto2'), GM_getValue('to2', 'auto') == 'auto' ? 'en' : GM_getValue('to2', 'auto'), toText2);
}
function addTextToSpeachLink(element, lang, text) {
if (GM_getValue('tts', false) == false)
return;
var speachLink = document.createElement('a');
speachLink.href = 'http://translate.google.com/translate_tts?tl=' + lang + '&q=' + text.replace(/[«»'"]/g, ' ');
speachLink.target = '_blank';
speachLink.innerHTML = '';
element.appendChild(speachLink);
}
function getSelection() {
var txt = null;
//get selected text
if (window.getSelection && !window.opera) // window.getSelection() bugs with Opera 12.16 and ViolentMonkey
{
txt = window.getSelection();
} else if (document.getSelection) {
txt = document.getSelection();
} else if (document.selection) {
txt = document.selection.createRange().text;
}
return txt;
}
function openCloseOptions(evt) {
var divOptions = getId('divOpt');
if (!divOptions) //Show options
{
divOptions = createElement('div', {
id : 'divOpt',
style : 'border-top:2px solid #5A91D8;position:relative; padding:5px;'
});
getId('divDic').appendChild(divOptions);
getId('optionsLink').style.visibility = 'hidden';
// color picker, the library doesn't work on Opera
try {
if (!window.divColorPicker) {
window.divColorPicker = createElement('div', {
id : 'optPicker',
class : 'cp-small'
});
window.colorPicker = ColorPicker(
window.divColorPicker,
function (hex, hsv, rgb) {
getId('divDic').style.backgroundColor = hex;
});
}
window.colorPicker.setHex(GM_getValue('backgroundColor', '#EDF4FC'));
divOptions.appendChild(window.divColorPicker);
} catch (err) {
divOptions.innerHTML += '
Error : Cannot load color picker (Known issue on Opera)
';
}
//fields container
divOptionsFields = createElement('p');
divOptions.appendChild(divOptionsFields);
//from
divOptionsFields.appendChild(createElement('span', null, null, 'From :'));
divOptionsFields.appendChild(createElement('select', {
id : 'optSelLangFrom'
}, null, languagesGoogle));
getId('optSelLangFrom').value = GM_getValue('from') ? GM_getValue('from') : 'auto';
getId('optSelLangFrom').addEventListener('change', quickLookup, false);
//to
divOptionsFields.appendChild(createElement('br'));
divOptionsFields.appendChild(createElement('span', null, null, ' To :'));
divOptionsFields.appendChild(createElement('select', {
id : 'optSelLangTo'
}, null, languagesGoogle));
getId('optSelLangTo').value = GM_getValue('to') ? GM_getValue('to') : 'auto';
getId('optSelLangTo').addEventListener('change', quickLookup, false);
//to2
divOptionsFields.appendChild(createElement('br'));
divOptionsFields.appendChild(createElement('span', null, null, ' To 2 :'));
divOptionsFields.appendChild(createElement('select', {
id : 'optSelLangTo2'
}, null, '' + languagesGoogle));
getId('optSelLangTo2').value = GM_getValue('to2') ? GM_getValue('to2') : 'Disabled';
getId('optSelLangTo2').addEventListener('change', quickLookup, false);
//use text to speach
divOptionsFields.appendChild(createElement('br'));
divOptionsFields.appendChild(createElement('input', {
id : 'checkTTS',
type : 'checkbox'
}));
divOptionsFields.appendChild(createElement('span', null, null, 'Display Text To Speach'));
getId('checkTTS').checked = GM_getValue('tts');
//hide details
divOptionsFields.appendChild(createElement('br'));
divOptionsFields.appendChild(createElement('input', {
id : 'checkDetails',
type : 'checkbox'
}));
divOptionsFields.appendChild(createElement('span', null, null, 'Hide details by default'));
getId('checkDetails').checked = GM_getValue('details');
//font size
divOptionsFields.appendChild(createElement('br'));
divOptionsFields.appendChild(createElement('span', null, null, 'Font size :'));
divOptionsFields.appendChild(createElement('select', {
id : 'optFontSize'
}, null, ''));
getId('optFontSize').value = GM_getValue('fontsize') ? GM_getValue('fontsize') : 'small';
getId('optFontSize').addEventListener('change', quickLookup, false);
//text color
divOptionsFields.appendChild(createElement('br'));
divOptionsFields.appendChild(createElement('span', null, null, 'Text color :'));
divOptionsFields.appendChild(createElement('select', {
id : 'optTextColor'
}, null, ''));
getId('optTextColor').value = GM_getValue('textcolor') ? GM_getValue('textcolor') : 'Gray';
getId('optTextColor').addEventListener('change', quickLookup, false);
//use ctrl
divOptionsFields.appendChild(createElement('br'));
divOptionsFields.appendChild(createElement('input', {
id : 'checkCtrl',
type : 'checkbox'
}));
divOptionsFields.appendChild(createElement('span', null, null, 'Use Ctrl key'));
getId('checkCtrl').checked = GM_getValue('ctrl');
//use alt
divOptionsFields.appendChild(createElement('br'));
divOptionsFields.appendChild(createElement('input', {
id : 'checkAlt',
type : 'checkbox'
}));
divOptionsFields.appendChild(createElement('span', null, null, 'Use Alt key'));
getId('checkAlt').checked = GM_getValue('alt');
//save
divOptionsFields.appendChild(createElement('br'));
divOptionsFields.appendChild(createElement('a', {
href : HREF_NO,
class : "gootranslink"
}, 'click saveOptions false', 'Save'));
//reset
divOptionsFields.appendChild(createElement('span', null, null, ' - '));
divOptionsFields.appendChild(createElement('a', {
href : HREF_NO,
class : "gootranslink"
}, 'click resetOptions false', 'Reset'));
//cancel
divOptionsFields.appendChild(createElement('span', null, null, ' - '));
divOptionsFields.appendChild(createElement('a', {
href : HREF_NO,
class : "gootranslink"
}, 'click openCloseOptions false', 'Cancel'));
} else // Hide options
{
divOptions.parentNode.removeChild(divOptions);
getId('optionsLink').style.visibility = 'visible';
}
}
function saveOptions(evt) {
var backgroundColor = getId('divDic').style.backgroundColor;
var from = getId('optSelLangFrom').value;
var to = getId('optSelLangTo').value;
var to2 = getId('optSelLangTo2').value;
var tts = getId('checkTTS').checked;
var details = getId('checkDetails').checked;
var fontsize = getId('optFontSize').value;
var textcolor = getId('optTextColor').value;
var ctrl = getId('checkCtrl').checked;
var alt = getId('checkAlt').checked;
GM_setValue('backgroundColor', backgroundColor);
GM_setValue('from', from);
GM_setValue('to', to);
GM_setValue('to2', to2);
GM_setValue('tts', tts);
GM_setValue('details', details);
GM_setValue('fontsize', fontsize);
GM_setValue('textcolor', textcolor);
GM_setValue('ctrl', ctrl);
GM_setValue('alt', alt);
quickLookup();
getId('divDic').removeChild(getId('divOpt'));
getId('optionsLink').style.visibility = 'visible';
}
function resetOptions(evt) {
GM_deleteValue('backgroundColor');
GM_deleteValue('from');
GM_deleteValue('to');
GM_deleteValue('to2');
GM_deleteValue('tts');
GM_deleteValue('fontsize');
GM_deleteValue('textcolor');
GM_deleteValue('ctrl');
GM_deleteValue('alt');
getId('divDic').parentNode.removeChild(getId('divDic'));
}
function css() {
var style = createElement('style', {
type : "text/css"
}, null, "" +
'a.gootranslink:link {color: #0000FF !important; text-decoration: underline !important;}' +
'a.gootranslink:visited {color: #0000FF !important; text-decoration: underline !important;}' +
'a.gootranslink:hover {color: #0000FF !important; text-decoration: underline !important;}' +
'a.gootranslink:active {color: #0000FF !important; text-decoration: underline !important;}' +
'.picker-wrapper,.slide-wrapper{position:relative;float:left}.picker-indicator,.slide-indicator{position:absolute;left:0;top:0;pointer-events:none}.picker,.slide{cursor:crosshair;float:left}.cp-default{background-color:gray;padding:12px;box-shadow:0 0 40px #000;border-radius:15px;float:left}.cp-default .picker{width:200px;height:200px}.cp-default .slide{width:30px;height:200px}.cp-default .slide-wrapper{margin-left:10px}.cp-default .picker-indicator{width:5px;height:5px;border:2px solid darkblue;-moz-border-radius:4px;-o-border-radius:4px;-webkit-border-radius:4px;border-radius:4px;opacity:.5;-ms-filter:"alpha(opacity=50)";filter:alpha(opacity=50);filter:alpha(opacity=50);background-color:white}.cp-default .slide-indicator{width:100%;height:10px;left:-4px;opacity:.6;-ms-filter:"alpha(opacity=60)";filter:alpha(opacity=60);filter:alpha(opacity=60);border:4px solid lightblue;-moz-border-radius:4px;-o-border-radius:4px;-webkit-border-radius:4px;border-radius:4px;background-color:white}.cp-small{padding:5px;background-color:white;float:left;border-radius:5px}.cp-small .picker{width:100px;height:100px}.cp-small .slide{width:15px;height:100px}.cp-small .slide-wrapper{margin-left:5px}.cp-small .picker-indicator{width:1px;height:1px;border:1px solid black;background-color:white}.cp-small .slide-indicator{width:100%;height:2px;left:0;background-color:black}.cp-fancy{padding:10px;background:-webkit-linear-gradient(top,#aaa 0,#222 100%);float:left;border:1px solid #999;box-shadow:inset 0 0 10px white}.cp-fancy .picker{width:200px;height:200px}.cp-fancy .slide{width:30px;height:200px}.cp-fancy .slide-wrapper{margin-left:10px}.cp-fancy .picker-indicator{width:24px;height:24px;background-image:url(http://cdn1.iconfinder.com/data/icons/fugue/bonus/icons-24/target.png)}.cp-fancy .slide-indicator{width:30px;height:31px;left:30px;background-image:url(http://cdn1.iconfinder.com/data/icons/bluecoral/Left.png)}.cp-normal{padding:10px;background-color:white;float:left;border:4px solid #d6d6d6;box-shadow:inset 0 0 10px white}.cp-normal .picker{width:200px;height:200px}.cp-normal .slide{width:30px;height:200px}.cp-normal .slide-wrapper{margin-left:10px}.cp-normal .picker-indicator{width:5px;height:5px;border:1px solid gray;opacity:.5;-ms-filter:"alpha(opacity=50)";filter:alpha(opacity=50);filter:alpha(opacity=50);background-color:white;pointer-events:none}.cp-normal .slide-indicator{width:100%;height:10px;left:-4px;opacity:.6;-ms-filter:"alpha(opacity=60)";filter:alpha(opacity=60);filter:alpha(opacity=60);border:4px solid gray;background-color:white;pointer-events:none}');
getTag('head')[0].appendChild(style);
}
/*
* Short functions to replace the document.createElement document.getElementById and document.getElementsByTagName
*/
function createElement(type, attrArray, evtListener, html) {
var node = document.createElement(type);
for (var attr in attrArray)
if (attrArray.hasOwnProperty(attr)) {
node.setAttribute(attr, attrArray[attr]);
}
if (evtListener) {
var a = evtListener.split(' ');
node.addEventListener(a[0], eval(a[1]), eval(a[2]));
}
if (html)
node.innerHTML = html;
return node;
}
function getId(id, parent) {
if (!parent)
return document.getElementById(id);
return parent.getElementById(id);
}
function getTag(name, parent) {
if (!parent)
return document.getElementsByTagName(name);
return parent.getElementsByTagName(name);
}
/*
* Drag and drop support adapted from http://www.hunlock.com/blogs/Javascript_Drag_and_Drop
*/
var savedTarget = null; // The target layer (effectively vidPane)
var orgCursor = null; // The original mouse style so we can restore it
var dragOK = false; // True if we're allowed to move the element under mouse
var dragXoffset = 0; // How much we've moved the element on the horozontal
var dragYoffset = 0; // How much we've moved the element on the verticle
var didDrag = false; // Set to true when we do a drag
function moveHandler(e) {
if (e == null)
return; // { e = window.event }
if (e.button <= 1 && dragOK) {
savedTarget.style.left = e.clientX - dragXoffset + 'px';
savedTarget.style.top = e.clientY - dragYoffset + 'px';
return false;
}
}
function dragCleanup(e) {
document.removeEventListener('mousemove', moveHandler, false);
document.removeEventListener('mouseup', dragCleanup, false);
savedTarget.style.cursor = orgCursor;
dragOK = false; // Its been dragged now
didDrag = true;
}
function dragHandler(e) {
var htype = '-moz-grabbing';
if (e == null)
return; // { e = window.event;} // htype='move';}
var target = e.target; // != null ? e.target : e.srcElement;
orgCursor = target.style.cursor;
if (target.nodeName != 'DIV' && target.nodeName != 'P')
return;
if (target = clickedInsideID(target, 'divDic')) {
savedTarget = target;
target.style.cursor = htype;
dragOK = true;
dragXoffset = e.clientX - target.offsetLeft;
dragYoffset = e.clientY - target.offsetTop;
// Set the left before removing the right
target.style.left = e.clientX - dragXoffset + 'px';
target.style.right = null;
document.addEventListener('mousemove', moveHandler, false);
document.addEventListener('mouseup', dragCleanup, false);
return false;
}
}
function clickedInsideID(target, id) {
if (target.getAttribute('id') == id)
return getId(id);
if (target.parentNode) {
while (target = target.parentNode) {
try {
if (target.getAttribute('id') == id)
return getId(id);
} catch (e) {}
}
}
return null;
}
// End drag code
/*
* Images
*/
function images() {
imgLookup = createElement('img', {
border : 0
});
imgLookup.src = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABs0lEQVQ4jY2SP4viQBiHX0UQWz/AXb+VX8Iu/YqFhdhcd5BKEOTKC9jJFYrFgo3FIjYiCRauhTCQDMp4bJFklzCuLJLOWNj8rpDMJt7u7Q08xQzze953/hAR0el4QJLw8KR4fXkE/Wtch01zjP6gmxLsd9uPJafjAf1BF82WjmZLR61eRa1eVfNmS4cMxP8JksGk6FPB6XjAii1Qq1fBBYMMBL79+InvDIrbB0CzIpSmQHF0RnF0vkiTFxZX7A+6MOzwU0FxdEZKYJpj1fp1eO5KzF0JzYreF/iekzr77QMUhh2q1zDsUIULPQl6fXkEFww53cWKLWCaY3DBVMuaFWHuSsT7fM/5W5DTXYUMBGQgUJoCpelFst9tcc84DDuE7znQrAiFnrwIkuGY/W6rBIYdQgYC7RmHZkXwPQf3jL8JiCglISLKVCaqzfhZfc9RcMFwc/eMfGd9EWQbS+R0F9nGEtnGEpnKBJnKJFWxPNygPNygPePggqE942nBdTjG9xyUhxvVcqEnsWILrNjiTfCRJN9ZI99Zp8LxWsy73ztTmYCI6ObuGV/7Tym+/PqtICL6A7F/dNYyWabFAAAAAElFTkSuQmCC';
}
if (typeof GM_deleteValue == 'undefined') {
GM_addStyle = function (css) {
var style = document.createElement('style');
style.textContent = css;
document.getElementsByTagName('head')[0].appendChild(style);
}
GM_deleteValue = function (name) {
localStorage.removeItem(name);
}
GM_getValue = function (name, defaultValue) {
var value = localStorage.getItem(name);
if (!value)
return defaultValue;
var type = value[0];
value = value.substring(1);
switch (type) {
case 'b':
return value == 'true';
case 'n':
return Number(value);
default:
return value;
}
}
GM_log = function (message) {
console.log(message);
}
GM_openInTab = function (url) {
return window.open(url, "_blank");
}
GM_registerMenuCommand = function (name, funk) {
//todo
}
GM_setValue = function (name, value) {
value = (typeof value)[0] + value;
localStorage.setItem(name, value);
}
}
/*
* Cross browser support for GM functions
* http://userscripts.org/topics/41177
*/
function initCrossBrowserSupportForGmFunctions() {
if (typeof GM_deleteValue == 'undefined') {
GM_addStyle = function (css) {
var style = document.createElement('style');
style.textContent = css;
document.getElementsByTagName('head')[0].appendChild(style);
}
GM_deleteValue = function (name) {
localStorage.removeItem(name);
}
GM_getValue = function (name, defaultValue) {
var value = localStorage.getItem(name);
if (!value)
return defaultValue;
var type = value[0];
value = value.substring(1);
switch (type) {
case 'b':
return value == 'true';
case 'n':
return Number(value);
default:
return value;
}
}
GM_log = function (message) {
console.log(message);
}
GM_openInTab = function (url) {
return window.open(url, "_blank");
}
GM_registerMenuCommand = function (name, funk) {
//todo
}
GM_setValue = function (name, value) {
value = (typeof value)[0] + value;
localStorage.setItem(name, value);
}
}
}